mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
This commit is contained in:
207
dump_telegrams.csv
Normal file
207
dump_telegrams.csv
Normal file
@@ -0,0 +1,207 @@
|
||||
telegram_type_id,name,is_fetched,is_received,is_cmd
|
||||
0x04,UBAFactory,fetched,,cmd
|
||||
0x06,RCTime,,,cmd
|
||||
0x0A,EasyMonitor,fetched,,cmd
|
||||
0x10,UBAErrorMessage1,,,cmd
|
||||
0x11,UBAErrorMessage2,,,cmd
|
||||
0x12,RCErrorMessage,,,cmd
|
||||
0x13,RCErrorMessage2,,,cmd
|
||||
0x14,UBATotalUptime,fetched,,cmd
|
||||
0x15,UBAMaintenanceData,,,cmd
|
||||
0x16,UBAParameters,fetched,,cmd
|
||||
0x18,UBAMonitorFast,,,cmd
|
||||
0x19,UBAMonitorSlow,,,cmd
|
||||
0x1A,UBASetPoints,,,cmd
|
||||
0x1C,UBAMaintenanceStatus,,,cmd
|
||||
0x1E,WM10TempMessage,,,cmd
|
||||
0x23,JunkersSetMixer,fetched,,cmd
|
||||
0x26,UBASettingsWW,fetched,,cmd
|
||||
0x28,WeatherComp,fetched,,cmd
|
||||
0x2A,MC110Status,,,cmd
|
||||
0x2E,Meters,,,cmd
|
||||
0x33,UBAParameterWW,fetched,,cmd
|
||||
0x34,UBAMonitorWW,,,cmd
|
||||
0x35,UBAFlags,,,cmd
|
||||
0x37,WWSettings,fetched,,cmd
|
||||
0x38,WWTimer,fetched,,cmd
|
||||
0x39,WWCircTimer,fetched,,cmd
|
||||
0x3A,RC30WWSettings,fetched,,cmd
|
||||
0x3B,Energy,,,cmd
|
||||
0x3D,RC35Set,,,cmd
|
||||
0x3E,RC35Monitor,,,cmd
|
||||
0x3F,RC35Timer,,,cmd
|
||||
0x40,RC30Temp,,,cmd
|
||||
0x41,RC30Monitor,,,cmd
|
||||
0x42,RC35Timer2,,,cmd
|
||||
0x47,RC35Set,,,cmd
|
||||
0x48,RC35Monitor,,,cmd
|
||||
0x49,RC35Timer,,,cmd
|
||||
0x4C,RC35Timer2,,,cmd
|
||||
0x51,RC35Set,,,cmd
|
||||
0x52,RC35Monitor,,,cmd
|
||||
0x53,RC35Timer,,,cmd
|
||||
0x56,RC35Timer2,,,cmd
|
||||
0x5B,RC35Set,,,cmd
|
||||
0x5C,RC35Monitor,,,cmd
|
||||
0x5D,RC35Timer,,,cmd
|
||||
0x60,RC35Timer2,,,cmd
|
||||
0x96,SM10Config,fetched,,cmd
|
||||
0x97,SM10Monitor,,,cmd
|
||||
0x9C,WM10MonitorMessage,,,cmd
|
||||
0x9D,WM10SetMessage,,,cmd
|
||||
0xA2,RCError,,,cmd
|
||||
0xA3,RCOutdoorTemp,,,cmd
|
||||
0xA5,IBASettings,fetched,,cmd
|
||||
0xA7,RC30Set,,,cmd
|
||||
0xAA,MMConfigMessage,fetched,,cmd
|
||||
0xAB,MMStatusMessage,,,cmd
|
||||
0xAC,MMSetMessage,,,cmd
|
||||
0xAF,RC20Remote,,,cmd
|
||||
0xB0,RC10Set,,,cmd
|
||||
0xB1,RC10Monitor,,,cmd
|
||||
0xBB,HybridSettings,fetched,,cmd
|
||||
0xBF,ErrorMessage,,,cmd
|
||||
0xC2,UBAErrorMessage3,,,cmd
|
||||
0xD1,UBAOutdoorTemp,,,cmd
|
||||
0xE3,UBAMonitorSlowPlus2,,,cmd
|
||||
0xE4,UBAMonitorFastPlus,,,cmd
|
||||
0xE5,UBAMonitorSlowPlus,,,cmd
|
||||
0xE6,UBAParametersPlus,fetched,,cmd
|
||||
0xE9,UBAMonitorWWPlus,,,cmd
|
||||
0xEA,UBAParameterWWPlus,fetched,,cmd
|
||||
0x0101,ISM1Set,fetched,,cmd
|
||||
0x0103,ISM1StatusMessage,fetched,,cmd
|
||||
0x0104,ISM2StatusMessage,,,cmd
|
||||
0x010C,IPMStatusMessage,,,cmd
|
||||
0x011E,IPMTempMessage,,,cmd
|
||||
0x0165,JunkersSet,,,cmd
|
||||
0x0166,JunkersSet,,,cmd
|
||||
0x0167,JunkersSet,,,cmd
|
||||
0x0168,JunkersSet,,,cmd
|
||||
0x016F,JunkersMonitor,,,cmd
|
||||
0x0170,JunkersMonitor,,,cmd
|
||||
0x0171,JunkersMonitor,,,cmd
|
||||
0x0172,JunkersMonitor,,,cmd
|
||||
0x0179,JunkersSet,,,cmd
|
||||
0x017A,JunkersSet,,,cmd
|
||||
0x017B,JunkersSet,,,cmd
|
||||
0x017C,JunkersSet,,,cmd
|
||||
0x01D3,JunkersDhw,fetched,,cmd
|
||||
0x023A,RC300OutdoorTemp,fetched,,cmd
|
||||
0x023E,PVSettings,fetched,,cmd
|
||||
0x0240,RC300Settings,fetched,,cmd
|
||||
0x0267,RC300Floordry,,,cmd
|
||||
0x0291,HPMode,fetched,,cmd
|
||||
0x0292,HPMode,fetched,,cmd
|
||||
0x0293,HPMode,fetched,,cmd
|
||||
0x0294,HPMode,fetched,,cmd
|
||||
0x029B,RC300Curves,,,cmd
|
||||
0x029C,RC300Curves,,,cmd
|
||||
0x029D,RC300Curves,,,cmd
|
||||
0x029E,RC300Curves,,,cmd
|
||||
0x029F,RC300Curves,,,cmd
|
||||
0x02A0,RC300Curves,,,cmd
|
||||
0x02A1,RC300Curves,,,cmd
|
||||
0x02A2,RC300Curves,,,cmd
|
||||
0x02A5,RC300Monitor,,,cmd
|
||||
0x02A6,RC300Monitor,,,cmd
|
||||
0x02A7,CRFMonitor,,,cmd
|
||||
0x02A8,RC300Monitor,,,cmd
|
||||
0x02A9,RC300Monitor,,,cmd
|
||||
0x02AA,RC300Monitor,,,cmd
|
||||
0x02AB,RC300Monitor,,,cmd
|
||||
0x02AC,RC300Monitor,,,cmd
|
||||
0x02AF,RC300Summer,,,cmd
|
||||
0x02B0,RC300Summer,,,cmd
|
||||
0x02B1,RC300Summer,,,cmd
|
||||
0x02B2,RC300Summer,,,cmd
|
||||
0x02B3,RC300Summer,,,cmd
|
||||
0x02B4,RC300Summer,,,cmd
|
||||
0x02B5,RC300Summer,,,cmd
|
||||
0x02B6,RC300Summer,,,cmd
|
||||
0x02B9,RC300Set,,,cmd
|
||||
0x02BA,RC300Set,,,cmd
|
||||
0x02BB,RC300Set,,,cmd
|
||||
0x02BC,RC300Set,,,cmd
|
||||
0x02BD,RC300Set,,,cmd
|
||||
0x02BE,RC300Set,,,cmd
|
||||
0x02BF,RC300Set,,,cmd
|
||||
0x02C0,RC300Set,,,cmd
|
||||
0x02CC,HPPressure,fetched,,cmd
|
||||
0x02CD,MMPLUSSetMessage_HC,fetched,,cmd
|
||||
0x02CE,RC300Set2,,,cmd
|
||||
0x02D0,RC300Set2,,,cmd
|
||||
0x02D2,RC300Set2,,,cmd
|
||||
0x02D5,MMPLUSSetMessage_HC,fetched,,cmd
|
||||
0x02D7,MMPLUSStatusMessage_HC,,,cmd
|
||||
0x02DF,MMPLUSStatusMessage_HC,,,cmd
|
||||
0x02F5,RC300WWmode,fetched,,cmd
|
||||
0x02F6,RC300WW2mode,fetched,,cmd
|
||||
0x031B,RC300WWtemp,fetched,,cmd
|
||||
0x031D,RC300WWmode2,,,cmd
|
||||
0x031E,RC300WWmode2,,,cmd
|
||||
0x0358,SM100SystemConfig,fetched,,cmd
|
||||
0x035A,SM100CircuitConfig,fetched,,cmd
|
||||
0x035C,SM100HeatAssist,fetched,,cmd
|
||||
0x035D,SM100Circuit2Config,fetched,,cmd
|
||||
0x035F,SM100Config1,fetched,,cmd
|
||||
0x0361,SM100Differential,fetched,,cmd
|
||||
0x0362,SM100Monitor,,,cmd
|
||||
0x0363,SM100Monitor2,,,cmd
|
||||
0x0364,SM100Status,,,cmd
|
||||
0x0366,SM100Config,,,cmd
|
||||
0x036A,SM100Status2,,,cmd
|
||||
0x0380,SM100CollectorConfig,fetched,,cmd
|
||||
0x038E,SM100Energy,fetched,,cmd
|
||||
0x0391,SM100Time,fetched,,cmd
|
||||
0x0467,HPSet,,,cmd
|
||||
0x0468,HPSet,,,cmd
|
||||
0x0469,HPSet,,,cmd
|
||||
0x046A,HPSet,,,cmd
|
||||
0x0471,RC300Summer2,,,cmd
|
||||
0x0472,RC300Summer2,,,cmd
|
||||
0x0473,RC300Summer2,,,cmd
|
||||
0x0474,RC300Summer2,,,cmd
|
||||
0x0475,RC300Summer2,,,cmd
|
||||
0x0476,RC300Summer2,,,cmd
|
||||
0x0477,RC300Summer2,,,cmd
|
||||
0x0478,RC300Summer2,,,cmd
|
||||
0x047B,HP2,,,cmd
|
||||
0x0484,HPSilentMode,fetched,,cmd
|
||||
0x0485,HpCooling,fetched,,cmd
|
||||
0x0486,HpInConfig,fetched,,cmd
|
||||
0x0488,HPValve,fetched,,cmd
|
||||
0x048A,HpPool,fetched,,cmd
|
||||
0x048B,HPPumps,fetched,,cmd
|
||||
0x048D,HpPower,fetched,,cmd
|
||||
0x048F,HpTemperatures,,,cmd
|
||||
0x0491,HPAdditionalHeater,fetched,,cmd
|
||||
0x0492,HpHeaterConfig,fetched,,cmd
|
||||
0x0494,UBAEnergySupplied,,,cmd
|
||||
0x0495,UBAInformation,,,cmd
|
||||
0x0499,HPDhwSettings,fetched,,cmd
|
||||
0x049C,HPSettings2,fetched,,cmd
|
||||
0x049D,HPSettings3,fetched,,cmd
|
||||
0x04A2,HpInput,fetched,,cmd
|
||||
0x04A5,HPFan,fetched,,cmd
|
||||
0x04AE,HPEnergy,fetched,,cmd
|
||||
0x04AF,HPMeters,fetched,,cmd
|
||||
0x056B,VentilationMode,fetched,,cmd
|
||||
0x0583,VentilationMonitor,,,cmd
|
||||
0x0585,Blowerspeed,,,cmd
|
||||
0x0587,Bypass,,,cmd
|
||||
0x05BA,HpPoolStatus,fetched,,cmd
|
||||
0x05D9,Airquality,,,cmd
|
||||
0x0772,HIUSettings,,,cmd
|
||||
0x0779,HIUMonitor,,,cmd
|
||||
0x0935,EM100SetMessage,fetched,,cmd
|
||||
0x0936,EM100OutMessage,,,cmd
|
||||
0x0937,EM100TempMessage,,,cmd
|
||||
0x0938,EM100InputMessage,,,cmd
|
||||
0x0939,EM100MonitorMessage,,,cmd
|
||||
0x093A,EM100ConfigMessage,,,cmd
|
||||
0x0998,HPSettings,fetched,,cmd
|
||||
0x0999,HPFunctionTest,fetched,,cmd
|
||||
0x099B,HPFlowTemp,,,cmd
|
||||
0x099C,HPComp,,,cmd
|
||||
0x09A0,HPTemperature,,,cmd
|
||||
|
@@ -5,5 +5,5 @@
|
||||
rm -f dump_entities.csv
|
||||
make clean
|
||||
make ARGS=-DEMSESP_STANDALONE
|
||||
echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv
|
||||
echo "test entity_dump" | ./emsesp | python3 ./scripts/strip_csv.py > dump_entities.csv
|
||||
cat dump_entities.csv
|
||||
10
scripts/dump_telegrams.sh
Executable file
10
scripts/dump_telegrams.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# creates an CSV file called "dump_telegrams.cvs" with all devices and their telegrams
|
||||
# run from top folder like `sh ./scripts/dump_telegrams.sh`
|
||||
rm -f dump_telegrams.csv
|
||||
# make clean
|
||||
# make
|
||||
make ARGS=-DEMSESP_STANDALONE
|
||||
echo "test telegram_dump" | ./emsesp | python3 ./scripts/strip_csv.py > dump_telegrams.csv
|
||||
cat dump_telegrams.csv
|
||||
@@ -1,8 +1,5 @@
|
||||
# strips out lines between two markers
|
||||
# pipe a file into, for example:
|
||||
# make clean; make; echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv
|
||||
# see dump_entities.sh
|
||||
|
||||
# pipe a file into, for example: 'cat x | python3 strip_csv.py'
|
||||
import fileinput
|
||||
with fileinput.input() as f_input:
|
||||
inRecordingMode = False
|
||||
@@ -1202,11 +1202,11 @@ void EMSdevice::getCustomizationEntities(std::vector<std::string> & entity_ids)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
// dumps all entity values in native English
|
||||
// the code is intended to run only once standalone, outside the ESP32 so not optimized for memory efficiency
|
||||
// pipe symbols (|) are escaped so they can be converted to Markdown in the Wiki
|
||||
// format is: device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
void EMSdevice::dump_value_info() {
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (dv.fullname != nullptr) {
|
||||
@@ -1375,6 +1375,16 @@ void EMSdevice::dump_value_info() {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// dumps all telegram details to a new vector
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
void EMSdevice::dump_telegram_info(std::vector<TelegramFunctionDump> & telegram_functions_dump) {
|
||||
for (auto & tf : telegram_functions_) {
|
||||
telegram_functions_dump.emplace_back(tf.telegram_type_id_, tf.telegram_type_name_, tf.fetch_, tf.received_, tf.process_function_ != nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// builds json for a specific device value / entity
|
||||
// cmd is the endpoint or name of the device entity
|
||||
// returns false if failed, otherwise true
|
||||
|
||||
@@ -457,6 +457,21 @@ class EMSdevice {
|
||||
*/
|
||||
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
struct TelegramFunctionDump {
|
||||
uint16_t type_id_;
|
||||
const char * name_;
|
||||
bool fetch_;
|
||||
bool received_;
|
||||
bool cmd_;
|
||||
TelegramFunctionDump(uint16_t type_id, const char * name, bool fetch, bool received, bool cmd)
|
||||
: type_id_(type_id)
|
||||
, name_(name)
|
||||
, fetch_(fetch)
|
||||
, received_(received)
|
||||
, cmd_(cmd) {
|
||||
}
|
||||
};
|
||||
void dump_telegram_info(std::vector<TelegramFunctionDump> & telegram_functions_dump);
|
||||
void dump_value_info();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -332,9 +332,8 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
|
||||
void EMSESP::dump_all_values(uuid::console::Shell & shell) {
|
||||
Serial.println("---- CSV START ----"); // marker use by py script
|
||||
// add header for CSV
|
||||
Serial.print(
|
||||
Serial.println(
|
||||
"device name,device type,product id,shortname,fullname,type [options...] \\| (min/max),uom,writeable,discovery entityid v3.4, discovery entityid");
|
||||
Serial.println();
|
||||
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
// go through each device type so they are sorted
|
||||
@@ -356,12 +355,10 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) {
|
||||
}
|
||||
|
||||
// add the device and print out all the entities
|
||||
|
||||
// if (device.product_id == 69) { // only for testing mixer
|
||||
// for testing the mixer use ... if (device.product_id == 69) {
|
||||
emsdevices.push_back(
|
||||
EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND));
|
||||
emsdevices.back()->dump_value_info();
|
||||
// } // only for testing mixer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,6 +367,80 @@ void EMSESP::dump_all_values(uuid::console::Shell & shell) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Dump all telegrams to Serial out
|
||||
// this is intended to run within the OS with lots of available memory!
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
void EMSESP::dump_all_telegrams(uuid::console::Shell & shell) {
|
||||
std::vector<EMSdevice::TelegramFunctionDump> telegram_functions_dump;
|
||||
|
||||
Serial.println("---- CSV START ----"); // marker use by py script
|
||||
// add header for CSV
|
||||
Serial.println("telegram_type_id,name,is_fetched,is_received,is_cmd");
|
||||
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
// go through each device type so they are sorted
|
||||
for (const auto & device : device_library_) {
|
||||
if (device_class.first == device.device_type) {
|
||||
uint8_t device_id = 0;
|
||||
// Mixer class looks at device_id to determine type and the tag
|
||||
// so fixing to 0x28 which will give all the settings except flowSetTemp
|
||||
if (device.device_type == DeviceType::MIXER) {
|
||||
if (device.flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device.product_id == 160) { // MM100
|
||||
device_id = 0x28; // dhw
|
||||
} else {
|
||||
device_id = 0x20; // hc
|
||||
}
|
||||
} else {
|
||||
device_id = 0x20; // should cover all the other device types
|
||||
}
|
||||
}
|
||||
|
||||
// add the device and print out all the entities
|
||||
emsdevices.push_back(
|
||||
EMSFactory::add(device.device_type, device_id, device.product_id, "1.0", device.name, device.flags, EMSdevice::Brand::NO_BRAND));
|
||||
// add to our vector list
|
||||
emsdevices.back()->dump_telegram_info(telegram_functions_dump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto num_entries = telegram_functions_dump.size();
|
||||
|
||||
// sort based on typeID
|
||||
std::sort(telegram_functions_dump.begin(),
|
||||
telegram_functions_dump.end(),
|
||||
[](const EMSdevice::TelegramFunctionDump & a, const EMSdevice::TelegramFunctionDump & b) { return a.type_id_ < b.type_id_; });
|
||||
|
||||
// Get the iterator for the modified vector
|
||||
auto it = std::unique(telegram_functions_dump.begin(),
|
||||
telegram_functions_dump.end(),
|
||||
[](const EMSdevice::TelegramFunctionDump & a, const EMSdevice::TelegramFunctionDump & b) { return a.type_id_ == b.type_id_; });
|
||||
|
||||
// Use erase method to remove all the duplicates from the vector
|
||||
telegram_functions_dump.erase(it, telegram_functions_dump.end());
|
||||
|
||||
|
||||
for (const auto & tf : telegram_functions_dump) {
|
||||
Serial.printf(Helpers::hextoa(tf.type_id_, true).c_str());
|
||||
Serial.print(',');
|
||||
Serial.print(tf.name_);
|
||||
Serial.print(',');
|
||||
Serial.print(tf.fetch_ ? "fetched" : "");
|
||||
Serial.print(',');
|
||||
Serial.print(tf.received_ ? "received" : "");
|
||||
Serial.print(',');
|
||||
Serial.print(tf.cmd_ ? "cmd" : "");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
Serial.println("---- CSV END ----"); // marker used by py script
|
||||
|
||||
Serial.printf("Total telegrams = %d, total unique telegrams = %d", num_entries, telegram_functions_dump.size());
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
// show EMS device values to the shell console
|
||||
void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
if (emsdevices.empty()) {
|
||||
@@ -647,7 +718,7 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
||||
strlcat(buffer, Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), 768);
|
||||
if (response_id_ != 0) {
|
||||
strlcat(buffer, " ", 768);
|
||||
return;
|
||||
return; // do not delete buffer
|
||||
}
|
||||
JsonDocument doc;
|
||||
char s[10];
|
||||
|
||||
@@ -131,6 +131,7 @@ class EMSESP {
|
||||
static void show_device_values(uuid::console::Shell & shell);
|
||||
static void show_sensor_values(uuid::console::Shell & shell);
|
||||
static void dump_all_values(uuid::console::Shell & shell);
|
||||
static void dump_all_telegrams(uuid::console::Shell & shell);
|
||||
|
||||
static void show_devices(uuid::console::Shell & shell);
|
||||
static void show_ems(uuid::console::Shell & shell);
|
||||
|
||||
@@ -422,12 +422,17 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
// all tests with EMSESP_STANDALONE
|
||||
|
||||
if (command == "entity_dump") {
|
||||
shell.printfln("Adding all devices and entities...");
|
||||
System::test_set_all_active(true);
|
||||
EMSESP::dump_all_values(shell);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "telegram_dump") {
|
||||
System::test_set_all_active(true);
|
||||
EMSESP::dump_all_telegrams(shell);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "modes") {
|
||||
shell.printfln("Testing thermostat modes...");
|
||||
test("general");
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace emsesp {
|
||||
// #define EMSESP_DEBUG_DEFAULT "api_wwmode"
|
||||
// #define EMSESP_DEBUG_DEFAULT "customization"
|
||||
// #define EMSESP_DEBUG_DEFAULT "entity_dump"
|
||||
// #define EMSESP_DEBUG_DEFAULT "telegram_dump"
|
||||
// #define EMSESP_DEBUG_DEFAULT "memory"
|
||||
// #define EMSESP_DEBUG_DEFAULT "coldshot"
|
||||
// #define EMSESP_DEBUG_DEFAULT "custom"
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.0-dev.6"
|
||||
#define EMSESP_APP_VERSION "3.7.0-dev.7"
|
||||
|
||||
Reference in New Issue
Block a user