void Comm5TCP::ParseData(const unsigned char* data, const size_t len) { buffer.append((const char*)data, len); std::stringstream stream(buffer); std::string line; while (std::getline(stream, line, '\n')) { line = rtrim(line); if (startsWith(line, "211")) { std::vector<std::string> tokens = tokenize(line); if (tokens.size() < 2) break; unsigned int relaybitfield = ::strtol(tokens[1].c_str(), 0, 16); for (int i = 0; i < 16; ++i) { bool on = (relaybitfield & (1 << i)) != 0 ? true : false; SendSwitch(i + 1, 1, 255, on, 0, "Relay " + boost::lexical_cast<std::string>(i + 1)); } } else if (startsWith(line, "210") && (!startsWith(line, "210 OK"))) { processSensorData(line); } } // Trim consumed bytes. buffer.erase(0, buffer.length() - static_cast<unsigned int>(stream.rdbuf()->in_avail())); }
void KMTronicTCP::GetMeterDetails() { std::string sResult; std::stringstream szURL; if (m_Password.empty()) { szURL << "http://" << m_szIPAddress << ":" << m_usIPPort; } else { szURL << "http://" << m_Username << ":" << m_Password << "@" << m_szIPAddress << ":" << m_usIPPort; } szURL << "/relays.cgi"; if (!HTTPClient::GET(szURL.str(), sResult)) { _log.Log(LOG_ERROR, "KMTronic: Error connecting to: %s", m_szIPAddress.c_str()); return; } std::vector<std::string> results; StringSplit(sResult, "\r\n", results); if (results.size()<8) { _log.Log(LOG_ERROR, "KMTronic: Invalid data received"); return; } size_t ii,jj; std::string tmpstr; for (ii = 1; ii < results.size(); ii++) { tmpstr = results[ii]; if (tmpstr.find("Status:") != std::string::npos) { tmpstr = tmpstr.substr(strlen("Status:")); std::vector<std::string> results2; StringSplit(tmpstr, " ", results2); if (results2.size() < 2) { _log.Log(LOG_ERROR, "KMTronic: Invalid data received"); return; } for (jj = 0; jj < results2.size(); jj++) { bool bIsOn = (results2[jj] != "0"); std::stringstream sstr; int iRelay = (jj + 1); sstr << "Relay " << iRelay; SendSwitch(iRelay, 1, 255, bIsOn, (bIsOn) ? 100 : 0, sstr.str()); if (iRelay > m_TotRelais) m_TotRelais = iRelay; } return; } } _log.Log(LOG_ERROR, "KMTronic: Invalid data received"); }
void Comm5TCP::processSensorData(const std::string& line) { std::vector<std::string> tokens = tokenize(line); if (tokens.size() < 2) return; unsigned int sensorbitfield = ::strtol(tokens[1].c_str(), 0, 16); for (int i = 0; i < 16; ++i) { bool on = (sensorbitfield & (1 << i)) != 0 ? true : false; if ((lastKnownSensorState & (1 << i) ^ (sensorbitfield & (1 << i))) || initSensorData) { SendSwitch((i + 1) << 8, 1, 255, on, 0, "Sensor " + boost::lexical_cast<std::string>(i + 1)); } } lastKnownSensorState = sensorbitfield; initSensorData = false; }
void CDomoticzHardwareBase::SendSwitchIfNotExists(const int NodeID, const int ChildID, const int BatteryLevel, const bool bOn, const double Level, const std::string &defaultname) { //make device ID unsigned char ID1 = (unsigned char)((NodeID & 0xFF000000) >> 24); unsigned char ID2 = (unsigned char)((NodeID & 0xFF0000) >> 16); unsigned char ID3 = (unsigned char)((NodeID & 0xFF00) >> 8); unsigned char ID4 = (unsigned char)NodeID & 0xFF; char szIdx[10]; sprintf(szIdx, "%X%02X%02X%02X", ID1, ID2, ID3, ID4); std::vector<std::vector<std::string> > result; result = m_sql.safe_query("SELECT Name,nValue,sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Unit == %d) AND (Type==%d) AND (Subtype==%d)", m_HwdID, szIdx, ChildID, int(pTypeLighting2), int(sTypeAC)); if (result.size() < 1) { SendSwitch(NodeID, ChildID, BatteryLevel, bOn, Level, defaultname); } }
int CJabloDongle::SendSwitchIfNotExists(const int NodeID, const int ChildID, const int BatteryLevel, const bool bOn, const double Level, const std::string &defaultname) { //make device ID unsigned char ID1 = (unsigned char)((NodeID & 0xFF000000) >> 24); unsigned char ID2 = (unsigned char)((NodeID & 0xFF0000) >> 16); unsigned char ID3 = (unsigned char)((NodeID & 0xFF00) >> 8); unsigned char ID4 = (unsigned char)NodeID & 0xFF; char szIdx[10]; sprintf(szIdx, "%X%02X%02X%02X", ID1, ID2, ID3, ID4); std::stringstream szQuery; std::vector<std::vector<std::string> > result; szQuery << "SELECT Name,nValue,sValue FROM DeviceStatus WHERE (HardwareID==" << m_HwdID << ") AND (DeviceID=='" << szIdx << "') AND (Unit == " << ChildID << ") AND (Type==" << int(pTypeLighting2) << ") AND (Subtype==" << int(sTypeAC) << ")"; result = m_sql.query(szQuery.str()); //-V519 if (result.size() < 1) { SendSwitch(NodeID, ChildID, BatteryLevel, bOn, Level, defaultname); return 0; } return 1; }
void CThermosmart::GetMeterDetails() { if (m_UserName.empty() || m_Password.empty() ) return; std::string sResult; #ifdef DEBUG_ThermosmartThermostat_read sResult = ReadFile("E:\\thermosmart_getdata.txt"); #else if (m_bDoLogin) { if (!Login()) return; } std::string sURL = THERMOSMART_ACCESS_PATH; stdreplace(sURL, "[TID]", m_ThermostatID); stdreplace(sURL, "[access_token]", m_AccessToken); if (!HTTPClient::GET(sURL, sResult)) { _log.Log(LOG_ERROR, "Thermosmart: Error getting thermostat data!"); m_bDoLogin = true; return; } #ifdef DEBUG_ThermosmartThermostat SaveString2Disk(sResult, "E:\\thermosmart_getdata.txt"); #endif #endif Json::Value root; Json::Reader jReader; bool ret = jReader.parse(sResult, root); if (!ret) { _log.Log(LOG_ERROR, "Thermosmart: Invalid/no data received..."); m_bDoLogin = true; return; } if (root["target_temperature"].empty() || root["room_temperature"].empty()) { _log.Log(LOG_ERROR, "Thermosmart: Invalid/no data received..."); m_bDoLogin = true; return; } float temperature; temperature = (float)root["target_temperature"].asFloat(); SendSetPointSensor(1, temperature, "target temperature"); temperature = (float)root["room_temperature"].asFloat(); SendTempSensor(2, 255, temperature, "room temperature"); if (!root["outside_temperature"].empty()) { temperature = (float)root["outside_temperature"].asFloat(); SendTempSensor(3, 255, temperature, "outside temperature"); } if (!root["source"].empty()) { std::string actSource = root["source"].asString(); bool bPauzeOn = (actSource == "pause"); SendSwitch(1, 1, 255, bPauzeOn, 0, "Thermostat Pause"); } }
bool Xbox360Peripheral::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest intf; IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; /* * Xbox One controller init packets. * The Rock Candy Xbox One controller requires more than just 0x05 * Minimum required packets unknown. */ UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 }; UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 }; if (!super::start(provider)) return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if(device->GetNumConfigurations()<1) { device=NULL; IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd=device->GetFullConfigurationDescriptor(0); if(cd==NULL) { device=NULL; IOLog("start - couldn't get configuration descriptor\n"); goto fail; } // Open if(!device->open(this)) { device=NULL; IOLog("start - unable to open device\n"); goto fail; } if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) { IOLog("start - unable to set configuration\n"); goto fail; } // Get release { UInt16 release = device->GetDeviceRelease(); switch (release) { default: IOLog("Unknown device release %.4x\n", release); // fall through case 0x0110: chatpadInit[0] = 0x01; chatpadInit[1] = 0x02; break; case 0x0114: chatpadInit[0] = 0x09; chatpadInit[1] = 0x00; break; } } // Find correct interface controllerType = Xbox360; intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=93; intf.bInterfaceProtocol=1; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox original intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=66; intf.bInterfaceProtocol=0; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox One intf.bInterfaceClass=255; intf.bInterfaceSubClass=71; intf.bInterfaceProtocol=208; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL, &intf); if(interface==NULL) { IOLog("start - unable to find the interface\n"); goto fail; } controllerType = XboxOne; goto interfacefound; } controllerType = XboxOriginal; goto interfacefound; } interfacefound: interface->open(this); // Find pipes pipe.direction=kUSBIn; pipe.interval=0; pipe.type=kUSBInterrupt; pipe.maxPacketSize=0; inPipe=interface->FindNextPipe(NULL,&pipe); if(inPipe==NULL) { IOLog("start - unable to find in pipe\n"); goto fail; } inPipe->retain(); pipe.direction=kUSBOut; outPipe=interface->FindNextPipe(NULL,&pipe); if(outPipe==NULL) { IOLog("start - unable to find out pipe\n"); goto fail; } outPipe->retain(); // Get a buffer inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } // Find chatpad interface intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass = 93; intf.bInterfaceProtocol = 2; intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; serialIn = device->FindNextInterface(NULL, &intf); if (serialIn == NULL) { IOLog("start - unable to find chatpad interface\n"); goto nochat; } serialIn->open(this); // Find chatpad pipe pipe.direction = kUSBIn; pipe.interval = 0; pipe.type = kUSBInterrupt; pipe.maxPacketSize = 0; serialInPipe = serialIn->FindNextPipe(NULL, &pipe); if (serialInPipe == NULL) { IOLog("start - unable to find chatpad in pipe\n"); goto fail; } serialInPipe->retain(); // Get a buffer for the chatpad serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); if (serialInBuffer == NULL) { IOLog("start - failed to allocate input buffer for chatpad\n"); goto fail; } // Create timer for chatpad serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } // Configure ChatPad // Send 'configuration' SendInit(0xa30c, 0x4423); SendInit(0x2344, 0x7f03); SendInit(0x5839, 0x6832); // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) { // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX //goto fail; } // Begin toggle serialHeard = false; serialActive = false; serialToggle = false; serialResetCount = 0; serialTimerState = tsToggle; serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) goto fail; if (controllerType == XboxOne) { QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst)); QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond)); QueueWrite(&xoneInitThird, sizeof(xoneInitThird)); QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth)); } else { // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); } // Done PadConnect(); registerService(); return true; fail: ReleaseAll(); return false; }
void KMTronicSerial::GetRelayStates() { unsigned char SendBuf[3]; int ii; m_TotRelais = 0; //First check if we are the USB 4/8 version SendBuf[0] = 0xFF; SendBuf[1] = 0x09; SendBuf[2] = 0x00; //Check if we have the 485 boards (max 6) bool bIs485 = false; for (int iBoard = 0; iBoard < 6; iBoard++) { SendBuf[1] = 0xA1 + iBoard; if (WriteInt(SendBuf, 3, true)) { bIs485 = true; if (m_buffer[1] == 0xA1 + iBoard) { m_bufferpos -= 2; if (m_bufferpos > Max_KMTronic_Relais) m_bufferpos = Max_KMTronic_Relais; for (ii = 0; ii < 8; ii++) { bool bIsOn = (m_buffer[2 + ii] == 1); if (m_bRelaisStatus[ii] != bIsOn) { m_bRelaisStatus[ii] = bIsOn; } std::stringstream sstr; int iRelay = (iBoard * 8) + ii + 1; sstr << "Board" << int(iBoard + 1) << " - " << int(ii + 1); SendSwitch(iRelay, 1, 255, bIsOn, (bIsOn) ? 100 : 0, sstr.str()); _log.Log(LOG_STATUS, "KMTronic: %s = %s", sstr.str().c_str(), (bIsOn) ? "On" : "Off"); if (iRelay > m_TotRelais) m_TotRelais = iRelay; } } } } if (bIs485) { //It could be that maybe one of the boards is turned off for various reasons, //for this, we assume we have all 6 boards available m_TotRelais = 48; return; } //Check if we are the USB 4/8 version SendBuf[0] = 0xFF; SendBuf[1] = 0x09; SendBuf[2] = 0x00; if (WriteInt(SendBuf, 3, true)) { if (m_bufferpos > Max_KMTronic_Relais) m_bufferpos = Max_KMTronic_Relais; m_TotRelais = m_bufferpos; for (ii = 0; ii < m_TotRelais; ii++) { bool bIsOn = (m_buffer[ii] == 1); if (m_bRelaisStatus[ii] != bIsOn) { m_bRelaisStatus[ii] = bIsOn; } std::stringstream sstr; int iRelay = (ii + 1); sstr << "Relay " << iRelay; SendSwitch(iRelay, 1, 255, bIsOn, (bIsOn) ? 100 : 0, sstr.str()); _log.Log(LOG_STATUS, "KMTronic: %s = %s", sstr.str().c_str(), (bIsOn) ? "On" : "Off"); if (iRelay > m_TotRelais) m_TotRelais = iRelay; } return; } //Check if we can get status of the 1/2 board SendBuf[0] = 0xFF; SendBuf[2] = 0x03; for (ii = 0; ii < Max_KMTronic_Relais; ii++) { SendBuf[1] = ii+1; if (WriteInt(SendBuf, 3,true)) { if (m_bufferpos == 3) { if (m_buffer[1] == (ii + 1)) { bool bIsOn = (m_buffer[2] == 1); if (m_bRelaisStatus[ii] != bIsOn) { m_bRelaisStatus[ii] = bIsOn; } std::stringstream sstr; int iRelay = ii + 1; sstr << "Relay " << iRelay; SendSwitch(iRelay, 1, 255, bIsOn, (bIsOn) ? 100 : 0, sstr.str()); _log.Log(LOG_STATUS, "KMTronic: %s = %s", sstr.str().c_str(), (bIsOn) ? "On" : "Off"); if (iRelay > m_TotRelais) m_TotRelais = iRelay; } } else { _log.Log(LOG_ERROR, "KMTronic: Invalid data received!"); } } } }
void CNest::GetMeterDetails() { std::string sResult; #ifdef DEBUG_NextThermostatR sResult = ReadFile("E:\\nest.json"); #else if (m_UserName.size()==0) return; if (m_Password.size()==0) return; if (m_bDoLogin) { if (!Login()) return; } std::vector<std::string> ExtraHeaders; ExtraHeaders.push_back("user-agent:Nest/1.1.0.10 CFNetwork/548.0.4"); ExtraHeaders.push_back("Authorization:Basic " + m_AccessToken); ExtraHeaders.push_back("X-nl-user-id:" + m_UserID); ExtraHeaders.push_back("X-nl-protocol-version:1"); //Get Data std::string sURL = m_TransportURL + NEST_GET_STATUS + m_UserID; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "Nest: Error getting current state!"); m_bDoLogin = true; return; } #endif #ifdef DEBUG_NextThermostatW SaveString2Disk(sResult, "E:\\nest.json"); #endif Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "Nest: Invalid data received!"); m_bDoLogin = true; return; } bool bHaveShared = !root["shared"].empty(); bool bHaveTopaz = !root["topaz"].empty(); if ((!bHaveShared) && (!bHaveTopaz)) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } //Protect if (bHaveTopaz) { if (root["topaz"].size() < 1) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } Json::Value::Members members = root["topaz"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } int SwitchIndex = 1; for (Json::Value::iterator itDevice = root["topaz"].begin(); itDevice != root["topaz"].end(); ++itDevice) { Json::Value device = *itDevice; std::string devstring = itDevice.key().asString(); if (device["where_id"].empty()) continue; std::string whereid = device["where_id"].asString(); //lookup name std::string devName = devstring; if (!root["where"].empty()) { for (Json::Value::iterator itWhere = root["where"].begin(); itWhere != root["where"].end(); ++itWhere) { Json::Value iwhere = *itWhere; if (!iwhere["wheres"].empty()) { for (Json::Value::iterator itWhereNest = iwhere["wheres"].begin(); itWhereNest != iwhere["wheres"].end(); ++itWhereNest) { Json::Value iwhereItt = *itWhereNest; if (!iwhereItt["where_id"].empty()) { std::string tmpWhereid = iwhereItt["where_id"].asString(); if (tmpWhereid == whereid) { devName = iwhereItt["name"].asString(); break; } } } } } } bool bIAlarm = false; bool bBool; if (!device["component_speaker_test_passed"].empty()) { bBool = device["component_speaker_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_smoke_test_passed"].empty()) { bBool = device["component_smoke_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_heat_test_passed"].empty()) { bBool = device["component_heat_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_buzzer_test_passed"].empty()) { bBool = device["component_buzzer_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_us_test_passed"].empty()) { bBool = device["component_us_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_temp_test_passed"].empty()) { bBool = device["component_temp_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_wifi_test_passed"].empty()) { bBool = device["component_wifi_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_als_test_passed"].empty()) { bBool = device["component_als_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_co_test_passed"].empty()) { bBool = device["component_co_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_hum_test_passed"].empty()) { bBool = device["component_hum_test_passed"].asBool(); if (!bBool) bIAlarm = true; } UpdateSmokeSensor(SwitchIndex, bIAlarm, devName); SwitchIndex++; } } //Thermostat if (!bHaveShared) return; if (root["shared"].size()<1) { if (bHaveTopaz) return; _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } size_t iThermostat = 0; for (Json::Value::iterator ittStructure = root["structure"].begin(); ittStructure != root["structure"].end(); ++ittStructure) { Json::Value nstructure = *ittStructure; if (!nstructure.isObject()) continue; std::string StructureID = ittStructure.key().asString(); std::string StructureName = nstructure["name"].asString(); for (Json::Value::iterator ittDevice = nstructure["devices"].begin(); ittDevice != nstructure["devices"].end(); ++ittDevice) { std::string devID = (*ittDevice).asString(); if (devID.find("device.")==std::string::npos) continue; std::string Serial = devID.substr(7); if (root["device"].empty()) continue; if (root["device"][Serial].empty()) continue; //not found !? if (root["shared"][Serial].empty()) continue; //Nothing shared? Json::Value ndevice = root["device"][Serial]; if (!ndevice.isObject()) continue; std::string Name = "Thermostat"; if (!ndevice["where_id"].empty()) { //Lookup our 'where' (for the Name of the thermostat) std::string where_id = ndevice["where_id"].asString(); if (!root["where"].empty()) { if (!root["where"][StructureID].empty()) { for (Json::Value::iterator ittWheres = root["where"][StructureID]["wheres"].begin(); ittWheres != root["where"][StructureID]["wheres"].end(); ++ittWheres) { Json::Value nwheres = *ittWheres; if (nwheres["where_id"] == where_id) { Name = StructureName + " " + nwheres["name"].asString(); break; } } } } } _tNestThemostat ntherm; ntherm.Serial = Serial; ntherm.StructureID = StructureID; ntherm.Name = Name; m_thermostats[iThermostat] = ntherm; Json::Value nshared = root["shared"][Serial]; //Setpoint if (!nshared["target_temperature"].empty()) { float currentSetpoint = nshared["target_temperature"].asFloat(); SendSetPointSensor((const unsigned char)(iThermostat * 3) + 1, currentSetpoint, Name + " Setpoint"); } //Room Temperature/Humidity if (!nshared["current_temperature"].empty()) { float currentTemp = nshared["current_temperature"].asFloat(); int Humidity = root["device"][Serial]["current_humidity"].asInt(); SendTempHumSensor((iThermostat * 3) + 2, 255, currentTemp, Humidity, Name + " TempHum"); } // Check if thermostat is currently Heating if (nshared["can_heat"].asBool() && !nshared["hvac_heater_state"].empty()) { bool bIsHeating = nshared["hvac_heater_state"].asBool(); UpdateSwitch((unsigned char)(113 + (iThermostat * 3)), bIsHeating, Name + " HeatingOn"); } // Check if thermostat is currently Cooling if (nshared["can_cool"].asBool() && !nshared["hvac_ac_state"].empty()) { bool bIsCooling = nshared["hvac_ac_state"].asBool(); UpdateSwitch((unsigned char)(114 + (iThermostat * 3)), bIsCooling, Name + " CoolingOn"); } //Away if (!nstructure["away"].empty()) { bool bIsAway = nstructure["away"].asBool(); SendSwitch((iThermostat * 3) + 3, 1, 255, bIsAway, 0, Name + " Away"); } iThermostat++; } } }
JaMessage CJabloDongle::ParseMessage(std::string msgstring) { JaMessage msg; std::stringstream msgstream(msgstring); std::string msgtok; int tokNum; bool singlePlaceTemp = false; if(msgstring == "\nOK\n") { msg.mtype = JMTYPE_OK; } else if(msgstring == "\nERROR\n") { msg.mtype = JMTYPE_ERR; } else if(!msgstring.compare(0, 16, "\nTURRIS DONGLE V") && (msgstring.length() > 17)) { msg.mtype = JMTYPE_VERSION; msg.version = std::string(msgstring.c_str() + 16); msg.version.erase(msg.version.size() - 1); } else if(!msgstring.compare(0, 6, "\nSLOT:")) { if(sscanf(msgstring.c_str(), "\nSLOT:%u [%u]\n", &msg.slot_num, &msg.slot_val) == 2) { msg.mtype = JMTYPE_SLOT; } else if(sscanf(msgstring.c_str(), "\nSLOT:%u [--------]\n", &msg.slot_num) == 1) { msg.mtype = JMTYPE_SLOT; msg.slot_val = 0; } } else { tokNum = 0; while(msgstream >> msgtok) { if(tokNum == 0) { if(sscanf(msgtok.c_str(), "[%u]", &msg.did) != 1) break; } #ifdef OLDFW else if(tokNum == 1) { if(sscanf(msgtok.c_str(), "ID:%u", &msg.mid) != 1) { msg.mid = -1; if(msgtok.compare("ID:---") != 0) break; } } #endif #ifdef OLDFW else if(tokNum == 2) { #else else if(tokNum == 1) { #endif msg.devmodel = msgtok; } #ifdef OLDFW else if(tokNum == 3) { #else else if(tokNum == 2) { #endif if(msgtok == "SENSOR") { msg.mtype = JMTYPE_SENSOR; } else if(msgtok == "TAMPER") { msg.mtype = JMTYPE_TAMPER; } else if(msgtok == "BEACON") { msg.mtype = JMTYPE_BEACON; } else if(msgtok == "BUTTON") { msg.mtype = JMTYPE_BUTTON; } else if(msgtok == "ARM:1") { msg.mtype = JMTYPE_ARM; } else if(msgtok == "ARM:0") { msg.mtype = JMTYPE_DISARM; } else if(sscanf(msgtok.c_str(), "SET:%f", &msg.temp) == 1) { msg.mtype = JMTYPE_SET; } else if(sscanf(msgtok.c_str(), "INT:%f", &msg.temp) == 1) { msg.mtype = JMTYPE_INT; } else if(msgtok == "SET:") { msg.mtype = JMTYPE_SET; singlePlaceTemp = true; } else if(msgtok == "INT:") { msg.mtype = JMTYPE_INT; singlePlaceTemp = true; } else { msg.mtype = JMTYPE_UNDEF; } } #ifdef OLDFW else if((tokNum == 4) && (singlePlaceTemp == true)) { #else else if((tokNum == 3) && (singlePlaceTemp == true)) { #endif if(sscanf(msgtok.c_str(), "%f", &msg.temp) != 1) { msg.temp = 0; msg.mtype = JMTYPE_UNDEF; } singlePlaceTemp = false; } else { if(sscanf(msgtok.c_str(), "LB:%d", &msg.lb) != 1) if(sscanf(msgtok.c_str(), "ACT:%d", &msg.act) != 1) sscanf(msgtok.c_str(), "BLACKOUT:%d", &msg.blackout); } tokNum++; } } return msg; } void CJabloDongle::ProcessMessage(JaMessage jmsg) { Ja_device *jdev; if((jmsg.mtype != JMTYPE_SLOT) && (jmsg.mtype != JMTYPE_VERSION) && (jmsg.mtype != JMTYPE_OK) && (jmsg.mtype != JMTYPE_ERR)) { _log.Log(LOG_STATUS, "Received message of type %s from device %d (%s)", jmsg.MtypeAsString().c_str(), jmsg.did, jmsg.devmodel.c_str()); } switch(jmsg.mtype) { case JMTYPE_SLOT: { SlotReadCallback(jmsg.slot_num, jmsg.slot_val); readSlotsCond.notify_one(); break; } case JMTYPE_VERSION: { ProbeCallback(jmsg.version); probeCond.notify_one(); break; } case JMTYPE_SENSOR: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_SENSOR"; SendSwitch(jmsg.did, SUBSWITCH_SENSOR, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_TAMPER: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_TAMPER"; SendSwitch(jmsg.did, SUBSWITCH_TAMPER, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_BUTTON: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_BUTTON"; SendSwitch(jmsg.did, SUBSWITCH_BUTTON, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_ARM: case JMTYPE_DISARM: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_ARM"; SendSwitch(jmsg.did, SUBSWITCH_ARM, (jmsg.lb == 1) ? 0 : 100, (jmsg.mtype == JMTYPE_ARM) ? 1 : 0, 0, dev_desc.str()); break; } case JMTYPE_SET: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_SET"; SendSetPointSensor(jmsg.did, (jmsg.lb == 1) ? 0 : 100, jmsg.temp, dev_desc.str()); break; } case JMTYPE_INT: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_INT"; SendTempSensor(jmsg.did, (jmsg.lb == 1) ? 0 : 100, jmsg.temp, dev_desc.str()); break; } } } void CJabloDongle::ReadCallback(const char *data, size_t len) { unsigned char *mf, *ml; unsigned char *bufptr; unsigned char msgline[128]; JaMessage jmsg; bool messagesInBuffer; boost::lock_guard<boost::mutex> l(readQueueMutex); if (!m_bIsStarted) return; if (!m_bEnableReceive) return; //receive data to buffer if((m_bufferpos + len) < sizeof(m_buffer)) { memcpy(m_buffer + m_bufferpos, data, len); m_bufferpos += len; } else { _log.Log(LOG_STATUS, "JabloDongle: Buffer Full"); } //m_buffer[m_bufferpos] = '\0'; //_log.Log(LOG_STATUS, "Pokus received: %s", m_buffer); do { messagesInBuffer = false; //find sync sequence \n[ bufptr = m_buffer; while((mf = (unsigned char*)strchr((const char*)bufptr, '\n')) != NULL) { //check if character after newline is printable character if((mf[1] > 32 && (mf[1] < 127))) break; bufptr = mf + 1; } //is there at least 1 whole msg in buffer? if((mf != NULL) && (strlen((char*)mf) > 2)) { ml = (unsigned char*)strchr((char*)mf + 2, '\n'); if(ml != NULL) messagesInBuffer = true; } if(messagesInBuffer) { //copy single message into separate buffer memcpy(msgline, mf, ml - mf + 1); msgline[ml - mf + 1] = '\0'; //shift message buffer and adjust end pointer memmove(m_buffer, ml + 1, m_bufferpos); m_bufferpos -= (ml - m_buffer) + 1; //process message //_log.Log(LOG_STATUS, "Received line %s", msgline); jmsg = ParseMessage(std::string((char*)msgline)); #ifdef OLDFW //quick and dirty hack for msg deduplication, will be removed in final version if((jmsg.mid == -1) && ((jmsg.mtype != last_mtype) || ((jmsg.mtype != JMTYPE_SET) && (jmsg.mtype != JMTYPE_INT)))) { ProcessMessage(jmsg); last_mtype = jmsg.mtype; } else if(jmsg.mid != last_mid) { ProcessMessage(jmsg); last_mid = jmsg.mid; } #else ProcessMessage(jmsg); #endif } }while(messagesInBuffer); } void CJabloDongle::SendTempSensor(int NodeID, const int BatteryLevel, const float temperature, const std::string &defaultname) { bool bDeviceExits = true; std::stringstream szQuery; std::vector<std::vector<std::string> > result; NodeID &= 0xFFFF; //TEMP packet has only 2 bytes for ID. char szTmp[30]; sprintf(szTmp, "%d", (unsigned int)NodeID); szQuery << "SELECT Name FROM DeviceStatus WHERE (HardwareID==" << m_HwdID << ") AND (DeviceID=='" << szTmp << "') AND (Type==" << int(pTypeTEMP) << ") AND (Subtype==" << int(sTypeTemperature) << ")"; result = m_sql.query(szQuery.str()); if (result.size() < 1) { bDeviceExits = false; } RBUF tsen; memset(&tsen, 0, sizeof(RBUF)); tsen.TEMP.packetlength = sizeof(tsen.TEMP) - 1; tsen.TEMP.packettype = pTypeTEMP; tsen.TEMP.subtype = sTypeTemperature; tsen.TEMP.battery_level = BatteryLevel; tsen.TEMP.rssi = 12; tsen.TEMP.id1 = (NodeID & 0xFF00) >> 8; tsen.TEMP.id2 = NodeID & 0xFF; tsen.TEMP.tempsign = (temperature >= 0) ? 0 : 1; int at10 = round(temperature*10.0f); tsen.TEMP.temperatureh = (BYTE)(at10 / 256); at10 -= (tsen.TEMP.temperatureh * 256); tsen.TEMP.temperaturel = (BYTE)(at10); sDecodeRXMessage(this, (const unsigned char *)&tsen.TEMP); if (!bDeviceExits) { //Assign default name for device szQuery.clear(); szQuery.str(""); szQuery << "UPDATE DeviceStatus SET Name='" << defaultname << "' WHERE (HardwareID==" << m_HwdID << ") AND (DeviceID=='" << szTmp << "') AND (Type==" << int(pTypeTEMP) << ") AND (Subtype==" << int(sTypeTemperature) << ")"; m_sql.query(szQuery.str()); } }
void KMTronicUDP::GetMeterDetails() { //status command int udpSocket, n; struct sockaddr_in udpClient; char buf[8]; socklen_t serverlen; struct hostent *he; if ((he=gethostbyname(m_szIPAddress.c_str())) == NULL) { // get the host info _log.Log(LOG_ERROR,"KMTronic: Error with IP address!..."); return; } udpSocket = socket(AF_INET, SOCK_DGRAM, 0); memset(&udpClient,0,sizeof(udpClient)); udpClient.sin_family = AF_INET; udpClient.sin_port = htons(m_usIPPort); // short, network byte order udpClient.sin_addr = *((struct in_addr *)he->h_addr); /** set timeout to 1 second**/ #if !defined WIN32 struct timeval tv; tv.tv_sec = 1; setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval)); #else unsigned long nTimeout = 1*1000; setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTimeout, sizeof(DWORD)); #endif /** send the packet **/ serverlen = sizeof(udpClient); n=sendto(udpSocket, "FF0000", 6, 0, (struct sockaddr*)&udpClient, serverlen); if (n < 0) { closesocket(udpSocket); _log.Log(LOG_ERROR, "KMTronic: Error sending relay command to: %s", m_szIPAddress.c_str()); return; } /** get reply from socket **/ n = recvfrom(udpSocket, buf, 8, 0, (struct sockaddr*)&udpClient, &serverlen); closesocket(udpSocket); if (n < 0) { _log.Log(LOG_ERROR, "KMTronic: Error reading relay status from: %s", m_szIPAddress.c_str()); return; } // _log.Debug(DEBUG_HARDWARE, "KMTronic: response %s",buf); m_TotRelais=n; int jj; for (jj = 0; jj < m_TotRelais; jj++) { bool bIsOn = (buf[jj] != '0'); std::stringstream sstr; int iRelay = (jj + 1); sstr << "Relay " << iRelay; SendSwitch(iRelay, 1, 255, bIsOn, 0, sstr.str()); } return; }
void CNestThermostat::GetMeterDetails() { if (m_UserName.size()==0) return; if (m_Password.size()==0) return; std::string sResult; if (m_bDoLogin) { if (!Login()) return; } std::vector<std::string> ExtraHeaders; ExtraHeaders.push_back("user-agent:Nest/1.1.0.10 CFNetwork/548.0.4"); ExtraHeaders.push_back("Authorization:Basic " + m_AccessToken); ExtraHeaders.push_back("X-nl-user-id:" + m_UserID); ExtraHeaders.push_back("X-nl-protocol-version:1"); //Get Data std::string sURL = m_TransportURL + NEST_GET_STATUS + m_UserID; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "NestThermostat: Error getting current state!"); m_bDoLogin = true; return; } Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "NestThermostat: Invalid data received!"); m_bDoLogin = true; return; } if (root["shared"].empty() == true) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } if (root["shared"].size()<1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } Json::Value::Members members = root["shared"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } //Get Serial m_Serial = *members.begin(); //Get Structure members = root["structure"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } m_StructureID = *members.begin(); Json::Value vShared = *root["shared"].begin(); //Setpoint if (!vShared["target_temperature"].empty()) { float currentSetpoint = vShared["target_temperature"].asFloat(); SendSetPointSensor(1, currentSetpoint, "Room Setpoint"); } //Room Temperature/Humidity if (!vShared["current_temperature"].empty()) { float currentTemp = vShared["current_temperature"].asFloat(); int Humidity = root["device"][m_Serial]["current_humidity"].asInt(); SendTempHumSensor(2, 255, currentTemp, Humidity, "Room TempHum"); } //Away Json::Value vStructure = *root["structure"].begin(); if (!vStructure["away"].empty()) { bool bIsAway = vStructure["away"].asBool(); SendSwitch(3, 1, 255, bIsAway, 0, "Away"); } }
void BleBox::GetDevicesState() { boost::lock_guard<boost::mutex> l(m_mutex); std::map<const std::string, const int>::const_iterator itt; for (itt = m_devices.begin(); itt != m_devices.end(); ++itt) { std::stringstream sstr; sstr << "/api/" << DevicesType[itt->second].api_state << "/state"; std::string command = sstr.str(); Json::Value root = SendCommand(itt->first, command); if (root == "") continue; int node = IPToUInt(itt->first); if (node != 0) { switch (itt->second) { case 0: { if (root["state"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'state' missing!"); break; } const bool state = root["state"].asBool(); SendSwitch(node, itt->second, 255, state, 0, DevicesType[itt->second].name); break; } case 1: { if (root["state"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'state' missing!"); break; } const int state = root["state"].asInt(); const int currentPos = root["currentPos"].asInt(); // const int desiredPos = root["desiredPos"].asInt(); const int pos = currentPos; bool opened = true; if ((state == 2 && pos == 100) || (state == 3)) opened = false; SendSwitch(node, itt->second, 255, opened, pos, DevicesType[itt->second].name); break; } case 2: { if (root["light"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'light' missing!"); break; } if (root["light"]["currentColor"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'currentColor' missing!"); break; } const std::string currentColor = root["light"]["currentColor"].asString(); int hexNumber; sscanf(currentColor.c_str(), "%x", &hexNumber); int level = (int)(hexNumber / (255.0 / 100.0)); SendSwitch(node, itt->second, 255, level > 0, level, DevicesType[itt->second].name); break; } case 3: { if (root["rgbw"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'rgbw' missing!"); break; } if (root["rgbw"]["currentColor"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'currentColor' missing!"); break; } const std::string currentColor = root["rgbw"]["currentColor"].asString(); int hexNumber; sscanf(currentColor.c_str(), "%x", &hexNumber); SendRGBWSwitch(node, itt->second, 255, hexNumber, true, DevicesType[itt->second].name); break; } case 4: { if (root["currentPos"].empty() == true) { _log.Log(LOG_ERROR, "BleBox: node 'currentPos' missing!"); break; } const int currentPos = root["currentPos"].asInt(); int level = (int)(currentPos / (255.0 / 100.0)); SendSwitch(node, itt->second, 255, level > 0, level, DevicesType[itt->second].name); break; } } SetHeartbeatReceived(); } } }