From 8afb06af73060712605092802b404e24486dd462 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:18:47 +0200 Subject: [PATCH 01/19] Create cap_measured_value_quantity.json --- devices/generic/items/cap_measured_value_quantity.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 devices/generic/items/cap_measured_value_quantity.json diff --git a/devices/generic/items/cap_measured_value_quantity.json b/devices/generic/items/cap_measured_value_quantity.json new file mode 100644 index 0000000000..fec7a25690 --- /dev/null +++ b/devices/generic/items/cap_measured_value_quantity.json @@ -0,0 +1,8 @@ +{ + "schema": "resourceitem1.schema.json", + "id": "cap/measured_value/quantity", + "datatype": "String", + "access": "R", + "public": true, + "description": "Quantity of measured_value." +} From 8e5a47588c4699580156468b440714904bdc7086 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:19:24 +0200 Subject: [PATCH 02/19] Update resource.cpp Add `state/measured_value` and `cap/measured_value/*`. --- resource.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resource.cpp b/resource.cpp index d285f70aae..305cd7869d 100644 --- a/resource.cpp +++ b/resource.cpp @@ -133,6 +133,7 @@ const char *RStateLocaltime = "state/localtime"; const char *RStateLockState = "state/lockstate"; const char *RStateLowBattery = "state/lowbattery"; const char *RStateLux = "state/lux"; +const char *RStateMeasuredValue = "state/measured_value"; const char *RStateMoisture = "state/moisture"; const char *RStateMountingModeActive = "state/mountingmodeactive"; const char *RStateMusicSync = "state/music_sync"; @@ -215,6 +216,11 @@ const char *RCapColorXyRedX = "cap/color/xy/red_x"; const char *RCapColorXyRedY = "cap/color/xy/red_y"; const char *RCapGroup = "cap/group"; const char *RCapGroupsNotSupported = "cap/groups/not_supported"; +const char *RCapMeasuredValueMax = "cap/measured_value/max"; +const char *RCapMeasuredValueMin = "cap/measured_value/min"; +const char *RCapMeasuredValueQuantity = "cap/measured_value/quantity"; +const char *RCapMeasuredValueSubstance = "cap/measured_value/substance"; +const char *RCapMeasuredValueUnit = "cap/measured_value/unit"; const char *RCapOnOffWithEffect = "cap/on/off_with_effect"; const char *RCapSleeper = "cap/sleeper"; const char *RCapTransitionBlock = "cap/transition_block"; @@ -438,6 +444,7 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RStateLockState)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateLowBattery)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt32, QVariant::Double, RStateLux)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RStateMeasuredValue)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, QVariant::Double, RStateMoisture)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateMountingModeActive)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateMusicSync)); @@ -506,6 +513,11 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, QVariant::Double, RCapColorXyRedY)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapGroup)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapGroupsNotSupported)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RCapMeasuredValueMax)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RCapMeasuredValueMin)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueQuantity)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueSubstance)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueUnit)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapOnOffWithEffect)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapSleeper)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapTransitionBlock)); From 8b495b5891b7a594caeb6044df2d1f9ff4e31607 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:19:28 +0200 Subject: [PATCH 03/19] Update resource.h Add `state/measured_value` and `cap/measured_value/*`. --- resource.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/resource.h b/resource.h index 176edf4c8d..cdf4464f96 100644 --- a/resource.h +++ b/resource.h @@ -112,8 +112,8 @@ extern const char *RActionScene; extern const char *RStateAction; extern const char *RStateAirQuality; extern const char *RStateAirQualityBis; -extern const char *RStateAirQualityPpb; -extern const char *RStateAirQualityPpbBis; +extern const char *RStateAirQualityPpb; // Deprecated +extern const char *RStateAirQualityPpbBis; // Deprecated extern const char *RStateAlarm; extern const char *RStateAlert; extern const char *RStateAllOn; @@ -162,6 +162,7 @@ extern const char *RStateLocaltime; extern const char *RStateLockState; extern const char *RStateLowBattery; extern const char *RStateLux; +extern const char *RStateMeasuredValue; extern const char *RStateMoisture; extern const char *RStateMountingModeActive; extern const char *RStateMusicSync; @@ -171,7 +172,7 @@ extern const char *RStateOpenBis; extern const char *RStateOrientationX; extern const char *RStateOrientationY; extern const char *RStateOrientationZ; -extern const char *RStatePM2_5; +extern const char *RStatePM2_5; // Deprecated extern const char *RStatePanel; extern const char *RStatePower; extern const char *RStatePresence; @@ -229,6 +230,11 @@ extern const char *RCapColorXyRedX; extern const char *RCapColorXyRedY; extern const char *RCapGroup; extern const char *RCapGroupsNotSupported; +extern const char *RCapMeasuredValueMax; +extern const char *RCapMeasuredValueMin; +extern const char *RCapMeasuredValueQuantity; +extern const char *RCapMeasuredValueSubstance; +extern const char *RCapMeasuredValueUnit; extern const char *RCapOnOffWithEffect; extern const char *RCapSleeper; extern const char *RCapTransitionBlock; From 543a1e1269b556974da62e904c66416476cd66c3 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:19:45 +0200 Subject: [PATCH 04/19] Update rest_sensors.cpp Expose `cap/measured_value` as map. --- rest_sensors.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/rest_sensors.cpp b/rest_sensors.cpp index 7b1709df14..65e1ad2c42 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -2697,6 +2697,7 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co const ResourceItem *iy = nullptr; QVariantList xy; QVariantMap cap; + QVariantMap measuredValue; QVariantMap config; const ResourceItem *ilcs = nullptr; const ResourceItem *ilca = nullptr; @@ -2805,7 +2806,14 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co { const char *key = item->descriptor().suffix + 4; - cap[key] = item->toVariant(); + if (strncmp(key, "measured_value/", 15) == 0) + { + measuredValue[key + 15] = item->toVariant(); + } + else + { + cap[key] = item->toVariant(); + } } else if (rid.suffix == RAttrLastAnnounced) { map["lastannounced"] = item->toString(); } else if (rid.suffix == RAttrLastSeen) { map["lastseen"] = item->toString(); } @@ -2923,6 +2931,7 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co } map[QLatin1String("state")] = state; map[QLatin1String("config")] = config; + if (!measuredValue.isEmpty()) cap[QLatin1String("measured_value")] = measuredValue; if (!cap.isEmpty()) map[QLatin1String("capabilities")] = cap; return true; @@ -3203,6 +3212,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) map[QLatin1String("uniqueid")] = sensor->uniqueId(); QVariantMap cap; + QVariantMap measuredValue; for (int i = 0; i < sensor->itemCount(); i++) { @@ -3215,15 +3225,26 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) if (gwWebSocketNotifyAll || item->needPushChange()) { - cap[key] = item->toVariant(); + if (strncmp(key, "measured_value/", 15) == 0) + { + measuredValue[key + 15] = item->toVariant(); + } + else + { + cap[key] = item->toVariant(); + } item->clearNeedPush(); } } } + if (!measuredValue.isEmpty()) + { + cap[QLatin1String("measured_value")] = measuredValue; + } if (!cap.isEmpty()) { - map["capabilities"] = cap; + map[QLatin1String("capabilities")] = cap; webSocketServer->broadcastTextMessage(Json::serialize(map)); updateSensorEtag(sensor); plugin->saveDatabaseItems |= DB_SENSORS; From 8d6934a416eb55736b5e0574a0afd10ec5fd7734 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:20:49 +0200 Subject: [PATCH 05/19] Update vindstyrka_air_quality_sensor.json - Change PM2.5 sensor to ZHAParticulateMatter; - Add `state/measured_value` and associated `cap/measured_value` items to all sensors. --- .../ikea/vindstyrka_air_quality_sensor.json | 396 ++++++++++++++++-- 1 file changed, 350 insertions(+), 46 deletions(-) diff --git a/devices/ikea/vindstyrka_air_quality_sensor.json b/devices/ikea/vindstyrka_air_quality_sensor.json index 49569f936e..73969d2119 100644 --- a/devices/ikea/vindstyrka_air_quality_sensor.json +++ b/devices/ikea/vindstyrka_air_quality_sensor.json @@ -46,6 +46,23 @@ { "name": "attr/name" }, + { + "name": "attr/productid", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0000", + "at": "0x000A", + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0000", + "at": "0x000A" + }, + "refresh.interval": 86400 + }, { "name": "attr/swversion" }, @@ -55,9 +72,50 @@ { "name": "attr/uniqueid" }, + { + "name": "cap/measured_value/max", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0402", + "at": "0x0002", + "eval": "Item.val = Attr.val / 100" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0402", + "at": [ + "0x0001", + "0x0002" + ] + }, + "refresh.interval": 86400 + }, + { + "name": "cap/measured_value/min", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0402", + "at": "0x0001", + "eval": "Item.val = Attr.val / 100" + } + }, + { + "name": "cap/measured_value/quantity", + "static": "temperature" + }, + { + "name": "cap/measured_value/substance", + "static": "air" + }, + { + "name": "cap/measured_value/unit", + "static": "°C" + }, { "name": "config/offset", - "description": "Relative offset to the main measured value.", "default": 0 }, { @@ -70,14 +128,26 @@ "name": "state/lastupdated" }, { - "name": "state/temperature", - "refresh.interval": 360, - "read": { + "name": "state/measured_value", + "awake": true, + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0402", "at": "0x0000", + "eval": "Item.val = (Attr.val - R.item('config/offset').val) / 100" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, "cl": "0x0402", - "fn": "zcl" + "at": "0x0000" }, - "default": 0 + "refresh.interval": 360 + }, + { + "name": "state/temperature", + "deprecated": "2023-09-17" } ] }, @@ -108,16 +178,38 @@ "name": "attr/lastseen" }, { - "name": "attr/manufacturername" + "name": "attr/manufacturername", + "read": { + "fn": "none" + } }, { - "name": "attr/modelid" + "name": "attr/modelid", + "read": { + "fn": "none" + } }, { "name": "attr/name" }, { - "name": "attr/swversion" + "name": "attr/productid", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0000", + "at": "0x000A", + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "none" + } + }, + { + "name": "attr/swversion", + "read": { + "fn": "none" + } }, { "name": "attr/type" @@ -125,9 +217,50 @@ { "name": "attr/uniqueid" }, + { + "name": "cap/measured_value/max", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0405", + "at": "0x0002", + "eval": "Item.val = Attr.val / 100" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0405", + "at": [ + "0x0001", + "0x0002" + ] + }, + "refresh.interval": 86400 + }, + { + "name": "cap/measured_value/min", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0405", + "at": "0x0001", + "eval": "Item.val = Attr.val / 100" + } + }, + { + "name": "cap/measured_value/quantity", + "static": "level" + }, + { + "name": "cap/measured_value/substance", + "static": "relative humidity" + }, + { + "name": "cap/measured_value/unit", + "static": "%" + }, { "name": "config/offset", - "description": "Relative offset to the main measured value.", "default": 0 }, { @@ -138,13 +271,25 @@ }, { "name": "state/humidity", - "refresh.interval": 360, - "read": { + "deprecated": "2023-09-17" + }, + { + "name": "state/measured_value", + "awake": true, + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0405", "at": "0x0000", + "eval": "Item.val = (Attr.val - R.item('config/offset').val) / 100" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, "cl": "0x0405", - "fn": "zcl" + "at": "0x0000" }, - "default": 0 + "refresh.interval": 360 }, { "name": "state/lastupdated" @@ -152,7 +297,7 @@ ] }, { - "type": "$TYPE_AIR_QUALITY_SENSOR", + "type": "$TYPE_PARTICULATEMATTER_SENSOR", "restapi": "/sensors", "uuid": [ "$address.ext", @@ -178,16 +323,38 @@ "name": "attr/lastseen" }, { - "name": "attr/manufacturername" + "name": "attr/manufacturername", + "read": { + "fn": "none" + } }, { - "name": "attr/modelid" + "name": "attr/modelid", + "read": { + "fn": "none" + } }, { "name": "attr/name" }, { - "name": "attr/swversion" + "name": "attr/productid", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0000", + "at": "0x000A", + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "none" + } + }, + { + "name": "attr/swversion", + "read": { + "fn": "none" + } }, { "name": "attr/type" @@ -195,6 +362,50 @@ { "name": "attr/uniqueid" }, + { + "name": "cap/measured_value/max", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", + "at": "0x0002", + "eval": "Item.val = Attr.val" + }, + "default": 0, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", + "at": [ + "0x0001", + "0x0002" + ] + }, + "refresh.interval": 86400 + }, + { + "name": "cap/measured_value/min", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", + "at": "0x0001", + "eval": "Item.val = Attr.val" + }, + "default": 0 + }, + { + "name": "cap/measured_value/quantity", + "static": "density" + }, + { + "name": "cap/measured_value/substance", + "static": "pm2.5" + }, + { + "name": "cap/measured_value/unit", + "static": "µg/m³" + }, { "name": "config/on" }, @@ -205,26 +416,38 @@ "name": "state/lastupdated" }, { - "name": "state/pm2_5", - "refresh.interval": 360, - "read": { + "name": "state/measured_value", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", "at": "0x0000", - "cl": "0x042a", - "fn": "zcl" + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", + "at": "0x0000" }, + "refresh.interval": 360 + }, + { + "name": "state/pm2_5", + "deprecated": "2023-09-17", "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", "at": "0x0000", - "cl": "0x042a", - "eval": "Item.val = Attr.val", - "fn": "zcl" - }, - "default": 0 + "eval": "Item.val = Attr.val" + } }, { "name": "state/airquality", "parse": { "fn": "numtostr", - "srcitem": "state/pm2_5", + "srcitem": "state/measured_value", "op": "le", "to": [ 10, @@ -271,16 +494,38 @@ "name": "attr/lastseen" }, { - "name": "attr/manufacturername" + "name": "attr/manufacturername", + "read": { + "fn": "none" + } }, { - "name": "attr/modelid" + "name": "attr/modelid", + "read": { + "fn": "none" + } }, { "name": "attr/name" }, { - "name": "attr/swversion" + "name": "attr/productid", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x0000", + "at": "0x000A", + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "none" + } + }, + { + "name": "attr/swversion", + "read": { + "fn": "none" + } }, { "name": "attr/type" @@ -288,6 +533,51 @@ { "name": "attr/uniqueid" }, + { + "name": "cap/measured_value/max", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0xFC7E", + "mf": "0x117C", + "at": "0x0002", + "eval": "Item.val = Attr.val" + }, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0x042A", + "mf": "0x117C", + "at": [ + "0x0001", + "0x0002" + ] + }, + "refresh.interval": 86400 + }, + { + "name": "cap/measured_value/min", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0xFC7E", + "mf": "0x117C", + "at": "0x0001", + "eval": "Item.val = Attr.val" + } + }, + { + "name": "cap/measured_value/quantity", + "static": "level" + }, + { + "name": "cap/measured_value/substance", + "static": "tvoc" + }, + { + "name": "cap/measured_value/unit", + "static": "ppm" + }, { "name": "config/on" }, @@ -295,28 +585,42 @@ "name": "config/reachable" }, { - "name": "state/airqualityppb", - "refresh.interval": 360, - "read": { + "name": "state/measured_value", + "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0xFC7E", + "mf": "0x117C", "at": "0x0000", - "cl": "0xfc7e", - "fn": "zcl", - "mf": "0x117c" + "eval": "Item.val = Attr.val" }, + "default": 0, + "read": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0xFC7E", + "mf": "0x117C", + "at": "0x0000" + }, + "refresh.interval": 360 + }, + { + "name": "state/airqualityppb", + "deprecated": "2023-09-17", "parse": { + "fn": "zcl:attr", + "ep": 1, + "cl": "0xFC7E", + "mf": "0x117C", "at": "0x0000", - "cl": "0xfc7e", - "eval": "Item.val = Attr.val", - "fn": "zcl", - "mf": "0x117c" + "eval": "Item.val = Attr.val" } }, { "name": "state/airquality", - "description": "Text representation of the air quality.", "parse": { "fn": "numtostr", - "srcitem": "state/airqualityppb", + "srcitem": "state/measured_value", "op": "le", "to": [ 65, @@ -349,7 +653,7 @@ "dt": "0x29", "min": 1, "max": 300, - "change": "0x00000032" + "change": "0x0032" } ] }, @@ -363,7 +667,7 @@ "dt": "0x21", "min": 1, "max": 300, - "change": "0x00000032" + "change": "0x0032" } ] }, From b7537f65d5f83433fe5110a7f2c955c8edc39f60 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 12:53:53 +0200 Subject: [PATCH 06/19] Update vindstyrka_air_quality_sensor.json --- devices/ikea/vindstyrka_air_quality_sensor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/ikea/vindstyrka_air_quality_sensor.json b/devices/ikea/vindstyrka_air_quality_sensor.json index 73969d2119..de97740c8c 100644 --- a/devices/ikea/vindstyrka_air_quality_sensor.json +++ b/devices/ikea/vindstyrka_air_quality_sensor.json @@ -572,7 +572,7 @@ }, { "name": "cap/measured_value/substance", - "static": "tvoc" + "static": "tVOC" }, { "name": "cap/measured_value/unit", From 70bf453ef29c917c64e0d8f6e2d79d0f986d0edf Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 14:16:21 +0200 Subject: [PATCH 07/19] Update resource.h Add support for `DataTypeReal`. --- resource.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resource.h b/resource.h index cdf4464f96..64373ff1bf 100644 --- a/resource.h +++ b/resource.h @@ -515,6 +515,8 @@ class ResourceItem quint16 m_flags = 0; // bitmap of ResourceItem::ItemFlags qint64 m_num = 0; qint64 m_numPrev = 0; + double m_double = 0.0; + double m_doublePrev = 0.0; deCONZ::SteadyTimeRef m_lastZclReport; BufStringCacheHandle m_strHandle; // for strings which don't fit into \c m_istr From e83b218b6817f578c70849e28c1cd359023692ef Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 14:16:57 +0200 Subject: [PATCH 08/19] Update resource.cpp Add support for `DataTypeReal`. --- resource.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/resource.cpp b/resource.cpp index 305cd7869d..054e3addb9 100644 --- a/resource.cpp +++ b/resource.cpp @@ -1190,11 +1190,30 @@ bool ResourceItem::setValue(const QVariant &val, ValueSource source) return true; } } + else if (m_rid->type == DataTypeReal) + { + bool ok = false; + double d = val.toDouble(&ok); + + if (ok) + { + m_lastSet = now; + m_doublePrev = m_double; + m_flags |= FlagNeedPushSet; + + if (m_double != d) + { + m_double = d; + m_lastChanged = m_lastSet; + m_flags |= FlagNeedPushChange; + } + } + } else { if (m_rid->type == DataTypeReal) { - DBG_Printf(DBG_ERROR, "todo handle DataTypeReal in %s", __FUNCTION__); + DBG_Printf(DBG_ERROR, "todo handle DataTypeReal in %s\n", __FUNCTION__); } bool ok = false; @@ -1275,6 +1294,10 @@ QVariant ResourceItem::toVariant() const { return toString(); } + else if (m_rid->type == DataTypeReal) + { + return (double)m_double; + } else { return (double)m_num; From 16096146eb7354cfe204debdb2402f7e38443080 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sun, 17 Sep 2023 14:33:49 +0200 Subject: [PATCH 09/19] Update resource.cpp --- resource.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/resource.cpp b/resource.cpp index 054e3addb9..4923173e5b 100644 --- a/resource.cpp +++ b/resource.cpp @@ -1207,6 +1207,7 @@ bool ResourceItem::setValue(const QVariant &val, ValueSource source) m_lastChanged = m_lastSet; m_flags |= FlagNeedPushChange; } + return true; } } else From 7d05d3f7d99b31c1cfa68c4ee6cf416b1731e29a Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:36:52 +0200 Subject: [PATCH 10/19] Revert "Update resource.cpp" This reverts commit 16096146eb7354cfe204debdb2402f7e38443080. --- resource.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/resource.cpp b/resource.cpp index 4923173e5b..054e3addb9 100644 --- a/resource.cpp +++ b/resource.cpp @@ -1207,7 +1207,6 @@ bool ResourceItem::setValue(const QVariant &val, ValueSource source) m_lastChanged = m_lastSet; m_flags |= FlagNeedPushChange; } - return true; } } else From 37dc72ef45d2155a16b3b962870bb1d1d5af6905 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:36:57 +0200 Subject: [PATCH 11/19] Revert "Update resource.cpp" This reverts commit e83b218b6817f578c70849e28c1cd359023692ef. --- resource.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/resource.cpp b/resource.cpp index 054e3addb9..305cd7869d 100644 --- a/resource.cpp +++ b/resource.cpp @@ -1190,30 +1190,11 @@ bool ResourceItem::setValue(const QVariant &val, ValueSource source) return true; } } - else if (m_rid->type == DataTypeReal) - { - bool ok = false; - double d = val.toDouble(&ok); - - if (ok) - { - m_lastSet = now; - m_doublePrev = m_double; - m_flags |= FlagNeedPushSet; - - if (m_double != d) - { - m_double = d; - m_lastChanged = m_lastSet; - m_flags |= FlagNeedPushChange; - } - } - } else { if (m_rid->type == DataTypeReal) { - DBG_Printf(DBG_ERROR, "todo handle DataTypeReal in %s\n", __FUNCTION__); + DBG_Printf(DBG_ERROR, "todo handle DataTypeReal in %s", __FUNCTION__); } bool ok = false; @@ -1294,10 +1275,6 @@ QVariant ResourceItem::toVariant() const { return toString(); } - else if (m_rid->type == DataTypeReal) - { - return (double)m_double; - } else { return (double)m_num; From 19affed9d06c62acdc19ae3a91878d248a24fa51 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:37:02 +0200 Subject: [PATCH 12/19] Revert "Update resource.h" This reverts commit 70bf453ef29c917c64e0d8f6e2d79d0f986d0edf. --- resource.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/resource.h b/resource.h index 64373ff1bf..cdf4464f96 100644 --- a/resource.h +++ b/resource.h @@ -515,8 +515,6 @@ class ResourceItem quint16 m_flags = 0; // bitmap of ResourceItem::ItemFlags qint64 m_num = 0; qint64 m_numPrev = 0; - double m_double = 0.0; - double m_doublePrev = 0.0; deCONZ::SteadyTimeRef m_lastZclReport; BufStringCacheHandle m_strHandle; // for strings which don't fit into \c m_istr From a5d8e6257e8b5649bdf6fae9354506b4f3de2cc9 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:37:06 +0200 Subject: [PATCH 13/19] Revert "Update rest_sensors.cpp" This reverts commit 543a1e1269b556974da62e904c66416476cd66c3. --- rest_sensors.cpp | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/rest_sensors.cpp b/rest_sensors.cpp index 65e1ad2c42..7b1709df14 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -2697,7 +2697,6 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co const ResourceItem *iy = nullptr; QVariantList xy; QVariantMap cap; - QVariantMap measuredValue; QVariantMap config; const ResourceItem *ilcs = nullptr; const ResourceItem *ilca = nullptr; @@ -2806,14 +2805,7 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co { const char *key = item->descriptor().suffix + 4; - if (strncmp(key, "measured_value/", 15) == 0) - { - measuredValue[key + 15] = item->toVariant(); - } - else - { - cap[key] = item->toVariant(); - } + cap[key] = item->toVariant(); } else if (rid.suffix == RAttrLastAnnounced) { map["lastannounced"] = item->toString(); } else if (rid.suffix == RAttrLastSeen) { map["lastseen"] = item->toString(); } @@ -2931,7 +2923,6 @@ bool DeRestPluginPrivate::sensorToMap(const Sensor *sensor, QVariantMap &map, co } map[QLatin1String("state")] = state; map[QLatin1String("config")] = config; - if (!measuredValue.isEmpty()) cap[QLatin1String("measured_value")] = measuredValue; if (!cap.isEmpty()) map[QLatin1String("capabilities")] = cap; return true; @@ -3212,7 +3203,6 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) map[QLatin1String("uniqueid")] = sensor->uniqueId(); QVariantMap cap; - QVariantMap measuredValue; for (int i = 0; i < sensor->itemCount(); i++) { @@ -3225,26 +3215,15 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) if (gwWebSocketNotifyAll || item->needPushChange()) { - if (strncmp(key, "measured_value/", 15) == 0) - { - measuredValue[key + 15] = item->toVariant(); - } - else - { - cap[key] = item->toVariant(); - } + cap[key] = item->toVariant(); item->clearNeedPush(); } } } - if (!measuredValue.isEmpty()) - { - cap[QLatin1String("measured_value")] = measuredValue; - } if (!cap.isEmpty()) { - map[QLatin1String("capabilities")] = cap; + map["capabilities"] = cap; webSocketServer->broadcastTextMessage(Json::serialize(map)); updateSensorEtag(sensor); plugin->saveDatabaseItems |= DB_SENSORS; From 5e2f0f467a6bcb3a2f19ff285cd8e29ba0f190f9 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:37:09 +0200 Subject: [PATCH 14/19] Revert "Update resource.h" This reverts commit 8b495b5891b7a594caeb6044df2d1f9ff4e31607. --- resource.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/resource.h b/resource.h index cdf4464f96..176edf4c8d 100644 --- a/resource.h +++ b/resource.h @@ -112,8 +112,8 @@ extern const char *RActionScene; extern const char *RStateAction; extern const char *RStateAirQuality; extern const char *RStateAirQualityBis; -extern const char *RStateAirQualityPpb; // Deprecated -extern const char *RStateAirQualityPpbBis; // Deprecated +extern const char *RStateAirQualityPpb; +extern const char *RStateAirQualityPpbBis; extern const char *RStateAlarm; extern const char *RStateAlert; extern const char *RStateAllOn; @@ -162,7 +162,6 @@ extern const char *RStateLocaltime; extern const char *RStateLockState; extern const char *RStateLowBattery; extern const char *RStateLux; -extern const char *RStateMeasuredValue; extern const char *RStateMoisture; extern const char *RStateMountingModeActive; extern const char *RStateMusicSync; @@ -172,7 +171,7 @@ extern const char *RStateOpenBis; extern const char *RStateOrientationX; extern const char *RStateOrientationY; extern const char *RStateOrientationZ; -extern const char *RStatePM2_5; // Deprecated +extern const char *RStatePM2_5; extern const char *RStatePanel; extern const char *RStatePower; extern const char *RStatePresence; @@ -230,11 +229,6 @@ extern const char *RCapColorXyRedX; extern const char *RCapColorXyRedY; extern const char *RCapGroup; extern const char *RCapGroupsNotSupported; -extern const char *RCapMeasuredValueMax; -extern const char *RCapMeasuredValueMin; -extern const char *RCapMeasuredValueQuantity; -extern const char *RCapMeasuredValueSubstance; -extern const char *RCapMeasuredValueUnit; extern const char *RCapOnOffWithEffect; extern const char *RCapSleeper; extern const char *RCapTransitionBlock; From e4ac9d14e251a4f047f93a0917058c9e440f77ff Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:37:14 +0200 Subject: [PATCH 15/19] Revert "Update resource.cpp" This reverts commit 8e5a47588c4699580156468b440714904bdc7086. --- resource.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/resource.cpp b/resource.cpp index 305cd7869d..d285f70aae 100644 --- a/resource.cpp +++ b/resource.cpp @@ -133,7 +133,6 @@ const char *RStateLocaltime = "state/localtime"; const char *RStateLockState = "state/lockstate"; const char *RStateLowBattery = "state/lowbattery"; const char *RStateLux = "state/lux"; -const char *RStateMeasuredValue = "state/measured_value"; const char *RStateMoisture = "state/moisture"; const char *RStateMountingModeActive = "state/mountingmodeactive"; const char *RStateMusicSync = "state/music_sync"; @@ -216,11 +215,6 @@ const char *RCapColorXyRedX = "cap/color/xy/red_x"; const char *RCapColorXyRedY = "cap/color/xy/red_y"; const char *RCapGroup = "cap/group"; const char *RCapGroupsNotSupported = "cap/groups/not_supported"; -const char *RCapMeasuredValueMax = "cap/measured_value/max"; -const char *RCapMeasuredValueMin = "cap/measured_value/min"; -const char *RCapMeasuredValueQuantity = "cap/measured_value/quantity"; -const char *RCapMeasuredValueSubstance = "cap/measured_value/substance"; -const char *RCapMeasuredValueUnit = "cap/measured_value/unit"; const char *RCapOnOffWithEffect = "cap/on/off_with_effect"; const char *RCapSleeper = "cap/sleeper"; const char *RCapTransitionBlock = "cap/transition_block"; @@ -444,7 +438,6 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RStateLockState)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateLowBattery)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt32, QVariant::Double, RStateLux)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RStateMeasuredValue)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, QVariant::Double, RStateMoisture)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateMountingModeActive)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RStateMusicSync)); @@ -513,11 +506,6 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, QVariant::Double, RCapColorXyRedY)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapGroup)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapGroupsNotSupported)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RCapMeasuredValueMax)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeReal, QVariant::Double, RCapMeasuredValueMin)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueQuantity)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueSubstance)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, QVariant::String, RCapMeasuredValueUnit)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapOnOffWithEffect)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapSleeper)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, QVariant::Bool, RCapTransitionBlock)); From e7ce3e2a0cf2cef2bcbd2c420ec78144d62c5f84 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 18 Sep 2023 19:37:18 +0200 Subject: [PATCH 16/19] Revert "Create cap_measured_value_quantity.json" This reverts commit 8afb06af73060712605092802b404e24486dd462. --- devices/generic/items/cap_measured_value_quantity.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 devices/generic/items/cap_measured_value_quantity.json diff --git a/devices/generic/items/cap_measured_value_quantity.json b/devices/generic/items/cap_measured_value_quantity.json deleted file mode 100644 index fec7a25690..0000000000 --- a/devices/generic/items/cap_measured_value_quantity.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "schema": "resourceitem1.schema.json", - "id": "cap/measured_value/quantity", - "datatype": "String", - "access": "R", - "public": true, - "description": "Quantity of measured_value." -} From 8115d0bd78637576002359482081685a695e50d7 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Thu, 21 Sep 2023 22:04:41 +0200 Subject: [PATCH 17/19] Update vindstyrka_air_quality_sensor.json Express units in ASCII. --- devices/ikea/vindstyrka_air_quality_sensor.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/ikea/vindstyrka_air_quality_sensor.json b/devices/ikea/vindstyrka_air_quality_sensor.json index de97740c8c..f379b0c05b 100644 --- a/devices/ikea/vindstyrka_air_quality_sensor.json +++ b/devices/ikea/vindstyrka_air_quality_sensor.json @@ -112,7 +112,7 @@ }, { "name": "cap/measured_value/unit", - "static": "°C" + "static": "degC" }, { "name": "config/offset", @@ -404,7 +404,7 @@ }, { "name": "cap/measured_value/unit", - "static": "µg/m³" + "static": "ug/m^3" }, { "name": "config/on" From 1ae9837e4ed086ed8908f0b2433713aedfafab16 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Sat, 23 Sep 2023 15:48:35 +0200 Subject: [PATCH 18/19] Update vindstyrka_air_quality_sensor.json --- devices/ikea/vindstyrka_air_quality_sensor.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/ikea/vindstyrka_air_quality_sensor.json b/devices/ikea/vindstyrka_air_quality_sensor.json index f379b0c05b..0c62a1e591 100644 --- a/devices/ikea/vindstyrka_air_quality_sensor.json +++ b/devices/ikea/vindstyrka_air_quality_sensor.json @@ -400,7 +400,7 @@ }, { "name": "cap/measured_value/substance", - "static": "pm2.5" + "static": "PM2.5" }, { "name": "cap/measured_value/unit", @@ -576,7 +576,7 @@ }, { "name": "cap/measured_value/unit", - "static": "ppm" + "static": "ppb" }, { "name": "config/on" From 0e4202921cbf08fa9092bbb2143661c021a7d932 Mon Sep 17 00:00:00 2001 From: ebaauw Date: Mon, 25 Sep 2023 11:53:07 +0200 Subject: [PATCH 19/19] Update vindstyrka_air_quality_sensor.json Remove deprecated mark on `state/temperature`. --- devices/ikea/vindstyrka_air_quality_sensor.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/devices/ikea/vindstyrka_air_quality_sensor.json b/devices/ikea/vindstyrka_air_quality_sensor.json index 0c62a1e591..fe7a372f95 100644 --- a/devices/ikea/vindstyrka_air_quality_sensor.json +++ b/devices/ikea/vindstyrka_air_quality_sensor.json @@ -146,8 +146,7 @@ "refresh.interval": 360 }, { - "name": "state/temperature", - "deprecated": "2023-09-17" + "name": "state/temperature" } ] },