GivEnergy - Battery/Inverter + home power things

I hope so Mark

NAS spec says Intel Celeron J4025/J4005 2-core/2-thread 64-bit x86. Let me know if you need any more detail

@britkat Any chance you can point me in the right direction; I’m not using the Docker image but have downloaded the code from the repo, installed required packages, put a settings.py file in place with the Inverter IP, # batteries and JSON interface enabled.

When I GET /runAll in Postman I get the following response:

{"result": "Error collecting registers: (<class 'pydantic.error_wrappers.ValidationError'>,
    ValidationError(model='Inverter', errors=[{'loc': ('__root__',), 'msg': \"'SD' is not a valid Model\", 'type':
    'value_error'}]), <traceback object at 0x8035e8940>)"}

Thanks in advance!

Hi there, there’s a known issue with v0.9.3 of GivEnergy-modbus library. It doesn’t have validation for SD invertors. My docker has a hot fix for it. The GitHub for the library has been updated but no new release yet. I’ll message the dev and get him to push a new version.

1 Like

FYI: I tried patching my giv-modbus library with the latest revision but that gave me a different error ("‘str’ object has no attribute ‘name’"), however, using the previous revision I now have it working.

Edit to say that I am intermittently getting the following error, that’s with me pushing the scan interval out to 30 seconds as at 20 seconds I was seeing it a lot – the environment its running in doesn’t seem like it’s under any particular strain (it’s a Jail within a TrueNAS Core install running on an quad core x86 with 16GB of RAM, for what its worth):

{"result": "Error collecting registers: (<class 'KeyError'>, KeyError(IR:110), <traceback object at 0x8034df3c0>)"}

Echoing the thanks @britkat - just about to spin up the tcp container and see if that starts but looking ahead I downloaded the packages/givtcp.yaml into my hass config folder but looking inside it I see the line: resource: http://192.168.2.10:6345/runAll referred to as the inverter connection. Is that IP the dongle? I haven’t been able to identify the device IP on my lan - I see no obvious mac or device name with my IP scanner so I’m hoping the auto discovery works. ** update ** it didn’t so I need to figure that IP out.

Thing is the IP in the yaml file is a x.x.2.0 subnet and I run x.x.100.0 so just want to check if I should change it or is that only for use inside the container itself.

Thanks!

Mike

The IP in the yaml file is the address of the docker container running GivTCP, not the invertor itself. GivTCP is essentially a middle man between HA (or other systems) and the invertor itself.
The auto discovery only work if the docker container is running on the host network (not bridge). Although its not always perfect.
Have a look here: https://terravolt.co.uk/Downloads/Misc/Powershell/Givenergy%20GIVTCP%20Local%20Data.pdf
for a good guide on how to set up GivTCP.

There’s just been an update pushed for the givenergy-modbus library. I’ve updated and pushed a new image to dockerhub. This should work no with no errors (let me know otherwise).

1 Like

Already had network mode set to host and just re-pulled and restarted but no joy finding the ip running a full ip scan looking for all ports on my lan but that is slooooooooow :slight_smile:

ok. I found the ip by logging into the dongle and that showed me the MAC. I then reconfigured the docker-compose and re-ran but it constantly fails to start cleanly. I am in no doubt I’m doing somthing(s) wrong but am stumped atm.

My environment is an intel core-i3 running Debian Bullseye and I’m using compose with this file
(host mode is off because I have the IP and it would not start MQTT in that mode):

version: “3.5”
services:
givtcp:
image: britkat/giv_tcp-ma
container_name: givtcp
ports:
- “6345:6345/tcp”
environment:
- INVERTOR_IP=192.168.100.159
- NUMBATTERIES=1
restart: “no”

Attempting to bring it up gives me:
Starting givtcp … done
Attaching to givtcp
givtcp | /app/settings.py exists.
givtcp | Starting Mosquitto on port 1883
givtcp | Running Invertor read loop every 20s…
givtcp | Starting Gunicorn on port 6345
givtcp | 1645439329: mosquitto version 2.0.11 starting
givtcp | 1645439329: Using default config.
givtcp | 1645439329: Starting in local only mode. Connections will only be possible from clients running on this machine.
givtcp | 1645439329: Create a configuration file which defines a listener to allow remote access.
givtcp | 1645439329: For more details see Authentication methods | Eclipse Mosquitto
givtcp | 1645439329: Opening ipv4 listen socket on port 1883.
givtcp | 1645439329: Opening ipv6 listen socket on port 1883.
givtcp | 1645439329: Error: Address not available
givtcp | 1645439329: mosquitto version 2.0.11 running
givtcp | Traceback (most recent call last):
givtcp | File “/app/sched.py”, line 6, in
givtcp | from read import runAll
givtcp | File “/app/read.py”, line 8, in
givtcp | from HA_Discovery import HAMQTT
givtcp | ModuleNotFoundError: No module named ‘HA_Discovery’
givtcp | [2022-02-21 10:28:49 +0000] [9] [INFO] Starting gunicorn 20.1.0
givtcp | [2022-02-21 10:28:49 +0000] [9] [INFO] Listening at: http://0.0.0.0:6345 (9)
givtcp | [2022-02-21 10:28:49 +0000] [9] [INFO] Using worker: sync
givtcp | [2022-02-21 10:28:49 +0000] [10] [INFO] Booting worker with pid: 10
givtcp | [2022-02-21 10:28:49 +0000] [11] [INFO] Booting worker with pid: 11
givtcp | [2022-02-21 10:28:49 +0000] [10] [ERROR] Exception in worker process
givtcp | Traceback (most recent call last):
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/arbiter.py”, line 589, in spawn_worker
givtcp | worker.init_process()
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/workers/base.py”, line 134, in init_process
givtcp | self.load_wsgi()
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/workers/base.py”, line 146, in load_wsgi
givtcp | self.wsgi = self.app.wsgi()
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/app/base.py”, line 67, in wsgi
givtcp | self.callable = self.load()
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py”, line 58, in load
givtcp | return self.load_wsgiapp()
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py”, line 48, in load_wsgiapp
givtcp | return util.import_app(self.app_uri)
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/util.py”, line 359, in import_app
givtcp | mod = importlib.import_module(module)
givtcp | File “/usr/local/lib/python3.10/importlib/init.py”, line 126, in import_module
givtcp | return _bootstrap._gcd_import(name[level:], package, level)
givtcp | File “”, line 1050, in _gcd_import
givtcp | File “”, line 1027, in _find_and_load
givtcp | File “”, line 1006, in _find_and_load_unlocked
givtcp | File “”, line 688, in _load_unlocked
givtcp | File “”, line 883, in exec_module
givtcp | File “”, line 241, in _call_with_frames_removed
givtcp | File “/app/REST.py”, line 5, in
givtcp | import read as rd #grab passthrough functions from main read file
givtcp | File “/app/read.py”, line 8, in
givtcp | from HA_Discovery import HAMQTT
givtcp | ModuleNotFoundError: No module named ‘HA_Discovery’
givtcp | [2022-02-21 10:28:49 +0000] [10] [INFO] Worker exiting (pid: 10)
givtcp | [2022-02-21 10:28:49 +0000] [12] [INFO] Booting worker with pid: 12
givtcp | [2022-02-21 10:28:49 +0000] [11] [ERROR] Exception in worker process
givtcp | Traceback (most recent call last):
givtcp | File “/usr/local/lib/python3.10/site-packages/gunicorn/arbiter.py”, line 589, in spawn_worker

It says it can’t open 1833 for listening (nothing else is using that port and I am running as root) but then also says mosquito is running…

Appreciate it if you have any suggestions?

Thanks

Mike

Mike, my bad, I uploaded a duff docker image. I’ve reuploaded and its available on dockerhub now.
If you aren’t going to use MQTT then you can set MQTT_OUTPUT=“False” and it wont try to set up Mosqitto.

Thanks Mark,

I appreciate all the hard work you and others have put in to getting this to where it is and if there’s anything I can do to help, just say (for what it’s worth, I am a software developer of ~15 years, albeit with very little Python experience, so I’m fairly technical).

I’ve updated the givenergy-modbus library and applied the change to read.py in your codebase to handle the change to the enum. This has worked and I’m getting data through as expected. I am still intermittently getting ‘unavailable’ values in the HA sensors, with this error or similar errors logged (using debug logging) – the ‘IR:000’ value appears to be different each time:

{"result": "Error collecting registers: (<class 'KeyError'>, KeyError(IR:000), <traceback object at 0x8034cdb40>)"}

I also changed the state_class on the kWh-related sensors from ‘measurement’ to ‘total_increasing’ so that they work properly in the Energy Dashboard (I hope, still nothing showing yet but it has removed the error HA was giving me when I added them previously).

Thanks again!

Intermittant “unavailable” is an unsolved challenge. The low-level Modbus RTU over TCP appears mildly flaky and occasional clashes in calls to the invertor return garbage, something to live with I’m afraid.

Is there anything in the yaml we can do to stop updates unless the rest command returns valid data? I do this in my NR flow, to prevent data drops in HA

1 Like

Hi Mark. Major progress as the container now starts and remains up. There does seem to be an issue though because there is an error in the log which is repeated (with no other output) when calling /runAll in the browser

== Docker Log ==
Attaching to givtcp
givtcp | /app/settings.py does not exist
givtcp | Starting Mosquitto on port 1883
givtcp | Running Invertor read loop every 20s…
givtcp | Starting Gunicorn on port 6345
givtcp | 1645459086: mosquitto version 2.0.11 starting
givtcp | 1645459086: Using default config.
givtcp | 1645459086: Starting in local only mode. Connections will only be possible from clients running on this machine.
givtcp | 1645459086: Create a configuration file which defines a listener to allow remote access.
givtcp | 1645459086: For more details see REDACTED
givtcp | 1645459086: Opening ipv4 listen socket on port 1883.
givtcp | 1645459086: Opening ipv6 listen socket on port 1883.
givtcp | 1645459086: Error: Address not available
givtcp | 1645459086: mosquitto version 2.0.11 running
givtcp | [2022-02-21 15:58:06 +0000] [9] [INFO] Starting gunicorn 20.1.0
givtcp | [2022-02-21 15:58:06 +0000] [9] [INFO] Listening at: 0.0.0.0:6345 (9)
givtcp | [2022-02-21 15:58:06 +0000] [9] [INFO] Using worker: sync
givtcp | [2022-02-21 15:58:06 +0000] [10] [INFO] Booting worker with pid: 10
givtcp | [2022-02-21 15:58:06 +0000] [11] [INFO] Booting worker with pid: 11
givtcp | [2022-02-21 15:58:06 +0000] [12] [INFO] Booting worker with pid: 12
givtcp | ERROR:GivTCP:Error processing registers: (<class ‘AttributeError’>, AttributeError("‘Battery’ object has no attribute ‘e_battery_charge_total_2’"), <traceback object at 0x7f4f5a2cb140>)

== Browser Output ==
http://192.168.100.49:6345/runAll
{“result”: “Error processing registers: (, AttributeError(”‘Battery’ object has no attribute ‘e_battery_charge_total_2’"), )"}

== Compose ==
version: “3.5”
services:
givtcp:
image: britkat/giv_tcp-ma
container_name: givtcp
ports:
- “6345:6345/tcp”
environment:
- INVERTOR_IP=192.168.100.159
- NUMBATTERIES=1
- MQTT_OUTPUT=False
restart: “no”

Regards ignoring the unavailable state, I found a post with a possible workaround – I’ll try this and report back.

Another possibility, if the inverter’s response cannot be counted on, would be to enable one or more retries, at least in the case of the /runAll endpoint, although if the inverter normally takes a while to start behaving then this will likely result in the same.

Have GivEnergy given any feedback as to why it intermittently responds with garbage?

That’s odd, that’s an old error from a previous version. Can you pull the docker image tag dated today? And see if it’s still occurring. The 0.9.4 release of GivEnergy-modbus is the one to use

Took me a couple of goes to get it right, though if I’d have just read the documentation I would probably have managed it first time out the gate… e.g.

      - name: "GivTCP Battery SOC"
        unit_of_measurement: "%"
        device_class: battery
        state_class: measurement
        state: >
          {% if state_attr('sensor.givtcp','Power') is not none %}
            {{ state_attr('sensor.givtcp','Power')['Power']['SOC'] }}
          {% else %}
            {{ states('sensor.givtcp_battery_soc') }}
          {% endif %}

That will use the existing value if the REST call returned no data

1 Like

I pulled 2022.02.21 and it certainly changed. Unsure how to know what modbus it’s using?

== Log ==
Starting givtcp … done
Attaching to givtcp
givtcp | /app/settings.py exists.
givtcp | Starting Mosquitto on port 1883
givtcp | Running Invertor read loop every 20s…
givtcp | Starting Gunicorn on port 6345
givtcp | 1645466734: mosquitto version 2.0.11 starting
givtcp | 1645466734: Using default config.
givtcp | 1645466734: Starting in local only mode. Connections will only be possible from clients running on this machine.
givtcp | 1645466734: Create a configuration file which defines a listener to allow remote access.
givtcp | 1645466734: For more details see
givtcp | 1645466734: Opening ipv4 listen socket on port 1883.
givtcp | 1645466734: Opening ipv6 listen socket on port 1883.
givtcp | 1645466734: Error: Address not available
givtcp | 1645466734: mosquitto version 2.0.11 running
givtcp | [2022-02-21 18:05:34 +0000] [9] [INFO] Starting gunicorn 20.1.0
givtcp | [2022-02-21 18:05:34 +0000] [9] [INFO] Listening at:
givtcp | [2022-02-21 18:05:34 +0000] [9] [INFO] Using worker: sync
givtcp | [2022-02-21 18:05:34 +0000] [10] [INFO] Booting worker with pid: 10
givtcp | [2022-02-21 18:05:34 +0000] [11] [INFO] Booting worker with pid: 11
givtcp | [2022-02-21 18:05:34 +0000] [12] [INFO] Booting worker with pid: 12
givtcp | ERROR:givenergy_modbus:Did not receive expected response type: ReadInputRegistersResponse != ReadHoldingRegistersResponse
givtcp | ERROR:givenergy_modbus:Did not receive expected response type: ReadHoldingRegistersResponse != ReadInputRegistersResponse
givtcp | ERROR:GivTCP:Error collecting registers: (<class ‘KeyError’>, KeyError(IR:183), <traceback object at 0x7f8a3420b2c0>)
givtcp | ERROR:givenergy_modbus:Returned base register (60) does not match that from request (120).
givtcp | ERROR:givenergy_modbus:Did not receive expected response type: ReadInputRegistersResponse != ReadHoldingRegistersResponse
givtcp | ERROR:givenergy_modbus:Returned base register (0) does not match that from request (180).
givtcp | ERROR:GivTCP:Error collecting registers: (<class ‘KeyError’>, KeyError(HR:113), <traceback object at 0x7f06080b78c0>)
givtcp | ERROR:GivTCP:Error processing registers: (<class ‘AttributeError’>, AttributeError("‘Battery’ object has no attribute ‘e_battery_charge_total_2’"), <traceback object at 0x7f8a35b20040>)

== browser ==
{“result”: “Error collecting registers: (, KeyError(HR:013), )”}

== OR ==
{“result”: “Error processing registers: (, AttributeError(”‘Battery’ object has no attribute ‘e_battery_charge_total_2’"), )"}

Noticed there is a tag for tomorrow (2022.02.22) but that went up yesterday so I have ignored it

if you terminal into the docker and run pip list, does it show ‘givenergy-modbus 0.9.4’?

It does indeed - full list below

bash-5.1# pip list
Package Version


certifi 2021.10.8
charset-normalizer 2.0.12
click 8.0.1
crccheck 1.1
Flask 2.0.3
givenergy-modbus 0.9.4
gunicorn 20.1.0
idna 3.3
influxdb-client 1.26.0
itsdangerous 2.1.0
Jinja2 3.0.3
loguru 0.6.0
Markdown 3.3.4
MarkupSafe 2.1.0
mkdocs-material-extensions 1.0.3
paho-mqtt 1.6.1
pip 21.2.4
pydantic 1.9.0
pymodbus 2.5.3
pyserial 3.5
python-dateutil 2.8.2
pytkdocs 0.16.0
pytz 2021.3
requests 2.27.1
Rx 3.2.0
scapy 2.4.5
schedule 1.1.0
setuptools 57.5.0
six 1.16.0
typing_extensions 4.1.1
urllib3 1.26.8
Werkzeug 2.0.3
wheel 0.37.0
WARNING: You are using pip version 21.2.4; however, version 22.0.3 is available.
You should consider upgrading via the ‘/usr/local/bin/python -m pip install --upgrade pip’ command.
bash-5.1#

could it be my firmware revision on the GE dongle, battery or inverter? It’s only just installed for a couple of weeks so assume it’s current

Inverter Firmware Version: D0.450-A0.450

Last Update Time

Battery Firmware Version: 3005