コード例 #1
0
json_spirit::Object ZWaveController::GetValue(uint64 value_id){

	EnterCriticalSection(&g_criticalSection);

	json_spirit::Object rtn;

	bool found = false;
	for (list<NodeInfo*>::iterator it = g_nodes.begin(); it != g_nodes.end(); ++it)
	{
		NodeInfo* nodeInfo = *it;

		for (list<ValueID>::iterator it2 = nodeInfo->m_values.begin(); it2 != nodeInfo->m_values.end(); ++it2)
		{
			ValueID v = *it2;
			uint64 vid = v.GetId();

			if (vid == value_id && ZWaveController::ExposeValue(v)){
				rtn.push_back(json_spirit::Pair("value", ZWaveController::GetValueInfo(v)));
				found = true;
				break;
			}
		}

		if (found){
			break;
		}

	}

	LeaveCriticalSection(&g_criticalSection);

	return rtn;

}
コード例 #2
0
bool ZWaveController::RefreshValue(uint64 value_id, string &error_msg){

	EnterCriticalSection(&g_criticalSection);

	bool success = false;
	bool found = false;
	error_msg = "";

	for (list<NodeInfo*>::iterator it = g_nodes.begin(); it != g_nodes.end(); ++it)
	{
		NodeInfo* nodeInfo = *it;

		for (list<ValueID>::iterator it2 = nodeInfo->m_values.begin(); it2 != nodeInfo->m_values.end(); ++it2)
		{
			ValueID v = *it2;
			uint64 vid = v.GetId();
			int node_id = v.GetNodeId();
			if (vid == value_id){
				found = true;
				success = Manager::Get()->RefreshValue(v);
				if (!success){
					error_msg = "Call to ZWave library RefreshValue failed (returned false)";
				}
				break;
			}
		}
	}
	LeaveCriticalSection(&g_criticalSection);

	if (!found){
		error_msg = "Value id " + to_string(value_id) + " could not be found";
	}

	return success;
}
コード例 #3
0
json_spirit::Object ZWaveController::GetValueChangesSince(uint64 since_milliseconds, uint64 only_node_id){

	if (since_milliseconds < ZWaveController::expire_seconds){
		return ZWaveController::GetAllValues(only_node_id);
	}

	json_spirit::Object rtn;

	uint64 current_milliseconds = Utils::GetTimeMilliseconds();
	string s_current_milliseconds = boost::lexical_cast<string>(current_milliseconds);
	rtn.push_back(json_spirit::Pair("time", s_current_milliseconds));

	std::vector<json_spirit::Value> values;

	EnterCriticalSection(&g_criticalSection);

	for (std::vector<ValueChange>::iterator i = ValueChange::value_changes.begin(); i != ValueChange::value_changes.end(); ++i){
		ValueChange vc = *i;
		if (i->time_added >= since_milliseconds && i->time_added <= current_milliseconds - 1){
			for (list<NodeInfo*>::iterator it = g_nodes.begin(); it != g_nodes.end(); ++it)
			{
				NodeInfo* nodeInfo = *it;

				if (only_node_id != 0 && only_node_id != (uint64)nodeInfo->m_nodeId){
					continue;
				}


				for (list<ValueID>::iterator it2 = nodeInfo->m_values.begin(); it2 != nodeInfo->m_values.end(); ++it2)
				{
					ValueID v = *it2;
					uint64 vid = v.GetId();

					if (vid == vc.value_id && ZWaveController::ExposeValue(v)){
						values.push_back(ZWaveController::GetValueInfo(v));
					}
				}
			}
		}
	}

	LeaveCriticalSection(&g_criticalSection);

	rtn.push_back(json_spirit::Pair("values", values));

	return rtn;

}
コード例 #4
0
bool ZWaveController::SetValue(uint64 value_id, string new_value, string &error_msg){

	EnterCriticalSection(&g_criticalSection);

	bool success = false;
	bool found = false;
	error_msg = "";

	for (list<NodeInfo*>::iterator it = g_nodes.begin(); it != g_nodes.end(); ++it)
	{
		NodeInfo* nodeInfo = *it;

		for (list<ValueID>::iterator it2 = nodeInfo->m_values.begin(); it2 != nodeInfo->m_values.end(); ++it2)
		{
			ValueID v = *it2;
			uint64 vid = v.GetId();
			int node_id = v.GetNodeId();
			if (vid == value_id){

				found = true;

				// make sure it's not a read only prop
				if (Manager::Get()->IsValueReadOnly(v)){
					error_msg = "This is a read only property";
				}

				else {

					bool bool_new_value;
					uint8 int8_new_value;
					int16 int16_new_value;
					int32 int32_new_value;

					switch (v.GetType()){

					case ValueID::ValueType::ValueType_Bool:
						if (
							new_value == ""
							|| new_value == "0"
							|| boost::iequals(new_value, "false")
							|| boost::iequals(new_value, "off")
							|| boost::iequals(new_value, "no")
							){
							bool_new_value = false;
						}
						else {
							bool_new_value = true;
						}
						success = Manager::Get()->SetValue(v, bool_new_value);
						if (!success){
							error_msg = "Call to ZWave library SetValue failed";
						}
						break;

					case ValueID::ValueType::ValueType_Byte:
						try {
							int8_new_value = (uint8)(boost::lexical_cast<int>(new_value));
							success = Manager::Get()->SetValue(v, int8_new_value);
							if (!success){
								error_msg = "Call to ZWave library SetValue failed";
							}
						}
						catch (boost::bad_lexical_cast const&) {
							error_msg = "Type required is byte (number from 0 to 255); could not convert new_value to byte";
						}
						break;

					case ValueID::ValueType::ValueType_Short:
						try {
							int16_new_value = boost::lexical_cast<int16>(new_value);
							success = Manager::Get()->SetValue(v, int16_new_value);
							if (!success){
								error_msg = "Call to ZWave library SetValue failed";
							}
						}
						catch (boost::bad_lexical_cast const&) {
							error_msg = "Type required is short (number from 0 to 65,535); could not convert new_value to short";
						}
						break;

					case ValueID::ValueType::ValueType_Decimal:
					case ValueID::ValueType::ValueType_Int:
						try {
							int32_new_value = boost::lexical_cast<int32>(new_value);
							success = Manager::Get()->SetValue(v, int32_new_value);
							if (!success){
								error_msg = "Call to ZWave library SetValue failed";
							}
						}
						catch (boost::bad_lexical_cast const&) {
							error_msg = "Type required is int32 (number from 0 to 4,294,967,295); could not convert new_value to int32";
						}
						break;

					case ValueID::ValueType::ValueType_Schedule:
						error_msg = "No support for setting 'schedule' value types yet";
						break;

					case ValueID::ValueType::ValueType_List:
					case ValueID::ValueType::ValueType_String:
					case ValueID::ValueType::ValueType_Button:
					case ValueID::ValueType::ValueType_Raw:
						success = Manager::Get()->SetValue(v, new_value);
						if (!success){
							error_msg = "Call to ZWave library SetValue failed";
						}
						break;

					default:
						error_msg = "Value is an unknown type, could not set";

					}

				}

				break;
			}
		}

	}

	LeaveCriticalSection(&g_criticalSection);

	if (!found){
		error_msg = "Value id " + to_string(value_id) + " could not be found";
	}

	return success;
}
コード例 #5
0
// Callback that is triggered when a value, group or node changes
void ZWaveController::OnNotification(Notification const* _notification, void* _context){

	// Must do this inside a critical section to avoid conflicts with the main thread
	EnterCriticalSection(&g_criticalSection);

	switch (_notification->GetType())
	{
		case Notification::Type_ValueAdded:
		{
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{

				// Add the new value to our list
				nodeInfo->m_values.push_back(_notification->GetValueID());

				ValueID v = _notification->GetValueID();

				Logger::LogNotice("added value id " + to_string(v.GetId())  + " to node " + to_string(v.GetNodeId()) );

				if (!ZWaveController::init_failed && ZWaveController::initial_node_queries_complete){
					if (ZWaveController::ExposeValue(v)){
						uint64 vid = v.GetId();
						ValueChange::add_change(vid);
					}
				}

			}
			break;
		}

		case Notification::Type_ValueRemoved:
		{
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{
				// Remove the value from out list
				for (list<ValueID>::iterator it = nodeInfo->m_values.begin(); it != nodeInfo->m_values.end(); ++it)
				{

					if (!ZWaveController::init_failed && ZWaveController::initial_node_queries_complete){
						ValueID v = *it;
						uint64 vid = v.GetId();
						ValueChange::remove_change(vid);
					}

					if ((*it) == _notification->GetValueID())
					{
						nodeInfo->m_values.erase(it);
						break;
					}

				}
			}
			break;
		}

		case Notification::Type_ValueChanged:
		{
			// One of the node values has changed
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{

				if (!ZWaveController::init_failed && ZWaveController::initial_node_queries_complete){

					// the value that changed
					ValueID v = _notification->GetValueID();

					string new_val;
					Manager::Get()->GetValueAsString(v, &new_val);
					Logger::LogNotice("node " + to_string(v.GetNodeId()) + ", value " + to_string(v.GetId()) + " (" + Manager::Get()->GetValueLabel(v) + "), has been changed to " + new_val);

					ValueChange::remove_expired_value_changes();

					// first remove this value from the change queue if it's already in there
					if (ZWaveController::ExposeValue(v)){
						string new_value;
						Manager::Get()->GetValueAsString(v, &new_value);

						uint64 vid = v.GetId();
						ValueChange::remove_change(vid);
						ValueChange::add_change(vid);
					}
				}

			}
			break;
		}

		case Notification::Type_Group:
		{
			// One of the node's association groups has changed
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{
				nodeInfo = nodeInfo;		// placeholder for real action
			}
			break;
			}

		case Notification::Type_NodeAdded:
		{
			// Add the new node to our list
			NodeInfo* nodeInfo = new NodeInfo();

			nodeInfo->m_homeId = _notification->GetHomeId();
			nodeInfo->m_nodeId = _notification->GetNodeId();
			nodeInfo->m_polled = false;
			g_nodes.push_back(nodeInfo);

			Logger::LogNotice("node " + to_string(nodeInfo->m_nodeId) + " added");

			break;
		}

		case Notification::Type_NodeRemoved:
		{
			// Remove the node from our list
			uint32 const homeId = _notification->GetHomeId();
			uint8 const nodeId = _notification->GetNodeId();
			for (list<NodeInfo*>::iterator it = g_nodes.begin(); it != g_nodes.end(); ++it)
			{
				NodeInfo* nodeInfo = *it;
				if ((nodeInfo->m_homeId == homeId) && (nodeInfo->m_nodeId == nodeId))
				{
					g_nodes.erase(it);
					Logger::LogNotice("node " + to_string(nodeInfo->m_nodeId) + " removed");
					delete nodeInfo;
					break;
				}
			}
			break;
		}

		case Notification::Type_NodeEvent:
		{
			// We have received an event from the node, caused by a
			// basic_set or hail message.
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{
				if (nodeInfo->m_nodeId == 5 || nodeInfo->m_nodeId == 6){
					Logger::LogNotice("node event received from node id " + to_string(nodeInfo->m_nodeId));
				}
				else {
					Logger::LogNotice("node event received from node id " + to_string(nodeInfo->m_nodeId));
				}
			}
			break;
		}

		case Notification::Type_PollingDisabled:
		{
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{
				nodeInfo->m_polled = false;
			}
			break;
		}

		case Notification::Type_PollingEnabled:
		{
			if (NodeInfo* nodeInfo = GetNodeInfo(_notification))
			{
				nodeInfo->m_polled = true;
			}
			break;
		}

		case Notification::Type_DriverReady:
		{
			ZWaveController::homeId = _notification->GetHomeId();
			Logger::LogNotice("controller driver is ready");
			break;
		}

		case Notification::Type_DriverFailed:
		{
			ZWaveController::init_failed = true;
			Logger::LogNotice("controller initialization failed. make sure another program is not already controlling the controller");
			break;
		}

		case Notification::Type_AwakeNodesQueried:
		case Notification::Type_AllNodesQueried:
		case Notification::Type_AllNodesQueriedSomeDead:
		{
			ZWaveController::initial_node_queries_complete = true;
			Logger::LogNotice("all zwave node queries complete");
			break;
		}

		case Notification::Type_NodeQueriesComplete:
		{
			Logger::LogNotice("node " + to_string(_notification->GetNodeId()) + " queries complete");
			break;
		}

		case Notification::Type_DriverReset:
		case Notification::Type_NodeNaming:
		case Notification::Type_NodeProtocolInfo:
		default:
		{
//			Logger::LogNotice("node " + to_string(_notification->GetNodeId()) + "");
		}

	} // end of switch

	LeaveCriticalSection(&g_criticalSection);
}
コード例 #6
0
json_spirit::Object ZWaveController::GetValueInfo(ValueID v){

	int home_id = (int)v.GetHomeId();
	int node_id = (int)v.GetNodeId();

	string product_name = Manager::Get()->GetNodeProductName(home_id, node_id);
	string product_id = Manager::Get()->GetNodeProductId(home_id, node_id);
	string product_type = Manager::Get()->GetNodeProductType(home_id, node_id);
	string node_type = Manager::Get()->GetNodeType(home_id, node_id);

	json_spirit::Object prop_info;

	prop_info.push_back(json_spirit::Pair("node_id", node_id));

	prop_info.push_back(json_spirit::Pair("node_type", node_type));

	prop_info.push_back(json_spirit::Pair("product_name", product_name));

	prop_info.push_back(json_spirit::Pair("product_id", product_id));

	prop_info.push_back(json_spirit::Pair("product_type", product_type));
	
	uint64 vid = v.GetId();
	string s_vid = boost::lexical_cast<string>(vid);
	prop_info.push_back(json_spirit::Pair("value_id", s_vid));

	prop_info.push_back(json_spirit::Pair("label", Manager::Get()->GetValueLabel(v)));

	prop_info.push_back(json_spirit::Pair("help_text", Manager::Get()->GetValueHelp(v)));

	bool bool_prop_value;
	uint8 int8_prop_value;
	int32 int32_prop_value;
	string s_int32_prop_value;
	int16 int16_prop_value;
	string str_prop_value;

	switch (v.GetType()){
	case ValueID::ValueType::ValueType_Bool:
		prop_info.push_back(json_spirit::Pair("type", "bool"));
		prop_info.push_back(json_spirit::Pair("type_help", "0/1, true/false, on/off"));
		Manager::Get()->GetValueAsBool(v, &bool_prop_value);
		prop_info.push_back(json_spirit::Pair("value", bool_prop_value));
		break;
	case ValueID::ValueType::ValueType_Byte:
		prop_info.push_back(json_spirit::Pair("type", "byte"));
		prop_info.push_back(json_spirit::Pair("type_help", "number from 0 to 255"));
		Manager::Get()->GetValueAsByte(v, &int8_prop_value);
		prop_info.push_back(json_spirit::Pair("value", int8_prop_value));
		break;
	case ValueID::ValueType::ValueType_Short:
		prop_info.push_back(json_spirit::Pair("type", "short"));
		prop_info.push_back(json_spirit::Pair("type_help", "number from 0 to 65,535"));
		Manager::Get()->GetValueAsShort(v, &int16_prop_value);
		prop_info.push_back(json_spirit::Pair("value", int16_prop_value));
		break;
	case ValueID::ValueType::ValueType_Decimal:
	case ValueID::ValueType::ValueType_Int:
		prop_info.push_back(json_spirit::Pair("type", "int32"));
		prop_info.push_back(json_spirit::Pair("type_help", "number from 0 to 4,294,967,295"));
		Manager::Get()->GetValueAsInt(v, &int32_prop_value);

		// do all this checking below because of a bug in openzwave: https://code.google.com/p/open-zwave/issues/detail?id=382
		s_int32_prop_value = boost::lexical_cast<string>(int32_prop_value);
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		if (boost::iequals(s_int32_prop_value, str_prop_value)){
			// bug did not happen
			prop_info.push_back(json_spirit::Pair("value", int32_prop_value));
		}
		else {
			// bug DID happen
			prop_info.push_back(json_spirit::Pair("value", str_prop_value));
		}
		break;
	case ValueID::ValueType::ValueType_List:
	{
		prop_info.push_back(json_spirit::Pair("type", "list"));
		prop_info.push_back(json_spirit::Pair("type_help", "list"));
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		prop_info.push_back(json_spirit::Pair("value", str_prop_value));

		std::vector<string> list_options;
		Manager::Get()->GetValueListItems(v, &list_options);
		std::vector<json_spirit::Value> values;
		for (std::vector<string>::iterator i = list_options.begin(); i != list_options.end(); ++i){
			string opt = *i;
			values.push_back(opt);
		}
		prop_info.push_back(json_spirit::Pair("list_options", values));

		break;
	}
	case ValueID::ValueType::ValueType_Schedule:
		prop_info.push_back(json_spirit::Pair("type", "schedule"));
		prop_info.push_back(json_spirit::Pair("type_help", "schedule"));
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		prop_info.push_back(json_spirit::Pair("value", str_prop_value));
		break;
	case ValueID::ValueType::ValueType_String:
		prop_info.push_back(json_spirit::Pair("type", "string"));
		prop_info.push_back(json_spirit::Pair("type_help", "string"));
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		prop_info.push_back(json_spirit::Pair("value", str_prop_value));
		break;
	case ValueID::ValueType::ValueType_Button:
		prop_info.push_back(json_spirit::Pair("type", "button"));
		prop_info.push_back(json_spirit::Pair("type_help", "button (string)"));
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		prop_info.push_back(json_spirit::Pair("value", str_prop_value));
		break;
	case ValueID::ValueType::ValueType_Raw:
		prop_info.push_back(json_spirit::Pair("type", "raw"));
		prop_info.push_back(json_spirit::Pair("type_help", "raw (string)"));
		Manager::Get()->GetValueAsString(v, &str_prop_value);
		prop_info.push_back(json_spirit::Pair("value", str_prop_value));
		break;
	default:
		prop_info.push_back(json_spirit::Pair("type", "unknown"));
		prop_info.push_back(json_spirit::Pair("type_help", "unknown"));
		prop_info.push_back(json_spirit::Pair("value", ""));
		break;
	}

	Manager::Get()->GetValueAsString(v, &str_prop_value);
	prop_info.push_back(json_spirit::Pair("string value", str_prop_value));

	prop_info.push_back(json_spirit::Pair("max", Manager::Get()->GetValueMax(v)));

	prop_info.push_back(json_spirit::Pair("min", Manager::Get()->GetValueMin(v)));

	prop_info.push_back(json_spirit::Pair("units", Manager::Get()->GetValueUnits(v)));

	prop_info.push_back(json_spirit::Pair("is_polled", Manager::Get()->IsValuePolled(v)));

	prop_info.push_back(json_spirit::Pair("read_only", Manager::Get()->IsValueReadOnly(v)));

	prop_info.push_back(json_spirit::Pair("write_only", Manager::Get()->IsValueWriteOnly(v)));

	prop_info.push_back(json_spirit::Pair("has_been_set", Manager::Get()->IsValueSet(v)));

	switch (v.GetGenre()){
	case ValueID::ValueGenre::ValueGenre_Basic:
		prop_info.push_back(json_spirit::Pair("genre", "basic"));
		break;
	case ValueID::ValueGenre::ValueGenre_User:
		prop_info.push_back(json_spirit::Pair("genre", "user"));
		break;
	case ValueID::ValueGenre::ValueGenre_Config:
		prop_info.push_back(json_spirit::Pair("genre", "config"));
		break;
	case ValueID::ValueGenre::ValueGenre_System:
		prop_info.push_back(json_spirit::Pair("genre", "system"));
		break;
	case ValueID::ValueGenre::ValueGenre_Count:
		prop_info.push_back(json_spirit::Pair("genre", "count"));
		break;
	default:
		prop_info.push_back(json_spirit::Pair("genre", "unknown"));
		break;
	}

	return prop_info;

}