generated from homebridge/homebridge-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
155 lines (131 loc) · 4.31 KB
/
index.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
148
149
150
151
152
153
154
155
import {
AccessoryConfig,
AccessoryPlugin,
API,
CharacteristicEventTypes,
CharacteristicGetCallback,
HAP,
Logging,
Service,
} from 'homebridge';
let hap: HAP;
/*
* Initializer function called when the plugin is loaded.
*/
export = (api: API) => {
hap = api.hap;
api.registerAccessory('AM2320TemperatureSensor', AM2320TemperatureSensor);
api.registerAccessory('AM2320HumiditySensor', AM2320HumiditySensor);
};
interface SensorData {
temperature: number;
humidity: number;
}
class AM2320HumiditySensor implements AccessoryPlugin {
private readonly log: Logging;
private readonly name: string;
private humidity = 0;
private readonly humidityService: Service;
private readonly informationService: Service;
constructor(log: Logging, config: AccessoryConfig/*, api: API*/) {
this.log = log;
this.name = config.name;
this.humidityService = new hap.Service.HumiditySensor(this.name);
this.humidityService
.getCharacteristic(hap.Characteristic.CurrentRelativeHumidity)
.on(CharacteristicEventTypes.GET, async (callback: CharacteristicGetCallback) => {
try {
const sensorData: SensorData = await readSensorData();
this.humidity = sensorData.humidity;
} catch (err) {
this.log.error(err);
} finally {
callback(undefined, this.humidity);
}
});
this.informationService = new hap.Service.AccessoryInformation()
.setCharacteristic(hap.Characteristic.Manufacturer, 'adafruit')
.setCharacteristic(hap.Characteristic.Model, 'AM2320');
log.info('AM2320HumiditySensor finished initializing!');
}
/*
* This method is optional to implement. It is called when HomeKit ask to identify the accessory.
* Typical this only ever happens at the pairing process.
*/
identify(): void {
this.log('Identify!');
}
/*
* This method is called directly after creation of this instance.
* It should return all services which should be added to the accessory.
*/
getServices(): Service[] {
return [
this.informationService,
this.humidityService,
];
}
}
class AM2320TemperatureSensor implements AccessoryPlugin {
private readonly log: Logging;
private readonly name: string;
private temperature = 0;
private readonly temperatureService: Service;
private readonly informationService: Service;
constructor(log: Logging, config: AccessoryConfig/*, api: API*/) {
this.log = log;
this.name = config.name;
this.temperatureService = new hap.Service.TemperatureSensor(this.name);
this.temperatureService
.getCharacteristic(hap.Characteristic.CurrentTemperature)
.on(CharacteristicEventTypes.GET, async (callback: CharacteristicGetCallback) => {
try {
const sensorData: SensorData = await readSensorData();
this.temperature = sensorData.temperature;
} catch (err) {
this.log.error(err);
} finally {
callback(undefined, this.temperature);
}
});
this.informationService = new hap.Service.AccessoryInformation()
.setCharacteristic(hap.Characteristic.Manufacturer, 'adafruit')
.setCharacteristic(hap.Characteristic.Model, 'AM2320');
log.info('AM2320TemperatureSensor finished initializing!');
}
/*
* This method is optional to implement. It is called when HomeKit ask to identify the accessory.
* Typical this only ever happens at the pairing process.
*/
identify(): void {
this.log('Identify!');
}
/*
* This method is called directly after creation of this instance.
* It should return all services which should be added to the accessory.
*/
getServices(): Service[] {
return [
this.informationService,
this.temperatureService,
];
}
}
async function readSensorData(): Promise<SensorData> {
const sensorScriptFile = `${__dirname}/lib/read-am2320-sensor.py`;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const spawn = require('child_process').spawn;
const process = spawn('python3', [sensorScriptFile]);
return new Promise((resolve, reject) => {
process.stdout.on('data', data => {
try {
resolve(JSON.parse(data.toString()));
} catch (err) {
reject(err.toString());
}
});
process.stderr.on('data', err => {
reject(err.toString());
});
});
}