mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 06:32:19 +03:00
fix esp32c6 & add ble, Fix Date Log, add BL0942, upd Descovery
This commit is contained in:
@@ -396,8 +396,8 @@ framework = arduino
|
|||||||
board = esp32-c6-devkitm-1
|
board = esp32-c6-devkitm-1
|
||||||
platform = espressif32 @6.9.0
|
platform = espressif32 @6.9.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
|
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1
|
||||||
platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1
|
framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
@@ -423,15 +423,16 @@ build_flags =
|
|||||||
-DARDUINO_USB_MODE=0
|
-DARDUINO_USB_MODE=0
|
||||||
-Wl,--wrap=esp_panic_handler
|
-Wl,--wrap=esp_panic_handler
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32-c6-devkitc-1
|
board = esp32-c6-devkitm-1
|
||||||
platform = espressif32 @6.9.0
|
platform = espressif32 @6.9.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
|
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1
|
||||||
platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1
|
framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
debug_tool = esp-prog
|
debug_tool = esp-prog
|
||||||
|
board_build.partitions = tools/partitions_custom_8mb.csv
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
+<*.cpp>
|
+<*.cpp>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "ESPConfiguration.h"
|
#include "ESPConfiguration.h"
|
||||||
#include "classes/IoTGpio.h"
|
#include "classes/IoTGpio.h"
|
||||||
|
//#include "classes/IoTDiscovery.h"
|
||||||
|
|
||||||
extern IoTGpio IoTgpio;
|
extern IoTGpio IoTgpio;
|
||||||
|
|
||||||
@@ -52,6 +53,26 @@ void configure(String path) {
|
|||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
SerialPrint("i", "Config", "Configured");
|
SerialPrint("i", "Config", "Configured");
|
||||||
|
/*
|
||||||
|
#ifdef ESP32
|
||||||
|
if(HOMEdDiscovery)
|
||||||
|
HOMEdDiscovery->mqttSubscribeDiscovery();
|
||||||
|
if(HADiscovery)
|
||||||
|
HADiscovery->mqttSubscribeDiscovery();
|
||||||
|
// оттправляем все статусы
|
||||||
|
if(HOMEdDiscovery || HADiscovery)
|
||||||
|
{
|
||||||
|
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->iAmLocal)
|
||||||
|
{
|
||||||
|
publishStatusMqtt((*it)->getID(), (*it)->getValue());
|
||||||
|
(*it)->onMqttWsAppConnectEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearConfigure() {
|
void clearConfigure() {
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ void getMqttData() {
|
|||||||
mqttUser = jsonReadStr(settingsFlashJson, F("mqttUser"));
|
mqttUser = jsonReadStr(settingsFlashJson, F("mqttUser"));
|
||||||
mqttPass = jsonReadStr(settingsFlashJson, F("mqttPass"));
|
mqttPass = jsonReadStr(settingsFlashJson, F("mqttPass"));
|
||||||
mqttPrefix = jsonReadStr(settingsFlashJson, F("mqttPrefix"));
|
mqttPrefix = jsonReadStr(settingsFlashJson, F("mqttPrefix"));
|
||||||
nameId = jsonReadStr(settingsFlashJson, F("name"));
|
if (jsonReadInt(settingsFlashJson, F("HOMEd_names"))){
|
||||||
|
nameId = jsonReadStr(settingsFlashJson, F("name"));}
|
||||||
|
else{nameId = getChipId();}
|
||||||
mqttRootDevice = mqttPrefix + "/" + chipId;
|
mqttRootDevice = mqttPrefix + "/" + chipId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
src/NTP.cpp
45
src/NTP.cpp
@@ -180,33 +180,30 @@ const String getTodayDateDotFormated() {
|
|||||||
|
|
||||||
// format 22.02.2022
|
// format 22.02.2022
|
||||||
unsigned long strDateToUnix(String date) {
|
unsigned long strDateToUnix(String date) {
|
||||||
int day = selectToMarker(date, ".").toInt();
|
int day, month, year;
|
||||||
date = deleteBeforeDelimiter(date, ".");
|
|
||||||
int month = selectToMarker(date, ".").toInt();
|
|
||||||
date = deleteBeforeDelimiter(date, ".");
|
|
||||||
int year = selectToMarker(date, ".").toInt();
|
|
||||||
int secsInOneDay = 86400;
|
|
||||||
int daysInOneYear = 365;
|
|
||||||
int daysInLeepYear = 366;
|
|
||||||
int numberOfLeepYears = 12;
|
|
||||||
int totalNormalYears = year - 1970 - numberOfLeepYears;
|
|
||||||
unsigned int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
unsigned int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
if (year % 4 == 0) {
|
|
||||||
if (year % 100 != 0 || year % 400 == 0) {
|
day = date.substring(0, date.indexOf(".")).toInt();
|
||||||
daysInMonth[1] = 29;
|
date = date.substring(date.indexOf(".") + 1);
|
||||||
} else {
|
month = date.substring(0, date.indexOf(".")).toInt();
|
||||||
daysInMonth[1] = 28;
|
date = date.substring(date.indexOf(".") + 1);
|
||||||
}
|
year = date.toInt();
|
||||||
} else {
|
|
||||||
daysInMonth[1] = 28;
|
unsigned long unixTime = (year - 1970) * 365 * 86400;
|
||||||
|
int numberOfLeepYears = (year - 1968) / 4 - (year - 1900) / 100 + (year - 1600) / 400;
|
||||||
|
unixTime += numberOfLeepYears * 86400;
|
||||||
|
|
||||||
|
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
|
||||||
|
daysInMonth[1] = 29;
|
||||||
}
|
}
|
||||||
int numberOfDaysInPastMonths = 0;
|
|
||||||
for (int i = 0; i <= 11; i++) {
|
for (int i = 0; i < month - 1; i++) {
|
||||||
if (i <= month - 2) {
|
unixTime += daysInMonth[i] * 86400;
|
||||||
numberOfDaysInPastMonths = numberOfDaysInPastMonths + daysInMonth[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (day * secsInOneDay) + (numberOfDaysInPastMonths * secsInOneDay) + (totalNormalYears * daysInOneYear * secsInOneDay) + (numberOfLeepYears * daysInLeepYear * secsInOneDay);
|
|
||||||
|
unixTime += (day - 1) * 86400;
|
||||||
|
|
||||||
|
return unixTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
const String getDateTimeDotFormatedFromUnix(unsigned long unixTime) {
|
const String getDateTimeDotFormatedFromUnix(unsigned long unixTime) {
|
||||||
|
|||||||
@@ -49,6 +49,12 @@
|
|||||||
},
|
},
|
||||||
"defActive": false,
|
"defActive": false,
|
||||||
"usedLibs": {
|
"usedLibs": {
|
||||||
|
"esp32c6_4mb": [
|
||||||
|
"exclude"
|
||||||
|
],
|
||||||
|
"esp32c6_8mb": [
|
||||||
|
"exclude"
|
||||||
|
],
|
||||||
"esp32*": []
|
"esp32*": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
289
src/modules/sensors/BL0942/BL0942.cpp
Normal file
289
src/modules/sensors/BL0942/BL0942.cpp
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
|
||||||
|
#include "Global.h"
|
||||||
|
#include "classes/IoTUart.h"
|
||||||
|
#include "datatypes.h"
|
||||||
|
|
||||||
|
//namespace bl0942
|
||||||
|
//{
|
||||||
|
class BL0942cmd;
|
||||||
|
BL0942cmd *BL0942 = nullptr;
|
||||||
|
DataPacket buffer;
|
||||||
|
uint8_t inpos = 0xFF;
|
||||||
|
uint8_t checksum;
|
||||||
|
uint8_t pubPhase = 0xFF;
|
||||||
|
bool needUpdate = false;
|
||||||
|
|
||||||
|
static const float BL0942_PREF = 596; // taken from tasmota
|
||||||
|
static const float BL0942_UREF = 15873.35944299; // should be 73989/1.218
|
||||||
|
static const float BL0942_IREF = 251213.46469622; // 305978/1.218
|
||||||
|
static const float BL0942_EREF = 3304.61127328; // Measured
|
||||||
|
|
||||||
|
static const char *const TAG = "bl0942";
|
||||||
|
|
||||||
|
static const uint8_t BL0942_READ_COMMAND = 0x58;
|
||||||
|
static const uint8_t BL0942_FULL_PACKET = 0xAA;
|
||||||
|
static const uint8_t BL0942_PACKET_HEADER = 0x55;
|
||||||
|
|
||||||
|
static const uint8_t BL0942_WRITE_COMMAND = 0xA8;
|
||||||
|
static const uint8_t BL0942_REG_I_FAST_RMS_CTRL = 0x10;
|
||||||
|
static const uint8_t BL0942_REG_MODE = 0x18;
|
||||||
|
static const uint8_t BL0942_REG_SOFT_RESET = 0x19;
|
||||||
|
static const uint8_t BL0942_REG_USR_WRPROT = 0x1A;
|
||||||
|
static const uint8_t BL0942_REG_TPS_CTRL = 0x1B;
|
||||||
|
|
||||||
|
// TODO: Confirm insialisation works as intended
|
||||||
|
const uint8_t BL0942_INIT[5][6] = {
|
||||||
|
// Reset to default
|
||||||
|
{BL0942_WRITE_COMMAND, BL0942_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38},
|
||||||
|
// Enable User Operation Write
|
||||||
|
{BL0942_WRITE_COMMAND, BL0942_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0},
|
||||||
|
// 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS
|
||||||
|
{BL0942_WRITE_COMMAND, BL0942_REG_MODE, 0x00, 0x10, 0x00, 0x37},
|
||||||
|
// 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS
|
||||||
|
{BL0942_WRITE_COMMAND, BL0942_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE},
|
||||||
|
// 0x181C = Half cycle, Fast RMS threshold 6172
|
||||||
|
{BL0942_WRITE_COMMAND, BL0942_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B}};
|
||||||
|
|
||||||
|
|
||||||
|
class BL0942cmd : public IoTUart
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float i_rms, watt, v_rms, frequency, total_energy_consumption = 0;
|
||||||
|
// Divide by this to turn into Watt
|
||||||
|
float power_reference_ = BL0942_PREF;
|
||||||
|
// Divide by this to turn into Volt
|
||||||
|
float voltage_reference_ = BL0942_UREF;
|
||||||
|
// Divide by this to turn into Ampere
|
||||||
|
float current_reference_ = BL0942_IREF;
|
||||||
|
// Divide by this to turn into kWh
|
||||||
|
float energy_reference_ = BL0942_EREF;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BL0942cmd(String parameters) : IoTUart(parameters)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
jsonRead(parameters, "R_current", CURRENT_RESISTOR);
|
||||||
|
jsonRead(parameters, "R_upstream", VOLTAGE_RESISTOR_UPSTREAM);
|
||||||
|
jsonRead(parameters, "R_downstream", VOLTAGE_RESISTOR_DOWNSTREAM);
|
||||||
|
jsonRead(parameters, "CF_GPIO", BL0942_CF_GPIO);
|
||||||
|
jsonRead(parameters, "CF1_GPIO", BL0942_CF1_GPIO);
|
||||||
|
jsonRead(parameters, "SEL_GPIO", BL0942_SEL_GPIO_INV);
|
||||||
|
jsonRead(parameters, "kfV", _kfV);
|
||||||
|
jsonRead(parameters, "kfA", _kfA);
|
||||||
|
jsonRead(parameters, "kfW", _kfW);
|
||||||
|
*/
|
||||||
|
for (auto *i : BL0942_INIT)
|
||||||
|
{
|
||||||
|
_myUART->write(i, 6);
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
_myUART->flush();
|
||||||
|
BL0942 = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if (_myUART->available())
|
||||||
|
{
|
||||||
|
while (_myUART->available())
|
||||||
|
{
|
||||||
|
uint8_t in;
|
||||||
|
_myUART->readBytes(&in, 1);
|
||||||
|
if (inpos < sizeof(buffer) - 1)
|
||||||
|
{ // читаем тело пакета
|
||||||
|
((uint8_t *)(&buffer))[inpos] = in;
|
||||||
|
inpos++;
|
||||||
|
checksum += in;
|
||||||
|
}
|
||||||
|
else if (inpos < sizeof(buffer))
|
||||||
|
{ // получили контрольную сумму
|
||||||
|
inpos++;
|
||||||
|
checksum ^= 0xFF;
|
||||||
|
if (in != checksum)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "BL0942 invalid checksum! 0x%02X != 0x%02X", checksum, in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pubPhase = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (in == BL0942_PACKET_HEADER)
|
||||||
|
{ // стартовый хидер
|
||||||
|
((uint8_t *)(&buffer))[0] = BL0942_PACKET_HEADER;
|
||||||
|
inpos = 1; // начало сохранения буфера
|
||||||
|
checksum = BL0942_READ_COMMAND + BL0942_PACKET_HEADER; // начальные данные рассчета кс
|
||||||
|
pubPhase = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Invalid data. Header mismatch: %d", in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pubPhase < 3)
|
||||||
|
{
|
||||||
|
if (pubPhase == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
i_rms = (uint24_t)buffer.i_rms / current_reference_;
|
||||||
|
|
||||||
|
watt = (int24_t)buffer.watt / power_reference_;
|
||||||
|
|
||||||
|
pubPhase = 1;
|
||||||
|
}
|
||||||
|
else if (pubPhase == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
v_rms = (uint24_t)buffer.v_rms / voltage_reference_;
|
||||||
|
|
||||||
|
frequency = 1000000.0f / buffer.frequency;
|
||||||
|
|
||||||
|
pubPhase = 2;
|
||||||
|
}
|
||||||
|
else if (pubPhase == 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t cf_cnt = (uint24_t)buffer.cf_cnt;
|
||||||
|
total_energy_consumption = cf_cnt / energy_reference_;
|
||||||
|
|
||||||
|
pubPhase = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IoTItem::loop();
|
||||||
|
}
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
_myUART->write(BL0942_READ_COMMAND);
|
||||||
|
_myUART->write(BL0942_FULL_PACKET);
|
||||||
|
}
|
||||||
|
float getEnergy() { return total_energy_consumption; }
|
||||||
|
float getPower() { return watt; }
|
||||||
|
float getCurrent() { return i_rms; }
|
||||||
|
float getVoltage() { return v_rms; }
|
||||||
|
|
||||||
|
~BL0942cmd(){
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BL0942v : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
BL0942v(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
if (BL0942)
|
||||||
|
regEvent(BL0942->getVoltage(), "BL0942 V");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regEvent(NAN, "BL0942v");
|
||||||
|
SerialPrint("E", "BL0942cmd", "initialization error", _id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~BL0942v(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BL0942a : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
BL0942a(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
if (BL0942)
|
||||||
|
regEvent(BL0942->getCurrent(), "BL0942 A");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regEvent(NAN, "BL0942a");
|
||||||
|
SerialPrint("E", "BL0942cmd", "initialization error", _id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~BL0942a(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BL0942w : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
BL0942w(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
if (BL0942)
|
||||||
|
regEvent(BL0942->getPower(), "BL0942 W");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regEvent(NAN, "BL0942w");
|
||||||
|
SerialPrint("E", "BL0942cmd", "initialization error", _id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~BL0942w(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BL0942wh : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
BL0942wh(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
if (BL0942)
|
||||||
|
regEvent(BL0942->getEnergy() / 3600.0 / 1000.0, "BL0942 Wh");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regEvent(NAN, "BL0942wh");
|
||||||
|
SerialPrint("E", "BL0942cmd", "initialization error", _id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~BL0942wh(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
//} // namespace bl0942
|
||||||
|
|
||||||
|
void *getAPI_BL0942(String subtype, String param)
|
||||||
|
{
|
||||||
|
if (subtype == F("BL0942v"))
|
||||||
|
{
|
||||||
|
return new BL0942v(param);
|
||||||
|
}
|
||||||
|
else if (subtype == F("BL0942a"))
|
||||||
|
{
|
||||||
|
return new BL0942a(param);
|
||||||
|
}
|
||||||
|
else if (subtype == F("BL0942w"))
|
||||||
|
{
|
||||||
|
return new BL0942w(param);
|
||||||
|
}
|
||||||
|
else if (subtype == F("BL0942wh"))
|
||||||
|
{
|
||||||
|
return new BL0942wh(param);
|
||||||
|
}
|
||||||
|
else if (subtype == F("BL0942cmd"))
|
||||||
|
{
|
||||||
|
return new BL0942cmd(param);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
116
src/modules/sensors/BL0942/datatypes.h
Normal file
116
src/modules/sensors/BL0942/datatypes.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
//#include "helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Various functions can be constexpr in C++14, but not in C++11 (because their body isn't just a return statement).
|
||||||
|
// Define a substitute constexpr keyword for those functions, until we can drop C++11 support.
|
||||||
|
#if __cplusplus >= 201402L
|
||||||
|
#define constexpr14 constexpr
|
||||||
|
#else
|
||||||
|
#define constexpr14 inline // constexpr implies inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// std::byteswap from C++23
|
||||||
|
template<typename T> constexpr14 T byteswap(T n) {
|
||||||
|
T m;
|
||||||
|
for (size_t i = 0; i < sizeof(T); i++)
|
||||||
|
reinterpret_cast<uint8_t *>(&m)[i] = reinterpret_cast<uint8_t *>(&n)[sizeof(T) - 1 - i];
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
template<> constexpr14 uint8_t byteswap(uint8_t n) { return n; }
|
||||||
|
template<> constexpr14 uint16_t byteswap(uint16_t n) { return __builtin_bswap16(n); }
|
||||||
|
template<> constexpr14 uint32_t byteswap(uint32_t n) { return __builtin_bswap32(n); }
|
||||||
|
template<> constexpr14 uint64_t byteswap(uint64_t n) { return __builtin_bswap64(n); }
|
||||||
|
template<> constexpr14 int8_t byteswap(int8_t n) { return n; }
|
||||||
|
template<> constexpr14 int16_t byteswap(int16_t n) { return __builtin_bswap16(n); }
|
||||||
|
template<> constexpr14 int32_t byteswap(int32_t n) { return __builtin_bswap32(n); }
|
||||||
|
template<> constexpr14 int64_t byteswap(int64_t n) { return __builtin_bswap64(n); }
|
||||||
|
|
||||||
|
/// Convert a value between host byte order and big endian (most significant byte first) order.
|
||||||
|
template<typename T> constexpr14 T convert_big_endian(T val) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
return byteswap(val);
|
||||||
|
#else
|
||||||
|
return val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a value between host byte order and little endian (least significant byte first) order.
|
||||||
|
template<typename T> constexpr14 T convert_little_endian(T val) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
return byteswap(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper class for memory using big endian data layout, transparently converting it to native order.
|
||||||
|
template<typename T> class BigEndianLayout {
|
||||||
|
public:
|
||||||
|
constexpr14 operator T() { return convert_big_endian(val_); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T val_;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/// Wrapper class for memory using big endian data layout, transparently converting it to native order.
|
||||||
|
template<typename T> class LittleEndianLayout {
|
||||||
|
public:
|
||||||
|
constexpr14 operator T() { return convert_little_endian(val_); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T val_;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// 24-bit unsigned integer type, transparently converting to 32-bit.
|
||||||
|
struct uint24_t { // NOLINT(readability-identifier-naming)
|
||||||
|
operator uint32_t() { return val; }
|
||||||
|
uint32_t val : 24;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/// 24-bit signed integer type, transparently converting to 32-bit.
|
||||||
|
struct int24_t { // NOLINT(readability-identifier-naming)
|
||||||
|
operator int32_t() { return val; }
|
||||||
|
int32_t val : 24;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// Integer types in big or little endian data layout.
|
||||||
|
using uint64_be_t = internal::BigEndianLayout<uint64_t>;
|
||||||
|
using uint32_be_t = internal::BigEndianLayout<uint32_t>;
|
||||||
|
using uint24_be_t = internal::BigEndianLayout<uint24_t>;
|
||||||
|
using uint16_be_t = internal::BigEndianLayout<uint16_t>;
|
||||||
|
using int64_be_t = internal::BigEndianLayout<int64_t>;
|
||||||
|
using int32_be_t = internal::BigEndianLayout<int32_t>;
|
||||||
|
using int24_be_t = internal::BigEndianLayout<int24_t>;
|
||||||
|
using int16_be_t = internal::BigEndianLayout<int16_t>;
|
||||||
|
using uint64_le_t = internal::LittleEndianLayout<uint64_t>;
|
||||||
|
using uint32_le_t = internal::LittleEndianLayout<uint32_t>;
|
||||||
|
using uint24_le_t = internal::LittleEndianLayout<uint24_t>;
|
||||||
|
using uint16_le_t = internal::LittleEndianLayout<uint16_t>;
|
||||||
|
using int64_le_t = internal::LittleEndianLayout<int64_t>;
|
||||||
|
using int32_le_t = internal::LittleEndianLayout<int32_t>;
|
||||||
|
using int24_le_t = internal::LittleEndianLayout<int24_t>;
|
||||||
|
using int16_le_t = internal::LittleEndianLayout<int16_t>;
|
||||||
|
|
||||||
|
struct DataPacket {
|
||||||
|
uint8_t frame_header;
|
||||||
|
uint24_le_t i_rms;
|
||||||
|
uint24_le_t v_rms;
|
||||||
|
uint24_le_t i_fast_rms;
|
||||||
|
int24_le_t watt;
|
||||||
|
uint24_le_t cf_cnt;
|
||||||
|
uint16_le_t frequency;
|
||||||
|
uint8_t reserved1;
|
||||||
|
uint8_t status;
|
||||||
|
uint8_t reserved2;
|
||||||
|
uint8_t reserved3;
|
||||||
|
uint8_t checksum;
|
||||||
|
} __attribute__((packed));
|
||||||
108
src/modules/sensors/BL0942/modinfo.json
Normal file
108
src/modules/sensors/BL0942/modinfo.json
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
{
|
||||||
|
"menuSection": "sensors",
|
||||||
|
"configItem": [
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "BL0942 Напряжение",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "BL0942v",
|
||||||
|
"id": "bl_v",
|
||||||
|
"widget": "anydataVlt",
|
||||||
|
"page": "BL0942",
|
||||||
|
"descr": "Напряжение",
|
||||||
|
"int": 15,
|
||||||
|
"round": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "BL0942 Сила тока",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "BL0942a",
|
||||||
|
"id": "bl_a",
|
||||||
|
"widget": "anydataAmp",
|
||||||
|
"page": "BL0942",
|
||||||
|
"descr": "Сила тока",
|
||||||
|
"int": 15,
|
||||||
|
"round": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "BL0942 Мощность",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "BL0942w",
|
||||||
|
"id": "bl_w",
|
||||||
|
"widget": "anydataWt",
|
||||||
|
"page": "BL0942",
|
||||||
|
"descr": "Мощность",
|
||||||
|
"int": 15,
|
||||||
|
"round": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "BL0942 Энергия",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "BL0942wh",
|
||||||
|
"id": "bl_wh",
|
||||||
|
"widget": "anydataWth",
|
||||||
|
"page": "BL0942",
|
||||||
|
"descr": "Энергия",
|
||||||
|
"int": 15,
|
||||||
|
"round": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "BL0942 настройка",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "BL0942cmd",
|
||||||
|
"id": "bl_set",
|
||||||
|
"widget": "nil",
|
||||||
|
"page": "",
|
||||||
|
"descr": "",
|
||||||
|
"int": "5",
|
||||||
|
"tx": 17,
|
||||||
|
"rx": 16,
|
||||||
|
"line": 2,
|
||||||
|
"speed": 9600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"about": {
|
||||||
|
"authorName": "Bubnov Mikhail",
|
||||||
|
"authorContact": "https://t.me/Mit4bmw",
|
||||||
|
"authorGit": "https://github.com/Mit4el",
|
||||||
|
"specialThanks": "",
|
||||||
|
"moduleName": "BL0942",
|
||||||
|
"moduleVersion": "1.0",
|
||||||
|
"usedRam": {
|
||||||
|
"esp32_4mb": 15,
|
||||||
|
"esp8266_4mb": 15
|
||||||
|
},
|
||||||
|
"title": "Счетчик электроэнергии BL0942",
|
||||||
|
"moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, силу тока и прочие параметры.",
|
||||||
|
"propInfo": {
|
||||||
|
"int": "Количество секунд между опросами датчика. В bl_set интервал между попытками калибровки (т.к. нужны сначала данные от датчика)",
|
||||||
|
"btn-reset": "Энергия BL0942 будет сброшена к нулю.",
|
||||||
|
"R_current": "Резистор подключенный последовательно к основной линии",
|
||||||
|
"R_upstream": "это 5 резисторов по 470 Ком в делителе напряжения, который питает вывод V2P",
|
||||||
|
"R_downstream": "это резистор емкостью 1 Ком в делителе напряжения, который питает вывод V2P",
|
||||||
|
"CF_GPIO": "пин CF",
|
||||||
|
"CF1_GPIO": "пин CF1",
|
||||||
|
"SEL_GPIO": "пин SEL",
|
||||||
|
"kfV": "Коэффициент корректировки напряжение, указать после калибровки",
|
||||||
|
"kfA": "Коэффициент корректировки тока, указать после калибровки",
|
||||||
|
"kfW": "Коэффициент корректировки мощности, указать после калибровки"
|
||||||
|
},
|
||||||
|
"funcInfo": [
|
||||||
|
{
|
||||||
|
"name": "calibration",
|
||||||
|
"descr": "Расчет коэффициентов калибровки. Вызывать от имени BL0942 настройка. bl_set.calibration(220, 16, 3.5). Полученный коэффициенты искать в логе и ввести в конфигурацию kfV, kfA и kfW",
|
||||||
|
"params": ["Напряжение, Ток, Мощность"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"defActive": true,
|
||||||
|
"usedLibs": {
|
||||||
|
"esp32*": [],
|
||||||
|
"esp82*": [],
|
||||||
|
"bk72*": []
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,7 +178,11 @@ void scanEndedCB(NimBLEScanResults results)
|
|||||||
// pBLEScan->clearResults();
|
// pBLEScan->clearResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
//class BleScan : public IoTItem, NimBLEScanCallbacks
|
||||||
|
//#else
|
||||||
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
||||||
|
//#endif
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// описание параметров передаваемых из настроек датчика из веба
|
// описание параметров передаваемых из настроек датчика из веба
|
||||||
@@ -218,7 +222,9 @@ public:
|
|||||||
BLEdata["manufacturerdata"] = manufacturerdata;
|
BLEdata["manufacturerdata"] = manufacturerdata;
|
||||||
free(manufacturerdata);
|
free(manufacturerdata);
|
||||||
}
|
}
|
||||||
|
#if !defined (esp32c6_4mb) && !defined (esp32c6_8mb)
|
||||||
if (advertisedDevice->haveRSSI())
|
if (advertisedDevice->haveRSSI())
|
||||||
|
#endif
|
||||||
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
||||||
if (advertisedDevice->haveTXPower())
|
if (advertisedDevice->haveTXPower())
|
||||||
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
||||||
@@ -243,7 +249,6 @@ public:
|
|||||||
mac_address = BLEdata["id"].as<const char *>();
|
mac_address = BLEdata["id"].as<const char *>();
|
||||||
}
|
}
|
||||||
mac_address.replace(":", "");
|
mac_address.replace(":", "");
|
||||||
|
|
||||||
if (_debug < 2)
|
if (_debug < 2)
|
||||||
{
|
{
|
||||||
BLEdata.remove("manufacturerdata");
|
BLEdata.remove("manufacturerdata");
|
||||||
@@ -297,7 +302,11 @@ public:
|
|||||||
|
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
pBLEScan = BLEDevice::getScan(); // create new scan
|
pBLEScan = BLEDevice::getScan(); // create new scan
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->setScanCallbacks(this);
|
||||||
|
#else
|
||||||
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
||||||
|
#endif
|
||||||
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
||||||
pBLEScan->setInterval(100);
|
pBLEScan->setInterval(100);
|
||||||
pBLEScan->setWindow(99); // less or equal setInterval value
|
pBLEScan->setWindow(99); // less or equal setInterval value
|
||||||
@@ -312,7 +321,11 @@ public:
|
|||||||
if (_scanDuration > 0)
|
if (_scanDuration > 0)
|
||||||
{
|
{
|
||||||
SerialPrint("i", F("BLE"), "Start Scanning...");
|
SerialPrint("i", F("BLE"), "Start Scanning...");
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->start(_scanDuration, false);
|
||||||
|
#else
|
||||||
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,10 +64,10 @@
|
|||||||
},
|
},
|
||||||
"defActive": false,
|
"defActive": false,
|
||||||
"usedLibs": {
|
"usedLibs": {
|
||||||
"esp32c62_4mb": [
|
"esp32c6_4mb": [
|
||||||
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
],
|
],
|
||||||
"esp32c62_8mb": [
|
"esp32c6_8mb": [
|
||||||
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
],
|
],
|
||||||
"esp32_4mb3f": [
|
"esp32_4mb3f": [
|
||||||
|
|||||||
@@ -178,7 +178,11 @@ void scanEndedCB(NimBLEScanResults results)
|
|||||||
// pBLEScan->clearResults();
|
// pBLEScan->clearResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
//class BleScan : public IoTItem, NimBLEScanCallbacks
|
||||||
|
//#else
|
||||||
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
||||||
|
//#endif
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// описание параметров передаваемых из настроек датчика из веба
|
// описание параметров передаваемых из настроек датчика из веба
|
||||||
@@ -218,7 +222,9 @@ public:
|
|||||||
BLEdata["manufacturerdata"] = manufacturerdata;
|
BLEdata["manufacturerdata"] = manufacturerdata;
|
||||||
free(manufacturerdata);
|
free(manufacturerdata);
|
||||||
}
|
}
|
||||||
|
#if !defined (esp32c6_4mb) && !defined (esp32c6_8mb)
|
||||||
if (advertisedDevice->haveRSSI())
|
if (advertisedDevice->haveRSSI())
|
||||||
|
#endif
|
||||||
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
||||||
if (advertisedDevice->haveTXPower())
|
if (advertisedDevice->haveTXPower())
|
||||||
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
||||||
@@ -296,7 +302,11 @@ public:
|
|||||||
|
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
pBLEScan = BLEDevice::getScan(); // create new scan
|
pBLEScan = BLEDevice::getScan(); // create new scan
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->setScanCallbacks(this);
|
||||||
|
#else
|
||||||
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
||||||
|
#endif
|
||||||
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
||||||
pBLEScan->setInterval(100);
|
pBLEScan->setInterval(100);
|
||||||
pBLEScan->setWindow(99); // less or equal setInterval value
|
pBLEScan->setWindow(99); // less or equal setInterval value
|
||||||
@@ -311,7 +321,11 @@ public:
|
|||||||
if (_scanDuration > 0)
|
if (_scanDuration > 0)
|
||||||
{
|
{
|
||||||
SerialPrint("i", F("BLE"), "Start Scanning...");
|
SerialPrint("i", F("BLE"), "Start Scanning...");
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->start(_scanDuration, false);
|
||||||
|
#else
|
||||||
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,12 @@
|
|||||||
},
|
},
|
||||||
"defActive": false,
|
"defActive": false,
|
||||||
"usedLibs": {
|
"usedLibs": {
|
||||||
|
"esp32c6_4mb": [
|
||||||
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
|
],
|
||||||
|
"esp32c6_8mb": [
|
||||||
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
|
],
|
||||||
"esp32*": [
|
"esp32*": [
|
||||||
"https://github.com/Mit4el/NimBLE-Arduino.git"
|
"https://github.com/Mit4el/NimBLE-Arduino.git"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -178,7 +178,11 @@ void scanEndedCB(NimBLEScanResults results)
|
|||||||
// pBLEScan->clearResults();
|
// pBLEScan->clearResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
//class BleScan : public IoTItem, NimBLEScanCallbacks
|
||||||
|
//#else
|
||||||
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks
|
||||||
|
//#endif
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// описание параметров передаваемых из настроек датчика из веба
|
// описание параметров передаваемых из настроек датчика из веба
|
||||||
@@ -218,7 +222,9 @@ public:
|
|||||||
BLEdata["manufacturerdata"] = manufacturerdata;
|
BLEdata["manufacturerdata"] = manufacturerdata;
|
||||||
free(manufacturerdata);
|
free(manufacturerdata);
|
||||||
}
|
}
|
||||||
|
#if !defined (esp32c6_4mb) && !defined (esp32c6_8mb)
|
||||||
if (advertisedDevice->haveRSSI())
|
if (advertisedDevice->haveRSSI())
|
||||||
|
#endif
|
||||||
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
|
||||||
if (advertisedDevice->haveTXPower())
|
if (advertisedDevice->haveTXPower())
|
||||||
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
|
||||||
@@ -254,7 +260,6 @@ public:
|
|||||||
BLEdata.remove("track");
|
BLEdata.remove("track");
|
||||||
BLEdata.remove("id");
|
BLEdata.remove("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
// дописываем время прихода пакета данных
|
// дописываем время прихода пакета данных
|
||||||
BLEdata["last"] = millis();
|
BLEdata["last"] = millis();
|
||||||
if (_debug)
|
if (_debug)
|
||||||
@@ -297,7 +302,11 @@ public:
|
|||||||
|
|
||||||
BLEDevice::init("");
|
BLEDevice::init("");
|
||||||
pBLEScan = BLEDevice::getScan(); // create new scan
|
pBLEScan = BLEDevice::getScan(); // create new scan
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->setScanCallbacks(this);
|
||||||
|
#else
|
||||||
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
pBLEScan->setAdvertisedDeviceCallbacks(this);
|
||||||
|
#endif
|
||||||
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster
|
||||||
pBLEScan->setInterval(100);
|
pBLEScan->setInterval(100);
|
||||||
pBLEScan->setWindow(99); // less or equal setInterval value
|
pBLEScan->setWindow(99); // less or equal setInterval value
|
||||||
@@ -312,7 +321,11 @@ public:
|
|||||||
if (_scanDuration > 0)
|
if (_scanDuration > 0)
|
||||||
{
|
{
|
||||||
SerialPrint("i", F("BLE"), "Start Scanning...");
|
SerialPrint("i", F("BLE"), "Start Scanning...");
|
||||||
|
#if defined (esp32c6_4mb) || defined (esp32c6_8mb)
|
||||||
|
pBLEScan->start(_scanDuration, false);
|
||||||
|
#else
|
||||||
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
pBLEScan->start(_scanDuration, scanEndedCB, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,12 @@
|
|||||||
},
|
},
|
||||||
"defActive": false,
|
"defActive": false,
|
||||||
"usedLibs": {
|
"usedLibs": {
|
||||||
|
"esp32c6_4mb": [
|
||||||
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
|
],
|
||||||
|
"esp32c6_8mb": [
|
||||||
|
"https://github.com/h2zero/NimBLE-Arduino#c6-build"
|
||||||
|
],
|
||||||
"esp32*": [
|
"esp32*": [
|
||||||
"https://github.com/Mit4el/NimBLE-Arduino.git"
|
"https://github.com/Mit4el/NimBLE-Arduino.git"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -28,25 +28,25 @@ public:
|
|||||||
// mqttSubscribeExternal(_topic);
|
// mqttSubscribeExternal(_topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void onMqttRecive(String &topic, String &msg)
|
void onMqttRecive(String &topic, String &msg)
|
||||||
{
|
|
||||||
if (!HA)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (msg.indexOf("HELLO") == -1)
|
|
||||||
{
|
{
|
||||||
String dev = selectToMarkerLast(topic, "/");
|
if (!HA)
|
||||||
dev.toUpperCase();
|
|
||||||
dev.replace(":", "");
|
|
||||||
if (_topic != topic)
|
|
||||||
{
|
|
||||||
// SerialPrint("i", "ExternalMQTT", _id + " not equal: " + topic + " msg: " + msg);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (msg.indexOf("HELLO") == -1)
|
||||||
|
{
|
||||||
|
String dev = selectToMarkerLast(topic, "/");
|
||||||
|
dev.toUpperCase();
|
||||||
|
dev.replace(":", "");
|
||||||
|
if (_topic != topic)
|
||||||
|
{
|
||||||
|
// SerialPrint("i", "ExternalMQTT", _id + " not equal: " + topic + " msg: " + msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// обработка топика, на который подписались
|
||||||
}
|
}
|
||||||
// обработка топика, на который подписались
|
} */
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
void doByInterval()
|
void doByInterval()
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ public:
|
|||||||
jsonWriteInt(errorsHeapJson, F("jse3"), 1); // Ошибка чтения json файла с виджетами при отправки в mqtt
|
jsonWriteInt(errorsHeapJson, F("jse3"), 1); // Ошибка чтения json файла с виджетами при отправки в mqtt
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// String path = jsonReadStr(settingsFlashJson, F("HomeAssistant"));
|
// String HATopic = jsonReadStr(settingsFlashJson, F("HomeAssistant"));
|
||||||
JsonArray arr = doc.as<JsonArray>();
|
JsonArray arr = doc.as<JsonArray>();
|
||||||
for (JsonVariant value : arr)
|
for (JsonVariant value : arr)
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,7 @@ public:
|
|||||||
dev.replace(":", "");
|
dev.replace(":", "");
|
||||||
String HAjson = "";
|
String HAjson = "";
|
||||||
HAjson = "{\"availability\":[{\"topic\": \"" + mqttRootDevice + "/state\",\"value_template\": \"{{ value_json.status }}\"}],\"availability_mode\": \"any\",";
|
HAjson = "{\"availability\":[{\"topic\": \"" + mqttRootDevice + "/state\",\"value_template\": \"{{ value_json.status }}\"}],\"availability_mode\": \"any\",";
|
||||||
HAjson = HAjson + " \"device\": {\"identifiers\": [\"" + value["page"].as<String>() + "\"],";
|
HAjson = HAjson + " \"device\": {\"identifiers\": [\"" + mqttRootDevice + value["page"].as<String>() + "\"],";
|
||||||
HAjson = HAjson + " \"name\": \" " + value["page"].as<String>() + "\"},";
|
HAjson = HAjson + " \"name\": \" " + value["page"].as<String>() + "\"},";
|
||||||
HAjson = HAjson + " \"name\": \"" + value["descr"].as<String>() + "\",";
|
HAjson = HAjson + " \"name\": \"" + value["descr"].as<String>() + "\",";
|
||||||
HAjson = HAjson + " \"state_topic\": \"" + value["topic"].as<String>() + "/status\",";
|
HAjson = HAjson + " \"state_topic\": \"" + value["topic"].as<String>() + "/status\",";
|
||||||
@@ -114,22 +114,39 @@ public:
|
|||||||
if (value["name"].as<String>() == "anydataTmp")
|
if (value["name"].as<String>() == "anydataTmp")
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\",";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
HAjson = HAjson + " \"state_class\": \"measurement\",";
|
|
||||||
HAjson = HAjson + " \"unit_of_measurement\": \"°C\"";
|
HAjson = HAjson + " \"unit_of_measurement\": \"°C\"";
|
||||||
}
|
}
|
||||||
else if (value["name"].as<String>() == "anydataHum")
|
else if (value["name"].as<String>() == "anydataHum")
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\",";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
HAjson = HAjson + " \"state_class\": \"measurement\",";
|
|
||||||
HAjson = HAjson + " \"unit_of_measurement\": \"%\"";
|
HAjson = HAjson + " \"unit_of_measurement\": \"%\"";
|
||||||
}
|
}
|
||||||
// ввод числа
|
else if (value["name"].as<String>() == "anydataMm")
|
||||||
|
{
|
||||||
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
|
HAjson = HAjson + " \"unit_of_measurement\": \"mm\"";
|
||||||
|
}
|
||||||
|
else if (value["name"].as<String>() == "anydataBar")
|
||||||
|
{
|
||||||
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
|
HAjson = HAjson + " \"unit_of_measurement\": \"Bar\"";
|
||||||
|
}
|
||||||
|
else if (value["name"].as<String>() == "anydataPpm")
|
||||||
|
{
|
||||||
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
|
HAjson = HAjson + " \"unit_of_measurement\": \"ppm\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ввод числаФВ
|
||||||
else if (value["name"].as<String>() == "inputDgt")
|
else if (value["name"].as<String>() == "inputDgt")
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ float( value_json.status, default = 0) | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\",";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\",";
|
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\",";
|
||||||
HAjson = HAjson + " \"mode\": \"box\",";
|
HAjson = HAjson + " \"mode\": \"box\",";
|
||||||
HAjson = HAjson + " \"min\": " + -1000000 + ",";
|
HAjson = HAjson + " \"min\": " + -1000000 + ",";
|
||||||
@@ -139,14 +156,14 @@ public:
|
|||||||
else if (value["name"].as<String>() == "inputTxt")
|
else if (value["name"].as<String>() == "inputTxt")
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\",";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\"";
|
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\"";
|
||||||
}
|
}
|
||||||
// переключатель
|
// переключатель
|
||||||
else if (value["name"].as<String>() == "toggle")
|
else if (value["name"].as<String>() == "toggle")
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\",";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\",";
|
||||||
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\",";
|
HAjson = HAjson + " \"command_topic\": \"" + value["topic"].as<String>() + "/control\",";
|
||||||
HAjson = HAjson + " \"device_class\": \"switch\",";
|
HAjson = HAjson + " \"device_class\": \"switch\",";
|
||||||
HAjson = HAjson + " \"payload_off\": " + 0 + ",";
|
HAjson = HAjson + " \"payload_off\": " + 0 + ",";
|
||||||
@@ -157,7 +174,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
HAjson = HAjson + " \"value_template\": \"{{ value_json.status | default }}\",";
|
||||||
HAjson = HAjson + " \"unique_id\": \"" + dev + "\"";
|
HAjson = HAjson + " \"unique_id\": \"" + mqttRootDevice + dev + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
HAjson = HAjson + " }";
|
HAjson = HAjson + " }";
|
||||||
|
|||||||
@@ -8,16 +8,29 @@ private:
|
|||||||
bool sendOk = false;
|
bool sendOk = false;
|
||||||
// bool topicOk = false;
|
// bool topicOk = false;
|
||||||
bool HOMEd = false;
|
bool HOMEd = false;
|
||||||
|
int _names = 0;
|
||||||
|
String esp_id = chipId;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiscoveryHomeD(String parameters) : IoTDiscovery(parameters)
|
DiscoveryHomeD(String parameters) : IoTDiscovery(parameters)
|
||||||
{
|
{
|
||||||
_topic = jsonReadStr(parameters, "topic");
|
_topic = jsonReadStr(parameters, "topic");
|
||||||
|
_names = jsonReadInt(parameters, "names");
|
||||||
if (_topic && _topic != "" && _topic != "null")
|
if (_topic && _topic != "" && _topic != "null")
|
||||||
{
|
{
|
||||||
HOMEd = true;
|
HOMEd = true;
|
||||||
HOMEdTopic = _topic;
|
HOMEdTopic = _topic;
|
||||||
}
|
}
|
||||||
|
if (_names)
|
||||||
|
{
|
||||||
|
esp_id = jsonReadStr(settingsFlashJson, F("name"));
|
||||||
|
jsonWriteInt(settingsFlashJson, F("HOMEd_names"), 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsonWriteInt(settingsFlashJson, F("HOMEd_names"), 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (mqttIsConnect() && HOMEd)
|
if (mqttIsConnect() && HOMEd)
|
||||||
{
|
{
|
||||||
mqttReconnect();
|
mqttReconnect();
|
||||||
@@ -33,14 +46,14 @@ public:
|
|||||||
|
|
||||||
if (payloadStr.indexOf("HELLO") == -1)
|
if (payloadStr.indexOf("HELLO") == -1)
|
||||||
{
|
{
|
||||||
/* String dev = selectToMarkerLast(topic, "/");
|
/* String dev = selectToMarkerLast(topic, "/");
|
||||||
dev.toUpperCase();
|
dev.toUpperCase();
|
||||||
dev.replace(":", "");
|
dev.replace(":", "");
|
||||||
if (_topic != topic)
|
if (_topic != topic)
|
||||||
{
|
{
|
||||||
// SerialPrint("i", "ExternalMQTT", _id + " not equal: " + topic + " msg: " + msg);
|
// SerialPrint("i", "ExternalMQTT", _id + " not equal: " + topic + " msg: " + msg);
|
||||||
return;
|
return;
|
||||||
} */
|
} */
|
||||||
// обработка топика, на который подписались
|
// обработка топика, на который подписались
|
||||||
if (topic.indexOf(F("/td/custom")) != -1)
|
if (topic.indexOf(F("/td/custom")) != -1)
|
||||||
{
|
{
|
||||||
@@ -52,7 +65,6 @@ public:
|
|||||||
{
|
{
|
||||||
|
|
||||||
String key = kvp.key().c_str();
|
String key = kvp.key().c_str();
|
||||||
SerialPrint("i", F("=>MQTT"), "Msg from HOMEd: " + key);
|
|
||||||
String value = kvp.value().as<const char *>();
|
String value = kvp.value().as<const char *>();
|
||||||
if (key.indexOf(F("status_")) != -1)
|
if (key.indexOf(F("status_")) != -1)
|
||||||
{
|
{
|
||||||
@@ -71,11 +83,17 @@ public:
|
|||||||
generateOrder(key, val);
|
generateOrder(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (!value)
|
|
||||||
{
|
{
|
||||||
float val = kvp.value();
|
if (!value)
|
||||||
generateOrder(key, (String)(val));
|
{
|
||||||
|
float val = kvp.value();
|
||||||
|
generateOrder(key, (String)(val));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
generateOrder(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +108,8 @@ public:
|
|||||||
if (mqttIsConnect() && !sendOk && topicOk)
|
if (mqttIsConnect() && !sendOk && topicOk)
|
||||||
{
|
{
|
||||||
sendOk = true;
|
sendOk = true;
|
||||||
publishRetain(_topic + "/device/custom/" + nameId, "{\"status\":\"online\"}");
|
publishRetain(_topic + "/device/custom/" + esp_id, "{\"status\":\"online\"}");
|
||||||
String HOMEdsubscribeTopic = _topic + "/td/custom/" + nameId;
|
String HOMEdsubscribeTopic = _topic + "/td/custom/" + esp_id;
|
||||||
// mqtt.subscribe(HOMEdsubscribeTopic.c_str());
|
// mqtt.subscribe(HOMEdsubscribeTopic.c_str());
|
||||||
mqttSubscribeExternal(HOMEdsubscribeTopic);
|
mqttSubscribeExternal(HOMEdsubscribeTopic);
|
||||||
}
|
}
|
||||||
@@ -103,7 +121,7 @@ public:
|
|||||||
|
|
||||||
void publishStatusHOMEd(const String &topic, const String &data)
|
void publishStatusHOMEd(const String &topic, const String &data)
|
||||||
{
|
{
|
||||||
String path_h = HOMEdTopic + "/fd/custom/" + nameId;
|
String path_h = HOMEdTopic + "/fd/custom/" + esp_id;
|
||||||
String json_h = "{}";
|
String json_h = "{}";
|
||||||
if (topic != "onStart")
|
if (topic != "onStart")
|
||||||
{
|
{
|
||||||
@@ -133,8 +151,8 @@ public:
|
|||||||
{
|
{
|
||||||
deleteFromHOMEd();
|
deleteFromHOMEd();
|
||||||
getlayoutHOMEd();
|
getlayoutHOMEd();
|
||||||
publishRetain(HOMEdTopic + "/device/custom/" + nameId, "{\"status\":\"online\"}");
|
publishRetain(HOMEdTopic + "/device/custom/" + esp_id, "{\"status\":\"online\"}");
|
||||||
String HOMEdsubscribeTopic = HOMEdTopic + "/td/custom/" + nameId;
|
String HOMEdsubscribeTopic = HOMEdTopic + "/td/custom/" + esp_id;
|
||||||
mqtt.subscribe(HOMEdsubscribeTopic.c_str());
|
mqtt.subscribe(HOMEdsubscribeTopic.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +182,7 @@ public:
|
|||||||
JsonArray arr = doc.as<JsonArray>();
|
JsonArray arr = doc.as<JsonArray>();
|
||||||
String HOMEdJSON = "";
|
String HOMEdJSON = "";
|
||||||
HOMEdJSON = "{\"action\":\"updateDevice\",";
|
HOMEdJSON = "{\"action\":\"updateDevice\",";
|
||||||
HOMEdJSON = HOMEdJSON + "\"device\":\"" + nameId + "\",";
|
HOMEdJSON = HOMEdJSON + "\"device\":\"" + chipId + "\",";
|
||||||
HOMEdJSON = HOMEdJSON + "\"data\":{";
|
HOMEdJSON = HOMEdJSON + "\"data\":{";
|
||||||
HOMEdJSON = HOMEdJSON + "\"active\": true,";
|
HOMEdJSON = HOMEdJSON + "\"active\": true,";
|
||||||
HOMEdJSON = HOMEdJSON + "\"cloud\": false,";
|
HOMEdJSON = HOMEdJSON + "\"cloud\": false,";
|
||||||
@@ -178,7 +196,7 @@ public:
|
|||||||
{
|
{
|
||||||
String name = value["descr"];
|
String name = value["descr"];
|
||||||
String device = selectToMarkerLast(value["topic"].as<String>(), "/");
|
String device = selectToMarkerLast(value["topic"].as<String>(), "/");
|
||||||
//String id = chipId + "-" + device;
|
// String id = ChipId + "-" + device;
|
||||||
String expose = value["name"];
|
String expose = value["name"];
|
||||||
if (value["name"].as<String>() == "toggle")
|
if (value["name"].as<String>() == "toggle")
|
||||||
{
|
{
|
||||||
@@ -219,7 +237,7 @@ public:
|
|||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
publishRetain(HOMEdTopic + "/device/custom/" + nameId, "{\"status\":\"online\"}");
|
publishRetain(HOMEdTopic + "/device/custom/" + esp_id, "{\"status\":\"online\"}");
|
||||||
|
|
||||||
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it)
|
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it)
|
||||||
{
|
{
|
||||||
@@ -243,7 +261,7 @@ public:
|
|||||||
String HOMEdjson = "";
|
String HOMEdjson = "";
|
||||||
HOMEdjson = "{\"action\":\"removeDevice\",";
|
HOMEdjson = "{\"action\":\"removeDevice\",";
|
||||||
HOMEdjson = HOMEdjson + "\"device\":\"";
|
HOMEdjson = HOMEdjson + "\"device\":\"";
|
||||||
HOMEdjson = HOMEdjson + nameId;
|
HOMEdjson = HOMEdjson + chipId;
|
||||||
HOMEdjson = HOMEdjson + "\"}";
|
HOMEdjson = HOMEdjson + "\"}";
|
||||||
String topic = (HOMEdTopic + "/command/custom").c_str();
|
String topic = (HOMEdTopic + "/command/custom").c_str();
|
||||||
if (!publish(topic, HOMEdjson))
|
if (!publish(topic, HOMEdjson))
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
"widget": "",
|
"widget": "",
|
||||||
"page": "",
|
"page": "",
|
||||||
"descr": "",
|
"descr": "",
|
||||||
"topic": "homed"
|
"topic": "homed",
|
||||||
|
"names":1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"about": {
|
"about": {
|
||||||
|
|||||||
6
tools/partitions_custom_8mb.csv
Normal file
6
tools/partitions_custom_8mb.csv
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
|
app0, app, ota_0, , 3000K,
|
||||||
|
app1, app, ota_1, , 3000K,
|
||||||
|
spiffs, data, spiffs, , 1500K,
|
||||||
|
Reference in New Issue
Block a user