Skip to content

Instantly share code, notes, and snippets.

@NisseDILLIGAF
Created July 21, 2017 20:43
Show Gist options
  • Save NisseDILLIGAF/fca6f06153a36bcd8f8b5cf80ab81605 to your computer and use it in GitHub Desktop.
Save NisseDILLIGAF/fca6f06153a36bcd8f8b5cf80ab81605 to your computer and use it in GitHub Desktop.
deCONZ, patch for Xiaomi Aqara Temperature Humidity Pressure Sensor
diff --git a/org/bindings.cpp b/nisse/bindings.cpp
index c8fad14..b5bd18f 100755
--- a/org/bindings.cpp
+++ b/nisse/bindings.cpp
@@ -544,6 +544,14 @@ bool DeRestPluginPrivate::sendConfigureReportingRequest(BindingTask &bt)
maxInterval = 300;
reportableChange16bit = 20;
}
+ else if (bt.binding.clusterId == PRESSURE_MEASUREMENT_CLUSTER_ID)
+ {
+ dataType = deCONZ::Zcl16BitUint;
+ attributeId = 0x0000; // measured value
+ minInterval = 10;
+ maxInterval = 300;
+ reportableChange16bit = 20;
+ }
else if (bt.binding.clusterId == POWER_CONFIGURATION_CLUSTER_ID)
{
dataType = deCONZ::Zcl8BitUint;
@@ -767,6 +775,10 @@ void DeRestPluginPrivate::checkSensorBindingsForAttributeReporting(Sensor *senso
{
val = sensor->getZclValue(*i, 0x0000); // measured value
}
+ else if (*i == PRESSURE_MEASUREMENT_CLUSTER_ID)
+ {
+ val = sensor->getZclValue(*i, 0x0000); // measured value
+ }
else if (*i == OCCUPANCY_SENSING_CLUSTER_ID)
{
val = sensor->getZclValue(*i, 0x0000); // occupied state
@@ -817,6 +829,7 @@ void DeRestPluginPrivate::checkSensorBindingsForAttributeReporting(Sensor *senso
case ILLUMINANCE_MEASUREMENT_CLUSTER_ID:
case TEMPERATURE_MEASUREMENT_CLUSTER_ID:
case RELATIVE_HUMIDITY_CLUSTER_ID:
+ case PRESSURE_MEASUREMENT_CLUSTER_ID:
case VENDOR_CLUSTER_ID:
{
DBG_Printf(DBG_INFO_L2, "0x%016llX (%s) create binding for attribute reporting of cluster 0x%04X on endpoint 0x%02X\n",
diff --git a/org/database.cpp b/nisse/database.cpp
index 043e885..779e0a3 100755
--- a/org/database.cpp
+++ b/nisse/database.cpp
@@ -1610,6 +1610,15 @@ static int sqliteLoadAllSensorsCallback(void *user, int ncols, char **colval , c
item = sensor.addItem(DataTypeInt32, RStateHumidity);
item->setValue(0);
}
+ else if (sensor.type().endsWith(QLatin1String("Pressure")))
+ {
+ if (sensor.fingerPrint().hasInCluster(PRESSURE_MEASUREMENT_CLUSTER_ID))
+ {
+ clusterId = PRESSURE_MEASUREMENT_CLUSTER_ID;
+ }
+ item = sensor.addItem(DataTypeInt32, RStatePressure);
+ item->setValue(0);
+ }
else if (sensor.type().endsWith(QLatin1String("Presence")))
{
if (sensor.fingerPrint().hasInCluster(OCCUPANCY_SENSING_CLUSTER_ID))
diff --git a/org/de_web_plugin.cpp b/nisse/de_web_plugin.cpp
index e1debdc..84d2b4d 100755
--- a/org/de_web_plugin.cpp
+++ b/nisse/de_web_plugin.cpp
@@ -85,6 +85,7 @@ static const SupportedDevice supportedDevices[] = {
{ VENDOR_PHILIPS, "SML001" },
{ VENDOR_LUMI, "lumi.sensor_ht" },
{ VENDOR_LUMI, "lumi.sens" },
+ { VENDOR_LUMI, "lumi.weather" },
{ 0, 0 }
};
@@ -2101,6 +2102,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node)
SensorFingerprint fpPresenceSensor;
SensorFingerprint fpTemperatureSensor;
SensorFingerprint fpHumiditySensor;
+ SensorFingerprint fpPressureSensor;
{ // scan client clusters of endpoint
QList<deCONZ::ZclCluster>::const_iterator ci = i->outClusters().constBegin();
@@ -2232,6 +2234,12 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node)
}
break;
+ case PRESSURE_MEASUREMENT_CLUSTER_ID:
+ {
+ fpPressureSensor.inClusters.push_back(ci->id());
+ }
+ break;
+
default:
break;
}
@@ -2343,6 +2351,23 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node)
checkSensorNodeReachable(sensor);
}
}
+ // ZHAPressure
+ if (fpPressureSensor.hasInCluster(PRESSURE_MEASUREMENT_CLUSTER_ID))
+ {
+ fpPressureSensor.endpoint = i->endpoint();
+ fpPressureSensor.deviceId = i->deviceId();
+ fpPressureSensor.profileId = i->profileId();
+
+ sensor = getSensorNodeForFingerPrint(node->address().ext(), fpPressureSensor, "ZHAPressure");
+ if (!sensor || sensor->deletedState() != Sensor::StateNormal)
+ {
+ addSensorNode(node, fpPressureSensor, "ZHAPressure", modelId);
+ }
+ else
+ {
+ checkSensorNodeReachable(sensor);
+ }
+ }
}
}
@@ -2437,6 +2462,14 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi
}
sensorNode.addItem(DataTypeInt32, RStateHumidity);
}
+ else if (sensorNode.type().endsWith(QLatin1String("Pressure")))
+ {
+ if (sensorNode.fingerPrint().hasInCluster(PRESSURE_MEASUREMENT_CLUSTER_ID))
+ {
+ clusterId = PRESSURE_MEASUREMENT_CLUSTER_ID;
+ }
+ sensorNode.addItem(DataTypeInt32, RStatePressure);
+ }
else if (sensorNode.type().endsWith(QLatin1String("Presence")))
{
if (sensorNode.fingerPrint().hasInCluster(OCCUPANCY_SENSING_CLUSTER_ID))
@@ -2792,6 +2825,7 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
case ILLUMINANCE_MEASUREMENT_CLUSTER_ID:
case TEMPERATURE_MEASUREMENT_CLUSTER_ID:
case RELATIVE_HUMIDITY_CLUSTER_ID:
+ case PRESSURE_MEASUREMENT_CLUSTER_ID:
case OCCUPANCY_SENSING_CLUSTER_ID:
case POWER_CONFIGURATION_CLUSTER_ID:
case BASIC_CLUSTER_ID:
@@ -3010,6 +3044,32 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
}
}
}
+ else if (event.clusterId() == PRESSURE_MEASUREMENT_CLUSTER_ID)
+ {
+ for (;ia != enda; ++ia)
+ {
+ if (ia->id() == 0x0000) // pressure
+ {
+ if (updateType != NodeValue::UpdateInvalid)
+ {
+ i->setZclValue(updateType, event.clusterId(), 0x0000, ia->numericValue());
+ }
+
+ int pressure = ia->numericValue().u16;
+ ResourceItem *item = i->item(RStatePressure);
+
+ if (item)
+ {
+ item->setValue(pressure);
+ i->updateStateTimestamp();
+ Event e(RSensors, RStatePressure, i->id());
+ enqueueEvent(e);
+ }
+
+ updateSensorEtag(&*i);
+ }
+ }
+ }
else if (event.clusterId() == OCCUPANCY_SENSING_CLUSTER_ID)
{
for (;ia != enda; ++ia)
@@ -5666,6 +5726,7 @@ void DeRestPluginPrivate::nodeEvent(const deCONZ::NodeEvent &event)
case ILLUMINANCE_LEVEL_SENSING_CLUSTER_ID:
case TEMPERATURE_MEASUREMENT_CLUSTER_ID:
case RELATIVE_HUMIDITY_CLUSTER_ID:
+ case PRESSURE_MEASUREMENT_CLUSTER_ID:
case OCCUPANCY_SENSING_CLUSTER_ID:
case IAS_ZONE_CLUSTER_ID:
case BASIC_CLUSTER_ID:
diff --git a/org/de_web_plugin_private.h b/nisse/de_web_plugin_private.h
index 74dac81..7fe757c 100755
--- a/org/de_web_plugin_private.h
+++ b/nisse/de_web_plugin_private.h
@@ -132,6 +132,7 @@
#define ILLUMINANCE_MEASUREMENT_CLUSTER_ID 0x0400
#define ILLUMINANCE_LEVEL_SENSING_CLUSTER_ID 0x0401
#define TEMPERATURE_MEASUREMENT_CLUSTER_ID 0x0402
+#define PRESSURE_MEASUREMENT_CLUSTER_ID 0x0403
#define RELATIVE_HUMIDITY_CLUSTER_ID 0x0405
#define OCCUPANCY_SENSING_CLUSTER_ID 0x0406
#define IAS_ZONE_CLUSTER_ID 0x0500
diff --git a/org/resource.cpp b/nisse/resource.cpp
index 11fb23b..ae70f33 100755
--- a/org/resource.cpp
+++ b/nisse/resource.cpp
@@ -40,6 +40,7 @@ const char *RStateLightLevel = "state/lightlevel";
const char *RStateLux = "state/lux";
const char *RStateTemperature = "state/temperature";
const char *RStateHumidity = "state/humidity";
+const char *RStatePressure = "state/pressure";
const char *RStateFlag = "state/flag";
const char *RStateReachable = "state/reachable";
const char *RStateSat = "state/sat";
@@ -87,6 +88,7 @@ void initResourceDescriptors()
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt32, RStateLux));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt32, RStateTemperature));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt32, RStateHumidity));
+ rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt32, RStatePressure));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateReachable));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RStateSat));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt32, RStateStatus));
diff --git a/org/resource.h b/nisse/resource.h
index e4f13ac..107fe0f 100755
--- a/org/resource.h
+++ b/nisse/resource.h
@@ -54,6 +54,7 @@ extern const char *RStateLightLevel;
extern const char *RStateLux;
extern const char *RStateTemperature;
extern const char *RStateHumidity;
+extern const char *RStatePressure;
extern const char *RStateFlag;
extern const char *RStateReachable;
extern const char *RStateSat;
diff --git a/org/rest_sensors.cpp b/nisse/rest_sensors.cpp
index dc25485..0a08042 100755
--- a/org/rest_sensors.cpp
+++ b/nisse/rest_sensors.cpp
@@ -289,6 +289,7 @@ int DeRestPluginPrivate::createSensor(const ApiRequest &req, ApiResponse &rsp)
else if (type == QLatin1String("CLIPPresence")) { item = sensor.addItem(DataTypeBool, RStatePresence); item->setValue(false); }
else if (type == QLatin1String("CLIPTemperature")) { item = sensor.addItem(DataTypeInt32, RStateTemperature); item->setValue(0); }
else if (type == QLatin1String("CLIPHumidity")) { item = sensor.addItem(DataTypeInt32, RStateHumidity); item->setValue(0); }
+ else if (type == QLatin1String("CLIPPressure")) { item = sensor.addItem(DataTypeInt32, RStatePressure); item->setValue(0); }
//setState optional
@@ -429,6 +430,24 @@ int DeRestPluginPrivate::createSensor(const ApiRequest &req, ApiResponse &rsp)
return REQ_READY_SEND;
}
}
+ if (state.contains("pressure"))
+ {
+ item = sensor.item(RStatePressure);
+ if (!item)
+ {
+ rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/sensors"), QString("parameter, pressure, not available")));
+ rsp.httpStatus = HttpStatusBadRequest;
+ return REQ_READY_SEND;
+ }
+
+ if (!item->setValue(state["pressure"]))
+ {
+ rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/sensors/state"), QString("invalid value, %1, for parameter pressure").arg(state["pressure"].toString())));
+ rsp.httpStatus = HttpStatusBadRequest;
+ return REQ_READY_SEND;
+ }
+ }
+
}
item = sensor.item(RConfigOn);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment