Gardena Smart Water Control

Others (MiLight, Hue, Toon etc...)

Moderator: leecollings

Post Reply
JeroenL
Posts: 54
Joined: Sunday 27 December 2015 19:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Netherlands
Contact:

Gardena Smart Water Control

Post by JeroenL »

LS,

Gardena has added a few new items in their collection.
Does any of you have any experience with the Gardena Smart Water Control in Domoticz?

Which protocol is being used? ?

Thanks for sharing your experiences.

Jeroen
stesko
Posts: 1
Joined: Monday 29 January 2018 13:50
Target OS: OS X
Domoticz version:
Contact:

Re: Gardena Smart Water Control

Post by stesko »

I've also been looking at Gardena Smart Water Control, but I haven't seen anything live.
I think they use 868MHz and Lemonbeat.
mojojojo490
Posts: 32
Joined: Saturday 03 August 2019 7:32
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Location: Netherlands, Heiloo
Contact:

Re: Gardena Smart Water Control

Post by mojojojo490 »

Hey Jeroen,

I have also this question. How to implament the Gardena Smart Control into Domoticz?
It would be nice to see in Domoticz if and when a waterzone is activated.

Rob
Starter RPi3B, Domoticz Stable 2020.2, 10x Qubino Mini Dimmer, 1x Qubino shutter
Plugwise Anna + Adam + 2x Koen-4 & 1x Floor; SolarEdge SE3000H
Dashticz v3
User avatar
waltervl
Posts: 5903
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Gardena Smart Water Control

Post by waltervl »

There is a nice Python library for this but I cannot find a Domoticz plugin based on this library.

https://github.com/py-smart-gardena/py-smart-gardena
Perhaps you can program some simple python scripts yourself?
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
thomasbaetge
Posts: 153
Joined: Wednesday 02 October 2019 11:47
Target OS: Linux
Domoticz version: 2023.1
Location: DE / BY / LT
Contact:

Re: Gardena Smart Water Control

Post by thomasbaetge »

given the last update dates for that library, it will most likely not work anymore.
They changed the whole API during the winter.

I played around with the new one a bit, using Node-Red, but I am stuck at the websocket part, because NR can not create a websocket based on a dynamic URL at runtime.
The rest of the API is a lot less informative than it used to be, they removed a lot of information (collision information, charging cycles and other stuff).

I would be happy to share my flow so far, if anyone is interested.
User avatar
waltervl
Posts: 5903
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Gardena Smart Water Control

Post by waltervl »

According the issues it is still working. I think it is used as a base for the home assistant integration.

https://github.com/py-smart-gardena/has ... art-system
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
thomasbaetge
Posts: 153
Joined: Wednesday 02 October 2019 11:47
Target OS: Linux
Domoticz version: 2023.1
Location: DE / BY / LT
Contact:

Re: Gardena Smart Water Control

Post by thomasbaetge »

hmm...yes, seems they updated the authentication bits with the new logic.
in the meantime I ran a small python program against the websocket while my Sileno was mowing outside.
The amount of information that is being transmitted has become ridiculously small, compared to what they used to have:

Code: Select all

data=b'{"id":"a13397a7-20df-4c1e-9771-6e4b260751ee","type":"COMMON","attributes":{"name":{"value":"C3PO"},"batteryLevel":{"value":60,"timestamp":"2021-05-18T15:22:55.852+0000"},"batteryState":{"value":"OK","timestamp":"2021-05-18T14:37:02.926+0000"},"rfLinkLevel":{"value":90,"timestamp":"2021-05-18T14:06:45.032+0000"},"serial":{"value":"161206172"},"modelType":{"value":"GARDENA smart Mower"},"rfLinkState":{"value":"ONLINE"}}}'
really not much in it. There used to be a lot more data for the mower that was actually usable. I used to determine an estimate of the battery life by relating charging cycles to cutting time and stuff like that. all gone now :(

maybe for irrigation there is more in it, but for the mower I will just send it home and pause the schedule when it is raining. For that, the snapshot functionality is good enough.
very disapointing.
thomasbaetge
Posts: 153
Joined: Wednesday 02 October 2019 11:47
Target OS: Linux
Domoticz version: 2023.1
Location: DE / BY / LT
Contact:

Re: Gardena Smart Water Control

Post by thomasbaetge »

So....thanks to the shitty weather over the weekend...for those of you who want to play with it...:

I took the sample websocket python program from the Gardena site, fixed a few bugs and stitched it together with MQTT.
the program does create a websocket connection and then will transmit all 'realtime' data to MQTT with the out-topic 'Gardena/out'
You also can send commands to your device(s) using 'Gardena/in'.
Part of an command request is the 'service ID', that will be appended to the service url.
This appears to be device dependend of dynamic, so you will need to send it as the request ID in every command (see my Node-Red example).

What you need:
  • Gardena Account
    Api Key (can be obtained here: https://developer.husqvarnagroup.cloud/ ... ng-started )
    MQTT broker (I have a local one that doesn't require login data)
    A machine running Python 3.8.4 (can be a windows machine, I'm running the program as a systemd service on a RPI)
    Node-Red
requirements (unless you already have them):

Code: Select all

pip install websocket
pip install websocket-client
pip install paho-mqtt
pip install requests
pip install json
in the program you need to enter your data in the top section:
  • Login information
    broker information
the program:

Code: Select all

#!/usr/bin/python3 -u
import websocket
from threading import Thread
import time
import sys
import requests
import json
import paho.mqtt.client as mqtt

# account specific values
USERNAME = 'YOUR_GARDENA_USER'
PASSWORD = 'YOUR_GIRLFRIENDS_NAME'
API_KEY = 'YOUR_API_KEY'
#MQTT Broker
BROKER = 'IP_ADRESS_OF_YOUR_MQTT_BROKER'
BROKER_PORT = 1883
# other constants
AUTHENTICATION_HOST = 'https://api.authentication.husqvarnagroup.dev'
SMART_HOST = 'https://api.smart.gardena.dev'

AUTH_TOKEN =''






class Client:
    def on_message(self, any, message):
        #print("msg", message)

        mclient.publish('Gardena/out', message)

    def on_error(self, error):
        print("error", error)

    def on_close(self):
        self.live = False
        print("### closed ###")
        sys.exit(0)

    def on_open(self, any):
        print("### connected ###")



        self.live = True

        def run(*args):
            while self.live:
                time.sleep(1)

        Thread(target=run).start()


class mqttClient:

    def on_close(self):
        self.live = False
        print("### closed ###")
        sys.exit(0)

    def on_message(client, userdata, any, message):
        #print('mqtt_in', message.payload)
        jsPayload = json.loads(message.payload)
        jdata = jsPayload['data']
        ServiceID = jdata['id']
        headers = {
        "Content-Type": "application/vnd.api+json",
        "x-api-key": API_KEY,
        "Authorization-Provider": "husqvarna",
        "Authorization": "Bearer " + AUTH_TOKEN}
        url = "https://api.smart.gardena.dev/v1/command/" + ServiceID
        response = requests.put(url, data=message.payload, headers=  headers)

        print(response)
    



if __name__ == "__main__":
    payload = {'grant_type': 'password', 'username': USERNAME, 'password': PASSWORD,
               'client_id': API_KEY}

    print("Logging into authentication system...")
    r = requests.post(f'{AUTHENTICATION_HOST}/v1/oauth2/token', data=payload)
    assert r.status_code == 200, r
    auth_token = r.json()["access_token"]
    AUTH_TOKEN = auth_token
   
    

    headers = {
        "Content-Type": "application/vnd.api+json",
        "x-api-key": API_KEY,
        "Authorization-Provider": "husqvarna",
        "Authorization": "Bearer " + auth_token
    }

    r = requests.get(f'{SMART_HOST}/v1/locations', headers=headers)
    assert r.status_code == 200, r
    assert len(r.json()["data"]) > 0, 'location missing - user has not setup system'
    location_id = r.json()["data"][0]["id"]

    payload = {
        "data": {
            "type": "WEBSOCKET",
            "attributes": {
                "locationId": location_id
            },
            "id": "does-not-matter"
        }
    }
    print("Logged in (%s), getting WebSocket ID..." % auth_token)
    r = requests.post(f'{SMART_HOST}/v1/websocket', json=payload, headers=headers)

    assert r.status_code == 201, r
    print("WebSocket ID obtained, connecting...")
    response = r.json()
    websocket_url = response["data"]["attributes"]["url"]

    #websocket.enableTrace(True)

    mclient = mqtt.Client('Gardena')
    
    mclient.connect(BROKER,BROKER_PORT)
    mclient.subscribe('Gardena/in')
    
    mclient.loop_start()
    #

    client = Client()
    MqttClient = mqttClient()
    mclient.on_message=MqttClient.on_message
     
    ws = websocket.WebSocketApp(
        websocket_url,
        on_message=client.on_message,
        on_error=client.on_error,
        on_close=client.on_close)
    ws.on_open = client.on_open
    ws.run_forever(ping_interval=150, ping_timeout=1)
sample Node-Red flow (for Mower)

Code: Select all

[{"id":"9fe51f8d.af06c","type":"tab","label":"Flow 8","disabled":false,"info":""},{"id":"d80688e4.be1028","type":"mqtt in","z":"9fe51f8d.af06c","name":"","topic":"Gardena/out","qos":"2","datatype":"auto","broker":"5660e74b.bef428","x":150,"y":80,"wires":[["e9116af1.fea438"]]},{"id":"14841d3d.db0c23","type":"debug","z":"9fe51f8d.af06c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":510,"y":80,"wires":[]},{"id":"e9116af1.fea438","type":"json","z":"9fe51f8d.af06c","name":"","property":"payload","action":"obj","pretty":false,"x":330,"y":80,"wires":[["14841d3d.db0c23","74ea86d5.089a08","d4b23963.da0cc8"]]},{"id":"8c262953.b12308","type":"mqtt out","z":"9fe51f8d.af06c","name":"","topic":"Gardena/in","qos":"","retain":"","broker":"5660e74b.bef428","x":1190,"y":440,"wires":[]},{"id":"b6745cd8.5ecb4","type":"inject","z":"9fe51f8d.af06c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":440,"wires":[["295ebdb4.1a8662"]]},{"id":"295ebdb4.1a8662","type":"function","z":"9fe51f8d.af06c","name":"Park until further notice","func":"\nvar id = flow.get(\"SERVICE_ID\")\nmsg.payload = {\n    \"data\":{\n          \"type\": \"MOWER_CONTROL\", \n          \"id\": id, \n          \"attributes\": {\n          \"command\": \"PARK_UNTIL_FURTHER_NOTICE\",\n          \"seconds\": 60\n        }\n}}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":370,"y":380,"wires":[["8c262953.b12308","7347f335.0d26dc"]]},{"id":"ac15ac94.147ec","type":"function","z":"9fe51f8d.af06c","name":"Resume operation","func":"var id = flow.get(\"SERVICE_ID\")\nmsg.payload = {\n    \"data\":{\n          \"type\": \"MOWER_CONTROL\", \n          \"id\": id, \n          \"attributes\": {\n          \"command\": \"START_DONT_OVERRIDE\",\n          \"seconds\": 60\n        }\n}\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":370,"y":480,"wires":[["8c262953.b12308","3fa17324.9b990c"]]},{"id":"874637d4.05ad08","type":"inject","z":"9fe51f8d.af06c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":500,"wires":[["ac15ac94.147ec"]]},{"id":"9d4c3f71.21ff9","type":"mqtt in","z":"9fe51f8d.af06c","name":"","topic":"domoticz/out","qos":"2","datatype":"auto","broker":"54505e91.d17d1","x":100,"y":580,"wires":[["2445fe7d.7bb1f2"]]},{"id":"2445fe7d.7bb1f2","type":"json","z":"9fe51f8d.af06c","name":"","property":"payload","action":"obj","pretty":false,"x":270,"y":580,"wires":[["abcddc25.dcb56","65e59f6a.7dc0f"]]},{"id":"abcddc25.dcb56","type":"function","z":"9fe51f8d.af06c","name":"Rain sensor","func":"var enabled = flow.get(\"ENABLED\")\nif (msg.payload.idx == \"14\" && enabled === 1)\n{\n\n\n\nvar rain = parseInt(msg.payload.svalue1)\n\nif (rain > 40)\n{msg.payload = \"true\" }\nif (rain < 10)\n{msg.payload = \"false\" }\n\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":440,"y":580,"wires":[["402589a0.1bb2c8"]]},{"id":"402589a0.1bb2c8","type":"rbe","z":"9fe51f8d.af06c","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":580,"y":580,"wires":[["87d8725c.19f35"]]},{"id":"87d8725c.19f35","type":"switch","z":"9fe51f8d.af06c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"true","vt":"str"},{"t":"eq","v":"false","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":700,"y":580,"wires":[["295ebdb4.1a8662"],["f5382574.cbcec8"]]},{"id":"f5382574.cbcec8","type":"delay","z":"9fe51f8d.af06c","name":"","pauseType":"delay","timeout":"30","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":880,"y":580,"wires":[["ac15ac94.147ec"]]},{"id":"7347f335.0d26dc","type":"function","z":"9fe51f8d.af06c","name":"message parking","func":"    msg.payload = \n   {\"command\": \"sendnotification\",\n    \"subject\": \"C3PO\",\n    \"body\": \"Robot is parking until next schedule\",\n    \"priority\": 0}\nreturn msg;","outputs":1,"noerr":0,"x":890,"y":320,"wires":[["217538dc.05c828"]]},{"id":"3fa17324.9b990c","type":"function","z":"9fe51f8d.af06c","name":"message resuming","func":"    msg.payload = \n   {\"command\": \"sendnotification\",\n    \"subject\": \"C3PO\",\n    \"body\": \"Robot is resuming schedule\",\n    \"priority\": 0}\nreturn msg;","outputs":1,"noerr":0,"x":890,"y":360,"wires":[["217538dc.05c828"]]},{"id":"217538dc.05c828","type":"mqtt out","z":"9fe51f8d.af06c","name":"","topic":"domoticz/in","qos":"","retain":"","broker":"1afefb3e.65c825","x":1210,"y":340,"wires":[]},{"id":"74ea86d5.089a08","type":"function","z":"9fe51f8d.af06c","name":"Extract Service ID","func":"\n//Service.Id\nif (msg.payload.type == \"DEVICE\")\n\nflow.set(\"SERVICE_ID\", msg.payload.relationships.services.data[1].id)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":540,"y":160,"wires":[[]]},{"id":"65e59f6a.7dc0f","type":"function","z":"9fe51f8d.af06c","name":"Main Switch","func":"if (msg.payload.idx == 464)\n{\n    flow.set(\"ENABLED\", msg.payload.nvalue)\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":430,"y":640,"wires":[["fd6d3be9.b6e2f8"]]},{"id":"1815d8e3.802f87","type":"switch","z":"9fe51f8d.af06c","name":"","property":"payload.idx","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":710,"y":640,"wires":[["ac15ac94.147ec"],["295ebdb4.1a8662"]]},{"id":"fd6d3be9.b6e2f8","type":"rbe","z":"9fe51f8d.af06c","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":590,"y":640,"wires":[["1815d8e3.802f87"]]},{"id":"d4b23963.da0cc8","type":"function","z":"9fe51f8d.af06c","name":"Parse Battery level and mower status","func":"var newmsg = {headers: \"\", payload:\"\", topic:\"\"}\nif (msg.payload.type == \"COMMON\")\n{\n\nnewmsg.payload = { \n    \"command\": \"udevice\",\n    \"idx\" :389,\n        \"nvalue\" :msg.payload.attributes.batteryLevel.value,\n    \"svalue\" :msg.payload.attributes.batteryLevel.value.toString()}\n\nreturn newmsg;\n}\nif (msg.payload.type == \"MOWER\")\n{\n    \n    newmsg.payload = { \n    \"command\": \"udevice\",\n    \"idx\" :393,\n    \"nvalue\" :0,\n    \"svalue\" :msg.payload.attributes.activity.value.toString()\n}\n    return newmsg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":620,"y":220,"wires":[["217538dc.05c828"]]},{"id":"5660e74b.bef428","type":"mqtt-broker","z":"","name":"Controlberry","broker":"192.168.2.40","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"54505e91.d17d1","type":"mqtt-broker","name":"Controlberry","broker":"192.168.2.40","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1afefb3e.65c825","type":"mqtt-broker","name":"Controlberry","broker":"192.168.2.40","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
Please note:
I am not a python developer, so the program may be a bit rough around the edges. Some additional error handling may be required. Feel free to adjust to your needs. That beeing said, anything you may break is entirely on you.

I'm running this for a few days now and so far it works as expected.
if this turns out to be a usable thing, maybe some real developer can make a plugin out of it.
I can only test it with my mower, but it should work with irrigation too.
unfortunately, the API documentation is the same kind of crappy as the API itself.
mikje
Posts: 3
Joined: Thursday 13 February 2020 9:28
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Gardena Smart Water Control

Post by mikje »

Hi

I Don;t see why I should install the pyhton script and where the relation with the Nodered flow is.
Where is the pyhton script called from the node red (as i presume that it is called)

gr
Mikje
thomasbaetge
Posts: 153
Joined: Wednesday 02 October 2019 11:47
Target OS: Linux
Domoticz version: 2023.1
Location: DE / BY / LT
Contact:

Re: Gardena Smart Water Control

Post by thomasbaetge »

Well....first of all I do not really expect you to do anything... :)
I'm just presenting the results of a rainy long weekend here, that led me to develop a usable solution to interface Gardena smart devices to NR and domoticz for now.

meaning no offense, but from what I understand in your message, you don't seem to be familiar with the concept of P&S interfaces in general and the MQTT protocol specifically.

the python program simply provides bi-directional interaction of the proprietary REST API from husqvarna/Garden with standard MQTT protocol.
from there you can then use it from Node-Red to implement logic and/or feed it into Domoticz, like in the small Node-Red example flow I provided.
That flow feeds a few domoticz devices and implements a simple logic that sends my mower home when it is raining above a specified rate. Additionally it provides a 'Main Switch' that suspends mower operation if required, which may be useful, if you got kids playing outside or having your gardener running around.

Any other solution may work too :)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest