Closed mpolak77 closed 1 year ago
HI @mpolak77 ,
thanks for the feedback - I agree, error handling is not the best - had a similar problem a few weeks ago. But unfortunately I am missing a little bit of time to do so....
Would be happy for some support - proposals, code-snippets, etc..
Thx
Here a first attempt which seems to work, and also prints exceptions more readable:
--- dbus-shelly-3em-smartmeter-master.py
+++ dbus-shelly-3em-smartmeter.py
@@ -104,7 +104,7 @@
def _getShellyData(self):
URL = self._getShellyStatusUrl()
- meter_r = requests.get(url = URL)
+ meter_r = requests.get(url = URL, timeout=5)
# check for response
if not meter_r:
@@ -158,14 +156,20 @@
logging.debug("House Reverse (/Ac/Energy/Revers): %s" % (self._dbusservice['/Ac/Energy/Reverse']))
logging.debug("---");
- # increment UpdateIndex - to show that new data is available
- index = self._dbusservice['/UpdateIndex'] + 1 # increment index
- if index > 255: # maximum value of the index
- index = 0 # overflow from 255 to 0
- self._dbusservice['/UpdateIndex'] = index
+ # increment UpdateIndex - to show that new data is available an wrap
+ self._dbusservice['/UpdateIndex'] = (self._dbusservice['/UpdateIndex'] + 1 ) % 256
#update lastupdate vars
self._lastUpdate = time.time()
+
+ except (ValueError, requests.exceptions.ConnectionError, requests.exceptions.Timeout, ConnectionError):
+ logging.critical('Error getting data from Shelly - check network or Shelly status. Setting power values to 0')
+ self._dbusservice['/Ac/L1/Power'] = 0
+ self._dbusservice['/Ac/L2/Power'] = 0
+ self._dbusservice['/Ac/L3/Power'] = 0
+ self._dbusservice['/Ac/Power'] = 0
+ self._dbusservice['/UpdateIndex'] = (self._dbusservice['/UpdateIndex'] + 1 ) % 256
+
except Exception as e:
logging.critical('Error at %s', '_update', exc_info=e)
@@ -233,7 +237,12 @@
logging.info('Connected to dbus, and switching over to gobject.MainLoop() (= event based)')
mainloop = gobject.MainLoop()
mainloop.run()
+
+ except (ValueError, requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
+ logging.critical('Error in main type %s', str(e))
+
except Exception as e:
logging.critical('Error at %s', 'main', exc_info=e)
+
if __name__ == "__main__"
```:
@mpolak77 Good idea, but only works if the gridpower set point is 0 Watt. It would be better to set it to "/Settings/Cgwacs/AcPowerSetPoint". Then it is aligned to target of ESS control loop. Another point: If the json decoding fails -> is this catched by ValueError? or should we add requests.exceptions.JSONDecodeError
Good point - just realized that Multiplus starts to charge, if SetPoiint is >0 and Meter reads 0 …. Now I need to find out, how to do this correctly depending on 1phase vs all phase Saldo mode.
@mpolak77 thank you for your input - will add that to the next commit
Should be all in now. Thanks for the input
Short story: I think the script should set current power meter values to 0, whenever the meter is not reachable.
Long story: I'm running the latest version with my Multiplus II and Venus on a raspberry pi.
Recently I've discovered my inverter pushing max power into L1, while the actual load only was around 300-500W. As a root cause I could find a broken Wifi connection to the shelly device, the log did show a long list of exceptions. Multiplus would still see a usage of 500 W and would push up power for compensating that ..... the meter value would not get back to Multiplus accordingly, and Multiplus increased even more. If a missing meter fetch attempt would have set values to 0, this would at least have prevented Multiplus from trying to compensating and emptying the battery.