Merge pull request #8722 from hallard/teleinfo

Added new features to Teleinfo
This commit is contained in:
Theo Arends 2020-06-18 19:13:07 +02:00 committed by GitHub
commit f9c03648a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 286 additions and 222 deletions

378
tasmota/xnrg_15_teleinfo.ino Normal file → Executable file
View File

@ -23,7 +23,12 @@
* Teleinfo : French energy provider metering telemety data * Teleinfo : French energy provider metering telemety data
* Source: http://hallard.me/category/tinfo/ * Source: http://hallard.me/category/tinfo/
* *
* Hardware Serial will be selected if GPIO1 = [TELEINFO_RX] * Denky ESP32 Teleinfo Template
* {"NAME":"Denky (Teleinfo)","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
*
* Denky (aka WifInfo) ESP8266 Teleinfo Template
* {"NAME":"WifInfo","GPIO":[7,255,255,208,6,5,255,255,255,255,255,255,255],"FLAG":15,"BASE":18}
*
\*********************************************************************************************/ \*********************************************************************************************/
#define XNRG_15 15 #define XNRG_15 15
@ -33,65 +38,92 @@
#define TINFO_READ_TIMEOUT 400 #define TINFO_READ_TIMEOUT 400
// All contract type
enum TInfoContrat{ enum TInfoContrat{
CONTRAT_BAS = 1, // BASE => Option Base. CONTRAT_BAS = 1, // BASE => Option Base.
CONTRAT_HC, // HC.. => Option Heures Creuses. CONTRAT_HC, // HC.. => Option Heures Creuses.
CONTRAT_EJP, // EJP. => Option EJP. CONTRAT_EJP, // EJP. => Option EJP.
CONTRAT_BBR // BBRx => Option Tempo CONTRAT_BBR, // BBRx => Option Tempo
CONTRAT_END
}; };
// contract displayed name
const char kContratName[] PROGMEM =
"|Base|Heures Creuses|EJP|Bleu Blanc Rouge"
;
// Received current contract value
const char kContratValue[] PROGMEM =
"|BASE|HC..|EJP.|BBR"
;
// all tariff type
enum TInfoTarif{ enum TInfoTarif{
TARIF_TH = 1, // Toutes les Heures. TARIF_TH = 1,
TARIF_HC, // Heures Creuses. TARIF_HC, TARIF_HP,
TARIF_HP, // Heures Pleines. TARIF_HN, TARIF_PM,
TARIF_HN, // BBRx => Option Tempo TARIF_CB, TARIF_CW, TARIF_CR,
TARIF_PM, // Heures de Pointe Mobile. TARIF_PB, TARIF_PW, TARIF_PR,
TARIF_CB, // Heures Creuses Jours Bleus. TARIF_END
TARIF_CW, // Heures Creuses Jours Blancs (White).
TARIF_CR, // Heures Creuses Jours Rouges.
TARIF_PB, // Heures Pleines Jours Bleus.
TARIF_PW, // Heures Pleines Jours Blancs (White).
TARIF_PR // Heures Pleines Jours Rouges.
}; };
// Label received // Received current tariff values
const char LABEL_HCHC[] PROGMEM = "HCHC"; const char kTarifValue[] PROGMEM =
const char LABEL_HCHP[] PROGMEM = "HCHP"; "|TH..|HC..|HP.."
const char LABEL_PTEC[] PROGMEM = "PTEC"; "|HN..|PM.."
const char LABEL_PAPP[] PROGMEM = "PAPP"; "|HCJB|HCJW|HCJR"
const char LABEL_IINST[] PROGMEM = "IINST"; "|HPJB|HPJW|HPJR"
const char LABEL_TENSION[] PROGMEM = "TENSION"; ;
// Some Values with string to compare to // tariff displayed name
const char VALUE_HCDD[] PROGMEM = "HC.."; const char kTarifName[] PROGMEM =
"|Toutes|Creuses|Pleines"
"|Normales|Pointe Mobile"
"|Creuses Bleu|Creuses Blanc|Creuse Rouges"
"|Pleines Bleu|Pleines Blanc|Pleines Rouges"
;
const char kTARIF_TH[] PROGMEM = "Toutes"; enum TInfoLabel{
const char kTARIF_HC[] PROGMEM = "Creuses"; LABEL_BASE = 1,
const char kTARIF_HP[] PROGMEM = "Pleines"; LABEL_HCHC, LABEL_HCHP,
const char kTARIF_HN[] PROGMEM = "Normales"; LABEL_OPTARIF, LABEL_ISOUSC, LABEL_PTEC,
const char kTARIF_PM[] PROGMEM = "Pointe Mobile"; LABEL_PAPP, LABEL_IINST, LABEL_IMAX, LABEL_TENSION,
const char kTARIF_CB[] PROGMEM = "Creuses Bleu"; LABEL_DEMAIN,
const char kTARIF_CW[] PROGMEM = "Creuses Blanc"; LABEL_END
const char kTARIF_CR[] PROGMEM = "Creuses Rouge";
const char kTARIF_PB[] PROGMEM = "Pleines Bleu";
const char kTARIF_PW[] PROGMEM = "Pleines Blanc";
const char kTARIF_PR[] PROGMEM = "Pleines Rouge";
const char * kTtarifNames[] PROGMEM = {
kTARIF_TH,
kTARIF_HC, kTARIF_HP,
kTARIF_HN, kTARIF_PM,
kTARIF_CB, kTARIF_CW, kTARIF_CR, kTARIF_PB, kTARIF_PW, kTARIF_PR
}; };
const char kLabel[] PROGMEM =
"|BASE|HCHC|HCHP"
"|OPTARIF|ISOUSC|PTEC"
"|PAPP|IINST|IMAX|TENSION"
"|DEMAIN"
;
TInfo tinfo; // Teleinfo object TInfo tinfo; // Teleinfo object
TasmotaSerial *TInfoSerial = nullptr; TasmotaSerial *TInfoSerial = nullptr;
bool tinfo_found = false; bool tinfo_found = false;
uint8_t contrat; uint8_t contrat;
uint8_t tarif; uint8_t tarif;
uint8_t isousc;
/*********************************************************************************************/ /*********************************************************************************************/
/* ======================================================================
Function: getValueFromLabelIndex
Purpose : return label value from label index
Input : label index to search for
Output : value filled
Comments: -
====================================================================== */
char * getValueFromLabelIndex(int labelIndex, char * value)
{
char labelName[16];
// Get the label name
GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel);
// Get value of label name
return tinfo.valueGet(labelName, value) ;
}
/* ====================================================================== /* ======================================================================
Function: ADPSCallback Function: ADPSCallback
Purpose : called by library when we detected a ADPS on any phased Purpose : called by library when we detected a ADPS on any phased
@ -107,9 +139,9 @@ Comments: should have been initialised in the main sketch with a
void ADPSCallback(uint8_t phase) void ADPSCallback(uint8_t phase)
{ {
// n = phase number 1 to 3 // n = phase number 1 to 3
if (phase == 0) if (phase == 0){
phase = 1; phase = 1;
}
AddLog_P2(LOG_LEVEL_INFO, PSTR("ADPS on phase %d"), phase); AddLog_P2(LOG_LEVEL_INFO, PSTR("ADPS on phase %d"), phase);
} }
@ -124,85 +156,109 @@ Comments: -
void DataCallback(struct _ValueList * me, uint8_t flags) void DataCallback(struct _ValueList * me, uint8_t flags)
{ {
char c = ' '; char c = ' ';
int ilabel ;
// Does this value is new or changed? // Does this value is new or changed?
if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) {
{ char labelName[16];
if (flags & TINFO_FLAGS_ADDED) { c = '#'; } // Find the label index
if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } for ( ilabel = 1 ; ilabel < LABEL_END ; ilabel++) {
GetTextIndexed(labelName, sizeof(labelName), ilabel, kLabel);
if (!strcmp(labelName, me->name)) {
break;
}
}
// Current tarif // Current tariff
if (!strcmp_P(LABEL_PTEC, me->name)) if (ilabel == LABEL_PTEC)
{ {
if (!strcmp_P("TH..", me->name)) { tarif = TARIF_TH; } char tarif_value[] = " "; // 4 spaces
else if (!strcmp_P("HC..", me->name)) { tarif = TARIF_HC; } // Find the tariff index
else if (!strcmp_P("HP..", me->name)) { tarif = TARIF_HP; } for (tarif = TARIF_TH ; tarif < TARIF_END ; tarif++) {
else if (!strcmp_P("HN..", me->name)) { tarif = TARIF_HN; } GetTextIndexed(tarif_value, sizeof(tarif_value), tarif-1, kTarifValue);
else if (!strcmp_P("PM..", me->name)) { tarif = TARIF_PM; } if (!strcmp(tarif_value, me->value)) {
else if (!strcmp_P("HCJB", me->name)) { tarif = TARIF_CB; } break;
else if (!strcmp_P("HCJW", me->name)) { tarif = TARIF_CW; } }
else if (!strcmp_P("HCJR", me->name)) { tarif = TARIF_CR; } }
else if (!strcmp_P("HPJB", me->name)) { tarif = TARIF_PB; }
else if (!strcmp_P("HPJW", me->name)) { tarif = TARIF_PW; }
else if (!strcmp_P("HPJR", me->name)) { tarif = TARIF_PR; }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif);
} }
// Voltage V (not present on all Smart Meter) // Voltage V (not present on all Smart Meter)
else if (!strcmp_P(LABEL_TENSION, me->name)) else if ( ilabel == LABEL_TENSION)
{ {
Energy.voltage_available = true; Energy.voltage_available = true;
int i = atoi(me->value);
Energy.voltage[0] = (float) atoi(me->value); Energy.voltage[0] = (float) atoi(me->value);
// Update current // Update current
if (Energy.voltage_available && Energy.voltage[0]) { if (Energy.voltage_available && Energy.voltage[0]) {
Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ;
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, (int) Energy.voltage[0]);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, i);
} }
// Current I // Current I
else if (!strcmp_P(LABEL_IINST, me->name)) else if (ilabel == LABEL_IINST)
{ {
if (!Energy.voltage_available) { if (!Energy.voltage_available) {
int i = atoi(me->value);
Energy.current[0] = (float) atoi(me->value); Energy.current[0] = (float) atoi(me->value);
} else if (Energy.voltage[0]) { } else if (Energy.voltage[0]) {
Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ;
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]);
} }
// Current P
else if (!strcmp_P(LABEL_PAPP, me->name)) // Power P
else if (ilabel == LABEL_PAPP)
{ {
int papp = atoi(me->value); int papp = atoi(me->value);
Energy.active_power[0] = (float) atoi(me->value);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp);
Energy.active_power[0] = (float) atoi(me->value);
// Update current // Update current
if (Energy.voltage_available && Energy.voltage[0]) { if (Energy.voltage_available && Energy.voltage[0]) {
Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ;
} }
} }
// kWh indexes
else if (!strcmp_P(LABEL_HCHC, me->name) || !strcmp(LABEL_HCHP, me->name)) // Wh indexes
else if ( ilabel == LABEL_HCHC || ilabel == LABEL_HCHP)
{ {
char value[32]; char value[32];
unsigned long hc = 0; uint32_t hc = 0;
unsigned long hp = 0; uint32_t hp = 0;
unsigned long total = 0; uint32_t total = 0;
if ( tinfo.valueGet_P(LABEL_HCHC, value) ) { hc = atol(value);} if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { hc = atoi(value);}
if ( tinfo.valueGet_P(LABEL_HCHP, value) ) { hp = atol(value);} if ( getValueFromLabelIndex(LABEL_HCHP, value) ) { hp = atoi(value);}
total = hc + hp; total = hc + hp;
EnergyUpdateTotal(total/1000.0f, true); EnergyUpdateTotal(total/1000.0f, true);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u HP:%u Total:%u"), hc, hp, total);
}
// Contract subscribed
else if (ilabel == LABEL_OPTARIF)
{
char contrat_value[] = " "; // 4 spaces
// Find the contract index
for (contrat = CONTRAT_BAS ; contrat < CONTRAT_END ; contrat++) {
GetTextIndexed(contrat_value, sizeof(contrat_value), contrat, kContratValue);
if (!strcmp(contrat_value, me->value)) {
break;
} }
} }
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s' (%d)"), me->value, contrat);
}
// Contract subscribed (Power)
else if (ilabel == LABEL_ISOUSC)
{
isousc = atoi( me->value);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc);
}
}
if (flags & TINFO_FLAGS_ADDED) { c = '#'; }
if (flags & TINFO_FLAGS_UPDATED) { c = '*'; }
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TIC: %c %s=%s"),c , me->name, me->value);
} }
/* ====================================================================== /* ======================================================================
@ -218,23 +274,14 @@ void NewFrameCallback(struct _ValueList * me)
Energy.data_valid[0] = 0; Energy.data_valid[0] = 0;
} }
/* ====================================================================== /* ======================================================================
Function: NewFrameCallback Function: TInfoDrvInit
Purpose : callback when we received a complete Teleinfo frama Purpose : Tasmota core driver init
Input : label to search for Input : -
Output : value filled Output : -
Comments: - Comments: -
====================================================================== */ ====================================================================== */
char * getDataValue_P(const char * label, char * value)
{
if (!tinfo.valueGet_P(label, value) ) {
*value = '\0';
}
return value;
}
void TInfoDrvInit(void) { void TInfoDrvInit(void) {
if (PinUsed(GPIO_TELEINFO_RX)) { if (PinUsed(GPIO_TELEINFO_RX)) {
energy_flg = XNRG_15; energy_flg = XNRG_15;
@ -244,6 +291,13 @@ void TInfoDrvInit(void) {
} }
} }
/* ======================================================================
Function: TInfoInit
Purpose : Tasmota core device init
Input : -
Output : -
Comments: -
====================================================================== */
void TInfoInit(void) void TInfoInit(void)
{ {
#ifdef USE_TELEINFO_STANDARD #ifdef USE_TELEINFO_STANDARD
@ -254,31 +308,32 @@ void TInfoInit(void)
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED);
if (PinUsed(GPIO_TELEINFO_RX)) if (PinUsed(GPIO_TELEINFO_RX)) {
{
uint8_t rx_pin = Pin(GPIO_TELEINFO_RX); uint8_t rx_pin = Pin(GPIO_TELEINFO_RX);
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d"), rx_pin); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d"), rx_pin);
// Enable Teleinfo
if (PinUsed(GPIO_TELEINFO_ENABLE)) // Enable Teleinfo pin used, control it
{ if (PinUsed(GPIO_TELEINFO_ENABLE)) {
uint8_t en_pin = Pin(GPIO_TELEINFO_ENABLE); uint8_t en_pin = Pin(GPIO_TELEINFO_ENABLE);
pinMode(en_pin, OUTPUT); pinMode(en_pin, OUTPUT);
digitalWrite(en_pin, HIGH); digitalWrite(en_pin, HIGH);
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Enable with GPIO%d"), en_pin); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Enable with GPIO%d"), en_pin);
} } else {
else
{
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled")); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled"));
} }
TInfoSerial = new TasmotaSerial(rx_pin, -1, 1); TInfoSerial = new TasmotaSerial(rx_pin, -1, 1);
// pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP);
// Trick here even using SERIAL_7E1 or TS_SERIAL_7E1 // Trick here even using SERIAL_7E1 or TS_SERIAL_7E1
// this is not working, need to call SetSerialConfig after // this is not working, need to call SetSerialConfig after
if (TInfoSerial->begin(TINFO_SPEED)) if (TInfoSerial->begin(TINFO_SPEED)) {
{ // This is a hack, looks like begin does not take into account
// the TS_SERIAL_7E1 configuration so on ESP8266 this is
// working only on Serial RX pin (Hardware Serial) for now
SetSerialConfig(TS_SERIAL_7E1);
TInfoSerial->setTimeout(TINFO_READ_TIMEOUT);
#if defined (ESP8266) #if defined (ESP8266)
if (TInfoSerial->hardwareSerial() ) { if (TInfoSerial->hardwareSerial() ) {
ClaimSerial(); ClaimSerial();
@ -287,35 +342,29 @@ void TInfoInit(void)
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using software serial")); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using software serial"));
} }
// This is a dirty hack, looks like begin does not take into account
// the TS_SERIAL_7E1 configuration so on ESP8266 this is
// working only on Serial RX pin (Hardware Serial) for now
SetSerialConfig(TS_SERIAL_7E1);
TInfoSerial->setTimeout(TINFO_READ_TIMEOUT);
#elif defined (ESP32) #elif defined (ESP32)
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial")); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial"));
// Waiting TasmotaSerial PR merged to change that
//TInfoSerial->reconf(TINFO_SPEED, SERIAL_7E1);
#endif #endif
// Init teleinfo // Init teleinfo
tinfo.init(); tinfo.init();
// Attach needed callbacks // Attach needed callbacks
tinfo.attachADPS(ADPSCallback); tinfo.attachADPS(ADPSCallback);
tinfo.attachData(DataCallback); tinfo.attachData(DataCallback);
tinfo.attachNewFrame(NewFrameCallback); tinfo.attachNewFrame(NewFrameCallback);
tinfo_found = true; tinfo_found = true;
AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready"));
} }
} }
} }
void TInfoLoop(void) /* ======================================================================
Function: TInfoEvery250ms
Purpose : Tasmota callback executed every 250ms
Input : -
Output : -
Comments: -
====================================================================== */
void TInfoEvery250ms(void)
{ {
char c; char c;
if (!tinfo_found) if (!tinfo_found)
@ -323,65 +372,86 @@ void TInfoLoop(void)
if (TInfoSerial->available()) { if (TInfoSerial->available()) {
//AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); //AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available());
// We received some data? // We received some data?
while (TInfoSerial->available()>8) while (TInfoSerial->available()>8) {
{
// get char // get char
c = TInfoSerial->read(); c = TInfoSerial->read();
// data processing // data processing
tinfo.process(c); tinfo.process(c);
} }
} }
} }
/* ======================================================================
void TInfoEvery250ms(void) Function: TInfoShow
{ Purpose : Tasmota callback executed to send telemetry or WEB display
} Input : -
Output : -
Comments: -
====================================================================== */
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_KILOWATTHOUR "{e}" ; const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ; const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ; const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif{m}%s{e}" ; const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif en cours{m}Heures %s{e}" ;
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}Contrat{m}%s %d" D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}Charge actuelle{m}%d" D_UNIT_PERCENT "{e}" ;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
void TInfoShow(bool json) void TInfoShow(bool json)
{ {
char name[32];
char value[32]; char value[32];
// TBD
// Since it's an Energy device , current, voltage and power are
// already present on the telemetry frame. No need to add here
// Just add the specific and missing ones there
if (json) if (json)
{ {
if ( tinfo.valueGet_P(LABEL_PTEC, value) ) { if ( getValueFromLabelIndex(LABEL_PTEC, value) ) {
ResponseAppend_P(PSTR(",\"" "TARIF" "\":%s"), value); ResponseAppend_P(PSTR(",\"" "TARIF" "\":\"%s\""), value);
} }
if ( tinfo.valueGet_P(LABEL_IINST, value) ) {
ResponseAppend_P(PSTR(",\"" D_CURRENT "\":%s"), value); GetTextIndexed(name, sizeof(name), LABEL_ISOUSC, kLabel);
ResponseAppend_P(PSTR(",\"%s\":%d"), name, isousc);
if ( getValueFromLabelIndex(LABEL_HCHC, value) ) {
GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel);
ResponseAppend_P(PSTR(",\"%s\":\"%u\""), name, atoi(value));
} }
if ( tinfo.valueGet_P(LABEL_PAPP, value) ) { if ( getValueFromLabelIndex(LABEL_HCHP, value) ) {
ResponseAppend_P(PSTR(",\"" D_POWERUSAGE "\":%s"), value); GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel);
ResponseAppend_P(PSTR(",\"%s\":\"%u\""),name , atoi(value));
} }
if ( tinfo.valueGet_P(LABEL_HCHC, value) ) {
ResponseAppend_P(PSTR(",\"" "HC" "\":%s"), value); if (isousc) {
} ResponseAppend_P(PSTR(",\"Load\":\"%d\""),(int) ((Energy.current[0]*100.0f) / isousc));
if ( tinfo.valueGet_P(LABEL_HCHP, value) ) {
ResponseAppend_P(PSTR(",\"" "HP" "\":%s"), value);
} }
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} }
else else
{ {
getDataValue_P(LABEL_HCHC, value); if (getValueFromLabelIndex(LABEL_HCHC, value) ) {
WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HC, value); GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel);
getDataValue_P(LABEL_HCHP, value); WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value);
WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HP, value); }
if (tarif) { if (getValueFromLabelIndex(LABEL_HCHP, value) ) {
WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, kTtarifNames[tarif-1]); GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel);
WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value);
}
if (tarif) {
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, name,value);
}
if (contrat) {
GetTextIndexed(name, sizeof(name), contrat, kContratName);
WSContentSend_PD(HTTP_ENERGY_CONTRAT_TELEINFO, name, isousc);
if (isousc) {
int percent = (int) ((Energy.current[0]*100.0f) / isousc) ;
WSContentSend_PD(HTTP_ENERGY_LOAD_TELEINFO, percent);
}
} }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
} }
@ -389,20 +459,14 @@ void TInfoShow(bool json)
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
bool Xnrg15(uint8_t function) bool Xnrg15(uint8_t function)
{ {
switch (function) switch (function)
{ {
case FUNC_LOOP:
if (TInfoSerial) { TInfoLoop(); }
break;
case FUNC_EVERY_250_MSECOND: case FUNC_EVERY_250_MSECOND:
if (uptime > 4) { TInfoEvery250ms(); } if (uptime > 4) { TInfoEvery250ms(); }
break; break;
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
TInfoShow(1); TInfoShow(1);
break; break;
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER