Smart Meter UK - Build an app / device handler for api?

Thanks will have a fresh try tomorrow

Hi - looks like the convo sent on since my post - so this might not help but just in case I’ve put a copy of my current code here. This is direct to their API and doesnt use smart things but glitch app gave me the pointers to get this up and working.

Its basic but has been stable for a couple of weeks now. I have the Trio II as well with the wifi module.

1 Like

Great. That’s a lot easier for me to get into openHAB than SmartThings

To get it to work I had to change the threading from
super(MyThread, self).init()
to
threading.Thread.init(self)
I’m now working on getting the periodic data

Here is my version with the periodic data for openHAB. It needs a string item MeterString and the meter and cost items are Numbers - I don’t have gas but the principle is the same for the gas data

-- coding: utf-8 --

“”"
Script to integrate GeoTogether meter readings into the Openhab
Still needs some work to handle errors
“”"
import requests, json
import threading
import time
from datetime import datetime
from openhab import OpenHAB
import os

BASE_URL= ‘won’t allow me to put the api url in’
LOGIN_URL=‘usersservice/v2/login’
DEVICEDETAILS_URL=‘api/userapi/v2/user/detail-systems?systemDetails=true’
LIVEDATA_URL = ‘api/userapi/system/smets2-live-data/’
PERIODICDATA_URL = ‘api/userapi/system/smets2-periodic-data/’
USERNAME= ‘emailaddress’
PASSWORD = ‘password’
LOG_DIRECTORY = ‘log’

openhab_URL = ‘http://x.x.x.x:8080/rest/
openhab = OpenHAB(openhab_URL)
HouseElectricityPower = openhab.get_item(‘HouseElectricityPower’)
HouseConsumptionPower = openhab.get_item(‘HouseConsumptionPower’)
MeterString = openhab.get_item(‘MeterString’)

class GeoHome(threading.Thread):

# Thread class with a _stop() method. 
# The thread itself has to check
# regularly for the stopped() condition.

def __init__(self, varUserName, varPassword):
    
    log = "Start Initialising: " + str(datetime.now())
    threading.Thread.__init__(self)
    self._stop = threading.Event()
    self.varUserName = varUserName
    self.varPassword = varPassword
    self.headers = ""
    self.deviceId = ""
    self.authorise()
    self.getDevice()
    log = log + os.linesep + "End Initialising: " + str(datetime.now())
    with open(LOG_DIRECTORY+"GeoHomeLog"+time.strftime("%Y%m%d")+".json",mode='a+', encoding='utf-8') as f:
        f.write(log + os.linesep)   

def authorise(self):
   data = { 'identity' : self.varUserName , 'password' : self.varPassword }
   r=requests.post(BASE_URL+LOGIN_URL, data=json.dumps(data), verify=False)
   authToken = json.loads(r.text)['accessToken']
   self.headers = {"Authorization": "Bearer " + authToken}
   return

def getDevice(self):
    r=requests.get(BASE_URL+DEVICEDETAILS_URL, headers=self.headers)
    self.deviceId = json.loads(r.text)['systemRoles'][0]['systemId']
    print( 'Device Id:' + self.deviceId)
    return

# function using _stop function
def stop(self):
    self._stop.set()

def stopped(self):
    return self._stop.isSet()

def run(self):
    while True:
        if self.stopped():
            return
        
        log ="Start Api Call: " + str(datetime.now())
        
        r=requests.get(BASE_URL+LIVEDATA_URL+ self.deviceId, headers=self.headers)
        if r.status_code != 200:
            #Not sucesful. Assume Authentication Error
            log = log + os.linesep + "Request Status Error:" + str(r.status_code)
            #Reauthenticate. Need to add more error trapping here in case api goes down.
            self.authorise()
            self.getDevice()
        else:    
            log = log + os.linesep + json.dumps(r.text)
            power_dict =json.loads(r.text)['power']
            #Try to find the electricity usage
            try:
                Electricity_usage=([x for x in power_dict if x['type'] == 'ELECTRICITY'][0]['watts'])
            except:
                # Cant find Electricity in list. Add to log file but do nothing else
                log = log + os.linesep + "No Electricity reading found"
            else:
                #Code executed ok so update the usage
                HouseElectricityPower.state= Electricity_usage
                log = log + os.linesep + "Electricity_usage:"+str(Electricity_usage)

        r=requests.get(BASE_URL+PERIODICDATA_URL+ self.deviceId, headers=self.headers)
        if r.status_code != 200:
            #Not successful. Assume Authentication Error
            log = log + os.linesep + "Request Status Error:" + str(r.status_code)
            #Reauthenticate. Need to add more error trapping here in case api goes down.
            self.authorise()
            self.getDevice()
        else:    
            log = log + os.linesep + json.dumps(r.text)
            power_dict =json.loads(r.text)['totalConsumptionList']
            #Try to find the electricity usage
            MeterString.state = r.text
                

            time.sleep(30)
        
        with open(LOG_DIRECTORY+"GeoHomeLog"+time.strftime("%Y%m%d")+".json",mode='a+', encoding='utf-8') as f:
            f.write(log + os.linesep)    

t1 = GeoHome(USERNAME,PASSWORD)
t1.start()
The openHAB rule is
var String Extract
var String MeterDownload

rule “Meter Update”
when
Item MeterString received update

then

MeterDownload = MeterString.state
Extract = transform("JSONPATH","$.totalConsumptionList[0].totalConsumption", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(MeterReading, Extract)
Extract = transform("JSONPATH","$.billToDateList[0].billToDate", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(CostReading, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[0].costAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(CostDay, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[0].energyAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(MeterDay, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[1].costAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(CostWeek, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[1].energyAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(MeterWeek, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[2].costAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(CostMonth, Extract)
Extract = transform("JSONPATH","$.currentCostsElec[2].energyAmount", MeterDownload)
logInfo("test", "simple " + Extract)
postUpdate(MeterMonth, Extract)

end
Hope it’s useful

1 Like

Hi all! Thanks mostly to this thread, I have just written a bridge to read Geotogether API and push data into domoticz via MQTT. Your welcome to re-use if it’s helpful.

My choice of language is PHP - yeah I know :slight_smile:

code can be found here:

cheers!
Stuart

2 Likes

Personally I’m a big fan of PHP! Especially as I got your code running and pulling data.
Thanks, Stuart, for sharing this.

Andy

You’re welcome!

Hi Stuart

The livedata seems to drop every 1-2 hours and MQTT reports failed status. It does not return to giving livedata updates. Have you come across this and is there a solution?

Many thanks,

Andy

Oops, looks like I didn’t update my repo. Yes it seems the server caches the token expiry against the connection, so I close the curl socket now after any failure. That seems to fix it.

Pull the repo again or view the changes as required. I had to re-type them on my mobile as I am away from home right now, so I have not been able to check the syntax. Hope it’s ok!

Stu

Hi Stu

Thanks for updating the repo. I have added the extra code lines but this has not resolved the problem. I do have the polling interval set to 120 rather than the 20 secs you have. Could this be having an impact?

Thanks again,

Andy

I have not tried with different polling intervals; seems unlikely to be the cause but that’s just an opinion :slightly_smiling_face:

What is the error you are seeing? I had a 403 forbidden which should cause the code to log in again and get a new token. Perhaps you can turn on debug and post the relevant bit of the log?

Stu

Hello again! I have just got a firmware update to A5.9.0/B2.2/T1.5 courtesy of a bug tracking report to the Geo support desk :slight_smile: which was to fix the ‘white screen’ that was appearing after a few hours uptime. The nice folks at Geo did this remotely, just based on my email ID.

The IHD now shows the exported power. Their API now reports export power as a negative value, which is great for my solar installation…

I have updated my bridge code to support two domoticz devices; one import and one export. Check the repo link above for details.

Stu

1 Like

Is that for the trio ii? I asked geo about newer firmware and they said export data isn’t available on any Firmware and they just closed my support ticket

Does anyone have a link to the API docuemtation page for the Geotogether API?

I am trying to replicate what @owainlloyd has done for OpenHab but using http request nodes in NodeRed.

I was never able to find any, my efforts above were just emulating what the app does when it calls the API

I was reading this thread again and again during the last two/three weeks to be able to find a way to extract the data from my IHD to HomeAssistant but the more I read the more I got disappointed with the services from BritishGas re providing “MY” own data.
The way that I could manage to solve the problem was/is to use n3rgy.com. Head to the site, go to “I am a consumer” section, authorise the site and voila! using a VERY simple API all your data is available to you. The only caveat is it does NOT provide live data usage. For that, perhaps you can use shelly or other devices that can collect data locally.
I put together a simple flow in NodeRed that reads the data every day using the API and pumps it into Influxdb. From there the possibilities are endless. You can do whatever you want to do with your data and create as much automation as you want…
Hope this helps someone with the same challenge with BritishGas and smart meters!

1 Like

I am also using n3rgy.com but would like to intigrate it into my NodeRed, would you be prepared to share your flow?

n3rgy.com solution sounds interesting. I did try to sign up but for some reason when I tried to register my IHD MAC address it did not seem to recognise it. Anyone else have this problem? There doesnt seem to be a contact us page on the website either.

@Aryankids I would also be interested in your node red flow if you are able to share

@F1ux sorry for late reply, yes I get export data on my Trio II now, and it works via their API also.

HTH Stu