Release 3.0.0

3.0.0 Release

Major changes from 2.1.0:
* Completely new configuration engine
* Completely new topic structure
* New template engine for creating friendly topic structure from raw DPS values
* Pre-defined templates for some common devices
* Directly control devices via Tuya JSON topic or via DPS key topics
This commit is contained in:
tsightler
2020-10-18 20:53:58 -04:00
parent 51bbd612f2
commit d61c1f7cee
7 changed files with 68 additions and 34 deletions

View File

@@ -31,6 +31,20 @@ class RGBTWLight extends TuyaDevice {
this.deviceData.mdl = 'RGBTW Light'
this.isRgbtwLight = true
// Set white value transform math
let whiteValueStateMath
let whiteValueCommandMath
if (this.config.whiteValueScale === 255) {
// Devices with brightness scale of 255 seem to not allow values
// less then 25 (10%) without producing timeout errors.
whiteValueStateMath = '/2.3-10.86'
whiteValueCommandMath = '*2.3+25'
} else {
// For other scale (usually 1000), 10-1000 seems OK.
whiteValueStateMath = '/('+this.config.whiteValueScale+'/100)'
whiteValueCommandMath = '*('+this.config.whiteValueScale+'/100)'
}
// Map generic DPS topics to device specific topic names
this.deviceTopics = {
state: {
@@ -40,11 +54,10 @@ class RGBTWLight extends TuyaDevice {
white_brightness_state: {
key: this.config.dpsWhiteValue,
type: 'int',
min: 1,
max: 100,
scale: this.config.whiteValueScale,
stateMath: '/('+this.config.whiteValueScale+'/100)',
commandMath: '*('+this.config.whiteValueScale+'/100)'
topicMin: 0,
topicMax: 100,
stateMath: whiteValueStateMath,
commandMath: whiteValueCommandMath
},
hs_state: {
key: this.config.dpsColor,
@@ -77,8 +90,8 @@ class RGBTWLight extends TuyaDevice {
this.deviceTopics.color_temp_state = {
key: this.config.dpsColorTemp,
type: 'int',
min: this.config.minColorTemp,
max: this.config.maxColorTemp,
topicMin: this.config.minColorTemp,
topicMax: this.config.maxColorTemp,
stateMath: '/'+scaleFactor+'*-'+rangeFactor+'+'+this.config.maxColorTemp,
commandMath: '/'+rangeFactor+'*-'+scaleFactor+'+'+tuyaMaxColorTemp
}

View File

@@ -12,6 +12,20 @@ class SimpleDimmer extends TuyaDevice {
this.deviceData.mdl = 'Dimmer Switch'
// Set white value transform math
let brightnessStateMath
let brightnessCommandMath
if (this.config.brightnessScale === 255) {
// Devices with brightness scale of 255 seem to not allow values
// less then 25 (10%) without producing timeout errors.
brightnessStateMath = '/2.3-10.86'
brightnessCommandMath = '*2.3+25'
} else {
// For other scale (usually 1000), 10-1000 seems OK.
brightnessStateMath = '/('+this.config.brightnessScale+'/100)'
brightnessCommandMath = '*('+this.config.brightnessScale+'/100)'
}
// Map generic DPS topics to device specific topic names
this.deviceTopics = {
state: {
@@ -21,9 +35,10 @@ class SimpleDimmer extends TuyaDevice {
brightness_state: {
key: this.config.dpsBrightness,
type: 'int',
min: (this.config.brightnessScale = 1000) ? 10 : 1,
max: this.config.brightnessScale,
scale: this.config.brightnessScale
topicMin: 0,
topicMax: 100,
stateMath: brightnessStateMath,
commandMath: brightnessCommandMath
}
}
@@ -44,6 +59,7 @@ class SimpleDimmer extends TuyaDevice {
command_topic: this.baseTopic+'command',
brightness_state_topic: this.baseTopic+'brightness_state',
brightness_command_topic: this.baseTopic+'brightness_command',
brightness_scale: 100,
availability_topic: this.baseTopic+'status',
payload_available: 'online',
payload_not_available: 'offline',

View File

@@ -409,14 +409,14 @@ class TuyaDevice {
// Check if it's a number and it's not outside of defined range
if (isNaN(command)) {
return invalid
} else if (deviceTopic.hasOwnProperty('min') && command < deviceTopic.min) {
} else if (deviceTopic.hasOwnProperty('topicMin') && command < deviceTopic.topicMin) {
debugError('Received command value "'+command+'" that is less than the configured minimum value')
debugError('Overriding command with minimum value '+deviceTopic.min)
command = deviceTopic.min
} else if (deviceTopic.hasOwnProperty('max') && command > deviceTopic.max) {
debugError('Overriding command with minimum value '+deviceTopic.topicMin)
command = deviceTopic.topicMin
} else if (deviceTopic.hasOwnProperty('topicMax') && command > deviceTopic.topicMax) {
debugError('Received command value "'+command+'" that is greater than the configured maximum value')
debugError('Overriding command with maximum value: '+deviceTopic.max)
command = deviceTopic.max
debugError('Overriding command with maximum value: '+deviceTopic.topicMax)
command = deviceTopic.topicMax
}
// Perform any required math transforms before returing command value

View File

@@ -46,8 +46,8 @@ Simple device with on/off and brightness functions (dimmer switches or lights)
| --- | --- | --- |
| state | Power state | on/off |
| command | Set power state | on/off, 0/1, true/false |
| brightness_state | Brightness in % | 1-100 |
| brightness_command | set brightness in % | 1-100 |
| brightness_state | Brightness in % | 0-100 |
| brightness_command | set brightness in % | 0-100 |
Manual configuration options:
| Option | Description | Default |
@@ -78,14 +78,14 @@ Tuya bulbs store their HSB color value in a single DPS key using a custom format
| --- | --- | --- |
| state | Power state | on/off |
| command | Set power state | on/off, 0/1, true/false |
| white_brightness_state | White mode brightness in % | 1-100 |
| white_brightness_command | Set white mode brightness in % | 1-100 |
| color_brightness_state | Color mode brightness in % | 1-100 |
| color_brightness_command | Set white mode brightness in % | 1-100 |
| hs_state | Hue, saturation % | H,S (Hue 0-360, Saturation 1-100) |
| hs_command | Set hue, saturation % | H,S (Hue 0-360, Saturation 1-100) |
| hsb_state | Hue, saturation %, brightness % | H,S,B (Hue 0-360, Saturation 1-100, Brightness 1-100) |
| hsb_command | Set hue, saturation %, brightness % | H,S,B (Hue 0-360, Saturation 1-100, Brightness 1-100) |
| white_brightness_state | White mode brightness in % | 0-100 |
| white_brightness_command | Set white mode brightness in % | 0-100 |
| color_brightness_state | Color mode brightness in % | 0-100 |
| color_brightness_command | Set white mode brightness in % | 0-100 |
| hs_state | Hue, saturation % | H,S (Hue 0-360, Saturation 0-100) |
| hs_command | Set hue, saturation % | H,S (Hue 0-360, Saturation 0-100) |
| hsb_state | Hue, saturation %, brightness % | H,S,B (Hue 0-360, Saturation 0-100, Brightness 0-100) |
| hsb_command | Set hue, saturation %, brightness % | H,S,B (Hue 0-360, Saturation 0-100, Brightness 0-100) |
| mode_state | White/Color mode | 'white', 'colour' (some devices also support scenes here) |
| mode_command | Set white/color mode | 'white', 'colour' (some devices also support scenes here) |
| color_temp_state | Color temperature in mireds (only available if device support color temp) | 154-400 (defult range, can be overridden) |

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "tuya-mqtt",
"version": "3.0.0-beta4",
"version": "3.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "tuya-mqtt",
"version": "3.0.0-beta4",
"version": "3.0.0",
"description": "Control Tuya devices locally via MQTT",
"homepage": "https://github.com/TheAgentK/tuya-mqtt#readme",
"main": "tuya-mqtt.js",

View File

@@ -20,7 +20,7 @@ process.on('SIGINT', processExit.bind(0))
process.on('SIGTERM', processExit.bind(0))
process.on('uncaughtException', processExit.bind(1))
// Set unreachable status on exit
// Disconnect from and publish offline status for all devices on exit
async function processExit(exitCode) {
for (let tuyaDevice of tuyaDevices) {
tuyaDevice.device.disconnect()
@@ -30,6 +30,7 @@ async function processExit(exitCode) {
process.exit()
}
// Get new deivce based on configured type
function getDevice(configDevice, mqttClient) {
const deviceInfo = {
configDevice: configDevice,
@@ -57,12 +58,16 @@ function initDevices(configDevices, mqttClient) {
}
}
// Republish devices 2x with 30 seconds sleep if restart of HA is detected
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()
for (let i = 0; i < 2; i++) {
debug('Resending device config/state in 30 seconds')
await utils.sleep(30)
for (let device of tuyaDevices) {
device.publishMqtt(device.baseTopic+'status', 'online')
device.init()
}
await utils.sleep(2)
}
}