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

Bitron-Video Wall Thermostat #199

Merged
merged 17 commits into from
Jan 8, 2019
62 changes: 62 additions & 0 deletions converters/fromZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,68 @@ const converters = {
return {occupancy: true};
},
},
bitron_battery: {
cid: 'genPowerCfg',
type: 'attReport',
convert: (model, msg, publish, options) => {
const battery = {max: 3200, min: 2500};
const voltage = msg.data.data['batteryVoltage'] * 100;
return {
battery: toPercentage(voltage, battery.min, battery.max),
voltage: voltage,
};
},
},
bitron_thermostat_att_report: {
cid: 'hvacThermostat',
type: 'attReport',
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['localTemperatureCalibration'] == 'number') {
result.local_temperature_calibration =
precisionRound(msg.data.data['localTemperatureCalibration'], 2) / 10;
}
if (typeof msg.data.data['occupiedHeatingSetpoint'] == 'number') {
result.occupied_heating_setpoint =
precisionRound(msg.data.data['occupiedHeatingSetpoint'], 2) / 100;
}
if (typeof msg.data.data['runningState'] == 'number') {
result.running_state = msg.data.data['runningState'];
}
if (typeof msg.data.data['batteryAlarmState'] == 'number') {
result.battery_alarm_state = msg.data.data['batteryAlarmState'];
}
return result;
},
},
bitron_thermostat_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['localTemperatureCalibration'] == 'number') {
result.local_temperature_calibration =
precisionRound(msg.data.data['localTemperatureCalibration'], 2) / 10;
}
if (typeof msg.data.data['occupiedHeatingSetpoint'] == 'number') {
result.occupied_heating_setpoint =
precisionRound(msg.data.data['occupiedHeatingSetpoint'], 2) / 100;
}
if (typeof msg.data.data['runningState'] == 'number') {
result.running_state = msg.data.data['runningState'];
}
if (typeof msg.data.data['batteryAlarmState'] == 'number') {
result.battery_alarm_state = msg.data.data['batteryAlarmState'];
}
return result;
},
},
smartthings_contact: {
cid: 'ssIasZone',
type: 'statusChange',
Expand Down
42 changes: 40 additions & 2 deletions converters/toZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ const converters = {
zclData: [{
attrId: zclId.attr(cid, attrId).value,
dataType: zclId.attrType(cid, attrId).value,
attrData: Math.round(value) * 100,
attrData: (Math.round((value * 2).toFixed(1))/2).toFixed(1) * 100,
}],
cfg: cfg.default,
};
Expand Down Expand Up @@ -333,7 +333,7 @@ const converters = {
zclData: [{
attrId: zclId.attr(cid, attrId).value,
dataType: zclId.attrType(cid, attrId).value,
attrData: Math.round(value) * 100, // TODO: Lookup in Zigbee documentation
attrData: (Math.round((value * 2).toFixed(1))/2).toFixed(1) * 100,
}],
cfg: cfg.default,
};
Expand Down Expand Up @@ -573,6 +573,44 @@ const converters = {
};
},
},
thermostat_running_state: {
key: 'running_state',
convert: (key, value, message, type) => {
const cid = 'hvacThermostat';
const attrId = 'runningState';
if (type === 'get') {
return {
cid: cid,
cmd: 'read',
cmdType: 'foundation',
zclData: [{attrId: zclId.attr(cid, attrId).value}],
cfg: cfg.default,
};
}
},
},
thermostat_temperature_display_mode: {
key: 'temperature_display_mode',
convert: (key, value, message, type) => {
const cid = 'hvacUserInterfaceCfg';
const attrId = 'tempDisplayMode';
if (type === 'set') {
return {
cid: cid,
cmd: 'write',
cmdType: 'foundation',
zclData: [{
// 0x00 Temperature in °C
// 0x01 Temperature in °F
attrId: zclId.attr(cid, attrId).value,
dataType: zclId.attrType(cid, attrId).value,
attrData: value,
}],
cfg: cfg.default,
};
}
},
},
/*
* Note when send the command to set sensitivity, press button on the device
* to make it wakeup
Expand Down
36 changes: 36 additions & 0 deletions devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -1862,6 +1862,42 @@ const devices = [
execute(device, actions, callback);
},
},
{
zigbeeModel: ['902010/32'],
model: 'AV2010/32',
vendor: 'Bitron',
description: 'Wireless wall thermostat with relay',
supports: 'temperature, heating/cooling system control',
fromZigbee: [
fz.ignore_basic_change, fz.bitron_thermostat_att_report,
fz.bitron_thermostat_dev_change, fz.bitron_battery,
],
toZigbee: [
tz.thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature_calibration,
tz.thermostat_local_temperature, tz.thermostat_running_state,
tz.thermostat_temperature_display_mode,
],
configure: (ieeeAddr, shepherd, coordinator, callback) => {
const device = shepherd.find(ieeeAddr, 1);
const actions = [
(cb) => device.bind('genBasic', coordinator, cb),
(cb) => device.bind('genPowerCfg', coordinator, cb),
(cb) => device.bind('genIdentify', coordinator, cb),
(cb) => device.bind('genTime', coordinator, cb),
(cb) => device.bind('genPollCtrl', coordinator, cb),
(cb) => device.bind('hvacThermostat', coordinator, cb),
(cb) => device.bind('hvacUserInterfaceCfg', coordinator, cb),
(cb) => device.report('hvacThermostat', 'localTemp', 300, 3600, 0, cb),
(cb) => device.report('hvacThermostat', 'localTemperatureCalibration', 1, 0, 0, cb),
(cb) => device.report('hvacThermostat', 'occupiedHeatingSetpoint', 1, 0, 1, cb),
(cb) => device.report('hvacThermostat', 'runningState', 1, 0, 0, cb),
(cb) => device.report('genPowerCfg', 'batteryVoltage', 1800, 43200, 0, cb),
(cb) => device.report('genPowerCfg', 'batteryAlarmState', 1, 0, 1, cb),
];

execute(device, actions, callback);
},
},

// Iris
{
Expand Down