18_JSN.pm 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. ################################################################################
  2. # FHEM-Modul see www.fhem.de
  3. # 18_JSN.pm
  4. # JeeSensorNode
  5. #
  6. # Usage: define <Name> JSN <Node-Nr>
  7. ################################################################################
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. ################################################################################
  21. # Autor: Axel Rieger
  22. # Version: 1.0
  23. # Datum: 07.2011
  24. # Kontakt: fhem [bei] anax [punkt] info
  25. ################################################################################
  26. package main;
  27. use strict;
  28. use warnings;
  29. use POSIX;
  30. use Data::Dumper;
  31. use vars qw(%defs);
  32. use vars qw(%attr);
  33. use vars qw(%data);
  34. use vars qw(%modules);
  35. ################################################################################
  36. sub JSN_Initialize($)
  37. {
  38. my ($hash) = @_;
  39. # Match/Prefix
  40. my $match = "JSN";
  41. $hash->{Match} = "^JSN";
  42. $hash->{DefFn} = "JSN_Define";
  43. $hash->{UndefFn} = "JSN_Undef";
  44. $hash->{ParseFn} = "JSN_Parse";
  45. $hash->{AttrList} = "do_not_notify:0,1 loglevel:0,5 disable:0,1";
  46. #-----------------------------------------------------------------------------
  47. # Arduino/JeeNodes-Variables:
  48. # http://arduino.cc/en/Reference/HomePage
  49. # Integer = 2 Bytes -> form -32,768 to 32,767
  50. # Long (unsigned) = 4 Bytes -> from 0 to 4,294,967,295
  51. # Long (signed) = 4 Bytes -> from -2,147,483,648 to 2,147,483,647
  52. #
  53. # JeeConf
  54. # $data{JEECONF}{<SensorType>}{ReadingName}
  55. # $data{JEECONF}{<SensorType>}{DataBytes}
  56. # $data{JEECONF}{<SensorType>}{Prefix}
  57. # $data{JEECONF}{<SensorType>}{CorrFactor}
  58. # $data{JEECONF}{<SensorType>}{Function}
  59. # <SensorType>: 0-9 -> Reserved/not Used
  60. # <SensorType>: 10-99 -> Default
  61. # <SensorType>: 100-199 -> Userdifined
  62. # <SensorType>: 200-255 -> Internal/Test
  63. # Default-2-Bytes-------------------------------------------------------------
  64. $data{JEECONF}{12}{ReadingName} = "SensorData";
  65. $data{JEECONF}{12}{DataBytes} = 2;
  66. $data{JEECONF}{12}{Prefix} = $match;
  67. # Temperature ----------------------------------------------------------------
  68. $data{JEECONF}{11}{ReadingName} = "temperature";
  69. $data{JEECONF}{11}{DataBytes} = 2;
  70. $data{JEECONF}{11}{Prefix} = $match;
  71. $data{JEECONF}{11}{CorrFactor} = 0.1;
  72. # Brightness- ----------------------------------------------------------------
  73. $data{JEECONF}{12}{ReadingName} = "brightness";
  74. $data{JEECONF}{12}{DataBytes} = 4;
  75. $data{JEECONF}{12}{Prefix} = $match;
  76. # Triple-Axis-X-Y-Z----------------------------------------------------------
  77. $data{JEECONF}{13}{ReadingName} = "rtiple_axis";
  78. $data{JEECONF}{13}{Function} = "JSN_parse_12";
  79. $data{JEECONF}{13}{DataBytes} = 12;
  80. $data{JEECONF}{13}{Prefix} = $match;
  81. #-----------------------------------------------------------------------------
  82. # 14 Used by 18_JME
  83. # Counter --------------------------------------------------------------------
  84. # $data{JEECONF}{14}{ReadingName} = "counter";
  85. # $data{JEECONF}{14}{DataBytes} = 4;
  86. # $data{JEECONF}{14}{Prefix} = $match;
  87. # Pressure -------------------------------------------------------------------
  88. $data{JEECONF}{15}{ReadingName} = "pressure";
  89. $data{JEECONF}{15}{DataBytes} = 4;
  90. $data{JEECONF}{15}{CorrFactor} = 0.01;
  91. $data{JEECONF}{15}{Prefix} = $match;
  92. # Humidity -------------------------------------------------------------------
  93. $data{JEECONF}{16}{ReadingName} = "humidity";
  94. $data{JEECONF}{16}{DataBytes} = 1;
  95. $data{JEECONF}{16}{Prefix} = $match;
  96. # Light LDR ------------------------------------------------------------------
  97. $data{JEECONF}{17}{ReadingName} = "light_ldr";
  98. $data{JEECONF}{17}{DataBytes} = 1;
  99. $data{JEECONF}{17}{Prefix} = $match;
  100. # Motion ---------------------------------------------------------------------
  101. $data{JEECONF}{18}{ReadingName} = "motion";
  102. $data{JEECONF}{18}{DataBytes} = 1;
  103. $data{JEECONF}{18}{Prefix} = $match;
  104. # JeeNode InternalTemperatur -------------------------------------------------
  105. $data{JEECONF}{251}{ReadingName} = "AtmelTemp";
  106. $data{JEECONF}{251}{DataBytes} = 2;
  107. $data{JEECONF}{251}{Prefix} = $match;
  108. # JeeNode InternalRefVolatge -------------------------------------------------
  109. $data{JEECONF}{252}{ReadingName} = "PowerSupply";
  110. $data{JEECONF}{252}{DataBytes} = 2;
  111. $data{JEECONF}{252}{CorrFactor} = 0.0001;
  112. $data{JEECONF}{252}{Prefix} = $match;
  113. # JeeNode RF12 LowBat --------------------------------------------------------
  114. $data{JEECONF}{253}{ReadingName} = "RF12LowBat";
  115. $data{JEECONF}{253}{DataBytes} = 1;
  116. $data{JEECONF}{253}{Prefix} = $match;
  117. # JeeNode Milliseconds -------------------------------------------------------
  118. $data{JEECONF}{254}{ReadingName} = "Millis";
  119. $data{JEECONF}{254}{DataBytes} = 4;
  120. $data{JEECONF}{254}{Prefix} = $match;
  121. }
  122. ################################################################################
  123. sub JSN_Define($){
  124. # define J001 JSN <Node-Nr> [<Path_to_User_Conf_File>]
  125. # hash = New Device
  126. # defs = $a[0] <DEVICE-NAME> $a[1] DEVICE-TYPE $a[2]<Parameter-1-> $a[3]<Parameter-2->
  127. my ($hash, $def) = @_;
  128. my @a = split(/\s+/, $def);
  129. return "JSN: Unknown argument count " . int(@a) . " , usage define <NAME>
  130. NodeID [<Path_to_User_Conf_File>]" if(int(@a) != 3);
  131. my $NodeID = $a[2];
  132. if(defined($modules{JSN}{defptr}{$NodeID})) {
  133. return "Node $NodeID allready define";
  134. }
  135. $hash->{CODE} = $NodeID;
  136. $hash->{STATE} = "NEW: " . TimeNow();
  137. $hash->{OrderID} = $NodeID;
  138. $modules{JSN}{defptr}{$NodeID} = $hash;
  139. return undef;
  140. }
  141. ################################################################################
  142. sub JSN_Undef($$){
  143. my ($hash, $name) = @_;
  144. Log 4, "JeeNode Undef: " . Dumper(@_);
  145. my $NodeID = $hash->{NodeID};
  146. if(defined($modules{JSN}{defptr}{$NodeID})) {
  147. delete $modules{JSN}{defptr}{$NodeID}
  148. }
  149. return undef;
  150. }
  151. ################################################################################
  152. sub JSN_Parse($$) {
  153. my ($iodev, $rawmsg) = @_;
  154. # $rawmsg = JeeNodeID + SensorType + SensorData
  155. # rawmsg = JSN 03 252 03 65
  156. Log 5, "JSN PARSE RAW-MSG: " . $rawmsg . " IODEV:" . $iodev->{NAME};
  157. #
  158. my @data = split(/\s+/,$rawmsg);
  159. my $NodeID = $data[1];
  160. # my $NodeID = sprintf("%02x" ,($data[1]));
  161. # $NodeID = hex($NodeID);
  162. # my $NodeID = chr(ord($data[1]));
  163. my $SType = $data[2];
  164. my $data_bytes = $data{JEECONF}{$SType}{DataBytes};
  165. my $data_end = int(@data) - 1;
  166. # $array[$#array];
  167. Log 5, "JSN PARSE N:$NodeID S:$SType B:$data_bytes CNT:" . @data . " END:" . $data_end;
  168. my @SData = @data[3..$data_end];
  169. my ($hash,$name);
  170. if(defined($modules{JSN}{defptr}{$NodeID})) {
  171. $hash = $modules{JSN}{defptr}{$NodeID};
  172. $name = $hash->{NAME};
  173. }
  174. else {
  175. return "UNDEFINED JSN_$NodeID JSN $NodeID";};
  176. my %readings;
  177. # Function-Data --------------------------------------------------------------
  178. # If defined $data{JEECONF}{<SensorType>}{Function} then the function handels
  179. # data parsing...return a hash key:reading_name Value:reading_value
  180. # Param to Function: $iodev,$name,$NodeID, $SType,@SData
  181. # Function-Data --------------------------------------------------------------
  182. if(defined($data{JEECONF}{$SType}{Function})) {
  183. my $func = $data{JEECONF}{$SType}{Function};
  184. if(!defined(&$func)) {
  185. Log 0, "JSN PARSE Function not defined: $SType -> $func";
  186. return undef;
  187. }
  188. no strict "refs";
  189. %readings = &$func($iodev,$name,$NodeID, $SType,@SData);
  190. use strict "refs";
  191. }
  192. else {
  193. # Sensor-Data Bytes to Values
  194. # lowBit HighBit reverse ....
  195. @SData = reverse(@SData);
  196. my $raw_value = join("",@SData);
  197. my $value = "";
  198. map {$value .= sprintf "%02x",$_} @SData;
  199. $value = hex($value);
  200. Log 5, "JSN PARSE DATA $NodeID - $SType - " . join(" " , @SData) . " -> " . $value;
  201. my $reading_name = $data{JEECONF}{$SType}{ReadingName};
  202. $readings{$reading_name} = $value;
  203. if(defined($data{JEECONF}{$SType}{CorrFactor})) {
  204. my $corr = $data{JEECONF}{$SType}{CorrFactor};
  205. $readings{$reading_name} = $value * $corr;
  206. }
  207. }
  208. #Reading
  209. my $i = 0;
  210. foreach my $r (sort keys %readings) {
  211. Log 5, "JSN $name $r:" . $readings{$r};
  212. $defs{$name}{READINGS}{$r}{VAL} = $readings{$r};
  213. $defs{$name}{READINGS}{$r}{TIME} = TimeNow();
  214. $defs{$name}{STATE} = TimeNow() . " " . $r;
  215. # Changed for Notify and Logs
  216. $defs{$name}{CHANGED}[$i] = $r . ": " . $readings{$r};
  217. $i++;
  218. }
  219. return $name;
  220. }
  221. ################################################################################
  222. sub JSN_parse_12() {
  223. my ($iodev,$name,$NodeID, $SType,@SData) = @_;
  224. Log 5, "JSN PARSE-12 DATA $NodeID - $SType - " . join(" " , @SData);
  225. my %reading;
  226. $reading{X} = "XXX";
  227. $reading{Y} = "YYY";
  228. $reading{Z} = "ZZZ";
  229. return \%reading;
  230. }
  231. ################################################################################
  232. 1;