Closed fu-zhou closed 4 years ago
Hi, 1). It seems that you have the script installed in your user home folder. Likely your environment variables differ between what is seen by a script when run from terminal and when run as a service. For this reason the system python does not realize that there are additional modules installed in your user home. To run it as a service I think the clean method would be doing the following: set up a python virtual environment for your systemd service. That way you ensure that running the script manually yields the same results as when run from systemd. Basically the workflow for preparing that venv (only to be done once) would be along the following lines:
# the following creates a sandboxed, local python installation in /opt/essmqtt
python3.8 -m venv /opt/essmqtt
# the following installs pyess in the sandbox
/opt/essmqtt/bin/pip install pyess
from then on you should be able to call /opt/essmqtt/bin/esmqtt
from both your terminal and a systemd service. Read up on virtualenvs or venvs if you want to know more about this approach, they can be very powerful.
2.) The request here is that essmqtt somehow registers as an mqtt client -- could you point me towards specification on how this is usually done?
3.) The typos are actually what is sent by the LG box -- I agree they are typos but I wouldn't want to rename these to fix a typo made by LG.
4.) I don't know exactly what the status means, I assume that they somehow relate to the direction of the power flows. You may get clues by running the app in parallel, especially when the direction of power flows changes (for instance monitor it while switching on a load that changes your power balance such that you go from feeding the grid to not feeding it any more, or compare it in the evening before and after the last watts have stopped coming in during sunset).
Thanks for the quick reply. I will try 1) as described by you. On 2) I have no clue about the protocol's details. What I see in iobroker's MQTT server adapter is: "List of connected clients: mosqsub|89309-iobroker-" when I run mosquitto_sub in parallel to essmqtt. If you give me a starting point, I'm more than happy to figure the details out, despite my limitiations when it comes to reverse engineering. 3) I fully agree. 4) Okay, I'll try to figure that out and keep you posted...
In Ubuntu 18.04 Server I got essmqtt to run as service like:
# install venv:
sudo apt install python3.8-venv
# create virtual environment:
python3 -m venv essmqtt
# activate:
source essmqtt/bin/activate
# install pyess:
pip install pyess
# create service:
sudo nano /etc/systemd/system/essmqtt.service
# Content of service:
[Unit]
Description=ESS MQTT Communication
[Service]
ExecStart=/home/user/essmqtt/bin/essmqtt --mqtt_server=<MQTT SERVER IP> --ess_password <PW> --interval_seconds <POLL INTERVALL>
[Install]
WantedBy=default.target
Problem: the service does not run after startup/ reboot, it needs to be started with:
systemctl start essmqtt.service
Having enabled the service (systemctl enable essmqtt.service
), systemctl status essmqtt.service
shows after startup:
● essmqtt.service - ESS MQTT Communication
Loaded: loaded (/etc/systemd/system/essmqtt.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2020-05-05 22:59:05 CEST; 1min 9s ago
Process: 625 ExecStart=/home/user/essmqtt/bin/essmqtt --mqtt_server=192.168.0.50 --ess_password XXX --interval_seconds 5 (code=exited, status=1/FAILUR
Main PID: 625 (code=exited, status=1/FAILURE)
May 05 22:59:05 iobroker-vm essmqtt[625]: sock.connect(sa)
May 05 22:59:05 iobroker-vm essmqtt[625]: ConnectionRefusedError: [Errno 111] Connection refused
May 05 22:59:05 iobroker-vm essmqtt[625]: /home/user/essmqtt/lib/python3.8/site-packages/pyess/aio_ess.py:202: RuntimeWarning: coroutine 'ClientSession.close' wa
May 05 22:59:05 iobroker-vm essmqtt[625]: ERROR:asyncio:Unclosed client session
May 05 22:59:05 iobroker-vm essmqtt[625]: client_session: <aiohttp.client.ClientSession object at 0x7fa2e96fab50>
May 05 22:59:05 iobroker-vm essmqtt[625]: ERROR:asyncio:Unclosed connector
May 05 22:59:05 iobroker-vm essmqtt[625]: connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7fa2e9705820>, 14.149501901)]']
May 05 22:59:05 iobroker-vm essmqtt[625]: connector: <aiohttp.connector.TCPConnector object at 0x7fa2e96fad30>
May 05 22:59:05 iobroker-vm systemd[1]: essmqtt.service: Main process exited, code=exited, status=1/FAILURE
May 05 22:59:05 iobroker-vm systemd[1]: essmqtt.service: Failed with result 'exit-code'
Manual start as descibed above works. Can it have something to do with permissions/ rights? I also tried a waiting time in the service but no success.
Hi @fu-zhou this looks promising, earlier on your logs showed that the module wasn't even found. The error now seems to be that the service cannot connect. Is the current log from a start at boot?
I'm asking because I had the same problem once with a systemd service that was starting before network was started. But if you're manually starting it via systemctl start
the above shouldn't happen. The issue now seems to be that for some reason the service cannot connect to the network.
I'll get back to you later after trying to replicate this on a debian machine.
I know what it is: The MQTT Server Adpater of iobroker needs to run first and that takes a while... According to "htop" the process/ Command which needs to run is "io.mqtt.0"
The a.m. service won't run on your system either as - I guess - you won't have an MQTT Server running on that machine...
Putting
[Unit]
Description=ESS MQTT Communication
After=iobroker.service
Is certainly the first step, but we also have to tell the service to wait until io.mqtt.0 is running:
● iobroker.service - ioBroker Server
Loaded: loaded (/lib/systemd/system/iobroker.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-05-06 19:19:08 CEST; 4min 19s ago
Docs: http://iobroker.net
Main PID: 655 (iobroker.js-con)
Tasks: 209 (limit: 2290)
CGroup: /system.slice/iobroker.service
├─ 655 iobroker.js-controller
├─ 992 io.admin.0
├─1027 io.s7.0
├─1182 io.web.0
├─1200 io.ping.0
├─1215 io.javascript.0
├─1230 io.fullcalendar.0
├─1247 io.text2command.0
├─1264 io.telegram.0
├─1279 io.sql.0
├─1384 io.motion.0
├─1399 io.samsung.0
├─1416 io.cloud.0
├─1432 io.socketio.0
├─1449 io.backitup.0
├─1465 io.web.1
├─1671 io.info.0
├─1690 io.worx.0
└─2111 io.mqtt.0
@fu-zhou great to see that you solved it. Actually I ran it against my mqtt server so it was working with systemd on my machine. I'll see that I add an optional reconnect loop. Also makes sense in case the mqtt server has to be restarted, we don't want to crash in that case, either.
Actually I didn't get it resolved yet... I still miss the piece to have the essmqtt.service wait for io.mqtt.0 to be started under iobroker.service. Reconnect loop sounds good!
@fu-zhou the easiest will be to just make systemd restart your service when it fails, something along these lines:
[Unit]
Description=ESS MQTT Communication
[Service]
ExecStart=/home/user/essmqtt/bin/essmqtt --mqtt_server=<MQTT SERVER IP> --ess_password <PW> --interval_seconds <POLL INTERVALL>
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.target
I split off the "register as an mqtt client" point from the original issue into a separate issue - it is currently hard to implement because the mqtt library used for pyess does not support a "last will and testament" and as far as I could find out that is required to provide this functionality.
edit: I also split off the "what do statuses mean" question.
Awesome, the service works now after boot-up with
Restart=on-failure
RestartSec=10
Okay, I will close this issue then. Thank you @fu-zhou for your comments and cooperation in fixing this, I will add your systemd service configuration example to the documentation later on. I will think about adding an internal auto-reconnect but for the time being i think it is fine to have it handled by systemd, maybe even better than "hiding" it behind an internal retry.
I got my system up and running now, essmqtt is awesome, thanks for all the effort put in so far! I have a couple of requests/ comments meanwhile:
[x] 2.)
The MQTT Broker updates all the values according to the set interval_seconds, but doesn't show that it is connected to the essmqtt client. As soon as I start mosquitto_sub, the MQTT Broker recognizes mosquitto_sub and shows it as client and mosquito_sub receives all the data from essmqttsplit into #4[x] 3.) Minor: typos in mqtt.0.ess.common.PCS.pcs_stauts is supposed to be pcs_status, I guess mqtt.0.ess.common.LOAD.today_batt_discharge_enery = energy
Is there a clue what the satusses mean? E.g. pcs_status 3, what does the 3 stand for? That also applies to e.g. mqtt.0.ess.common.BATT.statussplit into #5Thanks again for all the effort put in here!