57_ABFALL.pm 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. # $Id: 57_ABFALL.pm 11023 2018-06-13 12:34:34Z uniqueck $
  2. ###########################
  3. # ABFALL
  4. #
  5. # needs a defined Device 57_Calendar
  6. ###########################
  7. package main;
  8. use strict;
  9. use warnings;
  10. use POSIX;
  11. use Time::Local;
  12. use Time::Piece;
  13. use ABFALL_setUpdate;
  14. sub ABFALL_Initialize($)
  15. {
  16. my ($hash) = @_;
  17. $hash->{DefFn} = "ABFALL_Define";
  18. $hash->{UndefFn} = "ABFALL_Undef";
  19. $hash->{SetFn} = "ABFALL_Set";
  20. $hash->{AttrFn} = "ABFALL_Attr";
  21. $hash->{NotifyFn} = "ABFALL_Notify";
  22. $hash->{AttrList} = "abfall_clear_reading_regex "
  23. ."disable:0,1 "
  24. ."weekday_mapping calendarname_praefix:1,0 "
  25. ."delimiter_text_reading "
  26. ."delimiter_reading "
  27. ."filter "
  28. ."filter_type:include,exclude "
  29. ."enable_counting_pickups:0,1 "
  30. ."enable_old_readingnames:0,1 "
  31. ."date_style:date,dateTime "
  32. .$readingFnAttributes;
  33. }
  34. sub ABFALL_Define($$){
  35. my ( $hash, $def ) = @_;
  36. my @a = split( "[ \t][ \t]*", $def );
  37. return "\"set ABFALL\" needs at least an argument" if ( @a < 3 );
  38. my $name = $a[0];
  39. my @calendars = split( ",", $a[2] );
  40. foreach my $calender (@calendars)
  41. {
  42. return "invalid calendername \"$calender\", define it first" if((devspec2array("NAME=$calender")) != 1 );
  43. }
  44. $hash->{KALENDER} = $a[2];
  45. $hash->{NOTIFYDEV} = $a[2];
  46. $hash->{NAME} = $name;
  47. $hash->{STATE} = "Initialized";
  48. # prüfen, ob eine neue Definition angelegt wird
  49. if($init_done && !defined($hash->{OLDDEF}))
  50. {
  51. # set default stateFormat
  52. $attr{$name}{"stateFormat"} = "next_text in next_days Tag(en)";
  53. # set calendarname_praefix
  54. $attr{$name}{"calendarname_praefix"} = "0" if(@calendars == 1);
  55. # set default weekday_mapping
  56. $attr{$name}{"weekday_mapping"} = "Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag";
  57. # set default delimiter_text_reading
  58. $attr{$name}{"delimiter_text_reading"} = " und ";
  59. # set default delimiter_reading
  60. $attr{$name}{"delimiter_reading"} = "|";
  61. # set default date_style
  62. $attr{$name}{"date_style"} = "date";
  63. }
  64. InternalTimer(gettimeofday()+2, "ABFALL_setUpdate", $hash, 0);
  65. return undef;
  66. }
  67. sub ABFALL_Undef($$){
  68. my ( $hash, $arg ) = @_;
  69. RemoveInternalTimer($hash);
  70. return undef;
  71. }
  72. sub ABFALL_Set($@){
  73. my ($hash, $name, $cmd, @val) = @_;
  74. my $arg = join("", @val);
  75. my $list = "";
  76. my $result = undef;
  77. $list .= "update:noArg" if($hash->{STATE} ne 'disabled');
  78. $list .= " clear:noArg count" if(AttrVal($name, "enable_counting_pickups","0"));
  79. if ($cmd eq "update") {
  80. ABFALL_setUpdate($hash);
  81. } elsif ($cmd eq "count") {
  82. $result = ABFALL_Count($hash, $arg);
  83. } elsif ($cmd eq "clear") {
  84. ABFALL_Clear($hash);
  85. } else {
  86. $result = "ABFALL_Set ($name) - Unknown argument $cmd or wrong parameter(s), choose one of $list";
  87. }
  88. return $result;
  89. }
  90. sub ABFALL_Clear($) {
  91. my ($hash) = @_;
  92. my $name = $hash->{NAME};
  93. fhem("deletereading $name .*_pickups", 1);
  94. fhem("deletereading $name .*_pickups_used", 1);
  95. }
  96. sub ABFALL_Count($$){
  97. my ($hash, $abfallArt) = @_;
  98. my $name = $hash->{NAME};
  99. my $result = undef;
  100. my $waste_pickup_used = ReadingsVal($name, $abfallArt . "_pickups_used", "-1");
  101. Log3 $name, 5, "ABFALL_Count $abfallArt: looking for reading \"$abfallArt"."_pickups_used\" = $waste_pickup_used";
  102. if ($waste_pickup_used eq "-1") {
  103. $result = "\"set $name count $abfallArt\" : unknown waste type $abfallArt";
  104. } else {
  105. $waste_pickup_used = $waste_pickup_used + 1;
  106. readingsSingleUpdate($hash, $abfallArt ."_pickups_used", $waste_pickup_used, "1");
  107. }
  108. return $result;
  109. }
  110. sub ABFALL_Attr(@) {
  111. my ($cmd,$name,$attrName,$attrVal) = @_;
  112. my $hash = $defs{$name};
  113. if ($cmd eq "set") {
  114. if ($attrName eq "weekday_mapping") {
  115. my @weekdayMappingSplitted = split( "\ ", $attrVal );
  116. if (int(@weekdayMappingSplitted) != 7) {
  117. Log3 $name, 4, "ABFALL_Attr ($name) - $attrVal is a wrong weekday_mapping format";
  118. return ("ABFALL_Attr: $attrVal is a wrong mapping format. Format is a array like this So Mo Di Mi Do Fr Sa");
  119. }
  120. } elsif ($attrName eq "abfall_clear_reading_regex") {
  121. eval { qr/$attrVal/ };
  122. if ($@) {
  123. Log3 $name, 4, "ABFALL_Attr ($name) - $attrVal invalid regex: $@";
  124. return "ABFALL_Attr ($name) - $attrVal invalid regex";
  125. }
  126. }
  127. }
  128. return undef;
  129. }
  130. sub ABFALL_Notify($$)
  131. {
  132. my ($own_hash, $dev_hash) = @_;
  133. my $ownName = $own_hash->{NAME}; # own name / hash
  134. return "" if(IsDisabled($ownName)); # Return without any further action if the module is disabled
  135. my $devName = $dev_hash->{NAME}; # Device that created the events
  136. Log3 $ownName, 5, "ABFALL_Notify($ownName) - Device: " . $devName;
  137. my @calendernamen = split( ",", $own_hash->{KALENDER});
  138. foreach my $calendar (@calendernamen){
  139. if ($devName eq $calendar) {
  140. foreach my $event (@{$dev_hash->{CHANGED}}) {
  141. if ($event eq "triggered") {
  142. Log3 $ownName , 3, "ABFALL $ownName - CALENDAR:$devName triggered, updating ABFALL $ownName ...";
  143. ABFALL_setUpdate($own_hash);
  144. }
  145. }
  146. }
  147. }
  148. return undef;
  149. }
  150. 1;
  151. =pod
  152. =begin html
  153. <a name="ABFALL"></a>
  154. <h3>ABFALL</h3>
  155. <ul>
  156. <br>
  157. <a name="ABFALLdefine"></a>
  158. <b>Define</b>
  159. <ul>
  160. <code>define &lt;name&gt; ABFALL &lt;calendarname&gt;</code><br>
  161. <code>define &lt;name&gt; ABFALL &lt;calendarname&gt;,&lt;additional calendarname&gt;</code><br>
  162. <br>
  163. Defines a ABFALL device.<br>
  164. A ABFALL device creates events with deadlines based on one or more calendar-device (57_Calendar.pm). <br>
  165. You need to install the perl-modul Date::Parse!<br>
  166. </ul>
  167. <br>
  168. <a name="ABFALLset"></a>
  169. <b>Set</b>
  170. <ul>
  171. <code>set &lt;name&gt; update</code><br>
  172. Forces to read all events from the calendar-devices and create / update readings.<br>
  173. </ul>
  174. <br>
  175. <a name="ABFALLattr"></a>
  176. <b>Attributes</b>
  177. <ul>
  178. <li><code>abfall_clear_reading_regex</code><br>
  179. regex to remove part of the summary text</li><p>
  180. <li><code>weekday_mapping</code><br>
  181. mapping for the days of week
  182. </li><p>
  183. <li><code>calendarname_praefix </code><br>
  184. add calendar name as praefix for reading</li><p>
  185. <li><code>delimiter_text_reading</code><br>
  186. delimiter for join events on same day for readings now_text and next_text</li><p>
  187. <li><code>delimiter_reading </code><br>
  188. delimiter for join reading name on readings now and next</li><p>
  189. <li><code>filter</code><br>
  190. filter to skip or keep events, possible values regex or string with event name parts</li><p>
  191. <li><code>filter_type</code><br>
  192. skip events or keep events with filter, default value is include this mean keep</li><p>
  193. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  194. </ul>
  195. <br>
  196. <b>Examples</b>
  197. <ul>
  198. see <a href="https://wiki.fhem.de/wiki/ABFALL">FHEM Wiki</a>
  199. <br>
  200. </ul>
  201. </ul>
  202. =end html
  203. =begin html_DE
  204. <a name="ABFALL"></a>
  205. <h3>ABFALL</h3>
  206. <ul>
  207. <br>
  208. <a name="ABFALLdefine"></a>
  209. <b>Define</b>
  210. <ul>
  211. <code>define &lt;name&gt; ABFALL &lt;Kalendername&gt;</code><br>
  212. <code>define &lt;name&gt; ABFALL &lt;Kalendername&gt;,&lt;weiterer Kalendername&gt;</code><br>
  213. <br>
  214. Definiert ein Abfall-Device.<br><br>
  215. Ein Abfall-Device ermittelt, basierend auf einem oder mehreren Kalender-Devices, Termine und stellt verschiedene 'Readings' hierfür bereit.<br>
  216. Das Perl Modul Date::Parse muss installiert sein!<br>
  217. </ul>
  218. <br>
  219. <a name="ABFALLset"></a>
  220. <b>Set</b>
  221. <ul>
  222. <code>set &lt;name&gt; update</code><br>
  223. Erzwingt das Auslesen der Kalender-Devices und neuerstellen der Readings.<br><br>
  224. <code>set &lt;name&gt; count &lt;abfallArt&gt;</code><br>
  225. Steht nur zur Verfügung wenn das Attribut <code>enable_counting_pickups</code> auf 1 steht.<br>
  226. Erhöht das Reading <code>&lt;abfallArt&gt;_pickups_used</code> um 1, sofern die <code>AbfallArt</code> als Reading existiert.<br><br>
  227. <code>set &lt;name&gt; clear</code><br>
  228. Steht nur zur Verfügung wenn das Attribut <code>enable_counting_pickups</code> auf 1 steht.<br>
  229. Löscht alle Readings <code>*_pickups_used</code> und <code>*_pickups</code>
  230. </ul>
  231. <br>
  232. <a name="ABFALLattr"></a>
  233. <b>Attribute</b>
  234. <ul>
  235. <li><code>abfall_clear_reading_regex</code><br>
  236. regulärer Ausdruck zum Entfernt eines Bestandteils des Terminnamens</li><p>
  237. <li><code>weekday_mapping</code><br>
  238. Mapping der Wochentag</li><p>
  239. <li><code>calendarname_praefix</code><br>
  240. soll der <code>calendarname</code> als Präfix im reading geführt werden</li><p>
  241. <li><code>delimiter_text_reading</code><br>
  242. Trennzeichen(kette) zum Verbinden von Terminen, wenn sie auf den gleichen Tag fallen
  243. gilt nur für die Readings next_text und now_text</li><p>
  244. <li><code>delimiter_reading</code><br>
  245. Trennzeichen(kette) zum Verbinden von Terminen, wenn sie auf den gleichen Tag fallen
  246. gilt nur für die readings next und now</li><p>
  247. <li><code>filter</code><br>
  248. Zeichenkette zum Ausfiltern der Events aus den Kalendern, es sind auch regex möglich</li><p>
  249. <li><code>filter_type</code><br>
  250. Sollen durch den angegebene Filter Termine entfernt werden, oder erhalten bleiben</li><p>
  251. <li><code>date_style</code><br>
  252. Soll das Datum mit Uhrzeit oder ohne Uhrzeit angezeigt werden</li><p>
  253. <li><code>enable_old_readingnames</code><br>
  254. Stellt die Readings *_wochtag, *_datum und *_tage zur Verfügung, allerdings
  255. ist dieses Attribut deprecated, wird also in einer der folgenden Version entfernt, so dass dann diese Readings nur noch
  256. mit ihren englischen Varianten zur Verfügung stehen.
  257. </li><p>
  258. <li><code>enable_counting_pickups</code><br>
  259. Hiermit werden die Abholungen gezählt und es kann mit Milfe von <code>set &lt;name&gt; count &lt;abfallArt&gt;</code> die genutzte Abholung
  260. gezählt werden. Mit Hilfe von <code>set &lt;name&gt; clear</code> können die Abholungen wieder auf 0 gesetzt werden. Das ist sinnvoll bei Wechsel
  261. eines Abrechnungszeitraum.
  262. </li><p>
  263. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  264. </ul>
  265. <br>
  266. <b>Anwendungsbeispiele</b>
  267. <ul>
  268. siehe h<a href="https://wiki.fhem.de/wiki/ABFALL">FHEM Wiki</a>
  269. <br>
  270. </ul>
  271. </ul>
  272. =end html_DE
  273. =cut