Esempio n. 1
0
//"12345679","0052","D7FF","00747","id","*FDFF","*FFFF","0282","324.29999","224.89999","317.89999","1.60000","224.20000","-0.00300","50.01000","0.01180","1.00550","2.01350","9292"
int SolarEdgeBase::ParsePacket0x0282(const unsigned char *pData, int dlen)
{
	const unsigned char *b=pData;
	//10 Floats
	int totfloats=dlen/4;
	if (totfloats!=10)
		return 0;

	//DC1 Voltage
	float voltageDC1=GetFloat(b);
	b+=4;
	//AC2 Voltage
	float voltageAC1=GetFloat(b);
	b+=4;
	//DC2 Voltage
	float voltageDC2=GetFloat(b);
	b+=4;
	//Iets1
	float Iets1=GetFloat(b);
	b+=4;
	//AC2 Voltage
	float voltageAC2=GetFloat(b);
	b+=4;
	//Iets2
	float Iets2=GetFloat(b);
	b+=4;
	//Frequency
	float freq=GetFloat(b);
	SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz");
	b+=4;
	//skip the rest
	return dlen-2;
}
Esempio n. 2
0
//"12345679","0056","D3FF","00749","id","*FDFF","*FFFF","0280","325.60001","225.50000","1.60000","224.79999","50.00000","5.56000","15.39000","0.01220","0.01000","1254.00000","0.00000","B794"
int SolarEdgeBase::ParsePacket0x0280(const unsigned char *pData, int dlen)
{
	const unsigned char *b=pData;

	//11 Float values
	int totfloats=dlen/4;
	if (totfloats!=11)
		return 0;

	//DC Voltage
	float voltageDC=GetFloat(b);
	b+=4;
	dlen-=4;
	//AC Voltage1
	float voltageAC1=GetFloat(b);
	b+=4;
	dlen-=4;
	//Iets1
	float Iets1=GetFloat(b);
	b+=4;
	dlen-=4;
	//AC Voltage2
	float voltageAC2=GetFloat(b);
	b+=4;
	dlen-=4;
	//Frequency
	float freq=GetFloat(b);
	SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz");
	b+=4;
	dlen-=4;
	//Ampere
	float ampere=GetFloat(b);
	b+=4;
	dlen-=4;
	//Temp
	float temp=GetFloat(b);
	b+=4;
	dlen-=4;
	//Iets2
	float Iets2=GetFloat(b);
	b+=4;
	dlen-=4;
	//Iets3
	float Iets3=GetFloat(b);
	b+=4;
	dlen-=4;
	//Watt P-Out
	float Watt=GetFloat(b);
	b+=4;
	dlen-=4;
	//Iets4 (unsigned long)
	unsigned long *pUL=(unsigned long*)b;
	b+=4;
	dlen-=4;
	return (b-pData);
}
Esempio n. 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, 255, temp, devName);
	}
	else if (qType == "Load")
	{
		doffset = 1100;
		float perc = static_cast<float>(atof(devValue.c_str()));
		SendPercentageSensor(doffset + dindex, 0, 255, 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()));
		SendVoltageSensor(0, doffset + dindex, 255, volt, devName);
	}
	else if (qType == "Current")
	{
		doffset = 1400;
		float curr = static_cast<float>(atof(devValue.c_str()));
		SendCurrent(doffset + dindex, curr, devName);
	}
	return;
}
Esempio n. 4
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;
}
Esempio n. 5
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, 255, 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
				bool bExists = false;
				float rcounter= GetRainSensorValue(ID,bExists);
				m_ActRainCounter[ID%MAX_IDS] = rcounter;
			}
			m_ActRainCounter[ID%MAX_IDS] += Rainmm;
			SendRainSensor(ID, 255, 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, 255, 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()));
			SendPercentageSensor(ID, 0, 255, Percentage, "power of solar panel");
		}
		break;
	default:
		_log.Log(LOG_STATUS, "Unknown Type: %c", rCode);
		break;
	}

}
Esempio n. 6
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");
	}
}
Esempio n. 7
0
void MySensorsBase::SendSensor2Domoticz(_tMySensorNode *pNode, _tMySensorChild *pChild, const _eSetType vType)
{
	m_iLastSendNodeBatteryValue = 255;
	if (pChild->hasBattery)
	{
		m_iLastSendNodeBatteryValue = pChild->batValue;
	}
	int cNode = (pChild->nodeID << 8) | pChild->childID;
	int intValue;
	float floatValue;
	std::string stringValue;

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

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

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

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

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

}
Esempio n. 9
0
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, 255, temp, "SolarMain");
			SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz");
			SendVoltageSensor(0, SE_VOLT_AC, 255, voltageAC, "AC");
			SendVoltageSensor(0, SE_VOLT_DC, 255, voltageDC, "DC");
		}
		b+=restbytes;
		dlen-=restbytes;
		continue;
	}
	return (b-pData);
}
Esempio n. 10
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()));						UpdateTempSensor(idx-1,_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, _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()));
		bExists = CheckPercentageSensorExists(idx - 1, 1);
		if (_status.CH_water_pressure != 0)
		{
			UpdatePressureSensor(idx-1,_status.CH_water_pressure,"CH Water Pressure");
		}

		_status.Room_temperature = static_cast<float>(atof(results[idx++].c_str()));						UpdateTempSensor(idx - 1, _status.Room_temperature, "Room Temperature");
		_status.Boiler_water_temperature = static_cast<float>(atof(results[idx++].c_str()));				UpdateTempSensor(idx - 1, _status.Boiler_water_temperature, "Boiler Water Temperature");
		_status.DHW_temperature = static_cast<float>(atof(results[idx++].c_str()));						UpdateTempSensor(idx - 1, _status.DHW_temperature, "DHW Temperature");
		_status.Outside_temperature = static_cast<float>(atof(results[idx++].c_str()));					UpdateTempSensor(idx - 1, _status.Outside_temperature, "Outside Temperature");
		_status.Return_water_temperature = static_cast<float>(atof(results[idx++].c_str()));				UpdateTempSensor(idx - 1, _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("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());
			}
		}
	}

}