Skip to content

Commit

Permalink
fix: ensure temperature and mode are defined
Browse files Browse the repository at this point in the history
  • Loading branch information
robertsLando committed Dec 1, 2020
1 parent 3ab18c5 commit fe08a27
Showing 1 changed file with 92 additions and 81 deletions.
173 changes: 92 additions & 81 deletions lib/Gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -1160,98 +1160,109 @@ Gateway.prototype.discoverClimates = function (node) {
return
}

const nodeDevices = allDevices[node.deviceId] || []
try {
const nodeDevices = allDevices[node.deviceId] || []

// skip if there is already a climate device
if (nodeDevices.length > 0 && nodeDevices.find(d => d.type === 'climate')) {
return
}
// skip if there is already a climate device
if (nodeDevices.length > 0 && nodeDevices.find(d => d.type === 'climate')) {
return
}

const setpoints = []
const temperatures = []
const modes = []
const setpoints = []
const temperatures = []
const modes = []

for (const vId in node.values) {
const v = node.values[vId]
if (
v.commandClass === CommandClasses['Thermostat Setpoint'] &&
v.property === 'setpoint'
) {
setpoints.push(v)
} else if (
v.commandClass === CommandClasses['Multilevel Sensor'] &&
v.property === 'Air temperature'
) {
temperatures.push(v)
} else if (
v.commandClass === CommandClasses['Thermostat Mode'] &&
v.property === 'mode'
) {
modes.push(v)
for (const vId in node.values) {
const v = node.values[vId]
if (
v.commandClass === CommandClasses['Thermostat Setpoint'] &&
v.property === 'setpoint'
) {
setpoints.push(v)
} else if (
v.commandClass === CommandClasses['Multilevel Sensor'] &&
v.property === 'Air temperature'
) {
temperatures.push(v)
} else if (
v.commandClass === CommandClasses['Thermostat Mode'] &&
v.property === 'mode'
) {
modes.push(v)
}
}
}

const mode = modes[0]
const temperature = temperatures[0]

// [0, 1, 2] ---> ['off', 'heat', 'cold']
const availableModes = mode.states.map(s => s.value)

// zwave modes: https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/commandclass/ThermostatModeCC.ts#L54
const hassModes = [
// Available hass modes: [“auto”, “off”, “cool”, “heat”, “dry”, “fan_only”]
'off',
'heat',
'cool',
'auto',
undefined, // auxiliary
undefined, // resume
'fan_only',
undefined, // furnace
'dry',
undefined, // moist
'auto', // auto changeover
'heat', // energy heat
'cool', // energy cool
'off', // away
'heat', // full power
undefined // manufacturer specific
]

const config = copy(hassCfg.thermostat)

config.mode_map = {}
config.setpoint_topic = {}
config.values = [mode.id, temperature.id]

config.discovery_payload.mode_state_topic = mode.id
config.discovery_payload.current_temperature_topic = temperature.id

// for all available modes update the modes map and setpoint topics
for (const m of availableModes) {
config.mode_map[hassModes[m]] = availableModes[m]
config.discovery_payload.modes.push(hassModes[m])
if (m > 0) {
// find the mode setpoint, ignore off
const setpoint = setpoints.find(v => v.propertyKey === m)
if (setpoint) {
if (setpoint.propertyKey === 1) {
config.default_setpoint = setpoint.id
}
const mode = modes[0]
const temperature = temperatures[0]

if (!temperature || !mode) {
debug(
'Unable to discover climate device, there is no valid temperature/thermostat mode valueIds'
)
return
}

// [0, 1, 2] ---> ['off', 'heat', 'cold']
const availableModes = mode.states.map(s => s.value)

// zwave modes: https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/commandclass/ThermostatModeCC.ts#L54
const hassModes = [
// Available hass modes: [“auto”, “off”, “cool”, “heat”, “dry”, “fan_only”]
'off',
'heat',
'cool',
'auto',
undefined, // auxiliary
undefined, // resume
'fan_only',
undefined, // furnace
'dry',
undefined, // moist
'auto', // auto changeover
'heat', // energy heat
'cool', // energy cool
'off', // away
'heat', // full power
undefined // manufacturer specific
]

const config = copy(hassCfg.thermostat)

config.mode_map = {}
config.setpoint_topic = {}
config.values = [mode.id, temperature.id]

config.discovery_payload.mode_state_topic = mode.id
config.discovery_payload.current_temperature_topic = temperature.id

// for all available modes update the modes map and setpoint topics
for (const m of availableModes) {
config.mode_map[hassModes[m]] = availableModes[m]
config.discovery_payload.modes.push(hassModes[m])
if (m > 0) {
// find the mode setpoint, ignore off
const setpoint = setpoints.find(v => v.propertyKey === m)
if (setpoint) {
if (setpoint.propertyKey === 1) {
config.default_setpoint = setpoint.id
}

config.values.push(setpoint.id)
config.setpoint_topic[m] = setpoint.id
config.values.push(setpoint.id)
config.setpoint_topic[m] = setpoint.id
}
}
}
}

// add the new climate config to the nodeDevices so it will be
// discovered later when we call `discoverDevice`
nodeDevices.push(config)
// add the new climate config to the nodeDevices so it will be
// discovered later when we call `discoverDevice`
nodeDevices.push(config)

debug('New climate device discovered: ' + JSON.stringify(config))
debug('New climate device discovered: ' + JSON.stringify(config))

allDevices[node.deviceId] = nodeDevices
allDevices[node.deviceId] = nodeDevices
} catch (error) {
debug('Unable to discover climate device: ' + error.message)
}
}

/**
Expand Down

0 comments on commit fe08a27

Please sign in to comment.