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