Exemple #1
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;
}
Exemple #2
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!");
	}
}
Exemple #3
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;
}
Exemple #4
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);
			}
		}
	}
}
Exemple #5
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)
			}
		}
	}

}