Example #1
0
void CThermosmart::SetSetpoint(const int idx, const float temp)
{
	if (m_bDoLogin)
	{
		if (!Login())
			return;
	}

	char szTemp[20];
	sprintf(szTemp, "%.1f", temp);
	std::string sTemp = szTemp;

	std::string szPostdata = "target_temperature=" + sTemp;
	std::vector<std::string> ExtraHeaders;
	std::string sResult;

	std::string sURL = THERMOSMART_SETPOINT_PATH;
	stdreplace(sURL, "[TID]", m_ThermostatID);
	stdreplace(sURL, "[access_token]", m_AccessToken);
	if (!HTTPClient::PUT(sURL, szPostdata, ExtraHeaders, sResult))
	{
		_log.Log(LOG_ERROR, "Thermosmart: Error setting thermostat data!");
		m_bDoLogin = true;
		return;
	}
	SendSetPointSensor(1, temp, "target temperature");
}
Example #2
0
bool CToonThermostat::ParseThermostatData(const Json::Value &root)
{
	//thermostatInfo
	if (root["thermostatInfo"].empty())
		return false;

	float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f;
	float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f;
	SendSetPointSensor(1, currentSetpoint, "Room Setpoint");
	SendTempSensor(1, 255, currentTemp, "Room Temperature");

	//int programState = root["thermostatInfo"]["programState"].asInt();
	//int activeState = root["thermostatInfo"]["activeState"].asInt();

	if (root["thermostatInfo"]["burnerInfo"].empty() == false)
	{
		//burnerinfo
		//0=off
		//1=heating
		//2=hot water
		//3=pre-heating
		int burnerInfo = 0;

		if (root["thermostatInfo"]["burnerInfo"].isString())
		{
			burnerInfo = atoi(root["thermostatInfo"]["burnerInfo"].asString().c_str());
		}
		else if (root["thermostatInfo"]["burnerInfo"].isInt())
		{
			burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt();
		}
		if (burnerInfo == 1)
		{
			UpdateSwitch(113, true, "HeatingOn");
			UpdateSwitch(114, false, "TapwaterOn");
			UpdateSwitch(115, false, "PreheatOn");
		}
		else if (burnerInfo == 2)
		{
			UpdateSwitch(113, false, "HeatingOn");
			UpdateSwitch(114, true, "TapwaterOn");
			UpdateSwitch(115, false, "PreheatOn");
		}
		else if (burnerInfo == 3)
		{
			UpdateSwitch(113, false, "HeatingOn");
			UpdateSwitch(114, false, "TapwaterOn");
			UpdateSwitch(115, true, "PreheatOn");
		}
		else
		{
			UpdateSwitch(113, false, "HeatingOn");
			UpdateSwitch(114, false, "TapwaterOn");
			UpdateSwitch(115, false, "PreheatOn");
		}
	}
	return true;
}
Example #3
0
void CICYThermostat::GetMeterDetails()
{
    if (m_UserName.size()==0)
        return;
    if (m_Password.size()==0)
        return;
    if (!GetSerialAndToken())
        return;

    std::string sResult;

    //Get Data
    std::vector<std::string> ExtraHeaders;
    ExtraHeaders.push_back("Session-token:"+m_Token);

    std::string sURL = "";

    if (m_companymode == CMODE_PORTAL)
        sURL = ICY_DATA_URL;
    else if (m_companymode == CMODE_ENI)
        sURL = ENI_DATA_URL;
    else
        sURL = SEC_DATA_URL;

    if (!HTTPClient::GET(sURL, ExtraHeaders, sResult))
    {
        _log.Log(LOG_ERROR,"ICYThermostat: Error getting data!");
        return;
    }

    Json::Value root;

    Json::Reader jReader;
    bool ret = jReader.parse(sResult, root);
    if (!ret)
    {
        _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!");
        return;
    }
    if (root["temperature1"].empty() == true)
    {
        _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!");
        return;
    }
    SendSetPointSensor(1, root["temperature1"].asFloat(), "Room Setpoint");
    if (root["temperature2"].empty() == true)
    {
        _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!");
        return;
    }
    SendTempSensor(1, 255, root["temperature2"].asFloat(), "Room Temperature");
}
Example #4
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");
	}
}
Example #5
0
void CToonThermostat::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;

	std::stringstream sstr2;
	sstr2 << "?clientId=" << m_ClientID
		<< "&clientIdChecksum=" << m_ClientIDChecksum
		<< "&random=" << GetRandom();
	std::string szPostdata = sstr2.str();
	//Get Data
	std::string sURL = TOON_HOST + TOON_UPDATE_PATH + szPostdata;
	if (!HTTPClient::GET(sURL, ExtraHeaders, sResult))
	{
		_log.Log(LOG_ERROR, "ToonThermostat: Error getting current state!");
		m_bDoLogin = true;
		return;
	}
	time_t atime = mytime(NULL);

#ifdef DEBUG_ToonThermostat
	char szFileName[MAX_PATH];
	static int sNum = 1;
	sprintf_s(szFileName, "E:\\toonresult_%03d.txt", sNum++);
	SaveString2Disk(sResult, szFileName);
#endif

	Json::Value root;
	Json::Reader jReader;
	if (!jReader.parse(sResult, root))
	{
		_log.Log(LOG_ERROR, "ToonThermostat: Invalid data received!");
		m_bDoLogin = true;
		return;
	}
	if (root["success"].empty() == true)
	{
		_log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!");
		m_bDoLogin = true;
		return;
	}
	if (root["success"] == false)
	{
		_log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!");
		m_bDoLogin = true;
		return;
	}

	//ZWave Devices
	if (root["deviceStatusInfo"].empty() == false)
	{
		if (root["deviceStatusInfo"]["device"].empty() == false)
		{
			int totDevices = root["deviceStatusInfo"]["device"].size();
			for (int ii = 0; ii < totDevices; ii++)
			{
				std::string deviceName = root["deviceStatusInfo"]["device"][ii]["name"].asString();
				std::string uuid = root["deviceStatusInfo"]["device"][ii]["devUUID"].asString();
				int state = root["deviceStatusInfo"]["device"][ii]["currentState"].asInt();

				int Idx;
				if (!GetUUIDIdx(uuid, Idx))
				{
					if (!AddUUID(uuid, Idx))
					{
						_log.Log(LOG_ERROR, "ToonThermostat: Error adding UUID to database?! Uuid=%s", uuid.c_str());
						return;
					}
				}
				UpdateSwitch(Idx, state != 0, deviceName);
			}
		}
	}

	//thermostatInfo
	if (root["thermostatInfo"].empty() == false)
	{
		float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f;
		float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f;
		SendSetPointSensor(1, currentSetpoint, "Room Setpoint");
		SendTempSensor(1, currentTemp, "Room Temperature");

		//int programState = root["thermostatInfo"]["programState"].asInt();
		//int activeState = root["thermostatInfo"]["activeState"].asInt();

		if (root["thermostatInfo"]["burnerInfo"].empty() == false)
		{
			//burnerinfo
			//0=off
			//1=heating
			//2=hot water
			//3=pre-heating
			int burnerInfo = 0;

			if (root["thermostatInfo"]["burnerInfo"].isString())
			{
				burnerInfo = atoi(root["thermostatInfo"]["burnerInfo"].asString().c_str());
			}
			else if (root["thermostatInfo"]["burnerInfo"].isInt())
			{
				burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt();
			}
			if (burnerInfo == 1)
			{
				UpdateSwitch(113, true, "HeatingOn");
				UpdateSwitch(114, false, "TapwaterOn");
				UpdateSwitch(115, false, "PreheatOn");
			}
			else if (burnerInfo == 2)
			{
				UpdateSwitch(113, false, "HeatingOn");
				UpdateSwitch(114, true, "TapwaterOn");
				UpdateSwitch(115, false, "PreheatOn");
			}
			else if (burnerInfo == 3)
			{
				UpdateSwitch(113, false, "HeatingOn");
				UpdateSwitch(114, false, "TapwaterOn");
				UpdateSwitch(115, true, "PreheatOn");
			}
			else
			{
				UpdateSwitch(113, false, "HeatingOn");
				UpdateSwitch(114, false, "TapwaterOn");
				UpdateSwitch(115, false, "PreheatOn");
			}
		}
	}

	if (root["gasUsage"].empty() == false)
	{
		m_p1gas.gasusage = (unsigned long)(root["gasUsage"]["meterReading"].asFloat());
	}

	if (root["powerUsage"].empty() == false)
	{
		m_p1power.powerusage1 = (unsigned long)(root["powerUsage"]["meterReadingLow"].asFloat());
		m_p1power.powerusage2 = (unsigned long)(root["powerUsage"]["meterReading"].asFloat());

		if (root["powerUsage"]["meterReadingProdu"].empty() == false)
		{
			m_p1power.powerdeliv1 = (unsigned long)(root["powerUsage"]["meterReadingLowProdu"].asFloat());
			m_p1power.powerdeliv2 = (unsigned long)(root["powerUsage"]["meterReadingProdu"].asFloat());
		}

		m_p1power.usagecurrent = (unsigned long)(root["powerUsage"]["value"].asFloat());	//Watt
	}

	//Send Electra if value changed, or at least every 5 minutes
	if (
		(m_p1power.usagecurrent != m_lastelectrausage) ||
		(atime - m_lastSharedSendElectra >= 300)
		)
	{
		if ((m_p1power.powerusage1 != 0) || (m_p1power.powerusage2 != 0) || (m_p1power.powerdeliv1 != 0) || (m_p1power.powerdeliv2 != 0))
		{
			m_lastSharedSendElectra = atime;
			m_lastelectrausage = m_p1power.usagecurrent;
			sDecodeRXMessage(this, (const unsigned char *)&m_p1power);
		}
	}
	
	//Send GAS if the value changed, or at least every 5 minutes
	if (
		(m_p1gas.gasusage != m_lastgasusage) ||
		(atime - m_lastSharedSendGas >= 300)
		)
	{
		if (m_p1gas.gasusage != 0)
		{
			m_lastSharedSendGas = atime;
			m_lastgasusage = m_p1gas.gasusage;
			sDecodeRXMessage(this, (const unsigned char *)&m_p1gas);
		}
	}
}
Example #6
0
void CToonThermostat::GetMeterDetails()
{
	if (m_UserName.size()==0)
		return;
	if (m_Password.size()==0)
		return;
	if (m_bDoLogin)
	{
		if (!Login())
		return;
	}
	std::string sResult;
	std::vector<std::string> ExtraHeaders;

	std::stringstream sstr2;
	sstr2 << "?clientId=" << m_ClientID
		<< "&clientIdChecksum=" << m_ClientIDChecksum
		<< "&random=" << GetRandom();
	std::string szPostdata = sstr2.str();
	//Get Data
	std::string sURL = TOON_HOST + TOON_UPDATE_PATH + szPostdata;
	if (!HTTPClient::GET(sURL, ExtraHeaders, sResult))
	{
		_log.Log(LOG_ERROR, "ToonThermostat: Error getting current state!");
		m_bDoLogin = true;
		return;
	}

	time_t atime = mytime(NULL);

	Json::Value root;
	Json::Reader jReader;
	if (!jReader.parse(sResult, root))
	{
		_log.Log(LOG_ERROR, "ToonThermostat: Invalid data received!");
		m_bDoLogin = true;
		return;
	}
	if (root["success"].empty() == true)
	{
		_log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!");
		m_bDoLogin = true;
		return;
	}
	if (root["success"] == false)
	{
		_log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!");
		m_bDoLogin = true;
		return;
	}

	//thermostatInfo
	if (root["thermostatInfo"].empty() == false)
	{
		float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f;
		float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f;
		SendSetPointSensor(1, currentSetpoint, "Room Setpoint");
		SendTempSensor(1, currentTemp, "Room Temperature");

		//int programState = root["thermostatInfo"]["programState"].asInt();
		//int activeState = root["thermostatInfo"]["activeState"].asInt();

		if (root["thermostatInfo"]["burnerInfo"].empty() == false)
		{
			//burnerinfo
			//0=off
			//1=heating
			//2=hot water
			//3=pre-heating
			if (root["thermostatInfo"]["burnerInfo"].isString())
			{
				std::string sBurnerInfo = root["thermostatInfo"]["burnerInfo"].asString();
				int burnerInfo = atoi(sBurnerInfo.c_str());
				UpdateSwitch(113, burnerInfo != 0, "FlameOn");
			}
			else if (root["thermostatInfo"]["burnerInfo"].isInt())
			{
				int burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt();
				UpdateSwitch(113, burnerInfo != 0, "FlameOn");
			}
		}
	}

	if (root["gasUsage"].empty() == false)
	{
		m_p1gas.gasusage = (unsigned long)(root["gasUsage"]["meterReading"].asFloat());
	}

	if (root["powerUsage"].empty() == false)
	{
		m_p1power.powerusage1 = (unsigned long)(root["powerUsage"]["meterReading"].asFloat());
		m_p1power.powerusage2 = (unsigned long)(root["powerUsage"]["meterReadingLow"].asFloat());

		if (root["powerUsage"]["meterReadingProdu"].empty() == false)
		{
			m_p1power.powerdeliv1 = (unsigned long)(root["powerUsage"]["meterReadingProdu"].asFloat());
			m_p1power.powerdeliv2 = (unsigned long)(root["powerUsage"]["meterReadingLowProdu"].asFloat());
		}

		m_p1power.usagecurrent = (unsigned long)(root["powerUsage"]["value"].asFloat());	//Watt
	}

	//Send Electra if value changed, or at least every 5 minutes
	if (
		(m_p1power.usagecurrent != m_lastelectrausage) ||
		(atime - m_lastSharedSendElectra >= 300)
		)
	{
		if ((m_p1power.powerusage1 != 0) || (m_p1power.powerusage2 != 0) || (m_p1power.powerdeliv1 != 0) || (m_p1power.powerdeliv2 != 0))
		{
			m_lastSharedSendElectra = atime;
			m_lastelectrausage = m_p1power.usagecurrent;
			sDecodeRXMessage(this, (const unsigned char *)&m_p1power);
		}
	}
	
	//Send GAS if the value changed, or at least every 5 minutes
	if (
		(m_p1gas.gasusage != m_lastgasusage) ||
		(atime - m_lastSharedSendGas >= 300)
		)
	{
		if (m_p1gas.gasusage != 0)
		{
			m_lastSharedSendGas = atime;
			m_lastgasusage = m_p1gas.gasusage;
			sDecodeRXMessage(this, (const unsigned char *)&m_p1gas);
		}
	}
}
Example #7
0
void MySensorsBase::SendSensor2Domoticz(_tMySensorNode *pNode, _tMySensorChild *pChild, const _eSetType vType)
{
	m_iLastSendNodeBatteryValue = 255;
	if (pChild->hasBattery)
	{
		m_iLastSendNodeBatteryValue = pChild->batValue;
	}
	int cNode = (pChild->nodeID << 8) | pChild->childID;
	int intValue;
	float floatValue;
	std::string stringValue;

	switch (vType)
	{
	case V_TEMP:
	{
		float Temp = 0;
		pChild->GetValue(V_TEMP, Temp);
		_tMySensorChild *pChildHum = FindChildWithValueType(pChild->nodeID, V_HUM);
		_tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE);
		if (pChildHum && pChildBaro)
		{
			int Humidity;
			float Baro;
			bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity);
			bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro);
			if (bHaveHumidity && bHaveBaro)
			{
				int forecast = bmpbaroforecast_unknown;
				_tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST);
				if (pSensorForecast)
				{
					pSensorForecast->GetValue(V_FORECAST, forecast);
				}
				if (forecast == bmpbaroforecast_cloudy)
				{
					if (Baro < 1010)
						forecast = bmpbaroforecast_rain;
				}

				//We are using the TempHumBaro Float type now, convert the forecast
				int nforecast = wsbaroforcast_some_clouds;
				if (Baro <= 980)
					nforecast = wsbaroforcast_heavy_rain;
				else if (Baro <= 995)
				{
					if (Temp > 1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}
				else if (Baro >= 1029)
					nforecast = wsbaroforcast_sunny;
				switch (forecast)
				{
				case bmpbaroforecast_sunny:
					nforecast = wsbaroforcast_sunny;
					break;
				case bmpbaroforecast_cloudy:
					nforecast = wsbaroforcast_cloudy;
					break;
				case bmpbaroforecast_thunderstorm:
					nforecast = wsbaroforcast_heavy_rain;
					break;
				case bmpbaroforecast_rain:
					if (Temp>1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}
				SendTempHumBaroSensorFloat(cNode, pChild->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro");
			}
		}
		else if (pChildHum) {
			int Humidity;
			bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity);
			if (bHaveHumidity)
			{
				SendTempHumSensor(cNode, pChild->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum");
			}
		}
		else
		{
			SendTempSensor(cNode, pChild->batValue, Temp, (!pChild->childName.empty()) ? pChild->childName : "Temp");
		}
	}
	break;
	case V_HUM:
	{
		_tMySensorChild *pChildTemp = FindChildWithValueType(pChild->nodeID, V_TEMP);
		_tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE);
		int forecast = bmpbaroforecast_unknown;
		_tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST);
		if (pSensorForecast)
		{
			pSensorForecast->GetValue(V_FORECAST, forecast);
		}
		if (forecast == bmpbaroforecast_cloudy)
		{
			if (pChildBaro)
			{
				float Baro;
				if (pChildBaro->GetValue(V_PRESSURE, Baro))
				{
					if (Baro < 1010)
						forecast = bmpbaroforecast_rain;
				}
			}
		}
		float Temp;
		float Baro;
		int Humidity;
		pChild->GetValue(V_HUM, Humidity);
		if (pChildTemp && pChildBaro)
		{
			bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp);
			bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro);
			if (bHaveTemp && bHaveBaro)
			{
				cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID;

				//We are using the TempHumBaro Float type now, convert the forecast
				int nforecast = wsbaroforcast_some_clouds;
				if (Baro <= 980)
					nforecast = wsbaroforcast_heavy_rain;
				else if (Baro <= 995)
				{
					if (Temp > 1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}
				else if (Baro >= 1029)
					nforecast = wsbaroforcast_sunny;
				switch (forecast)
				{
				case bmpbaroforecast_sunny:
					nforecast = wsbaroforcast_sunny;
					break;
				case bmpbaroforecast_cloudy:
					nforecast = wsbaroforcast_cloudy;
					break;
				case bmpbaroforecast_thunderstorm:
					nforecast = wsbaroforcast_heavy_rain;
					break;
				case bmpbaroforecast_rain:
					if (Temp > 1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}

				SendTempHumBaroSensorFloat(cNode, pChildTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro");
			}
		}
		else if (pChildTemp) {
			bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp);
			if (bHaveTemp)
			{
				cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID;
				SendTempHumSensor(cNode, pChildTemp->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum");
			}
		}
		else
		{
			SendHumiditySensor(cNode, pChild->batValue, Humidity);
		}
	}
	break;
	case V_PRESSURE:
	{
		float Baro;
		pChild->GetValue(V_PRESSURE, Baro);
		_tMySensorChild *pSensorTemp = FindChildWithValueType(pChild->nodeID, V_TEMP);
		_tMySensorChild *pSensorHum = FindChildWithValueType(pChild->nodeID, V_HUM);
		int forecast = bmpbaroforecast_unknown;
		_tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST);
		if (pSensorForecast)
		{
			pSensorForecast->GetValue(V_FORECAST, forecast);
		}
		if (forecast == bmpbaroforecast_cloudy)
		{
			if (Baro < 1010)
				forecast = bmpbaroforecast_rain;
		}
		if (pSensorTemp && pSensorHum)
		{
			float Temp;
			int Humidity;
			bool bHaveTemp = pSensorTemp->GetValue(V_TEMP, Temp);
			bool bHaveHumidity = pSensorHum->GetValue(V_HUM, Humidity);

			if (bHaveTemp && bHaveHumidity)
			{
				cNode = (pSensorTemp->nodeID << 8) | pSensorTemp->childID;
				//We are using the TempHumBaro Float type now, convert the forecast
				int nforecast = wsbaroforcast_some_clouds;
				if (Baro <= 980)
					nforecast = wsbaroforcast_heavy_rain;
				else if (Baro <= 995)
				{
					if (Temp > 1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}
				else if (Baro >= 1029)
					nforecast = wsbaroforcast_sunny;
				switch (forecast)
				{
				case bmpbaroforecast_sunny:
					nforecast = wsbaroforcast_sunny;
					break;
				case bmpbaroforecast_cloudy:
					nforecast = wsbaroforcast_cloudy;
					break;
				case bmpbaroforecast_thunderstorm:
					nforecast = wsbaroforcast_heavy_rain;
					break;
				case bmpbaroforecast_rain:
					if (Temp > 1)
						nforecast = wsbaroforcast_rain;
					else
						nforecast = wsbaroforcast_snow;
					break;
				}
				SendTempHumBaroSensorFloat(cNode, pSensorTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro");
			}
		}
		else
			SendBaroSensor(pChild->nodeID, pChild->childID, pChild->batValue, Baro, forecast);
	}
	break;
	case V_TRIPPED:
		//	Tripped status of a security sensor. 1 = Tripped, 0 = Untripped
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Security Sensor");
		break;
	case V_ARMED:
		//Armed status of a security sensor. 1 = Armed, 0 = Bypassed
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Security Sensor");
		break;
	case V_LOCK_STATUS:
		//Lock status. 1 = Locked, 0 = Unlocked
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Lock Sensor");
		break;
	case V_STATUS:
		//	Light status. 0 = off 1 = on
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID, (intValue != 0), 100, "Light");
		break;
	case V_SCENE_ON:
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID + intValue, true, 100, "Scene");
		break;
	case V_SCENE_OFF:
		if (pChild->GetValue(vType, intValue))
			UpdateSwitch(pChild->nodeID, pChild->childID + intValue, false, 100, "Scene");
		break;
	case V_PERCENTAGE:
		//	Dimmer value. 0 - 100 %
		if (pChild->GetValue(vType, intValue))
		{
			int level = intValue;
			UpdateSwitch(pChild->nodeID, pChild->childID, (level != 0), level, "Light");
		}
		break;
	case V_RGB:
		//RRGGBB
		if (pChild->GetValue(vType, intValue))
			SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, false, (!pChild->childName.empty()) ? pChild->childName : "RGB Light");
		break;
	case V_RGBW:
		//RRGGBBWW
		if (pChild->GetValue(vType, intValue))
			SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, true, (!pChild->childName.empty()) ? pChild->childName : "RGBW Light");
		break;
	case V_UP:
	case V_DOWN:
	case V_STOP:
		if (pChild->GetValue(vType, intValue))
			SendBlindSensor(pChild->nodeID, pChild->childID, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Blinds/Window");
		break;
	case V_LIGHT_LEVEL:
		if (pChild->GetValue(vType, floatValue))
		{
			_tLightMeter lmeter;
			lmeter.id1 = 0;
			lmeter.id2 = 0;
			lmeter.id3 = 0;
			lmeter.id4 = pChild->nodeID;
			lmeter.dunit = pChild->childID;
			lmeter.fLux = floatValue;
			lmeter.battery_level = pChild->batValue;
			if (pChild->hasBattery)
				lmeter.battery_level = pChild->batValue;
			sDecodeRXMessage(this, (const unsigned char *)&lmeter);
		}
		break;
	case V_LEVEL:
		if ((pChild->presType == S_DUST)|| (pChild->presType == S_AIR_QUALITY))
		{
			if (pChild->GetValue(vType, intValue))
			{
				_tAirQualityMeter meter;
				meter.len = sizeof(_tAirQualityMeter) - 1;
				meter.type = pTypeAirQuality;
				meter.subtype = sTypeVoltcraft;
				meter.airquality = intValue;
				meter.id1 = pChild->nodeID;
				meter.id2 = pChild->childID;
				sDecodeRXMessage(this, (const unsigned char *)&meter);
			}
		}
		else if (pChild->presType == S_LIGHT_LEVEL)
		{
			if (pChild->GetValue(vType, intValue))
			{
				_tLightMeter lmeter;
				lmeter.id1 = 0;
				lmeter.id2 = 0;
				lmeter.id3 = 0;
				lmeter.id4 = pChild->nodeID;
				lmeter.dunit = pChild->childID;
				lmeter.fLux = (float)intValue;
				lmeter.battery_level = pChild->batValue;
				if (pChild->hasBattery)
					lmeter.battery_level = pChild->batValue;
				sDecodeRXMessage(this, (const unsigned char *)&lmeter);
			}
		}
		else if (pChild->presType == S_SOUND)
		{
			if (pChild->GetValue(vType, intValue))
				SendSoundSensor(cNode, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Sound Level");
		}
		else if (pChild->presType == S_MOISTURE)
		{
			if (pChild->GetValue(vType, intValue))
			{
				_tGeneralDevice gdevice;
				gdevice.subtype = sTypeSoilMoisture;
				gdevice.intval1 = intValue;
				gdevice.id = pChild->nodeID;
				sDecodeRXMessage(this, (const unsigned char *)&gdevice);
			}
		}
		break;
	case V_RAIN:
		if (pChild->GetValue(vType, floatValue))
			SendRainSensor(cNode, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Rain");
		break;
	case V_WATT:
		{
			if (pChild->GetValue(vType, floatValue))
			{
				_tMySensorChild *pSensorKwh = pNode->FindChildWithValueType(pChild->childID, V_KWH);// FindChildWithValueType(pChild->nodeID, V_KWH);
				if (pSensorKwh) {
					float Kwh;
					if (pSensorKwh->GetValue(V_KWH, Kwh))
						SendKwhMeter(pSensorKwh->nodeID, pSensorKwh->childID, pSensorKwh->batValue, floatValue / 1000.0f, Kwh, (!pChild->childName.empty()) ? pChild->childName : "Meter");
				}
				else {
					SendWattMeter(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Usage");
				}
			}
		}
		break;
	case V_KWH:
		if (pChild->GetValue(vType, floatValue))
		{
			_tMySensorChild *pSensorWatt = pNode->FindChildWithValueType(pChild->childID, V_WATT);// FindChildWithValueType(pChild->nodeID, V_WATT);
			if (pSensorWatt) {
				float Watt;
				if (pSensorWatt->GetValue(V_WATT, Watt))
					SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, Watt / 1000.0f, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter");
			}
			else {
				SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, 0, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter");
			}
		}
		break;
	case V_DISTANCE:
		if (pChild->GetValue(vType, floatValue))
			SendDistanceSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue);
		break;
	case V_FLOW:
		//Flow of water in meter (for now send as a percentage sensor)
		if (pChild->GetValue(vType, floatValue))
			SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water Flow");
		break;
	case V_VOLUME:
		//Water Volume
		if (pChild->GetValue(vType, floatValue))
			SendMeterSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water");
		break;
	case V_VOLTAGE:
		if (pChild->GetValue(vType, floatValue))
			SendVoltageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Voltage");
		break;
	case V_UV:
		if (pChild->GetValue(vType, floatValue))
			SendUVSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue);
		break;
	case V_IMPEDANCE:
		if (pChild->GetValue(vType, floatValue))
			SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Impedance");
		break;
	case V_WEIGHT:
		if (pChild->GetValue(vType, floatValue))
		{
			while (1 == 0);
		}
		break;
	case V_CURRENT:
		if (pChild->GetValue(vType, floatValue))
			SendCurrentSensor(cNode, pChild->batValue, floatValue, 0, 0, (!pChild->childName.empty()) ? pChild->childName : "Current");
		break;
	case V_FORECAST:
		if (pChild->GetValue(vType, intValue))
		{
			_tMySensorChild *pSensorBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE);
			if (pSensorBaro)
			{
				float Baro;
				if (pSensorBaro->GetValue(V_PRESSURE, Baro))
				{
					int forecast = intValue;
					if (forecast == bmpbaroforecast_cloudy)
					{
						if (Baro < 1010)
							forecast = bmpbaroforecast_rain;
					}
					SendBaroSensor(pSensorBaro->nodeID, pSensorBaro->childID, pSensorBaro->batValue, Baro, forecast);
				}
			}
			else
			{
				if (pChild->GetValue(V_FORECAST, stringValue))
				{
					std::stringstream sstr;
					sstr << pChild->nodeID;
					std::string devname = (!pChild->childName.empty()) ? pChild->childName : "Forecast";
					m_sql.UpdateValue(m_HwdID, sstr.str().c_str(), pChild->childID, pTypeGeneral, sTypeTextStatus, 12, pChild->batValue, 0, stringValue.c_str(), devname);
				}
			}
		}
		break;
	case V_WIND:
	case V_GUST:
	case V_DIRECTION:
		MakeAndSendWindSensor(pChild->nodeID, (!pChild->childName.empty()) ? pChild->childName : "Wind");
		break;
	case V_HVAC_SETPOINT_HEAT:
		if (pChild->GetValue(vType, floatValue))
		{
			SendSetPointSensor(pNode->nodeID, pChild->childID, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Heater Setpoint");
		}
		break;
	}
}
Example #8
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++;
		}
	}
}
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());
	}
}
Example #10
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");
	}


}
Example #11
0
void CAnnaThermostat::GetMeterDetails()
{
	if (m_UserName.size() == 0)
		return;
	if (m_Password.size() == 0)
		return;
	std::string sResult;
#ifdef DEBUG_AnnaThermostat
	sResult = ReadFile("E:\\appliances.xml");
#else
	//Get Data
	std::stringstream szURL;

	if (m_Password.empty())
	{
		szURL << "http://" << m_IPAddress << ":" << m_IPPort;
	}
	else
	{
		szURL << "http://" << m_UserName << ":" << m_Password << "@" << m_IPAddress << ":" << m_IPPort;
	}
	szURL << ANNA_GET_STATUS;

	if (!HTTPClient::GET(szURL.str(), sResult))
	{
		_log.Log(LOG_ERROR, "AnnaThermostat: Error getting current state!");
		return;
	}
#endif
	if (sResult.empty())
	{
		_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
		return;
	}

	stdreplace(sResult, "\r\n", "");

	TiXmlDocument doc;
	if (doc.Parse(sResult.c_str()))
	{
		_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
		return;
	}

	TiXmlElement *pRoot;
	TiXmlElement *pAppliance, *pElem;
	TiXmlAttribute *pAttribute;
	std::string sname, tmpstr;

	pRoot = doc.FirstChildElement("appliances");
	if (!pRoot)
	{
		_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
		return;
	}
	pAppliance = pRoot->FirstChildElement("appliance");
	while (pAppliance)
	{
		TiXmlHandle hAppliance = TiXmlHandle(pAppliance);

		pElem = pAppliance->FirstChildElement("name");
		if (pElem == NULL)
		{
			_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
			return;
		}
		std::string ApplianceName=pElem->GetText();

		if ((m_ThermostatID.empty()) && (ApplianceName == "Anna"))
		{
			pAttribute = pAppliance->FirstAttribute();
			if (pAttribute != NULL)
			{
				std::string aName = pAttribute->Name();
				if (aName == "id")
				{
					m_ThermostatID = pAttribute->Value();
				}
			}
		}

		//Handle point_log
		pElem = hAppliance.FirstChild("logs").FirstChild().Element();
		if (!pElem)
		{
			_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
			return;
		}
		TiXmlHandle hLogs = TiXmlHandle(pElem);
		pElem = hAppliance.FirstChild("logs").Child("point_log", 0).ToElement();
		if (!pElem)
		{
			_log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!");
			return;
		}
		for (pElem; pElem; pElem = pElem->NextSiblingElement())
		{
			sname = GetElementChildValue(pElem, "type");
			if (sname == "temperature")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendTempSensor(1, 255, temperature, sname);
				}
			}
			else if (sname == "illuminance")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float illuminance = (float)atof(tmpstr.c_str());
					SendLuxSensor(2, 1, 255, illuminance, sname);
				}
			}
			else if (sname == "thermostat")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendSetPointSensor(3, temperature, sname);
				}
			}
			/*
			else if (sname == "intended_boiler_temperature")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendTempSensor(4, 255, temperature, sname);
				}
			}
			*/
			else if (sname == "return_water_temperature")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendTempSensor(5, 255, temperature, sname);
				}
			}
			else if (sname == "boiler_temperature")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendTempSensor(6, 255, temperature, sname);
				}
			}
			else if (sname == "maximum_boiler_temperature")
			{
				tmpstr = GetPeriodMeasurement(pElem);
				if (!tmpstr.empty())
				{
					float temperature = (float)atof(tmpstr.c_str());
					SendTempSensor(7, 255, temperature, sname);
				}
			}
		}

		pAppliance = pAppliance->NextSiblingElement("appliance");
	}
	return;
}
Example #12
0
void CToonThermostat::SetSetpoint(const int idx, const float temp)
{
	if (m_UserName.size() == 0)
		return;
	if (m_Password.size() == 0)
		return;

	if (m_bDoLogin == true)
	{
		if (!Login())
			return;
	}

	std::string sResult;
	std::vector<std::string> ExtraHeaders;

	if (idx==1)
	{
		//Room Set Point

		char szTemp[20];
		sprintf(szTemp,"%d",int(temp*100.0f));
		std::string sTemp = szTemp;

		std::stringstream sstr2;
		sstr2 << "?clientId=" << m_ClientID
			<< "&clientIdChecksum=" << m_ClientIDChecksum
			<< "&value=" << sTemp
			<< "&random=" << GetRandom();
		std::string szPostdata = sstr2.str();

		std::string sURL = TOON_HOST + TOON_TEMPSET_PATH + szPostdata;
		if (!HTTPClient::GET(sURL, ExtraHeaders, sResult))
		{
			_log.Log(LOG_ERROR, "ToonThermostat: Error setting setpoint!");
			m_bDoLogin = true;
			return;
		}

		Json::Value root;
		Json::Reader jReader;
		if (!jReader.parse(sResult, root))
		{
			_log.Log(LOG_ERROR, "ToonThermostat: Invalid data received!");
			m_bDoLogin = true;
			return;
		}
		if (root["success"].empty() == true)
		{
			_log.Log(LOG_ERROR, "ToonThermostat: setPoint request not successful, restarting..!");
			m_bDoLogin = true;
			return;
		}
		if (root["success"] == false)
		{
			_log.Log(LOG_ERROR, "ToonThermostat: setPoint request not successful, restarting..!");
			m_bDoLogin = true;
			return;
		}
		SendSetPointSensor(idx, temp, "Room Setpoint");
		m_retry_counter = 0;
		m_poll_counter = TOON_POLL_INTERVAL_SHORT;
	}
}
Example #13
0
void CDaikin::GetControlInfo()
{
	std::string sResult;
#ifdef DEBUG_DaikinR
	sResult = ReadFile("E:\\Daikin_get_control_info.txt");
#else
	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 << "/aircon/get_control_info";

	if (!HTTPClient::GET(szURL.str(), sResult))
	{
		_log.Log(LOG_ERROR, "Daikin: Error connecting to: %s", m_szIPAddress.c_str());
		return;
	}
#ifdef DEBUG_DaikinW
	SaveString2Disk(sResult, "E:\\Daikin_get_control_info.txt");
#endif
#endif
	if (sResult.find("ret=OK") == std::string::npos)
	{
		_log.Log(LOG_ERROR, "Daikin: Error getting data (check IP/Port)");
		return;
	}
	std::vector<std::string> results;
	StringSplit(sResult, ",", results);
	if (results.size() < 8)
	{
		_log.Log(LOG_ERROR, "Daikin: Invalid data received");
		return;
	}
	std::vector<std::string>::const_iterator itt;
	for (itt = results.begin(); itt != results.end(); ++itt)
	{
		std::string sVar = *itt;
		std::vector<std::string> results2;
		StringSplit(sVar, "=", results2);
		if (results2.size() != 2)
			continue;
		if (results2[0] == "mode")
		{
			//0-1-7 auto
			//2 dehum
			//3 cooling
			//4 heating
			//6 fan
		}
		else if (results2[0] == "stemp")
		{
			//Target Temperature
			SendSetPointSensor(1, 1, 1, static_cast<float>(atof(results2[1].c_str())), "Target Temperature");
		}

	}
	//UpdateSwitch(1, Idx, (lValue == 1) ? true : false, 100, sstr.str());

}