-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
executable file
·88 lines (77 loc) · 4.14 KB
/
index.js
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
const miflora = require('miflora')
let Accessory, Service, Characteristic, UUIDGen
module.exports = function (homebridge) {
Accessory = homebridge.platformAccessory
Service = homebridge.hap.Service
Characteristic = homebridge.hap.Characteristic
UUIDGen = homebridge.hap.uuid
homebridge.registerPlatform('homebridge-xiaomi-plant-monitor', 'xiaomi-plant-monitor', MifloraPlatfrom, true)
}
class MifloraPlatfrom {
constructor(log, config, api) {
this.log = log
this.api = api
this.fetchDataIntervalInMs = config['fetchDataIntervalInMs'] || 3600000 // Every hours
this.plants = []
this.run().catch(error => this.log.error(error))
setInterval(() => this.run().catch(error => this.log.error(error)), this.fetchDataIntervalInMs)
}
async run() {
try {
this.log('Search and Add new plant')
await this.searchAndAddNewPlant()
this.log('Fetch plants data')
await this.fetchPlantsData()
} catch (e) {
this.log.error(e)
}
}
async fetchPlantsData() {
this.plants.forEach(plant => this.updatePlantData(plant))
}
async searchAndAddNewPlant() {
this.log('Scanning for Mi plant')
const devices = await miflora.discover()
this.log('Finish scanning found %s plant(s)', devices.length)
devices.forEach(device => this.addPlantAccessory(device))
}
async addPlantAccessory(device) {
const plant = this.plants.find(plant => plant.accessory.displayName === device.address)
if (plant === undefined) {
this.log(`Add new plant ${device.address}`)
const accessory = new Accessory(device.address, UUIDGen.generate(device.address))
accessory.addService(Service.HumiditySensor, device.address)
accessory.addService(Service.BatteryService, device.address)
this.plants.push({device, accessory})
this.api.registerPlatformAccessories('homebridge-xiaomi-plant-monitor', 'xiaomi-plant-monitor', [accessory])
} else if (plant.device === undefined) {
this.log(`Set cached plant`)
const indexToUpdate = this.plants.findIndex(plant => plant.accessory.displayName === device.address)
this.plants[indexToUpdate] = {device, accessory: plant.accessory}
} else {
this.log(`No plant to add`)
}
}
async updatePlantData(plant) {
if (plant.device === undefined) {
this.log('Cached plant not found remove from accessory')
this.api.unregisterPlatformAccessories('homebridge-xiaomi-plant-monitor', 'xiaomi-plant-monitor', [plant.accessory])
const indexToDelete = this.plants.findIndex(element => element === plant)
this.plants.splice(indexToDelete, 1)
return
}
const {firmwareInfo: {battery, firmware}, sensorValues: {temperature, lux, moisture, fertility}} = await plant.device.query()
this.log(`battery: ${battery}% firmware: ${firmware} temperature: ${temperature}° lux: ${lux} moisture: ${moisture}% fertility: ${fertility}`)
const humidityService = plant.accessory.getService(Service.HumiditySensor)
const batteryService = plant.accessory.getService(Service.BatteryService)
humidityService.getCharacteristic(Characteristic.CurrentRelativeHumidity).updateValue(moisture)
humidityService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(battery < 10 ? Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL)
batteryService.setCharacteristic(Characteristic.ChargingState, Characteristic.ChargingState.NOT_CHARGEABLE)
batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(battery)
batteryService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(battery < 10 ? Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL)
}
async configureAccessory(accessory) {
this.log(accessory.displayName, 'Add cached Accessory')
this.plants.push({device: undefined, accessory})
}
}