Пример #1
0
void ZWaveBase::InsertDevice(_tZWaveDevice device)
{
	device.string_id=GenerateDeviceStringID(&device);

	bool bNewDevice=(m_devices.find(device.string_id)==m_devices.end());
	
	device.lastreceived=mytime(NULL);
#ifdef _DEBUG
	if (bNewDevice)
	{
		std::cout << "New device: " << device.string_id << std::endl;
	}
	else
	{
		std::cout << "Update device: " << device.string_id << std::endl;
	}
#endif
	//insert or update device in internal record
	device.sequence_number=1;
	m_devices[device.string_id]=device;

	SendSwitchIfNotExists(&device);
}
Пример #2
0
void CRazberry::UpdateDevice(const std::string &path, const Json::Value &obj)
{
	boost::lock_guard<boost::mutex> l(m_NotificationMutex);

	_tZWaveDevice *pDevice=NULL;

	if (
		(path.find("srcId")!=std::string::npos)||
		(path.find("sensorTime")!=std::string::npos)
		)
		return;

	if (path.find("instances.0.commandClasses.128.data.last")!=std::string::npos)
	{
		//COMMAND_CLASS_BATTERY
		if (obj["value"].empty()==false)
		{
			int batValue=obj["value"].asInt();
			std::vector<std::string> results;
			StringSplit(path,".",results);
			int devID=atoi(results[1].c_str());
			UpdateDeviceBatteryStatus(devID,batValue);
		}
	}
	else if (path.find("instances.0.commandClasses.49.data.")!=std::string::npos)
	{
		//COMMAND_CLASS_SENSOR_MULTILEVEL
		//Possible fix for Everspring ST814. maybe others, my multi sensor is coming soon to find out!
		std::vector<std::string> results;
		StringSplit(path,".",results);
		//Find device by data id
		if (results.size()==8)
		{
			int cmdID=atoi(results[5].c_str());
			if (cmdID==49)
			{
				int devID=atoi(results[1].c_str());
				int scaleID=atoi(results[7].c_str());
				pDevice=FindDeviceByScale(devID,scaleID,cmdID);
			}
		}
	}
	else if (path.find("instances.0.commandClasses.48.data.")!=std::string::npos)
	{
		//COMMAND_CLASS_SENSOR_BINARY
		//Possible fix for door sensors reporting on another instance number
		std::vector<std::string> results;
		StringSplit(path,".",results);
		//Find device by data id
		if (results.size()==8)
		{
			int cmdID=atoi(results[5].c_str());
			if (cmdID==48)
			{
				int devID=atoi(results[1].c_str());
				int instanceID=atoi(results[7].c_str());
				pDevice=FindDeviceInstance(devID,instanceID,cmdID);
			}
		}
	}
	else if (path.find("instances.0.commandClasses.64.data.")!=std::string::npos)
	{
		//COMMAND_CLASS_THERMOSTAT_MODE
		std::vector<std::string> results;
		StringSplit(path,".",results);
		//Find device by data id
		if (results.size()==8)
		{
			int cmdID=atoi(results[5].c_str());
			if (cmdID==64)
			{
				int devID=atoi(results[1].c_str());
				int instanceID=atoi(results[3].c_str());
				int indexID=0;
				pDevice=FindDevice(devID,instanceID,indexID, cmdID, ZDTYPE_SWITCH_NORMAL);
			}
		}
	}
	else if (path.find("commandClasses.43.data.currentScene")!=std::string::npos)
	{
		//COMMAND_CLASS_SCENE_ACTIVATION
		std::vector<std::string> results;
		StringSplit(path,".",results);
		//Find device by data id
		if (results.size()==8)
		{
			int cmdID=atoi(results[5].c_str());
			if (cmdID==43)
			{
				int iScene=obj["value"].asInt();
				int devID=(iScene<<8)+atoi(results[1].c_str());
				int instanceID=atoi(results[3].c_str());
				if (instanceID==0)
				{
					//only allow instance 0 for now
					int indexID = 0;
					pDevice = FindDevice(devID, instanceID, indexID, cmdID, ZDTYPE_SWITCH_NORMAL);
					if (pDevice==NULL)
					{
						//Add new switch device
						_tZWaveDevice _device;
						_device.nodeID=devID;
						_device.instanceID=instanceID;
						_device.indexID=indexID;

						_device.basicType =		1;
						_device.genericType =	1;
						_device.specificType =	1;
						_device.isListening =	false;
						_device.sensor250=		false;
						_device.sensor1000=		false;
						_device.isFLiRS =		!_device.isListening && (_device.sensor250 || _device.sensor1000);
						_device.hasWakeup =		false;
						_device.hasBattery =	false;
						_device.scaleID=-1;

						_device.commandClassID=cmdID;
						_device.devType= ZDTYPE_SWITCH_NORMAL;
						_device.intvalue=255;
						InsertDevice(_device);
						pDevice=FindDevice(devID,instanceID,indexID, cmdID, ZDTYPE_SWITCH_NORMAL);
					}
				}
			}
		}
	}
	if (pDevice==NULL)
	{
		std::map<std::string,_tZWaveDevice>::iterator itt;
		for (itt=m_devices.begin(); itt!=m_devices.end(); ++itt)
		{
			std::string::size_type loc = path.find(itt->second.string_id,0);
			if (loc!=std::string::npos)
			{
				pDevice=&itt->second;
				break;
			}
		}
	}

	if (pDevice==NULL)
	{
		//Special Case for Controller received light commands
		size_t iPos= path.find(".data.level");
		if (iPos==std::string::npos)
		{
			return;
		}
		std::string tmpStr;
		//create this device
		_tZWaveDevice _device;

		//Get device node ID
		size_t pPos=path.find(".");
		if (pPos==std::string::npos)
			return;
		tmpStr=path.substr(pPos+1);
		pPos=tmpStr.find(".");
		if (pPos==std::string::npos)
			return;
		std::string sNodeID=tmpStr.substr(0,pPos);
		_device.nodeID=atoi(sNodeID.c_str());

		//Find instance ID
		pPos=path.find("instances.");
		if (pPos==std::string::npos)
			return;
		tmpStr=path.substr(pPos+sizeof("instances.")-1);
		pPos=tmpStr.find(".");
		if (pPos==std::string::npos)
			return;
		std::string sInstanceID=tmpStr.substr(0,pPos);
		_device.instanceID=atoi(sInstanceID.c_str());
		_device.indexID=0;
		pPos=path.find("commandClasses.");
		if (pPos==std::string::npos)
			return;
		tmpStr=path.substr(pPos+sizeof("commandClasses.")-1);
		pPos=tmpStr.find(".");
		if (pPos==std::string::npos)
			return;
		std::string sClassID=tmpStr.substr(0,pPos);
		

		// Device status and battery
		_device.basicType =		1;
		_device.genericType =	1;
		_device.specificType =	1;
		_device.isListening =	false;
		_device.sensor250=		false;
		_device.sensor1000=		false;
		_device.isFLiRS =		!_device.isListening && (_device.sensor250 || _device.sensor1000);
		_device.hasWakeup =		false;
		_device.hasBattery =	false;
		_device.scaleID=-1;

		_device.commandClassID=atoi(sClassID.c_str());
		_device.devType= ZDTYPE_SWITCH_NORMAL;
		std::string vstring=obj["value"].asString();
		if (vstring=="true")
			_device.intvalue=255;
		else if (vstring=="false")
			_device.intvalue=0;
		else
			_device.intvalue=obj["value"].asInt();

		bool bFoundInstance=false;
		int oldinstance=_device.instanceID;
		for (int iInst=0; iInst<7; iInst++)
		{
			_device.instanceID=iInst;
			std:: string devicestring_id=GenerateDeviceStringID(&_device);
			std::map<std::string,_tZWaveDevice>::iterator iDevice=m_devices.find(devicestring_id);
			if (iDevice!=m_devices.end())
			{
				bFoundInstance=true;
				break;
			}
		}
		if (!bFoundInstance)
			_device.instanceID=oldinstance;

		InsertDevice(_device);

		//find device again
		std:: string devicestring_id=GenerateDeviceStringID(&_device);
		std::map<std::string,_tZWaveDevice>::iterator iDevice=m_devices.find(devicestring_id);
		if (iDevice==m_devices.end())
			return; //uhuh?
		pDevice=&iDevice->second;
	}

	time_t atime=mytime(NULL);
//	if (atime-pDevice->lastreceived<2)
	//	return; //to soon
#ifdef _DEBUG
	_log.Log(LOG_NORM, "Razberry: Update device: %s", pDevice->string_id.c_str());
#endif

	switch (pDevice->devType)
	{
	case ZDTYPE_SWITCH_NORMAL:
	case ZDTYPE_SWITCH_DIMMER:
		{
			//switch
			int intValue = 0;
			if (pDevice->commandClassID==64) //Thermostat Mode
			{
				int iValue=obj["value"].asInt();
				if (iValue==0)
					intValue = 0;
				else
					intValue = 255;
			}
			else if (pDevice->commandClassID==43) //Switch Scene
			{
				intValue = 255;
			}
			else
			{
				std::string vstring="";
				if (obj["value"].empty()==false)
					vstring=obj["value"].asString();
				else if (obj["level"].empty()==false)
				{
					if (obj["level"]["value"].empty()==false)
						vstring=obj["level"]["value"].asString();
				}

				if (vstring=="true")
					intValue = 255;
				else if (vstring=="false")
					intValue = 0;
				else
					intValue = atoi(vstring.c_str());
			}
			if (pDevice->intvalue == intValue)
			{
				//Don't send same value twice
				pDevice->lastreceived = atime;
				pDevice->sequence_number += 1;
				if (pDevice->sequence_number == 0)
					pDevice->sequence_number = 1;
				return;
			}
			pDevice->intvalue = intValue;
		}
		break;
	case ZDTYPE_SENSOR_POWER:
		//meters
		pDevice->floatValue=obj["val"]["value"].asFloat()*pDevice->scaleMultiply;
		break;
	case ZDTYPE_SENSOR_VOLTAGE:
		//Voltage
		pDevice->floatValue=obj["val"]["value"].asFloat()*pDevice->scaleMultiply;
		break;
	case ZDTYPE_SENSOR_AMPERE:
		//Ampere
		pDevice->floatValue=obj["val"]["value"].asFloat()*pDevice->scaleMultiply;
		break;
	case ZDTYPE_SENSOR_PERCENTAGE:
		//Ampere
		pDevice->floatValue=obj["val"]["value"].asFloat()*pDevice->scaleMultiply;
		break;
	case ZDTYPE_SENSOR_POWERENERGYMETER:
		pDevice->floatValue=obj["val"]["value"].asFloat()*pDevice->scaleMultiply;
		break;
	case ZDTYPE_SENSOR_TEMPERATURE:
		//meters
		pDevice->floatValue=obj["val"]["value"].asFloat();
		break;
	case ZDTYPE_SENSOR_HUMIDITY:
		//switch
		pDevice->intvalue=obj["val"]["value"].asInt();
		break;
	case ZDTYPE_SENSOR_LIGHT:
		//switch
		pDevice->floatValue=obj["val"]["value"].asFloat();
		break;
	case ZDTYPE_SENSOR_SETPOINT:
		//meters
		if (obj["val"]["value"].empty()==false)
		{
			pDevice->floatValue=obj["val"]["value"].asFloat();
		}
		else if (obj["value"].empty()==false)
		{
			pDevice->floatValue=obj["value"].asFloat();
		}
		break;
	}

	pDevice->lastreceived=atime;
	pDevice->sequence_number+=1;
	if (pDevice->sequence_number==0)
		pDevice->sequence_number=1;
	SendDevice2Domoticz(pDevice);
}