mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-05-09 07:25:49 +00:00
Compare commits
50 Commits
latest
...
60b7d6d795
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b7d6d795 | ||
|
|
947f29cca0 | ||
|
|
d2a13ec0da | ||
|
|
cc39ba409e | ||
|
|
ac9db6256e | ||
|
|
096f628d97 | ||
|
|
22312812bb | ||
|
|
3584975acb | ||
|
|
30b9ca4e6c | ||
|
|
7c6ff01ebe | ||
|
|
a54edcaf5b | ||
|
|
e446954844 | ||
|
|
4a2d0d6787 | ||
|
|
9725314135 | ||
|
|
e610f0d57f | ||
|
|
8244af2940 | ||
|
|
40f371d23b | ||
|
|
817b791e59 | ||
|
|
25a7aac360 | ||
|
|
37115a174d | ||
|
|
1397f81fd0 | ||
|
|
56365cb403 | ||
|
|
dfd245ee7b | ||
|
|
9c81e4b34d | ||
|
|
67676df131 | ||
|
|
a73b129596 | ||
|
|
4600d886b5 | ||
|
|
0fe45a2405 | ||
|
|
db87213242 | ||
|
|
5c3c010d5a | ||
|
|
c804cedd7a | ||
|
|
aa30ca99bf | ||
|
|
c0ca9d1069 | ||
|
|
5e79e1d57f | ||
|
|
8c732f9f1e | ||
|
|
5e94c2f636 | ||
|
|
64e5d29996 | ||
|
|
b320d8ded2 | ||
|
|
0be1b20996 | ||
|
|
6c55460622 | ||
|
|
d627404dc2 | ||
|
|
f317123c26 | ||
|
|
e4df1887b0 | ||
|
|
34142c3e85 | ||
|
|
6e7f8bdf02 | ||
|
|
3dd9fcfb58 | ||
|
|
35e2954b8b | ||
|
|
59aa63db0f | ||
|
|
7a41a190f8 | ||
|
|
6741232450 |
8
.github/workflows/dev_release.yml
vendored
8
.github/workflows/dev_release.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
node-version: 24
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable pnpm
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
- name: Build webUI
|
||||
run: |
|
||||
platformio run -e build-webUI
|
||||
platformio run -e build_webUI
|
||||
|
||||
- name: Build modbus
|
||||
run: |
|
||||
@@ -62,13 +62,13 @@ jobs:
|
||||
platformio run
|
||||
|
||||
- name: Commit the generated files
|
||||
uses: stefanzweifel/git-auto-commit-action@v7
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore: update generated files for v${{steps.build_info.outputs.VERSION}}"
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: 'automatic_releases'
|
||||
uses: emsesp/action-automatic-releases@v1.0.1
|
||||
uses: emsesp/action-automatic-releases@v1.0.0
|
||||
with:
|
||||
repo_token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
title: Development Build v${{steps.build_info.outputs.VERSION}}
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: GitHub Releases To Discord
|
||||
uses: SethCohen/github-releases-to-discord@v1.13.1
|
||||
|
||||
2
.github/workflows/pr_check.yml
vendored
2
.github/workflows/pr_check.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install python 3.13
|
||||
uses: actions/setup-python@v6
|
||||
|
||||
2
.github/workflows/sonar_check.yml
vendored
2
.github/workflows/sonar_check.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
BUILD_WRAPPER_OUT_DIR: bw-output
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Build Wrapper
|
||||
|
||||
6
.github/workflows/stable_release.yml
vendored
6
.github/workflows/stable_release.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
node-version: 24
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable pnpm
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
|
||||
- name: Build webUI
|
||||
run: |
|
||||
platformio run -e build-webUI
|
||||
platformio run -e build_webUI
|
||||
|
||||
- name: Build modbus
|
||||
run: |
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
platformio run
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: emsesp/action-automatic-releases@v1.0.1
|
||||
uses: emsesp/action-automatic-releases@v1.0.0
|
||||
with:
|
||||
repo_token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
prerelease: false
|
||||
|
||||
6
.github/workflows/test_release.yml
vendored
6
.github/workflows/test_release.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
node-version: 24
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable pnpm
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
- name: Build webUI
|
||||
run: |
|
||||
platformio run -e build-webUI
|
||||
platformio run -e build_webUI
|
||||
|
||||
- name: Build modbus
|
||||
run: |
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: 'automatic_releases'
|
||||
uses: emsesp/action-automatic-releases@v1.0.1
|
||||
uses: emsesp/action-automatic-releases@v1.0.0
|
||||
with:
|
||||
repo_token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
title: Test Build v${{steps.build_info.outputs.VERSION}}
|
||||
|
||||
@@ -12,16 +12,12 @@ For more details go to [emsesp.org](https://emsesp.org/).
|
||||
- prometheus metrics for temperature/analog/scheduler/custom [#2962](https://github.com/emsesp/EMS-ESP32/issues/2962)
|
||||
- boiler pumpkick [#2965](https://github.com/emsesp/EMS-ESP32/discussions/2965)
|
||||
- heatpump reset [#2933](https://github.com/emsesp/EMS-ESP32/issues/2933)
|
||||
- 2.nd freshwater module (dhw4, dhw5) [#2991](https://github.com/emsesp/EMS-ESP32/issues/2991)
|
||||
- full system backup and restore
|
||||
- auto-logic to set ht3/ems+ tx-mode
|
||||
- e-mail notification using ReadyMail Client
|
||||
- 2.nd freshwater module (dhw4) [#2991](https://github.com/emsesp/EMS-ESP32/issues/2991)
|
||||
|
||||
## Fixed
|
||||
|
||||
- SRC climate creation [#2936](https://github.com/emsesp/EMS-ESP32/issues/2936) and [#2960](https://github.com/emsesp/EMS-ESP32/issues/2960)
|
||||
- missing translations [#3015](https://github.com/emsesp/EMS-ESP32/issues/3015)
|
||||
- custom entities check fetch length
|
||||
- modbus initialization [#3064](https://github.com/emsesp/EMS-ESP32/issues/3064)
|
||||
|
||||
## Changed
|
||||
|
||||
@@ -33,8 +29,5 @@ For more details go to [emsesp.org](https://emsesp.org/).
|
||||
- support `minflowtemp` and `baseflowtemp` [#2969](https://github.com/emsesp/EMS-ESP32/discussions/2969)
|
||||
- update version if it is 00.00 in first read [#2981](https://github.com/emsesp/EMS-ESP32/issues/2981)
|
||||
- device class for % values [#2980](https://github.com/emsesp/EMS-ESP32/issues/2980)
|
||||
- fetch telegrams: set length to fetch [#3017](https://github.com/emsesp/EMS-ESP32/issues/3017)
|
||||
- move http client from stack to heap
|
||||
- heap optimizations [#3021](https://github.com/emsesp/EMS-ESP32/discussions/3021)
|
||||
- check and read 0x470 as summer2_typeids[0] only if received [#2686](https://github.com/emsesp/EMS-ESP32/issues/2686), [#3055](https://github.com/emsesp/EMS-ESP32/issues/3055)
|
||||
- default bus-id: gateway1(0x49), tx-mode: auto
|
||||
- use tasmota core 2026.03.30
|
||||
- secure mqtt uses ESP_SSLClient
|
||||
|
||||
10
Makefile
10
Makefile
@@ -47,18 +47,18 @@ MAKEFLAGS += -j$(JOBS) -l$(shell echo $$(($(JOBS) * 2)))
|
||||
#----------------------------------------------------------------------
|
||||
TARGET := emsesp
|
||||
BUILD := build
|
||||
SOURCES := src/core src/devices src/web src/test lib_standalone lib/espMqttClient/src lib/espMqttClient/src/* lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/PButton
|
||||
INCLUDES := src/core src/devices src/web src/test lib_standalone lib/* lib/espMqttClient/src lib/espMqttClient/src/Transport lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src
|
||||
SOURCES := src/core src/devices src/web src/test lib_standalone lib/semver lib/espMqttClient/src lib/espMqttClient/src/* lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/PButton
|
||||
INCLUDES := src/core src/devices src/web src/test lib_standalone lib/* lib/semver lib/espMqttClient/src lib/espMqttClient/src/Transport lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src
|
||||
LIBRARIES :=
|
||||
|
||||
CPPCHECK = cppcheck
|
||||
CHECKFLAGS = -q --force --std=gnu++20
|
||||
CHECKFLAGS = -q --force --std=gnu++17
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Languages Standard
|
||||
#----------------------------------------------------------------------
|
||||
C_STANDARD := -std=c20
|
||||
CXX_STANDARD := -std=gnu++20
|
||||
C_STANDARD := -std=c17
|
||||
CXX_STANDARD := -std=gnu++17
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Defined Symbols
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DTASMOTA_SDK",
|
||||
"-DNO_TLS_SUPPORT",
|
||||
"-DARDUINO_LOLIN_C3_MINI",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DTASMOTA_SDK",
|
||||
"-DNO_TLS_SUPPORT",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0"
|
||||
],
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif ESP32-S3 32M Flash OPI PSRAM, 4608KB Code/OTA, 2MB FS",
|
||||
"name": "Tasmota ESP32-S3 32M Flash OPI PSRAM, 4608KB Code/OTA, 2MB FS",
|
||||
"upload": {
|
||||
"flash_size": "32MB",
|
||||
"maximum_ram_size": 327680,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DTASMOTA_SDK",
|
||||
"extra_flags": "-DNO_TLS_SUPPORT",
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
@@ -19,7 +19,7 @@
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif ESP32 16M Flash, 4608KB Code/OTA, 2MB FS",
|
||||
"name": "Tasmota ESP32 16M Flash, 4608KB Code/OTA, 2MB FS",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "Espressif ESP32 16M Flash DIO PSRAM, 4608KB Code/OTA, 2MB FS",
|
||||
"name": "Tasmota ESP32 16M Flash DIO PSRAM, 4608KB Code/OTA, 2MB FS",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DTASMOTA_SDK",
|
||||
"extra_flags": "-DNO_TLS_SUPPORT",
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"build": {
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DNO_TLS_SUPPORT",
|
||||
"-DARDUINO_XIAO_ESP32C6",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1"
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
"lib/esp32-psram/**",
|
||||
"test/test_api/test_api.h",
|
||||
"lib_standalone/**",
|
||||
"**/*.js"
|
||||
"lib/mbedtls_ssl/**"
|
||||
]
|
||||
}
|
||||
@@ -1,228 +1,85 @@
|
||||
{
|
||||
"type": "systembackup",
|
||||
"version": "3.8.2",
|
||||
"date": "2026-03-29T13:28:15",
|
||||
"systembackup": [
|
||||
{
|
||||
"type": "settings",
|
||||
"Network": {
|
||||
"ssid": "",
|
||||
"bssid": "",
|
||||
"password": "",
|
||||
"hostname": "ems-esp",
|
||||
"static_ip_config": false,
|
||||
"bandwidth20": false,
|
||||
"nosleep": true,
|
||||
"enableMDNS": true,
|
||||
"enableCORS": false,
|
||||
"CORSOrigin": "*",
|
||||
"tx_power": 0
|
||||
},
|
||||
"AP": {
|
||||
"provision_mode": 2,
|
||||
"ssid": "ems-esp",
|
||||
"password": "ems-esp-neo",
|
||||
"channel": 1,
|
||||
"ssid_hidden": false,
|
||||
"max_clients": 4,
|
||||
"local_ip": "192.168.4.1",
|
||||
"gateway_ip": "192.168.4.1",
|
||||
"subnet_mask": "255.255.255.0"
|
||||
},
|
||||
"MQTT": {
|
||||
"enableTLS": false,
|
||||
"rootCA": "",
|
||||
"enabled": false,
|
||||
"host": "",
|
||||
"port": 1883,
|
||||
"base": "ems-esp",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"client_id": "esp32-b8ffc9ec",
|
||||
"keep_alive": 60,
|
||||
"clean_session": false,
|
||||
"entity_format": 1,
|
||||
"publish_time_boiler": 10,
|
||||
"publish_time_thermostat": 10,
|
||||
"publish_time_solar": 10,
|
||||
"publish_time_mixer": 10,
|
||||
"publish_time_water": 10,
|
||||
"publish_time_other": 60,
|
||||
"publish_time_sensor": 10,
|
||||
"publish_time_heartbeat": 60,
|
||||
"mqtt_qos": 0,
|
||||
"mqtt_retain": false,
|
||||
"ha_enabled": false,
|
||||
"nested_format": 1,
|
||||
"discovery_prefix": "homeassistant",
|
||||
"discovery_type": 0,
|
||||
"ha_number_mode": 0,
|
||||
"publish_single": false,
|
||||
"publish_single2cmd": false,
|
||||
"send_response": false
|
||||
},
|
||||
"NTP": {
|
||||
"enabled": true,
|
||||
"server": "time.google.com",
|
||||
"tz_label": "Europe/Amsterdam",
|
||||
"tz_format": "CET-1CEST,M3.5.0,M10.5.0/3"
|
||||
},
|
||||
"Security": {
|
||||
"jwt_secret": "ems-esp-neo",
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin",
|
||||
"admin": true
|
||||
},
|
||||
{
|
||||
"username": "guest",
|
||||
"password": "guest",
|
||||
"admin": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Settings": {
|
||||
"version": "3.8.2",
|
||||
"board_profile": "E32V2_2",
|
||||
"platform": "ESP32",
|
||||
"locale": "en",
|
||||
"tx_mode": 1,
|
||||
"ems_bus_id": 11,
|
||||
"syslog_enabled": false,
|
||||
"syslog_level": 3,
|
||||
"trace_raw": false,
|
||||
"syslog_mark_interval": 0,
|
||||
"syslog_host": "",
|
||||
"syslog_port": 514,
|
||||
"boiler_heatingoff": false,
|
||||
"remote_timeout": 24,
|
||||
"remote_timeout_en": false,
|
||||
"shower_timer": false,
|
||||
"shower_alert": false,
|
||||
"shower_alert_coldshot": 10,
|
||||
"shower_alert_trigger": 7,
|
||||
"shower_min_duration": 180,
|
||||
"rx_gpio": 4,
|
||||
"tx_gpio": 5,
|
||||
"dallas_gpio": 14,
|
||||
"dallas_parasite": false,
|
||||
"led_gpio": 32,
|
||||
"hide_led": false,
|
||||
"led_type": 1,
|
||||
"low_clock": false,
|
||||
"telnet_enabled": true,
|
||||
"notoken_api": false,
|
||||
"readonly_mode": false,
|
||||
"analog_enabled": true,
|
||||
"pbutton_gpio": 34,
|
||||
"solar_maxflow": 30,
|
||||
"fahrenheit": false,
|
||||
"bool_format": 1,
|
||||
"bool_dashboard": 1,
|
||||
"enum_format": 1,
|
||||
"weblog_level": 6,
|
||||
"weblog_buffer": 50,
|
||||
"weblog_compact": true,
|
||||
"phy_type": 1,
|
||||
"eth_power": 15,
|
||||
"eth_phy_addr": 0,
|
||||
"eth_clock_mode": 1,
|
||||
"modbus_enabled": false,
|
||||
"modbus_port": 502,
|
||||
"modbus_max_clients": 10,
|
||||
"modbus_timeout": 300,
|
||||
"developer_mode": true,
|
||||
"email_enabled": false,
|
||||
"email_ssl": false,
|
||||
"email_starttls": true,
|
||||
"email_server": "smtp.example.net",
|
||||
"email_port": 587,
|
||||
"email_login": "",
|
||||
"email_pass": "",
|
||||
"email_sender": "ems-esp@example.net",
|
||||
"email_recp": "",
|
||||
"email_subject": "ems-esp notification"
|
||||
}
|
||||
"type": "settings",
|
||||
"Network": {
|
||||
"ssid": "my_wifi_ssid",
|
||||
"bssid": "",
|
||||
"password": "my_wifi_password",
|
||||
"hostname": "ems-esp"
|
||||
},
|
||||
{
|
||||
"type": "schedule",
|
||||
"Schedule": {
|
||||
"schedule": []
|
||||
}
|
||||
"AP": {
|
||||
"provision_mode": 2,
|
||||
"ssid": "ems-esp",
|
||||
"password": "ems-esp-neo",
|
||||
"channel": 1,
|
||||
"ssid_hidden": false,
|
||||
"max_clients": 4,
|
||||
"local_ip": "192.168.4.1",
|
||||
"gateway_ip": "192.168.4.1",
|
||||
"subnet_mask": "255.255.255.0"
|
||||
},
|
||||
{
|
||||
"type": "customizations",
|
||||
"Customizations": {
|
||||
"ts": [
|
||||
{
|
||||
"id": "28_1767_7B13_2502",
|
||||
"name": "gateway_temperature",
|
||||
"offset": 0,
|
||||
"is_system": true
|
||||
}
|
||||
],
|
||||
"as": [
|
||||
{
|
||||
"gpio": 39,
|
||||
"name": "core_voltage",
|
||||
"offset": 0,
|
||||
"factor": 0.003771,
|
||||
"uom": 23,
|
||||
"type": 3,
|
||||
"is_system": true
|
||||
},
|
||||
{
|
||||
"gpio": 36,
|
||||
"name": "supply_voltage",
|
||||
"offset": 0,
|
||||
"factor": 0.017,
|
||||
"uom": 23,
|
||||
"type": 3,
|
||||
"is_system": true
|
||||
},
|
||||
{
|
||||
"gpio": 2,
|
||||
"name": "led",
|
||||
"offset": 0,
|
||||
"factor": 1,
|
||||
"uom": 0,
|
||||
"type": 6,
|
||||
"is_system": true
|
||||
}
|
||||
],
|
||||
"masked_entities": []
|
||||
}
|
||||
"MQTT": {
|
||||
"enableTLS": false,
|
||||
"rootCA": "",
|
||||
"enabled": false,
|
||||
"host": "127.0.0.1",
|
||||
"port": 1883,
|
||||
"base": "ems-esp",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"client_id": "ems-esp",
|
||||
"entity_format": 1,
|
||||
"publish_time_boiler": 10,
|
||||
"publish_time_thermostat": 10,
|
||||
"publish_time_solar": 10,
|
||||
"publish_time_mixer": 10,
|
||||
"publish_time_water": 10,
|
||||
"publish_time_other": 60,
|
||||
"publish_time_sensor": 10,
|
||||
"publish_time_heartbeat": 60,
|
||||
"mqtt_qos": 0,
|
||||
"mqtt_retain": false,
|
||||
"ha_enabled": false,
|
||||
"nested_format": 1,
|
||||
"discovery_prefix": "homeassistant",
|
||||
"discovery_type": 0,
|
||||
"publish_single": false,
|
||||
"publish_single2cmd": false,
|
||||
"send_response": false
|
||||
},
|
||||
{
|
||||
"type": "entities",
|
||||
"Entities": {
|
||||
"entities": []
|
||||
}
|
||||
"NTP": {
|
||||
"enabled": true,
|
||||
"server": "time.google.com",
|
||||
"tz_label": "Europe/Amsterdam",
|
||||
"tz_format": "CET-1CEST,M3.5.0,M10.5.0/3"
|
||||
},
|
||||
{
|
||||
"type": "modules",
|
||||
"Modules": {
|
||||
"modules": []
|
||||
}
|
||||
"Security": {
|
||||
"jwt_secret": "ems-esp-neo",
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin",
|
||||
"admin": true
|
||||
},
|
||||
{
|
||||
"username": "guest",
|
||||
"password": "guest",
|
||||
"admin": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "customSupport",
|
||||
"Support": {
|
||||
"html": [
|
||||
"This product is installed and managed by:",
|
||||
"",
|
||||
"<b>Bosch Installer Example</b>",
|
||||
"",
|
||||
"Nefit Road 12",
|
||||
"1234 AB Amsterdam",
|
||||
"Phone: +31 123 456 789",
|
||||
"email: support@boschinstaller.nl",
|
||||
"",
|
||||
"For help and questions please <a target='_blank' href='https://emsesp.org'>contact</a> your installer."
|
||||
],
|
||||
"img_url": "https://emsesp.org/media/images/designer.png"
|
||||
}
|
||||
"Settings": {
|
||||
"board_profile": "S3",
|
||||
"locale": "en",
|
||||
"tx_mode": 1,
|
||||
"ems_bus_id": 11,
|
||||
"boiler_heatingoff": false,
|
||||
"hide_led": true,
|
||||
"telnet_enabled": true,
|
||||
"notoken_api": false,
|
||||
"analog_enabled": true,
|
||||
"fahrenheit": false,
|
||||
"bool_format": 1,
|
||||
"bool_dashboard": 1,
|
||||
"enum_format": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -7654,7 +7654,7 @@ uint8
|
||||
| cylmaxtemp | maximum cylinder temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 5 | 1 | 1 |
|
||||
| collectorshutdown | collector shutdown | boolean | | false | DEVICE_DATA | 6 | 1 | 1 |
|
||||
| cylheated | cyl heated | boolean | | false | DEVICE_DATA | 7 | 1 | 1 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS14) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| retheatassist | return temperature heat assistance (TS4) | int16 | C | false | DEVICE_DATA | 18 | 1 | 1/10 |
|
||||
| heatassistvalve | heat assistance valve (M1) | boolean | | false | DEVICE_DATA | 19 | 1 | 1 |
|
||||
| energylasthour | energy last hour | uint24 | Wh | false | DEVICE_DATA | 13 | 2 | 1/10 |
|
||||
@@ -7671,7 +7671,7 @@ uint8
|
||||
| cylmaxtemp | maximum cylinder temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 5 | 1 | 1 |
|
||||
| collectorshutdown | collector shutdown | boolean | | false | DEVICE_DATA | 6 | 1 | 1 |
|
||||
| cylheated | cyl heated | boolean | | false | DEVICE_DATA | 7 | 1 | 1 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS14) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| retheatassist | return temperature heat assistance (TS4) | int16 | C | false | DEVICE_DATA | 18 | 1 | 1/10 |
|
||||
| heatassistvalve | heat assistance valve (M1) | boolean | | false | DEVICE_DATA | 19 | 1 | 1 |
|
||||
| energylasthour | energy last hour | uint24 | Wh | false | DEVICE_DATA | 13 | 2 | 1/10 |
|
||||
@@ -7696,68 +7696,67 @@ uint8
|
||||
uint8
|
||||
| turnoffdiff | pump turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 11 | 1 | 1/10 |
|
||||
| collector2temp | collector 2 temperature (TS7) | int16 | C | false | DEVICE_DATA | 20 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS14) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| ts3 | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| retheatassist | return temperature heat assistance (TS4) | int16 | C | false | DEVICE_DATA | 18 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 23 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| heatassistvalve | heat assistance valve (M1) | boolean | | false | DEVICE_DATA | 19 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 26 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 30 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 36 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 23 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 26 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 30 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
uint8
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 36 | 1 | 1 |
|
||||
uint8
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 38 | 1 | 1 |
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| energylasthour | energy last hour | uint24 | Wh | false | DEVICE_DATA | 13 | 2 | 1/10 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 39 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 41 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 43 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 45 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 38 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 40 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 42 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 44 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 46 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
uint8
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 56 | 1 | 1 |
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
uint8
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 56 | 1 | 1/10 |
|
||||
uint8
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 58 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 58 | 1 | 1 |
|
||||
uint8
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 60 | 1 | 1 |
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
uint16
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 61 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 62 | 1 | 1 |
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 60 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 61 | 1 | 1 |
|
||||
uint16
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 63 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 65 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 67 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 68 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 62 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 63 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 65 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 67 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 68 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 72 | 1 | 1/10 |
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
|
||||
### SM100, MS100
|
||||
|
||||
@@ -7779,68 +7778,67 @@ uint8
|
||||
uint8
|
||||
| turnoffdiff | pump turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 11 | 1 | 1/10 |
|
||||
| collector2temp | collector 2 temperature (TS7) | int16 | C | false | DEVICE_DATA | 20 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS14) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| ts3 | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| retheatassist | return temperature heat assistance (TS4) | int16 | C | false | DEVICE_DATA | 18 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 23 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| heatassistvalve | heat assistance valve (M1) | boolean | | false | DEVICE_DATA | 19 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 26 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 30 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 36 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 23 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 26 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 30 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
uint8
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 36 | 1 | 1 |
|
||||
uint8
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 38 | 1 | 1 |
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| energylasthour | energy last hour | uint24 | Wh | false | DEVICE_DATA | 13 | 2 | 1/10 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 39 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 41 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 43 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 45 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 38 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 40 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 42 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 44 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 46 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
uint8
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 56 | 1 | 1 |
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
uint8
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 56 | 1 | 1/10 |
|
||||
uint8
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 58 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 58 | 1 | 1 |
|
||||
uint8
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 60 | 1 | 1 |
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
uint16
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 61 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 62 | 1 | 1 |
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 60 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 61 | 1 | 1 |
|
||||
uint16
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 63 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 65 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 67 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 68 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 62 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 63 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 65 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 67 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 68 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 72 | 1 | 1/10 |
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
|
||||
### SM200, MS200
|
||||
|
||||
@@ -7862,68 +7860,67 @@ uint8
|
||||
uint8
|
||||
| turnoffdiff | pump turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 11 | 1 | 1/10 |
|
||||
| collector2temp | collector 2 temperature (TS7) | int16 | C | false | DEVICE_DATA | 20 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS14) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| ts3 | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| cylmiddletemp | cylinder middle temperature (TS3) | int16 | C | false | DEVICE_DATA | 17 | 1 | 1/10 |
|
||||
| retheatassist | return temperature heat assistance (TS4) | int16 | C | false | DEVICE_DATA | 18 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 23 | 1 | 1/10 |
|
||||
| ts8 | (TS8) | int16 | C | false | DEVICE_DATA | 21 | 1 | 1/10 |
|
||||
| ts16 | (TS16) | int16 | C | false | DEVICE_DATA | 22 | 1 | 1/10 |
|
||||
| heatassistvalve | heat assistance valve (M1) | boolean | | false | DEVICE_DATA | 19 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 26 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 30 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 36 | 1 | 1 |
|
||||
| heatassistpower | heat assistance valve power (M1) | uint8 | % | false | DEVICE_DATA | 23 | 1 | 1 |
|
||||
| solarpump2 | pump 2 (PS4) | boolean | | false | DEVICE_DATA | 24 | 1 | 1 |
|
||||
| solarpump2mod | pump 2 modulation (PS4) | uint8 | % | false | DEVICE_DATA | 25 | 1 | 1 |
|
||||
| cyl2bottomtemp | second cylinder bottom temperature (TS5) | int16 | C | false | DEVICE_DATA | 26 | 1 | 1/10 |
|
||||
| cyl3bottomtemp | third cylinder bottom temperature (TS11) | int16 | C | false | DEVICE_DATA | 27 | 1 | 1/10 |
|
||||
| cyltoptemp | cylinder top temperature (TS10) | int16 | C | false | DEVICE_DATA | 28 | 1 | 1/10 |
|
||||
| heatexchangertemp | heat exchanger temperature (TS6) | int16 | C | false | DEVICE_DATA | 29 | 1 | 1/10 |
|
||||
| cylpumpmod | cylinder pump modulation (PS5) | uint8 | % | false | DEVICE_DATA | 30 | 1 | 1 |
|
||||
| valvestatus | valve status | boolean | | false | DEVICE_DATA | 31 | 1 | 1 |
|
||||
| vs1status | valve status VS1 | boolean | | false | DEVICE_DATA | 32 | 1 | 1 |
|
||||
| vs3status | valve status VS3 | boolean | | false | DEVICE_DATA | 33 | 1 | 1 |
|
||||
| transferpump | transfer pump | boolean | | false | DEVICE_DATA | 34 | 1 | 1 |
|
||||
| transferpumpmod | transfer pump modulation | uint8 | % | false | DEVICE_DATA | 35 | 1 | 1 |
|
||||
uint8
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| collectormaxtemp | maximum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 36 | 1 | 1 |
|
||||
uint8
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 38 | 1 | 1 |
|
||||
| collectormintemp | minimum collector temperature | uint8 (>=0<=0) | C | true | DEVICE_DATA | 37 | 1 | 1 |
|
||||
| energylasthour | energy last hour | uint24 | Wh | false | DEVICE_DATA | 13 | 2 | 1/10 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 39 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 41 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 43 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 45 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
| energytoday | total energy today | uint24 | Wh | false | DEVICE_DATA | 38 | 2 | 1 |
|
||||
| energytotal | total energy | uint24 | kWh | false | DEVICE_DATA | 40 | 2 | 1/10 |
|
||||
| pump2worktime | pump 2 working time | time | minutes | false | DEVICE_DATA | 42 | 2 | 1 |
|
||||
| m1worktime | differential control working time | time | minutes | false | DEVICE_DATA | 44 | 2 | 1 |
|
||||
| heattransfersystem | heattransfer system | boolean | | true | DEVICE_DATA | 46 | 1 | 1 |
|
||||
| externalcyl | external cylinder | boolean | | true | DEVICE_DATA | 47 | 1 | 1 |
|
||||
| thermaldisinfect | thermal disinfection | boolean | | true | DEVICE_DATA | 48 | 1 | 1 |
|
||||
| heatmetering | heatmetering | boolean | | true | DEVICE_DATA | 49 | 1 | 1 |
|
||||
| activated | activated | boolean | | true | DEVICE_DATA | 50 | 1 | 1 |
|
||||
| solarpumpmode | solar pump mode | enum | | true | DEVICE_DATA | 51 | 1 | 1 |
|
||||
| solarpumpkick | solar pump kick | boolean | | true | DEVICE_DATA | 52 | 1 | 1 |
|
||||
| plainwatermode | plain water mode | boolean | | true | DEVICE_DATA | 53 | 1 | 1 |
|
||||
| doublematchflow | doublematchflow | boolean | | true | DEVICE_DATA | 54 | 1 | 1 |
|
||||
uint8
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 56 | 1 | 1 |
|
||||
| pump2minmod | minimum pump 2 modulation | uint8 (>=0<=0) | % | true | DEVICE_DATA | 55 | 1 | 1 |
|
||||
uint8
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| turnondiff2 | pump 2 turn on difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 56 | 1 | 1/10 |
|
||||
uint8
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 58 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
| turnoffdiff2 | pump 2 turn off difference | uint8 (>=0<=0) | C | true | DEVICE_DATA | 57 | 1 | 1/10 |
|
||||
| pump2kick | pump kick 2 | boolean | | true | DEVICE_DATA | 58 | 1 | 1 |
|
||||
uint8
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 60 | 1 | 1 |
|
||||
| climatezone | climate zone | uint8 (>=0<=0) | | true | DEVICE_DATA | 59 | 1 | 1 |
|
||||
uint16
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 61 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 62 | 1 | 1 |
|
||||
| collector1area | collector 1 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 60 | 1 | 1/10 |
|
||||
| collector1type | collector 1 type | enum | | true | DEVICE_DATA | 61 | 1 | 1 |
|
||||
uint16
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 63 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 65 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 67 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 68 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
| collector2area | collector 2 area | uint16 (>=0<=0) | m² | true | DEVICE_DATA | 62 | 1 | 1/10 |
|
||||
| collector2type | collector 2 type | enum | | true | DEVICE_DATA | 63 | 1 | 1 |
|
||||
| cylpriority | cylinder priority | enum | | true | DEVICE_DATA | 64 | 1 | 1 |
|
||||
| heatcntflowtemp | heat counter flow temperature | uint16 | C | false | DEVICE_DATA | 65 | 1 | 1/10 |
|
||||
| heatcntrettemp | heat counter return temperature | uint16 | C | false | DEVICE_DATA | 66 | 1 | 1/10 |
|
||||
| heatcnt | heat counter impulses | uint8 | | false | DEVICE_DATA | 67 | 1 | 1 |
|
||||
| swapflowtemp | swap flow temperature (TS14) | uint16 | C | false | DEVICE_DATA | 68 | 1 | 1/10 |
|
||||
| swaprettemp | swap return temperature (TS15) | uint16 | C | false | DEVICE_DATA | 69 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
| heatassiston | heat assistance on | int8 (>=0<=0) | K | true | DEVICE_DATA | 70 | 1 | 1/10 |
|
||||
int8
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 72 | 1 | 1/10 |
|
||||
| heatassistoff | heat assistance off | int8 (>=0<=0) | K | true | DEVICE_DATA | 71 | 1 | 1/10 |
|
||||
|
||||
## Devices of type \_heatpump
|
||||
|
||||
|
||||
@@ -5495,7 +5495,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"ISM1",solar,101,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=0),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp,8,0,1,5,1
|
||||
"ISM1",solar,101,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown,8,0,1,6,1
|
||||
"ISM1",solar,101,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated,8,0,1,7,1
|
||||
"ISM1",solar,101,cylmiddletemp,cylinder middle temperature (TS14),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS14),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"ISM1",solar,101,cylmiddletemp,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"ISM1",solar,101,retheatassist,return temperature heat assistance (TS4),int16,C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist,8,0,1/10,18,1
|
||||
"ISM1",solar,101,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve,8,0,1,19,1
|
||||
"ISM1",solar,101,energylasthour,energy last hour,uint24,Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour,8,0,1/10,13,2
|
||||
@@ -5506,7 +5506,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"ISM2",solar,103,cylmaxtemp,maximum cylinder temperature,uint8 (>=0<=0),C,true,number.solar_maximum_cylinder_temperature,number.solar_cylmaxtemp,8,0,1,5,1
|
||||
"ISM2",solar,103,collectorshutdown,collector shutdown,boolean, ,false,binary_sensor.solar_collector_shutdown,binary_sensor.solar_collectorshutdown,8,0,1,6,1
|
||||
"ISM2",solar,103,cylheated,cyl heated,boolean, ,false,binary_sensor.solar_cyl_heated,binary_sensor.solar_cylheated,8,0,1,7,1
|
||||
"ISM2",solar,103,cylmiddletemp,cylinder middle temperature (TS14),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS14),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"ISM2",solar,103,cylmiddletemp,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"ISM2",solar,103,retheatassist,return temperature heat assistance (TS4),int16,C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist,8,0,1/10,18,1
|
||||
"ISM2",solar,103,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve,8,0,1,19,1
|
||||
"ISM2",solar,103,energylasthour,energy last hour,uint24,Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour,8,0,1/10,13,2
|
||||
@@ -5522,58 +5522,57 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"SM50",solar,162,turnondiff,pump turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff,8,0,1/10,10,1
|
||||
"SM50",solar,162,turnoffdiff,pump turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff,8,0,1/10,11,1
|
||||
"SM50",solar,162,collector2temp,collector 2 temperature (TS7),int16,C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp,8,0,1/10,20,1
|
||||
"SM50",solar,162,cylmiddletemp,cylinder middle temperature (TS14),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS14),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM50",solar,162,ts3,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_ts3,8,0,1/10,21,1
|
||||
"SM50",solar,162,cylmiddletemp,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM50",solar,162,retheatassist,return temperature heat assistance (TS4),int16,C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist,8,0,1/10,18,1
|
||||
"SM50",solar,162,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,22,1
|
||||
"SM50",solar,162,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,23,1
|
||||
"SM50",solar,162,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,21,1
|
||||
"SM50",solar,162,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,22,1
|
||||
"SM50",solar,162,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve,8,0,1,19,1
|
||||
"SM50",solar,162,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,24,1
|
||||
"SM50",solar,162,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,25,1
|
||||
"SM50",solar,162,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,26,1
|
||||
"SM50",solar,162,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,27,1
|
||||
"SM50",solar,162,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,28,1
|
||||
"SM50",solar,162,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,29,1
|
||||
"SM50",solar,162,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,30,1
|
||||
"SM50",solar,162,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,31,1
|
||||
"SM50",solar,162,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,32,1
|
||||
"SM50",solar,162,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,33,1
|
||||
"SM50",solar,162,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,34,1
|
||||
"SM50",solar,162,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,35,1
|
||||
"SM50",solar,162,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,36,1
|
||||
"SM50",solar,162,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,37,1
|
||||
"SM50",solar,162,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,38,1
|
||||
"SM50",solar,162,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,23,1
|
||||
"SM50",solar,162,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,24,1
|
||||
"SM50",solar,162,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,25,1
|
||||
"SM50",solar,162,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,26,1
|
||||
"SM50",solar,162,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,27,1
|
||||
"SM50",solar,162,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,28,1
|
||||
"SM50",solar,162,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,29,1
|
||||
"SM50",solar,162,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,30,1
|
||||
"SM50",solar,162,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,31,1
|
||||
"SM50",solar,162,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,32,1
|
||||
"SM50",solar,162,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,33,1
|
||||
"SM50",solar,162,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,34,1
|
||||
"SM50",solar,162,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,35,1
|
||||
"SM50",solar,162,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,36,1
|
||||
"SM50",solar,162,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,37,1
|
||||
"SM50",solar,162,energylasthour,energy last hour,uint24,Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour,8,0,1/10,13,2
|
||||
"SM50",solar,162,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,39,2
|
||||
"SM50",solar,162,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,41,2
|
||||
"SM50",solar,162,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,43,2
|
||||
"SM50",solar,162,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,45,2
|
||||
"SM50",solar,162,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,47,1
|
||||
"SM50",solar,162,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,48,1
|
||||
"SM50",solar,162,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,49,1
|
||||
"SM50",solar,162,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,50,1
|
||||
"SM50",solar,162,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,51,1
|
||||
"SM50",solar,162,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,52,1
|
||||
"SM50",solar,162,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,53,1
|
||||
"SM50",solar,162,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,54,1
|
||||
"SM50",solar,162,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,55,1
|
||||
"SM50",solar,162,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,56,1
|
||||
"SM50",solar,162,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,57,1
|
||||
"SM50",solar,162,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,58,1
|
||||
"SM50",solar,162,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,59,1
|
||||
"SM50",solar,162,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,60,1
|
||||
"SM50",solar,162,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,61,1
|
||||
"SM50",solar,162,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,62,1
|
||||
"SM50",solar,162,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,63,1
|
||||
"SM50",solar,162,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,64,1
|
||||
"SM50",solar,162,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,65,1
|
||||
"SM50",solar,162,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,66,1
|
||||
"SM50",solar,162,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,67,1
|
||||
"SM50",solar,162,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,68,1
|
||||
"SM50",solar,162,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,69,1
|
||||
"SM50",solar,162,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,70,1
|
||||
"SM50",solar,162,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,71,1
|
||||
"SM50",solar,162,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,72,1
|
||||
"SM50",solar,162,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,38,2
|
||||
"SM50",solar,162,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,40,2
|
||||
"SM50",solar,162,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,42,2
|
||||
"SM50",solar,162,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,44,2
|
||||
"SM50",solar,162,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,46,1
|
||||
"SM50",solar,162,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,47,1
|
||||
"SM50",solar,162,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,48,1
|
||||
"SM50",solar,162,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,49,1
|
||||
"SM50",solar,162,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,50,1
|
||||
"SM50",solar,162,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,51,1
|
||||
"SM50",solar,162,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,52,1
|
||||
"SM50",solar,162,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,53,1
|
||||
"SM50",solar,162,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,54,1
|
||||
"SM50",solar,162,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,55,1
|
||||
"SM50",solar,162,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,56,1
|
||||
"SM50",solar,162,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,57,1
|
||||
"SM50",solar,162,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,58,1
|
||||
"SM50",solar,162,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,59,1
|
||||
"SM50",solar,162,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,60,1
|
||||
"SM50",solar,162,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,61,1
|
||||
"SM50",solar,162,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,62,1
|
||||
"SM50",solar,162,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,63,1
|
||||
"SM50",solar,162,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,64,1
|
||||
"SM50",solar,162,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,65,1
|
||||
"SM50",solar,162,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,66,1
|
||||
"SM50",solar,162,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,67,1
|
||||
"SM50",solar,162,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,68,1
|
||||
"SM50",solar,162,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,69,1
|
||||
"SM50",solar,162,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,70,1
|
||||
"SM50",solar,162,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,71,1
|
||||
"SM100, MS100",solar,163,collectortemp,collector temperature (TS1),int16,C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp,8,0,1/10,0,1
|
||||
"SM100, MS100",solar,163,cylbottomtemp,cylinder bottom temperature (TS2),int16,C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp,8,0,1/10,1,1
|
||||
"SM100, MS100",solar,163,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump,8,0,1,2,1
|
||||
@@ -5586,58 +5585,57 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"SM100, MS100",solar,163,turnondiff,pump turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff,8,0,1/10,10,1
|
||||
"SM100, MS100",solar,163,turnoffdiff,pump turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff,8,0,1/10,11,1
|
||||
"SM100, MS100",solar,163,collector2temp,collector 2 temperature (TS7),int16,C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp,8,0,1/10,20,1
|
||||
"SM100, MS100",solar,163,cylmiddletemp,cylinder middle temperature (TS14),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS14),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM100, MS100",solar,163,ts3,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_ts3,8,0,1/10,21,1
|
||||
"SM100, MS100",solar,163,cylmiddletemp,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM100, MS100",solar,163,retheatassist,return temperature heat assistance (TS4),int16,C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist,8,0,1/10,18,1
|
||||
"SM100, MS100",solar,163,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,22,1
|
||||
"SM100, MS100",solar,163,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,23,1
|
||||
"SM100, MS100",solar,163,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,21,1
|
||||
"SM100, MS100",solar,163,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,22,1
|
||||
"SM100, MS100",solar,163,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve,8,0,1,19,1
|
||||
"SM100, MS100",solar,163,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,24,1
|
||||
"SM100, MS100",solar,163,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,25,1
|
||||
"SM100, MS100",solar,163,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,26,1
|
||||
"SM100, MS100",solar,163,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,27,1
|
||||
"SM100, MS100",solar,163,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,28,1
|
||||
"SM100, MS100",solar,163,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,29,1
|
||||
"SM100, MS100",solar,163,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,30,1
|
||||
"SM100, MS100",solar,163,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,31,1
|
||||
"SM100, MS100",solar,163,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,32,1
|
||||
"SM100, MS100",solar,163,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,33,1
|
||||
"SM100, MS100",solar,163,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,34,1
|
||||
"SM100, MS100",solar,163,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,35,1
|
||||
"SM100, MS100",solar,163,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,36,1
|
||||
"SM100, MS100",solar,163,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,37,1
|
||||
"SM100, MS100",solar,163,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,38,1
|
||||
"SM100, MS100",solar,163,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,23,1
|
||||
"SM100, MS100",solar,163,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,24,1
|
||||
"SM100, MS100",solar,163,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,25,1
|
||||
"SM100, MS100",solar,163,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,26,1
|
||||
"SM100, MS100",solar,163,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,27,1
|
||||
"SM100, MS100",solar,163,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,28,1
|
||||
"SM100, MS100",solar,163,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,29,1
|
||||
"SM100, MS100",solar,163,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,30,1
|
||||
"SM100, MS100",solar,163,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,31,1
|
||||
"SM100, MS100",solar,163,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,32,1
|
||||
"SM100, MS100",solar,163,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,33,1
|
||||
"SM100, MS100",solar,163,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,34,1
|
||||
"SM100, MS100",solar,163,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,35,1
|
||||
"SM100, MS100",solar,163,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,36,1
|
||||
"SM100, MS100",solar,163,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,37,1
|
||||
"SM100, MS100",solar,163,energylasthour,energy last hour,uint24,Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour,8,0,1/10,13,2
|
||||
"SM100, MS100",solar,163,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,39,2
|
||||
"SM100, MS100",solar,163,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,41,2
|
||||
"SM100, MS100",solar,163,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,43,2
|
||||
"SM100, MS100",solar,163,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,45,2
|
||||
"SM100, MS100",solar,163,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,47,1
|
||||
"SM100, MS100",solar,163,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,48,1
|
||||
"SM100, MS100",solar,163,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,49,1
|
||||
"SM100, MS100",solar,163,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,50,1
|
||||
"SM100, MS100",solar,163,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,51,1
|
||||
"SM100, MS100",solar,163,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,52,1
|
||||
"SM100, MS100",solar,163,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,53,1
|
||||
"SM100, MS100",solar,163,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,54,1
|
||||
"SM100, MS100",solar,163,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,55,1
|
||||
"SM100, MS100",solar,163,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,56,1
|
||||
"SM100, MS100",solar,163,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,57,1
|
||||
"SM100, MS100",solar,163,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,58,1
|
||||
"SM100, MS100",solar,163,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,59,1
|
||||
"SM100, MS100",solar,163,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,60,1
|
||||
"SM100, MS100",solar,163,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,61,1
|
||||
"SM100, MS100",solar,163,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,62,1
|
||||
"SM100, MS100",solar,163,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,63,1
|
||||
"SM100, MS100",solar,163,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,64,1
|
||||
"SM100, MS100",solar,163,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,65,1
|
||||
"SM100, MS100",solar,163,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,66,1
|
||||
"SM100, MS100",solar,163,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,67,1
|
||||
"SM100, MS100",solar,163,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,68,1
|
||||
"SM100, MS100",solar,163,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,69,1
|
||||
"SM100, MS100",solar,163,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,70,1
|
||||
"SM100, MS100",solar,163,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,71,1
|
||||
"SM100, MS100",solar,163,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,72,1
|
||||
"SM100, MS100",solar,163,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,38,2
|
||||
"SM100, MS100",solar,163,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,40,2
|
||||
"SM100, MS100",solar,163,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,42,2
|
||||
"SM100, MS100",solar,163,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,44,2
|
||||
"SM100, MS100",solar,163,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,46,1
|
||||
"SM100, MS100",solar,163,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,47,1
|
||||
"SM100, MS100",solar,163,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,48,1
|
||||
"SM100, MS100",solar,163,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,49,1
|
||||
"SM100, MS100",solar,163,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,50,1
|
||||
"SM100, MS100",solar,163,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,51,1
|
||||
"SM100, MS100",solar,163,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,52,1
|
||||
"SM100, MS100",solar,163,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,53,1
|
||||
"SM100, MS100",solar,163,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,54,1
|
||||
"SM100, MS100",solar,163,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,55,1
|
||||
"SM100, MS100",solar,163,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,56,1
|
||||
"SM100, MS100",solar,163,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,57,1
|
||||
"SM100, MS100",solar,163,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,58,1
|
||||
"SM100, MS100",solar,163,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,59,1
|
||||
"SM100, MS100",solar,163,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,60,1
|
||||
"SM100, MS100",solar,163,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,61,1
|
||||
"SM100, MS100",solar,163,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,62,1
|
||||
"SM100, MS100",solar,163,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,63,1
|
||||
"SM100, MS100",solar,163,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,64,1
|
||||
"SM100, MS100",solar,163,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,65,1
|
||||
"SM100, MS100",solar,163,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,66,1
|
||||
"SM100, MS100",solar,163,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,67,1
|
||||
"SM100, MS100",solar,163,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,68,1
|
||||
"SM100, MS100",solar,163,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,69,1
|
||||
"SM100, MS100",solar,163,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,70,1
|
||||
"SM100, MS100",solar,163,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,71,1
|
||||
"SM200, MS200",solar,164,collectortemp,collector temperature (TS1),int16,C,false,sensor.solar_collector_temperature_(TS1),sensor.solar_collectortemp,8,0,1/10,0,1
|
||||
"SM200, MS200",solar,164,cylbottomtemp,cylinder bottom temperature (TS2),int16,C,false,sensor.solar_cylinder_bottom_temperature_(TS2),sensor.solar_cylbottomtemp,8,0,1/10,1,1
|
||||
"SM200, MS200",solar,164,solarpump,pump (PS1),boolean, ,false,binary_sensor.solar_pump_(PS1),binary_sensor.solar_solarpump,8,0,1,2,1
|
||||
@@ -5650,58 +5648,57 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"SM200, MS200",solar,164,turnondiff,pump turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_on_difference,number.solar_turnondiff,8,0,1/10,10,1
|
||||
"SM200, MS200",solar,164,turnoffdiff,pump turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_turn_off_difference,number.solar_turnoffdiff,8,0,1/10,11,1
|
||||
"SM200, MS200",solar,164,collector2temp,collector 2 temperature (TS7),int16,C,false,sensor.solar_collector_2_temperature_(TS7),sensor.solar_collector2temp,8,0,1/10,20,1
|
||||
"SM200, MS200",solar,164,cylmiddletemp,cylinder middle temperature (TS14),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS14),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM200, MS200",solar,164,ts3,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_ts3,8,0,1/10,21,1
|
||||
"SM200, MS200",solar,164,cylmiddletemp,cylinder middle temperature (TS3),int16,C,false,sensor.solar_cylinder_middle_temperature_(TS3),sensor.solar_cylmiddletemp,8,0,1/10,17,1
|
||||
"SM200, MS200",solar,164,retheatassist,return temperature heat assistance (TS4),int16,C,false,sensor.solar_return_temperature_heat_assistance_(TS4),sensor.solar_retheatassist,8,0,1/10,18,1
|
||||
"SM200, MS200",solar,164,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,22,1
|
||||
"SM200, MS200",solar,164,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,23,1
|
||||
"SM200, MS200",solar,164,ts8,(TS8),int16,C,false,sensor.solar_(TS8),sensor.solar_ts8,8,0,1/10,21,1
|
||||
"SM200, MS200",solar,164,ts16,(TS16),int16,C,false,sensor.solar_(TS16),sensor.solar_ts16,8,0,1/10,22,1
|
||||
"SM200, MS200",solar,164,heatassistvalve,heat assistance valve (M1),boolean, ,false,binary_sensor.solar_heat_assistance_valve_(M1),binary_sensor.solar_heatassistvalve,8,0,1,19,1
|
||||
"SM200, MS200",solar,164,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,24,1
|
||||
"SM200, MS200",solar,164,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,25,1
|
||||
"SM200, MS200",solar,164,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,26,1
|
||||
"SM200, MS200",solar,164,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,27,1
|
||||
"SM200, MS200",solar,164,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,28,1
|
||||
"SM200, MS200",solar,164,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,29,1
|
||||
"SM200, MS200",solar,164,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,30,1
|
||||
"SM200, MS200",solar,164,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,31,1
|
||||
"SM200, MS200",solar,164,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,32,1
|
||||
"SM200, MS200",solar,164,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,33,1
|
||||
"SM200, MS200",solar,164,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,34,1
|
||||
"SM200, MS200",solar,164,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,35,1
|
||||
"SM200, MS200",solar,164,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,36,1
|
||||
"SM200, MS200",solar,164,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,37,1
|
||||
"SM200, MS200",solar,164,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,38,1
|
||||
"SM200, MS200",solar,164,heatassistpower,heat assistance valve power (M1),uint8,%,false,sensor.solar_heat_assistance_valve_power_(M1),sensor.solar_heatassistpower,8,0,1,23,1
|
||||
"SM200, MS200",solar,164,solarpump2,pump 2 (PS4),boolean, ,false,binary_sensor.solar_pump_2_(PS4),binary_sensor.solar_solarpump2,8,0,1,24,1
|
||||
"SM200, MS200",solar,164,solarpump2mod,pump 2 modulation (PS4),uint8,%,false,sensor.solar_pump_2_modulation_(PS4),sensor.solar_solarpump2mod,8,0,1,25,1
|
||||
"SM200, MS200",solar,164,cyl2bottomtemp,second cylinder bottom temperature (TS5),int16,C,false,sensor.solar_second_cylinder_bottom_temperature_(TS5),sensor.solar_cyl2bottomtemp,8,0,1/10,26,1
|
||||
"SM200, MS200",solar,164,cyl3bottomtemp,third cylinder bottom temperature (TS11),int16,C,false,sensor.solar_third_cylinder_bottom_temperature_(TS11),sensor.solar_cyl3bottomtemp,8,0,1/10,27,1
|
||||
"SM200, MS200",solar,164,cyltoptemp,cylinder top temperature (TS10),int16,C,false,sensor.solar_cylinder_top_temperature_(TS10),sensor.solar_cyltoptemp,8,0,1/10,28,1
|
||||
"SM200, MS200",solar,164,heatexchangertemp,heat exchanger temperature (TS6),int16,C,false,sensor.solar_heat_exchanger_temperature_(TS6),sensor.solar_heatexchangertemp,8,0,1/10,29,1
|
||||
"SM200, MS200",solar,164,cylpumpmod,cylinder pump modulation (PS5),uint8,%,false,sensor.solar_cylinder_pump_modulation_(PS5),sensor.solar_cylpumpmod,8,0,1,30,1
|
||||
"SM200, MS200",solar,164,valvestatus,valve status,boolean, ,false,binary_sensor.solar_valve_status,binary_sensor.solar_valvestatus,8,0,1,31,1
|
||||
"SM200, MS200",solar,164,vs1status,valve status VS1,boolean, ,false,binary_sensor.solar_valve_status_VS1,binary_sensor.solar_vs1status,8,0,1,32,1
|
||||
"SM200, MS200",solar,164,vs3status,valve status VS3,boolean, ,false,binary_sensor.solar_valve_status_VS3,binary_sensor.solar_vs3status,8,0,1,33,1
|
||||
"SM200, MS200",solar,164,transferpump,transfer pump,boolean, ,false,binary_sensor.solar_transfer_pump,binary_sensor.solar_transferpump,8,0,1,34,1
|
||||
"SM200, MS200",solar,164,transferpumpmod,transfer pump modulation,uint8,%,false,sensor.solar_transfer_pump_modulation,sensor.solar_transferpumpmod,8,0,1,35,1
|
||||
"SM200, MS200",solar,164,collectormaxtemp,maximum collector temperature,uint8 (>=0<=0),C,true,number.solar_maximum_collector_temperature,number.solar_collectormaxtemp,8,0,1,36,1
|
||||
"SM200, MS200",solar,164,collectormintemp,minimum collector temperature,uint8 (>=0<=0),C,true,number.solar_minimum_collector_temperature,number.solar_collectormintemp,8,0,1,37,1
|
||||
"SM200, MS200",solar,164,energylasthour,energy last hour,uint24,Wh,false,sensor.solar_energy_last_hour,sensor.solar_energylasthour,8,0,1/10,13,2
|
||||
"SM200, MS200",solar,164,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,39,2
|
||||
"SM200, MS200",solar,164,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,41,2
|
||||
"SM200, MS200",solar,164,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,43,2
|
||||
"SM200, MS200",solar,164,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,45,2
|
||||
"SM200, MS200",solar,164,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,47,1
|
||||
"SM200, MS200",solar,164,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,48,1
|
||||
"SM200, MS200",solar,164,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,49,1
|
||||
"SM200, MS200",solar,164,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,50,1
|
||||
"SM200, MS200",solar,164,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,51,1
|
||||
"SM200, MS200",solar,164,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,52,1
|
||||
"SM200, MS200",solar,164,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,53,1
|
||||
"SM200, MS200",solar,164,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,54,1
|
||||
"SM200, MS200",solar,164,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,55,1
|
||||
"SM200, MS200",solar,164,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,56,1
|
||||
"SM200, MS200",solar,164,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,57,1
|
||||
"SM200, MS200",solar,164,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,58,1
|
||||
"SM200, MS200",solar,164,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,59,1
|
||||
"SM200, MS200",solar,164,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,60,1
|
||||
"SM200, MS200",solar,164,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,61,1
|
||||
"SM200, MS200",solar,164,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,62,1
|
||||
"SM200, MS200",solar,164,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,63,1
|
||||
"SM200, MS200",solar,164,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,64,1
|
||||
"SM200, MS200",solar,164,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,65,1
|
||||
"SM200, MS200",solar,164,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,66,1
|
||||
"SM200, MS200",solar,164,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,67,1
|
||||
"SM200, MS200",solar,164,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,68,1
|
||||
"SM200, MS200",solar,164,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,69,1
|
||||
"SM200, MS200",solar,164,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,70,1
|
||||
"SM200, MS200",solar,164,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,71,1
|
||||
"SM200, MS200",solar,164,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,72,1
|
||||
"SM200, MS200",solar,164,energytoday,total energy today,uint24,Wh,false,sensor.solar_total_energy_today,sensor.solar_energytoday,8,0,1,38,2
|
||||
"SM200, MS200",solar,164,energytotal,total energy,uint24,kWh,false,sensor.solar_total_energy,sensor.solar_energytotal,8,0,1/10,40,2
|
||||
"SM200, MS200",solar,164,pump2worktime,pump 2 working time,time,minutes,false,sensor.solar_pump_2_working_time,sensor.solar_pump2worktime,8,0,1,42,2
|
||||
"SM200, MS200",solar,164,m1worktime,differential control working time,time,minutes,false,sensor.solar_differential_control_working_time,sensor.solar_m1worktime,8,0,1,44,2
|
||||
"SM200, MS200",solar,164,heattransfersystem,heattransfer system,boolean (>=0<=0), ,true,switch.solar_heattransfer_system,switch.solar_heattransfersystem,8,0,1,46,1
|
||||
"SM200, MS200",solar,164,externalcyl,external cylinder,boolean (>=0<=0), ,true,switch.solar_external_cylinder,switch.solar_externalcyl,8,0,1,47,1
|
||||
"SM200, MS200",solar,164,thermaldisinfect,thermal disinfection,boolean (>=0<=0), ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,48,1
|
||||
"SM200, MS200",solar,164,heatmetering,heatmetering,boolean (>=0<=0), ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,49,1
|
||||
"SM200, MS200",solar,164,activated,activated,boolean (>=0<=0), ,true,switch.solar_activated,switch.solar_activated,8,0,1,50,1
|
||||
"SM200, MS200",solar,164,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog] (>=0<=0), ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,51,1
|
||||
"SM200, MS200",solar,164,solarpumpkick,solar pump kick,boolean (>=0<=0), ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,52,1
|
||||
"SM200, MS200",solar,164,plainwatermode,plain water mode,boolean (>=0<=0), ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,53,1
|
||||
"SM200, MS200",solar,164,doublematchflow,doublematchflow,boolean (>=0<=0), ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,54,1
|
||||
"SM200, MS200",solar,164,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=0),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,55,1
|
||||
"SM200, MS200",solar,164,turnondiff2,pump 2 turn on difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_on_difference,number.solar_turnondiff2,8,0,1/10,56,1
|
||||
"SM200, MS200",solar,164,turnoffdiff2,pump 2 turn off difference,uint8 (>=0<=0),C,true,number.solar_pump_2_turn_off_difference,number.solar_turnoffdiff2,8,0,1/10,57,1
|
||||
"SM200, MS200",solar,164,pump2kick,pump kick 2,boolean (>=0<=0), ,true,switch.solar_pump_kick_2,switch.solar_pump2kick,8,0,1,58,1
|
||||
"SM200, MS200",solar,164,climatezone,climate zone,uint8 (>=0<=0), ,true,number.solar_climate_zone,number.solar_climatezone,8,0,1,59,1
|
||||
"SM200, MS200",solar,164,collector1area,collector 1 area,uint16 (>=0<=0),m²,true,number.solar_collector_1_area,number.solar_collector1area,8,0,1/10,60,1
|
||||
"SM200, MS200",solar,164,collector1type,collector 1 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_1_type,select.solar_collector1type,8,0,1,61,1
|
||||
"SM200, MS200",solar,164,collector2area,collector 2 area,uint16 (>=0<=0),m²,true,number.solar_collector_2_area,number.solar_collector2area,8,0,1/10,62,1
|
||||
"SM200, MS200",solar,164,collector2type,collector 2 type,enum [flat\|vacuum] (>=0<=0), ,true,select.solar_collector_2_type,select.solar_collector2type,8,0,1,63,1
|
||||
"SM200, MS200",solar,164,cylpriority,cylinder priority,enum [cyl 1\|cyl 2] (>=0<=0), ,true,select.solar_cylinder_priority,select.solar_cylpriority,8,0,1,64,1
|
||||
"SM200, MS200",solar,164,heatcntflowtemp,heat counter flow temperature,uint16,C,false,sensor.solar_heat_counter_flow_temperature,sensor.solar_heatcntflowtemp,8,0,1/10,65,1
|
||||
"SM200, MS200",solar,164,heatcntrettemp,heat counter return temperature,uint16,C,false,sensor.solar_heat_counter_return_temperature,sensor.solar_heatcntrettemp,8,0,1/10,66,1
|
||||
"SM200, MS200",solar,164,heatcnt,heat counter impulses,uint8, ,false,sensor.solar_heat_counter_impulses,sensor.solar_heatcnt,8,0,1,67,1
|
||||
"SM200, MS200",solar,164,swapflowtemp,swap flow temperature (TS14),uint16,C,false,sensor.solar_swap_flow_temperature_(TS14),sensor.solar_swapflowtemp,8,0,1/10,68,1
|
||||
"SM200, MS200",solar,164,swaprettemp,swap return temperature (TS15),uint16,C,false,sensor.solar_swap_return_temperature_(TS15),sensor.solar_swaprettemp,8,0,1/10,69,1
|
||||
"SM200, MS200",solar,164,heatassiston,heat assistance on,int8 (>=0<=0),K,true,number.solar_heat_assistance_on,number.solar_heatassiston,8,0,1/10,70,1
|
||||
"SM200, MS200",solar,164,heatassistoff,heat assistance off,int8 (>=0<=0),K,true,number.solar_heat_assistance_off,number.solar_heatassistoff,8,0,1/10,71,1
|
||||
"HP Module",heatpump,252,airhumidity,relative air humidity,uint8,%,false,sensor.heatpump_relative_air_humidity,sensor.heatpump_airhumidity,9,0,1,0,1
|
||||
"HP Module",heatpump,252,dewtemperature,dew point temperature,uint8,C,false,sensor.heatpump_dew_point_temperature,sensor.heatpump_dewtemperature,9,0,1,1,1
|
||||
"HP Module",heatpump,252,curflowtemp,current flow temperature,int16,C,false,sensor.heatpump_current_flow_temperature,sensor.heatpump_curflowtemp,9,0,1/10,2,1
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -112,10 +112,10 @@ telegram_type_id,name,is_fetched
|
||||
0x02A0,RC300Curves,
|
||||
0x02A1,RC300Curves,
|
||||
0x02A2,RC300Curves,
|
||||
0x02A5,RC300Monitor,
|
||||
0x02A6,RC300Monitor,
|
||||
0x02A5,RC300Monitor,fetched
|
||||
0x02A6,CRFMonitor,
|
||||
0x02A7,RC300Monitor,
|
||||
0x02A8,RC300Monitor,
|
||||
0x02A8,CRFMonitor,
|
||||
0x02A9,RC300Monitor,
|
||||
0x02AA,RC300Monitor,
|
||||
0x02AB,RC300Monitor,
|
||||
@@ -171,7 +171,6 @@ telegram_type_id,name,is_fetched
|
||||
0x0468,HPSet,
|
||||
0x0469,HPSet,
|
||||
0x046A,HPSet,
|
||||
0x0470,RC300Summer2,fetched
|
||||
0x0471,RC300Summer2,
|
||||
0x0472,RC300Summer2,
|
||||
0x0473,RC300Summer2,
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "EMS-ESP",
|
||||
"version": "3.8.2",
|
||||
"version": "3.8.0",
|
||||
"description": "EMS-ESP WebUI",
|
||||
"homepage": "https://emsesp.org",
|
||||
"author": "proddy, emsesp.org",
|
||||
@@ -17,7 +17,7 @@
|
||||
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"pnpm:mock-rest\" \"vite preview\"",
|
||||
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite dev\"",
|
||||
"typesafe-i18n": "typesafe-i18n --no-watch",
|
||||
"build-webUI": "typesafe-i18n --no-watch && vite build && node progmem-generator.js",
|
||||
"build_webUI": "typesafe-i18n --no-watch && vite build && node progmem-generator.js",
|
||||
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
|
||||
"lint": "eslint . --fix",
|
||||
"standalone-devcontainer": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite --host\""
|
||||
@@ -26,25 +26,25 @@
|
||||
"@alova/adapter-xhr": "2.3.1",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@mui/icons-material": "^9.0.1",
|
||||
"@mui/material": "^9.0.1",
|
||||
"@mui/icons-material": "^7.3.9",
|
||||
"@mui/material": "^7.3.9",
|
||||
"@preact/compat": "^18.3.2",
|
||||
"@table-library/react-table-library": "4.1.15",
|
||||
"alova": "3.5.1",
|
||||
"alova": "^3.5.1",
|
||||
"async-validator": "^4.2.5",
|
||||
"etag": "^1.8.1",
|
||||
"formidable": "^3.5.4",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"magic-string": "^0.30.21",
|
||||
"mime-types": "^3.0.2",
|
||||
"preact": "^10.29.1",
|
||||
"react": "^19.2.6",
|
||||
"react-dom": "^19.2.6",
|
||||
"preact": "^10.29.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-icons": "^5.6.0",
|
||||
"react-router": "^7.15.0",
|
||||
"react-toastify": "^11.1.0",
|
||||
"react-router": "^7.13.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"typesafe-i18n": "^5.27.1",
|
||||
"typescript": "^6.0.3"
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.29.0",
|
||||
@@ -52,20 +52,19 @@
|
||||
"@preact/compat": "^18.3.2",
|
||||
"@preact/preset-vite": "^2.10.5",
|
||||
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
||||
"@types/node": "^25.6.0",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"axe-core": "^4.11.4",
|
||||
"axe-core": "^4.11.1",
|
||||
"concurrently": "^9.2.1",
|
||||
"eslint": "^10.3.0",
|
||||
"eslint": "^10.1.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"prettier": "^3.8.3",
|
||||
"prettier": "^3.8.1",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"terser": "^5.47.0",
|
||||
"typescript-eslint": "^8.59.2",
|
||||
"vite": "^8.0.11",
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-tsconfig-paths": "^6.1.1"
|
||||
"terser": "^5.46.1",
|
||||
"typescript-eslint": "^8.57.1",
|
||||
"vite": "^8.0.1",
|
||||
"vite-plugin-imagemin": "^0.6.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.33.4"
|
||||
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be"
|
||||
}
|
||||
|
||||
1152
interface/pnpm-lock.yaml
generated
1152
interface/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -24,26 +24,20 @@ let bundleStats = {
|
||||
other: { count: 0, uncompressed: 0, compressed: 0 }
|
||||
};
|
||||
|
||||
// AsyncWebHandler that performs the lookup.
|
||||
const generateWWWClass = () => `// Bundle Statistics:
|
||||
const generateWWWClass =
|
||||
() => `typedef std::function<void(const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash)> RouteRegistrationHandler;
|
||||
// Bundle Statistics:
|
||||
// - Total compressed size: ${(totalSize / 1000).toFixed(1)} KB
|
||||
// - Total uncompressed size: ${(Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) / 1000).toFixed(1)} KB
|
||||
// - Compression ratio: ${(((Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) - totalSize) / Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0)) * 100).toFixed(1)}%
|
||||
// - Generated on: ${new Date().toISOString()}
|
||||
|
||||
struct WWWAsset {
|
||||
${INDENT}const char * uri;
|
||||
${INDENT}const char * contentType;
|
||||
${INDENT}const uint8_t * content;
|
||||
${INDENT}size_t len;
|
||||
${INDENT}const char * etag; // already includes enclosing double quotes
|
||||
class WWWData {
|
||||
${INDENT}public:
|
||||
${INDENT.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) {
|
||||
${fileInfo.map((f) => `${INDENT.repeat(3)}handler("${f.uri}", "${f.mimeType}", ${f.variable}, ${f.size}, ${f.hash});`).join('\n')}
|
||||
${INDENT.repeat(2)}}
|
||||
};
|
||||
|
||||
static const WWWAsset WWW_ASSETS[] = {
|
||||
${fileInfo.map((f) => `${INDENT}{"${f.uri}", "${f.mimeType}", ${f.variable}, ${f.size}, "\\"${f.rawHash}\\""},`).join('\n')}
|
||||
};
|
||||
|
||||
static constexpr size_t WWW_ASSETS_COUNT = sizeof(WWW_ASSETS) / sizeof(WWW_ASSETS[0]);
|
||||
`;
|
||||
|
||||
const getFilesSync = (dir, files = []) => {
|
||||
@@ -78,7 +72,6 @@ const writeFile = (relativeFilePath, buffer) => {
|
||||
const zipBuffer = zlib.gzipSync(buffer, { level: 9 });
|
||||
// const hash = crypto.createHash('sha256').update(zipBuffer).digest('hex');
|
||||
const hash = etag(zipBuffer); // use smaller md5 instead of sha256
|
||||
const rawHash = hash.replace(/^"|"$/g, '');
|
||||
|
||||
zipBuffer.forEach((b) => {
|
||||
if (!(size % bytesPerLine)) {
|
||||
@@ -101,8 +94,7 @@ const writeFile = (relativeFilePath, buffer) => {
|
||||
mimeType,
|
||||
variable,
|
||||
size,
|
||||
hash,
|
||||
rawHash
|
||||
hash
|
||||
});
|
||||
|
||||
totalSize += size;
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import { type FC, memo, useContext, useEffect, useRef } from 'react';
|
||||
import { type FC, Suspense, lazy, memo, useContext, useEffect, useRef } from 'react';
|
||||
import { Navigate, Route, Routes } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import AuthenticatedRouting from 'AuthenticatedRouting';
|
||||
import SignIn from 'SignIn';
|
||||
import { RequireAuthenticated, RequireUnauthenticated } from 'components';
|
||||
import {
|
||||
LoadingSpinner,
|
||||
RequireAuthenticated,
|
||||
RequireUnauthenticated
|
||||
} from 'components';
|
||||
import { Authentication, AuthenticationContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
// Lazy load route components for better code splitting
|
||||
const SignIn = lazy(() => import('SignIn'));
|
||||
const AuthenticatedRouting = lazy(() => import('AuthenticatedRouting'));
|
||||
|
||||
interface SecurityRedirectProps {
|
||||
readonly message: string;
|
||||
readonly signOut?: boolean;
|
||||
@@ -39,32 +45,34 @@ const AppRouting: FC = memo(() => {
|
||||
|
||||
return (
|
||||
<Authentication>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/unauthorized"
|
||||
element={<RootRedirect message={LL.PLEASE_SIGNIN()} signOut />}
|
||||
/>
|
||||
<Route
|
||||
path="/fileUpdated"
|
||||
element={<RootRedirect message={LL.UPLOAD_SUCCESSFUL()} />}
|
||||
/>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<RequireUnauthenticated>
|
||||
<SignIn />
|
||||
</RequireUnauthenticated>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/*"
|
||||
element={
|
||||
<RequireAuthenticated>
|
||||
<AuthenticatedRouting />
|
||||
</RequireAuthenticated>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/unauthorized"
|
||||
element={<RootRedirect message={LL.PLEASE_SIGNIN()} signOut />}
|
||||
/>
|
||||
<Route
|
||||
path="/fileUpdated"
|
||||
element={<RootRedirect message={LL.UPLOAD_SUCCESSFUL()} />}
|
||||
/>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<RequireUnauthenticated>
|
||||
<SignIn />
|
||||
</RequireUnauthenticated>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/*"
|
||||
element={
|
||||
<RequireAuthenticated>
|
||||
<AuthenticatedRouting />
|
||||
</RequireAuthenticated>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</Authentication>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,77 +1,86 @@
|
||||
import { memo, useContext } from 'react';
|
||||
import { Suspense, lazy, memo, useContext } from 'react';
|
||||
import { Navigate, Route, Routes } from 'react-router';
|
||||
|
||||
import CustomEntities from 'app/main/CustomEntities';
|
||||
import Customizations from 'app/main/Customizations';
|
||||
import Dashboard from 'app/main/Dashboard';
|
||||
import Devices from 'app/main/Devices';
|
||||
import Help from 'app/main/Help';
|
||||
import Modules from 'app/main/Modules';
|
||||
import Scheduler from 'app/main/Scheduler';
|
||||
import Sensors from 'app/main/Sensors';
|
||||
import UserProfile from 'app/main/UserProfile';
|
||||
import APSettings from 'app/settings/APSettings';
|
||||
import ApplicationSettings from 'app/settings/ApplicationSettings';
|
||||
import DownloadUpload from 'app/settings/DownloadUpload';
|
||||
import MqttSettings from 'app/settings/MqttSettings';
|
||||
import NTPSettings from 'app/settings/NTPSettings';
|
||||
import Settings from 'app/settings/Settings';
|
||||
import Network from 'app/settings/network/Network';
|
||||
import Security from 'app/settings/security/Security';
|
||||
import APStatus from 'app/status/APStatus';
|
||||
import Activity from 'app/status/Activity';
|
||||
import HardwareStatus from 'app/status/HardwareStatus';
|
||||
import MqttStatus from 'app/status/MqttStatus';
|
||||
import NTPStatus from 'app/status/NTPStatus';
|
||||
import NetworkStatus from 'app/status/NetworkStatus';
|
||||
import Status from 'app/status/Status';
|
||||
import SystemLog from 'app/status/SystemLog';
|
||||
import Version from 'app/status/Version';
|
||||
import { Layout } from 'components';
|
||||
import { Layout, LoadingSpinner } from 'components';
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
|
||||
// Lazy load all route components for better code splitting
|
||||
const Dashboard = lazy(() => import('app/main/Dashboard'));
|
||||
const Devices = lazy(() => import('app/main/Devices'));
|
||||
const Sensors = lazy(() => import('app/main/Sensors'));
|
||||
const Help = lazy(() => import('app/main/Help'));
|
||||
const Customizations = lazy(() => import('app/main/Customizations'));
|
||||
const Scheduler = lazy(() => import('app/main/Scheduler'));
|
||||
const CustomEntities = lazy(() => import('app/main/CustomEntities'));
|
||||
const Modules = lazy(() => import('app/main/Modules'));
|
||||
const UserProfile = lazy(() => import('app/main/UserProfile'));
|
||||
|
||||
const Status = lazy(() => import('app/status/Status'));
|
||||
const HardwareStatus = lazy(() => import('app/status/HardwareStatus'));
|
||||
const Activity = lazy(() => import('app/status/Activity'));
|
||||
const SystemLog = lazy(() => import('app/status/SystemLog'));
|
||||
const MqttStatus = lazy(() => import('app/status/MqttStatus'));
|
||||
const NTPStatus = lazy(() => import('app/status/NTPStatus'));
|
||||
const APStatus = lazy(() => import('app/status/APStatus'));
|
||||
const NetworkStatus = lazy(() => import('app/status/NetworkStatus'));
|
||||
const Version = lazy(() => import('app/status/Version'));
|
||||
|
||||
const Settings = lazy(() => import('app/settings/Settings'));
|
||||
const ApplicationSettings = lazy(() => import('app/settings/ApplicationSettings'));
|
||||
const MqttSettings = lazy(() => import('app/settings/MqttSettings'));
|
||||
const NTPSettings = lazy(() => import('app/settings/NTPSettings'));
|
||||
const APSettings = lazy(() => import('app/settings/APSettings'));
|
||||
const DownloadUpload = lazy(() => import('app/settings/DownloadUpload'));
|
||||
const Network = lazy(() => import('app/settings/network/Network'));
|
||||
const Security = lazy(() => import('app/settings/security/Security'));
|
||||
|
||||
const AuthenticatedRouting = memo(() => {
|
||||
const { me } = useContext(AuthenticatedContext);
|
||||
return (
|
||||
<Layout>
|
||||
<Routes>
|
||||
<Route path="/dashboard/*" element={<Dashboard />} />
|
||||
<Route path="/devices/*" element={<Devices />} />
|
||||
<Route path="/sensors/*" element={<Sensors />} />
|
||||
<Route path="/help/*" element={<Help />} />
|
||||
<Route path="/user/*" element={<UserProfile />} />
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<Routes>
|
||||
<Route path="/dashboard/*" element={<Dashboard />} />
|
||||
<Route path="/devices/*" element={<Devices />} />
|
||||
<Route path="/sensors/*" element={<Sensors />} />
|
||||
<Route path="/help/*" element={<Help />} />
|
||||
<Route path="/user/*" element={<UserProfile />} />
|
||||
|
||||
<Route path="/status/*" element={<Status />} />
|
||||
<Route path="/status/hardwarestatus/*" element={<HardwareStatus />} />
|
||||
<Route path="/status/activity" element={<Activity />} />
|
||||
<Route path="/status/log" element={<SystemLog />} />
|
||||
<Route path="/status/mqtt" element={<MqttStatus />} />
|
||||
<Route path="/status/ntp" element={<NTPStatus />} />
|
||||
<Route path="/status/ap" element={<APStatus />} />
|
||||
<Route path="/status/network" element={<NetworkStatus />} />
|
||||
<Route path="/status/version" element={<Version />} />
|
||||
<Route path="/status/*" element={<Status />} />
|
||||
<Route path="/status/hardwarestatus/*" element={<HardwareStatus />} />
|
||||
<Route path="/status/activity" element={<Activity />} />
|
||||
<Route path="/status/log" element={<SystemLog />} />
|
||||
<Route path="/status/mqtt" element={<MqttStatus />} />
|
||||
<Route path="/status/ntp" element={<NTPStatus />} />
|
||||
<Route path="/status/ap" element={<APStatus />} />
|
||||
<Route path="/status/network" element={<NetworkStatus />} />
|
||||
<Route path="/status/version" element={<Version />} />
|
||||
|
||||
{me.admin && (
|
||||
<>
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
<Route path="/settings/application" element={<ApplicationSettings />} />
|
||||
<Route path="/settings/mqtt" element={<MqttSettings />} />
|
||||
<Route path="/settings/ntp" element={<NTPSettings />} />
|
||||
<Route path="/settings/ap" element={<APSettings />} />
|
||||
<Route path="/settings/modules" element={<Modules />} />
|
||||
<Route path="/settings/downloadUpload" element={<DownloadUpload />} />
|
||||
{me.admin && (
|
||||
<>
|
||||
<Route path="/settings" element={<Settings />} />
|
||||
<Route
|
||||
path="/settings/application"
|
||||
element={<ApplicationSettings />}
|
||||
/>
|
||||
<Route path="/settings/mqtt" element={<MqttSettings />} />
|
||||
<Route path="/settings/ntp" element={<NTPSettings />} />
|
||||
<Route path="/settings/ap" element={<APSettings />} />
|
||||
<Route path="/settings/modules" element={<Modules />} />
|
||||
<Route path="/settings/downloadUpload" element={<DownloadUpload />} />
|
||||
|
||||
<Route path="/settings/network/*" element={<Network />} />
|
||||
<Route path="/settings/security/*" element={<Security />} />
|
||||
<Route path="/settings/network/*" element={<Network />} />
|
||||
<Route path="/settings/security/*" element={<Security />} />
|
||||
|
||||
<Route path="/customizations" element={<Customizations />} />
|
||||
<Route path="/scheduler" element={<Scheduler />} />
|
||||
<Route path="/customentities" element={<CustomEntities />} />
|
||||
</>
|
||||
)}
|
||||
<Route path="/customizations" element={<Customizations />} />
|
||||
<Route path="/scheduler" element={<Scheduler />} />
|
||||
<Route path="/customentities" element={<CustomEntities />} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Route path="/*" element={<Navigate to="/" />} />
|
||||
</Routes>
|
||||
<Route path="/*" element={<Navigate to="/" />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</Layout>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@ import { toast } from 'react-toastify';
|
||||
|
||||
import ForwardIcon from '@mui/icons-material/Forward';
|
||||
import { Box, Button, Paper, Typography } from '@mui/material';
|
||||
import type { Theme } from '@mui/material/styles';
|
||||
|
||||
import * as AuthenticationApi from 'components/routing/authentication';
|
||||
import { useRequest } from 'alova/client';
|
||||
@@ -18,7 +17,7 @@ import { PROJECT_NAME } from 'env';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { SignInRequest } from 'types';
|
||||
import { onEnterCallback, updateValue } from 'utils';
|
||||
import { SIGN_IN_REQUEST_VALIDATOR, ValidationError, validate } from 'validators';
|
||||
import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators';
|
||||
|
||||
const SignIn = memo(() => {
|
||||
const authenticationContext = useContext(AuthenticationContext);
|
||||
@@ -37,7 +36,7 @@ const SignIn = memo(() => {
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
).onSuccess((response: { data: { access_token: string } }) => {
|
||||
).onSuccess((response) => {
|
||||
if (response.data) {
|
||||
authenticationContext.signIn(response.data.access_token);
|
||||
}
|
||||
@@ -74,11 +73,12 @@ const SignIn = memo(() => {
|
||||
await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest);
|
||||
await signIn();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
setProcessing(false);
|
||||
}
|
||||
}, [signInRequest, signIn, LL]);
|
||||
|
||||
// Memoize callback to prevent recreation on every render
|
||||
const submitOnEnter = useMemo(() => onEnterCallback(signIn), [signIn]);
|
||||
|
||||
// get rid of scrollbar
|
||||
@@ -92,15 +92,13 @@ const SignIn = memo(() => {
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={(theme: Theme) => ({
|
||||
display: 'flex',
|
||||
height: '100vh',
|
||||
margin: 'auto',
|
||||
padding: 2,
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
maxWidth: theme.breakpoints.values.sm
|
||||
})}
|
||||
display="flex"
|
||||
height="100vh"
|
||||
margin="auto"
|
||||
padding={2}
|
||||
justifyContent="center"
|
||||
flexDirection="column"
|
||||
maxWidth={(theme) => theme.breakpoints.values.sm}
|
||||
>
|
||||
<Paper
|
||||
sx={(theme) => ({
|
||||
@@ -113,18 +111,16 @@ const SignIn = memo(() => {
|
||||
width: '100%'
|
||||
})}
|
||||
>
|
||||
<Typography sx={{ mb: 1 }} variant="h4">
|
||||
<Typography mb={1} variant="h4">
|
||||
{PROJECT_NAME}
|
||||
</Typography>
|
||||
<LanguageSelector />
|
||||
<Box
|
||||
sx={{
|
||||
mt: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 1,
|
||||
alignItems: 'center'
|
||||
}}
|
||||
mt={1}
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
gap={1}
|
||||
alignItems="center"
|
||||
>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
|
||||
@@ -343,9 +343,9 @@ const CustomEntities = () => {
|
||||
return (
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
<Typography sx={{ mb: 2 }} color="warning" variant="body1">
|
||||
{LL.ENTITIES_HELP_1()}.
|
||||
</Typography>
|
||||
<Box mb={2} color="warning.main">
|
||||
<Typography variant="body1">{LL.ENTITIES_HELP_1()}.</Typography>
|
||||
</Box>
|
||||
|
||||
{renderEntity()}
|
||||
|
||||
@@ -361,8 +361,8 @@ const CustomEntities = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
<Box sx={{ mt: 2, display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box mt={2} display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1}>
|
||||
{numChanges > 0 && (
|
||||
<ButtonRow>
|
||||
<Button
|
||||
@@ -384,7 +384,7 @@ const CustomEntities = () => {
|
||||
</ButtonRow>
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{ flexWrap: 'nowrap', whiteSpace: 'nowrap' }}>
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<Button
|
||||
startIcon={<AddIcon />}
|
||||
variant="outlined"
|
||||
|
||||
@@ -7,7 +7,7 @@ import DoneIcon from '@mui/icons-material/Done';
|
||||
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutlined';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -28,7 +28,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
||||
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import { DeviceValueType, DeviceValueTypeNames, DeviceValueUOM_s } from './types';
|
||||
import type { EntityItem } from './types';
|
||||
@@ -136,7 +136,7 @@ const CustomEntitiesDialog = ({
|
||||
}
|
||||
onSave(processedItem);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [validator, editItem, onSave]);
|
||||
|
||||
@@ -178,7 +178,7 @@ const CustomEntitiesDialog = ({
|
||||
onChange={updateFormValue}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid sx={{ mt: 3 }}>
|
||||
<Grid mt={3}>
|
||||
<BlockFormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
@@ -215,7 +215,7 @@ const CustomEntitiesDialog = ({
|
||||
name="value"
|
||||
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
|
||||
type="string"
|
||||
value={editItem.value}
|
||||
value={editItem.value as string}
|
||||
variant="outlined"
|
||||
onChange={updateFormValue}
|
||||
fullWidth
|
||||
@@ -238,7 +238,7 @@ const CustomEntitiesDialog = ({
|
||||
)}
|
||||
{editItem.ram === 0 && (
|
||||
<>
|
||||
<Grid sx={{ mt: 3 }}>
|
||||
<Grid mt={3}>
|
||||
<BlockFormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
@@ -260,7 +260,7 @@ const CustomEntitiesDialog = ({
|
||||
margin="normal"
|
||||
sx={{ width: '11ch' }}
|
||||
type="string"
|
||||
value={editItem.device_id}
|
||||
value={editItem.device_id as string}
|
||||
onChange={updateFormValue}
|
||||
slotProps={{
|
||||
input: {
|
||||
@@ -280,7 +280,7 @@ const CustomEntitiesDialog = ({
|
||||
margin="normal"
|
||||
sx={{ width: '11ch' }}
|
||||
type="string"
|
||||
value={editItem.type_id}
|
||||
value={editItem.type_id as string}
|
||||
onChange={updateFormValue}
|
||||
slotProps={{
|
||||
input: {
|
||||
@@ -381,7 +381,7 @@ const CustomEntitiesDialog = ({
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="factor"
|
||||
label={LL.BITMASK()}
|
||||
value={editItem.factor}
|
||||
value={editItem.factor as string}
|
||||
sx={{ width: '11ch' }}
|
||||
variant="outlined"
|
||||
onChange={updateFormValue}
|
||||
@@ -404,7 +404,7 @@ const CustomEntitiesDialog = ({
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
{!creating && (
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box flexGrow={1}>
|
||||
<Button
|
||||
startIcon={<RemoveIcon />}
|
||||
variant="outlined"
|
||||
|
||||
@@ -470,10 +470,10 @@ const Customizations = () => {
|
||||
|
||||
const renderDeviceList = () => (
|
||||
<>
|
||||
<Typography sx={{ mb: 1 }} color="warning" variant="body1">
|
||||
{LL.CUSTOMIZATIONS_HELP_1()}.
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 2 }}>
|
||||
<Box mb={1} color="warning.main">
|
||||
<Typography variant="body1">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
|
||||
</Box>
|
||||
<Box display="flex" flexWrap="wrap" alignItems="center" gap={2}>
|
||||
{rename ? (
|
||||
<>
|
||||
<TextField
|
||||
@@ -570,22 +570,27 @@ const Customizations = () => {
|
||||
const renderDeviceData = () => {
|
||||
return (
|
||||
<>
|
||||
<Typography sx={{ mt: 1, mb: 1 }} color="warning" variant="body2">
|
||||
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}
|
||||
|
||||
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}
|
||||
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />=
|
||||
{LL.CUSTOMIZATIONS_HELP_4()}
|
||||
<OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()}
|
||||
|
||||
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
|
||||
</Typography>
|
||||
<Box color="warning.main">
|
||||
<Typography variant="body2" mt={1} mb={1}>
|
||||
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}
|
||||
|
||||
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}
|
||||
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />=
|
||||
{LL.CUSTOMIZATIONS_HELP_4()}
|
||||
<OptionIcon type="web_exclude" isSet={true} />=
|
||||
{LL.CUSTOMIZATIONS_HELP_5()}
|
||||
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Grid
|
||||
container
|
||||
mb={1}
|
||||
mt={0}
|
||||
spacing={2}
|
||||
direction="row"
|
||||
sx={{ mb: 1, mt: 0, justifyContent: 'flex-start', alignItems: 'center' }}
|
||||
justifyContent="flex-start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid>
|
||||
<TextField
|
||||
@@ -774,8 +779,8 @@ const Customizations = () => {
|
||||
</Button>
|
||||
</MessageBox>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1}>
|
||||
{numChanges !== 0 && (
|
||||
<ButtonRow>
|
||||
<Button
|
||||
|
||||
@@ -37,7 +37,7 @@ interface LabelValueProps {
|
||||
|
||||
const LabelValue = memo(({ label, value }: LabelValueProps) => (
|
||||
<Grid container direction="row">
|
||||
<Typography variant="body2" color="warning">
|
||||
<Typography variant="body2" color="warning.main">
|
||||
{label}:
|
||||
</Typography>
|
||||
<Typography variant="body2">{value}</Typography>
|
||||
@@ -131,7 +131,7 @@ const CustomizationsDialog = ({
|
||||
/>
|
||||
<LabelValue label={LL.WRITEABLE()} value={writeableIcon} />
|
||||
|
||||
<Box sx={{ mt: 1, mb: 2 }}>
|
||||
<Box mt={1} mb={2}>
|
||||
<EntityMaskToggle onUpdate={updateDeviceEntity} de={editItem} />
|
||||
</Box>
|
||||
|
||||
@@ -172,7 +172,7 @@ const CustomizationsDialog = ({
|
||||
</Grid>
|
||||
|
||||
{error && (
|
||||
<Typography sx={{ mt: 2 }} variant="body2" color="error">
|
||||
<Typography variant="body2" color="error" mt={2}>
|
||||
Error: Check min and max values
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { toast } from 'react-toastify';
|
||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import HelpOutlineIcon from '@mui/icons-material/HelpOutlined';
|
||||
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
||||
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
|
||||
import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore';
|
||||
import {
|
||||
@@ -262,8 +262,22 @@ const Dashboard = memo(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{!data.connected && (
|
||||
<MessageBox level="error" message={LL.EMS_BUS_WARNING() + '.'}>
|
||||
(
|
||||
<Link
|
||||
target="_blank"
|
||||
to="https://docs.emsesp.org/Troubleshooting#ems-bus-is-not-connecting"
|
||||
style={{ color: 'white' }}
|
||||
>
|
||||
{LL.ONLINE_HELP()}
|
||||
</Link>
|
||||
)
|
||||
</MessageBox>
|
||||
)}
|
||||
|
||||
{data.connected && data.nodes.length > 0 && !hasFavEntities && (
|
||||
<MessageBox sx={{ mb: 2 }} level="warning">
|
||||
<MessageBox mb={2} level="warning">
|
||||
<Typography>
|
||||
{LL.NO_DATA_1()}
|
||||
<Link to="/customizations" style={{ color: 'white' }}>
|
||||
@@ -280,12 +294,10 @@ const Dashboard = memo(() => {
|
||||
)}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
flexWrap: 'nowrap',
|
||||
whiteSpace: 'nowrap'
|
||||
}}
|
||||
display="flex"
|
||||
justifyContent="flex-end"
|
||||
flexWrap="nowrap"
|
||||
whiteSpace="nowrap"
|
||||
>
|
||||
<ToggleButtonGroup
|
||||
size="small"
|
||||
@@ -308,7 +320,7 @@ const Dashboard = memo(() => {
|
||||
</Box>
|
||||
|
||||
{data.nodes.length > 0 ? (
|
||||
<Box sx={{ mt: 1, justifyContent: 'center', flexDirection: 'column' }}>
|
||||
<Box mt={1} justifyContent="center" flexDirection="column">
|
||||
<IconContext.Provider
|
||||
value={{
|
||||
color: 'lightblue',
|
||||
@@ -375,8 +387,13 @@ const Dashboard = memo(() => {
|
||||
</IconContext.Provider>
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex' }}>
|
||||
<Typography sx={{ mt: 1 }} color="warning" variant="body1">
|
||||
<Box
|
||||
display="flex"
|
||||
// justifyContent="flex-end"
|
||||
// flexWrap="nowrap"
|
||||
// whiteSpace="nowrap"
|
||||
>
|
||||
<Typography mt={1} color="warning.main" variant="body1">
|
||||
no data
|
||||
</Typography>
|
||||
<Tooltip title={LL.DASHBOARD_1()}>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { memo } from 'react';
|
||||
import type { IconType } from 'react-icons';
|
||||
import { AiOutlineAlert, AiOutlineControl, AiOutlineGateway } from 'react-icons/ai';
|
||||
import { CgSmartHomeBoiler } from 'react-icons/cg';
|
||||
import { FaSolarPanel } from 'react-icons/fa';
|
||||
@@ -16,9 +15,14 @@ import { PiFan, PiGauge } from 'react-icons/pi';
|
||||
import { TiFlowSwitch, TiThermometer } from 'react-icons/ti';
|
||||
import { VscVmConnect } from 'react-icons/vsc';
|
||||
|
||||
import type { SvgIconProps } from '@mui/material';
|
||||
|
||||
import { DeviceType } from './types';
|
||||
|
||||
const deviceIconLookup: Record<DeviceType, IconType | null> = {
|
||||
const deviceIconLookup: Record<
|
||||
DeviceType,
|
||||
React.ComponentType<SvgIconProps> | null
|
||||
> = {
|
||||
[DeviceType.TEMPERATURESENSOR]: TiThermometer,
|
||||
[DeviceType.ANALOGSENSOR]: PiGauge,
|
||||
[DeviceType.BOILER]: CgSmartHomeBoiler,
|
||||
|
||||
@@ -546,7 +546,7 @@ const Devices = memo(() => {
|
||||
)
|
||||
</MessageBox>
|
||||
) : (
|
||||
<Box sx={{ justifyContent: 'center', flexDirection: 'column' }}>
|
||||
<Box justifyContent="center" flexDirection="column">
|
||||
<IconContext.Provider
|
||||
value={{
|
||||
color: 'lightblue',
|
||||
@@ -670,12 +670,12 @@ const Devices = memo(() => {
|
||||
}}
|
||||
>
|
||||
<Box sx={{ p: 1 }}>
|
||||
<Grid container sx={{ justifyContent: 'space-between' }}>
|
||||
<Typography noWrap variant="subtitle1" color="warning">
|
||||
<Grid container justifyContent="space-between">
|
||||
<Typography noWrap variant="subtitle1" color="warning.main">
|
||||
{deviceInfo.n} (
|
||||
{deviceInfo.tn})
|
||||
</Typography>
|
||||
<Grid sx={{ justifyContent: 'flex-end' }}>
|
||||
<Grid justifyContent="flex-end">
|
||||
<ButtonTooltip title={LL.CLOSE()}>
|
||||
<IconButton onClick={resetDeviceSelect} aria-label={LL.CLOSE()}>
|
||||
<HighlightOffIcon color="primary" sx={{ fontSize: 18 }} />
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
||||
import { ValidatedTextField } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
|
||||
import type { DeviceValue } from './types';
|
||||
@@ -67,7 +67,7 @@ const DevicesDialog = ({
|
||||
await validate(validator, editItem);
|
||||
onSave(editItem);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [validator, editItem, onSave]);
|
||||
|
||||
@@ -128,9 +128,9 @@ const DevicesDialog = ({
|
||||
<Dialog sx={dialogStyle} open={open} onClose={onClose}>
|
||||
<DialogTitle>{dialogTitle}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography sx={{ mb: 2 }} color="warning" variant="body2">
|
||||
{editItem.id.slice(2)}
|
||||
</Typography>
|
||||
<Box color="warning.main" mb={2}>
|
||||
<Typography variant="body2">{editItem.id.slice(2)}</Typography>
|
||||
</Box>
|
||||
<Grid container>
|
||||
<Grid size={12}>
|
||||
{editItem.l ? (
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Divider,
|
||||
Grid,
|
||||
Link,
|
||||
List,
|
||||
ListItem,
|
||||
@@ -43,7 +42,7 @@ interface CustomSupport {
|
||||
html: string | null;
|
||||
}
|
||||
|
||||
const DEFAULT_IMAGE_URL = 'https://emsesp.org/media/images/installer.jpeg';
|
||||
const DEFAULT_IMAGE_URL = 'https://emsesp.org/_media/images/installer.jpeg';
|
||||
|
||||
const SUPPORT_BOX_STYLES: SxProps<Theme> = {
|
||||
borderRadius: 3,
|
||||
@@ -72,6 +71,7 @@ const HelpComponent = () => {
|
||||
});
|
||||
const [imgError, setImgError] = useState<boolean>(false);
|
||||
|
||||
// Memoize the request method to prevent re-creation on every render
|
||||
const getCustomSupportMethod = useMemo(
|
||||
() => callAction({ action: 'getCustomSupport' }),
|
||||
[]
|
||||
@@ -146,9 +146,11 @@ const HelpComponent = () => {
|
||||
<SectionContent>
|
||||
{customSupport.html && (
|
||||
<Stack
|
||||
padding={1}
|
||||
mb={2}
|
||||
direction="row"
|
||||
divider={<Divider orientation="vertical" flexItem />}
|
||||
sx={{ padding: 1, mb: 2, ...SUPPORT_BOX_STYLES }}
|
||||
sx={SUPPORT_BOX_STYLES}
|
||||
>
|
||||
<Typography variant="subtitle1">
|
||||
<div dangerouslySetInnerHTML={{ __html: customSupport.html }} />
|
||||
@@ -183,9 +185,9 @@ const HelpComponent = () => {
|
||||
</List>
|
||||
)}
|
||||
|
||||
<Grid container spacing={2} sx={{ mt: 2, alignItems: 'center' }}>
|
||||
<Typography sx={{ mb: 1 }} color="warning" variant="body1">
|
||||
{LL.HELP_INFORMATION_4()}:
|
||||
<Box p={2} color="warning.main">
|
||||
<Typography mb={1} variant="body1">
|
||||
{LL.HELP_INFORMATION_4()}.
|
||||
</Typography>
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
@@ -195,11 +197,11 @@ const HelpComponent = () => {
|
||||
>
|
||||
{LL.SUPPORT_INFORMATION(0)}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
<Divider sx={{ mt: 4 }} />
|
||||
|
||||
<Typography color="white" variant="subtitle1" align="center" sx={{ mt: 1 }}>
|
||||
<Typography color="white" variant="subtitle1" align="center" mt={1}>
|
||||
©
|
||||
<Link
|
||||
target="_blank"
|
||||
|
||||
@@ -186,9 +186,9 @@ const Modules = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography sx={{ mb: 2 }} color="warning" variant="body1">
|
||||
{LL.MODULES_DESCRIPTION()}.
|
||||
</Typography>
|
||||
<Box mb={2} color="warning.main">
|
||||
<Typography variant="body1">{LL.MODULES_DESCRIPTION()}.</Typography>
|
||||
</Box>
|
||||
<Table
|
||||
data={{ nodes: modules }}
|
||||
theme={modules_theme}
|
||||
@@ -236,8 +236,8 @@ const Modules = () => {
|
||||
)}
|
||||
</Table>
|
||||
|
||||
<Box sx={{ mt: 1, display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box mt={1} display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1}>
|
||||
{numChanges !== 0 && (
|
||||
<ButtonRow>
|
||||
<Button
|
||||
|
||||
@@ -79,7 +79,7 @@ const ModulesDialog = ({
|
||||
label="Enabled"
|
||||
/>
|
||||
</Grid>
|
||||
<Box sx={{ mt: 2, mb: 1 }}>
|
||||
<Box mt={2} mb={1}>
|
||||
<TextField
|
||||
name="license"
|
||||
label="License Key"
|
||||
|
||||
@@ -2,12 +2,12 @@ import { memo } from 'react';
|
||||
|
||||
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||
import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
|
||||
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutlined';
|
||||
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
|
||||
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
|
||||
import StarIcon from '@mui/icons-material/Star';
|
||||
import StarOutlineIcon from '@mui/icons-material/StarOutlined';
|
||||
import StarOutlineIcon from '@mui/icons-material/StarOutline';
|
||||
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
|
||||
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
|
||||
import type { SvgIconProps } from '@mui/material';
|
||||
|
||||
@@ -358,9 +358,9 @@ const Scheduler = () => {
|
||||
return (
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
<Typography sx={{ mb: 2 }} color="warning" variant="body1">
|
||||
{LL.SCHEDULER_HELP_1()}.
|
||||
</Typography>
|
||||
<Box mb={2} color="warning.main">
|
||||
<Typography variant="body1">{LL.SCHEDULER_HELP_1()}.</Typography>
|
||||
</Box>
|
||||
{renderSchedule()}
|
||||
|
||||
{selectedScheduleItem && (
|
||||
@@ -375,8 +375,8 @@ const Scheduler = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1}>
|
||||
{numChanges !== 0 && (
|
||||
<ButtonRow>
|
||||
<Button
|
||||
@@ -398,7 +398,7 @@ const Scheduler = () => {
|
||||
</ButtonRow>
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{ flexWrap: 'nowrap', whiteSpace: 'nowrap' }}>
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<AddIcon />}
|
||||
|
||||
@@ -4,7 +4,7 @@ import AddIcon from '@mui/icons-material/Add';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import DoneIcon from '@mui/icons-material/Done';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutlined';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -26,7 +26,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
||||
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import { ScheduleFlag } from './types';
|
||||
import type { ScheduleItem } from './types';
|
||||
@@ -120,7 +120,7 @@ const SchedulerDialog = ({
|
||||
await validate(validator, itemToSave);
|
||||
onSave(itemToSave);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
},
|
||||
[validator, onSave]
|
||||
@@ -338,13 +338,11 @@ const SchedulerDialog = ({
|
||||
onChange={updateFormValue}
|
||||
/>
|
||||
{isTimerSchedule && (
|
||||
<Typography
|
||||
sx={{ ml: 2, mt: 4 }}
|
||||
color="warning"
|
||||
variant="body2"
|
||||
>
|
||||
{LL.SCHEDULER_HELP_2()}
|
||||
</Typography>
|
||||
<Box color="warning.main" ml={2} mt={4}>
|
||||
<Typography variant="body2">
|
||||
{LL.SCHEDULER_HELP_2()}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
@@ -393,7 +391,7 @@ const SchedulerDialog = ({
|
||||
|
||||
<DialogActions>
|
||||
{!creating && (
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Box flexGrow={1}>
|
||||
<Button
|
||||
startIcon={<RemoveIcon />}
|
||||
variant="outlined"
|
||||
|
||||
@@ -348,7 +348,7 @@ const Sensors = () => {
|
||||
|
||||
const addAnalogSensor = useCallback(() => {
|
||||
if (firstAvailableGPIO.current === undefined) {
|
||||
toast.error(LL.NO_GPIO());
|
||||
toast.error('No available GPIO found');
|
||||
return;
|
||||
}
|
||||
setCreating(true);
|
||||
@@ -591,14 +591,7 @@ const Sensors = () => {
|
||||
/>
|
||||
)}
|
||||
{sensorData?.analog_enabled === true && me.admin && (
|
||||
<Box
|
||||
sx={{
|
||||
mt: 2,
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'flex-end'
|
||||
}}
|
||||
>
|
||||
<Box mt={2} display="flex" flexWrap="wrap" justifyContent="flex-end">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import DoneIcon from '@mui/icons-material/Done';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutlined';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
import {
|
||||
Box,
|
||||
@@ -23,7 +23,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
||||
import { ValidatedTextField } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types';
|
||||
import type { AnalogSensor } from './types';
|
||||
@@ -172,7 +172,7 @@ const SensorsAnalogDialog = ({
|
||||
await validate(validator, editItem);
|
||||
onSave(editItem);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [validator, editItem, onSave]);
|
||||
|
||||
@@ -479,7 +479,7 @@ const SensorsAnalogDialog = ({
|
||||
)}
|
||||
</Grid>
|
||||
{fieldErrors && Object.keys(fieldErrors).length > 0 && (
|
||||
<Box sx={{ mt: 1 }}>
|
||||
<Box mt={1}>
|
||||
{Object.values(fieldErrors).map((errArr, idx) =>
|
||||
Array.isArray(errArr)
|
||||
? errArr.map((err, j) => (
|
||||
@@ -487,7 +487,7 @@ const SensorsAnalogDialog = ({
|
||||
key={`${idx}-${j}`}
|
||||
color="error"
|
||||
variant="caption"
|
||||
sx={{ display: 'block' }}
|
||||
display="block"
|
||||
>
|
||||
{err.message}
|
||||
</Typography>
|
||||
@@ -498,7 +498,7 @@ const SensorsAnalogDialog = ({
|
||||
)}
|
||||
{editItem.s && (
|
||||
<Grid>
|
||||
<Typography sx={{ mt: 1 }} color="warning" variant="body2">
|
||||
<Typography mt={1} color="warning.main" variant="body2">
|
||||
<WarningIcon
|
||||
fontSize="small"
|
||||
sx={{ mr: 1, verticalAlign: 'middle' }}
|
||||
@@ -511,7 +511,7 @@ const SensorsAnalogDialog = ({
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
{!creating && (
|
||||
<Box sx={{ flexGrow: 1, '& button': { mt: 0 } }}>
|
||||
<Box flexGrow={1} sx={{ '& button': { mt: 0 } }}>
|
||||
<Button
|
||||
startIcon={<RemoveIcon />}
|
||||
disabled={editItem.s}
|
||||
|
||||
@@ -4,6 +4,7 @@ import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import DoneIcon from '@mui/icons-material/Done';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
@@ -21,7 +22,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
||||
import { ValidatedTextField } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import type { TemperatureSensor } from './types';
|
||||
|
||||
@@ -84,7 +85,7 @@ const SensorsTemperatureDialog = ({
|
||||
await validate(validator, editItem);
|
||||
onSave(editItem);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [validator, editItem, onSave]);
|
||||
|
||||
@@ -110,9 +111,11 @@ const SensorsTemperatureDialog = ({
|
||||
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||
<DialogTitle>{dialogTitle}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography sx={{ mb: 2 }} color="warning" variant="body2">
|
||||
{LL.ID_OF(LL.SENSOR(0))}: {editItem.id}
|
||||
</Typography>
|
||||
<Box color="warning.main" mb={2}>
|
||||
<Typography variant="body2">
|
||||
{LL.ID_OF(LL.SENSOR(0))}: {editItem.id}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Grid container spacing={2}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
@@ -139,7 +142,7 @@ const SensorsTemperatureDialog = ({
|
||||
</Grid>
|
||||
{editItem.s && (
|
||||
<Grid>
|
||||
<Typography sx={{ mt: 1 }} color="warning" variant="body2">
|
||||
<Typography mt={1} color="warning.main" variant="body2">
|
||||
<WarningIcon
|
||||
fontSize="small"
|
||||
sx={{ mr: 1, verticalAlign: 'middle' }}
|
||||
|
||||
@@ -41,12 +41,8 @@ const UserProfileComponent = () => {
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
<Box sx={{ mt: 2, mb: 2, display: 'flex', alignItems: 'center' }}>
|
||||
<Typography
|
||||
sx={{ mr: 2, textAlign: 'center' }}
|
||||
color="warning"
|
||||
variant="body1"
|
||||
>
|
||||
<Box mt={2} mb={2} display="flex" alignItems="center">
|
||||
<Typography mr={2} variant="body1" align="center">
|
||||
{LL.LANGUAGE()}:
|
||||
</Typography>
|
||||
<LanguageSelector />
|
||||
|
||||
@@ -43,6 +43,16 @@ export interface Settings {
|
||||
modbus_port: number;
|
||||
modbus_max_clients: number;
|
||||
modbus_timeout: number;
|
||||
email_enabled: boolean;
|
||||
email_ssl?: boolean;
|
||||
email_starttls?: boolean;
|
||||
email_server: string;
|
||||
email_port: number;
|
||||
email_login: string;
|
||||
email_pass: string;
|
||||
email_sender: string;
|
||||
email_recp: string;
|
||||
email_subject: string;
|
||||
developer_mode: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { APSettingsType } from 'types';
|
||||
import { APProvisionMode } from 'types';
|
||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||
import { ValidationError, createAPSettingsValidator, validate } from 'validators';
|
||||
import { createAPSettingsValidator, validate } from 'validators';
|
||||
|
||||
export const isAPEnabled = ({ provision_mode }: APSettingsType) =>
|
||||
provision_mode === APProvisionMode.AP_MODE_ALWAYS ||
|
||||
@@ -86,7 +86,7 @@ const APSettings = () => {
|
||||
await validate(createAPSettingsValidator(data), data);
|
||||
await saveData();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [data, saveData]);
|
||||
|
||||
|
||||
@@ -28,12 +28,13 @@ import {
|
||||
FormLoader,
|
||||
MessageBox,
|
||||
SectionContent,
|
||||
ValidatedPasswordField,
|
||||
ValidatedTextField,
|
||||
useLayoutTitle
|
||||
} from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
import { API, getBoardProfile, readSettings, writeSettings } from '../../api/app';
|
||||
import { BOARD_PROFILES } from '../main/types';
|
||||
@@ -153,7 +154,7 @@ const ApplicationSettings = () => {
|
||||
setFieldErrors(undefined);
|
||||
await validate(createSettingsValidator(data), data);
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
} finally {
|
||||
await saveData();
|
||||
}
|
||||
@@ -351,6 +352,156 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
<Typography color="secondary">eMail</Typography>
|
||||
<BlockFormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={data.email_enabled}
|
||||
onChange={updateFormValue}
|
||||
name="email_enabled"
|
||||
disabled={!hardwareData.psram}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography color={!hardwareData.psram ? 'grey' : 'default'}>
|
||||
Enable eMail notification
|
||||
{!hardwareData.psram && (
|
||||
<Typography variant="caption">
|
||||
({LL.IS_REQUIRED('PSRAM')})
|
||||
</Typography>
|
||||
)}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{data.email_enabled && (
|
||||
<>
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
direction="row"
|
||||
justifyContent="flex-start"
|
||||
alignItems="flex-start"
|
||||
>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_server"
|
||||
label="SMTP Server"
|
||||
variant="outlined"
|
||||
value={data.email_server}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
sx={{ width: '12ch' }}
|
||||
name="email_port"
|
||||
variant="outlined"
|
||||
label="Port"
|
||||
value={numberValue(data.email_port)}
|
||||
type="number"
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid size={4} mt={!data.email_ssl && !data.email_starttls ? 0 : 3}>
|
||||
{!data.email_starttls && (
|
||||
<BlockFormControlLabel
|
||||
sx={{ width: '12ch' }}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={data.email_ssl}
|
||||
onChange={updateFormValue}
|
||||
name="email_ssl"
|
||||
disabled={
|
||||
data.email_starttls || data.email_ssl === undefined
|
||||
}
|
||||
/>
|
||||
}
|
||||
label="SSL/TLS"
|
||||
/>
|
||||
)}
|
||||
{!data.email_ssl && (
|
||||
<BlockFormControlLabel
|
||||
sx={{ width: '12ch' }}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={data.email_starttls}
|
||||
onChange={updateFormValue}
|
||||
name="email_starttls"
|
||||
disabled={
|
||||
data.email_ssl || data.email_starttls === undefined
|
||||
}
|
||||
/>
|
||||
}
|
||||
label="STARTTLS"
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_login"
|
||||
label="Login"
|
||||
variant="outlined"
|
||||
value={data.email_login}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_pass"
|
||||
label="Password"
|
||||
variant="outlined"
|
||||
value={data.email_pass}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_sender"
|
||||
label="From"
|
||||
variant="outlined"
|
||||
value={data.email_sender}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_recp"
|
||||
label="To"
|
||||
variant="outlined"
|
||||
value={data.email_recp}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="email_subject"
|
||||
label="Subject"
|
||||
variant="outlined"
|
||||
value={data.email_subject}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
<Typography sx={{ pb: 1, pt: 2 }} variant="h6" color="primary">
|
||||
{LL.SENSORS()}
|
||||
</Typography>
|
||||
@@ -677,7 +828,6 @@ const ApplicationSettings = () => {
|
||||
<MenuItem value={2}>EMS+</MenuItem>
|
||||
<MenuItem value={3}>HT3</MenuItem>
|
||||
<MenuItem value={4}>{LL.HARDWARE()}</MenuItem>
|
||||
<MenuItem value={5}>Auto</MenuItem>
|
||||
</TextField>
|
||||
</Grid>
|
||||
<Grid>
|
||||
@@ -772,7 +922,7 @@ const ApplicationSettings = () => {
|
||||
label={LL.REMOTE_TIMEOUT_EN()}
|
||||
/>
|
||||
{data.remote_timeout_en && (
|
||||
<Box sx={{ mt: 2 }}>
|
||||
<Box mt={2}>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="remote_timeout"
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Grid,
|
||||
Typography
|
||||
} from '@mui/material';
|
||||
import { Box, Button, Grid, Typography } from '@mui/material';
|
||||
|
||||
import * as SystemApi from 'api/system';
|
||||
import { API, callAction } from 'api/app';
|
||||
|
||||
import { dialogStyle } from '@/CustomTheme';
|
||||
import { useRequest } from 'alova/client';
|
||||
import type { APIcall } from 'app/main/types';
|
||||
import SystemMonitor from 'app/status/SystemMonitor';
|
||||
@@ -30,11 +19,15 @@ import {
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { saveFile } from 'utils';
|
||||
|
||||
interface DownloadButton {
|
||||
type: string;
|
||||
label: string | number;
|
||||
isGridButton: boolean;
|
||||
}
|
||||
|
||||
const DownloadUpload = () => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const [confirmBackup, setConfirmBackup] = useState<boolean>(false);
|
||||
|
||||
const [restarting, setRestarting] = useState<boolean>(false);
|
||||
|
||||
const { send: sendExportData } = useRequest(
|
||||
@@ -69,50 +62,45 @@ const DownloadUpload = () => {
|
||||
|
||||
useLayoutTitle(LL.DOWNLOAD_UPLOAD());
|
||||
|
||||
const handleCloseBackupDialog = useCallback(() => {
|
||||
setConfirmBackup(false);
|
||||
}, []);
|
||||
|
||||
const renderBackupDialog = useMemo(
|
||||
() => (
|
||||
<Dialog
|
||||
sx={dialogStyle}
|
||||
open={confirmBackup}
|
||||
onClose={handleCloseBackupDialog}
|
||||
>
|
||||
<DialogTitle>{LL.DOWNLOAD_SYSTEM_BACKUP()}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<WarningIcon color="warning" sx={{ fontSize: 18 }} />
|
||||
|
||||
{LL.WARNING_SYSTEM_BACKUP()}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
onClick={handleCloseBackupDialog}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => handleDownload('systembackup')()}
|
||||
color="primary"
|
||||
>
|
||||
{LL.DOWNLOAD(0)}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
),
|
||||
[confirmBackup, handleCloseBackupDialog, LL]
|
||||
const downloadButtons: DownloadButton[] = useMemo(
|
||||
() => [
|
||||
{
|
||||
type: 'settings',
|
||||
label: LL.SETTINGS_OF(LL.APPLICATION()),
|
||||
isGridButton: true
|
||||
},
|
||||
{
|
||||
type: 'customizations',
|
||||
label: LL.CUSTOMIZATIONS(),
|
||||
isGridButton: true
|
||||
},
|
||||
{
|
||||
type: 'entities',
|
||||
label: LL.CUSTOM_ENTITIES(0),
|
||||
isGridButton: true
|
||||
},
|
||||
{
|
||||
type: 'schedule',
|
||||
label: LL.SCHEDULE(0),
|
||||
isGridButton: true
|
||||
},
|
||||
{
|
||||
type: 'systembackup',
|
||||
label: LL.DOWNLOAD_SYSTEM_BACKUP(),
|
||||
isGridButton: true
|
||||
},
|
||||
{
|
||||
type: 'allvalues',
|
||||
label: LL.ALLVALUES(),
|
||||
isGridButton: false
|
||||
}
|
||||
],
|
||||
[LL]
|
||||
);
|
||||
|
||||
const handleDownload = useCallback(
|
||||
(type: string) => () => {
|
||||
void sendExportData(type);
|
||||
setConfirmBackup(false);
|
||||
},
|
||||
[sendExportData]
|
||||
);
|
||||
@@ -129,57 +117,58 @@ const DownloadUpload = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const gridButtons = downloadButtons.filter((btn) => btn.isGridButton);
|
||||
const standaloneButton = downloadButtons.find((btn) => !btn.isGridButton);
|
||||
|
||||
return (
|
||||
<SectionContent>
|
||||
{renderBackupDialog}
|
||||
|
||||
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
|
||||
{LL.DOWNLOAD(0)}
|
||||
</Typography>
|
||||
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography variant="body1" color="warning">
|
||||
{LL.DOWNLOAD_SETTINGS_TEXT()}:
|
||||
</Typography>
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => setConfirmBackup(true)}
|
||||
>
|
||||
{LL.DOWNLOAD_SYSTEM_BACKUP()}
|
||||
</Button>
|
||||
<Typography mb={1} variant="body1" color="warning">
|
||||
{LL.DOWNLOAD_SETTINGS_TEXT()}.
|
||||
</Typography>
|
||||
|
||||
<Grid container spacing={2}>
|
||||
{gridButtons.map((button) => (
|
||||
<Grid key={button.type}>
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={handleDownload(button.type)}
|
||||
>
|
||||
{button.label}
|
||||
</Button>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
|
||||
<Grid container spacing={2} sx={{ mt: 2, alignItems: 'center' }}>
|
||||
<Typography variant="body1" color="warning">
|
||||
{LL.DOWNLOAD_SETTINGS_TEXT2()}:
|
||||
</Typography>
|
||||
<Typography mt={2} mb={1} variant="body1" color="warning">
|
||||
{LL.DOWNLOAD_SETTINGS_TEXT2()}.
|
||||
</Typography>
|
||||
|
||||
{standaloneButton && (
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={handleDownload('allvalues')}
|
||||
onClick={handleDownload(standaloneButton.type)}
|
||||
>
|
||||
{LL.ALLVALUES()}
|
||||
{standaloneButton.label}
|
||||
</Button>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
||||
{LL.UPLOAD()}
|
||||
</Typography>
|
||||
|
||||
<Typography sx={{ pb: 2 }} color="warning" variant="body1">
|
||||
{LL.UPLOAD_TEXT()}:
|
||||
</Typography>
|
||||
<Box color="warning.main" sx={{ pb: 2 }}>
|
||||
<Typography variant="body1">{LL.UPLOAD_TEXT()}.</Typography>
|
||||
</Box>
|
||||
|
||||
<SingleUpload doRestart={doRestart} />
|
||||
<SingleUpload text={LL.UPLOAD_DRAG()} doRestart={doRestart} />
|
||||
</SectionContent>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { MqttSettingsType } from 'types';
|
||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||
import { ValidationError, createMqttSettingsValidator, validate } from 'validators';
|
||||
import { createMqttSettingsValidator, validate } from 'validators';
|
||||
|
||||
import { callAction } from '../../api/app';
|
||||
|
||||
@@ -94,7 +94,7 @@ const MqttSettings = () => {
|
||||
await validate(createMqttSettingsValidator(data), data);
|
||||
await saveData();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [data, saveData]);
|
||||
|
||||
@@ -129,7 +129,7 @@ const MqttSettings = () => {
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
<>
|
||||
<Box sx={{ display: 'flex', gap: 2, mb: 1 }}>
|
||||
<Box display="flex" gap={2} mb={1}>
|
||||
<BlockFormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { NTPSettingsType, Time } from 'types';
|
||||
import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
||||
|
||||
import { TIME_ZONES, selectedTimeZone, useTimeZoneSelectItems } from './TZ';
|
||||
@@ -133,7 +133,7 @@ const NTPSettings = () => {
|
||||
await validate(NTP_SETTINGS_VALIDATOR, data);
|
||||
await saveData();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [data, saveData]);
|
||||
|
||||
@@ -193,9 +193,9 @@ const NTPSettings = () => {
|
||||
{timeZoneItems}
|
||||
</ValidatedTextField>
|
||||
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
{!data.enabled && !dirtyFlags.length && (
|
||||
<Box sx={{ flexWrap: 'nowrap', whiteSpace: 'nowrap' }}>
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<ButtonRow>
|
||||
<Button
|
||||
onClick={openSetTime}
|
||||
@@ -259,9 +259,9 @@ const NTPSettings = () => {
|
||||
<Dialog sx={dialogStyle} open={settingTime} onClose={handleCloseSetTime}>
|
||||
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography color="warning" variant="body2">
|
||||
{LL.SET_TIME_TEXT()}
|
||||
</Typography>
|
||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
||||
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
|
||||
</Box>
|
||||
<TextField
|
||||
label={LL.LOCAL_TIME(0)}
|
||||
type="datetime-local"
|
||||
|
||||
@@ -156,13 +156,11 @@ const Settings = () => {
|
||||
<Divider />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
mt: 2,
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
flexWrap: 'nowrap',
|
||||
whiteSpace: 'nowrap'
|
||||
}}
|
||||
mt={2}
|
||||
display="flex"
|
||||
justifyContent="flex-end"
|
||||
flexWrap="nowrap"
|
||||
whiteSpace="nowrap"
|
||||
>
|
||||
<Button
|
||||
startIcon={<SettingsBackupRestoreIcon />}
|
||||
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { NetworkSettingsType } from 'types';
|
||||
import { updateValueDirty, useRest } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
import { createNetworkSettingsValidator } from 'validators/network';
|
||||
|
||||
import SystemMonitor from '../../status/SystemMonitor';
|
||||
@@ -116,7 +116,7 @@ const NetworkSettings = () => {
|
||||
await validate(createNetworkSettingsValidator(data), data);
|
||||
await saveData();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
deselectNetwork();
|
||||
}, [data, saveData, deselectNetwork]);
|
||||
|
||||
@@ -54,27 +54,19 @@ const GenerateToken = ({ username, onClose }: GenerateTokenProps) => {
|
||||
<DialogContent dividers>
|
||||
{token ? (
|
||||
<>
|
||||
<MessageBox
|
||||
message={LL.ACCESS_TOKEN_TEXT()}
|
||||
level="info"
|
||||
sx={{ mt: 2, mb: 2 }}
|
||||
/>
|
||||
<Box sx={{ mt: 2, mb: 2 }}>
|
||||
<MessageBox message={LL.ACCESS_TOKEN_TEXT()} level="info" my={2} />
|
||||
<Box mt={2} mb={2}>
|
||||
<TextField
|
||||
label="Token"
|
||||
multiline
|
||||
value={token.token}
|
||||
fullWidth
|
||||
slotProps={{
|
||||
input: {
|
||||
readOnly: true
|
||||
}
|
||||
}}
|
||||
contentEditable={false}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<Box sx={{ m: 4, textAlign: 'center' }}>
|
||||
<Box m={4} textAlign="center">
|
||||
<LinearProgress />
|
||||
<Typography variant="h6">{LL.GENERATING_TOKEN()}…</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -240,16 +240,12 @@ const ManageUsers = () => {
|
||||
</Table>
|
||||
|
||||
{noAdminConfigured() && (
|
||||
<MessageBox
|
||||
level="warning"
|
||||
message={LL.USER_WARNING()}
|
||||
sx={{ mt: 2, mb: 2 }}
|
||||
/>
|
||||
<MessageBox level="warning" message={LL.USER_WARNING()} my={2} />
|
||||
)}
|
||||
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
{changed !== 0 && (
|
||||
<Box sx={{ flexGrow: 1, '& button': { mt: 2 } }}>
|
||||
<Box flexGrow={1} sx={{ '& button': { mt: 2 } }}>
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
@@ -274,7 +270,7 @@ const ManageUsers = () => {
|
||||
</ButtonRow>
|
||||
</Box>
|
||||
)}
|
||||
<Box sx={{ flexWrap: 'nowrap', whiteSpace: 'nowrap' }}>
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<PersonAddIcon />}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { AuthenticatedContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { SecuritySettingsType } from 'types';
|
||||
import { updateValueDirty, useRest } from 'utils';
|
||||
import { SECURITY_SETTINGS_VALIDATOR, ValidationError, validate } from 'validators';
|
||||
import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators';
|
||||
|
||||
const SecuritySettings = () => {
|
||||
const { LL } = useI18nContext();
|
||||
@@ -58,7 +58,7 @@ const SecuritySettings = () => {
|
||||
await saveData();
|
||||
await authenticatedContext.refresh();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}, [data, saveData, authenticatedContext]);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
import type { UserType } from 'types';
|
||||
import { updateValue } from 'utils';
|
||||
import { ValidationError, validate } from 'validators';
|
||||
import { validate } from 'validators';
|
||||
|
||||
interface UserFormProps {
|
||||
creating: boolean;
|
||||
@@ -69,7 +69,7 @@ const User: FC<UserFormProps> = ({
|
||||
await validate(validator, user);
|
||||
onDoneEditing();
|
||||
} catch (error) {
|
||||
setFieldErrors((error as ValidationError).fieldErrors);
|
||||
setFieldErrors(error as ValidateFieldsError);
|
||||
}
|
||||
}
|
||||
}, [user, validator, onDoneEditing]);
|
||||
|
||||
@@ -266,7 +266,7 @@ const SystemLog = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid container spacing={2} sx={{ alignItems: 'center' }}>
|
||||
<Grid container spacing={2} alignItems="center">
|
||||
<Grid>
|
||||
<TextField
|
||||
name="level"
|
||||
|
||||
@@ -118,15 +118,17 @@ const SystemMonitor = () => {
|
||||
p: 3
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
|
||||
<Box display="flex" alignItems="center" flexDirection="column">
|
||||
<img
|
||||
src="/app/icon.png"
|
||||
alt="EMS-ESP"
|
||||
style={{ width: '40px', height: '40px', marginBottom: '16px' }}
|
||||
/>
|
||||
<Typography
|
||||
sx={{ color: 'secondary', fontWeight: 400, textAlign: 'center' }}
|
||||
color="secondary"
|
||||
variant="h6"
|
||||
fontWeight={400}
|
||||
textAlign="center"
|
||||
>
|
||||
{statusMessage}
|
||||
</Typography>
|
||||
@@ -146,14 +148,11 @@ const SystemMonitor = () => {
|
||||
</MessageBox>
|
||||
) : (
|
||||
<>
|
||||
<Typography
|
||||
sx={{ mt: 2, fontWeight: 400, textAlign: 'center' }}
|
||||
variant="h6"
|
||||
>
|
||||
<Typography mt={2} variant="h6" fontWeight={400} textAlign="center">
|
||||
{LL.PLEASE_WAIT()}…
|
||||
</Typography>
|
||||
{isUploading && (
|
||||
<Box sx={{ width: '100%', pl: 2, pr: 2, py: 2 }}>
|
||||
<Box width="100%" pl={2} pr={2} py={2}>
|
||||
<LinearProgressWithLabel value={progressValue} />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
DialogTitle,
|
||||
Grid,
|
||||
IconButton,
|
||||
Link,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
@@ -274,8 +274,6 @@ const InstallDialog = memo(
|
||||
fetchDevVersion,
|
||||
latestVersion,
|
||||
latestDevVersion,
|
||||
upgradeImportantMessageType,
|
||||
downloadOnly,
|
||||
platform,
|
||||
LL,
|
||||
onClose,
|
||||
@@ -285,8 +283,6 @@ const InstallDialog = memo(
|
||||
fetchDevVersion: boolean;
|
||||
latestVersion?: VersionInfo;
|
||||
latestDevVersion?: VersionInfo;
|
||||
upgradeImportantMessageType: number;
|
||||
downloadOnly: boolean;
|
||||
platform: string;
|
||||
LL: TranslationFunctions;
|
||||
onClose: () => void;
|
||||
@@ -309,33 +305,12 @@ const InstallDialog = memo(
|
||||
{`${LL.INSTALL()} ${fetchDevVersion ? LL.DEVELOPMENT() : LL.STABLE()} Firmware`}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography sx={{ mb: 2 }}>
|
||||
<Typography mb={2}>
|
||||
{LL.INSTALL_VERSION(
|
||||
downloadOnly ? LL.DOWNLOAD(1) : LL.INSTALL(),
|
||||
LL.INSTALL(),
|
||||
fetchDevVersion ? latestDevVersion?.name : latestVersion?.name
|
||||
)}
|
||||
</Typography>
|
||||
{upgradeImportantMessageType === 2 && LL.UPGRADE_IMPORTANT_MESSAGES_2()}
|
||||
{upgradeImportantMessageType === 1 && (
|
||||
<>
|
||||
{LL.UPGRADE_IMPORTANT_MESSAGES_1()}
|
||||
<Typography sx={{ mt: 2 }}>
|
||||
<Link to="/settings/downloadUpload" style={{ color: 'lightblue' }}>
|
||||
{LL.DOWNLOAD_SYSTEM_BACKUP()}
|
||||
</Link>
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
<Typography sx={{ mt: 2 }}>
|
||||
<Link
|
||||
to="https://docs.emsesp.org/FAQ#upgrading-the-firmware"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
style={{ color: 'lightblue' }}
|
||||
>
|
||||
{LL.ONLINE_HELP()}
|
||||
</Link>
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
@@ -352,25 +327,18 @@ const InstallDialog = memo(
|
||||
onClick={onClose}
|
||||
color="primary"
|
||||
>
|
||||
<Link
|
||||
to={binURL}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
style={{ color: 'lightblue', textDecoration: 'none' }}
|
||||
>
|
||||
<Link underline="none" target="_blank" href={binURL} color="primary">
|
||||
{LL.DOWNLOAD(0)}
|
||||
</Link>
|
||||
</Button>
|
||||
{!downloadOnly && (
|
||||
<Button
|
||||
startIcon={<WarningIcon color="warning" />}
|
||||
variant="outlined"
|
||||
onClick={() => onInstall(binURL)}
|
||||
color="primary"
|
||||
>
|
||||
{LL.INSTALL()}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
startIcon={<WarningIcon color="warning" />}
|
||||
variant="outlined"
|
||||
onClick={() => onInstall(binURL)}
|
||||
color="primary"
|
||||
>
|
||||
{LL.INSTALL()}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
@@ -399,9 +367,7 @@ const InstallPartitionDialog = memo(
|
||||
{LL.INSTALL()} {LL.STORED_VERSIONS()}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Typography sx={{ mb: 2 }}>
|
||||
{LL.INSTALL_VERSION(LL.INSTALL(), version)}
|
||||
</Typography>
|
||||
<Typography mb={2}>{LL.INSTALL_VERSION(LL.INSTALL(), version)}</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
@@ -453,7 +419,6 @@ const Version = () => {
|
||||
const [stableUpgradeAvailable, setStableUpgradeAvailable] =
|
||||
useState<boolean>(false);
|
||||
const [internetLive, setInternetLive] = useState<boolean>(false);
|
||||
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
|
||||
const [showVersionInfo, setShowVersionInfo] = useState<number>(0); // 1 = stable, 2 = dev, 3 = partition
|
||||
const [firmwareSize, setFirmwareSize] = useState<number>(0);
|
||||
|
||||
@@ -479,9 +444,6 @@ const Version = () => {
|
||||
error
|
||||
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
|
||||
const systemData = event.data as VersionData;
|
||||
if (systemData.arduino_version.startsWith('Tasmota')) {
|
||||
setDownloadOnly(true);
|
||||
}
|
||||
setUsingDevVersion(systemData.emsesp_version.includes('dev'));
|
||||
});
|
||||
|
||||
@@ -497,26 +459,6 @@ const Version = () => {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const [upgradeImportantMessageType, setUpgradeImportantMessageType] =
|
||||
useState<number>(0);
|
||||
|
||||
const { send: checkUpgradeImportantMessages } = useRequest(
|
||||
(version: string) =>
|
||||
callAction({ action: 'upgradeImportantMessages', param: version }),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
)
|
||||
.onSuccess((event) => {
|
||||
const upgradeImportantMessageType_n = (
|
||||
event.data as { upgradeImportantMessageType: number }
|
||||
).upgradeImportantMessageType;
|
||||
setUpgradeImportantMessageType(upgradeImportantMessageType_n);
|
||||
})
|
||||
.onError((error) => {
|
||||
toast.error(String(error.error?.message || 'An error occurred'));
|
||||
});
|
||||
|
||||
// Memoized values
|
||||
const platform = useMemo(() => (data ? getPlatform(data) : ''), [data]);
|
||||
|
||||
@@ -582,16 +524,10 @@ const Version = () => {
|
||||
[]
|
||||
);
|
||||
|
||||
const showFirmwareDialog = useCallback(
|
||||
(useDevVersion: boolean) => {
|
||||
setFetchDevVersion(useDevVersion);
|
||||
void checkUpgradeImportantMessages(
|
||||
useDevVersion ? latestDevVersion?.name : latestVersion?.name
|
||||
);
|
||||
setOpenInstallDialog(true);
|
||||
},
|
||||
[latestDevVersion, latestVersion, fetchDevVersion]
|
||||
);
|
||||
const showFirmwareDialog = useCallback((useDevVersion: boolean) => {
|
||||
setFetchDevVersion(useDevVersion);
|
||||
setOpenInstallDialog(true);
|
||||
}, []);
|
||||
|
||||
const closeInstallDialog = useCallback(() => {
|
||||
setOpenInstallDialog(false);
|
||||
@@ -693,8 +629,8 @@ const Version = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box sx={{ p: 2, border: '1px solid #565656', borderRadius: 2 }}>
|
||||
<Typography sx={{ mb: 1 }} variant="h6" color="primary">
|
||||
<Box p={2} border="1px solid grey" borderRadius={2}>
|
||||
<Typography mb={1} variant="h6" color="primary">
|
||||
{LL.THIS_VERSION()}
|
||||
</Typography>
|
||||
|
||||
@@ -759,7 +695,7 @@ const Version = () => {
|
||||
|
||||
{internetLive ? (
|
||||
<>
|
||||
<Typography sx={{ mt: 4, mb: 1 }} variant="h6" color="primary">
|
||||
<Typography mt={4} mb={1} variant="h6" color="primary">
|
||||
{LL.AVAILABLE_VERSION()}
|
||||
</Typography>
|
||||
|
||||
@@ -781,7 +717,7 @@ const Version = () => {
|
||||
</Grid>
|
||||
<Grid size={{ xs: 8, md: 10 }}>
|
||||
{otherPartitions.map((partition) => (
|
||||
<Typography key={partition.partition} sx={{ mb: 1 }}>
|
||||
<Typography key={partition.partition} mb={1}>
|
||||
{partition.version}
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
@@ -847,7 +783,7 @@ const Version = () => {
|
||||
</Grid>
|
||||
</>
|
||||
) : (
|
||||
<Typography sx={{ mt: 2 }} color="warning">
|
||||
<Typography mt={2} color="warning">
|
||||
<WarningIcon color="warning" sx={{ verticalAlign: 'middle', mr: 2 }} />
|
||||
{LL.INTERNET_CONNECTION_REQUIRED()}
|
||||
</Typography>
|
||||
@@ -871,8 +807,6 @@ const Version = () => {
|
||||
fetchDevVersion={fetchDevVersion}
|
||||
latestVersion={latestVersion}
|
||||
latestDevVersion={latestDevVersion}
|
||||
upgradeImportantMessageType={upgradeImportantMessageType}
|
||||
downloadOnly={downloadOnly}
|
||||
platform={platform}
|
||||
LL={LL}
|
||||
onClose={closeInstallDialog}
|
||||
@@ -889,7 +823,7 @@ const Version = () => {
|
||||
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
||||
{LL.UPLOAD()}
|
||||
</Typography>
|
||||
<SingleUpload doRestart={doRestart} />
|
||||
<SingleUpload text={LL.UPLOAD_DROP_TEXT()} doRestart={doRestart} />
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
@@ -908,7 +842,6 @@ const Version = () => {
|
||||
locale,
|
||||
openInstallDialog,
|
||||
fetchDevVersion,
|
||||
downloadOnly,
|
||||
me.admin,
|
||||
showButtons,
|
||||
handleVersionInfoClose,
|
||||
|
||||
@@ -53,16 +53,12 @@ const MessageBox: FC<PropsWithChildren<MessageBoxProps>> = ({
|
||||
|
||||
return (
|
||||
<Box
|
||||
p={2}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
borderRadius={1}
|
||||
sx={{ backgroundColor, color: 'white', ...sx }}
|
||||
{...rest}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
borderRadius: 1,
|
||||
backgroundColor,
|
||||
color: 'white',
|
||||
p: 2,
|
||||
...sx
|
||||
}}
|
||||
>
|
||||
<Icon />
|
||||
{(message || children) && (
|
||||
|
||||
@@ -29,7 +29,7 @@ const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => {
|
||||
() => (
|
||||
<>
|
||||
<Toolbar disableGutters>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', p: 2 }}>
|
||||
<Box display="flex" alignItems="center" px={2}>
|
||||
<LayoutDrawerLogo src="/app/icon.png" alt={PROJECT_NAME} />
|
||||
<Typography variant="h6">{PROJECT_NAME}</Typography>
|
||||
</Box>
|
||||
|
||||
@@ -51,7 +51,9 @@ const LayoutMenuComponent = () => {
|
||||
sx={{ my: 0 }}
|
||||
slotProps={{
|
||||
primary: {
|
||||
sx: { fontWeight: 600, mb: '2px', color: 'lightblue' }
|
||||
fontWeight: '600',
|
||||
mb: '2px',
|
||||
color: 'lightblue'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -32,16 +32,8 @@ const FormLoaderComponent = ({ errorMessage, onRetry }: FormLoaderProps) => {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
m: 2,
|
||||
py: 2,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column'
|
||||
}}
|
||||
>
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Box m={2} py={2} display="flex" alignItems="center" flexDirection="column">
|
||||
<Box py={2}>
|
||||
<CircularProgress size={100} />
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -15,14 +15,12 @@ const circularProgressStyles: SxProps<Theme> = (theme: Theme) => ({
|
||||
const LoadingSpinner = ({ height = '100%' }: LoadingSpinnerProps) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
padding: 2,
|
||||
height
|
||||
}}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
flexDirection="column"
|
||||
padding={2}
|
||||
height={height}
|
||||
>
|
||||
<CircularProgress sx={circularProgressStyles} size={100} />
|
||||
</Box>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// drag/drop code inspired by Prince Azubuike from https://medium.com/@dprincecoder/creating-a-drag-and-drop-file-upload-component-in-react-a-step-by-step-guide-4d93b6cc21e0
|
||||
// Code inspired by Prince Azubuike from https://medium.com/@dprincecoder/creating-a-drag-and-drop-file-upload-component-in-react-a-step-by-step-guide-4d93b6cc21e0
|
||||
import {
|
||||
type ChangeEvent,
|
||||
type DragEvent,
|
||||
@@ -6,28 +6,12 @@ import {
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
||||
import UploadIcon from '@mui/icons-material/Upload';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Typography,
|
||||
styled
|
||||
} from '@mui/material';
|
||||
import { Box, Button, Typography, styled } from '@mui/material';
|
||||
|
||||
import { callAction } from 'api/app';
|
||||
|
||||
import { dialogStyle } from '@/CustomTheme';
|
||||
import { useRequest } from 'alova/client';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const DocumentUploader = styled(Box)<{ active?: boolean }>(({ theme, active }) => ({
|
||||
@@ -74,29 +58,6 @@ const DragNdrop = ({ text, onFileSelected }: DragNdropProps) => {
|
||||
const [dragged, setDragged] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const { LL } = useI18nContext();
|
||||
const [showUpgradeDialog, setShowUpgradeDialog] = useState(false);
|
||||
const [upgradeImportantMessageType, setUpgradeImportantMessageType] =
|
||||
useState<number>(0);
|
||||
|
||||
const { send: checkUpgradeImportantMessages } = useRequest(
|
||||
(version: string) =>
|
||||
callAction({ action: 'upgradeImportantMessages', param: version }),
|
||||
{
|
||||
immediate: false
|
||||
}
|
||||
)
|
||||
.onSuccess((event) => {
|
||||
const upgradeImportantMessageType_n = (
|
||||
event.data as { upgradeImportantMessageType: number }
|
||||
).upgradeImportantMessageType;
|
||||
setUpgradeImportantMessageType(upgradeImportantMessageType_n);
|
||||
if (upgradeImportantMessageType_n === 0) {
|
||||
onFileSelected(file);
|
||||
}
|
||||
})
|
||||
.onError((error) => {
|
||||
toast.error(String(error.error?.message || 'An error occurred'));
|
||||
});
|
||||
|
||||
const checkFileExtension = (file: File) => {
|
||||
const validExtensions = ['.json', '.bin', '.md5'];
|
||||
@@ -136,8 +97,9 @@ const DragNdrop = ({ text, onFileSelected }: DragNdropProps) => {
|
||||
|
||||
const handleUploadClick = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
void checkUpgradeImportantMessages(file?.name || '');
|
||||
setShowUpgradeDialog(true);
|
||||
if (file) {
|
||||
onFileSelected(file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBrowseClick = () => {
|
||||
@@ -196,56 +158,6 @@ const DragNdrop = ({ text, onFileSelected }: DragNdropProps) => {
|
||||
{LL.UPLOAD()}
|
||||
</Button>
|
||||
</Box>
|
||||
{showUpgradeDialog && upgradeImportantMessageType > 0 && (
|
||||
<Dialog
|
||||
sx={dialogStyle}
|
||||
open={showUpgradeDialog}
|
||||
onClose={() => setShowUpgradeDialog(false)}
|
||||
>
|
||||
<DialogTitle>
|
||||
<WarningIcon
|
||||
color="warning"
|
||||
sx={{ fontSize: 18, verticalAlign: 'middle' }}
|
||||
/>
|
||||
|
||||
{LL.UPGRADE_IMPORTANT_MESSAGES()}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
{upgradeImportantMessageType === 2 &&
|
||||
LL.UPGRADE_IMPORTANT_MESSAGES_2()}
|
||||
{upgradeImportantMessageType === 1 &&
|
||||
LL.UPGRADE_IMPORTANT_MESSAGES_1()}
|
||||
<Typography sx={{ mt: 2 }}>
|
||||
<Link
|
||||
to="https://docs.emsesp.org/FAQ#upgrading-the-firmware"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
style={{ color: 'lightblue' }}
|
||||
>
|
||||
{LL.ONLINE_HELP()}
|
||||
</Link>
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => setShowUpgradeDialog(false)}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<UploadIcon />}
|
||||
variant="outlined"
|
||||
onClick={() => onFileSelected(file)}
|
||||
color="primary"
|
||||
>
|
||||
{LL.UPLOAD()}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</DocumentUploader>
|
||||
|
||||
@@ -13,10 +13,11 @@ import DragNdrop from './DragNdrop';
|
||||
import { LinearProgressWithLabel } from './LinearProgressWithLabel';
|
||||
|
||||
interface SingleUploadProps {
|
||||
text: string;
|
||||
doRestart: () => void;
|
||||
}
|
||||
|
||||
const SingleUpload = ({ doRestart }: SingleUploadProps) => {
|
||||
const SingleUpload = ({ text, doRestart }: SingleUploadProps) => {
|
||||
const [md5, setMd5] = useState<string>();
|
||||
const [file, setFile] = useState<File>();
|
||||
const { LL } = useI18nContext();
|
||||
@@ -57,7 +58,7 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => {
|
||||
<>
|
||||
{isUploading ? (
|
||||
<>
|
||||
<Box sx={{ width: '100%', pl: 2, pr: 2 }}>
|
||||
<Box width="100%" pl={2} pr={2}>
|
||||
<LinearProgressWithLabel
|
||||
value={
|
||||
progress.total === 0 || progress.loaded === 0
|
||||
@@ -80,11 +81,11 @@ const SingleUpload = ({ doRestart }: SingleUploadProps) => {
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<DragNdrop text={LL.UPLOAD_DROP_TEXT()} onFileSelected={setFile} />
|
||||
<DragNdrop text={text} onFileSelected={setFile} />
|
||||
)}
|
||||
|
||||
{md5 && (
|
||||
<Box sx={{ mt: 2 }}>
|
||||
<Box mt={2}>
|
||||
<Typography variant="body2">{'MD5: ' + md5}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@@ -350,22 +350,16 @@ const cz: Translation = {
|
||||
NO_DATA_1: 'Nebyly nalezeny žádné oblíbené entity. Použijte modul',
|
||||
NO_DATA_2: 'pro jejich výběr.',
|
||||
NO_DATA_3: 'Pro zobrazení všech dostupných entit navštivte stránku',
|
||||
NO_GPIO: 'Nebylo nalezeno žádné volné GPIO',
|
||||
THIS_VERSION: 'Tato verze',
|
||||
PLATFORM: 'Platforma',
|
||||
RELEASE_TYPE: 'Typ sestavení',
|
||||
INTERNET_CONNECTION_REQUIRED: 'Pro automatickou kontrolu a instalaci aktualizací je třeba internetové připojení',
|
||||
SWITCH_RELEASE_TYPE: 'Přepnout na {0} verzi',
|
||||
FIRMWARE_VERSION_INFO: 'Informace o verzi firmwaru',
|
||||
NO_DATA: 'žádné údaje',
|
||||
NO_DATA: 'Žádná data',
|
||||
USER_PROFILE: 'Uživatelský profil',
|
||||
STORED_VERSIONS: 'Uložené verze',
|
||||
ONLINE_HELP: 'online nápověda',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Aktualizovat důležité zprávy',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Tato aktualizace vyžaduje obnovení továrního nastavení. Ujistěte se, že nejprve stáhnete systémovou zálohu před pokračováním a poté nahrajte tento soubor po instalaci nové verze.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujete se na novou hlavní verzi. Ujistěte se, že jste přečetli ChangeLog pro jakékoliv závažné změny.',
|
||||
WARNING_SYSTEM_BACKUP: 'Toto vytvoří zálohu vašich celých systémových konfigurací a nastavení. Všechna hesla budou v zálohovém souboru čitelná. Buďte opatrní při sdílení! Opravdu chcete pokračovat?'
|
||||
|
||||
ONLINE_HELP: 'online nápověda'
|
||||
};
|
||||
|
||||
export default cz;
|
||||
|
||||
@@ -187,7 +187,7 @@ const de: Translation = {
|
||||
COMPACT: 'Kompakte Darstellung',
|
||||
DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen',
|
||||
DOWNLOAD_SETTINGS_TEXT2: 'Exportiere alle Werte',
|
||||
DOWNLOAD_SYSTEM_BACKUP: 'Systemsicherung',
|
||||
DOWNLOAD_SYSTEM_BACKUP: 'System Sicherung',
|
||||
UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch',
|
||||
UPLOAD_DROP_TEXT: 'Legen Sie eine Firmware-Datei (.bin) ab oder klicken Sie hier',
|
||||
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.',
|
||||
@@ -350,7 +350,6 @@ const de: Translation = {
|
||||
NO_DATA_1: 'Keine favorisierten EMS-Entitäten gefunden! Verwenden Sie das Modul',
|
||||
NO_DATA_2: ', um sie zu markieren.',
|
||||
NO_DATA_3: 'Um alle verfügbaren Entitäten anzuzeigen, gehen Sie zu',
|
||||
NO_GPIO: 'Keine freien GPIO gefunden',
|
||||
THIS_VERSION: 'Diese Version',
|
||||
PLATFORM: 'Plattform',
|
||||
RELEASE_TYPE: 'Release Typ',
|
||||
@@ -360,12 +359,7 @@ const de: Translation = {
|
||||
NO_DATA: 'Keine Daten',
|
||||
USER_PROFILE: 'Benutzerprofil',
|
||||
STORED_VERSIONS: 'Gespeicherte Versionen',
|
||||
ONLINE_HELP: 'Online-Hilfe',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Wichtige Nachrichten aktualisieren',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Für diese Aktualisierung ist ein Werksreset erforderlich. Stellen Sie sicher, dass Sie zuerst eine Systemsicherung herunterladen, bevor Sie fortfahren, und laden Sie diese Datei dann nach der Installation der neuen Version hoch.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Sie aktualisieren auf eine neue Hauptversion. Stellen Sie sicher, dass Sie den ChangeLog für alle wichtigen Änderungen gelesen haben.',
|
||||
WARNING_SYSTEM_BACKUP: 'Dies wird eine Sicherung Ihrer vollständigen Systemkonfiguration und Einstellungen erstellen. Alle Passwörter werden in dieser Sicherungsdatei lesbar sein. Seien Sie vorsichtig beim Teilen! Möchten Sie fortfahren?'
|
||||
|
||||
ONLINE_HELP: 'Online-Hilfe'
|
||||
};
|
||||
|
||||
export default de;
|
||||
|
||||
@@ -350,7 +350,6 @@ const en: Translation = {
|
||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the',
|
||||
NO_DATA_2: 'module to mark them.',
|
||||
NO_DATA_3: 'To see all available entities go to',
|
||||
NO_GPIO: 'No available GPIO found',
|
||||
THIS_VERSION: 'This Version',
|
||||
PLATFORM: 'Platform',
|
||||
RELEASE_TYPE: 'Release Type',
|
||||
@@ -360,12 +359,7 @@ const en: Translation = {
|
||||
NO_DATA: 'No data',
|
||||
USER_PROFILE: 'User Profile',
|
||||
STORED_VERSIONS: 'Stored Versions',
|
||||
ONLINE_HELP: 'online help',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Upgrade Important Messages',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'This upgrade requires a factory reset. Make sure you first download a System Backup before continuing, and then upload this file after the new version is installed.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'You are upgrading to a new major version. Make sure you have read the ChangeLog for any breaking changes.',
|
||||
WARNING_SYSTEM_BACKUP: 'This will create a backup of your full system configuration and settings. All passwords will be readable in the backup file. Be careful with sharing! Do you want to continue?'
|
||||
|
||||
ONLINE_HELP: 'online help'
|
||||
};
|
||||
|
||||
export default en;
|
||||
|
||||
@@ -350,7 +350,6 @@ const fr: Translation = {
|
||||
NO_DATA_1: 'Aucune entité EMS favorite trouvée. Utilisez le',
|
||||
NO_DATA_2: 'module pour les marquer.',
|
||||
NO_DATA_3: 'Pour voir toutes les entités disponibles, aller à',
|
||||
NO_GPIO: "Aucun GPIO disponible n'a été détecté",
|
||||
THIS_VERSION: 'Cette version',
|
||||
PLATFORM: 'Plateforme',
|
||||
RELEASE_TYPE: 'Type de version',
|
||||
@@ -360,12 +359,7 @@ const fr: Translation = {
|
||||
NO_DATA: 'Aucune donnée',
|
||||
USER_PROFILE: 'Profil utilisateur',
|
||||
STORED_VERSIONS: 'Versions stockées',
|
||||
ONLINE_HELP: 'aide en ligne',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Mettre à jour les messages importants',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Cette mise à jour nécessite une réinitialisation de fabrique. Assurez-vous de télécharger une sauvegarde système avant de continuer, et de la charger après l\'installation de la nouvelle version.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Vous mettez à jour vers une nouvelle version majeure. Assurez-vous de lire le ChangeLog pour tout changement important.',
|
||||
WARNING_SYSTEM_BACKUP: 'Cela créera une sauvegarde de votre configuration et paramètres complets. Tous les mots de passe seront lisibles dans le fichier de sauvegarde. Soyez prudent avec le partage ! Voulez-vous continuer ?'
|
||||
|
||||
ONLINE_HELP: 'aide en ligne'
|
||||
};
|
||||
|
||||
export default fr;
|
||||
|
||||
@@ -350,7 +350,6 @@ const it: Translation = {
|
||||
NO_DATA_1: 'Nessuna entità EMS preferita trovata. Usa il',
|
||||
NO_DATA_2: 'modulo per marcarle.',
|
||||
NO_DATA_3: 'Per vedere tutte le entità disponibili vai a',
|
||||
NO_GPIO: 'Non è stato trovato alcun GPIO disponibile',
|
||||
THIS_VERSION: 'Questa versione',
|
||||
PLATFORM: 'Piattaforma',
|
||||
RELEASE_TYPE: 'Tipo di rilascio',
|
||||
@@ -360,12 +359,7 @@ const it: Translation = {
|
||||
NO_DATA: 'Nessun dato',
|
||||
USER_PROFILE: 'Profilo utente',
|
||||
STORED_VERSIONS: 'Versioni memorizzate',
|
||||
ONLINE_HELP: 'aiuto online',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Aggiorna Messaggi Importanti',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Questa aggiornamento richiede un ripristino di fabbrica. Assicurati di prima scaricare un backup del sistema prima di continuare, e poi caricare questo file dopo l\'installazione della nuova versione.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Stai aggiornando a una nuova versione principale. Assicurati di aver letto il ChangeLog per qualsiasi cambiamento importante.',
|
||||
WARNING_SYSTEM_BACKUP: 'Questo creerà un backup delle tue configurazioni e impostazioni complete. Tutte le password saranno leggibili nel file di backup. Sei sicuro di voler continuare?'
|
||||
|
||||
ONLINE_HELP: 'aiuto online'
|
||||
};
|
||||
|
||||
export default it;
|
||||
|
||||
@@ -350,7 +350,6 @@ const nl: Translation = {
|
||||
NO_DATA_1: 'Er zijn nog geen favoriete EMS-entiteiten gevonden. Gebruik de',
|
||||
NO_DATA_2: 'module om ze te markeren.',
|
||||
NO_DATA_3: 'Om alle beschikbare entiteiten te zien, ga naar',
|
||||
NO_GPIO: 'Er is geen beschikbare GPIO gevonden',
|
||||
THIS_VERSION: 'Deze Versie',
|
||||
PLATFORM: 'Platform',
|
||||
RELEASE_TYPE: 'Release Typ',
|
||||
@@ -360,12 +359,7 @@ const nl: Translation = {
|
||||
NO_DATA: 'Geen data',
|
||||
USER_PROFILE: 'Gebruikersprofiel',
|
||||
STORED_VERSIONS: 'Opgeslagen versies',
|
||||
ONLINE_HELP: 'online help',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Upgrade Belangrijke Berichten',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Deze upgrade vereist een fabrieksinstelling. Zorg ervoor dat u eerst een Systeem Backup download voordat u doorgaat, en upload deze file na de installatie van de nieuwe versie.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'U updatet naar een nieuwe grote versie. Zorg ervoor dat u de ChangeLog hebt gelezen voor alle brekende wijzigingen.',
|
||||
WARNING_SYSTEM_BACKUP: 'Dit zal een back-up van uw volledige systeemconfiguratie en instellingen maken. Alle wachtwoorden zijn leesbaar in het back-upbestand. Wees voorzichtig bij delen! Wilt u doorgaan?'
|
||||
|
||||
ONLINE_HELP: 'online help'
|
||||
};
|
||||
|
||||
export default nl;
|
||||
|
||||
@@ -350,7 +350,6 @@ const no: Translation = {
|
||||
NO_DATA_1: 'Ingen favoritte EMS enheter funnet enda. Bruk',
|
||||
NO_DATA_2: 'modul for å markere dem.',
|
||||
NO_DATA_3: 'For å se alle tilgjengelige enheter, gå til',
|
||||
NO_GPIO: 'Det ble ikke funnet noen tilgjengelige GPIO-porter',
|
||||
THIS_VERSION: 'Denne versjonen',
|
||||
PLATFORM: 'Plattform',
|
||||
RELEASE_TYPE: 'Utgivelses type',
|
||||
@@ -360,12 +359,7 @@ const no: Translation = {
|
||||
NO_DATA: 'Ingen data',
|
||||
USER_PROFILE: 'Brukerprofil',
|
||||
STORED_VERSIONS: 'Lagret versjoner',
|
||||
ONLINE_HELP: 'online hjelp',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Oppdater viktige meldinger',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Denne oppdateringen krever en fabriksinstilling. Sørg for at du først lastet ned en System Backup før du fortsetter, og last denne filen etter at den nye versjonen er installert.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Du oppdaterer til en ny hovedversjon. Sørg for at du har lest ChangeLog for eventuelle bruddende endringer.',
|
||||
WARNING_SYSTEM_BACKUP: 'Dette vil lage en sikkerhetskopi av din fullstendige systemkonfigurasjon og innstillinger. Alle passord vil være lesbare i sikkerhetskopien. Vær forsiktig med deling! Vil du fortsette?'
|
||||
|
||||
ONLINE_HELP: 'online hjelp'
|
||||
};
|
||||
|
||||
export default no;
|
||||
|
||||
@@ -350,7 +350,6 @@ const pl: BaseTranslation = {
|
||||
NO_DATA_1: 'Brak ulubionych encji EMS. Użyj',
|
||||
NO_DATA_2: 'moduł do ich oznaczenia.',
|
||||
NO_DATA_3: 'Aby zobaczyć wszystkie dostępne encje przejdź do',
|
||||
NO_GPIO: 'Nie znaleziono dostępnych pinów GPIO',
|
||||
THIS_VERSION: 'Ta wersja',
|
||||
PLATFORM: 'Platforma',
|
||||
RELEASE_TYPE: 'Typ wydania',
|
||||
@@ -360,12 +359,7 @@ const pl: BaseTranslation = {
|
||||
NO_DATA: 'Brak danych',
|
||||
USER_PROFILE: 'Profil użytkownika',
|
||||
STORED_VERSIONS: 'Zapisane wersje',
|
||||
ONLINE_HELP: 'pomoc online',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Aktualizuj ważne wiadomości',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Ta aktualizacja wymaga resetu fabrycznego. Upewnij się, że najpierw pobierzesz kopię zapasową systemu przed kontynuowaniem, a następnie przesuń tę plik po zainstalowaniu nowej wersji.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujesz się do nowej głównej wersji. Upewnij się, że przeczytałeś ChangeLog dla wszelkich istotnych zmian.',
|
||||
WARNING_SYSTEM_BACKUP: 'To spowoduje utworzenie kopii zapasowej całej konfiguracji i ustawień systemu. Wszystkie hasła będą widoczne w pliku kopii zapasowej. Bądź ostrożny przy udostępnianiu! Chcesz kontynuować?'
|
||||
|
||||
ONLINE_HELP: 'pomoc online'
|
||||
};
|
||||
|
||||
export default pl;
|
||||
|
||||
@@ -4,7 +4,7 @@ const sk: Translation = {
|
||||
LANGUAGE: 'Jazyk',
|
||||
RETRY: 'Opakovať',
|
||||
LOADING: 'Načítanie',
|
||||
IS_REQUIRED: '{0} je požadovaná',
|
||||
IS_REQUIRED: '{0} je požadovaných',
|
||||
SIGN_IN: 'Prihlásiť sa',
|
||||
SIGN_OUT: 'Odhlásiť sa',
|
||||
USERNAME: 'Užívateľské meno',
|
||||
@@ -276,11 +276,11 @@ const sk: Translation = {
|
||||
NETWORK_SUBNET: 'Maska podsiete',
|
||||
NETWORK_DNS: 'DNS servery',
|
||||
ADDRESS_OF: '{0} adresa',
|
||||
ADMINISTRATOR: 'Administrátor',
|
||||
ADMINISTRATOR: 'Administrator',
|
||||
GUEST: 'Hosť',
|
||||
NEW: 'Novú',
|
||||
NEW: 'Nová',
|
||||
NEW_NAME_OF: 'Nový názov {0}',
|
||||
ENTITY: 'entitu',
|
||||
ENTITY: 'entita',
|
||||
MIN: 'min',
|
||||
MAX: 'max',
|
||||
BLOCK_NAVIGATE_1: 'Máte neuložené zmeny',
|
||||
@@ -350,7 +350,6 @@ const sk: Translation = {
|
||||
NO_DATA_1: 'Nenašli sa žiadne obľúbené entity EMS. Použite',
|
||||
NO_DATA_2: 'modul na ich označenie.',
|
||||
NO_DATA_3: 'Ak chcete zobraziť všetky dostupné entity, prejdite na',
|
||||
NO_GPIO: 'Nebol nájdený žiadny dostupný GPIO',
|
||||
THIS_VERSION: 'Táto verzia',
|
||||
PLATFORM: 'Platforma',
|
||||
RELEASE_TYPE: 'Typ vydania',
|
||||
@@ -360,12 +359,7 @@ const sk: Translation = {
|
||||
NO_DATA: 'Žiadne dáta',
|
||||
USER_PROFILE: 'Profil používateľa',
|
||||
STORED_VERSIONS: 'Uložené verzie',
|
||||
ONLINE_HELP: 'online pomoc',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Aktualizovať dôležité správy',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Táto aktualizácia vyžaduje reštart základných nastavení. Uistite sa, že najprv stiahnete systémovú zálohu pred pokračovaním, a potom nahrajte tento súbor po instalácii novej verzie.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujete sa na novú hlavnú verziu. Uistite sa, že ste prečítali ChangeLog pre akékoľvek dôležité zmeny.',
|
||||
WARNING_SYSTEM_BACKUP: 'Toto vytvorí zálohu všetkých vašich celých systémových konfigurácií a nastavení. Všetky hesla budú čitateľné v zálohovom súbore. Buďte opatrní pri zdieľaní! Chcete pokračovať?'
|
||||
|
||||
ONLINE_HELP: 'online pomoc'
|
||||
};
|
||||
|
||||
export default sk;
|
||||
|
||||
@@ -350,7 +350,6 @@ const sv: Translation = {
|
||||
NO_DATA_1: 'Inga favorit EMS enheter hittade än. Använd',
|
||||
NO_DATA_2: 'modul för att markera dem.',
|
||||
NO_DATA_3: 'För att se alla tillgängliga enheter, gå till',
|
||||
NO_GPIO: 'Inga tillgängliga GPIO-portar hittades',
|
||||
THIS_VERSION: 'Denna version',
|
||||
PLATFORM: 'Plattform',
|
||||
RELEASE_TYPE: 'Utgivelsestyp',
|
||||
@@ -360,12 +359,7 @@ const sv: Translation = {
|
||||
NO_DATA: 'Ingen data',
|
||||
USER_PROFILE: 'Användarprofil',
|
||||
STORED_VERSIONS: 'Lagrad versioner',
|
||||
ONLINE_HELP: 'online hjälp',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Uppdatera viktiga meddelanden',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Denna uppdatering kräver en fabriksåterställning. Se till att du först laddar ned en System Backup innan du fortsätter, och ladda upp denna fil efter att den nya versionen är installerad.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Du uppdaterar till en ny huvudversion. Se till att du har läst ChangeLog för eventuella brkande ändringar.',
|
||||
WARNING_SYSTEM_BACKUP: 'Detta kommer att skapa en säkerhetskopia av din fullständiga systemkonfiguration och inställningar. Alla lösenord kommer att vara läsbara i säkerhetskopien. Var försiktig med att dela! Vill du fortsätta?'
|
||||
|
||||
ONLINE_HELP: 'online hjälp'
|
||||
};
|
||||
|
||||
export default sv;
|
||||
|
||||
@@ -350,7 +350,6 @@ const tr: Translation = {
|
||||
NO_DATA_1: 'Henüz bir favori EMS varlığı bulunamadı. Kullanın',
|
||||
NO_DATA_2: 'modülünü kullanın.',
|
||||
NO_DATA_3: 'Tüm kullanılabilir varlıkları görmek için git',
|
||||
NO_GPIO: 'Kullanılabilir GPIO bulunamadı',
|
||||
THIS_VERSION: 'Bu Sürüm',
|
||||
PLATFORM: 'Platforma',
|
||||
RELEASE_TYPE: 'Sürüm Tipi',
|
||||
@@ -360,12 +359,7 @@ const tr: Translation = {
|
||||
NO_DATA: 'Hiçbir veri yok',
|
||||
USER_PROFILE: 'Kullanıcı Profili',
|
||||
STORED_VERSIONS: 'Kaydedilmiş Sürümler',
|
||||
ONLINE_HELP: 'online yardım',
|
||||
UPGRADE_IMPORTANT_MESSAGES: 'Önemli Mesajları Güncelle',
|
||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Bu güncelleme továrnı ayarlarını gerektirir. Yapılandırmanızı ve ayarlarınızı önce yedekleyin ve ardından yeni sürüm yüklendikten sonra yükleyin.',
|
||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Yeni bir büyük sürüme yükselteceksiniz. Değişiklikleri ChangeLogı okuduğunuzdan emin olun.',
|
||||
WARNING_SYSTEM_BACKUP: 'Bu, sistem yapılandırmanızı ve ayarlarınızın bir yedeklemesi oluşturacaktır. Tüm şifreler yedekleme dosyasında okunabilir olacaktır. Paylaşırken dikkatli olun! Devam etmek istediğinize emin misiniz?'
|
||||
|
||||
ONLINE_HELP: 'online yardım'
|
||||
};
|
||||
|
||||
export default tr;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
const DEFAULT_DELAY = 5000;
|
||||
const DEFAULT_DELAY = 3000;
|
||||
|
||||
/**
|
||||
* Custom hook for setting up an interval with proper cleanup
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
import type {
|
||||
InternalRuleItem,
|
||||
ValidateFieldsError,
|
||||
ValidateOption
|
||||
} from 'async-validator';
|
||||
import type { InternalRuleItem, ValidateOption } from 'async-validator';
|
||||
import type Schema from 'async-validator';
|
||||
|
||||
export class ValidationError extends Error {
|
||||
readonly fieldErrors: ValidateFieldsError;
|
||||
|
||||
constructor(fieldErrors: ValidateFieldsError) {
|
||||
super('Validation failed');
|
||||
this.name = 'ValidationError';
|
||||
this.fieldErrors = fieldErrors;
|
||||
}
|
||||
}
|
||||
|
||||
export const validate = <T extends object>(
|
||||
validator: Schema,
|
||||
source: Partial<T>,
|
||||
@@ -22,7 +8,7 @@ export const validate = <T extends object>(
|
||||
): Promise<T> =>
|
||||
new Promise((resolve, reject) => {
|
||||
void validator.validate(source, options ?? {}, (errors, fieldErrors) => {
|
||||
errors ? reject(new ValidationError(fieldErrors)) : resolve(source as T);
|
||||
errors ? reject(fieldErrors as Error) : resolve(source as T);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const REPEAT_CHAR = '=';
|
||||
const REPEAT_COUNT = 50;
|
||||
const DEFAULT_OUT_DIR = 'dist';
|
||||
const ES_TARGET = 'es2020';
|
||||
const CHUNK_SIZE_WARNING_LIMIT = 1024;
|
||||
const CHUNK_SIZE_WARNING_LIMIT = 512;
|
||||
const ASSETS_INLINE_LIMIT = 4096;
|
||||
|
||||
// Common resolve aliases
|
||||
@@ -130,9 +130,40 @@ const createBasePlugins = (
|
||||
return plugins;
|
||||
};
|
||||
|
||||
const manualChunks = (id: string): string | undefined => {
|
||||
if (id.includes('node_modules')) return 'vendor';
|
||||
return undefined;
|
||||
// Manual chunk splitting strategy
|
||||
const createManualChunks = (detailed = false) => {
|
||||
return (id: string): string | undefined => {
|
||||
if (id.includes('node_modules')) {
|
||||
if (id.includes('preact')) return '@preact';
|
||||
if (detailed) {
|
||||
if (id.includes('react-router')) return '@react-router';
|
||||
if (id.includes('@mui/material')) return '@mui-material';
|
||||
if (id.includes('@mui/icons-material')) return '@mui-icons';
|
||||
if (id.includes('alova')) return '@alova';
|
||||
if (id.includes('typesafe-i18n')) return '@i18n';
|
||||
if (id.includes('react-toastify')) return '@toastify';
|
||||
if (id.includes('@table-library')) return '@table-library';
|
||||
if (id.includes('uuid')) return '@uuid';
|
||||
if (id.includes('axios') || id.includes('fetch')) return '@http';
|
||||
if (id.includes('lodash') || id.includes('ramda')) return '@utils';
|
||||
}
|
||||
return 'vendor';
|
||||
}
|
||||
if (detailed) {
|
||||
// Group circularly dependent modules together to avoid circular chunk warnings
|
||||
// components, app, and utils are tightly coupled, so combine them
|
||||
if (
|
||||
id.includes('components/') ||
|
||||
id.includes('app/') ||
|
||||
id.includes('utils/')
|
||||
) {
|
||||
return 'app';
|
||||
}
|
||||
// Keep api separate as it's typically more independent
|
||||
if (id.includes('api/')) return 'api';
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
};
|
||||
|
||||
// Common build base configuration
|
||||
@@ -259,7 +290,7 @@ export default defineConfig(
|
||||
moduleSideEffects: false
|
||||
},
|
||||
output: {
|
||||
manualChunks
|
||||
manualChunks: createManualChunks(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +330,7 @@ export default defineConfig(
|
||||
chunkFileNames: 'assets/[name]-[hash].js',
|
||||
entryFileNames: 'assets/[name]-[hash].js',
|
||||
assetFileNames: 'assets/[name]-[hash].[ext]',
|
||||
manualChunks,
|
||||
manualChunks: createManualChunks(true),
|
||||
sourcemap: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ the LICENSE file.
|
||||
#define EMC_CLIENTID_LENGTH 23 + 1
|
||||
#endif
|
||||
|
||||
#ifdef EMSESP_MQTT_STACKSIZE
|
||||
#define EMC_TASK_STACK_SIZE EMSESP_MQTT_STACKSIZE
|
||||
#endif
|
||||
|
||||
#ifndef EMC_TASK_STACK_SIZE
|
||||
#define EMC_TASK_STACK_SIZE 5120
|
||||
#endif
|
||||
@@ -66,14 +70,10 @@ the LICENSE file.
|
||||
#endif
|
||||
|
||||
#if EMC_USE_MEMPOOL
|
||||
#ifndef EMC_NUM_POOL_ELEMENTS
|
||||
#define EMC_NUM_POOL_ELEMENTS 32
|
||||
#endif
|
||||
#ifndef EMC_SIZE_POOL_ELEMENTS
|
||||
#define EMC_SIZE_POOL_ELEMENTS 128
|
||||
#endif
|
||||
#ifndef EMC_NUM_POOL_ELEMENTS
|
||||
#define EMC_NUM_POOL_ELEMENTS 32
|
||||
#endif
|
||||
#ifndef EMC_SIZE_POOL_ELEMENTS
|
||||
#define EMC_SIZE_POOL_ELEMENTS 128
|
||||
#endif
|
||||
|
||||
#ifndef TASMOTA_SDK
|
||||
#define EMC_CLIENT_SECURE
|
||||
#endif
|
||||
|
||||
@@ -62,7 +62,11 @@ MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint
|
||||
_xSemaphore = xSemaphoreCreateMutex();
|
||||
EMC_SEMAPHORE_GIVE(); // release before first use
|
||||
if (_useInternalTask == espMqttClientTypes::UseInternalTask::YES) {
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)_loop, "mqttclient", EMC_TASK_STACK_SIZE, this, priority, &_taskHandle, core);
|
||||
if (core > 1) {
|
||||
xTaskCreate((TaskFunction_t)_loop, "mqttclient", EMC_TASK_STACK_SIZE, this, priority, &_taskHandle);
|
||||
} else {
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)_loop, "mqttclient", EMC_TASK_STACK_SIZE, this, priority, &_taskHandle, core);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) useInternalTask;
|
||||
@@ -70,6 +74,7 @@ MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint
|
||||
(void) core;
|
||||
#endif
|
||||
_clientId = _generatedClientId;
|
||||
_core = core;
|
||||
}
|
||||
|
||||
MqttClient::~MqttClient() {
|
||||
|
||||
@@ -69,7 +69,17 @@ class MqttClient {
|
||||
const char* getClientId() const;
|
||||
size_t queueSize(); // No const because of mutex
|
||||
void loop();
|
||||
|
||||
uint32_t stack() {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
return uxTaskGetStackHighWaterMark(_taskHandle);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
uint8_t core() {
|
||||
return _core;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority = 1, uint8_t core = 1);
|
||||
espMqttClientTypes::UseInternalTask _useInternalTask;
|
||||
@@ -98,6 +108,7 @@ class MqttClient {
|
||||
uint8_t _willQos;
|
||||
bool _willRetain;
|
||||
uint32_t _timeout;
|
||||
uint8_t _core;
|
||||
|
||||
// state is protected to allow state changes by the transport system, defined in child classes
|
||||
// eg. to allow AsyncTCP
|
||||
|
||||
@@ -6,66 +6,65 @@ For a copy, see <https://opensource.org/licenses/MIT> or
|
||||
the LICENSE file.
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
|
||||
#include "ClientSecureSync.h"
|
||||
#include <lwip/sockets.h> // socket options
|
||||
#include <lwip/sockets.h>
|
||||
#include "../Config.h"
|
||||
|
||||
namespace espMqttClientInternals {
|
||||
|
||||
ClientSecureSync::ClientSecureSync()
|
||||
: client() {
|
||||
// empty
|
||||
: client() {
|
||||
client.setClient(&basic_client, true);
|
||||
client.setBufferSizes(EMC_RX_BUFFER_SIZE, EMC_TX_BUFFER_SIZE);
|
||||
client.setSessionTimeout(120); // Set the timeout in seconds (>=120 seconds)
|
||||
}
|
||||
|
||||
ClientSecureSync::~ClientSecureSync() {
|
||||
stop();
|
||||
}
|
||||
|
||||
bool ClientSecureSync::connect(IPAddress ip, uint16_t port) {
|
||||
bool ret = client.connect(ip, port); // implicit conversion of return code int --> bool
|
||||
if (ret) {
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
client.setNoDelay(true);
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
// Set TCP option directly to bypass lack of working setNoDelay for WiFiClientSecure
|
||||
int val = true;
|
||||
client.setSocketOption(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
bool ret = client.connect(ip, port); // implicit conversion of return code int --> bool
|
||||
if (ret) {
|
||||
// Set TCP option directly to bypass lack of working setNoDelay for WiFiClientSecure
|
||||
int val = true;
|
||||
basic_client.setSocketOption(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ClientSecureSync::connect(const char* host, uint16_t port) {
|
||||
bool ret = client.connect(host, port); // implicit conversion of return code int --> bool
|
||||
if (ret) {
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
client.setNoDelay(true);
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
// Set TCP option directly to bypass lack of working setNoDelay for WiFiClientSecure
|
||||
int val = true;
|
||||
client.setSocketOption(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
bool ClientSecureSync::connect(const char * host, uint16_t port) {
|
||||
bool ret = client.connect(host, port); // implicit conversion of return code int --> bool
|
||||
if (ret) {
|
||||
// Set TCP option directly to bypass lack of working setNoDelay for WiFiClientSecure
|
||||
int val = true;
|
||||
basic_client.setSocketOption(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ClientSecureSync::write(const uint8_t* buf, size_t size) {
|
||||
return client.write(buf, size);
|
||||
size_t ClientSecureSync::write(const uint8_t * buf, size_t size) {
|
||||
return client.write(buf, size);
|
||||
}
|
||||
|
||||
int ClientSecureSync::read(uint8_t* buf, size_t size) {
|
||||
return client.read(buf, size);
|
||||
int ClientSecureSync::read(uint8_t * buf, size_t size) {
|
||||
return client.read(buf, size);
|
||||
}
|
||||
|
||||
void ClientSecureSync::stop() {
|
||||
client.stop();
|
||||
client.stop();
|
||||
}
|
||||
|
||||
bool ClientSecureSync::connected() {
|
||||
return client.connected();
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
bool ClientSecureSync::disconnected() {
|
||||
return !client.connected();
|
||||
return !client.connected();
|
||||
}
|
||||
|
||||
} // namespace espMqttClientInternals
|
||||
} // namespace espMqttClientInternals
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -8,15 +8,11 @@ the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
|
||||
// Added for EMS-ESP
|
||||
#include "../Config.h"
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
#include <WiFiClientSecure.h> // includes IPAddress
|
||||
#else
|
||||
// #include "esp_tls.h"
|
||||
#include <WiFiClient.h>
|
||||
#endif
|
||||
#include <ESP_SSLClient.h>
|
||||
#include "Transport.h"
|
||||
|
||||
namespace espMqttClientInternals {
|
||||
@@ -24,6 +20,7 @@ namespace espMqttClientInternals {
|
||||
class ClientSecureSync : public Transport {
|
||||
public:
|
||||
ClientSecureSync();
|
||||
~ClientSecureSync();
|
||||
bool connect(IPAddress ip, uint16_t port) override;
|
||||
bool connect(const char * host, uint16_t port) override;
|
||||
size_t write(const uint8_t * buf, size_t size) override;
|
||||
@@ -31,14 +28,11 @@ class ClientSecureSync : public Transport {
|
||||
void stop() override;
|
||||
bool connected() override;
|
||||
bool disconnected() override;
|
||||
// added for EMS-ESP
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
WiFiClientSecure client;
|
||||
#else
|
||||
WiFiClient client;
|
||||
#endif
|
||||
|
||||
WiFiClient basic_client;
|
||||
ESP_SSLClient client;
|
||||
};
|
||||
|
||||
} // namespace espMqttClientInternals
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -8,50 +8,6 @@ the LICENSE file.
|
||||
|
||||
#include "espMqttClient.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
espMqttClient::espMqttClient()
|
||||
: MqttClientSetup(espMqttClientTypes::UseInternalTask::NO)
|
||||
, _client() {
|
||||
_transport = &_client;
|
||||
}
|
||||
|
||||
espMqttClientSecure::espMqttClientSecure()
|
||||
: MqttClientSetup(espMqttClientTypes::UseInternalTask::NO)
|
||||
, _client() {
|
||||
_transport = &_client;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setInsecure() {
|
||||
_client.client.setInsecure();
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setFingerprint(const uint8_t fingerprint[20]) {
|
||||
_client.client.setFingerprint(fingerprint);
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setTrustAnchors(const X509List * ta) {
|
||||
_client.client.setTrustAnchors(ta);
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setClientRSACert(const X509List * cert, const PrivateKey * sk) {
|
||||
_client.client.setClientRSACert(cert, sk);
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setClientECCert(const X509List * cert, const PrivateKey * sk, unsigned allowed_usages, unsigned cert_issuer_key_type) {
|
||||
_client.client.setClientECCert(cert, sk, allowed_usages, cert_issuer_key_type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setCertStore(CertStoreBase * certStore) {
|
||||
_client.client.setCertStore(certStore);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
espMqttClient::espMqttClient(espMqttClientTypes::UseInternalTask useInternalTask)
|
||||
: MqttClientSetup(useInternalTask)
|
||||
@@ -78,36 +34,35 @@ espMqttClientSecure::espMqttClientSecure(uint8_t priority, uint8_t core)
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setInsecure() {
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
_client.client.setInsecure();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setCACert(const char * rootCA) {
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
_client.client.setCACert(rootCA);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setCertificate(const char * clientCa) {
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
_client.client.setCertificate(clientCa);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setPrivateKey(const char * privateKey) {
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
_client.client.setPrivateKey(privateKey);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
espMqttClientSecure & espMqttClientSecure::setPreSharedKey(const char * pskIdent, const char * psKey) {
|
||||
#if defined(EMC_CLIENT_SECURE)
|
||||
_client.client.setPreSharedKey(pskIdent, psKey);
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
@@ -120,9 +75,4 @@ espMqttClient::espMqttClient()
|
||||
, _client() {
|
||||
_transport = &_client;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(__APPLE__)
|
||||
// Windows
|
||||
espMqttClient::espMqttClient()
|
||||
: MqttClientSetup(espMqttClientTypes::UseInternalTask::NO) {
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -65,10 +65,16 @@ class espMqttClientSecure : public MqttClientSetup<espMqttClientSecure> {
|
||||
espMqttClientSecure & setPreSharedKey(const char * pskIdent, const char * psKey);
|
||||
|
||||
protected:
|
||||
#ifndef NO_TLS_SUPPORT
|
||||
espMqttClientInternals::ClientSecureSync _client;
|
||||
#else
|
||||
espMqttClientInternals::ClientSync _client;
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif defined(__linux__)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
class espMqttClient : public MqttClientSetup<espMqttClient> {
|
||||
public:
|
||||
espMqttClient();
|
||||
@@ -76,10 +82,4 @@ class espMqttClient : public MqttClientSetup<espMqttClient> {
|
||||
protected:
|
||||
espMqttClientInternals::ClientPosix _client;
|
||||
};
|
||||
#elif defined(_WIN32) || defined(__APPLE__)
|
||||
class espMqttClient : public MqttClientSetup<espMqttClient> {
|
||||
public:
|
||||
espMqttClient();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
22
lib/semver/LICENSE
Normal file
22
lib/semver/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Živanović
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
7
lib/semver/README.md
Normal file
7
lib/semver/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# About
|
||||
|
||||
This project is MIT-licensed, C++14 implementation of [semantic versioning](http://semver.org) parser and comparator with support for modifying parsed version strings. Semantic versioning 2.0.0 specification is supported out-of-the-box and the code should be flexible-enough to support future revisions or other similar versioning schemes.
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Based on https://github.com/zmarko/semver
|
||||
121
lib/semver/Semver200_comparator.cpp
Normal file
121
lib/semver/Semver200_comparator.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include "semver200.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace version {
|
||||
|
||||
namespace {
|
||||
|
||||
// Compare normal version identifiers.
|
||||
int compare_normal(const Version_data & l, const Version_data & r) {
|
||||
if (l.major > r.major)
|
||||
return 1;
|
||||
if (l.major < r.major)
|
||||
return -1;
|
||||
if (l.minor > r.minor)
|
||||
return 1;
|
||||
if (l.minor < r.minor)
|
||||
return -1;
|
||||
if (l.patch > r.patch)
|
||||
return 1;
|
||||
if (l.patch < r.patch)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Compare alphanumeric prerelease identifiers.
|
||||
inline int cmp_alnum_prerel_ids(const string & l, const string & r) {
|
||||
auto cmp = l.compare(r);
|
||||
if (cmp == 0) {
|
||||
return cmp;
|
||||
} else {
|
||||
return cmp > 0 ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare numeric prerelease identifiers.
|
||||
inline int cmp_num_prerel_ids(const string & l, const string & r) {
|
||||
long long li = stoll(l);
|
||||
long long ri = stoll(r);
|
||||
if (li == ri)
|
||||
return 0;
|
||||
return li > ri ? 1 : -1;
|
||||
}
|
||||
|
||||
using Prerel_type_pair = pair<Id_type, Id_type>;
|
||||
using Prerel_id_comparator = function<int(const string &, const string &)>;
|
||||
const map<Prerel_type_pair, Prerel_id_comparator> comparators = {{{Id_type::alnum, Id_type::alnum}, cmp_alnum_prerel_ids},
|
||||
{{Id_type::alnum, Id_type::num}, [](const string &, const string &) { return 1; }},
|
||||
{{Id_type::num, Id_type::alnum}, [](const string &, const string &) { return -1; }},
|
||||
{{Id_type::num, Id_type::num}, cmp_num_prerel_ids}};
|
||||
|
||||
// Compare prerelease identifiers based on their types.
|
||||
inline int compare_prerel_identifiers(const Prerelease_identifier & l, const Prerelease_identifier & r) {
|
||||
auto cmp = comparators.at({l.second, r.second});
|
||||
return cmp(l.first, r.first);
|
||||
}
|
||||
|
||||
inline int cmp_rel_prerel(const Prerelease_identifiers & l, const Prerelease_identifiers & r) {
|
||||
if (l.empty() && !r.empty())
|
||||
return 1;
|
||||
if (r.empty() && !l.empty())
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Semver200_comparator::compare(const Version_data & l, const Version_data & r) const {
|
||||
// Compare normal version components.
|
||||
int cmp = compare_normal(l, r);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
// Compare if one version is release and the other prerelease - release is always higher.
|
||||
cmp = cmp_rel_prerel(l.prerelease_ids, r.prerelease_ids);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
// Compare prerelease by looking at each identifier: numeric ones are compared as numbers,
|
||||
// alphanum as ASCII strings.
|
||||
auto shorter = min(l.prerelease_ids.size(), r.prerelease_ids.size());
|
||||
for (size_t i = 0; i < shorter; i++) {
|
||||
cmp = compare_prerel_identifiers(l.prerelease_ids[i], r.prerelease_ids[i]);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
// Prerelease identifiers are the same, to the length of the shorter version string;
|
||||
// if they are the same length, then versions are equal, otherwise, longer one wins.
|
||||
if (l.prerelease_ids.size() == r.prerelease_ids.size())
|
||||
return 0;
|
||||
return l.prerelease_ids.size() > r.prerelease_ids.size() ? 1 : -1;
|
||||
}
|
||||
|
||||
} // namespace version
|
||||
187
lib/semver/Semver200_parser.cpp
Normal file
187
lib/semver/Semver200_parser.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include "semver200.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace version {
|
||||
|
||||
namespace {
|
||||
enum class Parser_state { major, minor, patch, prerelease, build };
|
||||
|
||||
using Validator = function<void(const string &, const char)>;
|
||||
using State_transition_hook = function<void(string &)>;
|
||||
/// State transition is described by a character that triggers it, a state to transition to and
|
||||
/// optional hook to be invoked on transition.
|
||||
using Transition = tuple<const char, Parser_state, State_transition_hook>;
|
||||
using Transitions = vector<Transition>;
|
||||
using State = tuple<Transitions, string &, Validator>;
|
||||
using State_machine = std::map<Parser_state, State>;
|
||||
|
||||
// Ranges of characters allowed in prerelease and build identifiers.
|
||||
const vector<pair<char, char>> allowed_prerel_id_chars = {{'0', '9'}, {'A', 'Z'}, {'a', 'z'}, {'-', '-'}};
|
||||
|
||||
inline Transition mkx(const char c, Parser_state p, State_transition_hook pth) {
|
||||
return make_tuple(c, p, pth);
|
||||
}
|
||||
|
||||
inline void Parse_error(const std::string & s) {
|
||||
// EMSESP::logger().err("parse error: %s", s.c_str());
|
||||
}
|
||||
|
||||
/// Advance parser state machine by a single step.
|
||||
/**
|
||||
Perform single step of parser state machine: if character matches one from transition tables -
|
||||
trigger transition to next state; otherwise, validate if current token is in legal state
|
||||
(throw Parse_error if not) and then add character to current token; State transition includes
|
||||
preparing various vars for next state and invoking state transition hook (if specified) which is
|
||||
where whole tokens are validated.
|
||||
*/
|
||||
inline void process_char(const char c, Parser_state & cstate, Parser_state & pstate, const Transitions & transitions, string & target, Validator validate) {
|
||||
for (const auto & transition : transitions) {
|
||||
if (c == get<0>(transition)) {
|
||||
if (get<2>(transition))
|
||||
get<2>(transition)(target);
|
||||
pstate = cstate;
|
||||
cstate = get<1>(transition);
|
||||
return;
|
||||
}
|
||||
}
|
||||
validate(target, c);
|
||||
target.push_back(c);
|
||||
}
|
||||
|
||||
/// Validate normal (major, minor, patch) version components.
|
||||
inline void normal_version_validator(const string & tgt, const char c) {
|
||||
if (c < '0' || c > '9')
|
||||
Parse_error("invalid character encountered: " + string(1, c));
|
||||
if (tgt.compare(0, 1, "0") == 0)
|
||||
Parse_error("leading 0 not allowed");
|
||||
}
|
||||
|
||||
/// Validate that prerelease and build version identifiers are comprised of allowed chars only.
|
||||
inline void prerelease_version_validator(const string &, const char c) {
|
||||
bool res = false;
|
||||
for (const auto & r : allowed_prerel_id_chars) {
|
||||
res |= (c >= r.first && c <= r.second);
|
||||
}
|
||||
if (!res)
|
||||
Parse_error("invalid character encountered: " + string(1, c));
|
||||
}
|
||||
|
||||
inline bool is_identifier_numeric(const string & id) {
|
||||
return id.find_first_not_of("0123456789") == string::npos;
|
||||
}
|
||||
|
||||
inline bool check_for_leading_0(const string & str) {
|
||||
return str.length() > 1 && str[0] == '0';
|
||||
}
|
||||
|
||||
/// Validate every individual prerelease identifier, determine it's type and add it to collection.
|
||||
void prerelease_hook_impl(string & id, Prerelease_identifiers & prerelease) {
|
||||
if (id.empty())
|
||||
Parse_error("version identifier cannot be empty");
|
||||
Id_type t = Id_type::alnum;
|
||||
if (is_identifier_numeric(id)) {
|
||||
t = Id_type::num;
|
||||
if (check_for_leading_0(id)) {
|
||||
Parse_error("numeric identifiers cannot have leading 0");
|
||||
}
|
||||
}
|
||||
prerelease.push_back(Prerelease_identifier(id, t));
|
||||
id.clear();
|
||||
}
|
||||
|
||||
/// Validate every individual build identifier and add it to collection.
|
||||
void build_hook_impl(string & id, Parser_state & pstate, Build_identifiers & build, std::string & prerelease_id, Prerelease_identifiers & prerelease) {
|
||||
// process last token left from parsing prerelease data
|
||||
if (pstate == Parser_state::prerelease)
|
||||
prerelease_hook_impl(prerelease_id, prerelease);
|
||||
if (id.empty())
|
||||
Parse_error("version identifier cannot be empty");
|
||||
build.push_back(id);
|
||||
id.clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Parse semver 2.0.0-compatible string to Version_data structure.
|
||||
/**
|
||||
Version text parser is implemented as a state machine. In each step one successive character from version
|
||||
string is consumed and is either added to current token or triggers state transition. Hooks can be
|
||||
injected into state transitions for validation/customization purposes.
|
||||
*/
|
||||
Version_data Semver200_parser::parse(const string & s) const {
|
||||
string major;
|
||||
string minor;
|
||||
string patch;
|
||||
string prerelease_id;
|
||||
string build_id;
|
||||
Prerelease_identifiers prerelease;
|
||||
Build_identifiers build;
|
||||
Parser_state cstate{Parser_state::major};
|
||||
Parser_state pstate;
|
||||
|
||||
auto prerelease_hook = [&](string & id) { prerelease_hook_impl(id, prerelease); };
|
||||
|
||||
auto build_hook = [&](string & id) { build_hook_impl(id, pstate, build, prerelease_id, prerelease); };
|
||||
|
||||
// State transition tables
|
||||
auto major_trans = {mkx('.', Parser_state::minor, {})};
|
||||
auto minor_trans = {mkx('.', Parser_state::patch, {})};
|
||||
auto patch_trans = {mkx('-', Parser_state::prerelease, {}), mkx('+', Parser_state::build, {})};
|
||||
auto prerelease_trans = {// When identifier separator (.) is found, stay in the same state but invoke hook
|
||||
// in order to process each individual identifier separately.
|
||||
mkx('.', Parser_state::prerelease, prerelease_hook),
|
||||
mkx('+', Parser_state::build, {})};
|
||||
auto build_trans = {// Same stay-in-the-same-state-but-invoke-hook trick from above.
|
||||
mkx('.', Parser_state::build, build_hook)};
|
||||
|
||||
State_machine state_machine = {{Parser_state::major, State{major_trans, major, normal_version_validator}},
|
||||
{Parser_state::minor, State{minor_trans, minor, normal_version_validator}},
|
||||
{Parser_state::patch, State{patch_trans, patch, normal_version_validator}},
|
||||
{Parser_state::prerelease, State{prerelease_trans, prerelease_id, prerelease_version_validator}},
|
||||
{Parser_state::build, State{build_trans, build_id, prerelease_version_validator}}};
|
||||
|
||||
// Main loop.
|
||||
for (const auto & c : s) {
|
||||
auto state = state_machine.at(cstate);
|
||||
process_char(c, cstate, pstate, get<0>(state), get<1>(state), get<2>(state));
|
||||
}
|
||||
|
||||
// Trigger appropriate hooks in order to process last token, because no state transition was
|
||||
// triggered for it.
|
||||
if (cstate == Parser_state::prerelease) {
|
||||
prerelease_hook(prerelease_id);
|
||||
} else if (cstate == Parser_state::build) {
|
||||
build_hook(build_id);
|
||||
}
|
||||
|
||||
return Version_data{stoi(major), stoi(minor), stoi(patch), prerelease, build};
|
||||
}
|
||||
|
||||
} // namespace version
|
||||
53
lib/semver/semver200.h
Normal file
53
lib/semver/semver200.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
|
||||
namespace version {
|
||||
|
||||
/// Parse string into Version_data structure according to semantic versioning 2.0.0 rules.
|
||||
struct Semver200_parser {
|
||||
Version_data parse(const std::string &) const;
|
||||
};
|
||||
|
||||
/// Compare Version_data to another using semantic versioning 2.0.0 rules.
|
||||
struct Semver200_comparator {
|
||||
int compare(const Version_data &, const Version_data &) const;
|
||||
};
|
||||
|
||||
/// Concrete version class that binds all semver 2.0.0 functionality together.
|
||||
class Semver200_version : public Basic_version<Semver200_parser, Semver200_comparator> {
|
||||
public:
|
||||
Semver200_version()
|
||||
: Basic_version{Semver200_parser(), Semver200_comparator()} {
|
||||
}
|
||||
|
||||
Semver200_version(const std::string & v)
|
||||
: Basic_version{v, Semver200_parser(), Semver200_comparator()} {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace version
|
||||
149
lib/semver/version.h
Normal file
149
lib/semver/version.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace version {
|
||||
|
||||
/// Type of prerelease identifier: alphanumeric or numeric.
|
||||
/**
|
||||
Type of identifier affects comparison: alphanumeric identifiers are compared as ASCII strings, while
|
||||
numeric identifiers are compared as numbers.
|
||||
*/
|
||||
enum class Id_type {
|
||||
alnum, ///< Identifier is alphanumerical
|
||||
num ///< Identifier is numeric
|
||||
};
|
||||
|
||||
/// Container for prerelease identifier value and it's type.
|
||||
/**
|
||||
Prerelease version string consist of an optional series of dot-separated identifiers.
|
||||
These identifiers can be either numerical or alphanumerical.
|
||||
This structure describes one such identifier.
|
||||
*/
|
||||
using Prerelease_identifier = std::pair<std::string, Id_type>;
|
||||
|
||||
/// Container for all prerelease identifiers for a given version string.
|
||||
using Prerelease_identifiers = std::vector<Prerelease_identifier>;
|
||||
|
||||
/// Build identifier is arbitrary string with no special meaning with regards to version precedence.
|
||||
using Build_identifier = std::string;
|
||||
|
||||
/// Container for all build identifiers of a given version string.
|
||||
using Build_identifiers = std::vector<Build_identifier>;
|
||||
|
||||
/// Description of version broken into parts, as per semantic versioning specification.
|
||||
struct Version_data {
|
||||
Version_data(const int M, const int m, const int p, const Prerelease_identifiers & pr, const Build_identifiers & b)
|
||||
: major{M}
|
||||
, minor{m}
|
||||
, patch{p}
|
||||
, prerelease_ids{pr}
|
||||
, build_ids{b} {
|
||||
}
|
||||
|
||||
int major; ///< Major version, change only on incompatible API modifications.
|
||||
int minor; ///< Minor version, change on backwards-compatible API modifications.
|
||||
int patch; ///< Patch version, change only on bugfixes.
|
||||
|
||||
/// Optional series of prerelease identifiers.
|
||||
Prerelease_identifiers prerelease_ids;
|
||||
|
||||
/// Optional series of build identifiers.
|
||||
Build_identifiers build_ids;
|
||||
};
|
||||
|
||||
// Forward declaration required for operators' template declarations.
|
||||
template <typename Parser, typename Comparator>
|
||||
class Basic_version;
|
||||
|
||||
/// Test if left-hand version operand is of lower precedence than the right-hand version.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator<(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Test if left-hand version operand if of equal precedence as the right-hand version.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator==(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Test if left-hand version and right-hand version are of different precedence.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator!=(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Test if left-hand version operand is of higher precedence than the right-hand version.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator>(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Test if left-hand version operand is of higher or equal precedence as the right-hand version.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator>=(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Test if left-hand version operand is of lower or equal precedence as the right-hand version.
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator<=(const Basic_version<Parser, Comparator> &, const Basic_version<Parser, Comparator> &);
|
||||
|
||||
/// Base class for various version parsing, precedence ordering and data manipulation schemes.
|
||||
/**
|
||||
Basic_version class describes general version object without prescribing parsing,
|
||||
validation, comparison and modification rules. These rules are implemented by supplied Parser, Comparator
|
||||
and Modifier objects.
|
||||
*/
|
||||
template <typename Parser, typename Comparator>
|
||||
class Basic_version {
|
||||
public:
|
||||
/// Construct Basic_version object using Parser object to parse default ("0.0.0") version string, Comparator for comparison and Modifier for modification.
|
||||
Basic_version(Parser, Comparator);
|
||||
|
||||
/// Construct Basic_version object using Parser to parse supplied version string, Comparator for comparison and Modifier for modification.
|
||||
Basic_version(const std::string &, Parser, Comparator);
|
||||
|
||||
/// Construct Basic_version object using supplied Version_data, Parser, Comparator and Modifier objects.
|
||||
Basic_version(const Version_data &, Parser, Comparator);
|
||||
|
||||
/// Construct Basic_version by copying data from another one.
|
||||
Basic_version(const Basic_version &);
|
||||
|
||||
/// Copy version data from another Basic_version to this one.
|
||||
Basic_version & operator=(const Basic_version &);
|
||||
|
||||
int major() const; ///< Get major version.
|
||||
int minor() const; ///< Get minor version.
|
||||
int patch() const; ///< Get patch version.
|
||||
const std::string prerelease() const; ///< Get prerelease version string.
|
||||
const std::string build() const; ///< Get build version string.
|
||||
|
||||
friend bool operator< <>(const Basic_version &, const Basic_version &);
|
||||
friend bool operator==<>(const Basic_version &, const Basic_version &);
|
||||
|
||||
private:
|
||||
Parser parser_;
|
||||
Comparator comparator_;
|
||||
Version_data ver_;
|
||||
};
|
||||
|
||||
} // namespace version
|
||||
|
||||
#include "version.inl"
|
||||
132
lib/semver/version.inl
Normal file
132
lib/semver/version.inl
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marko Zivanovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
|
||||
namespace version {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Utility function to splice all vector elements to output stream, using designated separator
|
||||
/// between elements and function object for getting values from vector elements.
|
||||
template <typename T, typename F>
|
||||
std::string & splice(std::string & ss, const std::vector<T> & vec, const std::string & sep, F read) {
|
||||
if (!vec.empty()) {
|
||||
for (auto it = vec.cbegin(); it < vec.cend() - 1; ++it) {
|
||||
ss += read(*it) + sep;
|
||||
}
|
||||
ss += read(*vec.crbegin());
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
Basic_version<Parser, Comparator>::Basic_version(Parser p, Comparator c)
|
||||
: parser_(p)
|
||||
, comparator_(c)
|
||||
, ver_(parser_.parse("0.0.0")) {
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
Basic_version<Parser, Comparator>::Basic_version(const std::string & v, Parser p, Comparator c)
|
||||
: parser_(p)
|
||||
, comparator_(c)
|
||||
, ver_(parser_.parse(v)) {
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
Basic_version<Parser, Comparator>::Basic_version(const Version_data & v, Parser p, Comparator c)
|
||||
: parser_(p)
|
||||
, comparator_(c)
|
||||
, ver_(v) {
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
Basic_version<Parser, Comparator>::Basic_version(const Basic_version<Parser, Comparator> &) = default;
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
Basic_version<Parser, Comparator> & Basic_version<Parser, Comparator>::operator=(const Basic_version<Parser, Comparator> &) = default;
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
int Basic_version<Parser, Comparator>::major() const {
|
||||
return ver_.major;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
int Basic_version<Parser, Comparator>::minor() const {
|
||||
return ver_.minor;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
int Basic_version<Parser, Comparator>::patch() const {
|
||||
return ver_.patch;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
const std::string Basic_version<Parser, Comparator>::prerelease() const {
|
||||
std::string ss;
|
||||
return splice(ss, ver_.prerelease_ids, ".", [](const Prerelease_identifier & id) { return id.first; });
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
const std::string Basic_version<Parser, Comparator>::build() const {
|
||||
std::string ss;
|
||||
return splice(ss, ver_.build_ids, ".", [](const std::string & id) { return id; });
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator<(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return l.comparator_.compare(l.ver_, r.ver_) == -1;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
bool operator==(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return l.comparator_.compare(l.ver_, r.ver_) == 0;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
inline bool operator!=(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
inline bool operator>(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return r < l;
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
inline bool operator>=(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return !(l < r);
|
||||
}
|
||||
|
||||
template <typename Parser, typename Comparator>
|
||||
inline bool operator<=(const Basic_version<Parser, Comparator> & l, const Basic_version<Parser, Comparator> & r) {
|
||||
return !(l > r);
|
||||
}
|
||||
|
||||
} // namespace version
|
||||
@@ -1,5 +1,5 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2026, Benoit BLANCHON
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@@ -239,11 +239,11 @@
|
||||
#define ARDUINOJSON_BIN2ALPHA_1111() P
|
||||
#define ARDUINOJSON_BIN2ALPHA_(A, B, C, D) ARDUINOJSON_BIN2ALPHA_##A##B##C##D()
|
||||
#define ARDUINOJSON_BIN2ALPHA(A, B, C, D) ARDUINOJSON_BIN2ALPHA_(A, B, C, D)
|
||||
#define ARDUINOJSON_VERSION "7.4.3"
|
||||
#define ARDUINOJSON_VERSION "7.4.2"
|
||||
#define ARDUINOJSON_VERSION_MAJOR 7
|
||||
#define ARDUINOJSON_VERSION_MINOR 4
|
||||
#define ARDUINOJSON_VERSION_REVISION 3
|
||||
#define ARDUINOJSON_VERSION_MACRO V743
|
||||
#define ARDUINOJSON_VERSION_REVISION 2
|
||||
#define ARDUINOJSON_VERSION_MACRO V742
|
||||
#ifndef ARDUINOJSON_VERSION_NAMESPACE
|
||||
#define ARDUINOJSON_VERSION_NAMESPACE \
|
||||
ARDUINOJSON_CONCAT5(ARDUINOJSON_VERSION_MACRO, \
|
||||
@@ -1536,12 +1536,11 @@ template <typename T, size_t = sizeof(T)>
|
||||
struct FloatTraits {};
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 8 /*64bits*/> {
|
||||
using mantissa_type = uint64_t;
|
||||
static const short mantissa_bits = 52;
|
||||
static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1;
|
||||
using exponent_type = int16_t;
|
||||
static const exponent_type exponent_max = 308;
|
||||
static const size_t binaryPowersOfTen = 9;
|
||||
using mantissa_type = uint64_t;
|
||||
static const short mantissa_bits = 52;
|
||||
static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1;
|
||||
using exponent_type = int16_t;
|
||||
static const exponent_type exponent_max = 308;
|
||||
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
||||
uint64_t,
|
||||
@@ -1602,12 +1601,11 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
||||
};
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 4 /*32bits*/> {
|
||||
using mantissa_type = uint32_t;
|
||||
static const short mantissa_bits = 23;
|
||||
static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1;
|
||||
using exponent_type = int8_t;
|
||||
static const exponent_type exponent_max = 38;
|
||||
static const size_t binaryPowersOfTen = 6;
|
||||
using mantissa_type = uint32_t;
|
||||
static const short mantissa_bits = 23;
|
||||
static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1;
|
||||
using exponent_type = int8_t;
|
||||
static const exponent_type exponent_max = 38;
|
||||
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t,
|
||||
factors,
|
||||
@@ -1670,12 +1668,9 @@ template <typename TFloat, typename TExponent>
|
||||
inline TFloat make_float(TFloat m, TExponent e) {
|
||||
using traits = FloatTraits<TFloat>;
|
||||
auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen() : traits::negativeBinaryPowersOfTen();
|
||||
auto count = traits::binaryPowersOfTen;
|
||||
if (e <= 0)
|
||||
e = TExponent(-e);
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (index >= count)
|
||||
return traits::nan();
|
||||
if (e & 1)
|
||||
m *= powersOfTen[index];
|
||||
e >>= 1;
|
||||
@@ -2427,7 +2422,7 @@ class VariantData {
|
||||
return;
|
||||
var->removeMember(key, resources);
|
||||
}
|
||||
void reset() { // TODO: remove
|
||||
void reset() {
|
||||
type_ = VariantType::Null;
|
||||
}
|
||||
void setBoolean(bool value) {
|
||||
@@ -4219,7 +4214,7 @@ template <typename T, typename Enable = void>
|
||||
struct Comparer;
|
||||
template <typename T>
|
||||
struct Comparer<T, enable_if_t<IsString<T>::value>> : ComparerBase {
|
||||
T rhs; // TODO: store adapted string?
|
||||
T rhs;
|
||||
explicit Comparer(T value)
|
||||
: rhs(value) {
|
||||
}
|
||||
@@ -5303,7 +5298,7 @@ class StringBuilder {
|
||||
append(*s++);
|
||||
}
|
||||
void append(const char * s, size_t n) {
|
||||
while (n-- > 0) // TODO: memcpy
|
||||
while (n-- > 0)
|
||||
append(*s++);
|
||||
}
|
||||
void append(char c) {
|
||||
|
||||
@@ -22,11 +22,10 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#define EMS_TXMODE_OFF 0
|
||||
#define EMS_TXMODE_EMS 1
|
||||
#define EMS_TXMODE_DEFAULT 1
|
||||
#define EMS_TXMODE_EMSPLUS 2
|
||||
#define EMS_TXMODE_HT3 3
|
||||
#define EMS_TXMODE_HW 4
|
||||
#define EMS_TXMODE_AUTO 5
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mock-api",
|
||||
"version": "3.8.2",
|
||||
"version": "3.8.0",
|
||||
"description": "mock api for EMS-ESP",
|
||||
"author": "proddy, emsesp.org",
|
||||
"license": "MIT",
|
||||
@@ -13,7 +13,7 @@
|
||||
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
||||
"formidable": "^3.5.4",
|
||||
"itty-router": "^5.0.23",
|
||||
"prettier": "^3.8.3"
|
||||
"prettier": "^3.8.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.33.1+sha512.05ba3c1d5d1c18f68df06470d74055e62d41fc110a0c660db1b2dfb2785327f04cf0f68345d4609bc52089e7fa0343c31593b2f9594e2c5d5da426230acc9820"
|
||||
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be"
|
||||
}
|
||||
|
||||
32
mock-api/pnpm-lock.yaml
generated
32
mock-api/pnpm-lock.yaml
generated
@@ -13,7 +13,7 @@ importers:
|
||||
version: 3.1.3
|
||||
'@trivago/prettier-plugin-sort-imports':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2(prettier@3.8.3)
|
||||
version: 6.0.2(prettier@3.8.1)
|
||||
formidable:
|
||||
specifier: ^3.5.4
|
||||
version: 3.5.4
|
||||
@@ -21,8 +21,8 @@ importers:
|
||||
specifier: ^5.0.23
|
||||
version: 5.0.23
|
||||
prettier:
|
||||
specifier: ^3.8.3
|
||||
version: 3.8.3
|
||||
specifier: ^3.8.1
|
||||
version: 3.8.1
|
||||
|
||||
packages:
|
||||
|
||||
@@ -112,8 +112,8 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
brace-expansion@2.1.0:
|
||||
resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==}
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
@@ -145,8 +145,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
lodash-es@4.18.1:
|
||||
resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
|
||||
lodash-es@4.17.23:
|
||||
resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
|
||||
|
||||
minimatch@9.0.9:
|
||||
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
|
||||
@@ -167,8 +167,8 @@ packages:
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
prettier@3.8.3:
|
||||
resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
|
||||
prettier@3.8.1:
|
||||
resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
@@ -246,17 +246,17 @@ snapshots:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.3)':
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.1)':
|
||||
dependencies:
|
||||
'@babel/generator': 7.29.1
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/traverse': 7.29.0
|
||||
'@babel/types': 7.29.0
|
||||
javascript-natural-sort: 0.7.1
|
||||
lodash-es: 4.18.1
|
||||
lodash-es: 4.17.23
|
||||
minimatch: 9.0.9
|
||||
parse-imports-exports: 0.2.4
|
||||
prettier: 3.8.3
|
||||
prettier: 3.8.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -264,7 +264,7 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
brace-expansion@2.1.0:
|
||||
brace-expansion@2.0.2:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
@@ -291,11 +291,11 @@ snapshots:
|
||||
|
||||
jsesc@3.1.0: {}
|
||||
|
||||
lodash-es@4.18.1: {}
|
||||
lodash-es@4.17.23: {}
|
||||
|
||||
minimatch@9.0.9:
|
||||
dependencies:
|
||||
brace-expansion: 2.1.0
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
@@ -311,6 +311,6 @@ snapshots:
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
prettier@3.8.3: {}
|
||||
prettier@3.8.1: {}
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
@@ -141,8 +141,8 @@ let system_status = {
|
||||
let DEV_VERSION_IS_UPGRADEABLE: boolean;
|
||||
let STABLE_VERSION_IS_UPGRADEABLE: boolean;
|
||||
let THIS_VERSION: string;
|
||||
let LATEST_STABLE_VERSION = '3.8.2';
|
||||
let LATEST_DEV_VERSION = '3.8.3-dev.2';
|
||||
let LATEST_STABLE_VERSION = '3.8.0';
|
||||
let LATEST_DEV_VERSION = '3.8.1-dev.2';
|
||||
|
||||
// scenarios for testing versioning
|
||||
let version_test = 0; // on latest stable, or switch to dev
|
||||
@@ -388,34 +388,13 @@ function custom_support() {
|
||||
'',
|
||||
"For help and questions please <a target='_blank' href='https://emsesp.org'>contact</a> your installer."
|
||||
],
|
||||
img_url: 'https://emsesp.org/media/images/designer.png'
|
||||
img_url: 'https://emsesp.org/_media/images/designer.png'
|
||||
// img_url: 'https://picsum.photos/200/300'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// called by Action endpoint upgradeImportantMessages
|
||||
function upgradeImportantMessages(version: string) {
|
||||
// 0 is do nothing
|
||||
// 1 means 3.9 and factory reset required
|
||||
// 2 means a major version upgrade
|
||||
let upgradeImportantMessageType_n = 0;
|
||||
|
||||
// see if its a filename with a .bin extension
|
||||
if (version.endsWith('.bin')) {
|
||||
upgradeImportantMessageType_n = 1; // 1 means 3.9 and factory reset required
|
||||
} else if (version.endsWith('.md')) {
|
||||
upgradeImportantMessageType_n = 0;
|
||||
} else {
|
||||
// this is a version string like "3.9.0"
|
||||
upgradeImportantMessageType_n = 2;
|
||||
}
|
||||
|
||||
console.log('upgradeImportantMessageType: ' + upgradeImportantMessageType_n);
|
||||
return { upgradeImportantMessageType: upgradeImportantMessageType_n };
|
||||
}
|
||||
|
||||
// called by Action endpoint checkUpgrade
|
||||
// called by Action endpoint
|
||||
function check_upgrade(version: string) {
|
||||
let data = {};
|
||||
if (version) {
|
||||
@@ -5191,9 +5170,6 @@ router
|
||||
// set partition
|
||||
console.log('setting partition to', content.param);
|
||||
return status(200);
|
||||
} else if (action === 'upgradeImportantMessages') {
|
||||
// check upgrade important messages
|
||||
return upgradeImportantMessages(content.param);
|
||||
}
|
||||
}
|
||||
return status(404); // cmd not found
|
||||
|
||||
@@ -20,7 +20,7 @@ my_build_flags =
|
||||
|
||||
[platformio]
|
||||
default_envs = s_16M_P ; BBQKees E32V2
|
||||
; default_envs = build-webUI ; build the web interface only
|
||||
; default_envs = build_webUI ; build the web interface only
|
||||
; default_envs = s3_16M_P ; BBQKees S3
|
||||
; default_envs = s_4M ; BBQKees older S32, 4MB no psram
|
||||
; default_envs = s_16M ; BBQKees newer S32 V2, 16MB no psram
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user