Mindergas.nl

From Domoticz
Jump to: navigation, search

Warning, when you have a new meter installed, both scripts stop working as Mindergas.nl doesn't allow to post lower readings then the last one. Mindergas.nl requires you to first give in a new meter!


The Python way

A simple Python script was published end of janauri 2015 to upload to mindergas.nl by Nicky Bulthuis. This works easier than the Bash script further down on this page. This script needs Python, which can be installed by this command:

sudo apt-get install python

Grab the latest version from the blog of the author. For backup purposes the script is also pasted below:

# encoding: utf-8
'''
mindergas -- Upload meterstand van Domoticz naar MinderGas.nl

Instructies:

An P1 Smart Meter krijgt elk uur een update van de Gas meter. Voer
dit script daarom in het eerste uur na middennacht uit. Bijvoorbeeld om
00:14. Hierdoor wordt de laatste meterstand van de vorige dag correct
geregistreerd onder de datum van de vorige dag.

@author:     Nicky Bulthuis

@copyright:  2014 Nicky Bulthuis. All rights reserved.

@license:    BSD

@deffield    updated: Updated
'''

import sys, json, urllib2
from datetime import datetime, timedelta
from argparse import ArgumentParser

def main(argv=None):
    
    parser = ArgumentParser(description='Upload meterstand van Domoticz naar MinderGas.nl')
    parser.add_argument("-a", "--apikey", dest="apikey", help="MinderGas.nl API Key", required=True)
    parser.add_argument("-u", "--url", dest="url", help="URL naar Domoticz, eg: http://localhost:8080", default='http://localhost:8080')
    parser.add_argument("-d", "--device-id", dest="device", help="Device id voor de P1 Gas Smart Meter", type=int, required=True)

    args = parser.parse_args()
    
    device_data = json.load(urllib2.urlopen("%s/json.htm?type=devices&rid=%s" % (args.url, args.device), timeout=5))
    meterstand = device_data['result'][0]['Counter']

    code = upload_meterstand(meterstand, args.apikey)

    if code == 201:
        return 0
    else:
        return code


def upload_meterstand(meterstand, apikey):
    """
    Upload meterstand naar mindergas.nl
    """
    data = {
            'date': (datetime.now().date() - timedelta(days=1)).strftime("%Y-%m-%d"),
            'reading': meterstand
    }
    
    req = urllib2.Request('http://www.mindergas.nl/api/gas_meter_readings')
    req.add_header('Content-Type', 'application/json')
    req.add_header('AUTH-TOKEN', apikey)
    
    return urllib2.urlopen(req, json.dumps(data)).getcode()
    
if __name__ == "__main__":
    sys.exit(main())

Save the script as 'mindergas.py' and schedule the script to be run once a day...

<0..59> 0 * * * python /home/pi/domoticz/scripts/mindergas.py -a <MINDERGASTOKEN> -d <IDXgasmeter>

Change the crontab entry fill in the blanks:

  1. <0..59> Minute of the hour after midnight when you post your usage to mindergas.nl. Make sure you pick a random number between 0 and 59 minutes, so we don't overload mindergas.nl The scripts uploads the gas usage as: today - 1 day. That is the reason you need to run it AFTER 0:00. So the gas usage of Monday is sent to Mindergas on Tuesday, but the script corrects this :)
  2. <MINDERGASTOKEN> Put the API-token you can find on your Mindergas.nl-profile here
  3. <IDXgasmeter> Put the IDX that corresponds to your gasmeter in Domoticz here

If you need more instruction on using crontab, just jump down on this page. Make sure you enter the right information as the solutions assume different hours to post data to mindergas.nl

Remarks:

  • When you use authentication for Domoticz, be sure to have added 127.0.0.* in the settings "Local networks (no username/password):".
  • When the API starts with the minus-character (like -qFG......) it won't work.
  • When the cron-job doesn't seem to work, a workaround is to create a bash-script mindergas.sh, where you put in the line: python /home/pi/domoticz/scripts/mindergas.py -a <MINDERGASTOKEN> -d <IDXgasmeter> . Make it executable by doing chmod a+x mindergas.sh. You add this scriptfile exactly the same way in the crontab-file as instructed for the python-script.

The bash route using JQ

Documented in: November 2014 By: Number3

So I decided that I want my gasmeter reading to be posted to the site http://mindergas.nl

This made me want to find out and understand the inner workings of Domoticz and Scripting. I looked into LUA scripting, but thinking about it I found that I was going to use CURL to post data to mindergas.nl. So after looking for help, asking for in the forum, looking on the IRC I decided to hack in bash again.

So here we go, you do need to install some stuff to get this working on a raspberry pi.

Prepare before you begin (pre-requirements)

The documentation below is for Linux on Raspberry PI. The script has not been tested on other platforms.

Install jq

The easiest way to install jq is using a package manager like apt-get for Debian and Raspbian. If that does not work you can build jq from source.

apt-get

apt-get update
apt-get install jq

Build from source

Before you begin you need to install: Flex, Bison, GCC, Make, Autotools

sudo apt-get install flex -y
sudo apt-get install bison -y
sudo apt-get install gcc -y
sudo apt-get install make -y
sudo apt-get install autotools -y

Then just fetch the latest tarball:

I build mine from the stable 1.5 tarball, like this:

curl -O http://stedolan.github.io/jq/download/source/jq-1.5.tar.gz
tar xfvz jq-1.5.tar.gz
cd jq-1.5
./configure
make
sudo make install



Or use: From: [1]
cd /tmp wget http://ftp.gnu.org/gnu/bison/bison-3.0.3.tar.gz tar -xvzf bison-3.0.3.tar.gz cd bison-3.0.3 sudo port install m4 ./configure --prefix=/usr/local/bison sudo make install sudo ln -s /usr/local/bison/bin/bison /usr/bin/bison
So once you got jq installed, then parsing JSON encoded blobs get easy in bash.

Next the Post Readings Script

Since I got no help at all, I will describe my a little, documenting my journey and explaining what the script does. In hope it helps the next man trying to build stuff for domoticz. Create the script using the following command:

 sudo nano ~/domoticz/scripts/post-mindergas.sh

And then cut and paste this script:

 #!/bin/bash
 
 #Token to authenicate with mindergas.nl
 TOKEN=<get your own from https://mindergas.nl/member/api>
 
 #fetch meterstand (use jq to parse JSON object correctly)
 METERSTAND=`curl -s "http://127.0.0.1:8080/json.htm?type=devices&rid=<ID P1 DEVICE>"  | jq '.result[0].Counter'| tr -d '"'`
  
 #Get OS date, and format it corectly.
 NOW=$(date +"%Y-%m-%d")
 
 #Build JSON by hand ;-)
 JSON='{ "date":"'$NOW'", "reading":"'$METERSTAND'"  }'
 
 #post using curl to API
 curl -v -H "Content-Type:application/json" -H "AUTH-TOKEN:$TOKEN" -d "$JSON"  https://www.mindergas.nl/api/gas_meter_readings

There are two parameters in this script that you need to modify.

  1. API Token from mindergas.nl

    The first one is the API token, get it from: https://mindergas.nl/member/api

  2. Device ID for the P1 device

    This Device ID is the hardware P1 device id, you can find it through the settings menu, under hardware. Just look for the P1 device that reads out the gasmeter values, look for the IDX colum and add the number in the script above.

The post readings script explained (skipping allowed)

So now lets explain this bash script a little better.

First lets tell bash, it's a bashscript.

 #!/bin/bash


Then put the token (cut and paste it from your member site), then put it in the variable TOKEN.

 #Token to authenicate with mindergas.nl
 TOKEN=<get your own from https://mindergas.nl/member/api>


Next you have to fetch the current gasmeter reading. Now we will be running this script once a day, after midnight and before 1am. So first you have to lookup your domotizs device id, goto your domoticz implementation and goto the devices page (http://<your domoticz pi>:8080/#/Devices). In my case it turns out the be device number 8. Next I hunted around how I could fetch the data from domoticz from a bash script, it turns out the easy way is using a JSON API call. So that's what this is, a call to fetch all data that belongs to device 8. If you have never heard of JSON, then just go here: http://en.wikipedia.org/wiki/JSON Anyway, the object that is returned is pretty big, now there another script on this site that uses awk and some tricks to get data out of the object. HOWEVER don't ever do it that way. Simple reason, the script can be broken easily by upgrades to the JSON object (domoticz will simple update the JSON objects and the order of fields might change). So you always NEED to parse data from an JSON opbject. But how to do that, I hunted around for a couple of hours, and finally decided that jq (a special parser is the simplest way, I did look at TickTick and JSON.sh, simply because it bash script only, but o well).

So if you only do on the cli of your pi you can find out what the actual JSON object is. Just do this:

 curl -s "http://127.0.0.1:8080/json.htm?type=devices&rid=8"


It turns out that the object looks like this:

{
  "5MinuteHistoryDays" : 7,
  "ActTime" : 1414866673,
  "AllowWidgetOrdering" : true,
  "DashboardType" : 0,
  "Latitude" : "52.135674",
  "Longitude" : "6.182462",
  "MobileType" : 0,
  "TempScale" : 1.0,
  "TempSign" : "C",
  "WindScale" : 1.0,
  "WindSign" : "m/s",
  "dontcachehtml" : true,
  "result" : [
     {
        "BatteryLevel" : 255,
        "Counter" : "128.865",
        "CounterToday" : "1.865 m3",
        "CustomImage" : 0,
        "Data" : "128865",
        "Favorite" : 1,
        "HardwareID" : 2,
        "HardwareName" : "Slimme-Meter",
        "HaveTimeout" : false,
        "ID" : "1",
        "LastUpdate" : "2014-11-01 19:27:32",
        "Name" : "Gas verbruik",
        "Notifications" : "false",
        "PlanID" : "0",
        "Protected" : false,
        "SignalLevel" : 12,
        "SubType" : "Gas",
        "SwitchTypeVal" : 1,
        "Timers" : "false",
        "Type" : "P1 Smart Meter",
        "TypeImg" : "counter",
        "Unit" : 2,
        "Used" : 1,
        "XOffset" : "0",
        "YOffset" : "0",
        "idx" : "8"
     }
  ],
  "status" : "OK",
  "title" : "Devices"
}

So looking around you will see that in the result section of the object you will find a metervalue, twice actually. Once in liters gas once in m3 gas. The API from mindergas.nl can handle both, you could upload using m3 or liters. I decided early on to use the m3 interface. Don't ask why.

So now how to parse the JSON into a number... Well, thats why I used jq. The addressing of the object works simple, just to this:

 
 #fetch meterstand (use jq to parse JSON object correctly)
 METERSTAND=`curl -s "http://127.0.0.1:8080/json.htm?type=devices&rid=8"  | jq '.result[0].Counter'| tr -d '"'`

The result is that jq parses into the JSON, result[0] make sure you get from the first result array, then .Counter will give you the data of the current gasmeter value. The command tr -d '"' simply removes all quotes from the string that jq puts out... putting back-single-quoute and put it in the METERSTAND value.

Next up, fetch current date, in correct format for mindergas.nl

 #Get OS date, and format it corectly.
 NOW=$(date +"%Y-%m-%d")

Now I decided to go simple, and build the JSON object by hand. Probably could have looked for a command or library to do it for me. But hell, this works.

 #Build JSON by hand ;-)
 JSON='{ "date":"'$NOW'", "reading":"'$METERSTAND'"  }'

Finally we are going to post it to mindergas.nl API, using the authenication token over a secure connection.

 #post using curl to API
 curl -v -H "Content-Type:application/json" -H "AUTH-TOKEN:$TOKEN" -d "$JSON"  https://www.mindergas.nl/api/gas_meter_readings

Tada.... it's done.

All you need to do now is to schedule it once a day after midnight (please don't post it right at midnight, lets prevent overloading the server. So pick your favorite number between 1..60 and post it using cron and this script.

Have fun with this, actually I don't understand why Domoticz did not have this already in it's core. This API and JSON bit is simple enough. In C code it must be a breeze ;-)

Make script executable

To make the script executable we change the attributes with chmod

  sudo chmod +x /home/pi/domoticz/scripts/post-mindergas.sh

You test the script by the executing the script one time:

  sudo /home/pi/domoticz/scripts/post-mindergas.sh

Test the script

Before you put the script in the crontab to post it you meter readings every day, you should go and test it manually. So here we go:

  1. Goto mindergas.nl and login
  2. Then goto the "meterstanden" page (https://mindergas.nl/member/gas_meter_readings)
  3. If there is a reading for today already, delete it by pressing the red X
  4. Execute the script by giving the command: ./post-mindergas.sh
  5. Refresh the meterreadings page (https://mindergas.nl/member/gas_meter_readings)
  6. A new reading should appear at the top for today. If not, then go into debug mode.

Debug tips:

  1. Check the Device ID
  2. Check the API token

If it worked, then continue to add the script to the crontab for daily execution.

Run the script once a day using crontab

Execute the crontab command to add a schedule to the crontab, run this:

crontab -e

Now add this line to the crontab (at the end):

47 23 * * * sudo ~/domoticz/scripts/post-mindergas.sh

This means that the script is run when time is 47 minutes, 23 hour, of any day of the month, any month of the year, any day of the week, which equals daily at 23:47.

Change the number in the time you want by changing the cron parameters

 *     *     *   *    *        command to be executed
 -     -     -   -    -
 |     |     |   |    |
 |     |     |   |    +----- day of week (0 - 6) (Sunday =0)
 |     |     |   +------- month (1 - 12)
 |     |     +--------- day of        month (1 - 31)
 |     +----------- hour (0 - 23)
 +------------- min (0 - 59)

And save the crontab

Please PICK A RANDOM number between 1..60 for the minutes... so not just 47.

Your gasmeter reading will be posted to mindergas.nl once a day! At the end of the day, so you get it posted just before midnight. Don't post it to close to midnight, the randomness is needed because you do not want to overload the server from www.mindergas.nl


Node Red Flows

Flows