31_TradfriDevice.pm 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # @author Peter Kappelt
  2. # @author Clemens Bergmann
  3. # @version 1.16.dev-cf.9
  4. package main;
  5. use strict;
  6. use warnings;
  7. use Data::Dumper;
  8. use JSON;
  9. use TradfriUtils;
  10. sub TradfriDevice_Initialize($) {
  11. my ($hash) = @_;
  12. $hash->{DefFn} = 'Tradfri_Define';
  13. $hash->{UndefFn} = 'Tradfri_Undef';
  14. $hash->{SetFn} = 'Tradfri_Set';
  15. $hash->{GetFn} = 'Tradfri_Get';
  16. $hash->{AttrFn} = 'Tradfri_Attr';
  17. $hash->{ReadFn} = 'Tradfri_Read';
  18. $hash->{ParseFn} = 'TradfriDevice_Parse';
  19. $hash->{Match} = '^subscribedDeviceUpdate::';
  20. $hash->{AttrList} =
  21. "usePercentDimming:1,0 "
  22. . $readingFnAttributes;
  23. }
  24. #messages look like this: (without newlines)
  25. # subscribedDeviceUpdate::device-id::{
  26. # "lastSeenAt":1501407261,
  27. # "createdAt":1492280964,
  28. # "reachabilityState":1,
  29. # "name":"Fenster Links",
  30. # "dimvalue":200,
  31. # "type":"TRADFRI bulb E27 opal 1000lm",
  32. # "deviceid":65537,
  33. # "version":"1.1.1.0-5.7.2.0",
  34. # "manufacturer":"IKEA of Sweden",
  35. # "onoff":0
  36. # }
  37. sub TradfriDevice_Parse ($$){
  38. my ($io_hash, $message) = @_;
  39. my @parts = split('::', $message);
  40. if(int(@parts) < 3){
  41. #expecting at least three parts
  42. return undef;
  43. }
  44. my $messageID = $parts[1];
  45. #check if device with the id exists
  46. if(my $hash = $modules{'TradfriDevice'}{defptr}{$messageID})
  47. {
  48. # the path returned "Not Found" -> unknown resource, but this message still suits for this device
  49. if($parts[2] eq "Not Found"){
  50. $hash->{STATE} = "NotFound";
  51. return $hash->{NAME};
  52. }
  53. #parse the JSON data
  54. my $jsonData = eval{ JSON->new->utf8->decode($parts[2]) };
  55. if($@){
  56. return undef; #the string was probably not valid JSON
  57. }
  58. my $manufacturer = $jsonData->{'manufacturer'} || '';
  59. my $type = $jsonData->{'type'} || '';
  60. #dimvalue is in range 0 - 254
  61. my $dimvalue = $jsonData->{'dimvalue'} || '0';
  62. #dimpercent is always in range 0 - 100
  63. my $dimpercent = int($dimvalue / 2.54 + 0.5);
  64. $dimpercent = 1 if($dimvalue == 1);
  65. $dimvalue = $dimpercent if (AttrVal($hash->{NAME}, 'usePercentDimming', 0) == 1);
  66. my $state = 'off';
  67. if($jsonData->{'onoff'} eq '0'){
  68. $dimpercent = 0;
  69. }else{
  70. $state = Tradfri_stateString($dimpercent);
  71. }
  72. my $onoff = ($jsonData->{'onoff'} || '0') ? 'on':'off';
  73. my $name = $jsonData->{'name'} || '';
  74. my $createdAt = FmtDateTimeRFC1123($jsonData->{'createdAt'} || '');
  75. my $reachableState = $jsonData->{'reachabilityState'} || '';
  76. my $lastSeen = FmtDateTimeRFC1123($jsonData->{'lastSeenAt'} || '');
  77. my $color = $jsonData->{'color'} || '';
  78. my $version = $jsonData->{'version'} || '';
  79. readingsBeginUpdate($hash);
  80. readingsBulkUpdateIfChanged($hash, 'dimvalue', $dimvalue, 1);
  81. readingsBulkUpdateIfChanged($hash, 'pct', $dimpercent, 1);
  82. readingsBulkUpdateIfChanged($hash, 'state', $state, 1);
  83. readingsBulkUpdateIfChanged($hash, 'name', $name, 1);
  84. readingsBulkUpdateIfChanged($hash, 'createdAt', $createdAt, 1);
  85. readingsBulkUpdateIfChanged($hash, 'softwareVersion', $version, 1);
  86. readingsBulkUpdateIfChanged($hash, 'type', $type, 1);
  87. readingsBulkUpdateIfChanged($hash, 'manufacturer', $manufacturer, 1);
  88. readingsBulkUpdateIfChanged($hash, 'reachableState', $reachableState, 1);
  89. readingsBulkUpdateIfChanged($hash, 'color', $color, 1);
  90. readingsBulkUpdateIfChanged($hash, 'lastSeen', $lastSeen, 1);
  91. readingsBulkUpdateIfChanged($hash, 'onoff', $onoff, 1);
  92. readingsEndUpdate($hash, 1);
  93. #$attr{$hash->{NAME}}{webCmd} = 'pct:toggle:on:off';
  94. #$attr{$hash->{NAME}}{devStateIcon} = '{(Tradfri_devStateIcon($name),"toggle")}' if( !defined( $attr{$hash->{NAME}}{devStateIcon} ) );
  95. #return the appropriate device's name
  96. return $hash->{NAME};
  97. }
  98. return undef;
  99. }
  100. 1;
  101. =pod
  102. =item device
  103. =item summary controls an IKEA Trådfri device (bulb, panel)
  104. =item summary_DE steuert ein IKEA Trådfri Gerät
  105. =begin html
  106. <a name="TradfriDevice"></a>
  107. <h3>TradfriDevice</h3>
  108. <ul>
  109. <i>TradfriDevice</i> is a module for controlling a single IKEA Trådfri device. You currently need a gateway for the connection.
  110. See TradfriGateway.
  111. <br><br>
  112. <a name="TradfriDevicedefine"></a>
  113. <b>Define</b>
  114. <ul>
  115. <code>define &lt;name&gt; TradfriDevice &lt;device-address&gt;</code>
  116. <br><br>
  117. Example: <code>define trDeviceOne TradfriDevice 65538</code>
  118. <br><br>
  119. You can get the ID of the devices by calling "get TradfriGW deviceList" on the gateway device
  120. </ul>
  121. <br>
  122. <a name="TradfriDeviceset"></a>
  123. <b>Set</b><br>
  124. <ul>
  125. <code>set &lt;name&gt; &lt;option&gt; [&lt;value&gt;]</code>
  126. <br><br>
  127. You can set the following options. See <a href="http://fhem.de/commandref.html#set">commandref#set</a>
  128. for more info about the set command.
  129. <br><br>
  130. Options:
  131. <ul>
  132. <li><i>on</i><br>
  133. Turns the device on.<br>The brightness is the one, before the device was turned off</li>
  134. <li><i>off</i><br>
  135. Turn the device off.</li>
  136. <li><i>dimvalue</i><br>
  137. Set the brightness of the device.<br>
  138. You need to specify the brightness value as an integer between 0 and 100/254.<br>
  139. The largest value depends on the attribute "usePercentDimming".<br>
  140. If this attribute is set, the largest value will be 100.<br>
  141. By default, it isn't set, so the largest value is 254.<br>
  142. A brightness value of 0 turns the device off.<br>
  143. If the device is off, and you set a value greater than 0, it will turn on.</li>
  144. <li><i>color</i>
  145. Set the color temperature of a bubl<br>
  146. Of course, that only works with bulbs, that can change their color temperature<br>
  147. You may pass "warm", "cold", "standard" or a RGB code in the format "RRGGBB"<br>
  148. Any RGB code can be set, though the bulb only is able to switch to certain colors.<br>
  149. IKEA uses the following RGB codes for their colors. Bulbs I've tested could only be set to those.<br>
  150. <ul>
  151. <li>F1E0B5 for standard</li>
  152. <li>F5FAF6 for cold</li>
  153. <li>EFD275 for warm</li>
  154. </ul>
  155. Other RGB codes than listed here do not work with the current bulb (they only set their color to those three values).
  156. </li>
  157. </ul>
  158. </ul>
  159. <br>
  160. <a name="TradfriDeviceget"></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 device. 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></i><br>
  172. There are no gets implemented</li>
  173. </ul>
  174. </ul>
  175. <br>
  176. <a name="TradfriDevicereadings"></a>
  177. <b>Readings</b><br>
  178. <ul>
  179. The following readings are displayed for a device. Once there is a change and the connection to the gateway is made, they get updated automatically.
  180. <br><br>
  181. Readings:
  182. <ul>
  183. <li><i>color</i><br>
  184. The color that is set for this bulb. Its value is a hexadecimal code in the format "RRGGBB".<br>
  185. If the device doesn't support the change of colors the reading's value will be "0"</li>
  186. <li><i>createdAt</i><br>
  187. A timestamp string, like "Sat, 15 Apr 2017 18:29:24 GMT", that indicates, when the device was paired with the gateway.</li>
  188. <li><i>dimvalue</i><br>
  189. The brightness that is set for this device. It is a integer in the range of 0 to 100/ 254.<br>
  190. The greatest dimvalue depends on the attribute "usePercentDimming", see below.</li>
  191. <li><i>pct</i><br>
  192. The brightness that is set for this device in percent.</li>
  193. <li><i>lastSeen</i><br>
  194. A timestamp string, like "Wed, 12 Jul 2017 14:32:06 GMT". I haven't understand the mechanism behind it yet.<br>
  195. Communication with the device won't update the lastSeen-timestamp - so I don't get the point of it. This needs some more investigation.</li>
  196. <li><i>manufacturer</i><br>
  197. The device's manufacturer. Since there are only devices from IKEA available yet, it'll surely be "IKEA of Sweden".</li>
  198. <li><i>name</i><br>
  199. The name of the device 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>reachableState</i><br>
  203. Indicates whether the gateway is able to connect to the device. This reading's value is either "0" or "1", where "1" indicates reachability.</li>
  204. <li><i>softwareVersion</i><br>
  205. The version of the software that is running on the device.</li>
  206. <li><i>state</i><br>
  207. Indicates, whether the device is on or off. Thus, the reading's value is either "on" or "off", too.</li>
  208. <li><i>type</i><br>
  209. The product type of the device. Is a string like "TRADFRI bulb E27 opal 1000lm"</li>
  210. </ul>
  211. </ul>
  212. <br>
  213. <a name="TradfriDeviceattr"></a>
  214. <b>Attributes</b>
  215. <ul>
  216. <code>attr &lt;name&gt; &lt;attribute&gt; &lt;value&gt;</code>
  217. <br><br>
  218. See <a href="http://fhem.de/commandref.html#attr">commandref#attr</a> for more info about
  219. the attr command.
  220. <br><br>
  221. Attributes:
  222. <ul>
  223. <li><i>usePercentDimming</i> 0/1<br>
  224. If this attribute is one, the largest value for "set dimvalue" will be 100.<br>
  225. Otherwise, the largest value is 254.<br>
  226. This attribute is useful, if you need to control the brightness in percent (0-100%)<br>
  227. For backward compatibility, it is disabled by default, so the largest dimvalue is 254 by default.
  228. </li>
  229. </ul>
  230. </ul>
  231. </ul>
  232. =end html
  233. =cut