88_xs1Dev.pm 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. #################################################################
  2. # $Id: 88_xs1Dev.pm 16598 2018-04-13 13:48:07Z HomeAuto_User $
  3. #################################################################
  4. # logisches Modul - einzelnes Gerät, über das mit physikalisches
  5. # Modul kommuniziert werden kann
  6. #
  7. # note / ToDo´s:
  8. # - PERL WARNING: Use of uninitialized value $_
  9. # - PERL WARNING: Use of uninitialized value $cmdList in string
  10. # - PERL WARNING: Use of uninitialized value $cmdList in concatenation
  11. #################################################################
  12. package main;
  13. # Laden evtl. abhängiger Perl- bzw. FHEM-Module
  14. use strict;
  15. use warnings; # Warnings
  16. use POSIX;
  17. use Time::Local;
  18. #use SetExtensions;
  19. sub xs1Dev_Initialize($) {
  20. my ($hash) = @_;
  21. $hash->{Match} = "[x][s][1][D][e][v][_][A][k][t][o][r]_[0-6][0-9].*|[x][s][1][D][e][v][_][S][e][n][s][o][r]_[0-6][0-9].*"; ## zum testen - https://regex101.com/
  22. $hash->{DefFn} = "xs1Dev_Define";
  23. $hash->{AttrFn} = "xs1Dev_Attr";
  24. $hash->{ParseFn} = "xs1Dev_Parse";
  25. $hash->{SetFn} = "xs1Dev_Set";
  26. $hash->{UndefFn} = "xs1Dev_Undef";
  27. $hash->{AttrList} = "debug:0,1 ".
  28. "IODev ".
  29. "useSetExtensions:0,1 ".
  30. $readingFnAttributes;
  31. $hash->{AutoCreate} = { "xs1Dev_Sensor_.*" => { GPLOT => "temp4hum4:Temp/Hum,", FILTER=>"%NAME", } };
  32. }
  33. sub xs1Dev_Define($$) {
  34. # $def --> Definition des Module
  35. # $hash --> ARRAY des Module
  36. my ($hash, $def) = @_;
  37. my @arg = split("[ \t][ \t]*", $def);
  38. #-----0------1------2----3----4
  39. return "Usage: define <NAME> xs1Dev <Typ> <ID> | wrong number of arguments" if( @arg != 4);
  40. return "Usage: define <NAME> xs1Dev <Typ> <ID> | wrong ID, must be 1-64" if ( $arg[3] <1 || $arg[3] >64);
  41. return "Usage: define <NAME> xs1Dev <Typ> <ID> | wrong Typ, must be A or S" if ( $arg[2] ne "A" && $arg[2] ne "S");
  42. splice( @arg, 1, 1 );
  43. my $iodev;
  44. my $i = 0;
  45. ############## !! ################ nicht genutzt derzeit ############# !! #################
  46. #### Schleife (Durchlauf der Argumente @arg) wo IODev= gefiltert wird aus define | Dispatch
  47. foreach my $param ( @arg ) {
  48. if( $param =~ m/IODev=([^\s]*)/ ) {
  49. $iodev = $1;
  50. splice( @arg, $i, 3 );
  51. last;
  52. }
  53. $i++;
  54. }
  55. ###########################################################################################
  56. my $name = $hash->{NAME}; ## Der Definitionsname, mit dem das Gerät angelegt wurde.
  57. my $typ = $hash->{TYPE}; ## Der Modulname, mit welchem die Definition angelegt wurde.
  58. #Log3 $name, 3, "$typ: Define arguments 0:$arg[0] | 1:$arg[1] | 2:$arg[2] | 3:$arg[3]";
  59. # Parameter Define
  60. my $xs1_ID = $arg[2]; ## Zusatzparameter 1 bei Define - ggf. nur in Sub
  61. my $xs1_typ1 = $arg[1]; ## A || S
  62. my $Device = $xs1_typ1.$xs1_ID; ## A02 || S05
  63. my $Device_count = 0;
  64. my $Device_exist;
  65. ### Check A02 || S05 bereits definiert
  66. foreach my $d (sort keys %defs) {
  67. if(defined($defs{$d}) && defined($defs{$d}{ID}) && $defs{$d}{ID} eq $Device) {
  68. $Device_count++;
  69. $Device_exist = $d;
  70. Log3 $name, 3, "$typ: $d $Device_count";
  71. }
  72. }
  73. return "The xs1 <ID> $Device is already definded: $Device_exist" if ($Device_count != 0);
  74. $hash->{ID} = $xs1_typ1.$xs1_ID; ## A02 || S05
  75. $modules{xs1Dev}{defptr}{$xs1_typ1.$xs1_ID} = $hash; ## !!! Adresse rückwärts dem Hash zuordnen (für ParseFn)
  76. my $debug = AttrVal($hash->{NAME},"debug",0);
  77. AttrVal($hash->{NAME},"useSetExtensions",0);
  78. $hash->{STATE} = "Defined"; ## Der Status des Modules nach Initialisierung.
  79. $hash->{TIME} = time(); ## Zeitstempel, derzeit vom anlegen des Moduls
  80. #$hash->{VERSION} = "1.17"; ## Version
  81. $hash->{xs1_name} = "undefined"; ## Aktor | Sensor Name welcher def. im xs1
  82. $hash->{xs1_typ} = "undefined"; ## xs1_Typ switch | hygrometer | temperature ...
  83. if ($xs1_typ1 eq "A"){
  84. $hash->{xs1_function1} = "undefined"; ## xs1_Funktion zugeordnete Funktion 1
  85. $hash->{xs1_function2} = "undefined"; ## xs1_Funktion zugeordnete Funktion 2
  86. $hash->{xs1_function3} = "undefined"; ## xs1_Funktion zugeordnete Funktion 3
  87. $hash->{xs1_function4} = "undefined"; ## xs1_Funktion zugeordnete Funktion 4
  88. }
  89. # Attribut gesetzt
  90. $attr{$name}{room} = "xs1" if( not defined( $attr{$name}{room} ) );
  91. AssignIoPort($hash,$iodev) if( !$hash->{IODev} ); ## sucht nach einem passenden IO-Gerät (physikalische Definition)
  92. # alles mit IODev erst NACH AssignIoPort nutzbar !!!
  93. $hash->{VERSION} = $hash->{IODev}->{VERSION}; ## Version
  94. if(defined($hash->{IODev}->{NAME})) {
  95. Log3 $name, 4, "xs1Dev: $name - I/O Device is " . $hash->{IODev}->{NAME};
  96. } else {
  97. Log3 $name, 3, "xs1Dev: $name - no I/O Device, Please delete and restart FHEM.";
  98. }
  99. #$iodev = $hash->{IODev}->{NAME};
  100. # if(defined($hash->{IODev}->{xs1_ip})) { ## IP von xs1Bridge - Device aus HASH
  101. # $hash->{xs1_ip} = $hash->{IODev}->{xs1_ip};
  102. # }
  103. return undef;
  104. }
  105. sub xs1Dev_Attr()
  106. {
  107. my ($cmd,$name,$attrName,$attrValue) = @_;
  108. my $hash = $defs{$name};
  109. my $typ = $hash->{TYPE};
  110. my $debug = AttrVal($hash->{NAME},"debug",0);
  111. #Debug " $name: Attr | Attributes $attrName = $attrValue" if($debug);
  112. }
  113. sub xs1Dev_Set ($$@)
  114. {
  115. my ( $hash, $name, @args ) = @_;
  116. my $xs1_ID = $hash->{ID};
  117. my $typ = $hash->{TYPE}; ## xs1Dev
  118. my $cmd = $args[0];
  119. my $debug = AttrVal($hash->{NAME},"debug",0);
  120. my $xs1_typ = $hash->{xs1_typ};
  121. my $Aktor_ID = substr($xs1_ID,1,2); ## A01 zu 01
  122. my $cmd2; ## notwendig für Switch Funktionsplatz xs1
  123. my $cmdFound;
  124. return "no set value specified" if(int(@args) < 1);
  125. my %xs1_function = (); ## Funktionen in ARRAY schreiben
  126. my %setList = (); ## Funktionen als Liste
  127. my %setListPos = (); ## Funktionen als Position|Funktion
  128. Debug " -------------- ERROR CHECK - START --------------" if($debug && $cmd ne "?");
  129. # http://192.168.2.5/control?callback=cname&cmd=set_state_actuator&number=7&function=1
  130. if (substr($xs1_ID,0,1) eq "A" && $xs1_typ ne "undefined") { ## nur bei Aktoren und nicht "undefined"
  131. for (my $d = 0; $d < 4; $d++) {
  132. if ($hash->{"xs1_function".($d+1)} ne "-") {
  133. if ($hash->{"xs1_function".($d+1)} eq "dim_up") { ## FHEM Mod xs1 dim_up -> FHEM dimup
  134. $xs1_function{"dimup:noArg"} = ($d+1);
  135. } elsif ($hash->{"xs1_function".($d+1)} eq "dim_down") { ## FHEM Mod xs1 dim_down -> FHEM dimdown
  136. $xs1_function{"dimdown:noArg"} = ($d+1);
  137. } elsif (exists $xs1_function{$hash->{"xs1_function".($d+1)}.":noArg"}){ ## CHECK ob Funktion bereits exists
  138. $xs1_function{$hash->{"xs1_function".($d+1)}."_".($d+1).":noArg"} = ($d+1);
  139. } else {
  140. $xs1_function{$hash->{"xs1_function".($d+1)}.":noArg"} = ($d+1); ## xs1 Standardbezeichnung Funktion
  141. }
  142. }
  143. }
  144. if ($xs1_typ eq "dimmer"){ #bei dimmer Typ, dim hinzufügen FHEM
  145. $xs1_function{"dim"} = (5);
  146. }
  147. while ( (my $k,my $v) = each %xs1_function ) {
  148. if ($v > 0 && $v < 7) {
  149. $setListPos{$v."|".$k} = $k;
  150. #Debug " $name: Set | $k|$v" if($debug && $cmd ne "?");
  151. }
  152. }
  153. my $setList = join(" ", keys %xs1_function);
  154. my $setListAll = join(" ", keys %setListPos);
  155. my $cmdFound = index($setListAll, $cmd.":"); ## check cmd in setListAll - Zuordnung Platz
  156. my $cmdFound2 = "";
  157. if ($cmdFound >= 0) { #$cmd für Sendebefehl anpassen
  158. $cmdFound2 = substr($setListAll,$cmdFound-2,1);
  159. $cmd2 = "function=".$cmdFound2;
  160. } else {
  161. $cmd2 = $cmd.$args[1] if (defined $args[1]);
  162. }
  163. ### dimmer - spezifisch dim hinzufügen FHEM + value Check
  164. if ($xs1_typ eq "dimmer" && $cmd eq "dim") {
  165. if (not defined $args[1]) {
  166. return "dim value arguments failed";
  167. } elsif ($args[1] !~ /[a-zA-Z]/ && $args[1] <= 1 || $args[1] !~ /[a-zA-Z]/ && $args[1] >= 99) {
  168. return "dim value must be 1 to 99";
  169. } elsif ($args[1] =~ /[a-zA-Z]/) {
  170. return "wrong dim value format! only value from 1 to 99";
  171. } else {
  172. $cmd = $cmd.$args[1]."%"; ## FHEM state mod --> anstatt nur dim --> dim47%
  173. }
  174. }
  175. Debug " $name: Set | xs1_typ=$xs1_typ cmd=$cmd setListAll=$setListAll cmdFound=$cmdFound cmdFound2=$cmdFound2" if($debug && $cmd ne "?");
  176. if(AttrVal($name,"useSetExtensions",undef) || AttrVal($name,"useSetExtensions","0")) {
  177. $cmd =~ s/([.?*])/\\$1/g;
  178. if($setList !~ m/\b$cmd\b/) {
  179. Debug " $name: Set | useSetExtensions check" if($debug && $cmd ne "?");
  180. unshift @args, $name;
  181. return SetExtensions($hash, $setList, $name, @args);
  182. }
  183. SetExtensionsCancel($hash);
  184. } else {
  185. return "Unknown argument ?, choose one of $setList" if($args[0] eq "?");
  186. }
  187. #Debug " $name: Set | xs1_typ=$xs1_typ (after mod) cmd=$cmd" if($debug && $cmd ne "?");
  188. if(defined($hash->{IODev}->{NAME})) {
  189. if ($xs1_typ eq "switch" || $xs1_typ eq "dimmer" || $xs1_typ eq "shutter" || $xs1_typ eq "timerswitch" && $cmd ne "?") {
  190. Debug " $name: Set IOWrite | xs1_ID=$xs1_ID xs1_typ=$xs1_typ cmd=$cmd cmd2=$cmd2" if($debug && $xs1_typ ne "temperature" && $xs1_typ ne "hygrometer");
  191. #Log3 $name, 3, "$name: Set IOWrite | xs1_ID=$xs1_ID xs1_typ=$xs1_typ cmd=$cmd cmd2=$cmd2 IODev=$hash->{IODev}->{NAME}";
  192. Log3 $name, 3, "$typ set $name $cmd";
  193. IOWrite($hash, $xs1_ID, $xs1_typ, $cmd, $cmd2);
  194. readingsSingleUpdate($hash, "state", $cmd , 1);
  195. }
  196. #else {
  197. #Log3 $name, 2, "$name: Device NOT SUPPORTED for Dispatch. In xs1 disabled.";
  198. #}
  199. } else {
  200. return "no IODev define. Please define xs1Bridge.";
  201. }
  202. #Debug " $name: Set | xs1_ID=$xs1_ID xs1_typ=$xs1_typ" if($debug);
  203. Debug " -------------- ERROR CHECK - END --------------" if($debug);
  204. }
  205. return undef;
  206. }
  207. sub xs1Dev_Parse($$) ## Input Data from 88_xs1Bridge
  208. {
  209. my ( $io_hash, $data) = @_; ## $io_hash = ezControl -> def. Name von xs1Bridge
  210. my ($xs1Dev,$xs1_readingsname,$xs1_ID,$xs1_typ2,$xs1_value,$xs1_f1,$xs1_f2,$xs1_f3,$xs1_f4,$xs1_name) = split("#", $data);
  211. my $xs1_typ1 = substr($xs1_readingsname,0,1); ## A || S
  212. my $def = $modules{xs1Dev}{defptr}{$xs1_typ1.$xs1_ID};
  213. $def = $modules{xs1Dev}{defptr}{$xs1_typ1.$xs1_ID} if(!$def); ## {xs1Dev}{defptr}{A02}
  214. my $hash = $def;
  215. $hash->{xs1_typ} = $xs1_typ2;
  216. $hash->{xs1_name} = $xs1_name;
  217. my $IODev = $io_hash->{NAME};
  218. my $name = $hash->{NAME}; ## xs1Dev_Aktor_01
  219. my $typ = $hash->{TYPE}; ## xs1Dev
  220. $typ = "xs1Dev" if (!$def); ## Erstanlegung
  221. ###### Define and values update ######
  222. #Log3 $typ, 3, "$typ: Parse | Data: $xs1Dev | $xs1_readingsname | $xs1_ID | $xs1_typ2 | $xs1_value | $xs1_typ1" if (!$def);
  223. #Log3 $typ, 3, "$typ: Parse | Data: $xs1Dev | $xs1_readingsname | $xs1_ID | $xs1_typ2 | $xs1_value | $xs1_typ1";
  224. if(!$def) {
  225. # "UNDEFINED xs1Dev_Aktor_12 xs1Dev A 12"
  226. Log3 $name, 3, "$typ: Unknown device ".$xs1Dev."_".$xs1_readingsname."_"."$xs1_ID $xs1_ID $xs1_typ1 , please define it";
  227. return "UNDEFINED xs1Dev"."_".$xs1_readingsname."_"."$xs1_ID xs1Dev $xs1_typ1 $xs1_ID";
  228. } else {
  229. #Log3 $name, 3, "$typ: device $xs1_readingsname"."_"."$xs1_ID xs1_value:$xs1_value xs1_typ2:$xs1_typ2";
  230. AssignIoPort($hash, $io_hash); ## sucht nach einem passenden IO-Gerät (physikalische Definition)
  231. if ($xs1_readingsname eq "Aktor") { ## zugeordnete xs1_Funktionen
  232. $hash->{xs1_function1} = $xs1_f1;
  233. $hash->{xs1_function2} = $xs1_f2;
  234. $hash->{xs1_function3} = $xs1_f3;
  235. $hash->{xs1_function4} = $xs1_f4;
  236. }
  237. #### Typ switch | on | off mod for FHEM Default
  238. if ($xs1_typ2 eq "switch") {
  239. if ($xs1_value == 0) { $xs1_value = "off"; }
  240. elsif ($xs1_value == 100) { $xs1_value = "on"; }
  241. readingsSingleUpdate($hash, "state", $xs1_value ,1); # Aktor | Sensor Update value
  242. ## RegEx devStateIcon da Symbole nicht gleich benannt -> dim_up | dim_down
  243. if ($hash->{xs1_function1} eq "dim_up" || $hash->{xs1_function2} eq "dim_up" || $hash->{xs1_function3} eq "dim_up" || $hash->{xs1_function4} eq "dim_up" ||
  244. $hash->{xs1_function1} eq "dim_down" || $hash->{xs1_function2} eq "dim_down" || $hash->{xs1_function3} eq "dim_down" || $hash->{xs1_function4} eq "dim_down" ) {
  245. $attr{$name}{devStateIcon} = "dim_up:dimup dim_down:dimdown" if( not defined( $attr{$name}{devStateIcon} ) );
  246. }
  247. }
  248. #### Typ temperature
  249. elsif ($xs1_typ2 eq "temperature") {
  250. my $xs1_value_new = "T: ".$xs1_value; ## temperature mod for FHEM Default
  251. readingsBeginUpdate($hash);
  252. readingsBulkUpdate($hash, "state", $xs1_value_new);
  253. readingsBulkUpdate($hash, "temperature", $xs1_value);
  254. readingsEndUpdate($hash, 1);
  255. }
  256. #### Typ hygrometer
  257. elsif ($xs1_typ2 eq "hygrometer") {
  258. my $xs1_value_new = "H: ".$xs1_value; ## hygrometer mod for FHEM Default
  259. readingsBeginUpdate($hash);
  260. readingsBulkUpdate($hash, "state", $xs1_value_new);
  261. readingsBulkUpdate($hash, "humidity", $xs1_value);
  262. readingsEndUpdate($hash, 1);
  263. }
  264. #### Typ dimmer
  265. elsif ($xs1_typ2 eq "dimmer") {
  266. ## RegEx devStateIcon da Symbole nicht durchweg von 0 - 100 | dim_up | dim_down
  267. $attr{$name}{devStateIcon} = "dim0[1-6]\\D%:dim06% dim[7-9]\\D|dim[1][0-2]%:dim12% dim[1][3-8]%:dim18% \n"
  268. ."dim[1][9]|dim[2][0-5]%:dim25% dim[2][6-9]|dim[3][0-1]%:dim31% dim[3][2-7]%:dim37% \n"
  269. ."dim[3][8-9]|dim[4][0-3]%:dim43% dim[4][4-9]|dim[5][0]%:dim50% dim[5][1-6]%:dim56% \n"
  270. ."dim[5][7-9]|dim[6][0-2]%:dim62% dim[6][3-8]%:dim68% dim[6][9]|dim[7][0-5]%:dim75% \n"
  271. ."dim[7][6-9]|dim[8][0-1]%:dim81% dim[8][2-7]%:dim87% dim[8][8-9]|dim[9][0-3]%:dim93% \n"
  272. ."dim[9][4-9]|dim[1][0][0]%:dim100% dim[_][u][p]:dimup dim[_][d][o]:dimdown" if( not defined( $attr{$name}{devStateIcon} ) );
  273. if ($xs1_value ne "0.0") {
  274. $xs1_value = "dim".sprintf("%02d", $xs1_value)."%";
  275. } elsif ($xs1_value eq "0.0") {
  276. $xs1_value = "off";
  277. }
  278. readingsSingleUpdate($hash, "state", $xs1_value ,1);
  279. }
  280. #### Typ shutter | on | off mod for FHEM Default
  281. elsif ($xs1_typ2 eq "shutter") {
  282. if ($xs1_value == 0) { $xs1_value = "off"; }
  283. elsif ($xs1_value == 100) { $xs1_value = "on"; }
  284. readingsSingleUpdate($hash, "state", $xs1_value ,1);
  285. }
  286. #### Typ timerswitch | on | off mod for FHEM Default
  287. elsif ($xs1_typ2 eq "timerswitch") {
  288. if ($xs1_value == 0) { $xs1_value = "off"; }
  289. elsif ($xs1_value == 100) { $xs1_value = "on"; }
  290. readingsSingleUpdate($hash, "state", $xs1_value ,1);
  291. }
  292. elsif ($xs1_typ2 eq "barometer") {
  293. readingsBeginUpdate($hash);
  294. readingsSingleUpdate($hash, "pressure", $xs1_value ,1);
  295. readingsSingleUpdate($hash, "state", "P: ".$xs1_value ,1);
  296. readingsEndUpdate($hash, 1);
  297. }
  298. elsif ($xs1_typ2 eq "rain") {
  299. readingsBeginUpdate($hash);
  300. readingsSingleUpdate($hash, "rain", $xs1_value ,1);
  301. readingsSingleUpdate($hash, "state", "R: ".$xs1_value ,1);
  302. readingsEndUpdate($hash, 1);
  303. }
  304. elsif ($xs1_typ2 eq "rain_1h") {
  305. readingsBeginUpdate($hash);
  306. readingsSingleUpdate($hash, "rain_calc_h", $xs1_value ,1);
  307. readingsSingleUpdate($hash, "state", "R: ".$xs1_value ,1);
  308. readingsEndUpdate($hash, 1);
  309. }
  310. elsif ($xs1_typ2 eq "rain_24h") {
  311. readingsBeginUpdate($hash);
  312. readingsSingleUpdate($hash, "rain_calc_d", $xs1_value ,1);
  313. readingsSingleUpdate($hash, "state", "R: ".$xs1_value ,1);
  314. readingsEndUpdate($hash, 1);
  315. }
  316. elsif ($xs1_typ2 eq "winddirection") {
  317. readingsBeginUpdate($hash);
  318. readingsSingleUpdate($hash, "Winddirection", $xs1_value ,1);
  319. readingsSingleUpdate($hash, "state", "D: ".$xs1_value ,1);
  320. readingsEndUpdate($hash, 1);
  321. }
  322. elsif ($xs1_typ2 eq "windspeed") {
  323. readingsBeginUpdate($hash);
  324. readingsSingleUpdate($hash, "Windspeed", $xs1_value ,1);
  325. readingsSingleUpdate($hash, "state", "W: ".$xs1_value ,1);
  326. readingsEndUpdate($hash, 1);
  327. }
  328. elsif ($xs1_typ2 eq "counter" || $xs1_typ2 eq "counterdiff" || $xs1_typ2 eq "fencedetector" || $xs1_typ2 eq "gas_consump" || $xs1_typ2 eq "gas_peak" ||
  329. $xs1_typ2 eq "light" || $xs1_typ2 eq "motion" || $xs1_typ2 eq "other" || $xs1_typ2 eq "rainintensity" || $xs1_typ2 eq "remotecontrol" ||
  330. $xs1_typ2 eq "uv_index" || $xs1_typ2 eq "waterdetector" || $xs1_typ2 eq "waterlevel" || $xs1_typ2 eq "windgust" || $xs1_typ2 eq "windvariance" ||
  331. $xs1_typ2 eq "wtr_consump" || $xs1_typ2 eq "wtr_peak") {
  332. readingsSingleUpdate($hash, "state", $xs1_value ,1);
  333. }
  334. ### Fenstermelder = windowopen | Tuermelder = dooropen --> 0 zu / 100 offen | mod for FHEM Default
  335. elsif ($xs1_typ2 eq "dooropen" || $xs1_typ2 eq "windowopen") {
  336. if ($xs1_value == 0.0) { $xs1_value = "closed";} elsif ($xs1_value == 100.0) { $xs1_value = "Open"; }
  337. readingsBeginUpdate($hash);
  338. if ($xs1_typ2 eq "windowopen") {
  339. readingsSingleUpdate($hash, "Window", $xs1_value ,1);
  340. }
  341. if ($xs1_typ2 eq "dooropen") {
  342. readingsSingleUpdate($hash, "Door", $xs1_value ,1);
  343. }
  344. my $value = Value($name);
  345. my $OldValue = OldValue($name);
  346. if ($value ne $OldValue) {
  347. readingsSingleUpdate($hash, "Previous", $xs1_value ,0);
  348. }
  349. readingsSingleUpdate($hash, "state", $xs1_value ,0);
  350. readingsEndUpdate($hash, 1);
  351. ### alles andere ...
  352. } else {
  353. readingsBeginUpdate($hash);
  354. readingsSingleUpdate($hash, "state", $xs1_value ,0);
  355. readingsEndUpdate($hash, 1);
  356. }
  357. }
  358. return $name;
  359. }
  360. sub xs1Dev_Undef($$)
  361. {
  362. my ( $hash, $name) = @_;
  363. my $typ = $hash->{TYPE};
  364. delete($modules{xs1Dev}{defptr}{$hash->{ID}});
  365. Log3 $name, 3, "$typ: Device with Name $name delete";
  366. return undef;
  367. }
  368. # Eval-Rückgabewert für erfolgreiches
  369. # Laden des Moduls
  370. 1;
  371. # Beginn der Commandref
  372. =pod
  373. =item summary Control of the devices which defined in xs1
  374. =item summary_DE Steuerung des Ger&auml;te welche im xs1 definiert sind
  375. =begin html
  376. <a name="xs1Dev"></a>
  377. <h3>xs1Dev</h3>
  378. <ul>
  379. This module works with the xs1Bridge module. (The <code>xs1_control</code> attribute in the xs1Bridge module must be set to 1!) <br>
  380. It communicates with this and creates all actuators of the xs1 as a device in FHEM. So you can control the actuators of the xs1 from the FHEM. <br><br>
  381. The module was developed based on the firmware version v4-Beta of the xs1. There may be errors due to different adjustments within the manufacturer's firmware.
  382. <br>
  383. <br><ul>
  384. <u>Currently implemented types of xs1 for processing: </u><br>
  385. <li>Aktor: dimmer, switch, shutter, timerswitch</li>
  386. <li>Sensor: barometer, counter, counterdiff, light, motion, other, rain, rain_1h, rain_24h, rainintensity, remotecontrol, uv_index, waterdetector, winddirection, windgust, windspeed, windvariance</li>
  387. </ul><br><br>
  388. <a name="xs1Dev_define"></a>
  389. <b>Define</b><br>
  390. <ul>
  391. <code>define &lt;name&gt; xs1Dev &lt;Typ&gt; &lt;ID&gt; IODev=&lt;NAME&gt;</code>
  392. <br><br>
  393. It is not possible to create the module without specifying type and ID of xs1.
  394. <ul>
  395. <li><code>&lt;ID&gt;</code> is internal id in xs1.</li>
  396. </ul>
  397. <ul>
  398. <li><code>&lt;Typ&gt;</code> is the abbreviation A for actuators or S for sensors.</li>
  399. </ul><br>
  400. example:
  401. <ul>
  402. define xs1Dev_Aktor_02 xs1Dev A 02 IODev=ezControl
  403. </ul>
  404. </ul><br>
  405. <b>Set</b>
  406. <ul><code>set &lt;name&gt; &lt;value&gt; </code></ul><br>
  407. in which <code>value</code> one of the following values:<br>
  408. <ul><code>
  409. on<br>
  410. off<br>
  411. dimup<br>
  412. dimupdown<br>
  413. toggle<br>
  414. on, wait, off<br>
  415. absolut<br>
  416. wait<br>
  417. long on<br>
  418. long off<br>
  419. Stopp<br>
  420. on, wait, on<br>
  421. off, wait, off<br>
  422. impuls<br>
  423. </code></ul><br>
  424. <b>Get</b><br>
  425. <ul>N/A</ul><br>
  426. <a name="xs1_attr"></a>
  427. <b>Attributes</b>
  428. <ul>
  429. <li>debug (0,1)<br>
  430. This brings the module into a very detailed debug output in the logfile. Thus, program parts can be controlled and errors can be checked.<br>
  431. (Default, debug 0)
  432. </li>
  433. <li>useSetExtensions (0,1)<br>
  434. Toggles the SetExtensions on or off.<br>
  435. (Default, useSetExtensions 0)
  436. </li>
  437. </ul><br>
  438. <b>Explanation:</b>
  439. <ul>
  440. <li>abstract Internals:</li>
  441. <ul>
  442. xs1_function(1-4): defined function in the device<br>
  443. xs1_name: defined name in the device<br>
  444. xs1_typ: defined type in the device<br>
  445. </ul><br>
  446. </ul>
  447. </ul>
  448. =end html
  449. =begin html_DE
  450. <a name="xs1Dev"></a>
  451. <h3>xs1Dev</h3>
  452. <ul>
  453. Dieses Modul arbeitet mit dem Modul xs1Bridge zusammen. (Das Attribut <code>xs1_control</code> im Modul xs1Bridge muss auf 1 gestellt sein!) <br>
  454. Es kommuniziert mit diesem und legt sämtliche Aktoren des xs1 als Device im FHEM an. So kann man vom FHEM aus, die Aktoren der xs1 steuern.
  455. <br><br>
  456. Das Modul wurde entwickelt basierend auf dem Firmwarestand v4-Beta des xs1. Es kann aufgrund von unterschiedlichen Anpassungen innerhalb der Firmware des Herstellers zu Fehlern kommen.<br>
  457. <br><ul>
  458. <u>Derzeit implementierte Typen des xs1 zur Verarbeitung: </u><br>
  459. <li>Aktor: dimmer, switch, shutter, timerswitch</li>
  460. <li>Sensor: barometer, counter, counterdiff, light, motion, other, rain, rain_1h, rain_24h, rainintensity, remotecontrol, uv_index, waterdetector, winddirection, windgust, windspeed, windvariance</li>
  461. </ul><br><br>
  462. <a name="xs1Dev_define"></a>
  463. <b>Define</b><br>
  464. <ul>
  465. <code>define &lt;name&gt; xs1Dev &lt;Typ&gt; &lt;ID&gt; IODev=&lt;NAME&gt;</code>
  466. <br><br>
  467. Ein anlegen des Modules ohne Angabe des Typ und der ID vom xs1 ist nicht möglich.
  468. <ul>
  469. <li><code>&lt;ID&gt;</code> ist interne ID im xs1.</li>
  470. </ul>
  471. <ul>
  472. <li><code>&lt;Typ&gt;</code> ist der Kürzel A für Aktoren oder S für Sensoren.</li>
  473. </ul><br>
  474. Beispiel:
  475. <ul>
  476. define xs1Dev_Aktor_02 xs1Dev A 02 IODev=ezControl
  477. </ul>
  478. </ul><br>
  479. <b>Set</b>
  480. <ul><code>set &lt;name&gt; &lt;value&gt; </code></ul><br>
  481. Wobei <code>value</code> der in der xs1 definierten Funktion entspricht. Bsp:<br>
  482. <ul><code>
  483. an<br>
  484. aus<br>
  485. dimup<br>
  486. dimupdown<br>
  487. umschalten<br>
  488. an, warten, aus<br>
  489. absolut<br>
  490. warten<br>
  491. langes AN<br>
  492. langes AUS<br>
  493. Stopp<br>
  494. an, warten, an<br>
  495. aus, warten, aus<br>
  496. Impuls<br>
  497. </code></ul><br>
  498. <b>Get</b><br>
  499. <ul>N/A</ul><br>
  500. <a name="xs1_attr"></a>
  501. <b>Attribute</b>
  502. <ul>
  503. <li>debug (0,1)<br>
  504. Dies bringt das Modul in eine sehr ausf&uuml;hrliche Debug-Ausgabe im Logfile. Somit lassen sich Programmteile kontrollieren und Fehler &uuml;berpr&uuml;fen.<br>
  505. (Default, debug 0)
  506. </li>
  507. <li>useSetExtensions (0,1)<br>
  508. Schaltet die SetExtensions ein bzw. aus.<br>
  509. (Default, useSetExtensions 0)
  510. </li>
  511. </ul><br>
  512. <b>Erl&auml;uterung:</b>
  513. <ul>
  514. <li>Auszug Internals:</li>
  515. <ul>
  516. xs1_function(1-4): definierte Funktion im Ger&auml;t<br>
  517. xs1_name: definierter Name im Ger&auml;t<br>
  518. xs1_typ: definierter Typ im Ger&auml;t<br>
  519. </ul><br>
  520. </ul>
  521. </ul>
  522. =end html_DE
  523. =cut