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,66 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // Lock.h
4
+ //
5
+ // Implementation of the Z-Wave COMMAND_CLASS_LOCK
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 _Lock_H
29
+ #define _Lock_H
30
+
31
+ #include "CommandClass.h"
32
+
33
+ namespace OpenZWave
34
+ {
35
+ class ValueBool;
36
+
37
+ /** \brief Implements COMMAND_CLASS_LOCK (0x76), a Z-Wave device command class.
38
+ */
39
+ class Lock: public CommandClass
40
+ {
41
+ public:
42
+ static CommandClass* Create( uint32 const _homeId, uint8 const _nodeId ){ return new Lock( _homeId, _nodeId ); }
43
+ virtual ~Lock(){}
44
+
45
+ static uint8 const StaticGetCommandClassId(){ return 0x76; }
46
+ static string const StaticGetCommandClassName(){ return "COMMAND_CLASS_LOCK"; }
47
+
48
+ // From CommandClass
49
+ virtual bool RequestState( uint32 const _requestFlags, uint8 const _instance, Driver::MsgQueue const _queue );
50
+ virtual bool RequestValue( uint32 const _requestFlags, uint8 const _index, uint8 const _instance, Driver::MsgQueue const _queue );
51
+ virtual uint8 const GetCommandClassId()const{ return StaticGetCommandClassId(); }
52
+ virtual string const GetCommandClassName()const{ return StaticGetCommandClassName(); }
53
+ virtual bool HandleMsg( uint8 const* _data, uint32 const _length, uint32 const _instance = 1 );
54
+ virtual bool SetValue( Value const& _value );
55
+
56
+ protected:
57
+ virtual void CreateVars( uint8 const _instance );
58
+
59
+ private:
60
+ Lock( uint32 const _homeId, uint8 const _nodeId ): CommandClass( _homeId, _nodeId ){}
61
+ };
62
+
63
+ } // namespace OpenZWave
64
+
65
+ #endif
66
+
@@ -0,0 +1,439 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // ManufacturerSpecific.cpp
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
+ #include "CommandClasses.h"
29
+ #include "ManufacturerSpecific.h"
30
+ #include "tinyxml.h"
31
+
32
+ #include "Defs.h"
33
+ #include "Msg.h"
34
+ #include "Node.h"
35
+ #include "Options.h"
36
+ #include "Manager.h"
37
+ #include "Driver.h"
38
+ #include "Notification.h"
39
+ #include "Log.h"
40
+
41
+ #include "ValueStore.h"
42
+ #include "ValueString.h"
43
+
44
+ using namespace OpenZWave;
45
+
46
+ enum ManufacturerSpecificCmd
47
+ {
48
+ ManufacturerSpecificCmd_Get = 0x04,
49
+ ManufacturerSpecificCmd_Report = 0x05
50
+ };
51
+
52
+ map<uint16,string> ManufacturerSpecific::s_manufacturerMap;
53
+ map<int64,ManufacturerSpecific::Product*> ManufacturerSpecific::s_productMap;
54
+ bool ManufacturerSpecific::s_bXmlLoaded = false;
55
+
56
+ //-----------------------------------------------------------------------------
57
+ // <ManufacturerSpecific::RequestState>
58
+ // Request current state from the device
59
+ //-----------------------------------------------------------------------------
60
+ bool ManufacturerSpecific::RequestState
61
+ (
62
+ uint32 const _requestFlags,
63
+ uint8 const _instance,
64
+ Driver::MsgQueue const _queue
65
+ )
66
+ {
67
+ if( ( _requestFlags & RequestFlag_Static ) && HasStaticRequest( StaticRequest_Values ) )
68
+ {
69
+ return RequestValue( _requestFlags, 0, _instance, _queue );
70
+ }
71
+
72
+ return false;
73
+ }
74
+
75
+ //-----------------------------------------------------------------------------
76
+ // <ManufacturerSpecific::RequestValue>
77
+ // Request current value from the device
78
+ //-----------------------------------------------------------------------------
79
+ bool ManufacturerSpecific::RequestValue
80
+ (
81
+ uint32 const _requestFlags,
82
+ uint8 const _dummy1, // = 0 (not used)
83
+ uint8 const _instance,
84
+ Driver::MsgQueue const _queue
85
+ )
86
+ {
87
+ if( _instance != 1 )
88
+ {
89
+ // This command class doesn't work with multiple instances
90
+ return false;
91
+ }
92
+
93
+ Msg* msg = new Msg( "ManufacturerSpecificCmd_Get", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true, true, FUNC_ID_APPLICATION_COMMAND_HANDLER, GetCommandClassId() );
94
+ msg->Append( GetNodeId() );
95
+ msg->Append( 2 );
96
+ msg->Append( GetCommandClassId() );
97
+ msg->Append( ManufacturerSpecificCmd_Get );
98
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
99
+ GetDriver()->SendMsg( msg, _queue );
100
+ return true;
101
+ }
102
+
103
+ string ManufacturerSpecific::SetProductDetails
104
+ (
105
+ Node* node,
106
+ uint16 manufacturerId,
107
+ uint16 productType,
108
+ uint16 productId
109
+ )
110
+ {
111
+ char str[64];
112
+
113
+ if (!s_bXmlLoaded) LoadProductXML();
114
+
115
+ snprintf( str, sizeof(str), "Unknown: id=%.4x", manufacturerId );
116
+ string manufacturerName = str;
117
+
118
+ snprintf( str, sizeof(str), "Unknown: type=%.4x, id=%.4x", productType, productId );
119
+ string productName = str;
120
+
121
+ string configPath = "";
122
+
123
+ // Try to get the real manufacturer and product names
124
+ map<uint16,string>::iterator mit = s_manufacturerMap.find( manufacturerId );
125
+ if( mit != s_manufacturerMap.end() )
126
+ {
127
+ // Replace the id with the real name
128
+ manufacturerName = mit->second;
129
+
130
+ // Get the product
131
+ map<int64,Product*>::iterator pit = s_productMap.find( Product::GetKey( manufacturerId, productType, productId ) );
132
+ if( pit != s_productMap.end() )
133
+ {
134
+ productName = pit->second->GetProductName();
135
+ configPath = pit->second->GetConfigPath();
136
+ }
137
+ }
138
+
139
+ // Set the values into the node
140
+
141
+ // Only set the manufacturer and product name if they are
142
+ // empty - we don't want to overwrite any user defined names.
143
+ if( node->GetManufacturerName() == "" )
144
+ {
145
+ node->SetManufacturerName( manufacturerName );
146
+ }
147
+
148
+ if( node->GetProductName() == "" )
149
+ {
150
+ node->SetProductName( productName );
151
+ }
152
+
153
+ snprintf( str, sizeof(str), "%.4x", manufacturerId );
154
+ node->SetManufacturerId( str );
155
+
156
+ snprintf( str, sizeof(str), "%.4x", productType );
157
+ node->SetProductType( str );
158
+
159
+ snprintf( str, sizeof(str), "%.4x", productId );
160
+ node->SetProductId( str );
161
+
162
+ return configPath;
163
+ }
164
+
165
+
166
+ //-----------------------------------------------------------------------------
167
+ // <ManufacturerSpecific::HandleMsg>
168
+ // Handle a message from the Z-Wave network
169
+ //-----------------------------------------------------------------------------
170
+ bool ManufacturerSpecific::HandleMsg
171
+ (
172
+ uint8 const* _data,
173
+ uint32 const _length,
174
+ uint32 const _instance // = 1
175
+ )
176
+ {
177
+ if( ManufacturerSpecificCmd_Report == (ManufacturerSpecificCmd)_data[0] )
178
+ {
179
+
180
+ // first two bytes are manufacturer id code
181
+ uint16 manufacturerId = (((uint16)_data[1])<<8) | (uint16)_data[2];
182
+
183
+ // next four are product type and product id
184
+ uint16 productType = (((uint16)_data[3])<<8) | (uint16)_data[4];
185
+ uint16 productId = (((uint16)_data[5])<<8) | (uint16)_data[6];
186
+
187
+ if( Node* node = GetNodeUnsafe() )
188
+ {
189
+ // Attempt to create the config parameters
190
+ string configPath = SetProductDetails( node, manufacturerId, productType, productId);
191
+ if( configPath.size() > 0 )
192
+ {
193
+ LoadConfigXML( node, configPath );
194
+ }
195
+
196
+ Log::Write( LogLevel_Info, GetNodeId(), "Received manufacturer specific report from node %d: Manufacturer=%s, Product=%s",
197
+ GetNodeId(), node->GetManufacturerName().c_str(), node->GetProductName().c_str() );
198
+ ClearStaticRequest( StaticRequest_Values );
199
+ node->m_manufacturerSpecificClassReceived = true;
200
+ }
201
+
202
+ // Notify the watchers of the name changes
203
+ Notification* notification = new Notification( Notification::Type_NodeNaming );
204
+ notification->SetHomeAndNodeIds( GetHomeId(), GetNodeId() );
205
+ GetDriver()->QueueNotification( notification );
206
+
207
+ return true;
208
+ }
209
+
210
+ return false;
211
+ }
212
+
213
+ //-----------------------------------------------------------------------------
214
+ // <ManufacturerSpecific::LoadProductXML>
215
+ // Load the XML that maps manufacturer and product IDs to human-readable names
216
+ //-----------------------------------------------------------------------------
217
+ bool ManufacturerSpecific::LoadProductXML
218
+ (
219
+ )
220
+ {
221
+ s_bXmlLoaded = true;
222
+
223
+ // Parse the Z-Wave manufacturer and product XML file.
224
+ string configPath;
225
+ Options::Get()->GetOptionAsString( "ConfigPath", &configPath );
226
+
227
+ string filename = configPath + "manufacturer_specific.xml";
228
+
229
+ TiXmlDocument* pDoc = new TiXmlDocument();
230
+ if( !pDoc->LoadFile( filename.c_str(), TIXML_ENCODING_UTF8 ) )
231
+ {
232
+ delete pDoc;
233
+ Log::Write( LogLevel_Info, "Unable to load %s", filename.c_str() );
234
+ return false;
235
+ }
236
+
237
+ TiXmlElement const* root = pDoc->RootElement();
238
+
239
+ char const* str;
240
+ char* pStopChar;
241
+
242
+ TiXmlElement const* manufacturerElement = root->FirstChildElement();
243
+ while( manufacturerElement )
244
+ {
245
+ str = manufacturerElement->Value();
246
+ if( str && !strcmp( str, "Manufacturer" ) )
247
+ {
248
+ // Read in the manufacturer attributes
249
+ str = manufacturerElement->Attribute( "id" );
250
+ if( !str )
251
+ {
252
+ Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing manufacturer id attribute", manufacturerElement->Row() );
253
+ delete pDoc;
254
+ return false;
255
+ }
256
+ uint16 manufacturerId = (uint16)strtol( str, &pStopChar, 16 );
257
+
258
+ str = manufacturerElement->Attribute( "name" );
259
+ if( !str )
260
+ {
261
+ Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing manufacturer name attribute", manufacturerElement->Row() );
262
+ delete pDoc;
263
+ return false;
264
+ }
265
+
266
+ // Add this manufacturer to the map
267
+ s_manufacturerMap[manufacturerId] = str;
268
+
269
+ // Parse all the products for this manufacturer
270
+ TiXmlElement const* productElement = manufacturerElement->FirstChildElement();
271
+ while( productElement )
272
+ {
273
+ str = productElement->Value();
274
+ if( str && !strcmp( str, "Product" ) )
275
+ {
276
+ str = productElement->Attribute( "type" );
277
+ if( !str )
278
+ {
279
+ Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product type attribute", productElement->Row() );
280
+ delete pDoc;
281
+ return false;
282
+ }
283
+ uint16 productType = (uint16)strtol( str, &pStopChar, 16 );
284
+
285
+ str = productElement->Attribute( "id" );
286
+ if( !str )
287
+ {
288
+ Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product id attribute", productElement->Row() );
289
+ delete pDoc;
290
+ return false;
291
+ }
292
+ uint16 productId = (uint16)strtol( str, &pStopChar, 16 );
293
+
294
+ str = productElement->Attribute( "name" );
295
+ if( !str )
296
+ {
297
+ Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product name attribute", productElement->Row() );
298
+ delete pDoc;
299
+ return false;
300
+ }
301
+ string productName = str;
302
+
303
+ // Optional config path
304
+ string configPath;
305
+ str = productElement->Attribute( "config" );
306
+ if( str )
307
+ {
308
+ configPath = str;
309
+ }
310
+
311
+ // Add the product to the map
312
+ Product* product = new Product( manufacturerId, productType, productId, productName, configPath );
313
+ if ( s_productMap[product->GetKey()] != NULL )
314
+ {
315
+ Product *c = s_productMap[product->GetKey()];
316
+ Log::Write( LogLevel_Info, "Product name collision: %s type %x id %x manufacturerid %x, collides with %s, type %x id %x manufacturerid %x", productName.c_str(), productType, productId, manufacturerId, c->GetProductName().c_str(), c->GetProductType(), c->GetProductId(), c->GetManufacturerId());
317
+ delete product;
318
+ }
319
+ else
320
+ {
321
+ s_productMap[product->GetKey()] = product;
322
+ }
323
+ }
324
+
325
+ // Move on to the next product.
326
+ productElement = productElement->NextSiblingElement();
327
+ }
328
+ }
329
+
330
+ // Move on to the next manufacturer.
331
+ manufacturerElement = manufacturerElement->NextSiblingElement();
332
+ }
333
+
334
+ delete pDoc;
335
+ return true;
336
+ }
337
+
338
+ //-----------------------------------------------------------------------------
339
+ // <ManufacturerSpecific::UnloadProductXML>
340
+ // Free the XML that maps manufacturer and product IDs
341
+ //-----------------------------------------------------------------------------
342
+ void ManufacturerSpecific::UnloadProductXML
343
+ (
344
+ )
345
+ {
346
+ if (s_bXmlLoaded)
347
+ {
348
+ map<int64,Product*>::iterator pit = s_productMap.begin();
349
+ while( !s_productMap.empty() )
350
+ {
351
+ delete pit->second;
352
+ s_productMap.erase( pit );
353
+ pit = s_productMap.begin();
354
+ }
355
+
356
+ map<uint16,string>::iterator mit = s_manufacturerMap.begin();
357
+ while( !s_manufacturerMap.empty() )
358
+ {
359
+ s_manufacturerMap.erase( mit );
360
+ mit = s_manufacturerMap.begin();
361
+ }
362
+
363
+ s_bXmlLoaded = false;
364
+ }
365
+ }
366
+
367
+ //-----------------------------------------------------------------------------
368
+ // <ManufacturerSpecific::LoadConfigXML>
369
+ // Try to find and load an XML file describing the device's config params
370
+ //-----------------------------------------------------------------------------
371
+ bool ManufacturerSpecific::LoadConfigXML
372
+ (
373
+ Node* _node,
374
+ string const& _configXML
375
+ )
376
+ {
377
+ string configPath;
378
+ Options::Get()->GetOptionAsString( "ConfigPath", &configPath );
379
+
380
+ string filename = configPath + _configXML;
381
+
382
+ TiXmlDocument* doc = new TiXmlDocument();
383
+ Log::Write( LogLevel_Info, _node->GetNodeId(), " Opening config param file %s", filename.c_str() );
384
+ if( !doc->LoadFile( filename.c_str(), TIXML_ENCODING_UTF8 ) )
385
+ {
386
+ delete doc;
387
+ Log::Write( LogLevel_Info, _node->GetNodeId(), "Unable to find or load Config Param file %s", filename.c_str() );
388
+ return false;
389
+ }
390
+
391
+ Node::QueryStage qs = _node->GetCurrentQueryStage();
392
+ if( qs == Node::QueryStage_ManufacturerSpecific1 )
393
+ {
394
+ _node->ReadDeviceProtocolXML( doc->RootElement() );
395
+ }
396
+ else
397
+ {
398
+ if( !_node->m_manufacturerSpecificClassReceived )
399
+ {
400
+ _node->ReadDeviceProtocolXML( doc->RootElement() );
401
+ }
402
+ _node->ReadCommandClassesXML( doc->RootElement() );
403
+ }
404
+
405
+ delete doc;
406
+ return true;
407
+ }
408
+
409
+ //-----------------------------------------------------------------------------
410
+ // <ManufacturerSpecific::ReLoadConfigXML>
411
+ // Reload previously discovered device configuration.
412
+ //-----------------------------------------------------------------------------
413
+ void ManufacturerSpecific::ReLoadConfigXML
414
+ (
415
+ )
416
+ {
417
+ if( Node* node = GetNodeUnsafe() )
418
+ {
419
+ if (!s_bXmlLoaded) LoadProductXML();
420
+
421
+ uint16 manufacturerId = (uint16)strtol( node->GetManufacturerId().c_str(), NULL, 16 );
422
+ uint16 productType = (uint16)strtol( node->GetProductType().c_str(), NULL, 16 );
423
+ uint16 productId = (uint16)strtol( node->GetProductId().c_str(), NULL, 16 );
424
+
425
+ map<uint16,string>::iterator mit = s_manufacturerMap.find( manufacturerId );
426
+ if( mit != s_manufacturerMap.end() )
427
+ {
428
+ map<int64,Product*>::iterator pit = s_productMap.find( Product::GetKey( manufacturerId, productType, productId ) );
429
+ if( pit != s_productMap.end() )
430
+ {
431
+ string configPath = pit->second->GetConfigPath();
432
+ if( configPath.size() > 0 )
433
+ {
434
+ LoadConfigXML( node, configPath );
435
+ }
436
+ }
437
+ }
438
+ }
439
+ }