- Platform information:
- Hardware: Raspberry Pi 3 Model B Rev 1.2_
- OS: Raspbian GNU/Linux 8 (stretch)
- OpenJDK Runtime Environment (Zulu 8.31.1.122-linux_aarch32hf) (build 1.8.0_181-b122)
- openHAB Version: 2.4.0 (Build)
- binding = expire1,fritzboxtr0641,mqtt1,weather1,astro,exec,network,ntp,systeminfo,logreader
- ui = paper,basic,classic
- persistence = rrd4j,mapdb
- action = mail,mqtt
- transformation = map,javascript,xslt,scale,jsonpath
- misc = restdocs
My weather station connected via WeeWX > mqtt > OH died, and I decided to quiz my other weather station (AccuRite 5in1) via 433MHz.
Installed rtl-sdr on a rPi, Realtek USB dongle; all working well.
Sending the weather data straight to a mosquitto-client to the mqtt-broker on the OHv2 rPi.
All working well.
However…
The JSON path rule does not seem to catch every message, or does not extract the field:value pairs I want… some are simply dropped (yet sent properly by the receiver)… like so:
08/11/19 14:11:40.486 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:39", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 0, "battery" : "OK", "message_type" : 49, "wind_speed_kph" : 11.761, "wind_dir_deg" : 225.000, "rain_mm" : 573.787}
08/11/19 14:11:40.498 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:39", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 1, "battery" : "OK", "message_type" : 49, "wind_speed_kph" : 11.761, "wind_dir_deg" : 225.000, "rain_mm" : 573.787}
08/11/19 14:11:40.512 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:39", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 2, "battery" : "OK", "message_type" : 49, "wind_speed_kph" : 11.761, "wind_dir_deg" : 225.000, "rain_mm" : 573.787}
08/11/19 14:11:59.359 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:58", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 0, "battery" : "OK", "message_type" : 56, "wind_speed_kph" : 10.934, "temperature_C" : 20.389, "humidity" : 20}
08/11/19 14:11:59.371 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:58", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 1, "battery" : "OK", "message_type" : 56, "wind_speed_kph" : 10.934, "temperature_C" : 20.389, "humidity" : 20}
08/11/19 14:11:59.415 ArgyleCourt/Property/AcuRite5in1 {"time" : "2019-08-11 14:11:58", "model" : "Acurite 5n1 sensor", "sensor_id" : 430, "channel" : "A", "sequence_num" : 2, "battery" : "OK", "message_type" : 56, "wind_speed_kph" : 10.934, "temperature_C" : 20.389, "humidity" : 20}
The following items have been defined:
// ----- 190810 MaxG: created
// ----- AccuRite 5in1 outdoor weather station
Group gAccuRite (gAll, gPersist_rrd4j)
// AccuRite Weather Charts
Group gAccuRiteTemp_Chart
Number gAccuRiteTemp_Chart_Period
Group gAccuRiteHumi_Chart
Number gAccuRiteHumi_Chart_Period
Group gAccuRiteWind_Chart
Number gAccuRiteWind_Chart_Period
Group gAccuRiteRain_Chart
Number gAccuRiteRain_Chart_Period
// data received
String ar_DataReceived "AccuRite data" {mqtt="<[mymosquitto:ArgyleCourt/Property/AcuRite5in1:state:default]"}
DateTime ar_LastUpdated "AccuRite: Last update [%1$td/%1$tm %1$tH:%1$tM]" <calendar> (gAccuRite, gLUP)
// data being extracted
Number ar_Temperature "Outdoor temperature [%.1f °C]" <temperature> (gAccuRite, gAccuRiteTemp_Chart, gSensors_Temperature)
Number ar_Humidity "Outdoor Humidity [%.0f %%]" <temperature> (gAccuRite, gAccuRiteHumi_Chart)
Number ar_WindSpeed "Wind speed [%.0f km/h]" <wind> (gAccuRite, gAccuRiteWind_Chart)
Number ar_WindDir "Wind direction [%.0f°]" <wind> (gAccuRite)
String ar_WindDirText "Wind direction [SCALE(wind_direction.scale):%s]" <wind> (gAccuRite)
String ar_Battery "AccuRite Battery [%s]" <battery4> (gAccuRite)
Number ar_RainTotal "Rain Total [%.0f mm]" <clouds_rain> (gAccuRite)
// data being derived / calculated
Number ar_TemperatureMin "Outdoor temperature minimum [%.1f °C]" <temperature> (gAccuRite, gAccuRiteTemp_Chart)
Number ar_TemperatureMax "Outdoor temperature maximum [%.1f °C]" <temperature> (gAccuRite, gAccuRiteTemp_Chart)
Number ar_HumidityMin "Outdoor humidity minimum [%.0f %%]" <temperature> (gAccuRite, gAccuRiteHumi_Chart)
Number ar_HumidityMax "Outdoor humidity maximum [%.0f %%]" <temperature> (gAccuRite, gAccuRiteHumi_Chart)
Number ar_Humidex "Outdoor Humidex [SCALE(humidex.scale):%s]" (gAccuRite)
Number ar_WindSpeedMin "Wind speed minimum [%.0f km/h]" <wind> (gAccuRite, gAccuRiteWind_Chart)
Number ar_WindSpeedMax "Wind speed maximum [%.0f km/h]" <wind> (gAccuRite, gAccuRiteWind_Chart)
Number ar_RainLast24H "Rain last 24 hours [%.0f mm]" <clouds_rain> (gAccuRite)
Number ar_RainToday "Rain Today [%.0f mm]" <clouds_rain> (gAccuRite, gAccuRiteRain_Chart)
Number ar_RainYesterday "Rain Yesterday [%.0f mm]" <clouds_rain> (gAccuRite)
Number ar_RainWeek "Rain Week [%.0f mm]" <clouds_rain> (gAccuRite)
Number ar_RainMonth "Rain Month [%.0f mm]" <clouds_rain> (gAccuRite)
With the following rule doing the work:
rule "AccuRite 5in1 data received"
when
Item ar_DataReceived changed
then
ar_LastUpdated.postUpdate(new DateTimeType())
//logInfo("AR.1.0", "ar_DataReceived.........: {}", "changed")
val String ar_json = (ar_DataReceived.state as StringType).toString
val String model = transform("JSONPATH", "$.model", ar_json)
val String sensor_id = transform("JSONPATH", "$.sensor_id", ar_json)
val String sequence = transform("JSONPATH", "$.sequence_num", ar_json)
val String message_type = transform("JSONPATH", "$.message_type", ar_json)
// make sure we are listening to the correct sender
if (model == "Acurite 5n1 sensor") {
// get sensor ID; in case have another one in the future :)
if (sensor_id == "430") {
// the weather stations sends the same msg 3 times with sequence_num [0..2]
if (sequence == "1") {
//logInfo("AR.1.02", "sequence./ message_type.: {} / {}", sequence, message_type)
// wind speed is in both messages (49, 56)
val String wind_speed = transform("JSONPATH", "$.wind_speed_kph", ar_json)
//logInfo("AR.1.03", "wind_speed..............: {}", wind_speed)
ar_WindSpeed.postUpdate(wind_speed)
// wind direction and rain
if (message_type == "49") {
val Number wind_dir = transform("JSONPATH", "$.wind_dir_deg", ar_json)
val String rain_total = transform("JSONPATH", "$.rain_mm", ar_json)
logInfo("AR.1.04", "wind_dir................: {}", wind_dir)
//logInfo("AR.1.05", "wind_speed..............: {}", wind_speed)
ar_WindDir.postUpdate(wind_dir)
ar_RainTotal.postUpdate(rain_total)
}
// temperature and humidity
if (message_type == "56") {
val String temp = transform("JSONPATH", "$.temperature_C", ar_json)
val String humi = transform("JSONPATH", "$.humidity", ar_json)
val String batt = transform("JSONPATH", "$.battery", ar_json)
ar_Temperature.postUpdate(temp)
ar_Humidity.postUpdate(humi)
ar_Battery.postUpdate(batt)
}
}
}
}
end
I have a wind direction item to convert the degrees to a text representation, with the following scale file:
[0.00..11.24]=N
[11.25..33.74]=NNE
[33.75..56.24]=NE
[56.25..78.74]=ENE
[78.75..101.24]=E
[101.25..123.74]=ESE
[123.75..146.24]=SE
[146.25..168.74]=SSE
[168.75..191.24]=S
[191.25..213.74]=SSW
[213.75..236.24]=SW
[236.25..258.74]=WSW
[258.75..281.24]=W
[281.25..303.74]=WNW
[303.75..326.24]=NW
[326.25..348.74]=NNW
[348.75..360.00]=N
NaN=Non-numeric state
The last line is from https://www.openhab.org/addons/transformations/scale/, and will result in:
2019-08-11 14:02:18.192 [WARN ] [.internal.ScaleTransformationService] - Scale transform file '/etc/openhab2/transform/wind_direction.scale' does not comply with syntax for entry : 'NaN', 'Non-numeric state'
… assuming this NaN entry is not really allowed.
However, with or without that line I am getting this error:
2019-08-11 14:02:18.196 [WARN ] [rm.AbstractFileTransformationService] - Could not transform '-' with the file 'wind_direction.scale' : Scale can only be used with numeric inputs or valid quantity types
… and the text translation never works, despite feeding a number (or at least I assume that to be the case).
Here the relevant lines:
items:
Number ar_WindDir "Wind direction [%.0f°]" <wind> (gAccuRite)
String ar_WindDirText "Wind direction [SCALE(wind_direction.scale):%s]" <wind> (gAccuRite)
rule part:
val Number wind_dir = transform("JSONPATH", "$.wind_dir_deg", ar_json)
I had a look at this post SCALE transform and UNDEF - Could not transform 'UNDEF' but could not think of a reason why this would apply to my problem.
The sequence of wind directions recognised by OH
2019-08-11 14:27:18.030 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 247.5
2019-08-11 14:27:18.042 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 247.5
2019-08-11 14:27:55.721 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 270.0
2019-08-11 14:28:32.921 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 247.5
2019-08-11 14:29:10.665 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 270.0
2019-08-11 14:29:10.681 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 270.0
2019-08-11 14:32:18.363 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 225.0
2019-08-11 14:33:33.375 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 270.0
2019-08-11 14:34:10.567 [INFO ] [lipse.smarthome.model.script.AR.1.04] - wind_dir................: 270.0