19_Revolt.pm 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ##############################################
  2. # #
  3. # Written by Martin Paulat, 2013 #
  4. # #
  5. ##############################################
  6. package main;
  7. use strict;
  8. use warnings;
  9. use Date::Parse;
  10. #####################################
  11. sub
  12. Revolt_Initialize($)
  13. {
  14. my ($hash) = @_;
  15. # r00C5E100303203C85921FF
  16. $hash->{Match} = "^r......................\$";
  17. $hash->{DefFn} = "Revolt_Define";
  18. $hash->{UndefFn} = "Revolt_Undef";
  19. $hash->{ParseFn} = "Revolt_Parse";
  20. $hash->{AttrList} = "IODev ".
  21. $readingFnAttributes;
  22. }
  23. #####################################
  24. sub
  25. Revolt_Define($$)
  26. {
  27. my ($hash, $def) = @_;
  28. my @a = split("[ \t][ \t]*", $def);
  29. return "wrong syntax: define <name> Revolt <id>" if(int(@a) != 3);
  30. $a[2] = lc($a[2]);
  31. return "Define $a[0]: wrong <id> format: specify a 4 digit hex value"
  32. if($a[2] !~ m/^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/);
  33. $hash->{ID} = $a[2];
  34. #$hash->{STATE} = "Initialized";
  35. $modules{REVOLT}{defptr}{$a[2]} = $hash;
  36. AssignIoPort($hash);
  37. return undef;
  38. }
  39. #####################################
  40. sub
  41. Revolt_Undef($$)
  42. {
  43. my ($hash, $name) = @_;
  44. delete($modules{REVOLT}{defptr}{$hash->{ID}})
  45. if(defined($hash->{ID}) &&
  46. defined($modules{REVOLT}{defptr}{$hash->{ID}}));
  47. return undef;
  48. }
  49. #####################################
  50. sub
  51. Revolt_Parse($$)
  52. {
  53. my ($hash, $msg) = @_;
  54. $msg = lc($msg);
  55. my $seq = substr($msg, 1, 2);
  56. my $dev = substr($msg, 3, 4);
  57. my $cde = substr($msg, 7, 4);
  58. my $val = substr($msg, 11, 22);
  59. my $id = substr($msg, 1, 4);
  60. my $voltage = hex(substr($msg, 5, 2));
  61. my $current = hex(substr($msg, 7, 4))*0.01;
  62. my $freq = hex(substr($msg, 11, 2));
  63. my $power = hex(substr($msg, 13, 4))*0.1;
  64. my $pf = hex(substr($msg, 17, 2))*0.01;
  65. my $energy = hex(substr($msg, 19, 4))*0.01;
  66. my $lastval;
  67. my $avg;
  68. my $type = "";
  69. if(!defined($modules{REVOLT}{defptr}{$id})) {
  70. Log3 undef,3, "Unknown Revolt device $id, please define it";
  71. $type = "Revolt" if(!$type);
  72. return "UNDEFINED ${type}_$id Revolt $id";
  73. }
  74. my $def = $modules{REVOLT}{defptr}{$id};
  75. my $name = $def->{NAME};
  76. return "" if(IsIgnored($name));
  77. my $state;
  78. $state="P: ".sprintf("%5.1f",$power)." E: ".sprintf("%6.2f",$energy)." V: ".sprintf("%3d",$voltage)." C: ".sprintf("%6.2f",$current)." F: $freq Pf: ".sprintf("%4.2f",$pf);
  79. readingsBeginUpdate($def);
  80. if (defined($def->{READINGS}{".lastenergy"})) {
  81. $lastval=$def->{READINGS}{".lastenergy"}{VAL};
  82. if ($lastval != $energy) {
  83. $avg=(($lastval-$energy)*1000.0*3600.0)/(str2time($def->{READINGS}{".lastenergy"}{TIME})-gettimeofday());
  84. readingsBulkUpdate($def,".lastenergy", $energy,1);
  85. readingsBulkUpdate($def,"avgpower", sprintf("%.2f",$avg),1);
  86. }
  87. } else {
  88. readingsBulkUpdate($def,".lastenergy", $energy,1);
  89. }
  90. readingsBulkUpdate($def,"state", $state,1);
  91. Log3 $name,4, "$name: $state";
  92. readingsBulkUpdate($def,"voltage", $voltage,1);
  93. #Log3 $def,3, "$name:voltage $voltage";
  94. readingsBulkUpdate($def,"current", $current,1);
  95. #Log3 $def,3, "$name:current $current";
  96. readingsBulkUpdate($def,"frequency", $freq,1);
  97. #Log3 $def,3, "$name:frequency $freq";
  98. readingsBulkUpdate($def,"power", $power,1);
  99. #Log3 $def,3, "$name:power $power";
  100. readingsBulkUpdate($def,"pf", $pf,1);
  101. #Log3 $def,3, "$name:Pf $pf";
  102. readingsBulkUpdate($def,"energy", $energy,1);
  103. #Log3 $def,3, "$name:energy $energy";
  104. readingsEndUpdate($def, 1);
  105. return $name;
  106. }
  107. 1;
  108. =pod
  109. =begin html
  110. <a name="Revolt"></a>
  111. <h3>Revolt NC-5462</h3>
  112. <ul>
  113. Provides voltage, current, frequency, power, pf, energy readings for Revolt NC-5462 devices via CUL.
  114. <br><br>
  115. <a name="RevoltDefine"></a>
  116. <b>Define</b>
  117. <ul>
  118. <code>define &lt;name&gt; Revolt &lt;id&gt;</code>
  119. <br><br>
  120. &lt;id&gt; is a 4 digit hex number to identify the NC-5462 device.<br>
  121. Note: devices are autocreated on reception of the first message.<br>
  122. </ul>
  123. <br>
  124. <a name="RevoltReadings"></a>
  125. <b>Readings</b>
  126. <ul>
  127. <li>energy [kWh]</li>
  128. <li>power [W]</li>
  129. <li>voltage [V]</li>
  130. <li>current [A]</li>
  131. <li>frequency [Hz]</li>
  132. <li>Pf</li>
  133. </ul>
  134. </ul>
  135. =end html
  136. =cut