62_EMEM.pm 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. ##############################################
  2. # $Id: 62_EMEM.pm 14888 2017-08-13 12:07:12Z rudolfkoenig $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use Time::HiRes qw(gettimeofday);
  7. sub EMEM_Get($@);
  8. sub EMEM_Define($$);
  9. sub EMEM_GetStatus($);
  10. ###################################
  11. sub
  12. EMEM_Initialize($)
  13. {
  14. my ($hash) = @_;
  15. $hash->{GetFn} = "EMEM_Get";
  16. $hash->{DefFn} = "EMEM_Define";
  17. $hash->{AttrList} = "IODev dummy:1,0 model:EM1000EM";
  18. }
  19. ###################################
  20. sub
  21. EMEM_GetStatus($)
  22. {
  23. my ($hash) = @_;
  24. if(!$hash->{LOCAL}) {
  25. InternalTimer(gettimeofday()+300, "EMEM_GetStatus", $hash, 0);
  26. }
  27. my $dnr = $hash->{DEVNR};
  28. my $name = $hash->{NAME};
  29. return "Empty status: dummy IO device" if(IsIoDummy($name));
  30. my $d = IOWrite($hash, sprintf("7a%02x", $dnr-1));
  31. if(!defined($d)) {
  32. my $msg = "EMEM $name read error (GetStatus 1)";
  33. Log3 $name, 2, $msg;
  34. return $msg;
  35. }
  36. if($d eq ((pack('H*',"00") x 45) . pack('H*',"FF") x 6)) {
  37. my $msg = "EMEM no device no. $dnr present";
  38. Log3 $name, 2, $msg;
  39. return $msg;
  40. }
  41. my $pulses=w($d,13);
  42. my $pulses_max= w($d,15);
  43. my $iec = 1000;
  44. my $cur_power = $pulses / 100;
  45. my $cur_power_max = $pulses_max / 100;
  46. if($cur_power > 30) { # 20Amp x 3 Phase
  47. my $msg = "EMEM Bogus reading: curr. power is reported to be $cur_power, setting to -1";
  48. Log3 $name, 2, $msg;
  49. #return $msg;
  50. $cur_power = -1.0;
  51. }
  52. if($cur_power_max > 30) { # 20Amp x 3 Phase
  53. $cur_power_max = -1.0;
  54. }
  55. my %vals;
  56. $vals{"5min_pulses"} = $pulses;
  57. $vals{"5min_pulses_max"} = $pulses_max;
  58. $vals{"energy_kWh_h"} = sprintf("%0.3f", dw($d,33) / $iec);
  59. $vals{"energy_kWh_d"} = sprintf("%0.3f", dw($d,37) / $iec);
  60. $vals{"energy_kWh_w"} = sprintf("%0.3f", dw($d,41) / $iec);
  61. $vals{"energy_kWh"} = sprintf("%0.3f", dw($d, 7) / $iec);
  62. $vals{"power_kW"} = sprintf("%.3f", $cur_power);
  63. $vals{"power_kW_max"} = sprintf("%.3f", $cur_power_max);
  64. $vals{"alarm_PA_W"} = w($d,45);
  65. $vals{"price_CF"} = sprintf("%.3f", w($d,47)/10000);
  66. my $tn = TimeNow();
  67. my $idx = 0;
  68. foreach my $k (keys %vals) {
  69. my $v = $vals{$k};
  70. $hash->{CHANGED}[$idx++] = "$k: $v";
  71. $hash->{READINGS}{$k}{TIME} = $tn;
  72. $hash->{READINGS}{$k}{VAL} = $v
  73. }
  74. if(!$hash->{LOCAL}) {
  75. DoTrigger($name, undef) if($init_done);
  76. }
  77. $hash->{STATE} = "$cur_power kW";
  78. Log3 $name, 4, "EMEM $name: $cur_power kW / $vals{energy_kWh} kWh";
  79. return $hash->{STATE};
  80. }
  81. ###################################
  82. sub
  83. EMEM_Get($@)
  84. {
  85. my ($hash, @a) = @_;
  86. return "argument is missing" if(int(@a) != 2);
  87. my $d = $hash->{DEVNR};
  88. my $msg;
  89. if($a[1] ne "status") {
  90. return "unknown argument $a[1], choose one of status";
  91. }
  92. $hash->{LOCAL} = 1;
  93. my $v = EMEM_GetStatus($hash);
  94. delete $hash->{LOCAL};
  95. return "$a[0] $a[1] => $v";
  96. }
  97. #############################
  98. sub
  99. EMEM_Define($$)
  100. {
  101. my ($hash, $def) = @_;
  102. my @a = split("[ \t][ \t]*", $def);
  103. return "syntax: define <name> EMEM devicenumber"
  104. if(@a != 3 || $a[2] !~ m,^[5-8]$,);
  105. $hash->{DEVNR} = $a[2];
  106. AssignIoPort($hash);
  107. EMEM_GetStatus($hash);
  108. return undef;
  109. }
  110. 1;
  111. =pod
  112. =item summary EM1000EM devices communicating over the EM1010PC
  113. =item summary_DE EM1000EM Ger&auml;te angebunden &uuml;ber ein EM1010PC
  114. =begin html
  115. <a name="EMEM"></a>
  116. <h3>EMEM</h3>
  117. <ul>
  118. <br>
  119. <a name="EMEMdefine"></a>
  120. <b>Define</b>
  121. <ul>
  122. <code>define &lt;name&gt; EMEM &lt;device-number&gt;</code>
  123. <br><br>
  124. Define up to 4 EM1000EM attached to the EM1010PC. The device number must
  125. be between 5 and 8.
  126. Defining an EMEM will schedule an internal task, which reads the
  127. status of the device every 5 minutes, and triggers notify/filelog commands.
  128. <br>Note: Currently this device does not support a "set" function.
  129. <br><br>
  130. Example:
  131. <ul>
  132. <code>define emem EMEM 5</code><br>
  133. </ul>
  134. </ul>
  135. <br>
  136. <b>Set</b> <ul>N/A</ul><br>
  137. <a name="EMEMget"></a>
  138. <b>Get</b>
  139. <ul>
  140. <code>get EMEM status</code>
  141. <br><br>
  142. This is the same command which is scheduled every 5 minutes internally.
  143. </ul>
  144. <br>
  145. <a name="EMEMattr"></a>
  146. <b>Attributes</b>
  147. <ul>
  148. <li><a href="#model">model</a> (EM1000EM)</li>
  149. <li><a href="#attrdummy">dummy</a></li>
  150. <li><a href="#IODev">IODev</a></li><br>
  151. </ul>
  152. <br>
  153. </ul>
  154. =end html
  155. =cut