/*
* By Hadley Rich
* Released under the MIT license.
* Some ideas taken from arduino.cc example code.
*/
#include
#include
#include
#include
byte mac[6] = { 0x90, 0xA2, 0xDA, 0x44, 0x34, 0x28 };
char macstr[18];
const int chan1_pin = 2;
//My meter flashes 1000 times per kWh
const float w_per_pulse = 1;
const unsigned long ms_per_hour = 3600000UL;
unsigned int chan1_count = 0;
unsigned long report_time = 0;
unsigned long chan1_first_pulse = 0;
unsigned long chan1_last_pulse = 0;
volatile byte chan1_pulse = 0;
EthernetClient ethClient;
PubSubClient client("192.168.1.3", 1883, callback, ethClient);
void callback(char* topic, byte* payload, unsigned int length) {
}
void chan1_isr() {
chan1_pulse = 1;
}
boolean connect_mqtt() {
Serial.print("MQTT...");
if (client.connect(macstr)) {
Serial.println("connected");
char topic[35];
snprintf(topic, 35, "house/node/%s/state", macstr);
client.publish(topic, "start");
return true;
}
Serial.println("Failed.");
return false;
}
void setup() {
pinMode(chan1_pin, INPUT);
attachInterrupt(0, chan1_isr, RISING);
Serial.begin(9600);
delay(1000);
snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.print("DHCP (");
Serial.print(macstr);
Serial.print(")...");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed.");
while(true);
}
Serial.println(Ethernet.localIP());
}
void loop() {
char topic[35];
char value[6];
static unsigned int chan1_watts;
unsigned long chan1_delta; // Time since last pulse
if (!client.connected() && !connect_mqtt()) {
return;
}
client.loop();
if (millis() - chan1_last_pulse > 60000) {
chan1_watts = 0;
}
if (millis() - report_time > 5000) {
chan1_delta = chan1_last_pulse - chan1_first_pulse;
if (chan1_delta && chan1_count) {
chan1_watts = (chan1_count - 1) * w_per_pulse * ms_per_hour / chan1_delta;
chan1_count = 0;
}
if (!(report_time == 0 && chan1_watts == 0)) {
snprintf(topic, 35, "house/power/meter/1/current");
snprintf(value, 6, "%d", chan1_watts);
client.publish(topic, value);
Serial.print("Chan1 ");
Serial.println(chan1_watts);
report_time = millis();
}
}
if (chan1_pulse == 1) {
chan1_count++;
chan1_pulse = 0;
chan1_last_pulse = millis();
if (chan1_count == 1) { // was reset
chan1_first_pulse = chan1_last_pulse;
}
snprintf(topic, 35, "house/power/meter/1/usage");
client.publish(topic, "1");
}
int dhcp_status = Ethernet.maintain();
/*
returns:
0: nothing happened
1: renew failed
2: renew success
3: rebind fail
4: rebind success
*/
if (dhcp_status) {
long now = millis();
Serial.println("DHCP Lease");
}
}
|