mirror of
https://github.com/lehanspb/tuya-mqtt.git
synced 2025-12-18 00:10:20 +00:00
Minor enhancements
* Properly disconnect from devices on exit * Monitor for Home Assistant status and resend discovery
This commit is contained in:
@@ -5,12 +5,16 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set device specific variables
|
// Set device specific variables
|
||||||
this.config.dpsPower = this.config.dpsPower ? this.config.dpsPower : this.guess.dpsPower
|
this.config.dpsPower = this.config.dpsPower ? this.config.dpsPower : this.guess.dpsPower
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
42
tuya-mqtt.js
42
tuya-mqtt.js
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user