Updated readme

This commit is contained in:
Arne van Iterson 2021-02-04 12:41:51 +01:00
parent 6bd04eda97
commit bd566a4b39
3 changed files with 413 additions and 122 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.vscode
*.code-workspace

View File

@ -1,22 +1,68 @@
// #include <TimeLib.h> #include <TimeLib.h>
#include <NTPClient.h>
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
#include <ESP8266HTTPClient.h> #include <ESP8266HTTPClient.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#include <Button2.h>
#include <Timer.h>
#include "CRC16.h" #include "CRC16.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Fonts/Org_01.h>
#include <Adafruit_PCD8544.h>
//===Change values from here=== // Function prototypes
const char* ssid = "WIFISSID"; void reboot();
const char* password = "PASSWORD"; time_t NTPgetTime();
const char* hostName = "ESPP1Meter"; void drawMenu();
const char* domoticzIP = "192.168.1.35";
const int domoticzPort = 8090; // Time related settings
const int domoticzGasIdx = 291; Timer t;
const int domoticzEneryIdx = 294; WiFiUDP ntpUDP;
const bool outputOnSerial = true; NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 10000);
//===Change values to here===
// Display settings
//// Software SPI (slower updates, more flexible pin options):
//// pin 7 - Serial clock out (SCLK)
//// pin 6 - Serial data out (DIN)
//// pin 5 - Data/Command select (D/C)
//// pin 4 - LCD chip select (CS)
//// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(D7, D6, D5, D4, D3);
int tab = 0;
int tabCount = 3;
// LED settings
#define ledPin D8
int ledBrightness = 192;
void ledOff();
int ledTimeout;
// Button settings
#define buttonPin D2
Button2 button = Button2(buttonPin);
// Wifi Settings
const char *ssid = "*";
const char *password = "*";
const char *hostName = "ESPP1Meter";
// Server settings
const char *apiIP = "192.168.2.6";
const int apiPort = 3000;
const char *apiKey = "*";
const int gasIdx = 291;
const int energyIdx = 294;
const bool outputOnSerial = false;
// Statistics variables
unsigned long telegramsTotal = 0;
unsigned long telegramsInvalid = 0;
unsigned long postedTotal = 0;
unsigned long postedFailed = 0;
// Vars to store meter readings // Vars to store meter readings
long mEVLT = 0; //Meter reading Electrics - consumption low tariff long mEVLT = 0; //Meter reading Electrics - consumption low tariff
@ -25,277 +71,512 @@ long mEOLT = 0; //Meter reading Electrics - return low tariff
long mEOHT = 0; //Meter reading Electrics - return high tariff long mEOHT = 0; //Meter reading Electrics - return high tariff
long mEAV = 0; //Meter reading Electrics - Actual consumption long mEAV = 0; //Meter reading Electrics - Actual consumption
long mEAT = 0; //Meter reading Electrics - Actual return long mEAT = 0; //Meter reading Electrics - Actual return
long mGAS = 0; //Meter reading Gas long mGAS = 0; //Meter reading Gas
long prevGAS = 0; long prevGAS = 0;
#define MAXLINELENGTH 128 // longest normal line is 47 char (+3 for \r\n\0) #define MAXLINELENGTH 128 // longest normal line is 47 char (+3 for \r\n\0)
char telegram[MAXLINELENGTH]; char telegram[MAXLINELENGTH];
unsigned int currentCRC = 0;
#define SERIAL_RX D5 // pin for SoftwareSerial RX // P1 Serial settings
SoftwareSerial mySerial(SERIAL_RX, -1, true, MAXLINELENGTH); // (RX, TX. inverted, buffer) #define SERIAL_RX D1 // pin for SoftwareSerial RX
SoftwareSerial mySerial(SERIAL_RX, -1, false); // (RX, TX, inverted)
unsigned int currentCRC=0; void setup()
void SendToDomoLog(char* message)
{ {
char url[512]; // Init Serial
sprintf(url, "http://%s:%d/json.htm?type=command&param=addlogmessage&message=%s", domoticzIP, domoticzPort, message);
}
void setup() {
Serial.begin(115200); Serial.begin(115200);
Serial.println("Booting"); delay(50);
// Init LED
pinMode(ledPin, OUTPUT);
analogWrite(ledPin, ledBrightness);
// Init Button
button.setReleasedHandler(press);
// Init Display
display.begin();
display.setContrast(50);
display.setFont(&Org_01);
drawMenu();
// Init WiFi
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
display.println("Connecting to:");
display.print(" ");
display.println(ssid);
display.display();
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) { while (WiFi.waitForConnectResult() != WL_CONNECTED)
{
Serial.println("Connection Failed! Rebooting..."); Serial.println("Connection Failed! Rebooting...");
drawMenu();
display.println("Connection Failed!");
display.display();
delay(5000); delay(5000);
ESP.restart(); ESP.restart();
} }
// Init P1 Serial
mySerial.begin(115200); mySerial.begin(115200);
// Port defaults to 8266 // Init ArduinoOTA
// ArduinoOTA.setPort(8266); //// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID] //// Hostname defaults to esp8266-[ChipID]
ArduinoOTA.setHostname(hostName); ArduinoOTA.setHostname(hostName);
// No authentication by default //// No authentication by default
// ArduinoOTA.setPassword((const char *)"123"); // ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() { ArduinoOTA.onStart([]() {
drawMenu();
display.println("OTA Update");
display.display();
Serial.println("Start"); Serial.println("Start");
}); });
ArduinoOTA.onEnd([]() { ArduinoOTA.onEnd([]() {
Serial.println("\nEnd"); Serial.println("\nEnd");
}); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
drawMenu();
display.println("OTA Update");
display.printf("Progress: %u%%\r", (progress / (total / 100)));
display.display();
Serial.printf("Progress: %u%%\r", (progress / (total / 100))); Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
}); });
ArduinoOTA.onError([](ota_error_t error) { ArduinoOTA.onError([](ota_error_t error) {
drawMenu();
display.println("OTA Update");
display.printf("Error[%u]: ", error);
display.display();
Serial.printf("Error[%u]: ", error); Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); if (error == OTA_AUTH_ERROR)
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); Serial.println("Auth Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_BEGIN_ERROR)
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); Serial.println("Begin Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed"); else if (error == OTA_CONNECT_ERROR)
Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR)
Serial.println("Receive Failed");
else if (error == OTA_END_ERROR)
Serial.println("End Failed");
}); });
ArduinoOTA.begin(); ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: "); // Init Time
Serial.println(WiFi.localIP()); timeClient.begin();
time_t test = NTPgetTime();
while (test < 10000)
{
test = NTPgetTime();
}
setTime(NTPgetTime());
getExternalTime NtpTime = &NTPgetTime;
setSyncProvider(NtpTime);
setSyncInterval(3600);
display.println("Time set");
display.display();
delay(1000);
// Exit setup
drawTab(2);
ledTimeout = t.after(5000, ledOff, (void *)0);
} }
// Reboot the ESP
void reboot()
{
drawMenu();
display.println("Scheduled reboot");
display.display();
delay(5000);
ESP.restart();
}
bool SendToDomo(int idx, int nValue, char* sValue) // Update Time
time_t NTPgetTime()
{
timeClient.update();
return timeClient.getEpochTime();
}
// Turn of the backlight LEDs
void ledOff(void *context)
{
tab = 0;
drawTab(tab);
analogWrite(ledPin, 0);
}
// Button action
void press(Button2 &btn)
{
analogWrite(ledPin, ledBrightness);
t.stop(ledTimeout);
ledTimeout = t.after(10000, ledOff, (void *)0);
if ((tab + 1) == tabCount)
{
tab = 0;
}
else
{
tab++;
}
drawTab(tab);
}
// Draw top bar
void drawMenu()
{
display.clearDisplay();
display.setCursor(0, 4);
display.println("P1 Reader");
display.drawLine(0, 6, 84, 6, 1);
display.display();
display.setCursor(0, 12);
}
void drawTab(int no)
{
drawMenu();
switch (no)
{
// Network
case 0:
drawMenu();
// SSID
display.println("Connected to:");
display.print(" ");
display.println(ssid);
// Own IP
display.println("IP address: ");
display.print(" ");
display.println(WiFi.localIP());
// Target server
display.println("Target host: ");
display.print(" ");
display.println(String(apiIP) + ":" + String(apiPort));
break;
// Stats
case 1:
drawMenu();
// Telegrams
display.println("Telegrams");
display.print(" Total: ");
display.println(String(telegramsTotal));
display.print(" Invalid: ");
display.println(String(telegramsInvalid));
// Posted
display.println("Posted");
display.print(" Total: ");
display.println(String(postedTotal));
display.print(" Failed: ");
display.println(String(postedFailed));
break;
// Time
case 2:
display.println("Current time:");
// Time
display.print(" ");
if (hour() < 10)
{
display.print("0");
}
display.print(hour());
display.print(":");
if (minute() < 10)
{
display.print("0");
}
display.println(minute());
// Date
display.print(" ");
if (day() < 10)
{
display.print("0");
}
display.print(day());
display.print("-");
if (month() < 10)
{
display.print("0");
}
display.print(month());
display.print("-");
display.println(year());
break;
}
display.display();
}
// Send data to server
bool Send(int idx, int nValue, char *sValue)
{ {
HTTPClient http; HTTPClient http;
bool retVal = false; bool retVal = false;
char url[255]; char httpRequestData[255];
sprintf(url, "http://%s:%d/json.htm?type=command&param=udevice&idx=%d&nvalue=%d&svalue=%s", domoticzIP, domoticzPort, idx, nValue, sValue);
Serial.printf("[HTTP] GET... URL: %s\n",url); // "http://%s:%d/json.htm?type=command&param=udevice&idx=%d&nvalue=%d&svalue=%s"
http.begin(url); //HTTP // "api_key=tPmAT5Ab3j7F9&sensor=BME280&value1=24.25&value2=49.54&value3=1005.14"
int httpCode = http.GET(); sprintf(httpRequestData, "api_key=%s&type=%d&nval=%d&sval=%s", apiKey, idx, nValue, sValue);
Serial.printf("[HTTP] GET... URL: %s\n", httpRequestData);
http.begin(String("http://" + String(apiIP) + ":" + String(apiPort))); //HTTP
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
postedTotal++;
int httpCode = http.POST(httpRequestData);
// httpCode will be negative on error // httpCode will be negative on error
if (httpCode > 0) if (httpCode > 0)
{ // HTTP header has been send and Server response header has been handled { // HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode); Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server // file found at server
if (httpCode == HTTP_CODE_OK) { if (httpCode == HTTP_CODE_OK)
{
String payload = http.getString(); String payload = http.getString();
retVal = true; retVal = true;
} }
} }
else else
{ {
postedFailed++;
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
} }
http.end(); http.end();
return retVal; return retVal;
} }
// Update Gas info
void UpdateGas() void UpdateGas()
{ {
//sends over the gas setting to domoticz if (prevGAS != mGAS)
if(prevGAS!=mGAS)
{ {
char sValue[10]; char sValue[10];
sprintf(sValue, "%d", mGAS); sprintf(sValue, "%d", mGAS);
if(SendToDomo(domoticzGasIdx, 0, sValue)) if (Send(gasIdx, 0, sValue))
prevGAS=mGAS; prevGAS = mGAS;
} }
} }
// Update Electricity info
void UpdateElectricity() void UpdateElectricity()
{ {
char sValue[255]; char sValue[255];
sprintf(sValue, "%d;%d;%d;%d;%d;%d", mEVLT, mEVHT, mEOLT, mEOHT, mEAV, mEAT); sprintf(sValue, "%d;%d;%d;%d;%d;%d", mEVLT, mEVHT, mEOLT, mEOHT, mEAV, mEAT);
SendToDomo(domoticzEneryIdx, 0, sValue); Send(energyIdx, 0, sValue);
} }
// Check if value is number
bool isNumber(char* res, int len) { bool isNumber(char *res, int len)
for (int i = 0; i < len; i++) { {
if (((res[i] < '0') || (res[i] > '9')) && (res[i] != '.' && res[i] != 0)) { for (int i = 0; i < len; i++)
{
if (((res[i] < '0') || (res[i] > '9')) && (res[i] != '.' && res[i] != 0))
{
return false; return false;
} }
} }
return true; return true;
} }
int FindCharInArrayRev(char array[], char c, int len) { // Find char in array
for (int i = len - 1; i >= 0; i--) { int FindCharInArrayRev(char array[], char c, int len)
if (array[i] == c) { {
for (int i = len - 1; i >= 0; i--)
{
if (array[i] == c)
{
return i; return i;
} }
} }
return -1; return -1;
} }
// Check if value is valid
long getValidVal(long valNew, long valOld, long maxDiffer) long getValidVal(long valNew, long valOld, long maxDiffer)
{ {
//check if the incoming value is valid //check if the incoming value is valid
if(valOld > 0 && ((valNew - valOld > maxDiffer) && (valOld - valNew > maxDiffer))) if (valOld > 0 && ((valNew - valOld > maxDiffer) && (valOld - valNew > maxDiffer)))
return valOld; return valOld;
return valNew; return valNew;
} }
long getValue(char* buffer, int maxlen) { // Get value from char buffer
long getValue(char *buffer, int maxlen)
{
int s = FindCharInArrayRev(buffer, '(', maxlen - 2); int s = FindCharInArrayRev(buffer, '(', maxlen - 2);
if (s < 8) return 0; if (s < 8)
if (s > 32) s = 32; return 0;
if (s > 32)
s = 32;
int l = FindCharInArrayRev(buffer, '*', maxlen - 2) - s - 1; int l = FindCharInArrayRev(buffer, '*', maxlen - 2) - s - 1;
if (l < 4) return 0; if (l < 4)
if (l > 12) return 0; return 0;
if (l > 12)
return 0;
char res[16]; char res[16];
memset(res, 0, sizeof(res)); memset(res, 0, sizeof(res));
if (strncpy(res, buffer + s + 1, l)) { if (strncpy(res, buffer + s + 1, l))
if (isNumber(res, l)) { {
if (isNumber(res, l))
{
return (1000 * atof(res)); return (1000 * atof(res));
} }
} }
return 0; return 0;
} }
bool decodeTelegram(int len) { // Decode P1 telegram
bool decodeTelegram(int len)
{
//need to check for start //need to check for start
int startChar = FindCharInArrayRev(telegram, '/', len); int startChar = FindCharInArrayRev(telegram, '/', len);
int endChar = FindCharInArrayRev(telegram, '!', len); int endChar = FindCharInArrayRev(telegram, '!', len);
bool validCRCFound = false; bool validCRCFound = false;
if(startChar>=0) if (startChar >= 0)
{ {
//start found. Reset CRC calculation //start found. Reset CRC calculation
currentCRC=CRC16(0x0000,(unsigned char *) telegram+startChar, len-startChar); currentCRC = CRC16(0x0000, (unsigned char *)telegram + startChar, len - startChar);
if(outputOnSerial) if (outputOnSerial)
{ {
for(int cnt=startChar; cnt<len-startChar;cnt++) for (int cnt = startChar; cnt < len - startChar; cnt++)
Serial.print(telegram[cnt]); Serial.print(telegram[cnt]);
} }
//Serial.println("Start found!"); Serial.println("Start found!");
telegramsTotal++;
} }
else if(endChar>=0) else if (endChar >= 0)
{ {
//add to crc calc //add to crc calc
currentCRC=CRC16(currentCRC,(unsigned char*)telegram+endChar, 1); currentCRC = CRC16(currentCRC, (unsigned char *)telegram + endChar, 1);
char messageCRC[5]; char messageCRC[5];
strncpy(messageCRC, telegram + endChar + 1, 4); strncpy(messageCRC, telegram + endChar + 1, 4);
messageCRC[4]=0; //thanks to HarmOtten (issue 5) messageCRC[4] = 0; //thanks to HarmOtten (issue 5)
if(outputOnSerial) if (outputOnSerial)
{ {
for(int cnt=0; cnt<len;cnt++) for (int cnt = 0; cnt < len; cnt++)
Serial.print(telegram[cnt]); Serial.print(telegram[cnt]);
} }
validCRCFound = (strtol(messageCRC, NULL, 16) == currentCRC); validCRCFound = (strtol(messageCRC, NULL, 16) == currentCRC);
if(validCRCFound) if (validCRCFound)
Serial.println("\nVALID CRC FOUND!"); {
Serial.println("\nVALID CRC FOUND!");
}
else else
Serial.println("\n===INVALID CRC FOUND!==="); {
Serial.println("\nINVALID CRC FOUND!");
telegramsInvalid++;
}
currentCRC = 0; currentCRC = 0;
} }
else else
{ {
currentCRC=CRC16(currentCRC, (unsigned char*)telegram, len); currentCRC = CRC16(currentCRC, (unsigned char *)telegram, len);
if(outputOnSerial) if (outputOnSerial)
{ {
for(int cnt=0; cnt<len;cnt++) for (int cnt = 0; cnt < len; cnt++)
Serial.print(telegram[cnt]); Serial.print(telegram[cnt]);
} }
} }
long val =0; long val = 0;
long val2=0; long val2 = 0;
// 1-0:1.8.1(000992.992*kWh) // 1-0:1.8.1(000992.992*kWh)
// 1-0:1.8.1 = Elektra verbruik laag tarief (DSMR v4.0) // 1-0:1.8.1 = Elektra verbruik laag tarief (DSMR v4.0)
if (strncmp(telegram, "1-0:1.8.1", strlen("1-0:1.8.1")) == 0) if (strncmp(telegram, "1-0:1.8.1", strlen("1-0:1.8.1")) == 0)
mEVLT = getValue(telegram, len); mEVLT = getValue(telegram, len);
// 1-0:1.8.2(000560.157*kWh) // 1-0:1.8.2(000560.157*kWh)
// 1-0:1.8.2 = Elektra verbruik hoog tarief (DSMR v4.0) // 1-0:1.8.2 = Elektra verbruik hoog tarief (DSMR v4.0)
if (strncmp(telegram, "1-0:1.8.2", strlen("1-0:1.8.2")) == 0) if (strncmp(telegram, "1-0:1.8.2", strlen("1-0:1.8.2")) == 0)
mEVHT = getValue(telegram, len); mEVHT = getValue(telegram, len);
// 1-0:2.8.1(000348.890*kWh) // 1-0:2.8.1(000348.890*kWh)
// 1-0:2.8.1 = Elektra opbrengst laag tarief (DSMR v4.0) // 1-0:2.8.1 = Elektra opbrengst laag tarief (DSMR v4.0)
if (strncmp(telegram, "1-0:2.8.1", strlen("1-0:2.8.1")) == 0) if (strncmp(telegram, "1-0:2.8.1", strlen("1-0:2.8.1")) == 0)
mEOLT = getValue(telegram, len); mEOLT = getValue(telegram, len);
// 1-0:2.8.2(000859.885*kWh) // 1-0:2.8.2(000859.885*kWh)
// 1-0:2.8.2 = Elektra opbrengst hoog tarief (DSMR v4.0) // 1-0:2.8.2 = Elektra opbrengst hoog tarief (DSMR v4.0)
if (strncmp(telegram, "1-0:2.8.2", strlen("1-0:2.8.2")) == 0) if (strncmp(telegram, "1-0:2.8.2", strlen("1-0:2.8.2")) == 0)
mEOHT = getValue(telegram, len); mEOHT = getValue(telegram, len);
// 1-0:1.7.0(00.424*kW) Actueel verbruik // 1-0:1.7.0(00.424*kW) Actueel verbruik
// 1-0:2.7.0(00.000*kW) Actuele teruglevering // 1-0:2.7.0(00.000*kW) Actuele teruglevering
// 1-0:1.7.x = Electricity consumption actual usage (DSMR v4.0) // 1-0:1.7.x = Electricity consumption actual usage (DSMR v4.0)
if (strncmp(telegram, "1-0:1.7.0", strlen("1-0:1.7.0")) == 0) if (strncmp(telegram, "1-0:1.7.0", strlen("1-0:1.7.0")) == 0)
mEAV = getValue(telegram, len); mEAV = getValue(telegram, len);
if (strncmp(telegram, "1-0:2.7.0", strlen("1-0:2.7.0")) == 0) if (strncmp(telegram, "1-0:2.7.0", strlen("1-0:2.7.0")) == 0)
mEAT = getValue(telegram, len); mEAT = getValue(telegram, len);
// 0-1:24.2.1(150531200000S)(00811.923*m3) // 0-1:24.2.1(150531200000S)(00811.923*m3)
// 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter // 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter
if (strncmp(telegram, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0) if (strncmp(telegram, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0)
mGAS = getValue(telegram, len); mGAS = getValue(telegram, len);
return validCRCFound; return validCRCFound;
} }
void readTelegram() { // Read P1 telegram
if (mySerial.available()) { void readTelegram()
{
if (mySerial.available())
{
memset(telegram, 0, sizeof(telegram)); memset(telegram, 0, sizeof(telegram));
while (mySerial.available()) { while (mySerial.available())
{
int len = mySerial.readBytesUntil('\n', telegram, MAXLINELENGTH); int len = mySerial.readBytesUntil('\n', telegram, MAXLINELENGTH);
telegram[len] = '\n'; telegram[len] = '\n';
telegram[len+1] = 0; telegram[len + 1] = 0;
yield(); yield();
if(decodeTelegram(len+1)) if (decodeTelegram(len + 1))
{ {
UpdateElectricity(); UpdateElectricity();
UpdateGas(); UpdateGas();
} }
} }
} }
} }
void loop()
{
if (hour() == 0 && minute() == 0 && second() == 0)
{
reboot();
}
void loop() {
readTelegram(); readTelegram();
button.loop();
t.update();
ArduinoOTA.handle(); ArduinoOTA.handle();
} }

View File

@ -1,15 +1,23 @@
# P1-Meter-ESP8266 # P1-Meter-ESP8266
## Original code by [jantenhove on GitHub](https://github.com/jantenhove/P1-Meter-ESP8266), I altered the code to add a screen and make it work with my own server. The original code works with Domoticz, be sure to check it out!
Software for the ESP2866 that sends P1 smart meter data to Domoticz (with CRC checking and OTA firmware updates) Software for the ESP2866 that sends P1 smart meter data to Domoticz (with CRC checking and OTA firmware updates)
### Installation instrucions ### Installation instrucions
- Make sure that your ESP8266 can be flashed from the Arduino environnment: https://github.com/esp8266/Arduino
- Install the SoftSerial library from: https://github.com/plerup/espsoftwareserial * Make sure that your ESP8266 can be flashed from the Arduino environnment: https://github.com/esp8266/Arduino
- Place all files from this repository in a directory. Open the .ino file. * Install the SoftSerial library from: https://github.com/plerup/espsoftwareserial
- Adjust WIFI, Domoticz and debug settings at the top of the file * Place all files from this repository in a directory. Open the .ino file.
- Compile and flash * Adjust WIFI, Domoticz and debug settings at the top of the file
* Compile and flash
### Connection of the P1 meter to the ESP8266 ### Connection of the P1 meter to the ESP8266
You need to connect the smart meter with a RJ11 connector. This is the pinout to use You need to connect the smart meter with a RJ11 connector. This is the pinout to use
![RJ11 P1 connetor](http://gejanssen.com/howto/Slimme-meter-uitlezen/RJ11-pinout.png) ![RJ11 P1 connetor](http://gejanssen.com/howto/Slimme-meter-uitlezen/RJ11-pinout.png)
Connect GND->GND on ESP, RTS->3.3V on ESP and RxD->any digital pin on ESP. In this sketch I use D5 Connect GND->GND on ESP, RTS->3.3V on ESP and RxD->any digital pin on ESP. In this sketch I use D5