From 0d53a82eb2c1debe1fb1ddde81de560588678e68 Mon Sep 17 00:00:00 2001 From: Byte09 <> Date: Sat, 28 Mar 2020 09:35:23 +0000 Subject: [PATCH] 98_Siro.pm: no longer available through svn git-svn-id: https://svn.fhem.de/fhem/trunk@21530 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_Siro.pm | 2022 ------------------------------------------ 1 file changed, 2022 deletions(-) delete mode 100644 fhem/FHEM/98_Siro.pm diff --git a/fhem/FHEM/98_Siro.pm b/fhem/FHEM/98_Siro.pm deleted file mode 100644 index 015cc776e..000000000 --- a/fhem/FHEM/98_Siro.pm +++ /dev/null @@ -1,2022 +0,0 @@ -# $Id$ -# -# Siro module for FHEM -# Thanks for templates/coding from SIGNALduino team and Jarnsen_darkmission_ralf9 -# Thanks to Dr. Smag for decoding the protocol, which made this module possible -# Needs SIGNALduino. -# Published under GNU GPL License, v2 -# History: -# 30.05.19 Version 1.0 innitial comit -################################################################################################################ -# Todo's: -# - -# - -############################################################################################################### - -package main; - -use strict; -use warnings; -my $version = "1.3"; - - -sub Siro_Initialize($) { - my ($hash) = @_; - - $hash->{SetFn} = "FHEM::Siro::Set"; - $hash->{NotifyFn} = "FHEM::Siro::Notify"; - $hash->{ShutdownFn} = "FHEM::Siro::Shutdown"; - $hash->{FW_deviceOverview} = 1; - $hash->{FW_detailFn} = "FHEM::Siro::fhemwebFn"; - $hash->{DefFn} = "FHEM::Siro::Define"; - $hash->{UndefFn} = "FHEM::Siro::Undef"; - $hash->{DeleteFn} = "FHEM::Siro::Delete"; - $hash->{ParseFn} = "FHEM::Siro::Parse"; - $hash->{AttrFn} = "FHEM::Siro::Attr"; - $hash->{Match} = "^P72#[A-Fa-f0-9]+"; - $hash->{AsyncOutput} = "FHEM::Siro::AsyncOutput"; - $hash->{AttrList} = - " IODev" - . " disable:0,1" - . " SIRO_signalRepeats:1,2,3,4,5,6,7,8,9" - . " SIRO_inversPosition:0,1" - . " SIRO_Battery_low" - . " SIRO_downLimit:slider,0,1,100" - . " SIRO_signalLongStopRepeats:10,15,20,40,45,50" - . " $readingFnAttributes" - . " SIRO_send_channel:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15" - . " SIRO_send_id" - . " SIRO_time_to_open" - . " SIRO_time_to_close" - . " SIRO_debug:0,1" - . " SIRO_no_IO_msg:0,1" - . " SIRO_dbl_msg_block" - . " SIRO_remote_correction:0,0.25,0.5,0.75,1,1.25,1.5,1.75,2,2.5,2.75,3" - ; - - - $hash->{AutoCreate} = { - "Siro.*" => { - #ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", - FILTER => "%NAME", - autocreateThreshold => "2:10" - } - }; - - $hash->{helper}{progmode} = "off"; #exexcmd on -} - - -############################# - - -#### arbeiten mit packages -package FHEM::Siro; - -use strict; -use warnings; - -use GPUtils qw(GP_Import) - ; # wird fuer den Import der FHEM Funktionen aus der fhem.pl ben?tigt - - -## Import der FHEM Funktionen -BEGIN { - GP_Import( - qw(readingsSingleUpdate - readingsBeginUpdate - readingsEndUpdate - readingsBulkUpdate - defs - modules - Log3 - AttrVal - ReadingsVal - IsDisabled - gettimeofday - InternalTimer - RemoveInternalTimer - AssignIoPort - IOWrite - ReadingsNum - CommandAttr - attr - fhem - init_done - setDevAttrList - readingFnAttributes - devspec2array - ) - - ); -} - - -my %codes = ( - "55" => "stop", # Stop the current movement or move to custom position - "11" => "off", # Move "up" - "33" => "on", # Move "down" - "CC" => "prog", # Programming-Mode (Remote-control-key: P2) -); - - -my %sets = ( - "open" => "noArg", - "close" => "noArg", - "up" => "noArg", - "down" => "noArg", - "off" => "noArg", - "stop" => "noArg", - "longstop" => "noArg", - "on" => "noArg", - "fav" => "noArg", - "prog" => "noArg", - "sequenz" => "noArg", - "prog_mode_on" => "noArg", - "prog_mode_off" => "noArg", - "lock_remote" => "on,off", - "lock_cmd" => "on,off", - "reset_motor_term" => "noArg", - "pct" => "slider,0,1,100", # Wird nur bei vorhandenen time_to attributen gesetzt - "position" => "slider,0,1,100", # Wird nur bei vorhandenen time_to attributen gesetzt - "set_favorite_position" => "slider,0,1,100", # manuelles setzen def fav position - #"state" => "noArg", - "set_favorite" => "noArg", - "del_favorite" => "only_modul,only_shutter,shutter_and_modul", - "down_for_timer" => "textField", - "up_for_timer" => "textField" - -); - -my %setsstandart = ( - "open" => "noArg", - "close" => "noArg", - "up" => "noArg", - "down" => "noArg", - "off" => "noArg", - "stop" => "noArg", - "longstop" => "noArg", - "on" => "noArg", - "fav" => "noArg", - "prog" => "noArg", - "sequenz" => "noArg", - "prog_mode_on" => "noArg", - "prog_mode_off" => "noArg", - "lock_remote" => "on,off", - "lock_cmd" => "on,off", - "reset_motor_term" => "noArg", - "pct" => "slider,0,1,100", # Wird nur bei vorhandenen time_to attributen gesetzt - "position" => "slider,0,1,100", # Wird nur bei vorhandenen time_to attributen gesetzt - #"state" => "noArg", - "Favorite-Position" => "slider,0,1,100", # manuelles setzen def fav position - "set_favorite" => "noArg", - "del_favorite" => "only_modul,only_shutter,shutter_and_modul", - "down_for_timer" => "textField", - "up_for_timer" => "textField" - -); - -my %setszero = ( - "open" => "noArg", - "close" => "noArg", - "up" => "noArg", - "down" => "noArg", - "off" => "noArg", - "stop" => "noArg", - "on" => "noArg", - "fav" => "noArg", -); - -my %sendCommands = ( - "pct" => "level", - "level" => "level", - "position" => "level", - "stop" => "stop", - "longstop" => "longstop", - "off" => "off", - "on" => "on", - "open" => "off", - "close" => "on", - "up" => "off", - "down" => "on", - "fav" => "fav", - "prog" => "prog", - "reset_motor_term" => "reset_motor_term", - "up_for_timer" => "upfortimer", - "down_for_timer" => "downfortimer", - "lock_remote" => "lock_remote", - "Favorite-Position" => "favposition", - "lock_cmd" => "lock_cmd" - -); - -my %siro_c2b; -# Map commands from web interface to codes used in Siro -foreach my $k ( keys %codes ) { - $siro_c2b{ $codes{$k} } = $k; -} - -############################# -sub Attr(@) { - my ( $cmd, $name, $aName, $aVal ) = @_; - my $hash = $defs{$name}; - return "\"Siro Attr: \" $name does not exist" if ( !defined($hash) ); - - if ( $cmd eq "set" and $init_done == 1) - { - - - if ( $aName eq "SIRO_inversPosition" ) - { - my $oldinvers = AttrVal($name,'SIRO_inversPosition','undef'); - Log3( $name,5 , "Siro_attr_oldinvers: $oldinvers "); - Log3( $name,5 , "Siro_attr_newinvers: $aVal "); - if ( $aVal ne $oldinvers) - { - my $aktstate = ReadingsVal( $name, 'state', 'undef' ); - $aktstate = 100 - $aktstate; - readingsSingleUpdate( $hash, "state", $aktstate , 1 ); - readingsSingleUpdate( $hash, "pct", $aktstate , 1 ); - } - } - - Log3( $name,5 , "Siro_attr: $cmd, $name, $aName, $aVal "); - - } - - Log3( $name,5 , "Siro_attr init done : $init_done"); -return; -} -############################# -sub Define($$) { - my ( $hash, $def ) = @_; - my @a = split( "[ \t][ \t]*", $def ); - - my $u = "Wrong syntax: define Siro id "; - my $askedchannel; # Angefragter kanal - - # Fail early and display syntax help - if ( int(@a) < 3 ) { - return $u; - } - - if ( $a[2] =~ m/^[A-Fa-f0-9]{8}$/i ) { - $hash->{ID} = uc( substr( $a[2], 0, 7 ) ); - $hash->{CHANNEL_RECEIVE} = sprintf( "%d", hex( substr( $a[2], 7, 1 ) ) ); - $askedchannel = sprintf( "%d", hex( substr( $a[2], 7, 1 ) ) ); - } - else { - return -"Define $a[0]: wrong address format: specify a 8 char hex value (id=7 chars, channel=1 char) . Example A23B7C51. The last hexchar identifies the channel. -> ID=A23B7C5, Channel=1. "; - } - - $hash->{Version} = $version; - my $name = $a[0]; - my $code = uc( $a[2] ); - my $ncode = 1; - - my $devpointer = $hash->{ID} . $hash->{CHANNEL_RECEIVE}; - $hash->{CODE}{ $ncode++ } = $code; - $hash->{MODEL} = "LE-serie"; - $modules{Siro}{defptr}{$devpointer} = $hash; - AssignIoPort($hash); - - # attributliste anlegen - - if ($hash->{CHANNEL_RECEIVE} eq '0') - { - my $attrzerolist = - " IODev" - . " disable:0,1" - . " SIRO_signalRepeats:1,2,3,4,5,6,7,8,9" - . " SIRO_signalLongStopRepeats:10,15,20,40,45,50" - . " $readingFnAttributes" - . " SIRO_debug:0,1"; - $hash->{MODEL} = "LE-Group"; - setDevAttrList($name, $attrzerolist); - } - else - { - setDevAttrList($name, $hash->{AttrList}); - $hash->{MODEL} = "LE-Device"; - } - - my $webcmd = "webCmd stop:open:close:fav:pct"; - $webcmd = "webCmd stop:open:close:fav" if $hash->{CHANNEL_RECEIVE} eq '0'; - - CommandAttr( undef,$name . ' devStateIcon {return FHEM::Siro::Siro_icon($name)}' ) - if ( AttrVal($name,'devStateIcon','none') eq 'none' ); - - CommandAttr(undef,$name . ' '.$webcmd) - if ( AttrVal($name,'webCmd','none') eq 'none' ); - - Log3( $name, 5, "Siro_define: angelegtes Device - code -> $code name -> $name hash -> $hash " - ); -} - -############################# -sub Undef($$) { - - my ( $hash, $name ) = @_; - delete( $modules{Siro}{defptr}{$hash} ); - return undef; -} - -############################# -sub Shutdown($) { - my ($hash) = @_; - my $name = $hash->{NAME}; - return; -} - -############################# -sub LoadHelper($) { - my ($hash) = @_; - my $name = $hash->{NAME}; - return; -} - -############################# - -sub Notify($$) { - - return; -} -############################# - -sub Delete($$) { - my ( $hash, $name ) = @_; - return undef; -} - -############################# -sub SendCommand($@) { - my ( $hash, @args ) = @_; - my $ret = undef; - my $cmd = $args[0]; # Command as text (on, off, stop, prog) - my $message; # IO-Message (full) - my $chan; # Channel - my $binChannel; # Binary channel - my $SignalRepeats; # - my $name = $hash->{NAME}; - my $binHash; - my $bin; # Full binary IO-Message - my $binCommand; - my $numberOfArgs = int(@args); - my $command = $siro_c2b{$cmd}; - my $io = $hash->{IODev}; # IO-Device (SIGNALduino) - - Log3( $name, 5,"Siro_sendCommand: cmd - $cmd"); - - if ($cmd eq "longstop") - { - $args[1]="longstop"; - $cmd="stop"; - $command = $siro_c2b{$cmd}; - } - - Log3( $name, 5,"Siro_sendCommand: args1 - $args[1]") if defined $args[1]; - - - - if ( defined($hash->{helper}{exexcmd}) and $hash->{helper}{exexcmd} eq "off") # send kommand blockiert / keine ausf?hrung - { - Log3( $name, 4,"Siro_sendCommand: ausfuehrung durch helper blockiert "); - return; - } - - if ( defined($hash->{helper}{ignorecmd}) and $hash->{helper}{ignorecmd} eq "on") # send kommand blockiert / keine ausf?hrung - { - Log3( $name, 4,"Siro_sendCommand: ausfuehrung einmalig blockiert "); - - delete( $hash->{helper}{ignorecmd} ); - return; - - } - - - - #if ( (defined($args[1]) and $args[1] eq "longstop" )|| (defined $hash->{helper}{progmode} and $hash->{helper}{progmode} eq "on")) - if ( (defined($args[1]) and $args[1] eq "longstop" )) - { - $SignalRepeats = AttrVal( $name, 'SIRO_signalLongStopRepeats', '15' ); - } - else - { - $SignalRepeats = AttrVal( $name, 'SIRO_signalRepeats', '10' ); - } - - - - Log3( $name, 5,"Siro_sendCommand: repeats - $SignalRepeats"); - - $chan = AttrVal( $name, 'SIRO_send_channel', undef ); - if ( !defined($chan) ) - { - $chan = $hash->{CHANNEL_RECEIVE}; - } - $binChannel = sprintf( "%04b", $chan ); - my $value = $name . " " . join( " ", @args ); - my $sendid = AttrVal( $name, 'SIRO_send_id', 'undef' ); - if ( $sendid eq 'undef') - { - $binHash = sprintf( "%028b", hex( $hash->{ID} ) ); - } - else{ - $binHash = sprintf( "%028b", hex( $sendid ) ); - } - Log3 $io, 5, "Siro_sendCommand: BinHash: = $binHash"; - $binCommand = sprintf( "%08b", hex($command) ); - Log3 $io, 5, "Siro_sendCommand: BinCommand: = $binCommand"; - - $bin = $binHash . $binChannel . $binCommand; # Binary code to send - Log3 $io, 5, "Siro_sendCommand: Siro set value = $value"; - - $message = 'P72#' . $bin . '#R' . $SignalRepeats; - - IOWrite( $hash, 'sendMsg', $message ) if AttrVal( $name, 'SIRO_debug', "0" ) ne "1"; - - Log3( $name, 5,"Siro_sendCommand: name-$name command-$cmd channel-$chan bincmd-$binCommand bin-$bin id-$sendid message-$message"); - Log3( $name, 3, "Siro_sendCommand: not sent upround debugmode 1") if AttrVal( $name, 'SIRO_debug', "0" ) eq "1"; - return $ret; -} - -############################# -sub Parse($$) { - - my @args; - my ( $hash, $msg ) = @_; - my $name = $hash->{NAME}; - my $testid = substr( $msg, 4, 8 ); - my $testcmd = substr( $msg, 12, 2 ); - my $timediff; - my $doubelmsgtime = AttrVal( $name, 'SIRO_dbl_msg_block',2 ); # zeit in sek in der doppelte nachrichten blockiert werden - my $favcheck = $doubelmsgtime + 2;# zeit in der ein zweiter stop kommen muss/darf für fav - - # Log3( $name, 0,"name $name"); - - return "" if ( IsDisabled($name) ); - - #my $devpointer = $hash->{ID} . $hash->{CHANNEL_RECEIVE}; - - if ( my $lh = $modules{Siro}{defptr}{$testid} ) { - my $name = $lh->{NAME}; - - #Log3( $name, 0,"name1 $name"); - - - if ( defined($name)&& $testcmd ne "54")# pr?fe auf doppele msg falls ger?t vorhanden und cmd nicht stop - { - #Log3 $lh, 5,"Siro_Parse: Incomming msg $msg from IODevice name/DEF $testid - Hash -> $lh"; - Log3( $name, 5,"Siro_Parse: Incomming msg $msg from IODevice name/DEF $testid - Hash -> $lh"); - my $testparsetime = gettimeofday(); - my $lastparse = $lh->{helper}{lastparse}; - my @lastparsearray = split( / /, $lastparse ); - if ( !defined( $lastparsearray[1] ) ) { $lastparsearray[1] = 0 } - if ( !defined( $lastparsearray[0] ) ) { $lastparsearray[0] = "" } - $timediff = $testparsetime - $lastparsearray[1]; - my $abort = "false"; - - - Log3( $name, 5,"Siro_Parse: test doublemsg "); - Log3( $name, 5,"Siro_Parse: lastparsearray[0] -> $lastparsearray[0] "); - Log3( $name, 5,"Siro_Parse: lastparsearray[1] -> $lastparsearray[1] "); - Log3( $name, 5,"Siro_Parse: testparsetime -> $testparsetime "); - Log3( $name, 5,"Siro_Parse: timediff -> $timediff "); - - - if ( $msg eq $lastparsearray[0] ) { - - if ( $timediff < $doubelmsgtime ) { - - $abort = "true"; - } - } - $lh->{helper}{lastparse} = "$msg $testparsetime"; - if ( $abort eq "true" ) { - - Log3( $name, 5,"Siro_Parse: aborted , doublemsg "); - return $name; - } - - - Log3( $name, 5,"Siro_Parse: not aborted , no doublemsg "); - } - - my ( undef, $rawData ) = split( "#", $msg ); - my $hlen = length($rawData); - my $blen = $hlen * 4; - my $bitData = unpack( "B$blen", pack( "H$hlen", $rawData ) ); - - - Log3( $name, 5,"Siro_Parse: msg = $rawData length: $msg"); - Log3( $name, 5,"Siro_Parse: rawData = $rawData length: $hlen"); - Log3( $name, 5,"Siro_Parse: converted to bits: $bitData"); - - my $id = substr( $rawData, 0, 7 ); # The first 7 hexcodes are the ID - my $BitChannel = substr( $bitData, 28, 4 ); # Not needed atm - my $channel = sprintf( "%d", hex( substr( $rawData, 7, 1 ) ) );# The last hexcode-char defines the channel - my $channelhex = substr( $rawData, 7, 1 ); # tmp - my $cmd = sprintf( "%d", hex( substr( $rawData, 8, 1 ) ) ); - my $newstate = $codes{ $cmd . $cmd }; # Set new state - my $deviceCode = $id. $channelhex;#Tmp change channel -> channelhex. The device-code is a combination of id and channel - - Log3( $name, 5,"Siro_Parse: device ID: $id"); - Log3( $name, 5,"Siro_Parse: Channel: $channel"); - Log3( $name, 5,"Siro_Parse: Cmd: $cmd Newstate: $newstate"); - Log3( $name, 5,"Siro_Parse: deviceCode: $deviceCode"); - - #if ( defined($name)&& $testcmd eq "54" )#prüfe auf doppele msg falls gerät vorhanden und cmd stop - if ( defined($name)&& $testcmd eq "54" )#pr?fe auf doppele msg falls ger?t vorhanden und cmd stop - { - - Log3( $name, 5,"Siro_Parse: prüfung auf douplestop "); - Log3( $name, 5,"################################ "); - my $testparsetime = gettimeofday(); - my $lastparsestop = 0; - $lastparsestop = $lh->{helper}{lastparse_stop} if defined $lh->{helper}{lastparse_stop}; - my $parseaborted = $lh->{helper}{parse_aborted}; - my @lastparsestoparray = split( / /, $lastparsestop ); - my $timediff = $testparsetime - $lastparsestoparray[1]; - my $abort = "false"; - $parseaborted = 0 if ( !defined($parseaborted) ); - - Log3( $name, 5,"Siro_Parse: test doublestop "); - Log3( $name, 5,"Siro_Parse: lastparsearray[0] -> $lastparsestoparray[0] "); - Log3( $name, 5,"Siro_Parse: lastparsearray[1] -> $lastparsestoparray[1] "); - Log3( $name, 5,"Siro_Parse: testparsetime -> $testparsetime "); - Log3( $name, 5,"Siro_Parse: timediff -> $timediff "); - Log3( $name, 5,"Siro_Parse: parseaborted -> $parseaborted "); - - - if ( $newstate eq $lastparsestoparray[0] ) { - - if ( $timediff < 3 ) { - $abort = "true"; - $parseaborted++; - } - - } - if ( $abort eq "true" && $parseaborted < 2 ) { - $lh->{helper}{parse_aborted} = $parseaborted; - - Log3( $name, 5,"Siro_Parse: aborted , doublestop "); - return $name; - } - - $lh->{helper}{lastparse_stop} = "$newstate $testparsetime"; - - if ( $parseaborted >= 2 ) { - $parseaborted = 0; - $lh->{helper}{parse_aborted} = $parseaborted; - $testparsetime = gettimeofday(); - $lh->{helper}{lastparse_stop} = "$newstate $testparsetime"; - if ( $newstate eq "stop" ) { - - - Log3( $name, 5,"Siro_Parse: double_msg signal_favoritenanfahrt erkannt "); - - $newstate = "fav"; - $args[0] = "fav"; - } - } - } - - Log3( $name, 5, "Siro Parse Befehl: $newstate"); - - if ($lh->{helper}{progmode} eq "on") - { - Log3( $name, 4, "Siro Parse deactivated cause off programmingmode"); - return; - } - - if ( defined($name) ) {#device vorhanden - my $parseaborted = 0; - $lh->{helper}{parse_aborted} = $parseaborted; - - - Log3( $name, 5,"Siro_ Parse: $name $newstate"); - - my $defchannnel = $lh->{CHANNEL_RECEIVE}; - my $atrrchannel = AttrVal( $name, 'SIRO_send_channel', $defchannnel ); - - - Log3( $name, 5,"Siro_Parse: defchannnel - $defchannnel "); - Log3( $name, 5,"Siro_Parse: atrrchannel - $atrrchannel "); - - if ($defchannnel eq $atrrchannel) - { - Log3( $name, 5,"Siro_Parse: setze remotecmd on "); - $lh->{helper}{remotecmd} = "on"; #verhindert das senden von signalen nur wenn nicht auf anderem kanal gesendet wird - } - - my $aktstate = ReadingsVal( $name, 'state', '0' ); - my $lock =ReadingsVal( $name, 'lock_remote', 'off' ); - - - - if ($defchannnel ne '0') - { - - - Log3( $name, 5,"Siro_Parse: lock = $lock "); - Log3( $name, 5,"Siro_Parse: newstate = $newstate "); - - # - if ($lock ne 'on') - { - Log3( $name, 5,"Siro_Parse: weiterleitung -> set "); - Set( $lh, $name, $newstate ); - } - # - if ($lock eq 'on' and ($newstate eq 'fav' or $newstate eq 'stop')) - { - Log3( $name, 5,"Siro_Parse: weiterleitung -> set "); - Set( $lh, $name, $newstate ); - } - elsif ($lock eq 'on' and $aktstate ne "0" and $aktstate ne "100") - { - Log3( $name, 5,"Siro_Parse: weiterleitung -> set "); - Set( $lh, $name, $newstate ); - } - - } - - - if ($defchannnel eq '0') - { - - Log3( $name, 5,"Siro_Parse: eingehender Gruppenbefehl , weiterleitung an deviceverteiler "); - Log3( $name, 5,"Siro_Parse: eingehender Gruppenbefehl $newstate"); - readingsSingleUpdate( $lh, "ActionTrigger", "remote", 1 ); - Distributor($name.' '.$newstate.' '.$testcmd); - return $name; - } - - - - Log3( $name, 4, "Siro_Parse: hash->{helper}{remotecmd} - ".$lh->{helper}{remotecmd}); - Log3( $name, 3, "Siro-Parse ($name) : Signal FB emfangen - $newstate"); - Log3( $name, 4, "Siro-Parse ($name) : test lock_remote - $lock"); - - if ($lock eq 'on') - # remotelock - { - Log3( $name, 4, "Siro-Parse ($name) : founde lock_remote - target: $aktstate"); - if ($aktstate eq "0") - { - $lh->{helper}{remotecmd} = "off"; - $lh->{helper}{exexcmd}="on"; - Log3( $name, 4, "Siro-Parse ($name) :send comand aufruf off"); - SendCommand( $lh, 'off' ); - - $lh->{helper}{savedcmds}{cmd1} = 'open' ; - - InternalTimer( (time + 3), "FHEM::Siro::Restartset", "$name" ); - return; - } - - elsif ($aktstate eq "100") - { - $lh->{helper}{remotecmd} = "off"; - $lh->{helper}{exexcmd}="on"; - Log3( $name, 4, "Siro-Parse ($name) :send comand aufruf on"); - SendCommand( $lh, 'on' ); - $lh->{helper}{savedcmds}{cmd1} = 'close' ; - InternalTimer( (time + 3), "FHEM::Siro::Restartset", "$name" ); - return; - } - else - { - Set( $lh, $name, 'stop'); - $lh->{helper}{savedcmds}{cmd1} = 'pct' ; - $lh->{helper}{savedcmds}{cmd2} = $aktstate; - - - RemoveInternalTimer("FHEM::Siro::Restartset", "$name"); - InternalTimer( (time + 1), "FHEM::Siro::Restartset", "$name" ); - return; - } - - - - } - return $name; - } - } - else - { # device nicht vorhanden - my ( undef, $rawData ) = split( "#", $msg ); - my $hlen = length($rawData); - my $blen = $hlen * 4; - my $bitData = unpack( "B$blen", pack( "H$hlen", $rawData ) ); - - Log3 $hash, 5, "Siro_Parse: msg = $rawData length: $msg"; - Log3 $hash, 5, "Siro_Parse: rawData = $rawData length: $hlen"; - Log3 $hash, 5, "Siro_Parse: converted to bits: $bitData"; - - my $id = substr( $rawData, 0, 7 ); # The first 7 hexcodes are the ID - my $BitChannel = substr( $bitData, 28, 4 ); # Not needed atm - my $channel = sprintf( "%d", hex( substr( $rawData, 7, 1 ) ) ); # The last hexcode-char defines the channel - my $channelhex = substr( $rawData, 7, 1 ); # tmp - my $cmd = sprintf( "%d", hex( substr( $rawData, 8, 1 ) ) ); - my $newstate = $codes{ $cmd . $cmd }; # Set new state - my $deviceCode = $id. $channelhex; # Tmp change channel -> channelhex. The device-code is a combination of id and channel - - Log3 $hash, 5, "Siro_Parse: device ID: $id"; - Log3 $hash, 5, "Siro_Parse: Channel: $channel"; - Log3 $hash, 5, "Siro_Parse: Cmd: $cmd Newstate: $newstate"; - Log3 $hash, 5, "Siro_Parse: deviceCode: $deviceCode"; - Log3 $hash, 2, "Siro unknown device $deviceCode, please define it"; - return "UNDEFINED Siro_$deviceCode Siro $deviceCode"; - } -} - -############################# - -# Call with hash, name, virtual/send, set-args -sub Set($@) { - my $testtimestart = gettimeofday(); - my $debug; - my ( $hash, $name, @args ) = @_; - my $cmd = $args[0]; # eingehendes set - my $zielposition = $args[1]; # eingehendes set position - my $param = $args[1]; # eingehendes set position - $param = "" if !defined $param; - Log3( $name, 5, "Siro-Set: eingehendes Kommando $cmd") if $cmd ne "?"; - ### check for old version - if (ReadingsVal( $name, 'last_reset_os', 'undef' ) ne 'undef' && $cmd ne "?") - { - Log3( $name,0 , "Das Siromodul wurde geaendert und die einstellungen sind nicht mehr Kompatibel. Bitte das Sirodevice \"$name\" kontrollieren ."); - } - ############################# - - my $actiontime = time; # zeit dieses Aufrufes - my $lastactiontime = ReadingsVal( $name, 'ActionTime', $actiontime ); # Zeit des letzten Aufrufes - my $betweentime = $actiontime-$lastactiontime; # Zeit zwischen aktuellem und letztem Aufruf - my $downtime = AttrVal( $name, 'SIRO_time_to_close','undef' ); # fahrdauer runter - my $uptime = AttrVal( $name, 'SIRO_time_to_open','undef' ); # fahrdauer hoch - my $correction = AttrVal( $name, 'SIRO_remote_correction',0 ); # zeitkorrektur fernbedienung - my $down1time ="undef"; # fahrzeit 1 prozent - my $up1time ="undef"; # fahrzeit 1 prozent - my $drivingtime; # fahrzeit bei positionsanfahrt - my $aktendaction = ReadingsVal( $name, 'aktEndAction', '0' ); #endzeit laufende avtion - my $akttimeaction = ReadingsVal( $name, 'aktTimeAction', '0' ); #dauer einer laufenden aktion - my $aktrunningaction = ReadingsVal( $name, 'aktRunningAction', '' ); #typ einer laufenden aktion - my $position = ReadingsVal( $name, 'pct', '' ); #position pct bis zum ende einer aktion - my $state = ReadingsVal( $name, 'state', 'undef' ); #aktuelle aktion ( runningDown/runningUp ) - my $drivedpercents; # beinhaltet gefahrene prozent bei aktionswechsel - my $newposition ; # beinhaltet neue positin bei aktionswechsel - my $favposition = ReadingsVal( $name, 'Favorite-Position', 'nA' ); #gespeicherte Favoritenposition - my $invers = 1; #invertiert position - my $oldcmdfrom = ReadingsVal( $name, 'ActionTrigger', 'fhem' );# ActionTrigger der letzten aktion - my $defchannnel = $hash->{CHANNEL_RECEIVE}; - - if ($downtime ne "undef" && $uptime ne "undef") - { - $down1time = $downtime/100; - $up1time = $uptime/100; - } - - return "" if ( IsDisabled($name) ); - - $hash->{helper}{progmode} = "off" if !defined $hash->{helper}{progmode}; - - # versionschange - #changeconfig - - - - # pruefe auf unbekannte sets - if ( $cmd =~ m/^exec.*/ )# empfangene sequenz aus programmiermode - { - $args[1] = $cmd; - $cmd = "sequenz"; - } - - if ($defchannnel eq '0') - { - %sets = %setszero; - } - else { - %sets = %setsstandart; - } - - if ( !exists( $sets{$cmd} ) ) { - my @cList; - my $atts = AttrVal( $name, 'setList', "" ); - my %setlist = split( "[: ][ ]*", $atts ); - foreach my $k ( sort keys %sets ) { - my $opts = undef; - $opts = $sets{$k}; - $opts = $setlist{$k} if ( exists( $setlist{$k} ) ); - if ( defined($opts) ) { - push( @cList, $k . ':' . $opts ); - } - else { - push( @cList, $k ); - } - } # end foreach - return "Unknown argument $cmd, choose one of " . join( " ", @cList ); - } - - -################## - if ($defchannnel eq '0') - { - - Log3( $name, 5, "Siro-def0: newstate $cmd"); - Log3( $name, 5, "Siro-def0: testcmd ".$sets{$cmd}); - - Distributor($name.' '.$cmd.' '.$sets{$cmd}); - readingsSingleUpdate( $hash, "ActionTrigger", "fhem", 1 ); - # name befehl befehlscode - $hash->{helper}{exexcmd}="on"; - - - Log3( $name, 5, "Siro-def0: sende kommando ".$sendCommands{$cmd}); - - if ($sendCommands{$cmd} eq 'fav'){ - SendCommand( $hash, 'stop' , 'longstop' );} - else{ - SendCommand( $hash, $sendCommands{$cmd} );} - return; - } - - -############################# -# programmiermodus -############################# - - #if ( $hash->{helper}{progmode} eq "on" && $cmd eq "sequenz") # sequenz ausführen - if ( defined $hash->{helper}{progmode} and $hash->{helper}{progmode} eq "on" && $cmd eq "sequenz") # sequenz ausf?hren - - { - Log3( $name, 5, "Siro-Programmiermodus: Sequenz gefunden :$args[1]"); - my @seq = split(/,/, $args[1]); - - shift @seq; - my $exectime = time; - foreach my $seqpart (@seq) - { - #$actiontime - $exectime = $exectime+2; - my $execcmd = $seqpart; - Log3( $name, 5, "Siro-Programmiermodus: Sequenz - $exectime - $execcmd"); - InternalTimer( $exectime, "FHEM::Siro::Prog", $name." ".$execcmd ); - } - return; - } - - if ($cmd eq "prog_mode_on" && $hash->{helper}{progmode} ne "on") - { - readingsSingleUpdate( $hash, "state", 'programming', 1 ); - $hash->{helper}{progmode} = "on"; - } - - if ($cmd eq "prog_mode_off" && $hash->{helper}{progmode} eq "on") - { - readingsSingleUpdate( $hash, "state", $position, 1 ); - #delete( $hash->{helper}{progmode} ); - $hash->{helper}{progmode} = "off"; - } - - if ($hash->{helper}{progmode} eq "on") - { - - Log3( $name, 5, "Siro-Programmiermodus: ".$sendCommands{$cmd}); - SendCommand( $hash, $sendCommands{$cmd} ); - delete( $hash->{Signalduino_RAWMSG} ); - delete( $hash->{Signalduino_MSGCNT} ); - delete( $hash->{Signalduino_RSSI} ); - delete( $hash->{Signalduino_TIME} ); - Log3( $name, 5, "Siro-Programmiermodus: Parse deaktiviert"); - return; - } - -############################# - - if ($state eq "programming") # keine Befehlsausf?hrung w?hrend einer programmierung - { - Log3( $name, 1, "Siro-Programmiermodus: Befehl nicht moeglich , Device ist im Programmiermodus"); - return; - } - - # setze actiontime und lastactiontime - # umbauen zu bulk update - RemoveInternalTimer($name); #alle vorhandenen timer l?schen - #delete( $hash->{helper}{exexcmd} ); # on/off off blockiert befehlsausf?hrung / l?schen vor jedem durchgang - $hash->{helper}{exexcmd}="on"; #reset ignore send comand states - $hash->{helper}{ignorecmd} = "off" ; #reset ignore send comand states - #setze helper neu wenn signal von fb kommt - #if ($hash->{helper}{remotecmd} eq "on") - - ############################# - my $aktcmdfrom ="fhem"; - if ( defined($hash->{helper}{remotecmd}) and $hash->{helper}{remotecmd} eq "on") - { - $hash->{helper}{exexcmd} = "off" ; - $aktcmdfrom = "remote"; - } - delete( $hash->{helper}{remotecmd} ); - ############################# - # befehl ist von distributor abgesetzt - kam von kanal 0 - Log3( $name, 5, "Siro-Set: param - $param"); - if (defined $param and $param eq "fakeremote") - { - $hash->{helper}{exexcmd} = "off" ; - $aktcmdfrom = "remote"; - } - ############################# - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "ActionTrigger", $aktcmdfrom, 1 ); - readingsBulkUpdate( $hash, "LastActionTime", $lastactiontime, 0 ); - readingsBulkUpdate( $hash, "BetweentActionTime", $betweentime, 0 ); - readingsBulkUpdate( $hash, "ActionTime", $actiontime, 0 ); - readingsEndUpdate($hash, 1); - # befehl aus %sendCommands ermitteln - my $comand = $sendCommands{$cmd}; # auzuf?hrender befehl - Log3( $name, 5, "Siro-Set: ermittelter Befehl: $comand " ) if defined $comand; - - ############################# - # limit testen , falls limit wird on zu level limit - my $downlimit = AttrVal( $name, 'SIRO_downLimit','undef' ) ; - if ($downlimit ne "undef" && ($comand eq 'on' || $comand eq 'level') && $hash->{helper}{exexcmd} ne "off") - # nur wenn befehl nicht von fb kommt - { - if (!defined $zielposition){$zielposition = 100} - if ( $position < $downlimit ) - { - $comand = 'level'; - $zielposition = $downlimit; - } - my $sendchan = AttrVal( $name, 'SIRO_send_channel', 'undef' ); - if ( $sendchan ne $hash->{CHANNEL_RECEIVE} && $position >= $downlimit ) - { - return; - } - } -############################# - if ($downlimit ne "undef" && ($comand eq 'on' || $comand eq 'level') && $hash->{helper}{exexcmd} eq "off") - # nur wenn befehl von fb kommt - { - if ( $position < $downlimit ) - { - #delete( $hash->{helper}{exexcmd} ); - $hash->{helper}{exexcmd}="on"; - $hash->{helper}{ignorecmd} ="on"; - $comand = 'level'; - $zielposition = $downlimit; - } - } -############################# lock_remote - if ($comand eq "lock_remote") - { - readingsSingleUpdate( $hash, "lock_remote", $args[1], 1 ) ; - if (ReadingsVal( $name, 'lock_cmd', 'off' ) eq "on" and $args[1] eq "on") - { - readingsSingleUpdate( $hash, "lock_remote", "off", 1 ) ; - Log3( $name, 1, "Siro-Set: Lock Remote ist nicht moeglich, wenn Lock CMD aktiviert ist"); - return "Lock Remote ist nicht moeglich, wenn Lock CMD aktiviert ist"; - } - return; - } - - ############################# lock_cmd - if ($comand eq "lock_cmd") - { - readingsSingleUpdate( $hash, "lock_cmd", $args[1], 1 ) ; - if (ReadingsVal( $name, 'lock_remote', 'off' ) eq "on" and $args[1] eq "on") - { - readingsSingleUpdate( $hash, "lock_cmd", "off", 1 ) ; - Log3( $name, 1, "Siro-Set: Lock Cmd ist nicht moeglich, wenn Lock Remote aktiviert ist"); - return "Lock Cmd ist nicht moeglich, wenn Lock Remote aktiviert ist"; - } - - - - return; - } - if (ReadingsVal( $name, 'lock_cmd', 'off' ) eq 'on' and $param ne "fakeremote" and $hash->{helper}{exexcmd} eq "on" ) - - { - Log3( $name, 3, "Siro-Set: angefragte Aktion $comand abgebrochen (lock_cmd -> on)"); - readingsSingleUpdate( $hash, "pct", $position , 1 ); - readingsSingleUpdate( $hash, "position", $position , 1 ); - - - return; - } - -############################# - # set reset_motor_term reset_motor_term - if ($comand eq "reset_motor_term") - { - readingsSingleUpdate( $hash, "motor-term", "0", 1 ) ; - readingsSingleUpdate( $hash, "batteryState", "unknown", 1 ) ; - readingsSingleUpdate( $hash, "motor-term-reset", time, 1 ); - return; - } - - # pruefe auf laufende aktion nur bei definierten laufzeiten - # wenn vorhanden neuberechnung aller readings - if ($aktendaction > time && ($downtime ne "undef" || $uptime ne "undef")) - { - Log3( $name, 5, "Siro-Set: laufende aktion gefunden - abbruch"); - Log3( $name, 5, "Siro-Set: laufende aktion -"); - - #aktTimeAction - dauer der laufenden aktion - in variable $akttimeaction - #aktEndAction geplantes aktionsende - in variabel $aktendaction - #$actiontime aktuelle zeit - #$aktrunningaction - typ der laufenden aktion - #$position -position bei actionsbeginn - - my $pastaction = $akttimeaction - ($aktendaction - $actiontime); - Log3( $name, 5, "Siro-Set: unterbrochene Aktion $state lief $pastaction "); - ##################korrektur zeitdifferenz fb/fhem - if ($oldcmdfrom eq "remote" and $aktcmdfrom eq "fhem") - { - $pastaction = $pastaction + $correction ; - Log3( $name, 5, "Siro-Set: unterbrochene Aktion wurde von $oldcmdfrom gestartet und von $aktcmdfrom unterbrochen, starte Korrektur "); - Log3( $name, 5, "Siro-Set: unterbrochene Aktion $state lief $pastaction mit Korrektur"); - Log3( $name, 5, "Siro-Set: Korrektur um $correction sekunden"); - } - - if ($oldcmdfrom eq "fhem" and $aktcmdfrom eq "remote") - { - $pastaction = $pastaction - $correction ; - Log3( $name, 5, "Siro-Set: unterbrochene Aktion wurde von $oldcmdfrom gestartet und von $aktcmdfrom unterbrochen, starte Korrektur "); - Log3( $name, 5, "Siro-Set: unterbrochene Aktion $state lief $pastaction mit Korrektur"); - Log3( $name, 5, "Siro-Set: Korrektur um $correction sekunden"); - } - ############################# - - Log3( $name, 5, "Siro-Set: Aktionsbeginn bei $position "); - - if ($state eq "runningDown" || $state eq "runningDownfortimer") - { - $drivedpercents = $pastaction/$down1time; - $drivedpercents = ( int( $drivedpercents * 10 ) / 10 ); - Log3( $name, 5, "Siro-Set: Positionsveraenderung um $drivedpercents Prozent nach unten "); - - - if (AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1") - { - $newposition = int ($position-$drivedpercents); - } - else{ - $newposition = int ($position+$drivedpercents); - } - } - - if ($state eq "runningUp" || $state eq "runningUpfortimer") - { - $drivedpercents = $pastaction/$up1time; - $drivedpercents = ( int( $drivedpercents * 10 ) / 10 ); - Log3( $name, 5, "Siro-Set: Positionsveraenderung um $drivedpercents Prozent nach oben "); - - if (AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1") - { - $newposition = int ($position+$drivedpercents); - } - else{ - $newposition = int ($position-$drivedpercents); - } - } - - Log3( $name, 5, "Siro-Set: neue Position - $newposition "); - - my $operationtime = ReadingsNum( $name, 'motor-term', 0 ); - my $newoperationtime = $operationtime + $pastaction; - - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "state", $newposition ) ; - readingsBulkUpdate( $hash, "pct", $newposition ) ; - readingsBulkUpdate( $hash, "position", $newposition) ; - readingsBulkUpdate( $hash, "aktRunningAction", "noAction" ) ; - readingsBulkUpdate( $hash, "aktEndAction", 0 ) ; - readingsBulkUpdate( $hash, "aktTimeAction", 0 ) ; - readingsBulkUpdate( $hash, "aktActionFinish", 0 ) ; - readingsBulkUpdate( $hash, "motor-term", $newoperationtime, 1 ) ; - readingsEndUpdate($hash, 1); - - if (defined $comand and $comand ne "stop") #wenn anders kommando als stop befehl zwischenspeichern und per internal timer neu aufrufen , vorher fahrt stoppen per befehl. Stopbefehl l?uft durch wegen notbetrieb ohne timer attribute, gespeicherter befehl wir abgelegt in reading ($cmd) helper/cmd1 und ($zielposition) helper/cmd2. bei aufruf set wird auf vorhandensein gepr?ft. - { - SendCommand( $hash, 'stop' ); - Log3( $name, 5, "Siro-Set: Twischenspeichern von Cmd ($cmd) und Position ($zielposition)"); - $hash->{helper}{savedcmds}{cmd1} = $cmd; - $hash->{helper}{savedcmds}{cmd2} = $zielposition if defined $zielposition; - InternalTimer( time, "FHEM::Siro::Restartset", "$name" ); - return; - } - } - - Log3( $name, 5, "Siro-Set: cmd nach change : $comand") if defined $comand;; -############################# -#pct 100 und pct 0 auf on oder off mappen - if (defined $comand and $comand eq "level" and $zielposition eq "100") - { - $comand = "on" if AttrVal( $name, 'SIRO_inversPosition',0 ) eq "0"; - $comand = "off" if AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1"; - Log3( $name, 4, "Siro-Set: mapping level 100 - on"); - } - - if (defined $comand and $comand eq "level" and $zielposition eq "0") - { - $comand = "off" if AttrVal( $name, 'SIRO_inversPosition',0 ) eq "0"; - $comand = "on" if AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1"; - Log3( $name, 4, "Siro-Set: mapping level 0 - off"); - } - -############################# -# mappe invers position - # verschoben in routine on/off - -############################# on off for timer -# up/down for timer mappen auf on/off und timer für stop setzen - if (defined $comand and $comand eq 'upfortimer' ) - { - Log3( $name, 5, "Siro-Set: up_for_timer $args[1]" ); - $hash->{helper}{savedcmds}{cmd1} = 'stop'; - InternalTimer( time + $args[1], "FHEM::Siro::Restartset", "$name" ); - } - -############################# on off for timer - -# up/down for timer mappen auf on/off und timer für stop setzen - if (defined $comand and $comand eq 'downfortimer' ) - { - Log3( $name, 5, "Siro_Set: down_for_timer $args[1]" ); - $hash->{helper}{savedcmds}{cmd1} = 'stop'; - InternalTimer( time + $args[1], "FHEM::Siro::Restartset", "$name" ); - } -############################# - if (defined $comand and $comand eq "fav") # favoritenanfahrt - { - if ($favposition eq "nA") - { - Log3( $name, 1, "Siro-Set: Favoritenanfahrt nicht m?glich , Reading nicht gesetzt"); - return; - } - Log3( $name, 3, "Siro-Set ($name) : set Favorit"); - SendCommand( $hash, 'stop' , 'longstop' ); - # befehl ?ndern auf position favorite - # weiterer programmdurchlauf - # per defintition keine weiteren send kommandos helper exexcmd on/off (off) - $hash->{helper}{exexcmd} = 'off'; # schaltet das senden folgender befehls ab / nur anpassung der readings - $comand = "level"; - $zielposition = $favposition; - } -############################# -# favoritenposition speichern - if ( $cmd eq "set_favorite" ) { - - # lockdevive einrichten ! - readingsSingleUpdate( $hash, "state", 'programming', 1 ); - - my $sequence ; - my $blocking; - if ($favposition eq "nA") - { - $sequence = '1:prog,3:stop,3:stop' ; - $blocking = 8; - } - else - { - $sequence = '1:prog,3:stop,3:stop,3:prog,3:stop,3:stop' ; - $blocking =17; - } - - my @sequenzraw =split (/,/,$sequence); - my $exectime = $actiontime; - foreach my $seqpart (@sequenzraw) - { - Log3( $name, 5, "Siro-Set: Favorit seqpart - $seqpart"); - my @seqpartraw =split (/\:/,$seqpart); - #$actiontime - $exectime = $exectime+$seqpartraw[0]; - my $execcmd = $seqpartraw[1]; - Log3( $name, 5, "Siro-Set: Favorit $exectime - $execcmd"); - InternalTimer( $exectime, "FHEM::Siro::Prog", $name." ".$execcmd ); - InternalTimer( ($actiontime+$blocking), "FHEM::Siro::Delock", $name ); - } - readingsSingleUpdate( $hash, "Favorite-Position", $position, 1 ); - return; - } - -############################# -# favoritenposition speichern - if ( $cmd eq "del_favorite" ) - { - if ($args[1] eq "only_shutter" || $args[1] eq "shutter_and_modul") - { - readingsSingleUpdate( $hash, "state", 'programming', 1 ); - my $sequence ; - $sequence = '0:prog,2:stop,2:stop' ; - my @sequenzraw =split (/,/,$sequence); - my $exectime = $actiontime; - foreach my $seqpart (@sequenzraw) - { - Log3( $name, 5, "Siro-Set: Delfavorit seqpart - $seqpart"); - my @seqpartraw =split (/\:/,$seqpart); - #$actiontime - $exectime = $exectime+$seqpartraw[0]; - my $execcmd = $seqpartraw[1]; - Log3( $name, 5, "Siro-Set: Delfavorit $exectime - $execcmd"); - InternalTimer( $exectime, "FHEM::Siro::Prog", $name." ".$execcmd ); - InternalTimer( $exectime+10, "FHEM::Siro::Delock", $name ); - } - } - if ($args[1] eq "only_modul" || $args[1] eq "shutter_and_modul") - { - readingsSingleUpdate( $hash, "Favorite-Position", 'nA', 1 ); - } - return; - } - ################# - # favoritenposition anpassen - if ( $cmd eq "Favorite-Position" ) - { - Log3( $name, 5, "Siro-Set: save favposition -> $args[1]"); - readingsSingleUpdate( $hash, "Favorite-Position", $args[1], 1 ); - return; - } - - - ############################# - - # set on ( device faehrt runter ) - if ($comand eq "on" || $comand eq "downfortimer" ) - { - Log3( $name, 3, "Siro-Set ($name) : set Down"); - if ($downtime eq "undef" || $uptime eq "undef") # bei ungesetzten fahrzeiten - { - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "state", "100" ) ; - readingsBulkUpdate( $hash, "pct", "100" ) ; - readingsBulkUpdate( $hash, "motor-term", "Function is not available without set runtime attribute, please define") ; - readingsBulkUpdate( $hash, "LastAction", $comand ); - readingsEndUpdate( $hash, 1); - SendCommand( $hash, 'on' ); - } - if ($state eq "undef" || $state eq "notAvaible") { $state = 0; } - my $waytodrive = 100 - $state; - - if (AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1"){$waytodrive = $state;} - - my $timetodrive = $waytodrive * $down1time; - my $endaction = time + $timetodrive; - Log3( $name, 5, "Siro-Set: on downtime - waytodrive $waytodrive"); - Log3( $name, 5, "Siro-Set: on downtime - state $state"); - Log3( $name, 5, "Siro-Set: on downtime - down1time $down1time"); - SendCommand( $hash, 'on' ); - #SendCommand( $hash, 'stop' ); - - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "aktRunningAction", $comand ) ; - readingsBulkUpdate( $hash, "aktEndAction", $endaction ) ; - readingsBulkUpdate( $hash, "aktTimeAction", $timetodrive ) ; - readingsBulkUpdate( $hash, "aktActionFinish", "100" ) ; - readingsBulkUpdate( $hash, "LastAction", $comand ); - readingsEndUpdate( $hash, 1); - - if ($comand eq "on") - { - readingsSingleUpdate( $hash, "state", "runningDown" , 1 ) ; - # internen timer setzen runningtime - dann states setzen - Log3( $name, 5, "Siro-Set: setze state down , setze Timer - $comand"); - InternalTimer( $endaction, "FHEM::Siro::Finish", "$name" ); - } - else{ - readingsSingleUpdate( $hash, "state", "runningDownfortimer" , 1 ) ; - } - #befehl ausfuhren - } - -############################# - # set off ( device faeht hoch ) - if ($comand eq "off" || $comand eq "upfortimer" ) - { - Log3( $name, 3, "Siro-Set ($name) : set Up"); - if ($downtime eq "undef" || $uptime eq "undef") # bei ungesetzten fahrzeiten - { - - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "state", "0" ) ; - readingsBulkUpdate( $hash, "pct", "0" ) ; - readingsBulkUpdate( $hash, "motor-term", "Function is not available without set runtime attribute, please define") ; - readingsBulkUpdate( $hash, "LastAction", $comand ); - readingsEndUpdate( $hash, 1); - SendCommand( $hash, 'off' ); - - #return; - } - # - if ($state eq "undef" || $state eq "notAvaible") { $state = 100; } - - my $waytodrive = 0 + $state; - if (AttrVal( $name, 'SIRO_inversPosition',0 ) eq "1"){$waytodrive = 0 + (100- $state);} - my $timetodrive = $waytodrive * $up1time; - my $endaction = time + $timetodrive; - Log3( $name, 5, "Siro-Set: off downtime - waytodrive $waytodrive"); - Log3( $name, 5, "Siro-Set: off downtime - state $state"); - Log3( $name, 5, "Siro-Set: off downtime - up1time $up1time"); - SendCommand( $hash, 'off' ); - - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "aktRunningAction", $comand ) ; - readingsBulkUpdate( $hash, "aktEndAction", $endaction ) ; - readingsBulkUpdate( $hash, "aktTimeAction", $timetodrive ) ; - readingsBulkUpdate( $hash, "aktActionFinish", "0" ) ; - readingsBulkUpdate( $hash, "LastAction", $comand ); - readingsEndUpdate( $hash, 1); - - - if ($comand eq "off") - { - readingsSingleUpdate( $hash, "state", "runningUp" , 1 ) ; - - # internen timer setzen runningtime - dann states setzen - Log3( $name, 5, "Siro-Set: setze timer -$comand"); - InternalTimer( $endaction, "FHEM::Siro::Finish", "$name" ); - } - else - { - readingsSingleUpdate( $hash, "state", "runningUpfortimer" , 1 ) ; - } - - #befehl ausfuhren - } - -############################# - # set level ( positionsanfahrt ) - if ($comand eq "level") - { - - if ( AttrVal($name,'SIRO_inversPosition','0') eq '1' ) - { - $zielposition = 100 - $zielposition; - $state = 100 - $state; - } - - Log3( $name, 3, "Siro-Set ($name) : set Position $zielposition "); - - if ($downtime eq "undef" || $uptime eq "undef") # bei ungesetzten fahrzeiten - { - Log3( $name, 1, "ERROR Siro - Set: Function is not available without set runtime attribute, please define"); - readingsSingleUpdate( $hash, "LastAction", $comand, 1 ); - readingsSingleUpdate( $hash, "motor-term", "Function is not available without set runtime attribute, please define", 1 ) ; - return "Function PCT is not available without set runtime attribute, please define "; - } - my $timetodrive; #enth?tlt fahrzeit - my $cmdpos ="undef"; # enth?lt fahrbefehl f?r gew?nschte richtung - my $cmdactiontime ; # enth?lt fahrtdauer f?r gew?nschte position - my $directionmsg; #enth?lt actionstesxt - # geforderte farhtrichtung ermitteln - if ($state < $zielposition) # fahrt runter ben?tigt - { - $cmdpos = "on"; - # fahrdauer ermitteln - $timetodrive = ($zielposition - $state) * $down1time; - $directionmsg ="runningDown"; - } - - if ($state > $zielposition) # fahrt hoch ben?tigt - { - $cmdpos = "off"; - # fahrdauer ermitteln - $timetodrive = ($state - $zielposition) * $up1time; - $directionmsg ="runningUp"; - } - - my $endaction = time + $timetodrive; - SendCommand( $hash, $cmdpos ); - - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "aktRunningAction", 'position' ) ; - readingsBulkUpdate( $hash, "aktEndAction", $endaction ) ; - readingsBulkUpdate( $hash, "aktTimeAction", $timetodrive ) ; - readingsBulkUpdate( $hash, "aktActionFinish", $zielposition ) ; - readingsBulkUpdate( $hash, "state", $directionmsg ) ; - readingsEndUpdate( $hash, 1); - - # internen timer setzen runningtime - dann states setzen - Log3( $name, 5, "Siro-Set: setze timer -$comand"); - InternalTimer( $endaction, "FHEM::Siro::Finish", "$name" ); - - Log3( $name, 5, "Siro-Set: found direction - $cmdpos"); - Log3( $name, 5, "Siro-Set: found finish - $zielposition"); - Log3( $name, 5, "Siro-Set: found position now - $state"); - - } - -############################# - # set stop - if ($comand eq "stop" && ReadingsVal( $name, 'LastAction', 'undef' ) ne $comand ) - { - Log3( $name, 3, "Siro-Set ($name) : set Stop "); - if ($downtime eq "undef" || $uptime eq "undef") # bei ungesetzten fahrzeiten - { - SendCommand( $hash, 'stop' ); - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "state", "notAvaible" ) ; - readingsBulkUpdate( $hash, "LastAction", $comand ); - readingsBulkUpdate( $hash, "motor-term", "Function is not available without set runtime attribute, please define", 1 ) ; - readingsEndUpdate( $hash, 1); - return; - } - else # bei gesetzten fahrzeiten - { - SendCommand( $hash, 'stop' ); - } - - } -############################# - # batteriecheck - if ( AttrVal( $name, 'SIRO_Battery_low','undef' ) ne "undef") - { - readingsSingleUpdate( $hash, "batteryState", "ok" , 1 ) if (AttrVal( $name, 'SIRO_Battery_low','' ) > ReadingsNum( $name, 'motor-term', 0 )); - readingsSingleUpdate( $hash, "batteryState", "low" , 1 ) if (AttrVal( $name, 'SIRO_Battery_low','' ) < ReadingsNum( $name, 'motor-term', 0 )); - } - else - { - readingsSingleUpdate( $hash, "batteryState", "unknown" , 1 ); - } - return; -} - -############################# -sub Delock($) { -# entsperrt device nach programmierung des shutters - my ($input) = @_; - my ( $name, $arg ) = split(/ /, $input ); - my $hash = $defs{$name}; - my $position = ReadingsVal( $name, 'pct', '' ); #position pct bis zum ende einer aktion - readingsSingleUpdate( $hash, "state", $position , 1 ); - } - -############################# -sub Prog($) { -#wird im programmiermode von internaltimer aufgerufen - my ($input) = @_; - my ( $name, $arg ) = split(/ /, $input ); - my $hash = $defs{$name}; - Log3( $name, 5, "Siro-Prog: $arg "); - SendCommand( $hash, $arg ); - return; - } - -############################# -sub Finish($) { -# wird bei errechnetem aktionsende aufgerufen - my ($input) = @_; - my ( $name, $arg ) = split( / /, $input ); - my $hash = $defs{$name}; - return "" if ( IsDisabled($name) ); - - my $invers = 1; - my $action = ReadingsVal( $name, 'aktRunningAction', '' ); - my $state = ReadingsVal( $name, 'aktActionFinish', 'notAvaible' ); - my $operationtime = ReadingsNum( $name, 'motor-term', 0 ); - my $newoperationtime = $operationtime + ReadingsNum ($name, 'aktTimeAction', 0 ); - - Log3( $name, 5, "Siro-Finish: action - $action"); - - SendCommand( $hash, 'stop' ) if ( $action ne "on" && $action ne "off" ) ; - - if ( AttrVal($name,'SIRO_inversPosition','0') eq '1' ) - { - $state = 100 - $state; - } - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "state", $state ) ; - readingsBulkUpdate( $hash, "pct", $state ) ; - readingsBulkUpdate( $hash, "position", $state ) ; - readingsBulkUpdate( $hash, "aktRunningAction", "noAction" ) ; - readingsBulkUpdate( $hash, "aktEndAction", 0 ) ; - readingsBulkUpdate( $hash, "aktTimeAction", 0 ) ; - readingsBulkUpdate( $hash, "aktActionFinish", 0 ) ; - readingsBulkUpdate( $hash, "motor-term", $newoperationtime, 1 ) ; - readingsEndUpdate( $hash, 1); - return; - } - -############################# -sub Restartset($) { - my ($input) = @_; - my ( $name, $arg ) = split( / /, $input ); - my $hash = $defs{$name}; - return "" if ( IsDisabled($name) ); - Log3( $name, 5, "Siro-Restartset : aufgerufen"); - my $cmd = $hash->{helper}{savedcmds}{cmd1}; - my $pos = $hash->{helper}{savedcmds}{cmd2}; - delete( $hash->{helper}{savedcmds} ); - Log3( $name, 5, "Siro-Restartset : cmds $input"); - Set($hash, $name, $cmd , $pos); - return; -} -############################# - -sub fhemwebFn($$$$) { -my ( $FW_wname, $d, $room, $pageHash ) =@_; # pageHash is set for summaryFn. - my $hash = $defs{$d}; - my $name = $hash->{NAME}; - - my $progmode =$hash->{helper}{progmode}; - Log3( $name, 5, "Siro-progmode: reached progmode $progmode"); - if (!defined $progmode){$progmode='off';} - my $msg; - -############################# -# debugmode - - if (AttrVal( $name, 'SIRO_no_IO_msg',0 ) eq "1") - { - delete( $hash->{Signalduino_RAWMSG} ); - delete( $hash->{Signalduino_MSGCNT} ); - delete( $hash->{Signalduino_RSSI} ); - delete( $hash->{Signalduino_TIME} ); - } - - - - if (AttrVal( $name, 'SIRO_debug', "0" ) eq "1") - { - $msg.= " - -
 
Das Device ist im Debugmodus, es werden keine Befehle gesendet"; - $msg.= "
 
"; - - } -############################# - - if (AttrVal( $name, 'disable', "0" ) eq "1") - - { - $msg= " - -
 
Das Device ist disabled"; - $msg.= "
 
"; - - } - - - - - if ( $progmode eq "on") - { - $msg= " - -
 
Programmiermodus aktiv, es werden nur folgende Befehle unterstuetzt:
 
"; - $msg.= "Das Anlernen ene Rollos erfolgt unter der ID: "; - - my $sendid = AttrVal( $name, 'SIRO_send_id', 'undef' ); - if ( $sendid eq 'undef') - { - $msg.= $hash->{ID} ; - } - else - { - $msg.= $sendid ; - } - $msg.= " und dem Kanal: "; - my $sendchan = AttrVal( $name, 'SIRO_send_channel', 'undef' ); - if ( $sendchan eq 'undef') - { - $msg.= $hash->{CHANNEL_RECEIVE} ; - } - else - { - $msg.= $sendchan ; - } - - $msg.= "
 
"; - - $msg.= ""; - $msg.= " "; - - $msg.= ""; - $msg.= " "; - - $msg.= ""; - $msg.= " "; - - $msg.= ""; - $msg.= " "; - - $msg.= ""; - $msg.= " "; - - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= " "; - $msg.= ""; - $msg.= " 
 "; - - $msg.= "
- Motor anlernen: P2,P2,DOWN je nach Wicklung des Rollos"; - $msg.= " "; - - $msg.= "
- Motor anlernen: P2,P2,UP je nach Wicklung des Rollos"; - $msg.= " "; - - $msg.= "
- Einstellmodus aktivieren: P2, UP, P2"; - $msg.= " "; - - $msg.= "
- Endlagen loeschen: P2, DOWN, P2"; - $msg.= " "; - - $msg.= "
- Pairing loeschen: P2, STOP, P2"; - $msg.= " "; - - $msg.= "
 
"; - } - - $msg.= ""; - return $msg; -} - -############################# -sub Siro_icon(@) - { - my ($name,$icon) = @_; - my $hash = $defs{$name}; - my $state = ReadingsVal( $name, 'state', 'undef' ); - my $move ="stop"; - $move = "open" if $state eq "100"; - $move = "close" if $state eq "0"; - - if ($state =~ m/[a-z].*/){$state=0;} - my $sticon = "fts_shutter_1w_"; - $sticon = $icon if defined $icon; - - - my $invers = AttrVal( $name, 'SIRO_inversPosition',0 ); - my $ret ="programming:edit_settings notAvaible:hue_room_garage runningUp.*:fts_shutter_up:stop runningDown.*:fts_shutter_down:stop ".$state.":".$sticon.(int($state/10)*10).":".$move; - $ret ="programming:edit_settings notAvaible:hue_room_garage runningUp.*:fts_shutter_up:stop runningDown.*:fts_shutter_down:stop ".$state.":".$sticon.(100 - (int($state/10)*10)).":".$move if $invers eq "1"; - $ret =".*:fts_shutter_all" if ($hash->{CHANNEL_RECEIVE} eq '0'); - $ret =".*:secur_locked\@red" if ReadingsVal( $name, 'lock_cmd', 'off' ) eq 'on'; - - - return $ret; - } - -############################# - -sub Distributor($) { - my ($input) = @_; - my ( $name, $arg, $cmd ) = split( / /, $input ); - my $hash = $defs{$name}; - return "" if ( IsDisabled($name) ); - Log3( $name, 5, "Siro-Distributor : aufgerufen"); - Log3( $name, 5, "Siro-Distributor : Befehl - $arg"); - #suche devices - my $devspec="TYPE=Siro:FILTER=ID=".$hash->{ID}.".*"; - my @devicelist = devspec2array($devspec); - shift @devicelist; - my $devicelist = join(" ",@devicelist); - my $owndef = $hash->{ID}; - Log3( $name, 5, "Siro-Distributor : own DEF - ".$owndef); - - my @list =qw( 1 2 3 4 5 6 7 8 9 A B C D E F); - - foreach my $key (@list) - { - my $targdev = $owndef.$key; - if (defined $modules{Siro}{defptr}{$targdev}) - { - Log3( $name, 5, "Siro-Distributor : found defice kanal $key ID ".$modules{Siro}{defptr}{$targdev}); - my $devhash = $modules{Siro}{defptr}{$targdev}; - my $msg = "P72#".$targdev.$cmd; - my $devname = $devhash->{NAME}; - #$cmd = $codes{$cmd}; - Log3( $name, 5, "Siro-Distributor : transfer msg für $devname - $msg -$cmd"); - fhem( "set " . $devname . " " . $arg. " fakeremote" ); - } - } - - readingsSingleUpdate( $hash, "LastAction", $arg, 1 ); - readingsSingleUpdate( $hash, "state", $arg, 1 ); - readingsSingleUpdate( $hash, "GroupDevices", $devicelist, 1 ); - - delete( $hash->{Signalduino_RAWMSG} ); - delete( $hash->{Signalduino_MSGCNT} ); - delete( $hash->{Signalduino_RSSI} ); - delete( $hash->{Signalduino_TIME} ); - return; -} - - -1; - -=pod - -=item summary Supports rf shutters from Siro -=item summary_DE Unterstützt Siro Rollo-Funkmotoren - - -=begin html - - -

Siro protocol

- - -=end html - -=begin html_DE - - -

Siro protocol

- - -=end html_DE - - - -=cut \ No newline at end of file