mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-05-27 21:29:21 +03:00
new Modules from Chat
This commit is contained in:
579
src/modules/sensors/Presence/Presence.cpp
Normal file
579
src/modules/sensors/Presence/Presence.cpp
Normal file
@@ -0,0 +1,579 @@
|
||||
// Licensed under the Cooperative Non-Violent Public License (CNPL)
|
||||
// See: https://github.com/CHE77/IoTManager-Modules/blob/main/LICENSE
|
||||
|
||||
|
||||
#define MQTT_MAX_PACKET_SIZE 512 // или 1024
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include <math.h>
|
||||
#define EARTH_RADIUS_KM 6371.0 // Радиус Земли в километрах
|
||||
|
||||
#include "NTP.h"
|
||||
#include <PubSubClient.h> // чтобы знать тип
|
||||
extern PubSubClient mqtt; // объявляем глобальный объект
|
||||
|
||||
class Presence : public IoTItem
|
||||
{
|
||||
private:
|
||||
String _MAC;
|
||||
String _parameter;
|
||||
IoTItem *tmp;
|
||||
int _minutesPassed = 0;
|
||||
String json = "{}";
|
||||
int orange = 0;
|
||||
int red = 0;
|
||||
int offline = 0;
|
||||
bool dataFromNode = false;
|
||||
String _topic = "";
|
||||
bool _isJson;
|
||||
bool _ticker = true;
|
||||
bool _debug = false;
|
||||
bool sendOk = false;
|
||||
float _lat_A = 0;
|
||||
float _lon_A = 0;
|
||||
|
||||
|
||||
struct PresenceData
|
||||
{
|
||||
String chargingState;
|
||||
String plugState;
|
||||
String connectedWifi;
|
||||
String geoLocation;
|
||||
float lat = 0.0;
|
||||
float lon = 0.0;
|
||||
unsigned long geoTimestamp = 0;
|
||||
String geoTime;
|
||||
String deviceName;
|
||||
int batteryLevel = -1;
|
||||
unsigned long currentTimestamp = 0;
|
||||
String currentTime;
|
||||
unsigned long nextScheduledTimestamp = 0;
|
||||
String nextScheduledTime;
|
||||
unsigned long nextAlarmclockTimestamp = 0;
|
||||
String nextAlarmclockTime;
|
||||
std::vector<String> conditionContent;
|
||||
String conditionContentString;
|
||||
};
|
||||
PresenceData pdata;
|
||||
|
||||
public:
|
||||
Presence(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
_parameter = jsonReadStr(parameters, "parameter");
|
||||
jsonRead(parameters, F("orange"), orange);
|
||||
jsonRead(parameters, F("red"), red);
|
||||
jsonRead(parameters, F("offline"), offline);
|
||||
_topic = jsonReadStr(parameters, "topic");
|
||||
if (_debug)
|
||||
SerialPrint("i", "Presence topic : ", _topic);
|
||||
jsonRead(parameters, F("isJson"), _isJson);
|
||||
// jsonRead(parameters, "addPrefix", _addPrefix);
|
||||
jsonRead(parameters, F("Lat. A"), _lat_A);
|
||||
jsonRead(parameters, F("Long. A"), _lon_A);
|
||||
jsonRead(parameters, F("ticker"), _ticker);
|
||||
jsonRead(parameters, F("debug"), _debug);
|
||||
dataFromNode = false;
|
||||
if (mqttIsConnect())
|
||||
{
|
||||
mqtt.setBufferSize(512);
|
||||
sendOk = true;
|
||||
mqttSubscribeExternal(_topic);
|
||||
}
|
||||
}
|
||||
|
||||
char *TimeToString(unsigned long t)
|
||||
{
|
||||
static char str[12];
|
||||
long h = t / 3600;
|
||||
t = t % 3600;
|
||||
int m = t / 60;
|
||||
int s = t % 60;
|
||||
sprintf(str, "%02ld:%02d:%02d", h, m, s);
|
||||
return str;
|
||||
}
|
||||
|
||||
double toRadians(double degrees)
|
||||
{
|
||||
return degrees * M_PI / 180.0;
|
||||
}
|
||||
|
||||
double toDegrees(double radians)
|
||||
{
|
||||
return radians * 180.0 / M_PI;
|
||||
}
|
||||
|
||||
// Возвращает пеленг в градусах: от 0 до 360
|
||||
double calculateInitialBearing(double lat1, double lon1, double lat2, double lon2)
|
||||
{
|
||||
lat1 = toRadians(lat1);
|
||||
lon1 = toRadians(lon1);
|
||||
lat2 = toRadians(lat2);
|
||||
lon2 = toRadians(lon2);
|
||||
|
||||
double deltaLon = lon2 - lon1;
|
||||
|
||||
double y = sin(deltaLon) * cos(lat2);
|
||||
double x = cos(lat1) * sin(lat2) -
|
||||
sin(lat1) * cos(lat2) * cos(deltaLon);
|
||||
|
||||
double bearing = atan2(y, x);
|
||||
bearing = toDegrees(bearing);
|
||||
|
||||
// Приводим к диапазону 0–360
|
||||
return fmod((bearing + 360.0), 360.0);
|
||||
}
|
||||
|
||||
// lat и lon — в градусах
|
||||
double haversineDistance(double lat1, double lon1, double lat2, double lon2)
|
||||
{
|
||||
double dLat = toRadians(lat2 - lat1);
|
||||
double dLon = toRadians(lon2 - lon1);
|
||||
|
||||
lat1 = toRadians(lat1);
|
||||
lat2 = toRadians(lat2);
|
||||
|
||||
double a = sin(dLat / 2) * sin(dLat / 2) +
|
||||
cos(lat1) * cos(lat2) *
|
||||
sin(dLon / 2) * sin(dLon / 2);
|
||||
|
||||
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
||||
|
||||
return EARTH_RADIUS_KM * c * 1000.0;
|
||||
}
|
||||
|
||||
void onMqttRecive(String &topic, String &msg)
|
||||
{
|
||||
Serial.printf("[MQTT] Topic: %s\nPayload size: %d bytes\n", topic.c_str(), msg.length());
|
||||
msg.trim(); // Убираем пробелы и переносы строк
|
||||
|
||||
if (msg.indexOf("HELLO") == -1)
|
||||
{
|
||||
if (_debug)
|
||||
SerialPrint("i", "Presence HELLO", " _1d: " + _id + " topic: " + topic + " msg: " + msg);
|
||||
String dev = selectToMarkerLast(topic, "/");
|
||||
dev.toUpperCase();
|
||||
dev.replace(":", "");
|
||||
if (_topic != topic)
|
||||
{
|
||||
if (_debug)
|
||||
{
|
||||
SerialPrint("i", "Presence", topic + " not equal: " + _topic + " msg: " + msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isJson)
|
||||
{
|
||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
DeserializationError err = deserializeJson(doc, msg);
|
||||
|
||||
if (err)
|
||||
{
|
||||
SerialPrint("E", F("Presence"), err.f_str());
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
if (obj.containsKey("chargingState"))
|
||||
{
|
||||
pdata.chargingState = obj["chargingState"].as<String>();
|
||||
}
|
||||
if (obj.containsKey("plugState"))
|
||||
{
|
||||
pdata.plugState = obj["plugState"].as<String>();
|
||||
}
|
||||
|
||||
if (obj.containsKey("connectedWifi"))
|
||||
pdata.connectedWifi = obj["connectedWifi"].as<String>();
|
||||
if (obj.containsKey("geoLocation"))
|
||||
{
|
||||
pdata.geoLocation = obj["geoLocation"].as<String>();
|
||||
// Разбор геолокации после получения
|
||||
parseGeo(pdata.geoLocation);
|
||||
pdata.geoTime = getDateTimeDotFormatedFromUnix(pdata.geoTimestamp);
|
||||
SerialPrint("i", "Presence", "GeoTime : " + pdata.geoTime);
|
||||
}
|
||||
|
||||
if (obj.containsKey("deviceName"))
|
||||
pdata.deviceName = obj["deviceName"].as<String>();
|
||||
if (obj.containsKey("batteryLevel"))
|
||||
pdata.batteryLevel = obj["batteryLevel"].as<int>();
|
||||
if (obj.containsKey("currentTimestamp"))
|
||||
{
|
||||
pdata.currentTimestamp = obj["currentTimestamp"].as<unsigned long>();
|
||||
pdata.currentTime = getDateTimeDotFormatedFromUnix(pdata.currentTimestamp);
|
||||
}
|
||||
|
||||
if (obj.containsKey("nextScheduledTimestamp"))
|
||||
{
|
||||
pdata.nextScheduledTimestamp = obj["nextScheduledTimestamp"].as<unsigned long>();
|
||||
pdata.nextScheduledTime = getDateTimeDotFormatedFromUnix(pdata.nextScheduledTimestamp);
|
||||
}
|
||||
|
||||
if (obj.containsKey("nextAlarmclockTimestamp"))
|
||||
{
|
||||
pdata.nextAlarmclockTimestamp = obj["nextAlarmclockTimestamp"].as<unsigned long>();
|
||||
pdata.nextAlarmclockTime = getDateTimeDotFormatedFromUnix(pdata.nextAlarmclockTimestamp);
|
||||
}
|
||||
|
||||
if (obj.containsKey("conditionContent"))
|
||||
{
|
||||
JsonArray arr = obj["conditionContent"].as<JsonArray>();
|
||||
pdata.conditionContent.clear();
|
||||
for (String s : arr)
|
||||
{
|
||||
pdata.conditionContent.push_back(s);
|
||||
}
|
||||
|
||||
String conditionStr;
|
||||
for (size_t i = 0; i < pdata.conditionContent.size(); ++i)
|
||||
{
|
||||
conditionStr += pdata.conditionContent[i];
|
||||
if (i < pdata.conditionContent.size() - 1)
|
||||
conditionStr += ", ";
|
||||
}
|
||||
pdata.conditionContentString = conditionStr;
|
||||
}
|
||||
|
||||
dataFromNode = true;
|
||||
_minutesPassed = 0;
|
||||
|
||||
String sensorVal;
|
||||
|
||||
if (_parameter == "latitude")
|
||||
{
|
||||
value.isDecimal = true;
|
||||
value.valD = pdata.lat;
|
||||
}
|
||||
else if (_parameter == "longitude")
|
||||
{
|
||||
value.isDecimal = true;
|
||||
value.valD = pdata.lon;
|
||||
}
|
||||
else if (_parameter == "azimuth")
|
||||
{
|
||||
value.isDecimal = true;
|
||||
value.valD = calculateInitialBearing(_lat_A, _lon_A, pdata.lat, pdata.lon);
|
||||
}
|
||||
else if (_parameter == "distance")
|
||||
{
|
||||
value.isDecimal = true;
|
||||
value.valD = haversineDistance(_lat_A, _lon_A, pdata.lat, pdata.lon);
|
||||
}
|
||||
else if (_parameter == "batteryLevel")
|
||||
{
|
||||
value.isDecimal = true;
|
||||
value.valD = pdata.batteryLevel;
|
||||
}
|
||||
else if (_parameter == "geoTime")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.geoTime;
|
||||
}
|
||||
else if (_parameter == "geoTimestamp")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.geoTimestamp;
|
||||
}
|
||||
else if (_parameter == "currentTime")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.currentTime;
|
||||
}
|
||||
else if (_parameter == "nextScheduledTime")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.nextScheduledTime;
|
||||
}
|
||||
else if (_parameter == "nextAlarmclockTime")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.nextAlarmclockTime;
|
||||
}
|
||||
else if (_parameter == "conditionContent")
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = pdata.conditionContentString;
|
||||
}
|
||||
else if (obj.containsKey(_parameter) && obj[_parameter].is<const char *>())
|
||||
{
|
||||
sensorVal = obj[_parameter].as<const char *>();
|
||||
value.isDecimal = false;
|
||||
value.valS = sensorVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.isDecimal = false;
|
||||
value.valS = "parameter mismatch";
|
||||
}
|
||||
|
||||
if (value.isDecimal)
|
||||
{
|
||||
regEvent(value.valD, F("Presence"), _debug, _ticker);
|
||||
}
|
||||
else
|
||||
{
|
||||
regEvent(value.valS, F("Presence"), _debug, _ticker);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug)
|
||||
{
|
||||
SerialPrint("i", "Presence", "Received MAC: " + dev + " val=" + msg);
|
||||
}
|
||||
dataFromNode = true;
|
||||
_minutesPassed = 0;
|
||||
setValue(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
IoTValue valTmp;
|
||||
|
||||
if (command == "latitude")
|
||||
{
|
||||
valTmp.isDecimal = true;
|
||||
valTmp.valD = pdata.lat;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "longitude")
|
||||
{
|
||||
valTmp.isDecimal = true;
|
||||
valTmp.valD = pdata.lon;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "azimuth")
|
||||
{
|
||||
if (param.size() == 2 && param[0].isDecimal && param[1].isDecimal)
|
||||
{
|
||||
valTmp.isDecimal = true;
|
||||
valTmp.valD = calculateInitialBearing(param[0].valD, param[1].valD, pdata.lat, pdata.lon);
|
||||
}
|
||||
else
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = "wrong parameters";
|
||||
}
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "distance")
|
||||
{
|
||||
if (param.size() == 2 && param[1].isDecimal && param[1].isDecimal)
|
||||
{
|
||||
valTmp.isDecimal = true;
|
||||
valTmp.valD = haversineDistance(param[0].valD, param[1].valD, pdata.lat, pdata.lon);
|
||||
}
|
||||
else
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = "wrong parameters";
|
||||
}
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "batteryLevel")
|
||||
{
|
||||
valTmp.isDecimal = true;
|
||||
valTmp.valD = pdata.batteryLevel;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "geoTime")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.geoTime;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "geoTimestamp")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.geoTimestamp;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "currentTime")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.currentTime;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "currentTimestamp")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.currentTimestamp;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "nextScheduledTime")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.nextScheduledTime;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "nextScheduledTimestamp")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.nextScheduledTimestamp;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "nextAlarmclockTime")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.nextAlarmclockTime;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "nextAlarmclockTimestamp")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.nextAlarmclockTimestamp;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "conditionContent")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.conditionContentString;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "chargingState")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.chargingState;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "plugState")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.plugState;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "connectedWifi")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.connectedWifi;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "deviceName")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.deviceName;
|
||||
return valTmp;
|
||||
}
|
||||
else if (command == "geoLocation")
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = pdata.geoLocation;
|
||||
return valTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
valTmp.isDecimal = false;
|
||||
valTmp.valS = "wrong command";
|
||||
return valTmp;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
String getMqttExterSub()
|
||||
{
|
||||
return _topic;
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
_minutesPassed++;
|
||||
setNewWidgetAttributes();
|
||||
if (mqttIsConnect() && !sendOk)
|
||||
{
|
||||
mqtt.setBufferSize(512); // ← ДО подписи
|
||||
sendOk = true;
|
||||
mqttSubscribeExternal(_topic);
|
||||
}
|
||||
}
|
||||
void onMqttWsAppConnectEvent()
|
||||
{
|
||||
setNewWidgetAttributes();
|
||||
}
|
||||
|
||||
void setNewWidgetAttributes()
|
||||
{
|
||||
|
||||
jsonWriteStr(json, F("info"), prettyMinutsTimeout(_minutesPassed));
|
||||
if (dataFromNode)
|
||||
{
|
||||
if (orange != 0 && red != 0 && offline != 0)
|
||||
{
|
||||
if (_minutesPassed < orange)
|
||||
{
|
||||
jsonWriteStr(json, F("color"), "");
|
||||
}
|
||||
if (_minutesPassed >= orange && _minutesPassed < red)
|
||||
{
|
||||
jsonWriteStr(json, F("color"), F("orange")); // сделаем виджет оранжевым
|
||||
}
|
||||
if (_minutesPassed >= red && _minutesPassed < offline)
|
||||
{
|
||||
jsonWriteStr(json, F("color"), F("red")); // сделаем виджет красным
|
||||
}
|
||||
if (_minutesPassed >= offline)
|
||||
{
|
||||
jsonWriteStr(json, F("info"), F("offline"));
|
||||
SerialPrint("i", "Presence", _id + " - offline");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonWriteStr(json, F("info"), F("awaiting"));
|
||||
}
|
||||
// SerialPrint("i", "JSON", json);
|
||||
sendSubWidgetsValues(_id, json);
|
||||
}
|
||||
|
||||
void parseGeo(const String &geo)
|
||||
{
|
||||
if (!geo.startsWith("geo:"))
|
||||
return;
|
||||
|
||||
int commaIndex = geo.indexOf(',', 4);
|
||||
int semicolonIndex = geo.indexOf(';', commaIndex);
|
||||
|
||||
if (commaIndex == -1 || semicolonIndex == -1)
|
||||
return;
|
||||
|
||||
String latStr = geo.substring(4, commaIndex);
|
||||
String lonStr = geo.substring(commaIndex + 1, semicolonIndex);
|
||||
|
||||
// timestamp
|
||||
String tsTag = "timestamp=";
|
||||
int tsIndex = geo.indexOf(tsTag);
|
||||
String tsStr = (tsIndex > 0) ? geo.substring(tsIndex + tsTag.length()) : "";
|
||||
|
||||
pdata.lat = latStr.toFloat();
|
||||
pdata.lon = lonStr.toFloat();
|
||||
pdata.geoTimestamp = tsStr.toInt();
|
||||
|
||||
if (_debug)
|
||||
{
|
||||
SerialPrint("i", "Presence", "Lat: " + String(pdata.lat, 6));
|
||||
SerialPrint("i", "Presence", "Lon: " + String(pdata.lon, 6));
|
||||
SerialPrint("i", "Presence", "Geo timestamp: " + String(pdata.geoTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
~Presence() {};
|
||||
};
|
||||
|
||||
void *getAPI_Presence(String subtype, String param)
|
||||
{
|
||||
if (subtype == F("Presence"))
|
||||
{
|
||||
return new Presence(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
372
src/modules/sensors/Presence/export.json
Normal file
372
src/modules/sensors/Presence/export.json
Normal file
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"mark": "iotm",
|
||||
"config": [
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutDistance",
|
||||
"needSave": 0,
|
||||
"widget": "anydataKm",
|
||||
"page": "Output",
|
||||
"descr": "Distance",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "",
|
||||
"plus": 0,
|
||||
"multiply": "0.001",
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutAzimuth",
|
||||
"needSave": 0,
|
||||
"widget": "anydataСorner",
|
||||
"page": "Output",
|
||||
"descr": "Azimuth",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Presence",
|
||||
"id": "presence",
|
||||
"widget": "anydataM",
|
||||
"page": "Presence",
|
||||
"descr": "Distance",
|
||||
"Lat. A": "47.0159",
|
||||
"Long. A": "28.8448",
|
||||
"parameter": "distance",
|
||||
"topic": "/myPhone/status",
|
||||
"isJson": 1,
|
||||
"round": "0",
|
||||
"orange": 60,
|
||||
"red": 120,
|
||||
"offline": 180,
|
||||
"int": 15,
|
||||
"ticker": 1,
|
||||
"debug": 1,
|
||||
"moduleName": "Presence"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutLat",
|
||||
"needSave": 0,
|
||||
"widget": "anydataСorner",
|
||||
"page": "Output",
|
||||
"descr": "Latitude",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": "1",
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutLong",
|
||||
"needSave": 0,
|
||||
"widget": "anydataСorner",
|
||||
"page": "Output",
|
||||
"descr": "Longitude",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": "1",
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutbatteryLevel",
|
||||
"needSave": 0,
|
||||
"widget": "anydataHum",
|
||||
"page": "Output",
|
||||
"descr": "batteryLevel",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutgeoTime",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "geoTime",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutgeoTimestamp",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "geoTimestamp",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutcurrentTime",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "currentTime",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutcurrentTimestamp",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "currentTimestamp",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutnextScheduledTime",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "nextScheduledTime",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutnextScheduledTimestamp",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "nextScheduledTimestamp",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutnextAlarmclockTime",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "nextAlarmclockTime",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutnextAlarmclockTimestamp",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "nextAlarmclockTimestamp",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutchargingState",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "chargingState",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutplugState",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "plugState",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutconnectedWifi",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "connectedWifi",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutdeviceName",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "deviceName",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutgeoLocation",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "geoLocation",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"type": "Reading",
|
||||
"subtype": "Variable",
|
||||
"id": "voutconditionContent",
|
||||
"needSave": 0,
|
||||
"widget": "anydataDef",
|
||||
"page": "Output",
|
||||
"descr": "conditionContent",
|
||||
"int": "0",
|
||||
"val": "0.0",
|
||||
"map": "1024,1024,1,100",
|
||||
"plus": 0,
|
||||
"multiply": 1,
|
||||
"round": 0,
|
||||
"moduleName": "Variable"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
scenario=> if presence then {
|
||||
voutDistance = presence.distance(47.0159,28.8448)
|
||||
voutAzimuth = presence.azimuth(47.0159,28.8448)
|
||||
voutLat = presence.latitude()
|
||||
voutLong = presence.longitude()
|
||||
voutbatteryLevel = presence.batteryLevel()
|
||||
voutgeoTime = presence.geoTime()
|
||||
voutgeoTimestamp = presence.geoTimestamp()
|
||||
voutcurrentTime = presence.currentTime()
|
||||
voutcurrentTimestamp = presence.currentTimestamp()
|
||||
voutnextScheduledTime = presence.nextScheduledTime()
|
||||
voutnextScheduledTimestamp = presence.nextScheduledTimestamp()
|
||||
voutnextAlarmclockTime = presence.nextAlarmclockTime()
|
||||
voutnextAlarmclockTimestamp = presence.nextAlarmclockTimestamp()
|
||||
voutchargingState = presence.chargingState()
|
||||
voutplugState = presence.plugState()
|
||||
voutconnectedWifi = presence.connectedWifi()
|
||||
voutdeviceName = presence.deviceName()
|
||||
voutgeoLocation = presence.geoLocation()
|
||||
voutconditionContent = presence.conditionContent()
|
||||
}
|
||||
199
src/modules/sensors/Presence/modinfo.json
Normal file
199
src/modules/sensors/Presence/modinfo.json
Normal file
@@ -0,0 +1,199 @@
|
||||
{
|
||||
"menuSection": "sensors",
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "MQTT Presence Subscriber",
|
||||
"type": "Reading",
|
||||
"subtype": "Presence",
|
||||
"id": "presence",
|
||||
"widget": "anydataM",
|
||||
"page": "Presence",
|
||||
"descr": "Дистанция",
|
||||
"Lat. A": "47.0159",
|
||||
"Long. A": "28.8448",
|
||||
"parameter": "distance",
|
||||
"topic": "/myPhone/status",
|
||||
"isJson": 1,
|
||||
"round": "0",
|
||||
"orange": 60,
|
||||
"red": 120,
|
||||
"offline": 180,
|
||||
"int": 15,
|
||||
"ticker": 1,
|
||||
"debug": 1
|
||||
}
|
||||
],
|
||||
"about": {
|
||||
"authorName": "Alex",
|
||||
"authorContact": "https://t.me/cmche",
|
||||
"authorGit": "https://github.com/CHE77/IoTManager-Modules",
|
||||
"exampleURL": "https://iotmanager.org/wiki",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Presence",
|
||||
"moduleVersion": "1.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"title": "MQTT Presence Subscriber",
|
||||
"moduleDesc": "Модуль получения и обработки данных из Presence Publisher app - https://f-droid.org/packages/org.ostrya.presencepublisher/ https://play.google.com/store/apps/details?id=org.ostrya.presencepublisher Получает геопозицию телефона, считает пеленг и дистанцию.",
|
||||
"license": "Cooperative Non-Violent Public License (CNPL)",
|
||||
"propInfo": {
|
||||
"Lat. A": "Широта точки отсчета (локации), в градусах",
|
||||
"Long. A": "Долгота точки отсчета (локации), в градусах",
|
||||
"parameter": "Параметр/ключ для получения данных из json и его производных. Совпадают с методами для сценария",
|
||||
"topic": "Топик на который подписывется модуль. Должен совпадать с топиком в приложении и оканчиваться на status",
|
||||
"isJson": "1 - ожидаем в топике json. Другие форматы пока не подерживаются. В приложении выберите тоже json",
|
||||
"round": "Округление после запятой.",
|
||||
"orange": "Количество минут после которого окрасить виджет в оранжевый цвет",
|
||||
"red": "количество минут после которого окрасить виджет в красный цвет",
|
||||
"offline": "Количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится",
|
||||
"int": "Интервал для изменения цвета",
|
||||
"ticker": "Генерировать(1) или нет(0) события при каждом тике часов (каждые int секунд).",
|
||||
"debug": "1 - выводить дополнительный лог в сериал"
|
||||
},
|
||||
"retInfo": " - Согласно выбраного параметра",
|
||||
"funcInfo": [
|
||||
{
|
||||
"name": "latitude",
|
||||
"descr": "Получить широту позиции устройства (и далее) с приложением Presence Publisher",
|
||||
"params": [
|
||||
"presence.latitude()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "longitude",
|
||||
"descr": "Получить долготу позиции устройства",
|
||||
"params": [
|
||||
"presence.longitude()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "distance",
|
||||
"descr": "Получить дистанцию до устройства",
|
||||
"params": [
|
||||
"presence.distance()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "azimuth",
|
||||
"descr": "Получить пеленг на устройтво",
|
||||
"params": [
|
||||
"presence.azimuth()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "batteryLevel",
|
||||
"descr": "Получить уровень заряда батареи устройства",
|
||||
"params": [
|
||||
"presence.batteryLevel()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "geoTime",
|
||||
"descr": "Получить время определения геопозии устройства",
|
||||
"params": [
|
||||
"presence.geoTime()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "geoTimestamp",
|
||||
"descr": "Получить UnixTime определения геопозии устройства",
|
||||
"params": [
|
||||
"presence.geoTimestamp()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "currentTime",
|
||||
"descr": "Получить время получения геопозиции от устройства",
|
||||
"params": [
|
||||
"presence.currentTime()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "currentTimestamp",
|
||||
"descr": "Получить UnixTime получения геопозиции от устройства",
|
||||
"params": [
|
||||
"presence.currentTimestamp()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nextScheduledTime",
|
||||
"descr": "Получить время следующего получения геопозиции от устройства",
|
||||
"params": [
|
||||
"presence.nextScheduledTime()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nextScheduledTimestamp",
|
||||
"descr": "Получить UnixTime следующего получения геопозиции от устройства",
|
||||
"params": [
|
||||
"presence.nextScheduledTimestamp()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nextAlarmclockTime",
|
||||
"descr": "Получить время следующего будильника на устройтве",
|
||||
"params": [
|
||||
"presence.nextAlarmclockTime()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nextAlarmclockTimestamp",
|
||||
"descr": "Получить UnixTime следующего будильника на устройтве",
|
||||
"params": [
|
||||
"presence.nextAlarmclockTimestamp()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "chargingState",
|
||||
"descr": "Получить статус зарядки устройства",
|
||||
"params": [
|
||||
"presence.chargingState()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "plugState",
|
||||
"descr": "Получить тип зарядки устройства",
|
||||
"params": [
|
||||
"presence.plugState()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "connectedWifi",
|
||||
"descr": "Получить Wi-Fi точку доступа к которой подключено устройство",
|
||||
"params": [
|
||||
"presence.connectedWifi()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deviceName",
|
||||
"descr": "Получить имя устройства",
|
||||
"params": [
|
||||
"presence.deviceName()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "geoLocation",
|
||||
"descr": "Получить строку с широтой, долготой и верменем определения геопозиции",
|
||||
"params": [
|
||||
"presence.geoLocation()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "conditionContent",
|
||||
"descr": "Получить дополнительное условие отправки данных (геопозиции и др)",
|
||||
"params": [
|
||||
"presence.conditionContent()"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"defActive": false,
|
||||
"usedLibs": {
|
||||
"esp32*": [],
|
||||
"esp82*": [],
|
||||
"bk72*": []
|
||||
}
|
||||
}
|
||||
BIN
src/modules/sensors/Presence/preview.png
Normal file
BIN
src/modules/sensors/Presence/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
383
src/modules/sensors/Presence/widgets.json
Normal file
383
src/modules/sensors/Presence/widgets.json
Normal file
@@ -0,0 +1,383 @@
|
||||
[
|
||||
{
|
||||
"name": "anydataRed",
|
||||
"label": "Сообщение1",
|
||||
"widget": "anydata",
|
||||
"icon": "body",
|
||||
"color": "red",
|
||||
"descrColor": "red"
|
||||
},
|
||||
{
|
||||
"name": "anydataDgr",
|
||||
"label": "Сообщение2",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"color": "red",
|
||||
"icon": "walk"
|
||||
},
|
||||
{
|
||||
"name": "anydataDef",
|
||||
"label": "Текст",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "anydataVlt",
|
||||
"label": "Вольты",
|
||||
"widget": "anydata",
|
||||
"after": "V",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataAmp",
|
||||
"label": "Амперы",
|
||||
"widget": "anydata",
|
||||
"after": "A",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataWt",
|
||||
"label": "Ватты",
|
||||
"widget": "anydata",
|
||||
"after": "Wt",
|
||||
"icon": "speedometer",
|
||||
"color": [
|
||||
{
|
||||
"level": 0,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"level": 200,
|
||||
"value": "#009933"
|
||||
},
|
||||
{
|
||||
"level": 2000,
|
||||
"value": "#FF9900"
|
||||
},
|
||||
{
|
||||
"level": 4000,
|
||||
"value": "red"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anydataWth",
|
||||
"label": "Энергия",
|
||||
"widget": "anydata",
|
||||
"after": "kWh",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataHtz",
|
||||
"label": "Герцы",
|
||||
"widget": "anydata",
|
||||
"after": "Hz",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataTmp",
|
||||
"label": "Температура",
|
||||
"widget": "anydata",
|
||||
"after": "°С",
|
||||
"icon": "thermometer",
|
||||
"font": "OCR A Std",
|
||||
"color": [
|
||||
{
|
||||
"level": -20,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": -10,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": 0,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": 12,
|
||||
"value": "#3366FF"
|
||||
},
|
||||
{
|
||||
"level": 16,
|
||||
"value": "#33CCFF"
|
||||
},
|
||||
{
|
||||
"level": 18,
|
||||
"value": "#009933"
|
||||
},
|
||||
{
|
||||
"level": 30,
|
||||
"value": "#FF9900"
|
||||
},
|
||||
{
|
||||
"level": 40,
|
||||
"value": "red"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anydataMm",
|
||||
"label": "Давление",
|
||||
"widget": "anydata",
|
||||
"after": "mm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataHum",
|
||||
"label": "Влажность",
|
||||
"widget": "anydata",
|
||||
"after": "%",
|
||||
"icon": "water",
|
||||
"color": "#88AADF"
|
||||
},
|
||||
{
|
||||
"name": "anydataTm",
|
||||
"label": "Время",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "button",
|
||||
"label": "Кнопка",
|
||||
"widget": "btn",
|
||||
"size": "large",
|
||||
"color": "green",
|
||||
"send": "test"
|
||||
},
|
||||
{
|
||||
"name": "toggle",
|
||||
"label": "Переключатель",
|
||||
"widget": "toggle",
|
||||
"icon": "",
|
||||
"iconOff": ""
|
||||
},
|
||||
{
|
||||
"name": "chart1",
|
||||
"label": "График без точек",
|
||||
"widget": "chart",
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "chart2",
|
||||
"label": "График с точками",
|
||||
"widget": "chart",
|
||||
"maxCount": 86400,
|
||||
"dateFormat": "HH:mm"
|
||||
},
|
||||
{
|
||||
"name": "chart3",
|
||||
"label": "График Дневной",
|
||||
"widget": "chart",
|
||||
"dateFormat": "DD.MM.YYYY",
|
||||
"maxCount": 86400,
|
||||
"type": "bar"
|
||||
},
|
||||
{
|
||||
"name": "chart4",
|
||||
"label": "График Часовой",
|
||||
"widget": "chart",
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 3600,
|
||||
"type": "bar"
|
||||
},
|
||||
{
|
||||
"name": "chart5",
|
||||
"label": "График двойной",
|
||||
"widget": "chart",
|
||||
"series": [
|
||||
"Температура, С",
|
||||
"Влажность, %"
|
||||
],
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "chart6",
|
||||
"label": "График тройной",
|
||||
"widget": "chart",
|
||||
"series": [
|
||||
"Температура, С",
|
||||
"Влажность, %",
|
||||
"Давление, кПа"
|
||||
],
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "fillgauge",
|
||||
"label": "Бочка",
|
||||
"widget": "fillgauge",
|
||||
"circleColor": "#00FFFF",
|
||||
"textColor": "#FFFFFF",
|
||||
"waveTextColor": "#000000",
|
||||
"waveColor": "#00FFFF"
|
||||
},
|
||||
{
|
||||
"name": "inputDate",
|
||||
"label": "Ввод даты",
|
||||
"widget": "input",
|
||||
"size": "small",
|
||||
"color": "orange",
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"name": "inputDgt",
|
||||
"label": "Ввод числа",
|
||||
"widget": "input",
|
||||
"color": "blue",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "inputTxt",
|
||||
"label": "Ввод текста",
|
||||
"widget": "input",
|
||||
"size": "small",
|
||||
"color": "orange",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"name": "inputTm",
|
||||
"label": "Ввод времени",
|
||||
"widget": "input",
|
||||
"color": "blue",
|
||||
"type": "time"
|
||||
},
|
||||
{
|
||||
"name": "progressLine",
|
||||
"label": "Статус линия",
|
||||
"widget": "progress-line",
|
||||
"icon": "sunny",
|
||||
"max": "100",
|
||||
"stroke": "10"
|
||||
},
|
||||
{
|
||||
"name": "progressRound",
|
||||
"label": "Статус круг",
|
||||
"widget": "progress-round",
|
||||
"max": "100",
|
||||
"stroke": "20",
|
||||
"color": "#45ccce",
|
||||
"background": "#777",
|
||||
"semicircle": "1"
|
||||
},
|
||||
{
|
||||
"name": "range",
|
||||
"label": "Ползунок",
|
||||
"widget": "range",
|
||||
"descrColor": "red",
|
||||
"after": "%",
|
||||
"k": 0.0977,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"debounce": 500
|
||||
},
|
||||
{
|
||||
"name": "rangeServo",
|
||||
"label": "Ползунок (Servo)",
|
||||
"widget": "range",
|
||||
"descrColor": "red",
|
||||
"after": "°",
|
||||
"k": 1,
|
||||
"min": 0,
|
||||
"max": 180,
|
||||
"debounce": 500
|
||||
},
|
||||
{
|
||||
"name": "select",
|
||||
"label": "Выпадающий",
|
||||
"widget": "select",
|
||||
"options": [
|
||||
"Выключен",
|
||||
"Включен"
|
||||
],
|
||||
"status": 0
|
||||
},
|
||||
{
|
||||
"name": "anydataPpm",
|
||||
"label": "PPM",
|
||||
"widget": "anydata",
|
||||
"after": "ppm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamAmp",
|
||||
"label": "миллиАмперы",
|
||||
"widget": "anydata",
|
||||
"after": "mAmp",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamVlt",
|
||||
"label": "миллиВольты",
|
||||
"widget": "anydata",
|
||||
"after": "mVlt",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamWt",
|
||||
"label": "миллиВатты",
|
||||
"widget": "anydata",
|
||||
"after": "mWt",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataKm",
|
||||
"label": "Километры",
|
||||
"widget": "anydata",
|
||||
"after": "km",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataM",
|
||||
"label": "Метры",
|
||||
"widget": "anydata",
|
||||
"after": "m",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataCm",
|
||||
"label": "Сантиметры",
|
||||
"widget": "anydata",
|
||||
"after": "cm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataLiter",
|
||||
"label": "Литры",
|
||||
"widget": "anydata",
|
||||
"after": "ltr",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataSpeed",
|
||||
"label": "мерты в секунду",
|
||||
"widget": "anydata",
|
||||
"after": "m/s",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataСorner",
|
||||
"label": "угол градусов",
|
||||
"widget": "anydata",
|
||||
"after": "°",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataBar",
|
||||
"label": "давление Bar",
|
||||
"widget": "anydata",
|
||||
"after": "Kg/cm²",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "nil",
|
||||
"label": "Без виджета"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user