Fetch Tesla Power Wall State of charge using EmonHub

@bwduncan @borpin

I added verify=False at the end of the line respecting commas, brackets & spaces.

It is now all working :slight_smile: … many thx to you both

I have successfully set up Log to Feed and can see a graph.
The data is also successfully being sent to watchman and I’ve set up Log to Feed & a graph there too.

NEXT STEPS …
The key things to know about a battery are …

Level of Charge - and we now have that albeit as a percentage
Discharge/Charge power at points in time … this is the next challenge

Do you have any thoughts on this?

Glad it’s working. I’ll make a pull request to make the change upstream, however

There is more that the powerwall can tell us beyond state of charge. I suspect the best way to get all this data is to use the powerwall python module someone else has already written. Once we have an easy way to get the power at the various interfaces we can do wonderful things!

I’ll see if I can hammer something together tomorrow…

1 Like

@bwduncan

Thx - that would be great.

This guy seems pretty with it also …

2 Likes

@borpin @bwduncan

I can no longer re-start the emonhub.service.
This is what status reports …

@emonpi-node-15:~ $ sudo systemctl status emonhub.service
● emonhub.service - emonHub service description
   Loaded: loaded (/opt/openenergymonitor/emonhub/service/emonhub.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-07-06 17:28:08 BST; 1min 0s ago
  Process: 14417 ExecStartPre=/bin/mkdir -p /var/log/emonhub/ (code=exited, status=0/SUCCESS)
  Process: 14418 ExecStartPre=/bin/chgrp -R emonhub /var/log/emonhub/ (code=exited, status=0/SUCCESS)
  Process: 14419 ExecStartPre=/bin/chmod 775 /var/log/emonhub/ (code=exited, status=0/SUCCESS)
 Main PID: 14420 (python3)
    Tasks: 3 (limit: 2319)
   Memory: 11.6M
   CGroup: /system.slice/emonhub.service
           └─14420 python3 /usr/local/bin/emonhub/emonhub.py --config-file=/etc/emonhub/emonhub.conf --logfile=/var/log/emonhub/emonhub.log

Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]: UnboundLocalError: local variable 'reply' referenced before assignment
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]: During handling of the above exception, another exception occurred:
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]: Traceback (most recent call last):
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]:   File "/usr/lib/python3.7/logging/handlers.py", line 68, in emit
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]:     if self.shouldRollover(record):
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]:   File "/usr/lib/python3.7/logging/handlers.py", line 185, in shouldRollover
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]:     self.stream.seek(0, 2)  #due to non-posix-compliant Windows feature
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]: OSError: [Errno 28] No space left on device
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]: Call stack:
Jul 06 17:28:49 emonpi-node-15 emonhub.py[14420]:   File "/usr/lib/python3.7/threading.py", line 885, in _bootstrap
pi@emonpi-node-15:~ $

I previously had the problem, rebooted but the problem remains

Any suggestions - most welcome

@borpin @bwduncan

Does the following help?

pi@emonpi-node-15:~ $ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      4.0G  2.2G  1.7G  58% /
devtmpfs       devtmpfs  484M     0  484M   0% /dev
tmpfs          tmpfs     488M     0  488M   0% /dev/shm
tmpfs          tmpfs     488M   56M  433M  12% /run
tmpfs          tmpfs     5.0M  4.0K  5.0M   1% /run/lock
tmpfs          tmpfs     488M     0  488M   0% /sys/fs/cgroup
tmpfs          tmpfs     1.0M     0  1.0M   0% /var/tmp
tmpfs          tmpfs     1.0M  4.0K 1020K   1% /var/lib/php/sessions
tmpfs          tmpfs      30M     0   30M   0% /tmp
/dev/mmcblk0p1 vfat      253M   52M  201M  21% /boot
/dev/mmcblk0p3 ext2       25G  3.5M   24G   1% /var/opt/emoncms
log2ram        tmpfs      50M   50M     0 100% /var/log
tmpfs          tmpfs      98M     0   98M   0% /run/user/1000
pi@emonpi-node-15:~ $ cd /var/log
pi@emonpi-node-15:/var/log $ ls -l
total 38268
-rw-r--r-- 1 root      root           0 Jul  2 01:17 alternatives.log
drwxr-x--- 2 root      adm          100 Jun 15 00:00 apache2
drwxr-xr-x 2 root      root         100 Jul  2 01:17 apt
-rw-r----- 1 root      adm       161533 Jul  6 17:51 auth.log
-rw-r--r-- 1 root      root           0 Sep 26  2019 bootstrap.log
-rw-rw---- 1 root      utmp           0 Jul  6 15:00 btmp
-rw-r----- 1 root      adm     28778496 Jul  6 17:52 daemon.log
-rw-r----- 1 root      adm            0 Jul  6 15:18 debug
-rw-r--r-- 1 root      root           0 Jul  2 01:17 dpkg.log
drwxr-xr-x 2 pi        root         180 Jul  5 00:17 emoncms
drwxrwxr-x 2 root      emonhub       80 Jul  5 23:03 emonhub
drwxr-xr-x 2 pi        root          60 Oct 17  2019 emonpilcd
-rw-r--r-- 1 root      root       24000 Oct 17  2019 faillog
-rw-r----- 1 root      adm            0 Jul  6 15:18 kern.log
-rw-rw-r-- 1 root      utmp      292292 Jul  6 17:51 lastlog
-rw-r--r-- 1 root      root        4096 Jul  6 16:17 log2ram.log
drwxr-xr-x 2 root      adm           80 Jul  6 17:17 logrotate
-rw-r----- 1 root      adm        81920 Jul  6 17:52 messages
drwxr-xr-x 2 mosquitto root          60 Oct 17  2019 mosquitto
drwxr-s--- 2 mysql     adm           60 Jul  6 15:18 mysql
drwx------ 2 root      root          40 Sep 26  2019 private
drwxr-s--- 2 redis     adm           60 Jul  6 15:18 redis
drwxr-xr-x 2 root      root          60 Jul  6 15:18 remoteit
lrwxrwxrwx 1 root      root          12 Oct 17  2019 rotated_logs -> /var/log.ol                            d
-rw-r----- 1 root      adm      9777152 Jul  6 17:52 syslog
-rw-r----- 1 root      adm         1030 Jul  6 15:18 user.log
-rw-r--r-- 1 root      root         533 Jul  6 15:18 wifiAP.log
-rw-rw-r-- 1 root      utmp       52992 Jul  6 17:51 wtmp
pi@emonpi-node-15:/var/log $

There’s an awful lot of daemon.log - how can I reduce its size?

/var/log full (search on that or on truncate for the solution).

Are you running an up to date version of emoncms?

@borpin

I’m running the latest 10.2.3
I had the file ownership issue
You are correct in yr suggestion …

I think this will fix that issue

sudo chown root:pi /opt/openenergymonitor/EmonScripts/defaults/etc/logrotate.d/*

I did indeed fix it - thx

My other 10.2.3’s seem to be getting very full too.

@TrystanLea - note issue not fully solved…

Thanks @borpin @johnbanks, looks like our pervious fix of just changing the file ownership did not work. I’ve switched to calling the command you copied above @borpin, see:

This is in stable tag 1.0.8-beta & release

1 Like

@TrystanLea @borpin

To be absolutely clear - this is what I did … per @borpin’s suggestions …

sudo chown root:pi /opt/openenergymonitor/EmonScripts/defaults/etc/logrotate.d/*

Then …

sudo /usr/sbin/logrotate -v /etc/logrotate.conf

After which I could see a reasonable amount of available space in /var/log

Sorry for any confusion

@TrystanLea can you sort out emonhub too please? A whole load of PRs (not just for the Tesla) that are now starting to get really confused.

Thanks @bwduncan Shall I make this change to the emonhub interfacer?

Yes please. It will get it working until there is time to get the rest of the API being collected.

1 Like

done, cheers skip TLS verification for tesla power wall self signed cert · openenergymonitor/emonhub@1da8085 · GitHub

@bwduncan @borpin @TrystanLea

I have made some small progress in obtaining PowerWall data.

If you substitute the following url in the EmonHubTeslaPowerWallInterfacer in emonhub.conf

url = http:// IP of PowerWall /api/meters/aggregates

… then a whole bunch of data becomes available.

The data is only available as part of an error log but at least it’s data in the Emon eco system.

To get the following log data, I commented out lines 54, 55 & 56 in EmonHubTeslaPowerWallInterfacer.py that Check if battery percentage key is in data object … which it isn’t in this url call.

Here’s the relevant bit of the log – pls ignore refs to watchman.

2020-07-08 18:43:35,756 INFO     MainThread EmonHub emonHub emon-pi variant v3-beta
2020-07-08 18:43:35,756 INFO     MainThread Opening hub...
2020-07-08 18:43:35,757 INFO     MainThread Logging level set to DEBUG
2020-07-08 18:43:35,757 INFO     MainThread Creating EmonHubMqttInterfacer 'MQTT' 
2020-07-08 18:43:35,759 DEBUG    MainThread Setting MQTT pubchannels: ['ToRFM12']
2020-07-08 18:43:35,760 DEBUG    MainThread Setting MQTT subchannels: ['ToEmonCMS']
2020-07-08 18:43:35,760 INFO     MainThread Setting MQTT node_format_enable: 0
2020-07-08 18:43:35,760 INFO     MainThread Setting MQTT nodevar_format_enable: 1
2020-07-08 18:43:35,761 INFO     MainThread Setting MQTT nodevar_format_basetopic: emon/
2020-07-08 18:43:35,762 INFO     MainThread Creating EmonHubTeslaPowerWallInterfacer 'PowerWall' 
2020-07-08 18:43:35,762 INFO     MainThread Setting PowerWall name: powerwall
2020-07-08 18:43:35,763 INFO     MainThread Setting PowerWall url: False
2020-07-08 18:43:35,763 INFO     MainThread Setting PowerWall readinterval: 10
2020-07-08 18:43:35,763 DEBUG    MainThread Setting PowerWall pubchannels: ['ToEmonCMS']
2020-07-08 18:43:35,764 INFO     MainThread Creating EmonHubEmoncmsHTTPInterfacer 'To_watchman' 
2020-07-08 18:43:35,765 DEBUG    MainThread Setting To_watchman pubchannels: ['ToRFM12']
2020-07-08 18:43:35,766 DEBUG    MainThread Setting To_watchman subchannels: ['ToEmonCMS']
2020-07-08 18:43:35,766 INFO     MainThread Setting To_watchman apikey: set
2020-07-08 18:43:35,766 INFO     MainThread Setting To_watchman url: http://192.168.1.10/emoncms
2020-07-08 18:43:35,766 INFO     MainThread Setting To_watchman senddata: 1
2020-07-08 18:43:35,767 INFO     MainThread Setting To_watchman sendstatus: 0
2020-07-08 19:26:31,478 INFO     MainThread Setting PowerWall url: http://192.168.1.100/api/meters/aggregates
2020-07-08 19:26:31,479 INFO     MainThread Setting PowerWall readinterval: 10
2020-07-08 19:26:38,126 INFO     MainThread EmonHub emonHub emon-pi variant v3-beta
2020-07-08 19:26:38,127 INFO     MainThread Opening hub...
2020-07-08 19:26:38,127 INFO     MainThread Logging level set to DEBUG
2020-07-08 19:26:38,128 INFO     MainThread Creating EmonHubMqttInterfacer 'MQTT' 
2020-07-08 19:26:38,130 DEBUG    MainThread Setting MQTT pubchannels: ['ToRFM12']
2020-07-08 19:26:38,131 DEBUG    MainThread Setting MQTT subchannels: ['ToEmonCMS']
2020-07-08 19:26:38,131 INFO     MainThread Setting MQTT node_format_enable: 0
2020-07-08 19:26:38,131 INFO     MainThread Setting MQTT nodevar_format_enable: 1
2020-07-08 19:26:38,131 INFO     MainThread Setting MQTT nodevar_format_basetopic: emon/
2020-07-08 19:26:38,132 INFO     MainThread Creating EmonHubTeslaPowerWallInterfacer 'PowerWall' 
2020-07-08 19:26:38,133 INFO     MainThread Setting PowerWall name: powerwall
2020-07-08 19:26:38,133 INFO     MainThread Setting PowerWall url: http://192.168.1.100/api/meters/aggregates
2020-07-08 19:26:38,134 INFO     MainThread Setting PowerWall readinterval: 10
2020-07-08 19:26:38,134 DEBUG    MainThread Setting PowerWall pubchannels: ['ToEmonCMS']
2020-07-08 19:26:38,136 INFO     MainThread Creating EmonHubEmoncmsHTTPInterfacer 'To_watchman' 
2020-07-08 19:26:38,137 DEBUG    MainThread Setting To_watchman pubchannels: ['ToRFM12']
2020-07-08 19:26:38,138 DEBUG    MainThread Setting To_watchman subchannels: ['ToEmonCMS']
2020-07-08 19:26:38,138 INFO     MainThread Setting To_watchman apikey: set
2020-07-08 19:26:38,139 INFO     MainThread Setting To_watchman url: http://192.168.1.10/emoncms
2020-07-08 19:26:38,139 INFO     MainThread Setting To_watchman senddata: 1
2020-07-08 19:26:38,139 INFO     MainThread Setting To_watchman sendstatus: 0
2020-07-08 19:26:38,278 DEBUG    PowerWall  PowerWall Request response: {"site":{"last_communication_time":"2020-07-08T19:26:38.190213726+01:00","instant_power":260.3262634277344,"instant_reactive_power":-142.2243995666504,"instant_apparent_power":296.64379862444514,"frequency":50.049781799316406,"energy_exported":151417.04500000057,"energy_imported":241906.8625000005,"instant_average_voltage":193.68669086797593,"instant_total_current":0,"i_a_current":0,"i_b_current":0,"i_c_current":0,"timeout":1500000000},"battery":{"last_communication_time":"2020-07-08T19:26:38.188451066+01:00","instant_power":-110,"instant_reactive_power":30,"instant_apparent_power":114.0175425099138,"frequency":50.067,"energy_exported":37100,"energy_imported":41530,"instant_average_voltage":246.43333333333337,"instant_total_current":0.30000000000000004,"i_a_current":0,"i_b_current":0,"i_c_current":0,"timeout":1500000000},"load":{"last_communication_time":"2020-07-08T19:26:38.188451066+01:00","instant_power":361.4218817850619,"instant_reactive_power":-119.27322196880134,"instant_apparent_power":380.5941120299606,"frequency":50.049781799316406,"energy_exported":0,"energy_imported":86059.81749999995,"instant_average_voltage":193.68669086797593,"instant_total_current":1.8660129932800624,"i_a_current":0,"i_b_current":0,"i_c_current":0,"timeout":1500000000},"solar":{"last_communication_time":"2020-07-08T19:26:38.190978437+01:00","instant_power":0,"instant_reactive_power":0,"instant_apparent_power":0,"frequency":0,"energy_exported":0,"energy_imported":0,"instant_average_voltage":0,"instant_total_current":0,"i_a_current":0,"i_b_current":0,"i_c_current":0,"timeout":1500000000}}
2020-07-08 19:26:38,281 WARNING  PowerWall  Exception caught in PowerWall thread. Traceback (most recent call last):
  File "/opt/openenergymonitor/emonhub/src/emonhub_interfacer.py", line 32, in wrapper
    return f(*args)
  File "/opt/openenergymonitor/emonhub/src/emonhub_interfacer.py", line 99, in run
    rxc = self.read()
  File "/opt/openenergymonitor/emonhub/src/interfacers/EmonHubTeslaPowerWallInterfacer.py", line 62, in read
    c.realdata = [data['percentage']]
KeyError: 'percentage'

Errors are reported in lines 32 & 99 in emonhub_interfacer.py and line 62 in EmonHubTeslaPowerWallInterfacer.py.

It’s way beyond my skill level to fix those errors so any help would be most welcome.

For me and most other PowerWall users I suspect, the key info is in the “battery” section namely – instant_power, energy_exported & energy_imported.

The percentage level of charge is also important. That requires a call to url = http:// IP of PowerWall /api/system_status/soe … per the current working EmonHubTeslaPowerWallInterfacer.

This begs the question – is it possible to have two url calls within one Interfacer?

TIA for any help/suggestions

That’s a decent chunk of instantaneous data! I’m surprised that you say you are really only interested in the battery power (presumably the energy imported/exported can be integrated by emoncms or something later). I guess you have other things monitoring your grid and solar flows?

Yes, in fact we don’t even need to specify the entire URL in the config. We know the endpoints which have the data we’re interested in. We just need the hostname (or the IP address) to be specified in the conf file.

To get the data you want out of that data blob, do something like this: (set the url to “https://192.168.1.100/”)

aggregates = requests.get(self._settings['url'] + '/api/meters/aggregates', timeout=10, verify=False).json()
c = Cargo.new_cargo(names=['battery_instant_power'], realdata=[aggregates['battery']['instant_power'])

If that and the battery percentage are all you need then it can be done quite simply. Let me know if the above works for you.

@bwduncan

Hoping I properly understood yr suggestion, I put this in emonhub.conf …

[[PowerWall]]
    Type = EmonHubTeslaPowerWallInterfacer
    [[[init_settings]]]
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        name = powerwall
        url = http://192.168.1.100/aggregates = requests.get(self._settings['url'] + '/api/meters/aggregates', timeout=10, verify=False).json()  
c = Cargo.new_cargo(names=['battery_instant_power'], realdata=[aggregates['battery']['instant_power'])
        ###url = http://192.168.1.100/api/system_status/soe
        readinterval = 10

… and got the following …

2020-07-09 02:05:16,503 WARNING  MainThread PowerWall thread is dead.
2020-07-09 02:05:16,504 WARNING  MainThread Attempting to restart thread PowerWall (thread has been restarted 106 times...
2020-07-09 02:05:16,505 INFO     MainThread Creating EmonHubTeslaPowerWallInterfacer 'PowerWall' 
2020-07-09 02:05:16,507 INFO     MainThread Setting PowerWall name: powerwall
2020-07-09 02:05:16,507 INFO     MainThread Setting PowerWall url: ["http://192.168.1.100/aggregates = requests.get(self._settings['url']   '/api/meters/aggregates'", 'timeout=10', 'verify=False).json()']
2020-07-09 02:05:16,508 INFO     MainThread Setting PowerWall readinterval: 10
2020-07-09 02:05:16,509 DEBUG    MainThread Setting PowerWall pubchannels: ['ToEmonCMS']
2020-07-09 02:05:16,514 WARNING  PowerWall  PowerWall couldn't send to server: No connection adapters were found for '["http://192.168.1.100/aggregates = requests.get(self._settings['url']   '/api/meters/aggregates'", 'timeout=10', 'verify=False).json()']'
2020-07-09 02:05:16,515 WARNING  PowerWall  Exception caught in PowerWall thread. Traceback (most recent call last):
  File "/opt/openenergymonitor/emonhub/src/emonhub_interfacer.py", line 32, in wrapper
    return f(*args)
  File "/opt/openenergymonitor/emonhub/src/emonhub_interfacer.py", line 99, in run
    rxc = self.read()
  File "/opt/openenergymonitor/emonhub/src/interfacers/EmonHubTeslaPowerWallInterfacer.py", line 43, in read
    jsonstr = reply.text.rstrip()
UnboundLocalError: local variable 'reply' referenced before assignment

Clearly I’ve misunderstood?

@johnbanks, the question is what do you want to do with the information (rhetorical)?

I’ve said before that emoncms doesn’t really want to go down the road of Home Automation; there are other, better systems to do that.

In your case, there is a ready made solution in form of the Home Assistant integration Tesla Powerwall - Home Assistant. You can then send the data to emoncms if you want to record it (back to the first question). If you want to control stuff, HA is better suited to that.

Unfortunately yes, Bruce was saying to reduce the 'url =` entry in the conf to just the IP address and also edit the source code, ie edit the Tesla Interfacer code in emonhub to try if it achieves what you want.

@bwduncan - in previous interfacers (hive, tplink, wunderground, darksky and some modbus devices etc) I have tackled this by having a list of “emonhub supported metrics” for the interfacer at hand that can be defined in a conf setting. E.G. if only the battery instant power was wanted, payload = battery_instant_power or if more metrics wanted payload = battery_instant_power, metricB, metricC etc. This approach gives access to all available metrics (if supported in emonhub) but doesn’t swamp the user with data, it also allows for rearranging the payload eg payload = metricC, battery_instant_power, metricB to allow more elaborate processing to be used in emoncms, which is input order dependent. It requires a bit more work by the coder but makes a much more “one size fits all” interfacer. There can be (and in my case always will be), of course a default payload hard coded for when the payload is not defined, that could be the most useful “standard” metrics for the average user and also allow for a suitable emoncms device module template to follow.

1 Like

@pb66 - Many thx for yr added insight.

In the Interfacer stanza in emonhub.conf, I’ve now just got the URL and have tried with/without quotes, with/without trailing slash and plain http:

I’ve also modified EmonHubTeslaPowerWallInterfacer.py as follows …

import time, json, Cargo, requests
from emonhub_interfacer import EmonHubInterfacer

"""class EmonHubTeslaPowerWallInterfacer

Fetch Tesla Power Wall state of charge

"""

class EmonHubTeslaPowerWallInterfacer(EmonHubInterfacer):

    def __init__(self, name):
        super().__init__(name)

        self._settings.update(self._defaults)

        # Interfacer specific settings
        self._template_settings = {'name': 'powerwall',
                                   'url': False,
                                   'readinterval': 10.0}

        # FIXME is there a good reason to reduce this from the default of 1000? If so, document it here.
        # set an absolute upper limit for number of items to process per post
        self._item_limit = 250

        # Fetch first reading at one interval lengths time
        self._last_time = 0

    def read(self):
        # Request Power Wall data at user specified interval
        if time.time() - self._last_time >= self._settings['readinterval']:
            self._last_time = time.time()

            # If URL is set, fetch the SOC
            if self._settings['url']:
                # HTTP Request
                try:
                    ##reply = requests.get(self._settings['url'], timeout=int(self._settings['readinterval']), verify=False)
					aggregates = requests.get(self._settings['url'] + '/api/meters/aggregates', timeout=10, verify=False).json()
                    reply.raise_for_status()  # Raise an exception if status code isn't 200
                except requests.exceptions.RequestException as ex:
                    self._log.warning("%s couldn't send to server: %s", self.name, ex)

                jsonstr = reply.text.rstrip()
                self._log.debug("%s Request response: %s", self.name, jsonstr)

                # Decode JSON
                try:
                    data = json.loads(jsonstr)
                except Exception:  # FIXME Too general exception
                    self._log.warning("%s Invalid JSON", self.name)
                    return

                # Check if battery percentage key is in data object
                ##if not 'percentage' in data:
                    ##self._log.warning("%s Percentage key not found", self.name)
                    ##return

                # Create cargo object
                ##c = Cargo.new_cargo()
                ##c.nodeid = self._settings['name']
                ##c.names = ["soc"]
                ##c.realdata = [data['percentage']]
				c = Cargo.new_cargo(names=['battery_instant_power'], realdata=[aggregates['battery']['instant_power'])
                return c

        # return empty if not time
        return

    def set(self, **kwargs):
        for key, setting in self._template_settings.items():
            # Decide which setting value to use
            if key in kwargs.keys():
                setting = kwargs[key]
            else:
                setting = self._template_settings[key]
            if key in self._settings and self._settings[key] == setting:
                continue
            elif key == 'readinterval':
                self._log.info("Setting %s %s: %s", self.name, key, setting)
                self._settings[key] = float(setting)
                continue
            elif key == 'name':
                self._log.info("Setting %s %s: %s", self.name, key, setting)
                self._settings[key] = setting
                continue
            elif key == 'url':
                self._log.info("Setting %s %s: %s", self.name, key, setting)
                self._settings[key] = setting
                continue
            else:
                self._log.warning("'%s' is not valid for %s: %s", setting, self.name, key)

        # include kwargs from parent
        super().set(**kwargs)

The double hashes are my commenting out.
And I’ve added the 2 lines suggested by @bwduncan at lines 39 and 64.
I’m a total beginner at json - and those lines just looked like the best fit.

However - it did not work - emonhub failed to restart.

I tried to restart emonhb.service via SSH with the following result …

pi@emonpi-node-15:~ $ sudo systemctl start emonhub.service
pi@emonpi-node-15:~ $ sudo systemctl status emonhub.service
● emonhub.service - emonHub service description
   Loaded: loaded (/opt/openenergymonitor/emonhub/service/emonhub.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Thu 2020-07-09 15:06:24 BST; 2s ago
  Process: 7452 ExecStartPre=/bin/mkdir -p /var/log/emonhub/ (code=exited, status=0/SUCCESS)
  Process: 7453 ExecStartPre=/bin/chgrp -R emonhub /var/log/emonhub/ (code=exited, status=0/SUCCESS)
  Process: 7454 ExecStartPre=/bin/chmod 775 /var/log/emonhub/ (code=exited, status=0/SUCCESS)
  Process: 7455 ExecStart=/usr/local/bin/emonhub/emonhub.py --config-file=/etc/emonhub/emonhub.conf --logfile=/var/log/emonhub/emonhub.log (code=exited, status=1/FAILURE)
 Main PID: 7455 (code=exited, status=1/FAILURE)

Jul 09 15:06:24 emonpi-node-15 systemd[1]: emonhub.service: Service RestartSec=100ms expired, scheduling restart.
Jul 09 15:06:24 emonpi-node-15 systemd[1]: emonhub.service: Scheduled restart job, restart counter is at 5.
Jul 09 15:06:24 emonpi-node-15 systemd[1]: Stopped emonHub service description.
Jul 09 15:06:24 emonpi-node-15 systemd[1]: emonhub.service: Start request repeated too quickly.
Jul 09 15:06:24 emonpi-node-15 systemd[1]: emonhub.service: Failed with result 'exit-code'.
Jul 09 15:06:24 emonpi-node-15 systemd[1]: Failed to start emonHub service description.
pi@emonpi-node-15:~ $

That makes no sense to me and when I revert to the published PowerWall Interfacer, emonhub service starts per normal.
I’m running the latest ver 10.2.3 - even did an extra Update to be sure.

Any pointers would be most welcome - thx

PS: I did look at the EmonHubTemplateInterfacer.py as a possible alternative but that looked more complex