mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
добавление возможности управления виджетами из модулей
This commit is contained in:
@@ -19,15 +19,16 @@ boolean publish(const String& topic, const String& data);
|
||||
boolean publishData(const String& topic, const String& data);
|
||||
boolean publishChartMqtt(const String& topic, const String& data);
|
||||
boolean publishControl(String id, String topic, String state);
|
||||
boolean publishChart_test(const String& topic, const String& data);
|
||||
boolean publishJsonMqtt(const String& topic, const String& json);
|
||||
boolean publishStatusMqtt(const String& topic, const String& data);
|
||||
boolean publishEvent(const String& topic, const String& data);
|
||||
boolean publishInfo(const String& topic, const String& data);
|
||||
boolean publishAnyJsonKey(const String& topic, const String& key, const String& data);
|
||||
boolean publishAnyJsonKeyMqtt(const String& topic, const String& key, const String& data);
|
||||
bool publishChartFileToMqtt(String path, String id, int maxCount);
|
||||
|
||||
void publishWidgets();
|
||||
void publishState();
|
||||
void publishMainWidgetsValues();
|
||||
void publishSubWidgetsValues();
|
||||
|
||||
void mqttCallback(char* topic, uint8_t* payload, size_t length);
|
||||
void handleMqttStatus(bool send);
|
||||
|
||||
@@ -10,7 +10,7 @@ struct IoTValue {
|
||||
|
||||
class IoTItem {
|
||||
public:
|
||||
IoTItem(const String ¶meters);
|
||||
IoTItem(const String& parameters);
|
||||
virtual ~IoTItem() {}
|
||||
virtual void loop();
|
||||
virtual void doByInterval();
|
||||
@@ -28,7 +28,10 @@ class IoTItem {
|
||||
virtual String getValue();
|
||||
long getInterval();
|
||||
bool isGlobal();
|
||||
|
||||
|
||||
void sendSubWidgetsValues(String& id, String& json);
|
||||
virtual void handleSendSubWidgetsValues();
|
||||
|
||||
void setInterval(long interval);
|
||||
void setIntFromNet(int interval);
|
||||
|
||||
@@ -38,7 +41,7 @@ class IoTItem {
|
||||
|
||||
IoTValue value; // хранение основного значения, которое обновляется из сценария, execute(), loop() или doByInterval()
|
||||
|
||||
//bool iAmDead = false; // признак необходимости удалить объект из базы
|
||||
// bool iAmDead = false; // признак необходимости удалить объект из базы
|
||||
bool iAmLocal = true; // признак того, что айтем был создан локально
|
||||
|
||||
bool enableDoByInt = true;
|
||||
@@ -63,11 +66,11 @@ class IoTItem {
|
||||
protected:
|
||||
bool _needSave = false; // признак необходимости сохранять и загружать значение элемента на flash
|
||||
String _subtype = "";
|
||||
String _id = "errorId"; // если будет попытка создания Item без указания id, то элемент оставит это значение
|
||||
String _id = "errorId"; // если будет попытка создания Item без указания id, то элемент оставит это значение
|
||||
long _interval = 0;
|
||||
int _intFromNet = -2; // количество секунд доверия, пришедших из сети вместе с данными для текущего ИД
|
||||
// -2 - данные не приходили, скорее всего, элемент локальный, доверие есть
|
||||
// -1 - данные приходили и обратный отсчет дошел до нуля, значит доверия нет
|
||||
int _intFromNet = -2; // количество секунд доверия, пришедших из сети вместе с данными для текущего ИД
|
||||
// -2 - данные не приходили, скорее всего, элемент локальный, доверие есть
|
||||
// -1 - данные приходили и обратный отсчет дошел до нуля, значит доверия нет
|
||||
|
||||
float _multiply; // умножаем на значение
|
||||
float _plus; // увеличиваем на значение
|
||||
@@ -80,9 +83,9 @@ class IoTItem {
|
||||
bool _global = false; // характеристика айтема, что ему нужно слать и принимать события из внешнего мира
|
||||
};
|
||||
|
||||
IoTItem* findIoTItem(const String& name); // поиск экземпляра элемента модуля по имени
|
||||
String getItemValue(const String& name); // поиск плюс получение значения
|
||||
bool isItemExist(const String& name); // существует ли айтем
|
||||
IoTItem* findIoTItem(const String& name); // поиск экземпляра элемента модуля по имени
|
||||
String getItemValue(const String& name); // поиск плюс получение значения
|
||||
bool isItemExist(const String& name); // существует ли айтем
|
||||
StaticJsonDocument<JSON_BUFFER_SIZE>* getLocalItemsAsJSON(); // сбор всех локальных значений Items
|
||||
|
||||
IoTItem* createItemFromNet(const String& itemId, const String& value, int interval);
|
||||
|
||||
@@ -113,8 +113,8 @@ build_src_filter =
|
||||
${env:esp8266_4mb_fromitems.build_src_filter}
|
||||
|
||||
[env:esp32_4mb]
|
||||
upload_port = COM8
|
||||
monitor_port = COM8
|
||||
;upload_port = COM13
|
||||
;monitor_port = COM13
|
||||
lib_deps =
|
||||
${common_env_data.lib_deps_external}
|
||||
${env:esp32_4mb_fromitems.lib_deps}
|
||||
|
||||
@@ -17,7 +17,6 @@ void globalVarsSync() {
|
||||
valuesFlashJson = readFile(F("values.json"), 4096);
|
||||
valuesFlashJson.replace("\r\n", "");
|
||||
|
||||
|
||||
mqttPrefix = jsonReadStr(settingsFlashJson, F("mqttPrefix"));
|
||||
mqttRootDevice = mqttPrefix + "/" + chipId;
|
||||
jsonWriteStr_(settingsFlashJson, "root", mqttRootDevice);
|
||||
@@ -27,6 +26,7 @@ void globalVarsSync() {
|
||||
// jsonWriteStr_(ssidListHeapJson, "ssids_", ""); //метка для парсинга удалить
|
||||
}
|
||||
|
||||
//к удалению. не используется
|
||||
String getParamsJson() {
|
||||
String json;
|
||||
serializeJson(*getLocalItemsAsJSON(), json);
|
||||
|
||||
@@ -133,7 +133,8 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) {
|
||||
if (payloadStr.startsWith("HELLO")) {
|
||||
SerialPrint("i", F("MQTT"), F("Full update"));
|
||||
publishWidgets();
|
||||
publishState();
|
||||
publishMainWidgetsValues();
|
||||
publishSubWidgetsValues();
|
||||
|
||||
//обращение к логированию из ядра
|
||||
//отправка данных графиков
|
||||
@@ -189,7 +190,7 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) {
|
||||
// loadScenario();
|
||||
// SerialPrint("i", F("=>MQTT"), F("Scenario received"));
|
||||
// }
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
||||
boolean publish(const String& topic, const String& data) {
|
||||
@@ -223,9 +224,9 @@ boolean publishControl(String id, String topic, String state) {
|
||||
return mqtt.publish(path.c_str(), state.c_str(), false);
|
||||
}
|
||||
|
||||
boolean publishChart_test(const String& topic, const String& data) {
|
||||
boolean publishJsonMqtt(const String& topic, const String& json) {
|
||||
String path = mqttRootDevice + "/" + topic + "/status";
|
||||
return mqtt.publish(path.c_str(), data.c_str(), false);
|
||||
return mqtt.publish(path.c_str(), json.c_str(), false);
|
||||
}
|
||||
|
||||
boolean publishStatusMqtt(const String& topic, const String& data) {
|
||||
@@ -235,7 +236,7 @@ boolean publishStatusMqtt(const String& topic, const String& data) {
|
||||
return mqtt.publish(path.c_str(), json.c_str(), false);
|
||||
}
|
||||
|
||||
boolean publishAnyJsonKey(const String& topic, const String& key, const String& data) {
|
||||
boolean publishAnyJsonKeyMqtt(const String& topic, const String& key, const String& data) {
|
||||
String path = mqttRootDevice + "/" + topic + "/status";
|
||||
String json = "{}";
|
||||
jsonWriteStr(json, key, data);
|
||||
@@ -272,21 +273,35 @@ void publishWidgets() {
|
||||
file.close();
|
||||
}
|
||||
|
||||
void publishState() {
|
||||
String json = getParamsJson();
|
||||
SerialPrint("i", F("DATA"), json);
|
||||
json.replace("{", "");
|
||||
json.replace("}", "");
|
||||
json.replace("\"", "");
|
||||
json += ",";
|
||||
while (json.length() != 0) {
|
||||
String tmp = selectToMarker(json, ",");
|
||||
String topic = selectToMarker(tmp, ":");
|
||||
String state = deleteBeforeDelimiter(tmp, ":");
|
||||
if (topic != "" && state != "") {
|
||||
publishStatusMqtt(topic, state);
|
||||
}
|
||||
json = deleteBeforeDelimiter(json, ",");
|
||||
//устаревшая версия к удалению
|
||||
// void publishMainWidgetsValues() {
|
||||
// String json = getParamsJson();
|
||||
// SerialPrint("i", F("DATA"), json);
|
||||
// json.replace("{", "");
|
||||
// json.replace("}", "");
|
||||
// json.replace("\"", "");
|
||||
// json += ",";
|
||||
// while (json.length() != 0) {
|
||||
// String tmp = selectToMarker(json, ",");
|
||||
// String topic = selectToMarker(tmp, ":");
|
||||
// String state = deleteBeforeDelimiter(tmp, ":");
|
||||
// if (topic != "" && state != "") {
|
||||
// publishStatusMqtt(topic, state);
|
||||
// }
|
||||
// json = deleteBeforeDelimiter(json, ",");
|
||||
// }
|
||||
//}
|
||||
|
||||
//оптимизированная версия
|
||||
void publishMainWidgetsValues() {
|
||||
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
||||
if ((*it)->iAmLocal) publishStatusMqtt((*it)->getID(), (*it)->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void publishSubWidgetsValues() {
|
||||
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
||||
if ((*it)->iAmLocal) (*it)->handleSendSubWidgetsValues();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "ESPConfiguration.h"
|
||||
#include "EventsAndOrders.h"
|
||||
|
||||
//получение параметров в экземпляр класса
|
||||
IoTItem::IoTItem(const String& parameters) {
|
||||
jsonRead(parameters, F("int"), _interval, false);
|
||||
if (_interval <= 0) enableDoByInt = false;
|
||||
@@ -33,11 +32,10 @@ IoTItem::IoTItem(const String& parameters) {
|
||||
setValue(valAsStr, false);
|
||||
|
||||
jsonRead(parameters, F("needSave"), _needSave, false);
|
||||
if (_needSave && jsonRead(valuesFlashJson, _id, valAsStr, false)) // пробуем достать из сохранения значение элемента, если указано, что нужно сохранять
|
||||
if (_needSave && jsonRead(valuesFlashJson, _id, valAsStr, false)) // пробуем достать из сохранения значение элемента, если указано, что нужно сохранять
|
||||
setValue(valAsStr, false);
|
||||
}
|
||||
|
||||
//луп выполняющий переодическое дерганье
|
||||
void IoTItem::loop() {
|
||||
if (enableDoByInt) {
|
||||
currentMillis = millis();
|
||||
@@ -49,7 +47,6 @@ void IoTItem::loop() {
|
||||
}
|
||||
}
|
||||
|
||||
//получить
|
||||
String IoTItem::getValue() {
|
||||
if (value.isDecimal) {
|
||||
return getRoundValue();
|
||||
@@ -59,12 +56,11 @@ String IoTItem::getValue() {
|
||||
|
||||
long IoTItem::getInterval() { return _interval; }
|
||||
|
||||
bool IoTItem::isGlobal() { return _global;}
|
||||
bool IoTItem::isGlobal() { return _global; }
|
||||
|
||||
//определяем тип прилетевшей величины
|
||||
void IoTItem::setValue(const String& valStr, bool genEvent) {
|
||||
value.isDecimal = isDigitDotCommaStr(valStr);
|
||||
|
||||
|
||||
if (value.isDecimal) {
|
||||
value.valD = valStr.toFloat();
|
||||
} else {
|
||||
@@ -73,10 +69,9 @@ void IoTItem::setValue(const String& valStr, bool genEvent) {
|
||||
setValue(value, genEvent);
|
||||
}
|
||||
|
||||
//
|
||||
void IoTItem::setValue(const IoTValue& Value, bool genEvent) {
|
||||
value = Value;
|
||||
|
||||
|
||||
if (value.isDecimal) {
|
||||
regEvent(value.valD, "", false, genEvent);
|
||||
} else {
|
||||
@@ -84,6 +79,15 @@ void IoTItem::setValue(const IoTValue& Value, bool genEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
//метод отправки из модуля дополнительных json полей виджета в приложение и веб интерфейс, необходимый для изменения виджетов "на лету" из модуля
|
||||
void IoTItem::sendSubWidgetsValues(String& id, String& json) {
|
||||
publishJsonMqtt(id, json);
|
||||
// to do publishJsonWs
|
||||
}
|
||||
|
||||
//метод который нужен что бы из ядра заставить модуль отправить его дополнительные json поля виджета
|
||||
void IoTItem::handleSendSubWidgetsValues() {}
|
||||
|
||||
//когда событие случилось
|
||||
void IoTItem::regEvent(const String& value, const String& consoleInfo, bool error, bool genEvent) {
|
||||
if (_needSave) {
|
||||
@@ -92,22 +96,22 @@ void IoTItem::regEvent(const String& value, const String& consoleInfo, bool erro
|
||||
}
|
||||
publishStatusMqtt(_id, value);
|
||||
publishStatusWs(_id, value);
|
||||
//SerialPrint("i", "Sensor", consoleInfo + " '" + _id + "' data: " + value + "'");
|
||||
|
||||
// SerialPrint("i", "Sensor", consoleInfo + " '" + _id + "' data: " + value + "'");
|
||||
|
||||
if (genEvent) {
|
||||
generateEvent(_id, value);
|
||||
|
||||
// распространяем событие через хуки
|
||||
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
||||
(*it)->onRegEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
//отправка события другим устройствам в сети если не было ошибки==============================
|
||||
if (jsonReadBool(settingsFlashJson, "mqttin") && _global && !error) {
|
||||
String json = "{}";
|
||||
jsonWriteStr_(json, "id", _id);
|
||||
jsonWriteStr_(json, "val", value);
|
||||
jsonWriteInt_(json, "int", _interval/1000);
|
||||
jsonWriteInt_(json, "int", _interval / 1000);
|
||||
publishEvent(_id, json);
|
||||
SerialPrint("i", F("<=MQTT"), "Broadcast event: " + json);
|
||||
}
|
||||
@@ -119,7 +123,7 @@ String IoTItem::getRoundValue() {
|
||||
if (_round >= 0 && _round <= 6) {
|
||||
int sot = _round ? pow(10, (int)_round) : 1;
|
||||
value.valD = round(value.valD * sot) / sot;
|
||||
|
||||
|
||||
char buf[15];
|
||||
sprintf(buf, ("%1." + (String)_round + "f").c_str(), value.valD);
|
||||
return (String)buf;
|
||||
@@ -154,7 +158,7 @@ void IoTItem::getNetEvent(String& event) {
|
||||
event = "{}";
|
||||
jsonWriteStr_(event, "id", _id);
|
||||
jsonWriteStr_(event, "val", getValue());
|
||||
jsonWriteInt_(event, "int", _interval/1000);
|
||||
jsonWriteInt_(event, "int", _interval / 1000);
|
||||
}
|
||||
|
||||
void IoTItem::setIntFromNet(int interval) {
|
||||
@@ -199,7 +203,6 @@ IoTGpio* IoTItem::getGpioDriver() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
//сетевое общение====================================================================================================================================
|
||||
|
||||
// externalVariable::externalVariable(const String& parameters) : IoTItem(parameters) {
|
||||
@@ -256,14 +259,14 @@ IoTItem* createItemFromNet(const String& itemId, const String& value, int interv
|
||||
jsonStr += "\",\"int\":";
|
||||
jsonStr += interval;
|
||||
jsonStr += "}";
|
||||
|
||||
|
||||
return createItemFromNet(jsonStr);
|
||||
}
|
||||
|
||||
// создаем временную копию элемента из сети на основе события
|
||||
IoTItem* createItemFromNet(const String& msgFromNet) {
|
||||
IoTItem *tmpp = new IoTItem(msgFromNet);
|
||||
if (tmpp->getInterval()) tmpp->setIntFromNet(tmpp->getInterval()/1000 + 5);
|
||||
IoTItem* tmpp = new IoTItem(msgFromNet);
|
||||
if (tmpp->getInterval()) tmpp->setIntFromNet(tmpp->getInterval() / 1000 + 5);
|
||||
tmpp->iAmLocal = false;
|
||||
IoTItems.push_back(tmpp);
|
||||
generateEvent(tmpp->getID(), tmpp->getValue());
|
||||
@@ -271,7 +274,7 @@ IoTItem* createItemFromNet(const String& msgFromNet) {
|
||||
}
|
||||
|
||||
void analyzeMsgFromNet(const String& msg, String altId) {
|
||||
if (!jsonRead(msg, F("id"), altId, altId == "") && altId == "") return; // ничего не предпринимаем, если ошибка и altId = "", вообще данная конструкция нужна для совместимости с форматом данных 3 версией
|
||||
if (!jsonRead(msg, F("id"), altId, altId == "") && altId == "") return; // ничего не предпринимаем, если ошибка и altId = "", вообще данная конструкция нужна для совместимости с форматом данных 3 версией
|
||||
IoTItem* itemExist = findIoTItem(altId);
|
||||
if (itemExist) {
|
||||
String valAsStr = msg;
|
||||
@@ -279,9 +282,9 @@ void analyzeMsgFromNet(const String& msg, String altId) {
|
||||
long interval = 0;
|
||||
jsonRead(msg, F("int"), interval, false);
|
||||
|
||||
itemExist->setInterval(interval); // устанавливаем такой же интервал как на источнике события
|
||||
itemExist->setValue(valAsStr, false); // только регистрируем изменения в интерфейсе без создания цикла сетевых событий
|
||||
if (interval) itemExist->setIntFromNet(interval+5); // если пришедший интервал =0, значит не нужно контролировать доверие, иначе даем фору в 5 сек
|
||||
itemExist->setInterval(interval); // устанавливаем такой же интервал как на источнике события
|
||||
itemExist->setValue(valAsStr, false); // только регистрируем изменения в интерфейсе без создания цикла сетевых событий
|
||||
if (interval) itemExist->setIntFromNet(interval + 5); // если пришедший интервал =0, значит не нужно контролировать доверие, иначе даем фору в 5 сек
|
||||
generateEvent(altId, valAsStr);
|
||||
} else {
|
||||
// временно зафиксируем данные в базе, если локально элемент отсутствует
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Arduino.h"
|
||||
#include "MySensorsGate.h"
|
||||
|
||||
#ifdef MYSENSORS
|
||||
// callback библиотеки mysensors
|
||||
void receive(const MyMessage& message) {
|
||||
String inMsg = String(message.getSender()) + "," + // node-id
|
||||
@@ -48,6 +49,7 @@ String parseToString(const MyMessage& message) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
class MySensorsGate : public IoTItem {
|
||||
private:
|
||||
public:
|
||||
@@ -344,20 +346,57 @@ class MySensorsGate : public IoTItem {
|
||||
|
||||
class MySensorsNode : public IoTItem {
|
||||
private:
|
||||
String id;
|
||||
int _minutesPassed = 0;
|
||||
String json = "{}";
|
||||
bool dataFromNode = false;
|
||||
|
||||
public:
|
||||
MySensorsNode(String parameters) : IoTItem(parameters) {
|
||||
SerialPrint("i", "MySensors", "Node initialized");
|
||||
jsonRead(parameters, F("id"), id);
|
||||
dataFromNode = false;
|
||||
}
|
||||
|
||||
void setValue(const IoTValue& Value, bool genEvent = true) {
|
||||
value = Value;
|
||||
regEvent(value.valD, "MySensorsNode", false, genEvent);
|
||||
_minutesPassed = 0;
|
||||
prevMillis = millis();
|
||||
dataFromNode = true;
|
||||
setNewWidgetAttributes();
|
||||
}
|
||||
|
||||
void doByInterval() {
|
||||
_minutesPassed++;
|
||||
setNewWidgetAttributes();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (difference > 60000) {
|
||||
prevMillis = millis();
|
||||
this->doByInterval();
|
||||
}
|
||||
}
|
||||
|
||||
void handleSendSubWidgetsValues() {
|
||||
setNewWidgetAttributes();
|
||||
}
|
||||
|
||||
void setNewWidgetAttributes() {
|
||||
if (dataFromNode) {
|
||||
jsonWriteStr(json, "info", String(_minutesPassed) + " min");
|
||||
if (_minutesPassed >= 60) {
|
||||
jsonWriteStr(json, "color", "orange"); //сделаем виджет оранжевым когда более 60 минут нода не выходила на связь
|
||||
} else if (_minutesPassed >= 120) {
|
||||
jsonWriteStr(json, "color", "red"); //сделаем виджет красным когда более 120 минут нода не выходила на связь
|
||||
}
|
||||
} else {
|
||||
jsonWriteStr(json, "info", "awaiting");
|
||||
}
|
||||
sendSubWidgetsValues(id, json);
|
||||
}
|
||||
|
||||
~MySensorsNode(){};
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
#pragma once
|
||||
#include "Const.h"
|
||||
#ifdef MYSENSORS
|
||||
|
||||
/*
|
||||
* DESCRIPTION
|
||||
* The ESP32 gateway sends data received from sensors to the WiFi link.
|
||||
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
|
||||
* ----------- PINOUT --------------
|
||||
* | IO | RF24 | RFM69 | RFM95 |
|
||||
|------|------|-------|-------|
|
||||
| MOSI | 23 | 23 | 23 |
|
||||
| MISO | 19 | 19 | 19 |
|
||||
| SCK | 18 | 18 | 18 |
|
||||
| CSN | 5 | 5 | 5 |
|
||||
| CE | 17 | - | - |
|
||||
| RST | - | 17 | 17 |
|
||||
| IRQ | 16* | 16 | 16 |
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
//#define MY_DEBUG
|
||||
@@ -7,7 +25,6 @@
|
||||
//#define MY_RF24_CS_PIN 9
|
||||
|
||||
// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
|
||||
|
||||
#define MY_BAUD_RATE 115200
|
||||
|
||||
// Enables and select radio type (if attached)
|
||||
@@ -22,7 +39,7 @@
|
||||
|
||||
// Set LOW transmit power level as default, if you have an amplified NRF-module and
|
||||
// power your radio separately with a good regulator you can turn up PA level.
|
||||
#define MY_RF24_PA_LEVEL RF24_PA_LOW
|
||||
#define MY_RF24_PA_LEVEL RF24_PA_MAX
|
||||
|
||||
// используем гейт в режиме serial хотя нам этот режим не нужен, поэтому в библиотеки отключаем MY_SERIALDEVICE.print
|
||||
// в файле MyGatewayTransportSerial.cpp в строчке 35
|
||||
@@ -32,4 +49,6 @@
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
extern String parseToString(const MyMessage& message);
|
||||
extern String parseToString(const MyMessage& message);
|
||||
|
||||
#endif
|
||||
@@ -32,17 +32,16 @@
|
||||
"moduleVersion": "1.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
"esp8266_4mb": 0
|
||||
},
|
||||
"title": "My Sensors Gate",
|
||||
"moduleDesc": "",
|
||||
"title": "Гейт MySensors",
|
||||
"moduleDesc": "Гейт состоит из esp32 и подключенному к нему радиомодулю NRF24L01. Вместе в связке они образуют гейт, способный принимать данные датчиков. Датчики способны работать до нескольких лет на батарейках",
|
||||
"retInfo": "",
|
||||
"propInfo": {
|
||||
"int": "",
|
||||
"pin": ""
|
||||
"id": "Для настройки следует выбрать один раз MySensorsGate и выбрать сколько необходимо раз MySensorsNode. Вместо ID нужно указать ID ноды дефис ID значения данной ноды. Например 100-1 - будет значить нода с ID 100 величина 1."
|
||||
}
|
||||
},
|
||||
"defActive": true,
|
||||
"defActive": false,
|
||||
"usedLibs": {
|
||||
"esp32_4mb": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user