UNPKG

homebridge-orbit-irrigation

Version:

Orbit Irrigation System platform plugin for [Homebridge](https://github.com/nfarina/homebridge).

645 lines (642 loc) 33.2 kB
'use strict' let OrbitAPI = require('./orbitapi') class Orbit { constructor(platform, log, config) { this.orbitapi = new OrbitAPI(this, log) this.log = log this.config = config this.platform = platform } async updateService(message) { //process incoming messages try { let jsonBody = JSON.parse(message) if (jsonBody.source == 'local') this.log('local source') let deviceName = this.deviceGraph.devices.filter(result => result.id == jsonBody.device_id)[0].name let deviceModel = this.deviceGraph.devices.filter(result => result.id == jsonBody.device_id)[0].hardware_version let eventType = this.deviceGraph.devices.filter(result => result.id == jsonBody.device_id)[0].type let activeService let uuid = UUIDGen.generate(jsonBody.device_id) /***************************** Possible states Active InUse HomeKit Shows False False Off True False Waiting True True Running False True Stopping ******************************/ if (this.showExtraDebugMessages) { this.log.debug('extra message', jsonBody) } //additional debug info before suppressing duplicates this.lastMessage.timestamp = jsonBody.timestamp //ignore message with no timestamp deltas, ignoring mode changes this.secondLastMessage.timestamp = jsonBody.timestamp //ignore message with no timestamp deltas, ignoring mode changes if (JSON.stringify(this.lastMessage) == JSON.stringify(jsonBody) || JSON.stringify(this.secondLastMessage) == JSON.stringify(jsonBody)) { return } //suppress duplicate websocket messages and checks sequence if (this.showExtraDebugMessages) { this.log.info('extra message', jsonBody) } //additional debug info after suppressing duplicates if (jsonBody.event != 'battery_status') //ignore event that is not logged this.secondLastMessage = this.lastMessage this.lastMessage = jsonBody switch (eventType) { case 'sprinkler_timer': let irrigationAccessory let irrigationSystemService let valveAccessory let percent if (this.showIrrigation) { //**Valve**// if (this.showSimpleValve && deviceModel.includes('HT25')) { valveAccessory = this.accessories[uuid] if (!valveAccessory) { return } let batteryService = valveAccessory.getService(Service.Battery) let switchServiceStandby = valveAccessory.getServiceById(Service.Switch, UUIDGen.generate(jsonBody.device_id + 'Standby')) let switchServiceRunall = valveAccessory.getServiceById(Service.Switch, UUIDGen.generate(jsonBody.device_id + 'Run All')) switch (jsonBody.event) { case 'watering_in_progress_notification': activeService = valveAccessory.getService(Service.Valve) if (activeService) { //stop last if program is running if (jsonBody.program != 'manual') { if (!this.activeProgram) { if (this.showSchedules) { this.log.info('Running Program %s, %s', jsonBody.program, valveAccessory.getServiceById(Service.Switch, jsonBody.program).getCharacteristic(Characteristic.Name).value) } else { this.log.info('Running Program %s', jsonBody.program) } } if (this.activeZone[jsonBody.device_id]) { activeService = valveAccessory.getServiceById(Service.Valve, this.activeZone[jsonBody.device_id]) activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) this.activeZone[jsonBody.device_id] = false if (jsonBody.source != 'local') { if (this.activeProgram) { this.log.info('Device %s, Faucet %s scheduled watering', deviceName, activeService.getCharacteristic(Characteristic.Name).value) } } } this.activeProgram = jsonBody.program } //start active zone if (jsonBody.source != 'local') { this.activeZone[jsonBody.device_id] = jsonBody.current_station this.log.info('Device %s faucet, %s watering in progress for %s mins', deviceName, activeService.getCharacteristic(Characteristic.Name).value, Math.round(jsonBody.run_time)) } activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.ACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.IN_USE) activeService.getCharacteristic(Characteristic.SetDuration).updateValue(jsonBody.total_run_time_sec) activeService.getCharacteristic(Characteristic.RemainingDuration).updateValue(parseInt(jsonBody.run_time * 60)) this.endTime[activeService.subtype] = new Date(Date.now() + parseInt(jsonBody.run_time * 60 * 1000)).toISOString() } break case 'watering_complete': activeService = valveAccessory.getService(Service.Valve) if (activeService) { if (jsonBody.source != 'local') { this.log.info('Device %s faucet, %s watering completed', deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.activeZone[jsonBody.device_id] = false } activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } break case 'device_idle': activeService = valveAccessory.getServiceById(Service.Switch, this.activeProgram) //activeService=valveAccessory.getService(Service.Switch) if (this.showRunall && switchServiceRunall) { switchServiceRunall.getCharacteristic(Characteristic.On).updateValue(false) this.log.info('Device is idle') } if (activeService) { //this.log.info('Device %s, %s zone idle',deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.log.info('Program %s completed', activeService.getCharacteristic(Characteristic.Name).value) activeService.getCharacteristic(Characteristic.On).updateValue(false) this.activeProgram = false } else { if (this.activeProgram) { this.log.info('Program %s completed', this.activeProgram) this.activeProgram = false } } activeService = valveAccessory.getService(Service.Valve) if (activeService) { //this.log.info('Device %s, %s zone idle',deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.log.info('Device %s idle', deviceName) activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } break case 'change_mode': this.log.debug('%s mode changed to %s', deviceName, jsonBody.mode) switch (jsonBody.mode) { case 'auto': if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(false) } break case 'manual': if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(false) } break case 'off': if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(true) } break } break case 'device_connected': this.log.info('%s connected at %s', deviceName, new Date(jsonBody.timestamp).toString()) valveAccessory.services.forEach(service => { if (Service.AccessoryInformation.UUID != service.UUID) { if (Service.Battery.UUID != service.UUID) { service.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } } if (Service.Valve.UUID == service.UUID) { service.getCharacteristic(Characteristic.Active).value } if (Service.Switch.UUID == service.UUID) { service.getCharacteristic(Characteristic.On).value } }) break case 'device_disconnected': this.log.warn('%s disconnected at %s! This will show as non-responding in Homekit until the connection is restored.', deviceName, jsonBody.timestamp) valveAccessory.services.forEach(service => { if (Service.AccessoryInformation.UUID != service.UUID) { if (Service.Battery.UUID != service.UUID) { service.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } } if (Service.Valve.UUID == service.UUID) { service.getCharacteristic(Characteristic.Active).value } if (Service.Switch.UUID == service.UUID) { service.getCharacteristic(Characteristic.On).value } }) break case 'battery_status': percent = 0 if (jsonBody.percent) { percent = jsonBody.percent } else if (jsonBody.mv) { percent = (jsonBody.mv / 3815) * 100 > 100 ? 100 : (jsonBody.mv / 3815) * 100 } if (jsonBody.charging == undefined) { jsonBody.charging = false } this.log.debug('update battery status %s to %s%, charging=%s', deviceName, percent, jsonBody.charging) batteryService.getCharacteristic(Characteristic.ChargingState).updateValue(jsonBody.charging) batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(percent) break case 'low_battery': this.log.warn('%s battery low', deviceName) activeService = valveAccessory.getServiceById(Service.Battery, jsonBody.device_id) if (activeService) { activeService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW) activeService.getCharacteristic(Characteristic.BatteryLevel).updateValue(jsonBody.percent_remaining) } break case 'clear_low_battery': this.log.debug('%s battery good', deviceName) activeService = valveAccessory.getServiceById(Service.Battery, jsonBody.device_id) if (activeService) { activeService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL) activeService.getCharacteristic(Characteristic.BatteryLevel).updateValue(jsonBody.percent_remaining) } break case 'device_status': if (this.showExtraDebugMessages) { this.log.debug('%s updated at %s', deviceName, new Date(jsonBody.timestamp).toString()) } break case 'program_changed': this.log.debug('%s program %s %s changed', deviceName, jsonBody.program.program, jsonBody.program.name) break case 'rain_delay': this.log.debug('%s rain delay for %s', deviceName, jsonBody.rain_delay_weather_type) break case 'fault': this.log.debug('Message received: %s for device id %s', jsonBody.event, jsonBody.device_id) break default: this.log.warn('Unknown faucet device message received: %s', jsonBody.event) break } } else { //irrigation system irrigationAccessory = this.accessories[uuid] irrigationSystemService = irrigationAccessory.getService(Service.IrrigationSystem) if (!irrigationAccessory) { return } let batteryService = irrigationAccessory.getService(Service.Battery) let switchServiceStandby = irrigationAccessory.getServiceById(Service.Switch, UUIDGen.generate(jsonBody.device_id + 'Standby')) let switchServiceRunall = irrigationAccessory.getServiceById(Service.Switch, UUIDGen.generate(jsonBody.device_id + 'Run All')) switch (jsonBody.event) { case 'watering_in_progress_notification': irrigationSystemService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.IN_USE) activeService = irrigationAccessory.getServiceById(Service.Valve, jsonBody.current_station) if (activeService) { //stop last if program is running if (jsonBody.program != 'manual') { if (!this.activeProgram) { if (this.showSchedules) { this.log.info('Program %s, %s started', jsonBody.program, irrigationAccessory.getServiceById(Service.Switch, jsonBody.program).getCharacteristic(Characteristic.Name).value) } else { this.log.info('Program %s started', jsonBody.program) } } if (this.activeZone[jsonBody.device_id]) { activeService = irrigationAccessory.getServiceById(Service.Valve, this.activeZone[jsonBody.device_id]) activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) this.activeZone[jsonBody.device_id] = false if (jsonBody.source != 'local') { if (this.activeProgram) { this.log.info('Device %s, Zone %s watering completed, starting next Zone', deviceName, activeService.getCharacteristic(Characteristic.Name).value) } } } this.activeProgram = jsonBody.program } //start active zone if (jsonBody.source != 'local') { this.activeZone[jsonBody.device_id] = jsonBody.current_station if (this.activeProgram) { this.log.info('Device %s, Zone %s watering in progress for %s mins', deviceName, activeService.getCharacteristic(Characteristic.Name).value, Math.round(jsonBody.run_time)) } } if (!jsonBody.total_run_time_sec) { //added for older firmware that may not have this field populated jsonBody.total_run_time_sec = jsonBody.run_time * 60 } activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.ACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.IN_USE) activeService.getCharacteristic(Characteristic.SetDuration).updateValue(jsonBody.total_run_time_sec) activeService.getCharacteristic(Characteristic.RemainingDuration).updateValue(parseInt(jsonBody.run_time * 60)) this.endTime[activeService.subtype] = new Date(Date.now() + parseInt(jsonBody.run_time * 60 * 1000)).toISOString() } //update other zones in quque with status if (jsonBody.water_event_queue) { if (jsonBody.water_event_queue.length > 0) { let match let deviceResponse = await this.orbitapi.getDevice(this.token, jsonBody.device_id).catch(err => { this.log.error('Failed to get device response %s', err) }) for (let n = 0; n < deviceResponse.zones.length; n++) { match = false deviceResponse.zones[n].enabled = true // need orbit version of enabled if (deviceResponse.zones[n]) { for (let i = 0; i < jsonBody.water_event_queue.length; i++) { if (deviceResponse.zones[n].station == jsonBody.current_station && jsonBody.current_station == jsonBody.water_event_queue[i].station) { this.log.debug('%s program %s for zone-%s %s running', deviceName, jsonBody.program, deviceResponse.zones[n].station, deviceResponse.zones[n].name) //zone already running /* activeService=irrigationAccessory.getServiceById(Service.Valve, deviceResponse.zones[n].station) activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.ACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.IN_USE) activeService.getCharacteristic(Characteristic.SetDuration).updateValue(jsonBody.total_run_time_sec) activeService.getCharacteristic(Characteristic.RemainingDuration).updateValue(parseInt(jsonBody.run_time * 60)) this.endTime[activeService.subtype]= new Date(Date.now() + parseInt(jsonBody.run_time * 60 * 1000)).toISOString() */ match = true break } else if (deviceResponse.zones[n].station == jsonBody.water_event_queue[i].station) { this.log.debug('%s program %s for zone-%s %s waiting', deviceName, jsonBody.program, deviceResponse.zones[n].station, deviceResponse.zones[n].name) activeService = irrigationAccessory.getServiceById(Service.Valve, deviceResponse.zones[n].station) if (activeService) { activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.ACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } match = true break } } if (!match) { this.log.debug('%s program %s for zone-%s %s stopped', deviceName, jsonBody.program, deviceResponse.zones[n].station, deviceResponse.zones[n].name) activeService = irrigationAccessory.getServiceById(Service.Valve, deviceResponse.zones[n].station) if (activeService) { activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } continue } } } } //turn program switch off at last zone if (jsonBody.water_event_queue.length == 1) { activeService = irrigationAccessory.getServiceById(Service.Switch, this.activeProgram) if (activeService) { //this.log.info('Device %s, %s zone idle',deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.log.info('Program %s finishing', activeService.getCharacteristic(Characteristic.Name).value) activeService.getCharacteristic(Characteristic.On).updateValue(false) this.activeProgram = false } else { if (this.activeProgram) { this.log.info('Program %s finishing', this.activeProgram) this.activeProgram = false } } } } break case 'watering_complete': irrigationSystemService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) activeService = irrigationAccessory.getServiceById(Service.Valve, this.activeZone[jsonBody.device_id]) if (activeService) { if (jsonBody.source != 'local') { this.log.info('Device %s, Zone %s watering completed', deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.activeZone[jsonBody.device_id] = false } activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } break case 'device_idle': irrigationSystemService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) activeService = irrigationAccessory.getServiceById(Service.Switch, this.activeProgram) if (this.showRunall && switchServiceRunall) { switchServiceRunall.getCharacteristic(Characteristic.On).updateValue(false) this.log.info('Device is idle') } if (activeService) { //this.log.info('Device %s, %s zone idle',deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.log.info('Program %s completed', activeService.getCharacteristic(Characteristic.Name).value) activeService.getCharacteristic(Characteristic.On).updateValue(false) this.activeProgram = false } else { if (this.activeProgram) { this.log.info('Program %s completed', this.activeProgram) this.activeProgram = false } } activeService = irrigationAccessory.getServiceById(Service.Valve, this.activeZone[jsonBody.device_id]) if (activeService) { //this.log.info('Device %s, %s zone idle',deviceName, activeService.getCharacteristic(Characteristic.Name).value) this.log.info('Device %s idle', deviceName) activeService.getCharacteristic(Characteristic.Active).updateValue(Characteristic.Active.INACTIVE) activeService.getCharacteristic(Characteristic.InUse).updateValue(Characteristic.InUse.NOT_IN_USE) } break case 'change_mode': this.log.debug('%s mode changed to %s', deviceName, jsonBody.mode) //this.log.info(activeService.getCharacteristic(Characteristic.Name)) switch (jsonBody.mode) { case 'auto': irrigationSystemService.getCharacteristic(Characteristic.ProgramMode).updateValue(Characteristic.ProgramMode.PROGRAM_SCHEDULED) if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(false) } break case 'manual': irrigationSystemService.getCharacteristic(Characteristic.ProgramMode).updateValue(Characteristic.ProgramMode.PROGRAM_SCHEDULED_MANUAL_MODE) if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(false) } break case 'off': irrigationSystemService.getCharacteristic(Characteristic.ProgramMode).updateValue(Characteristic.ProgramMode.NO_PROGRAM_SCHEDULED) if (this.showStandby && switchServiceStandby) { switchServiceStandby.getCharacteristic(Characteristic.On).updateValue(true) } break } break case 'device_connected': this.log.info('%s connected at %s', deviceName, new Date(jsonBody.timestamp).toString()) irrigationAccessory.services.forEach(service => { if (Service.AccessoryInformation.UUID != service.UUID) { if (Service.Battery.UUID != service.UUID) { service.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } } if (Service.Valve.UUID == service.UUID) { service.getCharacteristic(Characteristic.Active).value } if (Service.Switch.UUID == service.UUID) { service.getCharacteristic(Characteristic.On).value } }) break case 'device_disconnected': this.log.warn('%s disconnected at %s! This will show as non-responding in Homekit until the connection is restored.', deviceName, jsonBody.timestamp) irrigationAccessory.services.forEach(service => { if (Service.AccessoryInformation.UUID != service.UUID) { if (Service.Battery.UUID != service.UUID) { service.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } } if (Service.Valve.UUID == service.UUID) { service.getCharacteristic(Characteristic.Active).value } if (Service.Switch.UUID == service.UUID) { service.getCharacteristic(Characteristic.On).value } }) break case 'battery_status': percent = 0 if (jsonBody.percent) { percent = jsonBody.percent } else if (jsonBody.mv) { if (deviceModel.includes('HT32')) { this.log.debug(deviceModel) } percent = (jsonBody.mv / 3367) * 100 > 100 ? 100 : (jsonBody.mv / 3367) * 100 //not sure why not 3000 for 2 AA batteries } if (jsonBody.charging == undefined) { jsonBody.charging = false } this.log.debug('update battery status %s to %s%, charging=%s', deviceName, percent, jsonBody.charging) batteryService.getCharacteristic(Characteristic.ChargingState).updateValue(jsonBody.charging) batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(percent) break case 'low_battery': this.log.warn('%s battery low', deviceName) activeService = irrigationAccessory.getServiceById(Service.Battery, jsonBody.device_id) if (activeService) { activeService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW) activeService.getCharacteristic(Characteristic.BatteryLevel).updateValue(jsonBody.percent_remaining) } break case 'clear_low_battery': this.log.debug('%s battery good', deviceName) activeService = irrigationAccessory.getServiceById(Service.Battery, jsonBody.device_id) if (activeService) { activeService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL) activeService.getCharacteristic(Characteristic.BatteryLevel).updateValue(jsonBody.percent_remaining) } break case 'device_status': if (this.showExtraDebugMessages) { this.log.debug('%s updated at %s', deviceName, new Date(jsonBody.timestamp).toString()) } break case 'program_changed': this.log.debug('%s program %s %s changed', deviceName, jsonBody.program.program, jsonBody.program.name) break case 'rain_delay': this.log.debug('%s rain delay for %s', deviceName, jsonBody.rain_delay_weather_type) break case 'fault': this.log.debug('Message received: %s for device id %s', jsonBody.event, jsonBody.device_id) break default: this.log.warn('Unknown sprinkler device message received: %s', jsonBody.event) break } } } break case 'bridge': let bridgeAccessory if (this.showBridge) { bridgeAccessory = this.accessories[uuid] if (!bridgeAccessory) { return } activeService = bridgeAccessory.getServiceById(Service.Tunnel, jsonBody.device_id) } switch (jsonBody.event) { case 'device_connected': this.log.info('%s connected at %s', deviceName, new Date(jsonBody.timestamp).toString()) if (this.showBridge) { activeService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } break case 'device_disconnected': this.log.warn('%s disconnected at %s! This will show as non-responding in Homekit until the connection is restored.', deviceName, new Date(jsonBody.timestamp).toString()) if (this.showBridge) { activeService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } break case 'device_idle': //do nothing break case 'change_mode': //do nothing break case 'fault': //do nothing this.log.debug('Message received: %s for bridge device id %s', jsonBody.event, jsonBody.device_id) break default: this.log.warn('Unknown bridge device message received: %s', jsonBody.event) break } break case 'flood_sensor': let FSAccessory let leakService let tempService let batteryService let occupancySensor if (this.showFloodSensor || this.showTempSensor) { FSAccessory = this.accessories[uuid] if (!FSAccessory) { return } leakService = FSAccessory.getService(Service.LeakSensor) tempService = FSAccessory.getService(Service.TemperatureSensor) batteryService = FSAccessory.getService(Service.Battery) occupancySensor = FSAccessory.getService(Service.OccupancySensor) switch (jsonBody.event) { case 'battery_status': this.log.debug('update battery status %s %s to %s%', jsonBody.location_name, jsonBody.name, jsonBody.battery.percent) batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(jsonBody.battery.percent) if (jsonBody.battery.percent <= this.lowBattery) { batteryService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW) } else { batteryService.getCharacteristic(Characteristic.StatusLowBattery).updateValue(Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL) } //batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(Math.floor((Math.random() * 100) + 1)) //enable for testing break case 'fs_status_update': //this.log.info('%s status update at %s',deviceName,new Date(jsonBody.timestamp).toString()) if (this.showFloodSensor) { switch (jsonBody.flood_alarm_status) { case 'ok': leakService.getCharacteristic(Characteristic.LeakDetected).updateValue(Characteristic.LeakDetected.LEAK_NOT_DETECTED) break case 'alarm': leakService.getCharacteristic(Characteristic.LeakDetected).updateValue(Characteristic.LeakDetected.LEAK_DETECTED) break default: leakService.getCharacteristic(Characteristic.LeakDetected).updateValue(Characteristic.LeakDetected.LEAK_NOT_DETECTED) break } } if (this.showTempSensor) { tempService.getCharacteristic(Characteristic.CurrentTemperature).updateValue(((jsonBody.temp_f - 32) * 5) / 9) } if (this.showLimitsSensor) { switch (jsonBody.temp_alarm_status) { case 'ok': occupancySensor.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED) break case 'low_temp_alarm': occupancySensor.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_DETECTED) break case 'high_temp_alarm': occupancySensor.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_DETECTED) break default: occupancySensor.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED) break } } break case 'device_connected': this.log.info('%s connected at %s', deviceName, new Date(jsonBody.timestamp).toString()) if (this.showFloodSensor) { leakService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } if (this.showTempSensor) { tempService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } if (this.showLimitsSensor) { occupancySensor.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.NO_FAULT) } break case 'device_disconnected': this.log.warn('%s disconnected at %s! This will show as non-responding in Homekit until the connection is restored.', deviceName, new Date(jsonBody.timestamp).toString()) if (this.showFloodSensor) { leakService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } if (this.showTempSensor) { tempService.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } if (this.showLimitsSensor) { occupancySensor.getCharacteristic(Characteristic.StatusFault).updateValue(Characteristic.StatusFault.GENERAL_FAULT) } break case 'fault': //do nothing break default: this.log.warn('Unknown flood sensor device message received: %s', jsonBody.event) break } } break default: this.log.warn('Unknown irrigation device message received: %s', jsonBody.event) break } return } catch (err) { this.log.error('Error updating service %s', err) } } } module.exports = Orbit