From 61a763376442cf972acd3ae792ec0e0d885838e5 Mon Sep 17 00:00:00 2001 From: Donavan Becker Date: Mon, 4 Nov 2024 21:04:04 -0600 Subject: [PATCH] v1.1.2 ## [1.1.2](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.1.2) (2024-11-04) ### What's Changes - Fix refreshRate Issue **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.1.1...v1.1.2 --- CHANGELOG.md | 14 +-- package-lock.json | 12 +-- package.json | 4 +- src/devices/device.ts | 202 ++++++++++++++++++++++++++++++++++++++++++ src/platform.ts | 47 +++++----- src/settings.ts | 8 ++ 6 files changed, 250 insertions(+), 37 deletions(-) create mode 100644 src/devices/device.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dd8fd3..c441bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,16 @@ All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/) -## [1.1.1](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.1.1) (2024-11-03) +## [1.1.2](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.1.2) (2024-11-04) ### What's Changes +- Fix refreshRate Issue + +**Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.1.1...v1.1.2 + +## [1.1.1](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.1.1) (2024-11-03) +### What's Changes - Housekeeping and updated dependencies. **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.1.0...v1.1.1 @@ -13,7 +19,6 @@ All notable changes to this project will be documented in this file. This projec ## [1.1.0](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.1.0) (2024-09-25) ### What's Changes - - Add support for self-specified tunnel domain using the `domain` and `token` config. - Housekeeping and updated dependencies. @@ -22,7 +27,6 @@ All notable changes to this project will be documented in this file. This projec ## [1.0.3](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.0.3) (2024-05-26) ### What's Changes - - Housekeeping and updated dependencies. **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.0.2...v1.0.3 @@ -30,7 +34,6 @@ All notable changes to this project will be documented in this file. This projec ## [1.0.2](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.0.2) (2024-02-13) ### What's Changes - - Housekeeping and updated dependencies. **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.0.1...v1.0.2 @@ -38,7 +41,6 @@ All notable changes to this project will be documented in this file. This projec ## [1.0.1](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.0.1) (2024-01-31) ### What's Changes - - Housekeeping and updated dependencies. **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v1.0.0...v1.0.1 @@ -46,7 +48,6 @@ All notable changes to this project will be documented in this file. This projec ## [1.0.0](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v1.0.0) (2024-01-12) ### What's Changes - - Release of [homebridge-cloudflared-tunnel](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel) which allows you to setup a cloudflare tunnel so that you can access your homebridg instance remotely. **Full Changelog**: https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/compare/v0.1.0...v1.0.0 @@ -54,5 +55,4 @@ All notable changes to this project will be documented in this file. This projec ## [0.1.0](https://github.com/homebridge-plugins/homebridge-cloudflared-tunnel/releases/tag/v0.1.0) (2021-08-09) ### What's Changes - - Initial Release diff --git a/package-lock.json b/package-lock.json index 1dc69a0..b6fb534 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebridge-cloudflared-tunnel", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "homebridge-cloudflared-tunnel", - "version": "1.1.1", + "version": "1.1.2", "funding": [ { "type": "Paypal", @@ -29,7 +29,7 @@ "@types/debug": "^4.1.12", "@types/fs-extra": "^11.0.4", "@types/mdast": "^4.0.4", - "@types/node": "^22.8.7", + "@types/node": "^22.9.0", "@types/semver": "^7.5.8", "@types/source-map-support": "^0.5.10", "@vitest/coverage-v8": "^2.1.4", @@ -2345,9 +2345,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.7.tgz", - "integrity": "sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 0893d53..49f2847 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "homebridge-cloudflared-tunnel", "displayName": "Cloudflared Tunnel", "type": "module", - "version": "1.1.1", + "version": "1.1.2", "description": "The Cloudflared Tunnel plugin allows you to run a Cloudflare-Tunnel for exposing your homebridge instance for remote access.", "author": { "name": "donavanbecker", @@ -68,7 +68,7 @@ "@types/debug": "^4.1.12", "@types/fs-extra": "^11.0.4", "@types/mdast": "^4.0.4", - "@types/node": "^22.8.7", + "@types/node": "^22.9.0", "@types/semver": "^7.5.8", "@types/source-map-support": "^0.5.10", "@vitest/coverage-v8": "^2.1.4", diff --git a/src/devices/device.ts b/src/devices/device.ts new file mode 100644 index 0000000..08731cf --- /dev/null +++ b/src/devices/device.ts @@ -0,0 +1,202 @@ +/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * device.ts: homebridge-air. + */ +import type { API, CharacteristicValue, HAP, Logging, PlatformAccessory, Service } from 'homebridge' + +import type { CloudflaredTunnelPlatform } from '../platform.js' +import type { CloudflaredTunnelPlatformConfig, devicesConfig } from '../settings.js' + +export abstract class deviceBase { + public readonly api: API + public readonly log: Logging + public readonly config!: CloudflaredTunnelPlatformConfig + protected readonly hap: HAP + + // Config + protected deviceLogging!: string + protected deviceRefreshRate!: number + protected deviceUpdateRate!: number + protected devicePushRate!: number + protected deviceFirmwareVersion!: string + + constructor( + protected readonly platform: CloudflaredTunnelPlatform, + protected accessory: PlatformAccessory, + protected device: any, + ) { + this.api = this.platform.api + this.log = this.platform.log + this.config = this.platform.config + this.hap = this.api.hap + + this.getDeviceLogSettings(device) + this.getDeviceRateSettings(device) + this.getDeviceConfigSettings(device) + this.getDeviceContext(accessory, device) + + // Set accessory information + accessory + .getService(this.hap.Service.AccessoryInformation)! + .setCharacteristic(this.hap.Characteristic.Manufacturer, 'AirNow') + .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName) + .setCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName) + .setCharacteristic(this.hap.Characteristic.Model, accessory.context.model) + .setCharacteristic(this.hap.Characteristic.SerialNumber, accessory.context.serialNumber) + .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.deviceFirmwareVersion) + .getCharacteristic(this.hap.Characteristic.FirmwareRevision) + .updateValue(this.deviceFirmwareVersion) + } + + async getDeviceLogSettings(device: devicesConfig): Promise { + this.deviceLogging = this.platform.debugMode ? 'debugMode' : device.logging ?? this.platform.platformLogging ?? 'standard' + const logging = this.platform.debugMode ? 'Debug Mode' : device.logging ? 'Device Config' : this.platform.platformLogging ? 'Platform Config' : 'Default' + await this.debugLog(`Using ${logging} Logging: ${this.deviceLogging}`) + } + + async getDeviceRateSettings(device: devicesConfig): Promise { + // refreshRate + this.deviceRefreshRate = device.refreshRate ?? this.platform.platformRefreshRate ?? 3600 + const refreshRate = device.refreshRate ? 'Device Config' : this.platform.platformRefreshRate ? 'Platform Config' : 'Default' + await this.debugLog(`Using ${refreshRate} refreshRate: ${this.deviceRefreshRate}`) + // updateRate + this.deviceUpdateRate = device.updateRate ?? this.platform.platformUpdateRate ?? 5 + const updateRate = device.updateRate ? 'Device Config' : this.platform.platformUpdateRate ? 'Platform Config' : 'Default' + await this.debugLog(`Using ${updateRate} updateRate: ${this.deviceUpdateRate}`) + // pushRate + this.devicePushRate = device.pushRate ?? this.platform.platformPushRate ?? 1 + const pushRate = device.pushRate ? 'Device Config' : this.platform.platformPushRate ? 'Platform Config' : 'Default' + await this.debugLog(`Using ${pushRate} pushRate: ${this.devicePushRate}`) + } + + async getDeviceConfigSettings(device: devicesConfig): Promise { + const deviceConfig = {} + const properties = [ + 'logging', + 'refreshRate', + 'updateRate', + 'pushRate', + ] + properties.forEach((prop) => { + if (device[prop] !== undefined) { + deviceConfig[prop] = device[prop] + } + }) + if (Object.keys(deviceConfig).length !== 0) { + this.infoLog(`Config: ${JSON.stringify(deviceConfig)}`) + } + } + + async getDeviceContext(accessory: PlatformAccessory, device: devicesConfig): Promise { + const deviceFirmwareVersion = device.firmware ?? this.platform.version ?? '0.0.0' + const version = deviceFirmwareVersion.toString() + this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`) + if (version?.includes('.') === false) { + const replace = version?.replace(/^V|-.*$/g, '') + const match = replace?.match(/./g) + const validVersion = match?.join('.') + this.deviceFirmwareVersion = validVersion ?? '0.0.0' + } else { + this.deviceFirmwareVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0' + } + accessory + .getService(this.hap.Service.AccessoryInformation)! + .setCharacteristic(this.hap.Characteristic.HardwareRevision, this.deviceFirmwareVersion) + .setCharacteristic(this.hap.Characteristic.SoftwareRevision, this.deviceFirmwareVersion) + .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.deviceFirmwareVersion) + .getCharacteristic(this.hap.Characteristic.FirmwareRevision) + .updateValue(this.deviceFirmwareVersion) + this.debugSuccessLog(`deviceFirmwareVersion: ${this.deviceFirmwareVersion}`) + } + + /** + * Update the characteristic value and log the change. + * + * @param Service Service + * @param Characteristic Characteristic + * @param CharacteristicValue CharacteristicValue | undefined + * @param CharacteristicName string + * @return: void + * + */ + async updateCharacteristic(Service: Service, Characteristic: any, CharacteristicValue: CharacteristicValue | undefined, CharacteristicName: string): Promise { + if (CharacteristicValue === undefined) { + this.debugLog(`${CharacteristicName}: ${CharacteristicValue}`) + } else { + Service.updateCharacteristic(Characteristic, CharacteristicValue) + this.debugLog(`updateCharacteristic ${CharacteristicName}: ${CharacteristicValue}`) + this.debugWarnLog(`${CharacteristicName} context before: ${this.accessory.context[CharacteristicName]}`) + this.accessory.context[CharacteristicName] = CharacteristicValue + this.debugWarnLog(`${CharacteristicName} context after: ${this.accessory.context[CharacteristicName]}`) + } + } + + /** + * Logging for Device + */ + async infoLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + this.log.info(`${this.accessory.displayName}`, String(...log)) + } + } + + async successLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + this.log.success(`${this.accessory.displayName}`, String(...log)) + } + } + + async debugSuccessLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + if (await this.loggingIsDebug()) { + this.log.success(`[DEBUG] ${this.accessory.displayName}`, String(...log)) + } + } + } + + async warnLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + this.log.warn(`${this.accessory.displayName}`, String(...log)) + } + } + + async debugWarnLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + if (await this.loggingIsDebug()) { + this.log.warn(`[DEBUG] ${this.accessory.displayName}`, String(...log)) + } + } + } + + async errorLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + this.log.error(`${this.accessory.displayName}`, String(...log)) + } + } + + async debugErrorLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + if (await this.loggingIsDebug()) { + this.log.error(`[DEBUG] ${this.accessory.displayName}`, String(...log)) + } + } + } + + async debugLog(...log: any[]): Promise { + if (await this.enablingDeviceLogging()) { + if (this.deviceLogging === 'debug') { + this.log.info(`[DEBUG] ${this.accessory.displayName}`, String(...log)) + } else if (this.deviceLogging === 'debugMode') { + this.log.debug(`${this.accessory.displayName}`, String(...log)) + } + } + } + + async loggingIsDebug(): Promise { + return this.deviceLogging === 'debugMode' || this.deviceLogging === 'debug' + } + + async enablingDeviceLogging(): Promise { + return this.deviceLogging === 'debugMode' || this.deviceLogging === 'debug' || this.deviceLogging === 'standard' + } +} diff --git a/src/platform.ts b/src/platform.ts index 0c8c29b..992521d 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -164,6 +164,31 @@ export class CloudflaredTunnelPlatform implements DynamicPlatformPlugin { } } + async getPlatformLogSettings() { + this.debugMode = argv.includes('-D') ?? argv.includes('--debug') + this.platformLogging = (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' + || this.config.options?.logging === 'none') + ? this.config.options.logging + : this.debugMode ? 'debugMode' : 'standard' + const logging = this.config.options?.logging ? 'Platform Config' : this.debugMode ? 'debugMode' : 'Default' + await this.debugLog(`Using ${logging} Logging: ${this.platformLogging}`) + } + + async getPlatformRateSettings() { + // RefreshRate + this.platformRefreshRate = this.config.options?.refreshRate ? this.config.options.refreshRate : undefined + const refreshRate = this.config.options?.refreshRate ? 'Using Platform Config refreshRate' : 'Platform Config refreshRate Not Set' + await this.debugLog(`${refreshRate}: ${this.platformRefreshRate}`) + // UpdateRate + this.platformUpdateRate = this.config.options?.updateRate ? this.config.options.updateRate : undefined + const updateRate = this.config.options?.updateRate ? 'Using Platform Config updateRate' : 'Platform Config updateRate Not Set' + await this.debugLog(`${updateRate}: ${this.platformUpdateRate}`) + // PushRate + this.platformPushRate = this.config.options?.pushRate ? this.config.options.pushRate : undefined + const pushRate = this.config.options?.pushRate ? 'Using Platform Config pushRate' : 'Platform Config pushRate Not Set' + await this.debugLog(`${pushRate}: ${this.platformPushRate}`) + } + async getPlatformConfigSettings() { if (this.config.options) { const platformConfig: CloudflaredTunnelPlatformConfig = { @@ -180,28 +205,6 @@ export class CloudflaredTunnelPlatform implements DynamicPlatformPlugin { } } - async getPlatformRateSettings() { - this.platformRefreshRate = this.config.options?.refreshRate ? this.config.options.refreshRate : 0 - const refreshRate = this.config.options?.refreshRate ? 'Using Platform Config refreshRate' : 'refreshRate Disabled by Default' - await this.debugLog(`${refreshRate}: ${this.platformRefreshRate}`) - this.platformUpdateRate = this.config.options?.updateRate ? this.config.options.updateRate : 1 - const updateRate = this.config.options?.updateRate ? 'Using Platform Config updateRate' : 'Using Default updateRate' - await this.debugLog(`${updateRate}: ${this.platformUpdateRate}`) - this.platformPushRate = this.config.options?.pushRate ? this.config.options.pushRate : 1 - const pushRate = this.config.options?.pushRate ? 'Using Platform Config pushRate' : 'Using Default pushRate' - await this.debugLog(`${pushRate}: ${this.platformPushRate}`) - } - - async getPlatformLogSettings() { - this.debugMode = argv.includes('-D') ?? argv.includes('--debug') - this.platformLogging = (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' - || this.config.options?.logging === 'none') - ? this.config.options.logging - : this.debugMode ? 'debugMode' : 'standard' - const logging = this.config.options?.logging ? 'Platform Config' : this.debugMode ? 'debugMode' : 'Default' - await this.debugLog(`Using ${logging} Logging: ${this.platformLogging}`) - } - /** * Asynchronously retrieves the version of the plugin from the package.json file. * diff --git a/src/settings.ts b/src/settings.ts index abe989a..3c42486 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -29,3 +29,11 @@ export interface CloudflaredTunnelPlatformConfig extends PlatformConfig { pushRate?: number logging?: string } + +export interface devicesConfig { + refreshRate: number + updateRate: number + pushRate: number + logging: string + firmware: string +}