generated from homebridge/homebridge-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
platformAccessory.ts
148 lines (121 loc) · 6.37 KB
/
platformAccessory.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { PlatformAccessory, CharacteristicValue } from 'homebridge';
import { RadiantCoolingPlatformPlugin } from './platform';
/**
* Platform Accessory
* An instance of this class is created for each accessory your platform registers
* Each accessory may expose multiple services of different service types.
*/
export class RadiantCoolingZoneAccessory {
constructor(
private readonly platform: RadiantCoolingPlatformPlugin,
private readonly accessory: PlatformAccessory,
private readonly zoneIndex: number,
) {
// set accessory information
this.accessory.getService(this.platform.Service.AccessoryInformation)!
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Messana')
.setCharacteristic(this.platform.Characteristic.Model, 'Zone')
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'radiant-' + zoneIndex);
// get the Theromostat service if it exists, otherwise create a new Thermostat service
// you can create multiple services for each accessory
const thermostatService = this.accessory.getService(this.platform.Service.Thermostat)
|| this.accessory.addService(this.platform.Service.Thermostat);
// set the service name, this is what is displayed as the default name on the Home app
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
thermostatService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
// each service must implement at-minimum the "required characteristics" for the given service type
// see https://developers.homebridge.io/#/service/Lightbulb
// register handlers for the On/Off Characteristic
thermostatService.getCharacteristic(this.platform.Characteristic.CurrentHeatingCoolingState)
.onGet(this.getHeatingCoolingState.bind(this));
thermostatService.getCharacteristic(this.platform.Characteristic.TargetHeatingCoolingState)
.onGet(this.getTargetHeatingCoolingState.bind(this))
.onSet(this.setTargetHeatingCoolingState.bind(this));
thermostatService.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
.onGet(this.getCurrentTemperature.bind(this));
thermostatService.getCharacteristic(this.platform.Characteristic.TargetTemperature)
.onGet(this.getTargetTemperature.bind(this))
.onSet(this.setTargetTemperature.bind(this));
// Example: add two "motion sensor" services to the accessory
// const motionSensorOneService = this.accessory.getService('Motion Sensor One Name') ||
// this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor One Name', 'YourUniqueIdentifier-1');
// const motionSensorTwoService = this.accessory.getService('Motion Sensor Two Name') ||
// this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor Two Name', 'YourUniqueIdentifier-2');
/**
* Updating characteristics values asynchronously.
*
* Example showing how to update the state of a Characteristic asynchronously instead
* of using the `on('get')` handlers.
* Here we change update the motion sensor trigger states on and off every 10 seconds
* the `updateCharacteristic` method.
*
*/
// const motionDetected = false;
// setInterval(() => {
// // EXAMPLE - inverse the trigger
// motionDetected = !motionDetected;
// // push the new value to HomeKit
// motionSensorOneService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected);
// motionSensorTwoService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected);
// this.platform.log.debug('Triggering motionSensorOneService:', motionDetected);
// this.platform.log.debug('Triggering motionSensorTwoService:', !motionDetected);
// }, 10000);
}
async getHeatingCoolingState(): Promise<CharacteristicValue> {
return this.platform.messanaApiFetch('zone/thermalStatus/' + this.zoneIndex)
.then(json => json['status']);
}
async getTargetHeatingCoolingState(): Promise<CharacteristicValue> {
return this.platform.messanaApiFetch('zone/status/' + this.zoneIndex)
.then(json => {
const zoneStatus = json['status'];
// if zone is off, return off, else get the hc state from the overall system
if (zoneStatus === 0) {
return Promise.resolve(0);
} else {
return this.platform.messanaApiFetch('hc/mode/0')
.then(json => json['value'] + 1);
}
});
}
async setTargetHeatingCoolingState(value: CharacteristicValue) {
// messana zone only supports 0 or 1
this.platform.messanaApiPut('zone/status', {
'id': this.zoneIndex,
'value': Math.min(1, value.valueOf() as number),
});
}
async getCurrentTemperature(): Promise<CharacteristicValue> {
return this.platform.messanaApiFetch('zone/temperature/' + this.zoneIndex)
.then(json => this.toCelsius(json['value']));
}
async getTargetTemperature(): Promise<CharacteristicValue> {
return this.platform.messanaApiFetch('zone/setpoint/' + this.zoneIndex)
.then(json => this.toCelsius(json['value']));
}
async setTargetTemperature(value: CharacteristicValue) {
const fahrenheit = this.toFahrenheit(value.valueOf() as number);
// switch the zone on in case it was off before
this.platform.messanaApiPut('zone/status', { 'id': this.zoneIndex, 'value': 1 });
// try to disable the schedule in case the zone is off due to schedule
// but this doesn't work currently because messana api has a bug such that
// schedule can't be disabled through the scheduleOn api call
// this.platform.messanaApiFetch('zone/scheduleStatus/' + this.zoneIndex)
// .then(json => {
// const isOffBySchedule = (json['value'] === 0);
// if (isOffBySchedule) {
// // disable schedule
// this.platform.messanaApiPut('zone/scheduleOn', { 'id': this.zoneIndex, 'value': 0 });
// // in an ideal case, put the schedule back on after some time has elapsed
// // because the temporary need has probably gone away
// }
// });
this.platform.messanaApiPut('zone/setpoint', { 'id': this.zoneIndex, 'value': fahrenheit });
}
toCelsius(fahrenheit: number): number {
return (fahrenheit - 32) * 5.0 / 9;
}
toFahrenheit(celsius: number): number {
return celsius * 9.0 / 5 + 32;
}
}