Smartmeter
A good friend of mine told me a few years ago that he made a smartmeter with a RaspberryPi running in its fuse box and detects the red bar on the turning disc in the fuse box. The case says how big of a fraction of a kWh one turn measures. In my case it is 1/75 kWh. So measuring the red bar going around once implies that 13,333 Wh of electrical energy have been converted.
This signal can be consumed by a microcontroller with an infrared detector and send this information to an influxdb. This information can then be used to create a nice graph with Grafana seen here in the dashboard.
To send the information to influxdb I will use Message Queuing Telemetry Transport (MQTT). I will not go into detail into setting it up, as there are already enough and good tutorials for this. I already set up a MQTT server (with the docker image for Eclipse-Mosquitto) and added the MQTT consumer in the telegraf config of my server:
[[inputs.mqtt_consumer]]
## MQTT broker URLs to be used. The format should be scheme://host:port,
## schema can be tcp, ssl, or ws.
servers = ["tcp://mqtt-broker:1883"]
## Topics that will be subscribed to.
topics = [
"stromzaehler/smartmeter",
]
So Telegraf consumes information written to the given topics and writes the data into the influxdb. As I could not find the information to write data into the influxdb anywhere obvious I tried around and got it somehow. I also tried to share the information on SO
My microcontroller tries to send the number of signals received in the last 5 seconds and resets the counter if the send was successful.
#define INTERVAL 5000 // ms
#define COOLDOWN 500 // ms
void ICACHE_RAM_ATTR countTurns(){
noInterrupts();
if (lastTrigger<millis()-COOLDOWN) {
lastTrigger=millis();
turnCount++;
}
interrupts();
}
void sendData() {
char topic[63];
char value[31];
snprintf(topic, sizeof(topic), "%s/%s", NAME, "smartmeter");
snprintf(value, sizeof(value), "turns value=%d", turnCount);
Serial.printf("%s\t%s\n", topic, value);
if (mqtt.publish(topic, value)) {
turnCount = 0; // reset turncount only if data has been sent
// data processing does not happen on controller
}
else {
Serial.println(F("ERR send"));
}
}
void loop() {
if(!mqtt.connected()){
setupMqtt(); // reconnect if needed
delay(100); // wait for connect
blink(2);
}
sendData();
delay(INTERVAL)
}
As one can see from looking at the code I decided to just send the raw count to MQTT/Telegraf/InfluxDB and make the processing (multiplying with 1/75 kWh) in Grafana only.
In Grafana the reported values then need to be added together to have the cumulative energy usage.
As this is also work in progress, I am not quite sure if the COOLDOWN
and INTERVAL
variables can be improved with different values but this is quite a decent solution so far.