Пример #1
0
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()));
}
Пример #2
0
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");
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #6
0
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");
	}
}
Пример #7
0
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;
}
Пример #8
0
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!");
			}
		}
	}
}
Пример #9
0
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++;
		}
	}
}
Пример #10
0
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());
	}
}
Пример #11
0
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;
}
Пример #12
0
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");
	}


}
Пример #13
0
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();
		}
	}
}