ansible4ozw 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. data/lib/ansible.rb +12 -9
  2. data/lib/ansible/ansible_device.rb +1 -1
  3. data/lib/ansible/ansible_value.rb +1 -1
  4. data/lib/ansible/config.rb +8 -5
  5. data/lib/ansible/devices.rb +1 -0
  6. data/lib/ansible/knx.rb +0 -0
  7. data/lib/ansible/knx/dpt/tests/test_dpt10.rb~ +45 -0
  8. data/lib/ansible/knx/dpt/tests/test_dpt9.rb~ +55 -0
  9. data/lib/ansible/transceiver.rb +0 -3
  10. data/lib/ansible/version.rb +3 -0
  11. data/lib/ansible/zwave.rb +1 -0
  12. data/lib/ansible/{openzwave → zwave/openzwave}/ozw_constants.rb +1 -2
  13. data/lib/ansible/{openzwave → zwave/openzwave}/ozw_headers.rb +2 -6
  14. data/lib/ansible/{openzwave → zwave/openzwave}/ozw_remote_manager.rb +0 -3
  15. data/lib/ansible/{openzwave → zwave/openzwave}/ozw_types.rb +0 -0
  16. data/lib/ansible/zwave/openzwave/src/Driver.h +695 -0
  17. data/lib/ansible/zwave/openzwave/src/Notification.h +165 -0
  18. data/lib/ansible/zwave/openzwave/src/command_classes/Alarm.cpp +142 -0
  19. data/lib/ansible/zwave/openzwave/src/command_classes/Alarm.h +69 -0
  20. data/lib/ansible/zwave/openzwave/src/command_classes/ApplicationStatus.cpp +93 -0
  21. data/lib/ansible/zwave/openzwave/src/command_classes/ApplicationStatus.h +57 -0
  22. data/lib/ansible/zwave/openzwave/src/command_classes/Association.cpp +385 -0
  23. data/lib/ansible/zwave/openzwave/src/command_classes/Association.h +73 -0
  24. data/lib/ansible/zwave/openzwave/src/command_classes/AssociationCommandConfiguration.cpp +277 -0
  25. data/lib/ansible/zwave/openzwave/src/command_classes/AssociationCommandConfiguration.h +70 -0
  26. data/lib/ansible/zwave/openzwave/src/command_classes/Basic.cpp +212 -0
  27. data/lib/ansible/zwave/openzwave/src/command_classes/Basic.h +72 -0
  28. data/lib/ansible/zwave/openzwave/src/command_classes/BasicWindowCovering.cpp +118 -0
  29. data/lib/ansible/zwave/openzwave/src/command_classes/BasicWindowCovering.h +64 -0
  30. data/lib/ansible/zwave/openzwave/src/command_classes/Battery.cpp +141 -0
  31. data/lib/ansible/zwave/openzwave/src/command_classes/Battery.h +65 -0
  32. data/lib/ansible/zwave/openzwave/src/command_classes/ClimateControlSchedule.cpp +415 -0
  33. data/lib/ansible/zwave/openzwave/src/command_classes/ClimateControlSchedule.h +71 -0
  34. data/lib/ansible/zwave/openzwave/src/command_classes/Clock.cpp +227 -0
  35. data/lib/ansible/zwave/openzwave/src/command_classes/Clock.h +67 -0
  36. data/lib/ansible/zwave/openzwave/src/command_classes/CommandClass.cpp +546 -0
  37. data/lib/ansible/zwave/openzwave/src/command_classes/CommandClass.h +145 -0
  38. data/lib/ansible/zwave/openzwave/src/command_classes/CommandClasses.cpp +291 -0
  39. data/lib/ansible/zwave/openzwave/src/command_classes/CommandClasses.h +79 -0
  40. data/lib/ansible/zwave/openzwave/src/command_classes/Configuration.cpp +258 -0
  41. data/lib/ansible/zwave/openzwave/src/command_classes/Configuration.h +67 -0
  42. data/lib/ansible/zwave/openzwave/src/command_classes/ControllerReplication.cpp +142 -0
  43. data/lib/ansible/zwave/openzwave/src/command_classes/ControllerReplication.h +63 -0
  44. data/lib/ansible/zwave/openzwave/src/command_classes/EnergyProduction.cpp +163 -0
  45. data/lib/ansible/zwave/openzwave/src/command_classes/EnergyProduction.h +65 -0
  46. data/lib/ansible/zwave/openzwave/src/command_classes/Hail.cpp +68 -0
  47. data/lib/ansible/zwave/openzwave/src/command_classes/Hail.h +58 -0
  48. data/lib/ansible/zwave/openzwave/src/command_classes/Indicator.cpp +159 -0
  49. data/lib/ansible/zwave/openzwave/src/command_classes/Indicator.h +66 -0
  50. data/lib/ansible/zwave/openzwave/src/command_classes/Language.cpp +159 -0
  51. data/lib/ansible/zwave/openzwave/src/command_classes/Language.h +65 -0
  52. data/lib/ansible/zwave/openzwave/src/command_classes/Lock.cpp +159 -0
  53. data/lib/ansible/zwave/openzwave/src/command_classes/Lock.h +66 -0
  54. data/lib/ansible/zwave/openzwave/src/command_classes/ManufacturerSpecific.cpp +439 -0
  55. data/lib/ansible/zwave/openzwave/src/command_classes/ManufacturerSpecific.h +116 -0
  56. data/lib/ansible/zwave/openzwave/src/command_classes/Meter.cpp +541 -0
  57. data/lib/ansible/zwave/openzwave/src/command_classes/Meter.h +73 -0
  58. data/lib/ansible/zwave/openzwave/src/command_classes/MeterPulse.cpp +137 -0
  59. data/lib/ansible/zwave/openzwave/src/command_classes/MeterPulse.h +65 -0
  60. data/lib/ansible/zwave/openzwave/src/command_classes/MultiCmd.cpp +77 -0
  61. data/lib/ansible/zwave/openzwave/src/command_classes/MultiCmd.h +63 -0
  62. data/lib/ansible/zwave/openzwave/src/command_classes/MultiInstance.cpp +568 -0
  63. data/lib/ansible/zwave/openzwave/src/command_classes/MultiInstance.h +96 -0
  64. data/lib/ansible/zwave/openzwave/src/command_classes/MultiInstanceAssociation.cpp +61 -0
  65. data/lib/ansible/zwave/openzwave/src/command_classes/MultiInstanceAssociation.h +59 -0
  66. data/lib/ansible/zwave/openzwave/src/command_classes/NodeNaming.cpp +525 -0
  67. data/lib/ansible/zwave/openzwave/src/command_classes/NodeNaming.h +66 -0
  68. data/lib/ansible/zwave/openzwave/src/command_classes/Powerlevel.cpp +157 -0
  69. data/lib/ansible/zwave/openzwave/src/command_classes/Powerlevel.h +82 -0
  70. data/lib/ansible/zwave/openzwave/src/command_classes/Proprietary.cpp +62 -0
  71. data/lib/ansible/zwave/openzwave/src/command_classes/Proprietary.h +58 -0
  72. data/lib/ansible/zwave/openzwave/src/command_classes/Protection.cpp +177 -0
  73. data/lib/ansible/zwave/openzwave/src/command_classes/Protection.h +73 -0
  74. data/lib/ansible/zwave/openzwave/src/command_classes/SensorAlarm.cpp +208 -0
  75. data/lib/ansible/zwave/openzwave/src/command_classes/SensorAlarm.h +77 -0
  76. data/lib/ansible/zwave/openzwave/src/command_classes/SensorBinary.cpp +134 -0
  77. data/lib/ansible/zwave/openzwave/src/command_classes/SensorBinary.h +65 -0
  78. data/lib/ansible/zwave/openzwave/src/command_classes/SensorMultilevel.cpp +237 -0
  79. data/lib/ansible/zwave/openzwave/src/command_classes/SensorMultilevel.h +71 -0
  80. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchAll.cpp +219 -0
  81. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchAll.h +69 -0
  82. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchBinary.cpp +157 -0
  83. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchBinary.h +66 -0
  84. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchMultilevel.cpp +559 -0
  85. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchMultilevel.h +83 -0
  86. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchToggleBinary.cpp +151 -0
  87. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchToggleBinary.h +66 -0
  88. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchToggleMultilevel.cpp +195 -0
  89. data/lib/ansible/zwave/openzwave/src/command_classes/SwitchToggleMultilevel.h +75 -0
  90. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatFanMode.cpp +332 -0
  91. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatFanMode.h +77 -0
  92. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatFanState.cpp +149 -0
  93. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatFanState.h +71 -0
  94. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatMode.cpp +373 -0
  95. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatMode.h +76 -0
  96. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatOperatingState.cpp +147 -0
  97. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatOperatingState.h +71 -0
  98. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatSetpoint.cpp +317 -0
  99. data/lib/ansible/zwave/openzwave/src/command_classes/ThermostatSetpoint.h +73 -0
  100. data/lib/ansible/zwave/openzwave/src/command_classes/Version.cpp +255 -0
  101. data/lib/ansible/zwave/openzwave/src/command_classes/Version.h +71 -0
  102. data/lib/ansible/zwave/openzwave/src/command_classes/WakeUp.cpp +391 -0
  103. data/lib/ansible/zwave/openzwave/src/command_classes/WakeUp.h +85 -0
  104. data/lib/ansible/zwave/openzwave/src/platform/Controller.cpp +68 -0
  105. data/lib/ansible/zwave/openzwave/src/platform/Controller.h +106 -0
  106. data/lib/ansible/zwave/openzwave/src/platform/Event.cpp +102 -0
  107. data/lib/ansible/zwave/openzwave/src/platform/Event.h +91 -0
  108. data/lib/ansible/zwave/openzwave/src/platform/HidController.cpp +539 -0
  109. data/lib/ansible/zwave/openzwave/src/platform/HidController.h +147 -0
  110. data/lib/ansible/zwave/openzwave/src/platform/Log.cpp +310 -0
  111. data/lib/ansible/zwave/openzwave/src/platform/Log.h +184 -0
  112. data/lib/ansible/zwave/openzwave/src/platform/Mutex.cpp +96 -0
  113. data/lib/ansible/zwave/openzwave/src/platform/Mutex.h +88 -0
  114. data/lib/ansible/zwave/openzwave/src/platform/Ref.h +91 -0
  115. data/lib/ansible/zwave/openzwave/src/platform/SerialController.cpp +180 -0
  116. data/lib/ansible/zwave/openzwave/src/platform/SerialController.h +138 -0
  117. data/lib/ansible/zwave/openzwave/src/platform/Stream.cpp +229 -0
  118. data/lib/ansible/zwave/openzwave/src/platform/Stream.h +135 -0
  119. data/lib/ansible/zwave/openzwave/src/platform/Thread.cpp +118 -0
  120. data/lib/ansible/zwave/openzwave/src/platform/Thread.h +101 -0
  121. data/lib/ansible/zwave/openzwave/src/platform/TimeStamp.cpp +92 -0
  122. data/lib/ansible/zwave/openzwave/src/platform/TimeStamp.h +85 -0
  123. data/lib/ansible/zwave/openzwave/src/platform/Wait.cpp +176 -0
  124. data/lib/ansible/zwave/openzwave/src/platform/Wait.h +113 -0
  125. data/lib/ansible/zwave/openzwave/src/platform/unix/EventImpl.cpp +262 -0
  126. data/lib/ansible/zwave/openzwave/src/platform/unix/EventImpl.h +62 -0
  127. data/lib/ansible/zwave/openzwave/src/platform/unix/LogImpl.cpp +304 -0
  128. data/lib/ansible/zwave/openzwave/src/platform/unix/LogImpl.h +70 -0
  129. data/lib/ansible/zwave/openzwave/src/platform/unix/MutexImpl.cpp +136 -0
  130. data/lib/ansible/zwave/openzwave/src/platform/unix/MutexImpl.h +56 -0
  131. data/lib/ansible/zwave/openzwave/src/platform/unix/SerialControllerImpl.cpp +368 -0
  132. data/lib/ansible/zwave/openzwave/src/platform/unix/SerialControllerImpl.h +74 -0
  133. data/lib/ansible/zwave/openzwave/src/platform/unix/ThreadImpl.cpp +181 -0
  134. data/lib/ansible/zwave/openzwave/src/platform/unix/ThreadImpl.h +67 -0
  135. data/lib/ansible/zwave/openzwave/src/platform/unix/TimeStampImpl.cpp +121 -0
  136. data/lib/ansible/zwave/openzwave/src/platform/unix/TimeStampImpl.h +84 -0
  137. data/lib/ansible/zwave/openzwave/src/platform/unix/WaitImpl.cpp +160 -0
  138. data/lib/ansible/zwave/openzwave/src/platform/unix/WaitImpl.h +74 -0
  139. data/lib/ansible/zwave/openzwave/src/platform/windows/EventImpl.cpp +102 -0
  140. data/lib/ansible/zwave/openzwave/src/platform/windows/EventImpl.h +60 -0
  141. data/lib/ansible/zwave/openzwave/src/platform/windows/LogImpl.cpp +302 -0
  142. data/lib/ansible/zwave/openzwave/src/platform/windows/LogImpl.h +71 -0
  143. data/lib/ansible/zwave/openzwave/src/platform/windows/MutexImpl.cpp +114 -0
  144. data/lib/ansible/zwave/openzwave/src/platform/windows/MutexImpl.h +58 -0
  145. data/lib/ansible/zwave/openzwave/src/platform/windows/SerialControllerImpl.cpp +410 -0
  146. data/lib/ansible/zwave/openzwave/src/platform/windows/SerialControllerImpl.h +66 -0
  147. data/lib/ansible/zwave/openzwave/src/platform/windows/ThreadImpl.cpp +158 -0
  148. data/lib/ansible/zwave/openzwave/src/platform/windows/ThreadImpl.h +71 -0
  149. data/lib/ansible/zwave/openzwave/src/platform/windows/TimeStampImpl.cpp +95 -0
  150. data/lib/ansible/zwave/openzwave/src/platform/windows/TimeStampImpl.h +83 -0
  151. data/lib/ansible/zwave/openzwave/src/platform/windows/WaitImpl.cpp +134 -0
  152. data/lib/ansible/zwave/openzwave/src/platform/windows/WaitImpl.h +73 -0
  153. data/lib/ansible/zwave/openzwave/src/value_classes/ValueID.h +283 -0
  154. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_bool.rb +0 -0
  155. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_button.rb +0 -0
  156. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_byte.rb +0 -0
  157. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_decimal.rb +0 -0
  158. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_int.rb +0 -0
  159. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_list.rb +0 -0
  160. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_short.rb +0 -0
  161. data/lib/ansible/zwave/{types → openzwave/types}/valuetype_string.rb +0 -0
  162. data/lib/ansible/zwave/zwave_transceiver.rb +2 -8
  163. data/lib/ansible/zwave/zwave_value.rb +6 -10
  164. metadata +159 -17
  165. data/lib/ansible/zwave/zwave_node.rb +0 -5
@@ -0,0 +1,116 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // ManufacturerSpecific.h
4
+ //
5
+ // Implementation of the Z-Wave COMMAND_CLASS_MANUFACTURER_SPECIFIC
6
+ //
7
+ // Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
8
+ //
9
+ // SOFTWARE NOTICE AND LICENSE
10
+ //
11
+ // This file is part of OpenZWave.
12
+ //
13
+ // OpenZWave is free software: you can redistribute it and/or modify
14
+ // it under the terms of the GNU Lesser General Public License as published
15
+ // by the Free Software Foundation, either version 3 of the License,
16
+ // or (at your option) any later version.
17
+ //
18
+ // OpenZWave is distributed in the hope that it will be useful,
19
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ // GNU Lesser General Public License for more details.
22
+ //
23
+ // You should have received a copy of the GNU Lesser General Public License
24
+ // along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
25
+ //
26
+ //-----------------------------------------------------------------------------
27
+
28
+ #ifndef _ManufacturerSpecific_H
29
+ #define _ManufacturerSpecific_H
30
+
31
+ #include <map>
32
+ #include "CommandClass.h"
33
+
34
+ namespace OpenZWave
35
+ {
36
+ /** \brief Implements COMMAND_CLASS_MANUFACTURER_SPECIFIC (0x72), a Z-Wave device command class.
37
+ */
38
+ class ManufacturerSpecific: public CommandClass
39
+ {
40
+ public:
41
+ static CommandClass* Create( uint32 const _homeId, uint8 const _nodeId ){ return new ManufacturerSpecific( _homeId, _nodeId ); }
42
+ virtual ~ManufacturerSpecific(){ UnloadProductXML(); }
43
+
44
+ static uint8 const StaticGetCommandClassId(){ return 0x72; }
45
+ static string const StaticGetCommandClassName(){ return "COMMAND_CLASS_MANUFACTURER_SPECIFIC"; }
46
+
47
+ // From CommandClass
48
+ virtual bool RequestState( uint32 const _requestFlags, uint8 const _instance, Driver::MsgQueue const _queue );
49
+ virtual bool RequestValue( uint32 const _requestFlags, uint8 const _index, uint8 const _instance, Driver::MsgQueue const _queue );
50
+ virtual uint8 const GetCommandClassId()const{ return StaticGetCommandClassId(); }
51
+ virtual string const GetCommandClassName()const{ return StaticGetCommandClassName(); }
52
+ virtual bool HandleMsg( uint8 const* _data, uint32 const _length, uint32 const _instance = 1 );
53
+
54
+ static string SetProductDetails( Node *_node, uint16 _manufacturerId, uint16 _productType, uint16 _productId );
55
+ static bool LoadConfigXML( Node* _node, string const& _configXML );
56
+
57
+ void ReLoadConfigXML();
58
+
59
+ private:
60
+ ManufacturerSpecific( uint32 const _homeId, uint8 const _nodeId ): CommandClass( _homeId, _nodeId ){ SetStaticRequest( StaticRequest_Values ); }
61
+ static bool LoadProductXML();
62
+ static void UnloadProductXML();
63
+
64
+ class Product
65
+ {
66
+ public:
67
+ Product
68
+ (
69
+ uint16 _manufacturerId,
70
+ uint16 _productType,
71
+ uint16 _productId,
72
+ string const& _productName,
73
+ string const& _configPath
74
+ ):
75
+ m_manufacturerId( _manufacturerId ),
76
+ m_productType( _productType ),
77
+ m_productId( _productId ),
78
+ m_productName( _productName ),
79
+ m_configPath( _configPath )
80
+ {
81
+ }
82
+
83
+ int64 GetKey()const
84
+ {
85
+ return( GetKey( m_manufacturerId, m_productType, m_productId ) );
86
+ }
87
+
88
+ static int64 GetKey( uint16 _manufacturerId, uint16 _productType, uint16 _productId )
89
+ {
90
+ int64 key = (((int64)_manufacturerId)<<32) | (((int64)_productType)<<16) | (int64)_productId;
91
+ return key;
92
+ }
93
+
94
+ uint16 GetManufacturerId()const{ return m_manufacturerId; }
95
+ uint16 GetProductType()const{ return m_productType; }
96
+ uint16 GetProductId()const{ return m_productId; }
97
+ string GetProductName()const{ return m_productName; }
98
+ string GetConfigPath()const{ return m_configPath; }
99
+
100
+ private:
101
+ uint16 m_manufacturerId;
102
+ uint16 m_productType;
103
+ uint16 m_productId;
104
+ string m_productName;
105
+ string m_configPath;
106
+ };
107
+
108
+ static map<uint16,string> s_manufacturerMap;
109
+ static map<int64,Product*> s_productMap;
110
+ static bool s_bXmlLoaded;
111
+ };
112
+
113
+ } // namespace OpenZWave
114
+
115
+ #endif
116
+
@@ -0,0 +1,541 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // Meter.cpp
4
+ //
5
+ // Implementation of the Z-Wave COMMAND_CLASS_METER
6
+ //
7
+ // Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
8
+ //
9
+ // SOFTWARE NOTICE AND LICENSE
10
+ //
11
+ // This file is part of OpenZWave.
12
+ //
13
+ // OpenZWave is free software: you can redistribute it and/or modify
14
+ // it under the terms of the GNU Lesser General Public License as published
15
+ // by the Free Software Foundation, either version 3 of the License,
16
+ // or (at your option) any later version.
17
+ //
18
+ // OpenZWave is distributed in the hope that it will be useful,
19
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ // GNU Lesser General Public License for more details.
22
+ //
23
+ // You should have received a copy of the GNU Lesser General Public License
24
+ // along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
25
+ //
26
+ //-----------------------------------------------------------------------------
27
+
28
+ #include "CommandClasses.h"
29
+ #include "Meter.h"
30
+ #include "MultiInstance.h"
31
+ #include "Defs.h"
32
+ #include "Bitfield.h"
33
+ #include "Msg.h"
34
+ #include "Node.h"
35
+ #include "Driver.h"
36
+ #include "Log.h"
37
+
38
+ #include "ValueDecimal.h"
39
+ #include "ValueList.h"
40
+ #include "ValueButton.h"
41
+ #include "ValueInt.h"
42
+ #include "ValueBool.h"
43
+
44
+ using namespace OpenZWave;
45
+
46
+ enum MeterCmd
47
+ {
48
+ MeterCmd_Get = 0x01,
49
+ MeterCmd_Report = 0x02,
50
+ // Version 2
51
+ MeterCmd_SupportedGet = 0x03,
52
+ MeterCmd_SupportedReport = 0x04,
53
+ MeterCmd_Reset = 0x05
54
+ };
55
+
56
+ enum MeterType
57
+ {
58
+ MeterType_Electric = 1,
59
+ MeterType_Gas,
60
+ MeterType_Water
61
+ };
62
+
63
+ enum
64
+ {
65
+ MeterIndex_Exporting = 32,
66
+ MeterIndex_Reset
67
+ };
68
+
69
+
70
+ static char const* c_meterTypes[] =
71
+ {
72
+ "Unknown",
73
+ "Electric",
74
+ "Gas",
75
+ "Water"
76
+ };
77
+
78
+ static char const* c_electricityUnits[] =
79
+ {
80
+ "kWh",
81
+ "kVAh",
82
+ "W",
83
+ "pulses",
84
+ "V",
85
+ "A",
86
+ "Power Factor",
87
+ ""
88
+ };
89
+
90
+ static char const* c_gasUnits[] =
91
+ {
92
+ "cubic meters",
93
+ "cubic feet",
94
+ "",
95
+ "pulses"
96
+ "",
97
+ "",
98
+ "",
99
+ ""
100
+ };
101
+
102
+ static char const* c_waterUnits[] =
103
+ {
104
+ "cubic meters",
105
+ "cubic feet",
106
+ "US gallons",
107
+ "pulses"
108
+ "",
109
+ "",
110
+ "",
111
+ ""
112
+ };
113
+
114
+ static char const* c_electricityLabels[] =
115
+ {
116
+ "Energy",
117
+ "Energy",
118
+ "Power",
119
+ "Count",
120
+ "Voltage",
121
+ "Current",
122
+ "Power Factor",
123
+ "Unknown"
124
+ };
125
+
126
+ //-----------------------------------------------------------------------------
127
+ // <Meter::Meter>
128
+ // Constructor
129
+ //-----------------------------------------------------------------------------
130
+ Meter::Meter
131
+ (
132
+ uint32 const _homeId,
133
+ uint8 const _nodeId
134
+ ):
135
+ CommandClass( _homeId, _nodeId ),
136
+ m_scale( 0 )
137
+ {
138
+ SetStaticRequest( StaticRequest_Values );
139
+ }
140
+
141
+ //-----------------------------------------------------------------------------
142
+ // <Meter::RequestState>
143
+ // Request current state from the device
144
+ //-----------------------------------------------------------------------------
145
+ bool Meter::RequestState
146
+ (
147
+ uint32 const _requestFlags,
148
+ uint8 const _instance,
149
+ Driver::MsgQueue const _queue
150
+ )
151
+ {
152
+ bool res = false;
153
+ if( GetVersion() > 1 )
154
+ {
155
+ if( _requestFlags & RequestFlag_Static )
156
+ {
157
+ Msg* msg = new Msg( "MeterCmd_SupportedGet", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true, true, FUNC_ID_APPLICATION_COMMAND_HANDLER, GetCommandClassId() );
158
+ msg->SetInstance( this, _instance );
159
+ msg->Append( GetNodeId() );
160
+ msg->Append( 2 );
161
+ msg->Append( GetCommandClassId() );
162
+ msg->Append( MeterCmd_SupportedGet );
163
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
164
+ GetDriver()->SendMsg( msg, _queue );
165
+ res = true;
166
+ }
167
+ }
168
+
169
+ if( _requestFlags & RequestFlag_Dynamic )
170
+ {
171
+ res |= RequestValue( _requestFlags, 0, _instance, _queue );
172
+ }
173
+
174
+ return res;
175
+ }
176
+
177
+ //-----------------------------------------------------------------------------
178
+ // <Meter::RequestValue>
179
+ // Request current value from the device
180
+ //-----------------------------------------------------------------------------
181
+ bool Meter::RequestValue
182
+ (
183
+ uint32 const _requestFlags,
184
+ uint8 const _dummy1, // = 0 (not used)
185
+ uint8 const _instance,
186
+ Driver::MsgQueue const _queue
187
+ )
188
+ {
189
+ bool res = false;
190
+ for( uint8 i=0; i<8; ++i )
191
+ {
192
+ uint8 baseIndex = i<<2;
193
+
194
+ Value* value = GetValue( _instance, baseIndex );
195
+ if( value != NULL )
196
+ {
197
+ value->Release();
198
+ Msg* msg = new Msg( "MeterCmd_Get", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true, true, FUNC_ID_APPLICATION_COMMAND_HANDLER, GetCommandClassId() );
199
+ msg->SetInstance( this, _instance );
200
+ msg->Append( GetNodeId() );
201
+ msg->Append( 3 );
202
+ msg->Append( GetCommandClassId() );
203
+ msg->Append( MeterCmd_Get );
204
+ msg->Append( (uint8)( i << 3 ) );
205
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
206
+ GetDriver()->SendMsg( msg, _queue );
207
+ res |= true;
208
+ }
209
+ }
210
+ return res;
211
+ }
212
+
213
+ //-----------------------------------------------------------------------------
214
+ // <Meter::HandleMsg>
215
+ // Handle a message from the Z-Wave network
216
+ //-----------------------------------------------------------------------------
217
+ bool Meter::HandleMsg
218
+ (
219
+ uint8 const* _data,
220
+ uint32 const _length,
221
+ uint32 const _instance // = 1
222
+ )
223
+ {
224
+ bool handled = false;
225
+ if (MeterCmd_SupportedReport == (MeterCmd)_data[0])
226
+ {
227
+ handled = HandleSupportedReport( _data, _length, _instance );
228
+ }
229
+ else if (MeterCmd_Report == (MeterCmd)_data[0])
230
+ {
231
+ handled = HandleReport( _data, _length, _instance );
232
+ }
233
+
234
+ return handled;
235
+ }
236
+
237
+ //-----------------------------------------------------------------------------
238
+ // <Meter::HandleSupportedReport>
239
+ // Create the values for this command class based on the reported parameters
240
+ //-----------------------------------------------------------------------------
241
+ bool Meter::HandleSupportedReport
242
+ (
243
+ uint8 const* _data,
244
+ uint32 const _length,
245
+ uint32 const _instance
246
+ )
247
+ {
248
+ bool canReset = ((_data[1] & 0x80) != 0);
249
+ MeterType meterType = (MeterType)(_data[1] & 0x1f);
250
+
251
+ ClearStaticRequest( StaticRequest_Version );
252
+ if( Node* node = GetNodeUnsafe() )
253
+ {
254
+ string msg;
255
+ string valueLabel;
256
+
257
+ msg = c_meterTypes[meterType];
258
+ msg += ": ";
259
+ // Create the list of supported scales
260
+ uint8 scaleSupported = _data[2];
261
+ if( GetVersion() == 2 )
262
+ {
263
+ // Only four scales are allowed in version 2
264
+ scaleSupported &= 0x0f;
265
+ }
266
+
267
+ for( uint8 i=0; i<8; ++i )
268
+ {
269
+ if( scaleSupported & (1<<i) )
270
+ {
271
+ uint8 baseIndex = i<<2; // We leave space between the value indices to insert previous and time delta values if we need to later on.
272
+ switch( meterType )
273
+ {
274
+ case MeterType_Electric:
275
+ {
276
+ if( ValueDecimal* value = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex ) ) )
277
+ {
278
+ value->SetLabel( c_electricityLabels[i] );
279
+ value->SetUnits( c_electricityUnits[i] );
280
+ value->Release();
281
+ }
282
+ else
283
+ {
284
+ node->CreateValueDecimal( ValueID::ValueGenre_User, GetCommandClassId(), _instance, baseIndex, c_electricityLabels[i], c_electricityUnits[i], true, false, "0.0", 0 );
285
+ }
286
+ if( i != 0 )
287
+ msg += ", ";
288
+ msg += c_electricityUnits[i];
289
+ break;
290
+ }
291
+ case MeterType_Gas:
292
+ {
293
+ if( ValueDecimal* value = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex ) ) )
294
+ {
295
+ value->SetLabel( "Gas" );
296
+ value->SetUnits( c_gasUnits[i] );
297
+ value->Release();
298
+ }
299
+ else
300
+ {
301
+ node->CreateValueDecimal( ValueID::ValueGenre_User, GetCommandClassId(), _instance, baseIndex, "Gas", c_gasUnits[i], true, false, "0.0", 0 );
302
+ }
303
+ if( i != 0 )
304
+ msg += ", ";
305
+ msg += c_gasUnits[i];
306
+ break;
307
+ }
308
+ case MeterType_Water:
309
+ {
310
+ if( ValueDecimal* value = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex ) ) )
311
+ {
312
+ value->SetLabel( "Water" );
313
+ value->SetUnits( c_waterUnits[i] );
314
+ value->Release();
315
+ }
316
+ else
317
+ {
318
+ node->CreateValueDecimal( ValueID::ValueGenre_User, GetCommandClassId(), _instance, baseIndex, "Water", c_waterUnits[i], true, false, "0.0", 0 );
319
+ }
320
+ if( i != 0 )
321
+ msg += ", ";
322
+ msg += c_waterUnits[i];
323
+ break;
324
+ }
325
+ default:
326
+ {
327
+ break;
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ // Create the export flag
334
+ node->CreateValueBool( ValueID::ValueGenre_User, GetCommandClassId(), _instance, MeterIndex_Exporting, "Exporting", "", true, false, false, 0 );
335
+
336
+ // Create the reset button
337
+ if( canReset )
338
+ {
339
+ node->CreateValueButton( ValueID::ValueGenre_System, GetCommandClassId(), _instance, MeterIndex_Reset, "Reset", 0 );
340
+ }
341
+
342
+ Log::Write( LogLevel_Info, GetNodeId(), "Received Meter supported report from node %d, %s", GetNodeId(), msg.c_str() );
343
+ return true;
344
+ }
345
+
346
+ return false;
347
+ }
348
+
349
+ //-----------------------------------------------------------------------------
350
+ // <Meter::HandleReport>
351
+ // Read the reported meter value
352
+ //-----------------------------------------------------------------------------
353
+ bool Meter::HandleReport
354
+ (
355
+ uint8 const* _data,
356
+ uint32 const _length,
357
+ uint32 const _instance
358
+ )
359
+ {
360
+ // Import or Export (only valid in version > 1)
361
+ bool exporting = false;
362
+ if( GetVersion() > 1 )
363
+ {
364
+ exporting = ((_data[1] & 0x60) == 0x40 );
365
+ if( ValueBool* value = static_cast<ValueBool*>( GetValue( _instance, MeterIndex_Exporting ) ) )
366
+ {
367
+ value->OnValueRefreshed( exporting );
368
+ value->Release();
369
+ }
370
+ }
371
+
372
+ // Get the value and scale
373
+ uint8 scale;
374
+ uint8 precision = 0;
375
+ string valueStr = ExtractValue( &_data[2], &scale, &precision );
376
+
377
+ if( GetVersion() == 1 )
378
+ {
379
+ // In version 1, we don't know the scale until we get the first value report
380
+ string label;
381
+ string units;
382
+
383
+ switch( (MeterType)(_data[1] & 0x1f) )
384
+ {
385
+ case MeterType_Electric:
386
+ {
387
+ // Electricity Meter
388
+ label = c_electricityLabels[scale];
389
+ units = c_electricityUnits[scale];
390
+ break;
391
+ }
392
+ case MeterType_Gas:
393
+ {
394
+ // Gas Meter
395
+ label = "Gas";
396
+ units = c_gasUnits[scale];
397
+ break;
398
+ }
399
+ case MeterType_Water:
400
+ {
401
+ // Water Meter
402
+ label = "Water";
403
+ units = c_waterUnits[scale];
404
+ break;
405
+ }
406
+ default:
407
+ {
408
+ break;
409
+ }
410
+ }
411
+
412
+ if( ValueDecimal* value = static_cast<ValueDecimal*>( GetValue( _instance, 0 ) ) )
413
+ {
414
+ Log::Write( LogLevel_Info, GetNodeId(), "Received Meter report from node %d: %s=%s%s", GetNodeId(), label.c_str(), valueStr.c_str(), units.c_str() );
415
+ value->SetLabel( label );
416
+ value->SetUnits( units );
417
+ value->OnValueRefreshed( valueStr );
418
+ if( value->GetPrecision() != precision )
419
+ {
420
+ value->SetPrecision( precision );
421
+ }
422
+ value->Release();
423
+ }
424
+ }
425
+ else
426
+ {
427
+ // Version 2 and above
428
+ uint8 baseIndex = scale << 2;
429
+ if( GetVersion() > 2 )
430
+ {
431
+ // In version 3, an extra scale bit is stored in the meter type byte.
432
+ scale |= ((_data[1]&0x80)>>5);
433
+ baseIndex = scale << 2;
434
+ }
435
+
436
+ if( ValueDecimal* value = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex ) ) )
437
+ {
438
+ Log::Write( LogLevel_Info, GetNodeId(), "Received Meter report from node %d: %s%s=%s%s", GetNodeId(), exporting ? "Exporting ": "", value->GetLabel().c_str(), valueStr.c_str(), value->GetUnits().c_str() );
439
+ value->OnValueRefreshed( valueStr );
440
+ if( value->GetPrecision() != precision )
441
+ {
442
+ value->SetPrecision( precision );
443
+ }
444
+ value->Release();
445
+
446
+ // Read any previous value and time delta
447
+ uint8 size = _data[2] & 0x07;
448
+ uint16 delta = (uint16)( (_data[3+size]<<8) | _data[4+size]);
449
+
450
+ if( delta )
451
+ {
452
+ // There is only a previous value if the time delta is non-zero
453
+ ValueDecimal* previous = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex+1 ) );
454
+ if( NULL == previous )
455
+ {
456
+ // We need to create a value to hold the previous
457
+ if( Node* node = GetNodeUnsafe() )
458
+ {
459
+ node->CreateValueDecimal( ValueID::ValueGenre_User, GetCommandClassId(), _instance, baseIndex+1, "Previous Reading", value->GetUnits().c_str(), true, false, "0.0", 0 );
460
+ previous = static_cast<ValueDecimal*>( GetValue( _instance, baseIndex+1 ) );
461
+ }
462
+ }
463
+ if( previous )
464
+ {
465
+ precision = 0;
466
+ valueStr = ExtractValue( &_data[2], &scale, &precision, 3+size );
467
+ Log::Write( LogLevel_Info, GetNodeId(), " Previous value was %s%s, received %d seconds ago.", valueStr.c_str(), previous->GetUnits().c_str(), delta );
468
+ previous->OnValueRefreshed( valueStr );
469
+ if( previous->GetPrecision() != precision )
470
+ {
471
+ previous->SetPrecision( precision );
472
+ }
473
+ previous->Release();
474
+ }
475
+
476
+ // Time delta
477
+ ValueInt* interval = static_cast<ValueInt*>( GetValue( _instance, baseIndex+2 ) );
478
+ if( NULL == interval )
479
+ {
480
+ // We need to create a value to hold the time delta
481
+ if( Node* node = GetNodeUnsafe() )
482
+ {
483
+ node->CreateValueInt( ValueID::ValueGenre_User, GetCommandClassId(), _instance, baseIndex+2, "Interval", "seconds", true, false, 0, 0 );
484
+ interval = static_cast<ValueInt*>( GetValue( _instance, baseIndex+2 ) );
485
+ }
486
+ }
487
+ if( interval )
488
+ {
489
+ interval->OnValueRefreshed( (int32)delta );
490
+ interval->Release();
491
+ }
492
+ }
493
+ }
494
+ }
495
+
496
+ return true;
497
+ }
498
+
499
+ //-----------------------------------------------------------------------------
500
+ // <Meter::SetValue>
501
+ // Set the device's scale, or reset its accumulated values.
502
+ //-----------------------------------------------------------------------------
503
+ bool Meter::SetValue
504
+ (
505
+ Value const& _value
506
+ )
507
+ {
508
+ if( MeterIndex_Reset == _value.GetID().GetIndex() )
509
+ {
510
+ ValueButton const* button = static_cast<ValueButton const*>(&_value);
511
+ if( button->IsPressed() )
512
+ {
513
+ Msg* msg = new Msg( "MeterCmd_Reset", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true );
514
+ msg->SetInstance( this, _value.GetID().GetInstance() );
515
+ msg->Append( GetNodeId() );
516
+ msg->Append( 2 );
517
+ msg->Append( GetCommandClassId() );
518
+ msg->Append( MeterCmd_Reset );
519
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
520
+ GetDriver()->SendMsg( msg, Driver::MsgQueue_Send );
521
+ return true;
522
+ }
523
+ }
524
+
525
+ return false;
526
+ }
527
+
528
+ //-----------------------------------------------------------------------------
529
+ // <Meter::CreateVars>
530
+ // Create the values managed by this command class
531
+ //-----------------------------------------------------------------------------
532
+ void Meter::CreateVars
533
+ (
534
+ uint8 const _instance
535
+ )
536
+ {
537
+ if( Node* node = GetNodeUnsafe() )
538
+ {
539
+ node->CreateValueDecimal( ValueID::ValueGenre_User, GetCommandClassId(), _instance, 0, "Unknown", "", true, false, "0.0", 0 );
540
+ }
541
+ }