mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-19 00:26:03 +00:00
36_Shelly.pm: Version 3.0. Shellybulb/Duo, Timeout für Netz sowie Zusammenarbeit mit 36_ShellyMonitor.pm
git-svn-id: https://svn.fhem.de/fhem/trunk@23525 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
bf2012387b
commit
7985a36b80
@ -39,7 +39,7 @@ use vars qw{%attr %defs};
|
||||
sub Log($$);
|
||||
|
||||
#-- globals on start
|
||||
my $version = "2.20";
|
||||
my $version = "3.0";
|
||||
|
||||
#-- these we may get on request
|
||||
my %gets = (
|
||||
@ -82,6 +82,18 @@ my %setsrgbww = (
|
||||
"pct" => "B",
|
||||
);
|
||||
|
||||
my %setsbulbw = (
|
||||
"on" => "O",
|
||||
"off" => "F",
|
||||
"toggle" => "T",
|
||||
"on-for-timer" => "X",
|
||||
"off-for-timer" => "E",
|
||||
"config" => "K",
|
||||
"password" => "P",
|
||||
"ct:colorpicker,CT,3000,10,6500" => "R",
|
||||
"pct:slider,0,1,100" => "W"
|
||||
);
|
||||
|
||||
my %setsrgbwc = (
|
||||
"on" => "O",
|
||||
"off" => "F",
|
||||
@ -98,6 +110,7 @@ my %setsrgbwc = (
|
||||
|
||||
my %shelly_models = (
|
||||
#(relays,rollers,dimmers,meters)
|
||||
"generic" => [0,0,0,0],
|
||||
"shelly1" => [1,0,0,0],
|
||||
"shelly1pm" => [1,0,0,1],
|
||||
"shelly2" => [2,1,0,1],
|
||||
@ -106,7 +119,8 @@ my %shelly_models = (
|
||||
"shelly4" => [4,0,0,4],
|
||||
"shellyrgbw" => [0,0,4,1],
|
||||
"shellydimmer" => [0,0,1,1],
|
||||
"shellyem" => [1,0,0,2]
|
||||
"shellyem" => [1,0,0,2],
|
||||
"shellybulb" => [0,0,1,1]
|
||||
);
|
||||
|
||||
my %shelly_regs = (
|
||||
@ -138,7 +152,7 @@ sub Shelly_Initialize ($) {
|
||||
$hash->{SetFn} = "Shelly_Set";
|
||||
$hash->{RenameFn} = "Shelly_Rename";
|
||||
|
||||
$hash->{AttrList}= "verbose model:".join(",",(keys %shelly_models))." mode:relay,roller,white,color defchannel maxtime maxpower interval pct100:open,closed shellyuser ".
|
||||
$hash->{AttrList}= "verbose model:".join(",",(keys %shelly_models))." mode:relay,roller,white,color defchannel maxtime maxpower interval timeout pct100:open,closed shellyuser ".
|
||||
$readingFnAttributes;
|
||||
}
|
||||
|
||||
@ -171,6 +185,7 @@ sub Shelly_Define($$) {
|
||||
#-- InternalTimer blocks if init_done is not true
|
||||
my $oid = $init_done;
|
||||
$init_done = 1;
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
my $err = Shelly_status($hash);
|
||||
if( !defined($err) ){
|
||||
@ -182,6 +197,9 @@ sub Shelly_Define($$) {
|
||||
}
|
||||
readingsEndUpdate($hash,1);
|
||||
|
||||
#-- get settings
|
||||
$err = Shelly_configure($hash,"settings/");
|
||||
|
||||
#-- perform status update in a minute or so
|
||||
InternalTimer(time()+60, "Shelly_status", $hash,0);
|
||||
|
||||
@ -255,7 +273,7 @@ sub Shelly_Attr(@) {
|
||||
my $hash = $main::defs{$name};
|
||||
my $ret;
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $mode = AttrVal($name,"mode","");
|
||||
|
||||
#-- temporary code
|
||||
@ -318,7 +336,7 @@ sub Shelly_Attr(@) {
|
||||
|
||||
if( $model =~ /shelly2.*/ ){
|
||||
$new = $pre." mode:relay,roller ".$pos;
|
||||
}elsif( $model eq "shellyrgbw" ){
|
||||
}elsif( $model =~ /shelly(rgbw|bulb)/){
|
||||
$new = $pre." mode:white,color ".$pos;
|
||||
}elsif( $model =~ /shelly.*/){
|
||||
$new = $pre." ".$pos;
|
||||
@ -327,8 +345,8 @@ sub Shelly_Attr(@) {
|
||||
|
||||
#---------------------------------------
|
||||
}elsif ( ($cmd eq "set") && ($attrName =~ /mode/) ) {
|
||||
if( $model !~ /shelly(2|(rgb)).*/ ){
|
||||
Log3 $name,1,"[Shelly_Attr] setting the mode attribute only works for model=shelly2|shelly2.5|shellyrgbw";
|
||||
if( $model !~ /shelly(2|(rgb|bulb)).*/ ){
|
||||
Log3 $name,1,"[Shelly_Attr] setting the mode attribute only works for model=shelly2|shelly2.5|shellyrgbw|shellybulb";
|
||||
return
|
||||
}
|
||||
if( $model =~ /shelly2.*/ ){
|
||||
@ -350,7 +368,7 @@ sub Shelly_Attr(@) {
|
||||
fhem("deletereading ".$name." power.*");
|
||||
fhem("deletereading ".$name." energy.*");
|
||||
fhem("deletereading ".$name." overpower.*");
|
||||
}elsif( $model eq "shellyrgbw" ){
|
||||
}elsif( $model eq "shellyrgbw" || $model eq "shellybulb" ){
|
||||
fhem("deletereading ".$name." power.*");
|
||||
fhem("deletereading ".$name." energy.*");
|
||||
fhem("deletereading ".$name." overpower.*");
|
||||
@ -359,6 +377,7 @@ sub Shelly_Attr(@) {
|
||||
return;
|
||||
}elsif( $attrVal eq "color"){
|
||||
fhem("deletereading ".$name." pct.*");
|
||||
fhem("deletereading ".$name." ct.*");
|
||||
fhem("deletereading ".$name." state_.*");
|
||||
}elsif( $attrVal eq "white"){
|
||||
fhem("deletereading ".$name." L-.*");
|
||||
@ -411,7 +430,7 @@ sub Shelly_Get ($@) {
|
||||
my $name = $hash->{NAME};
|
||||
my $v;
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $mode = AttrVal($name,"mode","");
|
||||
|
||||
#-- get version
|
||||
@ -429,9 +448,9 @@ sub Shelly_Get ($@) {
|
||||
$txt = "roller";
|
||||
}elsif( $model eq "shellydimmer" ){
|
||||
$txt = "light";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "white") ){
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "white") ){
|
||||
$txt = "white";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "color") ){
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "color") ){
|
||||
$txt = "color";
|
||||
}else{
|
||||
$txt = "relay";
|
||||
@ -446,6 +465,9 @@ sub Shelly_Get ($@) {
|
||||
$chan = $a[3];
|
||||
}elsif( int(@a) == 3 ){
|
||||
$chan = 0;
|
||||
}elsif( int(@a) == 2 ){
|
||||
$reg = "";
|
||||
$chan = undef;
|
||||
}else{
|
||||
my $msg = "Error: wrong number of parameters";
|
||||
Log3 $name,1,"[Shelly_Get] ".$msg;
|
||||
@ -453,16 +475,18 @@ sub Shelly_Get ($@) {
|
||||
}
|
||||
|
||||
my $pre = "settings/";
|
||||
if( ($model =~ /shelly2.*/) && ($mode eq "roller") ){
|
||||
$pre .= "roller/0?";
|
||||
}elsif( $model eq "shellydimmer" ){
|
||||
$pre .= "light/0?";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "white") ){
|
||||
$pre .= "white/0?";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "color") ){
|
||||
$pre .= "color/0?";
|
||||
}else{
|
||||
$pre .= "relay/$chan?";
|
||||
if( $reg ne "" ){
|
||||
if( ($model =~ /shelly2.*/) && ($mode eq "roller") ){
|
||||
$pre .= "roller/0?";
|
||||
}elsif( $model eq "shellydimmer" ){
|
||||
$pre .= "light/0?";
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "white") ){
|
||||
$pre .= "white/0?";
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "color") ){
|
||||
$pre .= "color/0?";
|
||||
}elsif( defined($chan)){
|
||||
$pre .= "relay/$chan?";
|
||||
}
|
||||
}
|
||||
$v = Shelly_configure($hash,$pre.$reg);
|
||||
|
||||
@ -531,9 +555,9 @@ sub Shelly_Set ($@) {
|
||||
my $pre = "settings/";
|
||||
if( ($model =~ /shelly2.*/) && ($mode eq "roller") ){
|
||||
$pre .= "roller/0?";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "white") ){
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "white") ){
|
||||
$pre .= "white/0?";
|
||||
}elsif( ($model eq "shellyrgbw") && ($mode eq "color") ){
|
||||
}elsif( ($model eq "shellyrgbw" || $model eq "shellybulb") && ($mode eq "color") ){
|
||||
$pre .= "color/0?";
|
||||
}else{
|
||||
$pre .= "relay/$chan?";
|
||||
@ -757,8 +781,73 @@ sub Shelly_Set ($@) {
|
||||
Shelly_dim($hash,"white/$channel","?brightness=".$value);
|
||||
}
|
||||
}
|
||||
#-- we have a Shelly dimmer type device or rgbw type device in white mode
|
||||
}elsif( ($model =~ /shellybulb.*/) && ($mode eq "white") ){
|
||||
if( $cmd eq "?" ) {
|
||||
$newkeys = join(" ", sort keys %setsbulbw);
|
||||
return "[Shelly_Set] Unknown argument " . $cmd . ", choose one of ".$newkeys;
|
||||
}
|
||||
|
||||
if( $cmd =~ /^((on)|(off)|(toggle)).*/ ){
|
||||
$channel = $value;
|
||||
if( $cmd =~ /(.*)-for-timer/ ){
|
||||
$time = $value;
|
||||
$channel = shift @a;
|
||||
}
|
||||
if( $shelly_models{$model}[2] == 1){
|
||||
$channel = 0
|
||||
}elsif( !defined($channel) || ($channel !~ /[0123]/) || $channel >= $shelly_models{$model}[3] ){
|
||||
if( !defined($channel) ){
|
||||
$channel = AttrVal($name,"defchannel",undef);
|
||||
if( !defined($channel) ){
|
||||
$msg = "Error: wrong channel $channel given and defchannel attribute not set properly";
|
||||
Log3 $name, 1,"[Shelly_Set] ".$msg;
|
||||
return $msg;
|
||||
}else{
|
||||
Log3 $name, 4,"[Shelly_Set] switching default channel $channel";
|
||||
}
|
||||
}
|
||||
}
|
||||
if( $cmd =~ /(.*)-for-timer/ ){
|
||||
$cmd = $1;
|
||||
if( $time !~ /\d+/ ){
|
||||
$msg = "Error: wrong time spec $time, must be <integer>";
|
||||
Log3 $name, 1,"[Shelly_Set] ".$msg;
|
||||
return $msg;
|
||||
}
|
||||
$cmd = $cmd."&timer=$time";
|
||||
}
|
||||
if( $cmd eq "toggle"){
|
||||
$cmd = (ReadingsVal($name,"state","off") eq "on") ? "off" : "on";
|
||||
}
|
||||
Shelly_dim($hash,"light/$channel","?turn=".$cmd);
|
||||
#Shelly_onoff($hash,"white/$channel","?turn=".$cmd);
|
||||
#-- command received via web to register local changes of the device input
|
||||
|
||||
}elsif( $cmd eq "pct" || $cmd eq "brightness" ){
|
||||
$channel = shift @a;
|
||||
if( $shelly_models{$model}[2] == 1){
|
||||
$channel = 0
|
||||
}elsif( !defined($channel) || ($channel !~ /[0123]/) || $channel >= $shelly_models{$model}[3] ){
|
||||
if( !defined($channel) ){
|
||||
$channel = AttrVal($name,"defchannel",undef);
|
||||
if( !defined($channel) ){
|
||||
$msg = "Error: wrong channel $channel given and defchannel attribute not set properly";
|
||||
Log3 $name, 1,"[Shelly_Set] ".$msg;
|
||||
return $msg;
|
||||
}else{
|
||||
Log3 $name, 4,"[Shelly_Set] dimming default channel $channel";
|
||||
}
|
||||
}
|
||||
}
|
||||
Shelly_dim($hash,"light/$channel","?brightness=".$value);
|
||||
}elsif( $cmd eq "ct" ){
|
||||
$channel = shift @a;
|
||||
Shelly_dim($hash,"light/0","?temp=".$value);
|
||||
}
|
||||
|
||||
#-- we have a Shelly rgbw type device in color mode
|
||||
}elsif( ($model =~ /shellyrgbw.*/) && ($mode eq "color")){
|
||||
}elsif( ($model =~ /shelly(rgbw|bulb).*/) && ($mode eq "color")){
|
||||
my $channel = $value;
|
||||
#-- WEB asking for command list
|
||||
if( $cmd eq "?" ) {
|
||||
@ -794,12 +883,14 @@ sub Shelly_Set ($@) {
|
||||
}
|
||||
my ($red,$green,$blue)=Color::hsv2rgb($hue,$saturation,$value);
|
||||
$cmd=sprintf("red=%d&green=%d&blue=%d",int($red*255+0.5),int($green*255+0.5),int($blue*255+0.5));
|
||||
$cmd .= "&gain=100" if ($model eq "shellybulb");
|
||||
Shelly_dim($hash,"color/0","?".$cmd);
|
||||
}elsif( $cmd eq "rgb" ){
|
||||
my $red=hex(substr($value,0,2));
|
||||
my $green=hex(substr($value,2,2));
|
||||
my $blue=hex(substr($value,4,2));
|
||||
$cmd=sprintf("red=%d&green=%d&blue=%d",$red,$green,$blue);
|
||||
$cmd .= "&gain=100" if ($model eq "shellybulb");
|
||||
Shelly_dim($hash,"color/0","?".$cmd);
|
||||
}elsif( $cmd eq "rgbw" ){
|
||||
my $red=hex(substr($value,0,2));
|
||||
@ -807,6 +898,7 @@ sub Shelly_Set ($@) {
|
||||
my $blue=hex(substr($value,4,2));
|
||||
my $white=hex(substr($value,6,2));
|
||||
$cmd=sprintf("red=%d&green=%d&blue=%d&white=%d",$red,$green,$blue,$white);
|
||||
$cmd .= "&gain=100" if ($model eq "shellybulb");
|
||||
Shelly_dim($hash,"color/0","?".$cmd);
|
||||
}elsif( $cmd eq "white" ){
|
||||
$cmd=sprintf("white=%d",$value);
|
||||
@ -837,7 +929,7 @@ sub Shelly_pwd($){
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# Shelly_configure - Configure Shelly device
|
||||
# Shelly_configure - Configure Shelly device or read general configuration
|
||||
# acts as callable program Shelly_configure($hash,$channel,$cmd)
|
||||
# and as callback program Shelly_configure($hash,$channel,$cmd,$err,$data)
|
||||
#
|
||||
@ -848,21 +940,22 @@ sub Shelly_pwd($){
|
||||
sub Shelly_configure {
|
||||
my ($hash, $cmd, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
my $net = $hash->{READINGS}{network}{VAL};
|
||||
return
|
||||
if( $net !~ /connected/ );
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/".$cmd;
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/".$cmd;
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_configure] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_configure($hash,$cmd,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_configure($hash,$cmd,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -880,6 +973,12 @@ sub Shelly_pwd($){
|
||||
return;
|
||||
}
|
||||
|
||||
#-- if settings command, we obtain only basic settings
|
||||
if( $cmd eq "settings/" ){
|
||||
$hash->{SHELLYID} = $jhash->{'device'}{'hostname'};
|
||||
return
|
||||
}
|
||||
|
||||
#-- isolate register name
|
||||
my $reg = substr($cmd,index($cmd,"?")+1);
|
||||
my $chan= substr($cmd,index($cmd,"?")-1,1);
|
||||
@ -907,17 +1006,19 @@ sub Shelly_pwd($){
|
||||
sub Shelly_status {
|
||||
my ($hash, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/status";
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/status";
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_status] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_status($hash,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_status($hash,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -941,14 +1042,12 @@ sub Shelly_pwd($){
|
||||
return;
|
||||
}
|
||||
|
||||
my $model = AttrVal($name,"model","shelly1");
|
||||
my $mode = AttrVal($name,"mode","");
|
||||
|
||||
my $mode = AttrVal($name,"mode","");
|
||||
my $channels = $shelly_models{$model}[0];
|
||||
my $rollers = $shelly_models{$model}[1];
|
||||
my $dimmers = $shelly_models{$model}[2];
|
||||
my $meters = $shelly_models{$model}[3];
|
||||
|
||||
|
||||
my ($subs,$ison,$overpower,$rpower,$rstate,$power,$energy,$rstopreason,$rcurrpos,$position,$rlastdir,$pct,$pctnormal);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
@ -1048,7 +1147,7 @@ sub Shelly_pwd($){
|
||||
readingsBulkUpdateIfChanged($hash,"last_dir".$subs,$rlastdir);
|
||||
}
|
||||
#-- we have a Shelly dimmer or RGBW white device
|
||||
}elsif( ($model eq "shellydimmer") || ($model eq "shellyrgbw" && $mode eq "white") ){
|
||||
}elsif( ($model eq "shellydimmer") || ($model eq "shellyrgbw" && $mode eq "white") ){
|
||||
for( my $i=0;$i<$dimmers;$i++){
|
||||
$subs = (($dimmers == 1) ? "" : "_".$i);
|
||||
$ison = $jhash->{'lights'}[$i]{'ison'};
|
||||
@ -1063,12 +1162,34 @@ sub Shelly_pwd($){
|
||||
readingsBulkUpdateIfChanged($hash,"overpower".$subs,$overpower);
|
||||
readingsBulkUpdateIfChanged($hash,"power".$subs,$power);
|
||||
readingsBulkUpdateIfChanged($hash,"energy".$subs,$energy);
|
||||
}
|
||||
}
|
||||
readingsBulkUpdateIfChanged($hash,"state","OK")
|
||||
if ($dimmers > 1);
|
||||
|
||||
#-- we have a Shelly Bulb / Duo in white mode
|
||||
}elsif( $model eq "shellybulb" && $mode eq "white" ){
|
||||
for( my $i=0;$i<$dimmers;$i++){
|
||||
$subs = (($dimmers == 1) ? "" : "_".$i);
|
||||
$ison = $jhash->{'lights'}[$i]{'ison'};
|
||||
$ison =~ s/0|(false)/off/;
|
||||
$ison =~ s/1|(true)/on/;
|
||||
my $bri = $jhash->{'lights'}[$i]{'brightness'};
|
||||
my $ct = $jhash->{'lights'}[$i]{'temp'};
|
||||
$overpower = $jhash->{'lights'}[$i]{'overpower'};
|
||||
$power = $jhash->{'meters'}[$i]{'power'};
|
||||
$energy = (defined($jhash->{'meters'}[$i]{'total'}))?int($jhash->{'meters'}[$i]{'total'}/6)/10:"undefined";
|
||||
readingsBulkUpdateIfChanged($hash,"state".$subs,$ison);
|
||||
readingsBulkUpdateIfChanged($hash,"pct".$subs,$bri);
|
||||
readingsBulkUpdateIfChanged($hash,"ct".$subs,$ct);
|
||||
readingsBulkUpdateIfChanged($hash,"overpower".$subs,$overpower);
|
||||
readingsBulkUpdateIfChanged($hash,"power".$subs,$power);
|
||||
readingsBulkUpdateIfChanged($hash,"energy".$subs,$energy);
|
||||
}
|
||||
readingsBulkUpdateIfChanged($hash,"state","OK")
|
||||
if ($dimmers > 1);
|
||||
|
||||
#-- we have a Shelly RGBW color device
|
||||
}elsif( $model eq "shellyrgbw" && $mode eq "color" ){
|
||||
}elsif( $model =~ /shelly(rgbw|bulb)/ && $mode eq "color" ){
|
||||
$ison = $jhash->{'lights'}[0]{'ison'};
|
||||
$ison =~ s/0|(false)/off/;
|
||||
$ison =~ s/1|(true)/on/;
|
||||
@ -1077,6 +1198,13 @@ sub Shelly_pwd($){
|
||||
my $green = $jhash->{'lights'}[0]{'green'};
|
||||
my $blue = $jhash->{'lights'}[0]{'blue'};
|
||||
my $white = $jhash->{'lights'}[0]{'white'};
|
||||
my $gain = $jhash->{'lights'}[0]{'gain'};
|
||||
if ( defined $gain && $gain != 100 ) {
|
||||
$red = int ($red*$gain/100.0);
|
||||
$blue = int ($blue*$gain/100.0);
|
||||
$green = int ($green*$gain/100.0);
|
||||
$white = int ($white*$gain/100.0);
|
||||
}
|
||||
my $rgb = sprintf("%02X%02X%02X", $red,$green,$blue);
|
||||
|
||||
readingsBulkUpdateIfChanged($hash,"rgb",$rgb);
|
||||
@ -1138,21 +1266,22 @@ sub Shelly_pwd($){
|
||||
sub Shelly_dim {
|
||||
my ($hash, $channel, $cmd, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
my $net = $hash->{READINGS}{network}{VAL};
|
||||
return
|
||||
if( $net !~ /connected/ );
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/$channel$cmd";
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/$channel$cmd";
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_dim] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_dim($hash,$channel,$cmd,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_dim($hash,$channel,$cmd,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -1229,13 +1358,12 @@ sub Shelly_pwd($){
|
||||
sub Shelly_updown {
|
||||
my ($hash, $cmd, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
my $net = $hash->{READINGS}{network}{VAL};
|
||||
return
|
||||
if( $net !~ /connected/ );
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
#-- empty cmd parameter
|
||||
@ -1243,11 +1371,13 @@ sub Shelly_pwd($){
|
||||
if( !defined($cmd) );
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/roller/0".$cmd;
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/roller/0".$cmd;
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_updown] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_updown($hash,$cmd,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_updown($hash,$cmd,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -1313,21 +1443,22 @@ sub Shelly_updown2($){
|
||||
sub Shelly_onoff {
|
||||
my ($hash, $channel, $cmd, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
my $net = $hash->{READINGS}{network}{VAL};
|
||||
return
|
||||
if( $net !~ /connected/ );
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/relay/".$channel.$cmd;
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/relay/".$channel.$cmd;
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_onoff] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_onoff($hash,$channel,$cmd,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_onoff($hash,$channel,$cmd,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -1405,22 +1536,22 @@ sub Shelly_updown2($){
|
||||
sub Shelly_meter {
|
||||
my ($hash, $channel, $err, $data) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $url;
|
||||
my $state = $hash->{READINGS}{state}{VAL};
|
||||
my $net = $hash->{READINGS}{network}{VAL};
|
||||
return
|
||||
if( $net !~ /connected/ );
|
||||
|
||||
my $model = AttrVal($name,"model","");
|
||||
|
||||
my $model = AttrVal($name,"model","generic");
|
||||
my $creds = Shelly_pwd($hash);
|
||||
|
||||
if ( $hash && !$err && !$data ){
|
||||
$url = "http://$creds".$hash->{TCPIP}."/meter/".$channel;
|
||||
my $url = "http://$creds".$hash->{TCPIP}."/meter/".$channel;
|
||||
my $timeout = AttrVal($name,"timeout",4);
|
||||
Log3 $name, 5,"[Shelly_meter] Issue a non-blocking call to $url";
|
||||
HttpUtils_NonblockingGet({
|
||||
url => $url,
|
||||
callback=>sub($$$){ Shelly_meter($hash,$channel,$_[1],$_[2]) }
|
||||
timeout => $timeout,
|
||||
callback => sub($$$){ Shelly_meter($hash,$channel,$_[1],$_[2]) }
|
||||
});
|
||||
return undef;
|
||||
}elsif ( $hash && $err ){
|
||||
@ -1466,15 +1597,20 @@ sub Shelly_updown2($){
|
||||
Notes: <ul>
|
||||
<li>The attribute <code>model</code> <b>must</b> be set</li>
|
||||
<li>This module needs the JSON package</li>
|
||||
<li>In Shelly switch devices or the Shelly dimmer device one may set URL values that are "hit" when the input or output status changes. Here one must set
|
||||
<li>In Shelly button, switch, roller or dimmer devices one may set URL values that are "hit" when the input or output status changes.
|
||||
This is useful to transmit status changes arising from locally pressed buttons directly to FHEM by setting
|
||||
<ul>
|
||||
<li> <i>Button switched ON url</i>: http://<FHEM IP address>:<Port>/fhem?XHR=1&cmd=get%20<Devicename>%20status</li>
|
||||
</ul>
|
||||
If one wants to detach the button from the output, one may generate an additional reading <i>button</i> by setting in the Shelly
|
||||
<ul>
|
||||
<li> For <i>Button switched ON url</i>: http://<FHEM IP address>:<Port>/fhem?XHR=1&cmd=set%20<Devicename>%20<b>button_on</b>%20[<channel>]</li>
|
||||
<li> For <i>Button switched OFF url</i>: http://<FHEM IP address>:<Port>/fhem?XHR=1&cmd=set%20<Devicename>%20<b>button_off</b>%20[<channel>]</li>
|
||||
<li> For <i>Output switched ON url</i>: http://<FHEM IP address>:<Port>/fhem?XHR=1&cmd=set%20<Devicename>%20<b>out_on</b>%20[<channel>]</li>
|
||||
<li> For <i>Output switched OFF url</i>: http://<FHEM IP address>:<Port>/fhem?XHR=1&cmd=set%20<Devicename>%20<b>out_off</b>%20[<channel>]</li>
|
||||
</ul>
|
||||
Attention: Of course, a csrfToken must be included as well - or a proper <i>allowed</i> device declared.</li>
|
||||
<li>If the model attribute is set to <i>generic</i>, the device does not contain any actors, it is just a placeholder for arbitrary sensors</li>
|
||||
</ul>
|
||||
|
||||
<a name="Shellyset" id="Shellyset"></a>
|
||||
<h4>Set</h4>
|
||||
For all Shelly devices
|
||||
@ -1546,8 +1682,8 @@ sub Shelly_updown2($){
|
||||
<h4>Get</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<code>get <name> config <registername> [<channel>]</code>
|
||||
<br />get the value of a configuration register and writes it in reading config</li>
|
||||
<code>get <name> config [<registername>] [<channel>]</code>
|
||||
<br />get the value of a configuration register and writes it in reading config. If the register name is omitted, only general data like e.g. the SHELLYID are fetched.</li>
|
||||
<li>
|
||||
<code>get <name> registers</code>
|
||||
<br />displays the names of the configuration registers for this device</li>
|
||||
@ -1562,13 +1698,17 @@ sub Shelly_updown2($){
|
||||
<h4>Attributes</h4>
|
||||
<ul>
|
||||
<li><code>attr <name> shellyuser <shellyuser></code><br>username for addressing the Shelly web interface</li>
|
||||
<li><<code>attr <name> model shelly1|shelly1pm|shelly2|shelly2.5|shelly4|shellyplug|shellydimmer|shellyrgbw </code>
|
||||
<br />type of the Shelly device</li>
|
||||
<li><<code>attr <name> model generic|shelly1|shelly1pm|shelly2|shelly2.5|shelly4|shellyplug|shellydimmer|shellyrgbw </code>
|
||||
<br />type of the Shelly device. >If the model attribute is set to <i>generic</i>, the device does not contain any actors,
|
||||
it is just a placeholder for arbitrary sensors</li>
|
||||
<li><code>attr <name> mode relay|roller (only for model=shelly2/2.5) mode white|color (only for model=shellyrgbw)</code>
|
||||
<br />type of the Shelly device</li>
|
||||
<li>
|
||||
<code><interval></code>
|
||||
<br />Update interval for reading in seconds. The default is 60 seconds, a value of 0 disables the automatic update. </li>
|
||||
<li>
|
||||
<code><timeout></code>
|
||||
<br />Timeout in seconds for HttpUtils_NonblockingGet. The default is 4 seconds. Careful: Use this attribute only if you get timeout errors in your log.</li>
|
||||
</ul>
|
||||
<br/>For Shelly switching devices (mode=relay for model=shelly2/2.5, standard for all other switching models)
|
||||
<ul>
|
||||
@ -1600,4 +1740,4 @@ sub Shelly_updown2($){
|
||||
Absichtlich keine deutsche Dokumentation vorhanden, die englische Version gibt es hier: <a href="commandref.html#Shelly">Shelly</a>
|
||||
</ul>
|
||||
=end html_DE
|
||||
=cut
|
||||
=cut
|
Loading…
x
Reference in New Issue
Block a user