Ecowitt API - diverse Wetterstationen

Begonnen von gent, 15 Dezember 2021, 20:52:55

Vorheriges Thema - Nächstes Thema

Elektronikus

Hier meine Definition:
define WeatherScreen GW1000_TCP 192.168.0.170 45000
attr WeatherScreen room KS300
#   DEF        192.168.0.170 45000
#   DevState   3
#   DeviceName 192.168.0.170:45000
#   FUUID      6540d137-f33f-bc07-fa0b-4a8d7f3fff580af6
#   I_GW1000_IP 192.168.0.170
#   I_GW1000_Port 45000
#   NAME       WeatherScreen
#   NOTIFYDEV  global
#   NR         231
#   NTFY_ORDER 50-WeatherScreen
#   STATE      opened
#   TYPE       GW1000_TCP
#   UpdateCmd  60
#   name       WeatherScreen
#   READINGS:
#     2023-10-31 11:36:56   state           opened
#
setstate WeatherScreen opened
setstate WeatherScreen 2023-10-31 11:36:56 state opened


Elektronikus

Das Modell ist die HP2550A, HW Version 2.0, Firmware Pro_V1.90, WiFi Firmware EasyWeather V1.6.6

Habe ich bei dem Modell eine Chance mit der GW1000_TCP Daten zu empfangen?

Schon mal vielen Dank

Elektronikus

Hallo Allerseits,
Ich habe jetzt ein kleines Python Program geschrieben, das die Daten der Wetterstation empfangen kann (Custom Setting der HP2550A) und schicke das dann über MQTT als JSON Struktur an FHEM

Vielleicht hilft das jemandem.

Viele Grüße
 
-----------
import nclib
import re
import paho.mqtt.client as mqtt
import json

# Define Regexp Filter
Tempsens =re.compile('^temp(.{0,2})f=(-?\d{1,2}\.\d*)$', re.IGNORECASE)
Humiditysens = re.compile('^humidit(y.{1,2}|y)=(\d{1,2})$', re.IGNORECASE)
Barosens = re.compile('^(.*)barom(rel|abs)(.{1,2})=(\d{1,2}\.\d*)$', re.IGNORECASE)
Winddirsens = re.compile('^wind(dir|dir_avg10m)=(\d{1,3}\.?\d?)$', re.IGNORECASE)
Windsens = re.compile('^wind(speed|spd)(mph|mph_avg10m)=(\d{1,3}.\d)$', re.IGNORECASE)
Gustsens = re.compile('^(wind|maxdaily)gus(t|tmph)=(\d{1,3}.\d)$')
Rainsens = re.compile('^(\D*)rain(ratein|in)=(\d{1,3}\.\d{3})$', re.IGNORECASE)
Solarsens = re.compile('^solarradiation=(\d{1,4}\.\d{1,3})$', re.IGNORECASE)
Batterystatus = re.compile('^(.*)batt(.{0,2})=(\d)$', re.IGNORECASE)
StationTimestamp = re.compile('^dateutc=(\d{4})-(\d{2})-(\d{2})\+(\d{2}):(\d{2}):(\d{2})$')
StationID = re.compile('^stationtype=(.*)$')
StationFrequency = re.compile('^freq=(\d{3})M$')
StationModel = re.compile('^model=(.*)$')

MQTT_HOST = 'Hier gehört die MQTT Serveradresse hin['
ACCESS_TOKEN = ''

client = mqtt.Client()
#client.on_connect = on_connect
#client.on_message = on_message


# Set access token
client.username_pw_set(ACCESS_TOKEN)

# Connect to Server using default MQTT port and 60 seconds keepalive interval
client.connect(MQTT_HOST, 1883, 600)

client.loop_start()

#------------------------------------------------------------------
# Read Weatherstation Message
#------------------------------------------------------------------
port = 46000
TCPserver = nclib.TCPServer(('0.0.0.0', int(port)))
for TCPclient in TCPserver:
    try:
      # if command was entered by the user
      # get output until dollar sign (bash --posix forces bash-X.X$)
      data = TCPclient.read_until('$')
      #print(data.decode('utf-8'), end="")  # print string of received bytes

    # handle exceptions and exiting
    except KeyboardInterrupt:
        print("\nKeyboardInterrupt")
        exit(1)
    except Exception as e:
        print("\nException Occurred\n")
        print(e)
        exit(1)
    datalines = data.decode('utf-8').split('&')
    print('\n')
    sensoren = {}
    for textelement in datalines:
        m = Tempsens.match(textelement)
        if m :
            print(f'temp{m[1]}C = {(float(m[2])-32.0)*5/9:.1f}°C')
            sensoren[f'temp{m[1]}C'] = f'{(float(m[2])-32.0)*5/9:.1f}'
           
        m = Barosens.match(textelement)
        if m :
            print (f'barom{m[1]}{m[2]}hPa = {29.262*33.86:.2f}hPa')
            sensoren[f'barom{m[1]}{m[2]}hPa'] = f'{29.262*33.86:.2f}'
           
        m = Humiditysens.match(textelement)
        if m :
            print(f'humidity{m[1][1:]}={m[2]}')
            sensoren[f'humidity{m[1][1:]}'] = f'{m[2]}'
           
        m = Winddirsens.match(textelement)
        if m :
            print (f'wind{m[1]} = {float(m[2]):.1f}°')
            sensoren[f'wind{m[1]}'] = f'{float(m[2]):.1f}'
           
        m = Windsens.match(textelement)
        if m :
            print (f'wind{m[1]}kmh{m[2][3:]} = {1.609344 * float(m[3]):.1f} km/h')
            sensoren[f'wind{m[1]}kmh{m[2][3:]}'] = f'{1.609344 * float(m[3]):.1f}'
           
        m = Gustsens.match(textelement)
        if m:
            print(f'{m[1]}gust{m[2][1:-3]} = {1.609344 * float(m[3]):.1f} km/h')
            sensoren[f'{m[1]}gust{m[2][1:-3]}kmh'] = f'{1.609344 * float(m[3]):.1f}'
           
        m = Rainsens.match(textelement)
        if m :
            print(f'{m[1]}rain{m[2][:-2]}mm = {float(m[3])*25.4:.1f} mm')
            sensoren[f'{m[1]}rain{m[2][:-2]}mm'] = f'{float(m[3])*25.4:.1f}'
           
        m = Solarsens.match(textelement)
        if m :
            print(f'solarradiation = {float(m[1]):.1f}')
            sensoren[f'solarradiation'] = f'{float(m[1]):.1f}'
           
        m = Batterystatus.match(textelement)
        if m :
            print(f'batt{m[1]+m[2]}={m[3]}')
            sensoren[f'batt{m[1]+m[2]}'] = f'{m[3]}'
           
        m = StationTimestamp.match(textelement)
        if m :
            print(f'StationTimestamp = {m[3]}.{m[2]}.{m[1]} {m[4]}:{m[5]}:{m[6]}')
            sensoren[f'StationTimestamp'] = f'{m[1]}-{m[2]}-{m[3]} {m[4]}:{m[5]}:{m[6]}'
           
        m = StationID.match(textelement)
        if m:
            print(f'StationID = {m[1]}')
            sensoren[f'StationID'] = f'{m[1]}'
           
        m = StationFrequency.match(textelement)
        if m:
            print(f'StationFreq = {m[1]} MHz')
            sensoren[f'StationFreqM'] = f'{m[1]}'
           
        m = StationModel.match(textelement)
        if m:
            print(f'StationModel = {m[1]}')
            sensoren[f'StationModel'] = f'{m[1]}'
           

    #------------------------------------------------------------------
    # Publish Weatherstation Message
    #------------------------------------------------------------------
    client.publish('tele/WeatherScreen/data', json.dumps(sensoren), 1)

    #break
   
#------------------------------------------------------------------
# MQTT aufräumen
#------------------------------------------------------------------

client.loop_stop()
client.disconnect()
TCPserver.close()
print("Disconnected :-)")
print('\n')

   

JoWiemann

Zitat von: Elektronikus am 01 November 2023, 20:15:45Hallo Allerseits,
Ich habe jetzt ein kleines Python Program geschrieben, das die Daten der Wetterstation empfangen kann (Custom Setting der HP2550A) und schicke das dann über MQTT als JSON Struktur an FHEM

Vielleicht hilft das jemandem.

Viele Grüße
   

Hallo,

klammere doch bitte den Code in Code Tags.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

Elektronikus

# -*- coding:utf-8 -*-
import nclib
import re
import paho.mqtt.client as mqtt
import json
import time

# Define Regexp Filter
Tempsens =re.compile('^temp(.{0,2})f=(-?\d{1,2}\.\d*)$', re.IGNORECASE)
Humiditysens = re.compile('^humidit(y.{1,2}|y)=(\d{1,2})$', re.IGNORECASE)
Barosens = re.compile('^(.*)barom(rel|abs)(.{1,2})=(\d{1,2}\.\d*)$', re.IGNORECASE)
Winddirsens = re.compile('^wind(dir|dir_avg10m)=(\d{1,3}\.?\d?)$', re.IGNORECASE)
Windsens = re.compile('^wind(speed|spd)(mph|mph_avg10m)=(\d{1,3}.\d)$', re.IGNORECASE)
Gustsens = re.compile('^(wind|maxdaily)gus(t|tmph)=(\d{1,3}.\d)$')
Rainsens = re.compile('^(\D*)rain(ratein|in)=(\d{1,3}\.\d{3})$', re.IGNORECASE)
Solarsens = re.compile('^solarradiation=(\d{1,4}\.\d{1,3})$', re.IGNORECASE)
Batterystatus = re.compile('^(.*)batt(.{0,2})=(\d)$', re.IGNORECASE)
StationTimestamp = re.compile('^dateutc=(\d{4})-(\d{2})-(\d{2})\+(\d{2}):(\d{2}):(\d{2})$')
StationID = re.compile('^stationtype=(.*)$')
StationFrequency = re.compile('^freq=(\d{3})M$')
StationModel = re.compile('^model=(.*)$')

MQTT_HOST = 'ehinger-server'
ACCESS_TOKEN = ''

#time.sleep(120)

client = mqtt.Client()
#client.on_connect = on_connect
#client.on_message = on_message


# Set access token
client.username_pw_set(ACCESS_TOKEN)

# Connect to Server using default MQTT port and 60 seconds keepalive interval
client.connect(MQTT_HOST, 1883, 600)

client.loop_start()

#------------------------------------------------------------------
# Read Weatherstation Message
#------------------------------------------------------------------
port = 46000
TCPserver = nclib.TCPServer(('0.0.0.0', int(port)))

for TCPclient in TCPserver:
    try:
       # if command was entered by the user
       # get output until dollar sign (bash --posix forces bash-X.X$)
       data = TCPclient.read_until('$')
       #print(data.decode('utf-8'), end="")  # print string of received bytes

    # handle exceptions and exiting
    except KeyboardInterrupt:
        print("\nKeyboardInterrupt")
        exit(1)
    except Exception as e:
        print("\nException Occurred\n")
        print(e)
        exit(1)
    datalines = data.decode('utf-8').split('&')
    sensoren = {}
    for textelement in datalines:
        m = Tempsens.match(textelement)
        if m :
            sensoren[f'temp{m[1]}C'] = f'{(float(m[2])-32.0)*5/9:.1f}'
            continue

        m = Humiditysens.match(textelement)
        if m :
            sensoren[f'humidity{m[1][1:]}'] = f'{m[2]}'
            continue

        m = Batterystatus.match(textelement)
        if m :
            sensoren[f'batt{m[1]+m[2]}'] = f'{m[3]}'
            continue

        m = Winddirsens.match(textelement)
        if m :
            sensoren[f'wind{m[1]}'] = f'{float(m[2]):.1f}'
            continue

        m = Windsens.match(textelement)
        if m :
            sensoren[f'wind{m[1]}kmh{m[2][3:]}'] = f'{1.609344 * float(m[3]):.1f}'
            continue

        m = Gustsens.match(textelement)
        if m:
            sensoren[f'{m[1]}gust{m[2][1:-3]}kmh'] = f'{1.609344 * float(m[3]):.1f}'
            continue

        m = Rainsens.match(textelement)
        if m :
            sensoren[f'{m[1]}rain{m[2][:-2]}mm'] = f'{float(m[3])*25.4:.1f}'
            continue

        m = Barosens.match(textelement)
        if m :
            sensoren[f'barom{m[1]}{m[2]}hPa'] = f'{float(m[4])*33.86:.2f}'
            continue

        m = Solarsens.match(textelement)
        if m :
            sensoren[f'solarradiation'] = f'{float(m[1]):.1f}'
            continue

        m = StationTimestamp.match(textelement)
        if m :
            sensoren[f'StationTimestamp'] = f'{m[1]}-{m[2]}-{m[3]} {m[4]}:{m[5]}:{m[6]}'
            continue

        m = StationID.match(textelement)
        if m:
            sensoren[f'StationID'] = f'{m[1]}'
            continue

        m = StationFrequency.match(textelement)
        if m:
            sensoren[f'StationFreqM'] = f'{m[1]}'
            continue

        m = StationModel.match(textelement)
        if m:
            sensoren[f'StationModel'] = f'{m[1]}'
           

    #------------------------------------------------------------------
    # Publish Weatherstation Message
    #------------------------------------------------------------------
    client.publish('tele/WeatherScreen/data', json.dumps(sensoren), 1)

    #break
   
#------------------------------------------------------------------
# MQTT aufräumen
#------------------------------------------------------------------

client.loop_stop()
client.disconnect()
TCPserver.close()
print("Disconnected :-)")
print('\n')




Elektronikus

Anbindung einer dnt WeatherScreen PRO an FHEM

Mein Modell ist die HP2550A, HW Version 2.0, Firmware Pro_V1.90, WiFi Firmware EasyWeather V1.6.6

Ich habe FHEM auf einem Raspi4 und einen mosquitto MQTT server für meine Heimautomatisierung verwendet.

Ziel war es, alle Daten lokal zu handhaben. Deswegen konnte ich auch die Implementierten Server nicht verwenden.
Dankenswerterweise kann die WeatherScreen PRO aber einen fremden Server ansprechen und dort habe ich meinen Raspi4 eingetragen.

Als Gegenstelle musste ich jetzt noch einen Server aufsetzen, der die Daten empfängt und für FHEM aufbereitet.

Als Dateinamen habe ich Read_WeatherScreen_Pro.py verwendet:
Bitte noch <hier den Namen des MQTT Servers eintragen> durch den richtigen Namen ersetzen

# -*- coding:utf-8 -*-
import nclib
import re
import paho.mqtt.client as mqtt
import json
import time

# Define Regexp Filter
Tempsens =re.compile('^temp(.{0,2})f=(-?\d{1,2}\.\d*)$', re.IGNORECASE)
Humiditysens = re.compile('^humidit(y.{1,2}|y)=(\d{1,2})$', re.IGNORECASE)
Barosens = re.compile('^(.*)barom(rel|abs)(.{1,2})=(\d{1,2}\.\d*)$', re.IGNORECASE)
Winddirsens = re.compile('^wind(dir|dir_avg10m)=(\d{1,3}\.?\d?)$', re.IGNORECASE)
Windsens = re.compile('^wind(speed|spd)(mph|mph_avg10m)=(\d{1,3}.\d)$', re.IGNORECASE)
Gustsens = re.compile('^(wind|maxdaily)gus(t|tmph)=(\d{1,3}.\d)$')
Rainsens = re.compile('^(\D*)rain(ratein|in)=(\d{1,3}\.\d{3})$', re.IGNORECASE)
Solarsens = re.compile('^solarradiation=(\d{1,4}\.\d{1,3})$', re.IGNORECASE)
Batterystatus = re.compile('^(.*)batt(.{0,2})=(\d)$', re.IGNORECASE)
StationTimestamp = re.compile('^dateutc=(\d{4})-(\d{2})-(\d{2})\+(\d{2}):(\d{2}):(\d{2})$')
StationID = re.compile('^stationtype=(.*)$')
StationFrequency = re.compile('^freq=(\d{3})M$')
StationModel = re.compile('^model=(.*)$')

MQTT_HOST = '<hier den Namen des MQTT Servers eintragen >'
ACCESS_TOKEN = ''

#time.sleep(120)

client = mqtt.Client()
#client.on_connect = on_connect
#client.on_message = on_message


# Set access token
client.username_pw_set(ACCESS_TOKEN)

# Connect to Server using default MQTT port and 60 seconds keepalive interval
client.connect(MQTT_HOST, 1883, 600)

client.loop_start()

#------------------------------------------------------------------
# Read Weatherstation Message
#------------------------------------------------------------------
port = 46000
TCPserver = nclib.TCPServer(('0.0.0.0', int(port)))

for TCPclient in TCPserver:
    try:
       # if command was entered by the user
       # get output until dollar sign (bash --posix forces bash-X.X$)
       data = TCPclient.read_until('$')
       #print(data.decode('utf-8'), end="")  # print string of received bytes

    # handle exceptions and exiting
    except KeyboardInterrupt:
        print("\nKeyboardInterrupt")
        exit(1)
    except Exception as e:
        print("\nException Occurred\n")
        print(e)
        exit(1)
    datalines = data.decode('utf-8').split('&')
    sensoren = {}
    for textelement in datalines:
        m = Tempsens.match(textelement)
        if m :
            sensoren[f'temp{m[1]}C'] = f'{(float(m[2])-32.0)*5/9:.1f}'
            continue

        m = Humiditysens.match(textelement)
        if m :
            sensoren[f'humidity{m[1][1:]}'] = f'{m[2]}'
            continue

        m = Batterystatus.match(textelement)
        if m :
            sensoren[f'batt{m[1]+m[2]}'] = f'{m[3]}'
            continue

        m = Winddirsens.match(textelement)
        if m :
            sensoren[f'wind{m[1]}'] = f'{float(m[2]):.1f}'
            continue

        m = Windsens.match(textelement)
        if m :
            sensoren[f'wind{m[1]}kmh{m[2][3:]}'] = f'{1.609344 * float(m[3]):.1f}'
            continue

        m = Gustsens.match(textelement)
        if m:
            sensoren[f'{m[1]}gust{m[2][1:-3]}kmh'] = f'{1.609344 * float(m[3]):.1f}'
            continue

        m = Rainsens.match(textelement)
        if m :
            sensoren[f'{m[1]}rain{m[2][:-2]}mm'] = f'{float(m[3])*25.4:.1f}'
            continue

        m = Barosens.match(textelement)
        if m :
            sensoren[f'barom{m[1]}{m[2]}hPa'] = f'{float(m[4])*33.86:.2f}'
            continue

        m = Solarsens.match(textelement)
        if m :
            sensoren[f'solarradiation'] = f'{float(m[1]):.1f}'
            continue

        m = StationTimestamp.match(textelement)
        if m :
            sensoren[f'StationTimestamp'] = f'{m[1]}-{m[2]}-{m[3]} {m[4]}:{m[5]}:{m[6]}'
            continue

        m = StationID.match(textelement)
        if m:
            sensoren[f'StationID'] = f'{m[1]}'
            continue

        m = StationFrequency.match(textelement)
        if m:
            sensoren[f'StationFreqM'] = f'{m[1]}'
            continue

        m = StationModel.match(textelement)
        if m:
            sensoren[f'StationModel'] = f'{m[1]}'


    #------------------------------------------------------------------
    # Publish Weatherstation Message
    #------------------------------------------------------------------
    client.publish('tele/WeatherScreen/data', json.dumps(sensoren), 1)

    #break

#------------------------------------------------------------------
# MQTT aufräumen
#------------------------------------------------------------------

client.loop_stop()
client.disconnect()
TCPserver.close()
print("Disconnected :-)")
print('\n')
unter /home/pi/Read_WeatherScreen_Pro.py



Dann einen Service mit dem Namen Wetterstation.service anlegen:
[Unit]
Description=Oeffnet Port 46000, wartet auf Messages und sendet diese an MQTT
After=anzeige.service

[Service]
ExecStart=/usr/bin/python3 -u /home/pi/Read_WeatherScreen_Pro.py
WorkingDirectory=/home/pi/myscript
StandardOutput=inherit
StandardError=inherit
RestartSec=5s
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

und mit
sudo cp ./Wetterstation.service /lib/systemd/system/ ins richtige Verzeichnis kopieren.

Starten kann man das Ganze dann mit
sudo systemctl start Wetterstation.servicetesten mit
sudo systemctl status Wetterstation.serviceund dauerhaft verankern mit
sudo systemctl enable Wetterstation.service