Help needed python gardena smartwater websocket (SLL problem) Topic is solved

Python and python framework

Moderator: leecollings

Post Reply
zicht
Posts: 271
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Help needed python gardena smartwater websocket (SLL problem)

Post by zicht »

Code: Select all

import websocket
import datetime
from threading import Thread
import time
import sys
import requests
import json

# account specific values
CLIENT_ID = 'xxxxxxxxxx-xxxx-xxxx-xxxx-MYCLIENTID'
CLIENT_SECRET = 'xxxxxxxxxx-xxxx-xxxx-xxxx-MYSECRET'
API_KEY = 'xxxxxxxxxx-xxxx-xxxx-xxxx-MYKEY'

# other constants
AUTHENTICATION_HOST = 'https://api.authentication.husqvarnagroup.dev'
SMART_HOST = 'https://api.smart.gardena.dev'

class Client:
    def restart():
        import sys
        print("argv was",sys.argv)
        print("sys.executable was", sys.executable)
        print("restart now")

        import os
        os.execv(sys.executable, ['python'] + sys.argv)
    
    def on_message(self, ws, message):
        x = datetime.datetime.now()
         
        ws.messages_count+=1
        print("--")
        print("msg ", x.strftime("%H:%M:%S") + " " + str(ws.messages_count))
        print(message)
        sys.stdout.flush()
        thisdict = dict(json.loads(message))
        if thisdict["type"]=="COMMON" :
           message = "bat:" + str(thisdict["attributes"]["batteryLevel"]["value"]) 
           message = message + " lev:" + str(thisdict["attributes"]["rfLinkLevel"]["value"]) 
           message = message + " stat:" + str(thisdict["attributes"]["rfLinkState"]["value"]) 
                      
        if thisdict["type"]=="SENSOR" :
           message = "soilHum: " + str(thisdict["attributes"]["soilHumidity"]["value"]) 
           message = message + " soilTemp:" + str(thisdict["attributes"]["soilTemperature"]["value"]) 
           
           
        if thisdict["type"]=="VALVE" :
           #print("naam " + str(thisdict["attributes"]["name"]["value"]))
           message=str(thisdict["attributes"]["activity"]["value"]) 
           
           
    def on_error(self, ws, error):
        x = datetime.datetime.now()
        print("error ", x.strftime("%H:%M:%S"))
        print(error)

    def on_close(self, ws, close_status_code, close_msg):
        self.live = False
        x = datetime.datetime.now()
        print("closed ", x.strftime("%H:%M:%S,%f"))
        print("### closed ###")
        if close_status_code:
            print("status code: "+str(close_status_code))
        if close_msg:
            print("status message: "+str(close_msg))
        client.restart
        

    def on_open(self, ws):
        x = datetime.datetime.now()
        print("connected ", x.strftime("%H:%M:%S,%f"))
        print("### connected ###")

        self.live = True

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

        Thread(target=run).start()

def format(response):
    formatted = [response.url, "%s %s" % (response.status_code, response.reason)]
    for k,v in response.headers.items():
        formatted.append("%s: %s" % (k, v))
    formatted.append("")
    formatted.append(r.text)
    return "\n".join(formatted)

if __name__ == "__main__":
    while True:
        try:
            payload = {'grant_type': 'client_credentials', 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET}

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

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

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

            payload = {
                "data": {
                    "type": "WEBSOCKET",
                    "attributes": {
                        "locationId": location_id
                    },
                    "id": "does-not-matter"
                }
            }
            print("\ngetting websocket ID...")
            r = requests.post(f'{SMART_HOST}/v1/websocket', json=payload, headers=headers)

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

            websocket.enableTrace(True)  #True om raw output in display te hebben
            client = Client()
            ws = websocket.WebSocketApp(
                websocket_url, 
                on_message=client.on_message,
                on_error=client.on_error,
                on_close=client.on_close)
            ws.messages_count = 0         # Create a counter and an empty list to store messages
            ws.on_open = client.on_open
            ws.run_forever(ping_interval=120, ping_timeout=3)
        except Exception as e:
            gc.collect()
            print("Websocket connection Error  : {0}".format(e))                    
        print("Reconnecting websocket  after 600 sec")
        time.sleep(600)
The above code was working before but i paused the domoticz integration.
Now i tried to start implementing, but when testing it i run into an ssl problem.

The response i get :

Code: Select all

Logging into authentication system...

### get locations ###

getting websocket ID...

Websocket ID obtained, connecting...
error  12:10:05
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997) - goodbye
closed  12:10:05,445888
### closed ###
Reconnecting websocket  after 600 sec
As i am just an noob on python, it seems impossible for me to solve this ssl problem.
Maybe one of the domoticz members with python knowledge can help me out ?

Thanks in advance
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
Thorgal789
Posts: 833
Joined: Wednesday 15 August 2018 14:38
Target OS: -
Domoticz version:
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by Thorgal789 »

Hello, have you tried just with using "hhtp" instead of "https" ? Some API support both.
Else can try with certifi

Code: Select all

import certifi
response = requests.get('https://your-server-url', verify=certifi.where())
Or disable verification

Code: Select all

import requests
response = requests.get('https://your-server-url', verify=False)
zicht
Posts: 271
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by zicht »

thnx wil try that.
All goes well until i open de the websocket ... so will try both to see if it works.
No way arround the HTTPS ...

i need the ssl implementation on this part

Code: Select all

client = Client()
            ws = websocket.WebSocketApp(
                websocket_url, 
                on_message=client.on_message,
                on_error=client.on_error,
                on_close=client.on_close)

till there its running fine.
As in the log is visible the websocket is called succesfully, but on the above part i get the SSL error.
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
zicht
Posts: 271
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by zicht »

Solvedit by :

Code: Select all

            ws.run_forever(ping_interval=120, ping_timeout=3[b][u][i], sslopt={"cert_reqs": ssl.CERT_NONE}[/i][/u][/b])
many thanks, now lets find out how to integrate domoticz. if anyone interested, i can post updates in the forum ?
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
User avatar
waltervl
Posts: 5397
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by waltervl »

If possible make a python plugin out of it....
I believe there is already a Gardena/Husqvarna plugin but for mowers...
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
zicht
Posts: 271
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by zicht »

waltervl wrote: Sunday 12 January 2025 15:34 If possible make a python plugin out of it....
I believe there is already a Gardena/Husqvarna plugin but for mowers...
I am a bit stuck at the plugin structure and how to port into a plugin. Any possiility to point me at the mower plugin ?
Cant find it (to use it as an example would be really helpfull) but maybe i'm searching at the wrong places

As an intemediate solution :
I have compiled my python into and exe (for windows use) : that saves some processor time --> In the past i did this also for roomba with good results. It dumps values (update strings) into a text sensor and can be handled from there by handling the json textstring in a script. (If anyone interested i can disclose the files)
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
User avatar
waltervl
Posts: 5397
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Help needed python gardena smartwater websocket (SLL problem)

Post by waltervl »

This is an Husqvarna mowers plugin but Gardena seems to use something similar. viewtopic.php?t=39624
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests