mirror of
https://github.com/tsightler/ring-mqtt.git
synced 2025-10-27 10:40:41 +08:00
Initial device state framework
This commit is contained in:
@@ -22,6 +22,9 @@ class RingPolledDevice extends RingDevice {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.monitorHeartbeat()
|
this.monitorHeartbeat()
|
||||||
|
|
||||||
|
// Request saved state for device
|
||||||
|
utils.event.emit('get_device_state', this.deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish device discovery, set online, and send all state data
|
// Publish device discovery, set online, and send all state data
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class RingDevice {
|
|||||||
this.isOnline = () => {
|
this.isOnline = () => {
|
||||||
return this.availabilityState === 'online' ? true : false
|
return this.availabilityState === 'online' ? true : false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.debug = (message, debugType) => {
|
this.debug = (message, debugType) => {
|
||||||
utils.debug(debugType === 'disc' ? message : colors.green(`[${this.device.name}] `)+message, debugType ? debugType : 'mqtt')
|
utils.debug(debugType === 'disc' ? message : colors.green(`[${this.device.name}] `)+message, debugType ? debugType : 'mqtt')
|
||||||
}
|
}
|
||||||
@@ -19,10 +20,22 @@ class RingDevice {
|
|||||||
this.deviceTopic = `${utils.config.ring_topic}/${this.locationId}/${category}/${this.deviceId}`
|
this.deviceTopic = `${utils.config.ring_topic}/${this.locationId}/${category}/${this.deviceId}`
|
||||||
this.availabilityTopic = `${this.deviceTopic}/status`
|
this.availabilityTopic = `${this.deviceTopic}/status`
|
||||||
|
|
||||||
|
if (deviceInfo.hasOwnProperty('childDevices')) {
|
||||||
|
this.childDevices = deviceInfo.childDevices
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceInfo.hasOwnProperty('parentDevices')) {
|
||||||
|
this.parentDevices = deviceInfo.parentDevices
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize device with saved state data
|
||||||
|
utils.event.on(`device_state_${this.deviceId}`, (stateData) => {
|
||||||
|
this.init(stateData)
|
||||||
if (primaryAttribute !== 'disable') {
|
if (primaryAttribute !== 'disable') {
|
||||||
this.initAttributeEntities(primaryAttribute)
|
this.initAttributeEntities(primaryAttribute)
|
||||||
this.schedulePublishAttributes()
|
this.schedulePublishAttributes()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function loops through each entity of the device, creates a unique
|
// This function loops through each entity of the device, creates a unique
|
||||||
@@ -151,7 +164,7 @@ class RingDevice {
|
|||||||
Object.keys(discoveryMessage).filter(property => property.match('topic')).forEach(topic => {
|
Object.keys(discoveryMessage).filter(property => property.match('topic')).forEach(topic => {
|
||||||
this.entity[entityKey][topic] = discoveryMessage[topic]
|
this.entity[entityKey][topic] = discoveryMessage[topic]
|
||||||
if (topic.match('command_topic')) {
|
if (topic.match('command_topic')) {
|
||||||
utils.event.emit('mqttSubscribe', discoveryMessage[topic])
|
utils.event.emit('mqtt_subscribe', discoveryMessage[topic])
|
||||||
utils.event.on(discoveryMessage[topic], (command, message) => {
|
utils.event.on(discoveryMessage[topic], (command, message) => {
|
||||||
this.processCommand(command, message)
|
this.processCommand(command, message)
|
||||||
})
|
})
|
||||||
@@ -193,7 +206,7 @@ class RingDevice {
|
|||||||
if (debugType !== false) {
|
if (debugType !== false) {
|
||||||
this.debug(colors.blue(`${topic} `)+colors.cyan(`${message}`), debugType)
|
this.debug(colors.blue(`${topic} `)+colors.cyan(`${message}`), debugType)
|
||||||
}
|
}
|
||||||
utils.event.emit('mqttPublish', topic, message)
|
utils.event.emit('mqtt_publish', topic, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state topic online
|
// Set state topic online
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ class RingSocketDevice extends RingDevice {
|
|||||||
this.device.onData.subscribe((data) => {
|
this.device.onData.subscribe((data) => {
|
||||||
if (this.isOnline()) { this.publishState(data) }
|
if (this.isOnline()) { this.publishState(data) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Request saved state for device
|
||||||
|
utils.event.emit('get_device_state', this.deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish device discovery, set online, and send all state data
|
// Publish device discovery, set online, and send all state data
|
||||||
|
|||||||
@@ -4,14 +4,12 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class BaseStation extends RingSocketDevice {
|
class BaseStation extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm', 'acStatus')
|
super(deviceInfo, 'alarm', 'acStatus')
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
this.deviceData.mdl = 'Alarm Base Station'
|
this.deviceData.mdl = 'Alarm Base Station'
|
||||||
this.deviceData.name = this.device.location.name + ' Base Station'
|
this.deviceData.name = this.device.location.name + ' Base Station'
|
||||||
|
|
||||||
this.initVolumeEntity()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if account has access to control base state volume and initialize topics if so
|
|
||||||
async initVolumeEntity() {
|
|
||||||
const origVolume = (this.device.data.volume && !isNaN(this.device.data.volume) ? this.device.data.volume : 0)
|
const origVolume = (this.device.data.volume && !isNaN(this.device.data.volume) ? this.device.data.volume : 0)
|
||||||
const testVolume = (origVolume === 1) ? .99 : origVolume+.01
|
const testVolume = (origVolume === 1) ? .99 : origVolume+.01
|
||||||
this.device.setVolume(testVolume)
|
this.device.setVolume(testVolume)
|
||||||
|
|||||||
@@ -4,28 +4,29 @@ const { RingDeviceType } = require('ring-client-api')
|
|||||||
class BeamOutdoorPlug extends RingSocketDevice {
|
class BeamOutdoorPlug extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'lighting')
|
super(deviceInfo, 'lighting')
|
||||||
this.deviceData.mdl = 'Outdoor Smart Plug'
|
|
||||||
|
|
||||||
this.childDevices = {
|
|
||||||
outlet1: deviceInfo.childDevices.find(d => d.deviceType === RingDeviceType.BeamsSwitch && d.data.relToParentZid === "1"),
|
|
||||||
outlet2: deviceInfo.childDevices.find(d => d.deviceType === RingDeviceType.BeamsSwitch && d.data.relToParentZid === "2")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.deviceData.mdl = 'Outdoor Smart Plug'
|
||||||
|
|
||||||
|
this.outlet1 = this.childDevices.find(d => d.deviceType === RingDeviceType.BeamsSwitch && d.data.relToParentZid === "1"),
|
||||||
|
this.outlet2 = this.childDevices.find(d => d.deviceType === RingDeviceType.BeamsSwitch && d.data.relToParentZid === "2")
|
||||||
|
|
||||||
this.entity.outlet1 = {
|
this.entity.outlet1 = {
|
||||||
component: (this.childDevices.outlet1.data.categoryId === 2) ? 'light' : 'switch',
|
component: (this.outlet1.data.categoryId === 2) ? 'light' : 'switch',
|
||||||
name: `${this.childDevices.outlet1.name}`
|
name: `${this.outlet1.name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
this.entity.outlet2 = {
|
this.entity.outlet2 = {
|
||||||
component: (this.childDevices.outlet2.data.categoryId === 2) ? 'light' : 'switch',
|
component: (this.outlet2.data.categoryId === 2) ? 'light' : 'switch',
|
||||||
name: `${this.childDevices.outlet2.name}`
|
name: `${this.outlet2.name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
this.childDevices.outlet1.onData.subscribe((data) => {
|
this.outlet1.onData.subscribe((data) => {
|
||||||
if (this.isOnline()) { this.publishOutlet1State() }
|
if (this.isOnline()) { this.publishOutlet1State() }
|
||||||
})
|
})
|
||||||
|
|
||||||
this.childDevices.outlet2.onData.subscribe((data) => {
|
this.outlet2.onData.subscribe((data) => {
|
||||||
if (this.isOnline()) { this.publishOutlet2State() }
|
if (this.isOnline()) { this.publishOutlet2State() }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -37,11 +38,11 @@ class BeamOutdoorPlug extends RingSocketDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publishOutlet1State() {
|
publishOutlet1State() {
|
||||||
this.mqttPublish(this.entity.outlet1.state_topic, this.childDevices.outlet1.data.on ? "ON" : "OFF")
|
this.mqttPublish(this.entity.outlet1.state_topic, this.outlet1.data.on ? "ON" : "OFF")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishOutlet2State() {
|
publishOutlet2State() {
|
||||||
this.mqttPublish(this.entity.outlet2.state_topic, this.childDevices.outlet2.data.on ? "ON" : "OFF")
|
this.mqttPublish(this.entity.outlet2.state_topic, this.outlet2.data.on ? "ON" : "OFF")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process messages from MQTT command topic
|
// Process messages from MQTT command topic
|
||||||
@@ -73,7 +74,7 @@ class BeamOutdoorPlug extends RingSocketDevice {
|
|||||||
const duration = 32767
|
const duration = 32767
|
||||||
const on = command === 'on' ? true : false
|
const on = command === 'on' ? true : false
|
||||||
const data = on ? { lightMode: 'on', duration } : { lightMode: 'default' }
|
const data = on ? { lightMode: 'on', duration } : { lightMode: 'default' }
|
||||||
this.childDevices[outletId].sendCommand('light-mode.set', data)
|
this[outletId].sendCommand('light-mode.set', data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Beam extends RingSocketDevice {
|
class Beam extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'lighting')
|
super(deviceInfo, 'lighting')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
// Setup device topics based on capabilities.
|
// Setup device topics based on capabilities.
|
||||||
switch (this.device.data.deviceType) {
|
switch (this.device.data.deviceType) {
|
||||||
case 'group.light-group.beams':
|
case 'group.light-group.beams':
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ const { RingDeviceType } = require('ring-client-api')
|
|||||||
class BinarySensor extends RingSocketDevice {
|
class BinarySensor extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
let device_class = 'None'
|
let device_class = 'None'
|
||||||
|
|
||||||
// Override icons and and topics
|
// Override icons and and topics
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Bridge extends RingSocketDevice {
|
class Bridge extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm', 'commStatus')
|
super(deviceInfo, 'alarm', 'commStatus')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Bridge'
|
this.deviceData.mdl = 'Bridge'
|
||||||
this.deviceData.name = this.device.location.name + ' Bridge'
|
this.deviceData.name = this.device.location.name + ' Bridge'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ const rss = require('../lib/rtsp-simple-server')
|
|||||||
class Camera extends RingPolledDevice {
|
class Camera extends RingPolledDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'camera')
|
super(deviceInfo, 'camera')
|
||||||
|
}
|
||||||
|
|
||||||
|
init(stateData) {
|
||||||
this.data = {
|
this.data = {
|
||||||
motion: {
|
motion: {
|
||||||
active_ding: false,
|
active_ding: false,
|
||||||
@@ -109,6 +111,27 @@ class Camera extends RingPolledDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateData) {
|
||||||
|
if (utils.config.snapshot_mode.match(/^(interval|all)$/)) {
|
||||||
|
if (stateData.hasOwnProperty('snapshot')) {
|
||||||
|
this.data.snapshot.autoInterval = stateData.snapshot.hasOwnProperty('autoInterval')
|
||||||
|
? stateData.snapshot.autoInterval
|
||||||
|
: this.data.snapshot.autoInterval
|
||||||
|
if (!this.data.snapshot.autoInterval) {
|
||||||
|
this.data.snapshot.interval = stateData.snapshot.hasOwnProperty('interval')
|
||||||
|
? stateData.snapshot.interval
|
||||||
|
: this.data.snapshot.interval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateData.hasOwnProperty('event_select')) {
|
||||||
|
this.data.event_select.state = stateData.event_select.hasOwnProperty('state')
|
||||||
|
? stateData.event_select.state
|
||||||
|
: this.data.event_select.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.entity = {
|
this.entity = {
|
||||||
...this.entity,
|
...this.entity,
|
||||||
motion: {
|
motion: {
|
||||||
@@ -178,7 +201,7 @@ class Camera extends RingPolledDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.event.on(`${this.deviceId}_livestream`, (state) => {
|
utils.event.on(`livestream_${this.deviceId}`, (state) => {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'active':
|
case 'active':
|
||||||
if (this.data.stream.live.status !== 'active') {
|
if (this.data.stream.live.status !== 'active') {
|
||||||
@@ -207,34 +230,6 @@ class Camera extends RingPolledDevice {
|
|||||||
if (this.isOnline()) { this.processDing(ding) }
|
if (this.isOnline()) { this.processDing(ding) }
|
||||||
})
|
})
|
||||||
|
|
||||||
utils.event.on(`deviceState_${this.deviceId}`, (stateData) => {
|
|
||||||
this.initDeviceState(stateData)
|
|
||||||
})
|
|
||||||
utils.event.emit('getDeviceState', this.deviceId)
|
|
||||||
}
|
|
||||||
|
|
||||||
async initDeviceState(stateData) {
|
|
||||||
if (stateData) {
|
|
||||||
if (utils.config.snapshot_mode.match(/^(interval|all)$/)) {
|
|
||||||
if (stateData.hasOwnProperty('snapshot')) {
|
|
||||||
this.data.snapshot.autoInterval = stateData.snapshot.hasOwnProperty('autoInterval')
|
|
||||||
? stateData.snapshot.autoInterval
|
|
||||||
: this.data.snapshot.autoInterval
|
|
||||||
if (!this.data.snapshot.autoInterval) {
|
|
||||||
this.data.snapshot.interval = stateData.snapshot.hasOwnProperty('interval')
|
|
||||||
? stateData.snapshot.interval
|
|
||||||
: this.data.snapshot.interval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stateData.hasOwnProperty('event_select')) {
|
|
||||||
this.data.event_select.state = stateData.event_select.hasOwnProperty('state')
|
|
||||||
? stateData.event_select.state
|
|
||||||
: this.data.event_select.state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.data.snapshot.interval > 0) {
|
if (this.data.snapshot.interval > 0) {
|
||||||
this.scheduleSnapshotRefresh()
|
this.scheduleSnapshotRefresh()
|
||||||
}
|
}
|
||||||
@@ -249,10 +244,10 @@ class Camera extends RingPolledDevice {
|
|||||||
interval: this.data.snapshot.interval
|
interval: this.data.snapshot.interval
|
||||||
},
|
},
|
||||||
event_select: {
|
event_select: {
|
||||||
state: this.data.snapshot.state
|
state: this.data.event_select.state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils.event.emit(`saveDeviceState`, this.deviceId, stateData)
|
utils.event.emit(`save_device_state`, this.deviceId, stateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build standard and optional entities for device
|
// Build standard and optional entities for device
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ const RingPolledDevice = require('./base-polled-device')
|
|||||||
class Chime extends RingPolledDevice {
|
class Chime extends RingPolledDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'chime')
|
super(deviceInfo, 'chime')
|
||||||
|
}
|
||||||
|
|
||||||
|
init(stateData) {
|
||||||
this.data = {
|
this.data = {
|
||||||
volume: null,
|
volume: null,
|
||||||
snooze: null,
|
snooze: null,
|
||||||
@@ -14,6 +16,12 @@ class Chime extends RingPolledDevice {
|
|||||||
play_motion_sound: 'OFF'
|
play_motion_sound: 'OFF'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateData) {
|
||||||
|
this.data.snooze_minutes = (stateData.hasOwnProperty('snooze_minutes'))
|
||||||
|
? stateData.snooze_minutes
|
||||||
|
: this.data.snooze_minutes
|
||||||
|
}
|
||||||
|
|
||||||
// Define entities for this device
|
// Define entities for this device
|
||||||
this.entity = {
|
this.entity = {
|
||||||
...this.entity,
|
...this.entity,
|
||||||
@@ -48,6 +56,15 @@ class Chime extends RingPolledDevice {
|
|||||||
value_template: '{{ value_json["lastUpdate"] | default("") }}'
|
value_template: '{{ value_json["lastUpdate"] | default("") }}'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.saveDeviceState()
|
||||||
|
}
|
||||||
|
|
||||||
|
saveDeviceState() {
|
||||||
|
const stateData = {
|
||||||
|
snooze_minutes: this.data.snooze_minutes
|
||||||
|
}
|
||||||
|
utils.event.emit(`save_device_state`, this.deviceId, stateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
initAttributeEntities() {
|
initAttributeEntities() {
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class CoAlarm extends RingSocketDevice {
|
class CoAlarm extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'CO Alarm'
|
this.deviceData.mdl = 'CO Alarm'
|
||||||
this.deviceData.mf = (deviceInfo.hasOwnProperty('parentDevice') && deviceInfo.parentDevice.data && deviceInfo.parentDevice.data.hasOwnProperty('manufacturerName'))
|
this.deviceData.mf = (this.hasOwnProperty('parentDevice') && this.parentDevice.hasOwnProperty('data') && this.parentDevice.data.hasOwnProperty('manufacturerName'))
|
||||||
? deviceInfo.parentDevice.data.manufacturerName
|
? this.parentDevice.data.manufacturerName
|
||||||
: 'Ring'
|
: 'Ring'
|
||||||
|
|
||||||
this.entity.co = {
|
this.entity.co = {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Fan extends RingSocketDevice {
|
class Fan extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Fan Control'
|
this.deviceData.mdl = 'Fan Control'
|
||||||
|
|
||||||
this.entity.fan = {
|
this.entity.fan = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class FloodFreezeSensor extends RingSocketDevice {
|
class FloodFreezeSensor extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Flood & Freeze Sensor'
|
this.deviceData.mdl = 'Flood & Freeze Sensor'
|
||||||
|
|
||||||
this.entity.flood = {
|
this.entity.flood = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Keypad extends RingSocketDevice {
|
class Keypad extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Security Keypad'
|
this.deviceData.mdl = 'Security Keypad'
|
||||||
|
|
||||||
this.entity.volume = {
|
this.entity.volume = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Lock extends RingSocketDevice {
|
class Lock extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Lock'
|
this.deviceData.mdl = 'Lock'
|
||||||
|
|
||||||
this.entity.lock = {
|
this.entity.lock = {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const RingPolledDevice = require('./base-polled-device')
|
|||||||
class ModesPanel extends RingPolledDevice {
|
class ModesPanel extends RingPolledDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm', 'disable')
|
super(deviceInfo, 'alarm', 'disable')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Mode Control Panel'
|
this.deviceData.mdl = 'Mode Control Panel'
|
||||||
this.deviceData.name = `${this.device.location.name} Mode`
|
this.deviceData.name = `${this.device.location.name} Mode`
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class MultiLevelSwitch extends RingSocketDevice {
|
class MultiLevelSwitch extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Dimming Light'
|
this.deviceData.mdl = 'Dimming Light'
|
||||||
|
|
||||||
this.entity.light = {
|
this.entity.light = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class RangeExtender extends RingSocketDevice {
|
class RangeExtender extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm', 'acStatus')
|
super(deviceInfo, 'alarm', 'acStatus')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Z-Wave Range Extender'
|
this.deviceData.mdl = 'Z-Wave Range Extender'
|
||||||
this.deviceData.name = this.device.location.name + ' Range Extender'
|
this.deviceData.name = this.device.location.name + ' Range Extender'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class SecurityPanel extends RingSocketDevice {
|
class SecurityPanel extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm', 'alarmState')
|
super(deviceInfo, 'alarm', 'alarmState')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Alarm Control Panel'
|
this.deviceData.mdl = 'Alarm Control Panel'
|
||||||
this.deviceData.name = `${this.device.location.name} Alarm`
|
this.deviceData.name = `${this.device.location.name} Alarm`
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@ class SecurityPanel extends RingSocketDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publishState() {
|
publishState() {
|
||||||
var alarmMode
|
let alarmMode
|
||||||
const alarmInfo = this.device.data.alarmInfo ? this.device.data.alarmInfo : []
|
const alarmInfo = this.device.data.alarmInfo ? this.device.data.alarmInfo : []
|
||||||
|
|
||||||
// If alarm is active report triggered or, if entry-delay, pending
|
// If alarm is active report triggered or, if entry-delay, pending
|
||||||
@@ -150,7 +153,7 @@ class SecurityPanel extends RingSocketDevice {
|
|||||||
while (retries-- > 0 && !(setAlarmSuccess)) {
|
while (retries-- > 0 && !(setAlarmSuccess)) {
|
||||||
let bypassDeviceIds = []
|
let bypassDeviceIds = []
|
||||||
|
|
||||||
// If arming bypass arming mode is enabled, get device ids requiring bypass
|
// If arming bypass mode is enabled, get device ids requiring bypass
|
||||||
if (message.toLowerCase() !== 'disarm' && this.entity.bypass.state) {
|
if (message.toLowerCase() !== 'disarm' && this.entity.bypass.state) {
|
||||||
const bypassDevices = (await this.device.location.getDevices()).filter((device) => {
|
const bypassDevices = (await this.device.location.getDevices()).filter((device) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Siren extends RingSocketDevice {
|
class Siren extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = (this.device.data.deviceType === 'siren.outdoor-strobe') ? 'Outdoor Siren' : 'Siren'
|
this.deviceData.mdl = (this.device.data.deviceType === 'siren.outdoor-strobe') ? 'Outdoor Siren' : 'Siren'
|
||||||
this.entity = {
|
this.entity = {
|
||||||
...this.entity,
|
...this.entity,
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class SmokeAlarm extends RingSocketDevice {
|
class SmokeAlarm extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Smoke Alarm'
|
this.deviceData.mdl = 'Smoke Alarm'
|
||||||
|
|
||||||
this.entity.smoke = {
|
this.entity.smoke = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class SmokeCoListener extends RingSocketDevice {
|
class SmokeCoListener extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Smoke & CO Listener'
|
this.deviceData.mdl = 'Smoke & CO Listener'
|
||||||
|
|
||||||
this.entity.smoke = {
|
this.entity.smoke = {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class Switch extends RingSocketDevice {
|
class Switch extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = (this.device.data.categoryId === 2) ? 'Light' : 'Switch'
|
this.deviceData.mdl = (this.device.data.categoryId === 2) ? 'Light' : 'Switch'
|
||||||
this.component = (this.device.data.categoryId === 2) ? 'light' : 'switch'
|
this.component = (this.device.data.categoryId === 2) ? 'light' : 'switch'
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const RingSocketDevice = require('./base-socket-device')
|
|||||||
class TemperatureSensor extends RingSocketDevice {
|
class TemperatureSensor extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Temperature Sensor'
|
this.deviceData.mdl = 'Temperature Sensor'
|
||||||
|
|
||||||
this.entity.temperature = {
|
this.entity.temperature = {
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ const utils = require( '../lib/utils' )
|
|||||||
class Thermostat extends RingSocketDevice {
|
class Thermostat extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
this.deviceData.mdl = 'Thermostat'
|
this.deviceData.mdl = 'Thermostat'
|
||||||
|
|
||||||
this.childDevices = {
|
this.operatingStatus = this.childDevices.find(d => d.deviceType === 'thermostat-operating-status'),
|
||||||
operatingStatus: deviceInfo.childDevices.find(d => d.deviceType === 'thermostat-operating-status'),
|
this.temperatureSensor = this.childDevices.find(d => d.deviceType === RingDeviceType.TemperatureSensor)
|
||||||
temperatureSensor: deviceInfo.childDevices.find(d => d.deviceType === RingDeviceType.TemperatureSensor)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entity.thermostat = {
|
this.entity.thermostat = {
|
||||||
component: 'climate',
|
component: 'climate',
|
||||||
@@ -28,16 +29,16 @@ class Thermostat extends RingSocketDevice {
|
|||||||
setPoint: (() => {
|
setPoint: (() => {
|
||||||
return this.device.data.setPoint
|
return this.device.data.setPoint
|
||||||
? this.device.data.setPoint
|
? this.device.data.setPoint
|
||||||
: this.childDevices.temperatureSensor.data.celsius
|
: this.temperatureSensor.data.celsius
|
||||||
}),
|
}),
|
||||||
operatingMode: (() => {
|
operatingMode: (() => {
|
||||||
return this.childDevices.operatingStatus.data.operatingMode !== 'off'
|
return this.operatingStatus.data.operatingMode !== 'off'
|
||||||
? `${this.childDevices.operatingStatus.data.operatingMode}ing`
|
? `${this.operatingStatus.data.operatingMode}ing`
|
||||||
: this.device.data.mode === 'off'
|
: this.device.data.mode === 'off'
|
||||||
? 'off'
|
? 'off'
|
||||||
: this.device.data.fanMode === 'on' ? 'fan' : 'idle'
|
: this.device.data.fanMode === 'on' ? 'fan' : 'idle'
|
||||||
}),
|
}),
|
||||||
temperature: (() => { return this.childDevices.temperatureSensor.data.celsius }),
|
temperature: (() => { return this.temperatureSensor.data.celsius }),
|
||||||
... this.entity.thermostat.modes.includes('auto')
|
... this.entity.thermostat.modes.includes('auto')
|
||||||
? {
|
? {
|
||||||
autoSetPointInProgress: false,
|
autoSetPointInProgress: false,
|
||||||
@@ -49,14 +50,14 @@ class Thermostat extends RingSocketDevice {
|
|||||||
} : {}
|
} : {}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.childDevices.operatingStatus.onData.subscribe(() => {
|
this.operatingStatus.onData.subscribe(() => {
|
||||||
if (this.isOnline()) {
|
if (this.isOnline()) {
|
||||||
this.publishOperatingMode()
|
this.publishOperatingMode()
|
||||||
this.publishAttributes()
|
this.publishAttributes()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.childDevices.temperatureSensor.onData.subscribe(() => {
|
this.temperatureSensor.onData.subscribe(() => {
|
||||||
if (this.isOnline()) {
|
if (this.isOnline()) {
|
||||||
this.publishTemperature()
|
this.publishTemperature()
|
||||||
this.publishAttributes()
|
this.publishAttributes()
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class Main {
|
|||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
// Start event listeners
|
// Start event listeners
|
||||||
utils.event.on('generatedToken', (generatedToken) => {
|
utils.event.on('generated_token', (generatedToken) => {
|
||||||
this.init(generatedToken)
|
this.init(generatedToken)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
14
lib/mqtt.js
14
lib/mqtt.js
@@ -9,7 +9,7 @@ class Mqtt {
|
|||||||
this.connected = false
|
this.connected = false
|
||||||
|
|
||||||
// Configure event listeners
|
// Configure event listeners
|
||||||
utils.event.on('ringState', async (state) => {
|
utils.event.on('ring_state', async (state) => {
|
||||||
if (!this.client && state === 'connected') {
|
if (!this.client && state === 'connected') {
|
||||||
// Ring API connected, short wait before starting MQTT client
|
// Ring API connected, short wait before starting MQTT client
|
||||||
await utils.sleep(2)
|
await utils.sleep(2)
|
||||||
@@ -17,13 +17,13 @@ class Mqtt {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
utils.event.on('mqttPublish', (topic, message) => {
|
utils.event.on('mqtt_publish', (topic, message) => {
|
||||||
this.client.publish(topic, (typeof message === 'number') ? message.toString() : message, { qos: 1 }, () => {
|
this.client.publish(topic, (typeof message === 'number') ? message.toString() : message, { qos: 1 }, () => {
|
||||||
// Just a dummy callback to prevent MQTT memory leak in 4.3.5/4.3.6
|
// Just a dummy callback to prevent MQTT memory leak in 4.3.5/4.3.6
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
utils.event.on('mqttSubscribe', (topic) => {
|
utils.event.on('mqtt_subscribe', (topic) => {
|
||||||
this.client.subscribe(topic)
|
this.client.subscribe(topic)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ class Mqtt {
|
|||||||
this.client.on('connect', () => {
|
this.client.on('connect', () => {
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
this.connected = true
|
this.connected = true
|
||||||
utils.event.emit('mqttState', 'connected')
|
utils.event.emit('mqtt_state', 'connected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -72,20 +72,20 @@ class Mqtt {
|
|||||||
debug('Attempting to reconnect to MQTT broker...')
|
debug('Attempting to reconnect to MQTT broker...')
|
||||||
}
|
}
|
||||||
this.connected = false
|
this.connected = false
|
||||||
utils.event.emit('mqttState', 'disconnected')
|
utils.event.emit('mqtt_state', 'disconnected')
|
||||||
})
|
})
|
||||||
|
|
||||||
this.client.on('error', (error) => {
|
this.client.on('error', (error) => {
|
||||||
debug('Unable to connect to MQTT broker', error.message)
|
debug('Unable to connect to MQTT broker', error.message)
|
||||||
this.connected = false
|
this.connected = false
|
||||||
utils.event.emit('mqttState', 'disconnected')
|
utils.event.emit('mqtt_state', 'disconnected')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Process MQTT messages from subscribed command topics
|
// Process MQTT messages from subscribed command topics
|
||||||
this.client.on('message', (topic, message) => {
|
this.client.on('message', (topic, message) => {
|
||||||
message = message.toString()
|
message = message.toString()
|
||||||
if (topic === utils.config.hass_topic || topic === 'hass/status' || topic === 'hassio/status') {
|
if (topic === utils.config.hass_topic || topic === 'hass/status' || topic === 'hassio/status') {
|
||||||
utils.event.emit('haStatus', topic, message)
|
utils.event.emit('ha_status', topic, message)
|
||||||
} else {
|
} else {
|
||||||
utils.event.emit(topic, topic.split("/").slice(-2).join("/"), message)
|
utils.event.emit(topic, topic.split("/").slice(-2).join("/"), message)
|
||||||
}
|
}
|
||||||
|
|||||||
14
lib/ring.js
14
lib/ring.js
@@ -35,7 +35,7 @@ class RingMqtt {
|
|||||||
this.republishCount = 6 // Republish config/state this many times after startup or HA start/restart
|
this.republishCount = 6 // Republish config/state this many times after startup or HA start/restart
|
||||||
|
|
||||||
// Configure event listeners
|
// Configure event listeners
|
||||||
utils.event.on('mqttState', (state) => {
|
utils.event.on('mqtt_state', (state) => {
|
||||||
if (state === 'connected') {
|
if (state === 'connected') {
|
||||||
this.mqttConnected = true
|
this.mqttConnected = true
|
||||||
debug('MQTT connection established, processing Ring locations...')
|
debug('MQTT connection established, processing Ring locations...')
|
||||||
@@ -45,7 +45,7 @@ class RingMqtt {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
utils.event.on('haStatus', async (topic, message) => {
|
utils.event.on('ha_status', async (topic, message) => {
|
||||||
debug('Home Assistant state topic '+topic+' received message: '+message)
|
debug('Home Assistant state topic '+topic+' received message: '+message)
|
||||||
if (message === 'online') {
|
if (message === 'online') {
|
||||||
// Republish devices and state if restart of HA is detected
|
// Republish devices and state if restart of HA is detected
|
||||||
@@ -77,7 +77,7 @@ class RingMqtt {
|
|||||||
debug(`Attempting connection to Ring API using ${generatedToken ? 'generated' : 'saved'} refresh token...`)
|
debug(`Attempting connection to Ring API using ${generatedToken ? 'generated' : 'saved'} refresh token...`)
|
||||||
this.client = new RingApi(ringAuth)
|
this.client = new RingApi(ringAuth)
|
||||||
await this.client.getProfile()
|
await this.client.getProfile()
|
||||||
utils.event.emit('ringState', 'connected')
|
utils.event.emit('ring_state', 'connected')
|
||||||
debug(`Successfully established connection to Ring API using ${generatedToken ? 'generated' : 'saved'} token`)
|
debug(`Successfully established connection to Ring API using ${generatedToken ? 'generated' : 'saved'} token`)
|
||||||
|
|
||||||
// Subscribe to token update events and save new tokens to state file
|
// Subscribe to token update events and save new tokens to state file
|
||||||
@@ -145,12 +145,12 @@ class RingMqtt {
|
|||||||
// Get all Ring locations
|
// Get all Ring locations
|
||||||
const locations = await this.client.getLocations()
|
const locations = await this.client.getLocations()
|
||||||
|
|
||||||
debug(colors.green('-'.repeat(82)))
|
debug(colors.green('-'.repeat(90)))
|
||||||
debug(colors.white('This account has access to the following locations:'))
|
debug(colors.white('This account has access to the following locations:'))
|
||||||
locations.map(function(location) {
|
locations.map(function(location) {
|
||||||
debug(' '+colors.green(location.name)+colors.cyan(` (${location.id})`))
|
debug(' '+colors.green(location.name)+colors.cyan(` (${location.id})`))
|
||||||
})
|
})
|
||||||
debug(colors.green(' '.repeat(82)))
|
debug(colors.green(' '.repeat(90)))
|
||||||
debug(colors.brightYellow('IMPORTANT: ')+colors.white('All alarm and smart lighting hubs at these locations *MUST* be online '))
|
debug(colors.brightYellow('IMPORTANT: ')+colors.white('All alarm and smart lighting hubs at these locations *MUST* be online '))
|
||||||
debug(colors.white(' or device discovery for that location will hang indefinitely! '))
|
debug(colors.white(' or device discovery for that location will hang indefinitely! '))
|
||||||
debug(colors.white(' If desired, use the "location_ids" config option to restrict discovery '))
|
debug(colors.white(' If desired, use the "location_ids" config option to restrict discovery '))
|
||||||
@@ -162,7 +162,7 @@ class RingMqtt {
|
|||||||
let chimes = new Array()
|
let chimes = new Array()
|
||||||
const unsupportedDevices = new Array()
|
const unsupportedDevices = new Array()
|
||||||
|
|
||||||
debug(colors.green('-'.repeat(82)))
|
debug(colors.green('-'.repeat(90)))
|
||||||
// If new location, set custom properties and add to location list
|
// If new location, set custom properties and add to location list
|
||||||
if (this.locations.find(l => l.locationId == location.locationId)) {
|
if (this.locations.find(l => l.locationId == location.locationId)) {
|
||||||
debug(colors.white('Existing location: ')+colors.green(location.name)+colors.cyan(` (${location.id})`))
|
debug(colors.white('Existing location: ')+colors.green(location.name)+colors.cyan(` (${location.id})`))
|
||||||
@@ -238,7 +238,7 @@ class RingMqtt {
|
|||||||
debug(colors.yellow(` Unsupported device: ${deviceType}`))
|
debug(colors.yellow(` Unsupported device: ${deviceType}`))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
debug(colors.green('-'.repeat(82)))
|
debug(colors.green('-'.repeat(90)))
|
||||||
debug('Ring location/device data updated, sleeping for 5 seconds.')
|
debug('Ring location/device data updated, sleeping for 5 seconds.')
|
||||||
await utils.sleep(2)
|
await utils.sleep(2)
|
||||||
const cameras = await this.devices.filter(d => d.device instanceof RingCamera)
|
const cameras = await this.devices.filter(d => d.device instanceof RingCamera)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class RtspSimpleServer {
|
|||||||
this.cameras = cameras
|
this.cameras = cameras
|
||||||
}
|
}
|
||||||
this.started = true
|
this.started = true
|
||||||
debug(colors.green('-'.repeat(73)))
|
debug(colors.green('-'.repeat(90)))
|
||||||
debug('Starting rtsp-simple-server process...')
|
debug('Starting rtsp-simple-server process...')
|
||||||
|
|
||||||
this.rssProcess = spawn('rtsp-simple-server', [`${__dirname}/../config/rtsp-simple-server.yml`], {
|
this.rssProcess = spawn('rtsp-simple-server', [`${__dirname}/../config/rtsp-simple-server.yml`], {
|
||||||
@@ -108,7 +108,7 @@ class RtspSimpleServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
await utils.msleep(100)
|
await utils.msleep(100)
|
||||||
debug(colors.green('-'.repeat(73)))
|
debug(colors.green('-'.repeat(90)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPathDetails(path) {
|
async getPathDetails(path) {
|
||||||
|
|||||||
21
lib/state.js
21
lib/state.js
@@ -8,7 +8,7 @@ const writeFileAtomic = require('write-file-atomic')
|
|||||||
class State {
|
class State {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.valid = false
|
this.valid = false
|
||||||
this.writeDelay = false
|
this.writeScheduled = false
|
||||||
this.data = {
|
this.data = {
|
||||||
ring_token: '',
|
ring_token: '',
|
||||||
systemId: '',
|
systemId: '',
|
||||||
@@ -23,16 +23,16 @@ class State {
|
|||||||
: this.file = '/data/ring-state.json'
|
: this.file = '/data/ring-state.json'
|
||||||
await this.loadStateData()
|
await this.loadStateData()
|
||||||
|
|
||||||
utils.event.on(`saveDeviceState`, (deviceId, stateData) => {
|
utils.event.on(`save_device_state`, (deviceId, stateData) => {
|
||||||
this.data.devices[deviceId] = stateData
|
this.data.devices[deviceId] = stateData
|
||||||
this.updateStateFile()
|
this.updateStateFile()
|
||||||
})
|
})
|
||||||
|
|
||||||
utils.event.on('getDeviceState', (deviceId) => {
|
utils.event.on('get_device_state', (deviceId) => {
|
||||||
if (this.data.devices.hasOwnProperty(deviceId)) {
|
if (this.data.devices.hasOwnProperty(deviceId)) {
|
||||||
utils.event.emit(`deviceState_${deviceId}`, this.data.devices[deviceId])
|
utils.event.emit(`device_state_${deviceId}`, this.data.devices[deviceId])
|
||||||
} else {
|
} else {
|
||||||
utils.event.emit(`deviceState_${deviceId}`, false)
|
utils.event.emit(`device_state_${deviceId}`, false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -79,9 +79,13 @@ class State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateStateFile() {
|
async updateStateFile() {
|
||||||
if (!this.writeDelay) {
|
// The writeDelay flag is a hack to keep from writing too often when there are burst
|
||||||
this.writeDelay = true
|
// of state updates such as during startup. If a state file update is already scheduled
|
||||||
await utils.sleep(10)
|
// then calls to this function are skipped.
|
||||||
|
if (!this.writeScheduled) {
|
||||||
|
this.writeScheduled = true
|
||||||
|
await utils.sleep(5)
|
||||||
|
this.writeScheduled = false
|
||||||
try {
|
try {
|
||||||
await writeFileAtomic(this.file, JSON.stringify(this.data))
|
await writeFileAtomic(this.file, JSON.stringify(this.data))
|
||||||
debug('Successfully saved updated refresh token in state file: '+this.file)
|
debug('Successfully saved updated refresh token in state file: '+this.file)
|
||||||
@@ -89,7 +93,6 @@ class State {
|
|||||||
debug(colors.red('Failed to save updated refresh token in state file: '+this.file))
|
debug(colors.red('Failed to save updated refresh token in state file: '+this.file))
|
||||||
debug(err.message)
|
debug(err.message)
|
||||||
}
|
}
|
||||||
this.writeDelay = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,15 +49,15 @@ class StreamWorkers {
|
|||||||
if (workerId >= 0) {
|
if (workerId >= 0) {
|
||||||
switch (data.state) {
|
switch (data.state) {
|
||||||
case 'active':
|
case 'active':
|
||||||
utils.event.emit(`${deviceId}_livestream`, 'active')
|
utils.event.emit(`livestream_${deviceId}`, 'active')
|
||||||
this.streamWorkers[workerId].sessions[deviceId].streamData.sessionId = data.liveCallData.sessionId
|
this.streamWorkers[workerId].sessions[deviceId].streamData.sessionId = data.liveCallData.sessionId
|
||||||
break;
|
break;
|
||||||
case 'inactive':
|
case 'inactive':
|
||||||
utils.event.emit(`${deviceId}_livestream`, 'inactive')
|
utils.event.emit(`livestream_${deviceId}`, 'inactive')
|
||||||
delete this.streamWorkers[workerId].sessions[deviceId]
|
delete this.streamWorkers[workerId].sessions[deviceId]
|
||||||
break;
|
break;
|
||||||
case 'failed':
|
case 'failed':
|
||||||
utils.event.emit(`${deviceId}_livestream`, 'failed')
|
utils.event.emit(`livestream_${deviceId}`, 'failed')
|
||||||
delete this.streamWorkers[workerId].sessions[deviceId]
|
delete this.streamWorkers[workerId].sessions[deviceId]
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class TokenApp {
|
|||||||
this.start()
|
this.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.event.on('ringState', async (state) => {
|
utils.event.on('ring_state', async (state) => {
|
||||||
if (state === 'connected') {
|
if (state === 'connected') {
|
||||||
this.ringConnected = true
|
this.ringConnected = true
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ class TokenApp {
|
|||||||
}
|
}
|
||||||
if (generatedToken) {
|
if (generatedToken) {
|
||||||
res.sendFile('restart.html', {root: webdir})
|
res.sendFile('restart.html', {root: webdir})
|
||||||
utils.event.emit('generatedToken', generatedToken.refresh_token)
|
utils.event.emit('generated_token', generatedToken.refresh_token)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user