mirror of
https://github.com/tsightler/ring-mqtt.git
synced 2025-10-15 05:10:48 +08:00
Add chirp tone configuration
This commit is contained in:
@@ -1,11 +1,21 @@
|
|||||||
import RingSocketDevice from './base-socket-device.js'
|
import RingSocketDevice from './base-socket-device.js'
|
||||||
import { RingDeviceType } from 'ring-client-api'
|
import { RingDeviceType } from 'ring-client-api'
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
function chirpToMqttState(chirp) {
|
||||||
|
return chirp.replace('cowbell', 'dinner-bell')
|
||||||
|
.replace("-", " ")
|
||||||
|
.replace(/(^\w{1})|(\s+\w{1})/g, letter => letter.toUpperCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main device class
|
||||||
export default class BinarySensor extends RingSocketDevice {
|
export default class BinarySensor extends RingSocketDevice {
|
||||||
constructor(deviceInfo) {
|
constructor(deviceInfo) {
|
||||||
super(deviceInfo, 'alarm')
|
super(deviceInfo, 'alarm')
|
||||||
|
|
||||||
let device_class = false
|
let device_class = false
|
||||||
let bypass_modes = false
|
let bypass_modes = false
|
||||||
|
this.securityPanel = deviceInfo.securityPanel
|
||||||
|
|
||||||
// Override icons and and topics
|
// Override icons and and topics
|
||||||
switch (this.device.deviceType) {
|
switch (this.device.deviceType) {
|
||||||
@@ -40,6 +50,7 @@ export default class BinarySensor extends RingSocketDevice {
|
|||||||
bypass_modes = [ 'Never', 'Always' ]
|
bypass_modes = [ 'Never', 'Always' ]
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
delete this.securityPanel
|
||||||
if (this.device.name.toLowerCase().includes('motion')) {
|
if (this.device.name.toLowerCase().includes('motion')) {
|
||||||
this.entityName = 'motion'
|
this.entityName = 'motion'
|
||||||
this.deviceData.mdl = 'Motion Sensor',
|
this.deviceData.mdl = 'Motion Sensor',
|
||||||
@@ -59,19 +70,36 @@ export default class BinarySensor extends RingSocketDevice {
|
|||||||
// Only official Ring sensors can be bypassed
|
// Only official Ring sensors can be bypassed
|
||||||
if (bypass_modes) {
|
if (bypass_modes) {
|
||||||
const savedState = this.getSavedState()
|
const savedState = this.getSavedState()
|
||||||
|
|
||||||
this.data = {
|
this.data = {
|
||||||
bypass_mode: savedState?.bypass_mode ? savedState.bypass_mode[0].toUpperCase() + savedState.bypass_mode.slice(1) : 'Never',
|
bypass_mode: savedState?.bypass_mode ? savedState.bypass_mode[0].toUpperCase() + savedState.bypass_mode.slice(1) : 'Never',
|
||||||
published_bypass_mode: false
|
published_bypass_mode: false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.entity.bypass_mode = {
|
this.entity.bypass_mode = {
|
||||||
component: 'select',
|
component: 'select',
|
||||||
options: bypass_modes
|
options: bypass_modes
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDeviceState()
|
this.updateDeviceState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this?.securityPanel?.data?.chirps?.[this.device.id]?.type) {
|
||||||
|
this.data.chirp_tone = chirpToMqttState(this.securityPanel.data.chirps[this.device.id].type)
|
||||||
|
this.data.published_chirp_tone = false
|
||||||
|
this.entity.chirp_tone = {
|
||||||
|
component: 'select',
|
||||||
|
options: [
|
||||||
|
'None', 'Ding Dong', 'Harp', 'Navi', 'Wind Chime',
|
||||||
|
'Dinner Bell', 'Echo', 'Ping Pong', 'Siren', 'Sonar', 'Xylophone'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
this.securityPanel.onData.subscribe(() => {
|
||||||
|
if (this?.securityPanel?.data?.chirps?.[this.device.id]?.type) {
|
||||||
|
this.data.chirp_tone = chirpToMqttState(this.securityPanel.data.chirps[this.device.id].type)
|
||||||
|
}
|
||||||
|
if (this.isOnline()) {
|
||||||
|
this.publishChirpToneState()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDeviceState() {
|
updateDeviceState() {
|
||||||
@@ -86,16 +114,22 @@ export default class BinarySensor extends RingSocketDevice {
|
|||||||
const contactState = this.device.data.faulted ? 'ON' : 'OFF'
|
const contactState = this.device.data.faulted ? 'ON' : 'OFF'
|
||||||
this.mqttPublish(this.entity[this.entityName].state_topic, contactState)
|
this.mqttPublish(this.entity[this.entityName].state_topic, contactState)
|
||||||
this.publishBypassModeState(isPublish)
|
this.publishBypassModeState(isPublish)
|
||||||
|
this.publishChirpToneState(isPublish)
|
||||||
this.publishAttributes()
|
this.publishAttributes()
|
||||||
}
|
}
|
||||||
|
|
||||||
publishBypassModeState(isPublish) {
|
publishBypassModeState(isPublish) {
|
||||||
if (this.entity?.bypass_mode) {
|
if (this.entity?.bypass_mode && (this.data.bypass_mode !== this.data.published_bypass_mode || isPublish)) {
|
||||||
if (this.data.bypass_mode !== this.data.published_bypass_mode || isPublish) {
|
|
||||||
this.data.published_bypass_mode = this.data.bypass_mode.state
|
|
||||||
this.mqttPublish(this.entity.bypass_mode.state_topic, this.data.bypass_mode)
|
this.mqttPublish(this.entity.bypass_mode.state_topic, this.data.bypass_mode)
|
||||||
|
this.data.published_bypass_mode = this.data.bypass_mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
publishChirpToneState(isPublish) {
|
||||||
|
if (this.entity?.chirp_tone && (this.data.chirp_tone !== this.data.published_chirp_tone || isPublish)) {
|
||||||
|
this.mqttPublish(this.entity.chirp_tone.state_topic, this.data.chirp_tone)
|
||||||
|
this.data.published_chirp_tone = this.data.chirp_tone
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process messages from MQTT command topic
|
// Process messages from MQTT command topic
|
||||||
@@ -106,6 +140,11 @@ export default class BinarySensor extends RingSocketDevice {
|
|||||||
this.setBypassMode(message)
|
this.setBypassMode(message)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'chirp_tone/command':
|
||||||
|
if (this.entity?.chirp_tone) {
|
||||||
|
this.setChirpTone(message)
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this.debug(`Received message to unknown command topic: ${command}`)
|
this.debug(`Received message to unknown command topic: ${command}`)
|
||||||
}
|
}
|
||||||
@@ -124,4 +163,15 @@ export default class BinarySensor extends RingSocketDevice {
|
|||||||
this.debug(`Received invalid bypass mode for this sensor: ${message}`)
|
this.debug(`Received invalid bypass mode for this sensor: ${message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setChirpTone(message) {
|
||||||
|
this.debug(`Recevied command to set chirp tone ${message}`)
|
||||||
|
let chirpTone = this.entity.options.find(o => o.toLowerCase() === message.toLowerCase())
|
||||||
|
if (chirpTone) {
|
||||||
|
chirpTone = chirpTone.toLowerCase().replace(/\s+/g, "-").replace('dinner-bell', 'cowbell')
|
||||||
|
this.securityPanel.setInfo({ device: { v1: { chirps: { [this.deviceId]: { type: chirpTone }}}}})
|
||||||
|
} else {
|
||||||
|
this.debug('Received command to set unknown chirp tone')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -307,6 +307,9 @@ export default new class RingMqtt {
|
|||||||
case RingDeviceType.GlassbreakSensor:
|
case RingDeviceType.GlassbreakSensor:
|
||||||
case RingDeviceType.MotionSensor:
|
case RingDeviceType.MotionSensor:
|
||||||
case RingDeviceType.Sensor:
|
case RingDeviceType.Sensor:
|
||||||
|
deviceInfo.securityPanel = allDevices.find(device =>
|
||||||
|
device.deviceType === RingDeviceType.SecurityPanel
|
||||||
|
)
|
||||||
return new BinarySensor(deviceInfo)
|
return new BinarySensor(deviceInfo)
|
||||||
case RingDeviceType.FloodFreezeSensor:
|
case RingDeviceType.FloodFreezeSensor:
|
||||||
return new FloodFreezeSensor(deviceInfo)
|
return new FloodFreezeSensor(deviceInfo)
|
||||||
|
Reference in New Issue
Block a user