3.7.1
132
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by
|
||||||
|
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
|
||||||
|
at [https://www.contributor-covenant.org/translations][translations].
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||||
|
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||||
|
[FAQ]: https://www.contributor-covenant.org/faq
|
||||||
|
[translations]: https://www.contributor-covenant.org/translations
|
||||||
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -21,7 +21,7 @@ _Make sure your have performed every step and checked the applicable boxes befor
|
|||||||
|
|
||||||
- [ ] Searched the issue in [issues](https://github.com/emsesp/EMS-ESP32/issues)
|
- [ ] Searched the issue in [issues](https://github.com/emsesp/EMS-ESP32/issues)
|
||||||
- [ ] Searched the issue in [discussions](https://github.com/emsesp/EMS-ESP32/discussions)
|
- [ ] Searched the issue in [discussions](https://github.com/emsesp/EMS-ESP32/discussions)
|
||||||
- [ ] Searched the issue in the [docs](https://emsesp.org/Troubleshooting/)
|
- [ ] Searched the issue in the [docs](https://docs.emsesp.org/Troubleshooting/)
|
||||||
- [ ] Searched the issue in the [chat](https://discord.gg/3J3GgnzpyT)
|
- [ ] Searched the issue in the [chat](https://discord.gg/3J3GgnzpyT)
|
||||||
- [ ] Provide the System information in the area below, taken from `http://<IP>/api/system`
|
- [ ] Provide the System information in the area below, taken from `http://<IP>/api/system`
|
||||||
|
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: EMS-ESP Docs
|
- name: EMS-ESP Docs
|
||||||
url: https://emsesp.org
|
url: https://docs.emsesp.org
|
||||||
about: All the information related to EMS-ESP.
|
about: All the information related to EMS-ESP.
|
||||||
- name: EMS-ESP Discussions and Support
|
- name: EMS-ESP Discussions and Support
|
||||||
url: https://github.com/emsesp/EMS-ESP32/discussions
|
url: https://github.com/emsesp/EMS-ESP32/discussions
|
||||||
|
|||||||
1
.github/SUPPORT.md
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Support
|
||||||
37
.github/workflows/pr_check.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: 'pr_check'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
branches: dev
|
||||||
|
paths:
|
||||||
|
- '**.c'
|
||||||
|
- '**.cpp'
|
||||||
|
- '**.h'
|
||||||
|
- '**.hpp'
|
||||||
|
- '**.json'
|
||||||
|
- '**.py'
|
||||||
|
- '**.md'
|
||||||
|
- '.github/workflows/pr_check.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pre-release:
|
||||||
|
name: 'Automatic pre-release build'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install python 3.11
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install PlatformIO
|
||||||
|
run: |
|
||||||
|
pip install wheel
|
||||||
|
pip install -U platformio
|
||||||
|
|
||||||
|
- name: Build native
|
||||||
|
run: |
|
||||||
|
platformio run -e native
|
||||||
10
.gitignore
vendored
@@ -30,13 +30,8 @@ stats.html
|
|||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
.pnp.*
|
.pnp.*
|
||||||
*/.yarn/*
|
*/.yarn/cache/*
|
||||||
!.yarn/patches
|
*/.yarn/install-state.gz
|
||||||
!.yarn/plugins
|
|
||||||
!.yarn/releases
|
|
||||||
!.yarn/sdks
|
|
||||||
!.yarn/versions
|
|
||||||
yarn.lock
|
|
||||||
analyse.html
|
analyse.html
|
||||||
interface/vite.config.ts.timestamp*
|
interface/vite.config.ts.timestamp*
|
||||||
*.local
|
*.local
|
||||||
@@ -71,4 +66,3 @@ words-found-verbose.txt
|
|||||||
|
|
||||||
# sonarlint
|
# sonarlint
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
package.json
|
|
||||||
|
|||||||
6
.markdownlint.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"MD033": false,
|
||||||
|
"MD013": false,
|
||||||
|
"MD045": false,
|
||||||
|
"MD041": false
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [3.7.0] October 27 2024
|
## [3.7.0] 27 October 2024
|
||||||
|
|
||||||
## **IMPORTANT! BREAKING CHANGES with 3.6.5**
|
## **IMPORTANT! BREAKING CHANGES with 3.6.5**
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- The automatically generated temperature sensor ID has replaced dashes (`-`) with underscores (`_`) to be compatible with Home Assistant.
|
- The automatically generated temperature sensor ID has replaced dashes (`-`) with underscores (`_`) to be compatible with Home Assistant.
|
||||||
- `api/system/info` has it's JSON key names changed to camelCase syntax.
|
- `api/system/info` has it's JSON key names changed to camelCase syntax.
|
||||||
|
|
||||||
For more details go to [www.emsesp.org](https://www.emsesp.org/).
|
For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,34 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
|
||||||
|
|
||||||
|
## [3.7.1]
|
||||||
|
|
||||||
|
## **IMPORTANT! BREAKING CHANGES since v3.7.0**
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- include HA "unit_of_meas", "stat_cla" and "dev_cla" attributes for Number sensors [#2149](https://github.com/emsesp/EMS-ESP32/issues/2149)
|
||||||
|
- Bosch CS6800i AW - Silent Mode + Electrical Power Reduction (HP) [#2147](https://github.com/emsesp/EMS-ESP32/issues/2147)
|
||||||
|
- `/api/system/showeralert` and `/api/system/showertimer` [#2182](https://github.com/emsesp/EMS-ESP32/issues/2182)
|
||||||
|
- MX400 [#2198](https://github.com/emsesp/EMS-ESP32/issues/2198)
|
||||||
|
- SM200 values [#2212](https://github.com/emsesp/EMS-ESP32/discussions/2212)
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Modbus integration in 3.7.0 missing offset [#2148](https://github.com/emsesp/EMS-ESP32/issues/2148)
|
||||||
|
- fix changing TZ in NTPsettings without clearing enable+server, added DST support [#2142](https://github.com/emsesp/EMS-ESP32/issues/2142)
|
||||||
|
- Support MQTT Discovery (AD) with Domoticz [#2177](https://github.com/emsesp/EMS-ESP32/issues/2177)
|
||||||
|
- wwExtra (dhw extra) changed from temperature reading to number
|
||||||
|
- auxheaterstatus [#2192](https://github.com/emsesp/EMS-ESP32/issues/2192)
|
||||||
|
- lastCode character check [#2189](https://github.com/emsesp/EMS-ESP32/issues/2189)
|
||||||
|
- reading too many telegram parts
|
||||||
|
- heatpump cost UOMs [#2188](https://github.com/emsesp/EMS-ESP32/issues/2188)
|
||||||
|
- analog dac output and inputs on dac pins [#2201](https://github.com/emsesp/EMS-ESP32/discussions/2201)
|
||||||
|
- api memory leak [#2216](https://github.com/emsesp/EMS-ESP32/issues/2216)
|
||||||
|
- modbus multiple mixers [#2229](https://github.com/emsesp/EMS-ESP32/issues/2229)
|
||||||
|
- Last Will (LWT) not set on MQTT Connect [#2247](https://github.com/emsesp/EMS-ESP32/issues/2247)
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- name of wwstarts2 [#2217](https://github.com/emsesp/EMS-ESP32/discussions/2217)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Everybody is welcome and invited to contribute to the EMS-ESP Project by:
|
|||||||
|
|
||||||
- providing Pull Requests (Features, Fixes, suggestions)
|
- providing Pull Requests (Features, Fixes, suggestions)
|
||||||
- testing new released features and report issues on your EMS equipment
|
- testing new released features and report issues on your EMS equipment
|
||||||
- contributing to missing [documentation](https://emsesp.org)
|
- contributing to missing [documentation](https://docs.emsesp.org)
|
||||||
|
|
||||||
This document describes rules that are in effect for this repository, meant for handling issues by contributors in the issue tracker and PRs.
|
This document describes rules that are in effect for this repository, meant for handling issues by contributors in the issue tracker and PRs.
|
||||||
|
|
||||||
|
|||||||
42
Makefile
@@ -1,10 +1,27 @@
|
|||||||
#
|
#
|
||||||
# GNUMakefile for EMS-ESP
|
# GNUMakefile for EMS-ESP
|
||||||
# This is mainly used to generate the .o files for SonarQube analysis
|
|
||||||
#
|
#
|
||||||
|
|
||||||
# NUMJOBS=${NUMJOBS:-" -j10 "}
|
_mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
# MAKEFLAGS+="j "
|
I := $(patsubst %/,%,$(dir $(_mkfile_path)))
|
||||||
|
|
||||||
|
ifneq ($(words $(MAKECMDGOALS)),1)
|
||||||
|
.DEFAULT_GOAL = all
|
||||||
|
%:
|
||||||
|
@$(MAKE) $@ --no-print-directory -rRf $(firstword $(MAKEFILE_LIST))
|
||||||
|
else
|
||||||
|
ifndef ECHO
|
||||||
|
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
|
||||||
|
-nrRf $(firstword $(MAKEFILE_LIST)) \
|
||||||
|
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
|
||||||
|
N := x
|
||||||
|
C = $(words $N)$(eval N := x $N)
|
||||||
|
ECHO = python $(I)/echo_progress.py --stepno=$C --nsteps=$T
|
||||||
|
endif
|
||||||
|
|
||||||
|
# number of parallel compiles
|
||||||
|
JOBS ?= $(shell nproc)
|
||||||
|
MAKEFLAGS += -j $(JOBS) -l $(JOBS)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# Project Structure
|
# Project Structure
|
||||||
@@ -43,7 +60,7 @@ DEFINES += -DARDUINOJSON_ENABLE -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSO
|
|||||||
DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500
|
DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500
|
||||||
DEFINES += $(ARGS)
|
DEFINES += $(ARGS)
|
||||||
|
|
||||||
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.1-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S3\"
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# Sources & Files
|
# Sources & Files
|
||||||
@@ -125,23 +142,27 @@ COMPILE.cpp = $(CXX) $(CXX_STANDARD) $(CXXFLAGS) $(DEPFLAGS) -c $< -o $@
|
|||||||
.SILENT: $(OUTPUT)
|
.SILENT: $(OUTPUT)
|
||||||
|
|
||||||
all: $(OUTPUT)
|
all: $(OUTPUT)
|
||||||
|
@$(ECHO) All done
|
||||||
|
|
||||||
$(OUTPUT): $(OBJS)
|
$(OUTPUT): $(OBJS)
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
|
@$(ECHO) Linking $@
|
||||||
$(LINK.o)
|
$(LINK.o)
|
||||||
$(SYMBOLS.out)
|
$(SYMBOLS.out)
|
||||||
|
|
||||||
$(BUILD)/%.o: %.c
|
$(BUILD)/%.o: %.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(COMPILE.c)
|
@$(ECHO) Compiling $@
|
||||||
|
@$(COMPILE.c)
|
||||||
|
|
||||||
$(BUILD)/%.o: %.cpp
|
$(BUILD)/%.o: %.cpp
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(COMPILE.cpp)
|
@$(ECHO) Compiling $@
|
||||||
|
@$(COMPILE.cpp)
|
||||||
|
|
||||||
$(BUILD)/%.o: %.s
|
$(BUILD)/%.o: %.s
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(COMPILE.s)
|
@$(COMPILE.s)
|
||||||
|
|
||||||
cppcheck: $(SOURCES)
|
cppcheck: $(SOURCES)
|
||||||
$(CPPCHECK) $(CHECKFLAGS) $^
|
$(CPPCHECK) $(CHECKFLAGS) $^
|
||||||
@@ -150,6 +171,7 @@ run: $(OUTPUT)
|
|||||||
@$<
|
@$<
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(RM) -rf $(BUILD) $(OUTPUT)
|
@$(RM) -rf $(BUILD) $(OUTPUT)
|
||||||
|
|
||||||
@@ -157,4 +179,6 @@ help:
|
|||||||
@echo available targets: all run clean
|
@echo available targets: all run clean
|
||||||
@echo $(OUTPUT)
|
@echo $(OUTPUT)
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|||||||
54
README.md
@@ -1,4 +1,30 @@
|
|||||||
# 
|
<div align="center">
|
||||||
|
<p align="center">
|
||||||
|
<a href="#">
|
||||||
|
<img src="https://raw.githubusercontent.com/emsesp/EMS-ESP32/dev/media/favicon/android-chrome-512x512.png" height="100px" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 align="center">EMS-ESP</h1>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://emsesp.org">
|
||||||
|
<img src="https://img.shields.io/badge/Website-0077b5?style=for-the-badge&logo=googlehome&logoColor=white" alt="Website" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/emsesp/EMS-ESP32/blob/dev/CONTRIBUTING.md">
|
||||||
|
<img src="https://img.shields.io/badge/Contribute-ff4785?style=for-the-badge&logo=git&logoColor=white" alt="Contribute" />
|
||||||
|
</a>
|
||||||
|
<a href="https://docs.emsesp.org">
|
||||||
|
<img src="https://img.shields.io/badge/Documentation-0077b5?style=for-the-badge&logo=googledocs&logoColor=white" alt="Guides" />
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.gg/3J3GgnzpyT">
|
||||||
|
<img src="https://img.shields.io/badge/Discord-7289da?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md">
|
||||||
|
<img src="https://img.shields.io/badge/Changelog-6c5ce7?style=for-the-badge&logo=git&logoColor=white" alt="Changelog" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
[](https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md)
|
[](https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md)
|
||||||
[](https://github.com/emsesp/EMS-ESP32/commits/main)
|
[](https://github.com/emsesp/EMS-ESP32/commits/main)
|
||||||
@@ -16,7 +42,7 @@
|
|||||||
|
|
||||||
It requires a small circuit to interface with the EMS bus which can be purchased from <https://bbqkees-electronics.nl> or custom built.
|
It requires a small circuit to interface with the EMS bus which can be purchased from <https://bbqkees-electronics.nl> or custom built.
|
||||||
|
|
||||||
## **Key Features**
|
## 📦 **Key Features**
|
||||||
|
|
||||||
- Compatible with EMS, EMS+, EMS2, EMS Plus, Logamatic EMS, Junkers 2-wire, Heatronic 3 and 4
|
- Compatible with EMS, EMS+, EMS2, EMS Plus, Logamatic EMS, Junkers 2-wire, Heatronic 3 and 4
|
||||||
- Supporting over 120 different EMS compatible devices such as thermostats, boilers, heat pumps, mixing units, solar modules, connect modules, ventilation units, switches and more
|
- Supporting over 120 different EMS compatible devices such as thermostats, boilers, heat pumps, mixing units, solar modules, connect modules, ventilation units, switches and more
|
||||||
@@ -32,35 +58,31 @@ It requires a small circuit to interface with the EMS bus which can be purchased
|
|||||||
- A powerful Scheduler to automate tasks and trigger events based data changes
|
- A powerful Scheduler to automate tasks and trigger events based data changes
|
||||||
- A Notification service to alert you of important events
|
- A Notification service to alert you of important events
|
||||||
|
|
||||||
## **Installing**
|
## 🚀 **Installing**
|
||||||
|
|
||||||
For a quick install of the latest stable release go to [https://install.emsesp.org](https://install.emsesp.org). For other methods of installing and upgrading, and switching over to the development version go to [this section](https://emsesp.org/Getting-Started/#first-time-install) in the documentation.
|
Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Getting-Started/#first-time-install) of the documentation.
|
||||||
|
|
||||||
If you're upgrading a BBQKees Electronics EMS Gateway and unsure which firmware to use, please refer to the [this overview](https://emsesp.org/Getting-Started/#bbqkees-electronics-ems-gateway).
|
## 📋 **Documentation**
|
||||||
|
|
||||||
## **Documentation**
|
Visit [emsesp.org](https://docs.emsesp.org) for more details on how to install and configure EMS-ESP. There is also a collection of Frequently Asked Questions and Troubleshooting tips with example customizations from the community.
|
||||||
|
|
||||||
Visit [emsesp.org](https://emsesp.org) for more details on how to install and configure EMS-ESP. There is also a collection of Frequently Asked Questions and Troubleshooting tips with example customizations from the community.
|
## 💬 **Getting Support**
|
||||||
|
|
||||||
## **Getting Support**
|
|
||||||
|
|
||||||
To chat with the community reach out on our [Discord Server](https://discord.gg/3J3GgnzpyT).
|
To chat with the community reach out on our [Discord Server](https://discord.gg/3J3GgnzpyT).
|
||||||
|
|
||||||
If you find an issue or have a request, see [here](https://emsesp.org/Support/) on how to submit a bug report or feature request.
|
If you find an issue or have a request, see [here](https://docs.emsesp.org/Support/) on how to submit a bug report or feature request.
|
||||||
|
|
||||||
## **Live Demo**
|
## 🎥 **Live Demo**
|
||||||
|
|
||||||
For a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a language from the sign on page and log in with any username or password. Note not all features are operational as it's based on static data.
|
For a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a language from the sign on page and log in with any username or password. Note not all features are operational as it's based on static data.
|
||||||
|
|
||||||
## **Contributors**
|
## 💖 **Contributors**
|
||||||
|
|
||||||
EMS-ESP is a project created by [proddy](https://github.com/proddy) and owned and maintained by both [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP) with support from [BBQKees Electronics](https://bbqkees-electronics.nl).
|
EMS-ESP is a project created by [proddy](https://github.com/proddy) and owned and maintained by both [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP) with support from [BBQKees Electronics](https://bbqkees-electronics.nl).
|
||||||
|
|
||||||
You can contact us using [this form](https://emsesp.org/Contact/).
|
|
||||||
|
|
||||||
If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it and contribute. You can also offer a small donation. This is an open-source project maintained by volunteers, and your support is greatly appreciated.
|
If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it and contribute. You can also offer a small donation. This is an open-source project maintained by volunteers, and your support is greatly appreciated.
|
||||||
|
|
||||||
## **Libraries used**
|
## 📢 **Libraries used**
|
||||||
|
|
||||||
- [esp8266-react](https://github.com/rjwats/esp8266-react) by @rjwats for the core framework that provides the Web UI, which has been heavily modified
|
- [esp8266-react](https://github.com/rjwats/esp8266-react) by @rjwats for the core framework that provides the Web UI, which has been heavily modified
|
||||||
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
|
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
|
||||||
@@ -68,7 +90,7 @@ If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it
|
|||||||
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
|
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
|
||||||
- ESPAsyncWebServer and AsyncTCP for the Web server and TCP backends, with custom modifications for performance
|
- ESPAsyncWebServer and AsyncTCP for the Web server and TCP backends, with custom modifications for performance
|
||||||
|
|
||||||
## **License**
|
## 📜 **License**
|
||||||
|
|
||||||
This program is licensed under GPL-3.0
|
This program is licensed under GPL-3.0
|
||||||
|
|
||||||
|
|||||||
22
cspell.json
@@ -9,5 +9,25 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dictionaries": ["project-words"],
|
"dictionaries": ["project-words"],
|
||||||
"ignorePaths": ["node_modules", "compile_commands.json", "WWWData.h", "**/venv/**", "lib/eModbus", "lib/ESPAsyncWebServer", "lib/espMqttClient", "analyse.html", "dist", "**/*.csv", "locale_translations.h", "TZ.tsx", "**/*.txt","build/**", "**/i18n/**", "/project-words.txt"]
|
"ignorePaths": [
|
||||||
|
"node_modules",
|
||||||
|
"compile_commands.json",
|
||||||
|
"WWWData.h", "**/venv/**",
|
||||||
|
"lib/eModbus",
|
||||||
|
"lib/ESPAsyncWebServer",
|
||||||
|
"lib/espMqttClient",
|
||||||
|
"analyse.html",
|
||||||
|
"dist",
|
||||||
|
"**/*.csv",
|
||||||
|
"**/*.md",
|
||||||
|
"**/*.py",
|
||||||
|
"locale_translations.h",
|
||||||
|
"TZ.tsx",
|
||||||
|
"**/*.txt",
|
||||||
|
"build/**",
|
||||||
|
"**/i18n/**",
|
||||||
|
"/project-words.txt",
|
||||||
|
"Makefile",
|
||||||
|
"src/modbus_entity_parameters.hpp"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
85
data/pre_load.json
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"type": "settings",
|
||||||
|
"Network": {
|
||||||
|
"ssid": "my_wifi_ssid",
|
||||||
|
"bssid": "",
|
||||||
|
"password": "my_wifi_password",
|
||||||
|
"hostname": "ems-esp"
|
||||||
|
},
|
||||||
|
"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": "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
|
||||||
|
},
|
||||||
|
"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": {
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x3B,Energy,
|
0x3B,Energy,
|
||||||
0x3D,RC35Set,
|
0x3D,RC35Set,
|
||||||
0x3E,RC35Monitor,
|
0x3E,RC35Monitor,
|
||||||
0x3F,RC35Timer,
|
0x3F,RC30Timer,
|
||||||
0x40,RC30Temp,
|
0x40,RC30Temp,
|
||||||
0x41,RC30Monitor,
|
0x41,RC30Monitor,
|
||||||
0x42,RC35Timer2,
|
0x42,RC35Timer2,
|
||||||
@@ -75,6 +75,8 @@ telegram_type_id,name,is_fetched
|
|||||||
0x0104,ISM2StatusMessage,
|
0x0104,ISM2StatusMessage,
|
||||||
0x010C,IPMStatusMessage,
|
0x010C,IPMStatusMessage,
|
||||||
0x011E,IPMTempMessage,
|
0x011E,IPMTempMessage,
|
||||||
|
0x012E,HPEnergy1,
|
||||||
|
0x013B,HPEnergy2,
|
||||||
0x0165,JunkersSet,
|
0x0165,JunkersSet,
|
||||||
0x0166,JunkersSet,
|
0x0166,JunkersSet,
|
||||||
0x0167,JunkersSet,
|
0x0167,JunkersSet,
|
||||||
@@ -107,7 +109,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x02A2,RC300Curves,
|
0x02A2,RC300Curves,
|
||||||
0x02A5,RC300Monitor,
|
0x02A5,RC300Monitor,
|
||||||
0x02A6,RC300Monitor,
|
0x02A6,RC300Monitor,
|
||||||
0x02A7,RC300Monitor,
|
0x02A7,CRFMonitor,
|
||||||
0x02A8,RC300Monitor,
|
0x02A8,RC300Monitor,
|
||||||
0x02A9,RC300Monitor,
|
0x02A9,RC300Monitor,
|
||||||
0x02AA,RC300Monitor,
|
0x02AA,RC300Monitor,
|
||||||
@@ -129,20 +131,20 @@ telegram_type_id,name,is_fetched
|
|||||||
0x02BE,RC300Set,
|
0x02BE,RC300Set,
|
||||||
0x02BF,RC300Set,
|
0x02BF,RC300Set,
|
||||||
0x02C0,RC300Set,
|
0x02C0,RC300Set,
|
||||||
0x02CC,RC300Set2,
|
0x02CC,HPPressure,fetched
|
||||||
0x02CD,MMPLUSConfigMessage,fetched
|
0x02CD,MMPLUSConfigMessage,fetched
|
||||||
0x02CE,RC300Set2,
|
0x02CE,RC300Set2,
|
||||||
0x02D0,RC300Set2,
|
0x02D0,RC300Set2,
|
||||||
0x02D2,RC300Set2,
|
0x02D2,RC300Set2,
|
||||||
0x02D5,MMPLUSConfigMessage,fetched
|
|
||||||
0x02D6,HPPump2,fetched
|
0x02D6,HPPump2,fetched
|
||||||
0x02D7,MMPLUSStatusMessage,
|
0x02D7,MMPLUSStatusMessage,
|
||||||
0x02DF,MMPLUSStatusMessage,
|
|
||||||
0x02F5,RC300WWmode,fetched
|
0x02F5,RC300WWmode,fetched
|
||||||
0x02F6,RC300WW2mode,fetched
|
0x02F6,RC300WW2mode,fetched
|
||||||
|
0x0313,MMPLUSConfigMessage_WWC,fetched
|
||||||
0x031B,RC300WWtemp,fetched
|
0x031B,RC300WWtemp,fetched
|
||||||
0x031D,RC300WWmode2,
|
0x031D,RC300WWmode2,
|
||||||
0x031E,RC300WWmode2,
|
0x031E,RC300WWmode2,
|
||||||
|
0x0331,MMPLUSStatusMessage_WWC,
|
||||||
0x0358,SM100SystemConfig,fetched
|
0x0358,SM100SystemConfig,fetched
|
||||||
0x035A,SM100CircuitConfig,fetched
|
0x035A,SM100CircuitConfig,fetched
|
||||||
0x035C,SM100HeatAssist,fetched
|
0x035C,SM100HeatAssist,fetched
|
||||||
@@ -199,6 +201,15 @@ telegram_type_id,name,is_fetched
|
|||||||
0x05D9,Airquality,
|
0x05D9,Airquality,
|
||||||
0x0772,HIUSettings,
|
0x0772,HIUSettings,
|
||||||
0x0779,HIUMonitor,
|
0x0779,HIUMonitor,
|
||||||
|
0x07A5,SM100wwCirc,fetched
|
||||||
|
0x07A6,SM100wwParam,fetched
|
||||||
|
0x07AA,SM100wwStatus,
|
||||||
|
0x07AB,SM100wwCommand,
|
||||||
|
0x07AC,SM100wwParam1,
|
||||||
|
0x07AD,SM100ValveStatus,
|
||||||
|
0x07AE,SM100wwKeepWarm,fetched
|
||||||
|
0x07D6,SM100wwTemperature,
|
||||||
|
0x07E0,SM100wwStatus2,fetched
|
||||||
0x0935,EM100SetMessage,fetched
|
0x0935,EM100SetMessage,fetched
|
||||||
0x0936,EM100OutMessage,
|
0x0936,EM100OutMessage,
|
||||||
0x0937,EM100TempMessage,
|
0x0937,EM100TempMessage,
|
||||||
@@ -207,6 +218,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x093A,EM100ConfigMessage,
|
0x093A,EM100ConfigMessage,
|
||||||
0x0998,HPSettings,fetched
|
0x0998,HPSettings,fetched
|
||||||
0x0999,HPFunctionTest,fetched
|
0x0999,HPFunctionTest,fetched
|
||||||
|
0x099A,HPStarts,
|
||||||
0x099B,HPFlowTemp,
|
0x099B,HPFlowTemp,
|
||||||
0x099C,HPComp,
|
0x099C,HPComp,
|
||||||
0x09A0,HPTemperature,
|
0x09A0,HPTemperature,
|
||||||
|
28
echo_progress.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
"""
|
||||||
|
Print makefile progress
|
||||||
|
From https://stackoverflow.com/questions/451413/make-makefile-progress-indication
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument("--stepno", type=int, required=True)
|
||||||
|
parser.add_argument("--nsteps", type=int, required=True)
|
||||||
|
parser.add_argument("remainder", nargs=argparse.REMAINDER)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
nchars = int(math.log(args.nsteps, 10)) + 1
|
||||||
|
fmt_str = "[{:Xd}/{:Xd}]({:6.2f}%)".replace("X", str(nchars))
|
||||||
|
progress = 100 * args.stepno / args.nsteps
|
||||||
|
sys.stdout.write(fmt_str.format(args.stepno, args.nsteps, progress))
|
||||||
|
for item in args.remainder:
|
||||||
|
sys.stdout.write(" ")
|
||||||
|
sys.stdout.write(item)
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
934
interface/.yarn/releases/yarn-4.5.3.cjs
vendored
Executable file
@@ -1 +1,3 @@
|
|||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-4.5.3.cjs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "EMS-ESP",
|
"name": "EMS-ESP",
|
||||||
"version": "3.7.0",
|
"version": "3.7.1",
|
||||||
"description": "EMS-ESP WebUI",
|
"description": "EMS-ESP WebUI",
|
||||||
"homepage": "https://emsesp.org",
|
"homepage": "https://emsesp.org",
|
||||||
"author": "proddy, emsesp.org",
|
"author": "proddy, emsesp.org",
|
||||||
@@ -12,56 +12,55 @@
|
|||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted",
|
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted",
|
||||||
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"npm:mock-rest\" \"vite preview\"",
|
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"yarn:mock-rest\" \"vite preview\"",
|
||||||
"mock-rest": "bun --watch ../mock-api/rest_server.ts",
|
"mock-rest": "bun --watch ../mock-api/rest_server.ts",
|
||||||
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-rest\" \"vite\"",
|
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"yarn:mock-rest\" \"vite\"",
|
||||||
"typesafe-i18n": "typesafe-i18n --no-watch",
|
"typesafe-i18n": "typesafe-i18n --no-watch",
|
||||||
"webUI": "node progmem-generator.js",
|
"webUI": "node progmem-generator.js",
|
||||||
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
|
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
|
||||||
"lint": "eslint . --fix"
|
"lint": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alova/adapter-xhr": "2.0.9",
|
"@alova/adapter-xhr": "2.0.10",
|
||||||
"@emotion/react": "^11.13.3",
|
"@emotion/react": "^11.13.5",
|
||||||
"@emotion/styled": "^11.13.0",
|
"@emotion/styled": "^11.13.5",
|
||||||
"@mui/icons-material": "^6.1.5",
|
"@mui/icons-material": "^6.1.9",
|
||||||
"@mui/material": "^6.1.5",
|
"@mui/material": "^6.1.9",
|
||||||
"@table-library/react-table-library": "4.1.7",
|
"@table-library/react-table-library": "4.1.7",
|
||||||
"alova": "3.1.1",
|
"alova": "3.2.5",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"preact": "^10.24.3",
|
"preact": "^10.25.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-icons": "^5.3.0",
|
"react-icons": "^5.3.0",
|
||||||
"react-router-dom": "^6.27.0",
|
"react-router": "^7.0.1",
|
||||||
"react-toastify": "^10.0.6",
|
"react-toastify": "^10.0.6",
|
||||||
"typesafe-i18n": "^5.26.2",
|
"typesafe-i18n": "^5.26.2",
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.26.0",
|
"@babel/core": "^7.26.0",
|
||||||
"@eslint/js": "^9.13.0",
|
"@eslint/js": "^9.15.0",
|
||||||
"@preact/compat": "^18.3.1",
|
"@preact/compat": "^18.3.1",
|
||||||
"@preact/preset-vite": "^2.9.1",
|
"@preact/preset-vite": "^2.9.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/formidable": "^3",
|
"@types/formidable": "^3",
|
||||||
"@types/node": "^22.8.1",
|
"@types/node": "^22.10.1",
|
||||||
"@types/react": "^18.3.12",
|
"@types/react": "^18.3.12",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"concurrently": "^9.1.0",
|
||||||
"concurrently": "^9.0.1",
|
"eslint": "^9.15.0",
|
||||||
"eslint": "^9.13.0",
|
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"formidable": "^3.5.2",
|
"formidable": "^3.5.2",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.4.1",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"terser": "^5.36.0",
|
"terser": "^5.36.0",
|
||||||
"typescript-eslint": "8.11.0",
|
"typescript-eslint": "8.16.0",
|
||||||
"vite": "^5.4.10",
|
"vite": "^6.0.1",
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
"vite-tsconfig-paths": "^5.0.1"
|
"vite-tsconfig-paths": "^5.1.3"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.1"
|
"packageManager": "yarn@4.5.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useContext, useEffect } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import AuthenticatedRouting from 'AuthenticatedRouting';
|
import AuthenticatedRouting from 'AuthenticatedRouting';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router';
|
||||||
|
|
||||||
import CustomEntities from 'app/main/CustomEntities';
|
import CustomEntities from 'app/main/CustomEntities';
|
||||||
import Customizations from 'app/main/Customizations';
|
import Customizations from 'app/main/Customizations';
|
||||||
|
|||||||
@@ -57,7 +57,10 @@ export const alovaInstance = createAlova({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const alovaInstanceGH = createAlova({
|
export const alovaInstanceGH = createAlova({
|
||||||
baseURL: 'https://api.github.com/repos/emsesp/EMS-ESP32/releases',
|
baseURL:
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? '/gh'
|
||||||
|
: 'https://api.github.com/repos/emsesp/EMS-ESP32/releases',
|
||||||
statesHook: ReactHook,
|
statesHook: ReactHook,
|
||||||
requestAdapter: xhrRequestAdapter()
|
requestAdapter: xhrRequestAdapter()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useBlocker } from 'react-router-dom';
|
import { useBlocker } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useBlocker, useLocation } from 'react-router-dom';
|
import { useBlocker, useLocation } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const Dashboard = () => {
|
|||||||
},
|
},
|
||||||
&:hover .td {
|
&:hover .td {
|
||||||
background-color: #177ac9;
|
background-color: #177ac9;
|
||||||
}
|
},
|
||||||
`,
|
`,
|
||||||
BaseCell: `
|
BaseCell: `
|
||||||
&:nth-of-type(2) {
|
&:nth-of-type(2) {
|
||||||
@@ -185,18 +185,16 @@ const Dashboard = () => {
|
|||||||
// if its a device (parent node) and has entities
|
// if its a device (parent node) and has entities
|
||||||
if (di.nodes?.length) {
|
if (di.nodes?.length) {
|
||||||
return (
|
return (
|
||||||
<>
|
<span style={{ fontWeight: 'bold', fontSize: '14px' }}>
|
||||||
<span style="font-size: 14px">
|
<DeviceIcon type_id={di.t ?? 0} />
|
||||||
<DeviceIcon type_id={di.t ?? 0} />
|
{showType(di.n, di.t)}
|
||||||
{showType(di.n, di.t)}
|
|
||||||
</span>
|
|
||||||
<span style={{ color: 'lightblue' }}> ({di.nodes?.length})</span>
|
<span style={{ color: 'lightblue' }}> ({di.nodes?.length})</span>
|
||||||
</>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (di.dv) {
|
if (di.dv) {
|
||||||
return <span style="color:lightgrey">{di.dv.id.slice(2)}</span>;
|
return <span>{di.dv.id.slice(2)}</span>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,10 +248,10 @@ const Dashboard = () => {
|
|||||||
onChange={handleShowAll}
|
onChange={handleShowAll}
|
||||||
>
|
>
|
||||||
<ToggleButton value={true}>
|
<ToggleButton value={true}>
|
||||||
<UnfoldMoreIcon sx={{ fontSize: 14 }} />
|
<UnfoldMoreIcon sx={{ fontSize: 18 }} />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton value={false}>
|
<ToggleButton value={false}>
|
||||||
<UnfoldLessIcon sx={{ fontSize: 14 }} />
|
<UnfoldLessIcon sx={{ fontSize: 18 }} />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -304,9 +302,7 @@ const Dashboard = () => {
|
|||||||
title={formatValue(LL, di.dv?.v, di.dv?.u)}
|
title={formatValue(LL, di.dv?.v, di.dv?.u)}
|
||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
<span style={{ color: 'lightgrey' }}>
|
<span>{formatValue(LL, di.dv?.v, di.dv?.u)}</span>
|
||||||
{formatValue(LL, di.dv?.v, di.dv?.u)}
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Cell>
|
</Cell>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { IconContext } from 'react-icons';
|
import { IconContext } from 'react-icons';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||||
@@ -155,7 +155,6 @@ const Devices = () => {
|
|||||||
}
|
}
|
||||||
&.tr.tr-body.row-select.row-select-single-selected {
|
&.tr.tr-body.row-select.row-select-single-selected {
|
||||||
background-color: #177ac9;
|
background-color: #177ac9;
|
||||||
font-weight: normal;
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
@@ -169,11 +168,11 @@ const Devices = () => {
|
|||||||
HeaderRow: `
|
HeaderRow: `
|
||||||
.th {
|
.th {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
height: 36px;
|
|
||||||
`,
|
`,
|
||||||
Row: `
|
Row: `
|
||||||
|
font-weight: bold;
|
||||||
&:hover .td {
|
&:hover .td {
|
||||||
background-color: #177ac9;
|
background-color: #177ac9;
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@@ -216,7 +215,7 @@ const Devices = () => {
|
|||||||
background-color: #303030;
|
background-color: #303030;
|
||||||
},
|
},
|
||||||
&:hover .td {
|
&:hover .td {
|
||||||
background-color: #177ac9;
|
background-color: #177ac9;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
@@ -307,9 +306,9 @@ const Devices = () => {
|
|||||||
|
|
||||||
const customize = () => {
|
const customize = () => {
|
||||||
if (selectedDevice === 99) {
|
if (selectedDevice === 99) {
|
||||||
navigate('/customentities');
|
void navigate('/customentities');
|
||||||
} else {
|
} else {
|
||||||
navigate('/customizations', { state: selectedDevice });
|
void navigate('/customizations', { state: selectedDevice });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -523,7 +522,7 @@ const Devices = () => {
|
|||||||
<IconContext.Provider
|
<IconContext.Provider
|
||||||
value={{
|
value={{
|
||||||
color: 'lightblue',
|
color: 'lightblue',
|
||||||
size: '18',
|
size: '16',
|
||||||
style: { verticalAlign: 'middle' }
|
style: { verticalAlign: 'middle' }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -574,7 +573,9 @@ const Devices = () => {
|
|||||||
|
|
||||||
const deviceValueDialogClose = () => {
|
const deviceValueDialogClose = () => {
|
||||||
setDeviceValueDialogOpen(false);
|
setDeviceValueDialogOpen(false);
|
||||||
void sendDeviceData(selectedDevice);
|
if (selectedDevice !== undefined) {
|
||||||
|
void sendDeviceData(selectedDevice);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderDeviceData = () => {
|
const renderDeviceData = () => {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const Help = () => {
|
|||||||
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
|
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
|
||||||
const [notFound, setNotFound] = useState<boolean>(false);
|
const [notFound, setNotFound] = useState<boolean>(false);
|
||||||
|
|
||||||
useRequest(() => callAction({ action: 'customSupport' })).onSuccess((event) => {
|
useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
|
||||||
if (event && event.data && Object.keys(event.data).length !== 0) {
|
if (event && event.data && Object.keys(event.data).length !== 0) {
|
||||||
const data = event.data.Support;
|
const data = event.data.Support;
|
||||||
if (data.img_url) {
|
if (data.img_url) {
|
||||||
@@ -78,44 +78,43 @@ const Help = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContent>
|
<SectionContent>
|
||||||
<Stack
|
{customSupportHTML && (
|
||||||
padding={1}
|
<Stack
|
||||||
mb={2}
|
padding={1}
|
||||||
direction="row"
|
mb={2}
|
||||||
divider={<Divider orientation="vertical" flexItem />}
|
direction="row"
|
||||||
sx={{
|
divider={<Divider orientation="vertical" flexItem />}
|
||||||
borderRadius: 3,
|
|
||||||
border: '2px solid grey',
|
|
||||||
justifyContent: 'space-evenly',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography variant="subtitle1">
|
|
||||||
{customSupportHTML ? (
|
|
||||||
<div dangerouslySetInnerHTML={{ __html: customSupportHTML }} />
|
|
||||||
) : (
|
|
||||||
LL.HELP_INFORMATION_5()
|
|
||||||
)}
|
|
||||||
</Typography>
|
|
||||||
<Box
|
|
||||||
component="img"
|
|
||||||
referrerPolicy="no-referrer"
|
|
||||||
sx={{
|
sx={{
|
||||||
maxHeight: { xs: 100, md: 250 }
|
borderRadius: 3,
|
||||||
|
border: '2px solid grey',
|
||||||
|
justifyContent: 'space-evenly',
|
||||||
|
alignItems: 'center'
|
||||||
}}
|
}}
|
||||||
onError={() => setNotFound(true)}
|
>
|
||||||
src={
|
<Typography variant="subtitle1">
|
||||||
notFound
|
<div dangerouslySetInnerHTML={{ __html: customSupportHTML }} />
|
||||||
? ''
|
</Typography>
|
||||||
: customSupportIMG || 'https://emsesp.org/_media/images/installer.jpeg'
|
<Box
|
||||||
}
|
component="img"
|
||||||
/>
|
referrerPolicy="no-referrer"
|
||||||
</Stack>
|
sx={{
|
||||||
|
maxHeight: { xs: 100, md: 250 }
|
||||||
|
}}
|
||||||
|
onError={() => setNotFound(true)}
|
||||||
|
src={
|
||||||
|
notFound
|
||||||
|
? ''
|
||||||
|
: customSupportIMG ||
|
||||||
|
'https://docs.emsesp.org/_media/images/installer.jpeg'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
{me.admin && (
|
{me.admin && (
|
||||||
<List sx={{ borderRadius: 3, border: '2px solid grey' }}>
|
<List sx={{ borderRadius: 3, border: '2px solid grey' }}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemButton component="a" href="https://emsesp.org">
|
<ListItemButton component="a" href="https://docs.emsesp.org">
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar sx={{ bgcolor: '#72caf9' }}>
|
<Avatar sx={{ bgcolor: '#72caf9' }}>
|
||||||
<MenuBookIcon />
|
<MenuBookIcon />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useBlocker } from 'react-router-dom';
|
import { useBlocker } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useBlocker } from 'react-router-dom';
|
import { useBlocker } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
|||||||
@@ -438,7 +438,8 @@ const Sensors = () => {
|
|||||||
<Cell stiff>{a.g}</Cell>
|
<Cell stiff>{a.g}</Cell>
|
||||||
<Cell>{a.n}</Cell>
|
<Cell>{a.n}</Cell>
|
||||||
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
||||||
{a.t === AnalogType.DIGITAL_OUT || a.t === AnalogType.DIGITAL_IN ? (
|
{(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) ||
|
||||||
|
a.t === AnalogType.DIGITAL_IN ? (
|
||||||
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
|
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
|
||||||
) : (
|
) : (
|
||||||
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
||||||
|
|||||||
@@ -181,7 +181,8 @@ export enum DeviceValueUOM {
|
|||||||
K,
|
K,
|
||||||
VOLTS,
|
VOLTS,
|
||||||
MBAR,
|
MBAR,
|
||||||
LH
|
LH,
|
||||||
|
CTKWH
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceValueUOM_s = [
|
export const DeviceValueUOM_s = [
|
||||||
@@ -210,7 +211,8 @@ export const DeviceValueUOM_s = [
|
|||||||
'K',
|
'K',
|
||||||
'V',
|
'V',
|
||||||
'mbar',
|
'mbar',
|
||||||
'l/h'
|
'l/h',
|
||||||
|
'ct/kWh'
|
||||||
];
|
];
|
||||||
|
|
||||||
export enum AnalogType {
|
export enum AnalogType {
|
||||||
|
|||||||
@@ -383,8 +383,8 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
|
|||||||
{ type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
|
{ type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
|
||||||
],
|
],
|
||||||
factor: [
|
factor: [
|
||||||
{ required: true, message: 'Bytes is required' },
|
{ required: true, message: 'is required' },
|
||||||
{ type: 'number', min: 1, max: 255, message: 'Must be between 1 and 255' }
|
{ type: 'number', message: 'Must be a number' }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const APSettings = () => {
|
|||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
useLayoutTitle(LL.SETTINGS_OF(LL.ACCESS_POINT(0)));
|
useLayoutTitle(LL.ACCESS_POINT(0));
|
||||||
|
|
||||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ const ApplicationSettings = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useLayoutTitle(LL.SETTINGS_OF(LL.APPLICATION()));
|
useLayoutTitle(LL.APPLICATION());
|
||||||
|
|
||||||
const SecondsInputProps = {
|
const SecondsInputProps = {
|
||||||
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
|
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const MqttSettings = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.SETTINGS_OF('MQTT'));
|
useLayoutTitle('MQTT');
|
||||||
|
|
||||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const NTPSettings = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.SETTINGS_OF('NTP'));
|
useLayoutTitle('NTP');
|
||||||
|
|
||||||
const updateFormValue = updateValueDirty(
|
const updateFormValue = updateValueDirty(
|
||||||
origData,
|
origData,
|
||||||
@@ -71,12 +71,12 @@ const NTPSettings = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changeTimeZone = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const changeTimeZone = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
updateFormValue(event);
|
|
||||||
void updateState(readNTPSettings(), (settings: NTPSettingsType) => ({
|
void updateState(readNTPSettings(), (settings: NTPSettingsType) => ({
|
||||||
...settings,
|
...settings,
|
||||||
tz_label: event.target.value,
|
tz_label: event.target.value,
|
||||||
tz_format: TIME_ZONES[event.target.value]
|
tz_format: TIME_ZONES[event.target.value]
|
||||||
}));
|
}));
|
||||||
|
updateFormValue(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ const Settings = () => {
|
|||||||
<ListMenuItem
|
<ListMenuItem
|
||||||
icon={BuildIcon}
|
icon={BuildIcon}
|
||||||
bgcolor="#72caf9"
|
bgcolor="#72caf9"
|
||||||
label={LL.EMS_ESP_VER()}
|
label="EMS-ESP Firmware"
|
||||||
text={data.emsesp_version}
|
text={'v' + data.emsesp_version}
|
||||||
to="version"
|
to="version"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import CheckIcon from '@mui/icons-material/Done';
|
||||||
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import {
|
import {
|
||||||
@@ -11,7 +13,6 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Divider,
|
|
||||||
Link,
|
Link,
|
||||||
Typography
|
Typography
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
@@ -29,46 +30,12 @@ import { useI18nContext } from 'i18n/i18n-react';
|
|||||||
|
|
||||||
const Version = () => {
|
const Version = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
const [restarting, setRestarting] = useState<boolean>(false);
|
const [restarting, setRestarting] = useState<boolean>(false);
|
||||||
const [openDialog, setOpenDialog] = useState<boolean>(false);
|
const [openInstallDialog, setOpenInstallDialog] = useState<boolean>(false);
|
||||||
const [useDev, setUseDev] = useState<boolean>(false);
|
const [usingDevVersion, setUsingDevVersion] = useState<boolean>(false);
|
||||||
const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false);
|
const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false);
|
||||||
|
const [internetLive, setInternetLive] = useState<boolean>(false);
|
||||||
const { send: sendCheckUpgrade } = useRequest(
|
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
|
||||||
(version: string) => callAction({ action: 'checkUpgrade', param: version }),
|
|
||||||
{
|
|
||||||
immediate: false
|
|
||||||
}
|
|
||||||
).onSuccess((event) => {
|
|
||||||
const data = event.data as { emsesp_version: string; upgradeable: boolean };
|
|
||||||
setUpgradeAvailable(data.upgradeable);
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data, send: loadData, error } = useRequest(SystemApi.readSystemStatus);
|
|
||||||
|
|
||||||
const { send: sendUploadURL } = useRequest(
|
|
||||||
(url: string) => callAction({ action: 'uploadURL', param: url }),
|
|
||||||
{
|
|
||||||
immediate: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// called immediately to get the latest version, on page load
|
|
||||||
const { data: latestVersion } = useRequest(getStableVersion, {
|
|
||||||
// uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin
|
|
||||||
// immediate: false,
|
|
||||||
// initialData: '3.6.5'
|
|
||||||
});
|
|
||||||
|
|
||||||
// called immediately to get the latest version, on page load, then check for upgrade (works for both dev and stable)
|
|
||||||
const { data: latestDevVersion } = useRequest(getDevVersion, {
|
|
||||||
// uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin
|
|
||||||
// immediate: false,
|
|
||||||
// initialData: '3.7.0-dev.32'
|
|
||||||
}).onSuccess((event) => {
|
|
||||||
void sendCheckUpgrade(event.data);
|
|
||||||
});
|
|
||||||
|
|
||||||
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
|
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
|
||||||
const STABLE_RELNOTES_URL =
|
const STABLE_RELNOTES_URL =
|
||||||
@@ -78,17 +45,60 @@ const Version = () => {
|
|||||||
const DEV_RELNOTES_URL =
|
const DEV_RELNOTES_URL =
|
||||||
'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md';
|
'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md';
|
||||||
|
|
||||||
const getBinURL = (useDevVersion: boolean) => {
|
const { send: sendCheckUpgrade } = useRequest(
|
||||||
|
(versions: string) => callAction({ action: 'checkUpgrade', param: versions }),
|
||||||
|
{
|
||||||
|
immediate: false
|
||||||
|
}
|
||||||
|
).onSuccess((event) => {
|
||||||
|
const data = event.data as { emsesp_version: string; upgradeable: boolean };
|
||||||
|
setUpgradeAvailable(data.upgradeable);
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: data,
|
||||||
|
send: loadData,
|
||||||
|
error
|
||||||
|
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
|
||||||
|
// older version of EMS-ESP didn't have the psram set, so we can't do an OTA upgrade
|
||||||
|
setDownloadOnly(event.data.psram === undefined);
|
||||||
|
setUsingDevVersion(event.data.emsesp_version.includes('dev'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const { send: sendUploadURL } = useRequest(
|
||||||
|
(url: string) => callAction({ action: 'uploadURL', param: url }),
|
||||||
|
{
|
||||||
|
immediate: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// called immediately to get the latest versions on page load
|
||||||
|
const { data: latestVersion } = useRequest(getStableVersion);
|
||||||
|
const { data: latestDevVersion } = useRequest(getDevVersion);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (latestVersion && latestDevVersion) {
|
||||||
|
sendCheckUpgrade(latestDevVersion + ',' + latestVersion)
|
||||||
|
.catch((error: Error) => {
|
||||||
|
toast.error('Failed to check for upgrades: ' + error.message);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setInternetLive(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [latestVersion, latestDevVersion]);
|
||||||
|
|
||||||
|
const getBinURL = () => {
|
||||||
if (!latestVersion || !latestDevVersion) {
|
if (!latestVersion || !latestDevVersion) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
const filename =
|
const filename =
|
||||||
'EMS-ESP-' +
|
'EMS-ESP-' +
|
||||||
(useDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') +
|
(usingDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') +
|
||||||
'-' +
|
'-' +
|
||||||
getPlatform() +
|
getPlatform() +
|
||||||
'.bin';
|
'.bin';
|
||||||
return useDevVersion
|
return usingDevVersion
|
||||||
? DEV_URL + filename
|
? DEV_URL + filename
|
||||||
: STABLE_URL + 'v' + latestVersion + '/' + filename;
|
: STABLE_URL + 'v' + latestVersion + '/' + filename;
|
||||||
};
|
};
|
||||||
@@ -107,97 +117,131 @@ const Version = () => {
|
|||||||
setRestarting(true);
|
setRestarting(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
useLayoutTitle(LL.EMS_ESP_VER());
|
useLayoutTitle('EMS-ESP Firmware');
|
||||||
|
|
||||||
const internet_live =
|
const renderInstallDialog = () => (
|
||||||
latestDevVersion !== undefined && latestVersion !== undefined;
|
<Dialog
|
||||||
|
sx={dialogStyle}
|
||||||
|
open={openInstallDialog}
|
||||||
|
onClose={() => closeInstallDialog()}
|
||||||
|
>
|
||||||
|
<DialogTitle>
|
||||||
|
{LL.INSTALL() +
|
||||||
|
' ' +
|
||||||
|
(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE()) +
|
||||||
|
' Firmware'}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<Typography mb={2}>
|
||||||
|
{LL.INSTALL_VERSION(usingDevVersion ? latestDevVersion : latestVersion)}
|
||||||
|
</Typography>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
startIcon={<CancelIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => closeInstallDialog()}
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
{LL.CANCEL()}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => closeInstallDialog()}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<Link underline="none" target="_blank" href={getBinURL()} color="primary">
|
||||||
|
{LL.DOWNLOAD(1)}
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
startIcon={<WarningIcon color="warning" />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => installFirmwareURL(getBinURL())}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{LL.INSTALL()}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
|
||||||
const renderUploadDialog = () => {
|
const showFirmwareDialog = (useDevVersion?: boolean) => {
|
||||||
if (!internet_live) {
|
setUsingDevVersion(useDevVersion || usingDevVersion);
|
||||||
return null;
|
setOpenInstallDialog(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeInstallDialog = () => {
|
||||||
|
setOpenInstallDialog(false);
|
||||||
|
setUsingDevVersion(data.emsesp_version.includes('dev'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const switchToDev = () => {
|
||||||
|
setUsingDevVersion(true);
|
||||||
|
setUpgradeAvailable(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showButtons = () => {
|
||||||
|
if (!upgradeAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadOnly) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => setOpenInstallDialog(false)}
|
||||||
|
color="warning"
|
||||||
|
size="small"
|
||||||
|
sx={{ ml: 2 }}
|
||||||
|
>
|
||||||
|
<Link underline="none" target="_blank" href={getBinURL()} color="warning">
|
||||||
|
{LL.DOWNLOAD(1)}
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Button
|
||||||
sx={dialogStyle}
|
sx={{ ml: 2 }}
|
||||||
open={openDialog}
|
variant="outlined"
|
||||||
onClose={() => setOpenDialog(false)}
|
color="warning"
|
||||||
|
size="small"
|
||||||
|
onClick={() => showFirmwareDialog()}
|
||||||
>
|
>
|
||||||
<DialogTitle>
|
{LL.UPGRADE()}…
|
||||||
{LL.INSTALL('') +
|
</Button>
|
||||||
' ' +
|
|
||||||
(useDev ? LL.DEVELOPMENT() : LL.STABLE()) +
|
|
||||||
' Firmware'}
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent dividers>
|
|
||||||
<Typography mb={2}>
|
|
||||||
{LL.INSTALL_VERSION(useDev ? latestDevVersion : latestVersion)}
|
|
||||||
</Typography>
|
|
||||||
<Link
|
|
||||||
target="_blank"
|
|
||||||
href={useDev ? DEV_RELNOTES_URL : STABLE_RELNOTES_URL}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
changelog
|
|
||||||
</Link>
|
|
||||||
|
|
|
||||||
<Link target="_blank" href={getBinURL(useDev)} color="primary">
|
|
||||||
{LL.DOWNLOAD(1)}
|
|
||||||
</Link>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button
|
|
||||||
startIcon={<CancelIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => setOpenDialog(false)}
|
|
||||||
color="secondary"
|
|
||||||
>
|
|
||||||
{LL.CANCEL()}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
startIcon={<WarningIcon color="warning" />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => installFirmwareURL(getBinURL(useDev))}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
{LL.INSTALL('')}
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// useDevVersion = true to force using the dev version
|
|
||||||
const showFirmwareDialog = (useDevVersion: boolean) => {
|
|
||||||
if (useDevVersion || data.emsesp_version.includes('dev')) {
|
|
||||||
setUseDev(true);
|
|
||||||
}
|
|
||||||
setOpenDialog(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDev = data.emsesp_version.includes('dev');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box p={2} border="1px solid grey" borderRadius={2}>
|
<Box p={2} border="1px solid grey" borderRadius={2}>
|
||||||
<Grid container spacing={3}>
|
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
|
||||||
|
Firmware Version
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid container spacing={4}>
|
||||||
<Grid mb={1}>
|
<Grid mb={1}>
|
||||||
<Typography mb={1} fontWeight={'fontWeightBold'}>
|
<Typography mb={1} color="secondary">
|
||||||
{LL.VERSION()}
|
{LL.VERSION()}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography mb={1} fontWeight={'fontWeightBold'}>
|
<Typography mb={1} color="secondary">
|
||||||
Platform
|
Platform
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography mb={1} fontWeight={'fontWeightBold'}>
|
<Typography mb={1} color="secondary">
|
||||||
Release
|
Release Type
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Grid mb={1}>
|
||||||
<Typography mb={1}>
|
<Typography mb={1}>
|
||||||
{data.emsesp_version}
|
{data.emsesp_version}
|
||||||
{data.build_flags && (
|
{data.build_flags && (
|
||||||
@@ -207,63 +251,86 @@ const Version = () => {
|
|||||||
)}
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography mb={1}>{getPlatform()}</Typography>
|
<Typography mb={1}>{getPlatform()}</Typography>
|
||||||
<Typography>
|
<Typography mb={1}>
|
||||||
{isDev ? LL.DEVELOPMENT() : LL.STABLE()}
|
{data.emsesp_version.includes('dev')
|
||||||
<Link
|
? LL.DEVELOPMENT()
|
||||||
target="_blank"
|
: LL.STABLE()}
|
||||||
href={useDev ? DEV_RELNOTES_URL : STABLE_RELNOTES_URL}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
(changelog)
|
|
||||||
</Link>
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Divider />
|
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
|
||||||
|
{LL.AVAILABLE_VERSION()}
|
||||||
{!isDev && (
|
|
||||||
<Button
|
|
||||||
sx={{ mt: 2 }}
|
|
||||||
variant="outlined"
|
|
||||||
color="primary"
|
|
||||||
size="small"
|
|
||||||
onClick={() => showFirmwareDialog(true)}
|
|
||||||
>
|
|
||||||
{LL.SWITCH_DEV()}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Typography mt={2} color="warning">
|
|
||||||
<InfoOutlinedIcon color="warning" sx={{ verticalAlign: 'middle' }} />
|
|
||||||
|
|
||||||
{upgradeAvailable ? LL.UPGRADE_AVAILABLE() : LL.LATEST_VERSION()}
|
|
||||||
{upgradeAvailable &&
|
|
||||||
internet_live &&
|
|
||||||
(data.psram ? (
|
|
||||||
<Button
|
|
||||||
sx={{ ml: 2, textTransform: 'none' }}
|
|
||||||
variant="outlined"
|
|
||||||
color="primary"
|
|
||||||
size="small"
|
|
||||||
onClick={() => showFirmwareDialog(false)}
|
|
||||||
>
|
|
||||||
{isDev
|
|
||||||
? LL.INSTALL('v' + latestDevVersion)
|
|
||||||
: LL.INSTALL('v' + latestVersion)}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
|
|
||||||
<Link target="_blank" href={getBinURL(isDev)} color="primary">
|
|
||||||
{LL.DOWNLOAD(1)} v
|
|
||||||
{isDev ? latestDevVersion : latestVersion}
|
|
||||||
</Link>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{renderUploadDialog()}
|
{internetLive ? (
|
||||||
|
<>
|
||||||
|
<Grid container spacing={4}>
|
||||||
|
<Grid mb={1}>
|
||||||
|
<Typography mb={1} color="secondary">
|
||||||
|
{LL.STABLE()}
|
||||||
|
</Typography>
|
||||||
|
<Typography mb={1} color="secondary">
|
||||||
|
{LL.DEVELOPMENT()}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid mb={1}>
|
||||||
|
<Typography mb={1}>
|
||||||
|
{latestVersion}
|
||||||
|
<Link target="_blank" href={STABLE_RELNOTES_URL} color="primary">
|
||||||
|
(changelog)
|
||||||
|
</Link>
|
||||||
|
{!usingDevVersion && showButtons()}
|
||||||
|
</Typography>
|
||||||
|
<Typography mb={1}>
|
||||||
|
{latestDevVersion}
|
||||||
|
<Link target="_blank" href={DEV_RELNOTES_URL} color="primary">
|
||||||
|
(changelog)
|
||||||
|
</Link>
|
||||||
|
{usingDevVersion && showButtons()}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
{upgradeAvailable ? (
|
||||||
|
<Typography color="warning">
|
||||||
|
<InfoOutlinedIcon
|
||||||
|
color="warning"
|
||||||
|
sx={{ verticalAlign: 'middle', mr: 2 }}
|
||||||
|
/>
|
||||||
|
{LL.UPGRADE_AVAILABLE()}
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<Typography color="success">
|
||||||
|
<CheckIcon
|
||||||
|
color="success"
|
||||||
|
sx={{ verticalAlign: 'middle', mr: 2 }}
|
||||||
|
/>
|
||||||
|
{LL.LATEST_VERSION()}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!data.emsesp_version.includes('dev') && !usingDevVersion && (
|
||||||
|
<Typography variant="caption">
|
||||||
|
<Button
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={() => switchToDev()}
|
||||||
|
>
|
||||||
|
{LL.SWITCH_DEV()}
|
||||||
|
</Button>
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Typography mb={1} color="warning">
|
||||||
|
<WarningIcon color="warning" sx={{ verticalAlign: 'middle', mr: 2 }} />
|
||||||
|
device cannot access internet
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{renderInstallDialog()}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { Navigate, Route, Routes, useNavigate } from 'react-router-dom';
|
import { Navigate, Route, Routes, useNavigate } from 'react-router';
|
||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ import WiFiNetworkScanner from './WiFiNetworkScanner';
|
|||||||
|
|
||||||
const Network = () => {
|
const Network = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.SETTINGS_OF(LL.NETWORK(0)));
|
useLayoutTitle(LL.NETWORK(0));
|
||||||
|
|
||||||
const { routerTab } = useRouterTab();
|
const { routerTab } = useRouterTab();
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ const Network = () => {
|
|||||||
const selectNetwork = useCallback(
|
const selectNetwork = useCallback(
|
||||||
(network: WiFiNetwork) => {
|
(network: WiFiNetwork) => {
|
||||||
setSelectedNetwork(network);
|
setSelectedNetwork(network);
|
||||||
navigate('settings');
|
void navigate('/settings');
|
||||||
},
|
},
|
||||||
[navigate]
|
[navigate]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useContext, useState } from 'react';
|
import { useContext, useState } from 'react';
|
||||||
import { useBlocker } from 'react-router-dom';
|
import { useBlocker } from 'react-router';
|
||||||
|
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
import CheckIcon from '@mui/icons-material/Done';
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import PersonAddIcon from '@mui/icons-material/PersonAdd';
|
import PersonAddIcon from '@mui/icons-material/PersonAdd';
|
||||||
import VpnKeyIcon from '@mui/icons-material/VpnKey';
|
import VpnKeyIcon from '@mui/icons-material/VpnKey';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router';
|
||||||
|
|
||||||
import { Tab } from '@mui/material';
|
import { Tab } from '@mui/material';
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ import SecuritySettings from './SecuritySettings';
|
|||||||
|
|
||||||
const Security = () => {
|
const Security = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.SETTINGS_OF(LL.SECURITY(0)));
|
useLayoutTitle(LL.SECURITY(0));
|
||||||
|
|
||||||
const { routerTab } = useRouterTab();
|
const { routerTab } = useRouterTab();
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const APStatus = () => {
|
|||||||
} = useAutoRequest(APApi.readAPStatus, { pollingTime: 3000 });
|
} = useAutoRequest(APApi.readAPStatus, { pollingTime: 3000 });
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.STATUS_OF(LL.ACCESS_POINT(0)));
|
useLayoutTitle(LL.ACCESS_POINT(0));
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ function formatNumber(num: number) {
|
|||||||
const HardwareStatus = () => {
|
const HardwareStatus = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
useLayoutTitle(LL.STATUS_OF(LL.HARDWARE()));
|
useLayoutTitle(LL.HARDWARE());
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const MqttStatus = () => {
|
|||||||
} = useAutoRequest(MqttApi.readMqttStatus, { pollingTime: 3000 });
|
} = useAutoRequest(MqttApi.readMqttStatus, { pollingTime: 3000 });
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.STATUS_OF('MQTT'));
|
useLayoutTitle('MQTT');
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@@ -70,9 +70,9 @@ const MqttStatus = () => {
|
|||||||
return LL.NOT_ENABLED();
|
return LL.NOT_ENABLED();
|
||||||
}
|
}
|
||||||
if (connected) {
|
if (connected) {
|
||||||
return LL.CONNECTED(0) + (connect_count > 1 ? ' (' + connect_count + ')' : '');
|
return LL.CONNECTED(0) + ' (' + connect_count + ')';
|
||||||
}
|
}
|
||||||
return LL.DISCONNECTED() + (connect_count > 1 ? ' (' + connect_count + ')' : '');
|
return LL.DISCONNECTED() + ' (' + connect_count + ')';
|
||||||
};
|
};
|
||||||
|
|
||||||
const disconnectReason = ({ disconnect_reason }: MqttStatusType) => {
|
const disconnectReason = ({ disconnect_reason }: MqttStatusType) => {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const NTPStatus = () => {
|
|||||||
const [processing, setProcessing] = useState<boolean>(false);
|
const [processing, setProcessing] = useState<boolean>(false);
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.STATUS_OF('NTP'));
|
useLayoutTitle('NTP');
|
||||||
|
|
||||||
const { send: updateTime } = useRequest(
|
const { send: updateTime } = useRequest(
|
||||||
(local_time: Time) => NTPApi.updateTime(local_time),
|
(local_time: Time) => NTPApi.updateTime(local_time),
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ const NetworkStatus = () => {
|
|||||||
} = useAutoRequest(NetworkApi.readNetworkStatus, { pollingTime: 3000 });
|
} = useAutoRequest(NetworkApi.readNetworkStatus, { pollingTime: 3000 });
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.STATUS_OF(LL.NETWORK(1)));
|
useLayoutTitle(LL.NETWORK(1));
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const networkStatus = ({ status }: NetworkStatusType) => {
|
const networkStatus = ({ status }: NetworkStatusType) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
|
||||||
|
return LL.CONNECTED(0) + ' (Ethernet)';
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
case NetworkConnectionStatus.WIFI_STATUS_NO_SHIELD:
|
||||||
return LL.INACTIVE(1);
|
return LL.INACTIVE(1);
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_IDLE:
|
case NetworkConnectionStatus.WIFI_STATUS_IDLE:
|
||||||
@@ -101,13 +103,13 @@ const NetworkStatus = () => {
|
|||||||
case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL:
|
case NetworkConnectionStatus.WIFI_STATUS_NO_SSID_AVAIL:
|
||||||
return 'No SSID Available';
|
return 'No SSID Available';
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_CONNECTED:
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTED:
|
||||||
return LL.CONNECTED(0) + ' (WiFi)';
|
return LL.CONNECTED(0) + ' (WiFi) (' + data.reconnect_count + ')';
|
||||||
case NetworkConnectionStatus.ETHERNET_STATUS_CONNECTED:
|
|
||||||
return LL.CONNECTED(0) + ' (Ethernet)';
|
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECT_FAILED:
|
||||||
return LL.CONNECTED(1) + ' ' + LL.FAILED(0);
|
return (
|
||||||
|
LL.CONNECTED(1) + ' ' + LL.FAILED(0) + ' (' + data.reconnect_count + ')'
|
||||||
|
);
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
case NetworkConnectionStatus.WIFI_STATUS_CONNECTION_LOST:
|
||||||
return LL.CONNECTED(1) + ' ' + LL.LOST();
|
return LL.CONNECTED(1) + ' ' + LL.LOST() + ' (' + data.reconnect_count + ')';
|
||||||
case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
case NetworkConnectionStatus.WIFI_STATUS_DISCONNECTED:
|
||||||
return LL.DISCONNECTED();
|
return LL.DISCONNECTED();
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -261,16 +261,6 @@ const SystemLog = () => {
|
|||||||
>
|
>
|
||||||
{LL.EXPORT()}
|
{LL.EXPORT()}
|
||||||
</Button>
|
</Button>
|
||||||
{dirtyFlags && dirtyFlags.length !== 0 && (
|
|
||||||
<Button
|
|
||||||
startIcon={<WarningIcon color="warning" />}
|
|
||||||
variant="contained"
|
|
||||||
color="info"
|
|
||||||
onClick={saveSettings}
|
|
||||||
>
|
|
||||||
{LL.APPLY_CHANGES(dirtyFlags.length)}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{readOpen ? (
|
{readOpen ? (
|
||||||
@@ -315,6 +305,19 @@ const SystemLog = () => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{dirtyFlags && dirtyFlags.length !== 0 && (
|
||||||
|
<Grid>
|
||||||
|
<Button
|
||||||
|
startIcon={<WarningIcon color="warning" />}
|
||||||
|
variant="contained"
|
||||||
|
color="info"
|
||||||
|
onClick={saveSettings}
|
||||||
|
>
|
||||||
|
{LL.APPLY_CHANGES(dirtyFlags.length)}
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
import { Box, Toolbar } from '@mui/material';
|
import { Box, Toolbar } from '@mui/material';
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { Link, useLocation, useNavigate } from 'react-router';
|
||||||
|
|
||||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||||
import MenuIcon from '@mui/icons-material/Menu';
|
import MenuIcon from '@mui/icons-material/Menu';
|
||||||
import { AppBar, IconButton, Toolbar, Typography } from '@mui/material';
|
import { AppBar, IconButton, Toolbar, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export const DRAWER_WIDTH = 210;
|
export const DRAWER_WIDTH = 210;
|
||||||
|
|
||||||
interface LayoutAppBarProps {
|
interface LayoutAppBarProps {
|
||||||
@@ -12,12 +14,12 @@ interface LayoutAppBarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LayoutAppBar = ({ title, onToggleDrawer }: LayoutAppBarProps) => {
|
const LayoutAppBar = ({ title, onToggleDrawer }: LayoutAppBarProps) => {
|
||||||
|
const { LL } = useI18nContext();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const pathnames = useLocation()
|
const pathnames = useLocation()
|
||||||
.pathname.split('/')
|
.pathname.split('/')
|
||||||
.filter((x) => x);
|
.filter((x) => x);
|
||||||
const show_back = pathnames.length > 1;
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar
|
<AppBar
|
||||||
@@ -39,20 +41,30 @@ const LayoutAppBar = ({ title, onToggleDrawer }: LayoutAppBarProps) => {
|
|||||||
<MenuIcon />
|
<MenuIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
{show_back && (
|
{pathnames.length > 1 && (
|
||||||
<IconButton
|
<>
|
||||||
sx={{ mr: 1 }}
|
<IconButton
|
||||||
color="inherit"
|
sx={{ mr: 1, fontSize: 20, verticalAlign: 'middle' }}
|
||||||
edge="start"
|
color="primary"
|
||||||
onClick={() => navigate(pathnames[0])}
|
edge="start"
|
||||||
>
|
onClick={() => navigate('/' + pathnames[0])}
|
||||||
<ArrowBackIcon />
|
>
|
||||||
</IconButton>
|
<ArrowBackIcon />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
to={'/' + pathnames[0]}
|
||||||
|
style={{ textDecoration: 'none', color: 'white' }}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
{pathnames[0] === 'status' ? LL.STATUS_OF('') : LL.SETTINGS(0)}
|
||||||
|
<span style={{ color: '#90caf9' }}> | </span>
|
||||||
|
</Typography>
|
||||||
|
</Link>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Typography variant="h6" noWrap component="div">
|
<Typography variant="h6">{title}</Typography>
|
||||||
{title}
|
|
||||||
</Typography>
|
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router';
|
||||||
|
|
||||||
import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
|
import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
|
||||||
import type { SvgIconProps } from '@mui/material';
|
import type { SvgIconProps } from '@mui/material';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
|
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Blocker } from 'react-router-dom';
|
import type { Blocker } from 'react-router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router';
|
||||||
|
|
||||||
import { AuthenticatedContext } from 'contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import type { RequiredChildrenProps } from 'utils';
|
import type { RequiredChildrenProps } from 'utils';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useContext, useEffect } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { Navigate, useLocation } from 'react-router-dom';
|
import { Navigate, useLocation } from 'react-router';
|
||||||
|
|
||||||
import { storeLoginRedirect } from 'components/routing/authentication';
|
import { storeLoginRedirect } from 'components/routing/authentication';
|
||||||
import type { AuthenticatedContextValue } from 'contexts/authentication/context';
|
import type { AuthenticatedContextValue } from 'contexts/authentication/context';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router';
|
||||||
|
|
||||||
import { fetchLoginRedirect } from 'components/routing/authentication';
|
import { fetchLoginRedirect } from 'components/routing/authentication';
|
||||||
import { AuthenticationContext } from 'contexts/authentication';
|
import { AuthenticationContext } from 'contexts/authentication';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router';
|
||||||
|
|
||||||
import { Tabs, useMediaQuery, useTheme } from '@mui/material';
|
import { Tabs, useMediaQuery, useTheme } from '@mui/material';
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ const RouterTabs: FC<RouterTabsProps> = ({ value, children }) => {
|
|||||||
const smallDown = useMediaQuery(theme.breakpoints.down('sm'));
|
const smallDown = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
const handleTabChange = (_event: unknown, path: string) => {
|
const handleTabChange = (_event: unknown, path: string) => {
|
||||||
navigate(path);
|
void navigate(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Path } from 'react-router-dom';
|
import type { Path } from 'react-router';
|
||||||
|
|
||||||
import type * as H from 'history';
|
import type * as H from 'history';
|
||||||
import { jwtDecode } from 'jwt-decode';
|
import { jwtDecode } from 'jwt-decode';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useMatch, useResolvedPath } from 'react-router-dom';
|
import { useMatch, useResolvedPath } from 'react-router';
|
||||||
|
|
||||||
export const useRouterTab = () => {
|
export const useRouterTab = () => {
|
||||||
const routerTabPathMatch = useMatch(useResolvedPath(':tab').pathname);
|
const routerTabPathMatch = useMatch(useResolvedPath(':tab').pathname);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { redirect } from 'react-router-dom';
|
import { redirect } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { ACCESS_TOKEN } from 'api/endpoints';
|
import { ACCESS_TOKEN } from 'api/endpoints';
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ const cz: Translation = {
|
|||||||
UNDERCLOCK_CPU: 'Snížit takt CPU',
|
UNDERCLOCK_CPU: 'Snížit takt CPU',
|
||||||
REMOTE_TIMEOUT: 'Časový limit vzdáleného připojení',
|
REMOTE_TIMEOUT: 'Časový limit vzdáleného připojení',
|
||||||
REMOTE_TIMEOUT_EN: 'Zakázat vzdálený přístup při chybějící teplotě v místnosti',
|
REMOTE_TIMEOUT_EN: 'Zakázat vzdálený přístup při chybějící teplotě v místnosti',
|
||||||
HEATINGOFF: 'Spustit kotel s vynuceným vypnutým topením',
|
HEATINGOFF: 'Vynutit vypnuté topení při spuštění kotle',
|
||||||
MIN_DURATION: 'Čekací doba',
|
MIN_DURATION: 'Čekací doba',
|
||||||
ENABLE_SHOWER_TIMER: 'Povolit časovač sprchy',
|
ENABLE_SHOWER_TIMER: 'Povolit časovač sprchy',
|
||||||
ENABLE_SHOWER_ALERT: 'Povolit upozornění na sprchu',
|
ENABLE_SHOWER_ALERT: 'Povolit upozornění na sprchu',
|
||||||
TRIGGER_TIME: 'Čas spuštění',
|
TRIGGER_TIME: 'Čas spuštění',
|
||||||
COLD_SHOT_DURATION: 'Délka studeného výstřiku',
|
COLD_SHOT_DURATION: 'Délka studeného výtrysku',
|
||||||
FORMATTING_OPTIONS: 'Možnosti formátování',
|
FORMATTING_OPTIONS: 'Možnosti formátování',
|
||||||
BOOLEAN_FORMAT_DASHBOARD: 'Formát booleovské hodnoty na webu',
|
BOOLEAN_FORMAT_DASHBOARD: 'Formát booleovské hodnoty na webu',
|
||||||
BOOLEAN_FORMAT_API: 'Formát booleovské hodnoty v API/MQTT',
|
BOOLEAN_FORMAT_API: 'Formát booleovské hodnoty v API/MQTT',
|
||||||
@@ -137,17 +137,17 @@ const cz: Translation = {
|
|||||||
MINUTES: 'minuty',
|
MINUTES: 'minuty',
|
||||||
HOURS: 'hodiny',
|
HOURS: 'hodiny',
|
||||||
RESTART: 'Restart',
|
RESTART: 'Restart',
|
||||||
RESTART_TEXT: 'EMS-ESP musí být restartován, aby se změny systému projevily',
|
RESTART_TEXT: 'Pro projevení změn musí být zařízení EMS-ESP restartováno',
|
||||||
RESTART_CONFIRM: 'Opravdu chcete restartovat EMS-ESP?',
|
RESTART_CONFIRM: 'Opravdu chcete restartovat zařízení EMS-ESP?',
|
||||||
COMMAND: 'Příkaz',
|
COMMAND: 'Příkaz',
|
||||||
CUSTOMIZATIONS_RESTART: 'Všechna přizpůsobení byla odstraněna. Restartování...',
|
CUSTOMIZATIONS_RESTART: 'Všechna přizpůsobení byla odstraněna. Restartování...',
|
||||||
CUSTOMIZATIONS_FULL: 'Vybrané entity překročily limit. Uložte je po částech',
|
CUSTOMIZATIONS_FULL: 'Vybrané entity překročily limit. Ukládejte je postupně',
|
||||||
CUSTOMIZATIONS_SAVED: 'Přizpůsobení uloženo',
|
CUSTOMIZATIONS_SAVED: 'Přizpůsobení uloženo',
|
||||||
CUSTOMIZATIONS_HELP_1: 'Vyberte zařízení a přizpůsobte možnosti entit nebo klikněte pro přejmenování',
|
CUSTOMIZATIONS_HELP_1: 'Vyberte zařízení a přizpůsobte možnosti entit nebo klikněte pro přejmenování',
|
||||||
CUSTOMIZATIONS_HELP_2: 'označit jako oblíbené',
|
CUSTOMIZATIONS_HELP_2: 'označit jako oblíbené',
|
||||||
CUSTOMIZATIONS_HELP_3: 'zakázat akci zápisu',
|
CUSTOMIZATIONS_HELP_3: 'zakázat akci zápisu',
|
||||||
CUSTOMIZATIONS_HELP_4: 'vyloučit z MQTT a API',
|
CUSTOMIZATIONS_HELP_4: 'vyloučit z MQTT a API',
|
||||||
CUSTOMIZATIONS_HELP_5: 'skrýt z Zařízení',
|
CUSTOMIZATIONS_HELP_5: 'skrýt ze Zařízení',
|
||||||
CUSTOMIZATIONS_HELP_6: 'odstranit z paměti',
|
CUSTOMIZATIONS_HELP_6: 'odstranit z paměti',
|
||||||
SELECT_DEVICE: 'Vyberte zařízení',
|
SELECT_DEVICE: 'Vyberte zařízení',
|
||||||
SET_ALL: 'nastavit vše',
|
SET_ALL: 'nastavit vše',
|
||||||
@@ -156,13 +156,12 @@ const cz: Translation = {
|
|||||||
CUSTOMIZATIONS_RESET: 'Opravdu chcete odstranit všechna přizpůsobení včetně vlastních nastavení teplotních a analogových senzorů?',
|
CUSTOMIZATIONS_RESET: 'Opravdu chcete odstranit všechna přizpůsobení včetně vlastních nastavení teplotních a analogových senzorů?',
|
||||||
SUPPORT_INFORMATION: 'Podpora',
|
SUPPORT_INFORMATION: 'Podpora',
|
||||||
HELP_INFORMATION_1: 'Navštivte online wiki pro pokyny, jak konfigurovat EMS-ESP',
|
HELP_INFORMATION_1: 'Navštivte online wiki pro pokyny, jak konfigurovat EMS-ESP',
|
||||||
HELP_INFORMATION_2: 'Pro živý chat se komunitou se připojte k našemu serveru Discord',
|
HELP_INFORMATION_2: 'Pro živý chat s komunitou se připojte k našemu serveru Discord',
|
||||||
HELP_INFORMATION_3: 'Chcete-li požádat o funkci nebo nahlásit chybu',
|
HELP_INFORMATION_3: 'Požádejte o funkci nebo nahlášte chybu',
|
||||||
HELP_INFORMATION_4: 'Stáhněte a připojte informace o podpoře pro rychlejší odezvu při hlášení problému',
|
HELP_INFORMATION_4: 'Stáhněte a připojte informace podpoře pro rychlejší odezvu při hlášení problému',
|
||||||
HELP_INFORMATION_5: 'Pro pomoc a dotazy kontaktujte svého instalatéra',
|
|
||||||
UPLOAD: 'Nahrát',
|
UPLOAD: 'Nahrát',
|
||||||
DOWNLOAD: '{{S|s|s}}táhnout',
|
DOWNLOAD: '{{S|s|s}}táhnout',
|
||||||
INSTALL: 'Instalovat {0}',
|
INSTALL: 'Instalovat',
|
||||||
ABORTED: 'přerušeno',
|
ABORTED: 'přerušeno',
|
||||||
FAILED: 'neúspěšné',
|
FAILED: 'neúspěšné',
|
||||||
SUCCESSFUL: 'úspěšné',
|
SUCCESSFUL: 'úspěšné',
|
||||||
@@ -174,17 +173,17 @@ const cz: Translation = {
|
|||||||
USE: 'Použít',
|
USE: 'Použít',
|
||||||
FACTORY_RESET: 'Obnovení továrního nastavení',
|
FACTORY_RESET: 'Obnovení továrního nastavení',
|
||||||
SYSTEM_FACTORY_TEXT: 'Zařízení bylo obnoveno do továrního nastavení a nyní se restartuje',
|
SYSTEM_FACTORY_TEXT: 'Zařízení bylo obnoveno do továrního nastavení a nyní se restartuje',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Opravdu chcete resetovat EMS-ESP do továrního nastavení?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Opravdu chcete resetovat zařízení EMS-ESP do továrního nastavení?',
|
||||||
|
AVAILABLE_VERSION: 'Nejnovější dostupné verze',
|
||||||
STABLE: 'Stabilní',
|
STABLE: 'Stabilní',
|
||||||
DEVELOPMENT: 'Vývojová verze',
|
DEVELOPMENT: 'Vývojová verze',
|
||||||
EMS_ESP_VER: 'Verze firmwaru',
|
|
||||||
UPTIME: 'Doba provozu systému',
|
UPTIME: 'Doba provozu systému',
|
||||||
FREE_MEMORY: 'Volná paměť',
|
FREE_MEMORY: 'Volná paměť',
|
||||||
PSRAM: 'PSRAM (Velikost / Volná)',
|
PSRAM: 'PSRAM (Velikost / Volná)',
|
||||||
FLASH: 'Flash čip (Velikost, Rychlost)',
|
FLASH: 'Flash čip (Velikost, Rychlost)',
|
||||||
APPSIZE: 'Aplikace (Partition: Použito / Volné)',
|
APPSIZE: 'Aplikace (Partition: Použito / Volné)',
|
||||||
FILESYSTEM: 'Souborový systém (Použito / Volné)',
|
FILESYSTEM: 'Souborový systém (Použito / Volné)',
|
||||||
BUFFER_SIZE: 'Maximální velikost bufferu',
|
BUFFER_SIZE: 'Maximální velikost vyrovnávací paměti',
|
||||||
COMPACT: 'Kompaktní',
|
COMPACT: 'Kompaktní',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
|
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
|
||||||
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
|
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
|
||||||
@@ -193,7 +192,7 @@ const cz: Translation = {
|
|||||||
TIME_SET: 'Čas nastaven',
|
TIME_SET: 'Čas nastaven',
|
||||||
MANAGE_USERS: 'Spravovat uživatele',
|
MANAGE_USERS: 'Spravovat uživatele',
|
||||||
IS_ADMIN: 'je Admin',
|
IS_ADMIN: 'je Admin',
|
||||||
USER_WARNING: 'Musí být nakonfigurován alespoň jeden uživatel s oprávněním admin',
|
USER_WARNING: 'Musí být nastaven alespoň jeden uživatel s oprávněním admin',
|
||||||
ADD: 'Přidat',
|
ADD: 'Přidat',
|
||||||
ACCESS_TOKEN_FOR: 'Přístupový token pro',
|
ACCESS_TOKEN_FOR: 'Přístupový token pro',
|
||||||
ACCESS_TOKEN_TEXT: 'Níže uvedený token se používá s REST API voláními, která vyžadují autorizaci. Lze jej předat buď jako Bearer token v hlavičce Authorization, nebo v parametru URL access_token.',
|
ACCESS_TOKEN_TEXT: 'Níže uvedený token se používá s REST API voláními, která vyžadují autorizaci. Lze jej předat buď jako Bearer token v hlavičce Authorization, nebo v parametru URL access_token.',
|
||||||
@@ -220,10 +219,10 @@ const cz: Translation = {
|
|||||||
MQTT_PUBLISH_TEXT_4: 'Prefix pro Discovery témata',
|
MQTT_PUBLISH_TEXT_4: 'Prefix pro Discovery témata',
|
||||||
MQTT_PUBLISH_TEXT_5: 'Typ Discovery',
|
MQTT_PUBLISH_TEXT_5: 'Typ Discovery',
|
||||||
MQTT_PUBLISH_INTERVALS: 'Intervaly publikování',
|
MQTT_PUBLISH_INTERVALS: 'Intervaly publikování',
|
||||||
MQTT_INT_BOILER: 'Kotly a tepelná čerpadla',
|
MQTT_INT_BOILER: 'Kotle a tepelná čerpadla',
|
||||||
MQTT_INT_THERMOSTATS: 'Termostaty',
|
MQTT_INT_THERMOSTATS: 'Termostaty',
|
||||||
MQTT_INT_SOLAR: 'Solární moduly',
|
MQTT_INT_SOLAR: 'Solární moduly',
|
||||||
MQTT_INT_MIXER: 'Míchací moduly',
|
MQTT_INT_MIXER: 'Směšovací moduly',
|
||||||
MQTT_INT_WATER: 'Vodní moduly',
|
MQTT_INT_WATER: 'Vodní moduly',
|
||||||
MQTT_QUEUE: 'MQTT fronta',
|
MQTT_QUEUE: 'MQTT fronta',
|
||||||
DEFAULT: 'Výchozí',
|
DEFAULT: 'Výchozí',
|
||||||
@@ -260,8 +259,8 @@ const cz: Translation = {
|
|||||||
SCAN_AGAIN: 'Skenovat znovu',
|
SCAN_AGAIN: 'Skenovat znovu',
|
||||||
NETWORK_SCANNER: 'Síťový skener',
|
NETWORK_SCANNER: 'Síťový skener',
|
||||||
NETWORK_NO_WIFI: 'Nenalezeny žádné WiFi sítě',
|
NETWORK_NO_WIFI: 'Nenalezeny žádné WiFi sítě',
|
||||||
NETWORK_BLANK_SSID: 'nechte prázdné pro deaktivaci WiFi a povolení ETH',
|
NETWORK_BLANK_SSID: 'ponechte prázdné pro deaktivaci WiFi a povolení ETH',
|
||||||
NETWORK_BLANK_BSSID: 'nechte prázdné pro použití pouze SSID',
|
NETWORK_BLANK_BSSID: 'ponechte prázdné pokud použijete jen SSID',
|
||||||
TX_POWER: 'Vysílací výkon',
|
TX_POWER: 'Vysílací výkon',
|
||||||
HOSTNAME: 'Název hostitele',
|
HOSTNAME: 'Název hostitele',
|
||||||
NETWORK_DISABLE_SLEEP: 'Zakázat režim spánku WiFi',
|
NETWORK_DISABLE_SLEEP: 'Zakázat režim spánku WiFi',
|
||||||
@@ -332,7 +331,7 @@ const cz: Translation = {
|
|||||||
ALLVALUES: 'Všechny hodnoty',
|
ALLVALUES: 'Všechny hodnoty',
|
||||||
SPECIAL_FUNCTIONS: 'Speciální funkce',
|
SPECIAL_FUNCTIONS: 'Speciální funkce',
|
||||||
WAIT_FIRMWARE: 'Firmware se nahrává a instaluje',
|
WAIT_FIRMWARE: 'Firmware se nahrává a instaluje',
|
||||||
INSTALL_VERSION: 'Tímto se nainstaluje verze {0}. Jste si jistí?',
|
INSTALL_VERSION: 'Tímto se instalovat verze {0}. Jste si jistí?',
|
||||||
SWITCH_DEV: 'přepnout na vývojovou verzi',
|
SWITCH_DEV: 'přepnout na vývojovou verzi',
|
||||||
UPGRADE_AVAILABLE: 'Je k dispozici aktualizace firmwaru!',
|
UPGRADE_AVAILABLE: 'Je k dispozici aktualizace firmwaru!',
|
||||||
LATEST_VERSION: 'Používáte nejnovější verzi firmwaru.',
|
LATEST_VERSION: 'Používáte nejnovější verzi firmwaru.',
|
||||||
@@ -343,7 +342,8 @@ const cz: Translation = {
|
|||||||
DASHBOARD: 'Dashboard',
|
DASHBOARD: 'Dashboard',
|
||||||
NO_DATA: 'Žádná data nejsou k dispozici',
|
NO_DATA: 'Žádná data nejsou k dispozici',
|
||||||
DASHBOARD_1: 'Přizpůsobte si dashboard označením EMS entit jako Oblíbené pomocí modulu Přizpůsobení',
|
DASHBOARD_1: 'Přizpůsobte si dashboard označením EMS entit jako Oblíbené pomocí modulu Přizpůsobení',
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Režim vývojáře',
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default cz;
|
export default cz;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const de: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server',
|
HELP_INFORMATION_2: 'Für einen Live-Community-Chat besuchen Sie unseren Discord-Server',
|
||||||
HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub',
|
HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub',
|
||||||
HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an',
|
HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an',
|
||||||
HELP_INFORMATION_5: 'Für Hilfe und Fragen wenden Sie sich bitte an Ihren Installateur',
|
|
||||||
UPLOAD: 'Hochladen',
|
UPLOAD: 'Hochladen',
|
||||||
DOWNLOAD: '{{H|h|h}}erunterladen',
|
DOWNLOAD: '{{H|h|h}}erunterladen',
|
||||||
INSTALL: 'Installieren {0}',
|
INSTALL: 'Installieren',
|
||||||
ABORTED: 'abgebrochen',
|
ABORTED: 'abgebrochen',
|
||||||
FAILED: 'gescheitert',
|
FAILED: 'gescheitert',
|
||||||
SUCCESSFUL: 'erfolgreich',
|
SUCCESSFUL: 'erfolgreich',
|
||||||
@@ -175,9 +174,9 @@ const de: Translation = {
|
|||||||
FACTORY_RESET: 'Werkseinstellung',
|
FACTORY_RESET: 'Werkseinstellung',
|
||||||
SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu.',
|
SYSTEM_FACTORY_TEXT: 'EMS-ESP wurde auf Werkseinstellung gesetzt und startet als Zugangspunkt neu.',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher, alle Einstellungen auf Werkseinstellung zu setzen?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Sind Sie sicher, alle Einstellungen auf Werkseinstellung zu setzen?',
|
||||||
|
AVAILABLE_VERSION: 'Neuesten verfügbaren Versionen',
|
||||||
STABLE: 'Stabil',
|
STABLE: 'Stabil',
|
||||||
DEVELOPMENT: 'Entwicklung',
|
DEVELOPMENT: 'Entwicklung',
|
||||||
EMS_ESP_VER: 'Firmware-Version',
|
|
||||||
UPTIME: 'Systembetriebszeit',
|
UPTIME: 'Systembetriebszeit',
|
||||||
FREE_MEMORY: 'Freier RAM Speicher',
|
FREE_MEMORY: 'Freier RAM Speicher',
|
||||||
PSRAM: 'PSRAM (Größe / Frei)',
|
PSRAM: 'PSRAM (Größe / Frei)',
|
||||||
@@ -332,7 +331,7 @@ const de: Translation = {
|
|||||||
ALLVALUES: 'Alle Werte',
|
ALLVALUES: 'Alle Werte',
|
||||||
SPECIAL_FUNCTIONS: 'Sonderfunktionen',
|
SPECIAL_FUNCTIONS: 'Sonderfunktionen',
|
||||||
WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.',
|
WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.',
|
||||||
INSTALL_VERSION: 'Dadurch wird die Version installiert {0}. Sind Sie sicher?',
|
INSTALL_VERSION: 'Dadurch wird die Version {0} heruntergeladen. Sind Sie sicher?',
|
||||||
SWITCH_DEV: 'Wechseln Sie zur Entwicklungsversion!',
|
SWITCH_DEV: 'Wechseln Sie zur Entwicklungsversion!',
|
||||||
UPGRADE_AVAILABLE: 'Es ist ein Firmware-Upgrade verfügbar.',
|
UPGRADE_AVAILABLE: 'Es ist ein Firmware-Upgrade verfügbar.',
|
||||||
LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version.',
|
LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version.',
|
||||||
@@ -343,7 +342,8 @@ const de: Translation = {
|
|||||||
DASHBOARD: 'Dashboard',
|
DASHBOARD: 'Dashboard',
|
||||||
NO_DATA: 'Keine Daten verfügbar',
|
NO_DATA: 'Keine Daten verfügbar',
|
||||||
DASHBOARD_1: 'Passen Sie Ihr Dashboard an, indem Sie EMS-Entitäten mithilfe des Moduls „Anpassungen“ als Favorit markieren',
|
DASHBOARD_1: 'Passen Sie Ihr Dashboard an, indem Sie EMS-Entitäten mithilfe des Moduls „Anpassungen“ als Favorit markieren',
|
||||||
DEVELOPER_MODE: 'Entwicklermodus'
|
DEVELOPER_MODE: 'Entwicklermodus',
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default de;
|
export default de;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const en: Translation = {
|
|||||||
HELP_INFORMATION_2: 'For live community chat join our Discord server',
|
HELP_INFORMATION_2: 'For live community chat join our Discord server',
|
||||||
HELP_INFORMATION_3: 'To request a feature or report a bug',
|
HELP_INFORMATION_3: 'To request a feature or report a bug',
|
||||||
HELP_INFORMATION_4: 'Download and attach your support information for a faster response when reporting an issue',
|
HELP_INFORMATION_4: 'Download and attach your support information for a faster response when reporting an issue',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer',
|
|
||||||
UPLOAD: 'Upload',
|
UPLOAD: 'Upload',
|
||||||
DOWNLOAD: '{{D|d|d}}ownload',
|
DOWNLOAD: '{{D|d|d}}ownload',
|
||||||
INSTALL: 'Install {0}',
|
INSTALL: 'Install',
|
||||||
ABORTED: 'aborted',
|
ABORTED: 'aborted',
|
||||||
FAILED: 'failed',
|
FAILED: 'failed',
|
||||||
SUCCESSFUL: 'successful',
|
SUCCESSFUL: 'successful',
|
||||||
@@ -175,9 +174,9 @@ const en: Translation = {
|
|||||||
FACTORY_RESET: 'Factory Reset',
|
FACTORY_RESET: 'Factory Reset',
|
||||||
SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart',
|
SYSTEM_FACTORY_TEXT: 'Device has been factory reset and will now restart',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Are you sure you want to reset EMS-ESP to its factory defaults?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions',
|
||||||
STABLE: 'Stable',
|
STABLE: 'Stable',
|
||||||
DEVELOPMENT: 'Development',
|
DEVELOPMENT: 'Development',
|
||||||
EMS_ESP_VER: 'Firmware Version',
|
|
||||||
UPTIME: 'System Uptime',
|
UPTIME: 'System Uptime',
|
||||||
FREE_MEMORY: 'Free Memory',
|
FREE_MEMORY: 'Free Memory',
|
||||||
PSRAM: 'PSRAM (Size / Free)',
|
PSRAM: 'PSRAM (Size / Free)',
|
||||||
@@ -187,7 +186,7 @@ const en: Translation = {
|
|||||||
BUFFER_SIZE: 'Max Buffer Size',
|
BUFFER_SIZE: 'Max Buffer Size',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compact',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)',
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop file or click here',
|
UPLOAD_DROP_TEXT: 'Drop file or click here',
|
||||||
ERROR: 'Unexpected Error, please try again',
|
ERROR: 'Unexpected Error, please try again',
|
||||||
TIME_SET: 'Time set',
|
TIME_SET: 'Time set',
|
||||||
@@ -343,7 +342,8 @@ const en: Translation = {
|
|||||||
DASHBOARD: 'Dashboard',
|
DASHBOARD: 'Dashboard',
|
||||||
NO_DATA: 'No data available',
|
NO_DATA: 'No data available',
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module',
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module',
|
||||||
DEVELOPER_MODE: 'Developer Mode'
|
DEVELOPER_MODE: 'Developer Mode',
|
||||||
|
UPGRADE: 'Upgrade'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const fr: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord',
|
HELP_INFORMATION_2: 'Pour une discussion en direct avec la communauté, rejoignez notre serveur Discord',
|
||||||
HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème',
|
HELP_INFORMATION_3: 'Pour demander une fonctionnalité ou signaler un problème',
|
||||||
HELP_INFORMATION_4: "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème",
|
HELP_INFORMATION_4: "N'oubliez pas de télécharger et de joindre les informations relatives à votre système pour obtenir une réponse plus rapide lorsque vous signalez un problème",
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Upload',
|
UPLOAD: 'Upload',
|
||||||
DOWNLOAD: '{{D|d|d}}ownload',
|
DOWNLOAD: '{{D|d|d}}ownload',
|
||||||
INSTALL: 'Installer {0}',
|
INSTALL: 'Installer',
|
||||||
ABORTED: 'annulé',
|
ABORTED: 'annulé',
|
||||||
FAILED: 'échoué',
|
FAILED: 'échoué',
|
||||||
SUCCESSFUL: 'réussi',
|
SUCCESSFUL: 'réussi',
|
||||||
@@ -175,9 +174,9 @@ const fr: Translation = {
|
|||||||
FACTORY_RESET: 'Réinitialisation',
|
FACTORY_RESET: 'Réinitialisation',
|
||||||
SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer",
|
SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer",
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?",
|
SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?",
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Développement',
|
DEVELOPMENT: 'Développement',
|
||||||
EMS_ESP_VER: 'Firmware Version', // TODO translate
|
|
||||||
UPTIME: 'Durée de fonctionnement du système',
|
UPTIME: 'Durée de fonctionnement du système',
|
||||||
FREE_MEMORY: 'Libre Memory',
|
FREE_MEMORY: 'Libre Memory',
|
||||||
PSRAM: 'PSRAM (Taille / Libre)',
|
PSRAM: 'PSRAM (Taille / Libre)',
|
||||||
@@ -187,7 +186,7 @@ const fr: Translation = {
|
|||||||
BUFFER_SIZE: 'Max taille du buffer',
|
BUFFER_SIZE: 'Max taille du buffer',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compact',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici',
|
UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici',
|
||||||
ERROR: 'Erreur inattendue, veuillez réessayer',
|
ERROR: 'Erreur inattendue, veuillez réessayer',
|
||||||
TIME_SET: 'Time set',
|
TIME_SET: 'Time set',
|
||||||
@@ -343,7 +342,8 @@ const fr: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default fr;
|
export default fr;
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ const it: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Per la chat della community dal vivo unisciti al nostro server Discord',
|
HELP_INFORMATION_2: 'Per la chat della community dal vivo unisciti al nostro server Discord',
|
||||||
HELP_INFORMATION_3: 'Per richiedere una funzionalità o segnalare un errore',
|
HELP_INFORMATION_3: 'Per richiedere una funzionalità o segnalare un errore',
|
||||||
HELP_INFORMATION_4: 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema',
|
HELP_INFORMATION_4: 'Ricordati di scaricare e allegare le informazioni del tuo sistema per una risposta più rapida quando segnali un problema',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Carica',
|
UPLOAD: 'Carica',
|
||||||
DOWNLOAD: 'Scarica',
|
DOWNLOAD: 'Scarica',
|
||||||
INSTALL: 'Installare {0}',
|
INSTALL: 'Installare {0}',
|
||||||
@@ -175,9 +174,9 @@ const it: Translation = {
|
|||||||
FACTORY_RESET: 'Impostazioni di fabbrica',
|
FACTORY_RESET: 'Impostazioni di fabbrica',
|
||||||
SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato',
|
SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Sviluppo',
|
DEVELOPMENT: 'Sviluppo',
|
||||||
EMS_ESP_VER: 'Versione Firmware',
|
|
||||||
UPTIME: 'Tempo di attività del sistema',
|
UPTIME: 'Tempo di attività del sistema',
|
||||||
FREE_MEMORY: 'Free Memory',
|
FREE_MEMORY: 'Free Memory',
|
||||||
PSRAM: 'PSRAM (Size / Free)',
|
PSRAM: 'PSRAM (Size / Free)',
|
||||||
@@ -187,7 +186,7 @@ const it: Translation = {
|
|||||||
BUFFER_SIZE: 'Max Buffer Size',
|
BUFFER_SIZE: 'Max Buffer Size',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compact',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui',
|
UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui',
|
||||||
ERROR: 'Errore Inaspettato, prego tenta ancora',
|
ERROR: 'Errore Inaspettato, prego tenta ancora',
|
||||||
TIME_SET: 'Imposta Ora',
|
TIME_SET: 'Imposta Ora',
|
||||||
@@ -343,7 +342,8 @@ const it: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default it;
|
export default it;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const nl: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Voor de live community ga naar de Discord server',
|
HELP_INFORMATION_2: 'Voor de live community ga naar de Discord server',
|
||||||
HELP_INFORMATION_3: 'Om een nieuwe feature te vragen of een bug te rapporteren',
|
HELP_INFORMATION_3: 'Om een nieuwe feature te vragen of een bug te rapporteren',
|
||||||
HELP_INFORMATION_4: 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord',
|
HELP_INFORMATION_4: 'Zorg dat je ook je systeem details zijn toevoeged voor een sneller antwoord',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Upload',
|
UPLOAD: 'Upload',
|
||||||
DOWNLOAD: '{{D|d|d}}ownload',
|
DOWNLOAD: '{{D|d|d}}ownload',
|
||||||
INSTALL: 'Installeren {0}',
|
INSTALL: 'Installeren',
|
||||||
ABORTED: 'afgebroken',
|
ABORTED: 'afgebroken',
|
||||||
FAILED: 'mislukt',
|
FAILED: 'mislukt',
|
||||||
SUCCESSFUL: 'successvol',
|
SUCCESSFUL: 'successvol',
|
||||||
@@ -175,9 +174,9 @@ const nl: Translation = {
|
|||||||
FACTORY_RESET: 'Fabrieksinstellingen',
|
FACTORY_RESET: 'Fabrieksinstellingen',
|
||||||
SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen',
|
SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable',
|
STABLE: 'Stable',
|
||||||
DEVELOPMENT: 'Development',
|
DEVELOPMENT: 'Development',
|
||||||
EMS_ESP_VER: 'Firmware Versie',
|
|
||||||
UPTIME: 'Systeem Uptime',
|
UPTIME: 'Systeem Uptime',
|
||||||
FREE_MEMORY: 'Free Memory',
|
FREE_MEMORY: 'Free Memory',
|
||||||
PSRAM: 'PSRAM (Size / Free)',
|
PSRAM: 'PSRAM (Size / Free)',
|
||||||
@@ -187,7 +186,7 @@ const nl: Translation = {
|
|||||||
BUFFER_SIZE: 'Max Buffer Size',
|
BUFFER_SIZE: 'Max Buffer Size',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compact',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier',
|
UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier',
|
||||||
ERROR: 'Onverwachte fout, probeer opnieuw',
|
ERROR: 'Onverwachte fout, probeer opnieuw',
|
||||||
TIME_SET: 'Tijd ingesteld',
|
TIME_SET: 'Tijd ingesteld',
|
||||||
@@ -343,7 +342,8 @@ const nl: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nl;
|
export default nl;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const no: Translation = {
|
|||||||
HELP_INFORMATION_2: 'For community-support besøk vår Discord-server',
|
HELP_INFORMATION_2: 'For community-support besøk vår Discord-server',
|
||||||
HELP_INFORMATION_3: 'For å be om en ny funksjon eller melde feil',
|
HELP_INFORMATION_3: 'For å be om en ny funksjon eller melde feil',
|
||||||
HELP_INFORMATION_4: 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem',
|
HELP_INFORMATION_4: 'Husk å laste ned og legg ved din systeminformasjon for en raskere respons når du rapporterer et problem',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Opplasning',
|
UPLOAD: 'Opplasning',
|
||||||
DOWNLOAD: '{{N|n|n}}edlasting',
|
DOWNLOAD: '{{N|n|n}}edlasting',
|
||||||
INSTALL: 'Installer {0}',
|
INSTALL: 'Installer',
|
||||||
ABORTED: 'avbrutt',
|
ABORTED: 'avbrutt',
|
||||||
FAILED: 'feilet',
|
FAILED: 'feilet',
|
||||||
SUCCESSFUL: 'vellykket',
|
SUCCESSFUL: 'vellykket',
|
||||||
@@ -175,9 +174,9 @@ const no: Translation = {
|
|||||||
FACTORY_RESET: 'Sett tilbake til fabrikkinstilling',
|
FACTORY_RESET: 'Sett tilbake til fabrikkinstilling',
|
||||||
SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte',
|
SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Development',
|
DEVELOPMENT: 'Development',
|
||||||
EMS_ESP_VER: 'Firmware Version', // TODO translate
|
|
||||||
UPTIME: 'System Oppetid',
|
UPTIME: 'System Oppetid',
|
||||||
FREE_MEMORY: 'Ledig Memory',
|
FREE_MEMORY: 'Ledig Memory',
|
||||||
PSRAM: 'PSRAM (Størrelse / Ledig)',
|
PSRAM: 'PSRAM (Størrelse / Ledig)',
|
||||||
@@ -187,7 +186,7 @@ const no: Translation = {
|
|||||||
BUFFER_SIZE: 'Max Buffer Størrelse',
|
BUFFER_SIZE: 'Max Buffer Størrelse',
|
||||||
COMPACT: 'Komprimere',
|
COMPACT: 'Komprimere',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her',
|
UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her',
|
||||||
ERROR: 'Ukjent feil, prøv igjen',
|
ERROR: 'Ukjent feil, prøv igjen',
|
||||||
TIME_SET: 'Still in tid',
|
TIME_SET: 'Still in tid',
|
||||||
@@ -343,7 +342,8 @@ const no: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default no;
|
export default no;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const pl: BaseTranslation = {
|
|||||||
HELP_INFORMATION_2: 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością',
|
HELP_INFORMATION_2: 'Dołącz do naszego serwera Discord by komunikować się na żywo ze społecznością',
|
||||||
HELP_INFORMATION_3: 'Zaproponuj nową funkcjonalność lub zgłoś problem',
|
HELP_INFORMATION_3: 'Zaproponuj nową funkcjonalność lub zgłoś problem',
|
||||||
HELP_INFORMATION_4: 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!',
|
HELP_INFORMATION_4: 'Zgłaszając problem, nie zapomnij pobrać i dołączyć informacji o swoim systemie!',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Wysyłanie',
|
UPLOAD: 'Wysyłanie',
|
||||||
DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}',
|
DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}',
|
||||||
INSTALL: 'Zainstalować {0}',
|
INSTALL: 'Zainstalować',
|
||||||
ABORTED: 'zostało przerwane!',
|
ABORTED: 'zostało przerwane!',
|
||||||
FAILED: 'nie powiodł{{o|a|}} się!',
|
FAILED: 'nie powiodł{{o|a|}} się!',
|
||||||
SUCCESSFUL: 'powiodło się.',
|
SUCCESSFUL: 'powiodło się.',
|
||||||
@@ -175,9 +174,9 @@ const pl: BaseTranslation = {
|
|||||||
FACTORY_RESET: 'Ustawienia fabryczne',
|
FACTORY_RESET: 'Ustawienia fabryczne',
|
||||||
SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.',
|
SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Testowe',
|
DEVELOPMENT: 'Testowe',
|
||||||
EMS_ESP_VER: 'Wersja Firmware',
|
|
||||||
UPTIME: 'Czas działania systemu',
|
UPTIME: 'Czas działania systemu',
|
||||||
FREE_MEMORY: 'Wolne Memory',
|
FREE_MEMORY: 'Wolne Memory',
|
||||||
PSRAM: 'PSRAM (rozmiar / wolne)',
|
PSRAM: 'PSRAM (rozmiar / wolne)',
|
||||||
@@ -187,7 +186,7 @@ const pl: BaseTranslation = {
|
|||||||
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
|
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
|
||||||
COMPACT: 'Kompaktowy',
|
COMPACT: 'Kompaktowy',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij',
|
UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij',
|
||||||
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
|
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
|
||||||
TIME_SET: 'Zegar został ustawiony.',
|
TIME_SET: 'Zegar został ustawiony.',
|
||||||
@@ -343,7 +342,8 @@ const pl: BaseTranslation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default pl;
|
export default pl;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const sk: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server',
|
HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server',
|
||||||
HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu',
|
HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu',
|
||||||
HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému',
|
HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému',
|
||||||
HELP_INFORMATION_5: 'Pre pomoc a otázky, kontaktujte svojho inštalatéra',
|
|
||||||
UPLOAD: 'Nahrať',
|
UPLOAD: 'Nahrať',
|
||||||
DOWNLOAD: '{{S|s|s}}tiahnuť',
|
DOWNLOAD: '{{S|s|s}}tiahnuť',
|
||||||
INSTALL: 'Inštalovať {0}',
|
INSTALL: 'Inštalovať',
|
||||||
ABORTED: 'zrušené',
|
ABORTED: 'zrušené',
|
||||||
FAILED: 'chybné',
|
FAILED: 'chybné',
|
||||||
SUCCESSFUL: 'úspešné',
|
SUCCESSFUL: 'úspešné',
|
||||||
@@ -175,9 +174,9 @@ const sk: Translation = {
|
|||||||
FACTORY_RESET: 'Továrenské nastavenia',
|
FACTORY_RESET: 'Továrenské nastavenia',
|
||||||
SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje',
|
SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stabilná',
|
STABLE: 'Stabilná',
|
||||||
DEVELOPMENT: 'Vývojárska',
|
DEVELOPMENT: 'Vývojárska',
|
||||||
EMS_ESP_VER: 'Firmware verzia',
|
|
||||||
UPTIME: 'Beh systému',
|
UPTIME: 'Beh systému',
|
||||||
FREE_MEMORY: 'Voľné Memory',
|
FREE_MEMORY: 'Voľné Memory',
|
||||||
PSRAM: 'PSRAM (Veľkosť / Voľné)',
|
PSRAM: 'PSRAM (Veľkosť / Voľné)',
|
||||||
@@ -332,7 +331,7 @@ const sk: Translation = {
|
|||||||
ALLVALUES: 'Všetky hodnoty',
|
ALLVALUES: 'Všetky hodnoty',
|
||||||
SPECIAL_FUNCTIONS: 'Špeciálne funkcie',
|
SPECIAL_FUNCTIONS: 'Špeciálne funkcie',
|
||||||
WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje',
|
WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje',
|
||||||
INSTALL_VERSION: 'Týmto sa nainštaluje verzia {0}. Si si istý?',
|
INSTALL_VERSION: 'Týmto sa inštalovať verzia {0}. Si si istý?',
|
||||||
SWITCH_DEV: 'prejsť na vývojovú verziu',
|
SWITCH_DEV: 'prejsť na vývojovú verziu',
|
||||||
UPGRADE_AVAILABLE: 'K dispozícii je aktualizácia firmvéru!',
|
UPGRADE_AVAILABLE: 'K dispozícii je aktualizácia firmvéru!',
|
||||||
LATEST_VERSION: 'Používate poslednú verziu firmvéru.',
|
LATEST_VERSION: 'Používate poslednú verziu firmvéru.',
|
||||||
@@ -343,7 +342,8 @@ const sk: Translation = {
|
|||||||
DASHBOARD: 'Panel',
|
DASHBOARD: 'Panel',
|
||||||
NO_DATA: 'Nie sú k dispozícii žiadne údaje',
|
NO_DATA: 'Nie sú k dispozícii žiadne údaje',
|
||||||
DASHBOARD_1: 'Prispôsobte si svoj informačný panel tak, že označíte entity EMS ako Obľúbené pomocou modulu Prispôsobenia',
|
DASHBOARD_1: 'Prispôsobte si svoj informačný panel tak, že označíte entity EMS ako Obľúbené pomocou modulu Prispôsobenia',
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sk;
|
export default sk;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const sv: Translation = {
|
|||||||
HELP_INFORMATION_2: 'För community-support besök vår Discord-server',
|
HELP_INFORMATION_2: 'För community-support besök vår Discord-server',
|
||||||
HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg',
|
HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg',
|
||||||
HELP_INFORMATION_4: 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem',
|
HELP_INFORMATION_4: 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Uppladdning',
|
UPLOAD: 'Uppladdning',
|
||||||
DOWNLOAD: '{{N|n|n}}edladdning',
|
DOWNLOAD: '{{N|n|n}}edladdning',
|
||||||
INSTALL: 'Installera {0}',
|
INSTALL: 'Installera',
|
||||||
ABORTED: 'Avbruten',
|
ABORTED: 'Avbruten',
|
||||||
FAILED: 'Misslyckades',
|
FAILED: 'Misslyckades',
|
||||||
SUCCESSFUL: 'Lyckades',
|
SUCCESSFUL: 'Lyckades',
|
||||||
@@ -175,9 +174,9 @@ const sv: Translation = {
|
|||||||
FACTORY_RESET: 'Fabriksåterställning',
|
FACTORY_RESET: 'Fabriksåterställning',
|
||||||
SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om',
|
SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Utveckling',
|
DEVELOPMENT: 'Utveckling',
|
||||||
EMS_ESP_VER: 'Firmware Version', // TODO translate
|
|
||||||
UPTIME: 'Systemets Upptid',
|
UPTIME: 'Systemets Upptid',
|
||||||
FREE_MEMORY: 'Ledigt Memory',
|
FREE_MEMORY: 'Ledigt Memory',
|
||||||
PSRAM: 'PSRAM (Storlek / Ledigt)',
|
PSRAM: 'PSRAM (Storlek / Ledigt)',
|
||||||
@@ -187,7 +186,7 @@ const sv: Translation = {
|
|||||||
BUFFER_SIZE: 'Max Bufferstorlek',
|
BUFFER_SIZE: 'Max Bufferstorlek',
|
||||||
COMPACT: 'Komprimera',
|
COMPACT: 'Komprimera',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här',
|
UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här',
|
||||||
ERROR: 'Okänt Fel, var god försök igen',
|
ERROR: 'Okänt Fel, var god försök igen',
|
||||||
TIME_SET: 'Ställ in tid',
|
TIME_SET: 'Ställ in tid',
|
||||||
@@ -343,7 +342,8 @@ const sv: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sv;
|
export default sv;
|
||||||
|
|||||||
@@ -159,10 +159,9 @@ const tr: Translation = {
|
|||||||
HELP_INFORMATION_2: 'Canlı topluluk sohbeti için Discord sunucumuza katılın',
|
HELP_INFORMATION_2: 'Canlı topluluk sohbeti için Discord sunucumuza katılın',
|
||||||
HELP_INFORMATION_3: 'Yeni bir özellik talep etmek yada hata bildirmek için',
|
HELP_INFORMATION_3: 'Yeni bir özellik talep etmek yada hata bildirmek için',
|
||||||
HELP_INFORMATION_4: 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın',
|
HELP_INFORMATION_4: 'Bir sorun bildirirken daha hızlı bir dönüş için sistem bilginizi indirip eklemeyi unutmayın',
|
||||||
HELP_INFORMATION_5: 'For help and questions please contact your installer', // TODO translate
|
|
||||||
UPLOAD: 'Yükleme',
|
UPLOAD: 'Yükleme',
|
||||||
DOWNLOAD: '{{İ|i|i}}İndirme',
|
DOWNLOAD: '{{İ|i|i}}İndirme',
|
||||||
INSTALL: 'Düzenlemek {0}',
|
INSTALL: 'Düzenlemek',
|
||||||
ABORTED: 'iptal edildi',
|
ABORTED: 'iptal edildi',
|
||||||
FAILED: 'başarısız',
|
FAILED: 'başarısız',
|
||||||
SUCCESSFUL: 'başarılı',
|
SUCCESSFUL: 'başarılı',
|
||||||
@@ -175,9 +174,9 @@ const tr: Translation = {
|
|||||||
FACTORY_RESET: 'Fabrika ayarına dönme',
|
FACTORY_RESET: 'Fabrika ayarına dönme',
|
||||||
SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak',
|
SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?',
|
||||||
|
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable', // TODO translate
|
||||||
DEVELOPMENT: 'Geliştirme',
|
DEVELOPMENT: 'Geliştirme',
|
||||||
EMS_ESP_VER: 'Firmware Sürümü',
|
|
||||||
UPTIME: 'Sistem Çalışma Süresi',
|
UPTIME: 'Sistem Çalışma Süresi',
|
||||||
FREE_MEMORY: 'Yığın Memory',
|
FREE_MEMORY: 'Yığın Memory',
|
||||||
PSRAM: 'PSRAM (Boyut / Boş)',
|
PSRAM: 'PSRAM (Boyut / Boş)',
|
||||||
@@ -187,7 +186,7 @@ const tr: Translation = {
|
|||||||
BUFFER_SIZE: 'En fazla bellek boyutu',
|
BUFFER_SIZE: 'En fazla bellek boyutu',
|
||||||
COMPACT: 'Sıkışık',
|
COMPACT: 'Sıkışık',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
||||||
UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
||||||
UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın',
|
UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın',
|
||||||
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
|
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
|
||||||
TIME_SET: 'Zaman ayarı',
|
TIME_SET: 'Zaman ayarı',
|
||||||
@@ -343,7 +342,8 @@ const tr: Translation = {
|
|||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard', // TODO translate
|
||||||
NO_DATA: 'No data available', // TODO translate
|
NO_DATA: 'No data available', // TODO translate
|
||||||
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
|
||||||
DEVELOPER_MODE: 'Developer Mode' // TODO translate
|
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
||||||
|
UPGRADE: 'Upgrade' // TODO translate
|
||||||
};
|
};
|
||||||
|
|
||||||
export default tr;
|
export default tr;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
RouterProvider,
|
RouterProvider,
|
||||||
createBrowserRouter,
|
createBrowserRouter,
|
||||||
createRoutesFromElements
|
createRoutesFromElements
|
||||||
} from 'react-router-dom';
|
} from 'react-router';
|
||||||
|
|
||||||
import App from 'App';
|
import App from 'App';
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export interface NetworkStatusType {
|
|||||||
dns_ip_1: string;
|
dns_ip_1: string;
|
||||||
dns_ip_2: string;
|
dns_ip_2: string;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
|
reconnect_count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NetworkSettingsType {
|
export interface NetworkSettingsType {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useBlocker } from 'react-router-dom';
|
import { useBlocker } from 'react-router';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import type { AlovaGenerics, Method } from 'alova';
|
import type { AlovaGenerics, Method } from 'alova';
|
||||||
|
|||||||
@@ -27,5 +27,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*", "vite.config.ts"],
|
"include": ["src/**/*", "vite.config.ts"],
|
||||||
"exclude": ["node_modules", "dist", "src/**/*.test.tsx", "src/**/*.test.ts"]
|
"exclude": ["node_modules", "dist"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false
|
secure: false
|
||||||
},
|
},
|
||||||
'/rest': 'http://localhost:3080'
|
'/rest': 'http://localhost:3080',
|
||||||
|
'/gh': 'http://localhost:3080' // mock for GitHub API
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -117,11 +118,7 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
manualChunks(id: string) {
|
manualChunks(id: string) {
|
||||||
if (id.includes('node_modules')) {
|
if (id.includes('node_modules')) {
|
||||||
// creating a chunk to react routes deps. Reducing the vendor chunk size
|
// creating a chunk to react routes deps. Reducing the vendor chunk size
|
||||||
if (
|
if (id.includes('react-router')) {
|
||||||
id.includes('react-router-dom') ||
|
|
||||||
id.includes('@remix-run') ||
|
|
||||||
id.includes('react-router')
|
|
||||||
) {
|
|
||||||
return '@react-router';
|
return '@react-router';
|
||||||
}
|
}
|
||||||
return 'vendor';
|
return 'vendor';
|
||||||
|
|||||||
1171
interface/yarn.lock
@@ -239,11 +239,11 @@
|
|||||||
#define ARDUINOJSON_BIN2ALPHA_1111() P
|
#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_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.2.0"
|
#define ARDUINOJSON_VERSION "7.2.1"
|
||||||
#define ARDUINOJSON_VERSION_MAJOR 7
|
#define ARDUINOJSON_VERSION_MAJOR 7
|
||||||
#define ARDUINOJSON_VERSION_MINOR 2
|
#define ARDUINOJSON_VERSION_MINOR 2
|
||||||
#define ARDUINOJSON_VERSION_REVISION 0
|
#define ARDUINOJSON_VERSION_REVISION 1
|
||||||
#define ARDUINOJSON_VERSION_MACRO V720
|
#define ARDUINOJSON_VERSION_MACRO V721
|
||||||
#ifndef ARDUINOJSON_VERSION_NAMESPACE
|
#ifndef ARDUINOJSON_VERSION_NAMESPACE
|
||||||
# define ARDUINOJSON_VERSION_NAMESPACE \
|
# define ARDUINOJSON_VERSION_NAMESPACE \
|
||||||
ARDUINOJSON_CONCAT5( \
|
ARDUINOJSON_CONCAT5( \
|
||||||
@@ -323,15 +323,15 @@ template <int Bits>
|
|||||||
struct uint_;
|
struct uint_;
|
||||||
template <>
|
template <>
|
||||||
struct uint_<8> {
|
struct uint_<8> {
|
||||||
typedef uint8_t type;
|
using type = uint8_t;
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct uint_<16> {
|
struct uint_<16> {
|
||||||
typedef uint16_t type;
|
using type = uint16_t;
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct uint_<32> {
|
struct uint_<32> {
|
||||||
typedef uint32_t type;
|
using type = uint32_t;
|
||||||
};
|
};
|
||||||
template <int Bits>
|
template <int Bits>
|
||||||
using uint_t = typename uint_<Bits>::type;
|
using uint_t = typename uint_<Bits>::type;
|
||||||
@@ -417,11 +417,11 @@ class MemoryPool {
|
|||||||
};
|
};
|
||||||
template <bool Condition, class TrueType, class FalseType>
|
template <bool Condition, class TrueType, class FalseType>
|
||||||
struct conditional {
|
struct conditional {
|
||||||
typedef TrueType type;
|
using type = TrueType;
|
||||||
};
|
};
|
||||||
template <class TrueType, class FalseType>
|
template <class TrueType, class FalseType>
|
||||||
struct conditional<false, TrueType, FalseType> {
|
struct conditional<false, TrueType, FalseType> {
|
||||||
typedef FalseType type;
|
using type = FalseType;
|
||||||
};
|
};
|
||||||
template <bool Condition, class TrueType, class FalseType>
|
template <bool Condition, class TrueType, class FalseType>
|
||||||
using conditional_t =
|
using conditional_t =
|
||||||
@@ -430,7 +430,7 @@ template <bool Condition, typename T = void>
|
|||||||
struct enable_if {};
|
struct enable_if {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct enable_if<true, T> {
|
struct enable_if<true, T> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <bool Condition, typename T = void>
|
template <bool Condition, typename T = void>
|
||||||
using enable_if_t = typename enable_if<Condition, T>::type;
|
using enable_if_t = typename enable_if<Condition, T>::type;
|
||||||
@@ -451,8 +451,10 @@ template <typename T, T v>
|
|||||||
struct integral_constant {
|
struct integral_constant {
|
||||||
static const T value = v;
|
static const T value = v;
|
||||||
};
|
};
|
||||||
typedef integral_constant<bool, true> true_type;
|
template <bool B>
|
||||||
typedef integral_constant<bool, false> false_type;
|
using bool_constant = integral_constant<bool, B>;
|
||||||
|
using true_type = bool_constant<true>;
|
||||||
|
using false_type = bool_constant<false>;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_array : false_type {};
|
struct is_array : false_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -461,11 +463,11 @@ template <typename T, size_t N>
|
|||||||
struct is_array<T[N]> : true_type {};
|
struct is_array<T[N]> : true_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_reference {
|
struct remove_reference {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_reference<T&> {
|
struct remove_reference<T&> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using remove_reference_t = typename remove_reference<T>::type;
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
@@ -509,7 +511,7 @@ struct is_convertible {
|
|||||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||||
static int probe(To);
|
static int probe(To);
|
||||||
static char probe(...);
|
static char probe(...);
|
||||||
static From& from_;
|
static const From& from_;
|
||||||
public:
|
public:
|
||||||
static const bool value = sizeof(probe(from_)) == sizeof(int);
|
static const bool value = sizeof(probe(from_)) == sizeof(int);
|
||||||
};
|
};
|
||||||
@@ -527,19 +529,19 @@ template <typename T>
|
|||||||
struct is_same<T, T> : true_type {};
|
struct is_same<T, T> : true_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_cv {
|
struct remove_cv {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_cv<const T> {
|
struct remove_cv<const T> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_cv<volatile T> {
|
struct remove_cv<volatile T> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_cv<const volatile T> {
|
struct remove_cv<const volatile T> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using remove_cv_t = typename remove_cv<T>::type;
|
using remove_cv_t = typename remove_cv<T>::type;
|
||||||
@@ -592,7 +594,7 @@ struct is_unsigned : integral_constant<bool,
|
|||||||
is_same<remove_cv_t<T>, bool>::value> {};
|
is_same<remove_cv_t<T>, bool>::value> {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct type_identity {
|
struct type_identity {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct make_unsigned;
|
struct make_unsigned;
|
||||||
@@ -622,11 +624,11 @@ template <typename T>
|
|||||||
using make_unsigned_t = typename make_unsigned<T>::type;
|
using make_unsigned_t = typename make_unsigned<T>::type;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_const {
|
struct remove_const {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct remove_const<const T> {
|
struct remove_const<const T> {
|
||||||
typedef T type;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using remove_const_t = typename remove_const<T>::type;
|
using remove_const_t = typename remove_const<T>::type;
|
||||||
@@ -964,16 +966,6 @@ class ZeroTerminatedRamString {
|
|||||||
const char* data() const {
|
const char* data() const {
|
||||||
return str_;
|
return str_;
|
||||||
}
|
}
|
||||||
friend int stringCompare(ZeroTerminatedRamString a,
|
|
||||||
ZeroTerminatedRamString b) {
|
|
||||||
ARDUINOJSON_ASSERT(!a.isNull());
|
|
||||||
ARDUINOJSON_ASSERT(!b.isNull());
|
|
||||||
return ::strcmp(a.str_, b.str_);
|
|
||||||
}
|
|
||||||
friend bool stringEquals(ZeroTerminatedRamString a,
|
|
||||||
ZeroTerminatedRamString b) {
|
|
||||||
return stringCompare(a, b) == 0;
|
|
||||||
}
|
|
||||||
bool isLinked() const {
|
bool isLinked() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -982,14 +974,14 @@ class ZeroTerminatedRamString {
|
|||||||
};
|
};
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
struct StringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||||
typedef ZeroTerminatedRamString AdaptedString;
|
using AdaptedString = ZeroTerminatedRamString;
|
||||||
static AdaptedString adapt(const TChar* p) {
|
static AdaptedString adapt(const TChar* p) {
|
||||||
return AdaptedString(reinterpret_cast<const char*>(p));
|
return AdaptedString(reinterpret_cast<const char*>(p));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename TChar, size_t N>
|
template <typename TChar, size_t N>
|
||||||
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
|
struct StringAdapter<TChar[N], enable_if_t<IsChar<TChar>::value>> {
|
||||||
typedef ZeroTerminatedRamString AdaptedString;
|
using AdaptedString = ZeroTerminatedRamString;
|
||||||
static AdaptedString adapt(const TChar* p) {
|
static AdaptedString adapt(const TChar* p) {
|
||||||
return AdaptedString(reinterpret_cast<const char*>(p));
|
return AdaptedString(reinterpret_cast<const char*>(p));
|
||||||
}
|
}
|
||||||
@@ -1003,7 +995,7 @@ class StaticStringAdapter : public ZeroTerminatedRamString {
|
|||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct StringAdapter<const char*, void> {
|
struct StringAdapter<const char*, void> {
|
||||||
typedef StaticStringAdapter AdaptedString;
|
using AdaptedString = StaticStringAdapter;
|
||||||
static AdaptedString adapt(const char* p) {
|
static AdaptedString adapt(const char* p) {
|
||||||
return AdaptedString(p);
|
return AdaptedString(p);
|
||||||
}
|
}
|
||||||
@@ -1035,7 +1027,7 @@ class SizedRamString {
|
|||||||
};
|
};
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
struct SizedStringAdapter<TChar*, enable_if_t<IsChar<TChar>::value>> {
|
||||||
typedef SizedRamString AdaptedString;
|
using AdaptedString = SizedRamString;
|
||||||
static AdaptedString adapt(const TChar* p, size_t n) {
|
static AdaptedString adapt(const TChar* p, size_t n) {
|
||||||
return AdaptedString(reinterpret_cast<const char*>(p), n);
|
return AdaptedString(reinterpret_cast<const char*>(p), n);
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1099,7 @@ class JsonStringAdapter : public SizedRamString {
|
|||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct StringAdapter<JsonString> {
|
struct StringAdapter<JsonString> {
|
||||||
typedef JsonStringAdapter AdaptedString;
|
using AdaptedString = JsonStringAdapter;
|
||||||
static AdaptedString adapt(const JsonString& s) {
|
static AdaptedString adapt(const JsonString& s) {
|
||||||
return AdaptedString(s);
|
return AdaptedString(s);
|
||||||
}
|
}
|
||||||
@@ -1150,7 +1142,7 @@ struct StringAdapter<
|
|||||||
T,
|
T,
|
||||||
enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
|
enable_if_t<(string_traits<T>::has_cstr || string_traits<T>::has_data) &&
|
||||||
(string_traits<T>::has_length || string_traits<T>::has_size)>> {
|
(string_traits<T>::has_length || string_traits<T>::has_size)>> {
|
||||||
typedef SizedRamString AdaptedString;
|
using AdaptedString = SizedRamString;
|
||||||
static AdaptedString adapt(const T& s) {
|
static AdaptedString adapt(const T& s) {
|
||||||
return AdaptedString(get_data(s), get_size(s));
|
return AdaptedString(get_data(s), get_size(s));
|
||||||
}
|
}
|
||||||
@@ -1350,14 +1342,14 @@ class FlashString {
|
|||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct StringAdapter<const __FlashStringHelper*, void> {
|
struct StringAdapter<const __FlashStringHelper*, void> {
|
||||||
typedef FlashString AdaptedString;
|
using AdaptedString = FlashString;
|
||||||
static AdaptedString adapt(const __FlashStringHelper* s) {
|
static AdaptedString adapt(const __FlashStringHelper* s) {
|
||||||
return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0);
|
return AdaptedString(s, s ? strlen_P(reinterpret_cast<const char*>(s)) : 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct SizedStringAdapter<const __FlashStringHelper*, void> {
|
struct SizedStringAdapter<const __FlashStringHelper*, void> {
|
||||||
typedef FlashString AdaptedString;
|
using AdaptedString = FlashString;
|
||||||
static AdaptedString adapt(const __FlashStringHelper* s, size_t n) {
|
static AdaptedString adapt(const __FlashStringHelper* s, size_t n) {
|
||||||
return AdaptedString(s, n);
|
return AdaptedString(s, n);
|
||||||
}
|
}
|
||||||
@@ -1616,11 +1608,11 @@ template <typename T, size_t = sizeof(T)>
|
|||||||
struct FloatTraits {};
|
struct FloatTraits {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct FloatTraits<T, 8 /*64bits*/> {
|
struct FloatTraits<T, 8 /*64bits*/> {
|
||||||
typedef uint64_t mantissa_type;
|
using mantissa_type = uint64_t;
|
||||||
static const short mantissa_bits = 52;
|
static const short mantissa_bits = 52;
|
||||||
static const mantissa_type mantissa_max =
|
static const mantissa_type mantissa_max =
|
||||||
(mantissa_type(1) << mantissa_bits) - 1;
|
(mantissa_type(1) << mantissa_bits) - 1;
|
||||||
typedef int16_t exponent_type;
|
using exponent_type = int16_t;
|
||||||
static const exponent_type exponent_max = 308;
|
static const exponent_type exponent_max = 308;
|
||||||
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
||||||
@@ -1686,11 +1678,11 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
|||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct FloatTraits<T, 4 /*32bits*/> {
|
struct FloatTraits<T, 4 /*32bits*/> {
|
||||||
typedef uint32_t mantissa_type;
|
using mantissa_type = uint32_t;
|
||||||
static const short mantissa_bits = 23;
|
static const short mantissa_bits = 23;
|
||||||
static const mantissa_type mantissa_max =
|
static const mantissa_type mantissa_max =
|
||||||
(mantissa_type(1) << mantissa_bits) - 1;
|
(mantissa_type(1) << mantissa_bits) - 1;
|
||||||
typedef int8_t exponent_type;
|
using exponent_type = int8_t;
|
||||||
static const exponent_type exponent_max = 38;
|
static const exponent_type exponent_max = 38;
|
||||||
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
||||||
@@ -1777,9 +1769,9 @@ inline TFloat make_float(TFloat m, TExponent e) {
|
|||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
typedef double JsonFloat;
|
using JsonFloat = double;
|
||||||
#else
|
#else
|
||||||
typedef float JsonFloat;
|
using JsonFloat = float;
|
||||||
#endif
|
#endif
|
||||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
@@ -1996,11 +1988,11 @@ class ArrayData : public CollectionData {
|
|||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
typedef int64_t JsonInteger;
|
using JsonInteger = int64_t;
|
||||||
typedef uint64_t JsonUInt;
|
using JsonUInt = uint64_t;
|
||||||
#else
|
#else
|
||||||
typedef long JsonInteger;
|
using JsonInteger = long;
|
||||||
typedef unsigned long JsonUInt;
|
using JsonUInt = unsigned long;
|
||||||
#endif
|
#endif
|
||||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
||||||
@@ -2675,15 +2667,15 @@ template <typename T>
|
|||||||
struct VariantTo {};
|
struct VariantTo {};
|
||||||
template <>
|
template <>
|
||||||
struct VariantTo<JsonArray> {
|
struct VariantTo<JsonArray> {
|
||||||
typedef JsonArray type;
|
using type = JsonArray;
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct VariantTo<JsonObject> {
|
struct VariantTo<JsonObject> {
|
||||||
typedef JsonObject type;
|
using type = JsonObject;
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct VariantTo<JsonVariant> {
|
struct VariantTo<JsonVariant> {
|
||||||
typedef JsonVariant type;
|
using type = JsonVariant;
|
||||||
};
|
};
|
||||||
class VariantAttorney {
|
class VariantAttorney {
|
||||||
public:
|
public:
|
||||||
@@ -3008,7 +3000,7 @@ class JsonVariantConst : public detail::VariantTag,
|
|||||||
if (key.template is<size_t>())
|
if (key.template is<size_t>())
|
||||||
return operator[](key.template as<size_t>());
|
return operator[](key.template as<size_t>());
|
||||||
else
|
else
|
||||||
return operator[](key.template as<const char*>());
|
return operator[](key.template as<JsonString>());
|
||||||
}
|
}
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
ARDUINOJSON_DEPRECATED("use var[key].is<T>() instead")
|
ARDUINOJSON_DEPRECATED("use var[key].is<T>() instead")
|
||||||
@@ -3155,7 +3147,7 @@ class VariantRefBase : public VariantTag {
|
|||||||
if (key.template is<size_t>())
|
if (key.template is<size_t>())
|
||||||
return operator[](key.template as<size_t>());
|
return operator[](key.template as<size_t>());
|
||||||
else
|
else
|
||||||
return operator[](key.template as<const char*>());
|
return operator[](key.template as<JsonString>());
|
||||||
}
|
}
|
||||||
ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead")
|
ARDUINOJSON_DEPRECATED("use add<JsonVariant>() instead")
|
||||||
JsonVariant add() const;
|
JsonVariant add() const;
|
||||||
@@ -3392,7 +3384,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
|||||||
friend class JsonArray;
|
friend class JsonArray;
|
||||||
friend class detail::VariantAttorney;
|
friend class detail::VariantAttorney;
|
||||||
public:
|
public:
|
||||||
typedef JsonArrayConstIterator iterator;
|
using iterator = JsonArrayConstIterator;
|
||||||
iterator begin() const {
|
iterator begin() const {
|
||||||
if (!data_)
|
if (!data_)
|
||||||
return iterator();
|
return iterator();
|
||||||
@@ -3468,7 +3460,7 @@ class JsonObject;
|
|||||||
class JsonArray : public detail::VariantOperators<JsonArray> {
|
class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||||
friend class detail::VariantAttorney;
|
friend class detail::VariantAttorney;
|
||||||
public:
|
public:
|
||||||
typedef JsonArrayIterator iterator;
|
using iterator = JsonArrayIterator;
|
||||||
JsonArray() : data_(0), resources_(0) {}
|
JsonArray() : data_(0), resources_(0) {}
|
||||||
JsonArray(detail::ArrayData* data, detail::ResourceManager* resources)
|
JsonArray(detail::ArrayData* data, detail::ResourceManager* resources)
|
||||||
: data_(data), resources_(resources) {}
|
: data_(data), resources_(resources) {}
|
||||||
@@ -3687,7 +3679,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
friend class JsonObject;
|
friend class JsonObject;
|
||||||
friend class detail::VariantAttorney;
|
friend class detail::VariantAttorney;
|
||||||
public:
|
public:
|
||||||
typedef JsonObjectConstIterator iterator;
|
using iterator = JsonObjectConstIterator;
|
||||||
JsonObjectConst() : data_(0), resources_(0) {}
|
JsonObjectConst() : data_(0), resources_(0) {}
|
||||||
JsonObjectConst(const detail::ObjectData* data,
|
JsonObjectConst(const detail::ObjectData* data,
|
||||||
const detail::ResourceManager* resources)
|
const detail::ResourceManager* resources)
|
||||||
@@ -3751,8 +3743,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
template <typename TVariant>
|
template <typename TVariant>
|
||||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||||
operator[](const TVariant& key) const {
|
operator[](const TVariant& key) const {
|
||||||
if (key.template is<const char*>())
|
if (key.template is<JsonString>())
|
||||||
return operator[](key.template as<const char*>());
|
return operator[](key.template as<JsonString>());
|
||||||
else
|
else
|
||||||
return JsonVariantConst();
|
return JsonVariantConst();
|
||||||
}
|
}
|
||||||
@@ -3835,7 +3827,7 @@ class JsonArray;
|
|||||||
class JsonObject : public detail::VariantOperators<JsonObject> {
|
class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||||
friend class detail::VariantAttorney;
|
friend class detail::VariantAttorney;
|
||||||
public:
|
public:
|
||||||
typedef JsonObjectIterator iterator;
|
using iterator = JsonObjectIterator;
|
||||||
JsonObject() : data_(0), resources_(0) {}
|
JsonObject() : data_(0), resources_(0) {}
|
||||||
JsonObject(detail::ObjectData* data, detail::ResourceManager* resource)
|
JsonObject(detail::ObjectData* data, detail::ResourceManager* resource)
|
||||||
: data_(data), resources_(resource) {}
|
: data_(data), resources_(resource) {}
|
||||||
@@ -3897,10 +3889,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
}
|
}
|
||||||
template <typename TVariant>
|
template <typename TVariant>
|
||||||
detail::enable_if_t<detail::IsVariant<TVariant>::value,
|
detail::enable_if_t<detail::IsVariant<TVariant>::value,
|
||||||
detail::MemberProxy<JsonObject, const char*>>
|
detail::MemberProxy<JsonObject, JsonString>>
|
||||||
operator[](const TVariant& key) const {
|
operator[](const TVariant& key) const {
|
||||||
if (key.template is<const char*>())
|
if (key.template is<JsonString>())
|
||||||
return {*this, key.template as<const char*>()};
|
return {*this, key.template as<JsonString>()};
|
||||||
else
|
else
|
||||||
return {*this, nullptr};
|
return {*this, nullptr};
|
||||||
}
|
}
|
||||||
@@ -4059,6 +4051,10 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
|||||||
const T& src) {
|
const T& src) {
|
||||||
return to<JsonVariant>().set(src);
|
return to<JsonVariant>().set(src);
|
||||||
}
|
}
|
||||||
|
template <typename TChar>
|
||||||
|
bool set(TChar* src) {
|
||||||
|
return to<JsonVariant>().set(src);
|
||||||
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename detail::VariantTo<T>::type to() {
|
typename detail::VariantTo<T>::type to() {
|
||||||
clear();
|
clear();
|
||||||
@@ -4117,8 +4113,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
|||||||
template <typename TVariant>
|
template <typename TVariant>
|
||||||
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
detail::enable_if_t<detail::IsVariant<TVariant>::value, JsonVariantConst>
|
||||||
operator[](const TVariant& key) const {
|
operator[](const TVariant& key) const {
|
||||||
if (key.template is<const char*>())
|
if (key.template is<JsonString>())
|
||||||
return operator[](key.template as<const char*>());
|
return operator[](key.template as<JsonString>());
|
||||||
if (key.template is<size_t>())
|
if (key.template is<size_t>())
|
||||||
return operator[](key.template as<size_t>());
|
return operator[](key.template as<size_t>());
|
||||||
return {};
|
return {};
|
||||||
@@ -4238,7 +4234,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
|
|||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
template <typename TResult>
|
template <typename TResult>
|
||||||
struct VariantDataVisitor {
|
struct VariantDataVisitor {
|
||||||
typedef TResult result_type;
|
using result_type = TResult;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TResult visit(const T&) {
|
TResult visit(const T&) {
|
||||||
return TResult();
|
return TResult();
|
||||||
@@ -4246,7 +4242,7 @@ struct VariantDataVisitor {
|
|||||||
};
|
};
|
||||||
template <typename TResult>
|
template <typename TResult>
|
||||||
struct JsonVariantVisitor {
|
struct JsonVariantVisitor {
|
||||||
typedef TResult result_type;
|
using result_type = TResult;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TResult visit(const T&) {
|
TResult visit(const T&) {
|
||||||
return TResult();
|
return TResult();
|
||||||
@@ -4822,7 +4818,7 @@ struct FloatParts {
|
|||||||
};
|
};
|
||||||
template <typename TFloat>
|
template <typename TFloat>
|
||||||
inline int16_t normalize(TFloat& value) {
|
inline int16_t normalize(TFloat& value) {
|
||||||
typedef FloatTraits<TFloat> traits;
|
using traits = FloatTraits<TFloat>;
|
||||||
int16_t powersOf10 = 0;
|
int16_t powersOf10 = 0;
|
||||||
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
||||||
int bit = 1 << index;
|
int bit = 1 << index;
|
||||||
@@ -4965,7 +4961,7 @@ class TextFormatter {
|
|||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<is_signed<T>::value> writeInteger(T value) {
|
enable_if_t<is_signed<T>::value> writeInteger(T value) {
|
||||||
typedef make_unsigned_t<T> unsigned_type;
|
using unsigned_type = make_unsigned_t<T>;
|
||||||
unsigned_type unsigned_value;
|
unsigned_type unsigned_value;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
writeRaw('-');
|
writeRaw('-');
|
||||||
@@ -5703,7 +5699,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
|
|||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
class JsonVariantCopier {
|
class JsonVariantCopier {
|
||||||
public:
|
public:
|
||||||
typedef bool result_type;
|
using result_type = bool;
|
||||||
JsonVariantCopier(JsonVariant dst) : dst_(dst) {}
|
JsonVariantCopier(JsonVariant dst) : dst_(dst) {}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool visit(T src) {
|
bool visit(T src) {
|
||||||
@@ -6325,13 +6321,10 @@ template <typename T, typename... Rest>
|
|||||||
struct first_or_void<T, Rest...> {
|
struct first_or_void<T, Rest...> {
|
||||||
using type = T;
|
using type = T;
|
||||||
};
|
};
|
||||||
template <class T, class = void>
|
|
||||||
struct is_deserialize_destination : false_type {};
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct is_deserialize_destination<
|
using is_deserialize_destination =
|
||||||
T, enable_if_t<is_same<decltype(VariantAttorney::getResourceManager(
|
bool_constant<is_base_of<JsonDocument, remove_cv_t<T>>::value ||
|
||||||
detail::declval<T&>())),
|
IsVariant<T>::value>;
|
||||||
ResourceManager*>::value>> : true_type {};
|
|
||||||
template <typename TDestination>
|
template <typename TDestination>
|
||||||
inline void shrinkJsonDocument(TDestination&) {
|
inline void shrinkJsonDocument(TDestination&) {
|
||||||
}
|
}
|
||||||
@@ -6571,9 +6564,9 @@ class Number {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
inline Number parseNumber(const char* s) {
|
inline Number parseNumber(const char* s) {
|
||||||
typedef FloatTraits<JsonFloat> traits;
|
using traits = FloatTraits<JsonFloat>;
|
||||||
typedef largest_type<traits::mantissa_type, JsonUInt> mantissa_t;
|
using mantissa_t = largest_type<traits::mantissa_type, JsonUInt>;
|
||||||
typedef traits::exponent_type exponent_t;
|
using exponent_t = traits::exponent_type;
|
||||||
ARDUINOJSON_ASSERT(s != 0);
|
ARDUINOJSON_ASSERT(s != 0);
|
||||||
bool is_negative = false;
|
bool is_negative = false;
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
@@ -7212,7 +7205,7 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE
|
|||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||||
typedef JsonSerializer<TWriter> base;
|
using base = JsonSerializer<TWriter>;
|
||||||
public:
|
public:
|
||||||
PrettyJsonSerializer(TWriter writer, const ResourceManager* resources)
|
PrettyJsonSerializer(TWriter writer, const ResourceManager* resources)
|
||||||
: base(writer, resources), nesting_(0) {}
|
: base(writer, resources), nesting_(0) {}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Version 7.2.0
|
Version 7.2.1
|
||||||
|
|
||||||
From https://github.com/bblanchon/ArduinoJson/releases
|
From https://github.com/bblanchon/ArduinoJson/releases
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <Print.h>
|
#include <Print.h>
|
||||||
|
|
||||||
constexpr const char * JSON_MIMETYPE = "application/json";
|
constexpr const char * JSON_MIMETYPE = "application/json";
|
||||||
|
constexpr const char * MSGPACK_MIMETYPE = "application/msgpack";
|
||||||
|
|
||||||
class ChunkPrint : public Print {
|
class ChunkPrint : public Print {
|
||||||
private:
|
private:
|
||||||
@@ -54,7 +55,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse {
|
|||||||
: _isValid{false}
|
: _isValid{false}
|
||||||
, _isMsgPack{isMsgPack} {
|
, _isMsgPack{isMsgPack} {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_contentType = JSON_MIMETYPE;
|
_contentType = (isMsgPack) ? MSGPACK_MIMETYPE : JSON_MIMETYPE;
|
||||||
if (isArray)
|
if (isArray)
|
||||||
_root = _jsonBuffer.add<JsonArray>();
|
_root = _jsonBuffer.add<JsonArray>();
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -57,15 +57,15 @@ class ESP8266React {
|
|||||||
// special functions needed outside scope
|
// special functions needed outside scope
|
||||||
//
|
//
|
||||||
|
|
||||||
void setWill(const char * will_topic) {
|
|
||||||
_mqttSettingsService.setWill(will_topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
// true if AP is active
|
// true if AP is active
|
||||||
bool apStatus() {
|
bool apStatus() {
|
||||||
return _apSettingsService.getAPNetworkStatus() == APNetworkStatus::ACTIVE;
|
return _apSettingsService.getAPNetworkStatus() == APNetworkStatus::ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t getWifiReconnects() {
|
||||||
|
return _networkSettingsService.getWifiReconnects();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SecuritySettingsService _securitySettingsService;
|
SecuritySettingsService _securitySettingsService;
|
||||||
NetworkSettingsService _networkSettingsService;
|
NetworkSettingsService _networkSettingsService;
|
||||||
|
|||||||
@@ -101,16 +101,6 @@ const char * MqttSettingsService::getClientId() {
|
|||||||
return _mqttClient->getClientId();
|
return _mqttClient->getClientId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::setWill(const char * topic) {
|
|
||||||
#ifndef TASMOTA_SDK
|
|
||||||
if (_state.enableTLS) {
|
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MqttSettingsService::onMqttMessage(const espMqttClientTypes::MessageProperties & properties,
|
void MqttSettingsService::onMqttMessage(const espMqttClientTypes::MessageProperties & properties,
|
||||||
const char * topic,
|
const char * topic,
|
||||||
const uint8_t * payload,
|
const uint8_t * payload,
|
||||||
@@ -183,6 +173,14 @@ bool MqttSettingsService::configureMqtt() {
|
|||||||
|
|
||||||
// only connect if WiFi is connected and MQTT is enabled
|
// only connect if WiFi is connected and MQTT is enabled
|
||||||
if (_state.enabled && emsesp::EMSESP::system_.network_connected() && !_state.host.isEmpty()) {
|
if (_state.enabled && emsesp::EMSESP::system_.network_connected() && !_state.host.isEmpty()) {
|
||||||
|
// create last will topic with the base prefixed. It has to be static because the client destroys the reference
|
||||||
|
static char will_topic[FACTORY_MQTT_MAX_TOPIC_LENGTH];
|
||||||
|
if (_state.base.isEmpty()) {
|
||||||
|
snprintf(will_topic, sizeof(will_topic), "status");
|
||||||
|
} else {
|
||||||
|
snprintf(will_topic, sizeof(will_topic), "%s/status", _state.base.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
_reconfigureMqtt = false;
|
_reconfigureMqtt = false;
|
||||||
#ifndef TASMOTA_SDK
|
#ifndef TASMOTA_SDK
|
||||||
if (_state.enableTLS) {
|
if (_state.enableTLS) {
|
||||||
@@ -197,6 +195,7 @@ bool MqttSettingsService::configureMqtt() {
|
|||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setClientId(_state.clientId.c_str());
|
static_cast<espMqttClientSecure *>(_mqttClient)->setClientId(_state.clientId.c_str());
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
static_cast<espMqttClientSecure *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
static_cast<espMqttClientSecure *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
||||||
|
static_cast<espMqttClientSecure *>(_mqttClient)->setWill(will_topic, 1, true, "offline"); // QOS 1, retain
|
||||||
return _mqttClient->connect();
|
return _mqttClient->connect();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -207,6 +206,7 @@ bool MqttSettingsService::configureMqtt() {
|
|||||||
static_cast<espMqttClient *>(_mqttClient)->setClientId(_state.clientId.c_str());
|
static_cast<espMqttClient *>(_mqttClient)->setClientId(_state.clientId.c_str());
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
static_cast<espMqttClient *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
static_cast<espMqttClient *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setWill(will_topic, 1, true, "offline"); // QOS 1, retain
|
||||||
return _mqttClient->connect();
|
return _mqttClient->connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
|
|||||||
const char * getClientId();
|
const char * getClientId();
|
||||||
espMqttClientTypes::DisconnectReason getDisconnectReason();
|
espMqttClientTypes::DisconnectReason getDisconnectReason();
|
||||||
MqttClient * getMqttClient();
|
MqttClient * getMqttClient();
|
||||||
void setWill(const char * topic);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onConfigUpdated();
|
void onConfigUpdated();
|
||||||
|
|||||||
@@ -304,10 +304,14 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
||||||
emsesp::EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)",
|
connectcount_++; // count the number of WiFi reconnects
|
||||||
|
emsesp::EMSESP::logger().warning("WiFi disconnected (#%d). Reason: %s (%d)",
|
||||||
|
connectcount_,
|
||||||
disconnectReason(info.wifi_sta_disconnected.reason),
|
disconnectReason(info.wifi_sta_disconnected.reason),
|
||||||
info.wifi_sta_disconnected.reason); // IDF 4.0
|
info.wifi_sta_disconnected.reason); // IDF 4.0
|
||||||
emsesp::EMSESP::system_.has_ipv6(false);
|
emsesp::EMSESP::system_.has_ipv6(false);
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ class NetworkSettings {
|
|||||||
static StateUpdateResult update(JsonObject root, NetworkSettings & settings);
|
static StateUpdateResult update(JsonObject root, NetworkSettings & settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class NetworkSettingsService : public StatefulService<NetworkSettings> {
|
class NetworkSettingsService : public StatefulService<NetworkSettings> {
|
||||||
public:
|
public:
|
||||||
NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||||
@@ -95,6 +94,10 @@ class NetworkSettingsService : public StatefulService<NetworkSettings> {
|
|||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
|
uint16_t getWifiReconnects() const {
|
||||||
|
return connectcount_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpEndpoint<NetworkSettings> _httpEndpoint;
|
HttpEndpoint<NetworkSettings> _httpEndpoint;
|
||||||
FSPersistence<NetworkSettings> _fsPersistence;
|
FSPersistence<NetworkSettings> _fsPersistence;
|
||||||
@@ -102,6 +105,8 @@ class NetworkSettingsService : public StatefulService<NetworkSettings> {
|
|||||||
unsigned long _lastConnectionAttempt;
|
unsigned long _lastConnectionAttempt;
|
||||||
bool _stopping;
|
bool _stopping;
|
||||||
|
|
||||||
|
uint16_t connectcount_ = 0; // number of wifi reconnects
|
||||||
|
|
||||||
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info);
|
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
void mDNS_start() const;
|
void mDNS_start() const;
|
||||||
const char * disconnectReason(uint8_t code);
|
const char * disconnectReason(uint8_t code);
|
||||||
|
|||||||
@@ -60,12 +60,13 @@ void NetworkStatus::networkStatus(AsyncWebServerRequest * request) {
|
|||||||
#else
|
#else
|
||||||
root["local_ipv6"] = WiFi.linkLocalIPv6().toString();
|
root["local_ipv6"] = WiFi.linkLocalIPv6().toString();
|
||||||
#endif
|
#endif
|
||||||
root["mac_address"] = WiFi.macAddress();
|
root["mac_address"] = WiFi.macAddress();
|
||||||
root["rssi"] = WiFi.RSSI();
|
root["rssi"] = WiFi.RSSI();
|
||||||
root["ssid"] = WiFi.SSID();
|
root["ssid"] = WiFi.SSID();
|
||||||
root["bssid"] = WiFi.BSSIDstr();
|
root["bssid"] = WiFi.BSSIDstr();
|
||||||
root["channel"] = WiFi.channel();
|
root["channel"] = WiFi.channel();
|
||||||
root["subnet_mask"] = WiFi.subnetMask().toString();
|
root["reconnect_count"] = emsesp::EMSESP::esp8266React.getWifiReconnects();
|
||||||
|
root["subnet_mask"] = WiFi.subnetMask().toString();
|
||||||
|
|
||||||
if (WiFi.gatewayIP() != INADDR_NONE) {
|
if (WiFi.gatewayIP() != INADDR_NONE) {
|
||||||
root["gateway_ip"] = WiFi.gatewayIP().toString();
|
root["gateway_ip"] = WiFi.gatewayIP().toString();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#define UPLOAD_FILE_PATH "/rest/uploadFile"
|
#define UPLOAD_FILE_PATH "/rest/uploadFile"
|
||||||
|
|
||||||
#define TEMP_FILENAME_PATH "/tmp_upload" // for uploaded json files
|
#define TEMP_FILENAME_PATH "/pre_load.json" // for uploaded json files, handled by System::check_restore()
|
||||||
|
|
||||||
class UploadFileService {
|
class UploadFileService {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ class EMSuart {
|
|||||||
static void restart();
|
static void restart();
|
||||||
static void send_poll(uint8_t data);
|
static void send_poll(uint8_t data);
|
||||||
static uint16_t transmit(uint8_t * buf, uint8_t len);
|
static uint16_t transmit(uint8_t * buf, uint8_t len);
|
||||||
|
static uint8_t last_tx_src() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static char * hextoa(char * result, const uint8_t value);
|
static char * hextoa(char * result, const uint8_t value);
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 87 KiB |
BIN
media/favicon/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
media/favicon/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
media/favicon/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
media/favicon/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 505 B |
BIN
media/favicon/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
media/favicon/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
1
media/favicon/site.webmanifest
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||||
934
mock-api/.yarn/releases/yarn-4.5.3.cjs
vendored
Executable file
@@ -1 +1,3 @@
|
|||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-4.5.3.cjs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mock-api",
|
"name": "mock-api",
|
||||||
"version": "3.7.0",
|
"version": "3.7.1",
|
||||||
"description": "mock api for EMS-ESP",
|
"description": "mock api for EMS-ESP",
|
||||||
"author": "proddy, emsesp.org",
|
"author": "proddy, emsesp.org",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"formidable": "^3.5.2",
|
"formidable": "^3.5.2",
|
||||||
"itty-router": "^5.0.18",
|
"itty-router": "^5.0.18",
|
||||||
"prettier": "^3.3.3"
|
"prettier": "^3.4.1"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.1"
|
"packageManager": "yarn@4.5.3"
|
||||||
}
|
}
|
||||||
|
|||||||