Minor enhancements

* Properly disconnect from devices on exit
* Monitor for Home Assistant status and resend discovery
This commit is contained in:
tsightler
2020-10-15 11:05:41 -04:00
parent 271697439c
commit 748a5cae39
5 changed files with 52 additions and 11 deletions

View File

@@ -5,8 +5,12 @@ const utils = require('../lib/utils')
class RGBTWLight extends TuyaDevice { class RGBTWLight extends TuyaDevice {
async init() { async init() {
await this.guessLightInfo() // If no manual config try to detect device settings
if (!this.config.dpsPower) {
await this.guessLightInfo()
}
// If detection failed and no manual config return without initializing
if (!this.guess.dpsPower && !this.config.dpsPower) { if (!this.guess.dpsPower && !this.config.dpsPower) {
debug('Automatic discovery of Tuya bulb settings failed and no manual configuration') debug('Automatic discovery of Tuya bulb settings failed and no manual configuration')
return return
@@ -25,7 +29,6 @@ class RGBTWLight extends TuyaDevice {
this.config.colorType = this.config.colorType ? this.config.colorType : this.guess.colorType this.config.colorType = this.config.colorType ? this.config.colorType : this.guess.colorType
this.deviceData.mdl = 'RGBTW Light' this.deviceData.mdl = 'RGBTW Light'
this.isRgbtwLight = true this.isRgbtwLight = true
// Map generic DPS topics to device specific topic names // Map generic DPS topics to device specific topic names
@@ -66,7 +69,7 @@ class RGBTWLight extends TuyaDevice {
// If device supports Color Temperature add color temp device topic // If device supports Color Temperature add color temp device topic
if (this.config.dpsColorTemp) { if (this.config.dpsColorTemp) {
// Values used for tranform // Values used for tranforming from 1-255 scale to mireds range
const rangeFactor = (this.config.maxColorTemp-this.config.minColorTemp)/100 const rangeFactor = (this.config.maxColorTemp-this.config.minColorTemp)/100
const scaleFactor = this.config.colorTempScale/100 const scaleFactor = this.config.colorTempScale/100
const tuyaMaxColorTemp = this.config.maxColorTemp/rangeFactor*scaleFactor const tuyaMaxColorTemp = this.config.maxColorTemp/rangeFactor*scaleFactor
@@ -104,6 +107,9 @@ class RGBTWLight extends TuyaDevice {
white_value_state_topic: this.baseTopic+'white_brightness_state', white_value_state_topic: this.baseTopic+'white_brightness_state',
white_value_command_topic: this.baseTopic+'white_brightness_command', white_value_command_topic: this.baseTopic+'white_brightness_command',
white_value_scale: 100, white_value_scale: 100,
availability_topic: this.baseTopic+'status',
payload_available: 'online',
payload_not_available: 'offline',
unique_id: this.config.id, unique_id: this.config.id,
device: this.deviceData device: this.deviceData
} }

View File

@@ -44,6 +44,9 @@ class SimpleDimmer extends TuyaDevice {
command_topic: this.baseTopic+'command', command_topic: this.baseTopic+'command',
brightness_state_topic: this.baseTopic+'brightness_state', brightness_state_topic: this.baseTopic+'brightness_state',
brightness_command_topic: this.baseTopic+'brightness_command', brightness_command_topic: this.baseTopic+'brightness_command',
availability_topic: this.baseTopic+'status',
payload_available: 'online',
payload_not_available: 'offline',
unique_id: this.config.id, unique_id: this.config.id,
device: this.deviceData device: this.deviceData
} }

View File

@@ -33,6 +33,9 @@ class SimpleSwitch extends TuyaDevice {
name: (this.config.name) ? this.config.name : this.config.id, name: (this.config.name) ? this.config.name : this.config.id,
state_topic: this.baseTopic+'state', state_topic: this.baseTopic+'state',
command_topic: this.baseTopic+'command', command_topic: this.baseTopic+'command',
availability_topic: this.baseTopic+'status',
payload_available: 'online',
payload_not_available: 'offline',
unique_id: this.config.id, unique_id: this.config.id,
device: this.deviceData device: this.deviceData
} }

View File

@@ -1,7 +1,6 @@
const TuyAPI = require('tuyapi') const TuyAPI = require('tuyapi')
const { evaluate } = require('mathjs') const { evaluate } = require('mathjs')
const utils = require('../lib/utils') const utils = require('../lib/utils')
const { msSleep } = require('../lib/utils')
const debug = require('debug')('tuya-mqtt:tuyapi') const debug = require('debug')('tuya-mqtt:tuyapi')
const debugState = require('debug')('tuya-mqtt:state') const debugState = require('debug')('tuya-mqtt:state')
const debugCommand = require('debug')('tuya-mqtt:command') const debugCommand = require('debug')('tuya-mqtt:command')

View File

@@ -9,10 +9,27 @@ const SimpleSwitch = require('./devices/simple-switch')
const SimpleDimmer = require('./devices/simple-dimmer') const SimpleDimmer = require('./devices/simple-dimmer')
const RGBTWLight = require('./devices/rgbtw-light') const RGBTWLight = require('./devices/rgbtw-light')
const GenericDevice = require('./devices/generic-device') const GenericDevice = require('./devices/generic-device')
const utils = require('./lib/utils')
var CONFIG = undefined var CONFIG = undefined
var tuyaDevices = new Array() var tuyaDevices = new Array()
// Setup Exit Handlers
process.on('exit', processExit.bind(0))
process.on('SIGINT', processExit.bind(0))
process.on('SIGTERM', processExit.bind(0))
process.on('uncaughtException', processExit.bind(1))
// Set unreachable status on exit
async function processExit(exitCode) {
for (let tuyaDevice of tuyaDevices) {
tuyaDevice.device.disconnect()
}
if (exitCode || exitCode === 0) debug('Exit code: '+exitCode)
await utils.sleep(1)
process.exit()
}
function getDevice(configDevice, mqttClient) { function getDevice(configDevice, mqttClient) {
const deviceInfo = { const deviceInfo = {
configDevice: configDevice, configDevice: configDevice,
@@ -40,6 +57,15 @@ function initDevices(configDevices, mqttClient) {
} }
} }
async function republishDevices() {
// Republish devices and state after 30 seconds if restart of HA is detected
debug('Resending device config/state in 30 seconds')
await utils.sleep(30)
for (let device of tuyaDevices) {
device.init()
}
}
// Main code function // Main code function
const main = async() => { const main = async() => {
let configDevices let configDevices
@@ -84,10 +110,9 @@ const main = async() => {
mqttClient.on('connect', function (err) { mqttClient.on('connect', function (err) {
debug('Connection established to MQTT server') debug('Connection established to MQTT server')
let topic = CONFIG.topic + '#' let topic = CONFIG.topic + '#'
mqttClient.subscribe(topic, { mqttClient.subscribe(topic)
retain: CONFIG.retain, mqttClient.subscribe('homeassistant/status')
qos: CONFIG.qos mqttClient.subscribe('hass/status')
})
initDevices(configDevices, mqttClient) initDevices(configDevices, mqttClient)
}) })
@@ -111,8 +136,13 @@ const main = async() => {
const commandTopic = splitTopic[topicLength - 1] const commandTopic = splitTopic[topicLength - 1]
const deviceTopicLevel = splitTopic[1] const deviceTopicLevel = splitTopic[1]
// If it looks like a valid command topic try to process it if (topic === 'homeassistant/status' || topic === 'hass/status' ) {
if (commandTopic.includes('command')) { debug('Home Assistant state topic '+topic+' received message: '+message)
if (message === 'online') {
republishDevices()
}
} else if (commandTopic.includes('command')) {
// If it looks like a valid command topic try to process it
debugCommand('Received MQTT message -> ', JSON.stringify({ debugCommand('Received MQTT message -> ', JSON.stringify({
topic: topic, topic: topic,
message: message message: message