Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor code to run on modern frameworks #51

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .github/workflows/pio_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,6 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: PIP Cache
id: cache-pip
uses: actions/cache@v4
env:
cache-name: cache-pip-pkgs
with:
path: |
~/.cache/pip
key: ${{ runner.os }}-pip-${{env.cache-name}}
restore-keys: |
${{ runner.os }}-pio-
${{ runner.os }}-
- name: Set up Python
uses: actions/setup-python@v5
with:
Expand All @@ -57,7 +45,19 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
#platformio run -t buildfs
#platformio pkg update
- name: Patch Platformio
run: |
pwd
echo "REPO_NAME=$(basename ${{ github.repository }})" >> $GITHUB_ENV
cd $(dirname $(which pio) )
cd ../
echo $(find -type d -name site-packages)
cd $(find -type d -name site-packages)
pwd
git apply --verbose $GITHUB_WORKSPACE/extra/0001-LDF-refresh-lib-dependency-after-recursive-search.patch
cd $GITHUB_WORKSPACE
- name: Run PlatformIO
run: |
pio run -e espem -e espem_debug
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.vscode
config.json
lnk
data.*
drafts
*.bin
*.orig
Expand Down
Binary file added data/css/menu-dark.webp
Binary file not shown.
Binary file added data/css/menu-light.webp
Binary file not shown.
Binary file modified data/css/pure.css.gz
Binary file not shown.
Binary file modified data/css/style.css.gz
Binary file not shown.
Binary file modified data/css/style_dark.css.gz
Binary file not shown.
Binary file modified data/css/style_light.css.gz
Binary file not shown.
Binary file modified data/index.html.gz
Binary file not shown.
Binary file modified data/js/embui.js.gz
Binary file not shown.
Binary file modified data/js/espem.js.gz
Binary file not shown.
Binary file modified data/js/espem.ui.json.gz
Binary file not shown.
Binary file modified data/js/lodash.custom.js.gz
Binary file not shown.
Binary file added data/js/ui_embui.i18n.json.gz
Binary file not shown.
Binary file added data/js/ui_embui.json.gz
Binary file not shown.
Binary file added data/js/ui_embui.lang.json.gz
Binary file not shown.
Binary file removed data/js/ui_sys.json.gz
Binary file not shown.
24 changes: 0 additions & 24 deletions espem/config.h

This file was deleted.

92 changes: 44 additions & 48 deletions espem/espem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@
* A code for ESP32 based boards to interface with PeaceFair PZEM PowerMeters
* It can poll/collect PowerMeter data and provide it for futher processing in text/json format
*
* (c) Emil Muratov 2018-2022 https://github.com/vortigont/espem
* (c) Emil Muratov 2018-2024 https://github.com/vortigont/espem
*
*/

#include "espem.h"
#include "EmbUI.h" // EmbUI framework
#include "log.h"


#define MAX_FREE_MEM_BLK ESP.getMaxAllocHeap()
#define PUB_JSSIZE 1024
// sprintf template for json sampling data
#define JSON_SMPL_LEN 85 // {"t":1615496537000,"U":229.50,"I":1.47,"P":1216,"W":5811338,"hz":50.0,"pF":0.64},
static const char PGsmpljsontpl[] PROGMEM = "{\"t\":%u000,\"U\":%.2f,\"I\":%.2f,\"P\":%.0f,\"W\":%.0f,\"hz\":%.1f,\"pF\":%.2f},";
static const char PGdatajsontpl[] PROGMEM = "{\"age\":%llu,\"U\":%.1f,\"I\":%.2f,\"P\":%.0f,\"W\":%.0f,\"hz\":%.1f,\"pF\":%.2f}";
static constexpr const char* PGsmpljsontpl = "{\"t\":%u000,\"U\":%.2f,\"I\":%.2f,\"P\":%.0f,\"W\":%.0f,\"hz\":%.1f,\"pF\":%.2f},";
static constexpr const char* PGdatajsontpl = "{\"age\":%llu,\"U\":%.1f,\"I\":%.2f,\"P\":%.0f,\"W\":%.0f,\"hz\":%.1f,\"pF\":%.2f}";

// HTTP responce messages
static const char PGsmpld[] = "Metrics collector disabled";
static const char PGdre[] = "Data read error";
static const char PGacao[] = "Access-Control-Allow-Origin";
static const char* PGmimetxt = "text/plain";
//static const char* PGmimehtml = "text/html; charset=utf-8";
static constexpr const char* PGsmpld = "Metrics collector disabled";
static constexpr const char* PGdre = "Data read error";

using namespace pzmbus; // use general pzem abstractions

Expand All @@ -37,7 +34,7 @@ class FrameSendMQTTRaw : public FrameSendMQTT {
};

bool Espem::begin(const uart_port_t p, int rx, int tx){
LOG(printf, "espem.begin: port: %d, rx_pin: %d, tx_pin:%d\n", p, rx, tx);
LOGI(C_espem, printf, "espem.begin: port: %d, rx_pin: %d, tx_pin:%d\n", p, rx, tx);

// let's make our begin idempotent )
if (qport){
Expand Down Expand Up @@ -74,9 +71,9 @@ bool Espem::begin(const uart_port_t p, int rx, int tx){

if (pz->autopoll(true)){
t_uiupdater.restartDelayed();
LOG(println, "Autopolling enabled");
LOGI(C_espem, println, "Autopolling enabled");
} else {
LOG(println, "Sorry, can't autopoll somehow :(");
LOGE(C_espem, println, "Error on enabling autopolling!");
}

embui.server.on(PSTR("/getdata"), HTTP_GET, [this](AsyncWebServerRequest *request){
Expand Down Expand Up @@ -123,12 +120,12 @@ String& Espem::mktxtdata ( String& txtdata) {
// compat method for v 1.x cacti scripts
void Espem::wpmdata(AsyncWebServerRequest *request) {
if ( !ds.getTSsize(1) ) {
request->send(503, PGmimetxt, PGdre );
request->send(503, asyncsrv::T_text_plain, PGdre );
return;
}

String data;
request->send(200, PGmimetxt, mktxtdata(data) );
request->send(200, asyncsrv::T_text_plain, mktxtdata(data) );
}


Expand All @@ -147,7 +144,7 @@ void Espem::wdatareply(AsyncWebServerRequest *request){
m->asFloat(meter_t::frq),
m->asFloat(meter_t::pf)
);
request->send(200, PGmimejson, buffer );
request->send(200, asyncsrv::T_application_json, buffer );
}


Expand All @@ -162,7 +159,7 @@ void DataStorage::wsamples(AsyncWebServerRequest *request) {

// check if there is any sampled data
if ( !getTSsize(id) ) {
request->send(503, PGmimejson, "[]");
request->send(503, asyncsrv::T_application_json, "[]");
return;
}

Expand All @@ -180,17 +177,17 @@ void DataStorage::wsamples(AsyncWebServerRequest *request) {

const auto ts = getTS(id);
if (!ts)
request->send(503, PGmimejson, "[]");
request->send(503, asyncsrv::T_application_json, "[]");

auto iter = ts->cbegin(); // get const iterator

// set number of samples to send in responce
if (cnt > 0 && cnt < ts->getSize())
iter += ts->getSize() - cnt; // offset iterator to the last cnt elements

LOG(printf, "TimeSeries buffer has %d items, scntr: %d\n", ts->getSize(), cnt);
LOGV(C_espem, printf, "TimeSeries buffer has %d items, scntr: %d\n", ts->getSize(), cnt);

AsyncWebServerResponse* response = request->beginChunkedResponse(PGmimejson,
AsyncWebServerResponse* response = request->beginChunkedResponse(asyncsrv::T_application_json,
[this, iter, ts](uint8_t* buffer, size_t buffsize, size_t index) mutable -> size_t {

// If provided bufer is not large enough to fit 1 sample chunk, than I'm just sending
Expand Down Expand Up @@ -224,18 +221,18 @@ void DataStorage::wsamples(AsyncWebServerRequest *request) {
m.asFloat(meter_t::pf)
);
} else {
LOG(println, "SMLP pointer is null");
LOGW(C_espem, println, "SMLP pointer is null");
}

if (++iter == ts->cend())
buffer[len-1] = 0x5d; // ASCII ']' implaced over last comma
}

LOG(printf, "Sending timeseries JSON, buffer %d/%d, items left: %d\n", len, buffsize, ts->cend() - iter);
LOGV(C_espem, printf, "Sending timeseries JSON, buffer %d/%d, items left: %d\n", len, buffsize, ts->cend() - iter);
return len;
});

response->addHeader(PGacao, "*"); // CORS header
response->addHeader(asyncsrv::T_CORS_ACAO, "*"); // CORS header
request->send(response);
}

Expand All @@ -246,20 +243,19 @@ void Espem::wspublish(){

const auto m = pz->getMetricsPZ004();

DynamicJsonDocument doc(PUB_JSSIZE);
JsonObject obj = doc.to<JsonObject>();
doc["stale"] = pz->getState()->dataStale();
doc["age"] = pz->getState()->dataAge();
doc["U"] = m->voltage;
doc["I"] = m->current;
doc["P"] = m->power;
doc["W"] = m->energy + ds.getEnergyOffset();
doc["Pf"] = m->pf;
doc["freq"] = m->freq;

Interface interf(&embui.feeders, 128);
interf.json_frame(C_espem);
interf.jobject(doc, true);
Interface interf(&embui.feeders);
interf.json_frame(C_espem, C_sample);

JsonObject obj = interf.json_object_create();
obj["stale"] = pz->getState()->dataStale();
obj["age"] = pz->getState()->dataAge();
obj["U"] = m->voltage;
obj["I"] = m->current;
obj["P"] = m->power;
obj["W"] = m->energy + ds.getEnergyOffset();
obj["Pf"] = m->pf;
obj["freq"] = m->freq;

interf.json_frame_flush();
}

Expand All @@ -285,30 +281,30 @@ void DataStorage::reset(){
tsids.clear();

uint8_t a;
a = addTS(embui.paramVariant(V_TS_T1_CNT), time(nullptr), embui.paramVariant(V_TS_T1_INT), "Tier 1", 1);
a = addTS(embui.getConfig()[V_TS_T1_CNT] | TS_T1_CNT, time(nullptr), embui.getConfig()[V_TS_T1_INT] | TS_T1_INTERVAL, "Tier 1", 1);
tsids.push_back(a);
//LOG(printf, "Add TS: %d\n", a);
LOGD(C_espem, printf, "Add TS: %d\n", a);

a = addTS(embui.paramVariant(V_TS_T2_CNT), time(nullptr), embui.paramVariant(V_TS_T2_INT), "Tier 2", 2);
a = addTS(embui.getConfig()[V_TS_T2_CNT] | TS_T2_CNT, time(nullptr), embui.getConfig()[V_TS_T2_INT] | TS_T2_INTERVAL, "Tier 2", 2);
tsids.push_back(a);
//LOG(printf, "Add TS: %d\n", a);
LOGD(C_espem, printf, "Add TS: %d\n", a);

a = addTS(embui.paramVariant(V_TS_T3_CNT), time(nullptr), embui.paramVariant(V_TS_T3_INT), "Tier 3", 3);
a = addTS(embui.getConfig()[V_TS_T3_CNT] | TS_T3_CNT, time(nullptr), embui.getConfig()[V_TS_T3_INT] | TS_T3_INTERVAL, "Tier 3", 3);
tsids.push_back(a);
//LOG(printf, "Add TS: %d\n", a);
LOG(printf, "Add TS: %d\n", a);

LOG(println, "Setup TimeSeries DB:");
LOGI(C_espem, println, "Setup TimeSeries DB:");
LOG_CALL(
for ( auto i : tsids ){
auto t = getTS(i);
if (t){
LOG(printf, "%s: size:%d, interval:%u, mem:%u\n", t->getDescr(), t->capacity, t->getInterval(), t->capacity * sizeof(pz004::metrics));
LOGI(C_espem, printf, "%s: size:%d, interval:%u, mem:%u\n", t->getDescr(), t->capacity, t->getInterval(), t->capacity * sizeof(pz004::metrics));
}
}
)

LOG(printf, "SRAM: heap %u, free %u\n", ESP.getHeapSize(), ESP.getFreeHeap());
LOG(printf, "SPI-RAM: size %u, free %u\n", ESP.getPsramSize(), ESP.getFreePsram());
LOGI(C_espem, printf, "SRAM: heap %u, free %u\n", ESP.getHeapSize(), ESP.getFreeHeap());
LOGI(C_espem, printf, "SPI-RAM: size %u, free %u\n", ESP.getPsramSize(), ESP.getFreePsram());
}

mcstate_t Espem::set_collector_state(mcstate_t state){
Expand Down Expand Up @@ -351,7 +347,7 @@ mcstate_t Espem::set_collector_state(mcstate_t state){


void msgdebug(uint8_t id, const RX_msg* m){
Serial.printf("\nCallback triggered for PZEM ID: %d\n", id);
LOGD("DBG", printf, "\nCallback triggered for PZEM ID: %d\n", id);

/*
It is also possible to work directly on a raw data from PZEM
Expand Down
2 changes: 1 addition & 1 deletion espem/espem.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#include "main.h"
#include "pzem_edl.hpp"
#include "timeseries.hpp"

// Tasker object from EmbUI
#include "ts.h"
#include "ESPAsyncWebServer.h"

// Defaults
#ifndef DEFAULT_WS_UPD_RATE
Expand Down
Loading