question

kurtinge avatar image
kurtinge asked

dbus-shelly - showing blank in console

Have a totally fresh 3.30 running on rpi. Did setup outbound websocket from my Shelly Pro 1PM, pointed to the Venus and "Shelly energy meter" came up automatically in the device list in the console. But there are no values transferred. Seems like there are some connection, but still no values. Anyone who knows the reason?

1712231065020.png

1712231112351.png

1712233814894.png

shelly implimentation
1712231065020.png (79.9 KiB)
1712231112351.png (56.6 KiB)
1712233814894.png (93.1 KiB)
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

6 Answers
matt1309 avatar image
matt1309 answered ·

Hi @kurtinge


It maybe worth trying to run the dbus-shelly.py driver in debug mode. Or at least add add print statements in there so you can see which part of the driver maybe isn't working. The other option is making a websocket client to see the data structure to confirm there hasnt been a change on shelly data structure side or if the victron driver needs updated?


Try changing port to 8000.

1 comment
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

kurtinge avatar image kurtinge commented ·

The logfile (/opt/victronenergy/dbus-shelly/current) says nothing. Only that things is up and running. No errrors. Not sure how to stop the service and start it in debug mode?
Regarding the port and the IP and number you see in the console image I attached, this is the return number with the IP and port to the Shelly. This is not configurable and I guess it is derived from the socket the Shelly and Venus have. The Shelly is set up with IP to the Venus and with port-number 8000

0 Likes 0 ·
matt1309 avatar image
matt1309 answered ·

Hi @kurtinge


I've done some messing around using a test python script:


import asyncio
import websockets

async def echo(websocket, path):
    async for message in websocket:
        print(f"Received message from client: {message}")
        await websocket.send(message)

async def main():
    # Start the WebSocket server on localhost, port 8765
    async with websockets.serve(echo, "192.168.3.138", 8765):
        print("WebSocket server started on ws://192.168.3.138:8765")
        # Keep the event loop running forever
        await asyncio.Future()

# Run the main function to start the WebSocket server
asyncio.run(main())


Change it to your ip and it'll show you the data structure of the shelly device. The issue is the victron driver is written to get em0 data, so if you shelly device doesnt post to em:0 it wont work.


It's an easy fix however. You need to edit the python files in dbus-shelly folder, the file meter.py

You need to edit lines 129 i think. Where it says data['params']['em:0'] change the em:0 to whatever yours is for example i tested on shelly pro 1pm the data output looks like this:


Received message from client: {"src":"shellypro4pm-xxxxxx","dst":"ws","method":"NotifyStatus","params":{"ts":1712307840.20,"switch:2":{"id":2,"aenergy":{"by_minute":[0.000,0.000,0.000],"minute_ts":1712307839,"total":0.000}}}}


As you can see em:0 isn't there an instead it's switch:2 or whatever switch number you're using. Similarly the key's are different. So where victron driver is using


d["a_act_power"] it looks like this would just be d["a_power"]. You're better off using the test script above to see the data structure of your shelly device then editing the victron code to work with the data structure of your shelly device. Hope this helps

I'll raise the issue on github but not sure if it'll get looked at.


1 comment
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

kurtinge avatar image kurtinge commented ·
I will take a look next time I am at the boat. Tnx for input.
0 Likes 0 ·
matt1309 avatar image
matt1309 answered ·

As i was looking on github i found someone else describing the exact solution:

https://github.com/victronenergy/dbus-shelly/issues/3

2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

matt1309 avatar image
matt1309 answered ·

I'll debug over the weekend but I started fork and started integrating 1PM.

It's not done but started. I'll try debug it over the weekend (Need to upgrade by system first, running old venus os)


matt1309/dbus-shelly-1pmSupport: HTTP based driver for Shelly energy meters to be used on VenusOS (github.com)


1 comment
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

kurtinge avatar image kurtinge commented ·

You will work on the 1PM pro or the 1PM plus? Or are they behaiving same?

0 Likes 0 ·
matt1309 avatar image
matt1309 answered ·

Hi @kurtinge


I have 1PM pro.

But if you an send me what the data looks like for 1pm plus i can add that in.


You can use the below python script to see what data looks like. Edit the ip from 192.16.3.138 to your local ip of the device running the python script. Then setup shelly to use outbound websockets of whatever you ip is and port 8765 (in my example the machine running the script was running at 192.168..138).

If you then send me what data looks like i'll make sure my fork and work with that as well

import asyncio
import websockets
 
async def echo(websocket, path):
    async for message in websocket:
        print(f"Received message from client: {message}")
        await websocket.send(message)
 
async def main():
    # Start the WebSocket server on localhost, port 8765
    async with websockets.serve(echo, "192.168.3.138", 8765):
        print("WebSocket server started on ws://192.168.3.138:8765")
        # Keep the event loop running forever
        await asyncio.Future()
 
# Run the main function to start the WebSocket server
asyncio.run(main())
1 comment
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

kurtinge avatar image kurtinge commented ·
I have the pro as well so I guess if it works for yours, it will work for mine as well. If not I will check out how the data are looking with your websocket server.
0 Likes 0 ·
kurtinge avatar image
kurtinge answered ·

@matt1309
Did run your debug-script and it seems like switch:0 is the value. Inserted this in line 129 instad of the em:0 and rebooted. Same result from console, but some new lines in the logfile:

@4000000066129a2728470edc *** starting dbus-shelly ***
@4000000066129a2f08e08b7c INFO Starting main loop
@4000000066129c3c0a92ee9c INFO Waiting for localsettings
@4000000066129c3c0aae8904 INFO Connected to localsettings
@4000000066129c5e05c758e4 Error in connection handler
@4000000066129c5e05c7743c Traceback (most recent call last):
@4000000066129c5e05c77c0c File "/usr/lib/python3.8/site-packages/websockets/server.py", line 191, in handler
@4000000066129c5e05c78f94 await self.ws_handler(self, path)
@4000000066129c5e05c79b4c File "/opt/victronenergy/dbus-shelly/dbus_shelly.py", line 73, in __call__
@4000000066129c5e05c7aed4 await m.update(data)
@4000000066129c5e05c7b6a4 File "/opt/victronenergy/dbus-shelly/meter.py", line 134, in update
@4000000066129c5e05c9c214 s['/Ac/L1/Voltage'] = d["a_voltage"]
@4000000066129c5e05c9d1b4 KeyError: 'a_voltage'





Output from dbug-websocket:
WebSocket server started on ws://192.168.0.2:8765
Received message from client: {"src":"shellypro1pm-30c6f781a900","dst":"ws","method":"NotifyFullStatus","params":{"ts":2.29,"ble":{},"cloud":{"connected":false},"eth":{"ip":null},"input:0":{"id":0,"state":false
},"input:1":{"id":1,"state":false},"mqtt":{"connected":true},"switch:0":{"id":0, "source":"init", "output":false, "aenergy":{"total":4031.380}, "ret_aenergy":{"total":0.000},"temperature":{"tC":17.3, "tF":63.1}
},"sys":{"mac":"30C6F781A900","restart_required":false,"time":null,"unixtime":null,"uptime":2,"ram_size":243176,"ram_free":115008,"fs_size":524288,"fs_free":217088,"cfg_rev":50,"kvs_rev":0,"schedule_rev":0,"web
hook_rev":0,"available_updates":{},"reset_reason":3},"wifi":{"sta_ip":"192.168.0.24","status":"got ip","ssid":"Mavi","rssi":-56},"ws":{"connected":true}}}
Received message from client: {"src":"shellypro1pm-30c6f781a900","dst":"ws","method":"NotifyStatus","params":{"ts":2.29,"ws":{"connected":true}}}
Received message from client: {"src":"shellypro1pm-30c6f781a900","dst":"ws","method":"NotifyStatus","params":{"ts":2.32,"switch:0":{"id":0,"voltage":218.5}}}
Received message from client: {"src":"shellypro1pm-30c6f781a900","dst":"ws","method":"NotifyStatus","params":{"ts":1712494233.86,"cloud":{"connected":true}}}


6 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

matt1309 avatar image matt1309 commented ·

Hi @kurtinge

If its only one switch on your shelly device then you're right you need to change to switch:0


But as you can see from debug script you also need to edit the data lines


Ie these lines


s['/Ac/L1/Voltage'] = d["a_voltage"]


As its not a_voltage in the data it's just voltage.

See this line:

Received message from client: {"src":"shellypro1pm-30c6f781a900","dst":"ws","method":"NotifyStatus","params":{"ts":2.32,"switch:0":{"id":0,"voltage":218.5}}}


You may also need to edit the victron python code to not crash if some data isn't provided in every request.


For example the energy meter devices I imagine you receive all data everytime you receive data ie voltage current and power whenever they send data. Whereas from the dbug script you can see only voltage was provided on your one data receipt.

So you need to essentially do if current exists in data update it in dbus otherwise do nothing to stop code crashing in the event current is missing


So you'd need to edit code to check if current key exists in data and if it does write s ie

s['/Ac/L1/Current'] = d["current"]

Without this the oython script might crash when say voltage data is received from shelly but current hasn't been provided.


That make sense?

You might need to play around with this as no current data proved light mean current =0 but I'm sure you can test that out and if it is you just add an else state


Ie if current key exists

s['/Ac/L1/Current'] = d["current"]

Else

s['/Ac/L1/Current'] = 0



Hope this helps

0 Likes 0 ·
kurtinge avatar image kurtinge matt1309 commented ·
Really getting complicated, But I will check out next time. This feature is not very "mandatory" for me, more like nice-to-have to monitor when charger is turned on.

It might would have been easier for me to buy a ET112 energy meter, but that one does not have remote switch as far as I know.

Well, have of the fun is to make things work so I will play around with this info next time. Thanks so far


0 Likes 0 ·
matt1309 avatar image matt1309 kurtinge commented ·

I use the Shelly switches controlled via node red for switching rather than integrating into cerbo naively (if that impact anything).


I didnt get change to debug my 1pm pro code. but it'll be easy to integrate 1pm plus once i do.

-1 Like -1 ·
kurtinge avatar image kurtinge matt1309 commented ·

Switching is only done through the Shelly app. No need to have this done by Venus or Node Red. Just need to see how much the charger are consuming.

Well, I will do some test next time. Either with the existing files or I replace it with the file in the repo of yours: https://github.com/matt1309/dbus-shelly-1pmSupport/tree/master


0 Likes 0 ·
matt1309 avatar image matt1309 kurtinge commented ·

If the shelly 1 plus one switch you might be able to just add another try block like:


 try:
                            d = data['params']['switch:0']
                        except KeyError:
                            pass
                        else:
                            with service as s:
                                avoltage = d.get("voltage")
                                if avoltage is not None:
                                   s['/Ac/L1/Voltage'] = avoltage #could add option to getPhase from settings. 
                                acurrent = d.get("current")
                                if acurrent is not None:
                                    s['/Ac/L1/Current'] = acurrent #could add option to getPhase from settings. 
                                apower = d.get("apower")
                                if apower is not None:
                                    s['/Ac/L1/Power'] = apower #could add option to getPhase from settings. 
                                    s['/Ac/Power'] = apower
                                    #to add the total energy lookups not sure if can do reverse
                                    #aenergy = d.get("aenergy")
                                    #s["/Ac/Energy/Forward"] = round(aenergy.get("total")/1000,1)
                                    #s["/Ac/L1/Energy/Forward"] = round(aenergy.get("total")/1000,1)



I've not tested but this is my guess

1 Like 1 ·
kurtinge avatar image kurtinge matt1309 commented ·

changed the line:

old value: s['/Ac/L1/Voltage'] = d["a_voltage"]
new value: s['/Ac/L1/Voltage'] = d["voltage"]

This resulted in the following error in the log:

@400000006616511e0dd0183c Error in connection handler
@400000006616511e0dd02fac Traceback (most recent call last):
@400000006616511e0dd0377c File "/usr/lib/python3.8/site-packages/websockets/server.py", line 191, in handler
@400000006616511e0dd04b04 await self.ws_handler(self, path)
@400000006616511e0dd056bc File "/opt/victronenergy/dbus-shelly/dbus_shelly.py", line 73, in __call__
@400000006616511e0dd06a44 await m.update(data)
@400000006616511e0dd07214 File "/opt/victronenergy/dbus-shelly/meter.py", line 134, in update
@400000006616511e0dd28554 s['/Ac/L1/Voltage'] = d["voltage"]
@400000006616511e0dd294f4 KeyError: 'voltage'


0 Likes 0 ·

Related Resources

Additional resources still need to be added for this topic