Skip to content

Commit

Permalink
v3.0.2 - homebridge v2 (#72)
Browse files Browse the repository at this point in the history
- Fixed an issue where homekit complains about specific characters in device names
- `hisense-tv authorize` now also checks if mac address was already authorized
  • Loading branch information
LeLunZ authored Sep 11, 2024
1 parent 9bdc9a5 commit 1565307
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 19 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 3.0.2

Tested homebridge v2 and found no major issues.

### Fixed
- Fixed an issue where homekit complains about specific characters in device names

### Added
- `hisense-tv authorize` now also checks if mac address was already authorized

# 3.0.1

Please checkout the 3.0.0 release notes for the changes in this major version.
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"displayName": "HiSense TV",
"name": "homebridge-hisense-tv-remotenow",
"version": "3.0.1",
"version": "3.0.2",
"description": "Control RemoteNow-enabled HiSense TVs.",
"main": "dist/index.js",
"license": "MIT",
Expand Down Expand Up @@ -36,8 +36,8 @@
]
},
"engines": {
"node": "^18.17.0 || ^20.9.0",
"homebridge": "^1.8.0"
"homebridge": "^1.8.0 || ^2.0.0-beta.0",
"node": "^18.20.4 || ^20.15.1"
},
"dependencies": {
"fast-deep-equal": "^3.1.3",
Expand Down
9 changes: 5 additions & 4 deletions src/inputSourceSubPlatformAccessory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Characteristic, CharacteristicValue, PlatformAccessory, Service} from 'homebridge';
import {InputSource} from './interfaces/input-source.interface.js';
import {TVApp} from './interfaces/tv-app.interface.js';
import {validateHomeKitName} from './utils/validateHomeKitName.function.js';

/**
* InputSourceSubPlatformAccessory
Expand All @@ -12,8 +13,8 @@ export class InputSourceSubPlatformAccessory {
}

public createInputService(identifier: string){
return this.accessory.getService(identifier)
|| this.accessory.addService(this.service.InputSource, identifier, identifier);
return this.accessory.getService(validateHomeKitName(identifier))
|| this.accessory.addService(this.service.InputSource, validateHomeKitName(identifier), validateHomeKitName(identifier));
}

/**
Expand Down Expand Up @@ -59,8 +60,8 @@ export class InputSourceSubPlatformAccessory {
inputService
.setCharacteristic(this.characteristic.Identifier, identifier)
.setCharacteristic(this.characteristic.IsConfigured, this.characteristic.IsConfigured.CONFIGURED)
.setCharacteristic(this.characteristic.ConfiguredName, configuredName)
.setCharacteristic(this.characteristic.Name, sourceName)
.setCharacteristic(this.characteristic.ConfiguredName, validateHomeKitName(configuredName))
.setCharacteristic(this.characteristic.Name, validateHomeKitName(sourceName))
.setCharacteristic(this.characteristic.CurrentVisibilityState, this.characteristic.CurrentVisibilityState.SHOWN)
.setCharacteristic(this.characteristic.InputSourceType, inputType);
}
Expand Down
3 changes: 2 additions & 1 deletion src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {API, DynamicPlatformPlugin, PlatformAccessory, PlatformConfig, Service,
import { PLUGIN_NAME } from './settings.js';
import { HiSenseTVAccessory } from './platformAccessory.js';
import {DeviceConfig} from './interfaces/device-config.interface.js';
import {validateHomeKitName} from './utils/validateHomeKitName.function.js';

/**
* HomebridgePlatform
Expand Down Expand Up @@ -97,7 +98,7 @@ export class HiSenseTVPlatform implements DynamicPlatformPlugin {
this.log.info('Adding new accessory:', device.name);

// create a new accessory
const accessory = new this.api.platformAccessory(device.name, uuid, Categories.TELEVISION);
const accessory = new this.api.platformAccessory(validateHomeKitName(device.name), uuid, Categories.TELEVISION);

// store a copy of the device object in the `accessory.context`
// the `context` property can be used to store any data about the accessory you may need
Expand Down
3 changes: 2 additions & 1 deletion src/platformAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {WoL} from './wol.js';
import {sourcesAreEqual} from './utils/sourcesAreEqual.function.js';
import {InputSourceSubPlatformAccessory} from './inputSourceSubPlatformAccessory.js';
import {validateDeviceConfig} from './utils/validateDeviceConfig.function.js';
import {validateHomeKitName} from './utils/validateHomeKitName.function.js';

/**
* Platform Accessory
Expand Down Expand Up @@ -91,7 +92,7 @@ export class HiSenseTVAccessory {

// Configure the service.
this.service
.setCharacteristic(this.Characteristic.ConfiguredName, this.deviceConfig.name)
.setCharacteristic(this.Characteristic.ConfiguredName, validateHomeKitName(this.deviceConfig.name))
.setCharacteristic(this.Characteristic.SleepDiscoveryMode, this.Characteristic.SleepDiscoveryMode.NOT_DISCOVERABLE)
.setCharacteristic(this.Characteristic.Active, this.Characteristic.Active.INACTIVE);

Expand Down
7 changes: 2 additions & 5 deletions src/scripts/hisenseTV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ if(sslPrivateKey === '' && sslCertificate === '') {
sslMode = 'default';
}

if(values['help'] || macaddress == null || hostname == null) {
if(values['help'] || macaddress === undefined || hostname === undefined) {
terminateWithHelpMessage(rl, script);
process.exit(0);
}

const logger = {
Expand Down Expand Up @@ -140,10 +139,8 @@ try{

const get = values['get'];

if(get == null) {
if(get === undefined) {
terminateWithHelpMessage(rl, script);
// terminate so get is typed as not null
process.exit(0);
}
sendCommand(rl, mqttHelper, get);
break;
Expand Down
23 changes: 19 additions & 4 deletions src/scripts/hisenseTV/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,34 @@ import path from 'path';
import {clearTimeout} from 'node:timers';

export function authorize(rl: readline.Interface, mqttHelper: HisenseMQTTClient): SubscriptExitCode {
const aborter = new AbortController();
let timeout: NodeJS.Timeout|undefined;
mqttHelper.mqttClient.on('connect', () => {
// trigger the tv to show the pairing code
mqttHelper.callService('ui_service', 'gettvstate');

// also trigger the tv to send the source list
// to check if we are already authorized
// source list uses the device identifier (mac)
// thus it's better to use than the state
// as the state could also be sent by other devices
mqttHelper.subscribe(mqttHelper._SOURCE_LIST_TOPIC);
mqttHelper.callService('ui_service', 'sourcelist');
});

mqttHelper.mqttClient.on('message', (topic, message) => {
const strMessage = message.toString();
if(strMessage.length === 0) {
rl.write(`Received empty message on ${topic}`);
return;
}
const data = JSON.parse(strMessage);
if(data != null && typeof data === 'object' && 'result' in data) {
if(timeout != null) {
if(topic === mqttHelper._SOURCE_LIST_TOPIC){
aborter.abort();
rl.write('\nMac address is already authorized!\n');
process.exit(0);
} else if(data != null && typeof data === 'object' && 'result' in data) {
if(timeout !== undefined) {
clearTimeout(timeout);
}
mqttHelper.mqttClient.end(true);
Expand All @@ -34,12 +49,12 @@ export function authorize(rl: readline.Interface, mqttHelper: HisenseMQTTClient)
});

(async () => {
const code = await rl.question('Please enter the 4-digit code shown on tv: ');
const code = await rl.question('Please enter the 4-digit code shown on tv: ', { signal: aborter.signal });
mqttHelper.subscribe(path.join(mqttHelper._COMMUNICATION_TOPIC, '#'));
timeout = setTimeout(() => {
rl.write('Timeout\n');
process.exit(1);
}, 5000);
}, 8000);
mqttHelper.sendAuthCode(code);
})();

Expand Down
2 changes: 1 addition & 1 deletion src/scripts/terminationHelper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import readline from 'node:readline/promises';

export function terminateWithHelpMessage(rl: readline.Interface, script: string) {
export function terminateWithHelpMessage(rl: readline.Interface, script: string): never {
rl.write(`Usage: hisense-tv ${script} --hostname <hostname> --mac <macaddress> [--no-ssl] [--certfile <certfile>] [--keyfile <keyfile>]\n`);
rl.write('Options:\n');
rl.write(' --hostname <hostname> IP address of the TV\n');
Expand Down
10 changes: 10 additions & 0 deletions src/utils/validateHomeKitName.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function validateHomeKitName(name: string) {
// Remove leading and trailing whitespace
name = name.trim();
// Remove any characters that are not alphanumeric, whitespace, period, single quote, or hyphen
name = name.replace(/[^A-Za-z0-9\s'.-]/g, '');
// Remove leading non-alphanumeric characters
name = name.replace(/^[^a-zA-Z0-9]*/g, '');
// Remove trailing non-alphanumeric characters
return name.replace(/[^a-zA-Z0-9]+$/g, '');
}

0 comments on commit 1565307

Please sign in to comment.