JSONPATH to grab dates for garbage disposal

Hi,

I’m trying to grab the date for when the next date the garbage will be picked up from our house.

I successfully get the raw data, but I cannot figure the correct JSONPATH term to use in the items file, to only get the date as output.

This is the closest i have got, but i’m still getting wrong output:

String Recycle_test1                    "Recycle test1: [%s]"    <text>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($.[0])]" }

This is my source, and each “FraksjonId” is a different garbage type. I only need the first date from each “FraksjonId”:

[
{
“FraksjonId”: 1,
“Tommedatoer”: [
“2018-08-23T00:00:00”,
“2018-09-20T00:00:00”
]
},
{
“FraksjonId”: 3,
“Tommedatoer”: [
“2018-08-23T00:00:00”,
“2018-09-06T00:00:00”
]
},
{
“FraksjonId”: 2,
“Tommedatoer”: [
“2018-08-29T00:00:00”,
“2018-09-26T00:00:00”
]
},
{
“FraksjonId”: 7,
“Tommedatoer”: [
“2018-08-29T00:00:00”,
“2018-09-26T00:00:00”
]
},
{
“FraksjonId”: 4,
“Tommedatoer”: [
“2018-09-06T00:00:00”,
“2018-10-04T00:00:00”
]
}
]

I would appreciate if anyone have a suggestion for a solution.

The source is from a Norwegian system that is made to remind you to put out the garbage, when it will be picked up.

According to this Jayway JsonPath evaluator, you could use this JsonPath to return a list of the values you are going for (careful… the json you posted is not in code fences, so it has smart quotes in it)…

$[*][*][0]

Or, if you wanted to get a specific value…

$..[?(@.FraksjonId==7)].Tommedatoer[0]

The functionality of the JSONPATH transformation service has unfortunately been reduced to only allow JSONPATH results that return strings and single element lists. A JSONPATH that returns multiple elements is not supported by the transform. In this case, you would get an error, null or the entire original json, I’m not sure which.

There are other options for this, such as using a JS transform, or pulling the raw data into an item and then calculating the value in a rule using executeCommandLine with jq and updating items. Untested…

import java.util.List
...
// somewhere in your rule
val List<String> trashTimeList = executeCommandLine("/bin/sh@@-c@@/usr/bin/echo " + Raw_Date.state.toString + " | /usr/bin/jq '.[].Tommedatoer[0]'",10000).split("\n")

Hi Scott,

Thank you for your help. The second transformation example you mentioned, worked as i wanted it to, without any errors. If was supposed to generate a list, it seems to only adopt the first value. I also changed the item from string, to date, so that i can format it as i want in ex. habpanel.

This is how my items look like:

DateTime Recycle_paper                    "Søppeltømming, Papir: [%s]"    <time>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($..[?(@.FraksjonId==2)].Tommedatoer[0])]" }
DateTime Recycle_plastic                    "Søppeltømming, Plast: [%s]"    <time>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($..[?(@.FraksjonId==7)].Tommedatoer[0])]" }
DateTime Recycle_food                    "Søppeltømming, Matavfall: [%s]"    <time>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($..[?(@.FraksjonId==3)].Tommedatoer[0])]" }
DateTime Recycle_glass_metal                    "Søppeltømming, Glass/Metall: [%s]"    <time>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($..[?(@.FraksjonId==4)].Tommedatoer[0])]" }
DateTime Recycle_rest                    "Søppeltømming, Rest: [%s]"    <time>                  { mqtt="<[hostname:recycle01/output:state:JSONPATH($..[?(@.FraksjonId==1)].Tommedatoer[0])]" }

I will add the details on where i’m fetching the data from. I guess this is only usefull for us that live in Norway.
The data source is from a smartphone app, thats called “Min Renovasjon”, published by Norkart AS: https://play.google.com/store/apps/details?id=no.norkart.komtek.renovasjon.client&hl=nb
I got the correct URL by sniffing the traffic that was generated when i chose my address in the app. This is an example of a working curl request:

curl -H "Kommunenr: 0220" -H "RenovasjonAppKey: AE13DEEC-804F-4615-A74E-B4FAC11F0A30" -H "OS: Android" -H "Connection: Keep-Alive" -H "Accept-Encoding: gzip" -H "User-Agent: okhttp/3.2.0" -X GET "https:/komteksky.norkart.no/komtek.renovasjonwebapi/api/tommekalender/?gatenavn=Vak%C3%A5sveien&gatekode=1003&husnr=18B"

Note that this is just an example, and the AppKey seems to be unique to each address. I used the android app “Packet Capture” to get the correct URL for my address: https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture

I’m running a cronjob that fetches the data every day at 1 am, and push it to my mosquitto server.

recycle-cron.sh

#
#!/bin/bash
#
# crontab -e
# 0 1 * * * /home/openhabian/scripts/recycle-cron.sh

mosquitto_pub -h 127.0.0.1 -m "$(curl -H "Kommunenr: 0220" -H "RenovasjonAppKey: AE13DEEC-804F-4615-A74E-B4FAC11F0A30" -H "OS: Android" -H "Connection: Keep-Alive" -H "Accept-Encoding: gzip" -H "User-Agent: okhttp/3.2.0" -X GET "https:/komteksky.norkart.no/komtek.renovasjonwebapi/api/tommekalender/?gatenavn=Vak%C3%A5sveien&gatekode=1003&husnr=18B" | python -m json.tool | tr -d '\n')" -t recycle01/output

I edited my previous post to correct something and hopefully to clarify things better. You can’t get a list with more than one element from the JSONPATH transform anymore. And it will now always return a string. Looks like you got it working though!

Actually, instead of your cron job sending the update through MQTT, you could just run the same thing in a rule. And if you’re using a python script, you could just run the result through json.loads, instead of having to deal with a transform.

I agree with you that it would be better to run my script with a rule instead of the cronjob. That way, it will also be included by the backup script.

At this time, i dont have the time to convert the script into a rule. I wil update this post when i have a working rule that replace the cronjob.

For now, the cronjob is doing its job as a temporary workaround.

Not much to it… should be something like this…

rule "Test"
when
    Time cron "0 1 * * * ?"
then
    logDebug("Rules","Test: Start")
    val String garbageResult = executeCommandLine("/bin/sh@@-c@@/usr/bin/curl -s -H \"Kommunenr: 0220\" -H \"RenovasjonAppKey: AE13DEEC-804F-4615-A74E-B4FAC11F0A30\" -H \"OS: Android\" -H \"Connection: Keep-Alive\" -H \"Accept-Encoding: gzip\" -H \"User-Agent: okhttp/3.2.0\" -X GET \"https:/komteksky.norkart.no/komtek.renovasjonwebapi/api/tommekalender/?gatenavn=Vak%C3%A5sveien&gatekode=1003&husnr=18B\"",10000)
    logDebug("Rules","Test: garbageResult=[{}]",garbageResult)
    Recycle_paper.postUpdate(transform("JSONPATH", "$..[?(@.FraksjonId==2)].Tommedatoer[0])]", garbageResult))
    Recycle_plastic.postUpdate(transform("JSONPATH", "$..[?(@.FraksjonId==7)].Tommedatoer[0])]", garbageResult))
    Recycle_food.postUpdate(transform("JSONPATH", "$..[?(@.FraksjonId==3)].Tommedatoer[0])]", garbageResult))
    Recycle_glass_metal.postUpdate(transform("JSONPATH", "$..[?(@.FraksjonId==4)].Tommedatoer[0])]", garbageResult))
    Recycle_rest.postUpdate(transform("JSONPATH", "$..[?(@.FraksjonId==1)].Tommedatoer[0])]", garbageResult))
    logDebug("Rules","Test: End")
end

You really have control on the rules :slight_smile: Thank you for your contribution! I Will let you know when i have tested it.

I was on a different path, i was looking into using “sendHttpGetRequest”, but maybe you dont get an output from that?

I was also trying to run the http directly from an item, with " http="<". I was trying with the same JSONPATH in the end, but the error seems to say that only REGEX will work.

Anyway, thanks again :blush:

1 Like