31_TradfriGroup.pm 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. # @author Peter Kappelt
  2. # @author Clemens Bergmann
  3. # @author Sebastian Kessler
  4. # @version 1.18
  5. package main;
  6. use strict;
  7. use warnings;
  8. use Data::Dumper;
  9. use JSON;
  10. use TradfriUtils;
  11. sub TradfriGroup_Initialize($) {
  12. my ($hash) = @_;
  13. $hash->{DefFn} = 'Tradfri_Define';
  14. $hash->{UndefFn} = 'Tradfri_Undef';
  15. $hash->{SetFn} = 'Tradfri_Set';
  16. $hash->{GetFn} = 'Tradfri_Get';
  17. $hash->{AttrFn} = 'Tradfri_Attr';
  18. $hash->{ReadFn} = 'Tradfri_Read';
  19. $hash->{ParseFn} = 'TradfriGroup_Parse';
  20. $hash->{Match} = '(^subscribedGroupUpdate::)|(^moodList::)';
  21. $hash->{AttrList} =
  22. "usePercentDimming:1,0 "
  23. . $readingFnAttributes;
  24. }
  25. #messages look like this: (without newlines)
  26. # subscribedGroupUpdate::group-id::{
  27. # "createdAt":1494088484,
  28. # "mood":198884,
  29. # "groupid":173540,
  30. # "members":[
  31. # {
  32. # "name":"Fenster Links",
  33. # "deviceid":65537
  34. # },
  35. # {
  36. # "deviceid":65536
  37. # },
  38. # {
  39. # "name":"Fenster Rechts",
  40. # "deviceid":65538
  41. # }
  42. # ],
  43. # "name":"Wohnzimmer",
  44. # "dimvalue":200,
  45. # "onoff":0
  46. # }
  47. sub TradfriGroup_Parse($$){
  48. my ($io_hash, $message) = @_;
  49. my @parts = split('::', $message);
  50. if(int(@parts) < 3){
  51. #expecting at least three parts
  52. return undef;
  53. }
  54. my $messageID = $parts[1];
  55. #check if group with the id exists
  56. if(my $hash = $modules{'TradfriGroup'}{defptr}{$messageID})
  57. {
  58. #parse the JSON data
  59. my $jsonData = eval{ JSON->new->utf8->decode($parts[2]) };
  60. if($@){
  61. return undef; #the string was probably not valid JSON
  62. }
  63. if('subscribedGroupUpdate' eq $parts[0]){
  64. my $createdAt = FmtDateTimeRFC1123($jsonData->{'createdAt'} || '');
  65. my $name = $jsonData->{'name'} || '';
  66. my $members = JSON->new->pretty->encode($jsonData->{'members'});
  67. #dimvalue is in range 0 - 254
  68. my $dimvalue = $jsonData->{'dimvalue'} || '0';
  69. #dimpercent is always in range 0 - 100
  70. my $dimpercent = int($dimvalue / 2.54 + 0.5);
  71. $dimpercent = 1 if($dimvalue == 1);
  72. $dimvalue = $dimpercent if (AttrVal($hash->{name}, 'usePercentDimming', 0) == 1);
  73. my $state = 'off';
  74. if($jsonData->{'onoff'} eq '0'){
  75. $dimpercent = 0;
  76. }else{
  77. $state = Tradfri_stateString($dimpercent);
  78. }
  79. my $onoff = ($jsonData->{'onoff'} || '0') ? 'on':'off';
  80. readingsBeginUpdate($hash);
  81. readingsBulkUpdateIfChanged($hash, 'createdAt', $createdAt, 1);
  82. readingsBulkUpdateIfChanged($hash, 'name', $name, 1);
  83. readingsBulkUpdateIfChanged($hash, 'members', $members, 1);
  84. readingsBulkUpdateIfChanged($hash, 'dimvalue', $dimvalue, 1);
  85. readingsBulkUpdateIfChanged($hash, 'pct', $dimpercent, 1);
  86. readingsBulkUpdateIfChanged($hash, 'onoff', $onoff, 1) ;
  87. readingsBulkUpdateIfChanged($hash, 'state', $state, 1);
  88. readingsEndUpdate($hash, 1);
  89. }elsif('moodList' eq $parts[0]){
  90. #update of mood list
  91. readingsSingleUpdate($hash, 'moods', JSON->new->pretty->encode($jsonData), 1);
  92. $hash->{helper}{moods} = undef;
  93. foreach (@{$jsonData}){
  94. $hash->{helper}{moods}->{$_->{name}} = $_;
  95. }
  96. }
  97. #$attr{$hash->{NAME}}{webCmd} = 'pct:toggle:on:off';
  98. #$attr{$hash->{NAME}}{devStateIcon} = '{(Tradfri_devStateIcon($name),"toggle")}' if( !defined( $attr{$hash->{name}}{devStateIcon} ) );
  99. #return the appropriate group's name
  100. return $hash->{NAME};
  101. }
  102. return undef;
  103. }
  104. 1;
  105. =pod
  106. =item device
  107. =item summary controls an IKEA Trådfri lighting group
  108. =item summary_DE steuert eine IKEA Trådfri Beleuchtungsgruppe
  109. =begin html
  110. <a name="TradfriGroup"></a>
  111. <h3>TradfriGroup</h3>
  112. <ul>
  113. <i>TradfriGroup</i> is a module for controlling an IKEA Trådfri lighting group. You currently need a gateway for the connection.
  114. See TradfriGateway.
  115. <br><br>
  116. <a name="TradfriGroupdefine"></a>
  117. <b>Define</b>
  118. <ul>
  119. <code>define &lt;name&gt; TradfriGroup &lt;group-address&gt;</code>
  120. <br><br>
  121. Example: <code>define trGroupOne TradfriGroup 193768</code>
  122. <br><br>
  123. You can get the ID of the lighting groups by calling "get TradfriGW groupList" on the gateway device
  124. </ul>
  125. <br>
  126. <a name="TradfriGroupset"></a>
  127. <b>Set</b><br>
  128. <ul>
  129. <code>set &lt;name&gt; &lt;option&gt; [&lt;value&gt;]</code>
  130. <br><br>
  131. You can set the following options. See <a href="http://fhem.de/commandref.html#set">commandref#set</a>
  132. for more info about the set command.
  133. <br><br>
  134. Options:
  135. <ul>
  136. <li><i>on</i><br>
  137. Turns all devices in the group on.<br>The brightness is the one, before the devices were turned off</li>
  138. <li><i>off</i><br>
  139. Turn all devices in the group off.</li>
  140. <li><i>dimvalue</i><br>
  141. Set the brightness of all devices in the group.<br>
  142. You need to specify the brightness value as an integer between 0 and 100/254.<br>
  143. The largest value depends on the attribute "usePercentDimming".<br>
  144. If this attribute is set, the largest value will be 100.<br>
  145. By default, it isn't set, so the largest value is 254.<br>
  146. A brightness value of 0 turns the devices off.<br>
  147. If the devices are off, and you set a value greater than 0, they'll turn on.</li>
  148. <li><i>mood</i><br>
  149. Set the mood of the group.<br>
  150. Moods are preconfigured color temperatures, brightnesses and states for each device of the group<br>
  151. In order to set the mood, you need a mood ID or the mood's name.<br>
  152. You can list the moods that are available for this group by running "get moods".<br>
  153. Note, that the mood's name isn't necessarily the same that you've defined in the IKEA app.
  154. This module is currently unable to handle whitespaces in mood names, so whitespaces get removed internally.
  155. Check the reading "moods" after running "get moods" in order to get the names, that you may use with this module.<br>
  156. Mood names are case-sensitive. Mood names, that are only made out of numbers are not supported.</li>
  157. </ul>
  158. </ul>
  159. <br>
  160. <a name="TradfriGroupget"></a>
  161. <b>Get</b><br>
  162. <ul>
  163. <code>get &lt;name&gt; &lt;option&gt;</code>
  164. <br><br>
  165. You can get the following information about the group. See
  166. <a href="http://fhem.de/commandref.html#get">commandref#get</a> for more info about
  167. the get command.
  168. <br><br>
  169. Options:
  170. <ul>
  171. <li><i>moods</i><br>
  172. Get all moods (their name and their ID) that are configured for this group<br>
  173. The JSON-formatted result is stored in the Reading "moods"</br>
  174. Please note, that the mood IDs may differ between different groups (though they are the same moods) -> check them for each group</li>
  175. </ul>
  176. </ul>
  177. <br>
  178. <a name="TradfriGroupreadings"></a>
  179. <b>Readings</b><br>
  180. <ul>
  181. The following readings are displayed for a group. Once there is a change and the connection to the gateway is made, they get updated automatically.
  182. <br><br>
  183. Readings:
  184. <ul>
  185. <li><i>createdAt</i><br>
  186. A timestamp string, like "Sat, 15 Apr 2017 18:29:24 GMT", that indicates, when the group was created in the gateway.</li>
  187. <li><i>dimvalue</i><br>
  188. The brightness that is set for this group. It is a integer in the range of 0 to 100/ 254.<br>
  189. The greatest dimvalue depends on the attribute "usePercentDimming", see below.</li>
  190. <li><i>pct</i><br>
  191. The brightness that is set for this device in percent.</li>
  192. <li><i>members</i><br>
  193. JSON-String that contains all member-IDs and their names.</li>
  194. <li><i>moods</i><br>
  195. JSON info of all moods and their names, e.g.:<br>
  196. [ { "groupid" : 173540, "moodid" : 198884, "name" : "EVERYDAY" }, { "moodid" : 213983, "name" : "RELAX", "groupid" : 173540 }, { "groupid" : 173540, "name" : "FOCUS", "moodid" : 206399 } ]<br>
  197. This reading isn't updated automatically, you've to call "get moods" in order to refresh them.</li>
  198. <li><i>name</i><br>
  199. The name of the group that you've set in the app.</li>
  200. <li><i>onoff</i><br>
  201. Indicates whether the device is on or off, can be the strings 'on' or 'off'</li>
  202. <li><i>state</i><br>
  203. Indicates, whether the group is on or off. Thus, the reading's value is either "on" or "off", too.</li>
  204. </ul>
  205. </ul>
  206. <br>
  207. <a name="TradfriGroupattr"></a>
  208. <b>Attributes</b>
  209. <ul>
  210. <code>attr &lt;name&gt; &lt;attribute&gt; &lt;value&gt;</code>
  211. <br><br>
  212. See <a href="http://fhem.de/commandref.html#attr">commandref#attr</a> for more info about
  213. the attr command.
  214. <br><br>
  215. Attributes:
  216. <ul>
  217. <li><i>usePercentDimming</i> 0/1<br>
  218. If this attribute is one, the largest value for "set dimvalue" will be 100.<br>
  219. Otherwise, the largest value is 254.<br>
  220. This attribute is useful, if you need to control the brightness in percent (0-100%)<br>
  221. For backward compatibility, it is disabled by default, so the largest dimvalue is 254 by default.
  222. </li>
  223. </ul>
  224. </ul>
  225. </ul>
  226. =end html
  227. =cut