Skip to content

Commit

Permalink
ADD wIfI SETTINGS
Browse files Browse the repository at this point in the history
  • Loading branch information
stritti committed Mar 3, 2022
1 parent 9394c07 commit 346aee2
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 111 deletions.
12 changes: 4 additions & 8 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,20 @@

[platformio]
default_envs = esp32
extra_configs = private_config.ini

[env]
src_build_flags =
'-D WIFI_SSID="${env.wifi_ssid}"'
'-D WIFI_PWD="${env.wifi_pwd}"'
'-D KOSTAL_MODBUS_HOSTNAME="${env.kostal_modbus_hostname}"'
-D KOSTAL_MODBUS_PORT=${env.kostal_modbus_port}
-D KOSTAL_MODBUS_SLAVE_ID=${env.kostal_modbus_slave_id}
[env:esp32]
platform = espressif32
board = firebeetle32
framework = arduino
lib_deps =
emelianov/modbus-esp8266@^4.0.0
olikraus/U8g2@^2.32.10
juerd/ESP-WiFiSettings@^3.8.0

upload_port = COM9
monitor_port = COM9
monitor_speed = 74880

monitor_filters = esp32_exception_decoder
build_type = debug # for the above filter to work

Expand Down
24 changes: 0 additions & 24 deletions src/config.hpp

This file was deleted.

203 changes: 124 additions & 79 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@
*/
#include <Arduino.h>
#include <WiFi.h>
#include <SPIFFS.h>
#include <WiFiSettings.h>

#include <ModbusIP_ESP8266.h>
#include <U8g2lib.h>

// settings managed through a private_config.ini file
#include "config.hpp"
WiFiClient theClient; // Set up a client for the WiFi connection
const String hostname = "pv-monitor";
const int32_t DATA_UPDATE_DELAY_SECONDS = 20; // Show result every second

WiFiClient theClient; // Set up a client for the WiFi connection
IPAddress remote; // Address of Modbus Slave device

IPAddress remote; // Address of Modbus Slave device
const String hostname = "Kostal Plenticore Monitor";
ModbusIP mb; //ModbusTCP object

// Display hardware I2C interface constructor
// Display hardware I2C interface constructor for 0,96" OLED display
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(/* rotation=*/U8G2_R0, /* reset=*/U8X8_PIN_NONE);

const int32_t modbus_query_delay = 1500; // Show result every n'th millisecond
uint32_t modbus_query_last = 0;
ModbusIP mb; //ModbusTCP object
String kostal_modbus_hostname; // hostname of the Modbus TCP server
uint16_t kostal_modbus_port; // port of the Modbus TCP server
const uint8_t KOSTAL_MODBUS_SLAVE_ID = 71; // slave id of the Modbus TCP server
const int32_t MODBUS_QUERY_DELAY = 1500; // Show result every n'th millisecond
uint32_t modbus_query_last = 0;

/**
* @brief reconstruct the float from 2 unsigned integers
Expand Down Expand Up @@ -67,7 +70,7 @@ float get_float(uint16_t reg) { // get the float from the Modbus register
uint16_t numregs = 2;
uint16_t value[numregs];

while (millis() - modbus_query_last < modbus_query_delay) {
while (millis() - modbus_query_last < MODBUS_QUERY_DELAY) {
if (mb.isConnected(remote)) { // Check if connection to Modbus Slave is established
mb.task();
delay(10);
Expand All @@ -82,7 +85,7 @@ float get_float(uint16_t reg) { // get the float from the Modbus register
delay(10);
}
} else {
mb.connect(remote, KOSTAL_MODBUS_PORT); // Try to connect if no connection
mb.connect(remote, kostal_modbus_port); // Try to connect if no connection
Serial.println("Modbus connected.");
}
float float_reconstructed = f_2uint_float(value[0], value[1]);
Expand All @@ -98,7 +101,7 @@ float get_float(uint16_t reg) { // get the float from the Modbus register
uint16_t get_uint16(uint16_t reg) { // get the int16 from the Modbus register
uint16_t res;

while (millis() - modbus_query_last < modbus_query_delay) {
while (millis() - modbus_query_last < MODBUS_QUERY_DELAY) {
if (mb.isConnected(remote)) { // Check if connection to Modbus Slave is established
mb.task();
delay(10);
Expand All @@ -112,28 +115,52 @@ uint16_t get_uint16(uint16_t reg) { // get the int16 from the Modbus register
delay(10);
}
} else {
mb.connect(remote, KOSTAL_MODBUS_PORT); // Try to connect if no connection
mb.connect(remote, kostal_modbus_port); // Try to connect if no connection
Serial.println("Modbus connected.");
}

return res;
}

/**
* @brief
* @brief write the text to the display
*
* @param y
* @param label
* @param unit
* @param value
*/
void writeToDisplay(u8g2_uint_t y, const char* label, const char* unit, float value) { // write the text to the display
void writeToDisplay(u8g2_uint_t y, const char* label, const char* unit, float value) {
char buffer[50];
sprintf(buffer, "%s %4.0d%s", label, (int)value, unit);
if (value < 1000 && value > -1000) {
sprintf(buffer, "%s %4.0d%s", label, (int)value, unit);
} else {
sprintf(buffer, "%s %2.0dk%s", label, (int)value / 1000, unit);
}

u8g2.setFont(u8g2_font_t0_17b_tr);
//u8g2.setFont(u8g2_font_profont15_tr); // choose a suitable font
u8g2.setCursor(0, y * 16);
u8g2.print(buffer);
Serial.println(buffer);
}

/**
* @brief write the text to the display
*
* @param y
* @param label
* @param unit
* @param value
*/
void writeToDisplay(u8g2_uint_t y, const char* label, const char* unit, uint16_t value) {
char buffer[50];
sprintf(buffer, "%s %4.0d%s", label, value, unit);
u8g2.setFont(u8g2_font_t0_17b_tr);
//u8g2.setFont(u8g2_font_profont15_tr); // choose a suitable font
u8g2.setCursor(0, y * 16);
u8g2.print(buffer);
Serial.println(buffer);
}

/**
Expand Down Expand Up @@ -162,57 +189,87 @@ void setup() {
Serial.println(F(" Kostal Plenticore DC/DC converter Monitor "));
Serial.println(F("-------------------------------------------"));

SPIFFS.begin(true); // Will format on the first run after failing to mount

u8g2.begin();
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_t0_17b_tr); // choose a suitable font
u8g2.setFont(u8g2_font_t0_15b_tr); // choose a suitable font
u8g2.setCursor(0, 17);
u8g2.print(F("Kostal Plenticore"));
u8g2.setCursor(0, 48);
u8g2.print(F("Setup WiFi ..."));
u8g2.print(F("Kostal Monitor"));
u8g2.sendBuffer(); // transfer internal memory to the display

Serial.print(F("Connecting to WiFi SSID: "));
Serial.print(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
WiFi.setHostname(hostname.c_str()); //define hostname

WiFi.begin(WIFI_SSID, WIFI_PWD);
WiFiSettings.onPortal = []() {
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_t0_15b_tr); // choose a suitable font
u8g2.setCursor(0, 14);
u8g2.println("Setup Device");
u8g2.setCursor(0, 28);
u8g2.println("---------------");
u8g2.setCursor(0, 42);
u8g2.println(F("Connect to WiFi:"));
u8g2.setCursor(8, 56);
u8g2.println(hostname);
u8g2.sendBuffer(); // transfer internal memory to the display
};

while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(F(" ."));
}
Serial.println(F(""));
// Set custom callback functions
WiFiSettings.onSuccess = []() {
IPAddress wIP = WiFi.localIP();
Serial.printf("WiFi IP address: %u.%u.%u.%u\n", wIP[0], wIP[1], wIP[2], wIP[3]);

//WiFi.mode(WIFI_STA);
//WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
//WiFi.setHostname(hostname.c_str()); //define hostname

WiFi.hostByName(kostal_modbus_hostname.c_str(), remote);
Serial.print(F("Connecting to Modbus Slave: "));
Serial.print(kostal_modbus_hostname);
Serial.print(" IP address: ");
Serial.println(remote);
// Set up ModbusTCP client.
mb.slave(KOSTAL_MODBUS_SLAVE_ID);

u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_t0_15b_tr); // choose a suitable font
u8g2.setCursor(0, 16);
u8g2.print(F("Connected to:"));
u8g2.setCursor(0, 32);
u8g2.print(kostal_modbus_hostname);
u8g2.setCursor(0, 48);
u8g2.print(F("Loading data ..."));
u8g2.sendBuffer(); // transfer internal memory to the display
};

IPAddress wIP = WiFi.localIP();
Serial.printf("WiFi IP address: %u.%u.%u.%u\n", wIP[0], wIP[1], wIP[2], wIP[3]);
WiFiSettings.onFailure = []() {
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_t0_15b_tr); // choose a suitable font
u8g2.setCursor(2, 32);
u8g2.print(F("WiFi connection failed."));
u8g2.sendBuffer(); // transfer internal memory to the display
};

WiFi.hostByName(KOSTAL_MODBUS_HOSTNAME, remote);
Serial.print(F("Connecting to Modbus Slave: "));
Serial.print(KOSTAL_MODBUS_HOSTNAME);
Serial.print(" IP address: ");
Serial.println(remote);
// Set up ModbusTCP client.
mb.slave(KOSTAL_MODBUS_SLAVE_ID);
WiFiSettings.hostname = hostname.c_str();
// Define custom settings saved by WifiSettings
// These will return the default if nothing was set before
kostal_modbus_hostname = WiFiSettings.string("kostal_modbus_hostname", "hostname", "KOSTAL Modbus Hostname");
kostal_modbus_port = WiFiSettings.integer("kostal_modbus_port", 1, 65535, 1502, "KOSTAL Modbus Port");

u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_t0_17b_tr); // choose a suitable font
u8g2.setCursor(2, 32);
u8g2.print(F("Connected."));
u8g2.sendBuffer(); // transfer internal memory to the display
// Connect to WiFi with a timeout of 30 seconds
// Launches the portal if the connection failed
WiFiSettings.connect(true, 30);
}

const int32_t showDelay = 10000; // Show result every n'th millisecond
uint32_t showLast = 0;
uint32_t showLast = 0;
bool showConsumtion = true;

/**
* @brief
*
*/
void loop() {

if (millis() - showLast > showDelay) { // Display register value every n seconds (with default settings)
if (millis() - showLast >
(DATA_UPDATE_DELAY_SECONDS * 1000)) { // Display register value every n seconds (with default settings)
showLast = millis();

float battery_temp = get_float(214);
Expand All @@ -226,6 +283,7 @@ void loop() {
Serial.print(battery_soc);
Serial.println(F(" %"));

// TODO: Show Warning if level X is reached
Serial.print(F("Battery Temp: "));
Serial.print(battery_temp);
Serial.println(F("°C"));
Expand All @@ -234,52 +292,39 @@ void loop() {
Serial.print(get_float(100));
Serial.println(F(" W"));

Serial.print(F("Home own consumption from battery: "));
Serial.print(ownConsumption_battery);
Serial.println(F(" W"));

Serial.print(F("Home own consumption from grid: "));
Serial.print(ownConsumption_grid);
Serial.println(F(" W"));

Serial.print(F("Home own consumption from PV: "));
Serial.print(ownConsumption_pv);
Serial.println(F(" W"));

Serial.print(F("Total home own consumption: "));
Serial.print(ownConsumption_sum);
Serial.println(F(" W"));

Serial.print(F("Power limit from EVU: "));
Serial.print(get_uint16(122));
Serial.println(F(" %"));

Serial.println(F(" "));

u8g2.clearBuffer(); // clear the internal memory

u8g2.setFont(u8g2_font_t0_17b_tr);
char buffer_soc[50];
sprintf(buffer_soc, "SoC %3.0d%%", battery_soc);
u8g2.setCursor(0, 15);
u8g2.print(buffer_soc);

writeToDisplay(2, "PV ", "W", ownConsumption_pv);
writeToDisplay(3, "Akku", "W", ownConsumption_battery);
writeToDisplay(4, "Netz", "W", ownConsumption_grid);
if (showConsumtion == true) {
writeToDisplay(1, "SOC ", "%", battery_soc);
writeToDisplay(2, "PV ", "W", ownConsumption_pv);
writeToDisplay(3, "Akku", "W", ownConsumption_battery);
writeToDisplay(4, "Netz", "W", ownConsumption_grid);
} else {
writeToDisplay(2, "PVgen", "W", get_float(224) + get_float(234));
writeToDisplay(3, "react", "W", get_float(254));
writeToDisplay(4, "appar", "W", get_float(256));
}

drawBattery(battery_soc);

// draw smiley
u8g2.setFont(u8g2_font_emoticons21_tr);
if (ownConsumption_grid < 50) {
u8g2.drawGlyph(100, 64, 0x0021); /* hex 21 smily man */
} else if (ownConsumption_pv > ownConsumption_battery) {
if (ownConsumption_grid > (ownConsumption_pv + ownConsumption_battery)) {
u8g2.drawGlyph(100, 64, 0x0026); /* hex 26 sad man */
} else if (ownConsumption_pv > (ownConsumption_battery + ownConsumption_grid)) {
u8g2.drawGlyph(100, 64, 0x0036); /* hex 36 sunglass smily man */
} else {
u8g2.drawGlyph(100, 64, 0x0026); /* hex 26 sad man */
u8g2.drawGlyph(100, 64, 0x0021); /* hex 21 smily man */
}

u8g2.sendBuffer(); // transfer internal memory to the display

showConsumtion = !showConsumtion;
}
}

0 comments on commit 346aee2

Please sign in to comment.