Skip to content

Commit

Permalink
Added API state "ext_sensortemperature" for Danfoss Ally thermostat
Browse files Browse the repository at this point in the history
Allows for setting an externally-measured temperature value via the REST
API. Useful for those of us who have radiators under desks or covered by
radiator covers.
  • Loading branch information
hanskroner committed Feb 13, 2021
1 parent 9408372 commit e9405f5
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3669,6 +3669,7 @@ static int sqliteLoadAllSensorsCallback(void *user, int ncols, char **colval , c
// Supported with Danfoss firmware version 1.08
sensor.addItem(DataTypeBool, RConfigScheduleOn)->setValue(false);
sensor.addItem(DataTypeString, RConfigSchedule);
sensor.addItem(DataTypeInt16, RConfigExternalTemperatureSensor);
}
else if (sensor.modelId() == QLatin1String("AC201")) // OWON AC201 Thermostat
{
Expand Down
1 change: 1 addition & 0 deletions de_web_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6606,6 +6606,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi
// Supported with Danfoss firmware version 1.08
sensorNode.addItem(DataTypeBool, RConfigScheduleOn)->setValue(false);
sensorNode.addItem(DataTypeString, RConfigSchedule);
sensorNode.addItem(DataTypeInt16, RConfigExternalTemperatureSensor);
}
else if (modelId == QLatin1String("AC201")) // OWON AC201 Thermostat
{
Expand Down
2 changes: 1 addition & 1 deletion general.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,7 @@ Note: It does not clear or delete previous weekly schedule programming configura
<attribute id="0x4012" name="Mounting mode active" type="bool" default="0x01" access="r" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4013" name="Mounting mode control" type="bool" access="rw" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4014" name="eTRV Orientation" type="bool" default="0x00" access="rw" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4015" name="External Measured Room Sensor" type="s16" access="r" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4015" name="External Measured Room Sensor" type="s16" access="rw" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4016" name="Radiator Covered" type="bool" access="w" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4020" name="Control Algorithm Scale Factor" type="u8" default="1" access="rw" required="o" mfcode="0x1246"></attribute>
<attribute id="0x4030" name="Heat Available" type="bool" default="0x00" access="rw" required="o" mfcode="0x1246"></attribute>
Expand Down
2 changes: 2 additions & 0 deletions resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const char *RConfigLevelMin = "config/levelmin";
const char *RConfigMode = "config/mode";
const char *RConfigSetValve = "config/setvalve";
const char *RConfigMountingMode = "config/mountingmode";
const char *RConfigExternalSensorTemperature = "config/externalsensortemp";
const char *RConfigOffset = "config/offset";
const char *RConfigOn = "config/on";
const char *RConfigPending = "config/pending";
Expand Down Expand Up @@ -329,6 +330,7 @@ void initResourceDescriptors()
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RConfigUsertest));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigWindowCoveringType));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RConfigWindowOpen));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, RConfigExternalTemperatureSensor));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigUbisysJ1Mode));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigUbisysJ1WindowCoveringType));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigUbisysJ1ConfigurationAndStatus));
Expand Down
1 change: 1 addition & 0 deletions resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ extern const char *RConfigUrl;
extern const char *RConfigUsertest;
extern const char *RConfigWindowCoveringType;
extern const char *RConfigWindowOpen;
extern const char *RConfigExternalTemperatureSensor;
extern const char *RConfigUbisysJ1Mode;
extern const char *RConfigUbisysJ1WindowCoveringType;
extern const char *RConfigUbisysJ1ConfigurationAndStatus;
Expand Down
29 changes: 29 additions & 0 deletions rest_sensors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,35 @@ int DeRestPluginPrivate::changeSensorConfig(const ApiRequest &req, ApiResponse &
return REQ_READY_SEND;
}
}
else if (rid.suffix == RConfigExternalTemperatureSensor)
{
if (map[pi.key()].type() == QVariant::Double)
{
if (sensor->modelId() == QLatin1String("eTRV0100") || sensor->modelId() == QLatin1String("TRV001"))
{
qint16 externalMeasurement = map[pi.key()].toInt(&ok);

if (addTaskThermostatReadWriteAttribute(task, deCONZ::ZclWriteAttributesId, VENDOR_DANFOSS, 0x4015, deCONZ::Zcl16BitInt, externalMeasurement))
{
updated = true;
}
else
{
rsp.list.append(errorToMap(ERR_ACTION_ERROR, QString("/sensors/%1/config/%2").arg(id).arg(pi.key()).toHtmlEscaped(),
QString("Could not set attribute")));
rsp.httpStatus = HttpStatusBadRequest;
return REQ_READY_SEND;
}
}
}
else
{
rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/sensors/%1/config/%2").arg(id).arg(pi.key()).toHtmlEscaped(),
QString("invalid value, %1, for parameter %2").arg(map[pi.key()].toString()).arg(pi.key()).toHtmlEscaped()));
rsp.httpStatus = HttpStatusBadRequest;
return REQ_READY_SEND;
}
}
else if (rid.suffix == RConfigSetValve)
{
if (map[pi.key()].type() == QVariant::Bool)
Expand Down
25 changes: 25 additions & 0 deletions thermostat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,31 @@ void DeRestPluginPrivate::handleThermostatClusterIndication(const deCONZ::ApsDat
}
break;

case 0x4015: // External Measured Room Sensor
{
if (zclFrame.manufacturerCode() == VENDOR_DANFOSS && (sensor->modelId() == QLatin1String("eTRV0100") ||
sensor->modelId() == QLatin1String("TRV001")))
{
qint16 externalMeasurement = attr.numericValue().s16;
item = sensor->item(RConfigExternalSensorTemperature);
if (item)
{
if (updateType == NodeValue::UpdateByZclReport)
{
configUpdated = true;
}
if (item->toNumber() != externalMeasurement)
{
item->setValue(externalMeasurement);
enqueueEvent(Event(RSensors, RConfigExternalSensorTemperature, sensor->id(), item));
configUpdated = true;
}
}
}
sensor->setZclValue(updateType, ind.srcEndpoint(), THERMOSTAT_CLUSTER_ID, attrId, attr.numericValue());
}
break;

default:
break;
}
Expand Down

0 comments on commit e9405f5

Please sign in to comment.