1 //-----------------------------------------------------------------------------
2 //
3 // CentralScene.cpp
4 //
5 // Implementation of the Z-Wave COMMAND_CLASS_CENTRAL_SCENE
6 //
7 // Copyright (c) 2012 Greg Satz <satz@iranger.com>
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 "command_classes/CommandClasses.h"
29 #include "command_classes/CentralScene.h"
30 #include "Defs.h"
31 #include "Msg.h"
32 #include "Node.h"
33 #include "Driver.h"
34 #include "platform/Log.h"
35 #include "value_classes/ValueInt.h"
36
37 #include "tinyxml.h"
38
39 using namespace OpenZWave;
40
41 enum CentralSceneCmd
42 {
43 CentralSceneCmd_Capability_Get = 0x01,
44 CentralSceneCmd_Capability_Report = 0x02,
45 CentralSceneCmd_Set = 0x03
46 };
47
48
49 enum CentralScene_ValueID_Index
50 {
51 CentralScene_Count = 0x00
52 };
53
54 //-----------------------------------------------------------------------------
55 // <CentralScene::CentralScene>
56 // Constructor
57 //-----------------------------------------------------------------------------
CentralScene(uint32 const _homeId,uint8 const _nodeId)58 CentralScene::CentralScene
59 (
60 uint32 const _homeId,
61 uint8 const _nodeId
62 ):
63 CommandClass( _homeId, _nodeId ),
64 m_scenecount(0)
65 {
66 Log::Write(LogLevel_Info, GetNodeId(), "CentralScene - Created %d", HasStaticRequest( StaticRequest_Values ));
67 }
68
69
70 //-----------------------------------------------------------------------------
71 // <CentralScene::RequestState>
72 // Request current state from the device
73 //-----------------------------------------------------------------------------
RequestState(uint32 const _requestFlags,uint8 const _instance,Driver::MsgQueue const _queue)74 bool CentralScene::RequestState
75 (
76 uint32 const _requestFlags,
77 uint8 const _instance,
78 Driver::MsgQueue const _queue
79 )
80 {
81 Log::Write(LogLevel_Info, GetNodeId(), "CentralScene RequestState: %d", _requestFlags);
82 bool requests = false;
83 if( ( _requestFlags & RequestFlag_AfterMark ))
84 {
85 requests = RequestValue( _requestFlags, CentralSceneCmd_Capability_Get, _instance, _queue );
86 } else {
87 Log::Write(LogLevel_Info, GetNodeId(), "CentralScene: Not a StaticRequest");
88 }
89 return requests;
90 }
91
92 //-----------------------------------------------------------------------------
93 // <CentralScene::RequestValue>
94 // Request current value from the device
95 //-----------------------------------------------------------------------------
RequestValue(uint32 const _requestFlags,uint8 const _what,uint8 const _instance,Driver::MsgQueue const _queue)96 bool CentralScene::RequestValue
97 (
98 uint32 const _requestFlags,
99 uint8 const _what,
100 uint8 const _instance,
101 Driver::MsgQueue const _queue
102 )
103 {
104 if (_what == CentralSceneCmd_Capability_Get) {
105 Msg* msg = new Msg( "CentralSceneCmd_Capability_Get", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true, true, FUNC_ID_APPLICATION_COMMAND_HANDLER, GetCommandClassId() );
106 msg->SetInstance( this, _instance );
107 msg->Append( GetNodeId() );
108 msg->Append( 2 );
109 msg->Append( GetCommandClassId() );
110 msg->Append( _what );
111 msg->Append( GetDriver()->GetTransmitOptions() );
112 GetDriver()->SendMsg( msg, _queue );
113 }
114 return true;
115 }
116 //-----------------------------------------------------------------------------
117 // <CentralScene::ReadXML>
118 // Class specific configuration
119 //-----------------------------------------------------------------------------
ReadXML(TiXmlElement const * _ccElement)120 void CentralScene::ReadXML
121 (
122 TiXmlElement const* _ccElement
123 )
124 {
125 int32 intVal;
126
127 CommandClass::ReadXML( _ccElement );
128 if( TIXML_SUCCESS == _ccElement->QueryIntAttribute( "scenecount", &intVal ) )
129 {
130 m_scenecount = intVal;
131 }
132 }
133
134 //-----------------------------------------------------------------------------
135 // <CentralScene::WriteXML>
136 // Class specific configuration
137 //-----------------------------------------------------------------------------
WriteXML(TiXmlElement * _ccElement)138 void CentralScene::WriteXML
139 (
140 TiXmlElement* _ccElement
141 )
142 {
143 char str[32];
144
145 CommandClass::WriteXML( _ccElement );
146 snprintf( str, sizeof(str), "%d", m_scenecount );
147 _ccElement->SetAttribute( "scenecount", str);
148 }
149
150
151 //-----------------------------------------------------------------------------
152 // <CentralScene::HandleMsg>
153 // Handle a message from the Z-Wave network
154 //-----------------------------------------------------------------------------
HandleMsg(uint8 const * _data,uint32 const _length,uint32 const _instance)155 bool CentralScene::HandleMsg
156 (
157 uint8 const* _data,
158 uint32 const _length,
159 uint32 const _instance // = 1
160 )
161 {
162 if( CentralSceneCmd_Set == (CentralSceneCmd)_data[0] )
163 {
164 // Central Scene Set received so send notification
165 int32 when;
166 if( _data[2] == 0 )
167 when = 0;
168 else if( _data[2] <= 0x7F )
169 when = _data[2];
170 else if( _data[2] <= 0xFE )
171 when = 60 * _data[2];
172 else
173 when = 0;
174 Log::Write( LogLevel_Info, GetNodeId(), "Received Central Scene set from node %d: scene id=%d in %d seconds. Sending event notification.", GetNodeId(), _data[3], when);
175
176 if( ValueInt* value = static_cast<ValueInt*>( GetValue( _instance, _data[3] ) ) )
177 {
178 value->OnValueRefreshed( when );
179 value->Release();
180 } else {
181 Log::Write( LogLevel_Warning, GetNodeId(), "No ValueID created for Scene %d", _data[3]);
182 return false;
183 }
184 return true;
185 } else if (CentralSceneCmd_Capability_Report == (CentralSceneCmd)_data[0]) {
186 /* Create a Number of ValueID's based on the m_scenecount variable
187 * We prefer what the Config File specifies rather than what is returned by
188 * the Device...
189 */
190 int scenecount = _data[1];
191 if (m_scenecount != 0)
192 m_scenecount = scenecount;
193
194 if ( ValueInt* value = static_cast<ValueInt*>( GetValue( _instance, CentralScene_Count)))
195 {
196 value->OnValueRefreshed(m_scenecount);
197 value->Release();
198 } else {
199 Log::Write( LogLevel_Warning, GetNodeId(), "Can't find ValueID for SceneCount");
200 }
201
202 if( Node* node = GetNodeUnsafe() )
203 {
204 char lbl[64];
205 for (int i = 1; i <= m_scenecount; i++) {
206 snprintf(lbl, 64, "Scene %d", i);
207 node->CreateValueInt(ValueID::ValueGenre_User, GetCommandClassId(), _instance, i, lbl, "", true, false, 0, 0 );
208 }
209
210 } else {
211 Log::Write(LogLevel_Info, GetNodeId(), "CentralScene: Can't find Node!");
212 }
213 }
214
215 return false;
216 }
217
218 //-----------------------------------------------------------------------------
219 // <CentralScene::CreateVars>
220 // Create the values managed by this command class
221 //-----------------------------------------------------------------------------
CreateVars(uint8 const _instance)222 void CentralScene::CreateVars
223 (
224 uint8 const _instance
225 )
226 {
227 if( Node* node = GetNodeUnsafe() )
228 {
229 node->CreateValueInt( ValueID::ValueGenre_System, GetCommandClassId(), _instance, CentralScene_Count, "Scene Count", "", true, false, 0, 0 );
230 }
231 }
232
233
234