mirror of
https://bitbucket.org/myhomie/mycorerepository.git
synced 2025-12-06 17:51:20 +00:00
156 lines
3.9 KiB
C++
156 lines
3.9 KiB
C++
#include <Arduino.h>
|
|
#include "EmonLib.h"
|
|
#include "WiFi.h"
|
|
#include <driver/adc.h>
|
|
#include <PubSubClient.h>
|
|
|
|
|
|
// This is the device name as defined on AWS IOT
|
|
#define DEVICE_NAME "xd-home-energy-monitor-1"
|
|
|
|
// The GPIO pin were the CT sensor is connected to (should be an ADC input)
|
|
#define ADC_INPUT 34
|
|
|
|
// The voltage in our apartment. Usually this is 230V for Europe, 110V for US.
|
|
// Ours is higher because the building has its own high voltage cabin.
|
|
#define HOME_VOLTAGE 110.0
|
|
|
|
// Force EmonLib to use 10bit ADC resolution
|
|
#define ADC_BITS 10
|
|
#define ADC_COUNTS (1<<ADC_BITS)
|
|
|
|
// Create instances
|
|
EnergyMonitor emon1;
|
|
|
|
// Wifi credentials
|
|
const char *WIFI_SSID = "Xiaomi_Router";
|
|
const char *WIFI_PASSWORD = "UYQQMTHF";
|
|
const char* mqtt_server = "m21.cloudmqtt.com";
|
|
|
|
WiFiClient lolinClient;
|
|
PubSubClient client(lolinClient);
|
|
char message_buff[100];
|
|
|
|
// Array to store 30 readings (and then transmit in one-go to AWS)
|
|
short measurements[30];
|
|
short measureIndex = 0;
|
|
unsigned long lastMeasurement = 0;
|
|
unsigned long timeFinishedSetup = 0;
|
|
|
|
void setup()
|
|
{
|
|
Serial.begin(115200);
|
|
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
|
|
analogReadResolution(10);
|
|
|
|
connectToWiFi();
|
|
|
|
// Initialize emon library (30 = calibration number)
|
|
emon1.current(ADC_INPUT, 30);
|
|
|
|
timeFinishedSetup = millis();
|
|
client.setServer(mqtt_server, 18932);
|
|
}
|
|
|
|
void connectToWiFi() {
|
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
|
|
|
// Only try 15 times to connect to the WiFi
|
|
int retries = 0;
|
|
while (WiFi.status() != WL_CONNECTED && retries < 15) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
retries++;
|
|
}
|
|
|
|
// If we still couldn't connect to the WiFi, go to deep sleep for a
|
|
// minute and try again.
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
esp_sleep_enable_timer_wakeup(1 * 60L * 1000000L);
|
|
esp_deep_sleep_start();
|
|
}
|
|
|
|
// If we get here, print the IP address on the LCD
|
|
Serial.println(WiFi.localIP());
|
|
}
|
|
|
|
void reconnect() {
|
|
// Loop until we're reconnected
|
|
while (!client.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
// Attempt to connect
|
|
if (client.connect("LolinClient-EnergyMonitor", "oilkfgjy", "lEyZb90q49Rf")) {
|
|
Serial.println("connected");
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(client.state());
|
|
Serial.println(" try again in 5 seconds");
|
|
delay(5000);
|
|
}
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
|
|
if (!client.connected()) {
|
|
reconnect();
|
|
}
|
|
|
|
client.loop();
|
|
|
|
unsigned long currentMillis = millis();
|
|
|
|
// If it's been longer then 1000ms since we took a measurement, take one now!
|
|
if (currentMillis - lastMeasurement > 1000) {
|
|
double amps = emon1.calcIrms(1480); // Calculate Irms only
|
|
double watt = amps * HOME_VOLTAGE;
|
|
|
|
if(watt > 45) {
|
|
Serial.print("watt optimized: ");
|
|
Serial.println(watt*1.35);
|
|
}
|
|
|
|
// Update the display
|
|
Serial.print("watt: ");
|
|
Serial.println(watt);
|
|
Serial.print("amps: ");
|
|
Serial.println(amps);
|
|
|
|
String toSend = "WO: " + String(watt*1.35) + ", W: " + String(watt) + ", A: " + String(amps);
|
|
toSend.toCharArray(message_buff, toSend.length()+1);
|
|
|
|
client.publish("Energy", message_buff);
|
|
|
|
lastMeasurement = millis();
|
|
|
|
// Readings are unstable the first 5 seconds when the device powers on
|
|
// so ignore them until they stabilise.
|
|
if (millis() - timeFinishedSetup < 10000) {
|
|
Serial.println("Startup mode ");
|
|
} else {
|
|
Serial.println(WiFi.localIP());
|
|
measurements[measureIndex] = watt;
|
|
measureIndex++;
|
|
}
|
|
}
|
|
|
|
// When we have 30 measurements, send them to AWS!
|
|
if (measureIndex == 30) {
|
|
Serial.println("we have 30 measurements ");
|
|
|
|
// Construct the JSON to send to AWS
|
|
String msg = "{\"readings\": [";
|
|
|
|
for (short i = 0; i <= 28; i++) {
|
|
msg += measurements[i];
|
|
msg += ",";
|
|
}
|
|
|
|
msg += measurements[29];
|
|
msg += "]}";
|
|
|
|
Serial.println("Message is ready : " + msg);
|
|
measureIndex = 0;
|
|
}
|
|
}
|