-
-
Save puckipedia/b96f3039e0aec441274326d97452150f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// code is MIT licensed etc etc copyright 2018 Puck Meerburg that kind of stuff | |
// -- Libraries used -- | |
// DSMR lib: https://github.com/matthijskooijman/arduino-dsmr | |
#include <dsmr.h> | |
// MQTT client: https://github.com/knolleary/pubsubclient | |
#include <PubSubClient.h> | |
// ESP8266 OTA | |
#include <ArduinoOTA.h> | |
// look I'm not going to pay for a signal inverter. hooray for software | |
#define INVERT_SERIAL | |
#ifdef INVERT_SERIAL | |
#define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr))) | |
#define USC0(u) ESP8266_REG(0x020+(0xF00*(u&1))) //CONF0 | |
#define UCRXI 19 // Invert RX | |
#endif | |
#include <ESP8266WiFi.h> | |
using P1Data = ParsedData< | |
identification, | |
timestamp, | |
/* FixedValue */ energy_delivered_tariff1, | |
/* FixedValue */ energy_delivered_tariff2, | |
/* FixedValue */ energy_returned_tariff1, | |
/* FixedValue */ energy_returned_tariff2, | |
/* String */ electricity_tariff, | |
/* FixedValue */ power_delivered, | |
/* FixedValue */ power_returned | |
>; | |
// pin 3 is the request pin, but I'm like 90% certain it isn't connected on mine | |
P1Reader reader(&Serial, 3); | |
// connect via wifi | |
WiFiClient wifiClient; | |
// yes! mqtt! | |
PubSubClient mqtt("[mqtt host]", 1883, wifiClient); | |
void setup() { | |
// setup serial, both debug + non-debug | |
Serial.begin(115200); | |
// connect to the wifi | |
WiFi.begin("[wifi ssid]", "[wifi pass]"); | |
WiFi.hostname("SmartMeter"); | |
Serial.print("Connecting"); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(); | |
Serial.println(WiFi.localIP()); | |
// I have used this a few times, super useful | |
ArduinoOTA.onStart([]() { mqtt.publish("power/update", "updating", false); }); | |
ArduinoOTA.onEnd([]() { }); | |
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { }); | |
ArduinoOTA.begin(); | |
Serial.println("Flipping RX bit now... Goodbye!"); | |
delay(1000); | |
// use GPIO13/D7 for receiving from the P1 port, to allow for less work when debugging | |
Serial.pins(15, 13); | |
#ifdef INVERT_SERIAL | |
USC0(0) |= (1 << UCRXI); // magick the UART into inverse mode | |
#endif | |
reader.enable(false); | |
} | |
void loop() { | |
// ensure that MQTT is connected | |
if (!mqtt.connected()) { | |
// if the connection dies, the MQTT server will set power/status to disconnected. useful for debugging | |
while (!mqtt.connect("smartmeter", "bot_smartmeter", "[mqtt pass]", "power/status", 1, 1, "disconnected")); | |
mqtt.publish("power/status", "active", true); | |
} | |
// call event loop for subparts | |
mqtt.loop(); | |
reader.loop(); | |
ArduinoOTA.handle(); | |
if (reader.available()) { | |
P1Data data; | |
String err; | |
// do we have data? | |
if (reader.parse(&data, &err)) { | |
// put it all into the MQTT world | |
mqtt.publish("power/identification", data.identification.c_str(), false); | |
mqtt.publish("power/timestamp", data.timestamp.c_str(), false); | |
char buffer[24]; | |
itoa(data.energy_delivered_tariff1.int_val(), buffer, 10); | |
mqtt.publish("power/energy/delivered/t1", buffer, true); | |
itoa(data.energy_delivered_tariff2.int_val(), buffer, 10); | |
mqtt.publish("power/energy/delivered/t2", buffer, true); | |
itoa(data.energy_returned_tariff1.int_val(), buffer, 10); | |
mqtt.publish("power/energy/returned/t1", buffer, true); | |
itoa(data.energy_returned_tariff2.int_val(), buffer, 10); | |
mqtt.publish("power/energy/returned/t2", buffer, true); | |
mqtt.publish("power/tariff", data.electricity_tariff.c_str(), false); | |
itoa(data.power_delivered.int_val(), buffer, 10); | |
mqtt.publish("power/power/delivered", buffer, true); | |
itoa(data.power_returned.int_val(), buffer, 10); | |
mqtt.publish("power/power/returned", buffer, true); | |
} else { | |
// error occured. who cares. | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment