コード例 #1
0
ファイル: SBFSpot.cpp プロジェクト: AbsolutK/domoticz
void CSBFSpot::ImportOldMonthData()
{
	_log.Log(LOG_STATUS, "SBFSpot Import Old Month Data: Start");
	//check if this device exists in the database, if not exit
	bool bDeviceExits = true;
	std::vector<std::vector<std::string> > result;
	result = m_sql.safe_query("SELECT ID FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d)",
		m_HwdID, "00000001", int(pTypeGeneral), int(sTypeKwh));
	if (result.size() < 1)
	{
		//Lets create the sensor, and try again
		SendMeter(0, 1, 0, 0, "SolarMain");
		result = m_sql.safe_query("SELECT ID FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d)",
			m_HwdID, "00000001", int(pTypeGeneral), int(sTypeKwh));
		if (result.size() < 1)
		{
			_log.Log(LOG_ERROR, "SBFSpot Import Old Month Data: FAILED - Cannot find sensor in database");
			return;
		}
	}
	unsigned long long ulID;
	std::stringstream s_str(result[0][0]);
	s_str >> ulID;

	//Try actual year, and previous year
	time_t atime = time(NULL);
	struct tm ltime;
	localtime_r(&atime, &ltime);

	int totyearsback = 2;

	int startYear = ltime.tm_year + 1900 - totyearsback;
	for (int iYear = startYear; iYear != startYear + 1 + totyearsback; iYear++)
	{
		for (int iMonth = 1; iMonth != 12+1; iMonth++)
		{
			ImportOldMonthData(ulID,iYear, iMonth);
		}
	}
	_log.Log(LOG_STATUS, "SBFSpot Import Old Month Data: Complete");
}
コード例 #2
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,temp,"SolarMain");
			SendPercentage(SE_FREQ,freq,"Hz");
			SendVoltage(SE_VOLT_AC,voltageAC,"AC");
			SendVoltage(SE_VOLT_DC,voltageDC,"DC");
		}
		b+=restbytes;
		dlen-=restbytes;
		continue;
	}
	return (b-pData);
}
コード例 #3
0
void CPVOutputInput::GetMeterDetails()
{
	if (m_SID.size()==0)
		return;
	if (m_KEY.size()==0)
		return;

	std::string sResult;

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

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

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

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

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

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

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

	if (bHaveConsumption)
	{
		if (splitresult.size() > 11)
		{
			double kWhCounterConsumed = atof(splitresult[11].c_str());
			if (kWhCounterConsumed != 0)
			{
				SendMeter(0, 2, Consumption / 1000.0, kWhCounterConsumed / 1000.0, "SolarConsumed");
			}
		}
	}
}
コード例 #4
0
void S0MeterBase::ParseLine()
{
	if (m_bufferpos<2)
		return;
	std::string sLine((char*)&m_buffer);

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

	if (results[0][0]=='/') {
		//Meter restart
		//m_bMeterRestart=true;
		//Software Version

		std::string MeterID=results[0].substr(1);
		std::string SoftwareVersion=results[1];
		_log.Log(LOG_STATUS,"S0 Meter: ID: %s, Version: %s",MeterID.c_str(),SoftwareVersion.c_str());
		return;
	}
	if (results.size()<4)
	{
		_log.Log(LOG_ERROR,"S0 Meter: Invalid Data received! %s",sLine.c_str());
		return;
	}
	int totmeters=(results.size()-4)/3;
	if (totmeters>max_s0_meters)
		totmeters=max_s0_meters;
	//ID:0001:I:99:M1:123:456:M2:234:567 = ID(1)/Pulse Interval(3)/M1Actual(5)/M1Total(7)/M2Actual(8)/M2Total(9)
	//std::string MeterID=results[1];
	double s0_pulse_interval=atof(results[3].c_str());

	int roffset = 4;
	if (results[0] == "ID")
	{
		for (int ii = 0; ii < totmeters; ii++)
		{
			m_meters[ii].m_PacketsSinceLastPulseChange++;

			double s0_pulse = atof(results[roffset + 1].c_str());

			unsigned long LastTotalPulses = m_meters[ii].total_pulses;
			m_meters[ii].total_pulses = (unsigned long)atol(results[roffset + 2].c_str());
			if (m_meters[ii].total_pulses < LastTotalPulses)
			{
				//counter has looped
				m_meters[ii].m_counter_start += (LastTotalPulses + m_meters[ii].total_pulses);
				m_meters[ii].first_total_pulses_received = m_meters[ii].total_pulses;
			}

			if (s0_pulse != 0)
			{
				double pph = ((double)m_meters[ii].m_pulse_per_unit) / 1000; // Pulses per (watt) hour
				double ActualUsage = ((3600.0 / double(m_meters[ii].m_PacketsSinceLastPulseChange*s0_pulse_interval) / pph) * s0_pulse);
				m_meters[ii].m_PacketsSinceLastPulseChange = 0;

				m_meters[ii].m_last_values[m_meters[ii].m_value_buffer_write_pos] = ActualUsage;
				m_meters[ii].m_value_buffer_write_pos = (m_meters[ii].m_value_buffer_write_pos + 1) % 5;

				if (m_meters[ii].m_value_buffer_total < 5)
					m_meters[ii].m_value_buffer_total++;

				//Calculate Average
				double vTotal = 0;
				for (int iBuf = 0; iBuf < m_meters[ii].m_value_buffer_total; iBuf++)
					vTotal += m_meters[ii].m_last_values[iBuf];
				m_meters[ii].m_CurrentUsage = vTotal / double(m_meters[ii].m_value_buffer_total);
#ifdef _DEBUG
				_log.Log(LOG_STATUS, "S0 Meter: M%d, Watt: %.3f", ii + 1, m_meters[ii].m_CurrentUsage);
#endif
			}
			else
			{
				if (m_meters[ii].m_PacketsSinceLastPulseChange > 5 * 6)
				{
					//No pulses received for a long time, consider no usage
					m_meters[ii].m_PacketsSinceLastPulseChange = 0;
					m_meters[ii].m_last_values[0] = 0;
					m_meters[ii].m_value_buffer_total = 0;
					m_meters[ii].m_value_buffer_write_pos = 0;
					m_meters[ii].m_CurrentUsage = 0;
				}
			}

			if ((m_meters[ii].total_pulses != 0) || (m_meters[ii].m_firstTime))
			{
				m_meters[ii].m_firstTime = false;
				if (m_meters[ii].first_total_pulses_received == 0)
					m_meters[ii].first_total_pulses_received = m_meters[ii].total_pulses;

				double counter_value = m_meters[ii].m_counter_start + (((double)(m_meters[ii].total_pulses - m_meters[ii].first_total_pulses_received) / ((double)m_meters[ii].m_pulse_per_unit)));
				m_meters[ii].m_current_counter = counter_value;
				SendMeter(ii + 1, m_meters[ii].m_CurrentUsage / 1000.0f, counter_value);
			}

			roffset += 3;
		}
	}
	else if(results[0] == "EID")
	{
		roffset = 2;
		for (int ii = 0; ii < totmeters; ii++)
		{
			double s0_counter = atof(results[roffset + 1].c_str());
			if (s0_counter != 0)
			{
				if (m_meters[ii].m_firstTime)
				{
					m_meters[ii].m_current_counter = s0_counter;
					m_meters[ii].m_firstTime = false;
				}
				if (s0_counter < m_meters[ii].m_current_counter)
				{
					//counter has looped
					m_meters[ii].m_counter_start += m_meters[ii].m_current_counter;
				}
				m_meters[ii].m_current_counter = s0_counter;
				m_meters[ii].m_CurrentUsage = atof(results[roffset + 2].c_str());

				double counter_value = m_meters[ii].m_counter_start + s0_counter;
				SendMeter(ii + 1, m_meters[ii].m_CurrentUsage / 1000.0f, m_meters[ii].m_current_counter);
			}

			roffset += 3;
		}
	}
}
コード例 #5
0
ファイル: SBFSpot.cpp プロジェクト: AbsolutK/domoticz
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");
	}
}