2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-01 15:44:52 +00:00

mqtt2.template: small changes to tasmota venetian blind mode

git-svn-id: https://svn.fhem.de/fhem/trunk@25369 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2021-12-24 05:50:17 +00:00
parent 773740f876
commit 15255fbf1d
2 changed files with 85 additions and 98 deletions
fhem
FHEM/lib/AttrTemplate
contrib/RHASSPY

@ -1529,7 +1529,7 @@ set DEVICE,DEVICE_CH2 attrTemplate speechcontrol_type_blind
name:tasmota_2ch_shutter_venetian_invert_0 name:tasmota_2ch_shutter_venetian_invert_0
filter:TYPE=MQTT2_DEVICE:FILTER=readingList=.*(tele|cmnd|stat).* filter:TYPE=MQTT2_DEVICE:FILTER=readingList=.*(tele|cmnd|stat).*
desc:Configures a dual chanel tasmota device as venetian shutter; needs Tasmota version 10.0.0.1 or higher, see <a href="https://github.com/arendst/Tasmota/wiki/blinds-and-roller-shades">Tasmota wiki</a><br> and <a href="https://forum.fhem.de/index.php/topic,123842.0.html">Forum Thread</a><br>NOTE: This template will configure the shutter in Homematic-style device pct 100% = open. desc:Configures a dual chanel tasmota device as venetian shutter; needs Tasmota version 10.0.0.1 or higher, see <a href="https://github.com/arendst/Tasmota/wiki/blinds-and-roller-shades">Tasmota wiki</a><br> and <a href="https://forum.fhem.de/index.php/topic,123842.0.html">Forum Thread</a><br>NOTE: This template will configure the shutter in Homematic-style device pct 100% = open, and for a tilt range from -90 to 90 degrees.
order:A_02b3 order:A_02b3
par:CMNDTOPIC;Command topic prefix, without trailing /;{ AttrVal('DEVICE','readingList','') =~ m,([^:]*)\b(tele|cmnd|stat)(/.*)?/LWT:, ? "${1}cmnd$3" : undef } par:CMNDTOPIC;Command topic prefix, without trailing /;{ AttrVal('DEVICE','readingList','') =~ m,([^:]*)\b(tele|cmnd|stat)(/.*)?/LWT:, ? "${1}cmnd$3" : undef }
par:TELETOPIC;info topic prefix, without trailing /;{ AttrVal('DEVICE','readingList','') =~ m,([^:]*)\b(tele|cmnd|stat)(/.*)?/LWT:, ? "${1}tele$3" : undef } par:TELETOPIC;info topic prefix, without trailing /;{ AttrVal('DEVICE','readingList','') =~ m,([^:]*)\b(tele|cmnd|stat)(/.*)?/LWT:, ? "${1}tele$3" : undef }
@ -1564,27 +1564,26 @@ attr DEVICE readingList \
STATTOPIC/RESULT:.* { json2nameValue($EVENT,'',$JSONMAP) }\ STATTOPIC/RESULT:.* { json2nameValue($EVENT,'',$JSONMAP) }\
STATTOPIC/POWER1:.* {{'state' => 'opening'} if $EVENT eq 'on'}\ STATTOPIC/POWER1:.* {{'state' => 'opening'} if $EVENT eq 'on'}\
STATTOPIC/POWER2:.* {{'state' => 'closing'} if $EVENT eq 'on'} STATTOPIC/POWER2:.* {{'state' => 'closing'} if $EVENT eq 'on'}
attr DEVICE devStateIcon opening:fts_shutter_up@red closing:fts_shutter_down@red Online:10px-kreis-gruen Offline:10px-kreis-rot 100:fts_shutter_100 0:fts_shutter_10 9\d.*:fts_shutter_90 8\d.*:fts_shutter_80 7\d.*:fts_shutter_70 6\d.*:fts_shutter_60 5\d.*:fts_shutter_50 4\d.*:fts_shutter_40 3\d.*:fts_shutter_30 2\d.*:fts_shutter_20 1\d.*:fts_shutter_10 \b\d\b.*:fts_shutter_10 set_.*:fts_shutter_updown attr DEVICE devStateIcon opening:fts_shutter_up@red:stop closing:fts_shutter_down@red:stop Online:10px-kreis-gruen Offline:10px-kreis-rot 0:fts_shutter_100 100:fts_shutter_10 \b\d\b.*:fts_shutter_90 1\d.*:fts_shutter_80 2\d.*:fts_shutter_70 3\d.*:fts_shutter_60 4\d.*:fts_shutter_50 5\d.*:fts_shutter_40 6\d.*:fts_shutter_30 7\d.*:fts_shutter_20 8\d.*:fts_shutter_10 9\d.*:fts_shutter_10 set_.*:fts_shutter_updown
attr DEVICE cmdIcon open:fts_shutter_up close:fts_shutter_down stop:fts_shutter_manual half:fts_shutter_50 attr DEVICE cmdIcon open:fts_shutter_up close:fts_shutter_down stop:fts_shutter_manual half:fts_shutter_50
attr DEVICE webCmd :open:close:half:stop:pct attr DEVICE webCmd :open:close:half:stop:pctopenSlat:closeSlat:halfSlat:tiltSlat
attr DEVICE eventMap open:opens close:closes attr DEVICE eventMap open:opens close:closes
attr DEVICE jsonMap POWER1:0 POWER2:0 Shutter1_Tilt:tiltSlat Shutter1_Target:pct ANALOG_Temperature:temperature attr DEVICE jsonMap POWER1:0 POWER2:0 Shutter1_Tilt:tiltSlat Shutter1_Target:pct ANALOG_Temperature:temperature
attr DEVICE userReadings state:pct:.* {ReadingsNum($name,"pct",0)} attr DEVICE userReadings state:pct:.* {ReadingsNum($name,'pct',0)}
attr DEVICE stateFormat <a href="http://IPAddress" target="_blank">\ attr DEVICE stateFormat <a href="http://IPAddress" target="_blank">\
LWT\ LWT\
</a>\ </a>\
state\ state\
tiltSlat tiltSlat
deletereading -q DEVICE (?!associatedWith|IODev).* deletereading -q DEVICE (?!associatedWith|IODev).*
attr DEVICE setStateList open close half stop pct attr DEVICE setStateList open close half stop pct openSlat closeSlat halfSlat
attr DEVICE comment After applying the template set "ShutterOpenDuration1", "ShutterCloseDuration1" and "shuttertiltconfig1" first.\ attr DEVICE comment After applying the template set "ShutterOpenDuration1", "ShutterCloseDuration1" and "shuttertiltconfig1" first.\
Use the "set x_configuration" Option. Example: "set x_configuration ShutterOpenDuration1 35"\ Use the "set x_configuration" Option. Example: "set x_configuration ShutterOpenDuration1 35".\
Shutter specific commands available: ShutterOpenDuration1, ShutterCloseDuration1, ShutterRelay1, ShutterSetHalfway1, ShutterSetClose1, ShutterInvert1, ShutterMotordelay1, ShutterCalibration1; you may use this for general setOptions in tasmota also.\ This is for a tilt range from -90 to 90 degrees, if you have different tilt options, adopt range manually\
commands may need restart to take effect.\ For calibration, tilt range settings, use of more than one shutter device and further information on the available commands see <a href="https://tasmota.github.io/docs/Blinds-and-Shutters/</a>.
For calibration, use of more than one shutter device and further information on the available commands see <a href="https://tasmota.github.io/docs/Blinds-and-Shutters/</a>.
farewell:template has been applied successfully. Now it's recommended to set shutter's open and close duration and shuttertiltconfig1, see short instruction in comment attribute or the <br><a href="https://tasmota.github.io/docs/Blinds-and-Shutters/">Tasmota wiki</a>. farewell:template has been applied successfully. Now it's recommended to set shutter's open and close duration and shuttertiltconfig1, see short instruction in comment attribute or the <br><a href="https://tasmota.github.io/docs/Blinds-and-Shutters/">Tasmota wiki</a>.
attr DEVICE model tasmota_2ch_shutter_venetian_invert_0 attr DEVICE model tasmota_2ch_shutter_venetian_invert_0
setreading DEVICE attrTemplateVersion 20211116 setreading DEVICE attrTemplateVersion 20211224
option:{ CALLSPEECHRECOGN } option:{ CALLSPEECHRECOGN }
set DEVICE attrTemplate speechcontrol_type_blind set DEVICE attrTemplate speechcontrol_type_blind

@ -3340,38 +3340,38 @@ sub handleIntentShortcuts {
sub handleIntentSetOnOff { sub handleIntentSetOnOff {
my $hash = shift // return; my $hash = shift // return;
my $data = shift // return; my $data = shift // return;
my ($value, $numericValue, $device, $room, $siteId, $mapping, $response);
Log3($hash->{NAME}, 5, "handleIntentSetOnOff called"); Log3($hash->{NAME}, 5, "handleIntentSetOnOff called");
# Device AND Value must exist # Device AND Value must exist
if ( exists $data->{Device} && exists $data->{Value} ) { return respond( $hash, $data, getResponse($hash, 'NoValidData') ) if !defined $data->{Device} || !defined $data->{Value};
$room = getRoomName($hash, $data);
$value = $data->{Value};
$device = getDeviceByName($hash, $room, $data->{Device});
$mapping = getMapping($hash, $device, 'SetOnOff');
# Mapping found? my $room = getRoomName($hash, $data);
if ( defined $device && defined $mapping ) { my $device = getDeviceByName($hash, $room, $data->{Device}) // return respond( $hash, $data, getResponse($hash, 'NoDeviceFound') );
#check if confirmation is required my $mapping = getMapping($hash, $device, 'SetOnOff') // return respond( $hash, $data, getResponse($hash, 'NoMappingFound') );
return $hash->{NAME} if !$data->{Confirmation} && getNeedsConfirmation( $hash, $data, 'SetOnOff', $device ); my $value = $data->{Value};
my $cmdOn = $mapping->{cmdOn} // 'on';
my $cmdOff = $mapping->{cmdOff} // 'off';
my $cmd = $value eq 'on' ? $cmdOn : $cmdOff;
# execute Cmd # Mapping found?
analyzeAndRunCmd($hash, $device, $cmd); #check if confirmation is required
Log3($hash->{NAME}, 5, "Running command [$cmd] on device [$device]" ); return $hash->{NAME} if !$data->{Confirmation} && getNeedsConfirmation( $hash, $data, 'SetOnOff', $device );
my $cmdOn = $mapping->{cmdOn} // 'on';
my $cmdOff = $mapping->{cmdOff} // 'off';
my $cmd = $value eq 'on' ? $cmdOn : $cmdOff;
# Define response # execute Cmd
if ( defined $mapping->{response} ) { analyzeAndRunCmd($hash, $device, $cmd);
$numericValue = $value eq 'on' ? 1 : 0; Log3($hash->{NAME}, 5, "Running command [$cmd] on device [$device]" );
$response = _getValue($hash, $device, _shuffle_answer($mapping->{response}), $numericValue, $room);
Log3($hash->{NAME}, 5, "Response is $response" ); # Define response
} my $response;
else { $response = getResponse($hash, 'DefaultConfirmation'); } if ( defined $mapping->{response} ) {
} #my $numericValue = $value eq 'on' ? 1 : 0;
$response = _getValue($hash, $device, _shuffle_answer($mapping->{response}), $value eq 'on' ? 1 : 0, $room);
Log3($hash->{NAME}, 5, "Response is $response" );
} }
else { $response = getResponse($hash, 'DefaultConfirmation'); }
# Send response # Send response
$response //= getResponse($hash, 'DefaultError'); $response //= getResponse($hash, 'DefaultError');
respond( $hash, $data, $response ); respond( $hash, $data, $response );
@ -3411,11 +3411,8 @@ sub handleIntentSetOnOffGroup {
my $needs_sorting = (@{$hash->{".asyncQueue"}}); my $needs_sorting = (@{$hash->{".asyncQueue"}});
for my $device (@devlist) { for my $device (@devlist) {
my $mapping = getMapping($hash, $device, 'SetOnOff'); my $mapping = getMapping($hash, $device, 'SetOnOff') // next;
# Mapping found?
next if !defined $mapping;
my $cmdOn = $mapping->{cmdOn} // 'on'; my $cmdOn = $mapping->{cmdOn} // 'on';
my $cmdOff = $mapping->{cmdOff} // 'off'; my $cmdOff = $mapping->{cmdOff} // 'off';
my $cmd = $value eq 'on' ? $cmdOn : $cmdOff; my $cmd = $value eq 'on' ? $cmdOn : $cmdOff;
@ -3445,63 +3442,61 @@ sub handleIntentSetOnOffGroup {
sub handleIntentSetTimedOnOff { sub handleIntentSetTimedOnOff {
my $hash = shift // return; my $hash = shift // return;
my $data = shift // return; my $data = shift // return;
my ($value, $numericValue, $device, $room, $siteId, $mapping, $response);
Log3($hash->{NAME}, 5, "handleIntentSetTimedOnOff called"); Log3($hash->{NAME}, 5, "handleIntentSetTimedOnOff called");
return respond( $hash, $data, getResponse( $hash, 'duration_not_understood' ) ) return respond( $hash, $data, getResponse( $hash, 'duration_not_understood' ) )
if !defined $data->{Hourabs} && !defined $data->{Hour} && !defined $data->{Min} && !defined $data->{Sec}; if !defined $data->{Hourabs} && !defined $data->{Hour} && !defined $data->{Min} && !defined $data->{Sec};
# Device AND Value must exist
return if !exists $data->{Device} || !exists $data->{Value};
$room = getRoomName($hash, $data); # Device AND Value must exist
$value = $data->{Value}; return respond( $hash, $data, getResponse($hash, 'NoValidData') ) if !defined $data->{Device} || !defined $data->{Value};
$device = getDeviceByName($hash, $room, $data->{Device});
$mapping = getMapping($hash, $device, 'SetOnOff'); my $room = getRoomName($hash, $data);
my $device = getDeviceByName($hash, $room, $data->{Device}) // return respond( $hash, $data, getResponse($hash, 'NoDeviceFound') );
my $mapping = getMapping($hash, $device, 'SetOnOff') // return respond( $hash, $data, getResponse($hash, 'NoMappingFound') );
my $value = $data->{Value};
# Mapping found? # Mapping found?
if ( defined $device && defined $mapping ) { return $hash->{NAME} if !$data->{Confirmation} && getNeedsConfirmation( $hash, $data, 'SetTimedOnOff', $device );
return $hash->{NAME} if !$data->{Confirmation} && getNeedsConfirmation( $hash, $data, 'SetTimedOnOff', $device ); my $cmdOn = $mapping->{cmdOn} // 'on';
my $cmdOn = $mapping->{cmdOn} // 'on'; my $cmdOff = $mapping->{cmdOff} // 'off';
my $cmdOff = $mapping->{cmdOff} // 'off'; my $cmd = $value eq 'on' ? $cmdOn : $cmdOff;
my $cmd = $value eq 'on' ? $cmdOn : $cmdOff; $cmd .= "-for-timer";
$cmd .= "-for-timer";
my $allset = getAllSets($device); my $allset = getAllSets($device);
return respond( $hash, $data, getResponse($hash, 'NoTimedOnDeviceFound') ) if $allset !~ m{\b$cmd(?:[\b:\s]|\Z)}xms; return respond( $hash, $data, getResponse($hash, 'NoTimedOnDeviceFound') ) if $allset !~ m{\b$cmd(?:[\b:\s]|\Z)}xms;
my $hour = 0; my $hour = 0;
my $now1 = time; my $now1 = time;
my $now = $now1; my $now = $now1;
my @time = localtime($now); my @time = localtime($now);
if ( defined $data->{Hourabs} ) { if ( defined $data->{Hourabs} ) {
$hour = $data->{Hourabs}; $hour = $data->{Hourabs};
$now1 = $now1 - ($time[2] * HOURSECONDS) - ($time[1] * MINUTESECONDS) - $time[0]; #last midnight $now1 = $now1 - ($time[2] * HOURSECONDS) - ($time[1] * MINUTESECONDS) - $time[0]; #last midnight
}
elsif ($data->{Hour}) {
$hour = $data->{Hour};
}
$now1 += HOURSECONDS * $hour;
$now1 += MINUTESECONDS * $data->{Min} if $data->{Min};
$now1 += $data->{Sec} if $data->{Sec};
$now1 += +DAYSECONDS if $now1 < $now;
$now1 = $now1 - $now;
$cmd .= " $now1";
# execute Cmd
analyzeAndRunCmd($hash, $device, $cmd);
Log3($hash->{NAME}, 5, "Running command [$cmd] on device [$device]" );
# Define response
if ( defined $mapping->{response} ) {
$numericValue = $value eq 'on' ? 1 : 0;
$response = _getValue($hash, $device, _shuffle_answer($mapping->{response}), $numericValue, $room);
Log3($hash->{NAME}, 5, "Response is $response" );
}
else { $response = getResponse($hash, 'DefaultConfirmation'); }
} }
elsif ($data->{Hour}) {
$hour = $data->{Hour};
}
$now1 += HOURSECONDS * $hour;
$now1 += MINUTESECONDS * $data->{Min} if $data->{Min};
$now1 += $data->{Sec} if $data->{Sec};
$now1 += +DAYSECONDS if $now1 < $now;
$now1 = $now1 - $now;
$cmd .= " $now1";
# execute Cmd
analyzeAndRunCmd($hash, $device, $cmd);
Log3($hash->{NAME}, 5, "Running command [$cmd] on device [$device]" );
# Define response
my $response;
if ( defined $mapping->{response} ) {
my $numericValue = $value eq 'on' ? 1 : 0;
$response = _getValue($hash, $device, _shuffle_answer($mapping->{response}), $numericValue, $room);
Log3($hash->{NAME}, 5, "Response is $response" );
}
else { $response = getResponse($hash, 'DefaultConfirmation'); }
# Send response # Send response
$response //= getResponse($hash, 'DefaultError'); $response //= getResponse($hash, 'DefaultError');
respond( $hash, $data, $response ); respond( $hash, $data, $response );
@ -4908,18 +4903,13 @@ __END__
# Farben: # Farben:
Warum die Abfrage nach rgb? <code>if ( defined $data->{Colortemp} && defined $mapping->{rgb} && looks_like_number($data->{Colortemp}) ) {</code> Warum die Abfrage nach rgb? <code>if ( defined $data->{Colortemp} && defined $mapping->{rgb} && looks_like_number($data->{Colortemp}) ) {</code>
Gibt auch Lampen, die können nur ct Gibt auch Lampen, die können nur ct (Beta-User: unklare Frage: der fragliche Zweig wird nur bei "falschem ct" angesteuert, ansonsten wird schon vorher "nativ" ct verwendet)
# Custom Intents # Custom Intents
- Bei Verwendung des Dialouges wenn man keine Antwort spricht, bricht Rhasspy ab. Die voice response "Tut mir leid, da hat etwas zu lange gedauert" wird - Bei Verwendung des Dialouges wenn man keine Antwort spricht, bricht Rhasspy ab. Die voice response "Tut mir leid, da hat etwas zu lange gedauert" wird
also gar nicht ausgegeben und: also gar nicht ausgegeben und: (Beta-User: klingt nach "silent cancelation", grade keine Idee).
PERL WARNING: Use of uninitialized value $cmd in pattern match (m//) at fhem.pl line 5868. PERL WARNING: Use of uninitialized value $cmd in pattern match (m//) at fhem.pl line 5868. (Beta-User: nicht mehr zuordenbar)
# "rhasspySpecials" bzw. rhasspyTweaks als weitere Attribute
Denkbare Verwendung:
- siteId2room für mobile Geräte (Denkbare Anwendungsfälle: Auswertung BT-RSSI per Perl, aktives Setzen über ein Reading? Oder einen intent? (tweak)
- Bestätigungs-Mapping (special) (ist noch offen)
# Sonstiges, siehe insbes. https://forum.fhem.de/index.php/topic,119447.msg1148832.html#msg1148832 # Sonstiges, siehe insbes. https://forum.fhem.de/index.php/topic,119447.msg1148832.html#msg1148832
- kein "match in room" bei GetNumeric - kein "match in room" bei GetNumeric
@ -4928,13 +4918,11 @@ Denkbare Verwendung:
- gDT: mehr und bessere mappings? - gDT: mehr und bessere mappings?
- Farbe und Farbtemperatur (fast fertig?) - Farbe und Farbtemperatur (fast fertig?)
- Hat man in einem Raum einen Satelliten aber kein Device mit der siteId/Raum, kann man den Satelliten bei z.B. dem Timer nicht ansprechen, weil der Raum nicht in den Slots ist. - Hat man in einem Raum einen Satelliten aber kein Device mit der siteId/Raum, kann man den Satelliten bei z.B. dem Timer nicht ansprechen, weil der Raum nicht in den Slots ist.
Irgendwie müssen wir die neue siteId in den Slot Rooms bringen Irgendwie müssen wir die neue siteId in den Slot Rooms bringen (erl. mit extrarooms?)
# Parameter-Check für define? Anregung DrBasch aus https://forum.fhem.de/index.php/topic,119447.msg1157700.html#msg1157700 # Parameter-Check für define? Anregung DrBasch aus https://forum.fhem.de/index.php/topic,119447.msg1157700.html#msg1157700 (erl.)
# Keine shortcuts-Intents, wenn Attribut nicht gesetzt: Anregung DrBasch aus https://forum.fhem.de/index.php/topic,119447.msg1157700.html#msg1157700 (erl.) # Doku zu den "üblichen Formaten" (z.B. JSON-Keywords beginnen mit Großbuchstaben)? (erl. (?))
# Doku zu den "üblichen Formaten" (z.B. JSON-Keywords beginnen mit Großbuchstaben)?
=end ToDo =end ToDo
@ -4949,7 +4937,7 @@ https://forum.fhem.de/index.php/topic,113180.msg1130139.html#msg1130139
# Wetterdurchsage # Wetterdurchsage
Ist möglich. Dazu hatte ich einen rudimentären Intent in diesem Thread erstellt. Müsste halt nur erweitert werden. Ist möglich. Dazu hatte ich einen rudimentären Intent in diesem Thread erstellt. Müsste halt nur erweitert werden.
https://forum.fhem.de/index.php/topic,113180.msg1130754.html#msg1130754 https://forum.fhem.de/index.php/topic,113180.msg1130754.html#msg1130754 (evtl. ersetzt durch STATE-Abfrage/gDT info?)
=end ToClarify =end ToClarify