Skip to content

Commit

Permalink
Merge pull request #16 from justjam2013/bug-fixes
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
justjam2013 authored Nov 17, 2024
2 parents 7c23de8 + 6dc765c commit 48e5f11
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 31 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 7 additions & 3 deletions src/sensors/virtualSensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
}

Expand All @@ -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 {
Expand Down
49 changes: 27 additions & 22 deletions src/triggers/triggerPing.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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);
Expand All @@ -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);
}
Expand All @@ -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,
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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;
// }
}

Expand Down

0 comments on commit 48e5f11

Please sign in to comment.