Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ States:

### **WORK IN PROGRESS**
* (copilot) **BREAKING**: Commands now correctly use cmnd/ prefix instead of tele/ prefix - Fix regex bug causing MQTT commands to use "tele" instead of "cmnd" topics
* (copilot) Fix IRHVAC Power, Light and Mode fields showing NULL instead of actual string values
* (copilot) Add Zigbee device control support for Tasmota coordinators - users can now control Zigbee devices (Power/Dimmer) through ioBroker states via automatic ZbSend command generation
* (copilot) Added configuration for advanced MQTT settings
* (copilot) Add support for Tasmota tele/MARGINS messages enabling integration of PowerLow, PowerHigh, and PowerDelta limits
Expand Down
18 changes: 18 additions & 0 deletions lib/datapoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,22 @@ module.exports = {
VEML6075_UvIndexText: { type: 'string', role: 'state', read: true, write: false },
VEML6075_UvLevel: { type: 'number', role: 'value', read: true, write: false },
VEML6075_UvPower: { type: 'number', role: 'value', read: true, write: false, unit: 'W/m²' },
// IRHVAC specific datapoints to avoid conflicts with general Tasmota fields
IrReceived_IRHVAC_Power: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Light: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Mode: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Vendor: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Model: { type: 'number', role: 'value', read: true, write: false },
IrReceived_IRHVAC_Temp: { type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C' },
IrReceived_IRHVAC_FanSpeed: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_SwingV: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_SwingH: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Quiet: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Turbo: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Econo: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Filter: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Clean: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Beep: { type: 'string', role: 'state', read: true, write: false },
IrReceived_IRHVAC_Sleep: { type: 'number', role: 'value', read: true, write: false },
IrReceived_IRHVAC_Celsius: { type: 'string', role: 'state', read: true, write: false },
};
18 changes: 12 additions & 6 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -1029,15 +1029,17 @@ function MQTTServer(adapter) {
}
}

function addObject(attr, client, prefix, path) {
let replaceAttr = types[attr].replace || attr;
function addObject(typeKey, client, prefix, path) {
// Extract the actual attribute name for the state ID construction
const attr = typeKey.includes('_') && path.length > 0 ? typeKey.split('_').pop() : typeKey;
let replaceAttr = types[typeKey].replace || attr;
let id = `${adapter.namespace}.${client.iobId}.${prefix ? `${prefix}.` : ''}${path.length ? `${path.join('_')}_` : ''}${replaceAttr.replace(FORBIDDEN_CHARS, '_')}`;
let obj = {
type: 'addObject',
id: id,
data: {
_id: id,
common: Object.assign({}, types[attr]),
common: Object.assign({}, types[typeKey]),
native: {},
type: 'state',
},
Expand Down Expand Up @@ -1126,12 +1128,16 @@ function MQTTServer(adapter) {
}
nPath = undefined;
}
} else if (types[attr]) {
} else if (types[attr] || (path.length > 0 && types[`${path.join('_')}_${attr}`])) {
let allowReadColors;

// Check for path-based type definition first, then fallback to simple attr type
const typeKey =
path.length > 0 && types[`${path.join('_')}_${attr}`] ? `${path.join('_')}_${attr}` : attr;

// create object
const obj = addObject(attr, client, prefix, path);
let replaceAttr = types[attr].replace || attr;
const obj = addObject(typeKey, client, prefix, path);
let replaceAttr = types[typeKey].replace || attr;

if (obj.data.common.storeMap) {
delete obj.data.common.storeMap;
Expand Down
1 change: 1 addition & 0 deletions test/testServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const rules = {
'tele/HomeMonitor/STATE': {send: '{"Time":"2018-01-19T20:15:16","Uptime":0,"Vcc":3.170,"Wifi":{"AP":1,"SSId":"SmartHOME","RSSI":100,"APMac":"60:31:97:3E:74:B4"}}', expect: {Vcc: 3.170, Wifi_RSSI: 100}},
'tele/HomeMonitor/SENSOR': {send: '{"Time":"2018-01-19T20:15:16","Temperature":20.0,"Humidity":16.0,"Light":10,"Noise":60,"AirQuality":90,"TempUnit":"C"}', expect: {Temperature: 20.0, Humidity: 16.0, Light: 10, Noise: 60, AirQuality: 90}},
'tele/esp32_shutter/STATE': {send: '{"Time":"2025-01-07T10:00:00","Uptime":"0T01:00:00","SHUTTER1":0,"SHUTTER2":25,"SHUTTER3":50,"SHUTTER4":75,"SHUTTER5":100,"SHUTTER6":0,"SHUTTER7":25,"SHUTTER8":50,"SHUTTER9":75,"SHUTTER10":100,"SHUTTER11":0,"SHUTTER12":25,"SHUTTER13":50,"SHUTTER14":75,"SHUTTER15":100,"SHUTTER16":33}', expect: {SHUTTER1: 0, SHUTTER2: 25, SHUTTER3: 50, SHUTTER4: 75, SHUTTER5: 100, SHUTTER6: 0, SHUTTER7: 25, SHUTTER8: 50, SHUTTER9: 75, SHUTTER10: 100, SHUTTER11: 0, SHUTTER12: 25, SHUTTER13: 50, SHUTTER14: 75, SHUTTER15: 100, SHUTTER16: 33}},
'tele/tasmota/RESULT': {send: '{"IrReceived":{"Protocol":"FUJITSU_AC","Bits":128,"Data":"0x1463001010FE0930210000000000208F","Repeat":0,"IRHVAC":{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Auto","Power":"On","Celsius":"On","Temp":18,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}}}', expect: {'IrReceived_IRHVAC_Power': 'On', 'IrReceived_IRHVAC_Light': 'Off', 'IrReceived_IRHVAC_Mode': 'Auto', 'IrReceived_IRHVAC_Vendor': 'FUJITSU_AC', 'IrReceived_IRHVAC_Temp': 18}},
// Zigbee bulb test case from issue #265
'tele/Zigbee_Coordinator_CC2530/SENSOR': {send: '{"Time":"2022-05-05T20:49:08","ZbReceived":{"0x0856":{"Device":"0x0856","Name":"E14 Bulb","Power":1,"Dimmer":20,"Endpoint":1,"LinkQuality":65}}}', expect: {'ZbReceived_0x0856_Power': 1, 'ZbReceived_0x0856_Dimmer': 20, 'ZbReceived_0x0856_Device': '0x0856', 'ZbReceived_0x0856_Name': 'E14 Bulb'}},
// This rule must be last to ensure Emitter_1 maps to tasmota_0912A7 for the existing test
Expand Down
Loading