Closed DomiStyle closed 1 year ago
We currently don't support controlling devices without the cloud. You can control the mower via cloud using our officially supported GARDENA smart system API or the unofficial home assistant integration that was built on it.
If you still see a need to control it locally, you should be able to find some tools on the gateway (such as nngforward and related systemd units) that help you achieve what you want. But it could still be challenging depending on the mower model and what aspects you want to control.
Thanks for the response, I was not able to find nngforward
on the latest firmware but I was able to achieve local control by directly posting start/stop UDP packets to the ppp0
interface. I was also able to get the status of the device from /var/lib/shadoway/work
.
That should be sufficient for my needs.
Out of interest, is there any documentation on the values stored in the work
directory?
{
"address" : "",
"id" : 4,
"lemonId" : "4r",
"timestamp" : 1680073114516,
"uuid" : "014c2855-6196-4565-a468-c042c752ae26",
"value" : "12.0"
}
There's a description for which id
does what in the Value_description
directory but it does not state which value
represents what.
I can take an educated guess but maybe they are noted somewhere?
In that case, you are not yet on the latest gateway software version. There is no public documentation on those values / device details and they can change at any time.
With the latest gateway software version you get some more descriptive names if you interact with the device on nng level instead of the lower level you are using right now (UDP / radio). But the information you can retrieve is essential same as you get from the mentioned files / folders
Thanks! I let my gateway sit over night but doesn't seem to want to upgrade to a version that has nngforward
installed.
I'm going to stick to the current variant since I only need to send start/stop anyway. I removed internet access for now so it doesn't upgrade anything and the values can't change.
Hi @DomiStyle
If you connect your gateway to the internet, I can try to find out why it has not been upgraded yet. You should really move to the latest software.
BTW, you can prevent files from being deleted during upgrades by adding their paths to /etc/sysupgrade.conf
.
Cheers, Ezra
Thanks for the offer! I bought the gateway used and seems it was never opened and had a really old software version and needed to update multiple times.
I started swupdate-check manually a few times and it updated successfully, nngforward
is available now and I will take a look at it once I get some time.
BTW, you can prevent files from being deleted during upgrades by adding their paths to /etc/sysupgrade.conf.
That seems useful, thanks. Guess I can stop it from killing my SSH access on every update. ;)
That seems useful, thanks. Guess I can stop it from killing my SSH access on every update. ;)
This should not be needed. Setting dev_debug_allow_local_ssh in the U-Boot environment ensures that the local SSH access works across firmware updates:
# fw_setenv dev_debug_allow_local_ssh 1
This should not be needed. Setting dev_debug_allow_local_ssh in the U-Boot environment ensures that the local SSH access works across firmware updates
True, but he might want to persist the authorized_keys
file.
@DomiStyle, setting the dev_debug_enable_nngforward
U-Boot variable might also be interesting for you, it will allow you to send NNG messages to the gateway from within your LAN.
Hi,
@DomiStyle, setting the
dev_debug_enable_nngforward
U-Boot variable might also be interesting for you, it will allow you to send NNG messages to the gateway from within your LAN.
How does this work? Is it only possible to send messages to the gateway or also receiving communication. For my understanding nngcat --bus --connect tcp://
Hi, When i set the variable dev_debug_enable_nngforward to 1, the services nngforward-lemonbeatd.service and nngforward-lwm2mserver.service are started after restart. These two services open TCP ports 28150 and 28151 for lwm2mserver, and 28152 and 28153 for lemonbeatd. The first attempts to capture something on these ports were unsuccessful. At /usr/bin/nngforward is the shell script which is used for the nngforward services. An analysis of the script showed that the opened ports 28150-28153 are only set as INPUT in the firewall. If the quiet mode of the nngforward services is disabled (remove -q when calling the service) you get an output with the socat commands to use in your client.
If you use the socat commands directly as shown and send data to one of the 4 ports then you have built a loop. If you set up the forwarding to your own tcp server instead, you will see the data you send to one of the four ports in your own server. The nngforward service forwards the incoming data on the ports to the file /tmp/lwm2mserver-command.ipc, /tmp/lwm2mserver-event.ipc, /tmp/lemonbeatd-command.ipc and /tmp/lemonbeatd-event.ipc. If you enable the additional redirects mentioned from the service output, the data written to the mentioned files will be redirected to the self-selected endpoint. so far so good. As I understand it, with the nngforward service we have by default a service to write data to the file that the actual services lwm2m and lemonbeatd work with it?!?! Now I would have thought that if I trigger an action via the Gardena app, the respective command also ends up in one of these files and is therefore visible in the own endpoint when forwarding is active. Unfortunately, one gets here nothing to see.
You will see something if you subscribe to ipc:///tmp/lemonbeatd-event.ipc
with topics=""
. For Python, you can find the documentation here.
You will see something if you subscribe to
ipc:///tmp/lemonbeatd-event.ipc
withtopics=""
. For Python, you can find the documentation here.
Thank you for your reply @easybe.
I create a small python script to subscribe the events
import time
from pynng import Pub0, Sub0, Timeout
with Sub0(dial='ipc:///tmp/lemonbeatd-event.ipc', recv_timeout=20000) as sub0:
sub0.subscribe("")
print(sub0.recv())
and i will get the following output after starting the script two times when i park my lawnrobot in the gardena app
root@GARDENA-1f997d:~# python3 test.py
b'[{"entity":{"device":"XXXXXXXXXXXXXXXXXXXX","path":"lemonbeat/0"},"metadata":{"sequence":47,"source":"lemonbeatd"},"op":"update","payload":{"mower_timer":{"ts":1681655800,"vi":0}}}]'
root@GARDENA-1f997d:~# python3 test.py
b'[{"entity":{"device":"XXXXXXXXXXXXXXXXXXX","path":"lemonbeat/0"},"metadata":{"sequence":50,"source":"lemonbeatd"},"op":"update","payload":{"internal_connection_state":{"ts":1681655804,"vi":3}}}]'
When i subscribe the lwm2mserver-event.ipc i will get no output.
Is it possible to receive the data of the lemonbeatd-command.ipc file as well? I get no output when i subscribe the ipc file. Or can i directly publish a message in the shown format to the lemonbeatd-command?
Note that you can't directly use nng with tcp transport to connect to those ports exposed, instead use the mentioned socat commands from the nngforward command and execute them on your own machine or server, this essentially mirrors the nng sockets from your gateway to your own machine. You can then interact with the nng sockets as you would be on the gateway using the inter-process transport.
The command sockets are request/reply as opposed to the event sockets (which are pub/sub)
Intercepting requests from other components on the gateway is likely not that easy. You will be better off looking at enabling debug mode and/or increase verbosity via command line flags on the gateway components in question (e.g. cloudadapter) so that the commands received are logged.
Note that you can't directly use nng with tcp transport to connect to those ports exposed, instead use the mentioned socat commands from the nngforward command and execute them on your own machine or server, this essentially mirrors the nng sockets from your gateway to your own machine. You can then interact with the nng sockets as you would be on the gateway using the inter-process transport.
The command sockets are request/reply as opposed to the event sockets (which are pub/sub)
Thank you for making this clear. I now understand.
Intercepting requests from other components on the gateway is likely not that easy. You will be better off looking at enabling debug mode and/or increase verbosity via command line flags on the gateway components in question (e.g. cloudadapter) so that the commands received are logged.
Is there any documentation which command line flags are existing? With /usr/bin/cloudadapter(_native) --help or -? no output is generated.
Is there any documentation which command line flags are existing? With /usr/bin/cloudadapter(_native) --help or -? no output is generated.
--help
or -h
should work (note that it might take some time until component is being started on the gateway)
The flags that should you get the logs of the received commands is -vv
Thank you, we now see debug information. Also the sending of commands via pynng and Req0 to ipc:///tmp/lemonbeatd-command.ipc seems to be successful. Unfortunately we did not manage to connect to Rep0 to ipc:///tmp/lemonbeatd-command.ipc (Error: Address already in use).
Do you have any example for us?
Unfortunately we did not manage to connect to Rep0 to ipc:///tmp/lemonbeatd-command.ipc (Error: Address already in use).
You don't need Rep0
, this is the other side of the Req/Rep pair. You only need the Req0
and write to that socket to send a request and then read from that socket to receive the response. You can find an example in the pynng documentation (that example implements both ends)
Thank you for your hints @rettichschnidi @easybe @broglep-work.
We (@FredBit90 @andrexp) have successfully created a basic python script for communication to an own MQTT Broker.
You can use Version 1.0.1.0
We want to translate the state and lasterror values from the lemonbeat service to a description. We have already translate some codes through testing with the lawnrobot in the garden. The first idea was to use the MowerError Enumeration which is documented in the husquarna developer portal:
When i count up the enumeration starting at value 0 then you can see that value 10 equals with the documentation. We find out that for example value 15 is error lifted. In the documentation lifted is on zero based position 14 following on stuck_in_charging_station and charging_station_blocked.
The idea is that zero based values 0 to 11 equals with the API documentation. Error 12 in original documentation is no_drive. Is it possible that these error is not included in the Lemonbeat error enumeration, resulting in this shift?
Are there any documentation for the state values? In the API documentation only the MowerActivity enumeration is included, which is not comparable to the state enumeration or shows any relation to it.
There is no public documentation for those low level values and I can't help you with that unfortunately.
The reason why the API documentation does not match with what you observe on the lower level is because the officially supported API provides a conversion / compatibility layer so that all mowers can be controlled with a single interface. Internal values can be different for different mower models and the values can also change across firmware versions. You might be able to re-construct a mapping for your particular mower model & firmware version if you are using the developer API and correlate the developer API values with the internal values (e.g. pause mower via API and then check the internal values)
I'll close this issue here as we are getting a bit off topic now, this issue here regarding best method for local control has been resolved by now
Cool to see that Gardena has such a well documented open source repository.
I rooted a 19000 gateway and have SSH access to it, is it possible to locally control my garden mower?
I would like to control the mower from Home Assistant (Start, Stop, Status) without the cloud and before digging deeper into the protocols used I thought I would ask here.