2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2024-11-22 09:49:50 +00:00

mqtt2.template: change WLED, thx to DeeSPe

git-svn-id: https://svn.fhem.de/fhem/trunk@25360 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2021-12-21 05:31:01 +00:00
parent 602317afe8
commit 51543dbae7
4 changed files with 187 additions and 24 deletions

View File

@ -4698,43 +4698,55 @@ name:wled_controller
filter:TYPE=MQTT2_DEVICE
desc:To control a WLED device, see https://github.com/Aircoookie/WLED/wiki for details).
order:W_01
par:BASE_ID;BASE_ID typically is wled;{ AttrVal("DEVICE","readingList","") =~ m,([^:]+)[/][^/]+[/][^/]+:, ? $1 : undef }
par:DEVNAME;Device name as configured;{ AttrVal("DEVICE","readingList","") =~ m,[^:]+[/]([^/]+)[/][^/]+:, ? $1 : undef }
par:ICON;ICON as set, defaults to hue_filled_iris;{ AttrVal("DEVICE","icon","hue_filled_iris") }
{ Svn_GetFile('contrib/AttrTemplate/99_attrT_WLED_Utils.pm', 'FHEM/99_attrT_WLED_Utils.pm', sub(){ CommandReload(undef, '99_attrT_WLED_Utils') }) }
par:BASE_ID;BASE_ID typically is wled;{ AttrVal('DEVICE','readingList','') =~ m,([^:]+)[/][^/]+[/][^/]+:, ? $1 : undef }
par:DEVNAME;Device name as configured;{ AttrVal('DEVICE','readingList','') =~ m,[^:]+[/]([^/]+)[/][^/]+:, ? $1 : undef }
par:ICON;ICON as set, defaults to hue_filled_iris;{ AttrVal('DEVICE','icon','hue_filled_iris') }
attr DEVICE icon ICON
attr DEVICE setList\
on:noArg BASE_ID/DEVNAME on\
off:noArg BASE_ID/DEVNAME off\
toggle:noArg BASE_ID/DEVNAME t\
rgb:colorpicker,RGB BASE_ID/DEVNAME/col #$EVTPART1\
brightness:colorpicker,BRI,0,1,255 BASE_ID/DEVNAME\
brightness:colorpicker,BRI,0,1,255 BASE_ID/DEVNAME/api A=$EVTPART1\
dimup:noArg BASE_ID/DEVNAME/api A=~10\
dimdown:noArg BASE_ID/DEVNAME/api A=~-10\
speed:colorpicker,BRI,0,1,255 BASE_ID/DEVNAME/api SX=$EVTPART1\
intensity:colorpicker,BRI,0,1,255 BASE_ID/DEVNAME/api IX=$EVTPART1\
palette:selectnumbers,0,1,46,0,lin BASE_ID/DEVNAME/api FP=$EVTPART1\
effect:selectnumbers,0,1,101,0,lin BASE_ID/DEVNAME/api FX=$EVTPART1\
loadPreset:selectnumbers,0,1,3,0,lin BASE_ID/DEVNAME/api PL=$EVTPART1\
dimup:noArg BASE_ID/DEVNAME/api A=~10\
dimdown:noArg BASE_ID/DEVNAME/api A=~-10
effect:{'selectnumbers,0,1,'.ReadingsNum($name,'.effectscount',5).',0,lin'} BASE_ID/DEVNAME/api FX=$EVTPART1\
effectname:{'select,'.join(',',sort(split(',',ReadingsVal($name,'.effects','Solid,Police'))))} {FHEM::attrT_WLED_Utils::WLED_set($NAME,'effect',$EVTPART1)}\
effect_next:noArg BASE_ID/DEVNAME/api FX=~1\
effect_prev:noArg BASE_ID/DEVNAME/api FX=~-1\
effect_random:noArg BASE_ID/DEVNAME/api FX=r\
effect_reset:noArg BASE_ID/DEVNAME/api FX=0\
palette:{'selectnumbers,0,1,'.ReadingsNum($name,'.palettescount',5).',0,lin'} BASE_ID/DEVNAME/api FP=$EVTPART1\
palettename:{'select,'.join(',',sort(split(',',ReadingsVal($name,'.palettes','Default,Party'))))} {FHEM::attrT_WLED_Utils::WLED_set($NAME,'palette',$EVTPART1)}\
palette_next:noArg BASE_ID/DEVNAME/api FP=~1\
palette_prev:noArg BASE_ID/DEVNAME/api FP=~-1\
palette_random:noArg BASE_ID/DEVNAME/api FP=r\
palette_reset:noArg BASE_ID/DEVNAME/api FP=0\
preset:selectnumbers,0,1,15,0,lin BASE_ID/DEVNAME/api PL=$EVTPART1\
apiraw BASE_ID/DEVNAME/api $EVTPART1\
seg BASE_ID/DEVNAME/api {'seg':{'i':[$EVTPART1,[$EVTPART2]]}}
attr DEVICE readingList \
BASE_ID/DEVNAME/status:.* LWT\
BASE_ID/DEVNAME/g:.* brightness\
BASE_ID/DEVNAME/g:.* { $EVENT ? {"state"=>"on"} : {"state"=>"off"} }\
BASE_ID/DEVNAME/c:.* { {"rgb"=>substr("$EVENT",1,6)} }\
BASE_ID/DEVNAME/v:.* api\
BASE_ID/DEVNAME/v:.* { $EVENT =~ m,(?<=<sx>)([\d]+)(?=<\/sx>), ? $1 eq ReadingsVal($NAME,"speed","unknown") ? return : {"speed"=>$1} : return; }\
BASE_ID/DEVNAME/v:.* {$EVENT =~ m,(?<=<ix>)([\d]+)(?=<\/ix>), ? $1 eq ReadingsVal($NAME,"intensity","unknown") ? return : {"intensity"=>$1} : return }\
BASE_ID/DEVNAME/v:.* {$EVENT =~ m,(?<=<fp>)([\d]+)(?=<\/fp>), ? $1 eq ReadingsVal($NAME,"palette","unknown") ? return : {"palette"=>$1} : return }\
BASE_ID/DEVNAME/v:.* {$EVENT =~ m,(?<=<fx>)([\d]+)(?=<\/fx>), ? $1 eq ReadingsVal($NAME,"effect","unknown") ? return :{"effect"=>"$1"} : return }
BASE_ID/DEVNAME/g:.* {$EVENT ? {state => 'on'} : {state => 'off'}}\
BASE_ID/DEVNAME/c:.* {{rgb => substr($EVENT,1,6)}}\
BASE_ID/DEVNAME/v:.* {FHEM::attrT_WLED_Utils::WLED_get($NAME,$EVENT)}
deletereading -q DEVICE (?!associatedWith|IODev).*
attr DEVICE devStateIcon {Color::devStateIcon( $name, "rgb", "rgb", "brightness", "state" )}
attr DEVICE eventMap /effect 0:Solid/effect 2:Breathe/effect 63:Pride/effect 48:Police/
attr DEVICE webCmd rgb:brightness:Solid:Breathe:Pride:Police
attr DEVICE setStateList on off toggle
attr DEVICE devStateIcon {ReadingsVal($name,'LWT','offline') eq 'offline' ? '.*:message_attention@red' : Color::devStateIcon($name,'rgb','rgb','brightness','state')}
attr DEVICE webCmd rgb:brightness:effectname:speed:intensity:palettename:preset
attr DEVICE webCmdLabel RGB:Brightness\
:Effect:Speed:Intensity\
:Palette:Preset
attr DEVICE setStateList on off toggle dimdown dimup effect_prev effect_next effect_random palette_prev palette_next palette_random palette_reset effect_reset
attr DEVICE comment For questions about the use of different widgets for color selection see discussion at https://forum.fhem.de/index.php/topic,98880.msg995308.html
set DEVICE attrTemplate speechcontrol_type_light_255
farewell:template has been applied successfully. <br>Note: webCmd and eventMap are just examples; adopt this to your needs.
attr DEVICE model wled_controller
setreading DEVICE attrTemplateVersion 20200522 or prior
setreading DEVICE attrTemplateVersion 20211220
###########################################

View File

@ -0,0 +1,149 @@
##############################################
# $Id$
# contributed by DeeSPe, https://forum.fhem.de/index.php/topic,98880.msg1192196.html#msg1192196
package FHEM::attrT_WLED_Utils; ## no critic 'Package declaration'
use strict;
use warnings;
use GPUtils qw(GP_Import);
## Import der FHEM Funktionen
BEGIN {
GP_Import(
qw(
defs
InternalVal
ReadingsVal
ReadingsNum
AttrVal
readingsBeginUpdate
readingsBulkUpdate
readingsBulkUpdateIfChanged
readingsEndUpdate
HttpUtils_NonblockingGet
)
);
}
sub ::attrT_WLED_Utils_Initialize { goto &Initialize }
# initialize ##################################################################
sub Initialize {
my $hash = shift;
return;
}
# Enter you functions below _this_ line.
sub WLED_get {
my $dev = shift // return;
my $event = shift // undef;
my $c;
my $h = {
sx => 'speed',
ix => 'intensity',
fp => 'palette',
fx => 'effect',
ps => 'preset'
};
for (keys %{$h}) {
next if $event !~ m/(?<=<$_>)([\d]+)(?=<\/$_>)/x;
if ($1 != ReadingsNum($dev,$h->{$_},-2)){
$c->{$h->{$_}} = $1;
}
}
my $io = InternalVal($dev,'LASTInputDev',AttrVal($dev,'IODev',InternalVal($dev,'IODev',undef)->{NAME})) // return defined $event ? $c : undef;
my $ip = InternalVal($dev,$io.'_CONN',ReadingsVal($dev,'ip', undef)) =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/x ? $1 : return defined $event ? $c : undef;
HttpUtils_NonblockingGet({
url=>"http://$ip/json",
callback=>sub($$$){
my ($hash,$err,$data) = @_;
WLED_setReadings($dev,$data);
}
});
return defined $event ? $c : undef;
}
sub WLED_setReadings {
my $dev = shift // return;
my $data = shift // return;
my $fx = $data =~ m/effects..\[([^[]*?)]/x ? WLED_subst($1) : '';
my $pl = $data =~ m/palettes..\[([^[]*?)]/x ? WLED_subst($1) : '';
my $hash = $defs{$dev};
my @f = split m{,}, $fx;
my @p = split m{,}, $pl;
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,'effectname',$f[ReadingsNum($dev,'effect',0)]);
readingsBulkUpdate($hash,'palettename',$p[ReadingsNum($dev,'palette',0)]);
readingsEndUpdate($hash,1);
readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged($hash,'.effectscount',(scalar @f)-1);
readingsBulkUpdateIfChanged($hash,'.effects',$fx);
readingsBulkUpdateIfChanged($hash,'.palettescount',(scalar @p)-1);
readingsBulkUpdateIfChanged($hash,'.palettes',$pl);
readingsEndUpdate($hash,0);
return;
}
sub WLED_subst {
my $s = shift;
$s =~ s/["\n]//gx;
$s =~ s/[\s\&]/_/gx;
$s =~ s/\+/Plus/gx;
return $s;
}
sub WLED_set {
my $dev = shift // return;
my $read = shift // return;
my $val = shift // return;
my $wled = lc(InternalVal($dev,'CID',undef)) // return;
my $arr = ReadingsVal($dev,'.'.$read.'s',undef) // return WLED_get($dev);
$wled =~ s/_/\//;
my $top = $wled.'/api F';
$top .= $read eq 'effect'?'X=':'P=';
my $id;
my $i = 0;
for (split(',',$arr)){
if ($_ ne $val) {
$i++;
next;
} else {
$id = $i;
last;
}
}
return defined $id ? $top.$id : undef;
}
1;
__END__
=pod
=item summary helper functions needed for WLED MQTT2_DEVICE
=item summary_DE needed Hilfsfunktionen für WLED MQTT2_DEVICE
=begin html
<a id="attrT_WLED_Utils"></a>
<h3>attrT_WLED_Utils</h3>
<ul>
<b>Functions to support attrTemplates for WLEDs</b><br>
</ul>
<ul>
<li><b>FHEM::attrT_WLED_Utils::WLED_get</b><br>
<code>FHEM::attrT_WLED_Utils::WLED_get($$)</code><br>
This is used to provide some readings from the API.
</li>
</ul>
<ul>
<li><b>FHEM::attrT_WLED_Utils::WLED_set</b><br>
<code>FHEM::attrT_WLED_Utils::WLED_set($$$)</code><br>
This is used to set the effects and palettes with their names.
</li>
</ul>
=end html
=cut

View File

@ -1,5 +1,5 @@
##############################################
# $Id: attrTmqtt2_roborock_Utils.pm 2020-01-19 Beta-User $
# $Id$
#
package main;

View File

@ -3162,8 +3162,10 @@ sub RHASSPY_ParseHttpResponse {
$siteIds = encode($cp,$ref->{$_}{satellite_site_ids});
}
}
my @ids = uniq(split q{,},$siteIds);
readingsBulkUpdate($hash, 'siteIds', join q{,}, @ids);
if ( $siteIds ) {
my @ids = uniq(split m{,},$siteIds);
readingsBulkUpdate($hash, 'siteIds', join q{,}, @ids);
}
}
elsif ( $url =~ m{api/intents}ix ) {
my $refb;