Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't send thermostat setpoint_raise_lower command #1473

Closed
KKoovalsky opened this issue Apr 26, 2019 · 3 comments
Closed

Can't send thermostat setpoint_raise_lower command #1473

KKoovalsky opened this issue Apr 26, 2019 · 3 comments

Comments

@KKoovalsky
Copy link

Bug Report

What happened

When I try to send thermostat setpoint_raise_lower command the zigbee2mqtt service crashes.
I do it like that:

mosquitto_pub -m '{"setpoint_raise_lower":{"mode": "0x01", "amount": 1}}' -t zigbee2mqtt/0x2222223333333333/set

The 0x2222223333333333 is my custom device.

What did you expect to happen

I expected to receive setpoint_raise_lower command from thermostat cluster on my device.

How to reproduce it (minimal and precise)

Firstly I created my own device in the devices.js file:

{                                                                                                                   
    zigbeeModel: ['MyDevice'],                                                                                    
    model: 'MyDevice',                                                                                            
    vendor: 'Mua',                                                                                                
    description: 'Air Conditioning controller',                                                                     
    supports: 'thermostat',                                                                                         
    fromZigbee: [fz.ignore_basic_change, fz.mydevice_mua_att_report, fz.mydevice_mua_dev_change],           
    toZigbee: [                                                                                                     
        tz.thermostat_local_temperature,                                                                            
        tz.thermostat_occupied_cooling_setpoint,                                                                    
        tz.thermostat_control_sequence_of_operation,                                                                
        tz.thermostat_system_mode,                                                                                  
        tz.thermostat_setpoint_raise_lower,                                                                         
        tz.thermostat_min_cool_setpoint_limit,                                                                      
        tz.thermostat_max_cool_setpoint_limit,                                                                      
    ],                                                                                                              
    configure: (ieeeAddr, shepherd, coordinator, callback) => {                                                     
        const device = shepherd.find(ieeeAddr, 1);                                                                  
        const actions = [                                                                                           
            (cb) => device.bind('genBasic', coordinator, cb),                                                       
            (cb) => device.bind('hvacThermostat', coordinator, cb),                                                 
            (cb) => device.report('hvacThermostat', 'localTemp', 60, 120, 0, cb),                                   
        ];                                                                                                          
        execute(device, actions, callback);                                                                         
    },                                                                                                              
},                                                                                                                  

Then I added those corresponding sections in fromZigbee.js:

mydevice_mua_dev_change: {                                                                                      
    cid: 'hvacThermostat',                                                                                          
    type: 'devChange',                                                                                              
    convert: (model, msg, publish, options) => {                                                                    
        const result = {};                                                                                          
        if (typeof msg.data.data['localTemp'] == 'number') {                                                        
            result.local_temperature = precisionRound(msg.data.data['localTemp'], 2) / 100;                         
        }                                                                                                           
        if (typeof msg.data.data['occupiedCoolingSetpoint'] == 'number') {                                          
            result.occupied_cooling_setpoint =                                                                      
                precisionRound(msg.data.data['occupiedCoolingSetpoint'], 2) / 100;                                  
        }                                                                                                           
        const ctrl = msg.data.data['ctrlSeqeOfOper'];                                                               
        if (typeof ctrl == 'number' && common.thermostatControlSequenceOfOperations.hasOwnProperty(ctrl)) {         
            result.control_sequence_of_operation = common.thermostatControlSequenceOfOperations[ctrl];              
        }                                                                                                           
        const smode = msg.data.data['systemMode'];                                                                  
        if (typeof smode == 'number' && common.thermostatSystemModes.hasOwnProperty(smode)) {                       
            result.system_mode = common.thermostatSystemModes[smode];                                               
        }                                                                                                           
        if (typeof msg.data.data['minCoolSetpointLimit'] == 'number') {                                             
            result.min_cool_setpoint_limit = precisionRound(msg.data.data['minCoolSetpointLimit'], 2) / 100;        
        }                                                                                                           
        if (typeof msg.data.data['maxCoolSetpointLimit'] == 'number') {                                             
            result.max_cool_setpoint_limit = precisionRound(msg.data.data['maxCoolSetpointLimit'], 2) / 100;        
        }                                                                                                           
        return result;                                                                                              
    },                                                                                                              
},                                                                                                                  

and

mydevice_mua_att_report: {                                                                                      
    cid: 'hvacThermostat',                                                                                          
    type: ['attReport', 'readRsp'],                                                                                 
    convert: (model, msg, publish, options) => {                                                                    
        const result = {};                                                                                          
        if (typeof msg.data.data['localTemp'] == 'number') {                                                        
            result.local_temperature = precisionRound(msg.data.data['localTemp'], 2) / 100;                         
        }                                                                                                           
        if (typeof msg.data.data['occupiedCoolingSetpoint'] == 'number') {                                          
            result.occupied_cooling_setpoint =                                                                      
                precisionRound(msg.data.data['occupiedCoolingSetpoint'], 2) / 100;                                  
        }                                                                                                           
        const ctrl = msg.data.data['ctrlSeqeOfOper'];                                                               
        if (typeof ctrl == 'number' && common.thermostatControlSequenceOfOperations.hasOwnProperty(ctrl)) {         
            result.control_sequence_of_operation = common.thermostatControlSequenceOfOperations[ctrl];              
        }                                                                                                           
        const smode = msg.data.data['systemMode'];                                                                  
        if (typeof smode == 'number' && common.thermostatSystemModes.hasOwnProperty(smode)) {                       
            result.system_mode = common.thermostatSystemModes[smode];                                               
        }                                                                                                           
        if (typeof msg.data.data['minCoolSetpointLimit'] == 'number') {                                             
            result.min_cool_setpoint_limit = precisionRound(msg.data.data['minCoolSetpointLimit'], 2) / 100;        
        }                                                                                                           
        if (typeof msg.data.data['maxCoolSetpointLimit'] == 'number') {                                             
            result.max_cool_setpoint_limit = precisionRound(msg.data.data['maxCoolSetpointLimit'], 2) / 100;        
        }                                                                                                           
        return result;                                                                                              
    },                                                                                                              
},                                                                                                                  

Finally I added the lacking toZigbee.js sections:

thermostat_occupied_cooling_setpoint: {                                                                             
    key: 'occupied_cooling_setpoint',                                                                               
    convert: (key, value, message, type, postfix) => {                                                              
        const cid = 'hvacThermostat';                                                                               
        const attrId = 'occupiedCoolingSetpoint';                                                                   
        if (type === 'set') {                                                                                       
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'write',                                                                                       
                cmdType: 'foundation',                                                                              
                zclData: [{                                                                                         
                    attrId: zclId.attr(cid, attrId).value,                                                          
                    dataType: zclId.attrType(cid, attrId).value,                                                    
                    attrData: (Math.round((value * 2).toFixed(1))/2).toFixed(1) * 100,                              
                }],                                                                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        } else if (type === 'get') {                                                                                
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'read',                                                                                        
                cmdType: 'foundation',                                                                              
                zclData: [{attrId: zclId.attr(cid, attrId).value}],                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        }                                                                                                           
    },                                                                                                              
},                                                                                                                  
thermostat_min_cool_setpoint_limit: {                                                                               
    key: 'min_cool_setpoint_limit',                                                                                 
    convert: (key, value, message, type, postfix) => {                                                              
        const cid = 'hvacThermostat';                                                                               
        const attrId = 'minCoolSetpointLimit';                                                                      
        if (type === 'set') {                                                                                       
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'write',                                                                                       
                cmdType: 'foundation',                                                                              
                zclData: [{                                                                                         
                    attrId: zclId.attr(cid, attrId).value,                                                          
                    dataType: zclId.attrType(cid, attrId).value,                                                    
                    attrData: (Math.round((value * 2).toFixed(1))/2).toFixed(1) * 100,                              
                }],                                                                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        } else if (type === 'get') {                                                                                
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'read',                                                                                        
                cmdType: 'foundation',                                                                              
                zclData: [{attrId: zclId.attr(cid, attrId).value}],                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        }                                                                                                           
    },                                                                                                              
},                                                                                                                  
thermostat_max_cool_setpoint_limit: {                                                                               
    key: 'max_cool_setpoint_limit',                                                                                 
    convert: (key, value, message, type, postfix) => {                                                              
        const cid = 'hvacThermostat';                                                                               
        const attrId = 'maxCoolSetpointLimit';                                                                      
        if (type === 'set') {                                                                                       
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'write',                                                                                       
                cmdType: 'foundation',                                                                              
                zclData: [{                                                                                         
                    attrId: zclId.attr(cid, attrId).value,                                                          
                    dataType: zclId.attrType(cid, attrId).value,                                                    
                    attrData: (Math.round((value * 2).toFixed(1))/2).toFixed(1) * 100,                              
                }],                                                                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        } else if (type === 'get') {                                                                                
            return {                                                                                                
                cid: cid,                                                                                           
                cmd: 'read',                                                                                        
                cmdType: 'foundation',                                                                              
                zclData: [{attrId: zclId.attr(cid, attrId).value}],                                                 
                cfg: cfg.default,                                                                                   
            };                                                                                                      
        }                                                                                                           
    },                                                                                                              
},                                                                                                                  

Debug Info

zigbee2mqtt version: 1.3.1
CC253X firmware version: CC2531ZNP-Prod.hex

Crash report:

  zigbee2mqtt:debug 4/26/2019, 7:02:48 AM Received MQTT message on 'zigbee2mqtt/0x2222223333333333/set' with data '{"setpoint_raise_lower":{"mode": "0x01", "amount": 1}}'
/opt/zigbee2mqtt/node_modules/zigbee-shepherd-converters/converters/toZigbee.js:747
                        dataType: zclId.attrType(cid, attrId).value,
                                                             ^

TypeError: Cannot read property 'value' of undefined
    at Object.convert (/opt/zigbee2mqtt/node_modules/zigbee-shepherd-converters/converters/toZigbee.js:747:62)
    at keys.forEach (/opt/zigbee2mqtt/lib/extension/devicePublish.js:179:41)
    at Array.forEach (<anonymous>)
    at DevicePublish.onMQTTMessage (/opt/zigbee2mqtt/lib/extension/devicePublish.js:165:14)
    at results.extensions.filter.map (/opt/zigbee2mqtt/lib/controller.js:154:27)
    at Array.map (<anonymous>)
    at Controller.onMQTTMessage (/opt/zigbee2mqtt/lib/controller.js:154:14)
    at MQTT.onMessage (/opt/zigbee2mqtt/lib/mqtt.js:81:18)
    at MqttClient.emit (events.js:189:13)
    at MqttClient._handlePublish (/opt/zigbee2mqtt/node_modules/mqtt/lib/client.js:987:12)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `node index.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/pi/.npm/_logs/2019-04-26T07_02_48_357Z-debug.log
@Koenkk
Copy link
Owner

Koenkk commented Apr 26, 2019

I'm not sure what is going on here (this is an existing converter so should also be tested by others???)

Anyway, can you before https://github.com/Koenkk/zigbee-shepherd-converters/blob/master/converters/toZigbee.js#L657` add

console.log(cid, attrId, zclId.attrType(cid, attrId))

@KKoovalsky
Copy link
Author

Hello,

thank you for the response and sorry for such a delay, but I had a vacation.

I added the logging line like so:

...
const attrId = 'setpointRaiseLower'; 
if (type === 'set') { 
    console.log(cid, attrId, zclId.attrType(cid, attrId)) 
    return { 
...

The output is:

hvacThermostat setpointRaiseLower undefined

However, commenting out those lines:

// dataType: zclId.attrType(cid, attrId).value,                                                 
// attrData: Math.round(value) * 100, // TODO: Combine mode and amount in attrData?             

Fixed the problem.

Koenkk added a commit to Koenkk/zigbee-herdsman-converters that referenced this issue May 7, 2019
@Koenkk
Copy link
Owner

Koenkk commented May 7, 2019

Those lines aren't needed indeed, thanks, fixed in latest dev!

@Koenkk Koenkk closed this as completed May 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants