Shelly die Alternative zu Sonoff?!

Welche shelly hast du denn im Einsatz. Ist es richtig, dass die Shelly2 die Last messrn und schicken bzw. Sich diese Abfragen lässt?

Ich habe Shelly 2 im Produktiv Betrieb. Ja Du kannst die Werte des Gerätes ganz normal auslesen als auch aus IP-Symcon ein/ausschalten.

Get Info


$payload = GetShellyInfo();
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
var_dump($info);
$shelly_data = json_decode($info);
$type = $shelly_data->type;
var_dump($type);
$mac = $shelly_data->mac;
var_dump($mac);
$auth = $shelly_data->auth;
var_dump($auth);
$firmware = $shelly_data->fw;
var_dump($firmware);
$num_outputs = $shelly_data->num_outputs;
var_dump($num_outputs);
$num_meters = $shelly_data->num_meters;
var_dump($num_meters);
$num_rollers = $shelly_data->num_rollers;
var_dump($num_rollers);
}

function GetShellyInfo()
{
	$shelly_ip = "192.168.55.111";
	$command = "/shelly";
	$url = "http://".$shelly_ip.$command;
	$header = [];
	$info = SendShellyData($url, $header);
	return $info;
}

 function SendShellyData(string $url, array $header, array $postfields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        if (!is_null($postfields)) {
            $postdata = http_build_query($postfields);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
        }

        curl_setopt($ch, CURLOPT_URL, $url);

        $result = curl_exec($ch);
        if (curl_error($ch)) {
            trigger_error('Error:' . curl_error($ch));
        }
        $info = curl_getinfo($ch);
        curl_close($ch);

      
	return getReturnValues($info, $result);
    }

function getReturnValues(array $info, string $result)
    {
        $HeaderSize = $info['header_size'];

        $http_code = $info['http_code'];
        
        $header = explode("
", substr($result, 0, $HeaderSize));

        $body = substr($result, $HeaderSize);
      
        return ['http_code' => $http_code, 'header' => $header, 'body' => $body];
    }

Ein/Ausschalten


function PowerOn_1()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/0";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'on'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOff_1()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/0";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'off'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOn_2()
{
    $shelly_ip = "192.168.55.111";
	$command = "/relay/1";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'on'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOff_2()
{
    $shelly_ip = "192.168.55.111";
	$command = "/relay/1";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'off'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

Musst nur die IP Adresse des Shelly austauschen. Wenn Du willst kann man dann die Daten in eine Variable schreiben bzw. auch aus dem Webfront schalten.

Status auslesen


$payload = GetShellyState();
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
var_dump($info);
$shelly_data = json_decode($info);
//var_dump($shelly_data);
$wifi_connection = $shelly_data->wifi_sta->connected;
var_dump($wifi_connection);
$ssid = $shelly_data->wifi_sta->ssid;
var_dump($ssid);
$cloud_enabled = $shelly_data->cloud->enabled;
var_dump($cloud_enabled);
$cloud_connected = $shelly_data->cloud->connected;
var_dump($cloud_connected);
$time = $shelly_data->time;
var_dump($time);
$serial = $shelly_data->serial;
var_dump($serial);
$update = $shelly_data->has_update;
var_dump($update);
$mac = $shelly_data->mac;
var_dump($mac);
$relays = $shelly_data->relays;
//var_dump($relays);
$relay_1 = $relays[0];
//var_dump($relay_1);
$relay_2 = $relays[1];
//var_dump($relay_2);
$rollers = $shelly_data->rollers;
//var_dump($rollers);
$roller = $rollers[0];
//var_dump($roller);
$meters = $shelly_data->meters[0];
//var_dump($meters);
$power = $meters->power;
var_dump($power);
$is_valid = $meters->is_valid;
var_dump($is_valid);
$counter = $meters->counter;
var_dump($counter);
$ram_total = $shelly_data->ram_total;
var_dump($ram_total);
$ram_free = $shelly_data->ram_free;
var_dump($ram_free);
$uptime = $shelly_data->uptime;
var_dump($uptime);
}

$payload = GetShellyState1();
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
var_dump($info);
$shelly_data = json_decode($info);
//var_dump($shelly_data);
$ison = $shelly_data->ison;
var_dump($ison);
$has_timer = $shelly_data->has_timer;
var_dump($has_timer);
$overpower = $shelly_data->overpower;
var_dump($overpower);
$is_valid = $shelly_data->is_valid;
var_dump($is_valid);
}



$payload = GetShellyState2();
//var_dump($payload);
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
var_dump($info);
$shelly_data = json_decode($info);
//var_dump($shelly_data);
$ison = $shelly_data->ison;
var_dump($ison);
$has_timer = $shelly_data->has_timer;
var_dump($has_timer);
$overpower = $shelly_data->overpower;
var_dump($overpower);
$is_valid = $shelly_data->is_valid;
var_dump($is_valid);
}


function GetShellyState()
{
	$shelly_ip = "192.168.55.111";
	$command = "/status";
	$url = "http://".$shelly_ip.$command;
	$header = [];
	$info = SendShellyData($url, $header);
	return $info;
}

function GetShellyState1()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/0";
	$url = "http://".$shelly_ip.$command;
	$header = [];
	$info = SendShellyData($url, $header);
	return $info;
}

function GetShellyState2()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/1";
	$url = "http://".$shelly_ip.$command;
	$header = [];
	$info = SendShellyData($url, $header);
	return $info;
}

@Fonzo
Danke für die Beispiele. Die finale Firmware die MQTT unterstützt ist wohl für den 01.10 geplant :wink:

Grüße

Hallo Fonzo,
ich habe mal Deine Scripte auf die 4-Kanal Hutschienenversion angepasst, wie schaltest und wie fragst Du ab?

Außer Power 2,3,4 stehen mir jetzt die Funktionen zur Verfügung.

Da müßtest Du auch noch die Json Daten ausgelesen haben, da ich nicht so firn in PHP bin, bitte ich Dich diese Scripte mal zu zeigen.

Bemerkung zu dem Hutschienenteil:
Ich weiß gar nicht warum ich mir so’n Kopp mach von wegen Isoabstände und Bautelieauswahl, wenn ich diese Platinen sehe…
Seht selbst, allein die Abstände bei den Relais und Optokopplern…
Gruß Helmut
PS. Aber die Funktionen die das Teil per Webinterface und dem Display bietet: einfach toll und super gemacht.

Muß ja auch nicht. Steht ja nirgends das die Schalteingänge berührungssicher und potentialfrei sind. Referenz lt. Manual ist „N“. Also darfst da sowiso nicht hinlangen.

Was mich sehr interessieren würde wie genau die die Leistungsmessung hinbekommen. Insbesondere im unteren Leistungsbereich. So wie es aussieht arbeiten die ja mit einem kleinen SMD Shunt. Ob die auch den Cos Phi auswerten ? Oder einfach Strom mal Spannung und gut. Letzteres würde irgendwie zu den Chinesen passen.
Könntest du da mal ein paar Messungen machen ?

gruß
bb

berührungssicher und potentialfrei sind
Das sehe ich nicht als Problem, Überspannungsschutz Schutz gegeben Überschläge, wenn man(n) doch mal Induktiven Anteil an der Last hat.

Bei meinen Relaisplatinen habe ich > RM 5 und Isofräsungen, wenn ich mit Netzspannung arbeite und Die setze ich auch nur bei mir ein.

Messungen mach ich mal, im Moment zeittechnisch schlecht.
Gruß Helmut

Ach so meintest du das.
Ja in der Tat, bei induktiven Lasten könnts da schon mal brutzeln.
Außer der uC und die Steuerung hat L als Referenz. is aber eher unwahrscheinlich.

Ich möchte meine NeoCoolcam und die Fibaro Aktoren auch mal vermessen.
Die Plugwise Aktoren waren ja recht gut, aber bei den Teilen schwant mir böses.

Hier ein schöne Stilblüte aus dem Manual:
Parameter 99: Kalibrierung der UmgebungslichtintensitätDieser Parameter legt die kalibrierte Skala für die Umgebungshelligkeit fest. Da die Methode und die Position, dass der Sensor montiert ist, und die Abdeckung des Sensors wird Messfehler bringen, kann der Benutzer mehr reale Lichtintensität durch diese Parametereinstellung erhalten. Der Benutzer sollte die Schritte als Schläge für die Kalibrierung ausführen.Grösse: 2 Byte, Voreingestellt: 10

In Englisch ists aber auch net besser.

gruß
bb

Ich besitzte den 4 Kanal selber nicht, daher habe ich da auch keine Skripte für, das müste ich selber nachschauen. Schau doch mal einfach in die API Doku rein.

Ich habe mich schlecht ausgedrückt, ich sehe die JSON Strings, nur auswerten kann ich so was nicht. mit Get und Put geht es nicht oder per Adresszeile und für Tasmota ist die orginale Software zu gut !!

Ich dachte, Du hättest da was ala „schalte Relais 1 EIN“ als Script oder „schreibe Leistung Kanal 1 in eine Variable“ als Script.

Das ist sicher kein Unterschied zu Shelly 1

Bin schwer begeistert von dem Display und den Möglichkeiten, schade wegen des Platinenlayoutes, das könnte man sicherer machen.
Gruß Helmut

Ja habe ich ja ich lese den Status ja auch aus, siehe oben GetShellyState bzw. GetShellyState1 usw.

Da bekommst Du dann JSON zurück und in


$ison = $shelly_data->ison;

ist die Varibale mit dem Ein/Aus Zustand.
Power ist


$power = $meters->power;

Die schreibst Du dann ganz normal mit SetValue in eine IP-Symcon Variable fertig. Auf das Skript legst Du Dir einen Timer, der den Status eben so oft abholt wie Du das für sinnvoll hälst. Mit MQTT würde dann halt das stänige abfragen wegfallen. Wäre vielleicht doch ein Grund mehr mal für IP-Symcon über MQTT nachzudenken das dies offiziell einzubauen.

Kannst Du mal helfen?

Daraus habe ich den Relaisstatus für alle 4, Leistungsmessung bekomme ich aber nur für Kanal 1 (hier 1Watt) hin.
Ich habe als Auszug der Ausgabe:

string(1076) „{„wifi_sta“:{„connected“:true,„ssid“:„SSID“,„ip“:„192.168.0.66“},„cloud“:{„enabled“:false,„connected“:false},„time“:„21:45“,„serial“:1,„has_update“:false,„mac“:„a!FD19ffF607“,„relays“:[{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true}],„meters“:[{„power“:0.0,„is_valid“:true,„timestamp“:1538171118,„counters“:[0.001, 0.002, 0.002],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538171118,„counters“:[0.000, 0.000, 0.000],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538171118,„counters“:[0.000, 0.000, 0.000],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538171118,„counters“:[0.000, 0.000, 0.000],„total“:0}],„update“:{„status“:„idle“,„has_update“:false,„new_version“:„20180910-102812/v1.2.0@7b4c6583“,„old_version“:„20180910-102812/v1.2.0@7b4c6583“},„ram_total“:51388,„ram_free“:23720,„fs_size“:83081,„fs_free“:20331,„uptime“:5235}“

Kanal 1 bekomme ich so:

 $power = $meters->power;  
SetValueFloat(29799 /*[Shelly\Leistung Ka 1]*/,$power);  

Mit 1 Watt Leistung

string(1075) „{„wifi_sta“:{„connected“:true,„ssid“:„SSID“,„ip“:„192.168.0.66“},„cloud“:{„enabled“:false,„connected“:false},„time“:„22:08“,„serial“:1,„has_update“:false,„mac“:„a!FD19ffF607“,„relays“:[{„ison“:true,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true},{„ison“:false,„has_timer“:false,„overpower“:false,„is_valid“:true}],„meters“:[{„power“:1.0,„is_valid“:true,„timestamp“:1538172523,„counters“:[0.002, 0.002, 0.002],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538172523,„counters“:[0.000, 0.000, 0.000],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538172523,„counters“:[0.000, 0.000, 0.000],„total“:0},{„power“:0.0,„is_valid“:true,„timestamp“:1538172523,„counters“:[0.000, 0.000, 0.000],„total“:0}],„update“:{„status“:„idle“,„has_update“:false,„new_version“:„20180910-102812/v1.2.0@7b4c6583“,„old_version“:„20180910-102812/v1.2.0@7b4c6583“},„ram_total“:51388,„ram_free“:23720,„fs_size“:83081,„fs_free“:20331,„uptime“:6640}“

Gruß Helmut
PS Leistung habe ich bis jetzt mit einer 50Watt Halogen und einer 0,9Watt LED ausprobiert, stimmt.
Ergebnis 50W und 1W, kannst nicht meckern

edit json komplett, Kannst Du auch mal zeigen wie geschaltet wird (Funktion aufrufen geht nicht)

 function PowerOn_1()
{
    $shelly_ip = "http://192.168.0.66";
    $command = "/relay/0";
    $url = "http://".$shelly_ip.$command;
    $postfields = ['turn'    => 'on'];
    $header = ['Content-Type: application/x-www-form-urlencoded'];
    $info = SendShellyData($url, $header, $postfields);
    return $info;
}

Da musst Du schon das gesamte JSON posten sonst ist das teils Glaskugel lesen.

Ich habe es durch try and error rausbekommen, ich muß es so schreiben
meters[0]-power für Kanal1 und
meters[1]-power für Kanal2
meters[2]-power für Kanal3
meters[3]-power für Kanal4
Auszug aus Fonzo’s Script:

 if($http_code == 200)
{
$info = $payload["body"];
//var_dump($info);
$shelly_data = json_decode($info);
////var_dump($shelly_data);
$ison = $shelly_data->ison;
SetValueBoolean(41821 /*[Shelly\Kanal 1]*/, $ison);
//var_dump($ison);
$has_timer = $shelly_data->has_timer;
//var_dump($has_timer);
$overpower = $shelly_data->overpower;
//var_dump($overpower);
$is_valid = $shelly_data->is_valid;
//var_dump($is_valid);
$power = $meters[0]->power;  
SetValueFloat(29799 /*[Shelly\Leistung Ka 1]*/,$power);
}   

Nun fehlt mir noch das setzen der Kanäle über IPS.
Gruß Helmut

Ja genau


$meters1 = $shelly_data->meters[0];
$power1 = $meters1->power;
var_dump($power1);
$meters2 = $shelly_data->meters[1];
$power2 = $meters2->power;
var_dump($power2);
$meters3 = $shelly_data->meters[2];
$power3 = $meters3->power;
var_dump($power3);
$meters4 = $shelly_data->meters[3];
$power4 = $meters4->power;
var_dump($power4);

Schade, dass ich nicht gesehen hatte, dass Du am 23. den Fehler im Script berichtigt hattest, Schade, dass Du da auch nicht drauf hin gewiesen hast, nach meiner Fragerei.
Denn in der Schaltfunktion hattest Du http zuviel, ich nehme.

 function PowerOn_1()
{
    $shelly_ip = "http://192.168.0.66";
    $command = "/relay/0";
    $url = $shelly_ip.$command;
    $postfields = ['turn'    => 'on'];
    $header = ['Content-Type: application/x-www-form-urlencoded'];
    $info = SendShellyData($url, $header, $postfields);
    return $info;
	var_dump($info);
}  

statt

 function PowerOn_1()
{
    $shelly_ip = "http://192.168.0.66";
    $command = "/relay/0";
    $url = "http://".$shelly_ip.$command;
    $postfields = ['turn'    => 'on'];
    $header = ['Content-Type: application/x-www-form-urlencoded'];
    $info = SendShellyData($url, $header, $postfields);
    return $info;
	var_dump($info);
}  

Gruß Helmut
Nachtrag: in ersten Script in Deinem Beitrag 22 hast Du noch einen Schreibfehler „curl_error…“

Was geht denn nicht, bzw. was kommt für ein Fehler? Du musst alles in ein Skript kopieren.

Am besten jeweils ein Skript das ein /aus schaltet pro Kanal und ein Skript das die Standradfunktionen enthält.

Shelly schalten


function SendShellyData(string $url, array $header, array $postfields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        if (!is_null($postfields)) {
            $postdata = http_build_query($postfields);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
        }

        curl_setopt($ch, CURLOPT_URL, $url);

        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            trigger_error('Error:' . curl_error($ch));
        }
        $info = curl_getinfo($ch);
        curl_close($ch);

        
	return getReturnValues($info, $result);
    }

function getReturnValues(array $info, string $result)
    {
        $HeaderSize = $info['header_size'];

        $http_code = $info['http_code'];
        
        $header = explode("
", substr($result, 0, $HeaderSize));
        
        $body = substr($result, $HeaderSize);
        

        return ['http_code' => $http_code, 'header' => $header, 'body' => $body];
    }

function PowerOn_1()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/0";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'on'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOff_1()
{
	$shelly_ip = "192.168.55.111";
	$command = "/relay/0";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'off'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOn_2()
{
    $shelly_ip = "192.168.55.111";
	$command = "/relay/1";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'on'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

function PowerOff_2()
{
    $shelly_ip = "192.168.55.111";
	$command = "/relay/1";
	$url = "http://".$shelly_ip.$command;
	$postfields = ['turn'    => 'off'];
	$header = ['Content-Type: application/x-www-form-urlencoded'];
	$info = SendShellyData($url, $header, $postfields);
	return $info;
}

Und dann das eigentliche Skript zum Schalten
Ein


includeScript(39772 /*[Geräte\Shelly\Shelly schalten]*/);  
 
function includeScript($scriptID)
{
    $s = IPS_GetScript($scriptID);
    include($s['ScriptFile']);
}

$payload = PowerOn_1();
var_dump($payload);
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
//var_dump($info);
$shelly_data = json_decode($info);
//var_dump($shelly_data);
$ison = $shelly_data->ison;
// var_dump($ison);

if($ison)
{
	SetValue(43367 /*[Geräte\Shelly\Licht Hobbyraum]*/, true);
}
else
{
	SetValue(43367 /*[Geräte\Shelly\Licht Hobbyraum]*/, false);
}

Aus


includeScript(39772 /*[Geräte\Shelly\Shelly schalten]*/);  
 
function includeScript($scriptID)
{
    $s = IPS_GetScript($scriptID);
    include($s['ScriptFile']);
}

$payload = PowerOff_1();
var_dump($payload);
$http_code = $payload["http_code"];
if($http_code == 200)
{
$info = $payload["body"];
//var_dump($info);
$shelly_data = json_decode($info);
//var_dump($shelly_data);
$ison = $shelly_data->ison;
// var_dump($ison);

if($ison)
{
	SetValue(43367 /*[Geräte\Shelly\Licht Hobbyraum]*/, true);
}
else
{
	SetValue(43367 /*[Geräte\Shelly\Licht Hobbyraum]*/, false);
}

Letzlich must Du bei $shelly_ip nur die IP-Adresse angeben also 192.168.0.66 dann geht das auch. Ich schau mal ob ich Zeit finde das in ein Modul zu kippen dann muss man weniger eintippen bzw. anpassen.

Danke für den Hinweis habe ich korrigiert, vielleicht kippe ich die Skripte auch in ein Modul dann dann man sich nicht vertippen.

Hallo Fonzo,
Ein Modul mir all den Fähigkeiten, die das 4-Kanal Hutschienenmodul bietet, wäre toll und sicher viel Arbeit.

Wenn Du ein Modul zum Spielen brauchst, musst Du Dir deswegen nicht extra kaufen.

Ich könnte mal eine Sammelbestellung mit besseren Preisen anfragen.
Gruß Helmut

Edit: Laut Support ist eine Sammelbestellung mit besseren Preisen ist möglich, Interesse ?

Es gibt seit gestern ein offizielles Firmwareupdate mit MQTT support.

Leider sind meine bestellten Teile immer noch nicht da…

Laut Support ist eine Sammelbestellung mit besseren Preisen ist möglich, Interesse ?

Habe Interesse