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); }
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); }