Compare commits

...

29 Commits

Author SHA1 Message Date
Charles 8bdba6f2a5 Fix buffer size 2020-06-14 21:39:37 +02:00
Charles 4e2a5b603d Bump to 1.1.2 2020-06-14 21:39:03 +02:00
Charles c23c353a96 cleanup 2020-06-13 02:11:09 +02:00
Charles 3272960531 Fixed link ESP8266 2020-06-13 02:07:05 +02:00
Charles 54c54575f0 Ajout exemple ESP8266 2020-06-13 02:06:06 +02:00
Charles c3fdacc8db fixed (hopefully) corruption of data 2020-06-13 01:38:00 +02:00
Charles fe33bf622a bump to v1.1.1 2020-06-13 01:37:00 +02:00
Charles f54c40bdb3 Re ordered struct to be more aligned 2020-06-13 01:35:53 +02:00
Charles f85ec633a0 Fixed samples links 2020-06-11 13:23:01 +02:00
Charles 36904dc209 Merge branch 'master' of https://github.com/hallard/LibTeleinfo 2020-06-11 13:14:06 +02:00
Charles 7b11dda2a7 Creation 2020-06-11 13:14:02 +02:00
Charles 5b036bbf7d bump to V1.1.0 2020-06-11 13:13:50 +02:00
Charles 2849c7bbdd Ajout ESP32 2020-06-11 13:13:10 +02:00
Charles d5ae0803e0 Fix label name corruption + ESP32
Fixed buffer corruption
added ESP32 compatibility
2020-06-11 13:10:14 +02:00
Charles 12d8c6b797
Merge pull request #12 from Yogui79/master
Update LibTeleinfo.cpp
2018-02-01 00:36:11 +01:00
Yogui79 973977b304
Update LibTeleinfo.cpp
spelling correction checksum variable
2018-01-22 16:06:14 +01:00
Charles ee5e5ddfc3 UI, set Jeedom max input char to 48 2016-11-13 19:09:50 +01:00
Charles ced70de7d1 compiler fix on stricmp 2016-11-13 19:09:27 +01:00
Charles 2f4c6426df Set default RGB led to RGB instead of GRB 2016-11-13 19:09:05 +01:00
Charles 0cf237c7e5 Bump to Version 1.0.1 2016-11-13 19:08:13 +01:00
Charles f3aa58b76e set Jeedom API key size from 32 to 48 2016-11-13 19:07:54 +01:00
Charles 98ee48aae7 emoncms and jeedom port >255 problem fix 2016-07-26 18:30:23 +02:00
Charles 8fcf897859 AP Access problem BugFix 2016-07-26 18:29:56 +02:00
Charles d2b5a16450 calcChecksum is now public 2016-05-14 21:42:44 +02:00
Charles f35138ebfe correction pb avec les PSTR 2016-05-09 17:57:36 +02:00
Charles 048167311d Change according new NeoPixelbus library 2016-05-09 16:08:12 +02:00
Charles 976095f3ef Added bytes alignment calculation on ESP8266 2016-05-09 16:07:38 +02:00
Charles 61d36940d9 v1.0.2 2016-05-09 16:06:52 +02:00
Charles 8069dde82f Reworked http;begin call to conform new ESP lib 2016-05-09 15:49:08 +02:00
13 changed files with 804 additions and 101 deletions

View File

@ -1,5 +1,5 @@
Teleinfo Universal Library
==========================
Teleinfo (Aka TIC) Universal Library
====================================
This is a generic Teleinfo French Meter Measure Library, it can be used on Arduino like device and also such as Spark Core, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp code ...
@ -7,7 +7,9 @@ You can see Teleinformation official french datasheet [there][1]
Since this is really dedicated to French energy measuring system, I will continue in French
###Installation
Installation
============
Copier le contenu de ce dossier (download zip) dans le dossier libraries de votre environnement Arduino Vous devriez avoir maintenant quelque chose comme `your_sketchbook_folder/libraries/LibTeleinfo` et ce dossier doit contentir les fichiers .cpp et .h ainsi que le sous dossier `examples`.
<br/>
Pour trouver votre dossier de sketchbook, dans l'environnement IDE, allez dans File>Preferences.
@ -15,26 +17,35 @@ Pour trouver votre dossier de sketchbook, dans l'environnement IDE, allez dans F
allez voir ce [tutorial][2] sur les librairies Arduino si beoin.
<br/>
##Documentation
Documentation
=============
J'ai écrit un article [dédié][10] sur cette librairie, vous pouvez aussi voir les [catégories][6] associées à la téléinfo sur mon [blog][7].
Pour les commentaires et le support vous pouvez allez sur le [forum][8] dédié ou dans la [communauté][9]
###Sketch d'exemples
Sketch d'exemples
=================
- [Arduino_Softserial_Etiquette][3] Affiche des informations de téléinformation reçue étiquette par étiquette
- [Arduino_Softserial_Blink][11] Affiche des informations de téléinformation reçue trame par trame avec clignotement LED court/long si les données ont été modifiés
- [Arduino_Softserial_JSON][4] Retourne les informations de téléinformation au format JSON sur la liaison série.
- [Raspberry_JSON][12] Retourne les informations de téléinformation au format JSON sur stdout.
- [Wifinfo][5] ESP8266 Wifi Teleinformation, Web + Rest + bonus, version en cours de développement, à venir mais un article [dédié][13] est déjà présent sur mon blog
- [Wifinfo][5] ESP8266, ESP32 Wifi Teleinformation, Web + Rest + bonus, version en cours de développement, à venir mais un article [dédié][13] est déjà présent sur mon blog
- [ESP32][14] ESP32 Basic test pour WifInfo32 nouveau nom Denky :-)
- [ESP8266_DataChanged][15] ESP8266 Surveille et affiche les données changées entre 2 trames, clignote la LED RGB en fonction
##Pourquoi
- J'utilise la téléinfo dans plusieurs de mes programmes et j'en avait marre de devoir faire des copier/coller de code constament, j'ai donc décidé de faire une librairie commune que j'utilise sans me poser de question
Pourquoi
========
- J'utilise la téléinfo dans plusieurs de mes programmes et j'en avais marre de devoir faire des copier/coller de code constament, j'ai donc décidé de faire une librairie commune que j'utilise sans me poser de question
##License
License
=======
Cette oeuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas dUtilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.
Si vous êtes une entreprise et que vous souhaitez participer car vous utilisez cette librairie dans du hardware (box, automate, ...), vous pouvez toujours m'envoyer un exemplaire de votre fabrication, c'est toujours sympa de voir ce qui est fait avec ce code ;-)
##Divers
Divers
======
Vous pouvez aller voir les nouveautés et autres projets sur [blog][7]
[1]: http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf
@ -45,10 +56,12 @@ Vous pouvez aller voir les nouveautés et autres projets sur [blog][7]
[9]: https://community.hallard.me
[10]: https://hallard.me/libteleinfo
[3]: https://github.com/hallard/LibTeleinfo/blob/master/Examples/Arduino_Softserial/Arduino_Softserial_Etiquette.ino
[4]: https://github.com/hallard/LibTeleinfo/blob/master/Examples/Arduino_Softserial_JSON/Arduino_Softserial_JSON.ino
[3]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Etiquette.ino
[4]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial_JSON/Arduino_Softserial_JSON.ino
[5]: https://github.com/hallard/LibTeleinfo/tree/master/examples/Wifinfo/Wifinfo.ino
[11]: https://github.com/hallard/LibTeleinfo/blob/master/Examples/Arduino_Softserial/Arduino_Softserial_Blink.ino
[12]: https://github.com/hallard/LibTeleinfo/blob/master/Examples/Raspberry_JSON/Raspberry_JSON.ino
[11]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Blink.ino
[12]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Raspberry_JSON/Raspberry_JSON.ino
[13]: https://hallard.me/wifiinfo/
[14]: https://github.com/hallard/LibTeleinfo/blob/master/examples/ESP32/ESP32.ino
[15]: https://github.com/hallard/LibTeleinfo/blob/master/examples/ESP8266_DataChanged/ESP8266_DataChanged.ino

419
examples/ESP32/ESP32.ino Normal file
View File

@ -0,0 +1,419 @@
// **********************************************************************************
// ESP32 Teleinfo basic
// **********************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend this library but please abide with the CC-BY-SA license:
// Attribution-NonCommercial-ShareAlike 4.0 International License
// http://creativecommons.org/licenses/by-nc-sa/4.0/
//
// For any explanation about teleinfo ou use , see my blog
// http://hallard.me/category/tinfo
//
// This program works with the Wifinfo board
// see schematic here https://github.com/hallard/teleinfo/tree/master/Wifinfo
//
// Written by Charles-Henri Hallard (http://hallard.me)
//
// History : V1.00 2020-06-11 - First release
//
// All text above must be included in any redistribution.
//
// **********************************************************************************
#include <LibTeleinfo.h>
//#define BOARD_EZSBC
//#define BOARD_LOLIN32
#define BOARD_DENKY32
// https://www.tindie.com/products/ddebeer/esp32-dev-board-wifibluetooth-with-ftdi-/
#if defined (BOARD_EZSBC)
// Set up the rgb led names
#define LED_RED_PIN 16
#define LED_GRN_PIN 17
#define LED_BLU_PIN 18
#define PUSH_BUTTON 0
#define TIC_ENABLE_PIN 27
#define TIC_RX_PIN 33
#define TIC_TX_PIN 32
// Lolin32
#elif defined (BOARD_LOLIN32)
#define PUSH_BUTTON 15
#define TIC_ENABLE_PIN 32
#define TIC_RX_PIN 16
#define TIC_TX_PIN 17
#define RGB_LED_PIN 13
// Denky32
#elif defined (BOARD_DENKY32)
#define PUSH_BUTTON 0
#define TIC_ENABLE_PIN 4
#define TIC_RX_PIN 33
//#define TIC_TX_PIN 17
#define LORA_TX_PIN 26
#define LORA_RX_PIN 27
#define LORA_RESET 14
#define RGB_LED_PIN 25
#endif
#ifdef RGB_LED_PIN
#include <NeoPixelBus.h>
#define colorSaturation 128
// three element pixels, in different order and speeds
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(1, RGB_LED_PIN);
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
RgbColor white(colorSaturation);
RgbColor black(0);
#endif
TInfo tinfo; // Teleinfo object
// Pour clignotement LED asynchrone
unsigned long blinkLed = 0;
uint8_t blinkDelay= 0;
// Uptime timer
boolean tick1sec=0;// one for interrupt, don't mess with
unsigned long uptime=0; // save value we can use in sketch even if we're interrupted
// Used to indicate if we need to send all date or just modified ones
boolean fulldata = true;
//HardwareSerial Serial1(2); // UART1/Serial2 pins 16,17
//HardwareSerial Serial1(1); // UART1/Serial1 pins 9,10
//HardwareSerial Serial1(1); // UART1/Serial1 pins 9,10
/* ======================================================================
Function: ADPSCallback
Purpose : called by library when we detected a ADPS on any phased
Input : phase number
0 for ADPS (monophase)
1 for ADIR1 triphase
2 for ADIR2 triphase
3 for ADIR3 triphase
Output : -
Comments: should have been initialised in the main sketch with a
tinfo.attachADPSCallback(ADPSCallback())
====================================================================== */
void ADPSCallback(uint8_t phase)
{
// Envoyer JSON { "ADPS"; n}
// n = numero de la phase 1 à 3
if (phase == 0)
phase = 1;
Serial.print(F("{\"ADPS\":"));
Serial.print('0' + phase);
Serial.println(F("}"));
}
/* ======================================================================
Function: NewFrame
Purpose : callback when we received a complete teleinfo frame
Input : linked list pointer on the concerned data
Output : -
Comments: -
====================================================================== */
void NewFrame(ValueList * me)
{
// Start short led blink
#ifdef LED_RED_PIN
digitalWrite(LED_RED_PIN, LOW);
#endif
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, red);
strip.Show();
#endif
blinkLed = millis();
blinkDelay = 50; // 50ms
// Envoyer les valeurs uniquement si demandé
if (fulldata)
sendJSON(me, true);
fulldata = false;
}
/* ======================================================================
Function: UpdatedFrame
Purpose : callback when we received a complete teleinfo frame
Input : linked list pointer on the concerned data
Output : -
Comments: it's called only if one data in the frame is different than
the previous frame
====================================================================== */
void UpdatedFrame(ValueList * me)
{
// Start long led blink
#ifdef LED_BLU_PIN
digitalWrite(LED_BLU_PIN, LOW);
#endif
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, blue);
strip.Show();
#endif
blinkLed = millis();
blinkDelay = 50; // 50ms
// Envoyer les valeurs
sendJSON(me, fulldata);
fulldata = false;
}
/* ======================================================================
Function: sendJSON
Purpose : dump teleinfo values on serial
Input : linked list pointer on the concerned data
true to dump all values, false for only modified ones
Output : -
Comments: -
====================================================================== */
void sendJSON(ValueList * me, boolean all)
{
bool firstdata = true;
// Got at least one ?
if (me) {
// Json start
Serial.print(F("{"));
if (all) {
Serial.print(F("\"_UPTIME\":"));
Serial.print(uptime, DEC);
firstdata = false;
}
// Loop thru the node
while (me->next) {
// go to next node
me = me->next;
// uniquement sur les nouvelles valeurs ou celles modifiées
// sauf si explicitement demandé toutes
if ( all || ( me->flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED) ) )
{
// First elemement, no comma
if (firstdata)
firstdata = false;
else
Serial.print(F(", ")) ;
Serial.print(F("\"")) ;
Serial.print(me->name) ;
Serial.print(F("\":")) ;
// we have at least something ?
if (me->value && strlen(me->value))
{
boolean isNumber = true;
char * p = me->value;
// check if value is number
while (*p && isNumber) {
if ( *p < '0' || *p > '9' )
isNumber = false;
p++;
}
// this will add "" on not number values
if (!isNumber) {
Serial.print(F("\"")) ;
Serial.print(me->value) ;
Serial.print(F("\"")) ;
}
// this will remove leading zero on numbers
else
Serial.print(atol(me->value));
}
}
}
// Json end
Serial.println(F("}")) ;
}
}
/* ======================================================================
Function: setup
Purpose : Setup I/O and other one time startup stuff
Input : -
Output : -
Comments: -
====================================================================== */
void setup()
{
// Arduino LED
#ifdef BOARD_EZSBC
pinMode(LED_RED_PIN, OUTPUT);
pinMode(LED_GRN_PIN, OUTPUT);
pinMode(LED_BLU_PIN, OUTPUT);
digitalWrite(LED_RED_PIN, HIGH);
digitalWrite(LED_GRN_PIN, HIGH);
digitalWrite(LED_BLU_PIN, HIGH);
#endif
// Serial, pour le debug
Serial.begin(115200);
Serial.println(F("\r\n\r\n=============="));
Serial.println(F("Teleinfo"));
// Teleinfo enable pin
#ifdef TIC_ENABLE_PIN
pinMode(TIC_ENABLE_PIN, OUTPUT);
digitalWrite(TIC_ENABLE_PIN, HIGH);
Serial.printf_P(PSTR("Enable TIC on GPIO%d\r\n"), TIC_ENABLE_PIN);
#endif
// Button
#ifdef PUSH_BUTTON
pinMode(PUSH_BUTTON, INPUT_PULLUP);
Serial.printf_P(PSTR("Enable Button on GPIO=%d\r\n"), PUSH_BUTTON);
#endif
// this resets all the neopixels to an off state
#ifdef RGB_LED_PIN
Serial.printf_P(PSTR("Enable WS2812 RGB LED on GPIO=%d\r\n"), RGB_LED_PIN);
strip.Begin();
strip.SetPixelColor(0, green);
strip.Show();
blinkLed = millis();
blinkDelay = 500; // 500ms
#endif
// Configure Teleinfo Soft serial
// La téléinfo est connectee sur D3
// ceci permet d'eviter les conflits avec la
// vraie serial lors des uploads
Serial.printf_P(PSTR("TIC RX = GPIO=%d\r\n"), TIC_RX_PIN);
Serial1.begin(1200, SERIAL_7E1, TIC_RX_PIN);
pinMode(TIC_RX_PIN, INPUT_PULLUP);
// Init teleinfo
tinfo.init();
// Attacher les callback dont nous avons besoin
// pour cette demo, ADPS et TRAME modifiée
tinfo.attachADPS(ADPSCallback);
tinfo.attachUpdatedFrame(UpdatedFrame);
tinfo.attachNewFrame(NewFrame);
}
/* ======================================================================
Function: loop
Purpose : infinite loop main code
Input : -
Output : -
Comments: -
====================================================================== */
void loop()
{
static char c;
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
// Button to enable TIC
#if defined (PUSH_BUTTON) && defined (TIC_ENABLE_PIN)
static uint8_t enableTIC = HIGH;
static uint8_t buttonState = 0;
static unsigned long lastDebounceTime = 0;
uint8_t button = digitalRead(PUSH_BUTTON);
// New Press
if ( button==LOW && buttonState==0) {
buttonState = 1;
lastDebounceTime = millis();
// Pressed enought (debounced)
} else if ( buttonState==1 && button==LOW && (millis()-lastDebounceTime)>50 ) {
buttonState = 2;
// Release (no need debouce here)
} else if ( buttonState==2 && button==HIGH ) {
if ( enableTIC ) {
digitalWrite(TIC_ENABLE_PIN, LOW);
enableTIC = false;
} else {
digitalWrite(TIC_ENABLE_PIN, HIGH);
enableTIC = true;
}
Serial.printf_P(PSTR("\r\nEnable TIC=%d\r\n"), enableTIC);
lastDebounceTime = millis();
buttonState = 0;
}
#endif
// Avons nous recu un ticker de seconde?
if (tick1sec)
{
tick1sec = false;
uptime++;
// Forcer un envoi de trame complète toutes les minutes
// fulldata sera remis à 0 après l'envoi
if (uptime % 60 == 0)
fulldata = true;
}
// On a reçu un caractère ?
if ( Serial1.available() ) {
// Le lire
c = Serial1.read();
// Gérer
tinfo.process(c);
// L'affcher dans la console
if (c!=TINFO_STX && c!=TINFO_ETX) {
Serial.print(c);
}
}
// Verifier si le clignotement LED doit s'arreter
if (blinkLed && ((millis()-blinkLed) >= blinkDelay))
{
#ifdef BOARD_EZSBC
digitalWrite(LED_RED_PIN, HIGH);
digitalWrite(LED_GRN_PIN, HIGH);
digitalWrite(LED_BLU_PIN, HIGH);
#endif
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, black);
strip.Show();
#endif
blinkLed = 0;
}
if (currentMillis - previousMillis > 1000 ) {
// save the last time you blinked the LED
previousMillis = currentMillis;
tick1sec = true;
}
}

View File

@ -0,0 +1,200 @@
// **********************************************************************************
// ESP8266 Teleinfo, display changed data received and blink RGB Led
// **********************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend this library but please abide with the CC-BY-SA license:
// Attribution-NonCommercial-ShareAlike 4.0 International License
// http://creativecommons.org/licenses/by-nc-sa/4.0/
//
// For any explanation about teleinfo ou use , see my blog
// http://hallard.me/category/tinfo
//
// This program works with the Wifinfo board
// see schematic here https://github.com/hallard/teleinfo/tree/master/Wifinfo
//
// Written by Charles-Henri Hallard (http://hallard.me)
//
// History : V1.00 2020-06-11 - First release
//
// All text above must be included in any redistribution.
//
// **********************************************************************************
#include <LibTeleinfo.h>
#define RGB_LED_PIN 0 // GPIO0
// Output Debug on Serial1 since Hardware Serial is used to receive Teleinfo
#define SerialMon Serial1
#ifdef RGB_LED_PIN
#include <NeoPixelBus.h>
#define colorSaturation 128
// three element pixels, in different order and speeds
NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> strip(1, RGB_LED_PIN);
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
RgbColor white(colorSaturation);
RgbColor black(0);
#endif
TInfo tinfo; // Teleinfo object
// Pour clignotement LED asynchrone
unsigned long blinkLed = 0;
uint16_t blinkDelay= 0;
/* ======================================================================
Function: ADPSCallback
Purpose : called by library when we detected a ADPS on any phased
Input : phase number
0 for ADPS (monophase)
1 for ADIR1 triphase
2 for ADIR2 triphase
3 for ADIR3 triphase
Output : -
Comments: should have been initialised in the main sketch with a
tinfo.attachADPSCallback(ADPSCallback())
====================================================================== */
void ADPSCallback(uint8_t phase)
{
// n = numero de la phase 1 à 3
if (phase == 0)
phase = 1;
SerialMon.print(F("ADPS:"));
SerialMon.println('0' + phase);
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, red);
// Keep it RED between all frame until it disapears
blinkDelay = 2500; // 2.5s should be enough
strip.Show();
blinkLed = millis();
#endif
}
/* ======================================================================
Function: DataCallback
Purpose : callback when we detected new or modified data received
Input : linked list pointer on the concerned data
current flags value
Output : -
Comments: -
====================================================================== */
void DataCallback(ValueList * me, uint8_t flags)
{
RgbColor col(0, 0, colorSaturation);
// Nouvelle etiquette ?
if (flags & TINFO_FLAGS_ADDED) {
SerialMon.print(F("NEW -> "));
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, green);
strip.Show();
blinkDelay = 10; // 10ms
#endif
}
// Valeur de l'étiquette qui a changée ?
if (flags & TINFO_FLAGS_UPDATED) {
SerialMon.print(F("MAJ -> "));
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, blue);
strip.Show();
blinkDelay = 50; // 50ms
#endif
}
// Display values
SerialMon.print(me->name);
SerialMon.print("=");
SerialMon.println(me->value);
blinkLed = millis();
}
/* ======================================================================
Function: setup
Purpose : Setup I/O and other one time startup stuff
Input : -
Output : -
Comments: -
====================================================================== */
void setup()
{
// Serial1, pour le debug la Serial est pour la téléinfo
// Donc débrancher la téléinfo pour les update via USB
SerialMon.begin(115200);
SerialMon.println(F("\r\n\r\n=============="));
SerialMon.println(F("Teleinfo"));
// this resets all the neopixels to an off state
#ifdef RGB_LED_PIN
SerialMon.printf_P(PSTR("Enable WS2812 RGB LED on GPIO=%d\r\n"), RGB_LED_PIN);
strip.Begin();
strip.SetPixelColor(0, green);
strip.Show();
blinkLed = millis();
blinkDelay = 500; // 500ms
#endif
// Configure Teleinfo Soft serial
// La téléinfo est connectee sur D3
// ceci permet d'eviter les conflits avec la
// vraie serial lors des uploads
Serial.begin(1200, SERIAL_7E1);
//If you have no pullup on Serial entry try to uncomment the following line
//pinMode(TIC_RX_PIN, INPUT_PULLUP);
// Init teleinfo
tinfo.init();
// Attacher les callback dont nous avons besoin
// pour cette demo, ADPS et TRAME modifiée
tinfo.attachADPS(ADPSCallback);
tinfo.attachData(DataCallback);
}
/* ======================================================================
Function: loop
Purpose : infinite loop main code
Input : -
Output : -
Comments: -
====================================================================== */
void loop()
{
static char c;
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
// On a reçu un caractère ?
if ( Serial.available() ) {
// Le lire
c = Serial.read();
// Gérer
tinfo.process(c);
// L'affcher dans la console
//if (c!=TINFO_STX && c!=TINFO_ETX) {
//SerialMon.print(c);
//}
}
// Verifier si le clignotement LED doit s'arreter
if (blinkLed && ((millis()-blinkLed) >= blinkDelay)) {
#ifdef RGB_LED_PIN
strip.SetPixelColor(0, black);
strip.Show();
#endif
blinkLed = 0;
}
}

View File

@ -50,7 +50,7 @@ extern "C" {
#define DEBUG_SERIAL Serial1
#define DEBUG_SERIAL1
#define WIFINFO_VERSION "1.0.0"
#define WIFINFO_VERSION "1.0.1"
// I prefix debug macro to be sure to use specific for THIS library
// debugging, this should not interfere with main sketch or other
@ -74,14 +74,22 @@ extern "C" {
#define BLINK_LED_MS 50 // 50 ms blink
#define RGB_LED_PIN 14
#define RED_LED_PIN 12
// value for RGB color
#define COLOR_RED rgb_brightness, 0, 0
#define COLOR_ORANGE rgb_brightness, rgb_brightness>>1, 0
#define COLOR_YELLOW rgb_brightness, rgb_brightness, 0
#define COLOR_GREEN 0, rgb_brightness, 0
#define COLOR_CYAN 0, rgb_brightness, rgb_brightness
#define COLOR_BLUE 0, 0, rgb_brightness
#define COLOR_MAGENTA rgb_brightness, 0, rgb_brightness
// value for HSL color
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
#define COLOR_RED 0
#define COLOR_ORANGE 30
#define COLOR_ORANGE_YELLOW 45
#define COLOR_YELLOW 60
#define COLOR_YELLOW_GREEN 90
#define COLOR_GREEN 120
#define COLOR_GREEN_CYAN 165
#define COLOR_CYAN 180
#define COLOR_CYAN_BLUE 210
#define COLOR_BLUE 240
#define COLOR_BLUE_MAGENTA 275
#define COLOR_MAGENTA 300
#define COLOR_PINK 350
// GPIO 1 TX on board blue led
#ifdef BLU_LED_PIN
@ -95,10 +103,11 @@ extern "C" {
#define LedRedON() {digitalWrite(RED_LED_PIN, 1);}
#define LedRedOFF() {digitalWrite(RED_LED_PIN, 0);}
// Light off the RGB LED
#define LedRGBOFF() { rgb_led.SetPixelColor(0,0,0,0); rgb_led.Show(); }
#define LedRGBON(x) { rgb_led.SetPixelColor(0,x); rgb_led.Show(); }
// Light off the RGB LED
#ifndef RGB_LED_PIN
#define LedRGBOFF() {}
#define LedRGBON(x) {}
#endif
// sysinfo informations
typedef struct
{
@ -110,7 +119,6 @@ typedef struct
extern ESP8266WebServer server;
extern WiFiUDP OTA;
extern TInfo tinfo;
extern NeoPixelBus rgb_led ;
extern uint8_t rgb_brightness;
extern unsigned long seconds;
extern _sysinfo sysinfo;

View File

@ -46,11 +46,16 @@ bool ota_blink;
// Teleinfo
TInfo tinfo;
// RGB Loed
NeoPixelBus rgb_led = NeoPixelBus(1, RGB_LED_PIN, NEO_RGB | NEO_KHZ800);
// RGB Led
#ifdef RGB_LED_PIN
//NeoPixelBus rgb_led = NeoPixelBus(1, RGB_LED_PIN, NEO_RGB | NEO_KHZ800);
//NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> rgb_led(1, RGB_LED_PIN);
NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod> rgb_led(1, RGB_LED_PIN);
#endif
// define whole brigtness level for RGBLED
uint8_t rgb_brightness = 127;
// define whole brigtness level for RGBLED (50%)
uint8_t rgb_brightness = 50;
// LED Blink timers
Ticker rgb_ticker;
Ticker blu_ticker;
@ -143,6 +148,51 @@ void LedOff(int led)
LedRGBOFF();
}
// Light off the RGB LED
#ifdef RGB_LED_PIN
/* ======================================================================
Function: LedRGBON
Purpose : Light RGB Led with HSB value
Input : Hue (0..255)
Saturation (0..255)
Brightness (0..255)
Output : -
Comments:
====================================================================== */
void LedRGBON (uint16_t hue)
{
if (config.config & CFG_RGB_LED) {
// Convert to neoPixel API values
// H (is color from 0..360) should be between 0.0 and 1.0
// L (is brightness from 0..100) should be between 0.0 and 0.5
RgbColor target = HslColor( hue / 360.0f, 1.0f, rgb_brightness * 0.005f );
// Set RGB Led
rgb_led.SetPixelColor(0, target);
rgb_led.Show();
}
}
/* ======================================================================
Function: LedRGBOFF
Purpose : light off the RGN LED
Input : -
Output : -
Comments: -
====================================================================== */
//void LedOff(int led)
void LedRGBOFF(void)
{
if (config.config & CFG_RGB_LED) {
rgb_led.SetPixelColor(0,RgbColor(0));
rgb_led.Show();
}
}
#endif
/* ======================================================================
Function: ADPSCallback
Purpose : called by library when we detected a ADPS on any phased
@ -299,11 +349,11 @@ Comments: -
====================================================================== */
void ResetConfig(void)
{
// enable default configuration
// Start cleaning all that stuff
memset(&config, 0, sizeof(_Config));
// Set default Hostname
sprintf_P(config.host, PSTR("WifInfo_%06X"), ESP.getChipId());
sprintf_P(config.host, PSTR("WifInfo-%06X"), ESP.getChipId());
strcpy_P(config.ota_auth, PSTR(DEFAULT_OTA_AUTH));
config.ota_port = DEFAULT_OTA_PORT ;
@ -313,18 +363,12 @@ void ResetConfig(void)
strcpy_P(config.emoncms.host, CFG_EMON_DEFAULT_HOST);
config.emoncms.port = CFG_EMON_DEFAULT_PORT;
strcpy_P(config.emoncms.url, CFG_EMON_DEFAULT_URL);
config.emoncms.apikey[0] = '\0';
config.emoncms.node = 0;
config.emoncms.freq = 0;
// Jeedom
strcpy_P(config.jeedom.host, CFG_JDOM_DEFAULT_HOST);
config.jeedom.port = CFG_JDOM_DEFAULT_PORT;
strcpy_P(config.jeedom.url, CFG_JDOM_DEFAULT_URL);
strcpy_P(config.jeedom.adco, CFG_JDOM_DEFAULT_ADCO);
config.jeedom.apikey[0] = '\0';
config.jeedom.freq = 0;
//strcpy_P(config.jeedom.adco, CFG_JDOM_DEFAULT_ADCO);
config.config |= CFG_RGB_LED;
@ -426,6 +470,13 @@ int WifiHandleConn(boolean setup = false)
DebuglnF("Error!");
Debugflush();
// STA+AP Mode without connected to STA, autoconnect will search
// other frequencies while trying to connect, this is causing issue
// to AP mode, so disconnect will avoid this
// Disable auto retry search channel
WiFi.disconnect();
// SSID = hostname
strcpy(ap_ssid, config.host );
DebugF("Switching to AP ");

View File

@ -37,7 +37,7 @@
#define CFG_EMON_DEFAULT_URL "/input/post.json"
#define CFG_JDOM_HOST_SIZE 32
#define CFG_JDOM_APIKEY_SIZE 32
#define CFG_JDOM_APIKEY_SIZE 48
#define CFG_JDOM_URL_SIZE 64
#define CFG_JDOM_ADCO_SIZE 12
#define CFG_JDOM_DEFAULT_PORT 80
@ -93,23 +93,23 @@ typedef struct
char host[CFG_EMON_HOST_SIZE+1]; // FQDN
char apikey[CFG_EMON_APIKEY_SIZE+1]; // Secret
char url[CFG_EMON_URL_SIZE+1]; // Post URL
uint8_t port; // Protocol port (HTTP/HTTPS)
uint8_t node; // optional node
uint16_t port; // Protocol port (HTTP/HTTPS)
uint8_t node; // optional node
uint32_t freq; // refresh rate
uint8_t filler[23]; // in case adding data in config avoiding loosing current conf by bad crc*/
uint8_t filler[22]; // in case adding data in config avoiding loosing current conf by bad crc*/
} _emoncms;
// Config for jeedom
// 160 Bytes
// 256 Bytes
typedef struct
{
char host[CFG_JDOM_HOST_SIZE+1]; // FQDN
char apikey[CFG_JDOM_APIKEY_SIZE+1]; // Secret
char url[CFG_JDOM_URL_SIZE+1]; // Post URL
char adco[CFG_JDOM_ADCO_SIZE+1]; // Identifiant compteur
uint8_t port; // Protocol port (HTTP/HTTPS)
uint16_t port; // Protocol port (HTTP/HTTPS)
uint32_t freq; // refresh rate
uint8_t filler[11]; // in case adding data in config avoiding loosing current conf by bad crc*/
uint8_t filler[90]; // in case adding data in config avoiding loosing current conf by bad crc*/
} _jeedom;
// Config saved into eeprom
@ -126,7 +126,7 @@ typedef struct
uint8_t filler[131]; // in case adding data in config avoiding loosing current conf by bad crc
_emoncms emoncms; // Emoncms configuration
_jeedom jeedom; // jeedom configuration
uint8_t filler1[352]; // Another filler in case we need more
uint8_t filler1[256]; // Another filler in case we need more
uint16_t crc;
} _Config;

Binary file not shown.

View File

@ -39,7 +39,7 @@ boolean httpPost(char * host, uint16_t port, char * url)
unsigned long start = millis();
// configure traged server and url
http.begin(host, port, url, port==443 ? true : false);
http.begin(host, port, url);
//http.begin("http://emoncms.org/input/post.json?node=20&apikey=2f13e4608d411d20354485f72747de7b&json={PAPP:100}");
//http.begin("emoncms.org", 80, "/input/post.json?node=20&apikey=2f13e4608d411d20354485f72747de7b&json={}"); //HTTP

View File

@ -184,10 +184,10 @@ void handleFormConfig(void)
if ( saveConfig() ) {
ret = 200;
response = PSTR("OK");
response = "OK";
} else {
ret = 412;
response = PSTR("Unable to save configuration");
response = "Unable to save configuration";
}
showConfig();
@ -195,7 +195,7 @@ void handleFormConfig(void)
else
{
ret = 400;
response = PSTR("Missing Form Field");
response = "Missing Form Field";
}
DebugF("Sending response ");
@ -767,7 +767,7 @@ void handleNotFound(void)
//Debugf("compare to '%s' ", me->name);
// Do we have this one ?
if (stricmp (me->name, uri) == 0 )
if (strcmp (me->name, uri) == 0 )
{
// no need to continue
found = true;

View File

@ -1,13 +1,13 @@
{
"name": "LibTeleinfo",
"keywords": "teleinfo, french, meter, power, erdf, linky",
"description": "Teleinfo French power meter reader and decoding",
"version": "1.1.2",
"keywords": "teleinfo, french, meter, power, erdf, linky, tic",
"description": "Decoder for Teleinfo (aka TIC) from French smart power meters",
"repository":
{
"type": "git",
"url": "https://github.com/hallard/LibTeleinfo.git"
},
"version": "1.0.1",
"authors":
{
"name": "Charles-Henri Hallard",

View File

@ -1,9 +1,9 @@
name=LibTeleinfo
version=1.0.1
version=1.1.2
author=Charles-Henri Hallard <hallard.me>
maintainer=Charles-Henri Hallard <community.hallard.me>
sentence=Teleinfo French power meter reader and decoding
paragraph=This is a generic Teleinfo French Meter Measure Library, it can be used on Arduino, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp coding.
sentence=Decoder for Teleinfo (aka TIC) from French smart power meters
paragraph=This is a generic Teleinfo (aka TIC) French Meter Measure Library, it can be used on Arduino, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp coding.
category=Communication
url=https://github.com/hallard/LibTeleinfo
architectures=*

View File

@ -124,7 +124,7 @@ Input : -
Output : -
Comments: -
====================================================================== */
uint8_t TInfo::clearBuffer()
void TInfo::clearBuffer()
{
// Clear our buffer, set index to 0
memset(_recv_buff, 0, TINFO_BUFSIZE);
@ -190,7 +190,7 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t
TI_Debug('=');
TI_Debug(value);
TI_Debug(F(" '"));
TI_Debug((char) cheksum);
TI_Debug((char) checksum);
TI_Debug(F("' Not added bad checksum calculated '"));
TI_Debug((char) thischeck);
TI_Debugln(F("'"));
@ -209,10 +209,11 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t
// go to next node
me = me->next;
// Check if we already have this LABEL
if (strncmp(me->name, name, lgname) == 0) {
// Already got also this value, return US
if (strncmp(me->value, value, lgvalue) == 0) {
// Check if we already have this LABEL (same name AND same size)
if (lgname==strlen(me->name) && strcmp(me->name, name )==0) {
// Already got also this value return US
if (lgvalue==strlen(me->value) && strcmp(me->value, value) == 0) {
*flags |= TINFO_FLAGS_EXIST;
me->flags = *flags;
return ( me );
@ -223,7 +224,7 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t
// Do we have enought space to hold new value ?
if (strlen(me->value) >= lgvalue ) {
// Copy it
strncpy(me->value, value , lgvalue );
strlcpy(me->value, value , lgvalue + 1);
me->checksum = checksum ;
// That's all
@ -248,11 +249,11 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t
// + Name + '\0'
// + Value + '\0'
size_t size ;
#ifdef ESP8266
lgname = xPortWantedSizeAlign(lgname+1); // Align name buffer
lgvalue = xPortWantedSizeAlign(lgvalue+1); // Align value buffer
#if defined (ESP8266) || defined (ESP32)
lgname = ESP_allocAlign(lgname+1); // Align name buffer
lgvalue = ESP_allocAlign(lgvalue+1); // Align value buffer
// Align the whole structure
size = xPortWantedSizeAlign( sizeof(ValueList) + lgname + lgvalue ) ;
size = ESP_allocAlign( sizeof(ValueList) + lgname + lgvalue ) ;
#else
size = sizeof(ValueList) + lgname + 1 + lgvalue + 1 ;
#endif
@ -290,7 +291,7 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t
TI_Debug('=');
TI_Debug(value);
TI_Debug(F("' '"));
TI_Debug((char) cheksum);
TI_Debug((char) checksum);
TI_Debugln(F("'"));
// return pointer on the new node
@ -421,12 +422,12 @@ char * TInfo::valueGet(char * name, char * value)
me = me->next;
// Check if we match this LABEL
if (strncmp(me->name, name, lgname) == 0) {
if (lgname==strlen(me->name) && strcmp(me->name, name)==0) {
// this one has a value ?
if (me->value) {
// copy to dest buffer
uint8_t lgvalue = strlen(me->value);
strncpy(value, me->value , lgvalue );
strlcpy(value, me->value , lgvalue + 1 );
return ( value );
}
}
@ -471,17 +472,19 @@ uint8_t TInfo::valuesDump(void)
TI_Debug(index) ;
TI_Debug(F(") ")) ;
if (me->name)
if (me->name) {
TI_Debug(me->name) ;
else
} else {
TI_Debug(F("NULL")) ;
}
TI_Debug(F("=")) ;
if (me->value)
if (me->value) {
TI_Debug(me->value) ;
else
} else {
TI_Debug(F("NULL")) ;
}
TI_Debug(F(" '")) ;
TI_Debug(me->checksum) ;
@ -491,12 +494,15 @@ uint8_t TInfo::valuesDump(void)
if ( me->flags) {
TI_Debug(F("Flags:0x"));
TI_Debugf("%02X =>", me->flags);
if ( me->flags & TINFO_FLAGS_EXIST)
if ( me->flags & TINFO_FLAGS_EXIST) {
TI_Debug(F("Exist ")) ;
if ( me->flags & TINFO_FLAGS_UPDATED)
}
if ( me->flags & TINFO_FLAGS_UPDATED) {
TI_Debug(F("Updated ")) ;
if ( me->flags & TINFO_FLAGS_ADDED)
}
if ( me->flags & TINFO_FLAGS_ADDED) {
TI_Debug(F("New ")) ;
}
}
TI_Debugln() ;
@ -570,8 +576,7 @@ Comments: return '\0' in case of error
====================================================================== */
unsigned char TInfo::calcChecksum(char *etiquette, char *valeur)
{
uint8_t i ;
uint8_t sum = ' '; // Somme des codes ASCII du message + un espace
uint8_t sum = ' '; // Somme des codes ASCII du message + un espace
// avoid dead loop, always check all is fine
if (etiquette && valeur) {
@ -643,7 +648,7 @@ ValueList * TInfo::checkLine(char * pline)
char checksum;
char buff[TINFO_BUFSIZE];
uint8_t flags = TINFO_FLAGS_NONE;
boolean err = true ; // Assume error
//boolean err = true ; // Assume error
int len ; // Group len
if (pline==NULL)
@ -657,7 +662,7 @@ ValueList * TInfo::checkLine(char * pline)
return NULL;
// Get our own working copy
strncpy( buff, _recv_buff, len+1);
strlcpy( buff, pline, len+1);
p = &buff[0];
ptok = p; // for sure we start with token name
@ -832,6 +837,8 @@ _State_e TInfo::process(char c)
}
break;
}
return _state;
}

View File

@ -38,10 +38,10 @@
// Using ESP8266 ?
#ifdef ESP8266
//#include "stdlib_noniso.h"
#include <ESP8266WiFi.h>
#endif
// Define this if you want library to be verbose
//#define TI_DEBUG
@ -67,6 +67,11 @@
#define TI_Debugflush
#endif
#if defined (ESP8266) || defined (ESP32)
// For 4 bytes Aligment boundaries
#define ESP_allocAlign(size) ((size + 3) & ~((size_t) 3))
#endif
#pragma pack(push) // push current alignment to stack
#pragma pack(1) // set alignment to 1 byte boundary
@ -75,10 +80,10 @@ typedef struct _ValueList ValueList;
struct _ValueList
{
ValueList *next; // next element
uint8_t checksum;// checksum
uint8_t flags; // specific flags
char * name; // LABEL of value name
char * value; // value
uint8_t checksum;// checksum
uint8_t flags; // specific flags
};
#pragma pack(pop)
@ -113,25 +118,25 @@ class TInfo
{
public:
TInfo();
void init();
_State_e process (char c);
void attachADPS(void (*_fn_ADPS)(uint8_t phase));
void attachData(void (*_fn_data)(ValueList * valueslist, uint8_t state));
void attachNewFrame(void (*_fn_new_frame)(ValueList * valueslist));
void attachUpdatedFrame(void (*_fn_updated_frame)(ValueList * valueslist));
ValueList * addCustomValue(char * name, char * value, uint8_t * flags);
ValueList * getList(void);
uint8_t valuesDump(void);
char * valueGet(char * name, char * value);
boolean listDelete();
void init();
_State_e process (char c);
void attachADPS(void (*_fn_ADPS)(uint8_t phase));
void attachData(void (*_fn_data)(ValueList * valueslist, uint8_t state));
void attachNewFrame(void (*_fn_new_frame)(ValueList * valueslist));
void attachUpdatedFrame(void (*_fn_updated_frame)(ValueList * valueslist));
ValueList * addCustomValue(char * name, char * value, uint8_t * flags);
ValueList * getList(void);
uint8_t valuesDump(void);
char * valueGet(char * name, char * value);
boolean listDelete();
unsigned char calcChecksum(char *etiquette, char *valeur) ;
private:
uint8_t clearBuffer();
void clearBuffer();
ValueList * valueAdd (char * name, char * value, uint8_t checksum, uint8_t * flags);
boolean valueRemove (char * name);
boolean valueRemoveFlagged(uint8_t flags);
int labelCount();
unsigned char calcChecksum(char *etiquette, char *valeur) ;
void customLabel( char * plabel, char * pvalue, uint8_t * pflags) ;
ValueList * checkLine(char * pline) ;