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,227 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // Clock.cpp
4
+ //
5
+ // Implementation of the Z-Wave COMMAND_CLASS_CLOCK
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 "Clock.h"
30
+ #include "Defs.h"
31
+ #include "Msg.h"
32
+ #include "Node.h"
33
+ #include "Driver.h"
34
+ #include "Log.h"
35
+
36
+ #include "ValueByte.h"
37
+ #include "ValueList.h"
38
+
39
+ using namespace OpenZWave;
40
+
41
+ enum ClockCmd
42
+ {
43
+ ClockCmd_Set = 0x04,
44
+ ClockCmd_Get = 0x05,
45
+ ClockCmd_Report = 0x06
46
+ };
47
+
48
+ enum
49
+ {
50
+ ClockIndex_Day = 0,
51
+ ClockIndex_Hour,
52
+ ClockIndex_Minute
53
+ };
54
+
55
+ static char const* c_dayNames[] =
56
+ {
57
+ "Invalid",
58
+ "Monday",
59
+ "Tuesday",
60
+ "Wednesday",
61
+ "Thursday",
62
+ "Friday",
63
+ "Saturday",
64
+ "Sunday"
65
+ };
66
+
67
+ //-----------------------------------------------------------------------------
68
+ // <Clock::RequestState>
69
+ // Request current state from the device
70
+ //-----------------------------------------------------------------------------
71
+ bool Clock::RequestState
72
+ (
73
+ uint32 const _requestFlags,
74
+ uint8 const _instance,
75
+ Driver::MsgQueue const _queue
76
+ )
77
+ {
78
+ if( _requestFlags & RequestFlag_Dynamic )
79
+ {
80
+ return RequestValue( _requestFlags, 0, _instance, _queue );
81
+ }
82
+
83
+ return false;
84
+ }
85
+
86
+ //-----------------------------------------------------------------------------
87
+ // <Clock::RequestValue>
88
+ // Request current value from the device
89
+ //-----------------------------------------------------------------------------
90
+ bool Clock::RequestValue
91
+ (
92
+ uint32 const _requestFlags,
93
+ uint8 const _dummy1, // = 0 (not used)
94
+ uint8 const _instance,
95
+ Driver::MsgQueue const _queue
96
+ )
97
+ {
98
+ Msg* msg = new Msg( "ClockCmd_Get", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true, true, FUNC_ID_APPLICATION_COMMAND_HANDLER, GetCommandClassId() );
99
+ msg->SetInstance( this, _instance );
100
+ msg->Append( GetNodeId() );
101
+ msg->Append( 2 );
102
+ msg->Append( GetCommandClassId() );
103
+ msg->Append( ClockCmd_Get );
104
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
105
+ GetDriver()->SendMsg( msg, _queue );
106
+ return true;
107
+ }
108
+
109
+ //-----------------------------------------------------------------------------
110
+ // <Clock::HandleMsg>
111
+ // Handle a message from the Z-Wave network
112
+ //-----------------------------------------------------------------------------
113
+ bool Clock::HandleMsg
114
+ (
115
+ uint8 const* _data,
116
+ uint32 const _length,
117
+ uint32 const _instance // = 1
118
+ )
119
+ {
120
+ if (ClockCmd_Report == (ClockCmd)_data[0])
121
+ {
122
+ uint8 day = _data[1] >> 5;
123
+ uint8 hour = _data[1] & 0x1f;
124
+ uint8 minute = _data[2];
125
+
126
+ Log::Write( LogLevel_Info, GetNodeId(), "Received Clock report: %s %.2d:%.2d", c_dayNames[day], hour, minute );
127
+
128
+
129
+ if( ValueList* dayValue = static_cast<ValueList*>( GetValue( _instance, ClockIndex_Day ) ) )
130
+ {
131
+ dayValue->OnValueRefreshed( day );
132
+ dayValue->Release();
133
+ }
134
+ if( ValueByte* hourValue = static_cast<ValueByte*>( GetValue( _instance, ClockIndex_Hour ) ) )
135
+ {
136
+ hourValue->OnValueRefreshed( hour );
137
+ hourValue->Release();
138
+ }
139
+ if( ValueByte* minuteValue = static_cast<ValueByte*>( GetValue( _instance, ClockIndex_Minute ) ) )
140
+ {
141
+ minuteValue->OnValueRefreshed( minute );
142
+ minuteValue->Release();
143
+ }
144
+ return true;
145
+ }
146
+
147
+ return false;
148
+ }
149
+
150
+ //-----------------------------------------------------------------------------
151
+ // <Clock::SetValue>
152
+ // Set a value in the Z-Wave device
153
+ //-----------------------------------------------------------------------------
154
+ bool Clock::SetValue
155
+ (
156
+ Value const& _value
157
+ )
158
+ {
159
+ bool ret = false;
160
+
161
+ uint8 instance = _value.GetID().GetInstance();
162
+
163
+ ValueList* dayValue = static_cast<ValueList*>( GetValue( instance, ClockIndex_Day ) );
164
+ ValueByte* hourValue = static_cast<ValueByte*>( GetValue( instance, ClockIndex_Hour ) );
165
+ ValueByte* minuteValue = static_cast<ValueByte*>( GetValue( instance, ClockIndex_Minute ) );
166
+
167
+ if( dayValue && hourValue && minuteValue )
168
+ {
169
+ uint8 day = dayValue->GetItem().m_value;
170
+ uint8 hour = hourValue->GetValue();
171
+ uint8 minute = minuteValue->GetValue();
172
+
173
+ Msg* msg = new Msg( "ClockCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true );
174
+ msg->SetInstance( this, instance );
175
+ msg->Append( GetNodeId() );
176
+ msg->Append( 4 );
177
+ msg->Append( GetCommandClassId() );
178
+ msg->Append( ClockCmd_Set );
179
+ msg->Append( ( day << 5 ) | hour );
180
+ msg->Append( minute );
181
+ msg->Append( TRANSMIT_OPTION_ACK | TRANSMIT_OPTION_AUTO_ROUTE );
182
+ GetDriver()->SendMsg( msg, Driver::MsgQueue_Send );
183
+ ret = true;
184
+ }
185
+
186
+ if( dayValue != NULL )
187
+ {
188
+ dayValue->Release();
189
+ }
190
+ if( hourValue != NULL )
191
+ {
192
+ hourValue->Release();
193
+ }
194
+ if( minuteValue != NULL )
195
+ {
196
+ minuteValue->Release();
197
+ }
198
+ return ret;
199
+ }
200
+
201
+ //-----------------------------------------------------------------------------
202
+ // <Clock::CreateVars>
203
+ // Create the values managed by this command class
204
+ //-----------------------------------------------------------------------------
205
+ void Clock::CreateVars
206
+ (
207
+ uint8 const _instance
208
+ )
209
+ {
210
+ if( Node* node = GetNodeUnsafe() )
211
+ {
212
+ vector<ValueList::Item> items;
213
+ for( int i=1; i<=7; ++i )
214
+ {
215
+ ValueList::Item item;
216
+ item.m_label = c_dayNames[i];
217
+ item.m_value = i;
218
+ items.push_back( item );
219
+ }
220
+
221
+ node->CreateValueList( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ClockIndex_Day, "Day", "", false, false, 1, items, 0, 0 );
222
+ node->CreateValueByte( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ClockIndex_Hour, "Hour", "", false, false, 12, 0 );
223
+ node->CreateValueByte( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ClockIndex_Minute, "Minute", "", false, false, 0, 0 );
224
+ }
225
+ }
226
+
227
+
@@ -0,0 +1,67 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // Clock.h
4
+ //
5
+ // Implementation of the Z-Wave COMMAND_CLASS_CLOCK
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 _Clock_H
29
+ #define _Clock_H
30
+
31
+ #include "CommandClass.h"
32
+
33
+ namespace OpenZWave
34
+ {
35
+ class ValueByte;
36
+ class ValueList;
37
+
38
+ /** \brief Implements COMMAND_CLASS_CLOCK (0x81), a Z-Wave device command class.
39
+ */
40
+ class Clock: public CommandClass
41
+ {
42
+ public:
43
+ static CommandClass* Create( uint32 const _homeId, uint8 const _nodeId ){ return new Clock( _homeId, _nodeId ); }
44
+ virtual ~Clock(){}
45
+
46
+ static uint8 const StaticGetCommandClassId(){ return 0x81; }
47
+ static string const StaticGetCommandClassName(){ return "COMMAND_CLASS_CLOCK"; }
48
+
49
+ // From CommandClass
50
+ virtual bool RequestState( uint32 const _requestFlags, uint8 const _instance, Driver::MsgQueue const _queue );
51
+ virtual bool RequestValue( uint32 const _requestFlags, uint8 const _index, uint8 const _instance, Driver::MsgQueue const _queue );
52
+ virtual uint8 const GetCommandClassId()const{ return StaticGetCommandClassId(); }
53
+ virtual string const GetCommandClassName()const{ return StaticGetCommandClassName(); }
54
+ virtual bool HandleMsg( uint8 const* _data, uint32 const _length, uint32 const _instance = 1 );
55
+ virtual bool SetValue( Value const& _value );
56
+
57
+ protected:
58
+ virtual void CreateVars( uint8 const _instance );
59
+
60
+ private:
61
+ Clock( uint32 const _homeId, uint8 const _nodeId ): CommandClass( _homeId, _nodeId ){}
62
+ };
63
+
64
+ } // namespace OpenZWave
65
+
66
+ #endif
67
+
@@ -0,0 +1,546 @@
1
+ //-----------------------------------------------------------------------------
2
+ //
3
+ // CommandClass.cpp
4
+ //
5
+ // Base class for all Z-Wave Command Classes
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 <math.h>
29
+ #include <locale.h>
30
+ #include "tinyxml.h"
31
+ #include "CommandClass.h"
32
+ #include "MultiInstance.h"
33
+ #include "Msg.h"
34
+ #include "Node.h"
35
+ #include "Driver.h"
36
+ #include "Manager.h"
37
+ #include "Log.h"
38
+ #include "ValueStore.h"
39
+
40
+ using namespace OpenZWave;
41
+
42
+ static uint8 const c_sizeMask = 0x07;
43
+ static uint8 const c_scaleMask = 0x18;
44
+ static uint8 const c_scaleShift = 0x03;
45
+ static uint8 const c_precisionMask = 0xe0;
46
+ static uint8 const c_precisionShift = 0x05;
47
+
48
+
49
+ //-----------------------------------------------------------------------------
50
+ // <CommandClass::CommandClass>
51
+ // Constructor
52
+ //-----------------------------------------------------------------------------
53
+ CommandClass::CommandClass
54
+ (
55
+ uint32 const _homeId,
56
+ uint8 const _nodeId
57
+ ):
58
+ m_homeId( _homeId ),
59
+ m_nodeId( _nodeId ),
60
+ m_version( 1 ),
61
+ m_afterMark( false ),
62
+ m_createVars( true ),
63
+ m_overridePrecision( -1 ),
64
+ m_staticRequests( 0 )
65
+ {
66
+ }
67
+
68
+ //-----------------------------------------------------------------------------
69
+ // <CommandClass::GetDriver>
70
+ // Get a pointer to our driver
71
+ //-----------------------------------------------------------------------------
72
+ Driver* CommandClass::GetDriver
73
+ (
74
+ )const
75
+ {
76
+ return( Manager::Get()->GetDriver( m_homeId ) );
77
+ }
78
+
79
+ //-----------------------------------------------------------------------------
80
+ // <CommandClass::GetNode>
81
+ // Get a pointer to our node without locking the mutex
82
+ //-----------------------------------------------------------------------------
83
+ Node* CommandClass::GetNodeUnsafe
84
+ (
85
+ )const
86
+ {
87
+ return( GetDriver()->GetNodeUnsafe( m_nodeId ) );
88
+ }
89
+
90
+ //-----------------------------------------------------------------------------
91
+ // <CommandClass::GetValue>
92
+ // Get a pointer to a value by its instance and index
93
+ //-----------------------------------------------------------------------------
94
+ Value* CommandClass::GetValue
95
+ (
96
+ uint8 const _instance,
97
+ uint8 const _index
98
+ )
99
+ {
100
+ Value* value = NULL;
101
+ if( Node* node = GetNodeUnsafe() )
102
+ {
103
+ value = node->GetValue( GetCommandClassId(), _instance, _index );
104
+ }
105
+ return value;
106
+ }
107
+
108
+ //-----------------------------------------------------------------------------
109
+ // <CommandClass::SetInstances>
110
+ // Instances as set by the MultiInstance V1 command class
111
+ //-----------------------------------------------------------------------------
112
+ void CommandClass::SetInstances
113
+ (
114
+ uint8 const _instances
115
+ )
116
+ {
117
+ // Ensure we have a set of reported variables for each new instance
118
+ if( !m_afterMark )
119
+ {
120
+ for( uint8 i=0; i<_instances; ++i )
121
+ {
122
+ SetInstance( i+1 );
123
+ }
124
+ }
125
+ }
126
+
127
+ //-----------------------------------------------------------------------------
128
+ // <CommandClass::SetInstance>
129
+ // Instances as set by the MultiChannel (i.e. MultiInstance V2) command class
130
+ //-----------------------------------------------------------------------------
131
+ void CommandClass::SetInstance
132
+ (
133
+ uint8 const _endPoint
134
+ )
135
+ {
136
+ if( !m_instances.IsSet( _endPoint ) )
137
+ {
138
+ m_instances.Set( _endPoint );
139
+ if( IsCreateVars() )
140
+ {
141
+ CreateVars( _endPoint );
142
+ }
143
+ }
144
+ }
145
+
146
+ //-----------------------------------------------------------------------------
147
+ // <CommandClass::ReadXML>
148
+ // Read the saved command class data
149
+ //-----------------------------------------------------------------------------
150
+ void CommandClass::ReadXML
151
+ (
152
+ TiXmlElement const* _ccElement
153
+ )
154
+ {
155
+ int32 intVal;
156
+ char const* str;
157
+
158
+ if( TIXML_SUCCESS == _ccElement->QueryIntAttribute( "version", &intVal ) )
159
+ {
160
+ m_version = (uint8)intVal;
161
+ }
162
+
163
+ uint8 instances = 1;
164
+ if( TIXML_SUCCESS == _ccElement->QueryIntAttribute( "instances", &intVal ) )
165
+ {
166
+ instances = (uint8)intVal;
167
+ }
168
+
169
+ if( TIXML_SUCCESS == _ccElement->QueryIntAttribute( "request_flags", &intVal ) )
170
+ {
171
+ m_staticRequests = (uint8)intVal;
172
+ }
173
+
174
+ if( TIXML_SUCCESS == _ccElement->QueryIntAttribute( "override_precision", &intVal ) )
175
+ {
176
+ m_overridePrecision = (int8)intVal;
177
+ }
178
+
179
+ str = _ccElement->Attribute( "after_mark" );
180
+ if( str )
181
+ {
182
+ m_afterMark = !strcmp( str, "true" );
183
+ }
184
+
185
+ str = _ccElement->Attribute( "create_vars" );
186
+ if( str )
187
+ {
188
+ m_createVars = !strcmp( str, "true" );
189
+ }
190
+
191
+ // Setting the instance count will create all the values.
192
+ SetInstances( instances );
193
+
194
+ // Apply any differences from the saved XML to the values
195
+ TiXmlElement const* child = _ccElement->FirstChildElement();
196
+ while( child )
197
+ {
198
+ str = child->Value();
199
+ if( str )
200
+ {
201
+ if( !strcmp( str, "Instance" ) )
202
+ {
203
+ // Add an instance to the command class
204
+ if( TIXML_SUCCESS == child->QueryIntAttribute( "index", &intVal ) )
205
+ {
206
+ uint8 instance = (uint8)intVal;
207
+ SetInstance( instance );
208
+ }
209
+ }
210
+ else if( !strcmp( str, "Value" ) )
211
+ {
212
+ // Apply any differences from the saved XML to the value
213
+ GetNodeUnsafe()->ReadValueFromXML( GetCommandClassId(), child );
214
+ }
215
+ }
216
+
217
+ child = child->NextSiblingElement();
218
+ }
219
+ }
220
+
221
+ //-----------------------------------------------------------------------------
222
+ // <CommandClass::WriteXML>
223
+ // Save the static node configuration data
224
+ //-----------------------------------------------------------------------------
225
+ void CommandClass::WriteXML
226
+ (
227
+ TiXmlElement* _ccElement
228
+ )
229
+ {
230
+ char str[32];
231
+
232
+ snprintf( str, 32, "%d", GetCommandClassId() );
233
+ _ccElement->SetAttribute( "id", str );
234
+ _ccElement->SetAttribute( "name", GetCommandClassName().c_str() );
235
+
236
+ snprintf( str, 32, "%d", GetVersion() );
237
+ _ccElement->SetAttribute( "version", str );
238
+
239
+ if( m_staticRequests )
240
+ {
241
+ snprintf( str, 32, "%d", m_staticRequests );
242
+ _ccElement->SetAttribute( "request_flags", str );
243
+ }
244
+
245
+ if( m_overridePrecision >= 0 )
246
+ {
247
+ snprintf( str, 32, "%d", m_overridePrecision );
248
+ _ccElement->SetAttribute( "override_precision", str );
249
+ }
250
+
251
+ if( m_afterMark )
252
+ {
253
+ _ccElement->SetAttribute( "after_mark", "true" );
254
+ }
255
+
256
+ if( m_createVars )
257
+ {
258
+ _ccElement->SetAttribute( "create_vars", "true" );
259
+ }
260
+
261
+ // Write out the instances
262
+ for( Bitfield::Iterator it = m_instances.Begin(); it != m_instances.End(); ++ it )
263
+ {
264
+ TiXmlElement* instanceElement = new TiXmlElement( "Instance" );
265
+ _ccElement->LinkEndChild( instanceElement );
266
+
267
+ snprintf( str, 32, "%d", *it );
268
+ instanceElement->SetAttribute( "index", str );
269
+ }
270
+
271
+ // Write out the values for this command class
272
+ ValueStore* store = GetNodeUnsafe()->GetValueStore();
273
+ for( ValueStore::Iterator it = store->Begin(); it != store->End(); ++it )
274
+ {
275
+ Value* value = it->second;
276
+ if( value->GetID().GetCommandClassId() == GetCommandClassId() )
277
+ {
278
+ TiXmlElement* valueElement = new TiXmlElement( "Value" );
279
+ _ccElement->LinkEndChild( valueElement );
280
+ value->WriteXML( valueElement );
281
+ }
282
+ }
283
+ }
284
+
285
+ //-----------------------------------------------------------------------------
286
+ // <CommandClass::ExtractValue>
287
+ // Read a value from a variable length sequence of bytes
288
+ //-----------------------------------------------------------------------------
289
+ string CommandClass::ExtractValue
290
+ (
291
+ uint8 const* _data,
292
+ uint8* _scale,
293
+ uint8* _precision,
294
+ uint8 _valueOffset // = 1
295
+ )const
296
+ {
297
+ uint8 const size = _data[0] & c_sizeMask;
298
+ uint8 const precision = (_data[0] & c_precisionMask) >> c_precisionShift;
299
+
300
+ if( _scale )
301
+ {
302
+ *_scale = (_data[0] & c_scaleMask) >> c_scaleShift;
303
+ }
304
+
305
+ if( _precision )
306
+ {
307
+ *_precision = precision;
308
+ }
309
+
310
+ uint32 value = 0;
311
+ uint8 i;
312
+ for( i=0; i<size; ++i )
313
+ {
314
+ value <<= 8;
315
+ value |= (uint32)_data[i+(uint32)_valueOffset];
316
+ }
317
+
318
+ // Deal with sign extension. All values are signed
319
+ string res;
320
+ if( _data[_valueOffset] & 0x80 )
321
+ {
322
+ res = "-";
323
+
324
+ // MSB is signed
325
+ if( size == 1 )
326
+ {
327
+ value |= 0xffffff00;
328
+ }
329
+ else if( size == 2 )
330
+ {
331
+ value |= 0xffff0000;
332
+ }
333
+ }
334
+
335
+ // Convert the integer to a decimal string. We avoid
336
+ // using floats to prevent accuracy issues.
337
+ char numBuf[12];
338
+
339
+ if( precision == 0 )
340
+ {
341
+ // The precision is zero, so we can just print the number directly into the string.
342
+ snprintf( numBuf, 12, "%d", (signed long)value );
343
+ res = numBuf;
344
+ }
345
+ else
346
+ {
347
+ // We'll need to insert a decimal point and include any necessary leading zeros.
348
+
349
+ // Fill the buffer with the value padded with leading zeros.
350
+ snprintf( numBuf, 12, "%011d", (signed long)value );
351
+
352
+ // Calculate the position of the decimal point in the buffer
353
+ int32 decimal = 10-precision;
354
+
355
+ // Shift the characters to make space for the decimal point.
356
+ // We don't worry about overwriting any minus sign since that is
357
+ // already written into the res string. While we're shifting, we
358
+ // also look for the real starting position of the number so we
359
+ // can copy it into the res string later.
360
+ int32 start = -1;
361
+ for( int32 i=0; i<decimal; ++i )
362
+ {
363
+ numBuf[i] = numBuf[i+1];
364
+ if( ( start<0 ) && ( numBuf[i] != '0' ) )
365
+ {
366
+ start = i;
367
+ }
368
+ }
369
+ if( start<0 )
370
+ {
371
+ start = decimal-1;
372
+ }
373
+
374
+ // Insert the decimal point
375
+ struct lconv const* locale = localeconv();
376
+ numBuf[decimal] = *(locale->decimal_point);
377
+
378
+ // Copy the buffer into res
379
+ res += &numBuf[start];
380
+ }
381
+
382
+ return res;
383
+ }
384
+
385
+ //-----------------------------------------------------------------------------
386
+ // <CommandClass::AppendValue>
387
+ // Add a value to a message as a sequence of bytes
388
+ //-----------------------------------------------------------------------------
389
+ void CommandClass::AppendValue
390
+ (
391
+ Msg* _msg,
392
+ string const& _value,
393
+ uint8 const _scale
394
+ )const
395
+ {
396
+ uint8 precision;
397
+ uint8 size;
398
+ int32 val = ValueToInteger( _value, &precision, &size );
399
+
400
+ _msg->Append( (precision<<c_precisionShift) | (_scale<<c_scaleShift) | size );
401
+
402
+ int32 shift = (size-1)<<3;
403
+ for( int32 i=size; i>0; --i, shift-=8 )
404
+ {
405
+ _msg->Append( (uint8)(val >> shift) );
406
+ }
407
+ }
408
+
409
+ //-----------------------------------------------------------------------------
410
+ // <CommandClass::GetAppendValueSize>
411
+ // Get the number of bytes that would be added by a call to AppendValue
412
+ //-----------------------------------------------------------------------------
413
+ uint8 const CommandClass::GetAppendValueSize
414
+ (
415
+ string const& _value
416
+ )const
417
+ {
418
+ uint8 size;
419
+ ValueToInteger( _value, NULL, &size );
420
+ return size;
421
+ }
422
+
423
+ //-----------------------------------------------------------------------------
424
+ // <CommandClass::ValueToInteger>
425
+ // Convert a decimal string to an integer and report the precision and
426
+ // number of bytes required to store the value.
427
+ //-----------------------------------------------------------------------------
428
+ int32 CommandClass::ValueToInteger
429
+ (
430
+ string const& _value,
431
+ uint8* o_precision,
432
+ uint8* o_size
433
+ )const
434
+ {
435
+ int32 val;
436
+ uint8 precision;
437
+
438
+ // Find the decimal point
439
+ size_t pos = _value.find_first_of( "." );
440
+ if( pos == string::npos )
441
+ pos = _value.find_first_of( "," );
442
+
443
+ if( pos == string::npos )
444
+ {
445
+ // No decimal point
446
+ precision = 0;
447
+
448
+ // Convert the string to an integer
449
+ val = atol( _value.c_str() );
450
+ }
451
+ else
452
+ {
453
+ // Remove the decimal point and convert to an integer
454
+ precision = (_value.size()-pos)-1;
455
+
456
+ string str = _value.substr( 0, pos ) + _value.substr( pos+1 );
457
+ val = atol( str.c_str() );
458
+ }
459
+
460
+ if ( m_overridePrecision > 0 )
461
+ {
462
+ while ( precision < m_overridePrecision ) {
463
+ precision++;
464
+ val *= 10;
465
+ }
466
+ }
467
+
468
+ if ( o_precision ) *o_precision = precision;
469
+
470
+ if( o_size )
471
+ {
472
+ // Work out the size as either 1, 2 or 4 bytes
473
+ *o_size = 4;
474
+ if( val < 0 )
475
+ {
476
+ if( ( val & 0xffffff80 ) == 0xffffff80 )
477
+ {
478
+ *o_size = 1;
479
+ }
480
+ else if( ( val & 0xffff8000 ) == 0xffff8000 )
481
+ {
482
+ *o_size = 2;
483
+ }
484
+ }
485
+ else
486
+ {
487
+ if( ( val & 0xffffff00 ) == 0 )
488
+ {
489
+ *o_size = 1;
490
+ }
491
+ else if( ( val & 0xffff0000 ) == 0 )
492
+ {
493
+ *o_size = 2;
494
+ }
495
+ }
496
+ }
497
+
498
+ return val;
499
+ }
500
+
501
+ //-----------------------------------------------------------------------------
502
+ // <CommandClass::ClearStaticRequest>
503
+ // The static data for this command class has been read from the device
504
+ //-----------------------------------------------------------------------------
505
+ void CommandClass::ClearStaticRequest
506
+ (
507
+ uint8 _request
508
+ )
509
+ {
510
+ m_staticRequests &= ~_request;
511
+ }
512
+
513
+ //-----------------------------------------------------------------------------
514
+ // <CommandClass::RequestStateForAllInstances>
515
+ // Request current state from the device
516
+ //-----------------------------------------------------------------------------
517
+ bool CommandClass::RequestStateForAllInstances
518
+ (
519
+ uint32 const _requestFlags,
520
+ Driver::MsgQueue const _queue
521
+ )
522
+ {
523
+ bool res = false;
524
+ if( m_createVars )
525
+ {
526
+ if( Node* node = GetNodeUnsafe() )
527
+ {
528
+ MultiInstance* multiInstance = static_cast<MultiInstance*>( node->GetCommandClass( MultiInstance::StaticGetCommandClassId() ) );
529
+ if( multiInstance != NULL )
530
+ {
531
+ for( Bitfield::Iterator it = m_instances.Begin(); it != m_instances.End(); ++it )
532
+ {
533
+ res |= RequestState( _requestFlags, (uint8)*it, _queue );
534
+ }
535
+ }
536
+ else
537
+ {
538
+ res = RequestState( _requestFlags, 1, _queue );
539
+ }
540
+ }
541
+ }
542
+
543
+ return res;
544
+ }
545
+
546
+