Mobile Alerts and openHAB 2

OK some progess

the test didn’t like

 \\s*

but is OK with

 \s*

yes, the

\

that is used for escaping is a bit dependent on the programming language and testing tool that’s being used.

for you the following Javascript transformation should give you the temperature for your sensor

(function(i) {
    var re = new RegExp('Temperature Probe<\/h5>\\s*<h4>([0-9]+,[0-9]+) C<\/h4>', 'm');
    var out = i.match(re)[1];
    return parseFloat(out.replace(',', '.'));
})(input)

as your description is Temperature Probe

and I would suggest to start with the first sensor and when this works add the others.

Thanks for the support,

It’s almost working now. I see in the log my item has a temperature value.

2018-07-21 09:28:25.092 [vent.ItemStateChangedEvent] - inTemperature changed from NULL to 23.8

:slight_smile:

I think I have understood the important parts of this useful method for mobile/alerts sensors inclusion into Openhab. Now I just need to figure out how to get in the PaperUI control panel. and add it to the temperature group I have not created used item file before so I will have to do some more reading. Also, need to think how best to adapt the code to get it working for all my sensors.

One thing to note: I didn’t need to transform the ‘,’ to a ‘.’. The js threw an exception when I tried. It turns out my mobile-alerts html is already in the English style for all decimals. I removed from the js the following code

replace(',', '.')

I guess decimal indicator ‘.’ or ‘,’ is set by the mobile-alerts phone app somewhere.

Thanks, Mark

I spent hours trying get my multiple mobile-alert sensor data into openhab uing the javascript method from @Daniel_Weisser. I have about 10 Temperature sensors and other sensors too.

First approach was to try to load the multiple temperature sensor data into an array and the use the array index to match to an item for that sensor. That failed. I couldn’t get Regex ‘exec’ and the global flag to work and ‘match’ only finds the first instance of ‘Temperature’

Second approach, and I think its better, was to identify with regex each sensor using its ID and then extract the sensor data. I didn’t know Regex at all when I started. After some hours I figured out what I needed and what works with Openhab2. See below

I post the final js code here in case someone else needs a more generic approach to extract sensor data from the mobile alerts sensor page. It should work with other sensor types by changing the sensor id and the name eg Humidity, Temp In, Temp 1, Hum 2, Rain etc and the regex digits and measurement units if necessary. Create a script for each sensor+ data combination and then assign that to an item as above.

eg

Temperature

(function(i) {
    var re = new RegExp('sensor id goes here[\\s\\S]*?Temperature[\\s\\S]*?<h4>([0-9]+.[0-9]+) C');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)

Humidty

(function(i) {
    var re = new RegExp('sensor id goes here[\\s\\S]*?Humidity[\\s\\S]*?<h4>([0-9]+)%');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)

Wind speed

(function(i) {
    var re = new RegExp('sensor id goes here[\\s\\S]*?Windspeed[\\s\\S]*?<h4>([0-9]+.[0-9]+) m\/s');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)

Wind Gust

(function(i) {
    var re = new RegExp('sensor id goes here[\\s\\S]*?Gust[\\s\\S]*?<h4>([0-9]+.[0-9]+) m\/s');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)

Rain

(function(i) {
    var re = new RegExp('sensor id goes here[\\s\\S]*?Rain[\\s\\S]*?<h4>([0-9]+.[0-9]+) mm');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)

ps my mobile-alerts data was already using ‘.’ for the decimal so I didn’t need to replace any ‘,’ german style decimal places

Cheers Mark

Hi Mark,

thanks for the detailed scripts. As far as I known and after looking at several other discussions in the forum, there is currently no way of handing over a parameter to the script and thus the copying of the script is necessary.

If you have further questions concerning RegExps you may as well send me a direct message.

Cheers
Daniel

Hi,

I took this a step further but with only partial success and I am now stuck. I noticed that for the rain gauge the returned data in the cached web page method described previously is rounded up and this leads to large differences between what the app reports and what I see in Openhab. So, I used the mobile-alerts rest API and it returns with a 3 decimal place accuracy. For rain gauge the bucket tip is equivalent to 0.258mm and this gets rounded to 0.3mm in the web page. When calculating 24hr rainfall etc these rounding errors add up.

http://www.mobile-alerts.eu/index.php/en/

Documenation:
Mobile-alerts REST API

This command works from openhab command line :

curl -d deviceids=xxxxxxx -d phoneid=xxxxxx https://www.data199.com/api/pv1/device/lastmeasurement

or

curl -d 'deviceids=xxxxxxx&phoneid=xxxxxx' https://www.data199.com/api/pv1/device/lastmeasurement

It works also from command line using an sh script and I can output the result to a file if needed

Output is like this:

{
  "phoneid": "xxxxxxx",
  "devices": [
    {
      "deviceid": "xxxxxxxx",
      "lastseen": 1534267127,
      "lowbattery": false,
      "measurement": {
        "idx": 155506,
        "ts": 1534267125,
        "c": 1534267127,
        "t1": 18.6,
        "r": 525.03,
        "rf": 2035
      }
    }
  ],
  "success": true

I tested the REGEX at regex101 and it extracts the data

"r":[\s\S]*?([0-9]+.[0-9]+)

I think I need extra \ escapes for openhab like this:

\"r\":[\\s\\S]*?([0-9]+.[0-9]+)

But I can’t use the REGEX because I think the openhab exec command doesn’t want to work properly. I tried exec binding both as a command and as a Thing and a Run channel item and the result is the same

eg without any regex I get this, If use regex the item value is always null unless its REGEX((.*)) then its the same as the log below

String RainTest "Test" { exec="<[curl@@-d@@'deviceids=xxxxx&phoneid=xxxx'@@https://www.data199.com/api/pv1/device/lastmeasurement:60000]" }

or this if using the exec Thing

String RainTest "Test" { channel="exec:command:58831f93:run" }

In logs I see this and item state shows a string in openhab REST:

2018-08-15 09:58:56.690 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '{'

2018-08-15 09:58:56.692 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '  "phoneid": "xxxxxx",'

2018-08-15 09:58:56.693 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '  "devices": ['

2018-08-15 09:58:56.702 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '    {'

2018-08-15 09:58:56.705 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '      "deviceid": "xxxxxxxx",'

2018-08-15 09:58:56.710 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '      "lastseen": 1534316461,'

2018-08-15 09:58:56.712 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '      "lowbattery": false,'

2018-08-15 09:58:56.714 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '      "measurement": {'

2018-08-15 09:58:56.715 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "idx": 155522,'

2018-08-15 09:58:56.717 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "ts": 1534273161,'

2018-08-15 09:58:56.719 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "c": 1534273164,'

2018-08-15 09:58:56.720 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "t1": 17.1,'

2018-08-15 09:58:56.722 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "r": 525.804,'

2018-08-15 09:58:56.724 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '        "rf": 2038'

2018-08-15 09:58:56.726 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '      }'

2018-08-15 09:58:56.727 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '    }'

2018-08-15 09:58:56.729 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '  ],'

2018-08-15 09:58:56.731 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '  "success": true'

2018-08-15 09:58:56.732 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [OUTPUT]: '}'

2018-08-15 09:58:56.736 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: '  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current'

2018-08-15 09:58:56.738 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: '                                 Dload  Upload   Total   Spent    Left  Speed'

2018-08-15 09:58:56.740 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: ''

2018-08-15 09:58:56.741 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: '  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0'

2018-08-15 09:58:56.743 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: '  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0'

2018-08-15 09:58:56.744 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Exec [ERROR]: '100   400  100   357  100    43    356     42  0:00:01  0:00:01 --:--:--   356'


Log then shows as below for REGEX((.*)), but for anything else is always null;

Transformed response is

2018-08-15 09:58:56.751 [DEBUG] [hab.binding.exec.handler.ExecHandler] - Transformed response is '{

  "phoneid": "xxxx",

  "devices": [

    {

      "deviceid": "xxxxxxxx",

      "lastseen": 1534316461,

      "lowbattery": false,

      "measurement": {

        "idx": 155522,

        "ts": 1534273161,

        "c": 1534273164,

        "t1": 17.1,

        "r": 525.804,

        "rf": 2038

      }

    }

  ],

  "success": true

}

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

100   400  100   357  100    43    356     42  0:00:01  0:00:01 --:--:--   356

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

100   400  100   357  100    43    356     42  0:00:01  0:00:01 --:--:--   356'

I was hoping to get it to work something like this. That would be neat.

Number MobileAlertsWeatherStationRainTest "MS RainTest [%.3f mm]" <rain> { exec="<[curl -d deviceids=xxxx -d phoneid=xxxx https://www.data199.com/api/pv1/device/lastmeasurement:60000:REGEX(\"r\":[\\s\\S]*?([0-9]+.[0-9]+))]" }

Any help in getting this work would be appreciated. Thanks Mark.

@adb76 FYI

I got it to work with the mobile-alerts REST API using following method. There may be neater ways but it works.

The main advantage to using the API data is that the API rainfall data is more accurate than that shown on the web page, which is a rounded total amount. Using the web page data for calculating rainfall rates leads to differences between Openhab charts and the Mobile-Alerts charts. In principal the REST API method should also work with the other ‘Pro’ sensors.

I used EXEC binding with Thing pointing to a shell script with a curl command to extract the JSON data.
File:
var/lib/openhab2/Mobile-Alerts_rain_REST_API.sh

containing:

curl -d deviceids=<yourdevice ID's> -d phoneid=<your phone ID> https://www.data199.com/api/pv1/device/lastmeasurement

In the EXEC Thing config I couldn’t get the regex to to work at all but I did get a JS transform to work instead.

JS(get_RainAPIvalue.js)

with get_RainAPIvalue.js like this:

(function(i) {
    var re = new RegExp('"r":[\\s\\S]*?([0-9]+.[0-9]+)');
    var out = i.match(re)[1];
    return parseFloat(out);
})(input)
  • Created String Item EXECOutputRainAPI to contain the JSON output string linked to the EXEC output channel
  • Created Number Item RainAPIvalue to store the number from the transformed JSON API output
  • Created Rule to transform String Item to the Number Item
rule "Convert Mobile-Alerts rain API string EXEC output result to Number type Item"
//var/lib/openhab2/Mobile-Alerts_rain_REST_API.sh run from EXEC Thing
when
    Item EXECOutputRainAPI changed
then
// post the new value to the Number Item
    RainAPIvalue.sendCommand( EXECOutputRainAPI.state.toString )
    logInfo("Rain" , 'Rain API value '+ RainAPIvalue.state)
end
  • Added the Number Item RainAPIvalue to Influx persist file.
RainAPIvalue  : strategy = everyMinute
  • Created chart in Grafana using ‘mean’ and ‘difference’ transform to show changes to the total rainfall and mm/minute… Left chart is the API total rainfall value left axis and rainfall rate on the right axis. Left chart is just rainfall rate.

image

Building on the work I did already… I now have One EXEC thing pulling all the mobile-alerts data using the mobile-alerts REST API. I then use Javascript transforms and Rules to extract each item of the data I need. The relevant Openhab Item is updated only if the new API value is different to the old value. Items are added to my influx persistence list.

Now have Wind gust, speed and direction. Using these I set limits so that I get notifications when there are high winds at home and or if starrted to rain ie… storm warning from my own cheapo weather station. I am happy to share the code… I have Rain, and Wind data using the API method and for the temperature humidity sensors I am using the http cache method… but I plan to move the pro sensors over to API as the preferred method to get the sensor data.

Has nice animation when the needle changes

Not sure if it fits right in this topic
I started to create an openHAB2 binding for MobileAlerts.

What already works is discovering and viewing of the following devices via the phoneid:

MA10320 (temperature / humidity)
MA10200 (temperature / humidity)
MA10650 (rain)
MA10660 (wind)
MA10800 (door / window contact)
MA10230 (humidity guard)

The data is grabbed from the measurements website.
If you have other devices you like to have added please share their id with me and I add them.

Second step is to add a proxy that intercepts the messages from the gateway and forward is (or not) and displays the values in openHAB.

You can find the coresponding issue here: https://github.com/openhab/openhab2-addons/issues/4249

Hi Stefan,

I also have:

MA10100 Temperature sensor
MA10001 Temperature probe
MA10421 Temperature/Humidity station

I have them all in Openhab and charted with Grafana using either web page caching or API call and then using Regex to extract the relevant data. With the API you also get the low battery information and loss of connection.

I wish they did a barometer but they dont so now I am building one from RPi and sensor :slight_smile:

edit… Update I did build my barometer and it works great. Stepper motors drive the dials for pressure and rate of change. No need to tap this barometer to see which way its going :slight_smile: It sends data via MQTT to Openhab and then on to Influx and Grafana. In the meantime Mobile Alerts updated the app to accomodate a barometer. I have not yet seen it for sale.

Hey Mark,

sounds nice.

I haven’t checked the battery messages by now.
My last state of information was that the rest API only works on pro devices and not for the non pros?

Would you mind of sharing your sensor ids with me for testing purposes?

Hi folks,

i've read and reread all post, but i don't get into it...
I have multiple MA-Sensors. I got one Sensor working - the first in the list by using


`sensorCache.url=http://measurements.mobile-alerts.eu/Home/SensorsOverview?phoneid=xxx
sensorCache.updateInterval=60000`

But i don’t get the way to implement all the other sensors from the list…
Can anyone provide me a step by step tutorial for getting all Temp/Hum sensors to work?
(actually i don’t now where to put all the above listet codeings…)

THX

Hi, Sorry forgot about your question re sharing. What are the risks if any?

Also, I recently notified mobile alerts of an issue over the Christmas period. Non pro devices were not showing latest data in the App from 2 to 8am. Also, the sensor overview web page was unavailbale during this time. Later in the day the App caught up with the data. So, the data wasn’t lost but delayed. Annoying that the app and website both showed the last bit of the data in the history as the current data with the current time… even though it wasn’t.

Mobile alerts aknowledged there was an issue and have now said they have fixed it…

Maybe only I noticed it but in your charts you might see an unusually stable period in the early hours or even time slipped data.

ps Got my barometer built: Bosch sensor + MQTT for openhab input + stepper motor dials for fun display. RPi to the rescue again :slight_smile:

I wish I had the time but…

In a nutshell…cache the sensor page (and or use API call if you have pro devices) and the use transform file and regex to extract the data. I identify each sensor with its id. That way when I want to add a new sensor I just copy paste the regex and only need change the sensor id part for new sensors…

Hi, first of all I want to thank everybody for the good information in this thread.
I tried the examples but have encountered a problem.
I create an item that should display the status of 2 garage door contacts, the channels are defined like this

Group gGaragenDiiren
	"GaragenDiiren"
	(C_Garage)
String	garagenDiirAnnette
	"GaragenDiir Annette [%s]"
	(gGaragenDiiren)
	{ http="<[mobileAlerts:60000:JS(getGaragendiirAnnette.js)]" }
String garagenDiirMarc
	"GaragenDiir Marc [%s]"
	(gGaragenDiiren)
	{ http="<[mobileAlerts:60000:JS(getGaragendiirMarc.js)]" }

the problem is that i only get one item displayed, and where the second should be, I see de complete HTML code of the page.

The transformation is done like this

(function(i) {
	    var re = new RegExp('xxxxxxxxxx[\\s\\S]*?Contact Sensor[\\s\\S]*?<h4>([a-zA-Z]+)');
	    var out = i.match(re)[1];
	    return out;
})(input)

they are both identical, only the ID in the regex does change

Any ideas concerning this problem ? I also would like to find where the syntax of the channel line is documented, as I do not understand why it starts with a < tag

For testing that the regex works as expected I extracted the source code from sensor web page and then used one of the free regex test sites to test my expression. You may need to remove on the \ from double \ in your expression to work with the rest site.

Hi,

For those that are interested

I now have all Mobile Alert sensors as items in Opemhab and charted via Influx and Grafana. What was missing was some indication when a sensor had stopped working.

I could have used API call for the ‘Pro’ devices but wanted something that would work for ALL my devices. So, I used web caching (need HTTP binding for this) to extract each sensor time stamp and a rule to check the time since a sensor was last seen. It took quite a bit of work determining the best method to do the task and then more wok in getting the types correct.

Details are below:

Time stamp Item…
String HeatPumpReturnTemperatureTimestamp "Heat Pump return sensor time stamp [%s]" { http="<[sensorCache:60000:JS(getTimestamp.js)]" }

JS transform with REGEX to extract the time stamp…

(function(i) {
    var re = new RegExp('Sensor_ID_goes_here[\\s\\S]*?Timestamp[\\s\\S]*?<h4>([0-9]+/[0-9]+/[0-9]+ [0-9]+:[0-9]+:[0-9]+ [A|P]M)</h4>');
    var out = i.match(re)[1];
    return out;
})(input)

Rule to check when a sensor was last seen…

import java.text.SimpleDateFormat

rule "Heat pump return temperature time stamp check"
when
    Item HeatPumpReturnTemperatureTimestamp received update
then
    val String timestamp_str = HeatPumpReturnTemperatureTimestamp.state.toString //from http cache and REGEX transform

    val SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a")
    val DateTime timestamp = new DateTime(formatter.parse(timestamp_str))          
    val Number elapsedtime = (now.millis - timestamp.millis)/60000

    if (elapsedtime > 30) { // 30mins since last seen
        sendNotification('your email address','Heat pump return sensor not seen for  ' + elapsedtime + 'minutes')
        logInfo("Mobile Alerts" , "Time now = " + now)
        logInfo("Mobile Alerts" , "Heat pump return sensor time stamp = " + timestamp)
        logWarn("Mobile Alerts" , "Heat pump return sensor not seen for " + elapsedtime + " minutes")
    }
end

Hey Mark,
I tried to go your way. But it didn´t work.

My item:
Number MobileAlerts_Outside_Temperature “Temperatur Balkon [%.1f °C]” (mobilealerts) {http="<[mobileAlerts:60000:JS(getTemperatureout.js)]" }

My getTemperatureout.js
(function(i) {
var re = new RegExp(‘Sensor-ID[\s\S]?Temperature[\s\S]?

([0-9]+.[0-9]+) C’);
var out = i.match(re)[1];
return parseFloat(out);
})(input)

My addons.cfg:
transformation = javascript,map

My http.cfg:
mobileAlerts.url=http://measurements.mobile-alerts.eu/Home/SensorsOverview?phoneid=XXXXXXXXX
mobileAlerts.updateInterval=60000

at HABpanel it only shows NULL

at Basic UI it only shows - °C

at paper UI - Transfomations I installed Javasript Transformation und Map Transformation.

with https://measurements.mobile-alerts.eu/Home/SensorsOverview?phoneid=XXXXXXXXX all is shown correctly.

where did I made a mistake or what could missed?

Greetings, Ansgar

I see one problem so far

For checking regex on websites [\s\S] works but for Openhab it should be [\\s\\S]

Its easier to read if you enclose your posted in code in code fences. Button on far right after the smilie.

Any errors in the log?

Cheers Mark