TradfriUtils.pm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. # @author Clemens Bergmann
  2. # @author Peter Kappelt (small changes)
  3. # @version 1.16.dev-cf.9
  4. package main;
  5. use strict;
  6. use warnings;
  7. use SetExtensions;
  8. my %dim_values = (
  9. 0 => "dim06%",
  10. 1 => "dim12%",
  11. 2 => "dim18%",
  12. 3 => "dim25%",
  13. 4 => "dim31%",
  14. 5 => "dim37%",
  15. 6 => "dim43%",
  16. 7 => "dim50%",
  17. 8 => "dim56%",
  18. 9 => "dim62%",
  19. 10 => "dim68%",
  20. 11 => "dim75%",
  21. 12 => "dim81%",
  22. 13 => "dim87%",
  23. 14 => "dim93%",
  24. );
  25. sub Tradfri_devStateIcon($){
  26. my ($name) = @_;
  27. my $pct = ReadingsVal($name,"pct","100");
  28. my $s = $dim_values{int($pct/7)};
  29. $s="on" if( $pct eq "100" );
  30. $s="off" if( $pct eq "0" );
  31. return ".*:$s:toggle";
  32. }
  33. #get the on state of the group depending on the dimm value
  34. sub Tradfri_stateString($){
  35. my ($value) = @_;
  36. if($value <= 0){
  37. return 'off';
  38. }elsif($value >= 99){
  39. return 'on';
  40. }else{
  41. return "dim$value%";
  42. }
  43. }
  44. sub Tradfri_setBrightness($$){
  45. my ($hash, $dimpercent) = @_;
  46. #readingsSingleUpdate($hash, "pct", $dimpercent, 1);
  47. $hash->{STATE} = Tradfri_stateString($dimpercent);
  48. my $address = $hash->{address};
  49. #type, can be device or group
  50. my $type;
  51. if($hash->{TYPE} eq 'TradfriGroup'){
  52. $type = 1;
  53. }elsif($hash->{TYPE} eq 'TradfriDevice'){
  54. $type = 0;
  55. }else{
  56. Log(0, "[Tradfri] Trying to call Tradfri-Functions with a non-Tradfri device (with $hash->{TYPE}");
  57. }
  58. if( $dimpercent == 0 ){
  59. return IOWrite($hash, $type, 'set', $address, "onoff::0");
  60. }else{
  61. my $dimvalue = int($dimpercent * 2.54 + 0.5);
  62. #readingsSingleUpdate($hash, "dimvalue", $dimvalue, 1);
  63. return IOWrite($hash, $type, 'set', $address, "dimvalue::${dimvalue}");
  64. }
  65. }
  66. sub Tradfri_Set($@) {
  67. my ($hash, $name, $opt, @param) = @_;
  68. return "\"set $hash->{TYPE}\" needs at least one argument" unless(defined($opt));
  69. my $value = join("", @param);
  70. #parameters that can be set
  71. my $cmdList = "on off pct:colorpicker,BRI,0,1,100";
  72. #dynamic option: dimvalue depends on attribute usePercentDimming
  73. my $dimvalueMax = 254;
  74. $dimvalueMax = 100 if (AttrVal($hash->{name}, 'usePercentDimming', 0) == 1);
  75. $cmdList .= " dimvalue:slider,0,1,$dimvalueMax";
  76. #parameters that are only applicable to devices
  77. if($hash->{TYPE} eq 'TradfriDevice'){
  78. $cmdList .= " color:warm,cold,standard" ;
  79. }
  80. #parameters that are only applicable to groups
  81. if($hash->{TYPE} eq 'TradfriGroup'){
  82. #dynamic option: moods
  83. my $moodsList = join(",", map { "$_" } keys %{$hash->{helper}{moods}});
  84. $cmdList .= " mood:$moodsList"
  85. }
  86. if ($opt eq "toggle") {
  87. $opt = (ReadingsVal($hash->{name}, 'onoff', 0) eq 'off') ? "on" : "off";
  88. }elsif($opt eq "on"){
  89. my $dimpercent = ReadingsVal($hash->{name}, 'dimvalue', 254);
  90. $dimpercent = int($dimpercent / 2.54 + 0.5) if(AttrVal($hash->{name}, 'usePercentDimming', 0) == 0);
  91. #@todo ist das Setzen der Helligkeit hier angebracht, welche Auswirkungen hat das? Fehlerfälle betrachten!, evtl. nur einschalten?
  92. Tradfri_setBrightness($hash,$dimpercent);
  93. }elsif($opt eq "off"){
  94. Tradfri_setBrightness($hash,0);
  95. }elsif($opt eq "dimvalue"){
  96. return '"set TradfriDevice dimvalue" requires a brightness-value between 0 and 254!' if ! @param;
  97. my $dimpercent = int($value);
  98. $dimpercent = int($value / 2.54 + 0.5) if(AttrVal($hash->{name}, 'usePercentDimming', 0) == 0);
  99. Tradfri_setBrightness($hash,$dimpercent);
  100. }elsif($opt eq "pct"){
  101. return '"set TradfriDevice dimvalue" requires a brightness-value between 0 and 100!' if ! @param;
  102. Tradfri_setBrightness($hash,int($value));
  103. }elsif(($hash->{TYPE} eq 'TradfriGroup') and ($opt eq "mood")){
  104. return '"set TradfriGroup mood" requires a mood ID or a mood name. You can list the available moods for this group by running "get moods"' if ! @param;
  105. if(!($value =~ /^[0-9]+$/)){
  106. #user wrote a string -> a mood name
  107. if(exists($hash->{helper}{moods}->{"$value"})){
  108. $value = $hash->{helper}{moods}->{"$value"}->{moodid};
  109. }else{
  110. return "Unknown mood!";
  111. }
  112. }
  113. return IOWrite($hash, 1, 'set', $hash->{address}, "mood::${value}");
  114. }elsif(($hash->{TYPE} eq 'TradfriDevice') and ($opt eq "color")){
  115. return '"set TradfriDevice color" requires RGB value in format "RRGGBB" or "warm", "cold", "standard"!' if ! @param;
  116. my $rgb;
  117. if($value eq "warm"){
  118. $rgb = 'EFD275';
  119. }elsif($value eq "cold"){
  120. $rgb = 'F5FAF6';
  121. }elsif($value eq "standard"){
  122. $rgb = 'F1E0B5';
  123. }else{
  124. $rgb = $value;
  125. }
  126. return IOWrite($hash, 0, 'set', $hash->{address}, "color::${rgb}");
  127. }else{
  128. return SetExtensions($hash, $cmdList, $name, $opt, @param);
  129. }
  130. return undef;
  131. }
  132. sub Tradfri_Undef($$) {
  133. my ($hash, $arg) = @_;
  134. # nothing to do
  135. return undef;
  136. }
  137. sub Tradfri_Attr(@) {
  138. my ($cmd,$name,$attr_name,$attr_value) = @_;
  139. if($cmd eq "set") {
  140. if($attr_name eq ""){
  141. }
  142. }
  143. return undef;
  144. }
  145. sub Tradfri_Define($$) {
  146. my ($hash, $def) = @_;
  147. my @param = split('[ \t]+', $def);
  148. if(int(@param) < 3) {
  149. return "too few parameters: define <name> $hash->{TYPE} <Address>";
  150. }
  151. $hash->{name} = $param[0];
  152. $hash->{address} = $param[2];
  153. #$attr{$hash->{name}}{webCmd} = 'pct:toggle:on:off';
  154. #$attr{$hash->{name}}{devStateIcon} = '{(Tradfri_devStateIcon($name),"toggle")}' if( !defined( $attr{$hash->{name}}{devStateIcon} ) );
  155. AssignIoPort($hash);
  156. #start observing the coap resource, so the module will be informed about status updates
  157. #@todo stop observing, when deleting module, or stopping FHEM
  158. #reverse search, for Parse
  159. $modules{$hash->{TYPE}}{defptr}{$hash->{address}} = $hash;
  160. if($hash->{TYPE} eq 'TradfriDevice'){
  161. IOWrite($hash, 0, 'subscribe', $hash->{address});
  162. }elsif($hash->{TYPE} eq 'TradfriGroup'){
  163. IOWrite($hash, 1, 'subscribe', $hash->{address});
  164. #update the moodlist
  165. IOWrite($hash, 1, 'moodlist', $hash->{address});
  166. }
  167. return undef;
  168. }
  169. sub Tradfri_Get($@) {
  170. my ($hash, @param) = @_;
  171. return "\"get $hash->{TYPE}\" needs at least one argument" if (int(@param) < 2);
  172. my $name = shift @param;
  173. my $opt = shift @param;
  174. my $cmdList = "";
  175. #Only applicable for groups: moods list
  176. $cmdList .= " moods" if($hash->{TYPE} eq 'TradfriGroup');
  177. #$cmdList .= " groupInfo" if($hash->{TYPE} eq 'TradfriGroup');
  178. #$cmdList .= " deviceInfo" if($hash->{TYPE} eq 'TradfriDevice');
  179. if($hash->{TYPE} eq 'TradfriGroup' and $opt eq 'moods'){
  180. IOWrite($hash, 1, 'moodlist', $hash->{address});
  181. return undef
  182. #return '';
  183. # }elsif($hash->{TYPE} eq 'TradfriGroup' and $opt eq 'groupInfo'){
  184. # }elsif($hash->{TYPE} eq 'TradfriDevice' and $opt eq 'deviceInfo'){
  185. # my $jsonText = IOWrite($hash, 'get', PATH_DEVICE_ROOT . "/" . $hash->{address}, '');
  186. #
  187. # if(!defined($jsonText)){
  188. # return "Error while fetching device info!";
  189. # }
  190. #
  191. # #parse the JSON data
  192. # my $jsonData = eval{ JSON->new->utf8->decode($jsonText) };
  193. # if($@){
  194. # return $jsonText; #the string was probably not valid JSON
  195. # }
  196. #
  197. # return Dumper($jsonData);
  198. }else{
  199. return "Unknown argument $opt, choose one of $cmdList";
  200. }
  201. }