From 7c5f4dd552a2a44910b4cd34c57d24ec195c3566 Mon Sep 17 00:00:00 2001 From: Serge Wagener Date: Tue, 8 Feb 2022 20:32:40 +0100 Subject: [PATCH] Working on WindowCovering --- src/Accessories/WindowCovering.ts | 103 ++++++++++++++++++++++++++++++ src/platform.ts | 9 ++- tsconfig.json | 5 +- 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 src/Accessories/WindowCovering.ts diff --git a/src/Accessories/WindowCovering.ts b/src/Accessories/WindowCovering.ts new file mode 100644 index 0000000..9a28d8a --- /dev/null +++ b/src/Accessories/WindowCovering.ts @@ -0,0 +1,103 @@ +import { + AccessoryPlugin, + CharacteristicValue, + Service, + Nullable, +} from 'homebridge'; + +import { SmartHomeNGPlatform } from '../platform'; + +export class WindowCovering implements AccessoryPlugin { + private readonly deviceService: Service; + private readonly informationService: Service; + + public name: string; + private currentPosition = 0; + private currentPositionMin = 0; + private currentPositionMax = 100; + private currentPositionInverted = false; + private targetPosition = 0; + private positionState = this.platform.Characteristic.PositionState.STOPPED; + + constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) { + this.name = accessory.name; + this.deviceService = new this.platform.Service.WindowCovering(accessory.name); + + // create handlers for required characteristics + this.deviceService.getCharacteristic(this.platform.Characteristic.CurrentPosition) + .onGet(this.getCurrentPosition.bind(this)); + + this.deviceService.getCharacteristic(this.platform.Characteristic.TargetPosition) + .onGet(this.getTargetPosition.bind(this)) + .onSet(this.setTargetPosition.bind(this)); + + this.deviceService.getCharacteristic(this.platform.Characteristic.PositionState) + .onGet(this.getPositionState.bind(this)); + + this.informationService = + new this.platform.Service.AccessoryInformation() + .setCharacteristic(this.platform.Characteristic.Manufacturer, accessory.manufacturer) + .setCharacteristic(this.platform.Characteristic.Model, accessory.model) + .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.currentposition); + + this.platform.shng.addMonitor(accessory.currentposition, this.shngCallback.bind(this)); + + this.currentPositionMax = accessory.currentpositionmax ? accessory.currentpositionmax : this.currentPositionMax; + this.currentPositionMin = accessory.currentpositionmin ? accessory.currentpositionmin : this.currentPositionMin; + this.currentPositionInverted = accessory.currentpositioninverted ? accessory.currentpositioninverted : this.currentPositionInverted; + this.platform.log.info("WindowCovering '%s' created!", accessory.name); + } + + identify(): void { + this.platform.log.info('Identify!'); + } + + getServices(): Service[] { + return [this.informationService, this.deviceService]; + } + + getCurrentPosition(): Nullable { + this.platform.log.info('getCurrentPosition:', this.accessory.name, 'is currently', this.currentPosition); + return this.currentPosition; + } + + getPositionState(): Nullable { + this.platform.log.info('getPositionState:', this.accessory.name, 'is currently', this.positionState); + return this.positionState; + } + + getTargetPosition(): Nullable { + this.targetPosition = this.currentPosition; + this.platform.log.info('getTargetPosition:', this.accessory.name, 'is currently', this.targetPosition); + return this.targetPosition; + } + + setTargetPosition(value: CharacteristicValue) { + this.targetPosition = value as number; + this.platform.log.info('SetOn:', this.accessory.name, 'was set to', this.targetPosition); + //this.platform.shng.setItem(this.accessory.targetPosition, this.targetPosition); + } + + shngCallback(value: unknown): void { + this.platform.log.debug('shngCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); + if (typeof value === 'number') { + this.currentPosition = this.convertRange( + value as number, + this.currentPositionMin, this.currentPositionMax, + 0, 100, + this.currentPositionInverted, + ); + this.deviceService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, this.currentPosition); + } else { + this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value); + } + } + + convertRange(value: number, oldmin: number, oldmax: number, newmin: number, newmax: number, inverted: boolean): number { + let result = (((value - oldmin) * (newmax - newmin)) / (oldmax - oldmin)) + newmin; + if (inverted) { + result = newmax - result; + } + return result; + } +} diff --git a/src/platform.ts b/src/platform.ts index 1a8dab4..7f0c48e 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -17,6 +17,7 @@ import { Fan } from './Accessories/Fan'; import { Lightbulb } from './Accessories/Lightbulb'; import { TemperatureSensor } from './Accessories/TemperatureSensor'; import { Thermostat } from './Accessories/Thermostat'; +import { WindowCovering } from './Accessories/WindowCovering'; function uncapitalizeKeys(obj): Record { function isObject(o: unknown): boolean { @@ -113,11 +114,17 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin { devices.push(new TemperatureSensor(this, accessory)); break; - // TemperatureSensor + // Thermostat case 'thermostat': devices.push(new Thermostat(this, accessory)); break; + // WindowCovering + case 'windowcovering': + devices.push(new WindowCovering(this, accessory)); + break; + + // Show error for (yet ?) unsupported device default: this.log.warn('Accessory type', accessory.type, 'for', accessory.name, 'not recognized !'); break; diff --git a/tsconfig.json b/tsconfig.json index bf07099..5eba9c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,9 +18,10 @@ "noImplicitAny": false }, "include": [ - "src/" + "src/", + "src/Accessories/.ts" ], "exclude": [ "**/*.spec.ts" ] -} +} \ No newline at end of file