From ea9c5bfc68272eca0d24ab4929a0763d02141c69 Mon Sep 17 00:00:00 2001 From: Just Jam Date: Sun, 17 Nov 2024 13:33:26 +0000 Subject: [PATCH 1/3] Bug fixes --- config.schema.json | 6 ++--- src/sensors/virtualSensor.ts | 10 +++++--- src/triggers/triggerPing.ts | 49 ++++++++++++++++++++---------------- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/config.schema.json b/config.schema.json index 9fa9817..f07f6d6 100644 --- a/config.schema.json +++ b/config.schema.json @@ -42,11 +42,11 @@ "type": "string", "required": true, "oneOf": [ - { "title": "Switch", "enum": ["switch"] }, - { "title": "Lock", "enum": ["lock"] }, { "title": "Doorbell", "enum": ["doorbell"] }, { "title": "Garage Door", "enum": ["garagedoor"] }, - { "title": "Sensor", "enum": ["sensor"] } + { "title": "Lock", "enum": ["lock"] }, + { "title": "Sensor", "enum": ["sensor"] }, + { "title": "Switch", "enum": ["switch"] } ], "default": "switch" }, diff --git a/src/sensors/virtualSensor.ts b/src/sensors/virtualSensor.ts index b79a007..3fa67e0 100644 --- a/src/sensors/virtualSensor.ts +++ b/src/sensors/virtualSensor.ts @@ -118,7 +118,7 @@ export abstract class VirtualSensor extends Accessory { triggerCompanionSensorState(sensorState: number, accessory: Accessory) { if (!this.isCompanionSensor) { throw new NotCompanionError(`${this.accessoryConfiguration.accessoryName} is not a companion sensor`); - } else if (accessory.accessory.UUID === this.accessory.UUID) { + } else if (accessory.accessory.UUID !== this.accessory.UUID) { throw new AccessoryNotAllowedError(`Switch ${accessory.accessoryConfiguration.accessoryName} is not allowed to trigger this sensor`); } @@ -133,15 +133,19 @@ export abstract class VirtualSensor extends Accessory { * This method is called by the trigger to toggle the sensor */ triggerKeySensorState(sensorState: number, trigger: Trigger) { - if (!(trigger.sensorConfig.accessoryID === this.accessoryConfiguration.accessoryID)) { + if (trigger.sensorConfig.accessoryID !== this.accessoryConfiguration.accessoryID) { throw new TriggerNotAllowedError(`Trigger ${trigger.name} is not allowed to trigger this sensor`); } + const sensorStateChanged: boolean = (this.states.SensorState !== sensorState) ? true : false; + this.states.SensorState = sensorState; this.service!.updateCharacteristic(this.sensorCharacteristic, (this.states.SensorState)); - this.platform.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Sensor Current State: ${this.getStateName(this.states.SensorState)}`); + if (sensorStateChanged) { + this.platform.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Sensor Current State: ${this.getStateName(this.states.SensorState)}`); + } } protected getStateName(state: number): string { diff --git a/src/triggers/triggerPing.ts b/src/triggers/triggerPing.ts index 6a267d8..75d35f4 100644 --- a/src/triggers/triggerPing.ts +++ b/src/triggers/triggerPing.ts @@ -1,18 +1,18 @@ import { Trigger } from './trigger.js'; import { VirtualSensor } from '../sensors/virtualSensor.js'; +import { AccessoryConfiguration } from '../configuration/configurationAccessory.js'; +import { PingTriggerConfiguration } from '../configuration/configurationPingTrigger.js'; // import dns from 'dns'; import net from 'net'; import ping from 'net-ping'; -import { AccessoryConfiguration } from '../configuration/configurationAccessory.js'; -import { PingTriggerConfiguration } from '../configuration/configurationPingTrigger.js'; /** - * Private wrapper class to pass failureCount by reference + * Private helper classes to pass values by reference */ class Counter { - value: number = 0; + value: number; constructor( value: number, @@ -32,24 +32,22 @@ export class PingTrigger extends Trigger { private failureCount = new Counter(0); - private done: boolean = false; - constructor( sensor: VirtualSensor, name: string, ) { super(sensor, name); - const trigger: PingTriggerConfiguration = this.sensorConfig.pingTrigger; + const triggerConfig: PingTriggerConfiguration = this.sensorConfig.pingTrigger; - this.log.info(`[${this.sensorConfig.accessoryName}] PingTriggerConfig ${JSON.stringify(trigger)}`); + this.log.info(`[${this.sensorConfig.accessoryName}] PingTriggerConfig ${JSON.stringify(triggerConfig)}`); - if (trigger.isDisabled) { + if (triggerConfig.isDisabled) { this.log.info(`[${this.sensorConfig.accessoryName}] Ping trigger is disabled`); return; } - const ipProtocolVersion = net.isIP(trigger.host); + const ipProtocolVersion = net.isIP(triggerConfig.host); // TODO: DNS lookup // if (ipVersion === this.NOT_IP) { // const ip = this.getIP(trigger.host); @@ -64,19 +62,23 @@ export class PingTrigger extends Trigger { case this.IPv6: protocol = ping.NetworkProtocol.IPv6; break; + // case this.NOT_IP: + // // TODO: this is a domain name, perform DNS lookup + // protocol = ping.NetworkProtocol.None; // 0 + // break; default: this.log.error(`[${this.sensorConfig.accessoryName}] Unkown or invalid IP protocol version: ${ipProtocolVersion}`); return; } this.log.debug(`[${this.sensorConfig.accessoryName}] Protocol: ${ping.NetworkProtocol[protocol]}`); - const pingTimeoutMillis = 20 * 1000; // trigger.pingTimeout: 20 seconds - const intervalBetweenPingsMillis = 30 * 1000; // trigger.intervalBetweenPings: 60 seconds + const pingTimeoutMillis = 10 * 1000; // trigger.pingTimeout: 10 seconds + const intervalBetweenPingsMillis = 60 * 1000; // trigger.intervalBetweenPings: 60 seconds setInterval( this.ping, intervalBetweenPingsMillis, this, - trigger, + triggerConfig, protocol, pingTimeoutMillis); } @@ -85,16 +87,21 @@ export class PingTrigger extends Trigger { * Private methods */ - private ping( + private async ping( trigger: PingTrigger, triggerConfig: PingTriggerConfiguration, protocol: string, pingTimeoutMillis: number, ) { + // If protocol === None, do a DNS lookup + // const host = await getIP(hostname: string); + // protocol = ping.NetworkProtocol.IPv4; + // Create a helper class for protocol, so the value can be updated + const options = { networkProtocol: protocol, packetSize: 16, - retries: 1, + retries: 3, sessionId: (process.pid % 65535), timeout: pingTimeoutMillis, ttl: 128, @@ -103,6 +110,7 @@ export class PingTrigger extends Trigger { const sensorConfig: AccessoryConfiguration = trigger.sensor.accessoryConfiguration; const session = ping.createSession(options); + session.pingHost(triggerConfig.host, (error, target: string, sent: number, rcvd: number) => { const millis = rcvd - sent; if (error) { @@ -119,7 +127,7 @@ export class PingTrigger extends Trigger { trigger.sensor.triggerKeySensorState(trigger.sensor.OPEN_TRIGGERED, trigger); } } else { - trigger.log.debug(`[${sensorConfig.accessoryName}] Ping ${target}: Alive (ms=${millis})`); + trigger.log.debug(`[${sensorConfig.accessoryName}] Ping ${target}: Alive (latency: ${millis}ms)`); trigger.failureCount.value = 0; trigger.sensor.triggerKeySensorState(trigger.sensor.CLOSED_NORMAL, trigger); @@ -130,18 +138,15 @@ export class PingTrigger extends Trigger { } // private async getIP(hostname: string) { - // const obj = await dns.promises.lookup(hostname) + // const response = await dns.promises.lookup(hostname) // .then((result: dns.LookupAddress) => { // this.sensor.platform.log.error(`[${this.sensorConfig.accessoryName}] IP address retrieved for '${hostname}' is '${result.address}'`); // }) // .catch((error: Error) => { // this.sensor.platform.log.error(`[${this.sensorConfig.accessoryName}] Error retrieving IP address for '${hostname}': ${error.message}`); // }) - // .finally(() => { - // this.done = true; - // }); - - // return obj?.address; + // + // return response?.address; // } } From a4e04442bb73d328cf20a8715d2887e3c56c53f5 Mon Sep 17 00:00:00 2001 From: Just Jam Date: Sun, 17 Nov 2024 13:34:18 +0000 Subject: [PATCH 2/3] Bumped version to beta 10 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 021f4a1..107589c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebridge-virtual-accessories", - "version": "1.0.0-beta.9", + "version": "1.0.0-beta.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "homebridge-virtual-accessories", - "version": "1.0.0-beta.9", + "version": "1.0.0-beta.10", "license": "Apache-2.0", "dependencies": { "@js-joda/core": "^5.6.3", diff --git a/package.json b/package.json index 8457053..3ecf59e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "homebridge-virtual-accessories", "displayName": "Virtual Accessories for Homebridge", "type": "module", - "version": "1.0.0-beta.9", + "version": "1.0.0-beta.10", "description": "Virtual accessories for Homebridge.", "author": "justjam2013", "license": "Apache-2.0", From 6dc765c83171c78837bad5752174778bce2397c6 Mon Sep 17 00:00:00 2001 From: Just Jam Date: Sun, 17 Nov 2024 13:45:20 +0000 Subject: [PATCH 3/3] Updated known with known issues --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 608ff60..c56fcd9 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,10 @@ Note: **Note:** Due to limitations in the current version of one of Homebridge UI's dependencies, the Homebridge UI saves additional fields to the JSON config that may not be related by the particular accessory. This does not affect the behavior of the accessory, nor does it hurt to manually remove those fields from the JSON. The next release of the dependency used by Homebridge UI should implement the ability to make fields conditionally required and the configuration will be updated to reflect that. +## Known Issues + +- When creating a Cron Trigger, the date-time is saved properly, but upon editing is not displayed back. This is a UI bug with an open ticket. + ## Issues If you have problems, please feel free to open a ticket on GitHub. Please attach any log output to the a ticket, making