diff --git a/database.cpp b/database.cpp
index 8085e30abf..f416ed677e 100644
--- a/database.cpp
+++ b/database.cpp
@@ -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
{
diff --git a/de_web_plugin.cpp b/de_web_plugin.cpp
index 3d394a9e3f..8f45a341da 100644
--- a/de_web_plugin.cpp
+++ b/de_web_plugin.cpp
@@ -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
{
diff --git a/general.xml b/general.xml
index 003c8b7912..f798863b61 100644
--- a/general.xml
+++ b/general.xml
@@ -1874,7 +1874,7 @@ Note: It does not clear or delete previous weekly schedule programming configura
-
+
diff --git a/resource.cpp b/resource.cpp
index 0d9e16784f..27b08516a7 100644
--- a/resource.cpp
+++ b/resource.cpp
@@ -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 *RConfigExternalTemperatureSensor = "config/externalsensortemp";
const char *RConfigOffset = "config/offset";
const char *RConfigOn = "config/on";
const char *RConfigPending = "config/pending";
@@ -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));
diff --git a/resource.h b/resource.h
index 31e730695d..471ff271c5 100644
--- a/resource.h
+++ b/resource.h
@@ -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;
diff --git a/rest_sensors.cpp b/rest_sensors.cpp
index b606d06d33..fa4dbdff5f 100644
--- a/rest_sensors.cpp
+++ b/rest_sensors.cpp
@@ -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)
diff --git a/thermostat.cpp b/thermostat.cpp
index c92b6ebabc..c9289a432b 100644
--- a/thermostat.cpp
+++ b/thermostat.cpp
@@ -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(RConfigExternalTemperatureSensor);
+ if (item)
+ {
+ if (updateType == NodeValue::UpdateByZclReport)
+ {
+ configUpdated = true;
+ }
+ if (item->toNumber() != externalMeasurement)
+ {
+ item->setValue(externalMeasurement);
+ enqueueEvent(Event(RSensors, RConfigExternalTemperatureSensor, sensor->id(), item));
+ configUpdated = true;
+ }
+ }
+ }
+ sensor->setZclValue(updateType, ind.srcEndpoint(), THERMOSTAT_CLUSTER_ID, attrId, attr.numericValue());
+ }
+ break;
+
default:
break;
}