From c2fdb90761da06430686a2507c824800445dbe4e Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 16 Nov 2022 16:14:54 -0500 Subject: [PATCH 1/7] Create genericComponentUnknownSensor.groovy --- genericComponentUnknownSensor.groovy | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 genericComponentUnknownSensor.groovy diff --git a/genericComponentUnknownSensor.groovy b/genericComponentUnknownSensor.groovy new file mode 100644 index 0000000..3c9b7b0 --- /dev/null +++ b/genericComponentUnknownSensor.groovy @@ -0,0 +1,68 @@ +/* + +Copyright 2021 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------- + +Change history: + +0.1- @mboisson - initial version + +*/ + +metadata +{ + definition(name: "Generic Component Unknown Sensor", namespace: "community", author: "community", importUrl: "https://raw.githubusercontent.com/ymerj/HE-HA-control/main/genericComponentUnknownSensor.groovy") + { + capability "Refresh" + } + preferences { + input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true + } + attribute "value", "number" + attribute "unit", "string" +} + +void updated() { + log.info "Updated..." + log.warn "description logging is: ${txtEnable == true}" +} + +void installed() { + log.info "Installed..." + device.updateSetting("txtEnable",[type:"bool",value:true]) + refresh() +} + +void updateAttr(String aKey, aValue, String aUnit = ""){ + sendEvent(name:aKey, value:aValue, unit:aUnit) +} + +void parse(String description) { log.warn "parse(String description) not implemented" } + +void parse(List description) { + description.each { + if (it.name in ["unknown"]) { + if (txtEnable) log.info it.descriptionText + updateAttr("value", it.value, it.unit_of_measurement) + updateAttr("unit", it.unit_of_measurement) +// sendEvent(it) + } + } +} + +void refresh() { + parent?.componentRefresh(this.device) +} From 1dfefa3e88f7daaa016fccaf32d4b014796c83c5 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 16 Nov 2022 16:19:12 -0500 Subject: [PATCH 2/7] Update HA parent.groovy Add support for sensors with unknown device classes --- HA parent.groovy | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/HA parent.groovy b/HA parent.groovy index c542d67..b9a8af5 100644 --- a/HA parent.groovy +++ b/HA parent.groovy @@ -191,9 +191,13 @@ def parse(String description) { def friendly = response?.event?.data?.new_state?.attributes?.friendly_name def unit_of_measurement = response?.event?.data?.new_state?.attributes?.unit_of_measurement // if there is no device_class, we need to infer from the units - if (!device_class && unit_of_measurement in ["Bq/m³"]) device_class = "radon" + if (!device_class) { + if (unit_of_measurement in ["Bq/m³"]) device_class = "radon" + else device_class = "unknown" + } newVals << response?.event?.data?.new_state?.state + newVals << unit_of_measurement def mapping = null if (logEnable) log.debug "parse: domain: ${domain}, device_class: ${device_class}, entity: ${entity}, newVals: ${newVals}, friendly: ${friendly}" @@ -361,19 +365,20 @@ def translateSensors(device_class, newVals, friendly, origin) { def mapping = [ - humidity: [type: "Generic Component Humidity Sensor", event: [[name: "humidity", value: newVals[0], descriptionText:"${friendly} humidity is ${newVals[0]}"]]], - illuminance: [type: "Generic Component Illuminance Sensor", event: [[name: "illuminance", value: newVals[0], descriptionText:"${friendly} illuminance is ${newVals[0]}"]], namespace: "community"], + humidity: [type: "Generic Component Humidity Sensor", event: [[name: "humidity", value: newVals[0], descriptionText:"${friendly} humidity is ${newVals[0]} ${newVals[1]}"]]], + illuminance: [type: "Generic Component Illuminance Sensor", event: [[name: "illuminance", value: newVals[0], descriptionText:"${friendly} illuminance is ${newVals[0]} ${newVals[1]}"]], namespace: "community"], battery: [type: "Generic Component Battery", event: [[name: "battery", value: newVals[0], descriptionText:"${friendly} battery is ${newVals[0]}%"]], namespace: "community"], - power: [type: "Generic Component Power Meter", event: [[name: "power", value: newVals[0], descriptionText:"${friendly} power is ${newVals[0]}"]]], + power: [type: "Generic Component Power Meter", event: [[name: "power", value: newVals[0], descriptionText:"${friendly} power is ${newVals[0]} ${newVals[1]}"]]], pressure: [type: "Generic Component Pressure Sensor", event: [[name: "pressure", value: newVals[0], descriptionText:"${friendly} pressure is ${newVals[0]}"]], namespace: "community"], - carbon_dioxide: [type: "Generic Component Carbon Dioxide Sensor", event: [[name: "carbon_dioxide", value: newVals[0], descriptionText:"${friendly} carbon_dioxide is ${newVals[0]}"]], namespace: "community"], + carbon_dioxide: [type: "Generic Component Carbon Dioxide Sensor", event: [[name: "carbon_dioxide", value: newVals[0], descriptionText:"${friendly} carbon_dioxide is ${newVals[0]} ${newVals[1]}"]], namespace: "community"], volatile_organic_compounds: [type: "Generic Component Volatile Organic Compounds Sensor", - event: [[name: "volatile_organic_compounds", value: newVals[0], descriptionText:"${friendly} volatile_organic_compounds is ${newVals[0]}"]], namespace: "community"], - radon: [type: "Generic Component Radon Sensor", event: [[name: "radon", value: newVals[0], descriptionText:"${friendly} radon is ${newVals[0]}"]], namespace: "community"], - temperature: [type: "Generic Component Temperature Sensor", event: [[name: "temperature", value: newVals[0], descriptionText:"${friendly} temperature is ${newVals[0]}"]]], - voltage: [type: "Generic Component Voltage Sensor", event: [[name: "voltage", value: newVals[0], descriptionText:"${friendly} voltage is ${newVals[0]}"]]], - energy: [type: "Generic Component Energy Meter", event: [[name: "energy", value: newVals[0], descriptionText:"${friendly} energy is ${newVals[0]}"]]], - ] + event: [[name: "volatile_organic_compounds", value: newVals[0], descriptionText:"${friendly} volatile_organic_compounds is ${newVals[0]} ${newVals[1]}"]], namespace: "community"], + radon: [type: "Generic Component Radon Sensor", event: [[name: "radon", value: newVals[0], descriptionText:"${friendly} radon is ${newVals[0]} ${newVals[1]}"]], namespace: "community"], + temperature: [type: "Generic Component Temperature Sensor", event: [[name: "temperature", value: newVals[0], descriptionText:"${friendly} temperature is ${newVals[0]} ${newVals[1]}"]]], + voltage: [type: "Generic Component Voltage Sensor", event: [[name: "voltage", value: newVals[0], descriptionText:"${friendly} voltage is ${newVals[0]} ${newVals[1]}"]]], + energy: [type: "Generic Component Energy Meter", event: [[name: "energy", value: newVals[0], descriptionText:"${friendly} energy is ${newVals[0]} ${newVals[1]}"]]], + unknown: [type: "Generic Component Unknown Sensor", event: [[name: "unknown", value: newVals[0], unit_of_measurement: newVals[1], descriptionText:"${friendly} unknown is ${newVals[0]} ${newVals[1]}"]], namespace: "community"], + ] return mapping[device_class] } From c4dcddea0f66540cedac80cc18891d46a24e9e66 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 17 Nov 2022 09:09:10 -0500 Subject: [PATCH 3/7] Update genericComponentUnknownSensor.groovy Also add the string version of the value for sensors that do not report numbers, but status --- genericComponentUnknownSensor.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/genericComponentUnknownSensor.groovy b/genericComponentUnknownSensor.groovy index 3c9b7b0..ed82a34 100644 --- a/genericComponentUnknownSensor.groovy +++ b/genericComponentUnknownSensor.groovy @@ -32,6 +32,7 @@ metadata input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true } attribute "value", "number" + attribute "valueStr", "string" attribute "unit", "string" } @@ -57,8 +58,8 @@ void parse(List description) { if (it.name in ["unknown"]) { if (txtEnable) log.info it.descriptionText updateAttr("value", it.value, it.unit_of_measurement) + updateAttr("valueStr", it.value, it.unit_of_measurement) updateAttr("unit", it.unit_of_measurement) -// sendEvent(it) } } } From ededbe34329023428b2ed7e8202d6d7d1953b9e7 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 17 Nov 2022 09:11:49 -0500 Subject: [PATCH 4/7] moved device class inference to the sensor section --- HA parent.groovy | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/HA parent.groovy b/HA parent.groovy index b9a8af5..e45ad15 100644 --- a/HA parent.groovy +++ b/HA parent.groovy @@ -189,15 +189,8 @@ def parse(String description) { def domain = entity?.tokenize(".")?.getAt(0) def device_class = response?.event?.data?.new_state?.attributes?.device_class def friendly = response?.event?.data?.new_state?.attributes?.friendly_name - def unit_of_measurement = response?.event?.data?.new_state?.attributes?.unit_of_measurement - // if there is no device_class, we need to infer from the units - if (!device_class) { - if (unit_of_measurement in ["Bq/m³"]) device_class = "radon" - else device_class = "unknown" - } newVals << response?.event?.data?.new_state?.state - newVals << unit_of_measurement def mapping = null if (logEnable) log.debug "parse: domain: ${domain}, device_class: ${device_class}, entity: ${entity}, newVals: ${newVals}, friendly: ${friendly}" @@ -287,6 +280,14 @@ def parse(String description) { if (mapping) updateChildDevice(mapping, entity, friendly) break case "sensor": + def unit_of_measurement = response?.event?.data?.new_state?.attributes?.unit_of_measurement + // if there is no device_class, we need to infer from the units + if (!device_class) { + if (unit_of_measurement in ["Bq/m³"]) device_class = "radon" + else device_class = "unknown" + } + newVals << unit_of_measurement + mapping = translateSensors(device_class, newVals, friendly, origin) if (mapping) updateChildDevice(mapping, entity, friendly) break From 432e8aaf1d6dacc020b1d1eb2c09bd0bd46b196e Mon Sep 17 00:00:00 2001 From: tomwpublic <69065662+tomwpublic@users.noreply.github.com> Date: Fri, 25 Nov 2022 22:15:13 -0600 Subject: [PATCH 5/7] version info --- HA parent.groovy | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/HA parent.groovy b/HA parent.groovy index e45ad15..0511f56 100644 --- a/HA parent.groovy +++ b/HA parent.groovy @@ -68,6 +68,7 @@ * 0.1.46 2022-07-04 tomw Advanced configuration - manual add/remove of devices; option to disable filtering; unused child cleanup * 0.1.47 2022-11-03 mboisson Added support for Carbon Dioxide, Radon, and Volatile Organic Compounds sensors * 0.1.48 2022-11-14 Yves Mercier Added minimal RGB light support (no CT) +* 0.1.49 2022-11-16 mboisson Sensor units and support for "unknown" sensor types * * Thank you(s): */ @@ -280,12 +281,13 @@ def parse(String description) { if (mapping) updateChildDevice(mapping, entity, friendly) break case "sensor": - def unit_of_measurement = response?.event?.data?.new_state?.attributes?.unit_of_measurement - // if there is no device_class, we need to infer from the units - if (!device_class) { - if (unit_of_measurement in ["Bq/m³"]) device_class = "radon" - else device_class = "unknown" - } + def unit_of_measurement = response?.event?.data?.new_state?.attributes?.unit_of_measurement + if (!device_class) + { + // if there is no device_class, we need to infer from the units + if (unit_of_measurement in ["Bq/m³"]) device_class = "radon" + else device_class = "unknown" + } newVals << unit_of_measurement mapping = translateSensors(device_class, newVals, friendly, origin) From 4837f6c544fdc2763a48e6f54c4dd19da8f94428 Mon Sep 17 00:00:00 2001 From: tomwpublic <69065662+tomwpublic@users.noreply.github.com> Date: Fri, 25 Nov 2022 22:15:16 -0600 Subject: [PATCH 6/7] version info --- genericComponentUnknownSensor.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genericComponentUnknownSensor.groovy b/genericComponentUnknownSensor.groovy index ed82a34..b9673c8 100644 --- a/genericComponentUnknownSensor.groovy +++ b/genericComponentUnknownSensor.groovy @@ -18,7 +18,7 @@ limitations under the License. Change history: -0.1- @mboisson - initial version +0.1.49 - mboisson - initial version */ From 70bc3088c92890e6d6b9b5abcdc558a13ea144b2 Mon Sep 17 00:00:00 2001 From: tomwpublic <69065662+tomwpublic@users.noreply.github.com> Date: Fri, 25 Nov 2022 22:16:15 -0600 Subject: [PATCH 7/7] Update packageManifest.json --- packageManifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packageManifest.json b/packageManifest.json index f26286a..ba0e2cc 100644 --- a/packageManifest.json +++ b/packageManifest.json @@ -1,7 +1,7 @@ { "packageName": "HE-HA-control", "author": "ymerj", - "version": "0.1.48", + "version": "0.1.49", "minimumHEVersion": "2.1.9", "dateReleased": "2021-03-19", "drivers": [