mirror of https://github.com/lumapu/ahoy.git
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							283 lines
						
					
					
						
							8.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							283 lines
						
					
					
						
							8.9 KiB
						
					
					
				
								#ifndef __INVERTERS_H
							 | 
						|
								#define __INVERTERS_H
							 | 
						|
								
							 | 
						|
								// Ausgabe von Debug Infos auf der seriellen Console
							 | 
						|
								
							 | 
						|
								#include "Settings.h"
							 | 
						|
								#include "Debug.h"
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef struct _NRF24_packet_t {
							 | 
						|
								  uint32_t timestamp;
							 | 
						|
								  uint8_t  packetsLost;
							 | 
						|
								  uint8_t  rcvChannel;
							 | 
						|
								  uint8_t  packet[MAX_RF_PAYLOAD_SIZE];
							 | 
						|
								} NRF24_packet_t;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef struct _Serial_header_t {
							 | 
						|
								  unsigned long timestamp;
							 | 
						|
								  uint8_t  packetsLost;
							 | 
						|
								  uint8_t  address[RF_MAX_ADDR_WIDTH];    // MSB first, always RF_MAX_ADDR_WIDTH bytes.
							 | 
						|
								} Serial_header_t;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								// structs für Inverter und Kanalwerte
							 | 
						|
								
							 | 
						|
								// Liste der Einheiten
							 | 
						|
								enum UNITS {UNIT_V = 0, UNIT_HZ, UNIT_A, UNIT_W,  UNIT_WH, UNIT_C, UNIT_KWH, UNIT_MA, UNIT_PCT};
							 | 
						|
								const char* const units[] = {"V", "Hz", "A", "W", "Wh", "°C", "KWh", "mA", "%"};
							 | 
						|
								
							 | 
						|
								// CH0 is default channel (freq, ac, temp)
							 | 
						|
								enum CHANNELS {CH0 = 0, CH1, CH2, CH3, CH4};
							 | 
						|
								enum CMDS     {CMD01 = 0x01, CMD02, CMD03, CMD83 = 0x83, CMD84};
							 | 
						|
								enum DIVS     {DIV1 = 0, DIV10, DIV100, DIV1000};
							 | 
						|
								
							 | 
						|
								#define BYTES2        2
							 | 
						|
								#define BYTES4        4
							 | 
						|
								
							 | 
						|
								const char UDC[]      PROGMEM = "Udc";
							 | 
						|
								const char IDC[]      PROGMEM = "Idc";
							 | 
						|
								const char PDC[]      PROGMEM = "Pdc";
							 | 
						|
								const char E_WOCHE[]  PROGMEM = "E-Woche";
							 | 
						|
								const char E_TOTAL[]  PROGMEM = "E-Total";
							 | 
						|
								const char E_TAG[]    PROGMEM = "E-Tag";
							 | 
						|
								const char UAC[]      PROGMEM = "Uac";
							 | 
						|
								const char FREQ[]     PROGMEM = "Freq.ac";
							 | 
						|
								const char PAC[]      PROGMEM = "Pac";
							 | 
						|
								const char E_HEUTE[]  PROGMEM  = "E-heute";
							 | 
						|
								const char IPV[]      PROGMEM  = "Ipv";
							 | 
						|
								const char WR_TEMP[]  PROGMEM = "WR-Temp";
							 | 
						|
								const char PERCNT[]   PROGMEM = "Pct";
							 | 
						|
								
							 | 
						|
								#define IDX_UDC       0
							 | 
						|
								#define IDX_IDC       1
							 | 
						|
								#define IDX_PDC       2
							 | 
						|
								#define IDX_E_WOCHE   3
							 | 
						|
								#define IDX_E_TOTAL   4
							 | 
						|
								#define IDX_E_TAG     5
							 | 
						|
								#define IDX_UAC       6
							 | 
						|
								#define IDX_FREQ      7
							 | 
						|
								#define IDX_PAC       8
							 | 
						|
								#define IDX_E_HEUTE   9
							 | 
						|
								#define IDX_IPV      10
							 | 
						|
								#define IDX_WR_TEMP  11
							 | 
						|
								#define IDX_PERCNT   12    
							 | 
						|
								
							 | 
						|
								const char* const NAMES[] 
							 | 
						|
								  = {UDC, IDC, PDC, E_WOCHE, E_TOTAL, E_TAG, UAC, FREQ, PAC, E_HEUTE, IPV, WR_TEMP, PERCNT};
							 | 
						|
								
							 | 
						|
								typedef float (*calcValueFunc)(float *);
							 | 
						|
								
							 | 
						|
								struct measureDef_t {
							 | 
						|
								  uint8_t     nameIdx;        //const char* name;           // Zeiger auf den Messwertnamen
							 | 
						|
								  uint8_t     channel;        // 0..4, 
							 | 
						|
								  uint8_t     unitIdx;        // Index in die Liste der Einheiten 'units'
							 | 
						|
								  uint8_t     teleId;         // Telegramm ID, das was hinter der 2. WR Nummer im Telegramm, 02, 03, 83
							 | 
						|
								  uint8_t     pos;            // ab dieser POsition beginnt der Wert (Big Endian)
							 | 
						|
								  uint8_t     bytes;          // Anzahl der Bytes
							 | 
						|
								  uint8_t     digits;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								struct measureCalc_t {
							 | 
						|
								  uint8_t     nameIdx;        //const char* name;           // Zeiger auf den Messwertnamen
							 | 
						|
								  uint8_t     unitIdx;        // Index in die Liste der Einheiten 'units'
							 | 
						|
								  uint8_t     digits;
							 | 
						|
								  calcValueFunc f;            // die Funktion zur Berechnung von Werten, zb Summe von Werten
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								struct inverter_t {
							 | 
						|
								  uint8_t       ID;                       // Inverter-ID = Index
							 | 
						|
								  char          name[20];                 // Name des Inverters zb HM-600.1
							 | 
						|
								  uint64_t      serialNo;                 // dier Seriennummer wie im Barcode auf dem WR, also 1141.....
							 | 
						|
								  uint64_t      RadioId;                  // die gespiegelte (letzte 4 "Bytes") der Seriennummer
							 | 
						|
								  const measureDef_t  *measureDef;              // aus Include HMxxx.h : Liste mit Definitionen der Messwerte, wie Telgramm, offset, länge, ...
							 | 
						|
								  uint8_t       anzMeasures;              // Länge der Liste
							 | 
						|
								  measureCalc_t *measureCalculated;       // Liste mit Defintion für berechnete Werte
							 | 
						|
								  uint8_t       anzMeasureCalculated;     // Länge der Liste
							 | 
						|
								  uint8_t       anzTotalMeasures;         // Gesamtanzahl Messwerte
							 | 
						|
								  float         values[MAX_MEASURE_PER_INV];  // DIE Messewerte
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								char _buffer[20];
							 | 
						|
								
							 | 
						|
								uint8_t anzInv = 0;
							 | 
						|
								inverter_t inverters[MAX_ANZ_INV];
							 | 
						|
								  
							 | 
						|
								union longlongasbytes {
							 | 
						|
								  uint64_t ull;
							 | 
						|
								  uint32_t ul[2];
							 | 
						|
								  uint8_t bytes[8];  
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								char *uint64toa (uint64_t s) {
							 | 
						|
								//--------------------------------  
							 | 
						|
								//0x1141 72607952ULL   
							 | 
						|
								  sprintf(_buffer, "%lX%08lX", (unsigned long)(s>>32), (unsigned long)(s&0xFFFFFFFFULL));
							 | 
						|
								  return _buffer;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								uint64_t Serial2RadioID (uint64_t sn) {   
							 | 
						|
								//----------------------------------
							 | 
						|
								  longlongasbytes llsn;
							 | 
						|
								  longlongasbytes res;
							 | 
						|
								  llsn.ull = sn;
							 | 
						|
								  res.ull = 0;
							 | 
						|
								  res.bytes[4] = llsn.bytes[0];
							 | 
						|
								  res.bytes[3] = llsn.bytes[1];
							 | 
						|
								  res.bytes[2] = llsn.bytes[2];
							 | 
						|
								  res.bytes[1] = llsn.bytes[3];
							 | 
						|
								  res.bytes[0] = 0x01;
							 | 
						|
								  return res.ull;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void addInverter (uint8_t _ID, const char * _name, uint64_t _serial, 
							 | 
						|
								                  const measureDef_t * liste, int anzMeasure,
							 | 
						|
								                  measureCalc_t * calcs, int anzMeasureCalculated) {
							 | 
						|
								//-------------------------------------------------------------------------------------
							 | 
						|
								  if (anzInv >= MAX_ANZ_INV) {
							 | 
						|
								    DEBUG_OUT.println(F("ANZ_INV zu klein!"));
							 | 
						|
								    return;
							 | 
						|
								  }
							 | 
						|
								  inverter_t *p = &(inverters[anzInv]);
							 | 
						|
								  p->ID                   = _ID;
							 | 
						|
								  strcpy (p->name, _name);
							 | 
						|
								  p->serialNo             = _serial;
							 | 
						|
								  p->RadioId              = Serial2RadioID(_serial);
							 | 
						|
								  p->measureDef           = liste;
							 | 
						|
								  p->anzMeasures          = anzMeasure;
							 | 
						|
								  p->anzMeasureCalculated = anzMeasureCalculated;
							 | 
						|
								  p->measureCalculated    = calcs;
							 | 
						|
								  p->anzTotalMeasures     = anzMeasure + anzMeasureCalculated;
							 | 
						|
								  memset (p->values, 0, sizeof(p->values));
							 | 
						|
								
							 | 
						|
								  DEBUG_OUT.print (F("WR       : "));      DEBUG_OUT.println(anzInv);
							 | 
						|
								  DEBUG_OUT.print (F("Type     : "));      DEBUG_OUT.println(_name);
							 | 
						|
								  DEBUG_OUT.print (F("Serial   : "));      DEBUG_OUT.println(uint64toa(_serial));
							 | 
						|
								  DEBUG_OUT.print (F("Radio-ID : "));      DEBUG_OUT.println(uint64toa(p->RadioId));
							 | 
						|
								
							 | 
						|
								  anzInv++;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								static uint8_t toggle = 0;           // nur für Test, ob's auch für mehere WR funzt
							 | 
						|
								uint8_t findInverter (uint8_t *fourbytes) {
							 | 
						|
								//---------------------------------------
							 | 
						|
								  for (uint8_t i = 0; i < anzInv; i++) {
							 | 
						|
								    longlongasbytes llb;
							 | 
						|
								    llb.ull = inverters[i].serialNo;  
							 | 
						|
								    if (llb.bytes[3] == fourbytes[0] && 
							 | 
						|
								        llb.bytes[2] == fourbytes[1] && 
							 | 
						|
								        llb.bytes[1] == fourbytes[2] &&
							 | 
						|
								        llb.bytes[0] == fourbytes[3] )
							 | 
						|
								      {
							 | 
						|
								        return i;
							 | 
						|
								        //if (toggle) toggle = 0; else toggle = 1; return toggle;     // Test ob mehr WR  auch geht
							 | 
						|
								      }
							 | 
						|
								  }
							 | 
						|
								  return 0xFF;      // nicht gefunden
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								char * error = {"error"};
							 | 
						|
								
							 | 
						|
								char *getMeasureName (uint8_t wr, uint8_t i){
							 | 
						|
								//------------------------------------------
							 | 
						|
								  inverter_t *p = &(inverters[wr]);
							 | 
						|
								  if (i >= p->anzTotalMeasures) return error;
							 | 
						|
								  uint8_t idx, channel = 0;
							 | 
						|
								  if (i < p->anzMeasures) {
							 | 
						|
								    idx = p->measureDef[i].nameIdx;  
							 | 
						|
								    channel = p->measureDef[i].channel;
							 | 
						|
								  }
							 | 
						|
								  else {
							 | 
						|
								    idx = p->measureCalculated[i - p->anzMeasures].nameIdx;  
							 | 
						|
								  }
							 | 
						|
								  char tmp[20];
							 | 
						|
								  strcpy_P (_buffer, NAMES[idx]);
							 | 
						|
								  if (channel) {
							 | 
						|
								    sprintf_P (tmp, PSTR(".CH%d"), channel);
							 | 
						|
								    strcat(_buffer,tmp);
							 | 
						|
								  }
							 | 
						|
								  return _buffer;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const char *getUnit (uint8_t wr, uint8_t i) {
							 | 
						|
								//------------------------------------------
							 | 
						|
								  inverter_t *p = &(inverters[wr]);
							 | 
						|
								  if (i >= p->anzTotalMeasures) return error;
							 | 
						|
								  uint8_t idx;
							 | 
						|
								  if (i < p->anzMeasures)
							 | 
						|
								    idx = p->measureDef[i].unitIdx;
							 | 
						|
								  else
							 | 
						|
								    idx = p->measureCalculated[i-p->anzMeasures].unitIdx;
							 | 
						|
								  
							 | 
						|
								  //strcpy (_buffer, units[i]);
							 | 
						|
								  //return _buffer;
							 | 
						|
								  return units[idx];
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								float getMeasureValue (uint8_t wr, uint8_t i) {
							 | 
						|
								//------------------------------------------
							 | 
						|
								  if (i >= inverters[wr].anzTotalMeasures) return 0.0;
							 | 
						|
								  return inverters[wr].values[i];
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								int getDivisor (uint8_t wr, uint8_t i) {
							 | 
						|
								//------------------------------------
							 | 
						|
								  inverter_t *p = &(inverters[wr]);
							 | 
						|
								  if (i >= p->anzTotalMeasures) return 1;
							 | 
						|
								  if (i < p->anzMeasures) {
							 | 
						|
								    uint8_t digits = p->measureDef[i].digits;
							 | 
						|
								    if (digits == DIV1) return 1;
							 | 
						|
								    if (digits == DIV10) return 10;
							 | 
						|
								    if (digits == DIV100) return 100;
							 | 
						|
								    if (digits == DIV1000) return 1000;
							 | 
						|
								    return 1;
							 | 
						|
								  }
							 | 
						|
								  else
							 | 
						|
								    return p->measureCalculated[i].digits;  
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								uint8_t getDigits (uint8_t wr, uint8_t i) {
							 | 
						|
								//---------------------------------------  
							 | 
						|
								  inverter_t *p = &(inverters[wr]);
							 | 
						|
								  if (i >= p->anzTotalMeasures) return 0;
							 | 
						|
								  if (i < p->anzMeasures) 
							 | 
						|
								    return p->measureDef[i].digits;
							 | 
						|
								  else
							 | 
						|
								    return p->measureCalculated[i-p->anzMeasures].digits;  
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// +++++++++++++++++++++++++++++++++++    Inverter    ++++++++++++++++++++++++++++++++++++++++++++++
							 | 
						|
								
							 | 
						|
								#include "HM600.h"            // für HM-600 und HM-700
							 | 
						|
								
							 | 
						|
								#include "HM1200.h"
							 | 
						|
								
							 | 
						|
								// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void setupInverts() {
							 | 
						|
								//-----------------  
							 | 
						|
								
							 | 
						|
								  addInverter (0,"HM-600", 0x114172607952ULL, 
							 | 
						|
								               hm600_measureDef, HM600_MEASURE_LIST_LEN,     // Tabelle der Messwerte
							 | 
						|
								               hm600_measureCalc, HM600_CALCED_LIST_LEN); // Tabelle berechnete Werte
							 | 
						|
								
							 | 
						|
								/*
							 | 
						|
								  addInverter (1,"HM-1200", 0x114172607952ULL, 
							 | 
						|
								               hm1200_measureDef, HM1200_MEASURE_LIST_LEN,     // Tabelle der Messwerte
							 | 
						|
								               hm1200_measureCalc, HM1200_CALCED_LIST_LEN);    // Tabelle berechnete Werte
							 | 
						|
								*/
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif
							 | 
						|
								
							 |