Wetterstation WS980WiFi von ELV

Hi zusammen,

eigentlich sollte meine alte KS300 Wetterstation als letztes dran glauben, aber bei der Umstellung von der WU-API auf DarkSky bin ich auch auf einen Beitrag mit dieser Wetterstation gestoßen. In befreundeten Foren tauchten dann auch schon die ersten Programme zum Auslesen der Daten auf, was mich dazu bewegte zuzuschlagen :wink:

Dank einer hervorragenden Protokollbeschreibung im Hersteller-Forum war der Rest nur noch Fleißarbeit, welche ich Euch nicht vorenthalten möchte.

Anbei der erste Wurf für das Auslesen und Aufarbeiten der Daten. Laut Protokoll geht da noch mehr, aber fürs Erste sollte es reichen!
Ich lade gern alle ein es zu erweitern :cool:


<?php
################################################################################ 
# Scriptbezeichnung: Weather.WiFiStation.ips.php
# Version: 1.0.20190319
# Author:  Heiko Wilknitz (@Pitti)
#
# Abruf von Wetterdaten von einer WS980WiFi Station
#
# Beschreibung des Kommunikationsprotokolls der Wetterstation von
# R. Petzoldt (R.Petzoldt@web.de)
# https://www.elv.de/topic/protokolldefinition-zum-datenaustausch-ws980-zum-pc.html
#
# ------------------------------ Installation ----------------------------------
#
# Dieses Skript richtet automatisch alle nötigen Objekte bei manueller
# Ausführung ein. Eine weitere manuelle Ausführung setzt alle benötigten Objekte
# wieder auf den Ausgangszustand.
#
# - Neues Skript erstellen
# - Diesen PHP-Code hineinkopieren
# - Skript abspeichern
# - Skript ausführen
#
# ------------------------------ Changelog -------------------------------------
#
# 19.03.2019 - Initalversion (v1.0)
#
# ----------------------------- Konfigruration ---------------------------------
#
#
################################################################################ 

// INSTALLATION
if ($_IPS['SENDER']=='Execute') {
	$pos = 0;
	// Variablen
	$vid = CreateVariableByName($_IPS['SELF'], 'Innentemperatur', 2, '~Temperature', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Außentemperatur', 2, '~Temperature', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Gefühlte Temperatur', 2, '~Temperature', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Taupunkt', 2, '~Temperature', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Hitzeindex', 2, '~Temperature', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Innenluftfeuchtigkeit', 2, '~Intensity.1', $pos++);
	IPS_SetIcon($vid, 'Drops');
	$vid = CreateVariableByName($_IPS['SELF'], 'Außenluftfeuchtigkeit', 2, '~Intensity.1', $pos++);
	IPS_SetIcon($vid, 'Drops');
	$vid = CreateVariableByName($_IPS['SELF'], 'Absoluter Luftdruck', 2, '~AirPressure.F', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Relativer Luftdruck', 2, '~AirPressure.F', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windgeschwindigkeit', 2, '~WindSpeed.kmh', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windrichtung', 2, '~WindDirection.Text', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windböe', 2, '~WindSpeed.kmh', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/h', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Tag', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Woche', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Monat', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Jahr', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Gesamt', 2, '~Rainfall', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'Beleuchtungsstärke', 2, '~Illumination.F', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'UV Strahlung', 1, '', $pos++);
	$vid = CreateVariableByName($_IPS['SELF'], 'UV Index', 1, '', $pos++);
	// Service Update Event
	$eid = CreateEventByName($_IPS['SELF'], "StationUpdate", 5);
	IPS_SetHidden($eid, true);
	IPS_SetPosition($eid, -1);
	// Haben wir eine Station?
	FindStation();
	// Und wenn ja, welche Version
	GetVersion();
}
// TIMER EVENT
else if($_IPS['SENDER'] == 'TimerEvent') {
	// Aktuelle Daten
	GetCurrentData();
}

# ----------------------------- Functions ---------------------------------

// Extrahiert die aktuellen Wetterdaten
function GetCurrentData()
{
	// Sende-Befehl {0xff, 0xff, 0x0b, 0x00, 0x06, 0x06, 0x04, 0x19}
	$cmd=chr(0xFF).chr(0xFF).chr(0x0B).chr(0x00).chr(0x06).chr(0x04).chr(0x04).chr(0x19);
	// IP Adresse
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-ADDRESS', 3);
	$ip = GetValue($vid);
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-PORT', 1);
	$port = GetValue($vid);
	// Command senden
	if (false ===($data = ReceiveData($ip, $port, $cmd))) {
		exit();
	}
    // Formatieren/Extrahieren
	$format = 
      'x7/' .                 # Override first 7 bytes
      'n1Innentemperatur/' .  # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Aussentemperatur/' . # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Taupunkt/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Gefuehlte/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Hitze/' .            # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'C1Innenfeuchte/' .     # Get the next 1 byte
      'x1/' .                 # Override 1 byte
      'C1Aussenfeuchte/' .    # Get the next 1 byte
      'x1/' .                 # Override 1 byte
      'n1AbsDruck/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1RelDruck/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windrichtung/' .     # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windspeed/' .        # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windboe/' .          # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenH/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenD/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenW/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenM/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenY/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenS/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1Licht/' .            # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'n1UvRaw/' .            # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'C1UvIdx';              # Get the next 2 bytes
	$array = unpack($format, $data);
	// Daten manipulieren
	if($array['Innentemperatur'] >= pow(2, 15)) $array['Innentemperatur'] -= pow(2, 16); 
	if($array['Aussentemperatur'] >= pow(2, 15)) $array['Aussentemperatur'] -= pow(2, 16); 
	if($array['Gefuehlte'] >= pow(2, 15)) $array['Gefuehlte'] -= pow(2, 16); 
	if($array['Taupunkt'] >= pow(2, 15)) $array['Taupunkt'] -= pow(2, 16); 
	if($array['Hitze'] >= pow(2, 15)) $array['Hitze'] -= pow(2, 16); 
	// Daten kopieren
	$vid = CreateVariableByName($_IPS['SELF'], 'Innentemperatur', 2);
	SetValue($vid, $array['Innentemperatur'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Außentemperatur', 2);
	SetValue($vid, $array['Aussentemperatur'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Gefühlte Temperatur', 2);
	SetValue($vid, $array['Gefuehlte'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Taupunkt', 2);
	SetValue($vid, $array['Taupunkt'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Hitzeindex', 2);
	SetValue($vid, $array['Hitze'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Innenluftfeuchtigkeit', 2);
	SetValue($vid, $array['Innenfeuchte'] / 100.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Außenluftfeuchtigkeit', 2);
	SetValue($vid, $array['Aussenfeuchte'] / 100.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Absoluter Luftdruck', 2);
	SetValue($vid, $array['AbsDruck'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Relativer Luftdruck', 2);
	SetValue($vid, $array['RelDruck'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windgeschwindigkeit', 2);
	SetValue($vid, ($array['Windspeed'] /10.) * 3.6);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windrichtung', 2);
	SetValue($vid, $array['Windrichtung']);
	$vid = CreateVariableByName($_IPS['SELF'], 'Windböe', 2);
	SetValue($vid, ($array['Windboe'] /10.) * 3.6);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/h', 2);
	SetValue($vid, $array['RegenH'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Tag', 2);
	SetValue($vid, $array['RegenD'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Woche', 2);
	SetValue($vid, $array['RegenW'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Monat', 2);
	SetValue($vid, $array['RegenM'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Jahr', 2);
	SetValue($vid, $array['RegenY'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Niederschlag/Gesamt', 2);
	SetValue($vid, $array['RegenS'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'Beleuchtungsstärke', 2);
	SetValue($vid, $array['Licht'] / 10.);
	$vid = CreateVariableByName($_IPS['SELF'], 'UV Strahlung', 1);
	SetValue($vid, $array['UvRaw']);
	$vid = CreateVariableByName($_IPS['SELF'], 'UV Index', 1);
	SetValue($vid, $array['UvIdx']);
}

// WiFi Wetter Station finden (UDP Broadcast)
function FindStation($ip = '255.255.255.255', $port = 46000)
{
	// Sende-Befehl {0xff, 0xff, 0x12, 0x00, 0x04, 0x16}
	$cmd=chr(0xFF).chr(0xFF).chr(0x12).chr(0x00).chr(0x04).chr(0x16);
	
	$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
	socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); 
	// Befehl senden
	socket_sendto($sock, $cmd, strlen($cmd), 0, $ip, $port);
	// Antwort holen
	socket_recvfrom($sock, $buf, 39, 0, $ip, $port);
	// HexDump($buf);
	socket_close($sock);
	// Auslesen
	$format = 
		'x5/' .        # Get the first 2 bytes
		'C6MAC/' .     # Get the next 6 byte
		'C4IP/' .      # Get the next 4 byte
		'n1PORT/' .    # Get the next 2 byte
		'x1/' .        # Get the next 1 byte
		'A20NAME/' .   # Get the next 20 byte
		'x1';          # Get the next 1 byte
	$array = unpack($format, $buf);
	$pos = 100;
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-NAME', 3, '', $pos++);
	SetValue($vid, $array['NAME']);
	IPS_SetHidden($vid, true);
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-MAC', 3, '', $pos++);
	SetValue($vid, dechex($array['MAC1']).':'.dechex($array['MAC2']).':'.dechex($array['MAC3']).':'.dechex($array['MAC4']).':'.dechex($array['MAC5']).':'.dechex($array['MAC6']));
	IPS_SetHidden($vid, true);
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-ADDRESS', 3, '', $pos++);
	SetValue($vid, $array['IP1'].'.'.$array['IP2'].'.'.$array['IP3'].'.'.$array['IP4']);
	IPS_SetHidden($vid, true);
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-PORT', 1, '', $pos++);
	SetValue($vid, $array['PORT']);
	IPS_SetHidden($vid, true);
}

// Ermittelt die Firmware Version
function GetVersion()
{
	// Sende-Befehl {0xff, 0xff, 0x50, 0x03, 0x53}
	$cmd=chr(0xFF).chr(0xFF).chr(0x50).chr(0x03).chr(0x53);
	// IP Adresse
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-ADDRESS', 3);
	$ip = GetValue($vid);
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-PORT', 1);
	$port = GetValue($vid);
	// Command senden
	if (false ===($data = ReceiveData($ip, $port, $cmd))) {
		exit();
	}
	$format = 
		'@5/' .       # Override the first 5 bytes
		'A17Name';    # Get the next 17 byte
	$array = unpack($format, $data);
	$pos = strrpos($array['Name'], "V");
	if ($pos === false) { 
		$fw = $array['Name'];
	} else {
		$fw = substr($array['Name'], $pos);
	}
	$vid = CreateVariableByName($_IPS['SELF'], 'WS-VERSION', 3, '', 200);
	SetValue($vid, $fw);
	IPS_SetHidden($vid, true);
}

// Array daten als HEX Dump ausgeben; 16 Bytes pro Zeile
function HexDump($data, $newline=PHP_EOL)
{
	static $from = '';
	static $to = '';
	static $width = 16; # number of bytes per line
	static $pad = '.';  # padding for non-visible characters

	if ($from==='') {
		for ($i=0; $i<=0xFF; $i++) {
			$from .= chr($i);
			$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
		}
	}
	$hex = str_split(bin2hex($data), $width*2);
	$chars = str_split(strtr($data, $from, $to), $width);
	$offset = 0;
	foreach ($hex as $i => $line) {
		echo sprintf('%06X',$offset).' : '.strtoupper(implode(' ', str_split($line,2))) . ' [' . $chars[$i] . ']' . $newline;
		$offset += $width;
	}
}

// TCP Soccket Daten senden und Resultat zurückliefern
function ReceiveData($ip, $port, $cmd)
{
	// TCP Socket
	if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
		IPS_LogMessage('WetterStation', 'socket_create() fehlgeschlagen: Grund: ' . socket_strerror(socket_last_error()));
		return false;
	}
	if (socket_connect($sock, $ip, $port) === false) {
		IPS_LogMessage('WetterStation', 'socket_connect() fehlgeschlagen: Grund: ' . socket_strerror(socket_last_error($sock)));
		return false;
	}
	if (socket_write($sock, $cmd, strlen($cmd)) === false) {
		IPS_LogMessage('WetterStation', 'socket_write() fehlgeschlagen: Grund: ' . socket_strerror(socket_last_error($sock)));
		return false;
	}
	if (false === ($buf = socket_read($sock, 2048, PHP_BINARY_READ ))) {
		IPS_LogMessage('WetterStation', 'socket_read() fehlgeschlagen: Grund: '.socket_strerror(socket_last_error($sock)));
		return false;
	}
	socket_close ($sock);
    // Kommt ab und zu mal vor???
    if(strlen($buf) == 0) {
        IPS_LogMessage('WetterStation', 'socket_read() fehlgeschlagen: Grund: Länge Daten gleich Null');
        return false;
    }
	return $buf;
}

// Erzeugt eine Variable unterhalb {id} mit dem Namen {name} vom Typ [type}
// Existiert die Variable schon wird diese zurückgeliefert.
// Type: 0 = Boolean, 1 = Integer, 2 = Float, 3 = String
// Profile: leer für kein Profil, sonst Profilnamen
function CreateVariableByName($id, $name, $type, $profile = '', $pos = null) 
{
	$vid = @IPS_GetVariableIDByName($name, $id); 
	if($vid===false) {
		$vid = IPS_CreateVariable($type); 
		IPS_SetParent($vid, $id); 
		IPS_SetName($vid, $name); 
		if($profile !== '') { 
			IPS_SetVariableCustomProfile($vid, $profile); 
		}
		if($pos !== null) { 
			IPS_SetPosition($vid, $pos); 
		}
	}
	return $vid; 
}

// Erzeugt einen Timer unterhalb {id} mit dem Namen {name} um Zeit {time}
// Existiert das  Event schon wird diese zurückgeliefert.
function CreateEventByName($id, $name, $time)
{
	$eid = @IPS_GetEventIDByName($name, $id);
	if($eid===false) {
		// zyklisches Event
		$eid = IPS_CreateEvent(1);
		IPS_SetParent($eid, $id);
		IPS_SetName($eid, $name);
	}
	// tägliches Event
	IPS_SetEventCyclic($eid, 0, 1, 0, 0, 2, $time);
	IPS_SetEventActive($eid, true);
	return $eid;
}

?>

Ciao Heiko

PS: Der Monitor zu dem Teil ist echt h**lich :frowning:

Hallo Heiko,

danke für das Skript.
Da ich die Sainlogic Wetterstation umbauen wollte, aber leider das Modul verlegt habe :rolleyes:. Kommt dein Skript gerade zu rechten Zeit. Installiert - Wetterstation wird gefunden aber die Variablen nicht befüllt.


Was mache ich falsch?

VG

Andreas

PS Skript wird als fehlerhaft markiert

Hi Andreas,

Soweit sieht ja der Output recht gut aus. Er hat die Station gefunden und die Version geholt, d.h. Er kann eine TCP Verbindung zur Station aufbauen.
Steht was im Log? Bin gerade unterwegs, wird spät [emoji853] schau mal ob du mehr Infos rausholen kannst.

Gruß Heiko

Gesendet von iPhone mit Tapatalk

Hallo Heiko,

wieder Mal ein tolles Script von dir. Vielen Dank dafür.

Bei mir ist exakt das selbe Phänomen wie bei Andreas.

Eines fällt mir auf: in der MAC Adresse wird das 4. Byte nur 1-stellig angegeben?!?

20.03.2019 18:04:53 | 41005 | DEBUG   | ScriptEngine         | Skriptausführung: 41005 ~ Absender: Execute
20.03.2019 18:04:53 | 37251 | MESSAGE | VariableManager      | [SainlogicWetterstation\SainlogicWetterstationDatenAuslesen\WS-NAME] = EasyWeather-WIFI1153
20.03.2019 18:04:53 | 25188 | MESSAGE | VariableManager      | [SainlogicWetterstation\SainlogicWetterstationDatenAuslesen\WS-MAC] = b4:e6:2d:b:xx:xx
20.03.2019 18:04:53 | 51672 | MESSAGE | VariableManager      | [SainlogicWetterstation\SainlogicWetterstationDatenAuslesen\WS-ADDRESS] = 192.168.xxx.xxx
20.03.2019 18:04:53 | 28814 | MESSAGE | VariableManager      | [SainlogicWetterstation\SainlogicWetterstationDatenAuslesen\WS-PORT] = 45000
20.03.2019 18:04:53 | 19000 | MESSAGE | VariableManager      | [SainlogicWetterstation\SainlogicWetterstationDatenAuslesen\WS-VERSION] = V1.3.1
20.03.2019 18:04:53 | 41005 | DEBUG   | ScriptEngine         | Executed Script 41005 ~ Sender: Execute ~ Duration: 299 ms

Gruß
Andi

Hallo Andi

Ist mir gerade auch aufgefallen.
Bin mir nicht sicher, glaube es gibt einen fehlerhaften Socket Server (WeatherStation) Port 1024 falls dieser Socket vor dir kommt Heiko.

VG

ebenfalls Andi :stuck_out_tongue:

Hi zusammen,

also habe gerade ein komplett neues Script bei mir angelegt - Inhalt vom Forum reinkopiert - und laufen lassen - ohne jegliche Fehler :frowning:

Das mit der MAC-Adresse ist wirklich unsauber - dechex() Funktion macht keine führende Nullen, d.h. eine int(10) wird zu einem einfachen hex(A) und nicht hex(0A) - mein Fehler!
Aber die MAC Adresse ist nur Beiwerk und wird nicht verwendet, ich ändere das die Tage mal!

Der ServerSocket ist definitiv nicht von mir - läuft da noch was parallel?

Wie kann ich Euch helfen, brauche mehr Input!

Gruß Heiko

Hi nochmal,

ich habe hier ein Script was ich initial zum Testen verwendet hatte. Muss man nur überall die IP eintragen, aber vielleicht findet man so den Fehler!


<?php

//FindStation();
//GetVersion();
GetData();

function FindStation()
{
	// UDP Broadcast
	$ip = "255.255.255.255";
	$port = 46000;
	$str=chr(0xFF).chr(0xFF).chr(0x12).chr(0x00).chr(0x04).chr(0x16);
	
	$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
	socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); 
	socket_sendto($sock, $str, strlen($str), 0, $ip, $port);
	
	socket_recvfrom($sock, $buf, 39, 0, $ip, $port);
	//echo "Messagge : < $buf > , $ip : $port <br>";
	$format = 
      'C2Code/' .    # Get the first 2 bytes
      'C1Befehl/' .  # Get the next 1 bytes
      'n1Laenge/' .  # Get the next 2 bytes
      'C6MAC/' .     # Get the next 6 byte
      'C4IP/' .      # Get the next 4 byte
      'n1Port/' .    # Get the next 2 byte
      'C1Namenslaenge/' .  # Get the next 1 bytes
      'A20Name/' .    # Get the next 20 byte
      'C1CRC';       # Get the next 1 byte
			
	$array = unpack($format, $buf);
	
	echo 'Name: '.$array['Name'].', IP: '.$array['IP1'].'.'.$array['IP2'].'.'.$array['IP3'].'.'.$array['IP4'].', Port: '.$array['Port'];
	//var_dump($array;
	socket_close($sock);
}

function GetVersion()
{
	// TCP Socket
	$ip = "192.168.xxx.xxx";
	$port = 45000;
	$str=chr(0xFF).chr(0xFF).chr(0x50).chr(0x03).chr(0x53);
	$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

	if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
		echo "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . "
";
	}
	if (socket_connect($sock, $ip, $port) === false) {
		echo "socket_connect() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
	}
	$len = socket_write($sock, $str, strlen($str));
	if (false === $len) {
		echo "socket_write() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
	}
	if (false === ($buf = socket_read ($sock, 2048, PHP_BINARY_READ ))) {
		echo "socket_read() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
		return;
	}
	socket_close ($sock);

	$format = 
      '@5/' .       # Override the first 5 bytes
      'A17Name';    # Get the next 17 byte
	$array = unpack($format, $buf);
	echo $array['Name'];
}

function GetData()
{
	// TCP Socket
	$ip = "192.168.xxx.xxx";
	$port = 45000;
	// Aktuellen Data
	$str=chr(0xFF).chr(0xFF).chr(0x0B).chr(0x00).chr(0x06).chr(0x04).chr(0x04).chr(0x19);
	$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

	if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
		echo "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . "
";
	}
	if (socket_connect($sock, $ip, $port) === false) {
		echo "socket_connect() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
	}
	$len = socket_write($sock, $str, strlen($str));
	if (false === $len) {
		echo "socket_write() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
	}
	if (false === ($buf = socket_read ($sock, 2048, PHP_BINARY_READ ))) {
		echo "socket_read() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error($sock)) . "
";
		return;
	}
	socket_close ($sock);
	hex_dump($buf);
	$format = 
      'x7/' .                 # Override first 7 bytes
      'n1Innentemperatur/' .  # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Außentemperatur/' .  # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Taupunkt/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Gefuehlt/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Hitze/' .            # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'C1Innenfeuchte/' .     # Get the next 1 byte
      'x1/' .                 # Override 1 byte
      'C1Aussenfeuchte/' .    # Get the next 1 byte
      'x1/' .                 # Override 1 byte
      'n1AbsDruck/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1RelDruck/' .         # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windrichtung/' .     # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windspeed/' .        # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'n1Windboe/' .          # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenH/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenD/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenW/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenM/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenY/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1RegenS/' .           # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'N1Licht/' .            # Get the next 4 bytes
      'x1/' .                 # Override 1 byte
      'n1UvRaw/' .            # Get the next 2 bytes
      'x1/' .                 # Override 1 byte
      'C1UvIdxRaw';           # Get the next 2 bytes

	$array = unpack($format, $buf);
	if($array['Taupunkt'] >= pow(2, 15)) $array['Taupunkt'] -= pow(2, 16); 
	var_dump($array);
}


function hex_dump($data, $newline="
")
{
  static $from = '';
  static $to = '';
  static $width = 16; # number of bytes per line
  static $pad = '.'; # padding for non-visible characters

  if ($from==='') {
    for ($i=0; $i<=0xFF; $i++) {
      $from .= chr($i);
      $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
    }
  }
  $hex = str_split(bin2hex($data), $width*2);
  $chars = str_split(strtr($data, $from, $to), $width);
  $offset = 0;
  foreach ($hex as $i => $line) {
    echo sprintf('%06X',$offset).' : '.strtoupper(implode(' ', str_split($line,2))) . ' [' . $chars[$i] . ']' . $newline;
    $offset += $width;
  }
}

Hallo Heiko,

dein Test-Skript läuft bei mir endlos (Sanduhr).

Der ServerSocket ist definitiv nicht von mir - läuft da noch was parallel?

Muss ich mal nachsehen evtl. von der WMRS .

VG

Andreas

Hi Lukky,

das ist ja nicht schön :frowning:

Hast Du eine Original WS980WiFi oder eine geflashte? Geht bei Dir die WeatherSmartIP-Anwendung?

Hier bei ELV zum runterladen https://files.elv.com/Assets/Produkte/25/2504/250408/Downloads/ws980wifi_weathersmartip_v1.1_0426.zip

Ciao Heiko

Hallo Heiko,

Leider auch keine Daten. Wetterstation ist die Sainlogic unverändert. d.h. im org. Zustand.

VG

Andreas

Hallo Heiko,

Station wird gefunden. Es kommen aber auch keine Daten. Es ist die Sainlogic im org. Zustand.

VG

Andreas

Bei mir das Gleiche. Original Sainlogic.
Station wird gefunden und auch die SoftwareVersion ( EasyWeatherV1.2.2)
Auf die Anfrage nach Daten ( FF FF 0B 00 06 04 04 19 )
Bekommt man keine Antwort.

Gesendet von iPad mit Tapatalk

Sorry, aber dann bin ich da auch ratlos :frowning: Anscheinend sind die Dinger dann doch nicht ganz gleich :banghead:

Hi Heiko,

ja, irgendwo ist irgendetwas unterschiedlich. Habe auch die Sainlogic, die mit deinem Script nicht alles kommunizieren mag.
Macht aber nichts. Die Sonne scheint trotzdem noch :slight_smile:

Danke, dass du dein Wissen geteilt hast.

Gruß
Andi

Hallo Pitti,

Skript läuft perfekt. Vielen Dank.

:slight_smile:

Hallo Pitti,

gleiches bei mir. Skript läuft. Daten kommen an.

Danke und LG
Georg

Hallo,

da meine WMRS200 den Geist aufgegeben hat, ich Ersatz brauche und einen Fehlkauf vermeiden möchte eine Frage zum Verständnis:
Die ELV WS980WiFi lässt sich mit dem Skript problemlos einbinden, die Sainlogic nicht unbedingt?

Schöne Grüsse
Stephan

Hi Stephan,

was ist schon problemlos [emoji2957], aber ja - wenn man das Teil mal im eigenen WLAN hat läuft das Teil mit dem Script!

Einmal hat das Teil die WLAN-Einstellung verloren - warum auch immer- aber sonst liefert es durchgehend aller 10 min bei mir die Daten in IPS.

Gruß Heiko

Gesendet von iPhone mit Tapatalk

Hallo Heiko,

herzlichen Dank für Dein ultra-schnelles Feedback.
Ich habe jetzt bestellt und bin gespannt ob alles klappt. :wink:

Schöne Grüsse
Stephan

das Skript passt auch für die froggit WH4000SE 1 zu 1 übernehmbar :slight_smile:

Danke für deine arbeit, ich nutze das Skript jetzt dauerhaft.

Sollte es weiterentwickelt werden teste ich gern mit, am Skript helfen kann ich leider nicht, das Programmieren versuche ich erst zu verstehen.

VG
Sven