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.