Beispiel #1
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;
}
Beispiel #2
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");
}
Beispiel #3
0
void CHardwareMonitor::UpdateSystemSensor(const std::string& qType, const int dindex, const std::string& devName, const std::string& devValue)
{
	if (!m_HwdID) {
#ifdef _DEBUG
		_log.Log(LOG_NORM,"Hardware Monitor: Id not found!");
#endif		
		return;
	}
	int doffset = 0;
	if (qType == "Temperature")
	{
		doffset = 1000;
		float temp = static_cast<float>(atof(devValue.c_str()));
		SendTempSensor(doffset + dindex, temp, devName);
	}
	else if (qType == "Load")
	{
		doffset = 1100;
		float perc = static_cast<float>(atof(devValue.c_str()));
		SendPercentage(doffset + dindex, perc, devName);
	}
	else if (qType == "Fan")
	{
		doffset = 1200;
		int fanspeed = atoi(devValue.c_str());
		SendFanSensor(doffset + dindex, fanspeed, devName);
	}
	else if (qType == "Voltage")
	{
		doffset = 1300;
		float volt = static_cast<float>(atof(devValue.c_str()));
		SendVoltage(doffset + dindex, volt, devName);
	}
	else if (qType == "Current")
	{
		doffset = 1400;
		float curr = static_cast<float>(atof(devValue.c_str()));
		SendCurrent(doffset + dindex, curr, devName);
	}
	return;
}
Beispiel #4
0
void CHardwareMonitor::GetInternalTemperature()
{
	std::vector<std::string> ret = ExecuteCommandAndReturn(szInternalTemperatureCommand);
	if (ret.empty())
		return;
	std::string tmpline = ret[0];
	if (tmpline.find("temp=") == std::string::npos)
		return;
	tmpline = tmpline.substr(5);
	size_t pos = tmpline.find("'");
	if (pos != std::string::npos)
	{
		tmpline = tmpline.substr(0, pos);
	}

	float temperature = static_cast<float>(atof(tmpline.c_str()));
	if (temperature == 0)
		return; //hardly possible for a on board temp sensor, if it is, it is probably not working

	if ((temperature != 85) && (temperature > -273))
	{
		SendTempSensor(1, temperature, "Internal Temperature");
	}
}
Beispiel #5
0
void CAccuWeather::GetMeterDetails()
{
	std::string sResult;
#ifdef DEBUG_AccuWeatherR
	sResult=ReadFile("E:\\AccuWeather.json");
#else
	std::stringstream sURL;
	std::string szLoc = CURLEncode::URLEncode(m_LocationKey);
	sURL << "https://dataservice.accuweather.com/currentconditions/v1/" << szLoc << "?apikey=" << m_APIKey << "&details=true";
	try
	{
		bool bret;
		std::string szURL = sURL.str();
		bret = HTTPClient::GET(szURL, sResult);
		if (!bret)
		{
			_log.Log(LOG_ERROR, "AccuWeather: Error getting http data!");
			return;
		}
	}
	catch (...)
	{
		_log.Log(LOG_ERROR, "AccuWeather: Error getting http data!");
		return;
	}
#endif
#ifdef DEBUG_AccuWeatherW
	SaveString2Disk(sResult, "E:\\AccuWeather.json");
#endif

	try
	{
		Json::Value root;

		Json::Reader jReader;
		bool ret = jReader.parse(sResult, root);
		if (!ret)
		{
			_log.Log(LOG_ERROR, "AccuWeather: Invalid data received!");
			return;
		}

		if (root.size() < 1)
		{
			_log.Log(LOG_ERROR, "AccuWeather: Invalid data received!");
			return;
		}
		root = root[0];

		if (root["LocalObservationDateTime"].empty())
		{
			_log.Log(LOG_ERROR, "AccuWeather: Invalid data received, or unknown location!");
			return;
		}

		float temp = 0;
		int humidity = 0;
		int barometric = 0;
		int barometric_forcast = baroForecastNoInfo;

		if (!root["Temperature"].empty())
		{
			temp = root["Temperature"]["Metric"]["Value"].asFloat();
		}

		if (!root["RelativeHumidity"].empty())
		{
			humidity = root["RelativeHumidity"].asInt();
		}
		if (!root["Pressure"].empty())
		{
			barometric = atoi(root["Pressure"]["Metric"]["Value"].asString().c_str());
			if (barometric < 1000)
				barometric_forcast = baroForecastRain;
			else if (barometric < 1020)
				barometric_forcast = baroForecastCloudy;
			else if (barometric < 1030)
				barometric_forcast = baroForecastPartlyCloudy;
			else
				barometric_forcast = baroForecastSunny;

			if (!root["WeatherIcon"].empty())
			{
				int forcasticon = atoi(root["WeatherIcon"].asString().c_str());
				switch (forcasticon)
				{
				case 1:
				case 2:
				case 3:
					barometric_forcast = baroForecastSunny;
					break;
				case 4:
				case 5:
				case 6:
					barometric_forcast = baroForecastCloudy;
					break;
				case 7:
				case 8:
				case 9:
				case 10:
				case 11:
				case 20:
				case 21:
				case 22:
				case 23:
				case 24:
				case 25:
				case 26:
				case 27:
				case 28:
				case 29:
				case 39:
				case 40:
				case 41:
				case 42:
				case 43:
				case 44:
					barometric_forcast = baroForecastRain;
					break;
				case 12:
				case 13:
				case 14:
				case 15:
				case 16:
				case 17:
				case 18:
				case 19:
					barometric_forcast = baroForecastCloudy;
					break;
				}
			}
		}

		if (barometric != 0)
		{
			//Add temp+hum+baro device
			SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB");
		}
		else if (humidity != 0)
		{
			//add temp+hum device
			SendTempHumSensor(1, 255, temp, humidity, "TempHum");
		}
		else
		{
			//add temp device
			SendTempSensor(1, 255, temp, "Temperature");
		}

		//Wind
		if (!root["Wind"].empty())
		{
			int wind_degrees = -1;
			float windspeed_ms = 0;
			float windgust_ms = 0;
			float wind_temp = temp;
			float wind_chill = temp;

			if (!root["Wind"]["Direction"].empty())
			{
				wind_degrees = root["Wind"]["Direction"]["Degrees"].asInt();
			}
			if (!root["Wind"]["Speed"].empty())
			{
				windspeed_ms = root["Wind"]["Speed"]["Metric"]["Value"].asFloat() / 3.6f; //km/h to m/s
			}
			if (!root["WindGust"].empty())
			{
				if (!root["WindGust"]["Speed"].empty())
				{
					windgust_ms = root["WindGust"]["Speed"]["Metric"]["Value"].asFloat() / 3.6f; //km/h to m/s
				}
			}
			if (!root["RealFeelTemperature"].empty())
			{
				wind_chill = root["RealFeelTemperature"]["Metric"]["Value"].asFloat();
			}
			if (wind_degrees != -1)
			{
				SendWind(1, 255, wind_degrees, windspeed_ms, windgust_ms, temp, wind_chill, true, "Wind");
			}
		}

		//UV
		if (!root["UVIndex"].empty())
		{
			float UV = static_cast<float>(atof(root["UVIndex"].asString().c_str()));
			if ((UV < 16) && (UV >= 0))
			{
				SendUVSensor(0, 1, 255, UV, "UV");
			}
		}

		//Rain
		if (!root["PrecipitationSummary"].empty())
		{
			if (!root["PrecipitationSummary"]["Precipitation"].empty())
			{
				float RainCount = static_cast<float>(atof(root["PrecipitationSummary"]["Precipitation"]["Metric"]["Value"].asString().c_str()));
				if ((RainCount != -9999.00f) && (RainCount >= 0.00f))
				{
					RBUF tsen;
					memset(&tsen, 0, sizeof(RBUF));
					tsen.RAIN.packetlength = sizeof(tsen.RAIN) - 1;
					tsen.RAIN.packettype = pTypeRAIN;
					tsen.RAIN.subtype = sTypeRAINWU;
					tsen.RAIN.battery_level = 9;
					tsen.RAIN.rssi = 12;
					tsen.RAIN.id1 = 0;
					tsen.RAIN.id2 = 1;

					tsen.RAIN.rainrateh = 0;
					tsen.RAIN.rainratel = 0;

					if (!root["PrecipitationSummary"]["PastHour"].empty())
					{
						float rainrateph = static_cast<float>(atof(root["PrecipitationSummary"]["PastHour"]["Metric"]["Value"].asString().c_str()));
						if (rainrateph != -9999.00f)
						{
							int at10 = round(std::abs(rainrateph*10.0f));
							tsen.RAIN.rainrateh = (BYTE)(at10 / 256);
							at10 -= (tsen.RAIN.rainrateh * 256);
							tsen.RAIN.rainratel = (BYTE)(at10);
						}
					}

					int tr10 = int((float(RainCount)*10.0f));
					tsen.RAIN.raintotal1 = 0;
					tsen.RAIN.raintotal2 = (BYTE)(tr10 / 256);
					tr10 -= (tsen.RAIN.raintotal2 * 256);
					tsen.RAIN.raintotal3 = (BYTE)(tr10);

					sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255);
				}
			}
		}

		//Visibility
		if (!root["Visibility"].empty())
		{
			if (!root["Visibility"]["Metric"].empty())
			{
				float visibility = root["Visibility"]["Metric"]["Value"].asFloat();
				if (visibility >= 0)
				{
					_tGeneralDevice gdevice;
					gdevice.subtype = sTypeVisibility;
					gdevice.floatval1 = visibility;
					sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);
				}
			}
		}

		//Forecast URL
		if (!root["Link"].empty())
		{
			m_ForecastURL = root["Link"].asString();
		}
	}
	catch (...)
	{
		_log.Log(LOG_ERROR, "AccuWeather: Error parsing JSon data!");
	}
}
Beispiel #6
0
void Meteostick::ParseLine()
{
	if (m_bufferpos < 1)
		return;
	std::string sLine((char*)&m_buffer);

	std::vector<std::string> results;
	StringSplit(sLine, " ", results);
	if (results.size() < 1)
		return; //invalid data

	switch (m_state)
	{
	case MSTATE_INIT:
		if (sLine.find("# MeteoStick Version") == 0) {
			_log.Log(LOG_STATUS, sLine.c_str());
			return;
		}
		if (results[0] == "?")
		{
			//Turn off filters
			write("f0\n");
			m_state = MSTATE_FILTERS;
		}
		return;
	case MSTATE_FILTERS:
		//Set output to 'computer values'
		write("o1\n");
		m_state = MSTATE_VALUES;
		return;
	case MSTATE_VALUES:
#ifdef USE_868_Mhz
		//Set listen frequency to 868Mhz
		write("m1\n");
#else
		//Set listen frequency to 915Mhz
		write("m0\n");
#endif
		m_state = MSTATE_DATA;
		return;
	}

	if (m_state != MSTATE_DATA)
		return;

	if (results.size() < 3)
		return;

	unsigned char rCode = results[0][0];
	if (rCode == '#')
		return;

//#ifdef _DEBUG
	_log.Log(LOG_NORM, sLine.c_str());
//#endif

	switch (rCode)
	{
	case 'B':
		//temperature in Celsius, pressure in hPa
		if (results.size() >= 3)
		{
			float temp = static_cast<float>(atof(results[1].c_str()));
			float baro = static_cast<float>(atof(results[2].c_str()));

			SendTempBaroSensor(0, temp, baro, "Meteostick Temp+Baro");
		}
		break;
	case 'W':
		//current wind speed in m / s, wind direction in degrees
		if (results.size() >= 5)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			if (m_LastOutsideTemp[ID%MAX_IDS] != 12345)
			{
				float speed = static_cast<float>(atof(results[2].c_str()));
				int direction = static_cast<int>(atoi(results[3].c_str()));
				SendWindSensor(ID, m_LastOutsideTemp[ID%MAX_IDS], speed, direction, "Wind");
			}
		}
		break;
	case 'T':
		//temperature in degree Celsius, humidity in percent
		if (results.size() >= 5)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			float temp = static_cast<float>(atof(results[2].c_str()));
			int hum = static_cast<int>(atoi(results[3].c_str()));

			SendTempHumSensor(ID, temp, hum, "Outside Temp+Hum");
			m_LastOutsideTemp[ID%MAX_IDS] = temp;
			m_LastOutsideHum[ID%MAX_IDS] = hum;
		}
		break;
	case 'R':
		//Rain
		//counter value (value 0 - 255), ticks, 1 tick = 0.2mm or 0.01in
		//it only has a small counter, so we should make the total counter ourselfses
		if (results.size() >= 4)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			int raincntr = atoi(results[2].c_str());
			float Rainmm = 0;
			if (m_LastRainValue[ID%MAX_IDS] != -1)
			{
				int cntr_diff = (raincntr - m_LastRainValue[ID%MAX_IDS])&255;
				Rainmm = float(cntr_diff);
#ifdef RAIN_IN_MM
				//one tick is one mm
				Rainmm*=0.2f; //convert to mm;
#else
				//one tick is 0.01 inch, we need to convert this also to mm
				//Rainmm *= 0.01f; //convert to inch
				//Rainmm *= 25.4f; //convert to mm
				//or directly
				Rainmm *= 0.254;
#endif
			}
			m_LastRainValue[ID%MAX_IDS] = raincntr;

			if (m_ActRainCounter[ID%MAX_IDS] == -1)
			{
				//Get Last stored Rain counter
				float rcounter=GetRainSensorCounter(ID);
				m_ActRainCounter[ID%MAX_IDS] = rcounter;
			}
			m_ActRainCounter[ID%MAX_IDS] += Rainmm;

			SendRainSensor(ID, m_ActRainCounter[ID%MAX_IDS], "Rain");
		}
		break;
	case 'S':
		//solar radiation, solar radiation in W / qm
		if (results.size() >= 4)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			float Radiation = static_cast<float>(atof(results[2].c_str()));
			SendSolarRadiationSensor(ID, Radiation, "Solar Radiation");
		}
		break;
	case 'U':
		//UV index
		if (results.size() >= 4)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			float UV = static_cast<float>(atof(results[2].c_str()));
			SendUVSensor(ID, UV, "UV");
		}
		break;
	case 'L':
		//wetness data of a leaf station
		//channel number (1 - 4), leaf wetness (0-15)
		if (results.size() >= 5)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			unsigned char Channel = (unsigned char)atoi(results[2].c_str());
			unsigned char Wetness = (unsigned char)atoi(results[3].c_str());
			SendLeafWetnessRainSensor(ID, Channel, Wetness, "Leaf Wetness");
		}
		break;
	case 'M':
		//soil moisture of a soil station
		//channel number (1 - 4), Soil moisture in cbar(0 - 200)
		if (results.size() >= 5)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			unsigned char Channel = (unsigned char)atoi(results[2].c_str());
			unsigned char Moisture = (unsigned char)atoi(results[3].c_str());
			SendSoilMoistureSensor(ID, Channel, Moisture, "Soil Moisture");
		}
		break;
	case 'O':
		//soil / leaf temperature of a soil / leaf station
		//channel number (1 - 4), soil / leaf temperature in degrees Celsius
		if (results.size() >= 5)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			unsigned char Channel = (unsigned char)atoi(results[2].c_str());
			float temp = static_cast<float>(atof(results[3].c_str()));
			unsigned char finalID = (ID * 10) + Channel;
			SendTempSensor(finalID, temp, "Soil/Leaf Temp");
		}
		break;
	case 'P':
		//solar panel power in(0 - 100)
		if (results.size() >= 4)
		{
			unsigned char ID = (unsigned char)atoi(results[1].c_str());
			float Percentage = static_cast<float>(atof(results[2].c_str()));
			SendPercentage(ID, Percentage, "power of solar panel");
		}
		break;
	default:
		_log.Log(LOG_STATUS, "Unknown Type: %c", rCode);
		break;
	}

}
Beispiel #7
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);
		}
	}
}
int SolarEdgeBase::ParsePacket0x0500(const unsigned char *pData, int dlen)
{
	const unsigned char *b=pData;
	short *pShort;

	int orgdlen=dlen;
	//Meter and Panel report
	while (dlen>20)
	{
		bool bIsPanel=false;
		bool bIsMain=false;
		bool bIs0300=false;
		//0000 for Panel, 0010 for Main?
		pShort=(short*)b;
		int ReportType=*pShort;
		b+=2;
		dlen-=2;

		if (ReportType==0x000)
		{
			bIsPanel=true;
			bIsMain=false;
			bIs0300=false;
		}
		else if (ReportType==0x0010)
		{
			bIsPanel=false;
			bIsMain=true;
			bIs0300=false;
		}
		else if (ReportType==0x0300)
		{
			bIsPanel=false;
			bIsMain=false;
			bIs0300=true;
		}
		else
		{
			//don't know you!
			return orgdlen-2;
		}

		//PanelID/Main
		unsigned long ID2=*(unsigned long*)b;
		//sprintf_s(szTmp,"\"%08X\"",ID2);
		b+=4;
		dlen-=4;
		//rest bytes
		pShort=(short*)b;
		int restbytes=*pShort;
		//sprintf_s(szTmp,"\"%04d\"",restbytes);
		b+=2;
		dlen-=2;

		const unsigned char *b2=(const BYTE*)b;
		int len2=restbytes;
		//Something
		//sprintf_s(szTmp,"\"%02X%02X\"",b2[0],b2[1]);
		b2+=2;
		len2-=2;
		//F052 (F352 for 0300)
		b2+=2;
		len2-=2;
		//2 times ID
		b2+=4;
		len2-=4;
		//uL=*(unsigned long*)b2;
		b2+=4;
		len2-=4;

		if (bIsMain)
		{
			//Temp
			float temp=GetFloat(b2);
			b2+=4;
			//Watt P-Out
			float Watt=GetFloat(b2);
			b2+=4;
			float Pac=GetFloat(b2);
			b2+=4;
			//AC Voltage
			float voltageAC=GetFloat(b2);
			b2+=4;
			//Iets2
			float Iets2=GetFloat(b2);
			b2+=4;
			//Frequency
			float freq=GetFloat(b2);
			b2+=4;
			//Iets3
			float Iets3=GetFloat(b2);
			b2+=4;
			//Iets4
			float Iets4=GetFloat(b2);
			b2+=4;
			//DC Voltage
			float voltageDC=GetFloat(b2);
			b2+=4;
			//Iets5
			float Iets5=GetFloat(b2);
			b2+=4;
			//Counter
			float counter=GetFloat(b2);
			b2+=4;
			SendMeter(0,1, Pac/100.0f, counter/1000.0f, "SolarMain");
			SendTempSensor(1,temp,"SolarMain");
			SendPercentage(SE_FREQ,freq,"Hz");
			SendVoltage(SE_VOLT_AC,voltageAC,"AC");
			SendVoltage(SE_VOLT_DC,voltageDC,"DC");
		}
		b+=restbytes;
		dlen-=restbytes;
		continue;
	}
	return (b-pData);
}
Beispiel #9
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");
	}
}
Beispiel #10
0
void SolarMaxTCP::ParseLine()
{
	std::string InputStr = std::string((const char*)&m_buffer);
	size_t npos = InputStr.find("|");
	if (npos == std::string::npos)
	{
		_log.Log(LOG_ERROR, "SolarMax: Invalid data received!");
		return;
	}
	InputStr = InputStr.substr(npos + 4);
	npos = InputStr.find("|");
	if (npos == std::string::npos)
	{
		_log.Log(LOG_ERROR, "SolarMax: Invalid data received!");
		return;
	}
	InputStr = InputStr.substr(0,npos);

	std::vector<std::string> results;
	StringSplit(InputStr, ";", results);
	if (results.size() < 2)
		return; //invalid data

	std::vector<std::string>::const_iterator itt;

	double kwhCounter = 0;
	double ActUsage = 0;

	for (itt = results.begin(); itt != results.end(); ++itt)
	{
		std::vector<std::string> varresults;
		StringSplit(*itt, "=", varresults);
		if (varresults.size() !=2)
			continue;

		std::string sLabel = varresults[0];
		std::string sVal = varresults[1];

		if (sLabel == "KT0")
		{
			//Energy total
			kwhCounter = SolarMaxGetHexStringValue(sVal);// / 10.0f;
		}
		else if (sLabel == "KDY")
		{
			//Energy Today
		}
		else if (sLabel == "PAC")
		{
			//AC power
			ActUsage = SolarMaxGetHexStringValue(sVal)/2.0f;
		}
		else if (sLabel == "UDC")
		{
			//DC voltage [mV]
			float voltage = float(SolarMaxGetHexStringValue(sVal)) / 10.0f;
			SendVoltageSensor(1, 2, 255, voltage, "DC voltage");
		}
		else if (sLabel == "UL1")
		{
			//AC voltage [mV]
			float voltage = float(SolarMaxGetHexStringValue(sVal)) / 10.0f;
			SendVoltageSensor(1, 3, 255, voltage, "AC voltage");
		}
		else if (sLabel == "IDC")
		{
			//DC current [mA]
			float amps = float(SolarMaxGetHexStringValue(sVal)) / 100.0f;
			SendCurrentSensor(4, 255, amps, 0, 0, "DC current");
		}
		else if (sLabel == "IL1")
		{
			//AC current [mA]
			float amps = float(SolarMaxGetHexStringValue(sVal)) / 100.0f;
			SendCurrentSensor(5, 255, amps, 0, 0, "AC current");
		}
		else if (sLabel == "PIN")
		{
			//Power installed [mW] (PIN)
			//float power_installed = (float)SolarMaxGetHexStringValue(sVal);
		}
		else if (sLabel == "PRL")
		{
			//AC power [%]
			float percentage = (float)SolarMaxGetHexStringValue(sVal);
			SendPercentageSensor(6, 6, 255, percentage, "AC power Percentage");
		}
		else if (sLabel == "TNF")
		{
			//AC Frequency (Hz)
			float freq = (float)SolarMaxGetHexStringValue(sVal)/100;
			SendPercentageSensor(7, 7, 255, freq, "Hz");
		}
		else if (sLabel == "TKK")
		{
			//Temperature Heat Sink
			float temp = (float)SolarMaxGetHexStringValue(sVal);// / 10.0f;
			SendTempSensor(8, 255, temp,"Temperature Heat Sink");
		}
	}
	if (kwhCounter != 0)
	{
		SendKwhMeterOldWay(1, 1, 255, ActUsage/1000.0f, kwhCounter, "kWh Meter");
	}

}
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());
	}
}
Beispiel #12
0
bool CRFLink::ParseLine(const std::string &sLine)
{
	m_LastReceivedTime = mytime(NULL);

	std::vector<std::string> results;
	StringSplit(sLine, ";", results);
	if (results.size() < 2)
		return false; //not needed

	bool bHideDebugLog = (
		(sLine.find("PONG") != std::string::npos)||
		(sLine.find("PING") != std::string::npos)
		);

	int RFLink_ID = atoi(results[0].c_str());
	if (RFLink_ID != 20)
	{
		return false; //only accept RFLink->Master messages
	}

#ifdef ENABLE_LOGGING
	if (!bHideDebugLog)
		_log.Log(LOG_NORM, "RFLink: %s", sLine.c_str());
#endif

	//std::string Sensor_ID = results[1];
	if (results.size() >2)
	{
		//Status reply
		std::string Name_ID = results[2];
		if (Name_ID.find("Nodo RadioFrequencyLink") != std::string::npos)
		{
			_log.Log(LOG_STATUS, "RFLink: Controller Initialized!...");
			//Enable DEBUG
			//write("10;RFDEBUG=ON;\n");

			//Enable Undecoded DEBUG
			//write("10;RFUDEBUG=ON;\n");
			return true;
		}
		if (Name_ID.find("OK") != std::string::npos) {
			//_log.Log(LOG_STATUS, "RFLink: OK received!...");
            m_bTXokay = true; // variable to indicate an OK was received
			return true;
		}
	}
	if (results.size() < 4)
		return true;

	if (results[3].find("ID=") == std::string::npos)
		return false; //??

	std::stringstream ss;
	unsigned int ID;
	ss << std::hex << results[3].substr(3);
	ss >> ID;

	int Node_ID = (ID & 0xFF00) >> 8;
	int Child_ID = ID & 0xFF;

	bool bHaveTemp = false; float temp = 0;
	bool bHaveHum = false; int humidity = 0;
	bool bHaveHumStatus = false; int humstatus = 0;
	bool bHaveBaro = false; float baro = 0;
	int baroforecast = 0;
	bool bHaveRain = false; int raincounter = 0;
	bool bHaveLux = false; float lux = 0;
	bool bHaveUV = false; float uv = 0;
    
	bool bHaveWindDir = false; int windir = 0;
	bool bHaveWindSpeed = false; float windspeed = 0;
	bool bHaveWindGust = false; float windgust = 0;
	bool bHaveWindTemp = false; float windtemp = 0;
	bool bHaveWindChill = false; float windchill = 0;

	bool bHaveRGB = false; int rgb = 0;
	bool bHaveRGBW = false; int rgbw = 0;
	bool bHaveSound = false; int sound = 0;
	bool bHaveCO2 = false; int co2 = 0;
	bool bHaveBlind = false; int blind = 0;   

	bool bHaveKWatt = false; float kwatt = 0;   
	bool bHaveWatt = false; float watt = 0;   
	bool bHaveDistance = false; float distance = 0;   
	bool bHaveMeter = false; float meter = 0;   
	bool bHaveVoltage = false; float voltage = 0;   
	bool bHaveCurrent = false; float current = 0;   
    
	bool bHaveSwitch = false; int switchunit = 0; 
	bool bHaveSwitchCmd = false; std::string switchcmd = ""; int switchlevel = 0;

	int BatteryLevel = 255;
	std::string tmpstr;
	int iTemp;
	for (size_t ii = 4; ii < results.size(); ii++)
	{
		if (results[ii].find("TEMP") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveTemp = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			temp = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("HUM") != std::string::npos)
		{
			bHaveHum = true;
			humidity = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("HSTATUS") != std::string::npos)
		{
			bHaveHumStatus = true;
			humstatus = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("BARO") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveBaro = true;
			baro = float(iTemp);
		}
		else if (results[ii].find("BFORECAST") != std::string::npos)
		{
			baroforecast = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RAIN") != std::string::npos)
		{
			bHaveRain = true;
			raincounter = RFLinkGetHexStringValue(results[ii]);
		}
		else if (results[ii].find("LUX") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveLux = true;
			lux = float(iTemp);
		}
		else if (results[ii].find("UV") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveUV = true;
			uv = float(iTemp);
		}
		else if (results[ii].find("BAT") != std::string::npos)
		{
			tmpstr = RFLinkGetStringValue(results[ii]);
			BatteryLevel = (tmpstr == "OK") ? 100 : 0;
		}
		else if (results[ii].find("WINDIR") != std::string::npos)
		{
			bHaveWindDir = true;
			windir = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("WINSP") != std::string::npos)
		{
			bHaveWindSpeed = true;
			iTemp = RFLinkGetHexStringValue(results[ii]);
			windspeed = float(iTemp) * 0.0277778f; //convert to m/s
		}
		else if (results[ii].find("WINGS") != std::string::npos)
		{
			bHaveWindGust = true;
			iTemp = RFLinkGetHexStringValue(results[ii]);
			windgust = float(iTemp) * 0.0277778f; //convert to m/s
		}
		else if (results[ii].find("WINTMP") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWindTemp = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			windtemp = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("WINCHL") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWindChill = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			windchill = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("SOUND") != std::string::npos)
		{
			bHaveSound = true;
			sound = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("CO2") != std::string::npos)
		{
			bHaveCO2 = true;
			co2 = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RGBW") != std::string::npos)
		{
			bHaveRGBW = true;
			rgbw = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RGB") != std::string::npos)
		{
			bHaveRGB = true;
			rgb = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("BLIND") != std::string::npos)
		{
			bHaveBlind = true;
			blind = RFLinkGetIntStringValue(results[ii]);
		}

		else if (results[ii].find("KWATT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveKWatt = true;
			kwatt = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("WATT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWatt = true;
			watt = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("DIST") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveDistance = true;
			distance = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("METER") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveMeter = true;
			meter = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("VOLT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveVoltage = true;
			voltage = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("CURRENT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveCurrent = true;
			current = float(iTemp) / 10.0f;
		}

		else if (results[ii].find("SWITCH") != std::string::npos)
		{
			bHaveSwitch = true;
			switchunit = RFLinkGetHexStringValue(results[ii]);
		}
		else if (results[ii].find("CMD") != std::string::npos)
		{
			bHaveSwitchCmd = true;
			switchcmd = RFLinkGetStringValue(results[ii]);
		}
		else if (results[ii].find("SMOKEALERT") != std::string::npos)
		{
			bHaveSwitch = true;
			switchunit = 1;
			bHaveSwitchCmd = true;
			switchcmd = RFLinkGetStringValue(results[ii]);
		}
	}

	if (bHaveTemp&&bHaveHum&&bHaveBaro)
	{
		SendTempHumBaroSensor(ID, BatteryLevel, temp, humidity, baro, baroforecast);
	}
	else if (bHaveTemp&&bHaveHum)
	{
		SendTempHumSensor(ID, BatteryLevel, temp, humidity, "TempHum");
	}
	else if (bHaveTemp)
	{
		SendTempSensor(ID, BatteryLevel, temp,"Temp");
	}
	else if (bHaveHum)
	{
		SendHumiditySensor(ID, BatteryLevel, humidity);
	}
	else if (bHaveBaro)
	{
		SendBaroSensor(Node_ID, Child_ID, BatteryLevel, baro, baroforecast);
	}

	if (bHaveLux)
	{
		SendLuxSensor(Node_ID, Child_ID, BatteryLevel, lux, "Lux");
	}

	if (bHaveUV)
	{
  		SendUVSensor(Node_ID, Child_ID, BatteryLevel, uv);
	}
    
	if (bHaveRain)
	{
		SendRainSensor(ID, BatteryLevel, float(raincounter), "Rain");
	}

	if (bHaveWindDir && bHaveWindSpeed && bHaveWindGust && bHaveWindChill)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind");
	}
	else if (bHaveWindDir && bHaveWindGust)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind");
	}
	else if (bHaveWindSpeed)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind");
	}
    
	if (bHaveCO2)
	{
		SendAirQualitySensor((ID & 0xFF00) >> 8, ID & 0xFF, BatteryLevel, co2, "CO2");
	}
	if (bHaveSound)
	{
		SendSoundSensor(ID, BatteryLevel, sound, "Sound");
	}

	if (bHaveRGB)
	{
		//RRGGBB
		SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgb, false, "RGB Light");
	}
	if (bHaveRGBW)
	{
		//RRGGBBWW
		SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgbw, true, "RGBW Light");
	}
	if (bHaveBlind)
	{
		SendBlindSensor(Node_ID, Child_ID, BatteryLevel, blind, "Blinds/Window");
	}

	if (bHaveKWatt)
	{
		SendKwhMeter(Node_ID, Child_ID, BatteryLevel, kwatt / 1000.0f, kwatt, "Meter");
	}
	if (bHaveWatt)
	{
		SendKwhMeter(Node_ID, Child_ID, BatteryLevel, 0, watt, "Meter");
	}
	if (bHaveDistance)
	{
		SendDistanceSensor(Node_ID, Child_ID, BatteryLevel, distance);
	}
	if (bHaveMeter)
	{
		SendMeterSensor(Node_ID, Child_ID, BatteryLevel, meter);
	}
	if (bHaveVoltage)
	{
		SendVoltageSensor(Node_ID, Child_ID, BatteryLevel, voltage, "Voltage");
	}
	if (bHaveCurrent)
	{
		SendCurrentSensor(ID, BatteryLevel, current, 0, 0, "Current");
	}
    
	if (bHaveSwitch && bHaveSwitchCmd)
	{
		std::string switchType = results[2];
		SendSwitchInt(ID, switchunit, BatteryLevel, switchType, switchcmd, switchlevel);
	}

    return true;
}
Beispiel #13
0
void OTGWBase::ParseLine()
{
	if (m_bufferpos<2)
		return;
	std::string sLine((char*)&m_buffer);

	std::vector<std::string> results;
	StringSplit(sLine,",",results);
	if (results.size()==25)
	{
		//status report
		//0    Status (MsgID=0) - Printed as two 8-bit bitfields
		//1    Control setpoint (MsgID=1) - Printed as a floating point value
		//2    Remote parameter flags (MsgID= 6) - Printed as two 8-bit bitfields
		//3    Maximum relative modulation level (MsgID=14) - Printed as a floating point value
		//4    Boiler capacity and modulation limits (MsgID=15) - Printed as two bytes
		//5    Room Setpoint (MsgID=16) - Printed as a floating point value
		//6    Relative modulation level (MsgID=17) - Printed as a floating point value
		//7    CH water pressure (MsgID=18) - Printed as a floating point value
		//8    Room temperature (MsgID=24) - Printed as a floating point value
		//9    Boiler water temperature (MsgID=25) - Printed as a floating point value
		//10    DHW temperature (MsgID=26) - Printed as a floating point value
		//11    Outside temperature (MsgID=27) - Printed as a floating point value
		//12    Return water temperature (MsgID=28) - Printed as a floating point value
		//13    DHW setpoint boundaries (MsgID=48) - Printed as two bytes
		//14    Max CH setpoint boundaries (MsgID=49) - Printed as two bytes
		//15    DHW setpoint (MsgID=56) - Printed as a floating point value
		//16    Max CH water setpoint (MsgID=57) - Printed as a floating point value
		//17    Burner starts (MsgID=116) - Printed as a decimal value
		//18    CH pump starts (MsgID=117) - Printed as a decimal value
		//19    DHW pump/valve starts (MsgID=118) - Printed as a decimal value
		//20    DHW burner starts (MsgID=119) - Printed as a decimal value
		//21    Burner operation hours (MsgID=120) - Printed as a decimal value
		//22    CH pump operation hours (MsgID=121) - Printed as a decimal value
		//23    DHW pump/valve operation hours (MsgID=122) - Printed as a decimal value
		//24    DHW burner operation hours (MsgID=123) - Printed as a decimal value
		_tOTGWStatus _status;
		int idx=0;

		_status.MsgID=results[idx++];
		if (_status.MsgID.size()==17)
		{
			bool bCH_enabled=(_status.MsgID[7]=='1');														UpdateSwitch(101,bCH_enabled,"CH_enabled");
			bool bDHW_enabled=(_status.MsgID[6]=='1');														UpdateSwitch(102,bDHW_enabled,"DHW_enabled");
			bool bCooling_enable=(_status.MsgID[5]=='1');													UpdateSwitch(103,bCooling_enable,"Cooling_enable");
			bool bOTC_active=(_status.MsgID[4]=='1');														UpdateSwitch(104,bOTC_active,"OTC_active");
			bool bCH2_enabled=(_status.MsgID[3]=='1');														UpdateSwitch(105,bCH2_enabled,"CH2_enabled");

			bool bFault_indication=(_status.MsgID[9+7]=='1');												UpdateSwitch(110,bFault_indication,"Fault_indication");
			bool bCH_active=(_status.MsgID[9+6]=='1');														UpdateSwitch(111,bCH_active,"CH_active");
			bool bDHW_active=(_status.MsgID[9+5]=='1');														UpdateSwitch(112,bDHW_active,"DHW_active");
			bool bFlameOn=(_status.MsgID[9+4]=='1');														UpdateSwitch(113,bFlameOn,"FlameOn");
			bool bCooling_Mode_Active=(_status.MsgID[9+3]=='1');											UpdateSwitch(114,bCooling_Mode_Active,"Cooling_Mode_Active");
			bool bCH2_Active=(_status.MsgID[9+2]=='1');														UpdateSwitch(115,bCH2_Active,"CH2_Active");
			bool bDiagnosticEvent=(_status.MsgID[9+1]=='1');												UpdateSwitch(116,bDiagnosticEvent,"DiagnosticEvent");
		}

		_status.Control_setpoint = static_cast<float>(atof(results[idx++].c_str()));						SendTempSensor(idx - 1, 255, _status.Control_setpoint, "Control Setpoint");
		_status.Remote_parameter_flags=results[idx++];
		_status.Maximum_relative_modulation_level = static_cast<float>(atof(results[idx++].c_str()));
		bool bExists = CheckPercentageSensorExists(idx - 1, 1);
		if ((_status.Maximum_relative_modulation_level != 0) || (bExists))
		{
			SendPercentageSensor(idx - 1, 1, 255, _status.Maximum_relative_modulation_level, "Maximum Relative Modulation Level");
		}
		_status.Boiler_capacity_and_modulation_limits=results[idx++];
		_status.Room_Setpoint = static_cast<float>(atof(results[idx++].c_str()));							UpdateSetPointSensor(idx - 1, ((m_OverrideTemperature!=0.0f) ? m_OverrideTemperature : _status.Room_Setpoint), "Room Setpoint");
		_status.Relative_modulation_level = static_cast<float>(atof(results[idx++].c_str()));
		bExists = CheckPercentageSensorExists(idx - 1, 1);
		if ((_status.Relative_modulation_level != 0) || (bExists))
		{
			SendPercentageSensor(idx - 1, 1, 255, _status.Relative_modulation_level, "Relative modulation level");
		}
		_status.CH_water_pressure = static_cast<float>(atof(results[idx++].c_str()));
		if (_status.CH_water_pressure != 0)
		{
			SendPressureSensor(0, idx - 1, 255, _status.CH_water_pressure, "CH Water Pressure");
		}

		_status.Room_temperature = static_cast<float>(atof(results[idx++].c_str()));						SendTempSensor(idx - 1, 255, _status.Room_temperature, "Room Temperature");
		_status.Boiler_water_temperature = static_cast<float>(atof(results[idx++].c_str()));				SendTempSensor(idx - 1, 255, _status.Boiler_water_temperature, "Boiler Water Temperature");
		_status.DHW_temperature = static_cast<float>(atof(results[idx++].c_str()));							SendTempSensor(idx - 1, 255, _status.DHW_temperature, "DHW Temperature");
		_status.Outside_temperature = static_cast<float>(atof(results[idx++].c_str()));						SendTempSensor(idx - 1, 255, _status.Outside_temperature, "Outside Temperature");
		_status.Return_water_temperature = static_cast<float>(atof(results[idx++].c_str()));				SendTempSensor(idx - 1, 255, _status.Return_water_temperature, "Return Water Temperature");
		_status.DHW_setpoint_boundaries=results[idx++];
		_status.Max_CH_setpoint_boundaries=results[idx++];
		_status.DHW_setpoint = static_cast<float>(atof(results[idx++].c_str()));							UpdateSetPointSensor(idx - 1, _status.DHW_setpoint, "DHW Setpoint");
		_status.Max_CH_water_setpoint = static_cast<float>(atof(results[idx++].c_str()));					UpdateSetPointSensor(idx - 1, _status.Max_CH_water_setpoint, "Max_CH Water Setpoint");
		_status.Burner_starts=atol(results[idx++].c_str());
		_status.CH_pump_starts=atol(results[idx++].c_str());
		_status.DHW_pump_valve_starts=atol(results[idx++].c_str());
		_status.DHW_burner_starts=atol(results[idx++].c_str());
		_status.Burner_operation_hours=atol(results[idx++].c_str());
		_status.CH_pump_operation_hours=atol(results[idx++].c_str());
		_status.DHW_pump_valve_operation_hours=atol(results[idx++].c_str());
		_status.DHW_burner_operation_hours=atol(results[idx++].c_str());
		return;
	}
	else
	{
		if (sLine=="SE")
		{
			_log.Log(LOG_ERROR,"OTGW: Error received!");
		}
		else if (sLine.find("PR: G")!=std::string::npos)
		{
			_tOTGWGPIO _GPIO;
			_GPIO.A=static_cast<int>(sLine[6]- '0');
//			if (_GPIO.A==0 || _GPIO.A==1)
//			{
				UpdateSwitch(96,(_GPIO.A==1),"GPIOAPulledToGround");
//			}
//			else
//			{
				// Remove device (how?)
//			}
			_GPIO.B=static_cast<int>(sLine[7]- '0');
//			if (_GPIO.B==0 || _GPIO.B==1)
//			{
				UpdateSwitch(97,(_GPIO.B==1),"GPIOBPulledToGround");
//			}
//			else
//			{
				// Remove device (how?)
//			}
		}
		else if (sLine.find("PR: I")!=std::string::npos)
		{
			_tOTGWGPIO _GPIO;
			_GPIO.A=static_cast<int>(sLine[6]- '0');
			UpdateSwitch(98,(_GPIO.A==1),"GPIOAStatusIsHigh");
			_GPIO.B=static_cast<int>(sLine[7]- '0');
			UpdateSwitch(99,(_GPIO.B==1),"GPIOBStatusIsHigh");
		}
		else if (sLine.find("PR: O")!=std::string::npos)
		{
			// Check if setpoint is overriden
 			m_OverrideTemperature=0.0f;
			char status=sLine[6];
			if (status == 'c' || status == 't')
			{
				// Get override setpoint value
				m_OverrideTemperature=static_cast<float>(atof(sLine.substr(7).c_str()));
			}
		}
		else if (sLine.find("PR: A") != std::string::npos)
		{
			//Gateway Version
			std::string tmpstr = sLine.substr(6);
			size_t tpos = tmpstr.find(' ');
			if (tpos != std::string::npos)
			{
				m_Version = tmpstr.substr(tpos + 9);
			}
		}
		else
		{
			if (
				(sLine.find("OT") == std::string::npos)&&
				(sLine.find("PS") == std::string::npos)&&
				(sLine.find("SC") == std::string::npos)
				)
			{
				//Dont report OT/PS/SC feedback
				_log.Log(LOG_STATUS,"OTGW: %s",sLine.c_str());
			}
		}
	}

}
Beispiel #14
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;
}
Beispiel #15
0
void CDarkSky::GetMeterDetails()
{
	std::string sResult;
#ifdef DEBUG_DarkSkyR
	sResult=ReadFile("E:\\DarkSky.json");
#else
	std::stringstream sURL;
	std::string szLoc = m_Location;
	std::string szExclude = "minutely,hourly,daily,alerts,flags";
	sURL << "https://api.darksky.net/forecast/" << m_APIKey << "/" << szLoc << "?exclude=" << szExclude;
	try
	{
		bool bret;
		std::string szURL = sURL.str();
		bret = HTTPClient::GET(szURL, sResult);
		if (!bret)
		{
			_log.Log(LOG_ERROR, "DarkSky: Error getting http data!.");
			return;
		}
	}
	catch (...)
	{
		_log.Log(LOG_ERROR, "DarkSky: Error getting http data!");
		return;
	}
#ifdef DEBUG_DarkSkyW
	SaveString2Disk(sResult, "E:\\DarkSky.json");
#endif

#endif
	Json::Value root;

	Json::Reader jReader;
	bool ret=jReader.parse(sResult,root);
	if ((!ret) || (!root.isObject()))
	{
		_log.Log(LOG_ERROR,"DarkSky: Invalid data received! Check Location, use a City or GPS Coordinates (xx.yyyy,xx.yyyyy)");
		return;
	}
	if (root["currently"].empty()==true)
	{
		_log.Log(LOG_ERROR,"DarkSky: Invalid data received, or unknown location!");
		return;
	}
	/*
	std::string tmpstr2 = root.toStyledString();
	FILE *fOut = fopen("E:\\DarkSky.json", "wb+");
	fwrite(tmpstr2.c_str(), 1, tmpstr2.size(), fOut);
	fclose(fOut);
	*/

	float temp;
	int humidity=0;
	int barometric=0;
	int barometric_forcast=baroForecastNoInfo;

	temp=root["currently"]["temperature"].asFloat();
	//Convert to celcius
	temp=float((temp-32)*(5.0/9.0));

	if (root["currently"]["humidity"].empty()==false)
	{
		humidity=round(root["currently"]["humidity"].asFloat()*100.0f);
	}
	if (root["currently"]["pressure"].empty()==false)
	{
		barometric=atoi(root["currently"]["pressure"].asString().c_str());
		if (barometric<1000)
			barometric_forcast=baroForecastRain;
		else if (barometric<1020)
			barometric_forcast=baroForecastCloudy;
		else if (barometric<1030)
			barometric_forcast=baroForecastPartlyCloudy;
		else
			barometric_forcast=baroForecastSunny;

		if (root["currently"]["icon"].empty()==false)
		{
			std::string forcasticon=root["currently"]["icon"].asString();
			if ((forcasticon=="partly-cloudy-day")||(forcasticon=="partly-cloudy-night"))
			{
				barometric_forcast=baroForecastPartlyCloudy;
			}
			else if (forcasticon=="cloudy")
			{
				barometric_forcast=baroForecastCloudy;
			}
			else if ((forcasticon=="clear-day")||(forcasticon=="clear-night"))
			{
				barometric_forcast=baroForecastSunny;
			}
			else if ((forcasticon=="rain")||(forcasticon=="snow"))
			{
				barometric_forcast=baroForecastRain;
			}
		}
	}

	if (barometric!=0)
	{
		//Add temp+hum+baro device
		SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB");
	}
	else if (humidity!=0)
	{
		//add temp+hum device
		SendTempHumSensor(1, 255, temp, humidity, "TempHum");
	}
	else
	{
		//add temp device
		SendTempSensor(1, 255, temp, "Temperature");
	}

	//Wind
	int wind_degrees=-1;
	float windspeed_ms=0;
	float windgust_ms=0;
	float wind_temp=temp;
	float wind_chill=temp;
	int windgust=1;
	float windchill=-1;

	if (root["currently"]["windBearing"].empty()==false)
	{
		wind_degrees=atoi(root["currently"]["windBearing"].asString().c_str());
	}
	if (root["currently"]["windSpeed"].empty()==false)
	{
		if ((root["currently"]["windSpeed"] != "N/A") && (root["currently"]["windSpeed"] != "--"))
		{
			float temp_wind_mph = static_cast<float>(atof(root["currently"]["windSpeed"].asString().c_str()));
			if (temp_wind_mph!=-9999.00f)
			{
				//convert to m/s
				windspeed_ms=temp_wind_mph*0.44704f;
			}
		}
	}
	if (root["currently"]["windGust"].empty()==false)
	{
		if ((root["currently"]["windGust"] != "N/A") && (root["currently"]["windGust"] != "--"))
		{
			float temp_wind_gust_mph = static_cast<float>(atof(root["currently"]["windGust"].asString().c_str()));
			if (temp_wind_gust_mph!=-9999.00f)
			{
				//convert to m/s
				windgust_ms=temp_wind_gust_mph*0.44704f;
			}
		}
	}
	if (root["currently"]["apparentTemperature"].empty()==false)
	{
		if ((root["currently"]["apparentTemperature"] != "N/A") && (root["currently"]["apparentTemperature"] != "--"))
		{
			wind_chill = static_cast<float>(atof(root["currently"]["apparentTemperature"].asString().c_str()));
			//Convert to celcius
			wind_chill=float((wind_chill-32)*(5.0/9.0));
		}
	}
	if (wind_degrees!=-1)
	{
		RBUF tsen;
		memset(&tsen,0,sizeof(RBUF));
		tsen.WIND.packetlength=sizeof(tsen.WIND)-1;
		tsen.WIND.packettype=pTypeWIND;
		tsen.WIND.subtype=sTypeWIND4;
		tsen.WIND.battery_level=9;
		tsen.WIND.rssi=12;
		tsen.WIND.id1=0;
		tsen.WIND.id2=1;

		float winddir=float(wind_degrees);
		int aw=round(winddir);
		tsen.WIND.directionh=(BYTE)(aw/256);
		aw-=(tsen.WIND.directionh*256);
		tsen.WIND.directionl=(BYTE)(aw);

		tsen.WIND.av_speedh=0;
		tsen.WIND.av_speedl=0;
		int sw=round(windspeed_ms*10.0f);
		tsen.WIND.av_speedh=(BYTE)(sw/256);
		sw-=(tsen.WIND.av_speedh*256);
		tsen.WIND.av_speedl=(BYTE)(sw);

		tsen.WIND.gusth=0;
		tsen.WIND.gustl=0;
		int gw=round(windgust_ms*10.0f);
		tsen.WIND.gusth=(BYTE)(gw/256);
		gw-=(tsen.WIND.gusth*256);
		tsen.WIND.gustl=(BYTE)(gw);

		//this is not correct, why no wind temperature? and only chill?
		tsen.WIND.chillh=0;
		tsen.WIND.chilll=0;
		tsen.WIND.temperatureh=0;
		tsen.WIND.temperaturel=0;

		tsen.WIND.tempsign=(wind_temp>=0)?0:1;
		int at10=round(std::abs(wind_temp*10.0f));
		tsen.WIND.temperatureh=(BYTE)(at10/256);
		at10-=(tsen.WIND.temperatureh*256);
		tsen.WIND.temperaturel=(BYTE)(at10);

		tsen.WIND.chillsign=(wind_temp>=0)?0:1;
		at10=round(std::abs(wind_chill*10.0f));
		tsen.WIND.chillh=(BYTE)(at10/256);
		at10-=(tsen.WIND.chillh*256);
		tsen.WIND.chilll=(BYTE)(at10);

		sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255);
	}

	//UV
	if (root["currently"]["uvIndex"].empty() == false)
	{
		if ((root["currently"]["uvIndex"] != "N/A") && (root["currently"]["uvIndex"] != "--"))
		{
			float UV = root["currently"]["uvIndex"].asFloat();
			if ((UV < 16) && (UV >= 0))
			{
				SendUVSensor(0, 1, 255, UV, "UV Index");
			}
		}
	}

	//Rain
	if (root["currently"]["precipIntensity"].empty()==false)
	{
		if ((root["currently"]["precipIntensity"] != "N/A") && (root["currently"]["precipIntensity"] != "--"))
		{
			float RainCount = static_cast<float>(atof(root["currently"]["precipIntensity"].asString().c_str()))*25.4f; //inches to mm
			if ((RainCount!=-9999.00f)&&(RainCount>=0.00f))
			{
				RBUF tsen;
				memset(&tsen,0,sizeof(RBUF));
				tsen.RAIN.packetlength=sizeof(tsen.RAIN)-1;
				tsen.RAIN.packettype=pTypeRAIN;
				tsen.RAIN.subtype=sTypeRAINWU;
				tsen.RAIN.battery_level=9;
				tsen.RAIN.rssi=12;
				tsen.RAIN.id1=0;
				tsen.RAIN.id2=1;

				tsen.RAIN.rainrateh=0;
				tsen.RAIN.rainratel=0;

				int tr10=int((float(RainCount)*10.0f));
				tsen.RAIN.raintotal1=0;
				tsen.RAIN.raintotal2=(BYTE)(tr10/256);
				tr10-=(tsen.RAIN.raintotal2*256);
				tsen.RAIN.raintotal3=(BYTE)(tr10);

				sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255);
			}
		}
	}

	//Visibility
	if (root["currently"]["visibility"].empty()==false)
	{
		if ((root["currently"]["visibility"] != "N/A") && (root["currently"]["visibility"] != "--"))
		{
			float visibility = static_cast<float>(atof(root["currently"]["visibility"].asString().c_str()))*1.60934f; //miles to km
			if (visibility>=0)
			{
				_tGeneralDevice gdevice;
				gdevice.subtype=sTypeVisibility;
				gdevice.floatval1=visibility;
				sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);
			}
		}
	}
	//Solar Radiation
	if (root["currently"]["ozone"].empty()==false)
	{
		if ((root["currently"]["ozone"] != "N/A") && (root["currently"]["ozone"] != "--"))
		{
			float radiation = static_cast<float>(atof(root["currently"]["ozone"].asString().c_str()));
			if (radiation>=0.0f)
			{
				SendCustomSensor(1, 0, 255, radiation, "Ozone Sensor", "DU"); //(dobson units)
			}
		}
	}

}
bool CDavisLoggerSerial::HandleLoopData(const unsigned char *data, size_t len)
{
	const uint8_t *pData=data+1;

#ifndef DEBUG_DAVIS
	if (len!=100)
		return false;

	if (
		(data[1]!='L')||
		(data[2]!='O')||
		(data[3]!='O')||
		(data[96]!=0x0a)||
		(data[97]!=0x0d)
		)
		return false;
	//bool bIsRevA = (data[4]=='P');
#else
//	FILE *fOut=fopen("davisrob.bin","wb+");
//	fwrite(data,1,len,fOut);
//	fclose(fOut);
	unsigned char szBuffer[200];
	FILE *fIn=fopen("E:\\davis2.bin","rb+");
	//FILE *fIn=fopen("davisrob.bin","rb+");
	fread(&szBuffer,1,100,fIn);
	fclose(fIn);
	pData=szBuffer+1;
	bool bIsRevA(szBuffer[4]=='P');
#endif

	RBUF tsen;
	memset(&tsen,0,sizeof(RBUF));


	unsigned char tempIdx=1;

	bool bBaroValid=false;
	float BaroMeter=0;
	bool bInsideTemperatureValid=false;
	float InsideTemperature=0;
	bool bInsideHumidityValid=false;
	int InsideHumidity=0;
	bool bOutsideTemperatureValid=false;
	float OutsideTemperature=0;
	bool bOutsideHumidityValid=false;
	int OutsideHumidity=0;

	bool bWindDirectionValid=false;
	int WindDirection=0;

	bool bWindSpeedValid=false;
	float WindSpeed=0;
	bool bWindSpeedAVR10Valid=false;
	float WindSpeedAVR10=0;

	bool bUVValid=false;
	float UV=0;

	//Barometer
	if ((pData[7]!=0xFF)&&(pData[8]!=0xFF))
	{
		bBaroValid=true;
		BaroMeter=((unsigned int)((pData[8] << 8) | pData[7])) / 29.53f; //in hPa
	}
	//Inside Temperature
	if ((pData[9]!=0xFF)||(pData[10]!=0x7F))
	{
		bInsideTemperatureValid=true;
		InsideTemperature=((unsigned int)((pData[10] << 8) | pData[9])) / 10.f;
		InsideTemperature = (InsideTemperature - 32.0f) * 5.0f / 9.0f;
	}
	//Inside Humidity
	if (pData[11]!=0xFF)
	{
		InsideHumidity=pData[11];
		if (InsideHumidity<101)
			bInsideHumidityValid=true;
	}

	if (bBaroValid&&bInsideTemperatureValid&&bInsideHumidityValid)
	{
		uint8_t forecastitem = pData[89];
		int forecast = 0;

		if ((forecastitem & 0x01) == 0x01)
			forecast = wsbaroforcast_rain;
		else if ((forecastitem & 0x02) == 0x02)
			forecast = wsbaroforcast_cloudy;
		else if ((forecastitem & 0x04) == 0x04)
			forecast = wsbaroforcast_some_clouds;
		else if ((forecastitem & 0x08) == 0x08)
			forecast = wsbaroforcast_sunny;
		else if ((forecastitem & 0x10) == 0x10)
			forecast = wsbaroforcast_snow;

		SendTempHumBaroSensorFloat(tempIdx++, 255, InsideTemperature, InsideHumidity, BaroMeter, forecast, "THB");
	}

	//Outside Temperature
	if ((pData[12]!=0xFF)||(pData[13]!=0x7F))
	{
		bOutsideTemperatureValid=true;
		OutsideTemperature=((unsigned int)((pData[13] << 8) | pData[12])) / 10.f;

		OutsideTemperature = (OutsideTemperature - 32.0f) * 5.0f / 9.0f;
	}
	//Outside Humidity
	if (pData[33]!=0xFF)
	{
		OutsideHumidity=pData[33];
		if (OutsideHumidity<101)
			bOutsideHumidityValid=true;
	}
	if (bOutsideTemperatureValid||bOutsideHumidityValid)
	{
		if ((bOutsideTemperatureValid)&&(bOutsideHumidityValid))
		{
			//Temp+hum
			SendTempHumSensor(tempIdx++, 255, OutsideTemperature, OutsideHumidity,"Outside TempHum");
		}
		else if (bOutsideTemperatureValid)
		{
			//Temp
			SendTempSensor(tempIdx++, 255, OutsideTemperature, "Outside Temp");
		}
		else if (bOutsideHumidityValid)
		{
			//hum
			SendHumiditySensor(tempIdx++, 255, OutsideHumidity, "Outside Humidity");
		}
	}

	tempIdx=10;
	//Add Extra Temp/Hum Sensors
	int iTmp;
	for (int iTmp=0; iTmp<7; iTmp++)
	{
		bool bTempValid=false;
		bool bHumValid=false;
		float temp=0;
		uint8_t hum=0;

		if (pData[18+iTmp]!=0xFF)
		{
			bTempValid=true;
			temp=pData[18+iTmp]-90.0f;
			temp = (temp - 32.0f) * 5.0f / 9.0f;
		}
		if (pData[34+iTmp]!=0xFF)
		{
			bHumValid=true;
			hum=pData[34+iTmp];
		}
		if ((bTempValid)&&(bHumValid))
		{
			//Temp+hum
			SendTempHumSensor(tempIdx++, 255, temp, hum, "Extra TempHum");
		}
		else if (bTempValid)
		{
			//Temp
			SendTempSensor(tempIdx++, 255, temp, "Extra Temp");
		}
		else if (bHumValid)
		{
			//hum
			SendHumiditySensor(tempIdx++, 255, hum, "Extra Humidity");
		}
	}

	tempIdx=20;
	//Add Extra Soil Temp Sensors
	for (iTmp=0; iTmp<4; iTmp++)
	{
		bool bTempValid=false;
		float temp=0;

		if (pData[25+iTmp]!=0xFF)
		{
			bTempValid=true;
			temp=pData[25+iTmp]-90.0f;
			temp = (temp - 32.0f) * 5.0f / 9.0f;
		}
		if (bTempValid)
		{
			SendTempSensor(tempIdx++, 255, temp, "Soil Temp");
		}
	}

	tempIdx=30;
	//Add Extra Leaf Temp Sensors
	for (iTmp=0; iTmp<4; iTmp++)
	{
		bool bTempValid=false;
		float temp=0;

		if (pData[29+iTmp]!=0xFF)
		{
			bTempValid=true;
			temp=pData[29+iTmp]-90.0f;
			temp = (temp - 32.0f) * 5.0f / 9.0f;
		}
		if (bTempValid)
		{
			SendTempSensor(tempIdx++, 255, temp, "Leaf Temp");
		}
	}

	//Wind Speed
	if (pData[14]!=0xFF)
	{
		bWindSpeedValid=true;
		WindSpeed=(pData[14])*(4.0f/9.0f);
	}
	//Wind Speed AVR 10 minutes
	if (pData[15]!=0xFF)
	{
		bWindSpeedAVR10Valid=true;
		WindSpeedAVR10=(pData[15])*(4.0f/9.0f);
	}
	//Wind Direction
	if ((pData[16]!=0xFF)&&(pData[17]!=0x7F))
	{
		bWindDirectionValid=true;
		WindDirection=((unsigned int)((pData[17] << 8) | pData[16]));
	}

	if ((bWindSpeedValid)&&(bWindDirectionValid))
	{
		memset(&tsen,0,sizeof(RBUF));
		tsen.WIND.packetlength=sizeof(tsen.WIND)-1;
		tsen.WIND.packettype=pTypeWIND;
		tsen.WIND.subtype=sTypeWINDNoTemp;
		tsen.WIND.battery_level=9;
		tsen.WIND.rssi=12;
		tsen.WIND.id1=0;
		tsen.WIND.id2=1;

		int aw=round(WindDirection);
		tsen.WIND.directionh=(BYTE)(aw/256);
		aw-=(tsen.WIND.directionh*256);
		tsen.WIND.directionl=(BYTE)(aw);

		tsen.WIND.av_speedh=0;
		tsen.WIND.av_speedl=0;
		int sw=round(WindSpeed*10.0f);
		tsen.WIND.av_speedh=(BYTE)(sw/256);
		sw-=(tsen.WIND.av_speedh*256);
		tsen.WIND.av_speedl=(BYTE)(sw);

		tsen.WIND.gusth=0;
		tsen.WIND.gustl=0;

		//this is not correct, why no wind temperature? and only chill?
		tsen.WIND.chillh=0;
		tsen.WIND.chilll=0;
		tsen.WIND.temperatureh=0;
		tsen.WIND.temperaturel=0;
		if (bOutsideTemperatureValid)
		{
			tsen.WIND.tempsign=(OutsideTemperature>=0)?0:1;
			tsen.WIND.chillsign=(OutsideTemperature>=0)?0:1;
			int at10=round(abs(OutsideTemperature*10.0f));
			tsen.WIND.temperatureh=(BYTE)(at10/256);
			tsen.WIND.chillh=(BYTE)(at10/256);
			at10-=(tsen.WIND.chillh*256);
			tsen.WIND.temperaturel=(BYTE)(at10);
			tsen.WIND.chilll=(BYTE)(at10);
		}

		sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255);
	}

	//UV
	if (pData[43]!=0xFF)
	{
		UV=(pData[43])/10.0f;
		if (UV<100)
			bUVValid=true;
	}
	if (bUVValid)
	{
		RBUF tsen;
		memset(&tsen,0,sizeof(RBUF));
		tsen.UV.packetlength=sizeof(tsen.UV)-1;
		tsen.UV.packettype=pTypeUV;
		tsen.UV.subtype=sTypeUV1;
		tsen.UV.battery_level=9;
		tsen.UV.rssi=12;
		tsen.UV.id1=0;
		tsen.UV.id2=1;

		tsen.UV.uv=(BYTE)round(UV*10);
		sDecodeRXMessage(this, (const unsigned char *)&tsen.UV, NULL, 255);
	}
	
	//Rain Rate
	if ((pData[41]!=0xFF)&&(pData[42]!=0xFF))
	{
		float rainRate=((unsigned int)((pData[42] << 8) | pData[41])) / 100.0f; //inches
		rainRate*=25.4f; //mm
	}
	//Rain Day
	if ((pData[50]!=0xFF)&&(pData[51]!=0xFF))
	{
		float rainDay=((unsigned int)((pData[51] << 8) | pData[50])) / 100.0f; //inches
		rainDay*=25.4f; //mm
	}
	//Rain Year
	if ((pData[54]!=0xFF)&&(pData[55]!=0xFF))
	{
		float rainYear=((unsigned int)((pData[55] << 8) | pData[54])) / 100.0f; //inches
		rainYear*=25.4f; //mm

		SendRainSensor(1, 255, rainYear, "Rain");
	}

	//Solar Radiation
	if ((pData[44]!=0xFF)&&(pData[45]!=0x7F))
	{
		unsigned int solarRadiation=((unsigned int)((pData[45] << 8) | pData[44]));//Watt/M2
		_tGeneralDevice gdevice;
		gdevice.subtype=sTypeSolarRadiation;
		gdevice.floatval1=float(solarRadiation);
		sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);

	}

	//Soil Moistures
	for (int iMoister=0; iMoister<4; iMoister++)
	{
		if (pData[62+iMoister]!=0xFF)
		{
			int moister=pData[62+iMoister];
			SendMoistureSensor(1 + iMoister, 255, moister, "Moisture");
		}
	}

	//Leaf Wetness
	for (int iLeaf=0; iLeaf<4; iLeaf++)
	{
		if (pData[66+iLeaf]!=0xFF)
		{
			int leaf_wetness=pData[66+iLeaf];

			_tGeneralDevice gdevice;
			gdevice.subtype=sTypeLeafWetness;
			gdevice.intval1=leaf_wetness;
			gdevice.id=1+iLeaf;
			sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);
		}
	}

	return true;
}
Beispiel #17
0
bool CRFLinkBase::ParseLine(const std::string &sLine)
{
	m_LastReceivedTime = mytime(NULL);

	std::vector<std::string> results;
	StringSplit(sLine, ";", results);
	if (results.size() < 2)
		return false; //not needed

	bool bHideDebugLog = (
		(sLine.find("PONG") != std::string::npos)||
		(sLine.find("PING") != std::string::npos)
		);

	int RFLink_ID = atoi(results[0].c_str());
	if (RFLink_ID != 20)
	{
		return false; //only accept RFLink->Master messages
	}

#ifdef ENABLE_LOGGING
	if (!bHideDebugLog)
		_log.Log(LOG_NORM, "RFLink: %s", sLine.c_str());
#endif

	//std::string Sensor_ID = results[1];
	if (results.size() >2)
	{
		//Status reply
		std::string Name_ID = results[2];
		if ((Name_ID.find("Nodo RadioFrequencyLink") != std::string::npos) || (Name_ID.find("RFLink Gateway") != std::string::npos))
		{
			_log.Log(LOG_STATUS, "RFLink: Controller Initialized!...");
			WriteInt("10;VERSION;\n");  // 20;3C;VER=1.1;REV=37;BUILD=01;

			//Enable DEBUG
			//write("10;RFDEBUG=ON;\n");

			//Enable Undecoded DEBUG
			//write("10;RFUDEBUG=ON;\n");
			return true;
		}
		if (Name_ID.find("VER") != std::string::npos) {
			//_log.Log(LOG_STATUS, "RFLink: %s", sLine.c_str());
			int versionlo = 0;
			int versionhi = 0;
			int revision = 0;
			int build = 0;
			if (results[2].find("VER") != std::string::npos) {
				versionhi = RFLinkGetIntStringValue(results[2]);
				versionlo = RFLinkGetIntDecStringValue(results[2]);
			}
			if (results[3].find("REV") != std::string::npos){
				revision = RFLinkGetIntStringValue(results[3]);
			}
			if (results[4].find("BUILD") != std::string::npos) {
				build = RFLinkGetIntStringValue(results[4]);
			}
			_log.Log(LOG_STATUS, "RFLink Detected, Version: %d.%d Revision: %d Build: %d", versionhi, versionlo, revision, build);

			std::stringstream sstr;
			sstr << revision << "." << build;
			m_Version = sstr.str();

			mytime(&m_LastHeartbeatReceive);  // keep heartbeat happy
			mytime(&m_LastHeartbeat);  // keep heartbeat happy
			m_LastReceivedTime = m_LastHeartbeat;

			m_bTXokay = true; // variable to indicate an OK was received
			return true;
		}
		if (Name_ID.find("PONG") != std::string::npos) {
			//_log.Log(LOG_STATUS, "RFLink: PONG received!...");
			mytime(&m_LastHeartbeatReceive);  // keep heartbeat happy
			mytime(&m_LastHeartbeat);  // keep heartbeat happy
			m_LastReceivedTime = m_LastHeartbeat;

			m_bTXokay = true; // variable to indicate an OK was received
			return true;
		}
		if (Name_ID.find("OK") != std::string::npos) {
			//_log.Log(LOG_STATUS, "RFLink: OK received!...");
			mytime(&m_LastHeartbeatReceive);  // keep heartbeat happy
			mytime(&m_LastHeartbeat);  // keep heartbeat happy
			m_LastReceivedTime = m_LastHeartbeat;

			m_bTXokay = true; // variable to indicate an OK was received
			return true;
		}
		else if (Name_ID.find("CMD UNKNOWN") != std::string::npos) {
			_log.Log(LOG_ERROR, "RFLink: Error/Unknown command received!...");
			m_bTXokay = true; // variable to indicate an ERROR was received
			return true;
		}
	}
	if (results.size() < 4)
		return true;

	if (results[3].find("ID=") == std::string::npos)
		return false; //??

	mytime(&m_LastHeartbeatReceive);  // keep heartbeat happy
	mytime(&m_LastHeartbeat);  // keep heartbeat happy
	//_log.Log(LOG_STATUS, "RFLink: t1=%d t2=%d", m_LastHeartbeat, m_LastHeartbeatReceive);
	m_LastReceivedTime = m_LastHeartbeat;

	std::stringstream ss;
	unsigned int ID;
	ss << std::hex << results[3].substr(3);
	ss >> ID;

	int Node_ID = (ID & 0xFF00) >> 8;
	int Child_ID = ID & 0xFF;

	bool bHaveTemp = false; float temp = 0;
	bool bHaveHum = false; int humidity = 0;
	bool bHaveHumStatus = false; int humstatus = 0;
	bool bHaveBaro = false; float baro = 0;
	int baroforecast = 0;
	bool bHaveRain = false; float raincounter = 0;
	bool bHaveLux = false; float lux = 0;
	bool bHaveUV = false; float uv = 0;
    
	bool bHaveWindDir = false; int windir = 0;
	bool bHaveWindSpeed = false; float windspeed = 0;
	bool bHaveWindGust = false; float windgust = 0;
	bool bHaveWindTemp = false; float windtemp = 0;
	bool bHaveWindChill = false; float windchill = 0;

	bool bHaveRGB = false; int rgb = 0;
	bool bHaveRGBW = false; int rgbw = 0;
	bool bHaveSound = false; int sound = 0;
	bool bHaveCO2 = false; int co2 = 0;
	bool bHaveBlind = false; int blind = 0;   

	bool bHaveKWatt = false; float kwatt = 0;   
	bool bHaveWatt = false; float watt = 0;   
	bool bHaveDistance = false; float distance = 0;   
	bool bHaveMeter = false; float meter = 0;   
	bool bHaveVoltage = false; float voltage = 0;   
	bool bHaveCurrent = false; float current = 0;   
	bool bHaveCurrent2 = false; float current2 = 0;
	bool bHaveCurrent3 = false; float current3 = 0;
	bool bHaveImpedance = false; float impedance = 0;
	bool bHaveSwitch = false; int switchunit = 0; 
	bool bHaveSwitchCmd = false; std::string switchcmd = ""; int switchlevel = 0;

	int BatteryLevel = 255;
	std::string tmpstr;
	int iTemp;
	for (size_t ii = 4; ii < results.size(); ii++)
	{
		if (results[ii].find("TEMP") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveTemp = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			temp = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("HUM") != std::string::npos)
		{
			bHaveHum = true;
			humidity = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("HSTATUS") != std::string::npos)
		{
			bHaveHumStatus = true;
			humstatus = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("BARO") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveBaro = true;
			baro = float(iTemp);
		}
		else if (results[ii].find("BFORECAST") != std::string::npos)
		{
			baroforecast = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RAIN") != std::string::npos)
		{
			bHaveRain = true;
			iTemp = RFLinkGetHexStringValue(results[ii]);
			raincounter = float(iTemp) / 10.0f; 
		}
		else if (results[ii].find("LUX") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveLux = true;
			lux = float(iTemp);
		}
		else if (results[ii].find("UV") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveUV = true;
			uv = float(iTemp) /10.0f;
		}
		else if (results[ii].find("BAT") != std::string::npos)
		{
			tmpstr = RFLinkGetStringValue(results[ii]);
			BatteryLevel = (tmpstr == "OK") ? 100 : 0;
		}
		else if (results[ii].find("WINDIR") != std::string::npos)
		{
			bHaveWindDir = true;
			windir = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("WINSP") != std::string::npos)
		{
			bHaveWindSpeed = true;
			iTemp = RFLinkGetHexStringValue(results[ii]); // received value is km/u
			windspeed = (float(iTemp) * 0.0277778f);   //convert to m/s
		}
		else if (results[ii].find("WINGS") != std::string::npos)
		{
			bHaveWindGust = true;
			iTemp = RFLinkGetHexStringValue(results[ii]); // received value is km/u
			windgust = (float(iTemp) * 0.0277778f);    //convert to m/s
		}
		else if (results[ii].find("WINTMP") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWindTemp = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			windtemp = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("WINCHL") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWindChill = true;
			if ((iTemp & 0x8000) == 0x8000) {
				//negative temp
				iTemp = -(iTemp & 0xFFF);
			}
			windchill = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("SOUND") != std::string::npos)
		{
			bHaveSound = true;
			sound = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("CO2") != std::string::npos)
		{
			bHaveCO2 = true;
			co2 = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RGBW") != std::string::npos)
		{
			bHaveRGBW = true;
			rgbw = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("RGB") != std::string::npos)
		{
			bHaveRGB = true;
			rgb = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("BLIND") != std::string::npos)
		{
			bHaveBlind = true;
			blind = RFLinkGetIntStringValue(results[ii]);
		}
		else if (results[ii].find("KWATT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveKWatt = true;
			kwatt = float(iTemp) / 1000.0f;
		}
		else if (results[ii].find("WATT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveWatt = true;
			watt = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("DIST") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveDistance = true;
			distance = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("METER") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveMeter = true;
			meter = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("VOLT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveVoltage = true;
			voltage = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("CURRENT") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveCurrent = true;
			current = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("CURRENT2") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveCurrent2 = true;
			current2 = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("CURRENT3") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveCurrent3 = true;
			current3 = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("IMPEDANCE") != std::string::npos)
		{
			iTemp = RFLinkGetHexStringValue(results[ii]);
			bHaveCurrent = true;
			current = float(iTemp) / 10.0f;
		}
		else if (results[ii].find("SWITCH") != std::string::npos)
		{
			bHaveSwitch = true;
			switchunit = RFLinkGetHexStringValue(results[ii]);
		}
		else if (results[ii].find("CMD") != std::string::npos)
		{
			bHaveSwitchCmd = true;
			switchcmd = RFLinkGetStringValue(results[ii]);
		}
		else if (results[ii].find("SMOKEALERT") != std::string::npos)
		{
			bHaveSwitch = true;
			switchunit = 1;
			bHaveSwitchCmd = true;
			switchcmd = RFLinkGetStringValue(results[ii]);
		}
		else if (results[ii].find("CHIME") != std::string::npos)
		{
			bHaveSwitch = true;
			switchunit = 2;
			bHaveSwitchCmd = true;
			switchcmd = "ON";
		}
	}

	std::string tmp_Name = results[2];
	if (bHaveTemp&&bHaveHum&&bHaveBaro)
	{
		SendTempHumBaroSensor(ID, BatteryLevel, temp, humidity, baro, baroforecast, tmp_Name);
	}
	else if (bHaveTemp&&bHaveHum)
	{
		SendTempHumSensor(ID, BatteryLevel, temp, humidity, tmp_Name);
	}
	else if (bHaveTemp)
	{
		SendTempSensor(ID, BatteryLevel, temp, tmp_Name);
	}
	else if (bHaveHum)
	{
		SendHumiditySensor(ID, BatteryLevel, humidity, tmp_Name);
	}
	else if (bHaveBaro)
	{
		SendBaroSensor(Node_ID, Child_ID, BatteryLevel, baro, baroforecast, tmp_Name);
	}

	if (bHaveLux)
	{
		SendLuxSensor(Node_ID, Child_ID, BatteryLevel, lux, tmp_Name);
	}

	if (bHaveUV)
	{
  		SendUVSensor(Node_ID, Child_ID, BatteryLevel, uv, tmp_Name);
	}
    
	if (bHaveRain)
	{
		SendRainSensor(ID, BatteryLevel, float(raincounter), tmp_Name);
	}

	if (bHaveWindDir && bHaveWindSpeed && bHaveWindGust && bHaveWindChill)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name);
	}
	else if (bHaveWindDir && bHaveWindGust)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name);
	}
	else if (bHaveWindSpeed)
	{
		SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name);
	}
    
	if (bHaveCO2)
	{
		SendAirQualitySensor((ID & 0xFF00) >> 8, ID & 0xFF, BatteryLevel, co2, tmp_Name);
	}
	if (bHaveSound)
	{
		SendSoundSensor(ID, BatteryLevel, sound, tmp_Name);
	}

	if (bHaveRGB)
	{
		//RRGGBB
		SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgb, false, tmp_Name);
	}
	if (bHaveRGBW)
	{
		//RRGGBBWW
		SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgbw, true, tmp_Name);
	}
	if (bHaveBlind)
	{
		SendBlindSensor(Node_ID, Child_ID, BatteryLevel, blind, tmp_Name);
	}

	if (bHaveKWatt&bHaveWatt)
	{
		SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name);
	}
	else if (bHaveKWatt)
	{
		SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name);
	}
	else if (bHaveWatt)
	{
		SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name);
	}
	if (bHaveDistance)
	{
		SendDistanceSensor(Node_ID, Child_ID, BatteryLevel, distance, tmp_Name);
	}
	if (bHaveMeter)
	{
		SendMeterSensor(Node_ID, Child_ID, BatteryLevel, meter, tmp_Name);
	}
	if (bHaveVoltage)
	{
		SendVoltageSensor(Node_ID, Child_ID, BatteryLevel, voltage, tmp_Name);
	}
	if (bHaveCurrent && bHaveCurrent2 && bHaveCurrent3) 
	{
		SendCurrentSensor(ID, BatteryLevel, current, current2, current3, tmp_Name);
	} 
	else if (bHaveCurrent)
	{
		SendCurrentSensor(ID, BatteryLevel, current, 0, 0, tmp_Name);
	}
	if (bHaveImpedance)
	{
		SendPercentageSensor(Node_ID, Child_ID, BatteryLevel, impedance, tmp_Name);
	}
	if (bHaveSwitch && bHaveSwitchCmd)
	{
		std::string switchType = results[2];
		SendSwitchInt(ID, switchunit, BatteryLevel, switchType, switchcmd, switchlevel);
	}

    return true;
}
Beispiel #18
0
void CWunderground::GetMeterDetails()
{
	std::string sResult;
#ifdef DEBUG_WUNDERGROUND
	sResult= ReadFile("E:\\wu.json");
#else
	std::stringstream sURL;
	std::string szLoc = CURLEncode::URLEncode(m_Location);
	sURL << "http://api.wunderground.com/api/" << m_APIKey << "/conditions/q/" << szLoc << ".json";
	bool bret;
	std::string szURL=sURL.str();
	bret=HTTPClient::GET(szURL,sResult);
	if (!bret)
	{
		_log.Log(LOG_ERROR,"Wunderground: Error getting http data!");
		return;
	}
#ifdef DEBUG_WUNDERGROUND2
	SaveString2Disk(sResult, "E:\\wu.json");
#endif
#endif
	Json::Value root;

	Json::Reader jReader;
	bool ret=jReader.parse(sResult,root);
	if (!ret)
	{
		_log.Log(LOG_ERROR,"WUnderground: Invalid data received!");
		return;
	}

	bool bValid = true;
	if (root["response"].empty() == true)
	{
		bValid = false;
	}
	else if (!root["response"]["error"].empty())
	{
		bValid = false;
		if (!root["response"]["error"]["description"].empty())
		{
			_log.Log(LOG_ERROR, "WUnderground: Error: %s", root["response"]["error"]["description"].asString().c_str());
			return;
		}
	}
	else if (root["current_observation"].empty()==true)
	{
		bValid = false;
		return;
	}
	else if (root["current_observation"]["temp_c"].empty() == true)
	{
		bValid = false;
	}
	if (!bValid)
	{
		_log.Log(LOG_ERROR, "WUnderground: Invalid data received, or no data returned!");
		return;
	}
	/*
	std::string tmpstr2 = root.toStyledString();
	FILE *fOut = fopen("E:\\underground.json", "wb+");
	fwrite(tmpstr2.c_str(), 1, tmpstr2.size(), fOut);
	fclose(fOut);
	*/

	std::string tmpstr;
	float temp;
	int humidity=0;
	int barometric=0;
	int barometric_forcast=baroForecastNoInfo;


	temp=root["current_observation"]["temp_c"].asFloat();

	if (root["current_observation"]["relative_humidity"].empty()==false)
	{
		tmpstr=root["current_observation"]["relative_humidity"].asString();
		size_t pos=tmpstr.find("%");
		if (pos==std::string::npos)
		{
			_log.Log(LOG_ERROR,"WUnderground: Invalid data received!");
			return;
		}
		humidity=atoi(tmpstr.substr(0,pos).c_str());
	}
	if (root["current_observation"]["pressure_mb"].empty()==false)
	{
		barometric=atoi(root["current_observation"]["pressure_mb"].asString().c_str());
		if (barometric<1000)
			barometric_forcast=baroForecastRain;
		else if (barometric<1020)
			barometric_forcast=baroForecastCloudy;
		else if (barometric<1030)
			barometric_forcast=baroForecastPartlyCloudy;
		else
			barometric_forcast=baroForecastSunny;

		if (root["current_observation"]["icon"].empty()==false)
		{
			std::string forcasticon=root["current_observation"]["icon"].asString();
			if (forcasticon=="partlycloudy")
			{
				barometric_forcast=baroForecastPartlyCloudy;
			}
			else if (forcasticon=="cloudy")
			{
				barometric_forcast=baroForecastCloudy;
			}
			else if (forcasticon=="sunny")
			{
				barometric_forcast=baroForecastSunny;
			}
			else if (forcasticon=="rain")
			{
				barometric_forcast=baroForecastRain;
			}
		}
	}

	if (barometric!=0)
	{
		//Add temp+hum+baro device
		SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB");
	}
	else if (humidity!=0)
	{
		//add temp+hum device
		SendTempHumSensor(1, 255, temp, humidity, "TempHum");
	}
	else
	{
		//add temp device
		SendTempSensor(1, 255, temp, "Temperature");
	}

	//Wind
	int wind_degrees=-1;
	float wind_mph=-1;
	float wind_gust_mph=-1;
	float windspeed_ms=0;
	float windgust_ms=0;
	float wind_temp=temp;
	float wind_chill=temp;
	int windgust=1;
	float windchill=-1;

	if (root["current_observation"]["wind_degrees"].empty()==false)
	{
		wind_degrees=atoi(root["current_observation"]["wind_degrees"].asString().c_str());
	}
	if (root["current_observation"]["wind_mph"].empty()==false)
	{
		if ((root["current_observation"]["wind_mph"] != "N/A") && (root["current_observation"]["wind_mph"] != "--"))
		{
			float temp_wind_mph = static_cast<float>(atof(root["current_observation"]["wind_mph"].asString().c_str()));
			if (temp_wind_mph!=-9999.00f)
			{
				wind_mph=temp_wind_mph;
				//convert to m/s
				windspeed_ms=wind_mph*0.44704f;
			}
		}
	}
	if (root["current_observation"]["wind_gust_mph"].empty()==false)
	{
		if ((root["current_observation"]["wind_gust_mph"] != "N/A") && (root["current_observation"]["wind_gust_mph"] != "--"))
		{
			float temp_wind_gust_mph = static_cast<float>(atof(root["current_observation"]["wind_gust_mph"].asString().c_str()));
			if (temp_wind_gust_mph!=-9999.00f)
			{
				wind_gust_mph=temp_wind_gust_mph;
				//convert to m/s
				windgust_ms=wind_gust_mph*0.44704f;
			}
		}
	}
	if (root["current_observation"]["feelslike_c"].empty()==false)
	{
		if ((root["current_observation"]["feelslike_c"] != "N/A") && (root["current_observation"]["feelslike_c"] != "--"))
		{
			wind_chill = static_cast<float>(atof(root["current_observation"]["feelslike_c"].asString().c_str()));
		}
	}
	if (wind_degrees!=-1)
	{
		RBUF tsen;
		memset(&tsen,0,sizeof(RBUF));
		tsen.WIND.packetlength=sizeof(tsen.WIND)-1;
		tsen.WIND.packettype=pTypeWIND;
		tsen.WIND.subtype=sTypeWIND4;
		tsen.WIND.battery_level=9;
		tsen.WIND.rssi=12;
		tsen.WIND.id1=0;
		tsen.WIND.id2=1;

		float winddir=float(wind_degrees);
		int aw=round(winddir);
		tsen.WIND.directionh=(BYTE)(aw/256);
		aw-=(tsen.WIND.directionh*256);
		tsen.WIND.directionl=(BYTE)(aw);

		tsen.WIND.av_speedh=0;
		tsen.WIND.av_speedl=0;
		int sw=round(windspeed_ms*10.0f);
		tsen.WIND.av_speedh=(BYTE)(sw/256);
		sw-=(tsen.WIND.av_speedh*256);
		tsen.WIND.av_speedl=(BYTE)(sw);

		tsen.WIND.gusth=0;
		tsen.WIND.gustl=0;
		int gw=round(windgust_ms*10.0f);
		tsen.WIND.gusth=(BYTE)(gw/256);
		gw-=(tsen.WIND.gusth*256);
		tsen.WIND.gustl=(BYTE)(gw);

		//this is not correct, why no wind temperature? and only chill?
		tsen.WIND.chillh=0;
		tsen.WIND.chilll=0;
		tsen.WIND.temperatureh=0;
		tsen.WIND.temperaturel=0;

		tsen.WIND.tempsign=(wind_temp>=0)?0:1;
		int at10=round(std::abs(wind_temp*10.0f));
		tsen.WIND.temperatureh=(BYTE)(at10/256);
		at10-=(tsen.WIND.temperatureh*256);
		tsen.WIND.temperaturel=(BYTE)(at10);

		tsen.WIND.chillsign=(wind_temp>=0)?0:1;
		at10=round(std::abs(wind_chill*10.0f));
		tsen.WIND.chillh=(BYTE)(at10/256);
		at10-=(tsen.WIND.chillh*256);
		tsen.WIND.chilll=(BYTE)(at10);

		sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255);
	}

	//UV
	if (root["current_observation"].empty() == false)
	{
		if (root["current_observation"]["UV"].empty() == false)
		{
			if ((root["current_observation"]["UV"] != "N/A") && (root["current_observation"]["UV"] != "--"))
			{
				float UV = static_cast<float>(atof(root["current_observation"]["UV"].asString().c_str()));
				if ((UV < 16) && (UV >= 0))
				{
					SendUVSensor(0, 1, 255, UV, "UV");
				}
			}
		}
	}

	//Rain
	if (root["current_observation"]["precip_today_metric"].empty() == false)
	{
		if ((root["current_observation"]["precip_today_metric"] != "N/A") && (root["current_observation"]["precip_today_metric"] != "--"))
		{
			float RainCount = static_cast<float>(atof(root["current_observation"]["precip_today_metric"].asString().c_str()));
			if ((RainCount != -9999.00f) && (RainCount >= 0.00f))
			{
				RBUF tsen;
				memset(&tsen, 0, sizeof(RBUF));
				tsen.RAIN.packetlength = sizeof(tsen.RAIN) - 1;
				tsen.RAIN.packettype = pTypeRAIN;
				tsen.RAIN.subtype = sTypeRAINWU;
				tsen.RAIN.battery_level = 9;
				tsen.RAIN.rssi = 12;
				tsen.RAIN.id1 = 0;
				tsen.RAIN.id2 = 1;

				tsen.RAIN.rainrateh = 0;
				tsen.RAIN.rainratel = 0;

				if (root["current_observation"]["precip_1hr_metric"].empty() == false)
				{
					if ((root["current_observation"]["precip_1hr_metric"] != "N/A") && (root["current_observation"]["precip_1hr_metric"] != "--"))
					{
						float rainrateph = static_cast<float>(atof(root["current_observation"]["precip_1hr_metric"].asString().c_str()));
						if (rainrateph != -9999.00f)
						{
							int at10 = round(std::abs(rainrateph*10.0f));
							tsen.RAIN.rainrateh = (BYTE)(at10 / 256);
							at10 -= (tsen.RAIN.rainrateh * 256);
							tsen.RAIN.rainratel = (BYTE)(at10);
						}
					}
				}

				int tr10 = int((float(RainCount)*10.0f));
				tsen.RAIN.raintotal1 = 0;
				tsen.RAIN.raintotal2 = (BYTE)(tr10 / 256);
				tr10 -= (tsen.RAIN.raintotal2 * 256);
				tsen.RAIN.raintotal3 = (BYTE)(tr10);

				sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255);
			}
		}
	}

	//Visibility
	if (root["current_observation"]["visibility_km"].empty() == false)
	{
		if ((root["current_observation"]["visibility_km"] != "N/A") && (root["current_observation"]["visibility_km"] != "--"))
		{
			float visibility = static_cast<float>(atof(root["current_observation"]["visibility_km"].asString().c_str()));
			if (visibility >= 0)
			{
				_tGeneralDevice gdevice;
				gdevice.subtype = sTypeVisibility;
				gdevice.floatval1 = visibility;
				sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);
			}
		}
	}

	//Solar Radiation
	if (root["current_observation"]["solarradiation"].empty() == false)
	{
		if ((root["current_observation"]["solarradiation"] != "N/A") && (root["current_observation"]["solarradiation"] != "--"))
		{
			float radiation = static_cast<float>(atof(root["current_observation"]["solarradiation"].asString().c_str()));
			if (radiation >= 0.0f)
			{
				_tGeneralDevice gdevice;
				gdevice.subtype = sTypeSolarRadiation;
				gdevice.floatval1 = radiation;
				sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255);
			}
		}
	}
}
void CPVOutputInput::GetMeterDetails()
{
	if (m_SID.size()==0)
		return;
	if (m_KEY.size()==0)
		return;

	std::string sResult;

	std::stringstream sstr;
	sstr << "http://pvoutput.org/service/r2/getstatus.jsp?sid=" << m_SID << "&key=" << m_KEY;
	if (!HTTPClient::GET(sstr.str(),sResult))
	{
		_log.Log(LOG_ERROR,"PVOutput (Input): Error login!");
		return;
	}
	std::vector<std::string> splitresult;
	StringSplit(sResult,",",splitresult);
	if (splitresult.size()<9)
	{
		_log.Log(LOG_ERROR,"PVOutput (Input): Invalid Data received!");
		return;
	}

	double Usage=atof(splitresult[3].c_str());
	if (Usage < 0)
		Usage = 0;

	bool bHaveConsumption=false;
	double Consumption=0;
	if (splitresult[5]!="NaN")
	{
		Consumption=atof(splitresult[5].c_str());
		if (Consumption < 0)
			Consumption = 0;
		bHaveConsumption=true;
	}

	if (splitresult[6]!="NaN")
	{
		double Efficiency=atof(splitresult[6].c_str())*100.0;
		if (Efficiency>100.0)
			Efficiency=100.0;
		SendPercentage(1,float(Efficiency),"Efficiency");
	}
	if (splitresult[7]!="NaN")
	{
		double Temperature=atof(splitresult[7].c_str());
		SendTempSensor(1,float(Temperature),"Temperature");
	}
	if (splitresult[8]!="NaN")
	{
		double Voltage=atof(splitresult[8].c_str());
		if (Voltage>=0)
			SendVoltage(1,float(Voltage),"Voltage");
	}

	sstr.clear();
	sstr.str("");

	sstr << "http://pvoutput.org/service/r2/getstatistic.jsp?sid=" << m_SID << "&key=" << m_KEY << "&c=1";
	if (!HTTPClient::GET(sstr.str(),sResult))
	{
		_log.Log(LOG_ERROR,"PVOutput (Input): Error login!");
		return;
	}
	StringSplit(sResult,",",splitresult);
	if (splitresult.size()<11)
	{
		_log.Log(LOG_ERROR,"PVOutput (Input): Invalid Data received!");
		return;
	}

	double kWhCounterUsage=atof(splitresult[0].c_str());
	SendMeter(0, 1, Usage / 1000.0, kWhCounterUsage / 1000.0, "SolarMain");

	if (bHaveConsumption)
	{
		if (splitresult.size() > 11)
		{
			double kWhCounterConsumed = atof(splitresult[11].c_str());
			if (kWhCounterConsumed != 0)
			{
				SendMeter(0, 2, Consumption / 1000.0, kWhCounterConsumed / 1000.0, "SolarConsumed");
			}
		}
	}
}
Beispiel #20
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;
	}
}
Beispiel #21
0
void CSterbox::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 << "/x.cgi"; 

	if (!HTTPClient::GET(szURL.str(),sResult))
	{
		_log.Log(LOG_ERROR,"Sterbox: Error connecting to: %s", m_szIPAddress.c_str());
		return;
	}
	std::vector<std::string> results;
	std::vector<std::string> outputs;
	std::vector<std::string> inputs;
	std::vector<std::string> analog;
	StringSplit(sResult, "<br>", results);
	if (results.size()<8)
	{
		_log.Log(LOG_ERROR,"Sterbox: Result 8 Error connecting to: %s", m_szIPAddress.c_str());
		return;
	}
	//if (results[0] != "<body>")
	std::string tmpstr;
	std::string tmpstr2;
	std::string tmpinp;
	tmpstr = results[0];
	if (tmpstr.find("<title>SterBox_State</title>") != std::string::npos)
	{
		_log.Log(LOG_ERROR, "Sterbox: Error getting status");
		return;
	}
	size_t ii;
	size_t jj;
	int pos1;
	int Idx = 0;

	if (m_Username.empty())
	{
		StringSplit("o,o,o,o,i,i,i,i", ",", inputs);
	}
	else
	{
		StringSplit(m_Username, ",", inputs);
		//_log.Log(LOG_ERROR,"Sterbox: Username : %s , IP: %s", m_Username.c_str(), m_szIPAddress.c_str());
	}

	for (ii = 1; ii < results.size(); ii++)
	{
		tmpstr = results[ii];
		if (tmpstr.find("OU") != std::string::npos)
		{
			tmpstr = tmpstr.substr(strlen("OU"));
			pos1 = tmpstr.find("=");
			if (pos1 != std::string::npos)
			{	
				tmpstr = tmpstr.substr(pos1+1);
				//_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str());
				StringSplit(tmpstr, ",", outputs);
				for (jj = 0; jj < inputs.size(); jj++) 
				{	
					tmpinp = inputs[jj];
					//if (( jj < 4 || jj > 7  ))
					pos1 = tmpinp.find("o");
					if (pos1 != std::string::npos)
					{
					int lValue = 0;
					//tmpstr = tmpstr.substr(pos1+1);
					tmpstr2 = outputs[jj];
					//_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());
					pos1 = tmpstr2.find("s");
					if (pos1 != std::string::npos)
					{
						lValue = 1;
					}
					else
					{
						lValue = 0;
					}
					std::stringstream sstr;
					sstr << "Relay " << jj;
					UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str());
					}
				}
			}
		}
		else if (tmpstr.find("IN") != std::string::npos)
		{
			tmpstr = tmpstr.substr(strlen("IN"));
			pos1 = tmpstr.find("=");
			if (pos1 != std::string::npos)
			{	
				tmpstr = tmpstr.substr(pos1+1);
				//_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str());
				StringSplit(tmpstr, ",", outputs);
				for (jj = 0; jj < inputs.size(); jj++) 
				{	
					tmpinp = inputs[jj];
					//if (( jj > 3 && jj < 8  ))
					pos1 = tmpinp.find("i");
					if (pos1 != std::string::npos)
					{
					int lValue = 0;
					//tmpstr = tmpstr.substr(pos1+1);
					tmpstr2 = outputs[jj];
					//_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());
					pos1 = tmpstr2.find("S");
					if (pos1 != std::string::npos)
					{
						lValue = 1;
					}
					else
					{
						lValue = 0;
					}
					std::stringstream sstr;
					sstr << "Relay " << jj;
					UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str());
					}
				}
			}
		}
		else if (tmpstr.find("AN") != std::string::npos)
		{
			tmpstr = tmpstr.substr(strlen("AN"));
			pos1 = tmpstr.find("=");
			if (pos1 != std::string::npos)
			{
				tmpstr = tmpstr.substr(pos1+1);
				StringSplit(tmpstr, ",", outputs);
				if (m_Password.empty())
				{
					StringSplit("t,t,t", ",", analog);
				}
				else
				{
					//StringSplit("t,t,t", ",", inputs);
					StringSplit(m_Password, ",", analog);
				//_log.Log(LOG_ERROR,"Sterbox: Pass : %s", m_Password.c_str());

				}
				for (jj = 0; jj < 3; jj++)
				{
					tmpstr2 = outputs[jj];
					tmpinp = analog[jj];
					tmpstr2 = tmpstr2.substr(1, 10);

					float lValue = (float)atof(tmpstr2.c_str());
					std::stringstream sstr;
					sstr << "Analog " << jj;
					pos1 = tmpinp.find("t");
					if (pos1 != std::string::npos)
					{
						SendTempSensor(jj,255,lValue, sstr.str());
					}
					pos1 = tmpinp.find("v");
					if (pos1 != std::string::npos)
					{
						SendVoltageSensor(0, jj, 255, lValue, sstr.str());
					}
					pos1 = tmpinp.find("l");
					if (pos1 != std::string::npos)
					{
						SendLuxSensor(0, jj, 255,lValue, sstr.str());
					}
					pos1 = tmpinp.find("h");
					if (pos1 != std::string::npos)
					{
						SendHumiditySensor(jj,255,int(lValue), sstr.str());
					}
	
					//SendTempSensor(jj,255,lValue, sstr.str());
					//_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str());

				}
				//Idx = atoi(tmpstr.substr(0, pos1).c_str());
				//tmpstr = tmpstr.substr(pos1 + 1);
				//pos1 = tmpstr.find("<");
				//if (pos1 != std::string::npos)
				//{
				//	int lValue = atoi(tmpstr.substr(0, pos1).c_str());
				//	float voltage = (float)(5.0f / 1023.0f)*lValue;
				//	if (voltage > 5.0f)
				//		voltage = 5.0f;
				//	std::stringstream sstr;
				//	sstr << "Voltage " << Idx;
				//	SendVoltageSensor(0, Idx, 255, voltage, sstr.str());
				//}
			}
		}
	}
}
Beispiel #22
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);
		}
	}
}
Beispiel #23
0
void CSBFSpot::GetMeterDetails()
{
	if (m_SBFDataPath.size() == 0)
	{
		_log.Log(LOG_ERROR, "SBFSpot: Data path empty!");
		return;
	}
	if (m_SBFPlantName.size() == 0)
	{
		_log.Log(LOG_ERROR, "SBFSpot: Plant name empty!");
		return;
	}

	time_t atime = time(NULL);
	struct tm ltime;
	localtime_r(&atime, &ltime);

	int ActHourMin = (ltime.tm_hour * 60) + ltime.tm_min;

	int sunRise = getSunRiseSunSetMinutes(true);
	int sunSet = getSunRiseSunSetMinutes(false);

	//We only poll one hour before sunrise till one hour after sunset
	if (ActHourMin + 120 < sunRise)
		return;
	if (ActHourMin - 120 > sunSet)
		return;

	char szLogFile[256];
	char szDateStr[50];
	strcpy(szDateStr, strftime_t("%Y%m%d", atime));
	sprintf(szLogFile, "%s%s-Spot-%s.csv", strftime_t(m_SBFDataPath.c_str(), atime), m_SBFPlantName.c_str(), szDateStr);

	std::string szSeperator = ";";
	bool bHaveVersion = false;
	std::string tmpString;
	std::ifstream infile;
	std::string szLastDate = "";
	std::vector<std::string> szLastLines;
	std::vector<std::string> results;
	std::string sLine;
	infile.open(szLogFile);
	if (!infile.is_open())
	{
		if ((ActHourMin > sunRise) && (ActHourMin < sunSet))
		{
			_log.Log(LOG_ERROR, "SBFSpot: Could not open spot file: %s", szLogFile);
		}
		return;
	}
	while (!infile.eof())
	{
		getline(infile, sLine);
		sLine.erase(std::remove(sLine.begin(), sLine.end(), '\r'), sLine.end());
		if (sLine.size() != 0)
		{
			if (sLine.find("sep=") == 0)
			{
				tmpString = sLine.substr(strlen("sep="));
				if (tmpString != "")
				{
					szSeperator = tmpString;
				}
			}
			else if (sLine.find("Version CSV1") == 0)
			{
				bHaveVersion = true;
			}
			else if (bHaveVersion)
			{
				if (
					(sLine.find(";DeviceName") == std::string::npos) &&
					(sLine.find(";Watt") == std::string::npos)
					)
				{
					StringSplit(sLine, szSeperator, results);
					if (results.size() >= 30)
					{
						if (m_SBFInverter.empty() || (m_SBFInverter == results[3]))
						{
							if (szLastDate.empty() || (szLastDate != results[0]))
							{
								szLastDate = results[0];
								szLastLines.clear();
							}
							if (szLastDate == results[0])
							{
								szLastLines.push_back(sLine);
							}
						}
					}
				}
			}
		}
	}
	infile.close();

	if (szLastLines.empty())
	{
		_log.Log(LOG_ERROR, "SBFSpot: No data record found in spot file!");
		return;
	}

	if (szLastDate == m_LastDateTime)
	{
		return;
	}
	m_LastDateTime = szLastDate;

	double kWhCounter = 0;
	double Pac = 0;
	int InvIdx = 0;

	std::vector<std::string>::const_iterator itt;
	for (itt = szLastLines.begin(); itt != szLastLines.end(); ++itt)
	{
		StringSplit(*itt, szSeperator, results);

		if (results[1].size() < 1)
		{
			_log.Log(LOG_ERROR, "SBFSpot: No data record found in spot file!");
			return;
		}
		if ((results[28] != "OK") && (results[28] != "Ok"))
		{
			_log.Log(LOG_ERROR, "SBFSpot: Invalid field [28] should be OK!");
			return;
		}

		std::string szKwhCounter = results[23];
		stdreplace(szKwhCounter, ",", ".");
		kWhCounter += atof(szKwhCounter.c_str());
		std::string szPacActual = results[20];
		stdreplace(szPacActual, ",", ".");
		Pac += atof(szPacActual.c_str());

		float voltage;
		tmpString = results[16];
		stdreplace(tmpString, ",", ".");
		voltage = static_cast<float>(atof(tmpString.c_str()));
		SendVoltageSensor(0, (InvIdx * 10) + 1, 255, voltage, "Volt uac1");
		tmpString = results[17];
		stdreplace(tmpString, ",", ".");
		voltage = static_cast<float>(atof(tmpString.c_str()));
		if (voltage != 0) {
			SendVoltageSensor(0, (InvIdx * 10) + 2, 255, voltage, "Volt uac2");
		}
		tmpString = results[18];
		stdreplace(tmpString, ",", ".");
		voltage = static_cast<float>(atof(tmpString.c_str()));
		if (voltage != 0) {
			SendVoltageSensor(0, (InvIdx * 10) + 3, 255, voltage, "Volt uac3");
		}

		float percentage;
		tmpString = results[21];
		stdreplace(tmpString, ",", ".");
		percentage = static_cast<float>(atof(tmpString.c_str()));
		SendPercentageSensor((InvIdx * 10) + 1, 0, 255, percentage, "Efficiency");
		tmpString = results[24];
		stdreplace(tmpString, ",", ".");
		percentage = static_cast<float>(atof(tmpString.c_str()));
		SendPercentageSensor((InvIdx * 10) + 2, 0, 255, percentage, "Hz");
		tmpString = results[27];
		stdreplace(tmpString, ",", ".");
		percentage = static_cast<float>(atof(tmpString.c_str()));
		SendPercentageSensor((InvIdx * 10) + 3, 0, 255, percentage, "BT_Signal");

		if (results.size() >= 31)
		{
			tmpString = results[30];
			stdreplace(tmpString, ",", ".");
			float temperature = static_cast<float>(atof(tmpString.c_str()));
			SendTempSensor((InvIdx * 10) + 1, 255, temperature, "Temperature");
		}
		InvIdx++;
	}
	//Send combined counter/pac
	if (kWhCounter != 0)
	{
		double LastUsage = 0;
		double LastTotal = 0;
		if (GetMeter(0, 1, LastUsage, LastTotal))
		{
			if (kWhCounter < (int)(LastTotal * 100) / 100)
			{
				_log.Log(LOG_ERROR, "SBFSpot: Actual KwH counter (%f) less then last Counter (%f)!", kWhCounter, LastTotal);
				return;
			}
		}
		SendMeter(0, 1, Pac / 1000.0, kWhCounter, "SolarMain");
	}
}
Beispiel #24
0
void CDaikin::GetSensorInfo()
{
	std::string sResult;
#ifdef DEBUG_DaikinR
	sResult = ReadFile("E:\\Daikin_get_sensor_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_sensor_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_sensor_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() < 6)
	{
		_log.Log(LOG_ERROR, "Daikin: Invalid data received");
		return;
	}
	float htemp = -1;
	int hhum = -1;
	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] == "htemp")
		{
			htemp = static_cast<float>(atof(results2[1].c_str()));
		}
		else if (results2[0] == "hhum")
		{
			if (results2[1]!="-")
				hhum = static_cast<int>(atoi(results2[1].c_str()));
		}
		else if (results2[0] == "otemp")
		{
			SendTempSensor(11, -1, static_cast<float>(atof(results2[1].c_str())), "Outside Temperature");
		}
		if (htemp != -1)
		{
			if (hhum != -1)
				SendTempHumSensor(10, -1, htemp, hhum, "Home Temp+Hum");
			else
				SendTempSensor(10, -1, htemp, "Home Temperature");
		}
	}
}