Source file: /~heha/mb-iwp/Energiemessung/VIPsys3/vipsys3.zip/src/analyzer.h

#pragma once
/*======================================================================*
 * Data structures of ELCONTROL VIP System 3 / VIP MK3 Energy Analyzer	*
 * Added useful generic routines and necessary constant data		*
 * heha, 100811								*
 * This is a C++ header file, not intended to be used with C		*
 *======================================================================*/
#include <windows.h>	// definitions of BYTE, etc

struct HEXBYTE{
 char d[2];	// two hexadecimal digits ('0'..'9', 'A'..'F'), LSD first!
};

// The "string" record, here for maximum data length
// This is very similar to an INTEL HEX record
struct STRING{
 union{
  char summed[39];	// 7 to 39 bytes, always odd length
  struct{
   char colon;		// always ':'
   HEXBYTE len;		// the length of <summed>(?)
   HEXBYTE addr[2];	// LSB first, sequence number, zero-based, EOF=0x1000 *)
   HEXBYTE data[16];	// 0 to 16 data bytes
  };		// Following struct members cannot be used directly!
 };
 char check;	// one hexadecimal digit over <summed>, then HIGH and LOW nibble XORed
 char cr;	// always '\r'
 char lf;	// always '\n'
};		// sizeof() must be 42

// *) For memory pack transfers, addr is the byte address >>4.

enum{
 wrong_hex=-1,		// Wrong hexadecimal numbers (not [0-9A-F]) detected at string_decode(), NO small letters allowed!
 wrong_length=-2,	// Wrong length detected at string_decode(), wrong length given at string_encode() (must be 0..16)
 wrong_header=-3,	// Wrong header (not ':', or the two length characters) detected at string_decode()
 wrong_footer=-4,	// Wrong footer (not CR LF) detected at string_decode()
 wrong_check=-5,	// Wrong checksum detected at string_decode()
 buffer_too_small=-6,	// 1. The string_encode() target buffer must have enough room for data
			// 2. The target buffer is too small while recording recordsizes
 wrong_recordsize=-7,	// record size received doesn't match to <delim> array given
 cannot_record=-8,	// delim buffer too small
 no_buffer=-9,		// no buffer allocated
 incomplete=-10,	// when buffer must be sent/received completely
 wrong_echo=-14,	// transmission error while canceling an (elsewhere correct) transmission due to a short receive buffer condition
 unmatched_recordsize=-15,	// wrong record size detected while receiving string records
 sendrecv_errors=-256,	// error codes are shifted below this value (i.e. 256 is subtracted)
};

// Two functions for conversion from/to raw data
// <dl> is the "destination length", in bytes or characters.
// The return value is the number of bytes/characters written, or a negative error value.
int string_encode(const void*s, int l, int a, char*d, int dl=42);
int string_decode(const char*s, int l, int*a, void*d, int dl=16);

// Two functions for processing longer STRING messages, with blocking sendrecv()
//   sendrecv() must block until '\n' is received.
//   sendrecv() should notify the waiting user for progress,
//   because transferring can be time-consuming (some seconds).
int string_send(const void*s, int l, int(*sendrecv)(const char*,int,char*,int), const BYTE*delim=NULL, int a=0);
// <delim> says how to split the data given by <s>. If NULL, maximum sizes (16) are assumed.
// <a> holds the first block number or the high 16 bits of the first row address of a memory expansion module.
// The address is auto-incremented by 1 for each record.
// This enables memory transfers of up to 1 MByte, as designed by ELCONTROL.
// An EOF record is appended and sent automatically.
// The return value should be equal <l> but may be less if <delim> array is zero-terminated earlier.
int string_recv(void*d, int l, int(*sendrecv)(const char*,int,char*,int), BYTE*delim=NULL, int dl=0, int a=0);
// This function reads STRING records until it receives an EOF record, or the <d> buffer (byte size <l>) is full.
// In the latter case, an Abort (ESC A CR LF) is sent.
// The EOF record has zero data length, the EOF address (0x1000) is not checked.
// <delim> saves the received record sizes, its buffer size is given with <dl>
// If <dl> is zero and <delim> not NULL, this function /checks/ the received block sizes against <delim> array given
// (cast the const pointer, no write access is made)
// If <delim> is NULL, no checking or recording is done, <dl> should be 0.
// Both functions return negative error codes from <send>,<recv>,<string_encode>,<string_decode>,
// and failing delim-array match
// <a> is expected as first address.

/****************************************************************
 * Definition of record sizes (<delim>), needed for encoding	*
 * (and for checking while receiving) STRING records		*
 ****************************************************************/
 
extern const BYTE RecordListP[];	// ESC P (programming data) "packed" record sizes
extern const BYTE RecordList0[];	// ESC M (all measures) - but without tariff band tails
extern const BYTE RecordListT[];	// One tariff tail, and for ESC m<10> to ESC m<14>
extern const BYTE RecordList6[];	// ESC m6
extern const BYTE RecordList9[];	// ESC m9
extern const BYTE RecordListD[];	// ESC D

// Two helper functions
// 1. To check how many records must be read beyond a specific data byte offset
//    Returns 0 on error (offset too large)
//    All predefined record lists define less than 256 records, so you can cast the result to BYTE safely.
int offsettorecord(const BYTE*delim, int offset);
// 2. How often <sendrecv> is called for this list, to draw a meaningful progress bar.
//    The EOF record and the initial "ESC?\r\n" are not counted, so add 2 for an exact progress.
int numberofrecords(const BYTE*delim);

/****************************************************************
 * Definition of serial transferred data structures		*
 * AFTER decoding vs. BEFORE encoding into STRING records	*
 ****************************************************************/

#pragma pack(1)
// The <short> data are only valid if:
// * the machine has little-endian architecture (otherwise, swap bytes)
// * the machine supports unaligned data access (otherwise, re-define the following 2 structs)
// The current targets are "x86" and "amd64", where these assumptions are true.

struct VAL2{
 short w;	// mantissa with fixed exponent (always a fixed-point number in the form "x.xxx" or "xx.xx")
 double toFloat(char e) const;
};

struct VAL3{
 short w;	// mantissa (documentation says nothing about sign, but I've never seen integers larger than 9999)
 char e;	// exponent of base 10 (decimal point position and/or unit prefix)
 double toFloat() const;
};

struct VAL9{
 char b[9];	// ASCII data (maybe left-justified with zeroes) - but the manual says "packed BCD"
};

// Answer for all measurement values request (ESC M)
struct STRING_ESCM{
 VAL2 f;	// frequency * 10^-2
 VAL3 i[4];	// instanteous currents (RMS - Effektivwert), sum - Stromsumme
 VAL3 in;	// neutral wire - Nullleiter
 VAL3 u[4];	// instanteous voltages, mean value of u1..u3
 VAL3 u12;	// delta connection voltages - Spannungen der Dreieckschaltung
 VAL2 u23;	// common exponent with u12
 VAL2 u31;
 VAL3 p[4];	// active power - Wirkleistung
 VAL3 pa[4];	// average active power - Gemittelte Wirkleistung
 VAL3 s[4];	// apparent power - Scheinleistung
 VAL3 sa[4];	// average apparent power - Gemittelte Scheinleistung
 VAL3 q[4];	// reactive power - Blindleistung
 VAL3 qa[4];	// average reactive power - Gemittelte Blindleistung
 VAL2 d[4];	// harmonic distortion - Klirrfaktor * 10^-2 %
 VAL2 da[4];	// average harmonic distortion - Klirrfaktor-Mittel * 10^-2 %
 VAL2 c[4];	// power factor - Leistungsfaktor (cos phi) * 10^-3
 VAL2 ca[4];	// average power factor - Leistungsfaktor-Mittel (cos phi) * 10^-3
 VAL3 ta[4];	// average tan phi
 VAL9 w1;	// Phase 1 active energy consumption
 VAL9 y1;	// Phase 1 reactive energy "consumption"
 VAL9 w2;
 VAL9 y2;
 VAL9 w3;
 VAL9 y3;
 VAL9 ws;
 VAL9 ys;	// packed BCD msb,lsb (ganze kWh? Wäre 18-stellig)
 BYTE aux[6];
 VAL3 pp[4];	// Maximum active power - Spitzen-Wirkleistung
 VAL3 sp[4];	// Maximum apparent power - Spitzen-Scheinleistung
 VAL3 qp[4];	// Maximum reactive power - Spitzen-Blindleistung
 VAL2 dp[4];	// Maximum harmonic distortion - Spitzen-Klirrfaktor * 10^-2 %
};		// sizeof() should be 274!

// this is appended to STRING_ESCM for each tariff band set
struct STRING_ESC10{
 VAL3 ca[4];	// average power factors
 VAL3 ta[4];	// average tan phi
 VAL9 w1,y1,w2,y2,w3,y3,ws,ys;	// format ASCII msb,lsb (oder doch BCD?)
};

// Answer for ESC M 1 (?)
struct STRING_ESCM1{
 VAL3 u,i,p;	// Instanteous voltage, current, power (sum)
 VAL2 c;
};

// Answer for ESC 5
struct STRING_ESC5{
 VAL3 u12;
 VAL2 u23;
 VAL2 u31;
 VAL3 in;
 VAL2 f;
};

// Answer for ESC 6
struct STRING_ESC6{
 VAL3 p[4];	// Instanteous powers (1-2-3-S)
 VAL3 pa[4];	// Average powers
 VAL3 pp[4];	// Peak powers
};

// Answer for ESC 9
struct STRING_ESC9{
 VAL2 d[4];
 VAL2 da[4];
 VAL2 dp[4];
};

// Answer for ESC 15
struct STRING_ESC15{
 VAL3 aux[2];
};

enum MODO{
 F_3W,			// instead of 4W
 F_MediumVoltage,	// instead of Low Voltage (max. 1000 V)
 F_ClampMeterInversion,
 F_BlackBox,
 F_BB_with_secondary_program,
 F_LMA,			// otherwise, Pyrometer
 F_Calibration
};

struct STRING_ESCP{
 BYTE modo;		// bits of MODO enum
 BYTE colleg[2];	// 4 Wire -> 03,8A, 3 Wire -> 03,DE
 BYTE t_tens[2];	// Low Voltage -> 04,8A, Medium Voltage -> 04,DE
 BYTE ka[6];		// current full scale, ASCII msb,lsb
 BYTE ku[6];		// voltage vull scale, ASCII msb,lsb
 BYTE cos0[4];		// cos phi set, ASCII msb,lsb
 BYTE t_integ[2];	// integration time, ASCII msb,lsb (minutes?)
 BYTE t_stampa[2];	// print time, ASCII msb,lsb (minutes?)
 BYTE t_p_all[2];	// alarm print time, ASCII msb,lsb (minutes?)
 BYTE day[2];
 BYTE month[2];
 BYTE year[2];
 BYTE hour[2];
 BYTE minutes[2];
 BYTE seconds[2];	// clock set-up, ASCII msb,lsb (minutes?)
 BYTE lingua;		// 0=it, 1=en, 2=de, 3=fr
 BYTE layer[2];		// it->00,82, en->01,95, de->02,AC, fr->03,BF
// Local printer programming group
 struct PR{
  BYTE n_posiz;		// positions occupied(?) 00/04
  BYTE n_contat;	// meters selected 00/02
  BYTE n_grand;		// other parameters selected 00/04
  BYTE layer[8];	// pointer for display of the 4 parameters selected
  BYTE strada[54];	// pointer for display of path of reverses for parameter select (??)
  BYTE strad0;		// bit 0: 1 -> at least 1 parameter selected
  BYTE memori[8];	// parameter selection buffer
 }pr;
// Plotter 1+2 programming data group
 struct PL{
  BYTE n_posiz;		// positions occupied
  BYTE layer[2];
  BYTE strada[42];
  BYTE strad0;
  BYTE fifo[2];
  BYTE range;
  BYTE tcamp[2];	// sampling time (format ASCII)
  BYTE bufexp[8];	// exponent of every parameter available
  BYTE wplott[82];	// plotter range in manual selection
 }pl[2];
// Remote printer programming data group
 struct RPR{
  BYTE n_posiz;		// positions occupied 00/0D
  BYTE layer[26];
  BYTE strada[54];
  BYTE strad0;		// bit 5,6: 1,1 -> at least 1 parameter for remote print-out
  BYTE driver[26];	// parameter selection buffer
  BYTE n_ar_est[3];	// Number of spaced characters (format ASCII) e.g. "80"
  BYTE n_car_com[3];	// Number of condensed characters e.g. "132"
  BYTE seq_comp[8];	// Sequence for Compressed Font ON (17 cpi)
  BYTE seq_decom[8];	// Sequence for Compressed Font OFF (10 cpi)
  BYTE on_sott[8];	// Sequence for Underlining ON (e.g. ESC U 1)
  BYTE off_sott[8];	// Sequence for Underlining ONF (e.g. ESC U 0)
 }rpr;
// Relay 1+2 programming data group
 struct REL{
  BYTE n_posiz;		// positions occupied 00/01
  BYTE layer[2];
  BYTE strad0;
  BYTE strad2;
  BYTE strad3;		// bit 0: minimum alarm, bit 1: maximum alarm
  BYTE fifo[3];
  BYTE strada[84];
 }rel[2];
// Alarm programming group
 struct AL{
  BYTE layer_min[96];	// pointer for display of parameter selected for Minimum Alarms
  BYTE layer_max[96];	// pointer for display of parameter selected for Maximum Alarms
  BYTE layer_tar[96];	// pointer for display of parameter selected for Tariff Band Alarms
  BYTE wall1[206];
  BYTE wall2[206];
  BYTE bufexp[30];
  BYTE wall5[192];
  BYTE tins[2];		// intensity time
 }al;
// RESET code
 BYTE wres[4];		// RESET code (format ASCII) = Password
 BYTE fascie;		// Flag of band programmed, bit 0 = band 1 etc. up to band 4
// Timed Alarms
 BYTE wfunz[32];
};

struct STRING_ESCD{
 struct SURVEY{
  BYTE YY[2],MM[2],GG[2],HH[2],mm[2];	// start/end time, format ASCII
 }survey[2];
 BYTE EE;
 BYTE BB[4];
 BYTE mm;		// rate, in minutes
 BYTE modo;		// see MODO enum
 BYTE ka[3];		// current full scale
 BYTE ku[3];		// voltage full scale
 BYTE cc;		// full-scale power factor, HEX
 BYTE tt;		// integration time, packed BCD
};


struct STRING_ESCL{
 BYTE cadenza[2];	// sampling rate for manual survey (01/99), format ASCII msb,lsb
 BYTE codice[4];	// code of manual survey (0000/9999), format ASCII msb,lsb
};


#pragma pack()

Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded