98_HOL.pm 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package main;
  2. use strict;
  3. use warnings;
  4. use POSIX;
  5. use Time::HiRes qw(gettimeofday);
  6. sub CommandHOL($$);
  7. #####################################
  8. sub
  9. HOL_Initialize($$) {
  10. my ($hash) = @_;
  11. $hash->{SetFn} = "HOL_Set";
  12. $hash->{DefFn} = "HOL_Define";
  13. $hash->{UndefFn} = "HOL_Undef";
  14. }
  15. sub
  16. HOL_Set {
  17. my ($hash, @a) = @_;
  18. my $name = shift @a;
  19. my $v = join(" ", @a);
  20. my $currentState = $hash->{STATE};
  21. return "state is already $v" if $currentState eq $v;
  22. if ($v eq "on" || $v eq "off" || $v eq "switch") {
  23. if($v eq "on") {
  24. $hash->{STATE} = "on";
  25. HOL_switch($hash);
  26. } elsif ($v eq "off") {
  27. $hash->{STATE} = "off";
  28. HOL_turnOffCurrentDevice($hash);
  29. } elsif ($v eq "switch") {
  30. my $state = "$hash->{STATE}";
  31. return "can only switch if state is on" if ($state ne "on");
  32. HOL_switch($hash);
  33. }
  34. return $v;
  35. } else {
  36. return "unknown set value, choose one of on off switch";
  37. }
  38. }
  39. sub
  40. HOL_Define($$) {
  41. my ($hash, $def) = @_;
  42. return undef;
  43. }
  44. sub
  45. HOL_turnOffCurrentDevice {
  46. my ($hash) = @_;
  47. RemoveInternalTimer($hash);
  48. if (defined($hash->{currentSwitchDevice})) {
  49. my $currentDeviceName = $hash->{currentSwitchDevice};
  50. fhem "set $currentDeviceName off";
  51. }
  52. }
  53. sub
  54. HOL_switch {
  55. my ($hash) = @_;
  56. HOL_turnOffCurrentDevice($hash);
  57. my $state = $hash->{STATE};
  58. Log 2, "holiday state is $state";
  59. return undef if ($state eq "off");
  60. my $deviceName;
  61. if (defined($hash->{currentSwitchDevice}) &&
  62. defined($attr{$hash->{currentSwitchDevice}}{holidaySwitchFollowUp})) {
  63. my $followUp = $attr{$hash->{currentSwitchDevice}}{holidaySwitchFollowUp};
  64. Log 2, "possible follow up devices $followUp";
  65. my @possibleDevices = split(/,/, $followUp);
  66. $deviceName = HOL_GetRandomItemInArray(@possibleDevices);
  67. Log 2, "follow up $deviceName";
  68. } else {
  69. my @switchDevices = HOL_getHolidaySwitchDeviceNames();
  70. $deviceName = HOL_GetRandomItemInArray(@switchDevices);
  71. Log 2, "no follow up, chose $deviceName";
  72. }
  73. my $switchTime = $attr{$deviceName}{holidaySwitchTime};
  74. my $waitTime = int(rand(10)) + 5;
  75. $hash->{currentSwitchDevice} = $deviceName;
  76. $hash->{currentSwitchTime} = $switchTime;
  77. my $nextTrigger = gettimeofday()+$switchTime+$waitTime;
  78. $hash->{lastTrigger} = TimeNow();
  79. $hash->{nextTrigger} = FmtDateTime($nextTrigger);
  80. fhem "set $deviceName on-for-timer $switchTime";
  81. InternalTimer($nextTrigger, "HOL_switch", $hash, 0);
  82. return 1;
  83. }
  84. sub
  85. HOL_Undef($$)
  86. {
  87. my ($hash, $arg) = @_;
  88. RemoveInternalTimer($hash);
  89. return undef;
  90. }
  91. sub
  92. HOL_GetRandomItemInArray {
  93. my (@arr) = @_;
  94. my $arrayPosition = int(rand(scalar(@arr)));
  95. return $arr[$arrayPosition];
  96. }
  97. sub HOL_getHolidaySwitchDeviceNames() {
  98. my @devices = ();
  99. my $device;
  100. for my $deviceKey (keys %defs) {
  101. $device = $defs{$deviceKey};
  102. next if $device->{TYPE} ne "FS20" || ! defined($attr{$deviceKey}{holidaySwitchTime});
  103. push (@devices, $device->{NAME});
  104. }
  105. return @devices;
  106. }
  107. 1;
  108. =pod
  109. =begin html
  110. <a name="HOL"></a>
  111. <h3>HOL</h3>
  112. <ul>
  113. <tr>The HOL module attempts to simulate your presence using your FHEM devices.<br/>
  114. Device support: All devices that are able to handle on-for-timer and on commands.<br />
  115. Currently the device can be found within the <i>contrib/</i> folder.<td>
  116. <br /><br />
  117. <a name="HOLdefine"></a>
  118. <b>Define</b>
  119. <ul>
  120. <code>define &lt;name&gt; HOL</code><br>
  121. <br>
  122. To make the module find the devices you want to switch in holiday mode,
  123. you have to specify a global user attribute (attr global userattr holidaySwitchTime).
  124. The attribute tells the HOL module how long each device should be switched on.
  125. If you want to switch a device in your FHEM configuration, just add this attribute as device attribute
  126. with your defined duration.
  127. When being switched to on, the module chooses a random defined device
  128. having the <i>holidaySwitchTime</i> attribute and trigger it to on-for-timer.
  129. After the on-timespan, this device is switched to off and another random one triggered to on-for-timer.
  130. </ul>
  131. <br>
  132. <a name="HOLset"></a>
  133. <b>Set</b>
  134. <ul>
  135. <li>on</li>
  136. <li>off</li>
  137. </ul>
  138. </ul>
  139. =end html
  140. =cut