Compare commits

..

965 Commits

Author SHA1 Message Date
Thomas Basler
653efb41a2 Fix: Syntax error in defines 2025-01-14 23:07:46 +01:00
Thomas Basler
571ba2f350 Fix: Hint regarding required device profile is shown for profiles which don't need a device profile
This patch introduces a define which allows to specifiy for each environment if a device profile is absolutly required.

Fixes #2500
2025-01-14 22:13:48 +01:00
Thomas Basler
220cfbf7ae Update nrf24/RF24 from 1.4.10 to 1.4.11 2025-01-14 19:17:14 +01:00
Thomas Basler
db130f646e Upgrade ESPAsyncWebServer from 3.4.2 to 3.6.0 2025-01-14 19:14:17 +01:00
Thomas Basler
5510c9ff57 webapp: add app.js.gz 2025-01-14 18:43:41 +01:00
Thomas Basler
ebf4e921ee Merge branch 'pr2420' into dev 2025-01-14 18:38:23 +01:00
Thomas Basler
d068542c94 Merge branch 'pr2421' into dev 2025-01-14 18:37:40 +01:00
Thomas Basler
19fa310f43 webapp: Update dependencies 2025-01-14 18:35:45 +01:00
Thomas Basler
87772cb76b Feature: Add support for HERF-600 inverters
Fixes #2492
2025-01-08 17:52:33 +01:00
Thomas Basler
50207a42bf webapp: Update dependencies 2024-12-31 16:08:56 +01:00
Thomas Basler
a0e6942537 Feature: Detect if inverter supports 'Power Distribution Logic'
The detection of 'Power Distribution Logic' is based on the firmware version for specific models and is needed to disable any means of overscaling, as it simply does not work when 'Power Distrbution Logic' is available.

Based on the code from @AndreasBoehm
2024-12-31 16:08:37 +01:00
Thomas Basler
c37397acca Fix lint errors 2024-12-30 00:16:14 +01:00
Thomas Basler
498afe377b Remove extra semikolon 2024-12-30 00:06:08 +01:00
Thomas Basler
d43ac7fb92 Update bblanchon/ArduinoJson from 7.2.1 to 7.3.0 2024-12-29 22:32:43 +01:00
Thomas Basler
11105944be Fix: Uptime overflow after ~50 days
Fixes #2473
2024-12-29 20:53:20 +01:00
Thomas Basler
c7fa4ff212 Disable queue debugging 2024-12-21 11:59:51 +01:00
Thomas Basler
96ba58af8c Fix: Wifi.begin was called with wrong parameters
The third parameter should be a optional channel name and not a scan method. There exists a separate method for the scan method.
2024-12-18 23:00:27 +01:00
Thomas Basler
d485d1b820 Show totals in blue and producing inverters in green 2024-12-18 22:16:23 +01:00
Thomas Basler
8f60a3a12a Feature: Show inverter status and current power in overview (if multiple inverters are available) 2024-12-18 21:21:10 +01:00
Thomas Basler
940027ab19 Upgrade ESPAsyncWebServer from 3.4.1 to 3.4.2 2024-12-18 19:31:56 +01:00
Thomas Basler
24b3f27364 webapp: Update dependencies 2024-12-16 20:50:09 +01:00
Thomas Basler
5265c6281f Feature: Set Limit transfer only to "OK" if the queue does not contain any more commands 2024-12-15 20:45:32 +01:00
Thomas Basler
8acae28c59 Feature: New handling of command queue
Goal of this change is to  prevent a overflow in the command queue by flooding it with MQTT commands and therefor also prevent  the reading of the inverter data.

To achieve this it is now possible to specify a insert type for each  queue element.
2024-12-15 20:45:32 +01:00
Thomas Basler
0061d5e159 Upgrade ESPAsyncWebServer from 3.4.0 to 3.4.1 2024-12-15 20:45:15 +01:00
Thomas Basler
5d14454185 Fix: Auto reboot was not triggered on pin mapping change 2024-12-14 13:33:44 +01:00
Thomas Basler
58382be16c Feature: show hint if device profile missing or not selected 2024-12-14 13:07:31 +01:00
Thomas Basler
2edec642fb Fix: Remove temperature readings for ESP32-S2 modules
For some reasons this leads to WDT resets on this kind of module.
This is just a workaround until another solution is found.
2024-12-14 12:36:50 +01:00
Thomas Basler
726a08ec2c Upgrade ESPAsyncWebServer from 3.3.23 to 3.4.0 2024-12-13 21:07:50 +01:00
Thomas Basler
d775ee9e89 Update bblanchon/ArduinoJson from 7.2.0 to 7.2.1 2024-12-05 22:23:18 +01:00
Thomas Basler
1c1fcbea51 Upgrade ESPAsyncWebServer from 3.3.22 to 3.3.23 2024-12-05 22:22:45 +01:00
Thomas Basler
bf89fd7558 webapp: Update dependencies 2024-12-05 22:21:48 +01:00
Bernhard Kirchen
8247070aae webapp: improve styling of hints on home view
* increase the spacing between the icon and the text.
* put the text into its own box so it does not flow around the icon.
* vertically center the icon to account for multiple lines of text.
* vertically center the text to account for a single line of text.

closes #1441.
2024-12-03 22:59:25 +01:00
Thomas Basler
241ee1e99d webapp: Update dependencies 2024-12-02 23:07:55 +01:00
Thomas Basler
a75543c309 Feature:: Added support for HMS-450 inverters which begin with 1400 2024-12-02 22:45:50 +01:00
Bernhard Kirchen
1c5a3cf6fe webapp: avoid undefined serial for InputSerial
if variables are set with 'const foo = {} as Inverter', then
'foo.serial' will be undefined, causing warnings and errors
when using InputSerial.
2024-12-02 22:20:52 +01:00
Bernhard Kirchen
b2dcac549c Fix: need to skip BOM also when migrating config 2024-12-02 22:20:12 +01:00
Bernhard Kirchen
37b173071e webapp: fix line break for reload button
if a page uses the reload button, it had only 1 column of space, and
only if the viewport was at least "sm". this is not the case for typical
smartphones, in which case the reload button would appear on its own row
instead of to the right.

we now limit the heading to 10 columns if and only if the reload button
is to be used, otherwise the heading uses all 12 columns, regardless of
the viewport size. the reload buton uses two columns -- if it is
displayed at all.

the font size of the icon is increased slightly.

as the font size of h1 headings changes with the viewport size, we need
to center both the heading and the button vertically.
2024-12-02 22:19:03 +01:00
Florian
041ae7bae7 add Sum of DC Powrr
add Sum of DC power of all enabled inverters to Homeassistant MQTT autodiscovery
2024-11-22 08:21:13 +01:00
stefan123t
680863fb00
Update README.md 2024-11-20 08:02:07 +01:00
stefan123t
8297591853
change markdown table to github style 2024-11-20 08:00:26 +01:00
Thomas Basler
cc3290be8e Use correct variable 2024-11-13 19:21:41 +01:00
Thomas Basler
9bfded055a Remove not required string generation 2024-11-13 19:20:56 +01:00
Thomas Basler
2b07e3c2c8 Organize includes 2024-11-12 20:23:28 +01:00
Thomas Basler
eac2e2fb39 Fix: Really always execute the generate of the factory.bin file 2024-11-11 23:52:59 +01:00
Thomas Basler
d843ac6422 Fix comment 2024-11-11 22:11:57 +01:00
Thomas Basler
33a9b7454c Make function getClientId const 2024-11-10 02:45:42 +01:00
Thomas Basler
3dc70ab40a webapp: add app.js.gz 2024-11-07 19:13:45 +01:00
Thomas Basler
ecb5e9cc32 Build factory.bin in every compile attempt
This is required to apply changes  which are maybe only related to  the data directory.
2024-11-07 19:10:41 +01:00
Thomas Basler
9a53d6e209 Fix lint errors 2024-11-07 18:30:29 +01:00
Thomas Basler
63405a712c Upgrade ESPAsyncWebServer from 3.3.21 to 3.3.22 2024-11-07 18:21:59 +01:00
Thomas Basler
69c67f96e7 webapp: Update dependencies 2024-11-07 18:16:18 +01:00
Bernhard Kirchen
d088021902 webapp: declare emitted event in FormFooter component
fixes an annoying warning (visible in the browser console):

[Vue warn]: Extraneous non-emits event listeners (reload) were passed to
component but could not be automatically inherited because component
renders fragment or text root nodes. If the listener is intended to be a
component custom event listener only, declare it using the "emits"
option.
2024-11-06 22:34:56 +01:00
Thomas Basler
74e3947cb2 Merge branch 'pr2360' into dev 2024-11-06 19:55:03 +01:00
Thomas Basler
ca060e406e Remove not required include 2024-11-06 19:39:39 +01:00
Thomas Basler
53b496fd00 Replace multiline print by printf 2024-11-06 19:39:24 +01:00
Thomas Basler
ab60875142 Remove not required include 2024-11-06 19:24:37 +01:00
Bernhard Kirchen
3948adf460 keep console.log() when serving webapp
the removal of console and debugger statements by esbuild even when not
building for production seems to be a regression, as these were
definitely working in the past.

this change uses the command parameter to configure esbuild to either
keep or indeed remove the respective statements. they are only kept if
command is not "serve".

to avoid having to indent everything in defineConfig() by one block, the
return statement and closing curly brace were added "inline".
2024-11-05 19:21:45 +01:00
Bernhard Kirchen
3c56ec3738 webapp: fix inverter selection button breaking
on small viewports, the icon and the inverter label would be displayed
in two lines. this change keeps the icon and the label tied together in
any case, and the icon is centered vertically around the label.
2024-11-03 20:35:14 +01:00
Bernhard Kirchen
661ea6c022 webapp: always scroll up when navigating to another view 2024-11-02 00:32:49 +01:00
Bernhard Kirchen
3fa864ce52 webapp: device manager: optimize cards for tab nav
the top border of the card was breaking the design of the tabs, where
the active tab would be "visually connected" to the content. also, the
rounded border at the top did not blend in with the navbar's bottom
border.
2024-11-02 00:30:03 +01:00
Bernhard Kirchen
71f312d830 webapp: show pin mapping categories as cards
on a desktop browser, this approach allows to display all categories at
once. we also increase readability as the values are much closer to
their label. previously, the values were far to the right of the screen
and it was unpleasent to read which value belonged to which setting. the
grouping of values per category was also not very well conceived.

by using cards, we also avoid some styling issues, namely the use of
rowspan, which caused a spurious table cell border at the end of the old
table layout.
2024-11-02 00:28:18 +01:00
Bernhard Kirchen
f1c095e41d webapp: optimize placement of device profile doc buttons
* remove empty container for device profile links. if a device profile
  has no links, no buttons are generated, but a row was still part of
  the DOM, adding spurious space between the select and the alert with
  the hint.
2024-11-02 00:25:36 +01:00
Bernhard Kirchen
bac7179f73 webapp: consistently use no colon in form labels
there are no colons for table headers as well. some form labels had no
colon already, so this change uses a unified look among form labels.
2024-11-02 00:10:05 +01:00
Bernhard Kirchen
9f315207d4 webapp: optimize body bottom padding and length
long forms, when scrolled to the bottom, would leave no space between
the bottom of the viewport and the buttons, which is unpleasent.

short views would still createa large (high) body, for apparently no
reason.
2024-11-01 23:56:48 +01:00
Bernhard Kirchen
08f4d623c7 webapp: optimize look of login page
improve spacing and align login buton to the right, where all our
buttons are.
2024-11-01 23:55:25 +01:00
Bernhard Kirchen
f85297d52f webapp: inverter advanced tab needs space at the top
this avoids the input text box from colliding with the tab navigation
bottom border.
2024-11-01 23:54:39 +01:00
Bernhard Kirchen
e724fb8375 webapp: optimize look of firmware update cards 2024-11-01 23:53:24 +01:00
Bernhard Kirchen
54b4a2e9e8 webapp: properly space alert with hint for hostname 2024-11-01 23:50:28 +01:00
Bernhard Kirchen
94cecc23f5 webapp: avoid inline style for inverter channel info value 2024-11-01 23:46:35 +01:00
Bernhard Kirchen
866b539757 webapp: MQTT: no login with cert if TLS disabled
in the settings view we hide the "login with cert" setting while TLS is
disabled, so we should also hide that info in the info view when TLS is
disabled.
2024-11-01 23:46:01 +01:00
Bernhard Kirchen
9132a88963 webapp: MQTT: use v-if in favor of v-show
if we hide elements (which is done using style="display:none;"), they
are still part of the DOM and mess with CSS rules that shall apply to
the last element of a card or the last row of a table.
2024-11-01 23:44:35 +01:00
Bernhard Kirchen
eecd7f7c28 webapp: optimize spacing on bottom of cards
if the last child in a card (div.card > div.card-body) adds bottom
marging, we don't want the card to add more space through its
padding-bottom. most cards have children that add sufficient space
at the bottom anyways.
2024-11-01 23:43:51 +01:00
Bernhard Kirchen
ba304b2871 webapp: fix inverter "add" and "save order" button positions
the source tells us that the buttons are supposed to be on the right of
tha card, but the CSS broke at some point.
2024-11-01 23:42:56 +01:00
Bernhard Kirchen
0832d3e18c webapp: beautify radio statistics reset button
it would be nice to have this in the header of the accordion, which is
hard, but doable. however, clicking the button then also toggles the
accordion, which is unacceptable. preventing that seems non-trivial, as
the @click.stop() is not enough. also, nesting interactive elements is
simply bad practice. the button can also go to the right of header, with
reasonable effort, but the corner radii are then messed up and would
need to react interactively (accordion collapsed or not), which is also
a pain.

we now "float" the reset button to the right, add a nice icon, and give
the button some space so it at least looks like it belongs there.
2024-11-01 23:42:04 +01:00
Bernhard Kirchen
3c188f2f9f webapp: adjust look of tables in accordions to live view cards
this is relevant for the radio statistics table, as well as the tables
in the grid profile modal.
2024-11-01 23:40:52 +01:00
Bernhard Kirchen
68d2f7bf29 webapp: apply card-table class to info view cards
the cards in all information views still used a div.card-body around the
table, which added a margin on all sides of the table. to achieve a
unified look, these cards and tables now look the same as the inverter
channel cards.
2024-11-01 23:39:54 +01:00
Bernhard Kirchen
ad73fd8abd webapp: align table headers with card headers
set the left margin of table header cells to the same marging the card
header use, such that the text align on the same axis.
2024-11-01 23:39:00 +01:00
Bernhard Kirchen
e6a994fd7a webapp: use reasonable name for radio stats accordion 2024-11-01 23:38:29 +01:00
Bernhard Kirchen
d324a5c83f webapp: equalize style of cards with tables in live view
this change adjusts the style of cards showing tables such that they
look the same as inverter channel info tables.
2024-11-01 23:37:49 +01:00
Bernhard Kirchen
0aba1595df webapp: avoid inline style in inverter channel info card 2024-11-01 23:37:03 +01:00
Bernhard Kirchen
376912d821 webapp: add gap between inverter selectors 2024-11-01 23:36:17 +01:00
Bernhard Kirchen
d3eabc3311 webapp: remove table's bottom margin
we don't need a margin at the bottom of tables in general. not sure why
this is even a thing in bootstrap. this change, in particular, makes the
space between a table and a parent card symmetric on all sides.
2024-11-01 23:35:34 +01:00
Bernhard Kirchen
d06ea51c7a webapp: last table row shall have no bottom border
similar to the first row which has no border at the top.
2024-11-01 23:34:41 +01:00
Bernhard Kirchen
c750defc5f webapp: right-align labels for inputs on non-sm viewports
this change tries to achieve a pleasing look of input forms by
right-aligning the texts of labels. the input form now looks similar
to a table, achieving a cleaner look, especially for forms where the
labels have varying text lenghts.
2024-11-01 23:33:48 +01:00
Thomas Basler
130d90ce04 Merge branch 'pr2328' into dev 2024-11-01 22:12:41 +01:00
Thomas Basler
55c98ef880 Fix: skip BOM in JSON files (pin_mapping and config)
based on #2387
2024-11-01 22:07:48 +01:00
Thomas Basler
6c903abda1 Fix: Lint Error 2024-11-01 22:01:30 +01:00
Thomas Basler
28788070b2 Upgrade ESPAsyncWebServer from 3.3.17 to 3.3.21 2024-11-01 21:56:41 +01:00
Thomas Basler
0fc1ffc4d3 webapp: Update dependencies 2024-11-01 21:52:55 +01:00
Thomas Basler
8019eaf182 Feature: Validate JSON before uploading 2024-11-01 21:52:13 +01:00
Thomas Basler
225cab676a Fix: Take DST into account when recalculating the sunrise sunset time
If it is not considered the correct sunset / sunrise time is only calculated at the next day

Fixes: #2377
2024-10-27 14:03:44 +01:00
Thomas Basler
4594bcb23e Feature: Added device info for HMS-700 2024-10-26 14:51:03 +02:00
Thomas Basler
b21e8f8c80 Added README.md to lang folder 2024-10-25 23:04:14 +02:00
Thomas Basler
8566b08723 Feature: Added italian display translation 2024-10-25 22:42:47 +02:00
Thomas Basler
8452a8d110 Feature: Added spanish display translation 2024-10-25 22:39:25 +02:00
Thomas Basler
70f301941b Feature: Implement language pack support for display texts 2024-10-25 22:38:55 +02:00
Thomas Basler
d259042542 Rewrite display language handling to work with locale strings instead of magic numbers.
This is required to implement further i18n functions using the language packs
2024-10-25 21:43:29 +02:00
Thomas Basler
6113e0737b webapp: Fix: WaitRetstartView showed basic auth dialog 2024-10-25 21:42:52 +02:00
Bernhard Kirchen
b1edb13b3c add and use configuration write guard
the configuration write guard is now required when the configuration
struct shall be mutated. the write guards locks multiple writers against
each other and also, more importantly, makes the writes synchronous to
the main loop. all code running in the main loop can now be sure that
(1) reads from the configuration struct are non-preemtive and (2) the
configuration struct as a whole is in a consistent state when reading
from it.

NOTE that acquiring a write guard from within the main loop's task will
immediately cause a deadlock and the watchdog will trigger a reset. if
writing from inside the main loop should ever become necessary, the
write guard must be updated to only lock the mutex but not wait for a
signal.
2024-10-22 20:39:23 +02:00
Thomas Basler
2a21e53422 webapp: Rename interface to prevent lint errors 2024-10-21 22:41:52 +02:00
Thomas Basler
521fce35e4 webapp: Added global reboot wait screen 2024-10-21 21:59:38 +02:00
Thomas Basler
2e23c7e0ae Check if language pack metadata are valid 2024-10-21 20:15:56 +02:00
Thomas Basler
68c87c9217 Move lookup for translation path to separate method 2024-10-21 20:15:56 +02:00
Thomas Basler
4a247f5e94 Feature: Added italian language pack 2024-10-21 20:15:56 +02:00
Thomas Basler
05006e0642 Feature: Added spanish language pack 2024-10-21 20:15:56 +02:00
Thomas Basler
d9a8461a2e Feature: Allow custom language pack for webapp 2024-10-21 20:15:56 +02:00
Thomas Basler
c3d3d947d7 webapp: Allow upload of language packs 2024-10-21 19:02:50 +02:00
Thomas Basler
e29b86e4dc Add API endpoint to retrieve custom languages and complete language pack 2024-10-21 19:02:50 +02:00
Thomas Basler
8257eb7aa2 webapp: Use global AlertResponse interface 2024-10-19 17:39:12 +02:00
Thomas Basler
1e857b79c1 Feature: Refactor config management interface 2024-10-19 17:35:19 +02:00
Thomas Basler
16901482d9 Refactor file handling API and add endpoint to delete files 2024-10-19 12:40:43 +02:00
Thomas Basler
aa9f36ee8f Rename config API to file API 2024-10-19 11:07:15 +02:00
Thomas Basler
cf1693e1a0 Upgrade ESPAsyncWebServer from 3.3.16 to 3.3.17 2024-10-16 21:25:29 +02:00
Thomas Basler
e5cf12cebd Update nrf24/RF24 from 1.4.9 to 1.4.10 2024-10-16 21:24:01 +02:00
Thomas Basler
bcf4b70dc9 Fix: cpplint errors 2024-10-15 19:11:17 +02:00
Thomas Basler
dc5eb96f50 webapp: add app.js.gz 2024-10-15 18:22:57 +02:00
Thomas Basler
507e86d3b6 Upgrade ESPAsyncWebServer from 3.3.15 to 3.3.16 2024-10-15 18:12:41 +02:00
Thomas Basler
1900d78122 webapp: Update dependencies 2024-10-15 18:11:31 +02:00
Thomas Basler
b2522961cd Upgrade olikraus/U8g2 from 2.35.30 to 2.36.2 2024-10-14 19:46:17 +02:00
Thomas Basler
499f872641 Upgrade ESPAsyncWebServer from 3.3.14 to 3.3.15 2024-10-14 19:42:33 +02:00
Thomas Basler
fcf401d20a Upgrade ESPAsyncWebServer from 3.3.13 to 3.3.14 2024-10-13 12:33:12 +02:00
Thomas Basler
0468ccc34a webapp: Update dependencies 2024-10-12 21:38:07 +02:00
Thomas Basler
f8ad1acca9 Fix: Correct output of wifi disconnect reason code 2024-10-12 21:22:02 +02:00
Thomas Basler
36f0ed9ff8 Upgrade ESPAsyncWebServer from 3.3.12 to 3.3.13 2024-10-12 21:21:39 +02:00
Thomas Basler
ecef32a58e Merge branch 'pr2344' into dev 2024-10-12 13:13:24 +02:00
LennartF22
9ee947e9b0 Hotfix to not use DMA on SPI3 of ESP32-S2
See issue #2343.
2024-10-10 02:06:51 +02:00
Thomas Basler
e533320d92 Merge branch 'pr2115' into dev 2024-10-09 18:38:16 +02:00
Thomas Basler
4e293d4b93 Merge branch 'pr2340' into dev 2024-10-09 18:37:06 +02:00
Bernhard Kirchen
096a1ba3a0 Feature: show task details in system info view
shows whether or not known tasks are alive, and in particular shows how
much of the respective stack is still available.
2024-10-09 18:31:06 +02:00
LennartF22
6297ae3428 Don't set TX timeout to 0 anymore for HW/USB CDC
Due to a change in the Espressif Arduino core, the TX timeout for the HW CDC
(used in the ESP32-S3, for example) must not be set to 0, as otherwise, an
integer underflow occurs.

Removing the TX timeout is not necessary anymore anyways, because it is now
detected when CDC is not active, and attempts to write will return immediately
until the host read something again. Only when the transmit buffer becomes
full initially, the default timeout of just 100ms takes effect once.

For USB CDC (used with the ESP32-S2, for example), the timeout is not relevant
either.
2024-10-09 02:36:37 +02:00
Thomas Basler
e3b66f7ffe webapp: Update dependencies 2024-10-08 18:15:03 +02:00
Bernhard Kirchen
da9fb13079 webapp: pin assignment: hide unsupported pins
if the pin_mapping.json includes unsupported pins, e.g., `eth` pins on
an ESP32-S3, the whole category should still be hidden in the device
manager.
2024-10-06 22:37:05 +02:00
Thomas Basler
b7f830f64e webapp: add app.js.gz 2024-10-06 18:43:06 +02:00
Thomas Basler
90ea73b2ba Upgrade ESPAsyncWebServer from 3.3.11 to 3.3.12 2024-10-06 18:40:36 +02:00
Thomas Basler
eaa2f07cf3 Merge branch 'pr2333' into dev 2024-10-06 11:46:00 +02:00
Thomas Basler
b5ca2cfd21 Fix: "Equal brightness" in LED settings does not work correctly
fixes: #2332
2024-10-06 11:39:09 +02:00
Thomas Basler
2659204d96 Initialize the last rssi value with -127 instead of 0 to indicate a non existing connection of no data was received yet 2024-10-06 11:08:10 +02:00
LennartF22
6d048ae01d Remove EMAC related code for devices that don't have one 2024-10-06 03:08:58 +02:00
CommanderRedYT
d3d96b51ce
webapp: Fix eslint issues 2024-10-05 23:33:23 +02:00
Thomas Basler
4cd5d79c73 webapp: add app.js.gz 2024-10-05 22:14:14 +02:00
Thomas Basler
2c10e2510b webapp: Update dependencies 2024-10-05 22:12:49 +02:00
Thomas Basler
8f4b89a193 Replace format strings by platform independent macros 2024-10-05 00:50:13 +02:00
Thomas Basler
7dac96810f Rename NetworkEventCbList_t to DtuNetworkEventCbList_t for further upgrades 2024-10-04 23:02:12 +02:00
Thomas Basler
10b97fabb4 webapp: Update dependencies 2024-10-04 18:59:01 +02:00
Thomas Basler
d5abdc6d74 Upgrade ESPAsyncWebServer from 3.3.7 to 3.3.11 2024-10-04 18:44:23 +02:00
Thomas Basler
edfe06e31e Feature: Show RSSI of last received packet in radio stats
The value is also published via MQTT
2024-10-04 17:36:17 +02:00
janrombold
d0b2b972e2
Update UpgradePartition.md
Fixed typo
2024-10-04 00:19:26 +02:00
Thomas Basler
0c2b6f1a61 Fix: Add state_class to several Home Assistant sensors
state_class was added to yieldtotal, yieldday ac power and temperature for the whole dtu

closes: #2324
2024-10-02 18:13:12 +02:00
Thomas Basler
68793001a2 Merge branch 'pr2323' into dev 2024-10-02 11:50:43 +02:00
Thomas Basler
5040636aa2 Merge branch 'pr2322' into dev 2024-10-02 11:50:08 +02:00
mbo18
9df3e30bb2
Remove unused DEVICE_CLASS_TEMP 2024-10-02 11:02:52 +02:00
mbo18
38b5807ef7
Remove icon because device_class is set 2024-10-02 10:44:43 +02:00
Thomas Basler
2234ac9703 Upgrade ESPAsyncWebServer from 3.3.1 to 3.3.7 2024-10-02 10:32:58 +02:00
Thomas Basler
99a37fe01c webapp: Update dependencies 2024-09-30 18:47:41 +02:00
Thomas Basler
aa5087cc8a Merge branch 'pr2320' into dev 2024-09-30 16:02:58 +02:00
Bernhard Kirchen
d5d1a9982f Fix: force websocket clients to authenticate
when changing the security settings (disabling read-only access or
changing the password), existing websocket connections are now closed,
forcing the respective clients to authenticate (with the new password).
otherwise, existing websocket clients keep connected even though the
security settings now expect authentication with a (changed) password.
2024-09-30 15:54:55 +02:00
Bernhard Kirchen
ebb225f6c0 Fix: avoid deprecated setAuthentication() to fix memory exhaustion
with ESPAsyncWebServer 3.3.0, the setAuthentication() method became
deprecated and a replacement method was provided which acts as a shim
and uses the new middleware-based approach to setup authentication. in
order to eventually apply a changed "read-only access allowed" setting,
the setAuthentication() method was called periodically. the shim
implementation each time allocates a new AuthenticationMiddleware and
adds it to the chain of middlewares, eventually exhausting the memory.

we now use the new middleware-based approach ourselves and only add the
respective AuthenticatonMiddleware instance once to the respective
websocket server instance.

a regression where enabling unauthenticated read-only access is not
applied until reboot is also fixed. all the AuthenticationMiddleware
instances were never removed from the chain of middlewares when calling
setAuthentication("", "").
2024-09-30 15:16:30 +02:00
Thomas Basler
3a7295c341 Merge branch 'pr2311' into dev 2024-09-28 10:45:09 +02:00
LennartF22
69d2727106 Add device profiles for OpenDTU Fusion v2 PoE with displays 2024-09-28 02:42:31 +02:00
LennartF22
cafdb305a3 Adjust name of OpenDTU Fusion v2 PoE build environment 2024-09-28 02:37:09 +02:00
LennartF22
b05975b97c Prevent warning on GPIO ISR service registration 2024-09-28 02:26:40 +02:00
LennartF22
251bb7bd89 Add connection check for W5500 before full initialization 2024-09-28 02:26:36 +02:00
Bernhard Kirchen
6f9ded5f20 issue template: fix typo 2024-09-28 02:02:44 +02:00
Thomas Basler
b206cee820 webapp: add app.js.gz 2024-09-28 00:52:28 +02:00
Thomas Basler
759f899620 webapp: Update dependencies 2024-09-28 00:50:57 +02:00
Thomas Basler
d758a347eb Update espressif32 from 6.8.1 to 6.9.0 2024-09-27 19:36:52 +02:00
Thomas Basler
0fcf6061c1 Added required include to work with IDF 5 2024-09-27 18:30:44 +02:00
Thomas Basler
8b05bd22b5 Take care of different signature of ETH.begin method in Arduino Core 3.x 2024-09-27 18:27:26 +02:00
Thomas Basler
b85e0ab574 Add default values for ethernet pins in case they are not defined for a specific board 2024-09-27 17:35:33 +02:00
Thomas Basler
b43383007a Rename NetworkEventCb to DtuNetworkEventCb to prevent further upgrade issues 2024-09-27 17:32:28 +02:00
vaterlangen
d770566aec increase chunkSizeWarningLimit for webapp build (#1287)
increase from 500k (default) to 1024k in order to get rid of the warning messages.
2024-09-26 21:31:53 +02:00
Thomas Basler
12b9542f72 Added device profile for OpenDTU Fusion v2 PoE 2024-09-26 20:15:19 +02:00
Thomas Basler
a18e298cdd Apply automatic code formatting 2024-09-26 19:22:30 +02:00
Thomas Basler
7746d01fc0 Apply license headers and automatic code formatting to SpiManager 2024-09-26 18:47:27 +02:00
Thomas Basler
326525c961 Merge branch 'pr2306' into dev 2024-09-26 18:34:07 +02:00
Thomas Basler
355900743d webapp: add app.js.gz 2024-09-26 18:21:16 +02:00
Thomas Basler
818fdc42c9 Simplify inverter handling 2024-09-26 18:17:11 +02:00
Thomas Basler
595b153bbf Simplify network callback handling 2024-09-26 18:08:48 +02:00
Thomas Basler
cc7145361e webapp: Update dependencies 2024-09-26 18:01:59 +02:00
Thomas Basler
8db267b21a webapp: Apply auto format 2024-09-26 18:00:30 +02:00
Thomas Basler
8e26ef4e2e Fix: Only count RF RX packets when packets where sent
This mainly occours after a reset of  the statistics that receive count is higher then transmit count
2024-09-26 17:45:34 +02:00
Thomas Basler
67cae68e83 GitHub Build Action: Automatically generate littlefs image
If a data directory exists, the content of this directory will be placed in the littlefs image and embedded into the factory.bin file
2024-09-26 17:43:07 +02:00
Thomas Basler
468cbad4f3 Upgrade github actions/checkout to v4 2024-09-25 21:53:30 +02:00
Thomas Basler
d69a43373e Slight adjustments to github bug_report template 2024-09-25 21:49:38 +02:00
Thomas Basler
155735c828 Embed current branch into building process 2024-09-25 21:46:38 +02:00
Thomas Basler
0847f021f1 webapp: Update dependencies 2024-09-25 20:21:24 +02:00
Thomas Basler
9b565596d5 Feature: Allow reset of radio statistics via WebApp 2024-09-25 20:18:36 +02:00
LennartF22
31cf756a7e Only use a single SPI device for CMT 2024-09-25 00:37:06 +02:00
LennartF22
36da830f96 Use shared SPI bus for CMT and W5500 2024-09-25 00:37:06 +02:00
LennartF22
5457db269c Use SpiManager for nRF, CMT and W5500 2024-09-25 00:37:06 +02:00
LennartF22
ece4520687 Add Arduino SPI translation 2024-09-25 00:37:06 +02:00
LennartF22
1a583e765d Change cmt_spi3 implementation from C to C++ 2024-09-25 00:37:06 +02:00
LennartF22
4364daf54c Optimize CMT FIFO access 2024-09-25 00:37:06 +02:00
LennartF22
9b9c1e29f1 Add SpiManager library 2024-09-25 00:37:06 +02:00
LennartF22
851190dbcc Implement W5500 support 2024-09-25 00:37:03 +02:00
LennartF22
992e174bb2 Remove unnecessary delays 2024-09-25 00:31:05 +02:00
LennartF22
ec47e8978f Fix cs_ena_posttrans calculation 2024-09-25 00:31:05 +02:00
LennartF22
a02ad8b52c Remove unnecessary CMT SPI inversions 2024-09-25 00:31:05 +02:00
Thomas Basler
d3903d8602 MQTT Hass: Implement method to add common metadata to json output 2024-09-24 23:23:08 +02:00
Thomas Basler
2230850201 MQTT Hass: Implement device class as enum instead of String 2024-09-24 22:55:18 +02:00
Thomas Basler
bb4be0bbf7 MQTT Hass: Implement category as enum instead of String 2024-09-24 22:38:52 +02:00
Thomas Basler
2fb026074a Feature: Publish YieldTotal, YieldDay and Power of all inverters to Home Assistant 2024-09-24 22:16:17 +02:00
Thomas Basler
01e43777d2 MQTT Hass: Append dtu prefix topic for each single sensor 2024-09-24 22:04:07 +02:00
Thomas Basler
2213ad7bce MQTT Hass: Move serialization and allocation check into own method 2024-09-24 21:47:56 +02:00
Thomas Basler
9a318d5170 MQTT Hass: Reorder defines 2024-09-24 20:47:43 +02:00
Thomas Basler
c699f1b487 MQTT Hass: Add device_type and category to publishInverterBinarySensor 2024-09-24 20:45:55 +02:00
Thomas Basler
ac5a960581 MQTT Hass: Move yield into the publish method 2024-09-24 20:42:38 +02:00
Thomas Basler
239a77198d MQTT Hass: Move publishSensor logic into separate method 2024-09-24 20:38:12 +02:00
Thomas Basler
e5ca0ab784 MQTT Hass: Reorder binary sensor methods 2024-09-24 20:06:45 +02:00
Thomas Basler
f46a5017c7 MQTT Hass: Move publishBinarySensor logic into separate method 2024-09-24 20:03:42 +02:00
Thomas Basler
27910042ea MQTT Hass: Remove no more required checks 2024-09-24 19:47:23 +02:00
Thomas Basler
d899ea7364 MQTT Hass: Harmonise parameter names 2024-09-24 19:44:58 +02:00
Thomas Basler
7aca72b8fd MQTT Hass: Change parameter order for publishInverterNumber 2024-09-24 19:39:14 +02:00
Thomas Basler
483c10785b MQTT Hass: Change parameter order for publishInverterButton 2024-09-24 19:30:21 +02:00
Thomas Basler
a7100f238b MQTT Hass: Change parameter order for publishDtuBinarySensor 2024-09-24 19:23:04 +02:00
Thomas Basler
57c5b8c97e MQTT Hass: Make publish methods static 2024-09-24 19:22:05 +02:00
Thomas Basler
1c3e7de390 MQTT Hass: Change parameter order for publishDtuSensor 2024-09-24 19:21:06 +02:00
Thomas Basler
96e83f3d37 MQTT Hass: Change parameter order for publishInverterSensor 2024-09-24 19:18:56 +02:00
Thomas Basler
8e68632ed9 MQTT Hass: Rename caption parameter to name 2024-09-24 18:17:42 +02:00
Thomas Basler
8de1f7e70f MQTT Hass: Change char* to String& 2024-09-24 18:15:38 +02:00
Thomas Basler
bef81eed45 Feature: Publish Radio statistics to home assistant 2024-09-23 23:13:23 +02:00
Thomas Basler
181802a76b Feature: Allow reset of radio statistics via mqtt 2024-09-23 22:46:23 +02:00
Thomas Basler
0c012bf62a Move inverter housekeeping tasks inside the InverterAbstract class 2024-09-23 22:08:53 +02:00
Thomas Basler
93b6e5a885 Optimize MQTT subscription handling 2024-09-23 21:59:43 +02:00
Thomas Basler
d6a5fef4e7 Decrease restart delay to 1 second
This prevents a reload of the webapp (during firmware update) before the esp is online again
2024-09-23 18:33:01 +02:00
Thomas Basler
00584a0787 webapp: add app.js.gz 2024-09-23 18:25:49 +02:00
Thomas Basler
e29ac4f171 webapp: Fix data type for all range inputs 2024-09-23 18:24:22 +02:00
Thomas Basler
e37baedddb webapp: Update dependencies 2024-09-23 18:16:05 +02:00
Thomas Basler
e785904fca Fix: Restart was triggered before all website data was sent
This led to the effect that e.g. the confirmation messages where  not shown.

It is somehow related to ESPAsyncWebServer 3.3.0
2024-09-23 18:11:52 +02:00
Thomas Basler
5c460e26c9 Fix: Unable to CMT transmit power in WebApp
The pa_level was sent as string instead of a number.

fixes #2299
2024-09-23 17:57:29 +02:00
Thomas Basler
a3bd6dd7fb webapp: add app.js.gz 2024-09-22 19:01:43 +02:00
Thomas Basler
c4efda2e0c Added icon to radio statistics 2024-09-22 18:51:07 +02:00
Thomas Basler
a54b19bf5b Feature: Inverter radio statistics (rx/tx statistics)
The  statistics are shown in the WebApp and published via MQTT.
Statistics are reset at midnight.
2024-09-22 18:51:07 +02:00
Thomas Basler
1115418ce1 Publish temperature only if its not NAN 2024-09-22 18:51:07 +02:00
Thomas Basler
84e5c0821c Fix: Saving DTU config values just returned "Values are missing" 2024-09-22 13:16:34 +02:00
Thomas Basler
0c5e702a28 Fix: Wrong topic in home assistant auto discovery for maxalloc and minfree 2024-09-22 13:01:34 +02:00
Thomas Basler
a1fddb4ac1 Merge branch 'pr2293' into dev 2024-09-22 12:52:06 +02:00
Tobias Diedrich
fdcbf9de95 Publish ESP heap and temperature details on MQTT
I noticed that some useful ESP stats are missing on the MQTT feed, so this adds:

- ESP temperature
- ESP heap stats (size, free, minFree, maxAlloc)
2024-09-21 22:39:48 +02:00
Thomas Basler
175e5752fe Github Action: Update node version from 20 to 22 2024-09-21 20:30:42 +02:00
Thomas Basler
98f4aedbfb webapp: add app.js.gz 2024-09-21 19:09:32 +02:00
Thomas Basler
2f41f43d49 Update bblanchon/ArduinoJson from 7.1.0 to 7.2.0 2024-09-21 00:12:15 +02:00
Thomas Basler
3b3e6995c2 Fix: WebApp was not reloaded after firmware update
With the upgrade from ESPAsyncWebServer to 3.3.1 it seems that something has changed. Have to trigger the reboot from the main context.
2024-09-21 00:04:27 +02:00
Thomas Basler
34e1c43ca7 webapp: Fix html error in eventlog 2024-09-20 23:08:08 +02:00
Bernhard Kirchen
43394bc1bc actions: enable corepack to use fixed version of yarn
this allows us to fix the version of yarn, the Node.js package manager,
to a particular version. using corepack is the recommended way to use
yarn these days.
2024-09-20 22:30:46 +02:00
Thomas Basler
a204263fb2 webapp: add app.js.gz 2024-09-20 22:14:41 +02:00
Thomas Basler
0fec55a659 webapp: Update dependencies 2024-09-20 22:13:46 +02:00
Thomas Basler
e9b5f3eac7 Upgrade olikraus/U8g2 from 2.35.27 to 2.35.30 2024-09-20 22:09:23 +02:00
Thomas Basler
0b59a662df Doc: Remove inverter list and add a link to the documentation
This reduces redundant effort when a inverter is added.
2024-09-20 21:36:18 +02:00
Bernhard Kirchen
304b898ddc changelogs: group webapp-related changes 2024-09-20 21:12:08 +02:00
Bernhard Kirchen
1fd09d527a actions: fix a typo 2024-09-20 21:11:44 +02:00
Bernhard Kirchen
bd22f00539 actions: run yarn prettier to check web app formatting 2024-09-20 21:11:18 +02:00
Bernhard Kirchen
2f77b9e500 actions: switch to node version 20 for linting
use version consistent with the version used when building the web
application.
2024-09-20 21:10:18 +02:00
Bernhard Kirchen
ee3b62d671 actions: use setup-node@v4 as v3 causes warning
the "Yarn Linting" action causes a warning to appear about a deprecated
Node version. switch to actions/setup-node@v4, which is already in use
by the action building the web app for the firmware, to avoid this
warning.
2024-09-20 21:09:50 +02:00
Bernhard Kirchen
00626b63f7 issue template: asks for firmware variant 2024-09-20 16:37:33 +02:00
Thomas Basler
e8b1e7a71c webapp: Parse version string event if update search is not allowed 2024-09-16 19:30:45 +02:00
Thomas Basler
d3d92e90e0 webapp: Upgrade tsconfig node18 to node22 2024-09-16 19:13:17 +02:00
Thomas Basler
3e3cf3cd64 webapp: Update dependencies 2024-09-16 19:04:26 +02:00
Thomas Basler
c2e50a9594 Upgrade olikraus/U8g2 from 2.35.21 to 2.35.27 2024-09-16 18:41:18 +02:00
Thomas Basler
5a1d4946fb Upgrade ESPAsyncWebServer from 3.2.0 to 3.3.1 2024-09-16 18:37:51 +02:00
Thomas Basler
a949776966 Feature: Add support for HERF 1 channel inverters 2024-09-02 20:44:26 +02:00
Thomas Basler
ac5b6f3097 webapp: update dependencies 2024-09-02 20:37:54 +02:00
Thomas Basler
e00d831103 Upgrade arkhipenko/TaskScheduler from git #testing to 3.8.5 2024-09-02 20:28:21 +02:00
Thomas Basler
8529cb0fca Upgrade olikraus/U8g2 from 2.35.19 to 2.35.21 2024-09-02 20:21:38 +02:00
Thomas Basler
7b60c92db9 Upgrade ESPAsyncWebServer from 3.1.2 to 3.2.0 2024-09-02 20:18:37 +02:00
Thomas Basler
b52cd31309 Output WiFi disconnect reason in console 2024-09-02 20:16:03 +02:00
Thomas Basler
1f3af949a0 Add serial prefix 1410 to HMS_2CH inverters
This is related to #2235 and fixes #2230
2024-08-28 21:25:15 +02:00
Thomas Basler
e4260d3370 webapp: Update dependencies 2024-08-17 11:34:26 +02:00
Thomas Basler
0cc55f3b87 webapp: update dependencies 2024-08-05 18:31:31 +02:00
Thomas Basler
0bb3fc8b94 Fixed documentation for webapp dev mode 2024-08-05 18:31:31 +02:00
Thomas Basler
e279cf5cec Added hint in issue template that HMS-xxxW inverters are not supported 2024-08-05 18:31:31 +02:00
Thomas Basler
cdaf10a92a Fix: Wifi reconnect issue introduced with #2117 and discussed in #2185 was fixed 2024-08-05 18:31:21 +02:00
Thomas Basler
e85001b2d2 webapp: add app.js.gz 2024-08-01 18:42:12 +02:00
Thomas Basler
eef0335d37 Update espressif32 from 6.7.0 to 6.8.1 2024-08-01 18:39:53 +02:00
Thomas Basler
931eafff18 Merge branch 'pr2109' into dev 2024-08-01 18:23:40 +02:00
Thomas Basler
7627db6c39 Update nrf24/RF24 from 1.4.8 to 1.4.9 2024-08-01 18:16:11 +02:00
Thomas Basler
1984eeeca3 Update bblanchon/ArduinoJson from 7.0.4 to 7.1.0 2024-08-01 18:13:46 +02:00
Thomas Basler
03137e15dd Upgrade ESPAsyncWebServer from 2.10.8 to 3.1.2 2024-08-01 18:11:39 +02:00
Thomas Basler
a17aa031dd webapp: update dependencies 2024-08-01 18:11:29 +02:00
Thomas Basler
70dacb5ea6 Merge branch 'pr2168' into dev 2024-08-01 17:53:53 +02:00
Thomas Basler
7e52003830 Merge branch 'pr2035' into dev 2024-07-05 22:01:27 +02:00
Thomas Basler
342642ec01 webapp: Apply auto formatter 2024-07-05 21:57:53 +02:00
Thomas Basler
d8316db20f webapp: Add Autoformatter 2024-07-05 21:32:26 +02:00
Thomas Basler
b4e4e3b04d webapp: update dependencies 2024-07-05 21:24:38 +02:00
Thomas Basler
45b7f45734 Merge branch 'pr2099' into dev 2024-07-05 21:17:06 +02:00
Thomas Basler
4fd0cabe29 Merge branch 'pr2117' into dev 2024-07-05 21:15:34 +02:00
Thomas Basler
d09be3a384 Feature: Add support for HMS-800-2T-LV inverters 2024-07-05 21:10:15 +02:00
Marc-Philip
5ee411fcc6
Update patch_apply.py 2024-07-01 06:53:10 +02:00
Marc-Philip
1d92d9ed08
fix comment 2024-06-30 20:46:12 +02:00
jstammi
1eab3ae773 Fix: explicitly disconnect prior connecting to wifi
to prevent from invalid association packets exchange
#618

(cherry picked from commit b6c320d481eb77b4f4e0407237917d2d897bfd9d)
2024-06-30 20:20:05 +02:00
Marc-Philip
fc1267fe55 massage file handling 2024-06-30 18:55:33 +02:00
Tobias Wohlfrom
faed3056dd Increase stack size for MQTT task due to SSL handshake 2024-06-30 10:35:31 +02:00
Thomas Basler
e541a885f5 webapp: add app.js.gz 2024-06-29 18:57:35 +02:00
Thomas Basler
4640ddfba0 Better handling of empty MQTT client id
If the configured client id is empty, the default value (auto generated) will be used
2024-06-29 11:05:04 +02:00
Thomas Basler
a667042977 webapp: Update dependencies 2024-06-29 00:33:49 +02:00
Thomas Basler
ba95f99e03 Feature: Allow custom MQTT Client ID 2024-06-29 00:28:21 +02:00
Thomas Basler
e4bbf55ea5 webapp: Check if temperature is set
It seems that some ESPs don't have a temperature sensor anymore
2024-06-29 00:08:57 +02:00
Thomas Basler
b9b2a19ac5 Fix: Remove not required semicolon 2024-06-29 00:08:27 +02:00
Florian Mösch
ca4c45fcf2 Update AlarmLogParser.cpp
added a few German translations
2024-06-24 17:22:30 +02:00
Marc-Philip
3d66b318ec
avoid using pkg_resources
This is deprecated in python 3.12.
Also, improve file handling
2024-06-10 22:31:15 +02:00
Thomas Basler
c144b68306 webapp: add app.js.gz 2024-06-10 21:45:56 +02:00
Thomas Basler
119b7b18e6 Upgrade ESP Async WebServer from 2.10.6 to 2.10.8 2024-06-10 21:44:33 +02:00
Thomas Basler
417df65b92 webapp: update dependencies 2024-06-10 21:40:55 +02:00
Thomas Basler
a2b568923c Upgrade ESP Async WebServer from 2.10.5 to 2.10.6 2024-06-09 14:54:03 +02:00
Thomas Basler
b5398a4297 Changed issue template to make clear that issues are bugs that affect all users 2024-06-08 12:39:04 +02:00
Thomas Basler
c960602c62 Upgrade ESP Async WebServer from 2.10.3 to 2.10.5 2024-06-08 11:16:06 +02:00
Thomas Basler
8ef28e27b4 webapp: update dependencies 2024-06-08 11:11:31 +02:00
nexulm
d940932d3c
Update wt32-eth01.json
SH1106 (I2C = Type3) support for joy-it 128x64 1,3" OLED SBC-OLED01.3 display added
2024-06-04 11:28:03 +02:00
Thomas Basler
b2515753c1 Upgrade ESP Async WebServer from 2.10.0 to 2.10.3 2024-06-02 14:13:32 +02:00
Thomas Basler
b1a8f04617 Fix: Wrong divider in gridprofile RVHF
Fixes #2021
The result may look wrong for some profiles (e.g. 502 Hz) but it seems to be correct as the Hoymiles parser also outputs 502 Hz. See #1606
2024-06-02 13:56:13 +02:00
Thomas Basler
ea54397cfc Merge branch 'pr2025' into dev 2024-06-02 13:44:32 +02:00
Bernhard Kirchen
7548fceb48 check FW bin file size when creating factory.bin 2024-06-02 13:28:10 +02:00
Thomas Basler
cffa7a2b2c Remove no more required async_tcp patch 2024-05-31 01:01:47 +02:00
Thomas Basler
b27a476507 Fix: Apply inverter settings only once and not for each channel 2024-05-31 00:56:15 +02:00
Thomas Basler
35aa835891 Merge branch 'pr2022' into dev 2024-05-31 00:52:28 +02:00
Stefan Oberhumer
8e8c463849 NFC: Includes list: Remove unneeded PinMapping.h 2024-05-31 00:30:15 +02:00
Thomas Basler
6e607f7f67 Feature: Add option to clear eventlog at midnight 2024-05-31 00:07:28 +02:00
Thomas Basler
3a4f70dc75 Added parser documentation 2024-05-30 23:27:29 +02:00
Thomas Basler
5af7e67de7 Upgrade ESP Async WebServer from 2.9.5 to 2.10.0 2024-05-30 00:11:57 +02:00
Thomas Basler
4fea9d81a8 Upgrade espMqttClient from 1.6.0 to 1.7.0 2024-05-30 00:08:55 +02:00
Thomas Basler
72492c267f webapp: Remove no more required locale 2024-05-30 00:05:14 +02:00
Thomas Basler
33bfde34b2 Added some missing names to grid profile parser 2024-05-29 22:48:27 +02:00
Thomas Basler
ea4e7b77f5 webapp: Remove duplicated code 2024-05-29 21:09:37 +02:00
Thomas Basler
df80953b5e Use correct units in hardware info 2024-05-28 23:38:43 +02:00
Thomas Basler
6ce474053e Feature: Show MCU temperature in system info 2024-05-28 23:24:08 +02:00
Thomas Basler
e211dd5be2 Add proper formatting for flashsize output 2024-05-28 21:37:20 +02:00
Thomas Basler
5761e9facf webapp: Locale update for "screensaver"
Fix #2010
2024-05-28 21:32:46 +02:00
Thomas Basler
24983acf17 Merge branch 'pr2015' into dev 2024-05-28 20:13:22 +02:00
Bernhard Kirchen
4972892d9a Feature: show ESP32 flash memory size in system info 2024-05-27 21:52:49 +02:00
Thomas Basler
49c2a51980 Merge branch 'pr1974' into dev 2024-05-20 20:32:13 +02:00
Thomas Basler
918c3449da Fix #2000: MQTT subscriptions where not updated if MQTT base was changed 2024-05-20 17:56:59 +02:00
Thomas Basler
90711ddd76 Code Refactoring: Use internal inverter instance in handleResponse method 2024-05-16 19:58:20 +02:00
Thomas Basler
6d6d62bb77 Code Refactoring: Use internal inverter instance in gotTimeout method 2024-05-16 19:55:01 +02:00
Thomas Basler
6a7bed0ecf Code Refactoring: Add inverter reference to each command
Instead of just adding the target_address to a command this patch adds a reference to the whole inverter instance
2024-05-16 19:54:09 +02:00
Thomas Basler
6358b1ebee Update espressif32 from 6.6.0 to 6.7.0 2024-05-15 18:10:10 +02:00
Stefan Schultheis, OE1SCS
a11cc82782
Typos de.json translation 2024-05-07 13:58:27 +02:00
Thomas Basler
1f1227fa10 webapp: add app.js.gz 2024-05-06 20:04:51 +02:00
Thomas Basler
d3b134fe90 Upgrade ESP Async WebServer from 2.9.4 to 2.9.5 2024-05-06 19:49:15 +02:00
Thomas Basler
f6e048b064 webapp: update dependencies 2024-05-06 19:40:36 +02:00
Thomas Basler
7d2fb3490e Fix #1960: Prometheus API return wrong information in function addPanelInfo 2024-05-04 22:24:40 +02:00
Thomas Basler
d5a24906fa Merge branch 'pr1920' into dev 2024-05-02 20:59:26 +02:00
Thomas Basler
c08969b782 Upgrade olikraus/U8g2 from 2.35.17 to 2.35.19 2024-04-29 23:26:01 +02:00
Thomas Basler
2cde219317 Upgrade build action to support node 20 2024-04-29 23:17:40 +02:00
Thomas Basler
69e257dc8e webapp: update dependencies 2024-04-29 22:54:26 +02:00
Thomas Basler
783a7b3868 Upgrade ESP Async WebServer from 2.9.3 to 2.9.4 and set ASYNC_TCP_QUEUE_SIZE to 128 for different Async TCP library 2024-04-29 22:51:54 +02:00
Thomas Basler
b704126453 Use fixed versions for all dependencies 2024-04-28 22:08:55 +02:00
Thomas Basler
4623839425 webapp: add app.js.gz 2024-04-24 22:34:39 +02:00
Thomas Basler
5a93a7e4b9 Updated timezone config 2024-04-24 22:33:37 +02:00
Thomas Basler
5ab4b6d38e webapp: update dependencies 2024-04-24 22:31:13 +02:00
Thomas Basler
29403013f5 Fix: Device Manager shows 404 if no pin_mapping.json was available 2024-04-24 22:28:59 +02:00
Thomas Basler
f8cc171e4a Fix: Return 404 (and nothing else) if file not found 2024-04-24 22:15:25 +02:00
Thomas Basler
21cadabd5d Upgrade olikraus/U8g2 from 2.35.15 to 2.35.17 2024-04-23 18:52:47 +02:00
Thomas Basler
c36369a83b Upgrade ESP Async WebServer from 2.9.0 to 2.9.3 2024-04-23 18:49:52 +02:00
Stefan Oberhumer
97800434c4 Prevent compiling the whole project on each commit.
Putting the git information into a generated sourcefile prevents
recompiling the whole project after each commit.
2024-04-18 09:02:57 +02:00
Thomas Basler
d0981934b0 webapp: add app.js.gz 2024-04-12 22:37:52 +02:00
Thomas Basler
68b1a9ee08 Remove no more required web server patch
By using the new ESPAsyncWebserver this patch is no more required as it is already included in the upstream repo
2024-04-12 20:53:36 +02:00
Thomas Basler
011f00e5de Fix: If unauthenticaed, the redirect to login page did not work 2024-04-12 20:38:28 +02:00
Thomas Basler
de156ef10a webapp: Fix lint errors 2024-04-12 20:34:30 +02:00
Thomas Basler
b58d08683e webapp: update dependencies 2024-04-12 20:02:18 +02:00
Thomas Basler
bf49410f6d Merge branch 'pr1909' into dev 2024-04-12 17:05:51 +02:00
Bernhard Kirchen
153293e1c7 remove remaining usage of F() macro 2024-04-12 15:28:26 +02:00
Thomas Basler
ea28903761 Move parsing of serial from web request to separate method 2024-04-05 19:14:56 +02:00
Thomas Basler
980e847ccb Feature: Check for out of memory situations when sending json responses
Also shows a nice message in the frontend if an internal error occours
2024-04-05 19:14:56 +02:00
Thomas Basler
2e3125fe8d Feature: Migrated ArduinoJson 6 to 7 2024-04-05 19:14:56 +02:00
Thomas Basler
e7a9c96b72 Upgrade ESP Async WebServer from 2.8.1 to 2.9.0 2024-04-03 23:11:30 +02:00
Thomas Basler
aa10c2c5e1 Fix: Too small event_queue_size in AsyncTCP lead to wdt reset
Fix #1705
2024-04-03 19:12:08 +02:00
Thomas Basler
b55ca53d1d Fix: Setting DTU options was only possible once without reboot
Fix #1884
2024-04-03 18:35:27 +02:00
Thomas Basler
d2d775d687 Update espressif32 from 6.5.0 to 6.6.0 2024-04-02 19:58:42 +02:00
Thomas Basler
718690030e Fix include for TimeoutHelper 2024-04-01 13:52:59 +02:00
Thomas Basler
8add226a7c Save flash: Move WebApi json parsing to separate method to prevent a lot of redundant code 2024-04-01 13:52:09 +02:00
Thomas Basler
58efd9e954 Move source files for ThreadSafeQueue to correct directories 2024-04-01 00:03:04 +02:00
Thomas Basler
6940418955 Move source files for TimeoutHelper to correct directories 2024-04-01 00:00:36 +02:00
Thomas Basler
12588655df webapp: add app.js.gz 2024-03-31 23:07:08 +02:00
Thomas Basler
bdff1e1ac3 Added github workflow to do some repository cleanup 2024-03-31 22:39:59 +02:00
Thomas Basler
f0a8cabc2c webapp: update dependencies 2024-03-31 14:31:57 +02:00
Thomas Basler
1888054627 Fix: Re-Request grid profile parameters if received data are invalid / to short
Fixes #1874
2024-03-31 12:42:00 +02:00
Thomas Basler
6f3b8fb8e1 Fix: Change default NTP server
Fixes #1877
2024-03-31 12:27:27 +02:00
Rene
eff8d52014 better alignment inverter, issue 360 2024-03-25 22:42:22 +01:00
Thomas Basler
3b05f447d5 webapp: add app.js.gz 2024-03-22 20:46:22 +01:00
Thomas Basler
326cb15a76 Upgrade olikraus/U8g2 from 2.35.14 to 2.35.15 2024-03-22 20:42:14 +01:00
Thomas Basler
bf4d128e49 webapp: update dependencies 2024-03-22 20:39:12 +01:00
Thomas Basler
3125f16d99 Fix: Previously check for HwPartNumber 124097 was implemented wrong
Fix: #1846
2024-03-21 20:00:34 +01:00
Thomas Basler
ed326763b7 webapp: update dependencies 2024-03-21 19:59:13 +01:00
Thomas Basler
f66b4fa5f1 webapp: add app.js.gz 2024-03-15 22:03:54 +01:00
Thomas Basler
7c60c37f49 webapp: update dependencies 2024-03-15 20:16:59 +01:00
Thomas Basler
77b38dff2b Fix: Updated source comments to also match hex numbers 2024-03-15 20:14:29 +01:00
Thomas Basler
dc04a63f7c Upgrade ESP Async WebServer from 2.7.0 to 2.8.1 2024-03-15 20:04:42 +01:00
Thomas Basler
cab38d3c84 Upgrade olikraus/U8g2 from 2.35.10 to 2.35.14 2024-03-15 19:57:28 +01:00
Thomas Basler
3138e28cdf webapp: Remove not required cast to string 2024-03-15 19:54:29 +01:00
Thomas Basler
a0d0aec677 Fix: Correct detection of Hoymiles serial if it contains hex characters 2024-03-15 19:46:24 +01:00
Thomas Basler
0b7258d50e Upgrade olikraus/U8g2 from 2.35.9 to 2.35.10 2024-03-14 20:12:24 +01:00
Thomas Basler
33bf2117c6 Fix: Set all settings to default when deleting an inverters
Previously some old settings from previous inverters could have been shown in a new inverter
2024-03-13 18:47:28 +01:00
Thomas Basler
437f572c39 Fix: Don't throw exception if git_hash is not set 2024-03-12 22:11:19 +01:00
Thomas Basler
bd8d93bf92 Feature: Allow enabling and disabling of the version check
Fix #1787
2024-03-12 18:35:19 +01:00
Thomas Basler
9634c93a3c Fix: Show firmware update tooltip only if newer version available
Closes #1796
2024-03-12 17:27:43 +01:00
Thomas Basler
57a997baac webapp: update dependencies 2024-03-12 16:42:29 +01:00
Thomas Basler
103207cead Merge branch 'dev-herf' into dev 2024-03-12 16:34:08 +01:00
Thomas Basler
2526d3dad6 Remove deprecated extension recommendation 2024-03-12 16:33:55 +01:00
Thomas Basler
f995287a6e Feature: Add support for HERF inverters 2024-03-06 21:57:18 +01:00
Thomas Basler
10cd2e4201 webapp: update dependencies 2024-03-04 21:07:01 +01:00
Thomas Basler
b8c1168687 Fix: Exclude hardware part number 124097 from valid part numbers.
This triggers a  re-fetch of the hardware information. Especially 124097 seems to be a wrong read-out.
2024-03-03 16:35:34 +01:00
Thomas Basler
3c2b35016a webapp: update dependencies 2024-03-01 19:36:18 +01:00
Thomas Basler
021d9b5f44 Feature: Added description for alarm id 152
Fixes: #1798
2024-03-01 19:31:47 +01:00
Thomas Basler
50abcd1061 Fix: Prevent hiding text on display if it's too long
Fixes: #1797
2024-03-01 19:30:24 +01:00
Thomas Basler
9b7df71da0 webapp: Fix typo
Fixes #1780
2024-02-25 11:23:49 +01:00
Thomas Basler
f80d03210b webapp: update dependencies 2024-02-19 15:47:59 +01:00
Thomas Basler
43c3c8d30c webapp: add app.js.gz 2024-02-16 19:23:40 +01:00
Thomas Basler
380879e077 webapp: update dependencies 2024-02-16 18:24:14 +01:00
Thomas Basler
bfc604db88 Added HMS-300 to DevInfoParser
Fix #1758
2024-02-16 18:15:50 +01:00
Thomas Basler
06e3498027 Merge branch 'pr1746' into dev 2024-02-16 18:14:47 +01:00
Thomas Basler
dfe82ff17e Added HMT-2000 to DevInfoParser
Fix #1752
2024-02-15 22:11:50 +01:00
Thomas Basler
03758ad35a Upgrade espMqttClient from 1.5.0 to 1.6.0 and ESPAsyncWebServer to a more maintained version 2024-02-15 20:58:53 +01:00
Hannes0009
a1cd1617e4
Update de.json
improved german orthography
2024-02-14 11:06:07 +01:00
Thomas Basler
c24a4ea41d Added second HMS-450 to DevInfoParser
Fix #1744
2024-02-13 16:42:08 +01:00
Thomas Basler
79e5c642eb Bump actions/setup-python from 4 to 5 2024-02-12 19:41:17 +01:00
Thomas Basler
c4702915a7 Bump actions/cache from 3 to 4 2024-02-12 18:52:07 +01:00
Thomas Basler
d22c783a6d Doc: Added hint regarding breaking changes 2024-02-12 18:27:05 +01:00
Thomas Basler
e8b4e25452 webapp: add app.js.gz 2024-02-12 18:20:10 +01:00
Thomas Basler
c97de9b690 webapp: update dependencies 2024-02-12 16:48:54 +01:00
Thomas Basler
d26333dd76 Apply automatic code formatting 2024-02-10 23:37:44 +01:00
Thomas Basler
1d2055cc89 Merge branch 'pr1732' into dev 2024-02-10 23:37:09 +01:00
Thomas Basler
1973cb986c Merge branch 'pr1731' into dev 2024-02-10 23:37:03 +01:00
Thomas Basler
d635a9babd Merge branch 'pr1729' into dev 2024-02-10 23:36:47 +01:00
Bernhard Kirchen
6036d8efea implement oscillating screensaver
this implementation avoids the display content jumping the full
screensaver offset from right to left when the modulo operator
wraps. this change makes the display content walk from right to
left as it did walk from left to right.
2024-02-10 18:41:47 +01:00
Bernhard Kirchen
5f51c80022 Fix: make text of total production fit displays
in case the total production is larger than 1 MWh, i.e., 1000 kWh, the
text on the respective line becomes too large such that it reaches out
of the display when the screensaver is enabled.

this happens on the small and large displays.

this change switches the number format to a float without decimal places
if the total production is larger or equal to 1000 kWh. this saves a dot
and a digit, making the text short enough to fit the display even when
the screensaver moved the display contents as far to the right as it
does.
2024-02-10 17:38:32 +01:00
Bernhard Kirchen
25a66a1722 make efficient use of available display area
fix calculation of the text baselines, using getAscent() in favor of
getMaxCharHeight(), which includes ascent and descent. this moves the
first text up and allows to insert margin between the lines until the
display area is fully utilized.

on large displays, if the small diagram is selected, keep the first line
rather low to avoid collision with the diagram y-axis label. in this mode,
there is still more space between the text lines as before, allowing for
improved readability.
2024-02-10 13:33:51 +01:00
Thomas Basler
b9bf454237 webapp: Add link to documentation in about view 2024-02-10 02:10:06 +01:00
Thomas Basler
5419135abf Merge branch 'pr1728' into dev 2024-02-08 22:54:01 +01:00
iiidefix
0fe942adce
Add AhoyDTU Pinout
Add AhoyDTU Pinout for easy testing and migration. 
Based on current Pinout as seen on https://ahoydtu.de/img/fritzing/esp32-38_nrf_ssd1306_sch.png
2024-02-08 19:28:10 +01:00
Thomas Basler
ac91a50ffe webapp: update dependencies 2024-02-07 19:29:09 +01:00
Thomas Basler
3cf8fea8e0 Fix: Guru Meditation (StoreProhibited) when saving DTU settings
Fixed #1725
2024-02-06 21:47:06 +01:00
Thomas Basler
8e01a275af Merge branch 'pr1693' into dev 2024-02-02 22:36:18 +01:00
Nikolaj Kappler
86b9625254 fix #1668
use builtin bootstrap css for scrolling
2024-02-02 22:34:58 +01:00
Thomas Basler
0ab5785b7d Feature: Added pin-mapping for LILYGO T-ETH-Lite 2024-02-02 21:42:21 +01:00
Thomas Basler
7e2064e264 Feature: Added support for boards with 16MB flash and PSRAM 2024-02-02 20:33:42 +01:00
Thomas Basler
e81a280b87 Fix: Calculate the AC current for 3 phase inverters correctly 2024-01-30 22:29:25 +01:00
Thomas Basler
abb37242e8 Rename internal variables and methods 2024-01-30 22:29:25 +01:00
Thomas Basler
1b637f0870 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
Yield total and Yield day where moved from the AC section to the INV section
2024-01-30 22:29:25 +01:00
Thomas Basler
e1564780d6 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
Power DC was moved from the AC section to the INV section
2024-01-30 22:29:25 +01:00
Thomas Basler
f0b5542c2d BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
Efficiency was moved from the AC section to the INV section
2024-01-30 22:29:25 +01:00
Thomas Basler
c27ecc3620 BREAKING CHANGE: Web API Endpoint /api/livedata/status
To reduce the heap usage it is necessary to send the inverters one by one instead of a huge response. A simple call to `/api/livedata/status` returns just some very general information. If detailed inverter information are required the inverter serial number has to appended `?inv=<serial number>`.
The websocket also returns only one inverter at a time. It as to be assembled at client side.
2024-01-30 22:29:25 +01:00
Thomas Basler
557c5d645e Remove all files but the pin_mapping.json from filesystem on factory reset
This allows to create more user defined files and get them deleted on factory reset.
2024-01-30 22:29:12 +01:00
Thomas Basler
48a722f826 Merge branch 'pr1642' into dev 2024-01-30 20:47:45 +01:00
Thomas Basler
a848275bb9 Merge branch 'pr1706' into dev 2024-01-30 19:34:19 +01:00
Sabouflage
5d7512e026 fix(mqtt): setting MQTT LWT online message for frontend 2024-01-30 19:03:23 +01:00
Sabouflage
dfed23261a fix(mqtt): MQTTs LWT QoS config used also for TLS connections 2024-01-30 19:02:57 +01:00
Stefan Oberhumer
e752c433af Use http header ETag caching for all static content.
Using the md5sum as ETag http header value should enable caching on all static http content.
2024-01-30 00:35:23 +01:00
vaterlangen
97f006d867 fixed typo in OTA text 2024-01-27 15:18:25 +01:00
Thomas Basler
2716f4c5df Removed not required pointer to AsyncServer instance 2024-01-27 01:09:55 +01:00
Thomas Basler
21ec72f4c0 webapp: add app.js.gz 2024-01-26 21:42:55 +01:00
Thomas Basler
59022347eb Doc: Remove deprecated documentation 2024-01-26 21:40:57 +01:00
Thomas Basler
2c4952b196 Doc: Migrated needed hardware info to official documentation 2024-01-26 21:30:58 +01:00
Thomas Basler
ac2e963799 Doc: Move display documentation to official documentation 2024-01-26 17:12:55 +01:00
Thomas Basler
c04407f740 Doc: Move partition migration to official documentation 2024-01-26 17:02:55 +01:00
Thomas Basler
fe9ac6a2fd webapp: update dependencies 2024-01-26 16:56:49 +01:00
Thomas Basler
f0061b976d Merge branch 'pr1676' into dev 2024-01-26 16:48:15 +01:00
Thomas Basler
4e669d8932 Feature: Add support for ST7567 GM12864I-59N Display 2024-01-26 16:05:56 +01:00
Stefan Oberhumer
7aece2e143 Call SunPosition.isDayPeriod() once 2024-01-23 09:42:13 +01:00
Thomas Basler
a5cc0a424f webapp: add app.js.gz 2024-01-21 16:49:41 +01:00
Thomas Basler
d99de94c00 webapp: Fix lint errors 2024-01-21 16:48:47 +01:00
Thomas Basler
3f135e8349 webapp: update dependencies 2024-01-21 16:39:22 +01:00
Thomas Basler
178525a49b Feature: Added device profile for Olimex ESP32 Gateway
Thanks to @fdcg in #1672
2024-01-21 11:32:18 +01:00
Thomas Basler
4cfb1b1c26 Fix: PullToRefresh does not work anymore
It was using the wrong mainElement
2024-01-21 00:55:05 +01:00
Thomas Basler
4f2fbaaf2a Remove unused function parameter 2024-01-20 23:12:59 +01:00
Thomas Basler
8a80289474 Feature: Implement firmware update check is a opt-in to protect your privacy 2024-01-20 22:43:40 +01:00
Thomas Basler
16fbad92ac simplify calculations in WebApi_ws_Live 2024-01-20 11:38:52 +01:00
Thomas Basler
7bc1a17fac Move task initialization from init method to constructor
This saves flash
2024-01-20 11:24:57 +01:00
Thomas Basler
251d197fb6 Migrate WebApi loop() methods to scheduler tasks 2024-01-20 02:00:22 +01:00
Thomas Basler
e66060e769 Move the conversation from time_t to String into DevInfoParser 2024-01-20 01:09:42 +01:00
Thomas Basler
dcc157261e Don't perform redundant conversions 2024-01-20 00:32:13 +01:00
Thomas Basler
9428eecce4 webapp: Use CardElement in InverterTotalInfo 2024-01-19 22:03:26 +01:00
Thomas Basler
a06d21024c webapp: Move interfaces to seperate file 2024-01-19 21:48:39 +01:00
Thomas Basler
6b31a4d470 webapp: Introduce Modal component
Less duplicated code
2024-01-19 21:36:18 +01:00
Thomas Basler
5d63f64411 webapp: Fix typo 2024-01-19 20:02:03 +01:00
Thomas Basler
0584eadcf2 Feature: Automatic page reload after firmware upgrade
This will work after the current upgrade if this code was loaded.
2024-01-19 19:10:49 +01:00
Thomas Basler
f7119bc3c7 webapp: Fix font-feature class 2024-01-19 17:20:57 +01:00
Thomas Basler
bdfdc3913b webapp: add app.js.gz 2024-01-18 21:23:28 +01:00
Thomas Basler
149444decb Fix: Gridprofile dump contained the whole buffer instead of the actual length
As a result, a lot of zeros where placed at the end of the dump
2024-01-18 21:21:40 +01:00
Thomas Basler
ce978cb0f5 webapp: update dependencies 2024-01-18 20:39:44 +01:00
Nikolaj Kappler
199351c703 webapp: Correctly center header text 2024-01-18 20:39:43 +01:00
Nikolaj Kappler
a7479d33e3 webapp: Reduce wasted horizontal space for better mobile UX 2024-01-18 20:39:43 +01:00
Nikolaj Kappler
41f3955429 webapp: Vertically center Header/Logo Text 2024-01-18 20:39:43 +01:00
Nikolaj Kappler
bfeb852e23 webapp: Remove redundant main container 2024-01-18 20:39:43 +01:00
Thomas Basler
72a2c58f1e Update bblanchon/ArduinoJson from 6.21.4 to 6.21.5 2024-01-18 20:39:43 +01:00
Nikolaj Kappler
caaa7b6347 fix count being a string 2024-01-18 20:39:43 +01:00
Nikolaj Kappler
f26e824247 fix #1649
one of the goals of my pull request, besides simplifying the code was to have localization.

It's nice that the browser can handle this, but for consistency, we'll go with vue-i18n since it is already available
2024-01-18 20:39:42 +01:00
Thomas Basler
6233ad12ae webapp: Prefix Country with CMT2300A 2024-01-18 20:39:28 +01:00
Thomas Basler
47417276a0 webapp: add app.js.gz 2024-01-14 17:15:12 +01:00
Thomas Basler
9093f9de79 Change default target frequency for US and BR 2024-01-14 17:09:53 +01:00
Thomas Basler
a1f2c93cf6 Added const keywords 2024-01-14 16:37:43 +01:00
Thomas Basler
18485ffefd webapp: update dependencies 2024-01-14 16:37:43 +01:00
Thomas Basler
c20caf8097 Feature: Support HMS/HMT inverters in different countries with different frequency bands
Thanks to @Fribur, @homeautomation2022 and @stefan123t
2024-01-14 16:37:34 +01:00
Thomas Basler
188c4688ab Distinct between Band and Country
This allows different frequencies (Startup/Default etc.) for the same band configuration.
2024-01-14 00:06:35 +01:00
Thomas Basler
6b44694a12 Added frequency and command definitions for the 900 MHz band (North America) 2024-01-13 15:29:17 +01:00
Thomas Basler
16cd1a90d5 Move HOY_BOOT_FREQ from define to function 2024-01-13 14:48:23 +01:00
Thomas Basler
58f0121c11 Create separate definition for the 860MHz band of the CMT2300A
This is required to support different countries in the future. The defines where moved to function to change the values dynamically
2024-01-13 14:48:23 +01:00
Thomas Basler
abc53f4257 Merge branch 'pr1639' into dev 2024-01-13 13:01:21 +01:00
Thomas Basler
2c92750100 webapp: Remove hard coded min/max frequencies for CMT module 2024-01-13 12:51:20 +01:00
Thomas Basler
ee78698e37 Migrate all frequency calculations to Hz
Previously the code contains calculations  using a mixture  of kHz and Hz.

Thanks to @Fribur
2024-01-13 12:51:20 +01:00
Thomas Basler
ce2109ab1b Rename define CMT_BASE_CH_OFFSET860 to CMT_BASE_CH_OFFSET 2024-01-13 11:40:30 +01:00
Thomas Basler
638f52a8da Feature: Add current limit to prometheus output
Fixes #1617
2024-01-13 11:33:58 +01:00
Thomas Basler
f013698471 Feature: Added fullscreen diagram to display 2024-01-13 11:31:12 +01:00
Nikolaj Kappler
6166ecdb7d refactor webapp/utils/time 2024-01-13 11:14:20 +01:00
Thomas Basler
637d4f06a3 Feature: Added option to disable the diagram at the display 2024-01-08 14:19:26 +01:00
Thomas Basler
265a44c517 Sort recommend extensions by name 2024-01-07 01:55:05 +01:00
Thomas Basler
9d8e195ce1 Merge branch 'pr1611' into dev 2024-01-07 01:53:43 +01:00
Thomas Basler
6556268056 Allow multiple patch directories per environment 2024-01-07 00:47:05 +01:00
Bernhard Kirchen
2608080708 Feature: add heap details to system info and prometheus (#595)
this change adds the values of ESP.gteMaxAllocHeap() and
ESP.getMinFreeHead() to the prometheus metrics and the system
information object. the web UI uses these values to diplay the size of
the largest free contiguous block, calculate a rough estimate for the
level of fragmentation, and the maximum usage of heap memory since boot
in absolute and relative amounts.
2024-01-06 20:12:35 +01:00
Thomas Basler
024ee26705 Feature: Added pull to refresh and websocket indicator 2024-01-06 20:03:52 +01:00
Thomas Basler
7b5d31efca Added .editorconfig 2024-01-05 17:26:02 +01:00
Thomas Basler
69cf63ed5e webapp: add app.js.gz 2024-01-04 23:02:13 +01:00
Thomas Basler
22e2d1bb54 webapp: update dependencies 2024-01-04 22:57:12 +01:00
Thomas Basler
3c37b61f44 Use auto keyword and references more often 2024-01-04 15:38:56 +01:00
Thomas Basler
b0b9764a23 Use Utils::checkJsonAlloc in ConfigurationClass 2024-01-04 14:47:21 +01:00
Thomas Basler
ef9f0040e8 Better handling of out of memory situations in live data websocket 2024-01-04 14:47:21 +01:00
Thomas Basler
ca18d2c841 Prevent empty HASS auto discovery topics if memory allocation fails 2024-01-04 14:09:58 +01:00
Thomas Basler
4053e31a5e Prevent config corruption by checking whether memory allocation was successfull. 2024-01-04 13:42:39 +01:00
Thomas Basler
c1fc907ecb Fix: Access Point not working after firmware update
Fixes #1613
2024-01-03 22:04:50 +01:00
Thomas Basler
cbbe053cd5 Fix: Optimize network connection handling
This should provide a more reliable connection to several AP types. See #576
2024-01-03 01:17:39 +01:00
Moritz Lerch
d62234ac65
webapp: add missing button spacing 2024-01-02 23:40:21 +01:00
Thomas Basler
892230b153 Merge branch 'pr1598' into dev 2023-12-31 20:23:36 +01:00
Thomas Basler
5285ddb954 Doc: Migrate most of documentation to the new URL 2023-12-31 19:45:54 +01:00
Thomas Basler
6e49451935 webapp: add app.js.gz 2023-12-31 19:36:58 +01:00
Thomas Basler
1ebd5620de webapp: update dependencies 2023-12-31 19:28:53 +01:00
Thomas Basler
798a6b74e9 Merge branch 'pr1602' into dev 2023-12-31 11:55:49 +01:00
Thomas Basler
8aa3fd0412 Added the SSD1309 display to several device profiles 2023-12-31 11:28:42 +01:00
Thomas Basler
aa8068370e Feature: Add support for SSD1309 2.4" Display 2023-12-30 12:42:42 +01:00
Bernhard Kirchen
03060e453c remove obsolete save button texts in french locale 2023-12-30 10:27:46 +01:00
Bernhard Kirchen
21936a8e1a Fix: define _TASK_THREAD_SAFE for TaskScheduler
the TaskScheduler runs in the context of a FreeRTOS thread/task. there
are other such threads (MQTT client and web server in particular). to
allow changing TaskScheduler task properties from different threads, we
need to enable the use of a mutex to protect the TaskScheduler.
2023-12-29 11:41:35 +01:00
Thomas Basler
4182e3a071 Upgrade olikraus/U8g2 from 2.35.8 to 2.35.9 2023-12-28 14:52:36 +01:00
Thomas Basler
92504875bf webapp: update dependencies 2023-12-28 14:08:27 +01:00
Thomas Basler
32fff131c8 Update espressif32 from 6.3.2 to 6.5.0 2023-12-28 14:06:34 +01:00
Thomas Basler
34983471de Simplfy diagram drawing code 2023-12-28 00:10:40 +01:00
Thomas Basler
5b39c1803e Feature: Added latest grid profile information from wiki 2023-12-26 12:52:21 +01:00
Thomas Basler
9dd24c9f87 webapp: update dependencies 2023-12-25 23:38:41 +01:00
Thomas Basler
1732d2c620 webapp: update dependencies 2023-12-24 15:08:29 +01:00
Thomas Basler
06b8fb65a1 Move the diagram in Y direction if screen saver mode is turned on 2023-12-24 15:08:10 +01:00
Thomas Basler
2259b1b525 Add const keyword to variable 2023-12-24 14:35:29 +01:00
Stefan Oberhumer
ac427523b5 Feature: Add screensavermode also to diagram drawing. 2023-12-24 12:24:10 +01:00
Stefan Oberhumer
733a566172 NFC: Use std::size() instead of define. 2023-12-24 12:13:57 +01:00
Stefan Oberhumer
c1f0b9ea6f http response header tag 'ETag' needs quotes.
As per RFC7232 ( https://www.rfc-editor.org/rfc/rfc7232#section-2.3 ) and
MDN docs ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives )
the value of the ETag in the http header response has to be between quotes.
2023-12-23 19:00:44 +01:00
Thomas Basler
6f09011961 webapp: add app.js.gz 2023-12-19 17:32:12 +01:00
Thomas Basler
25294a190a webapp: update dependencies 2023-12-19 17:28:39 +01:00
Thomas Basler
0ddc7fd28d Feature: Added diagram to display
This is based on the idea of @Henrik-Ingenieur and was discussed in #1504
2023-12-19 17:26:24 +01:00
Thomas Basler
3b923885de Fix #1579: Static IP in Ethernet mode did not work correctly 2023-12-19 11:30:33 +01:00
Thomas Basler
48a02e522f Correct variable name 2023-12-19 11:06:34 +01:00
Thomas Basler
0704c9682f Fix: Allow negative values in GridProfileParser 2023-12-19 11:05:57 +01:00
Thomas Basler
e9b113486b Fix: Reset Yield day correction in combination with Zero Yield Day on Midnight lead to wrong values. 2023-12-19 10:46:54 +01:00
Thomas Basler
677d822a3e Fix: yarn build error 2023-12-18 21:24:52 +01:00
Thomas Basler
5adabd32f5 Fix: yarn.lock was outdated 2023-12-18 21:11:45 +01:00
Thomas Basler
00e856701f webapp: add app.js.gz 2023-12-18 20:46:00 +01:00
Thomas Basler
8b551491a9 webapp: update dependencies 2023-12-18 15:01:32 +01:00
Thomas Basler
8798ca5a13 Fix: Offset cache for "YieldDay" did not work correctly 2023-12-18 12:14:11 +01:00
Thomas Basler
fbc39ef742 webapp: add app.js.gz 2023-12-17 19:03:48 +01:00
Thomas Basler
4cae93964d Fix: Gridprofileparser: Add additional error handling if profile is unknown 2023-12-17 17:55:51 +01:00
Thomas Basler
3288b974c1 Fix: Remove debug output as it floods the console 2023-12-17 17:55:26 +01:00
Thomas Basler
84248ec9b6 Feature: Add DTU to Home Assistant Auto Discovery
This is based on PR 1365 from @CFenner with several fixes and optimizations
2023-12-17 14:40:04 +01:00
Thomas Basler
e0cc1559d0 webapp: Fix lint errors 2023-12-17 14:40:04 +01:00
Thomas Basler
eac479430a Gridprofileparser: Added latest known values
Thanks to @stefan123t and @noone2k
2023-12-17 14:40:04 +01:00
Thomas Basler
e08570058c webapp: add app.js.gz 2023-12-16 11:33:51 +01:00
Thomas Basler
382abeecd3 Upgrade actions/download-artifact from v3 to v4 2023-12-15 16:28:41 +01:00
Thomas Basler
00fb6445b9 Upgrade actions/upload-artifact from v3 to v4 2023-12-15 16:28:10 +01:00
Thomas Basler
ac10700427 Feature: Added DeviceProfile for CASmo-DTU
Based on #1565
2023-12-15 16:25:28 +01:00
Thomas Basler
ab260dde0a Doc: Added hint regarding HMS-xxxx-xT-NA inverters 2023-12-15 16:21:50 +01:00
Thomas Basler
7950f92d8b Feature: Allow links in device profiles
These links will be shown on the hardware settings page.
2023-12-14 13:53:45 +01:00
Thomas Basler
b4ead9d6ec Feature: Allow setting of an inverter limit of 0% and 0W
Thanks to @madmartin in #1270
2023-12-13 22:15:49 +01:00
Thomas Basler
1d9c91c0fb Merge branch 'pr1505' into dev 2023-12-13 20:28:16 +01:00
Thomas Basler
14f6669314 webapp: Beautify and unify form footers 2023-12-13 19:40:07 +01:00
Thomas Basler
4d266a930a webapp: Update timezone database to latest version 2023-12-13 14:56:04 +01:00
Thomas Basler
4f7597eaa1 Adjust member variable names in NetworkSettings 2023-12-12 23:55:03 +01:00
Thomas Basler
66530638de Adjust member variable names in MqttSettings 2023-12-12 23:54:58 +01:00
Thomas Basler
e95afbf2cc Use references instead of pointers whenver possible 2023-12-12 13:26:07 +01:00
Thomas Basler
8fb43fedf8 Add const keyword to methods 2023-12-12 01:30:40 +01:00
Thomas Basler
d6494fa791 Add const keyword to method parameters 2023-12-12 00:21:14 +01:00
Thomas Basler
a0c47e97fb Update bblanchon/ArduinoJson from 6.21.3 to 6.21.4 2023-12-11 21:00:22 +01:00
Thomas Basler
5e45006831 Replace NULL by nullptr 2023-12-11 20:23:45 +01:00
Thomas Basler
47e905bcfc Add const statement to several variables 2023-12-11 19:54:57 +01:00
Thomas Basler
ab4a872daa Add additional compiler flags to prevent errors 2023-12-11 18:45:28 +01:00
Thomas Basler
efe0b6b383 Remove not required casts 2023-12-11 18:44:02 +01:00
Thomas Basler
8b806e46c1 Apply better variable names 2023-12-11 17:24:53 +01:00
Thomas Basler
a82e98d176 webapp: Update dependencies 2023-12-11 16:10:56 +01:00
Thomas Basler
06651f365a Feature: First version of GridProfile Parser which shows all values contained in the profile. 2023-12-11 14:58:17 +01:00
Thomas Basler
f851acab4d Add libfrozen to project to create constexpr maps 2023-12-10 14:57:05 +01:00
Thomas Basler
0737cb0cb3 Optimize AlarmLogParser to save memory 2023-12-09 11:41:32 +01:00
Thomas Basler
00bc631e87 Feature: Added basic Grid Profile parser which shows the used profile and version
Other values are still outstanding.
2023-12-09 11:12:37 +01:00
Thomas Basler
c9508d2660 Doc: Added byte specification to each command 2023-12-07 20:26:11 +01:00
Thomas Basler
b937532505 Remove not required AsyncEventSource 2023-12-07 15:21:24 +01:00
Thomas Basler
8b5d406a4f Introduce several const statements 2023-12-07 15:19:04 +01:00
Thomas Basler
e0c07b9bcf Remove code nesting 2023-12-07 14:13:58 +01:00
Thomas Basler
e9a55cf361 Remove not required onWebsocketEvent 2023-12-07 14:09:32 +01:00
Thomas Basler
c0a185394c Update olikraus/U8g2 from 2.35.7 to 2.35.8 2023-12-07 12:56:45 +01:00
Thomas Basler
08d45f2751 webapp: Update dependencies 2023-12-07 12:51:21 +01:00
Thomas Basler
9ae791edd4 Feature: Added ability to change the brightness of the LEDs
Based on the idea of @moritzlerch with several modifications like pwmTable and structure
2023-12-07 12:46:38 +01:00
Thomas Basler
3b6e9343d4 Adjust device web api endpoint for dynamic led count 2023-11-25 12:45:18 +01:00
Thomas Basler
d0397c821f Add channel count to description of detected inverter type (DevInfoParser) 2023-11-24 18:17:11 +01:00
Thomas Basler
8cf31729df Adjusted inverter names for HMS-1600/1800/2000-4T 2023-11-24 18:11:08 +01:00
Thomas Basler
bcc647fd51 Added HMT-1600-4T and HMT-1800-4T to DevInfoParser
Fix #1524
2023-11-24 18:10:08 +01:00
Thomas Basler
3dc91449aa Doc: Correct amount of MPP-Tracker 2023-11-24 17:57:44 +01:00
Thomas Basler
0fd4c603d5 Upgrade espMqttClient from 1.4.5 to 1.5.0 2023-11-23 22:55:25 +01:00
Thomas Basler
f8f79c816a Split LedSingle into multiple tasks 2023-11-23 22:35:05 +01:00
Thomas Basler
0db5b2eb9a Calculate SunPosition only every 5 seconds 2023-11-23 22:35:05 +01:00
Thomas Basler
134fefa30e Split InverterSettings into multiple tasks 2023-11-23 22:35:05 +01:00
Thomas Basler
80d534e045 Migrate WebApi to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
ab8679e7b9 Migrate Display_Graphic to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
ad1f1b690c Migrate MessageOutput to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
77779a1ed9 Migrate InverterSettings to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
1501411037 Migrate NetworkSettings to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
7881d955bd Migrate LedSingle to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
524483451f Migrate MqttHandleInverter to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
5c501f879f Migrate MqttHandleDtu to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
48a27fbfad Migrate MqttHandleHass to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
98c30d1042 Migrate MqttHandleInverterTotal to TaskSchedule 2023-11-23 22:35:05 +01:00
Thomas Basler
c045b5df48 Migrate Datastore to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
12031ed09e Migrate SunPosition to TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
a7c9c2df1a Initialize TaskScheduler 2023-11-23 22:35:05 +01:00
Thomas Basler
94170545ed webapp: Update dependencies 2023-11-23 22:34:18 +01:00
Thomas Basler
dff6da9a5f Feature: High resolution Icon and PWA (Progressive Web App) functionality
Fix: #1289
2023-11-23 22:32:01 +01:00
Pierre Kancir
b158a5682e remove broken LilyGO_T_ETH_POE config, use device profile instead 2023-11-22 23:01:28 +01:00
Pierre Kancir
203e871c4a Add Esp32-Stick-PoE-A 2023-11-22 23:01:23 +01:00
Thomas Basler
1de3b48166 Feature: Implement offset cache for "YieldDay"
Thanks to @broth-itk for the idea!
Fix: #1258 #1397
2023-11-22 20:21:25 +01:00
Thomas Basler
7538b4363c Made resetreason methods static 2023-11-19 17:00:26 +01:00
Thomas Basler
ee4811bbe7 Feature: Allow configuration of LWT QoS 2023-11-19 16:17:10 +01:00
Thomas Basler
b85c53f476 Split config struct into different sub structs 2023-11-19 14:53:26 +01:00
Thomas Basler
6bafd734d7 Remove not required enum 2023-11-18 22:35:58 +01:00
Thomas Basler
d3f95000e2 Optimize Sun data calculation 2023-11-18 22:34:55 +01:00
Thomas Basler
859b902ef9 webapp: add app.js.gz 2023-11-16 18:15:45 +01:00
Thomas Basler
614c0a0990 webapp: Update dependencies 2023-11-16 18:13:46 +01:00
Thomas Basler
6f685a4ab5 Fix: Day period is only calculated once 2023-11-16 18:03:25 +01:00
Thomas Basler
527c2eaf4a webapp: add app.js.gz 2023-11-15 18:00:43 +01:00
Thomas Basler
352fec539a Doc: Add hint regarding wiki 2023-11-15 17:58:43 +01:00
Thomas Basler
22da8ff4c7 Doc: Fix readme syntax errors 2023-11-15 17:03:12 +01:00
Thomas Basler
ac0655ea64 Doc: Add additional breaking changes 2023-11-15 16:47:04 +01:00
Thomas Basler
aea2afad29 webapp: Update dependencies 2023-11-15 16:45:10 +01:00
Thomas Basler
07e2c5998b Build webapp using nodejs v20 2023-11-15 16:40:04 +01:00
Thomas Basler
3d837bdd29 Upgrade actions/setup-node from v3 to v4 2023-11-15 16:39:09 +01:00
Thomas Basler
7b9ddb5033 Upgrade actions/checkout from v3 to v4 2023-11-15 16:38:30 +01:00
Thomas Basler
bd26d09564 Fix: build action fails due to ModuleNotFoundError: No module named 'pkg_resources':
Fix #1500
2023-11-15 16:36:46 +01:00
Thomas Basler
fa7641f715 Fix: Power not set to 0 when not reachable at EOD
If the inverter polling was disabled before it got unreachable the values where not set to zero
Fix: #1488
2023-11-09 22:30:35 +01:00
Thomas Basler
71d1b3b846 BREAKING CHANGE: Home Assistant Auto Discovery to new naming scheme
Please Upgrade to HASS 2023.8 or greater.
Thanks to @LennartF22 for the first implementation
2023-11-07 19:37:28 +01:00
Thomas Basler
17e92fc5eb Feature: Support HMT-1600/1800/2000-4T 2023-11-07 18:34:37 +01:00
Thomas Basler
2ae8ed5e18 Doc: Add class description for inverters 2023-11-05 13:44:08 +01:00
Thomas Basler
0a4945ae39 Adjusted inverter names 2023-11-05 13:43:48 +01:00
Thomas Basler
89b4b8ea85 Merge branch 'pr1441' into dev 2023-10-31 19:30:56 +01:00
CommanderRedYT
7c875187a8
Implemented mDNS 2023-10-30 20:53:45 +01:00
Thomas Basler
a068eb2586 Remove duplicated code 2023-10-30 20:42:56 +01:00
Thomas Basler
aba57e687a Set dnsServerStatus first to prevent running 2023-10-30 20:25:39 +01:00
Thomas Basler
6a64fe6e1a Fix #1456: Prevent white spaces in username field 2023-10-30 16:45:34 +01:00
Thomas Basler
7e7d372338 webapp: Update dependencies 2023-10-29 11:28:49 +01:00
Thomas Basler
b477db7045 Fix #1440: Add CSS code to stop numbers changing the size of their container 2023-10-21 12:54:51 +02:00
Thomas Basler
11d7b78d80 Apply automatic code formatting 2023-10-11 14:19:20 +02:00
Thomas Basler
97d481fa65 Merge branch 'pr1408' into dev 2023-10-11 14:16:23 +02:00
Thomas Basler
c25e93eb09 Merge branch 'pr1406' into dev 2023-10-11 13:40:05 +02:00
Thomas Basler
f1a8c2ea82 Feature: Added additional event log descriptions and implemented i18n 2023-10-11 13:22:42 +02:00
Thomas Basler
dc5b5e837f Rename "DTU command failed" to "Time calibration" as mentioned in #121 2023-10-10 16:23:11 +02:00
Thomas Basler
2991af79f2 webapp: add app.js.gz 2023-10-09 19:43:04 +02:00
Thomas Basler
f203a971b0 Feature: Added Descriptions for Event Log Messages as shown in #121 2023-10-09 19:38:22 +02:00
Thomas Basler
76dfaa7d3b Fix #1405: Add some border around icons when in multi line mode 2023-10-09 17:06:47 +02:00
Thomas Basler
0037e5969e webapp: Update dependencies 2023-10-09 17:01:58 +02:00
Thomas Basler
d373702d7b Added additional ID for HMS-1000 to DevInfoParser
Fix #1392
2023-10-09 16:58:21 +02:00
Stefan Oberhumer
be88da7b26 NFC: Call PinMapping.get() not every iteration. 2023-10-06 11:44:37 +02:00
Stefan Oberhumer
7f99095fca Remove SUNPOS_UPDATE_INTERVAL define and introduce INVERTER_UPDATE_SETTINGS_INTERVAL. 2023-10-06 11:13:09 +02:00
Stefan Oberhumer
943dfc2dbf Compute sunrise and sunset only if necessary.
Sunrise and -set must recomputed if one of the following conditions is met:
* The date changed (based on the selected timezone)
* Location (Lat/Lon) changed
* Sunset type changed

So instead of calculating that every minute just do it on update via web interface or date change.

If a new config is uploaded, the DTU gets restarted. There is no need to initiate a recalculation in this case.
2023-10-06 10:20:36 +02:00
Thomas Basler
4d61b20f39 Update olikraus/U8g2 from 2.35.4 to 2.35.7 2023-09-30 11:07:20 +02:00
Thomas Basler
253b50f765 Update nrf24/RF24 from 1.4.7 to 1.4.8 2023-09-30 11:05:13 +02:00
Thomas Basler
ea6a7f1a88 webapp: Update dependencies 2023-09-30 10:52:35 +02:00
Thomas Basler
32d91379fa Init all data members befor pushing it into the buffer 2023-09-30 10:48:41 +02:00
Thomas Basler
d4345917da Added additional ID for HMS-900 to DevInfoParser
Fix #1392
2023-09-30 10:45:49 +02:00
Thomas Basler
f8cba5721e Fix: Deny passwordless access to prometheus API if readonly access is disabled
Fix #1358
2023-09-19 18:59:20 +02:00
Thomas Basler
d419fd4794 webapp: add app.js.gz 2023-09-18 20:48:44 +02:00
Thomas Basler
64bfb63ba8 Revert espressif32 from 6.4.0 back to 6.3.2
Total available heap size was reduced from 281kb to 247kb which causes TLS issues (among others)
2023-09-18 20:47:29 +02:00
Thomas Basler
59ceac650b webapp: Update dependencies 2023-09-18 20:45:20 +02:00
Thomas Basler
35da310420 Initialize variables before first usage 2023-09-18 20:23:00 +02:00
Thomas Basler
1cf41426de Replace char array by String buffer 2023-09-16 02:21:25 +02:00
Thomas Basler
21fb10f7f2 Feature: Add one channel HMS inverter with different byte assignment
Fix #1148
2023-09-14 23:58:08 +02:00
Thomas Basler
0533c0bcc8 webapp: Rename Fehlernummer to ID
It's not just errors, its also regular messges
2023-09-13 23:19:43 +02:00
Thomas Basler
4ce0c21eb1 webapp: add app.js.gz 2023-09-13 20:17:58 +02:00
Thomas Basler
3b61c3e1ab webapp: Update dependencies 2023-09-13 20:12:12 +02:00
Thomas Basler
a974e217df Fix #1335: Only the first inverter was set to zero at midnight via mqtt 2023-09-13 18:46:23 +02:00
Thomas Basler
a0f9d22395 webapp: add app.js.gz 2023-09-11 20:05:12 +02:00
Thomas Basler
555b6c6750 Fix: HASS exp_aft should be based on reachable threshold and poll interval 2023-09-11 19:53:05 +02:00
Thomas Basler
55e98bc068 webapp: Update dependencies 2023-09-11 18:24:23 +02:00
Thomas Basler
3a3adb4723 Completly ignore a disabled (polling + command) inverter.
This leads to higher update rates on still enabled inverters.
2023-09-10 11:49:41 +02:00
Thomas Basler
8023b6620a Fix: Ignore incomplete SystemConfigPara packages
Some inverters seem to transmit too less and incomplete data. These packages will be ignored now.
2023-09-07 23:10:01 +02:00
Thomas Basler
0260af9ada Hoymiles Lib: Move semaphore handing into parser base class 2023-09-07 22:08:07 +02:00
Thomas Basler
9ac6dd6e8d Feature: First very basic support to read the grid profile
The parser is still missing and requires community support to collect data.
2023-09-07 22:08:07 +02:00
Thomas Basler
1acefd8b8c Fix: Do not resend fetch limit request if the last one failed
Due to side effects it is possible that the inverter receives the request but the DTU does not receive the answer. In this case the DTU would resend the request but the inverter would generate a event log entry (DTU command failed) because it received the message twice.
2023-09-05 22:09:16 +02:00
Thomas Basler
ec9af886d5 Feature: Added option to set daily yield to zero at midnight 2023-09-05 20:27:52 +02:00
Thomas Basler
23dd248073 webapp: Update dependencies 2023-09-04 19:57:23 +02:00
Thomas Basler
c46f85db9c webapp: Use max field to determine whether to show a string or not 2023-09-04 19:54:07 +02:00
Thomas Basler
1df8285833 Feature: Add configured max irradiation to live data api 2023-09-04 19:53:33 +02:00
Thomas Basler
7d90937d0f Publish mqtt string stats values periodically if they are set to zero if unreachable 2023-09-04 18:20:51 +02:00
Thomas Basler
abf95634db Replace platform dependent variable types by platform independent 2023-09-03 23:27:53 +02:00
Thomas Basler
55afa81cf1 Convert from FreeRTOS Semaphore to std::mutex 2023-09-02 16:46:23 +02:00
Thomas Basler
986d67a3d0 Fix: Better reconnect handling in Live View if invalid data where received 2023-09-02 12:22:55 +02:00
Thomas Basler
6127fbe940 Feature: Added option to set runtime values to zero when inverter becames unreachable 2023-09-02 12:22:22 +02:00
Thomas Basler
4f85d5286d Simplify debug output 2023-09-02 02:14:08 +02:00
Thomas Basler
9dec05def8 Fix: Check if valid data was received from websocket before assigning it
Otherwise it can lead to exceptions in inverterData method
2023-09-02 01:43:20 +02:00
Thomas Basler
b34b22c658 Fix: Workaround: Don't allow memory intensive web functions in parallel
Somehow the API has to be adjusted to reduce memory consumption. For now lets just prevent both methods to allocate memory at the same time.
2023-09-02 01:41:53 +02:00
Thomas Basler
2c41be106e Feature: Allow setting of the Reachable Threshold per inverter 2023-09-01 19:17:12 +02:00
Thomas Basler
c5f9f460cd Feature: Added config option to change MQTT CleanSession Flag 2023-09-01 18:03:30 +02:00
Thomas Basler
b95236c170 Feature: webapp: Move inverter settings into different tabs 2023-09-01 00:20:56 +02:00
Thomas Basler
72e3001d43 webapp: Update dependencies 2023-09-01 00:08:56 +02:00
Thomas Basler
094fadb2ee Update espressif32 from 6.3.2 to 6.4.0 2023-09-01 00:02:47 +02:00
Thomas Basler
34b3dad252 Upgrade espMqttClient from 1.4.4 to 1.4.5 2023-08-31 23:55:48 +02:00
Thomas Basler
3f1b6be857 Merge branch 'pr1271' into dev 2023-08-28 18:40:28 +02:00
Thomas Basler
8bf6935693 webapp: Update dependencies 2023-08-28 18:39:30 +02:00
Thomas Basler
701c490654 Feature: Turn off Display before reboot
Thanks for the idea to @StefanOberhumer
This prevents always on Display if the device profile does not contain Display pins anymore after the reboot
2023-08-25 16:57:24 +02:00
Thomas Basler
c91bd42a77 Feature: Turn off LEDs before reboot
Thanks for the idea to @StefanOberhumer
This prevents always on LEDs if the device profile does not contain LEDs pins anymore after the reboot
2023-08-25 13:15:55 +02:00
Thomas Basler
77a90095d9 Move different restart calls into one method 2023-08-25 12:58:53 +02:00
Thomas Basler
b88030f76e Feature: Re-Request DevInfo if it contains invalid data
It can sometimes occour that the DevInfo request returns invalid data. Currently this is identified if the firmware build year is < 2016. In this case the package will be re-requested now.
2023-08-25 11:04:14 +02:00
Simon Schwarz
1e26e87bc2 Added a pin profile where the nrf24 module can be soldered directly.
Also added a profile with SSD1306 display
2023-08-24 22:02:02 +02:00
Thomas Basler
08ca221410 webapp: add app.js.gz 2023-08-22 18:55:25 +02:00
Thomas Basler
e2594ac843 Fix: Calculate the json buffer for the inverter list based on INV_MAX_COUNT 2023-08-22 17:05:46 +02:00
Thomas Basler
6429d64062 Prometheus Endpoint: Simplify code by looping over fields instead of duplicated code 2023-08-22 13:00:52 +02:00
Thomas Basler
4bf9083b23 Prometheus Endpoint: Publish only relevant amount of digits
Implemented method to return the correctly formatted field value as string
2023-08-22 11:45:14 +02:00
Thomas Basler
b025c079c5 Merge branch 'pr1257' into dev 2023-08-22 10:43:37 +02:00
Thomas Basler
0c5aef8599 webapp: Update dependencies 2023-08-22 10:43:31 +02:00
Bernhard Roth
6eb3c63288 Fix issue #1256 (HMS-2000-4T reactive power should be signed) 2023-08-21 11:14:24 +02:00
Thomas Basler
4bf094c3ef webapp: Update default proxy ip 2023-08-09 18:23:50 +02:00
Thomas Basler
871dc051d7 Merge branch 'pr1229' into dev 2023-08-09 18:22:58 +02:00
Stefan Schultheis, OE1SCS
629ede3cbd Update en.json
typo. power safe != power save
2023-08-09 18:21:36 +02:00
Stefan Schultheis, OE1SCS
94f6078c9e Update de.json
bessere Übersetzung
2023-08-09 18:20:36 +02:00
Bernhard Kirchen
452679e90b make vite proxy target easily configurable
the current proxy target IP address is probably only working for a
single developer at a time. this change introduces a vite.user.ts, which
is ingored by GIT, and which can define a proxy_target that works for
the respective developer.

this does not change the default behavior, as the fallback value is
still the old IP address. if the new vite.user.ts file does not exist,
or if it does not export proxy_target, the fallback value is used.

file vite.config.ts adds an example in a comment of how to bootstrap a
vite.user.ts.
2023-08-09 16:58:58 +02:00
Thomas Basler
b71106c9ef webapp: add app.js.gz 2023-08-08 22:54:07 +02:00
Thomas Basler
ac4ddbe23d webapp: Fix lint error 2023-08-08 22:50:30 +02:00
Thomas Basler
3d67d934c1 webapp: Update dependencies 2023-08-08 22:50:09 +02:00
Thomas Basler
9179b672f5 Use lock_guard to simplify code 2023-08-05 01:25:53 +02:00
Thomas Basler
188a6cf39d Replace template by abstract class 2023-08-05 01:01:53 +02:00
Thomas Basler
22d9b128b9 Fix: Move setting of CMD_PENDING state into the right order 2023-08-04 23:44:18 +02:00
Thomas Basler
f3e3ec0685 webapp: Update dependencies 2023-08-03 22:36:48 +02:00
Thomas Basler
43cba67531 Fix: Virtual console scrambled output when the output came from different contexts 2023-08-03 22:16:29 +02:00
Thomas Basler
10ba10d792 cpplint: do not complain mutex include 2023-08-03 22:07:53 +02:00
Thomas Basler
0bdee6ec99 Fix: Prevent access to nullptr object when reconnecting to mqtt
It could occour when saving the settings via the web ui
2023-08-03 18:46:28 +02:00
Thomas Basler
832df5a80e Implement the command queue thread safe
The queue will be maybe filled from within another thread (mqtt/web) and handled from the main loop
2023-08-03 00:17:32 +02:00
Thomas Basler
be09c4052f Fix: Ensure that only completly assembled packets are put into the command queue 2023-08-02 22:41:53 +02:00
Thomas Basler
686112e4ee Fix: Wrong detection of HM-300 inverters
Was introduced in v23.8.1; Fixes #1198
2023-08-02 18:41:25 +02:00
Thomas Basler
77528f6e6a webapp: add app.js.gz 2023-08-01 21:55:25 +02:00
Thomas Basler
ba9bddf277 webapp: Update dependencies 2023-08-01 21:54:19 +02:00
Thomas Basler
5bbc67bc49 Fix: Clear parser buffers to prevent random numbers if no data was received 2023-07-31 22:52:38 +02:00
Thomas Basler
2eeb7423bf Update olikraus/U8g2 from 2.35.3 to 2.35.4 2023-07-31 22:42:06 +02:00
Thomas Basler
c374a83cfe Update bblanchon/ArduinoJson from 6.21.2 to 6.21.3 2023-07-31 22:40:54 +02:00
Thomas Basler
a90073cba2 webapp: Update dependencies 2023-07-31 22:31:53 +02:00
Thomas Basler
ef65094181 Fix: Prevent wrong values of devinfo data because of non-atomic transaction 2023-07-31 22:27:28 +02:00
Thomas Basler
74169c3b17 Fix: Prevent wrong values of systemconfigpara data because of non-atomic transaction 2023-07-31 22:06:04 +02:00
Thomas Basler
698ecbcd53 Fix: Prevent wrong values of alarm data because of non-atomic transaction and fix calculation of getEntryCount() 2023-07-31 22:06:04 +02:00
Thomas Basler
14305a9f12 Fix: Prevent wrong values of statistics data because of non-atomic transaction 2023-07-31 22:05:22 +02:00
Thomas Basler
9821c1905b Fix: Uninitliazed variable used before first use 2023-07-31 21:44:50 +02:00
Thomas Basler
92c9544bb3 webapp: add app.js.gz 2023-07-22 20:25:55 +02:00
Thomas Basler
1146e15ea6 Move units from description to postfix for AP timeout 2023-07-22 18:30:18 +02:00
Martin Dummer
8bfa7e530c Feature: Admin AccessPoint Timeout now configurable
Make the administrative accesspoint timeout configurable. The default
value is 3 minutes, values from 0-99999 are possible, where 0 means
infinite (no timeout).

Signed-off-by: Martin Dummer <martin.dummer@gmx.net>
2023-07-22 18:14:07 +02:00
Thomas Basler
2e25fdcf8f Formatting style in platformio.ini 2023-07-22 18:08:34 +02:00
Thomas Basler
a68c553d27 Code formatting without functional changes 2023-07-22 18:07:03 +02:00
Thomas Basler
658a42db80 Apply code formatter without functional changes 2023-07-22 18:00:41 +02:00
Thomas Basler
a06a56a490 Harden config parser by defining right unsigned data type 2023-07-22 17:41:56 +02:00
Thomas Basler
736220c80d Reorder config struct components 2023-07-22 17:28:58 +02:00
Thomas Basler
0d5b938328 Update olikraus/U8g2 from 2.34.22 to 2.35.3 2023-07-22 16:01:19 +02:00
Thomas Basler
cc0af372ef webapp: Update dependencies 2023-07-22 15:53:51 +02:00
Thomas Basler
eaacce7483 Feature: Show error in webapp if pin_mapping.json contains syntax errors 2023-07-22 15:51:16 +02:00
Thomas Basler
972dea297b Fix: Prevent runtime errors in webapp when invalid pin_mapping.json is provided 2023-07-22 15:30:40 +02:00
Thomas Basler
bf4dc56cb8 Fix: Reboot loop if negative display pins and type where provided
Fix #1163
2023-07-21 19:02:18 +02:00
Thomas Basler
9dbeec3a31 Fix: Set WiFi setScanMethod and setSortMethod also on first connect 2023-07-20 23:44:09 +02:00
Thomas Basler
3b02ffe7a8 webapp: Update dependencies 2023-07-12 18:40:23 +02:00
Thomas Basler
cf91839838 Upgrade espMqttClient from 1.4.3 to 1.4.4 2023-07-12 18:38:35 +02:00
Thomas Basler
0d07b1aa4a webapp: add app.js.gz 2023-07-10 20:45:51 +02:00
Thomas Basler
56e2b462fb Update espressif32 from 6.3.1 to 6.3.2 2023-07-10 20:26:07 +02:00
Thomas Basler
b8c75b02a0 Merge branch 'pr1003' into dev 2023-07-10 19:11:54 +02:00
Stephan
1871a9a692 use FSPI for esp32-c3 and revise device profiles 2023-07-10 19:04:13 +02:00
Thomas Basler
99b316587e webapp: Update dependencies 2023-07-10 18:34:55 +02:00
Thomas Basler
fe3d6588bc Feature: Turn off LED 1 if no inverters are enabled for polling
This means that e.g. at night, when polling at night is disabled, LED 1 will be turned off now.
2023-07-10 18:31:04 +02:00
Thomas Basler
0ffbba0cf5 Fix: Allow sending of ChannelChangeCommand even if EnableCommands is disabled
This is required to successfull move the inverter to another frequency and then polling it. Without this command its not even possible to poll a inverter.

Fixes #1127
2023-07-10 18:30:59 +02:00
Thomas Basler
9b0d2ff25f webapp: Update dependencies 2023-06-28 20:11:36 +02:00
jstammi
82038d3e2d Fix: do not calc sizes multiple times
tbnobody/OpenDTU/issues/1022
2023-06-28 19:26:45 +02:00
jstammi
4ae6a2b4ef Fix: calc expected statistics packet length per parser
tbnobody/OpenDTU/issues/1022
2023-06-28 16:53:38 +02:00
Thomas Basler
a510afe53e webapp: Update dependencies 2023-06-27 19:01:43 +02:00
Thomas Basler
69aa247470 Added check in statistics data that at least all required bytes are received
It can occour for some inverters that incomplete fragments with valid crc but less bytes are received

This was mentioned in #1084
2023-06-27 18:59:54 +02:00
Thomas Basler
12a18fb34b webapp: add app.js.gz 2023-06-26 20:44:30 +02:00
Thomas Basler
6955233371 webapp: Update dependencies 2023-06-26 20:42:43 +02:00
Gregor Wolf
d8a3a75c0b Device Profile for Wemos Lolin32 OLED 2023-06-26 18:31:54 +02:00
jdloic
3df65b3d37 Ajout de traductions en Français 2023-06-26 18:31:54 +02:00
Thomas Basler
93057fc3dc Feature: Added touch icon for iOS and Android
Implements #1060
2023-06-21 22:44:18 +02:00
Thomas Basler
582867cdb9 Update olikraus/U8g2 from 2.34.18 to 2.34.22 2023-06-21 20:44:18 +02:00
Thomas Basler
37b3b5abb9 webapp: Update dependencies 2023-06-21 20:38:52 +02:00
Thomas Basler
e0b054d2b5 Pre-Compile a new generic esp32s3 binary without any pin config. 2023-06-21 20:31:31 +02:00
Thomas Basler
7656735103 Pre-Compile a new generic esp32 binary without any pin config. 2023-06-21 20:30:08 +02:00
Thomas Basler
e8fee49dc8 Allow the non-existence of the HOYMILES_PIN_ defines 2023-06-21 19:59:35 +02:00
Thomas Basler
30fbd98274 Fix: Reboot loop occoured when no rf module was configured 2023-06-21 19:56:14 +02:00
Thomas Basler
915b084af5 webapp: Update dependencies 2023-06-19 11:35:48 +02:00
Thomas Basler
184c659197 Added new found HMS-400 to DevInfoParser
Fixes #1045
2023-06-19 11:33:06 +02:00
Thomas Basler
0a56dc2ae1 webapp: Update dependencies 2023-06-14 21:53:53 +02:00
Thomas Basler
64c96c34f4 Revert "Fix: String numbers for HMT inverters are mirrored"
This reverts commit 593a33020f.
2023-06-14 21:44:55 +02:00
Dominic Michel
3562e85b5e Change metric type back to gauge 2023-06-13 20:59:24 +02:00
Thomas Basler
ee4b479b7d webapp: Update dependencies 2023-06-11 21:00:14 +02:00
Thomas Basler
88de38e694 Doc: Add hint to adjusted partition upgrade guide to use only one .bin file 2023-06-11 20:07:41 +02:00
Thomas Basler
08f47c2f4c Fix: Prometheus syntax error with wifi_bssid
Fixes #1021
2023-06-11 20:04:23 +02:00
Thomas Basler
170978c6f8 webapp: add app.js.gz 2023-06-09 01:42:17 +02:00
Thomas Basler
c8fc123e81 Feature: Only require one binary file for initial flashing
There is no need anymore to upload multiple .bin files. All binaries are combined into one.
2023-06-09 00:03:01 +02:00
Thomas Basler
abfc2735ba Add separate property to platformio.ini to control the environments built by github actions
This is now independent of the default_envs which also affects local development
2023-06-08 22:48:04 +02:00
Thomas Basler
9ac1bb3409 Update olikraus/U8g2 from 2.34.17 to 2.34.18 2023-06-08 21:05:53 +02:00
Thomas Basler
b8745f6199 Update nrf24/RF24 from 1.4.5 to 1.4.7 2023-06-08 21:01:58 +02:00
Thomas Basler
78135fb62e Update espressif32 from 6.3.0 to 6.3.1 2023-06-08 21:00:38 +02:00
Thomas Basler
c1f64396d8 Always use a latest patch level of the softprops/action-gh-release 2023-06-08 20:43:46 +02:00
Thomas Basler
abef455249 Doc: Enhanced device profile for nodemcu esp32 2023-06-08 20:38:14 +02:00
Thomas Basler
2ccc4a766e webapp: Update dependencies 2023-06-08 20:29:14 +02:00
Thomas Basler
88cb59d177 Feature: Publish BSSID via prometheus 2023-06-08 19:57:07 +02:00
Thomas Basler
b3e41c957b Feature: Publish BSSID via MQTT 2023-06-08 19:56:44 +02:00
Thomas Basler
91d3cd1da2 Feature: Show BSSID in the web interface 2023-06-08 19:56:22 +02:00
Thomas Basler
721f82a17c Added additional exception handler to also show unknown exceptions in live data api endpoint 2023-06-08 19:39:56 +02:00
Thomas Basler
593a33020f Fix: String numbers for HMT inverters are mirrored
Fixes: #1005
2023-06-07 18:05:51 +02:00
Thomas Basler
3b6c529efb Fix: Do not publish leading blanks in MQTT payload
Fixes #1011
2023-06-07 17:58:31 +02:00
Thomas Basler
82b0272ceb Removed duplicate code by moving it into the radio base class 2023-06-03 12:07:46 +02:00
Thomas Basler
c5a31de5a8 First try to output some dBm info for the NRF module 2023-06-03 11:54:23 +02:00
Thomas Basler
7f267ff2fb Fix: Lint Error: Almost always, snprintf is better than strcpy 2023-06-01 23:30:13 +02:00
Thomas Basler
5558dffa70 webapp: add app.js.gz 2023-06-01 23:25:28 +02:00
Thomas Basler
114ebb247a webapp: Update dependencies 2023-06-01 23:24:31 +02:00
Thomas Basler
5a37948ca9 Fix: If no sunset/sunrise calculation is possible a wrong value is shown
This is catched now and a proper message is shown in the web UI. Also the mode is set to day.
2023-06-01 18:39:50 +02:00
Thomas Basler
aa4868cd9c webapp: add app.js.gz 2023-05-31 19:49:59 +02:00
Thomas Basler
ac201ba689 webapp: Update dependencies 2023-05-31 19:43:22 +02:00
Thomas Basler
249436a303 Added possible description for alarm code 73
https://github.com/tbnobody/OpenDTU/discussions/590#discussioncomment-6049750
2023-05-31 19:23:35 +02:00
Thomas Basler
24f063dd7b Fix: Prevent partly calculated total data in web ui and display
Leads to zeros where no zeros should be.
2023-05-30 22:10:27 +02:00
Thomas Basler
bd891f9a6d Upgrade espMqttClient from 1.4.2 to 1.4.3 2023-05-29 21:08:09 +02:00
Thomas Basler
a4cf16bb0b webapp: Update dependencies 2023-05-29 21:02:19 +02:00
Thomas Basler
853ac3560b Feature: DeviceProfile: Added display sample to WT32-ETH01
Thanks to #844
2023-05-29 20:46:41 +02:00
Thomas Basler
1c8bd8091b Feature: Allow reordering of the inverters in the live view
Reordering can be done in the inverter settings via drag&drop.
2023-05-29 20:17:07 +02:00
Thomas Basler
e0027d951b Feature: Added new found HMS-900 to DevInfoParser
Fixes #967
2023-05-27 11:14:15 +02:00
Thomas Basler
08b44fb2ba Added post build script to generate a .factory.bin file
This file can just be flashed to address 0x0 and contains all other required data. No need to flash multiple files anymore.
2023-05-25 20:47:45 +02:00
Thomas Basler
5fea7ee066 Fix: Doublecheck if the MutiDataCommand begins with the correct ID
ID is 0x15 | 0x80
2023-05-24 22:06:58 +02:00
Thomas Basler
8f2a2b40b1 Fix: Filter incoming packages from CMT module for the right destination address
The CMT module receives every package on it's target frequency. Compared to the NRF module to filtering takes place. Therefor it's required to check if the package destination id is really the id of our dtu
2023-05-24 21:55:15 +02:00
Thomas Basler
e7198073af Feature: Allow configuration of sunset type 2023-05-24 19:21:44 +02:00
Thomas Basler
889e191589 webapp: add app.js.gz 2023-05-23 20:14:35 +02:00
Thomas Basler
a66a3fc44e webapp: Update dependencies 2023-05-23 19:39:03 +02:00
Thomas Basler
fe90c863bf Fix: Better handling of invalid fragment ids 2023-05-23 19:32:51 +02:00
Thomas Basler
752362d2df Feature: Added localization setting to display
Its possible to change the language of the display
2023-05-23 18:25:12 +02:00
Thomas Basler
4e11d653a3 webapp: add app.js.gz 2023-05-22 18:46:11 +02:00
Thomas Basler
456a433cd5 Upgrade platform-espressif32 from 6.1.0 to 6.3.0 2023-05-22 18:40:30 +02:00
Thomas Basler
450fa4dbe9 webapp: Update dependencies 2023-05-22 18:26:05 +02:00
Thomas Basler
40820c07f2 Use the new data store in the graphic display class.
With this patch, the display turns off if no inverter is reachable anymore. Previously it turned off if the production was zero.
This fixes #933
2023-05-21 22:40:32 +02:00
Thomas Basler
cd98941c5d Implement global data store to handle all invert total values
Use the new values in the LED, MQTT and Web interface.
2023-05-21 22:37:33 +02:00
Thomas Basler
56fe72d900 Add new log location to .gitignore 2023-05-19 18:21:07 +02:00
Thomas Basler
3596c79d3b webapp: Update dependencies 2023-05-19 11:05:47 +02:00
Thomas Basler
295eeba556 Feature: Added new found HMS-450 to DevInfoParser
Fixes #911
2023-05-11 18:26:56 +02:00
Thomas Basler
29e9da9126 webapp: add app.js.gz 2023-05-09 20:23:24 +02:00
Thomas Basler
aa6812ccd9 webapp: Update dependencies 2023-05-09 20:06:20 +02:00
Thomas Basler
7be5dd865a Feature: Added new found HMS-1600 to DevInfoParser 2023-05-09 19:29:23 +02:00
Thomas Basler
efcbd81927 Feature: Add used PIO environment to the system info page 2023-05-08 21:43:50 +02:00
Thomas Basler
99ab78d544 Feature: Added new found HMS-600 to DevInfoParser 2023-05-06 17:49:04 +02:00
Thomas Basler
74abc1ec1d Feature: Added new found HMS-2000 to DevInfoParser
Fix #886
2023-05-06 12:16:05 +02:00
Thomas Basler
71c937c3cb Merge branch 'pr851' into dev 2023-05-03 21:22:43 +02:00
Thomas Basler
65b728eebb Fix: No OpenDTU startup of CDC (like Pico or ESP32-S3) devices if no usb host is connected
Should also fix #826
2023-05-03 21:16:27 +02:00
Thomas Basler
7c80fe2bf9 webapp: Update dependencies 2023-05-02 21:03:24 +02:00
Thomas Basler
09f8a633d7 Fix: Source does not build with platform >= 6.2.0
Stick at 6.1.0 at the moment... There is already a issue opened on arduino-esp32 (https://github.com/espressif/arduino-esp32/issues/8108)
2023-05-02 20:49:11 +02:00
Martin Dummer
834b938185
Fix: README.md: change binary download instructions
new download instructions since github releases are on the project homepage

Signed-off-by: Martin Dummer <martin.dummer@gmx.net>
2023-04-28 22:01:59 +02:00
Thomas Basler
90a0cb60c6 webapp: add app.js.gz 2023-04-28 21:47:49 +02:00
Thomas Basler
ae321d633a webapp: Update dependencies 2023-04-28 21:47:05 +02:00
Markus Krause
357d9edbd8 add device profile for opendtufusion 2023-04-28 21:26:22 +02:00
Markus Krause
a56d5adb77 fix SPI assignment across generations 2023-04-28 21:26:22 +02:00
Markus Krause
b086c6ace6 remove non-sensical octa-spi setting in FIFO mode 2023-04-28 21:26:22 +02:00
Markus Krause
a37b394139 try fix SPI driver for CMT 2023-04-28 21:26:22 +02:00
Markus Krause
14f9d1b3c6 avert SPI collision on S3/S2/C3 2023-04-28 21:26:22 +02:00
Markus Krause
d361619ade add v2 opendtufusion 2023-04-28 21:26:22 +02:00
Markus Krause
72231bca5e improve opendtufusion ini 2023-04-28 21:26:22 +02:00
Markus Krause
4e51914a04 add opendtufusion board 2023-04-28 21:26:22 +02:00
Markus Krause
6a74663af4 fix typo in disply type for 1106 2023-04-28 21:25:36 +02:00
Markus Krause
a7911dab64 add openDTU v1 pinout device file 2023-04-28 21:25:36 +02:00
Thomas Basler
35f307d745 Merge branch 'pr846' into dev 2023-04-28 21:16:20 +02:00
Thomas Basler
0a36ae3c1c Merge branch 'pr847' into dev 2023-04-28 21:05:06 +02:00
Thomas Basler
41405d5fa1 Merge branch 'pr842' into dev 2023-04-28 21:04:31 +02:00
Thomas Basler
58214ccbea Fix: webapp console: Only add the date at the beginning if the last character was a newline 2023-04-28 21:03:45 +02:00
Thomas Basler
3504884836 Fix: xSemaphoreTake was useless
There was no check of the return value implemented therefore xSemaphoreTake was just executed and not locked
2023-04-28 21:02:10 +02:00
Timo Schindler
210a186c0c added opendtu breakout board to readme 2023-04-25 20:27:30 +02:00
Moritz
e88517df07
Update MQTT_Topics.md
typo
2023-04-25 20:20:03 +02:00
Timo Schindler
5b2e3ca05a added oepndtu breakout board to builds readme 2023-04-25 20:05:30 +02:00
Timo Schindler
92a4e25230 added some opendtu breakout board pictures 2023-04-25 20:05:09 +02:00
Thomas Basler
0441bbbe72 Fix: Queue consumed whole memory on inverter timeout
When the poll interval was e.g. 1sec it was possible that the queue ran full and consumed the whole memory.
Now new entries are only added to the queue automatically if the queue is empty.  This issue also caused a lot of "DTU command failed" messages.
2023-04-25 19:24:56 +02:00
Thomas Basler
5996fb0edf Fix: MQTT topics ac/yieldday and ac/yieldtotal are swapped
Fix #843
2023-04-25 18:43:56 +02:00
Moritz
6a4ad0446d
Update README.md
typo
2023-04-24 23:02:11 +02:00
Thomas Basler
bf648a586f Doc: Added new total MQTT topics 2023-04-24 22:55:20 +02:00
Thomas Basler
98da2b64e2 Rename FLD_PRA to FLD_Q 2023-04-24 22:29:59 +02:00
Thomas Basler
270a7f4933 Rename UNIT_VA to UNIT_VAR 2023-04-24 22:25:15 +02:00
Thomas Basler
8a85aea543 webapp: add app.js.gz 2023-04-24 20:33:24 +02:00
Thomas Basler
b2c249a711 webapp: Enable stricter error reporting 2023-04-24 20:31:24 +02:00
Thomas Basler
1da545725a webapp: Update dependencies 2023-04-24 20:21:51 +02:00
Thomas Basler
ece488cb2a Doc: Added hint regarding multiple DTUs per inverter
Fix #831
2023-04-24 18:54:52 +02:00
Thomas Basler
26cbc496a7 Feature: Implemented MQTT publishing of total values
If one or more inverter is not reachable the flag is_valid changes to zero. Disabled inverters are ignored.
2023-04-24 18:51:30 +02:00
Thomas Basler
793cd9db91 Fix: Possible crash when multiple tasks accessed the SPI bus
This could happen when  the main loop and the web server callback accessed the  SPI bus at the same time  (e.g. to show the isConnected status)
2023-04-22 10:59:32 +02:00
Thomas Basler
f5c15a445b Move byteAssignment to stack (avoid container) to save heap 2023-04-22 01:12:29 +02:00
Thomas Basler
0e9c666981 Implement method as static 2023-04-21 19:02:10 +02:00
Thomas Basler
8373a9cffb webapp: update dependencies 2023-04-20 23:16:38 +02:00
Thomas Basler
12d03f06b0 Added functionality to apply custom patch files during building
Usefull  to patch existing libraries
2023-04-20 23:13:18 +02:00
Thomas Basler
f5fc52b92f Move auto_firmware_version.py to pio-scripts subdirectory 2023-04-20 22:46:05 +02:00
Thomas Basler
04f62e03b8 BREAKING CHANGE: Web API Endpoint /api/eventlog/status no nested serial object
It's not required as the  eventlog just contains events from requested inverter
2023-04-20 22:41:55 +02:00
Thomas Basler
188d865671 Fix: Device profile "Olimex ESP32-POE with SH1106" used wrong display type. Fix #825 2023-04-19 23:37:06 +02:00
Thomas Basler
5d2656550c Optimize detection if RF module is configured
Use PinMapping method instead of dedicated method in Hoymiles lib --> Same result but reduces variables
2023-04-17 23:19:53 +02:00
Thomas Basler
ebc1b3aed2 webapp: add app.js.gz 2023-04-17 22:06:32 +02:00
Thomas Basler
a1d5f97efb Upgrade ArduinoJson from 6.21.1 to 6.21.2 2023-04-17 22:01:38 +02:00
Thomas Basler
15791b457a Doc: Add breaking change hint 2023-04-17 21:50:17 +02:00
Thomas Basler
18f880530f Apply correct order to extension.json items
VSCode applys this sorting anyways
2023-04-17 21:49:17 +02:00
Thomas Basler
59f43a82a8 BREAKING CHANGE: Web API Endpoint /api/devinfo/status requires GET parameter inv=
Only the requested inverter is sent to the client. This reduces the size of the json response --> Less memory.

It should also fix #814.
2023-04-17 21:48:16 +02:00
Thomas Basler
af3a277e30 Introduced HoymilesRadio property to determine if a configuration attempt was done 2023-04-17 18:59:56 +02:00
Thomas Basler
1416efc6f9 Fix: Endless loop when CMT module was configured but not connected 2023-04-17 18:58:23 +02:00
Thomas Basler
481bc00f28 webapp: add app.js.gz 2023-04-15 11:05:57 +02:00
Thomas Basler
34ac6faefc webapp: Update dependencies 2023-04-15 11:01:40 +02:00
Thomas Basler
7c37d289c0 Enabled additional statistics data for HMT inverters
Not yet shown in web ui and mqtt
2023-04-15 10:55:48 +02:00
Thomas Basler
6856ba9972 Fix: Change defines to get a correct calculation if base frequency of CMT module is different compared to Hoymiles base frequency 2023-04-15 10:55:48 +02:00
Thomas Basler
f3942bb647 Fix: Set correct frequency when changing it via web ui
Previously it could happen that the frequency was changed between saving old and recovering new frequency. Therefor an invalid frequency was saved in the CMT module
2023-04-15 10:55:48 +02:00
Thomas Basler
f1f4322db5 Doc: Added MPP-Tracker count 2023-04-15 10:55:48 +02:00
Thomas Basler
d15b6ffe67 Doc: Added some remarks regarding the CMT2300A module 2023-04-15 10:55:48 +02:00
Thomas Basler
71e88e6f73 Doc: Added some device profiles containing the CMT2300A pin assignment 2023-04-15 10:55:48 +02:00
Thomas Basler
5448a6d0ba Doc: Added new supported inverters 2023-04-15 10:55:48 +02:00
Thomas Basler
8356db94b9 Send ChannelChangeCommand only once per cycle as the inverter will not response at all 2023-04-15 10:55:48 +02:00
Thomas Basler
ac7b5dba11 Resend and Retransmit count is now implementable per command 2023-04-15 10:55:48 +02:00
Thomas Basler
e2aa29f117 Remove cmtProocess method and move RF logic into the cmt2300wrapper class 2023-04-15 10:55:48 +02:00
Thomas Basler
f5767e61ef Implement CMD56 as own command.
By doing so, it's possible to send all packets via the sendEsbPacket method. A lot of stuff could be removed which is no more used.
2023-04-15 10:55:48 +02:00
Thomas Basler
cfb37906ca Rename cmtFreqToChan to getChannelFromFrequency and simplify handling of current channel 2023-04-15 10:55:48 +02:00
Thomas Basler
1259f09503 Replace multiple print calls by a single printf in HoymilesRadio_NRF 2023-04-15 10:55:48 +02:00
Thomas Basler
a11ee472c6 Optimize cmtChToFreq method to return float instead of string. Renamed also to getFrequencyFromChannel 2023-04-15 10:55:48 +02:00
Thomas Basler
2a92f67a9a Implement get and set channel in cmt2300 wrapper class 2023-04-15 10:55:48 +02:00
Thomas Basler
fffd872b20 Replace HOY_BASE_FREQ by CMT_BASE_FREQ 2023-04-15 10:55:48 +02:00
Thomas Basler
5b648b63ac Implemented blocking write method in CMT2300 driver and use it in sendEsbPacket. 2023-04-15 10:55:48 +02:00
Thomas Basler
6331210b94 IsReachable of the inverter was never reached 2023-04-15 10:55:48 +02:00
Thomas Basler
25722f6055 Adjust buffer size in StatisticsParser for inverters with more inputs 2023-04-15 10:55:48 +02:00
Thomas Basler
85070ffda0 webapp: Add hint to cmt frequency that it can take up to 15min until a connection is established 2023-04-15 10:55:48 +02:00
Thomas Basler
d6c2a4ba1c webapp: Remove hard coded texts in dtuadmin view 2023-04-15 10:55:48 +02:00
Thomas Basler
ac5df9a91d webapp: Implement CMT pa level as range control 2023-04-15 10:55:48 +02:00
Thomas Basler
15156b4b87 Set CMT frequency only if a valid pin config was found 2023-04-15 10:55:48 +02:00
Thomas Basler
c3368450f6 Initialize spiClass only if valid pin config was found 2023-04-15 10:55:48 +02:00
Thomas Basler
1e7b16adb9 webapp: Nicer cmt frequency input 2023-04-15 10:55:48 +02:00
Thomas Basler
50ce7f014d Expose min and max frequency in HoymilesRadio_CMT 2023-04-15 10:55:48 +02:00
Thomas Basler
6ea34b331d Increase command timeouts to support inverters with 6 channels and more phases 2023-04-15 10:55:48 +02:00
Thomas Basler
1614b2ad2d Add newline after log output 2023-04-15 10:55:48 +02:00
Thomas Basler
371e405eed Added configuration of CMT modules frequency to webapp 2023-04-15 10:55:48 +02:00
Thomas Basler
5e11f0b854 Implement property in HoymilesRadio_CMT to set the frequency during runtime 2023-04-15 10:55:48 +02:00
Thomas Basler
70b85fad6f Doc: Added sample device profile for CMT and NRF module 2023-04-15 10:55:48 +02:00
Thomas Basler
fe5e5bc4b1 Implement cmtBaseChOff860 as a define 2023-04-15 10:55:48 +02:00
Thomas Basler
4561e52735 Adjusted some comments 2023-04-15 10:55:48 +02:00
Thomas Basler
996404ceed Introduce gpio2 for the CMT2300A module
This implements the sending interrupt instead of polling. On the other hand, gpio3 is made optional.
2023-04-15 10:55:48 +02:00
Thomas Basler
854fcdaeae Allow configuration of the TX PA Level of the CMT2300A module 2023-04-15 10:55:48 +02:00
Thomas Basler
bec9870347 Move alarm messages from heap to stack 2023-04-15 10:55:47 +02:00
Thomas Basler
fc5f6887cb Adjust name from CMT2300a to CMT2300A 2023-04-15 10:55:47 +02:00
Thomas Basler
098691af9d First step towards a modular CMT2300 driver similar to the NRF24 one 2023-04-15 10:55:47 +02:00
Thomas Basler
035fdbc54a Increase CMT SPI speed to 4 MHz 2023-04-15 10:55:47 +02:00
Thomas Basler
defcc02204 Set CMT to 13dBm and added parameter values in plain text 2023-04-15 10:55:47 +02:00
Thomas Basler
67055276ca Implement different Eventlog messages for HMT inverters
Also make message list much more readable
2023-04-15 10:55:47 +02:00
Thomas Basler
06cc19fc70 Use TimeoutHelper for TX timeout 2023-04-15 10:55:47 +02:00
Thomas Basler
3e1b778565 Change max power limit from 1500W to 2250W to support HMS/HMT inverters 2023-04-15 10:55:47 +02:00
Thomas Basler
0ec90e0000 webapp: Adjusted radio problem hint in home view to detect problems of nrf and cmt radios 2023-04-15 10:55:47 +02:00
Thomas Basler
c19d2007bd webapp: Added cmt radio status to system overview 2023-04-15 10:55:47 +02:00
Thomas Basler
46036eb958 Simplify dumpBuf method in HoymilesRadio 2023-04-15 10:55:47 +02:00
Thomas Basler
83c623708f Fix crash if radio settings where changed while the radio was not initialized 2023-04-15 10:55:47 +02:00
Thomas Basler
de2b7ab2d2 Check that all RF modules as in idle mode before sending mqtt packages 2023-04-15 10:55:47 +02:00
Thomas Basler
b7fb294368 Set DTU serial for CMT modules 2023-04-15 10:55:47 +02:00
Thomas Basler
dc91929d6e First rough implementation of HMT inverters 2023-04-15 10:55:47 +02:00
Thomas Basler
ef614751b1 webapp: Show CMT pins in device manager 2023-04-15 10:55:47 +02:00
Thomas Basler
45882543b6 Allow dynamic pin mapping for CMT module 2023-04-15 10:55:47 +02:00
Thomas Basler
3c0d89f599 Replaced println by printf and code style changes 2023-04-15 10:55:47 +02:00
Thomas Basler
a585ffe199 Add variable for max channel count (to extend serveral arrays) 2023-04-15 10:55:47 +02:00
Thomas Basler
90c689a41a Implement HoymilesRadio_CMT 2023-04-15 10:55:47 +02:00
Thomas Basler
8927b8374a Added HMS/HMT devices to the DevInfoParser 2023-04-15 10:55:47 +02:00
Thomas Basler
41e2ba7fcf Move serveral methods from the HoymilesRadio_NRF class to the HoymilesRadio base class 2023-04-15 10:55:47 +02:00
Thomas Basler
8404dd57a7 Add a HoymilesRadio base class
This enables to have multiple radio implementations while the inverter classes just refere to the base class
2023-04-15 10:55:47 +02:00
Thomas Basler
a7e9aaa862 Move reference to the radio instance into the inverter instance
This is required to support different radios for different inverters
2023-04-15 10:55:47 +02:00
Thomas Basler
c2e4c5d43e Added first implementation of HMS inverter classes 2023-04-15 10:55:47 +02:00
Thomas Basler
a252d2ac3a Added CMT2300 driver 2023-04-15 10:55:47 +02:00
Thomas Basler
3cbb2ac1e2 Merge branch 'pr805' into dev 2023-04-14 19:11:58 +02:00
Marc-Philip
a554423d39
one more typo 2023-04-14 08:14:23 +02:00
Thomas Basler
5d289dac47 vscode: Recommend additional extensions for development 2023-04-13 19:21:29 +02:00
Marc-Philip
16877a8ea3
fix typo 2023-04-13 09:18:07 +02:00
387 changed files with 28053 additions and 10982 deletions

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
# http://editorconfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

View File

@ -5,11 +5,18 @@ body:
- type: markdown
attributes:
value: >
### ✋ **This is bug tracker, not a support forum**
### ⚠️ Please remember: issues are for *bugs*
That is, something you believe affects every single user of OpenDTU, not just you. If you're not sure, start with one of the other options below.
- type: markdown
attributes:
value: |
#### Have a question? 👉 [Start a new discussion](https://github.com/tbnobody/OpenDTU/discussions/new) or [ask in chat](https://discord.gg/WzhxEY62mB).
If something isn't working right, you have questions or need help, [**get in touch on the Discussions**](https://github.com/tbnobody/OpenDTU/discussions).
#### Before opening an issue, please double check:
Please quickly search existing issues first before submitting a bug.
- [Documentation](https://www.opendtu.solar).
- [The FAQs](https://www.opendtu.solar/firmware/faq/).
- [Existing issues and discussions](https://github.com/tbnobody/OpenDTU/search?q=&type=issues).
- type: textarea
id: what-happened
attributes:
@ -40,7 +47,8 @@ body:
label: Install Method
description: How did you install OpenDTU?
options:
- Pre-Compiled binary from GitHub
- Pre-Compiled binary from GitHub releases
- Pre-Compiled binary from GitHub actions/pull-request
- Self-Compiled
validations:
required: true
@ -52,6 +60,14 @@ body:
placeholder: "e.g. 359d513"
validations:
required: true
- type: input
id: environment
attributes:
label: What firmware variant (PIO Environment) are you using?
description: You can find this in by going to Info -> System
placeholder: "generic_esp32s3_usb"
validations:
required: true
- type: textarea
id: logs
attributes:
@ -65,4 +81,17 @@ body:
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
required: false
- type: checkboxes
id: required-checks
attributes:
label: Please confirm the following
options:
- label: I believe this issue is a bug that affects all users of OpenDTU, not something specific to my installation.
required: true
- label: I have already searched for relevant existing issues and discussions before opening this report.
required: true
- label: I have updated the title field above with a concise description.
required: true
- label: I have double checked that my inverter does not contain a W in the model name (like HMS-xxxW) as they are not supported.
required: true

View File

@ -15,17 +15,17 @@ jobs:
name: Gather Environments
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache pip
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
@ -37,26 +37,26 @@ jobs:
- name: Get default environments
id: envs
run: |
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
echo "environments=$(pio project config --json-output | jq -cr '.[1][1][0][1]|split(",")')" >> $GITHUB_OUTPUT
outputs:
environments: ${{ steps.envs.outputs.environments }}
build:
name: Build Enviornments
name: Build Environments
runs-on: ubuntu-latest
needs: get_default_envs
strategy:
matrix:
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Get tags
run: git fetch --force --tags origin
- name: Cache pip
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
@ -64,33 +64,42 @@ jobs:
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
pip install --upgrade platformio setuptools
- name: Enable Corepack
run: |
cd webapp
corepack enable
- name: Setup Node.js and yarn
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "18"
node-version: "22"
cache: "yarn"
cache-dependency-path: "webapp/yarn.lock"
- name: Install WebApp dependencies
run: yarn --cwd webapp install --frozen-lockfile
run: |
cd webapp
yarn install --frozen-lockfile
- name: Build WebApp
run: yarn --cwd webapp build
run: |
cd webapp
yarn build
- name: Build firmware
run: pio run -e ${{ matrix.environment }}
@ -98,17 +107,15 @@ jobs:
- name: Rename Firmware
run: mv .pio/build/${{ matrix.environment }}/firmware.bin .pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.bin
- name: Copy boot_app0.bin
run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio/build/${{ matrix.environment }}/boot_app0.bin
- name: Rename Factory Firmware
run: mv .pio/build/${{ matrix.environment }}/firmware.factory.bin .pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.factory.bin
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: opendtu-${{ matrix.environment }}
path: |
.pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.bin
.pio/build/${{ matrix.environment }}/partitions.bin
.pio/build/${{ matrix.environment }}/bootloader.bin
.pio/build/${{ matrix.environment }}/boot_app0.bin
.pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.factory.bin
release:
name: Create Release
@ -117,11 +124,11 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Build Changelog
id: github_release
uses: mikepenz/release-changelog-builder-action@v3.7.0
uses: mikepenz/release-changelog-builder-action@v4
with:
failOnError: true
commitMode: true
@ -129,20 +136,18 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: artifacts/
- name: Create ZIPs
- name: Move all files to the same location
run: |
ls -R
sudo apt install zip
cd artifacts
for i in */; do zip -r "${i%/}.zip" "$i"; done
for i in */; do cp ${i}opendtu-*.bin ./; done
- name: Create release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
body: ${{steps.github_release.outputs.changelog}}
draft: False

View File

@ -18,6 +18,12 @@
"fix"
]
},
{
"title": "## 🌎 Web Application",
"labels": [
"webapp"
]
},
{
"title": "## 📚 Documentation",
"labels": [

View File

@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install dependencies
@ -18,4 +18,4 @@ jobs:
pip install cpplint
- name: Linting
run: |
cpplint --repository=. --recursive --filter=-runtime/references,-readability/braces,-whitespace,-legal,-build/include ./src ./include ./lib/Hoymiles ./lib/MqttSubscribeParser ./lib/TimeoutHelper ./lib/ResetReason
cpplint --repository=. --recursive --filter=-build/c++11,-runtime/references,-readability/braces,-whitespace,-legal,-build/include ./src ./include ./lib/Hoymiles ./lib/MqttSubscribeParser ./lib/TimeoutHelper ./lib/ResetReason

54
.github/workflows/repo-maintenance.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: 'Repository Maintenance'
on:
schedule:
- cron: '0 4 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
discussions: write
concurrency:
group: lock
jobs:
stale:
name: 'Stale'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-stale: 14
days-before-close: 60
any-of-labels: 'cant-reproduce,not a bug'
stale-issue-label: stale
stale-pr-label: stale
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
lock-threads:
name: 'Lock Old Threads'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
issue-inactive-days: '30'
pr-inactive-days: '30'
discussion-inactive-days: '30'
log-output: true
issue-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion or issue for related concerns.
pr-comment: >
This pull request has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion or issue for related concerns.
discussion-comment: >
This discussion has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new discussion for related concerns.

View File

@ -6,17 +6,23 @@ jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: webapp
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable
- name: Setup Node.js and yarn
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "18"
node-version: "22"
cache: "yarn"
cache-dependency-path: "webapp/yarn.lock"
- name: Install WebApp dependencies
run: yarn --cwd webapp install --frozen-lockfile
run: yarn install --frozen-lockfile
- name: Linting
run: yarn --cwd webapp lint
run: yarn lint

28
.github/workflows/yarnprettier.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: Yarn Prettier
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: webapp
steps:
- uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable
- name: Setup Node.js and yarn
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "yarn"
cache-dependency-path: "webapp/yarn.lock"
- name: Install WebApp dependencies
run: yarn install --frozen-lockfile
- name: Check Formatting
run: yarn prettier --check src/

1
.gitignore vendored
View File

@ -5,5 +5,6 @@
.vscode/ipch
.vscode/settings.json
platformio-device-monitor*.log
logs/device-monitor*.log
platformio_override.ini
.DS_Store

View File

@ -2,6 +2,9 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"DavidAnson.vscode-markdownlint",
"EditorConfig.EditorConfig",
"Vue.volar",
"platformio.platformio-ide"
],
"unwantedRecommendations": [

294
README.md
View File

@ -13,76 +13,23 @@ If you are upgrading from a version before 15.03.2023 you have to upgrade the pa
This project was started from [this](https://www.mikrocontroller.net/topic/525778) discussion (Mikrocontroller.net).
It was the goal to replace the original Hoymiles DTU (Telemetry Gateway) with their cloud access. With a lot of reverse engineering the Hoymiles protocol was decrypted and analyzed.
## Screenshots
## Documentation
Several screenshots of the frontend can be found here: [Screenshots](docs/screenshots/README.md)
## Builds
Different builds from existing installations can be found here [Builds](docs/builds/README.md)
Like to show your own build? Just send me a Pull Request.
## Currently supported Inverters
* Hoymiles HM-300
* Hoymiles HM-350
* Hoymiles HM-400
* Hoymiles HM-600
* Hoymiles HM-700
* Hoymiles HM-800
* Hoymiles HM-1000
* Hoymiles HM-1200
* Hoymiles HM-1500
* Solenso SOL-H350
* Solenso SOL-H400
* Solenso SOL-H800
* TSUN TSOL-M350 (Maybe depending on firmware/serial number on the inverter)
* TSUN TSOL-M800 (Maybe depending on firmware/serial number on the inverter)
* TSUN TSOL-M1600 (Maybe depending on firmware/serial number on the inverter)
**TSUN compatibility remark:**
Compatibility with OpenDTU seems to be related to serial numbers. Current findings indicate that TSUN inverters with a serial number starting with "11" are supported, whereby inverters with a serial number starting with "10" are not.
Firmware version seems to play not a significant role and cannot be read from the stickers. For completeness, the following firmware version have been reported to work with OpenDTU:
* v1.0.8, v1.0.10 TSOL-M800 (DE)
* v1.0.12 TSOL-M1600
## Features for end users
* Read live data from inverter
* Show inverters internal event log
* Show inverter information like firmware version, firmware build date, hardware revision and hardware version
* Show and set the current inverter limit
* Function to turn the inverter off and on
* Uses ESP32 microcontroller and NRF24L01+
* Multi-Inverter support
* MQTT support (with TLS)
* Home Assistant MQTT Auto Discovery support
* Nice and fancy WebApp with visualization of current data
* Firmware upgrade using the web UI
* Default source supports up to 10 inverters
* Time zone support
* Ethernet support
* Prometheus API endpoint (/api/prometheus/metrics)
* English, german and french web interface
* Displays (SSD1306, SH1106, PCD8544)
* Dark Theme
## Features for developers
* The microcontroller part
* Build with Arduino PlatformIO Framework for the ESP32
* Uses a fork of [ESPAsyncWebserver](https://github.com/yubox-node-org/ESPAsyncWebServer) and [espMqttClient](https://github.com/bertmelis/espMqttClient)
* The WebApp part
* Build with [Vue.js](https://vuejs.org)
* Source is written in TypeScript
The documentation can be found [here](https://tbnobody.github.io/OpenDTU-docs/).
Please feel free to support and create a PR in [this](https://github.com/tbnobody/OpenDTU-docs) repository to make the documentation even better.
## Breaking changes
Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | grep BREAKING`
```code
* 1b637f08 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
* e1564780 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
* f0b5542c 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
* c27ecc36 2024-01-29 BREAKING CHANGE: Web API Endpoint /api/livedata/status
* 71d1b3b 2023-11-07 BREAKING CHANGE: Home Assistant Auto Discovery to new naming scheme
* 04f62e0 2023-04-20 BREAKING CHANGE: Web API Endpoint /api/eventlog/status no nested serial object
* 59f43a8 2023-04-17 BREAKING CHANGE: Web API Endpoint /api/devinfo/status requires GET parameter inv=
* 318136d 2023-03-15 BREAKING CHANGE: Updated partition table: Make sure you have a configuration backup and completly reflash the device!
* 3b7aef6 2023-02-13 BREAKING CHANGE: Web API!
* d4c838a 2023-02-06 BREAKING CHANGE: Prometheus API!
@ -91,223 +38,6 @@ Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | gre
* 27ed4e3 2022-10-31 BREAKING: Change power factor from percent value to value between 0 and 1
```
## Hardware you need
## Currently supported Inverters
### ESP32 board
For ease of use, buy a "ESP32 DEVKIT DOIT" or "ESP32 NodeMCU Development Board" with an ESP32-S3 or ESP-WROOM-32 chipset on it.
Sample Picture:
![NodeMCU-ESP32](docs/nodemcu-esp32.png)
Also supported: Board with Ethernet-Connector and Power-over-Ethernet [Olimex ESP32-POE](https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware)
### NRF24L01+ radio board
The PLUS sign is IMPORTANT! There are different variants available, with antenna on the printed circuit board or external antenna.
Sample picture:
![nrf24l01plus](docs/nrf24l01plus.png)
Buy your hardware from a trusted source, at best from a dealer/online shop in your country where you have support and the right to return non-functional hardware.
When you want to buy from Amazon, AliExpress, eBay etc., take note that there is a lot of low-quality or fake hardware offered. Read customer comments and ratings carefully!
A heavily incomplete list of trusted hardware shops in germany is:
* [AZ-Delivery](https://www.az-delivery.de/)
* [Makershop](https://www.makershop.de/)
* [Berrybase](https://www.berrybase.de/)
This list is for your convenience only, the project is not related to any of these shops.
### Power supply
Use a power suppy with 5 V and 1 A. The USB cable connected to your PC/Notebook may be powerful enough or may be not.
## Wiring up
### Schematic
![Schematic](docs/Wiring_ESP32_Schematic.png)
### Symbolic view
![Symbolic](docs/Wiring_ESP32_Symbol.png)
### Change pin assignment
Its possible to change all the pins of the NRF24L01+ module, the Display, the LED etc.
The recommend way to change the pin assignment is by creating a custom [device profile](docs/DeviceProfiles.md).
It is also possible to create a custom environment and compile the source yourself. This can be achieved by copying one of the [env:....] sections from 'platformio.ini' to 'platformio_override.ini' and editing the 'platformio_override.ini' file and add/change one or more of the following lines to the 'build_flags' parameter:
```makefile
-DHOYMILES_PIN_MISO=19
-DHOYMILES_PIN_MOSI=23
-DHOYMILES_PIN_SCLK=18
-DHOYMILES_PIN_IRQ=16
-DHOYMILES_PIN_CE=4
-DHOYMILES_PIN_CS=5
```
It is recommended to make all changes only in the 'platformio_override.ini', this is your personal copy.
## Flashing and starting up
### with Visual Studio Code
* Install [Visual Studio Code](https://code.visualstudio.com/download) (from now named "vscode")
* In Visual Studio Code, install the [PlatformIO Extension](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide)
* Install git and enable git in vscode - [git download](https://git-scm.com/downloads/) - [Instructions](https://www.jcchouinard.com/install-git-in-vscode/)
* Clone this repository (you really have to clone it, don't just download the ZIP file. During the build process the git hash gets embedded into the firmware. If you download the ZIP file a build error will occur): Inside vscode open the command palette by pressing `CTRL` + `SHIFT` + `P`. Enter `git clone`, add the repository-URL `https://github.com/tbnobody/OpenDTU`. Next you have to choose (or create) a target directory.
* In vscode, choose File --> Open Folder and select the previously downloaded source code. (You have to select the folder which contains the "platformio.ini" and "platformio_override.ini" file)
* Adjust the COM port in the file "platformio_override.ini" for your USB-to-serial-converter. It occurs twice:
* upload_port
* monitor_port
* Select the arrow button in the blue bottom status bar (PlatformIO: Upload) to compile and upload the firmware. During the compilation, all required libraries are downloaded automatically.
* Under Linux, if the upload fails with error messages "Could not open /dev/ttyUSB0, the port doesn't exist", you can check via ```ls -la /dev/tty*``` to which group your port belongs to, and then add your user this group via ```sudo adduser <yourusername> dialout``` (if you are using ```arch-linux``` use: ```sudo gpasswd -a <yourusername> uucp```, this method requires a logout/login of the affected user).
* There are two videos showing these steps:
* [Git Clone and compilation](https://youtu.be/9cA_esv3zeA)
* [Full installation and compilation](https://youtu.be/xs6TqHn7QWM)
### on the commandline with PlatformIO Core
* Install [PlatformIO Core](https://platformio.org/install/cli)
* Clone this repository (you really have to clone it, don't just download the ZIP file. During the build process the git hash gets embedded into the firmware. If you download the ZIP file a build error will occur)
* Adjust the COM port in the file "platformio_override.ini". It occurs twice:
* upload_port
* monitor_port
* build: `platformio run -e generic`
* upload to esp module: `platformio run -e generic -t upload`
* other options:
* clean the sources: `platformio run -e generic -t clean`
* erase flash: `platformio run -e generic -t erase`
### using the pre-compiled .bin files
The pre-compiled files can be found on the [github page](https://github.com/tbnobody/OpenDTU) in the tab "Actions" and the sub menu "OpenDTU Build". Just choose the latest build from the master branch (search for "master" in the blue font text but click on the white header text!). You need to be logged in with your github account to download the files.
Use a ESP32 flash tool of your choice (see next chapter) and flash the `.bin` files to the right addresses:
| Address | File |
| ---------| ---------------------- |
| 0x1000 | bootloader.bin |
| 0x8000 | partitions.bin |
| 0xe000 | boot_app0.bin |
| 0x10000 | opendtu-*.bin |
For further updates you can just use the web interface and upload the `opendtu-*.bin` file.
#### Flash with esptool.py (Linux)
```bash
esptool.py --port /dev/ttyUSB0 --chip esp32 --before default_reset --after hard_reset \
write_flash --flash_mode dout --flash_freq 40m --flash_size detect \
0x1000 bootloader.bin \
0x8000 partitions.bin \
0xe000 boot_app0.bin \
0x10000 opendtu-generic.bin
```
#### Flash with Espressif Flash Download Tool (Windows)
[Download link](https://www.espressif.com/en/support/download/other-tools)
* On startup, select Chip Type -> "ESP32" / WorkMode -> "Develop"
* Prepare all settings (see picture). Make sure to uncheck the `DoNotChgBin` option. Otherwise you may get errors like "invalid header".
* ![flash tool image](docs/esp32_flash_download_tool.png)
* Press "Erase" button on screen. Look into the terminal window, you should see dots appear. Then press the "Boot" button on the ESP32 board. Wait for "FINISH" to see if flashing/erasing is done.
* To program, press "Start" on screen, then the "Boot" button.
* When flashing is complete (FINISH appears) then press the Reset button on the ESP32 board (or powercycle ) to start the OpenDTU application.
#### Flash with ESP_Flasher (Windows)
Users report that [ESP_Flasher](https://github.com/Jason2866/ESP_Flasher/releases/) is suitable for flashing OpenDTU on Windows.
#### Flash with [ESP_Flasher](https://espressif.github.io/esptool-js/) - web version
It is also possible to flash it via the web tools which might be more convenient and is platform independent.
## First configuration
* After the initial flashing of the microcontroller, an Access Point called "OpenDTU-*" is opened. The default password is "openDTU42".
* Use a web browser to open the address [http://192.168.4.1](http://192.168.4.1)
* Navigate to Settings --> Network Settings and enter your WiFi credentials. The username to access the config menu is "admin" and the password the same as for accessing the Access Point (default: "openDTU42").
* OpenDTU then simultaneously connects to your WiFi AP with these credentials. Navigate to Info --> Network and look into section "Network Interface (Station)" for the IP address received via DHCP.
* If your WiFi AP uses an allow-list for MAC-addresses, please be aware that the ESP32 has two different MAC addresses for its AP and client modes, they are also listed at Info --> Network.
* When OpenDTU is connected to a configured WiFI AP, the "OpenDTU-*" Access Point is closed after 3 minutes.
* OpenDTU needs access to a working NTP server to get the current date & time. Both are sent to the inverter with each request. Default NTP server is pool.ntp.org. If your network has different requirements please change accordingly (Settings --> NTP Settings).
* Add your inverter in the inverter settings (Settings --> Inverter Settings)
## Flashing an Update using "Over The Air" OTA Update
Once you have your OpenDTU running and connected to WLAN, you can do further updates through the web interface.
Navigate to Settings --> Firmware upgrade and press the browse button. Select the firmware file from your local computer.
You'll find the firmware file (after a successful build process) under `.pio/build/generic/firmware.bin`.
If you downloaded a precompiled zip archive, unpack it and choose `opendtu-generic.bin`.
After the successful upload, the OpenDTU immediately restarts into the new firmware.
## MQTT Topic Documentation
A documentation of all available MQTT Topics can be found here: [MQTT Documentation](docs/MQTT_Topics.md)
## Web API Documentation
A documentation of the Web API can be found here: [Web-API Documentation](docs/Web-API.md)
## Available cases
* <https://www.thingiverse.com/thing:5435911>
* <https://www.printables.com/model/293003-sol-opendtu-esp32-nrf24l01-case>
* <https://www.thingiverse.com/thing:5661780>
* <https://www.thingiverse.com/thing:5632374>
* <https://www.thingiverse.com/thing:5852233>
* <https://www.printables.com/model/377994-opendtu-pcb-box-for-the-wider-board>
* <https://www.printables.com/model/376840-esp32-ahoy-opendtu-pcb-housing>
## Available layouts for printed circuit boards
* [BreakoutBoard - sample printed circuit board for OpenDTU and Ahoy](https://github.com/dokuhn/openDTU-BreakoutBoard)
* [Board for OpenDTU with Display](https://github.com/SteffMUC/openDTU_wDisplay2)
* [OpenDTU PCB mit Display](https://github.com/turrican944/OpenDTU-PCB)
* [PCB for OpenDTU in Cable Branchbox](https://github.com/plewka/ESP-Solar_OpenDTU)
## Building
* Building the WebApp
* The WebApp can be build using yarn
```bash
cd webapp
yarn install
yarn build
```
* The updated output is placed in the 'webapp_dist' directory
* It is only necessary to build the webapp when you made changes to it
* Building the microcontroller firmware
* Visual Studio Code with the PlatformIO Extension is required for building
## Troubleshooting
* First: When there is no light on the solar panels, the inverter completely turns off and does not answer to OpenDTU! So if you assembled your OpenDTU in the evening, wait until tomorrow.
* When there is no data received from the inverter(s) - try to reduce the distance between the openDTU and the inverter (e.g. move it to the window towards the roof)
* Under Settings -> DTU Settings you can increase the transmit power "PA level". Default is "minimum".
* The NRF24L01+ needs relatively much current. With bad power supply (and especially bad cables!) a 10 µF capacitor soldered directly to the NRF24L01+ board connector brings more stability (pin 1+2 are the power supply). Note the polarity of the capacitor…
* You can try to use an USB power supply with 1 A or more instead of connecting the ESP32 to the computer.
* Try a different USB cable. Once again, a stable power source is important. Some USB cables are made of much plastic and very little copper inside.
* Double check that you have a radio module NRF24L01+ with a plus sign at the end. NRF24L01 module without the plus are not compatible with this project.
* There is no possibility of auto-discovering the inverters. Double check you have entered the serial numbers of the inverters correctly.
* OpenDTU needs access to a working NTP server to get the current date & time.
* If your problem persists, check the [Issues on Github](https://github.com/tbnobody/OpenDTU/issues). Please inspect not only the open issues, also the closed issues contain useful information.
* Another source of information are the [Discussions](https://github.com/tbnobody/OpenDTU/discussions/)
* When flashing with VSCode Plattform.IO fails and also with ESPRESSIF tool a demo bin file cannot be flashed to the ESP32 with error message "A fatal error occurred: MD5 of file does not match data in flash!" than un-wire/unconnect ESP32 from the NRF24L01+ board. Try to flash again and rewire afterwards.
## Related Projects
* [Ahoy](https://github.com/grindylow/ahoy)
* [DTU Simulator](https://github.com/Ziyatoe/DTUsimMI1x00-Hoymiles)
* [OpenDTU extended to talk to Victrons MPPT battery chargers (Ve.Direct)](https://github.com/helgeerbe/OpenDTU_VeDirect)
A list of all currently supported inverters can be found [here](https://www.opendtu.solar/hardware/inverter_overview/)

View File

@ -1,29 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022 Thomas Basler and others
#
import pkg_resources
Import("env")
required_pkgs = {'dulwich'}
installed_pkgs = {pkg.key for pkg in pkg_resources.working_set}
missing_pkgs = required_pkgs - installed_pkgs
if missing_pkgs:
env.Execute('"$PYTHONEXE" -m pip install dulwich')
from dulwich import porcelain
def get_firmware_specifier_build_flag():
try:
build_version = porcelain.describe('.') # '.' refers to the repository root dir
except:
build_version = "g0000000"
build_flag = "-D AUTO_GIT_HASH=\\\"" + build_version + "\\\""
print ("Firmware Revision: " + build_version)
return (build_flag)
env.Append(
BUILD_FLAGS=[get_firmware_specifier_build_flag()]
)

View File

@ -1,107 +1,3 @@
# Device Profiles
It is possible to change hardware settings like pin assignments or ethernet support using a json file. The json file can be uploaded using the configuration management in the web interface. Just select "Pin Mapping (pin_mapping.json)" in the recovery section.
When the file is uploaded the ESP performs a reboot. This is required as the pin settings could have changed within the file. By default all the pin assignments are used as compiled into the firmware.
To change the device profile, navigate to the "Device Manager" and selected the appropriate profile. You can see the current (Active) and the new (Selected) in assignment in the table below the combobox.
## Structure of the json file
```json
[
{
"name": "Generic NodeMCU 38 pin",
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": -1,
"clk_mode": -1
}
},
{
"name": "Generic NodeMCU 38 pin with SSD1306",
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": -1,
"clk_mode": -1
},
"display": {
"type": 2,
"data": 21,
"clk": 22
}
},
{
"name": "Olimex ESP32-POE",
"nrf24": {
"miso": 15,
"mosi": 2,
"clk": 14,
"irq": 13,
"en": 16,
"cs": 5
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
}
}
]
```
The json file can contain multiple profiles. Each profile requires a name and different parameters. If one parameter is not set, the default value, as compiled into the firmware is used. The example above shows all the currently supported values. Others may follow. Sample files for some boards can be found [here](DeviceProfiles/). This means you can just flash the generic bin file and upload the json file. Then you select your board and everything works hopyfully as expected.
## Implemented configuration values
| Parameter | Data Type | Description |
| ------------- | --------- | ----------- |
| name | string | Unique name of the profile (max 63 characters) |
| nrf24.miso | number | MISO Pin |
| nrf24.mosi | number | MOSI Pin |
| nrf24.clk | number | Clock Pin |
| nrf24.irq | number | Interrupt Pin |
| nrf24.en | number | Enable Pin |
| nrf24.cs | number | Chip Select Pin |
| eth.enabled | boolean | Enable/Disable the ethernet stack |
| eth.phy_addr | number | Unique PHY addr |
| eth.power | number | Power Pin (if available). Use -1 for not assigned pins. |
| eth.mdc | number | Serial Management Interface MDC Pin. Use -1 for not assigned pins. |
| eth.mdio | number | Serial Management Interface MDIO Pin. Use -1 for not assigned pins. |
| eth.type | number | Possible values:<br>* 0 = ETH_PHY_LAN8720<br>* 1 = ETH_PHY_TLK110<br>* 2 = ETH_PHY_RTL8201<br>* 3 = ETH_PHY_DP83848<br>* 4 = ETH_PHY_DM9051<br>* 5 = ETH_PHY_KSZ8041<br>* 6 = ETH_PHY_KSZ8081 |
| eth.clk_mode | number | Possible values:<br>* 0 = ETH_CLOCK_GPIO0_IN<br>* 1 = ETH_CLOCK_GPIO0_OUT<br>* 2 = ETH_CLOCK_GPIO16_OUT<br>* 3 = ETH_CLOCK_GPIO17_OUT |
| display.type | number | Specify type of display. Possible values:<br>* 0 = None (default)<br>* 1 = PCD8544 <br>* 2 = SSD1306 <br>* 3 = SH1106 |
| display.data | number | Data Pin (e.g. SDA for i2c displays) required for all displays. Use 255 for not assigned pins. |
| display.clk | number | Clock Pin (e.g. SCL for i2c displays) required for SSD1306 and SH1106. Use 255 for not assigned pins. |
| display.cs | number | Chip Select Pin required for PCD8544. Use 255 for not assigned pins. |
| display.reset | number | Reset Pin required for PCD8544, optional for all other displays. Use 255 for not assigned pins. |
| led.led0 | number | LED pin for network indication. Blinking = WLAN connected but NTP & MQTT (if enabled) disconnected. On = WLAN, NTP, MQTT connected. Off = Network not connected |
| led.led1 | number | LED pin for inverter indication. On = All inverters reachable & producing. Blinking = All inverters reachable but not producing. Off = At least one inverter is not reachable. Only inverters with polling enabled are considered. |
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/device_profiles/>

View File

@ -0,0 +1,76 @@
[
{
"name": "AhoyDTU ESP32 Display LED",
"links": [
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"led": {
"led0": 25,
"led1": 26
},
"display": {
"type": 2,
"data": 21,
"clk": 22
}
},
{
"name": "AhoyDTU ESP32 Display",
"links": [
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"display": {
"type": 2,
"data": 21,
"clk": 22
}
},
{
"name": "AhoyDTU ESP32 LED",
"links": [
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"led": {
"led0": 25,
"led1": 26
}
},
{
"name": "AhoyDTU ESP32",
"links": [
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
}
}
]

View File

@ -0,0 +1,20 @@
[
{
"name": "CASmo-DTU",
"links": [
{"name": "Information", "url": "https://casmo.info/product-details/?product=2"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"led": {
"led0": 25,
"led1": 26
}
}
]

View File

@ -1,6 +1,12 @@
[
{
"name": "LEDs, Display",
"name": "NRF, LEDs, Display",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
@ -20,7 +26,47 @@
}
},
{
"name": "Only Display",
"name": "CMT, LEDs, Display",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"display": {
"type": 3,
"data": 21,
"clk": 22
},
"led": {
"led0": 25,
"led1": 26
}
},
{
"name": "NRF, Display",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
@ -36,7 +82,43 @@
}
},
{
"name": "Only LEDs",
"name": "CMT, Display",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"display": {
"type": 3,
"data": 21,
"clk": 22
}
},
{
"name": "NRF, LEDs",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
@ -51,7 +133,42 @@
}
},
{
"name": "No Output",
"name": "CMT, LEDs",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"led": {
"led0": 25,
"led1": 26
}
},
{
"name": "NRF",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": 19,
"mosi": 23,
@ -60,5 +177,30 @@
"en": 4,
"cs": 5
}
},
{
"name": "CMT",
"links": [
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
],
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
}
}
]

View File

@ -0,0 +1,25 @@
[
{
"name": "Esp32-Stick-PoE-A",
"links": [
{"name": "Information", "url": "https://github.com/allexoK/Esp32-Stick-Boards-Docs"}
],
"nrf24": {
"miso": 2,
"mosi": 15,
"clk": 14,
"irq": 34,
"en": 12,
"cs": 4
},
"eth": {
"enabled": true,
"phy_addr": 1,
"power": -1,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
}
}
]

View File

@ -0,0 +1,74 @@
[
{
"name": "LILYGO T-ETH-Lite-POE CMT",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
],
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 2,
"clk_mode": 0
},
"cmt": {
"clk": 15,
"cs": 32,
"fcs": 33,
"sdio": 4
}
},
{
"name": "LILYGO T-ETH-Lite-POE NRF24",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
],
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 2,
"clk_mode": 0
},
"nrf24": {
"miso": 34,
"mosi": 13,
"clk": 14,
"irq": 35,
"en": 4,
"cs": 2
}
},
{
"name": "LILYGO T-ETH-Lite-POE NRF24 + Display",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
],
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 2,
"clk_mode": 0
},
"nrf24": {
"miso": 34,
"mosi": 13,
"clk": 14,
"irq": 35,
"en": 4,
"cs": 2
},
"display": {
"type": 3,
"data": 32,
"clk": 33
}
}
]

View File

@ -1,6 +1,9 @@
[
{
"name": "LILYGO TTGO T-Internet-POE",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
],
"nrf24": {
"miso": 2,
"mosi": 15,
@ -18,5 +21,56 @@
"type": 0,
"clk_mode": 3
}
},
{
"name": "LILYGO TTGO T-Internet-POE, nrf24 direct solder",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
],
"nrf24": {
"miso": 12,
"mosi": 4,
"clk": 15,
"irq": 33,
"en": 14,
"cs": 2
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": -1,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
}
},
{
"name": "LILYGO TTGO T-Internet-POE, nrf24 direct solder, SSD1306",
"links": [
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
],
"nrf24": {
"miso": 12,
"mosi": 4,
"clk": 15,
"irq": 33,
"en": 14,
"cs": 2
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": -1,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
},
"display": {
"type": 2,
"data": 16,
"clk": 32
}
}
]

View File

@ -1,6 +1,6 @@
[
{
"name": "Generic NodeMCU 32",
"name": "NRF24",
"nrf24": {
"miso": 19,
"mosi": 23,
@ -10,17 +10,33 @@
"cs": 5
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
"enabled": false
}
},
{
"name": "Generic NodeMCU 32 with SSD1306",
"name": "CMT2300A",
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"eth": {
"enabled": false
}
},
{
"name": "NRF24 with SSD1306",
"nrf24": {
"miso": 19,
"mosi": 23,
@ -30,13 +46,7 @@
"cs": 5
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
"enabled": false
},
"display": {
"type": 2,
@ -45,7 +55,7 @@
}
},
{
"name": "Generic NodeMCU 32 with SH1106",
"name": "NRF24 with SH1106",
"nrf24": {
"miso": 19,
"mosi": 23,
@ -55,18 +65,131 @@
"cs": 5
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
"enabled": false
},
"display": {
"type": 3,
"data": 21,
"clk": 22
}
},
{
"name": "NRF24 with SSD1309",
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"eth": {
"enabled": false
},
"display": {
"type": 4,
"data": 21,
"clk": 22
}
},
{
"name": "CMT2300A with SSD1306",
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"eth": {
"enabled": false
},
"display": {
"type": 2,
"data": 21,
"clk": 22
}
},
{
"name": "CMT2300A with SH1106",
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"eth": {
"enabled": false
},
"display": {
"type": 3,
"data": 21,
"clk": 22
}
},
{
"name": "CMT2300A with SSD1309",
"nrf24": {
"miso": -1,
"mosi": -1,
"clk": -1,
"irq": -1,
"en": -1,
"cs": -1
},
"cmt": {
"clk": 18,
"cs": 4,
"fcs": 5,
"sdio": 23,
"gpio2": 19,
"gpio3": 16
},
"eth": {
"enabled": false
},
"display": {
"type": 4,
"data": 21,
"clk": 22
}
},
{
"name": "NRF24 + CMT2300A",
"nrf24": {
"miso": 19,
"mosi": 23,
"clk": 18,
"irq": 16,
"en": 4,
"cs": 5
},
"cmt": {
"clk": 12,
"sdio": 14,
"cs": 27,
"fcs": 26,
"gpio2": -1,
"gpio3": -1
}
}
]

View File

@ -1,6 +1,9 @@
[
{
"name": "Olimex ESP32-EVB",
"links": [
{ "name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-EVB/open-source-hardware" }
],
"nrf24": {
"miso": 15,
"mosi": 2,

View File

@ -0,0 +1,47 @@
[
{
"name": "Olimex ESP32-Gateway",
"nrf24": {
"miso": 14,
"mosi": 13,
"clk": 12,
"irq": 15,
"en": 2,
"cs": 4
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
}
},
{
"name": "Olimex ESP32-Gateway with SSH1106",
"nrf24": {
"miso": 14,
"mosi": 13,
"clk": 12,
"irq": 15,
"en": 2,
"cs": 4
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
},
"display": {
"type": 3,
"data": 32,
"clk": 16
}
}
]

View File

@ -1,6 +1,9 @@
[
{
"name": "Olimex ESP32-POE",
"links": [
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
],
"nrf24": {
"miso": 15,
"mosi": 2,
@ -21,6 +24,9 @@
},
{
"name": "Olimex ESP32-POE with SSD1306",
"links": [
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
],
"nrf24": {
"miso": 15,
"mosi": 2,
@ -46,6 +52,9 @@
},
{
"name": "Olimex ESP32-POE with SH1106",
"links": [
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
],
"nrf24": {
"miso": 15,
"mosi": 2,
@ -64,7 +73,35 @@
"clk_mode": 3
},
"display": {
"type": 2,
"type": 3,
"data": 33,
"clk": 32
}
},
{
"name": "Olimex ESP32-POE with SSD1309",
"links": [
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
],
"nrf24": {
"miso": 15,
"mosi": 2,
"clk": 14,
"irq": 13,
"en": 16,
"cs": 5
},
"eth": {
"enabled": true,
"phy_addr": 0,
"power": 12,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 3
},
"display": {
"type": 4,
"data": 33,
"clk": 32
}

View File

@ -0,0 +1,325 @@
[
{
"name": "OpenDTU Fusion v1",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
}
},
{
"name": "OpenDTU Fusion v1 with SSD1306 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 2,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v1 with SH1106 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 3,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v2 with CMT2300A and NRF24",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
}
},
{
"name": "OpenDTU Fusion v2 with CMT2300A, NRF24 and SH1106 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 3,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v2 with CMT2300A, NRF24 and SSD1306 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"eth": {
"enabled": false,
"phy_addr": -1,
"power": -1,
"mdc": -1,
"mdio": -1,
"type": 0,
"clk_mode": 0
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 2,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v2 PoE",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"w5500": {
"mosi": 40,
"miso": 41,
"sclk": 39,
"cs": 42,
"int": 44,
"rst": 43
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 0,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v2 PoE with SH1106 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"w5500": {
"mosi": 40,
"miso": 41,
"sclk": 39,
"cs": 42,
"int": 44,
"rst": 43
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 3,
"data": 2,
"clk": 1
}
},
{
"name": "OpenDTU Fusion v2 PoE with SSD1306 Display",
"links": [
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
],
"nrf24": {
"miso": 48,
"mosi": 35,
"clk": 36,
"irq": 47,
"en": 38,
"cs": 37
},
"cmt": {
"clk": 6,
"cs": 4,
"fcs": 21,
"sdio": 5,
"gpio2": 3,
"gpio3": 8
},
"w5500": {
"mosi": 40,
"miso": 41,
"sclk": 39,
"cs": 42,
"int": 44,
"rst": 43
},
"led": {
"led0": 17,
"led1": 18
},
"display": {
"type": 2,
"data": 2,
"clk": 1
}
}
]

View File

@ -0,0 +1,21 @@
[
{
"name": "Wemos Lolin32 OLED",
"nrf24": {
"miso": 2,
"mosi": 14,
"clk": 12,
"irq": 0,
"en": 15,
"cs": 13
},
"eth": {
"enabled": false
},
"display": {
"type": 2,
"data": 5,
"clk": 4
}
}
]

View File

@ -1,6 +1,9 @@
[
{
"name": "WT32-ETH01",
"links": [
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
],
"nrf24": {
"miso": 4,
"mosi": 2,
@ -18,5 +21,89 @@
"type": 0,
"clk_mode": 0
}
},
{
"name": "WT32-ETH01 with SH1106",
"links": [
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
],
"nrf24": {
"miso": 4,
"mosi": 2,
"clk": 32,
"irq": 33,
"en": 14,
"cs": 15
},
"eth": {
"enabled": true,
"phy_addr": 1,
"power": 16,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 0
},
"display": {
"type": 3,
"data": 5,
"clk": 17
}
},
{
"name": "WT32-ETH01 with SSD1306",
"links": [
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
],
"nrf24": {
"miso": 4,
"mosi": 2,
"clk": 32,
"irq": 33,
"en": 14,
"cs": 15
},
"eth": {
"enabled": true,
"phy_addr": 1,
"power": 16,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 0
},
"display": {
"type": 2,
"data": 5,
"clk": 17
}
},
{
"name": "WT32-ETH01 with SSD1309",
"links": [
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
],
"nrf24": {
"miso": 4,
"mosi": 2,
"clk": 32,
"irq": 33,
"en": 14,
"cs": 15
},
"eth": {
"enabled": true,
"phy_addr": 1,
"power": 16,
"mdc": 23,
"mdio": 18,
"type": 0,
"clk_mode": 0
},
"display": {
"type": 4,
"data": 5,
"clk": 17
}
}
]
]

View File

@ -1,20 +1,3 @@
# Display integration
OpenDTU currently supports 3 types of displays (SSD1306, SH1106 and PCD8544). Currently only displays with a resolution of 128x64 pixel are supported. To activate a display you have to specify it's type and pin assignment either in the `platformio_override.ini` or in a device profile. Due to the fact that device profiles work with the pre-compiled binary the following documentation will only cover the device profile method.
You can either create your own device profile as described [here](DeviceProfiles.md) or use some pre-defined. The pre-defined profiles can be found [here](DeviceProfiles/). You can simply open the json file with a text editor of your choice to view/edit the pin assignment.
## Uploading Device Profiles
Use the "Config Management" site to upload (Restore) the json file. Make sure to choose "Pin Mapping (pin_mapping.json)" in the combo box. After you click on restore the ESP will restart. At this point, the profile is not yet active. Please read the next chapter.
![Config Management](screenshots/14_ConfigManagement.png)
## Selecting a Device Profile
After you uploaded the device profile you can select the profile in the "Device Manager" view. After a click on "Save" the ESP will be restarted and the pin assignment is active. At this point the display should already show something. Please see the next chapter for display settings.
![Device Manager](screenshots/20_DeviceManager_Pin.png)
## Display Settings
Display settings can also be found in the "Device Manager".
![Device Manager Display](screenshots/21_DeviceManager_Display.png)
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/hardware/display/>

View File

@ -1,74 +1,3 @@
# MQTT Topics
The base topic, as configured in the web GUI is prepended to all follwing topics.
## General topics
| Topic | R / W | Description | Value / Unit |
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| dtu/ip | R | IP address of OpenDTU | IP address |
| dtu/hostname | R | Current hostname of the dtu (as set in web GUI) | |
| dtu/rssi | R | WiFi network quality | db value |
| dtu/status | R | Indicates whether OpenDTU network is reachable | online / offline |
| dtu/uptime | R | Time in seconds since startup | seconds |
## Inverter specific topics
serial will be replaced with the serial number of the inverter.
| Topic | R / W | Description | Value / Unit |
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| [serial]/name | R | Name of the inverter as configured in web GUI | |
| [serial]/device/bootloaderversion | R | Bootloader version of the inverter | |
| [serial]/device/fwbuildversion | R | Firmware version of the inverter | |
| [serial]/device/fwbuilddatetime | R | Build date / time of inverter firmware | |
| [serial]/device/hwpartnumber | R | Hardware part number of the inverter | |
| [serial]/device/hwversion | R | Hardware version of the inverter | |
| [serial]/status/reachable | R | Indicates whether the inverter is reachable | 0 or 1 |
| [serial]/status/producing | R | Indicates whether the inverter is producing AC power | 0 or 1 |
| [serial]/status/last_update | R | Unix timestamp of last inverter statistics udpate | seconds since JAN 01 1970 (UTC) |
### AC channel / global specific topics
| Topic | R / W | Description | Value / Unit |
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| [serial]/0/current | R | AC current in ampere | Ampere (A) |
| [serial]/0/efficiency | R | Ratio AC Power over DC Power in percent | % |
| [serial]/0/frequency | R | AC frequency in hertz | Hertz (Hz) |
| [serial]/0/power | R | AC active power in watts | Watt (W) |
| [serial]/0/powerdc | R | DC power in watts | Watt (W) |
| [serial]/0/powerfactor | R | Power factor in percent | % |
| [serial]/0/reactivepower | R | AC reactive power in VAr | VAr |
| [serial]/0/temperature | R | Temperature of inverter in degree celsius | Degree Celsius (°C) |
| [serial]/0/voltage | R | AC voltage in volt | Volt (V) |
| [serial]/0/yieldday | R | Energy converted to AC per day in watt hours | Watt hours (Wh) |
| [serial]/0/yieldtotal | R | Energy converted to AC since reset watt hours | Kilo watt hours (kWh) |
### DC input channel topics
[1-4] represents the different inputs. The amount depends on the inverter model.
| Topic | R / W | Description | Value / Unit |
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| [serial]/[1-4]/current | R | DC current of specific input in ampere | Ampere (A) |
| [serial]/[1-4]/name | R | Name of the DC input channel as configured in web GUI| |
| [serial]/[1-4]/irradiation | R | Ratio DC Power over set maximum power (in web GUI) | % |
| [serial]/[1-4]/power | R | DC power of specific input in watt | Watt (W) |
| [serial]/[1-4]/voltage | R | DC voltage of specific input in volt | Volt (V) |
| [serial]/[1-4]/yieldday | R | Energy converted to AC per day on specific input | Watt hours (Wh) |
| [serial]/[1-4]/yieldtotal | R | Energy converted to AC since reset on specific input | Kilo watt hours (kWh) |
### Inverter limit specific topics
cmd topics are used to set values. Status topics are updated from values set in the inverter.
| Topic | R / W | Description | Value / Unit |
| ----------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| [serial]/status/limit_relative | R | Current applied production limit of the inverter | % of total possible output |
| [serial]/status/limit_absolute | R | Current applied production limit of the inverter | Watt (W) |
| [serial]/cmd/limit_persistent_relative | W | Set the inverter limit as a percentage of total production capability. The value will survive the night without power. The updated value will show up in the web GUI and limit_relative topic immediatly. | % |
| [serial]/cmd/limit_persistent_absolute | W | Set the inverter limit as a absolute value. The value will survive the night without power. The updated value will set immediatly within the inverter but show up in the web GUI and limit_relative topic after around 4 minutes. If you are using a already known inverter (known Hardware ID), the updated value will show up within a few seconds. | Watt (W) |
| [serial]/cmd/limit_nonpersistent_relative | W | Set the inverter limit as a percentage of total production capability. The value will reset to the last persistent value at night without power. The updated value will show up in the web GUI and limit_relative topic immediatly. The value must be published non-retained, otherwise it will be ignored! | % |
| [serial]/cmd/limit_nonpersistent_absolute | W | Set the inverter limit as a absolute value. The value will reset to the last persistent value at night without power. The updated value will set immediatly within the inverter but show up in the web GUI and limit_relative topic after around 4 minutes. If you are using a already known inverter (known Hardware ID), the updated value will show up within a few seconds. The value must be published non-retained, otherwise it will be ignored! | Watt (W) |
| [serial]/cmd/power | W | Turn the inverter on (1) or off (0) | 0 or 1 |
| [serial]/cmd/restart | W | Restarts the inverters (also resets YieldDay) | 1 |
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/mqtt_topics/>

View File

@ -1,24 +1,3 @@
# Upgrade Partition
To be able to install further updates you have to update the partition table of the ESP32. Doing so will **erase** all configuration data. Over The Air update using the web interface is **NOT** possible!
**So make sure you export a backup of your configuration files before continuing.**
There are several possibilities to update the partition table:
- Using Visual Studio Code or PlatformIO CLI
If you have already used Visual Studio Code or the `platformio` command you can use it again to install the latest version. The partition table is upgraded automatically.
- Any kind of flash interface
If you like to use any kind of flash interface like `esptool.py`, Espressif Flash Download Tool, ESP_Flasher or esptool-js you have to make sure to upload **ALL** provided .bin files. It is important to enter the correct target addresses.
| Address | File |
| ---------| ---------------------- |
| 0x1000 | bootloader.bin |
| 0x8000 | partitions.bin |
| 0xe000 | boot_app0.bin |
| 0x10000 | opendtu-*.bin |
After upgrading the ESP32 will open the intergrated access point (AP) again. Just connect to it using the default password ("openDTU42"). If you are connected, just visit <http://192.168.4.1> and enter the "Configuration Management". Recover the previously backuped config files.
This documentation has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/howto/upgrade_partition/>

View File

@ -1,564 +1,3 @@
# Web API
Information in JSON format can be obtained through the web API
## List of URLs
may be incomplete
| GET/POST | Auth required | URL |
| -------- | --- | -- |
| Get | yes | /api/config/get |
| Post | yes | /api/config/delete |
| Get | yes | /api/config/list |
| Post | yes | /api/config/upload |
| Get+Post | yes | /api/device/config |
| Get | no | /api/devinfo/status |
| Get+Post | yes | /api/dtu/config |
| Get | no | /api/eventlog/status?inv=inverter-serialnumber |
| Post | yes | /api/firmware/update |
| Get | yes | /api/inverter/list |
| Post | yes | /api/inverter/add |
| Post | yes | /api/inverter/del |
| Post | yes | /api/inverter/edit |
| Post | yes | /api/limit/config |
| Get | no | /api/limit/status |
| Get | no | /api/livedata/status |
| Post | yes | /api/maintenance/reboot |
| Get+Post | yes | /api/mqtt/config |
| Get | no | /api/mqtt/status |
| Get+Post | yes | /api/network/config |
| Get | no | /api/network/status |
| Get+Post | yes | /api/ntp/config |
| Get | no | /api/ntp/status |
| Get+Post | yes | /api/ntp/time |
| Get | no | /api/power/status |
| Post | yes | /api/power/config |
| Get | no | /api/prometheus/metrics |
| Get+Post | yes | /api/security/config |
| Get | yes | /api/security/authenticate |
| Get | no | /api/system/status |
## Examples of Use
### Important notes
- IP addresses and serial numbers in this examples are anonymized. Adjust to your own needs.
- The output from curl is without a linefeed at the end, so please be careful when copying the output - do not accidentally add the shell prompt directly after it.
- When POSTing config data to OpenDTU, always send all settings back, even if only one setting was changed. Sending single settings is not supported and you will receive a response `{"type":"warning","message":"Values are missing!"}`
- When POSTing, always put single quotes around the data part. Do not confuse the single quote `'` with the backtick `` ` ``. You have been warned.
- Some API calls have a single URL for GET and POST - e.g. `/api/ntp/config`
- Other API calls use e.g. `/api/limit/status` to GET data and a different URL `/api/limit/config` to POST data.
- If you want to investigate the web api communication, a good tool is [Postman](https://www.postman.com/)
- Settings API require username and password provided with Basic Authentication credentials
- If you disable the readonly access to the web API, every endpoint requires authentication
### Get information
You can "talk" to the OpenDTU with a command line tool like `curl`. The output is in plain JSON, without carriage return/linefeed and is therefore not very human readable.
#### Get current livedata
```bash
$ curl http://192.168.10.10/api/livedata/status
{"inverters":[{"serial":"11617160xxxx","name":"Meine Solaranlage","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"2":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"3":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0},{"serial":"11417160xxxx","name":"test","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"test 1"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":"test 2"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":2}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}}
```
To enhance readability (and filter information) use the JSON command line processor `jq`.
```bash
$ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq
{
"inverters": [
{
"serial": "116171603546",
"name": "Meine Solaranlage",
"data_age": 7038,
"reachable": false,
"producing": false,
"limit_relative": 0,
"limit_absolute": -1,
"AC": {
"0": {
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"Power DC": {
"v": 0,
"u": "W",
"d": 1
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Frequency": {
"v": 0,
"u": "Hz",
"d": 2
},
"PowerFactor": {
"v": 0,
"u": "",
"d": 3
},
"ReactivePower": {
"v": 0,
"u": "var",
"d": 1
},
"Efficiency": {
"v": 0,
"u": "%",
"d": 3
}
}
},
"DC": {
"0": {
"name": {
"u": ""
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Irradiation": {
"v": 0,
"u": "%",
"d": 3
}
},
"1": {
"name": {
"u": ""
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Irradiation": {
"v": 0,
"u": "%",
"d": 3
}
},
"2": {
"name": {
"u": ""
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Irradiation": {
"v": 0,
"u": "%",
"d": 3
}
},
"3": {
"name": {
"u": ""
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
}
}
},
"INV": {
"0": {
"Temperature": {
"v": 0,
"u": "°C",
"d": 1
}
}
},
"events": 0
},
{
"serial": "114171603548",
"name": "test",
"data_age": 7038,
"reachable": false,
"producing": false,
"limit_relative": 0,
"limit_absolute": -1,
"AC": {
"0": {
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"Power DC": {
"v": 0,
"u": "W",
"d": 1
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Frequency": {
"v": 0,
"u": "Hz",
"d": 2
},
"PowerFactor": {
"v": 0,
"u": "",
"d": 3
},
"ReactivePower": {
"v": 0,
"u": "var",
"d": 1
},
"Efficiency": {
"v": 0,
"u": "%",
"d": 3
}
}
},
"DC": {
"0": {
"name": {
"u": "test 1"
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Irradiation": {
"v": 0,
"u": "%",
"d": 3
}
},
"1": {
"name": {
"u": "test 2"
},
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"Voltage": {
"v": 0,
"u": "V",
"d": 1
},
"Current": {
"v": 0,
"u": "A",
"d": 2
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 3
},
"Irradiation": {
"v": 0,
"u": "%",
"d": 3
}
}
},
"INV": {
"0": {
"Temperature": {
"v": 0,
"u": "°C",
"d": 1
}
}
},
"events": 0
}
],
"total": {
"Power": {
"v": 0,
"u": "W",
"d": 1
},
"YieldDay": {
"v": 0,
"u": "Wh",
"d": 0
},
"YieldTotal": {
"v": 0,
"u": "kWh",
"d": 2
}
},
"hints": {
"time_sync": false,
"radio_problem": false,
"default_password": false
}
}
```
The eventlog can be fetched with the inverter serial number as parameter:
```bash
$ curl --no-progress-meter http://192.168.10.10/api/eventlog/status?inv=11418186xxxx | jq
{
"11418186xxxx": {
"count": 4,
"events": [
{
"message_id": 1,
"message": "Inverter start",
"start_time": 28028,
"end_time": 28028
},
{
"message_id": 209,
"message": "PV-1: No input",
"start_time": 28036,
"end_time": 0
},
{
"message_id": 2,
"message": "DTU command failed",
"start_time": 28092,
"end_time": 28092
},
{
"message_id": 207,
"message": "MPPT-A: Input undervoltage",
"start_time": 28336,
"end_time": 0
}
]
}
}
```
#### combine curl and jq
`jq` can filter specific fields from json output.
For example, filter out the current total power:
```bash
$ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq '.total | .Power.v'
140.7999878
```
#### Get information where login is required
When config data is requested, username and password have to be provided to `curl`
Username is always `admin`, the default password is `openDTU42`. The password is used for both the admin login and the Admin-mode Access Point.
```bash
$ curl --u admin:openDTU42 http://192.168.10.10/api/ntp/config
{"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}
```
### Post information
With HTTP POST commands information can be written to the OpenDTU.
The Web API is designed to allow the web frontend in the web browser to communicate with the OpenDTU software running on the ESP32. It is not designed to be intuitive or user-friendly, so please follow the instructions here.
#### Example 1: change ntp settings
If you want to configure the ntp server setting, first fetch the information from the web API:
```bash
$ curl -u "admin:password" http://192.168.10.10/api/ntp/config
{"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}
```
Then, second step, send your new settings. Use the text output from curl in the first step, add `data=` and enclose the whole data with single quotes.
```bash
$ curl -u "admin:password" http://192.168.10.10/api/ntp/config -d 'data={"ntp_server":"my.own.ntp.server.home","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}'
{"type":"success","message":"Settings saved!"}
```
You will receive a json formatted response.
#### Example 2: change power limit
In the second example, I want to change the non persistent power limit of an inverter. Again, first fetch current data:
```bash
$ curl http://192.168.10.10/api/limit/status
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Ok"}}
```
I see data from two configured inverters.
Now I set the relative power limit of inverter with serialnumber `11418180xxxx` to 50%.
```bash
$ curl -u "admin:password" http://192.168.10.10/api/limit/config -d 'data={"serial":"11418180xxxx", "limit_type":1, "limit_value":50}'
{"type":"success","message":"Settings saved!"}
```
Then I read again the limit status. In the first answer the status is `pending`, some seconds later it changed to `OK`.
```bash
$ curl http://192.168.10.10/api/limit/status
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Pending"}}
...
$ curl http://192.168.10.10/api/limit/status
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":50,"max_power":800,"limit_set_status":"Ok"}}
```
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/web_api/>

View File

@ -1,6 +1,15 @@
# Builds using different boards
## ESP32 Dev Board
### Build by @tbnobody, jan and @marove2000
* Used build environment: generic
* Case: https://www.printables.com/de/model/441037-opendtu-breakoutboard-case
* Soldering Kit: https://shop.blinkyparts.com/en/OpenDTU-Breakoutboard-Your-evaluation-for-your-balcony-solar-system/blink237542
* Breakout board: https://github.com/marove2000/openDTU_BreakoutBoard
![](opendtu_breakoutboard.jpg)
![](thumbnail.jpg)
### Build by @Marc--
* Used build environment: generic
* Case: https://www.thingiverse.com/thing:5435911

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
docs/builds/thumbnail.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 168 KiB

View File

@ -1,10 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <Arduino.h>
#include "PinMapping.h"
#include <cstdint>
#include <TaskSchedulerDeclarations.h>
#include <mutex>
#include <condition_variable>
#define CONFIG_FILENAME "/config.json"
#define CONFIG_VERSION 0x00011800 // 0.1.24 // make sure to clean all after change
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
#define WIFI_MAX_SSID_STRLEN 32
#define WIFI_MAX_PASSWORD_STRLEN 64
@ -15,6 +19,7 @@
#define NTP_MAX_TIMEZONEDESCR_STRLEN 50
#define MQTT_MAX_HOSTNAME_STRLEN 128
#define MQTT_MAX_CLIENTID_STRLEN 64
#define MQTT_MAX_USERNAME_STRLEN 64
#define MQTT_MAX_PASSWORD_STRLEN 64
#define MQTT_MAX_TOPIC_STRLEN 32
@ -23,13 +28,12 @@
#define INV_MAX_NAME_STRLEN 31
#define INV_MAX_COUNT 10
#define INV_MAX_CHAN_COUNT 4
#define INV_MAX_CHAN_COUNT 6
#define CHAN_MAX_NAME_STRLEN 31
#define DEV_MAX_MAPPING_NAME_STRLEN 63
#define JSON_BUFFER_SIZE 12288
#define LOCALE_STRLEN 2
struct CHANNEL_CONFIG_T {
uint16_t MaxChannelPower;
@ -40,85 +44,153 @@ struct CHANNEL_CONFIG_T {
struct INVERTER_CONFIG_T {
uint64_t Serial;
char Name[INV_MAX_NAME_STRLEN + 1];
uint8_t Order;
bool Poll_Enable;
bool Poll_Enable_Night;
bool Command_Enable;
bool Command_Enable_Night;
uint8_t ReachableThreshold;
bool ZeroRuntimeDataIfUnrechable;
bool ZeroYieldDayOnMidnight;
bool ClearEventlogOnMidnight;
bool YieldDayCorrection;
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
};
struct CONFIG_T {
uint32_t Cfg_Version;
uint Cfg_SaveCount;
struct {
uint32_t Version;
uint32_t SaveCount;
} Cfg;
char WiFi_Ssid[WIFI_MAX_SSID_STRLEN + 1];
char WiFi_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
byte WiFi_Ip[4];
byte WiFi_Netmask[4];
byte WiFi_Gateway[4];
byte WiFi_Dns1[4];
byte WiFi_Dns2[4];
bool WiFi_Dhcp;
char WiFi_Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1];
struct {
char Ssid[WIFI_MAX_SSID_STRLEN + 1];
char Password[WIFI_MAX_PASSWORD_STRLEN + 1];
uint8_t Ip[4];
uint8_t Netmask[4];
uint8_t Gateway[4];
uint8_t Dns1[4];
uint8_t Dns2[4];
bool Dhcp;
char Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1];
uint32_t ApTimeout;
} WiFi;
char Ntp_Server[NTP_MAX_SERVER_STRLEN + 1];
char Ntp_Timezone[NTP_MAX_TIMEZONE_STRLEN + 1];
char Ntp_TimezoneDescr[NTP_MAX_TIMEZONEDESCR_STRLEN + 1];
double Ntp_Longitude;
double Ntp_Latitude;
struct {
bool Enabled;
} Mdns;
bool Mqtt_Enabled;
uint Mqtt_Port;
char Mqtt_Username[MQTT_MAX_USERNAME_STRLEN + 1];
char Mqtt_Password[MQTT_MAX_PASSWORD_STRLEN + 1];
char Mqtt_Topic[MQTT_MAX_TOPIC_STRLEN + 1];
bool Mqtt_Retain;
char Mqtt_LwtTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char Mqtt_LwtValue_Online[MQTT_MAX_LWTVALUE_STRLEN + 1];
char Mqtt_LwtValue_Offline[MQTT_MAX_LWTVALUE_STRLEN + 1];
uint32_t Mqtt_PublishInterval;
struct {
char Server[NTP_MAX_SERVER_STRLEN + 1];
char Timezone[NTP_MAX_TIMEZONE_STRLEN + 1];
char TimezoneDescr[NTP_MAX_TIMEZONEDESCR_STRLEN + 1];
double Longitude;
double Latitude;
uint8_t SunsetType;
} Ntp;
struct {
bool Enabled;
char Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
uint32_t Port;
char ClientId[MQTT_MAX_CLIENTID_STRLEN + 1];
char Username[MQTT_MAX_USERNAME_STRLEN + 1];
char Password[MQTT_MAX_PASSWORD_STRLEN + 1];
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
bool Retain;
uint32_t PublishInterval;
bool CleanSession;
struct {
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
char Value_Online[MQTT_MAX_LWTVALUE_STRLEN + 1];
char Value_Offline[MQTT_MAX_LWTVALUE_STRLEN + 1];
uint8_t Qos;
} Lwt;
struct {
bool Enabled;
bool Retain;
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
bool IndividualPanels;
bool Expire;
} Hass;
struct {
bool Enabled;
char RootCaCert[MQTT_MAX_CERT_STRLEN + 1];
bool CertLogin;
char ClientCert[MQTT_MAX_CERT_STRLEN + 1];
char ClientKey[MQTT_MAX_CERT_STRLEN + 1];
} Tls;
} Mqtt;
struct {
uint64_t Serial;
uint32_t PollInterval;
struct {
uint8_t PaLevel;
} Nrf;
struct {
int8_t PaLevel;
uint32_t Frequency;
uint8_t CountryMode;
} Cmt;
} Dtu;
struct {
char Password[WIFI_MAX_PASSWORD_STRLEN + 1];
bool AllowReadonly;
} Security;
struct {
bool PowerSafe;
bool ScreenSaver;
uint8_t Rotation;
uint8_t Contrast;
char Locale[LOCALE_STRLEN + 1];
struct {
uint32_t Duration;
uint8_t Mode;
} Diagram;
} Display;
struct {
uint8_t Brightness;
} Led_Single[PINMAPPING_LED_COUNT];
INVERTER_CONFIG_T Inverter[INV_MAX_COUNT];
uint64_t Dtu_Serial;
uint32_t Dtu_PollInterval;
uint8_t Dtu_PaLevel;
bool Mqtt_Hass_Enabled;
bool Mqtt_Hass_Retain;
char Mqtt_Hass_Topic[MQTT_MAX_TOPIC_STRLEN + 1];
bool Mqtt_Hass_IndividualPanels;
bool Mqtt_Tls;
char Mqtt_RootCaCert[MQTT_MAX_CERT_STRLEN + 1];
bool Mqtt_TlsCertLogin;
char Mqtt_ClientCert[MQTT_MAX_CERT_STRLEN + 1];
char Mqtt_ClientKey[MQTT_MAX_CERT_STRLEN + 1];
char Mqtt_Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
bool Mqtt_Hass_Expire;
char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
bool Security_AllowReadonly;
char Dev_PinMapping[DEV_MAX_MAPPING_NAME_STRLEN + 1];
bool Display_PowerSafe;
bool Display_ScreenSaver;
uint8_t Display_Rotation;
uint8_t Display_Contrast;
};
class ConfigurationClass {
public:
void init();
void init(Scheduler& scheduler);
bool read();
bool write();
void migrate();
CONFIG_T& get();
CONFIG_T const& get();
class WriteGuard {
public:
WriteGuard();
CONFIG_T& getConfig();
~WriteGuard();
private:
std::unique_lock<std::mutex> _lock;
};
WriteGuard getWriteGuard();
INVERTER_CONFIG_T* getFreeInverterSlot();
INVERTER_CONFIG_T* getInverterConfig(uint64_t serial);
INVERTER_CONFIG_T* getInverterConfig(const uint64_t serial);
void deleteInverterById(const uint8_t id);
private:
void loop();
Task _loopTask;
};
extern ConfigurationClass Configuration;
extern ConfigurationClass Configuration;

85
include/Datastore.h Normal file
View File

@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <mutex>
class DatastoreClass {
public:
DatastoreClass();
void init(Scheduler& scheduler);
// Sum of yield total of all enabled inverters, a inverter which is just disabled at night is also included
float getTotalAcYieldTotalEnabled();
// Sum of yield day of all enabled inverters, a inverter which is just disabled at night is also included
float getTotalAcYieldDayEnabled();
// Sum of total AC power of all enabled inverters
float getTotalAcPowerEnabled();
// Sum of total DC power of all enabled inverters
float getTotalDcPowerEnabled();
// Sum of total DC power of all enabled inverters with maxStringPower set
float getTotalDcPowerIrradiation();
// Sum of total installed irradiation of all enabled inverters
float getTotalDcIrradiationInstalled();
// Percentage (1-100) of total irradiation
float getTotalDcIrradiation();
// Amount of relevant digits for yield total
uint32_t getTotalAcYieldTotalDigits();
// Amount of relevant digits for yield total
uint32_t getTotalAcYieldDayDigits();
// Amount of relevant digits for AC power
uint32_t getTotalAcPowerDigits();
// Amount of relevant digits for DC power
uint32_t getTotalDcPowerDigits();
// True, if at least one inverter is reachable
bool getIsAtLeastOneReachable();
// True if at least one inverter is producing
bool getIsAtLeastOneProducing();
// True if at least one inverter is enabled for polling
bool getIsAtLeastOnePollEnabled();
// True if all enabled inverters are producing
bool getIsAllEnabledProducing();
// True if all enabled inverters are reachable
bool getIsAllEnabledReachable();
private:
void loop();
Task _loopTask;
std::mutex _mutex;
float _totalAcYieldTotalEnabled = 0;
float _totalAcYieldDayEnabled = 0;
float _totalAcPowerEnabled = 0;
float _totalDcPowerEnabled = 0;
float _totalDcPowerIrradiation = 0;
float _totalDcIrradiationInstalled = 0;
float _totalDcIrradiation = 0;
uint32_t _totalAcYieldTotalDigits = 0;
uint32_t _totalAcYieldDayDigits = 0;
uint32_t _totalAcPowerDigits = 0;
uint32_t _totalDcPowerDigits = 0;
bool _isAtLeastOneReachable = false;
bool _isAtLeastOneProducing = false;
bool _isAllEnabledProducing = false;
bool _isAllEnabledReachable = false;
bool _isAtLeastOnePollEnabled = false;
};
extern DatastoreClass Datastore;

View File

@ -1,14 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Display_Graphic_Diagram.h"
#include "defaults.h"
#include <TaskSchedulerDeclarations.h>
#include <U8g2lib.h>
#define CHART_HEIGHT 20 // chart area hight in pixels
#define CHART_WIDTH 47 // chart area width in pixels
// Left-Upper position of diagram is drawn
// (text of Y-axis is display left of that pos)
#define CHART_POSX 80
#define CHART_POSY 0
enum DisplayType_t {
None,
PCD8544,
SSD1306,
SH1106,
SSD1309,
ST7567_GM12864I_59N,
DisplayType_Max,
};
enum DiagramMode_t {
Off,
Small,
Fullscreen,
DisplayMode_Max,
};
class DisplayGraphicClass {
@ -16,31 +36,52 @@ public:
DisplayGraphicClass();
~DisplayGraphicClass();
void init(DisplayType_t type, uint8_t data, uint8_t clk, uint8_t cs, uint8_t reset);
void loop();
void setContrast(uint8_t contrast);
void setOrientation(uint8_t rotation = DISPLAY_ROTATION);
void init(Scheduler& scheduler, const DisplayType_t type, const uint8_t data, const uint8_t clk, const uint8_t cs, const uint8_t reset);
void setContrast(const uint8_t contrast);
void setStatus(const bool turnOn);
void setOrientation(const uint8_t rotation = DISPLAY_ROTATION);
void setLocale(const String& locale);
void setDiagramMode(DiagramMode_t mode);
void setStartupDisplay();
DisplayGraphicDiagramClass& Diagram();
bool enablePowerSafe = true;
bool enableScreensaver = true;
private:
void printText(const char* text, uint8_t line);
void loop();
void printText(const char* text, const uint8_t line);
void calcLineHeights();
void setFont(uint8_t line);
void setFont(const uint8_t line);
bool isValidDisplay();
Task _loopTask;
U8G2* _display;
DisplayGraphicDiagramClass _diagram;
bool _displayTurnedOn;
DisplayType_t _display_type = DisplayType_t::None;
DiagramMode_t _diagram_mode = DiagramMode_t::Off;
String _display_language = DISPLAY_LOCALE;
uint8_t _mExtra;
uint16_t _period = 1000;
uint16_t _interval = 60000; // interval at which to power save (milliseconds)
uint32_t _lastDisplayUpdate = 0;
const uint16_t _period = 1000;
const uint16_t _interval = 60000; // interval at which to power save (milliseconds)
uint32_t _previousMillis = 0;
char _fmtText[32];
bool _isLarge = false;
uint8_t _lineOffsets[5];
String _i18n_offline;
String _i18n_yield_today_kwh;
String _i18n_yield_today_wh;
String _i18n_date_format;
String _i18n_current_power_kw;
String _i18n_current_power_w;
String _i18n_yield_total_mwh;
String _i18n_yield_total_kwh;
};
extern DisplayGraphicClass Display;
extern DisplayGraphicClass Display;

View File

@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <U8g2lib.h>
#include <array>
#define MAX_DATAPOINTS 128
class DisplayGraphicDiagramClass {
public:
DisplayGraphicDiagramClass();
void init(Scheduler& scheduler, U8G2* display);
void redraw(uint8_t screenSaverOffsetX, uint8_t xPos, uint8_t yPos, uint8_t width, uint8_t height, bool isFullscreen);
void updatePeriod();
private:
void averageLoop();
void dataPointLoop();
uint32_t getSecondsPerDot();
Task _averageTask;
Task _dataPointTask;
U8G2* _display = nullptr;
std::array<float, MAX_DATAPOINTS> _graphValues = {};
uint8_t _graphValuesCount = 0;
uint8_t _chartWidth = MAX_DATAPOINTS;
float _iRunningAverage = 0;
uint16_t _iRunningAverageCnt = 0;
};

35
include/I18n.h Normal file
View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <WString.h>
#include <list>
struct LanguageInfo_t {
String code;
String name;
String filename;
};
class I18nClass {
public:
I18nClass();
void init(Scheduler& scheduler);
std::list<LanguageInfo_t> getAvailableLanguages();
String getFilenameByLocale(const String& locale) const;
void readDisplayStrings(
const String& locale,
String& date_format,
String& offline,
String& power_w, String& power_kw,
String& yield_today_wh, String& yield_today_kwh,
String& yield_total_kwh, String& yield_total_mwh);
private:
void readLangPacks();
void readConfig(String file);
std::list<LanguageInfo_t> _availLanguages;
};
extern I18nClass I18n;

View File

@ -1,15 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <cstdint>
#define INVERTER_UPDATE_SETTINGS_INTERVAL 60000l
class InverterSettingsClass {
public:
void init();
void loop();
InverterSettingsClass();
void init(Scheduler& scheduler);
private:
uint32_t _lastUpdate = 0;
void settingsLoop();
void hoyLoop();
Task _settingsTask;
Task _hoyTask;
};
extern InverterSettingsClass InverterSettings;
extern InverterSettingsClass InverterSettings;

View File

@ -2,34 +2,38 @@
#pragma once
#include "PinMapping.h"
#include <TaskSchedulerDeclarations.h>
#include <TimeoutHelper.h>
#define LEDSINGLE_UPDATE_INTERVAL 2000
enum eLedFunction {
CONNECTED_NETWORK,
CONNECTED_MQTT,
INV_REACHABLE,
INV_PRODUCING,
};
class LedSingleClass {
public:
LedSingleClass();
void init();
void loop();
void init(Scheduler& scheduler);
void turnAllOff();
void turnAllOn();
private:
void setLoop();
void outputLoop();
void setLed(const uint8_t ledNo, const bool ledState);
Task _setTask;
Task _outputTask;
enum class LedState_t {
On,
Off,
Blink,
};
LedState_t _ledState[PINMAPPING_LED_COUNT];
TimeoutHelper _updateTimeout;
LedState_t _ledMode[PINMAPPING_LED_COUNT];
LedState_t _allMode;
bool _ledStateCurrent[PINMAPPING_LED_COUNT];
TimeoutHelper _blinkTimeout;
uint8_t _ledActive = 0;
};
extern LedSingleClass LedSingle;

View File

@ -1,27 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <AsyncWebSocket.h>
#include <HardwareSerial.h>
#include <Stream.h>
#define BUFFER_SIZE 500
class MessageOutputClass : public Print {
public:
MessageOutputClass();
void loop();
size_t write(uint8_t c);
void register_ws_output(AsyncWebSocket* output);
private:
AsyncWebSocket* _ws = NULL;
char _buffer[BUFFER_SIZE];
uint16_t _buff_pos = 0;
uint32_t _lastSend = 0;
bool _forceSend = false;
SemaphoreHandle_t _lock;
};
extern MessageOutputClass MessageOutput;
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <AsyncWebSocket.h>
#include <HardwareSerial.h>
#include <Stream.h>
#include <TaskSchedulerDeclarations.h>
#include <mutex>
#define BUFFER_SIZE 500
class MessageOutputClass : public Print {
public:
MessageOutputClass();
void init(Scheduler& scheduler);
size_t write(uint8_t c) override;
size_t write(const uint8_t* buffer, size_t size) override;
void register_ws_output(AsyncWebSocket* output);
private:
void loop();
Task _loopTask;
AsyncWebSocket* _ws = nullptr;
char _buffer[BUFFER_SIZE];
uint16_t _buff_pos = 0;
uint32_t _lastSend = 0;
bool _forceSend = false;
std::mutex _msgLock;
};
extern MessageOutputClass MessageOutput;

View File

@ -1,15 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <cstdint>
class MqttHandleDtuClass {
public:
void init();
void loop();
MqttHandleDtuClass();
void init(Scheduler& scheduler);
private:
uint32_t _lastPublish;
void loop();
Task _loopTask;
};
extern MqttHandleDtuClass MqttHandleDtu;
extern MqttHandleDtuClass MqttHandleDtu;

View File

@ -3,31 +3,45 @@
#include <ArduinoJson.h>
#include <Hoymiles.h>
#include <TaskSchedulerDeclarations.h>
// mqtt discovery device classes
enum {
enum DeviceClassType {
DEVICE_CLS_NONE = 0,
DEVICE_CLS_CURRENT,
DEVICE_CLS_ENERGY,
DEVICE_CLS_PWR,
DEVICE_CLS_VOLTAGE,
DEVICE_CLS_FREQ,
DEVICE_CLS_TEMP,
DEVICE_CLS_POWER_FACTOR,
DEVICE_CLS_REACTIVE_POWER
DEVICE_CLS_REACTIVE_POWER,
DEVICE_CLS_CONNECTIVITY,
DEVICE_CLS_DURATION,
DEVICE_CLS_SIGNAL_STRENGTH,
DEVICE_CLS_TEMPERATURE,
DEVICE_CLS_RESTART
};
const char* const deviceClasses[] = { 0, "current", "energy", "power", "voltage", "frequency", "temperature", "power_factor", "reactive_power" };
enum {
const char* const deviceClass_name[] = { 0, "current", "energy", "power", "voltage", "frequency", "power_factor", "reactive_power", "connectivity", "duration", "signal_strength", "temperature", "restart" };
enum StateClassType {
STATE_CLS_NONE = 0,
STATE_CLS_MEASUREMENT,
STATE_CLS_TOTAL_INCREASING
};
const char* const stateClasses[] = { 0, "measurement", "total_increasing" };
const char* const stateClass_name[] = { 0, "measurement", "total_increasing" };
enum CategoryType {
CATEGORY_NONE = 0,
CATEGORY_CONFIG,
CATEGORY_DIAGNOSTIC
};
const char* const category_name[] = { 0, "config", "diagnostic" };
typedef struct {
FieldId_t fieldId; // field id
uint8_t deviceClsId; // device class
uint8_t stateClsId; // state class
DeviceClassType deviceClsId; // device class
StateClassType stateClsId; // state class
} byteAssign_fieldDeviceClass_t;
const byteAssign_fieldDeviceClass_t deviceFieldAssignment[] = {
@ -40,31 +54,54 @@ const byteAssign_fieldDeviceClass_t deviceFieldAssignment[] = {
{ FLD_IAC, DEVICE_CLS_CURRENT, STATE_CLS_MEASUREMENT },
{ FLD_PAC, DEVICE_CLS_PWR, STATE_CLS_MEASUREMENT },
{ FLD_F, DEVICE_CLS_FREQ, STATE_CLS_MEASUREMENT },
{ FLD_T, DEVICE_CLS_TEMP, STATE_CLS_MEASUREMENT },
{ FLD_T, DEVICE_CLS_TEMPERATURE, STATE_CLS_MEASUREMENT },
{ FLD_PF, DEVICE_CLS_POWER_FACTOR, STATE_CLS_MEASUREMENT },
{ FLD_EFF, DEVICE_CLS_NONE, STATE_CLS_NONE },
{ FLD_IRR, DEVICE_CLS_NONE, STATE_CLS_NONE },
{ FLD_PRA, DEVICE_CLS_REACTIVE_POWER, STATE_CLS_MEASUREMENT }
{ FLD_Q, DEVICE_CLS_REACTIVE_POWER, STATE_CLS_MEASUREMENT }
};
#define DEVICE_CLS_ASSIGN_LIST_LEN (sizeof(deviceFieldAssignment) / sizeof(byteAssign_fieldDeviceClass_t))
class MqttHandleHassClass {
public:
void init();
void loop();
MqttHandleHassClass();
void init(Scheduler& scheduler);
void publishConfig();
void forceUpdate();
private:
void publish(const String& subtopic, const String& payload);
void publishField(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear = false);
void publishInverterButton(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload);
void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, int16_t min = 1, int16_t max = 100);
void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);
void createDeviceInfo(JsonObject& object, std::shared_ptr<InverterAbstract> inv);
void loop();
static void publish(const String& subtopic, const String& payload);
static void publish(const String& subtopic, const JsonDocument& doc);
static void addCommonMetadata(JsonDocument& doc, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
// Binary Sensor
static void publishBinarySensor(JsonDocument& doc, const String& root_device, const String& unique_id_prefix, const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishDtuBinarySensor(const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
// Sensor
static void publishSensor(JsonDocument& doc, const String& root_device, const String& unique_id_prefix, const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishDtuSensor(const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishInverterSensor(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishInverterField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const byteAssign_fieldDeviceClass_t fieldType, const bool clear = false);
static void publishInverterButton(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& payload, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
static void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& command_topic, const int16_t min, const int16_t max, float step, const String& unit_of_measure, const String& icon, const StateClassType state_class, const CategoryType category);
static void createInverterInfo(JsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
static void createDtuInfo(JsonDocument& doc);
static void createDeviceInfo(JsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = "");
static String getDtuUniqueId();
static String getDtuUrl();
Task _loopTask;
bool _wasConnected = false;
bool _updateForced = false;
};
extern MqttHandleHassClass MqttHandleHass;
extern MqttHandleHassClass MqttHandleHass;

View File

@ -3,21 +3,28 @@
#include "Configuration.h"
#include <Hoymiles.h>
#include <TaskSchedulerDeclarations.h>
#include <espMqttClient.h>
#include <frozen/map.h>
#include <frozen/string.h>
class MqttHandleInverterClass {
public:
void init();
void loop();
MqttHandleInverterClass();
void init(Scheduler& scheduler);
static String getTopic(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);
static String getTopic(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
void subscribeTopics();
void unsubscribeTopics();
private:
void publishField(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
void loop();
void publishField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
uint32_t _lastPublishStats[INV_MAX_COUNT];
uint32_t _lastPublish;
Task _loopTask;
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
FieldId_t _publishFields[14] = {
FLD_UDC,
@ -33,8 +40,31 @@ private:
FLD_PF,
FLD_EFF,
FLD_IRR,
FLD_PRA
FLD_Q
};
enum class Topic : unsigned {
LimitPersistentRelative,
LimitPersistentAbsolute,
LimitNonPersistentRelative,
LimitNonPersistentAbsolute,
Power,
Restart,
ResetRfStats,
};
static constexpr frozen::string _cmdtopic = "+/cmd/";
static constexpr frozen::map<frozen::string, Topic, 7> _subscriptions = {
{ "limit_persistent_relative", Topic::LimitPersistentRelative },
{ "limit_persistent_absolute", Topic::LimitPersistentAbsolute },
{ "limit_nonpersistent_relative", Topic::LimitNonPersistentRelative },
{ "limit_nonpersistent_absolute", Topic::LimitNonPersistentAbsolute },
{ "power", Topic::Power },
{ "restart", Topic::Restart },
{ "reset_rf_stats", Topic::ResetRfStats },
};
void onMqttMessage(Topic t, const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, const size_t len, const size_t index, const size_t total);
};
extern MqttHandleInverterClass MqttHandleInverter;
extern MqttHandleInverterClass MqttHandleInverter;

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
class MqttHandleInverterTotalClass {
public:
MqttHandleInverterTotalClass();
void init(Scheduler& scheduler);
private:
void loop();
Task _loopTask;
};
extern MqttHandleInverterTotalClass MqttHandleInverterTotal;

View File

@ -5,6 +5,7 @@
#include <MqttSubscribeParser.h>
#include <Ticker.h>
#include <espMqttClient.h>
#include <mutex>
class MqttSettingsClass {
public:
@ -13,30 +14,30 @@ public:
void performReconnect();
bool getConnected();
void publish(const String& subtopic, const String& payload);
void publishGeneric(const String& topic, const String& payload, bool retain, uint8_t qos = 0);
void publishGeneric(const String& topic, const String& payload, const bool retain, const uint8_t qos = 0);
void subscribe(const String& topic, uint8_t qos, const espMqttClientTypes::OnMessageCallback& cb);
void subscribe(const String& topic, const uint8_t qos, const espMqttClientTypes::OnMessageCallback& cb);
void unsubscribe(const String& topic);
String getPrefix();
String getPrefix() const;
String getClientId() const;
private:
void NetworkEvent(network_event event);
void onMqttDisconnect(espMqttClientTypes::DisconnectReason reason);
void onMqttConnect(bool sessionPresent);
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
void onMqttConnect(const bool sessionPresent);
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, const size_t len, const size_t index, const size_t total);
void performConnect();
void performDisconnect();
void createMqttClientObject();
MqttClient* mqttClient = nullptr;
String clientId;
String willTopic;
Ticker mqttReconnectTimer;
MqttClient* _mqttClient = nullptr;
Ticker _mqttReconnectTimer;
MqttSubscribeParser _mqttSubscribeParser;
std::mutex _clientLock;
};
extern MqttSettingsClass MqttSettings;
extern MqttSettingsClass MqttSettings;

View File

@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "W5500.h"
#include <DNSServer.h>
#include <TaskSchedulerDeclarations.h>
#include <WiFi.h>
#include <vector>
@ -22,59 +24,67 @@ enum class network_event {
NETWORK_EVENT_MAX
};
typedef std::function<void(network_event event)> NetworkEventCb;
typedef std::function<void(network_event event)> DtuNetworkEventCb;
typedef struct NetworkEventCbList {
NetworkEventCb cb;
typedef struct DtuNetworkEventCbList {
DtuNetworkEventCb cb;
network_event event;
NetworkEventCbList()
: cb(NULL)
DtuNetworkEventCbList()
: cb(nullptr)
, event(network_event::NETWORK_UNKNOWN)
{
}
} NetworkEventCbList_t;
} DtuNetworkEventCbList_t;
class NetworkSettingsClass {
public:
NetworkSettingsClass();
void init();
void loop();
void init(Scheduler& scheduler);
void applyConfig();
void enableAdminMode();
String getApName();
String getApName() const;
IPAddress localIP();
IPAddress subnetMask();
IPAddress gatewayIP();
IPAddress dnsIP(uint8_t dns_no = 0);
String macAddress();
IPAddress localIP() const;
IPAddress subnetMask() const;
IPAddress gatewayIP() const;
IPAddress dnsIP(const uint8_t dns_no = 0) const;
String macAddress() const;
static String getHostname();
bool isConnected();
network_mode NetworkMode();
bool isConnected() const;
network_mode NetworkMode() const;
bool onEvent(NetworkEventCb cbEvent, network_event event = network_event::NETWORK_EVENT_MAX);
void raiseEvent(network_event event);
bool onEvent(DtuNetworkEventCb cbEvent, const network_event event = network_event::NETWORK_EVENT_MAX);
void raiseEvent(const network_event event);
private:
void loop();
void setHostname();
void setStaticIp();
void handleMDNS();
void setupMode();
void NetworkEvent(WiFiEvent_t event);
bool adminEnabled = true;
bool forceDisconnection = false;
int adminTimeoutCounter = 0;
int connectTimeoutTimer = 0;
int connectRedoTimer = 0;
uint32_t lastTimerCall = 0;
const byte DNS_PORT = 53;
IPAddress apIp;
IPAddress apNetmask;
std::unique_ptr<DNSServer> dnsServer;
bool dnsServerStatus = false;
void NetworkEvent(const WiFiEvent_t event, WiFiEventInfo_t info);
Task _loopTask;
static constexpr byte DNS_PORT = 53;
bool _adminEnabled = true;
bool _forceDisconnection = false;
uint32_t _adminTimeoutCounter = 0;
uint32_t _adminTimeoutCounterMax = 0;
uint32_t _connectTimeoutTimer = 0;
uint32_t _connectRedoTimer = 0;
uint32_t _lastTimerCall = 0;
IPAddress _apIp;
IPAddress _apNetmask;
std::unique_ptr<DNSServer> _dnsServer;
bool _dnsServerStatus = false;
network_mode _networkMode = network_mode::Undefined;
bool _ethConnected = false;
std::vector<NetworkEventCbList_t> _cbEventList;
std::vector<DtuNetworkEventCbList_t> _cbEventList;
bool _lastMdnsEnabled = false;
std::unique_ptr<W5500> _w5500;
};
extern NetworkSettingsClass NetworkSettings;
extern NetworkSettingsClass NetworkSettings;

View File

@ -12,12 +12,29 @@
struct PinMapping_t {
char name[MAPPING_NAME_STRLEN + 1];
int8_t nrf24_miso;
int8_t nrf24_mosi;
int8_t nrf24_clk;
int8_t nrf24_irq;
int8_t nrf24_en;
int8_t nrf24_cs;
int8_t cmt_clk;
int8_t cmt_cs;
int8_t cmt_fcs;
int8_t cmt_gpio2;
int8_t cmt_gpio3;
int8_t cmt_sdio;
int8_t w5500_mosi;
int8_t w5500_miso;
int8_t w5500_sclk;
int8_t w5500_cs;
int8_t w5500_int;
int8_t w5500_rst;
#if CONFIG_ETH_USE_ESP32_EMAC
int8_t eth_phy_addr;
bool eth_enabled;
int eth_power;
@ -25,11 +42,14 @@ struct PinMapping_t {
int eth_mdio;
eth_phy_type_t eth_type;
eth_clock_mode_t eth_clk_mode;
#endif
uint8_t display_type;
uint8_t display_data;
uint8_t display_clk;
uint8_t display_cs;
uint8_t display_reset;
int8_t led[PINMAPPING_LED_COUNT];
};
@ -39,11 +59,19 @@ public:
bool init(const String& deviceMapping);
PinMapping_t& get();
bool isValidNrf24Config();
bool isValidEthConfig();
bool isMappingSelected() const { return _mappingSelected; }
bool isValidNrf24Config() const;
bool isValidCmt2300Config() const;
bool isValidW5500Config() const;
#if CONFIG_ETH_USE_ESP32_EMAC
bool isValidEthConfig() const;
#endif
private:
PinMapping_t _pinMapping;
bool _mappingSelected = false;
};
extern PinMappingClass PinMapping;
extern PinMappingClass PinMapping;

18
include/RestartHelper.h Normal file
View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
class RestartHelperClass {
public:
RestartHelperClass();
void init(Scheduler& scheduler);
void triggerRestart();
private:
void loop();
Task _rebootTask;
};
extern RestartHelperClass RestartHelper;

6
include/Scheduler.h Normal file
View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
extern Scheduler scheduler;

View File

@ -1,30 +1,36 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <TaskSchedulerDeclarations.h>
#include <atomic>
#include <sunset.h>
#define SUNPOS_UPDATE_INTERVAL 60000l
class SunPositionClass {
public:
SunPositionClass();
void init();
void loop();
void init(Scheduler& scheduler);
bool isDayPeriod();
bool sunsetTime(struct tm* info);
bool sunriseTime(struct tm* info);
bool isDayPeriod() const;
bool isSunsetAvailable() const;
bool sunsetTime(struct tm* info) const;
bool sunriseTime(struct tm* info) const;
void setDoRecalc(const bool doRecalc);
private:
void loop();
void updateSunData();
bool checkRecalcDayChanged() const;
bool getSunTime(struct tm* info, const uint32_t offset) const;
SunSet _sun;
bool _isDayPeriod = true;
uint _sunriseMinutes = 0;
uint _sunsetMinutes = 0;
Task _loopTask;
bool _isSunsetAvailable = true;
uint32_t _sunriseMinutes = 0;
uint32_t _sunsetMinutes = 0;
uint32_t _lastUpdate = 0;
bool _isValidInfo = false;
std::atomic_bool _doRecalc = true;
uint32_t _lastSunPositionCalculatedYMD = 0;
};
extern SunPositionClass SunPosition;
extern SunPositionClass SunPosition;

View File

@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ArduinoJson.h>
#include <LittleFS.h>
#include <cstdint>
class Utils {
@ -8,4 +10,8 @@ public:
static uint32_t getChipId();
static uint64_t generateDtuSerial();
static int getTimezoneOffset();
static bool checkJsonAlloc(const JsonDocument& doc, const char* function, const uint16_t line);
static void removeAllFiles();
static String generateMd5FromFile(String file);
static void skipBom(File& f);
};

29
include/W5500.h Normal file
View File

@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <Arduino.h>
#include <driver/spi_master.h>
#include <esp_eth.h> // required for esp_eth_handle_t
#include <esp_netif.h>
#include <memory>
class W5500 {
private:
explicit W5500(spi_device_handle_t spi, gpio_num_t pin_int);
public:
W5500(const W5500&) = delete;
W5500& operator=(const W5500&) = delete;
~W5500();
static std::unique_ptr<W5500> setup(int8_t pin_mosi, int8_t pin_miso, int8_t pin_sclk, int8_t pin_cs, int8_t pin_int, int8_t pin_rst);
String macAddress();
private:
static bool connection_check_spi(spi_device_handle_t spi);
static bool connection_check_interrupt(gpio_num_t pin_int);
esp_eth_handle_t eth_handle;
esp_netif_t* eth_netif;
};

View File

@ -1,12 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "WebApi_config.h"
#include "WebApi_device.h"
#include "WebApi_devinfo.h"
#include "WebApi_dtu.h"
#include "WebApi_errors.h"
#include "WebApi_eventlog.h"
#include "WebApi_file.h"
#include "WebApi_firmware.h"
#include "WebApi_device.h"
#include "WebApi_gridprofile.h"
#include "WebApi_i18n.h"
#include "WebApi_inverter.h"
#include "WebApi_limit.h"
#include "WebApi_maintenance.h"
@ -20,29 +23,38 @@
#include "WebApi_webapp.h"
#include "WebApi_ws_console.h"
#include "WebApi_ws_live.h"
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiClass {
public:
WebApiClass();
void init();
void loop();
void init(Scheduler& scheduler);
void reload();
static bool checkCredentials(AsyncWebServerRequest* request);
static bool checkCredentialsReadonly(AsyncWebServerRequest* request);
static void sendTooManyRequests(AsyncWebServerRequest* request);
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, JsonDocument& json_document);
static uint64_t parseSerialFromRequest(AsyncWebServerRequest* request, String param_name = "inv");
static bool sendJsonResponse(AsyncWebServerRequest* request, AsyncJsonResponse* response, const char* function, const uint16_t line);
private:
AsyncWebServer _server;
AsyncEventSource _events;
WebApiConfigClass _webApiConfig;
WebApiDeviceClass _webApiDevice;
WebApiDevInfoClass _webApiDevInfo;
WebApiDtuClass _webApiDtu;
WebApiEventlogClass _webApiEventlog;
WebApiFileClass _webApiFile;
WebApiFirmwareClass _webApiFirmware;
WebApiGridProfileClass _webApiGridprofile;
WebApiI18nClass _webApiI18n;
WebApiInverterClass _webApiInverter;
WebApiLimitClass _webApiLimit;
WebApiMaintenanceClass _webApiMaintenance;
@ -58,4 +70,4 @@ private:
WebApiWsLiveClass _webApiWsLive;
};
extern WebApiClass WebApi;
extern WebApiClass WebApi;

View File

@ -1,19 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
class WebApiConfigClass {
public:
void init(AsyncWebServer* server);
void loop();
private:
void onConfigGet(AsyncWebServerRequest* request);
void onConfigDelete(AsyncWebServerRequest* request);
void onConfigListGet(AsyncWebServerRequest* request);
void onConfigUploadFinish(AsyncWebServerRequest* request);
void onConfigUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
AsyncWebServer* _server;
};

View File

@ -2,15 +2,13 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiDeviceClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onDeviceAdminGet(AsyncWebServerRequest* request);
void onDeviceAdminPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,14 +2,12 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiDevInfoClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onDevInfoStatus(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,15 +2,17 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiDtuClass {
public:
void init(AsyncWebServer* server);
void loop();
WebApiDtuClass();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onDtuAdminGet(AsyncWebServerRequest* request);
void onDtuAdminPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
Task _applyDataTask;
void applyDataTaskCb();
};

View File

@ -5,18 +5,23 @@ enum WebApiError {
GenericBase = 1000,
GenericSuccess,
GenericNoValueFound,
GenericDataTooLarge,
GenericDataTooLarge, // not used anymore
GenericParseError,
GenericValueMissing,
GenericWriteFailed,
GenericInternalServerError,
DtuBase = 2000,
DtuSerialZero,
DtuPollZero,
DtuInvalidPowerLevel,
DtuInvalidCmtFrequency,
DtuInvalidCmtCountry,
ConfigBase = 3000,
ConfigNotDeleted,
ConfigSuccess,
FileBase = 3000,
FileNotDeleted,
FileSuccess,
FileDeleteSuccess,
InverterBase = 4000,
InverterSerialZero,
@ -27,6 +32,8 @@ enum WebApiError {
InverterInvalidMaxChannel,
InverterChanged,
InverterDeleted,
InverterOrdered,
InverterStatsResetted,
LimitBase = 5000,
LimitSerialZero,
@ -54,6 +61,8 @@ enum WebApiError {
MqttPublishInterval,
MqttHassTopicLength,
MqttHassTopicCharacter,
MqttLwtQos,
MqttClientIdLength,
NetworkBase = 8000,
NetworkIpInvalid,
@ -61,6 +70,7 @@ enum WebApiError {
NetworkGatewayInvalid,
NetworkDns1Invalid,
NetworkDns2Invalid,
NetworkApTimeoutInvalid,
NtpBase = 9000,
NtpServerLength,
@ -84,4 +94,4 @@ enum WebApiError {
HardwareBase = 12000,
HardwarePinMappingLength,
};
};

View File

@ -2,14 +2,12 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiEventlogClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onEventlogStatus(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

18
include/WebApi_file.h Normal file
View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiFileClass {
public:
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onFileGet(AsyncWebServerRequest* request);
void onFileDelete(AsyncWebServerRequest* request);
void onFileDeleteAll(AsyncWebServerRequest* request);
void onFileListGet(AsyncWebServerRequest* request);
void onFileUploadFinish(AsyncWebServerRequest* request);
void onFileUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
};

View File

@ -2,15 +2,13 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiFirmwareClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onFirmwareUpdateFinish(AsyncWebServerRequest* request);
void onFirmwareUpdateUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
AsyncWebServer* _server;
};
};

View File

@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiGridProfileClass {
public:
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onGridProfileStatus(AsyncWebServerRequest* request);
void onGridProfileRawdata(AsyncWebServerRequest* request);
};

14
include/WebApi_i18n.h Normal file
View File

@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiI18nClass {
public:
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onI18nLanguages(AsyncWebServerRequest* request);
void onI18nLanguage(AsyncWebServerRequest* request);
};

View File

@ -2,17 +2,17 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiInverterClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onInverterList(AsyncWebServerRequest* request);
void onInverterAdd(AsyncWebServerRequest* request);
void onInverterEdit(AsyncWebServerRequest* request);
void onInverterDelete(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
void onInverterOrder(AsyncWebServerRequest* request);
void onInverterStatReset(AsyncWebServerRequest* request);
};

View File

@ -2,15 +2,13 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiLimitClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onLimitStatus(AsyncWebServerRequest* request);
void onLimitPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,14 +2,12 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiMaintenanceClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onRebootPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,19 +2,15 @@
#pragma once
#include <ESPAsyncWebServer.h>
#define MQTT_JSON_DOC_SIZE 10240
#include <TaskSchedulerDeclarations.h>
class WebApiMqttClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onMqttStatus(AsyncWebServerRequest* request);
void onMqttAdminGet(AsyncWebServerRequest* request);
void onMqttAdminPost(AsyncWebServerRequest* request);
String getTlsCertInfo(const char* cert);
AsyncWebServer* _server;
};
};

View File

@ -2,16 +2,14 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiNetworkClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onNetworkStatus(AsyncWebServerRequest* request);
void onNetworkAdminGet(AsyncWebServerRequest* request);
void onNetworkAdminPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,11 +2,11 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiNtpClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onNtpStatus(AsyncWebServerRequest* request);
@ -14,6 +14,4 @@ private:
void onNtpAdminPost(AsyncWebServerRequest* request);
void onNtpTimeGet(AsyncWebServerRequest* request);
void onNtpTimePost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,15 +2,13 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiPowerClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onPowerStatus(AsyncWebServerRequest* request);
void onPowerPost(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -3,43 +3,46 @@
#include <ESPAsyncWebServer.h>
#include <Hoymiles.h>
#include <TaskSchedulerDeclarations.h>
#include <map>
class WebApiPrometheusClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onPrometheusMetricsGet(AsyncWebServerRequest* request);
void addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, const char* channelName = NULL);
void addField(AsyncResponseStream* stream, const String& serial, const uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, const char* metricName, const char* channelName = nullptr);
void addPanelInfo(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel);
void addPanelInfo(AsyncResponseStream* stream, const String& serial, const uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel);
AsyncWebServer* _server;
enum {
METRIC_TYPE_NONE = 0,
METRIC_TYPE_GAUGE,
METRIC_TYPE_COUNTER,
enum MetricType_t {
NONE = 0,
GAUGE,
COUNTER,
};
const char* _metricTypes[3] = { 0, "gauge", "counter" };
std::map<FieldId_t, uint8_t> _fieldMetricAssignment {
{ FLD_UDC, METRIC_TYPE_GAUGE },
{ FLD_IDC, METRIC_TYPE_GAUGE },
{ FLD_PDC, METRIC_TYPE_GAUGE },
{ FLD_YD, METRIC_TYPE_COUNTER },
{ FLD_YT, METRIC_TYPE_COUNTER },
{ FLD_UAC, METRIC_TYPE_GAUGE },
{ FLD_IAC, METRIC_TYPE_GAUGE },
{ FLD_PAC, METRIC_TYPE_GAUGE },
{ FLD_F, METRIC_TYPE_GAUGE },
{ FLD_T, METRIC_TYPE_GAUGE },
{ FLD_PF, METRIC_TYPE_GAUGE },
{ FLD_EFF, METRIC_TYPE_GAUGE },
{ FLD_IRR, METRIC_TYPE_GAUGE },
{ FLD_PRA, METRIC_TYPE_GAUGE }
struct publish_type_t {
FieldId_t field;
MetricType_t type;
};
};
const publish_type_t _publishFields[14] = {
{ FLD_PAC, MetricType_t::GAUGE },
{ FLD_UAC, MetricType_t::GAUGE },
{ FLD_IAC, MetricType_t::GAUGE },
{ FLD_PDC, MetricType_t::GAUGE },
{ FLD_UDC, MetricType_t::GAUGE },
{ FLD_IDC, MetricType_t::GAUGE },
{ FLD_YD, MetricType_t::COUNTER },
{ FLD_YT, MetricType_t::COUNTER },
{ FLD_F, MetricType_t::GAUGE },
{ FLD_T, MetricType_t::GAUGE },
{ FLD_PF, MetricType_t::GAUGE },
{ FLD_Q, MetricType_t::GAUGE },
{ FLD_EFF, MetricType_t::GAUGE },
{ FLD_IRR, MetricType_t::GAUGE },
};
};

View File

@ -2,17 +2,15 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiSecurityClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onSecurityGet(AsyncWebServerRequest* request);
void onSecurityPost(AsyncWebServerRequest* request);
void onAuthenticateGet(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,14 +2,12 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiSysstatusClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
void onSystemStatus(AsyncWebServerRequest* request);
AsyncWebServer* _server;
};
};

View File

@ -2,12 +2,12 @@
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiWebappClass {
public:
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
private:
AsyncWebServer* _server;
};
void responseBinaryDataWithETagCache(AsyncWebServerRequest* request, const String &contentType, const String &contentEncoding, const uint8_t *content, size_t len);
};

View File

@ -1,19 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
class WebApiWsConsoleClass {
public:
WebApiWsConsoleClass();
void init(AsyncWebServer* server);
void loop();
private:
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
AsyncWebServer* _server;
AsyncWebSocket _ws;
uint32_t _lastWsCleanup = 0;
};
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>
class WebApiWsConsoleClass {
public:
WebApiWsConsoleClass();
void init(AsyncWebServer& server, Scheduler& scheduler);
void reload();
private:
AsyncWebSocket _ws;
AsyncAuthenticationMiddleware _simpleDigestAuth;
Task _wsCleanupTask;
void wsCleanupTaskCb();
};

View File

@ -1,28 +1,39 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Configuration.h"
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <Hoymiles.h>
#include <TaskSchedulerDeclarations.h>
class WebApiWsLiveClass {
public:
WebApiWsLiveClass();
void init(AsyncWebServer* server);
void loop();
void init(AsyncWebServer& server, Scheduler& scheduler);
void reload();
private:
void generateJsonResponse(JsonVariant& root);
void addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic = "");
void addTotalField(JsonObject& root, String name, float value, String unit, uint8_t digits);
static void generateInverterCommonJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
static void generateInverterChannelJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
static void generateCommonJsonResponse(JsonVariant& root);
static void addField(JsonObject& root, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic = "");
static void addTotalField(JsonObject& root, const String& name, const float value, const String& unit, const uint8_t digits);
void onLivedataStatus(AsyncWebServerRequest* request);
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
AsyncWebServer* _server;
AsyncWebSocket _ws;
AsyncAuthenticationMiddleware _simpleDigestAuth;
uint32_t _lastWsPublish = 0;
uint32_t _lastInvUpdateCheck = 0;
uint32_t _lastWsCleanup = 0;
uint32_t _newestInverterTimestamp = 0;
};
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
std::mutex _mutex;
Task _wsCleanupTask;
void wsCleanupTaskCb();
Task _sendDataTask;
void sendDataTaskCb();
};

View File

@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// The referenced values are generated by pio-scripts/auto_firmware_version.py
extern const char *__COMPILED_GIT_HASH__;
extern const char *__COMPILED_GIT_BRANCH__;
// extern const char *__COMPILED_DATE_TIME_UTC_STR__;

View File

@ -9,26 +9,30 @@
#define ACCESS_POINT_NAME "OpenDTU-"
#define ACCESS_POINT_PASSWORD "openDTU42"
#define ACCESS_POINT_TIMEOUT 3
#define AUTH_USERNAME "admin"
#define SECURITY_ALLOW_READONLY true
#define ADMIN_TIMEOUT 180
#define WIFI_RECONNECT_TIMEOUT 15
#define WIFI_RECONNECT_TIMEOUT 30
#define WIFI_RECONNECT_REDO_TIMEOUT 600
#define WIFI_SSID ""
#define WIFI_PASSWORD ""
#define WIFI_DHCP true
#define NTP_SERVER "pool.ntp.org"
#define MDNS_ENABLED false
#define NTP_SERVER_OLD "pool.ntp.org"
#define NTP_SERVER "opendtu.pool.ntp.org"
#define NTP_TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
#define NTP_TIMEZONEDESCR "Europe/Berlin"
#define NTP_LONGITUDE 10.4515f
#define NTP_LATITUDE 51.1657f
#define NTP_SUNSETTYPE 1U
#define MQTT_ENABLED false
#define MQTT_HOST ""
#define MQTT_PORT 1883
#define MQTT_PORT 1883U
#define MQTT_USER ""
#define MQTT_PASSWORD ""
#define MQTT_TOPIC "solar/"
@ -72,11 +76,16 @@
#define MQTT_LWT_TOPIC "dtu/status"
#define MQTT_LWT_ONLINE "online"
#define MQTT_LWT_OFFLINE "offline"
#define MQTT_PUBLISH_INTERVAL 5
#define MQTT_LWT_QOS 2U
#define MQTT_PUBLISH_INTERVAL 5U
#define MQTT_CLEAN_SESSION true
#define DTU_SERIAL 0x99978563412
#define DTU_POLL_INTERVAL 5
#define DTU_PA_LEVEL 0
#define DTU_SERIAL 0x99978563412U
#define DTU_POLL_INTERVAL 5U
#define DTU_NRF_PA_LEVEL 0U
#define DTU_CMT_PA_LEVEL 0
#define DTU_CMT_FREQUENCY 865000000U
#define DTU_CMT_COUNTRY_MODE 0U
#define MQTT_HASS_ENABLED false
#define MQTT_HASS_EXPIRE true
@ -88,5 +97,16 @@
#define DISPLAY_POWERSAFE true
#define DISPLAY_SCREENSAVER true
#define DISPLAY_ROTATION 2
#define DISPLAY_CONTRAST 60
#define DISPLAY_ROTATION 2U
#define DISPLAY_CONTRAST 60U
#define DISPLAY_LOCALE "en"
#define DISPLAY_DIAGRAM_DURATION (10UL * 60UL * 60UL)
#define DISPLAY_DIAGRAM_MODE 1U
#define REACHABLE_THRESHOLD 2U
#define LED_BRIGHTNESS 100U
#define MAX_INVERTER_LIMIT 2250
#define LANG_PACK_SUFFIX ".lang.json"

9
lang/README.md Normal file
View File

@ -0,0 +1,9 @@
# Language Packs
This folder contains language packs for OpenDTU which can be uploaded to the
device using the "Config Management" function.
Select "Language Pack" in the restore section, select a `.json` file containing
your language and press "Restore". Afterwards all language selection drop down
menues contain the new language.
Create a pull to request to share your own language pack (or corrections) with the community.

696
lang/es.lang.json Normal file
View File

@ -0,0 +1,696 @@
{
"meta": {
"name": "Español",
"code": "es"
},
"display": {
"date_format": "%d/%m/%Y %H:%M",
"offline": "Apagado",
"power_w": "%.0f W",
"power_kw": "%.1f kW",
"yield_today_wh": "Hoy: %4.0f Wh",
"yield_today_kwh": "Hoy: %.1f kWh",
"yield_total_kwh": "Total: %.1f kWh",
"yield_total_mwh": "Total: %.0f kWh"
},
"webapp": {
"menu": {
"LiveView": "Vista en directo",
"Settings": "Ajustes",
"NetworkSettings": "Ajustes de Red",
"NTPSettings": "Ajustes NTP",
"MQTTSettings": "Ajustes MQTT",
"InverterSettings": "Ajustes Inversor",
"SecuritySettings": "Ajustes Seguridad",
"DTUSettings": "Ajustes DTU",
"DeviceManager": "Administrador Dispositivos",
"ConfigManagement": "Gestión configuración",
"FirmwareUpgrade": "Actualización Firmware",
"DeviceReboot": "Reinicio Dispositivo",
"Info": "Info",
"System": "Sistema",
"Network": "Red",
"NTP": "NTP",
"MQTT": "MQTT",
"Console": "Consola",
"About": "Acerca",
"Logout": "Logout",
"Login": "Login"
},
"base": {
"Loading": "Cargando...",
"Reload": "Recargar",
"Cancel": "Cancelar",
"Save": "Guardar",
"Refreshing": "Refrescando",
"Pull": "Tira hacia abajo para refrescar",
"Release": "Soltar para refrescar",
"Close": "Cerrar",
"Yes": "Yes",
"No": "No"
},
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": {
"Oops": "Oops!"
},
"localeswitcher": {
"Dark": "Oscuro",
"Light": "Claro",
"Auto": "Automático"
},
"apiresponse": {
"1001": "¡Opciones guardadas!",
"1002": "No se encontraron valores",
"1003": "Datos demasiado grandes",
"1004": "Fallo al procesar los datos",
"1005": "Faltan valores",
"1006": "Fallo en la escritura",
"2001": "¡El número de serie no puede ser cero!",
"2002": "Intervalo de Poll interval debe ser mayor que cero!",
"2003": "Configuración de potencia incorrecta!",
"2004": "La frecuencia debe estar entre {min} y {max} kHz y debe ser un múltiplo de 250 kHz!",
"2005": "Modelo desconocido! Por favor, informe el \"Modelo de pieza de hardware\" y el modelo (por ejemplo, HM-350) como un problema en <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">aquí</a>.",
"3001": "No se eliminó nada",
"3002": "Configuración borrada. Reinicio en curso...",
"4001": "@:apiresponse.2001",
"4002": "El nombre debe tener entre 1 y {max} caracteres de longitud!",
"4003": "Solo se admiten {max} inversores!",
"4004": "Inversor creado!",
"4005": "ID no válido especificado",
"4006": "Cantidad de canales máxima incorrecta dada!",
"4007": "Inversor modificado!",
"4008": "Inversor eliminado!",
"4009": "Orden de inversores guardado!",
"5001": "@:apiresponse.2001",
"5002": "Límite debe estar entre 1 y {max}!",
"5003": "Tipo incorrecto especificado!",
"5004": "Inversor incorrecto especificado!",
"6001": "Reinicio desencadenado!",
"6002": "Reinicio cancelado!",
"7001": "¡El servidor MQTT debe tener entre 1 y {max} caracteres de longitud!",
"7002": "¡El nombre de usuario debe no tener más de {max} caracteres!",
"7003": "¡La contraseña debe no tener más de {max} caracteres!",
"7004": "¡El tema debe tener entre 1 y {max} caracteres de longitud!",
"7005": "¡El tema no debe contener caracteres de espacio!",
"7006": "¡El tema debe terminar con barra inclinada (/)!",
"7007": "¡El puerto debe ser un número entre 1 y 65535!",
"7008": "¡El certificado debe tener entre 1 y {max} caracteres de longitud!",
"7009": "¡El tema LWT debe tener entre 1 y {max} caracteres de longitud!",
"7010": "¡El tema LWT no debe contener caracteres de espacio!",
"7011": "¡El valor LWT en línea debe tener entre 1 y {max} caracteres de longitud!",
"7012": "¡El valor LWT fuera de línea debe tener entre 1 y {max} caracteres de longitud!",
"7013": "¡El intervalo de publicación debe ser un número entre {min} y {max}!",
"7014": "¡El tema Hass debe tener entre 1 y {max} caracteres de longitud!",
"7015": "¡El tema Hass no debe contener caracteres de espacio!",
"7016": "¡La QoS LWT no debe ser mayor que {max}!",
"7017": "Client ID must not longer then {max} characters!",
"8001": "¡La dirección IP no es válida!",
"8002": "¡La máscara de red no es válida!",
"8003": "¡El gateway no es válido!",
"8004": "¡La dirección IP del servidor DNS 1 no es válida!",
"8005": "¡La dirección IP del servidor DNS 2 no es válida!",
"8006": "¡El valor de tiempo de espera del punto de acceso administrativo es inválido!",
"9001": "¡El servidor NTP debe tener entre 1 y {max} caracteres de longitud!",
"9002": "¡La zona horaria debe tener entre 1 y {max} caracteres de longitud!",
"9003": "¡La descripción de la zona horaria debe tener entre 1 y {max} caracteres de longitud!",
"9004": "¡El año debe ser un número entre {min} y {max}!",
"9005": "¡El mes debe ser un número entre {min} y {max}!",
"9006": "¡El día debe ser un número entre {min} y {max}!",
"9007": "¡La hora debe ser un número entre {min} y {max}!",
"9008": "¡Los minutos deben ser un número entre {min} y {max}!",
"9009": "¡Los segundos deben ser un número entre {min} y {max}!",
"9010": "¡Hora actualizada!",
"10001": "¡La contraseña debe tener entre 8 y {max} caracteres de longitud!",
"10002": "¡Autenticación exitosa!",
"11001": "¡@:apiresponse.2001",
"11002": "¡@:apiresponse:5004",
"12001": "¡El perfil debe tener entre 1 y {max} caracteres de longitud!"
},
"home": {
"LiveData": "Datos en Vivo",
"SerialNumber": "Número de Serie: ",
"CurrentLimit": "Límite de Corriente: ",
"DataAge": "Edad de los Datos: ",
"Seconds": "{val} segundos",
"ShowSetInverterLimit": "Ver / Establecer Límite del Inversor",
"TurnOnOff": "Encender/Apagar el Inversor",
"ShowInverterInfo": "Ver Información del Inversor",
"ShowEventlog": "Ver Registro de Eventos",
"UnreadMessages": "mensajes sin leer",
"Loading": "@:base.Cargando",
"EventLog": "Registro de Eventos",
"InverterInfo": "Información del Inversor",
"LimitSettings": "Configuración de Límites",
"LastLimitSetStatus": "Último Estado de Configuración del Límite:",
"SetLimit": "Establecer Límite:",
"Relative": "Relativo (%)",
"Absolute": "Absoluto (W)",
"LimitHint": "<b>Consejo:</b> Si establece el límite como un valor absoluto, la visualización del valor actual solo se actualizará después de ~4 minutos.",
"SetPersistent": "Establecer Límite Permanente",
"SetNonPersistent": "Establecer Límite No Permanente",
"PowerSettings": "Configuración de Energía",
"LastPowerSetStatus": "Último Estado de Configuración de Energía:",
"TurnOn": "Encender",
"TurnOff": "Apagar",
"Restart": "Reiniciar",
"Failure": "Fallo",
"Pending": "Pendiente",
"Ok": "Aceptar",
"Unknown": "Desconocido",
"ShowGridProfile": "Ver Perfil de la Red",
"GridProfile": "Perfil de la Red",
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)",
"RadioStats": "Radio Statistics",
"TxRequest": "TX Request Count",
"RxSuccess": "RX Success",
"RxFailNothing": "RX Fail: Receive Nothing",
"RxFailPartial": "RX Fail: Receive Partial",
"RxFailCorrupt": "RX Fail: Receive Corrupt",
"TxReRequest": "TX Re-Request Fragment",
"StatsReset": "Reset Statistics",
"StatsResetting": "Resetting...",
"Rssi": "RSSI of last received packet",
"RssiHint": "HM inverters only support RSSI values < -64 dBm and > -64 dBm. In this case, -80 dbm and -30 dbm is shown.",
"dBm": "{dbm} dBm"
},
"eventlog": {
"Start": "Iniciar",
"Stop": "Parar",
"Id": "ID",
"Message": "Mensaje"
},
"devinfo": {
"NoInfo": "Sin información disponible",
"NoInfoLong": "No se ha recibido ningún dato válido del inversor hasta ahora. Todavía estamos intentando...",
"UnknownModel": "¡Modelo desconocido! Por favor, informe el \"Número de parte de hardware\" y el modelo (por ejemplo, HM-350) como un problema <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">aquí</a>.",
"Serial": "Número de serie",
"ProdYear": "Año de producción",
"ProdWeek": "Semana de producción",
"Model": "Modelo",
"DetectedMaxPower": "Potencia máxima detectada",
"BootloaderVersion": "Versión del cargador de arranque",
"FirmwareVersion": "Versión del firmware",
"FirmwareBuildDate": "Fecha de construcción del firmware",
"HardwarePartNumber": "Número de parte de hardware",
"HardwareVersion": "Versión de hardware",
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
"Yes": "@:base.Yes",
"No": "@:base.No"
},
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
"NoInfoLong": "@:devinfo.NoInfoLong",
"Name": "Nombre",
"Version": "Versión",
"Enabled": "@:wifistationinfo.Enabled",
"Disabled": "@:wifistationinfo.Disabled",
"GridprofileSupport": "Apoyar el desarrollo",
"GridprofileSupportLong": "Por favor, consulte <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">aquí</a> para obtener más información."
},
"systeminfo": {
"SystemInfo": "Información del sistema",
"VersionError": "Error al obtener información de la versión",
"VersionNew": "¡Nueva versión disponible! ¡Mostrar cambios!",
"VersionOk": "¡Actualizado!"
},
"firmwareinfo": {
"FirmwareInformation": "Información del firmware",
"Hostname": "Hostname",
"SdkVersion": "Versión del SDK",
"ConfigVersion": "Versión de la configuración",
"FirmwareVersion": "Versión del firmware / Hash de Git",
"PioEnv": "Entorno PIO",
"FirmwareVersionHint": "Haga clic aquí para mostrar información sobre su versión actual",
"FirmwareUpdate": "Actualización de firmware",
"FirmwareUpdateHint": "Haga clic aquí para ver las diferencias entre su versión y la última versión",
"FrmwareUpdateAllow": "Al activar la comprobación de actualización, se envía una solicitud a GitHub.com cada vez que se llama a la página para recuperar la versión actualmente disponible. Si no está de acuerdo con esto, deje esta función desactivada.",
"ResetReason0": "Razón de reinicio CPU 0",
"ResetReason1": "Razón de reinicio CPU 1",
"ConfigSaveCount": "Contador de guardado de configuración",
"Uptime": "Tiempo de actividad",
"UptimeValue": "0 días {time} | 1 día {time} | {count} días {time}"
},
"hardwareinfo": {
"HardwareInformation": "Información del hardware",
"ChipModel": "Modelo de chip",
"ChipRevision": "Revisión de chip",
"ChipCores": "Núcleos del chip",
"CpuFrequency": "Frecuencia de la CPU",
"Mhz": "MHz",
"CpuTemperature": "CPU Temperature",
"FlashSize": "Flash Memory Size"
},
"memoryinfo": {
"MemoryInformation": "Información de la memoria",
"Type": "Tipo",
"Usage": "Uso",
"Free": "Libre",
"Used": "Usado",
"Size": "Tamaño",
"Heap": "Montón",
"PsRam": "PSRAM",
"LittleFs": "LittleFs",
"Sketch": "Boceto"
},
"heapdetails": {
"HeapDetails": "Detalles del montón",
"TotalFree": "Total libre",
"LargestFreeBlock": "Bloque libre contiguo más grande",
"MaxUsage": "Uso máximo desde el inicio",
"Fragmentation": "Nivel de fragmentación"
},
"taskdetails": {
"TaskDetails": "Task Details",
"Name": "Name",
"StackFree": "Stack Free",
"Priority": "Priority",
"Task_idle0": "Idle (CPU Core 0)",
"Task_idle1": "Idle (CPU Core 1)",
"Task_wifi": "Wi-Fi",
"Task_tit": "TCP/IP",
"Task_looptask": "Arduino Main Loop",
"Task_asynctcp": "Async TCP",
"Task_mqttclient": "MQTT Client",
"Task_huaweican0": "AC Charger CAN",
"Task_pmsdm": "PowerMeter (SDM)",
"Task_pmhttpjson": "PowerMeter (HTTP+JSON)",
"Task_pmsml": "PowerMeter (Serial SML)",
"Task_pmhttpsml": "PowerMeter (HTTP+SML)"
},
"radioinfo": {
"RadioInformation": "Información de la radio",
"Status": "Estado de {module}",
"ChipStatus": "Estado del chip de {module}",
"ChipType": "Tipo de chip de {module}",
"Connected": "conectado",
"NotConnected": "no conectado",
"Configured": "configurado",
"NotConfigured": "no configurado",
"Unknown": "Desconocido"
},
"networkinfo": {
"NetworkInformation": "Información de la red"
},
"wifistationinfo": {
"WifiStationInfo": "Información de WiFi (Estación)",
"Status": "Estado",
"Enabled": "habilitado",
"Disabled": "deshabilitado",
"Ssid": "SSID",
"Bssid": "BSSID",
"Quality": "Calidad",
"Rssi": "RSSI"
},
"wifiapinfo": {
"WifiApInfo": "Información de WiFi (Punto de acceso)",
"Status": "@:wifistationinfo.Status",
"Enabled": "@:wifistationinfo.Enabled",
"Disabled": "@:wifistationinfo.Disabled",
"Ssid": "@:wifistationinfo.Ssid",
"Stations": "# Estaciones"
},
"interfacenetworkinfo": {
"NetworkInterface": "Interfaz de red ({iface})",
"Hostname": "@:firmwareinfo.Hostname",
"IpAddress": "Dirección IP",
"Netmask": "Máscara de red",
"DefaultGateway": "Puerta de enlace predeterminada",
"Dns": "DNS {num}",
"MacAddress": "Dirección MAC"
},
"interfaceapinfo": {
"NetworkInterface": "Interfaz de red (Punto de acceso)",
"IpAddress": "@:interfacenetworkinfo.IpAddress",
"MacAddress": "@:interfacenetworkinfo.MacAddress"
},
"ntpinfo": {
"NtpInformation": "Información de NTP",
"ConfigurationSummary": "Resumen de configuración",
"Server": "Servidor",
"Timezone": "Zona horaria",
"TimezoneDescription": "Descripción de la zona horaria",
"CurrentTime": "Hora actual",
"Status": "Estado",
"Synced": "sincronizado",
"NotSynced": "no sincronizado",
"LocalTime": "Hora local",
"Sunrise": "Amanecer",
"Sunset": "Atardecer",
"NotAvailable": "No disponible",
"Mode": "Modo",
"Day": "Día",
"Night": "Noche"
},
"mqttinfo": {
"MqttInformation": "Información de MQTT",
"ConfigurationSummary": "@:ntpinfo.ConfigurationSummary",
"Status": "@:ntpinfo.Status",
"Enabled": "Habilitado",
"Disabled": "Deshabilitado",
"Server": "@:ntpinfo.Server",
"Port": "Puerto",
"ClientId": "Client ID",
"Username": "Nombre de usuario",
"BaseTopic": "Tema base",
"PublishInterval": "Intervalo de publicación",
"Seconds": "{sec} segundos",
"CleanSession": "Bandera CleanSession",
"Retain": "Retener",
"Tls": "TLS",
"RootCertifcateInfo": "Información del certificado raíz de CA",
"TlsCertLogin": "Iniciar sesión con certificado TLS",
"ClientCertifcateInfo": "Información del Certificado del Cliente",
"HassSummary": "Resumen de la Configuración de Descubrimiento Automático MQTT de Home Assistant",
"Expire": "Expirar",
"IndividualPanels": "Paneles Individuales",
"RuntimeSummary": "Resumen de Tiempo de Ejecución",
"ConnectionStatus": "Estado de Conexión",
"Connected": "conectado",
"Disconnected": "desconectado"
},
"console": {
"Console": "Consola",
"VirtualDebugConsole": "Consola de Depuración Virtual",
"EnableAutoScroll": "Habilitar Desplazamiento Automático",
"ClearConsole": "Limpiar Consola",
"CopyToClipboard": "Copiar al Portapapeles"
},
"inverterchannelinfo": {
"String": "Cadena {num}",
"Phase": "Fase {num}",
"General": "General"
},
"invertertotalinfo": {
"TotalYieldTotal": "Total de Rendimiento Acumulado",
"TotalYieldDay": "Total de Rendimiento del Día",
"TotalPower": "Potencia Total"
},
"inverterchannelproperty": {
"Power": "Potencia",
"Voltage": "Voltaje",
"Current": "Corriente",
"Power DC": "Potencia DC",
"YieldDay": "Rendimiento del Día",
"YieldTotal": "Rendimiento Total",
"Frequency": "Frecuencia",
"Temperature": "Temperatura",
"PowerFactor": "Factor de Potencia",
"ReactivePower": "Potencia Reactiva",
"Efficiency": "Eficiencia",
"Irradiation": "Irradiación"
},
"maintenancereboot": {
"DeviceReboot": "Reinicio del Dispositivo",
"PerformReboot": "Realizar Reinicio",
"Reboot": "¡Reiniciar!",
"Cancel": "@:base.Cancel",
"RebootOpenDTU": "Reiniciar OpenDTU",
"RebootQuestion": "¿Realmente desea reiniciar el dispositivo?",
"RebootHint": "<b>Nota:</b> Normalmente no es necesario realizar un reinicio manual. OpenDTU realiza cualquier reinicio necesario (por ejemplo, después de una actualización de firmware) automáticamente. También se adoptan configuraciones sin reiniciar. Si necesita reiniciar debido a un error, considere informarlo en <a href=\"https://github.com/tbnobody/OpenDTU/issues\" class=\"alert-link\" target=\"_blank\">https://github.com/tbnobody/OpenDTU/issues</a>."
},
"dtuadmin": {
"DtuSettings": "Configuración de DTU",
"DtuConfiguration": "Configuración de DTU",
"Serial": "Serial",
"SerialHint": "Tanto el inversor como el DTU tienen un número de serie. El número de serie del DTU se genera aleatoriamente en el primer inicio y generalmente no es necesario cambiarlo.",
"PollInterval": "Intervalo de Sondeo",
"Seconds": "Segundos",
"NrfPaLevel": "Potencia de Transmisión NRF24",
"CmtPaLevel": "Potencia de Transmisión CMT2300A",
"NrfPaLevelHint": "Utilizado para inversores HM. Asegúrese de que su fuente de alimentación sea lo suficientemente estable antes de aumentar la potencia de transmisión.",
"CmtPaLevelHint": "Utilizado para inversores HMS/HMT. Asegúrese de que su fuente de alimentación sea lo suficientemente estable antes de aumentar la potencia de transmisión.",
"CmtCountry": "Región/País CMT2300A",
"CmtCountryHint": "Cada país tiene asignaciones de frecuencia diferentes.",
"country_0": "Europa ({min}MHz - {max}MHz)",
"country_1": "América del Norte ({min}MHz - {max}MHz)",
"country_2": "Brasil ({min}MHz - {max}MHz)",
"CmtFrequency": "Frecuencia CMT2300A",
"CmtFrequencyHint": "¡Asegúrese de utilizar solo frecuencias permitidas en el país respectivo! Después de un cambio de frecuencia, puede tardar hasta 15 minutos en establecer una conexión.",
"CmtFrequencyWarning": "La frecuencia seleccionada está fuera del rango permitido en su región/país seleccionado. Asegúrese de que esta selección no infrinja ninguna regulación local.",
"MHz": "{mhz} MHz",
"dBm": "{dbm} dBm",
"Min": "Mínimo ({db} dBm)",
"Low": "Bajo ({db} dBm)",
"High": "Alto ({db} dBm)",
"Max": "Máximo ({db} dBm)"
},
"securityadmin": {
"SecuritySettings": "Configuración de Seguridad",
"AdminPassword": "Contraseña de Administrador",
"Password": "Contraseña",
"RepeatPassword": "Repetir Contraseña",
"PasswordHint": "<b>Consejo:</b> La contraseña de administrador se utiliza para acceder a esta interfaz web (usuario 'admin'), pero también para conectarse al dispositivo cuando está en modo AP. Debe tener 8 a 64 caracteres.",
"Permissions": "Permisos",
"ReadOnly": "Permitir acceso de solo lectura a la interfaz web sin contraseña"
},
"ntpadmin": {
"NtpSettings": "Configuración de NTP",
"NtpConfiguration": "Configuración de NTP",
"TimeServer": "Servidor de Tiempo",
"TimeServerHint": "El valor predeterminado es adecuado siempre que OpenDTU tenga acceso directo a Internet.",
"Timezone": "Zona Horaria",
"TimezoneConfig": "Configuración de Zona Horaria",
"LocationConfiguration": "Configuración de Ubicación",
"Longitude": "Longitud",
"Latitude": "Latitud",
"SunSetType": "Tipo de Atardecer",
"SunSetTypeHint": "Afecta al cálculo día/noche. Puede tardar hasta un minuto en aplicarse el nuevo tipo.",
"OFFICIAL": "Amanecer estándar (90.8°)",
"NAUTICAL": "Amanecer náutico (102°)",
"CIVIL": "Amanecer civil (96°)",
"ASTONOMICAL": "Amanecer astronómico (108°)",
"ManualTimeSynchronization": "Sincronización Manual del Tiempo",
"CurrentOpenDtuTime": "Hora Actual de OpenDTU",
"CurrentLocalTime": "Hora Local Actual",
"SynchronizeTime": "Sincronizar Tiempo",
"SynchronizeTimeHint": "<b>Consejo:</b> Puede utilizar la sincronización manual del tiempo para establecer la hora actual de OpenDTU si no hay un servidor NTP disponible. Pero tenga en cuenta que en caso de un ciclo de energía, se perderá la hora. Además, tenga en cuenta que la precisión del tiempo se verá gravemente afectada, ya que no se puede resincronizar regularmente y el microcontrolador ESP32 no tiene un reloj en tiempo real."
},
"networkadmin": {
"NetworkSettings": "Configuración de Red",
"WifiConfiguration": "Configuración de WiFi",
"WifiSsid": "SSID de WiFi",
"WifiPassword": "Contraseña de WiFi",
"Hostname": "Nombre de Host",
"HostnameHint": "<b>Consejo:</b> El texto <span class=\"font-monospace\">%06X</span> se remplazará con los últimos 6 dígitos del ChipID de ESP en formato hexadecimal.",
"EnableDhcp": "Habilitar DHCP",
"StaticIpConfiguration": "Configuración de IP Estática",
"IpAddress": "Dirección IP",
"Netmask": "Máscara de Red",
"DefaultGateway": "Puerta de Enlace Predeterminada",
"Dns": "Servidor DNS {num}",
"AdminAp": "Configuración de WiFi (Punto de Acceso de Administrador)",
"ApTimeout": "Tiempo de espera del Punto de Acceso",
"ApTimeoutHint": "Tiempo que se mantiene abierto el Punto de Acceso. Un valor de 0 significa infinito.",
"Minutes": "minutos",
"EnableMdns": "Habilitar mDNS",
"MdnsSettings": "Configuración de mDNS"
},
"mqttadmin": {
"MqttSettings": "Configuración de MQTT",
"MqttConfiguration": "Configuración de MQTT",
"EnableMqtt": "Habilitar MQTT",
"EnableHass": "Habilitar Descubrimiento Automático MQTT de Home Assistant",
"MqttBrokerParameter": "Parámetros del Broker MQTT",
"Hostname": "Nombre de Host",
"HostnameHint": "Nombre de host o dirección IP",
"Port": "Puerto",
"ClientId": "Client ID",
"Username": "Nombre de Usuario",
"UsernameHint": "Nombre de usuario, dejar vacío para conexión anónima",
"Password": "Contraseña",
"PasswordHint": "Contraseña, dejar vacío para conexión anónima",
"BaseTopic": "Tema Base",
"BaseTopicHint": "Tema base, se antepondrá a todos los temas publicados (por ejemplo, inverter/)",
"PublishInterval": "Intervalo de Publicación",
"Seconds": "segundos",
"CleanSession": "Habilitar Bandera CleanSession",
"EnableRetain": "Habilitar Bandera Retain",
"EnableTls": "Habilitar TLS",
"RootCa": "Certificado Raíz CA (predeterminado Letsencrypt)",
"TlsCertLoginEnable": "Habilitar Inicio de Sesión con Certificado TLS",
"ClientCert": "Certificado del Cliente TLS",
"ClientKey": "Clave del Cliente TLS",
"LwtParameters": "Parámetros de LWT",
"LwtTopic": "Tema de LWT",
"LwtTopicHint": "Tema de LWT, se añadirá al tema base",
"LwtOnline": "Mensaje de LWT en línea",
"LwtOnlineHint": "Mensaje que se publicará en el tema de LWT cuando esté en línea",
"LwtOffline": "Mensaje de LWT fuera de línea",
"LwtOfflineHint": "Mensaje que se publicará en el tema de LWT cuando esté fuera de línea",
"LwtQos": "QoS (Calidad de Servicio)",
"QOS0": "0 (Como máximo una vez)",
"QOS1": "1 (Al menos una vez)",
"QOS2": "2 (Exactamente una vez)",
"HassParameters": "Parámetros de Descubrimiento Automático MQTT de Home Assistant",
"HassPrefixTopic": "Tema de Prefijo",
"HassPrefixTopicHint": "El prefijo para el tema de descubrimiento",
"HassRetain": "Habilitar Bandera Retain",
"HassExpire": "Habilitar Expiración",
"HassIndividual": "Paneles Individuales"
},
"inverteradmin": {
"InverterSettings": "Configuración del Inversor",
"AddInverter": "Agregar un nuevo Inversor",
"Serial": "Serial",
"Name": "Nombre",
"Add": "Agregar",
"AddHint": "<b>Consejo:</b> Puede configurar parámetros adicionales después de haber creado el inversor. Use el ícono de lápiz en la lista de inversores.",
"InverterList": "Lista de Inversores",
"Status": "Estado",
"Send": "Enviar",
"Receive": "Recibir",
"StatusHint": "<b>Consejo:</b> El inversor se alimenta con su entrada de CC. Si no hay sol, el inversor está apagado. Aún se pueden enviar solicitudes.",
"Type": "Tipo",
"Action": "Acción",
"SaveOrder": "Guardar orden",
"DeleteInverter": "Eliminar inversor",
"EditInverter": "Editar inversor",
"General": "General",
"String": "Cadena",
"Advanced": "Avanzado",
"InverterSerial": "Serial del Inversor:",
"InverterName": "Nombre del Inversor:",
"InverterNameHint": "Aquí puede especificar un nombre personalizado para su inversor.",
"InverterStatus": "Recibir / Enviar",
"PollEnable": "Sondear datos del inversor",
"PollEnableNight": "Sondear datos del inversor por la noche",
"CommandEnable": "Enviar comandos",
"CommandEnableNight": "Enviar comandos por la noche",
"StringName": "Nombre de cadena {num}:",
"StringNameHint": "Aquí puede especificar un nombre personalizado para el puerto respectivo de su inversor.",
"StringMaxPower": "Potencia máxima de cadena {num}:",
"StringMaxPowerHint": "Ingrese la potencia máxima de los paneles solares conectados.",
"StringYtOffset": "Compensación total de rendimiento de cadena {num}:",
"StringYtOffsetHint": "Esta compensación se aplica al valor total de rendimiento leído del inversor. Esto se puede usar para ajustar el rendimiento total del inversor a cero si se utiliza un inversor usado. Pero aún puede intentar sondear datos.",
"InverterHint": "*) Ingrese W<sub>p</sub> del canal para calcular la irradiación.",
"ReachableThreshold": "Umbral de Alcanzabilidad",
"ReachableThresholdHint": "Define cuántas solicitudes se permiten fallar hasta que el inversor se considere no alcanzable.",
"ZeroRuntime": "Datos de tiempo cero",
"ZeroRuntimeHint": "Datos de tiempo cero (sin datos de rendimiento) si el inversor se vuelve inalcanzable.",
"ZeroDay": "Rendimiento diario cero a medianoche",
"ZeroDayHint": "Esto solo funciona si el inversor es inalcanzable. Si se leen datos del inversor, se usarán sus valores. (El reinicio solo ocurre en el ciclo de energía)",
"ClearEventlog": "Clear Eventlog at midnight",
"Cancel": "@:base.Cancel",
"Save": "@:base.Save",
"DeleteMsg": "¿Está seguro de que desea eliminar el inversor \"{name}\" con número de serie {serial}?",
"Delete": "Eliminar",
"YieldDayCorrection": "Corrección de Rendimiento Diario",
"YieldDayCorrectionHint": "Sumar el rendimiento diario incluso si el inversor se reinicia. El valor se restablecerá a medianoche"
},
"fileadmin": {
"ConfigManagement": "Gestión de Configuración",
"BackupHeader": "Copia de seguridad: Copia de Seguridad del Archivo de Configuración",
"BackupConfig": "Copia de seguridad del archivo de configuración",
"Backup": "Copia de seguridad",
"Restore": "Restaurar",
"NoFileSelected": "Ningún archivo seleccionado",
"RestoreHeader": "Restaurar: Restaurar el Archivo de Configuración",
"Back": "Atrás",
"UploadSuccess": "Carga Exitosa",
"RestoreHint": "<b>Nota:</b> Esta operación reemplaza el archivo de configuración con la configuración restaurada y reinicia OpenDTU para aplicar todas las configuraciones.",
"ResetHeader": "Inicializar: Realizar Restablecimiento de Fábrica",
"FactoryResetButton": "Restaurar Configuraciones Predeterminadas de Fábrica",
"ResetHint": "<b>Nota:</b> Haga clic en Restaurar Configuraciones Predeterminadas de Fábrica para restaurar e inicializar las configuraciones predeterminadas de fábrica y reiniciar.",
"FactoryReset": "Restablecimiento de Fábrica",
"ResetMsg": "¿Está seguro de que desea eliminar la configuración actual y restablecer todas las configuraciones a sus valores predeterminados de fábrica?",
"ResetConfirm": "Restablecimiento de Fábrica",
"Cancel": "@:base.Cancel",
"InvalidJson": "JSON file is formatted incorrectly.",
"InvalidJsonContent": "JSON file has the wrong content."
},
"login": {
"Login": "Iniciar Sesión",
"SystemLogin": "Inicio de Sesión en el Sistema",
"Username": "Nombre de Usuario",
"UsernameRequired": "Se requiere el nombre de usuario",
"Password": "Contraseña",
"PasswordRequired": "Se requiere la contraseña",
"LoginButton": "Iniciar Sesión"
},
"firmwareupgrade": {
"FirmwareUpgrade": "Actualización de Firmware",
"Loading": "@:base.Loading",
"OtaError": "Error OTA",
"Back": "Atrás",
"Retry": "Reintentar",
"OtaStatus": "Estado OTA",
"OtaSuccess": "La carga de firmware fue exitosa. El dispositivo se reinició automáticamente. Cuando el dispositivo vuelva a ser accesible, la interfaz se recargará automáticamente.",
"FirmwareUpload": "Carga de Firmware",
"UploadProgress": "Progreso de Carga"
},
"about": {
"AboutOpendtu": "Acerca de OpenDTU",
"Documentation": "Documentation",
"DocumentationBody": "The firmware and hardware documentation can be found here: <a href=\"https://www.opendtu.solar\" target=\"_blank\">https://www.opendtu.solar</a>",
"ProjectOrigin": "Origen del Proyecto",
"ProjectOriginBody1": "Este proyecto se inició a partir de <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">esta discusión. (Mikrocontroller.net)</a>",
"ProjectOriginBody2": "El protocolo de Hoymiles fue descifrado mediante los esfuerzos voluntarios de muchos participantes. OpenDTU, entre otros, se desarrolló basado en este trabajo. El proyecto está bajo una Licencia de Código Abierto (<a href=\"https://www.gnu.de/documents/gpl-2.0.de.html\" target=\"_blank\">Licencia Pública General de GNU versión 2</a>).",
"ProjectOriginBody3": "El software se desarrolló según nuestro mejor conocimiento y creencia. Sin embargo, no se acepta ninguna responsabilidad por un mal funcionamiento o pérdida de garantía del inversor.",
"ProjectOriginBody4": "OpenDTU está disponible de forma gratuita. Si pagaste dinero por el software, probablemente te estafaron.",
"NewsUpdates": "Noticias y Actualizaciones",
"NewsUpdatesBody": "Las nuevas actualizaciones se pueden encontrar en Github: <a href=\"https://github.com/tbnobody/OpenDTU\" target=\"_blank\">https://github.com/tbnobody/OpenDTU</a>",
"ErrorReporting": "Reporte de Errores",
"ErrorReportingBody": "Por favor, informa problemas utilizando la función proporcionada por <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">Github</a>",
"Discussion": "Discusión",
"DiscussionBody": "Discute con nosotros en <a href=\"https://discord.gg/WzhxEY62mB\" target=\"_blank\">Discord</a> o <a href=\"https://github.com/tbnobody/OpenDTU/discussions\" target=\"_blank\">Github</a>"
},
"hints": {
"RadioProblem": "No se pudo conectar a un módulo de radio configurado. Por favor, verifica la conexión.",
"TimeSync": "El reloj aún no ha sido sincronizado. Sin un reloj correctamente ajustado, no se realizan solicitudes al inversor. Esto es normal poco después del inicio. Sin embargo, después de un tiempo de ejecución más largo (>1 minuto), indica que el servidor NTP no es accesible.",
"TimeSyncLink": "Por favor, verifica la configuración de tu hora.",
"DefaultPassword": "Estás utilizando la contraseña predeterminada para la interfaz web y el punto de acceso de emergencia. Esto potencialmente es inseguro.",
"DefaultPasswordLink": "Por favor, cambia la contraseña.",
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu.solar/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
},
"deviceadmin": {
"DeviceManager": "Administrador de Dispositivos",
"ParseError": "Error de análisis en 'pin_mapping.json': {error}",
"PinAssignment": "Configuración de Conexión",
"SelectedProfile": "Perfil Seleccionado",
"DefaultProfile": "(Configuraciones predeterminadas)",
"ProfileHint": "Tu dispositivo puede dejar de responder si seleccionas un perfil incompatible. En este caso, debes realizar una eliminación a través de la interfaz serial.",
"Display": "Pantalla",
"PowerSafe": "Habilitar Ahorro de Energía",
"PowerSafeHint": "Apaga la pantalla si no hay un inversor produciendo.",
"Screensaver": "Habilitar Protector de Pantalla",
"ScreensaverHint": "Mueve la pantalla un poco en cada actualización para evitar el quemado. (Útil especialmente para pantallas OLED)",
"DiagramMode": "Modo de Diagrama",
"off": "Apagar",
"small": "Pequeño",
"fullscreen": "Pantalla Completa",
"DiagramDuration": "Duración del Diagrama",
"DiagramDurationHint": "El período de tiempo que se muestra en el diagrama.",
"Seconds": "Segundos",
"Contrast": "Contraste ({contrast})",
"Rotation": "Rotación",
"rot0": "Sin rotación",
"rot90": "Rotación de 90 grados",
"rot180": "Rotación de 180 grados",
"rot270": "Rotación de 270 grados",
"DisplayLanguage": "Idioma de la Pantalla",
"en": "Inglés",
"de": "Alemán",
"fr": "Francés",
"Leds": "LEDs",
"EqualBrightness": "Brillo Equitativo",
"LedBrightness": "Brillo del LED {led} ({brightness})"
},
"pininfo": {
"Category": "Categoría",
"Name": "Nombre",
"Number": "Número",
"ValueSelected": "Seleccionado",
"ValueActive": "Activo"
},
"inputserial": {
"format_hoymiles": "Hoymiles serial number format",
"format_converted": "Already converted serial number",
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
"format_unknown": "Unknown format"
}
}
}

696
lang/it.lang.json Normal file
View File

@ -0,0 +1,696 @@
{
"meta": {
"name": "Italiano",
"code": "it"
},
"display": {
"date_format": "%d/%m/%Y %H:%M",
"offline": "Offline",
"power_w": "%.0f W",
"power_kw": "%.1f kW",
"yield_today_wh": "oggi: %4.0f Wh",
"yield_today_kwh": "oggi: %.1f kWh",
"yield_total_kwh": "totale: %.1f kWh",
"yield_total_mwh": "totale: %.0f kWh"
},
"webapp": {
"menu": {
"LiveView": "Dati in tempo reale",
"Settings": "Impostazioni",
"NetworkSettings": "Impostazioni di rete",
"NTPSettings": "Impostazioni NTP",
"MQTTSettings": "Impostazioni MQTT",
"InverterSettings": "Impostazioni Inverter",
"SecuritySettings": "Impostazioni di Sicurezza",
"DTUSettings": "Impostazioni DTU",
"DeviceManager": "Gestione Dispositivi",
"ConfigManagement": "Gestione Configurazione",
"FirmwareUpgrade": "Aggiornamento Firmware",
"DeviceReboot": "Riavvio DTU",
"Info": "Info",
"System": "Sistema",
"Network": "Rete",
"NTP": "NTP",
"MQTT": "MQTT",
"Console": "Console",
"About": "Informazioni DTU",
"Logout": "Esci",
"Login": "Login"
},
"base": {
"Loading": "Caricamento...",
"Reload": "Ricarica",
"Cancel": "Cancella",
"Save": "Salva",
"Refreshing": "Aggiorna",
"Pull": "Trascina in basso per aggiornare",
"Release": "Rilascia per aggiornare",
"Close": "Chiudi",
"Yes": "Yes",
"No": "No"
},
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": {
"Oops": "Oops!"
},
"localeswitcher": {
"Dark": "Scuro",
"Light": "Chiaro",
"Auto": "Automatico"
},
"apiresponse": {
"1001": "Settings saved!",
"1002": "No values found!",
"1003": "Data too large!",
"1004": "Failed to parse data!",
"1005": "Values are missing!",
"1006": "Write failed!",
"2001": "Serial cannot be zero!",
"2002": "Poll interval must be greater zero!",
"2003": "Invalid power level setting!",
"2004": "The frequency must be set between {min} and {max} kHz and must be a multiple of 250kHz!",
"2005": "Invalid country selection!",
"3001": "Not deleted anything!",
"3002": "Configuration resettet. Rebooting now...",
"4001": "@:apiresponse.2001",
"4002": "Name must between 1 and {max} characters long!",
"4003": "Only {max} inverters are supported!",
"4004": "Inverter created!",
"4005": "Invalid ID specified!",
"4006": "Invalid amount of max channel setting given!",
"4007": "Inverter changed!",
"4008": "Inverter deleted!",
"4009": "Inverter order saved!",
"5001": "@:apiresponse.2001",
"5002": "Limit must between 1 and {max}!",
"5003": "Invalid type specified!",
"5004": "Invalid inverter specified!",
"6001": "Reboot triggered!",
"6002": "Reboot cancled!",
"7001": "MQTT Server must between 1 and {max} characters long!",
"7002": "Username must not longer then {max} characters!",
"7003": "Password must not longer then {max} characters!",
"7004": "Topic must not longer then {max} characters!",
"7005": "Topic must not contain space characters!",
"7006": "Topic must end with slash (/)!",
"7007": "Port must be a number between 1 and 65535!",
"7008": "Certificate must not longer then {max} characters!",
"7009": "LWT topic must not longer then {max} characters!",
"7010": "LWT topic must not contain space characters!",
"7011": "LWT online value must not longer then {max} characters!",
"7012": "LWT offline value must not longer then {max} characters!",
"7013": "Publish interval must be a number between {min} and {max}!",
"7014": "Hass topic must not longer then {max} characters!",
"7015": "Hass topic must not contain space characters!",
"7016": "LWT QOS must not greater then {max}!",
"7017": "Client ID must not longer then {max} characters!",
"8001": "IP address is invalid!",
"8002": "Netmask is invalid!",
"8003": "Gateway is invalid!",
"8004": "DNS Server IP 1 is invalid!",
"8005": "DNS Server IP 2 is invalid!",
"8006": "Administrative AccessPoint Timeout value is invalid",
"9001": "NTP Server must between 1 and {max} characters long!",
"9002": "Timezone must between 1 and {max} characters long!",
"9003": "Timezone description must between 1 and {max} characters long!",
"9004": "Year must be a number between {min} and {max}!",
"9005": "Month must be a number between {min} and {max}!",
"9006": "Day must be a number between {min} and {max}!",
"9007": "Hour must be a number between {min} and {max}!",
"9008": "Minute must be a number between {min} and {max}!",
"9009": "Second must be a number between {min} and {max}!",
"9010": "Time updated!",
"10001": "Password must between 8 and {max} characters long!",
"10002": "Authentication successful!",
"11001": "@:apiresponse.2001",
"11002": "@:apiresponse:5004",
"12001": "Profil must between 1 and {max} characters long!"
},
"home": {
"LiveData": "Dati in tempo reale",
"SerialNumber": "Numero seriale: ",
"CurrentLimit": "Limite attuale: ",
"DataAge": "Aggiornamento Dati: ",
"Seconds": "{val} secondi",
"ShowSetInverterLimit": "Mostra / Imposta Limite di Potenza",
"TurnOnOff": "Accendi/Spegni Inverter",
"ShowInverterInfo": "Mostra info Inverter",
"ShowEventlog": "Mostra Log Eventi",
"UnreadMessages": "msg non letti",
"Loading": "@:base.Loading",
"EventLog": "Log Eventi",
"InverterInfo": "Info Inverter",
"LimitSettings": "Impostazioni Limite Potenza",
"LastLimitSetStatus": "Stato ultimo limite impostato:",
"SetLimit": "Imposta Limite a:",
"Relative": "Percentuale (%)",
"Absolute": "Assoluto (W)",
"LimitHint": "<b>Nota:</b> Se imposti il limite assoluto, il valore sul display sarà aggiornato dopo circa 4 minuti.",
"SetPersistent": "Imposta Limite in Modo Persistente",
"SetNonPersistent": "Imposta Limite Temporaneamente",
"PowerSettings": "Impostazioni Potenza",
"LastPowerSetStatus": "Ultimo Stato dell'Inverter:",
"TurnOn": "Accendi Inverter",
"TurnOff": "Spegni Inverter",
"Restart": "Riavvia Inverter",
"Failure": "Fallito",
"Pending": "In Attesa",
"Ok": "Ok",
"Unknown": "Sconosciuto",
"ShowGridProfile": "Mostra Settaggi Inverter",
"GridProfile": "Settaggi Inverter",
"LoadingInverter": "In attesa dei dati... (puo' richiedere fino a 10 secondi)",
"RadioStats": "Radio Statistics",
"TxRequest": "TX Request Count",
"RxSuccess": "RX Success",
"RxFailNothing": "RX Fail: Receive Nothing",
"RxFailPartial": "RX Fail: Receive Partial",
"RxFailCorrupt": "RX Fail: Receive Corrupt",
"TxReRequest": "TX Re-Request Fragment",
"StatsReset": "Reset Statistics",
"StatsResetting": "Resetting...",
"Rssi": "RSSI of last received packet",
"RssiHint": "HM inverters only support RSSI values < -64 dBm and > -64 dBm. In this case, -80 dbm and -30 dbm is shown.",
"dBm": "{dbm} dBm"
},
"eventlog": {
"Start": "Inizio",
"Stop": "Fine",
"Id": "ID",
"Message": "Messaggio"
},
"devinfo": {
"NoInfo": "Informazioni non disponibili",
"NoInfoLong": "Ancora nessuna informazione dall'inverter. Sto riprovando...",
"UnknownModel": "Modello sconosciuto! Per favore fornisci \"Hardware Part Number\" ed il modello (esempio HM-350) in una Issue su <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">GitHub</a>.",
"Serial": "Seriale",
"ProdYear": "Produzione Annua",
"ProdWeek": "Produzione Settimanale",
"Model": "Modello",
"DetectedMaxPower": "Rilevata potenza massima",
"BootloaderVersion": "Versione Bootloader",
"FirmwareVersion": "Versione Firmware",
"FirmwareBuildDate": "Data Firmware",
"HardwarePartNumber": "Hardware Part Number",
"HardwareVersion": "Hardware Version",
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
"Yes": "@:base.Yes",
"No": "@:base.No"
},
"gridprofile": {
"NoInfo": "@:devinfo.NoInfo",
"NoInfoLong": "@:devinfo.NoInfoLong",
"Name": "Nome",
"Version": "Versione",
"Enabled": "@:wifistationinfo.Enabled",
"Disabled": "@:wifistationinfo.Disabled",
"GridprofileSupport": "Supporto sviluppatori",
"GridprofileSupportLong": "Clicca <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">qui</a> per ulteriori informazioni."
},
"systeminfo": {
"SystemInfo": "Info Sistema",
"VersionError": "Errore ricezione della versione",
"VersionNew": "Nuova versione disponibile! Mostra aggiornamenti!",
"VersionOk": "Già aggiornato!"
},
"firmwareinfo": {
"FirmwareInformation": "Info Firmware",
"Hostname": "Hostname",
"SdkVersion": "SDK Version",
"ConfigVersion": "Config Version",
"FirmwareVersion": "Firmware Version / Git Hash",
"PioEnv": "PIO Environment",
"FirmwareVersionHint": "Click here to show information about your current version",
"FirmwareUpdate": "Firmware Update",
"FirmwareUpdateHint": "Click here to view the changes between your version and the latest version",
"FrmwareUpdateAllow": "By activating the update check, a request is sent to GitHub.com each time the page is called up to retrieve the currently available version. If you do not agree with this, leave this function deactivated.",
"ResetReason0": "Reset Reason CPU 0",
"ResetReason1": "Reset Reason CPU 1",
"ConfigSaveCount": "Config save count",
"Uptime": "Uptime",
"UptimeValue": "0 days {time} | 1 day {time} | {count} days {time}"
},
"hardwareinfo": {
"HardwareInformation": "Info Hardware",
"ChipModel": "Chip Model",
"ChipRevision": "Chip Revision",
"ChipCores": "Chip Cores",
"CpuFrequency": "CPU Frequency",
"Mhz": "MHz",
"CpuTemperature": "CPU Temperature",
"FlashSize": "Flash Memory Size"
},
"memoryinfo": {
"MemoryInformation": "Info Memoria",
"Type": "Tipo",
"Usage": "Uso",
"Free": "Libera",
"Used": "Usata",
"Size": "Dimensione",
"Heap": "Heap",
"PsRam": "PSRAM",
"LittleFs": "LittleFs",
"Sketch": "Sketch"
},
"heapdetails": {
"HeapDetails": "Dettagli memoria Heap",
"TotalFree": "Libera totale",
"LargestFreeBlock": "Blocco contiguo libero più grande",
"MaxUsage": "Massima utilizzata dall'avvio",
"Fragmentation": "Livello frammentazione"
},
"taskdetails": {
"TaskDetails": "Task Details",
"Name": "Name",
"StackFree": "Stack Free",
"Priority": "Priority",
"Task_idle0": "Idle (CPU Core 0)",
"Task_idle1": "Idle (CPU Core 1)",
"Task_wifi": "Wi-Fi",
"Task_tit": "TCP/IP",
"Task_looptask": "Arduino Main Loop",
"Task_asynctcp": "Async TCP",
"Task_mqttclient": "MQTT Client",
"Task_huaweican0": "AC Charger CAN",
"Task_pmsdm": "PowerMeter (SDM)",
"Task_pmhttpjson": "PowerMeter (HTTP+JSON)",
"Task_pmsml": "PowerMeter (Serial SML)",
"Task_pmhttpsml": "PowerMeter (HTTP+SML)"
},
"radioinfo": {
"RadioInformation": "Info Transceiver Radio",
"Status": "{module} Stato",
"ChipStatus": "{module} Chip Stato",
"ChipType": "{module} Chip Tipo",
"Connected": "connesso",
"NotConnected": "non connesso",
"Configured": "configurato",
"NotConfigured": "no configurato",
"Unknown": "Sconosciuto"
},
"networkinfo": {
"NetworkInformation": "Informazioni Rete"
},
"wifistationinfo": {
"WifiStationInfo": "Info WiFi (Station)",
"Status": "Stato",
"Enabled": "abilitato",
"Disabled": "disabilitato",
"Ssid": "SSID",
"Bssid": "BSSID",
"Quality": "Qualità",
"Rssi": "RSSI"
},
"wifiapinfo": {
"WifiApInfo": "Info WiFi (Access Point)",
"Status": "@:wifistationinfo.Status",
"Enabled": "@:wifistationinfo.Enabled",
"Disabled": "@:wifistationinfo.Disabled",
"Ssid": "@:wifistationinfo.Ssid",
"Stations": "Numero Stazioni"
},
"interfacenetworkinfo": {
"NetworkInterface": "Interfaccia di Rete ({iface})",
"Hostname": "@:firmwareinfo.Hostname",
"IpAddress": "Indirizzo IP",
"Netmask": "Netmask",
"DefaultGateway": "Gateway",
"Dns": "DNS {num}",
"MacAddress": "Indirizzo MAC"
},
"interfaceapinfo": {
"NetworkInterface": "Interfaccia di Rete (Access Point)",
"IpAddress": "@:interfacenetworkinfo.IpAddress",
"MacAddress": "@:interfacenetworkinfo.MacAddress"
},
"ntpinfo": {
"NtpInformation": "Informazioni NTP",
"ConfigurationSummary": "Riepilogo Configurazione",
"Server": "Server",
"Timezone": "Timezone",
"TimezoneDescription": "Descrizione Timezone",
"CurrentTime": "Data/Ora attuale",
"Status": "Stato",
"Synced": "sincronizzata",
"NotSynced": "non sincronizzata",
"LocalTime": "Ora Locale",
"Sunrise": "Alba",
"Sunset": "Tramonto",
"NotAvailable": "Non Disponibile",
"Mode": "Modalità",
"Day": "Giorno",
"Night": "Notte"
},
"mqttinfo": {
"MqttInformation": "Informazioni MQTT",
"ConfigurationSummary": "@:ntpinfo.ConfigurationSummary",
"Status": "@:ntpinfo.Status",
"Enabled": "Abilitato",
"Disabled": "Disabilitato",
"Server": "@:ntpinfo.Server",
"Port": "Porta",
"ClientId": "Client ID",
"Username": "Username",
"BaseTopic": "Topic Base",
"PublishInterval": "Intervallo Publish",
"Seconds": "{sec} secondi",
"CleanSession": "CleanSession",
"Retain": "Retain",
"Tls": "TLS",
"RootCertifcateInfo": "Info Certificato Root CA",
"TlsCertLogin": "Entra con Certificato TLS",
"ClientCertifcateInfo": "Info Certificato Client",
"HassSummary": "Riepilogo Configurazione Home Assistant MQTT Auto Discovery",
"Expire": "Scade",
"IndividualPanels": "Pannello Individuale",
"RuntimeSummary": "Riepilogo Runtime",
"ConnectionStatus": "Stato Connessione",
"Connected": "connesso",
"Disconnected": "disconnesso"
},
"console": {
"Console": "Console",
"VirtualDebugConsole": "Virtual Debug Console",
"EnableAutoScroll": "Abilita AutoScroll",
"ClearConsole": "Pulisci Console",
"CopyToClipboard": "Copia nella clipboard"
},
"inverterchannelinfo": {
"String": "Stringa {num}",
"Phase": "Fase {num}",
"General": "Generale"
},
"invertertotalinfo": {
"TotalYieldTotal": "Totale Energia",
"TotalYieldDay": "Energia Giornaliera",
"TotalPower": "Potenza Totale"
},
"inverterchannelproperty": {
"Power": "Potenza",
"Voltage": "Tensione",
"Current": "Corrente",
"Power DC": "PotenzaDC",
"YieldDay": "EnergiaOggi",
"YieldTotal": "EnergiaTotale",
"Frequency": "Frequenza",
"Temperature": "Temperatura",
"PowerFactor": "FattorePotenza",
"ReactivePower": "PotenzaReattiva",
"Efficiency": "Efficienza",
"Irradiation": "Irragiamento"
},
"maintenancereboot": {
"DeviceReboot": "Riavvio DTU",
"PerformReboot": "Fai il riavvio",
"Reboot": "Riavvio!",
"Cancel": "@:base.Cancel",
"RebootOpenDTU": "Riavvio OpenDTU",
"RebootQuestion": "Vuoi veramente riavvia il DTU?",
"RebootHint": "<b>Nota:</b> Normalmente non serve riavviare OpenDTU, in quanto esegue automaticamente il ravvio quando necessario (ad esempio dopo aggiornamento firmware). Modifiche alla configurazione vengono apprese subito, senza richiedere riavvio. Se devi riavviare a causa di un errore, ti preghiamo di segnalarcelo cliccando su <a href=\"https://github.com/tbnobody/OpenDTU/issues\" class=\"alert-link\" target=\"_blank\">https://github.com/tbnobody/OpenDTU/issues</a>."
},
"dtuadmin": {
"DtuSettings": "Impostazioni DTU",
"DtuConfiguration": "Configurazione DTU",
"Serial": "Seriale",
"SerialHint": "Sia il DTU che l'inverter hanno un numero seriale. Il numero seriale del DTU è generato casualmente al primo avvio e normalmente non serve modificarlo.",
"PollInterval": "Intervallo Interrogazione",
"Seconds": "Secondi",
"NrfPaLevel": "Potenza Trasmettitore NRF24",
"CmtPaLevel": "Potenza Trasmettitore CMT2300A",
"NrfPaLevelHint": "Usato per inverter HM. Considera che aumentando la potenza aumentano il consumo di corrente.",
"CmtPaLevelHint": "Usato per inverter HMS/HMT. Considera che aumentando la potenza aumentano il consumo di corrente.",
"CmtCountry": "CMT2300A Zona/Paese",
"CmtCountryHint": "Ogni zona ha una differente allocazione di frequenze utilizzabili.",
"country_0": "Europa ({min}MHz - {max}MHz)",
"country_1": "Nord America ({min}MHz - {max}MHz)",
"country_2": "Brasile ({min}MHz - {max}MHz)",
"CmtFrequency": "Frequenza CMT2300A",
"CmtFrequencyHint": "Fai attenzione ad usare solo frequenze ammesse nel tuo Paese! Dopo la modifica frequenza, servono fino a 15 minuti affinché la connessione si ristabilisca.",
"CmtFrequencyWarning": "La frequenza selezionata è fuori dal range selezionato dal tuo Paese. Verifica che la frequenza selezionata non violi le normative del tuo Paese.",
"MHz": "{mhz} MHz",
"dBm": "{dbm} dBm",
"Min": "Minima ({db} dBm)",
"Low": "Bassa ({db} dBm)",
"High": "Alta ({db} dBm)",
"Max": "Massima ({db} dBm)"
},
"securityadmin": {
"SecuritySettings": "Impostazioni di Sicurezza",
"AdminPassword": "Password Admin",
"Password": "Password",
"RepeatPassword": "Ripeti Password",
"PasswordHint": "<b>Nota:</b> La password di amministrazione viene utilizzata non solo per accedere a questa interfaccia web (con user 'admin'), ma anche per connettersi al dispositivo in modalità AP. Deve avere da 8 a 64 caratteri.",
"Permissions": "Permessi",
"ReadOnly": "Permetti accessi web in sola lettura senza richiedere la password"
},
"ntpadmin": {
"NtpSettings": "Impostazioni NTP (Data / Ora)",
"NtpConfiguration": "Configurazione NTP",
"TimeServer": "Server NTP",
"TimeServerHint": "Puoi lasciare il valore di default, nel caso in cui OpenDTU abbia accesso ad internet.",
"Timezone": "Timezone",
"TimezoneConfig": "Timezone Config",
"LocationConfiguration": "Configurazione Posizione",
"Longitude": "Longitudine",
"Latitude": "Latitudine",
"SunSetType": "Tipo di Alba",
"SunSetTypeHint": "Influenza il calcolo dell'ora di Alba/Tramonto. Dopo la conferma, è richiesto fino ad un minuto perché la modifica venga applicata.",
"OFFICIAL": "Standard dawn (90.8°)",
"NAUTICAL": "Nautical dawn (102°)",
"CIVIL": "Civil dawn (96°)",
"ASTONOMICAL": "Astronomical dawn (108°)",
"ManualTimeSynchronization": "Sincronizzazione Manuale Data/Ora",
"CurrentOpenDtuTime": "Ora OpenDTU attuale",
"CurrentLocalTime": "Ora Locale attuale",
"SynchronizeTime": "Sincronizza Data/Ora",
"SynchronizeTimeHint": "<b>Nota:</b> Puoi usare la sincronizzazione manuale per impostare Data/Ora nel caso che non sia disponibile un server NTP. In questo caso la data/ora viene persa in caso di mancata alimentazione. Inoltre, con la sincronizzazione manuale ci sarà una progressiva deriva della Data/Ora in quanto l'ESP32 non ha un Real Time Clock interno."
},
"networkadmin": {
"NetworkSettings": "Impostazioni di Rete",
"WifiConfiguration": "Configurazione WiFi",
"WifiSsid": "WiFi SSID",
"WifiPassword": "WiFi Password",
"Hostname": "Hostname",
"HostnameHint": "<b>Nota:</b> Il testo <span class=\"font-monospace\">%06X</span> sarà rimpiazzato con le ultime 6 cifre del ChipID dell'ESP32 in formato esadecimale.",
"EnableDhcp": "Abilita DHCP",
"StaticIpConfiguration": "Configurazione IP Statico",
"IpAddress": "Indirizzo IP",
"Netmask": "Netmask",
"DefaultGateway": "Default Gateway",
"Dns": "DNS Server {num}",
"AdminAp": "Configurazione WiFi (Admin AccessPoint)",
"ApTimeout": "Timeout AccessPoint",
"ApTimeoutHint": "Tempo in cui la modalità AccessPoint rimarrà attiva. 0=per sempre.",
"Minutes": "minuti",
"EnableMdns": "Abilita mDNS",
"MdnsSettings": "Configurazione mDNS"
},
"mqttadmin": {
"MqttSettings": "Impostazioni MQTT",
"MqttConfiguration": "Configurazione MQTT",
"EnableMqtt": "Abilita MQTT",
"EnableHass": "Abilita Home Assistant MQTT Auto Discovery",
"MqttBrokerParameter": "Parametri Broker MQTT",
"Hostname": "Hostname",
"HostnameHint": "Hostname o Indirizzo IP",
"Port": "Porta",
"ClientId": "Client ID",
"Username": "Username",
"UsernameHint": "Username, lascia vuoto per connessione anonima",
"Password": "Password",
"PasswordHint": "Password, lascia vuota per connessione anonima",
"BaseTopic": "Topic Base",
"BaseTopicHint": "Topic Base, prefisso da aggiungere (ad esempio inverter/)",
"PublishInterval": "Intervallo pubblicazione",
"Seconds": "secondi",
"CleanSession": "Abilita CleanSession",
"EnableRetain": "Abilita Retain",
"EnableTls": "Abilita TLS",
"RootCa": "CA-Root-Certificate (default Letsencrypt)",
"TlsCertLoginEnable": "Abilita Login con certificato TLS",
"ClientCert": "TLS Client-Certificate",
"ClientKey": "TLS Client-Key",
"LwtParameters": "Parametri LWT",
"LwtTopic": "Topic LWT",
"LwtTopicHint": "Topic LWT, da aggiungere al Topic Base",
"LwtOnline": "Messaggio 'Online0 LWT",
"LwtOnlineHint": "Messaggio pubblicato quando online",
"LwtOffline": "Messaggio 'Offline' LWT",
"LwtOfflineHint": "Messaggio che sarà pubblicato quando offline",
"LwtQos": "QoS (Quality of Service)",
"QOS0": "0 (Al massimo una volta)",
"QOS1": "1 (Almeno una volta)",
"QOS2": "2 (Esattamente una volta)",
"HassParameters": "Parametri Home Assistant MQTT Auto Discovery",
"HassPrefixTopic": "Prefisso Topic",
"HassPrefixTopicHint": "Prefisso per Topic autodiscovery",
"HassRetain": "Abilita Retain",
"HassExpire": "Abilita Scadenza",
"HassIndividual": "Pannelli Individuale"
},
"inverteradmin": {
"InverterSettings": "Impostazioni Inverter",
"AddInverter": "Aggiungi nuovo Inverter",
"Serial": "Seriale",
"Name": "Nome",
"Add": "Aggiungi",
"AddHint": "<b>Nota:</b> Potrai aggiungere ulteriori parametri dopo aver creato l'inverter, cliccando sull'icona 'Matita' nella lista inverter.",
"InverterList": "Lista Inverter",
"Status": "Stato",
"Send": "Invia",
"Receive": "Riceve",
"StatusHint": "<b>Nota:</b> L'inverter viene alimentato dal fotovoltaico. Durante la notte, l'inverter risulterà spento. Le richieste potranno comunque essere trasmesse.",
"Type": "Tipo",
"Action": "Azione",
"SaveOrder": "Salva ordine",
"DeleteInverter": "Rimuovi inverter",
"EditInverter": "Modifica inverter",
"General": "Generale",
"String": "Stringa",
"Advanced": "Avanzate",
"InverterSerial": "Seriale Inverter:",
"InverterName": "Nome Inverter:",
"InverterNameHint": "Puoi specificare un nome qualsiasi da assegnare all'inverter.",
"InverterStatus": "Riceve / Invia",
"PollEnable": "Interroga inverter",
"PollEnableNight": "Interroga inverter di notte",
"CommandEnable": "Invia comandi",
"CommandEnableNight": "Invia comandi di notte",
"StringName": "Nome stringa {num}:",
"StringNameHint": "Qui puoi specificare un nome qualsiasi per la porta dell'inverter o per il pannello fotovoltaico collegato.",
"StringMaxPower": "Massima potenza stringa {num}:",
"StringMaxPowerHint": "Inserisci la potenza massima associata ai panelli fotovoltaici collegati a questa stringa.",
"StringYtOffset": "Offset Energia totale per la stringa {num}:",
"StringYtOffsetHint": "Questo offset viene utilizzato per azzerare il contatore qualora venga usato un inverter usato.",
"InverterHint": "*) Inserisci la potenza W<sub>p</sub> dei pannelli fotovoltaici collegati alla stringa: servirà per calcolare l'irragiamento.",
"ReachableThreshold": "Reachable Threshold",
"ReachableThresholdHint": "Definisce il numero di richieste fallite prima che l'inverter sia considerato irraggiungibile.",
"ZeroRuntime": "Azzera dati in tempo reale",
"ZeroRuntimeHint": "Azzera i dati in tempo reale (tranne l'Energia) se l'inverter diventa irraggiunbile.",
"ZeroDay": "Azzera dati energia alla mezzanotte",
"ZeroDayHint": "Questo vale se l'inverter risulta irraggiungibile. Se l'inverter risponde anche di notte, verranno mostrati i suoi valori. (Il Reset si verifica al riavvio)",
"ClearEventlog": "Clear Eventlog at midnight",
"Cancel": "@:base.Cancel",
"Save": "@:base.Save",
"DeleteMsg": "Sicuro di voler rimuovere l'inverter \"{name}\" con numero seriale {serial}?",
"Delete": "Rimuovi",
"YieldDayCorrection": "Correzione energia giornaliera",
"YieldDayCorrectionHint": "Aggiungi questo valore all'energia giornaliera se l'inverter è stato riavviato. Questo valore sarò resettato a mezzanotte"
},
"fileadmin": {
"ConfigManagement": "Configurazione Gestione",
"BackupHeader": "Backup: Configurazione File Backup",
"BackupConfig": "Esegui il backup del file",
"Backup": "Backup",
"Restore": "Ripristina",
"NoFileSelected": "Nessun file selezionato",
"RestoreHeader": "Ripristina: Ripristina File Configurazione",
"Back": "Indietro",
"UploadSuccess": "Invio File con successo",
"RestoreHint": "<b>Nota:</b> questa operazione rimpiazza la configurazione con quella contenuta nel file, e poi riavvia automaticamente OpenDTU per applicare la nuova configurazione.",
"ResetHeader": "Inizializza: Esegui il Factory Reset",
"FactoryResetButton": "Ripristina Configurazione Factory-Default",
"ResetHint": "<b>Nota:</b> Clicca 'Ripristina Configurazione Factory-Default' per stabilire le impostazioni di fabbrica e riavviare automaticamente OpenDTU.",
"FactoryReset": "Factory Reset",
"ResetMsg": "Sei sicuro di voler cancellare la configurazione attuale e applicare la configurazione di fabbrica?",
"ResetConfirm": "Factory Reset!",
"Cancel": "@:base.Cancel",
"InvalidJson": "JSON file is formatted incorrectly.",
"InvalidJsonContent": "JSON file has the wrong content."
},
"login": {
"Login": "Login",
"SystemLogin": "System Login",
"Username": "Username",
"UsernameRequired": "Inserisci Username",
"Password": "Password",
"PasswordRequired": "Inserisci Password",
"LoginButton": "Login"
},
"firmwareupgrade": {
"FirmwareUpgrade": "Aggiornamento Firmware",
"Loading": "@:base.Loading",
"OtaError": "Errore aggiornamento OTA",
"Back": "Indietro",
"Retry": "Riprova",
"OtaStatus": "Stato OTA",
"OtaSuccess": "Aggiornamento firmware eseguito con successo. Il dispositivo si riavvierà automaticamente. Quando sarà nuovamente disponibile, l'interfacca sarà ricaricata automaticamente.",
"FirmwareUpload": "Invia Firmware",
"UploadProgress": "Upload in corso"
},
"about": {
"AboutOpendtu": "About OpenDTU",
"Documentation": "Documentazione",
"DocumentationBody": "La documentazione firmware e hardware sono disponibili qui: <a href=\"https://www.opendtu.solar\" target=\"_blank\">https://www.opendtu.solar</a>",
"ProjectOrigin": "Origine Progetto",
"ProjectOriginBody1": "Questo progetto è partito da <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">questa discussione. (Mikrocontroller.net)</a>",
"ProjectOriginBody2": "Il protocollo Hoymiles è stato decriptato grazie al contributo volontario di molti programmatori. OpenDTU, fra gli altri, è stato sviluppato grazie a questo lavoro. Il progetto è distribuito con Licenza Open Source (<a href=\"https://www.gnu.de/documents/gpl-2.0.de.html\" target=\"_blank\">GNU General Public License version 2</a>).",
"ProjectOriginBody3": "Il software è stato sviluppato con le nostre migliori conoscenze e convinzioni. Tuttavia, non si assume alcuna responsabilità per malfunzionamenti o perdita di garanzia dell'inverter.",
"ProjectOriginBody4": "OpenDTU è disponibile gratuitamente. Se hai pagato per questo software, probabilmente sei stato truffato.",
"NewsUpdates": "Novità e Aggiornamenti",
"NewsUpdatesBody": "Nuovi aggiornamenti sono disponibili su Github: <a href=\"https://github.com/tbnobody/OpenDTU\" target=\"_blank\">https://github.com/tbnobody/OpenDTU</a>",
"ErrorReporting": "Segnalazione Errori",
"ErrorReportingBody": "Per favore segnala eventuali problemi utilizzando le funzionalità della piattaforma <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">Github</a>",
"Discussion": "Discussioni",
"DiscussionBody": "Puoi avviare una discussione con noi su <a href=\"https://discord.gg/WzhxEY62mB\" target=\"_blank\">Discord</a> o <a href=\"https://github.com/tbnobody/OpenDTU/discussions\" target=\"_blank\">Github</a>"
},
"hints": {
"RadioProblem": "Non è possibile dialogare con il modulo radio selezionato. Controlla i collegamenti alla radio.",
"TimeSync": "La Data/Ora non sono state sincronizzate, ed in tal caso non è possibile eseguire richieste all'inverter. Questa condizione è normale appena avviato, tuttavia dopo un po' (>1 minuto), questa situazione potrebbe indicare un problema di accesso al server NTP.",
"TimeSyncLink": "Controlla le impostazioni Data/Ora.",
"DefaultPassword": "Stai usando la password di default per accedere all'interfaccia web e per la modalità Access Point di emergenza. Questo può portare ad un rischio di sicurezza.",
"DefaultPasswordLink": "Per favore cambia la password.",
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu.solar/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
},
"deviceadmin": {
"DeviceManager": "Device-Manager",
"ParseError": "Parse error in 'pin_mapping.json': {error}",
"PinAssignment": "Impostazioni Connessione",
"SelectedProfile": "Profilo selezionato",
"DefaultProfile": "(Impostazioni di Default)",
"ProfileHint": "Il tuo dispositivo potrebbe smettere di rispondere selezionando un profilo incompatibile. In questo caso, dovrai eseguire una cancellazione collegandoti all'interfaccia seriale.",
"Display": "Display",
"PowerSafe": "Abilita Risparmio Energetico",
"PowerSafeHint": "Spegni il display se l'inverter non produce.",
"Screensaver": "Abilita Screensaver",
"ScreensaverHint": "Muove il testo nel display per prevenire danneggiamento pixel. (Utile in caso di display OLED)",
"DiagramMode": "Modalità grafica",
"off": "Off",
"small": "Small",
"fullscreen": "Fullscreen",
"DiagramDuration": "Durata grafico",
"DiagramDurationHint": "Periodo che viene mostrato nel grafico.",
"Seconds": "Secondi",
"Contrast": "Contrasto ({contrast})",
"Rotation": "Rotazione",
"rot0": "Nessuna rotazione",
"rot90": "Rotazione 90 gradi",
"rot180": "Rotazione 180 gradi",
"rot270": "Rotazione 270 gradi",
"DisplayLanguage": "Linuga Display",
"en": "English",
"de": "German",
"fr": "French",
"Leds": "LEDs",
"EqualBrightness": "Equalizza luminosità",
"LedBrightness": "LED {led}, Luminosità ({brightness})"
},
"pininfo": {
"Category": "Categoria",
"Name": "Nome",
"Number": "Numero",
"ValueSelected": "Selezionato",
"ValueActive": "Attivo"
},
"inputserial": {
"format_hoymiles": "Hoymiles serial number format",
"format_converted": "Already converted serial number",
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
"format_unknown": "Unknown format"
}
}
}

778
lib/CMT2300a/cmt2300a.c Normal file
View File

@ -0,0 +1,778 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) CMOSTEK SZ.
*/
/*!
* @file cmt2300a.c
* @brief CMT2300A transceiver RF chip driver
*
* @version 1.3
* @date Jul 17 2017
* @author CMOSTEK R@D
*/
#include "cmt2300a.h"
/*! ********************************************************
* @name CMT2300A_SoftReset
* @desc Soft reset.
* *********************************************************/
void CMT2300A_SoftReset(void)
{
CMT2300A_WriteReg(0x7F, 0xFF);
}
/*! ********************************************************
* @name CMT2300A_GetChipStatus
* @desc Get the chip status.
* @return
* CMT2300A_STA_PUP
* CMT2300A_STA_SLEEP
* CMT2300A_STA_STBY
* CMT2300A_STA_RFS
* CMT2300A_STA_TFS
* CMT2300A_STA_RX
* CMT2300A_STA_TX
* CMT2300A_STA_EEPROM
* CMT2300A_STA_ERROR
* CMT2300A_STA_CAL
* *********************************************************/
uint8_t CMT2300A_GetChipStatus(void)
{
return CMT2300A_ReadReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA;
}
/*! ********************************************************
* @name CMT2300A_AutoSwitchStatus
* @desc Auto switch the chip status, and 10 ms as timeout.
* @param nGoCmd: the chip next status
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_AutoSwitchStatus(uint8_t nGoCmd)
{
#ifdef ENABLE_AUTO_SWITCH_CHIP_STATUS
uint32_t nBegTick = CMT2300A_GetTickCount();
uint8_t nWaitStatus = 0;
switch (nGoCmd) {
case CMT2300A_GO_SLEEP:
nWaitStatus = CMT2300A_STA_SLEEP;
break;
case CMT2300A_GO_STBY:
nWaitStatus = CMT2300A_STA_STBY;
break;
case CMT2300A_GO_TFS:
nWaitStatus = CMT2300A_STA_TFS;
break;
case CMT2300A_GO_TX:
nWaitStatus = CMT2300A_STA_TX;
break;
case CMT2300A_GO_RFS:
nWaitStatus = CMT2300A_STA_RFS;
break;
case CMT2300A_GO_RX:
nWaitStatus = CMT2300A_STA_RX;
break;
}
CMT2300A_WriteReg(CMT2300A_CUS_MODE_CTL, nGoCmd);
while (CMT2300A_GetTickCount() - nBegTick < 10) {
CMT2300A_DelayUs(100);
if (nWaitStatus == CMT2300A_GetChipStatus())
return true;
if (CMT2300A_GO_TX == nGoCmd) {
CMT2300A_DelayUs(100);
if (CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1))
return true;
}
if (CMT2300A_GO_RX == nGoCmd) {
CMT2300A_DelayUs(100);
if (CMT2300A_MASK_PKT_OK_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG))
return true;
}
}
return false;
#else
CMT2300A_WriteReg(CMT2300A_CUS_MODE_CTL, nGoCmd);
return true;
#endif
}
/*! ********************************************************
* @name CMT2300A_GoSleep
* @desc Entry SLEEP mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoSleep(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_SLEEP);
}
/*! ********************************************************
* @name CMT2300A_GoStby
* @desc Entry Sleep mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoStby(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_STBY);
}
/*! ********************************************************
* @name CMT2300A_GoTFS
* @desc Entry TFS mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoTFS(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_TFS);
}
/*! ********************************************************
* @name CMT2300A_GoRFS
* @desc Entry RFS mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoRFS(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_RFS);
}
/*! ********************************************************
* @name CMT2300A_GoTx
* @desc Entry Tx mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoTx(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_TX);
}
/*! ********************************************************
* @name CMT2300A_GoRx
* @desc Entry Rx mode.
* @return TRUE or FALSE
* *********************************************************/
bool CMT2300A_GoRx(void)
{
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_RX);
}
/*! ********************************************************
* @name CMT2300A_ConfigGpio
* @desc Config GPIO pins mode.
* @param nGpioSel: GPIO1_SEL | GPIO2_SEL | GPIO3_SEL | GPIO4_SEL
* GPIO1_SEL:
* CMT2300A_GPIO1_SEL_DOUT/DIN
* CMT2300A_GPIO1_SEL_INT1
* CMT2300A_GPIO1_SEL_INT2
* CMT2300A_GPIO1_SEL_DCLK
*
* GPIO2_SEL:
* CMT2300A_GPIO2_SEL_INT1
* CMT2300A_GPIO2_SEL_INT2
* CMT2300A_GPIO2_SEL_DOUT/DIN
* CMT2300A_GPIO2_SEL_DCLK
*
* GPIO3_SEL:
* CMT2300A_GPIO3_SEL_CLKO
* CMT2300A_GPIO3_SEL_DOUT/DIN
* CMT2300A_GPIO3_SEL_INT2
* CMT2300A_GPIO3_SEL_DCLK
*
* GPIO4_SEL:
* CMT2300A_GPIO4_SEL_RSTIN
* CMT2300A_GPIO4_SEL_INT1
* CMT2300A_GPIO4_SEL_DOUT
* CMT2300A_GPIO4_SEL_DCLK
* *********************************************************/
void CMT2300A_ConfigGpio(uint8_t nGpioSel)
{
CMT2300A_WriteReg(CMT2300A_CUS_IO_SEL, nGpioSel);
}
/*! ********************************************************
* @name CMT2300A_ConfigInterrupt
* @desc Config interrupt on INT1 and INT2.
* @param nInt1Sel, nInt2Sel
* CMT2300A_INT_SEL_RX_ACTIVE
* CMT2300A_INT_SEL_TX_ACTIVE
* CMT2300A_INT_SEL_RSSI_VLD
* CMT2300A_INT_SEL_PREAM_OK
* CMT2300A_INT_SEL_SYNC_OK
* CMT2300A_INT_SEL_NODE_OK
* CMT2300A_INT_SEL_CRC_OK
* CMT2300A_INT_SEL_PKT_OK
* CMT2300A_INT_SEL_SL_TMO
* CMT2300A_INT_SEL_RX_TMO
* CMT2300A_INT_SEL_TX_DONE
* CMT2300A_INT_SEL_RX_FIFO_NMTY
* CMT2300A_INT_SEL_RX_FIFO_TH
* CMT2300A_INT_SEL_RX_FIFO_FULL
* CMT2300A_INT_SEL_RX_FIFO_WBYTE
* CMT2300A_INT_SEL_RX_FIFO_OVF
* CMT2300A_INT_SEL_TX_FIFO_NMTY
* CMT2300A_INT_SEL_TX_FIFO_TH
* CMT2300A_INT_SEL_TX_FIFO_FULL
* CMT2300A_INT_SEL_STATE_IS_STBY
* CMT2300A_INT_SEL_STATE_IS_FS
* CMT2300A_INT_SEL_STATE_IS_RX
* CMT2300A_INT_SEL_STATE_IS_TX
* CMT2300A_INT_SEL_LED
* CMT2300A_INT_SEL_TRX_ACTIVE
* CMT2300A_INT_SEL_PKT_DONE
* *********************************************************/
void CMT2300A_ConfigInterrupt(uint8_t nInt1Sel, uint8_t nInt2Sel)
{
nInt1Sel &= CMT2300A_MASK_INT1_SEL;
nInt1Sel |= (~CMT2300A_MASK_INT1_SEL) & CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, nInt1Sel);
nInt2Sel &= CMT2300A_MASK_INT2_SEL;
nInt2Sel |= (~CMT2300A_MASK_INT2_SEL) & CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, nInt2Sel);
}
/*! ********************************************************
* @name CMT2300A_SetInterruptPolar
* @desc Set the polarity of the interrupt.
* @param bEnable(TRUE): active-high (default)
* bEnable(FALSE): active-low
* *********************************************************/
void CMT2300A_SetInterruptPolar(bool bActiveHigh)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
if (bActiveHigh)
tmp &= ~CMT2300A_MASK_INT_POLAR;
else
tmp |= CMT2300A_MASK_INT_POLAR;
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_SetFifoThreshold
* @desc Set FIFO threshold.
* @param nFifoThreshold
* *********************************************************/
void CMT2300A_SetFifoThreshold(uint8_t nFifoThreshold)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_PKT29);
tmp &= ~CMT2300A_MASK_FIFO_TH;
tmp |= nFifoThreshold & CMT2300A_MASK_FIFO_TH;
CMT2300A_WriteReg(CMT2300A_CUS_PKT29, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableAntennaSwitch
* @desc Enable antenna switch, output TX_ACTIVE/RX_ACTIVE
* via GPIO1/GPIO2.
* @param nMode
* 0: RF_SWT1_EN=1, RF_SWT2_EN=0
* GPIO1: RX_ACTIVE, GPIO2: TX_ACTIVE
* 1: RF_SWT1_EN=0, RF_SWT2_EN=1
* GPIO1: RX_ACTIVE, GPIO2: ~RX_ACTIVE
* *********************************************************/
void CMT2300A_EnableAntennaSwitch(uint8_t nMode)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
if (0 == nMode) {
tmp |= CMT2300A_MASK_RF_SWT1_EN;
tmp &= ~CMT2300A_MASK_RF_SWT2_EN;
} else if (1 == nMode) {
tmp &= ~CMT2300A_MASK_RF_SWT1_EN;
tmp |= CMT2300A_MASK_RF_SWT2_EN;
}
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableInterrupt
* @desc Enable interrupt.
* @param nEnable
* CMT2300A_MASK_SL_TMO_EN |
* CMT2300A_MASK_RX_TMO_EN |
* CMT2300A_MASK_TX_DONE_EN |
* CMT2300A_MASK_PREAM_OK_EN |
* CMT2300A_MASK_SYNC_OK_EN |
* CMT2300A_MASK_NODE_OK_EN |
* CMT2300A_MASK_CRC_OK_EN |
* CMT2300A_MASK_PKT_DONE_EN
* *********************************************************/
void CMT2300A_EnableInterrupt(uint8_t nEnable)
{
CMT2300A_WriteReg(CMT2300A_CUS_INT_EN, nEnable);
}
/*! ********************************************************
* @name CMT2300A_EnableRxFifoAutoClear
* @desc Auto clear Rx FIFO before entry Rx mode.
* @param bEnable(TRUE): Enable it(default)
* bEnable(FALSE): Disable it
* *********************************************************/
void CMT2300A_EnableRxFifoAutoClear(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
if (bEnable)
tmp &= ~CMT2300A_MASK_FIFO_AUTO_CLR_DIS;
else
tmp |= CMT2300A_MASK_FIFO_AUTO_CLR_DIS;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableFifoMerge
* @desc Enable FIFO merge.
* @param bEnable(TRUE): use a single 64-byte FIFO for either Tx or Rx
* bEnable(FALSE): use a 32-byte FIFO for Tx and another 32-byte FIFO for Rx(default)
* *********************************************************/
void CMT2300A_EnableFifoMerge(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
if (bEnable)
tmp |= CMT2300A_MASK_FIFO_MERGE_EN;
else
tmp &= ~CMT2300A_MASK_FIFO_MERGE_EN;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableReadFifo
* @desc Enable SPI to read the FIFO.
* *********************************************************/
void CMT2300A_EnableReadFifo(void)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
tmp &= ~CMT2300A_MASK_SPI_FIFO_RD_WR_SEL;
tmp &= ~CMT2300A_MASK_FIFO_RX_TX_SEL;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableWriteFifo
* @desc Enable SPI to write the FIFO.
* *********************************************************/
void CMT2300A_EnableWriteFifo(void)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
tmp |= CMT2300A_MASK_SPI_FIFO_RD_WR_SEL;
tmp |= CMT2300A_MASK_FIFO_RX_TX_SEL;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_RestoreFifo
* @desc Restore the FIFO.
* *********************************************************/
void CMT2300A_RestoreFifo(void)
{
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_RESTORE);
}
/*! ********************************************************
* @name CMT2300A_ClearFifo
* @desc Clear the Tx FIFO.
* @return FIFO flags
* CMT2300A_MASK_RX_FIFO_FULL_FLG |
* CMT2300A_MASK_RX_FIFO_NMTY_FLG |
* CMT2300A_MASK_RX_FIFO_TH_FLG |
* CMT2300A_MASK_RX_FIFO_OVF_FLG |
* CMT2300A_MASK_TX_FIFO_FULL_FLG |
* CMT2300A_MASK_TX_FIFO_NMTY_FLG |
* CMT2300A_MASK_TX_FIFO_TH_FLG
* *********************************************************/
uint8_t CMT2300A_ClearTxFifo(void)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG);
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_CLR_TX);
return tmp;
}
/*! ********************************************************
* @name CMT2300A_ClearFifo
* @desc Clear the Rx FIFO.
* @return FIFO flags
* CMT2300A_MASK_RX_FIFO_FULL_FLG |
* CMT2300A_MASK_RX_FIFO_NMTY_FLG |
* CMT2300A_MASK_RX_FIFO_TH_FLG |
* CMT2300A_MASK_RX_FIFO_OVF_FLG |
* CMT2300A_MASK_TX_FIFO_FULL_FLG |
* CMT2300A_MASK_TX_FIFO_NMTY_FLG |
* CMT2300A_MASK_TX_FIFO_TH_FLG
* *********************************************************/
uint8_t CMT2300A_ClearRxFifo(void)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG);
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_CLR_RX);
return tmp;
}
/*! ********************************************************
* @name CMT2300A_ClearInterruptFlags
* @desc Clear all interrupt flags.
* @return Some interrupt flags
* CMT2300A_MASK_SL_TMO_EN |
* CMT2300A_MASK_RX_TMO_EN |
* CMT2300A_MASK_TX_DONE_EN |
* CMT2300A_MASK_PREAM_OK_FLG |
* CMT2300A_MASK_SYNC_OK_FLG |
* CMT2300A_MASK_NODE_OK_FLG |
* CMT2300A_MASK_CRC_OK_FLG |
* CMT2300A_MASK_PKT_OK_FLG
* *********************************************************/
uint8_t CMT2300A_ClearInterruptFlags(void)
{
uint8_t nFlag1, nFlag2;
uint8_t nClr1 = 0;
uint8_t nClr2 = 0;
uint8_t nRet = 0;
uint8_t nIntPolar;
nIntPolar = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
nIntPolar = (nIntPolar & CMT2300A_MASK_INT_POLAR) ? 1 : 0;
nFlag1 = CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
nFlag2 = CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1);
if (nIntPolar) {
/* Interrupt flag active-low */
nFlag1 = ~nFlag1;
nFlag2 = ~nFlag2;
}
if (CMT2300A_MASK_LBD_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_LBD_CLR; /* Clear LBD_FLG */
}
if (CMT2300A_MASK_COL_ERR_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear COL_ERR_FLG by PKT_DONE_CLR */
}
if (CMT2300A_MASK_PKT_ERR_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear PKT_ERR_FLG by PKT_DONE_CLR */
}
if (CMT2300A_MASK_PREAM_OK_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_PREAM_OK_CLR; /* Clear PREAM_OK_FLG */
nRet |= CMT2300A_MASK_PREAM_OK_FLG; /* Return PREAM_OK_FLG */
}
if (CMT2300A_MASK_SYNC_OK_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_SYNC_OK_CLR; /* Clear SYNC_OK_FLG */
nRet |= CMT2300A_MASK_SYNC_OK_FLG; /* Return SYNC_OK_FLG */
}
if (CMT2300A_MASK_NODE_OK_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_NODE_OK_CLR; /* Clear NODE_OK_FLG */
nRet |= CMT2300A_MASK_NODE_OK_FLG; /* Return NODE_OK_FLG */
}
if (CMT2300A_MASK_CRC_OK_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_CRC_OK_CLR; /* Clear CRC_OK_FLG */
nRet |= CMT2300A_MASK_CRC_OK_FLG; /* Return CRC_OK_FLG */
}
if (CMT2300A_MASK_PKT_OK_FLG & nFlag1) {
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear PKT_OK_FLG */
nRet |= CMT2300A_MASK_PKT_OK_FLG; /* Return PKT_OK_FLG */
}
if (CMT2300A_MASK_SL_TMO_FLG & nFlag2) {
nClr1 |= CMT2300A_MASK_SL_TMO_CLR; /* Clear SL_TMO_FLG */
nRet |= CMT2300A_MASK_SL_TMO_EN; /* Return SL_TMO_FLG by SL_TMO_EN */
}
if (CMT2300A_MASK_RX_TMO_FLG & nFlag2) {
nClr1 |= CMT2300A_MASK_RX_TMO_CLR; /* Clear RX_TMO_FLG */
nRet |= CMT2300A_MASK_RX_TMO_EN; /* Return RX_TMO_FLG by RX_TMO_EN */
}
if (CMT2300A_MASK_TX_DONE_FLG & nFlag2) {
nClr1 |= CMT2300A_MASK_TX_DONE_CLR; /* Clear TX_DONE_FLG */
nRet |= CMT2300A_MASK_TX_DONE_EN; /* Return TX_DONE_FLG by TX_DONE_EN */
}
CMT2300A_WriteReg(CMT2300A_CUS_INT_CLR1, nClr1);
CMT2300A_WriteReg(CMT2300A_CUS_INT_CLR2, nClr2);
if (nIntPolar) {
/* Interrupt flag active-low */
nRet = ~nRet;
}
return nRet;
}
/*! ********************************************************
* @name CMT2300A_ConfigTxDin
* @desc Used to select whether to use GPIO1 or GPIO2 or GPIO3
* as DIN in the direct mode. It only takes effect when
* call CMT2300A_EnableTxDin(TRUE) in the direct mode.
* @param nDinSel
* CMT2300A_TX_DIN_SEL_GPIO1
* CMT2300A_TX_DIN_SEL_GPIO2
* CMT2300A_TX_DIN_SEL_GPIO3
* *********************************************************/
void CMT2300A_ConfigTxDin(uint8_t nDinSel)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
tmp &= ~CMT2300A_MASK_TX_DIN_SEL;
tmp |= nDinSel;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableTxDin
* @desc Used to change GPIO1/GPIO2/GPIO3 between DOUT and DIN.
* @param bEnable(TRUE): used as DIN
* bEnable(FALSE): used as DOUT(default)
* *********************************************************/
void CMT2300A_EnableTxDin(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
if (bEnable)
tmp |= CMT2300A_MASK_TX_DIN_EN;
else
tmp &= ~CMT2300A_MASK_TX_DIN_EN;
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableTxDinInvert
* @desc Used to invert DIN data in direct mode.
* @param bEnable(TRUE): invert DIN
* bEnable(FALSE): not invert DIN(default)
* *********************************************************/
void CMT2300A_EnableTxDinInvert(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
if (bEnable)
tmp |= CMT2300A_MASK_TX_DIN_INV;
else
tmp &= ~CMT2300A_MASK_TX_DIN_INV;
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_IsExist
* @desc Chip indentify.
* @return TRUE: chip is exist, FALSE: chip not found
* *********************************************************/
bool CMT2300A_IsExist(void)
{
uint8_t back, dat;
back = CMT2300A_ReadReg(CMT2300A_CUS_PKT17);
CMT2300A_WriteReg(CMT2300A_CUS_PKT17, 0xAA);
dat = CMT2300A_ReadReg(CMT2300A_CUS_PKT17);
CMT2300A_WriteReg(CMT2300A_CUS_PKT17, back);
if (0xAA == dat)
return true;
else
return false;
}
/*! ********************************************************
* @name CMT2300A_GetRssiCode
* @desc Get RSSI code.
* @return RSSI code
* *********************************************************/
uint8_t CMT2300A_GetRssiCode(void)
{
return CMT2300A_ReadReg(CMT2300A_CUS_RSSI_CODE);
}
/*! ********************************************************
* @name CMT2300A_GetRssiDBm
* @desc Get RSSI dBm.
* @return dBm
* *********************************************************/
int CMT2300A_GetRssiDBm(void)
{
return (int)CMT2300A_ReadReg(CMT2300A_CUS_RSSI_DBM) - 128;
}
/*! ********************************************************
* @name CMT2300A_SetFrequencyChannel
* @desc This defines up to 255 frequency channel
* for fast frequency hopping operation.
* @param nChann: the frequency channel
* *********************************************************/
void CMT2300A_SetFrequencyChannel(const uint8_t nChann)
{
CMT2300A_WriteReg(CMT2300A_CUS_FREQ_CHNL, nChann);
}
/*! ********************************************************
* @name CMT2300A_SetFrequencyStep
* @desc This defines the frequency channel step size
* for fast frequency hopping operation.
* One step size is 2.5 kHz.
* @param nOffset: the frequency step
* *********************************************************/
void CMT2300A_SetFrequencyStep(uint8_t nOffset)
{
CMT2300A_WriteReg(CMT2300A_CUS_FREQ_OFS, nOffset);
}
/*! ********************************************************
* @name CMT2300A_SetPayloadLength
* @desc Set payload length.
* @param nLength
* *********************************************************/
void CMT2300A_SetPayloadLength(uint16_t nLength)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_PKT14);
tmp &= ~CMT2300A_MASK_PAYLOAD_LENG_10_8;
tmp |= (nLength >> 4) & CMT2300A_MASK_PAYLOAD_LENG_10_8;
CMT2300A_WriteReg(CMT2300A_CUS_PKT14, tmp);
tmp = nLength & CMT2300A_MASK_PAYLOAD_LENG_7_0;
CMT2300A_WriteReg(CMT2300A_CUS_PKT15, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableLfosc
* @desc If you need use sleep timer, you should enable LFOSC.
* @param bEnable(TRUE): Enable it(default)
* bEnable(FALSE): Disable it
* *********************************************************/
void CMT2300A_EnableLfosc(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_SYS2);
if (bEnable) {
tmp |= CMT2300A_MASK_LFOSC_RECAL_EN;
tmp |= CMT2300A_MASK_LFOSC_CAL1_EN;
tmp |= CMT2300A_MASK_LFOSC_CAL2_EN;
} else {
tmp &= ~CMT2300A_MASK_LFOSC_RECAL_EN;
tmp &= ~CMT2300A_MASK_LFOSC_CAL1_EN;
tmp &= ~CMT2300A_MASK_LFOSC_CAL2_EN;
}
CMT2300A_WriteReg(CMT2300A_CUS_SYS2, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableLfoscOutput
* @desc LFOSC clock is output via GPIO3.
* @param bEnable(TRUE): Enable it
* bEnable(FALSE): Disable it(default)
* *********************************************************/
void CMT2300A_EnableLfoscOutput(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
if (bEnable)
tmp |= CMT2300A_MASK_LFOSC_OUT_EN;
else
tmp &= ~CMT2300A_MASK_LFOSC_OUT_EN;
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, tmp);
}
/*! ********************************************************
* @name CMT2300A_EnableAfc
* @desc AFC enable or disanble.
* @param bEnable(TRUE): Enable it
* bEnable(FALSE): Disable it(default)
* *********************************************************/
void CMT2300A_EnableAfc(bool bEnable)
{
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FSK5);
if (bEnable)
tmp |= 0x10;
else
tmp &= ~0x10;
CMT2300A_WriteReg(CMT2300A_CUS_FSK5, tmp);
}
/*! ********************************************************
* @name CMT2300A_SetAfcOvfTh
* @desc This is optional, only needed when using Rx fast frequency hopping.
* @param afcOvfTh: AFC_OVF_TH see AN142 and AN197 for details.
* *********************************************************/
void CMT2300A_SetAfcOvfTh(uint8_t afcOvfTh)
{
CMT2300A_WriteReg(CMT2300A_CUS_FSK4, afcOvfTh);
}
/*! ********************************************************
* @name CMT2300A_Init
* @desc Initialize chip status.
* *********************************************************/
bool CMT2300A_Init(void)
{
uint8_t tmp;
CMT2300A_SoftReset();
CMT2300A_DelayMs(20);
if (!CMT2300A_GoStby())
return false; // CMT2300A not switched to standby mode!
if (!CMT2300A_IsExist())
return false; // CMT2300A not found!
tmp = CMT2300A_ReadReg(CMT2300A_CUS_MODE_STA);
tmp |= CMT2300A_MASK_CFG_RETAIN; /* Enable CFG_RETAIN */
tmp &= ~CMT2300A_MASK_RSTN_IN_EN; /* Disable RSTN_IN */
CMT2300A_WriteReg(CMT2300A_CUS_MODE_STA, tmp);
tmp = CMT2300A_ReadReg(CMT2300A_CUS_EN_CTL);
tmp |= CMT2300A_MASK_LOCKING_EN; /* Enable LOCKING_EN */
CMT2300A_WriteReg(CMT2300A_CUS_EN_CTL, tmp);
CMT2300A_EnableLfosc(false); /* Disable LFOSC */
CMT2300A_ClearInterruptFlags();
return true;
}
/*! ********************************************************
* @name CMT2300A_ConfigRegBank
* @desc Config one register bank.
* *********************************************************/
bool CMT2300A_ConfigRegBank(uint8_t base_addr, const uint8_t bank[], uint8_t len)
{
uint8_t i;
for (i = 0; i < len; i++)
CMT2300A_WriteReg(i + base_addr, bank[i]);
return true;
}

96
lib/CMT2300a/cmt2300a.h Normal file
View File

@ -0,0 +1,96 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) CMOSTEK SZ.
*/
/*!
* @file cmt2300a.h
* @brief CMT2300A transceiver RF chip driver
*
* @version 1.3
* @date Jul 17 2017
* @author CMOSTEK R@D
*/
#ifndef __CMT2300A_H
#define __CMT2300A_H
#include "cmt2300a_defs.h"
#include "cmt2300a_hal.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ENABLE_AUTO_SWITCH_CHIP_STATUS /* Enable the auto switch chip status */
/* ************************************************************************
The following are for chip status controls.
* ************************************************************************ */
void CMT2300A_SoftReset(void);
uint8_t CMT2300A_GetChipStatus(void);
bool CMT2300A_AutoSwitchStatus(uint8_t nGoCmd);
bool CMT2300A_GoSleep(void);
bool CMT2300A_GoStby(void);
bool CMT2300A_GoTFS(void);
bool CMT2300A_GoRFS(void);
bool CMT2300A_GoTx(void);
bool CMT2300A_GoRx(void);
/* ************************************************************************
* The following are for chip interrupts, GPIO, FIFO operations.
* ************************************************************************ */
void CMT2300A_ConfigGpio(uint8_t nGpioSel);
void CMT2300A_ConfigInterrupt(uint8_t nInt1Sel, uint8_t nInt2Sel);
void CMT2300A_SetInterruptPolar(bool bActiveHigh);
void CMT2300A_SetFifoThreshold(uint8_t nFifoThreshold);
void CMT2300A_EnableAntennaSwitch(uint8_t nMode);
void CMT2300A_EnableInterrupt(uint8_t nEnable);
void CMT2300A_EnableRxFifoAutoClear(bool bEnable);
void CMT2300A_EnableFifoMerge(bool bEnable);
void CMT2300A_EnableReadFifo(void);
void CMT2300A_EnableWriteFifo(void);
void CMT2300A_RestoreFifo(void);
uint8_t CMT2300A_ClearTxFifo(void);
uint8_t CMT2300A_ClearRxFifo(void);
uint8_t CMT2300A_ClearInterruptFlags(void);
/* ************************************************************************
* The following are for Tx DIN operations in direct mode.
* ************************************************************************ */
void CMT2300A_ConfigTxDin(uint8_t nDinSel);
void CMT2300A_EnableTxDin(bool bEnable);
void CMT2300A_EnableTxDinInvert(bool bEnable);
/* ************************************************************************
* The following are general operations.
* ************************************************************************ */
bool CMT2300A_IsExist(void);
uint8_t CMT2300A_GetRssiCode(void);
int CMT2300A_GetRssiDBm(void);
void CMT2300A_SetFrequencyChannel(const uint8_t nChann);
void CMT2300A_SetFrequencyStep(uint8_t nOffset);
void CMT2300A_SetPayloadLength(uint16_t nLength);
void CMT2300A_EnableLfosc(bool bEnable);
void CMT2300A_EnableLfoscOutput(bool bEnable);
void CMT2300A_EnableAfc(bool bEnable);
void CMT2300A_SetAfcOvfTh(uint8_t afcOvfTh);
/* ************************************************************************
* The following are for chip initializes.
* ************************************************************************ */
bool CMT2300A_Init(void);
bool CMT2300A_ConfigRegBank(uint8_t base_addr, const uint8_t bank[], uint8_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,606 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) CMOSTEK SZ.
*/
/*!
* @file cmt2300a_defs.h
* @brief CMT2300A registers defines
*
* @version 1.2
* @date Jul 17 2017
* @author CMOSTEK R@D
*/
#ifndef __CMT2300A_DEFS_H
#define __CMT2300A_DEFS_H
/* ---------- CMT bank defines ---------- */
#define CMT2300A_CMT_BANK_ADDR 0x00
#define CMT2300A_CMT_BANK_SIZE 12
#define CMT2300A_CUS_CMT1 0x00
#define CMT2300A_CUS_CMT2 0x01
#define CMT2300A_CUS_CMT3 0x02
#define CMT2300A_CUS_CMT4 0x03
#define CMT2300A_CUS_CMT5 0x04
#define CMT2300A_CUS_CMT6 0x05
#define CMT2300A_CUS_CMT7 0x06
#define CMT2300A_CUS_CMT8 0x07
#define CMT2300A_CUS_CMT9 0x08
#define CMT2300A_CUS_CMT10 0x09
#define CMT2300A_CUS_CMT11 0x0A
#define CMT2300A_CUS_RSSI 0x0B
/* ---------- System bank defines ---------- */
#define CMT2300A_SYSTEM_BANK_ADDR 0x0C
#define CMT2300A_SYSTEM_BANK_SIZE 12
#define CMT2300A_CUS_SYS1 0x0C
#define CMT2300A_CUS_SYS2 0x0D
#define CMT2300A_CUS_SYS3 0x0E
#define CMT2300A_CUS_SYS4 0x0F
#define CMT2300A_CUS_SYS5 0x10
#define CMT2300A_CUS_SYS6 0x11
#define CMT2300A_CUS_SYS7 0x12
#define CMT2300A_CUS_SYS8 0x13
#define CMT2300A_CUS_SYS9 0x14
#define CMT2300A_CUS_SYS10 0x15
#define CMT2300A_CUS_SYS11 0x16
#define CMT2300A_CUS_SYS12 0x17
/* ---------- Frequency bank defines ---------- */
#define CMT2300A_FREQUENCY_BANK_ADDR 0x18
#define CMT2300A_FREQUENCY_BANK_SIZE 8
#define CMT2300A_CUS_RF1 0x18
#define CMT2300A_CUS_RF2 0x19
#define CMT2300A_CUS_RF3 0x1A
#define CMT2300A_CUS_RF4 0x1B
#define CMT2300A_CUS_RF5 0x1C
#define CMT2300A_CUS_RF6 0x1D
#define CMT2300A_CUS_RF7 0x1E
#define CMT2300A_CUS_RF8 0x1F
/* ---------- Data rate bank defines ---------- */
#define CMT2300A_DATA_RATE_BANK_ADDR 0x20
#define CMT2300A_DATA_RATE_BANK_SIZE 24
#define CMT2300A_CUS_RF9 0x20
#define CMT2300A_CUS_RF10 0x21
#define CMT2300A_CUS_RF11 0x22
#define CMT2300A_CUS_RF12 0x23
#define CMT2300A_CUS_FSK1 0x24
#define CMT2300A_CUS_FSK2 0x25
#define CMT2300A_CUS_FSK3 0x26
#define CMT2300A_CUS_FSK4 0x27
#define CMT2300A_CUS_FSK5 0x28
#define CMT2300A_CUS_FSK6 0x29
#define CMT2300A_CUS_FSK7 0x2A
#define CMT2300A_CUS_CDR1 0x2B
#define CMT2300A_CUS_CDR2 0x2C
#define CMT2300A_CUS_CDR3 0x2D
#define CMT2300A_CUS_CDR4 0x2E
#define CMT2300A_CUS_AGC1 0x2F
#define CMT2300A_CUS_AGC2 0x30
#define CMT2300A_CUS_AGC3 0x31
#define CMT2300A_CUS_AGC4 0x32
#define CMT2300A_CUS_OOK1 0x33
#define CMT2300A_CUS_OOK2 0x34
#define CMT2300A_CUS_OOK3 0x35
#define CMT2300A_CUS_OOK4 0x36
#define CMT2300A_CUS_OOK5 0x37
/* ---------- Baseband bank defines ---------- */
#define CMT2300A_BASEBAND_BANK_ADDR 0x38
#define CMT2300A_BASEBAND_BANK_SIZE 29
#define CMT2300A_CUS_PKT1 0x38
#define CMT2300A_CUS_PKT2 0x39
#define CMT2300A_CUS_PKT3 0x3A
#define CMT2300A_CUS_PKT4 0x3B
#define CMT2300A_CUS_PKT5 0x3C
#define CMT2300A_CUS_PKT6 0x3D
#define CMT2300A_CUS_PKT7 0x3E
#define CMT2300A_CUS_PKT8 0x3F
#define CMT2300A_CUS_PKT9 0x40
#define CMT2300A_CUS_PKT10 0x41
#define CMT2300A_CUS_PKT11 0x42
#define CMT2300A_CUS_PKT12 0x43
#define CMT2300A_CUS_PKT13 0x44
#define CMT2300A_CUS_PKT14 0x45
#define CMT2300A_CUS_PKT15 0x46
#define CMT2300A_CUS_PKT16 0x47
#define CMT2300A_CUS_PKT17 0x48
#define CMT2300A_CUS_PKT18 0x49
#define CMT2300A_CUS_PKT19 0x4A
#define CMT2300A_CUS_PKT20 0x4B
#define CMT2300A_CUS_PKT21 0x4C
#define CMT2300A_CUS_PKT22 0x4D
#define CMT2300A_CUS_PKT23 0x4E
#define CMT2300A_CUS_PKT24 0x4F
#define CMT2300A_CUS_PKT25 0x50
#define CMT2300A_CUS_PKT26 0x51
#define CMT2300A_CUS_PKT27 0x52
#define CMT2300A_CUS_PKT28 0x53
#define CMT2300A_CUS_PKT29 0x54
/* ---------- Tx bank defines ---------- */
#define CMT2300A_TX_BANK_ADDR 0x55
#define CMT2300A_TX_BANK_SIZE 11
#define CMT2300A_CUS_TX1 0x55
#define CMT2300A_CUS_TX2 0x56
#define CMT2300A_CUS_TX3 0x57
#define CMT2300A_CUS_TX4 0x58
#define CMT2300A_CUS_TX5 0x59
#define CMT2300A_CUS_TX6 0x5A
#define CMT2300A_CUS_TX7 0x5B
#define CMT2300A_CUS_TX8 0x5C
#define CMT2300A_CUS_TX9 0x5D
#define CMT2300A_CUS_TX10 0x5E
#define CMT2300A_CUS_LBD 0x5F
/* ---------- Control1 bank defines ---------- */
#define CMT2300A_CONTROL1_BANK_ADDR 0x60
#define CMT2300A_CONTROL1_BANK_SIZE 11
#define CMT2300A_CUS_MODE_CTL 0x60
#define CMT2300A_CUS_MODE_STA 0x61
#define CMT2300A_CUS_EN_CTL 0x62
#define CMT2300A_CUS_FREQ_CHNL 0x63
#define CMT2300A_CUS_FREQ_OFS 0x64
#define CMT2300A_CUS_IO_SEL 0x65
#define CMT2300A_CUS_INT1_CTL 0x66
#define CMT2300A_CUS_INT2_CTL 0x67
#define CMT2300A_CUS_INT_EN 0x68
#define CMT2300A_CUS_FIFO_CTL 0x69
#define CMT2300A_CUS_INT_CLR1 0x6A
/* ---------- Control2 bank defines ---------- */
#define CMT2300A_CONTROL2_BANK_ADDR 0x6B
#define CMT2300A_CONTROL2_BANK_SIZE 7
#define CMT2300A_CUS_INT_CLR2 0x6B
#define CMT2300A_CUS_FIFO_CLR 0x6C
#define CMT2300A_CUS_INT_FLAG 0x6D
#define CMT2300A_CUS_FIFO_FLAG 0x6E
#define CMT2300A_CUS_RSSI_CODE 0x6F
#define CMT2300A_CUS_RSSI_DBM 0x70
#define CMT2300A_CUS_LBD_RESULT 0x71
/* ********** CMT2300A_CUS_CMT2 registers ********** */
#define CMT2300A_MASK_PRODUCT_ID 0xFF
/* ********** CMT2300A_CUS_CMT5 registers ********** */
#define CMT2300A_MASK_LMT_CODE 0xC0
/* ********** CMT2300A_CUS_CMT9 registers ********** */
#define CMT2300A_MASK_RSSI_OFFSET_SIGN 0x80
#define CMT2300A_MASK_DIG_CLKDIV 0x1F
/* ********** CMT2300A_CUS_RSSI registers ********** */
#define CMT2300A_MASK_RSSI_OFFSET 0xF8
#define CMT2300A_MASK_RSSI_SLOPE 0x07
/* ********** CMT2300A_CUS_SYS1 registers ********** */
#define CMT2300A_MASK_LMT_VTR 0xC0
#define CMT2300A_MASK_MIXER_BIAS 0x30
#define CMT2300A_MASK_LNA_MODE 0x0C
#define CMT2300A_MASK_LNA_BIAS 0x03
/* ********** CMT2300A_CUS_SYS2 registers ********** */
#define CMT2300A_MASK_LFOSC_RECAL_EN 0x80
#define CMT2300A_MASK_LFOSC_CAL1_EN 0x40
#define CMT2300A_MASK_LFOSC_CAL2_EN 0x20
#define CMT2300A_MASK_RX_TIMER_EN 0x10
#define CMT2300A_MASK_SLEEP_TIMER_EN 0x08
#define CMT2300A_MASK_TX_DC_EN 0x04
#define CMT2300A_MASK_RX_DC_EN 0x02
#define CMT2300A_MASK_DC_PAUSE 0x01
/* ********** CMT2300A_CUS_SYS3 registers ********** */
#define CMT2300A_MASK_SLEEP_BYPASS_EN 0x80
#define CMT2300A_MASK_XTAL_STB_TIME 0x70
#define CMT2300A_MASK_TX_EXIT_STATE 0x0C
#define CMT2300A_MASK_RX_EXIT_STATE 0x03
/* ********** CMT2300A_CUS_SYS4 registers ********** */
#define CMT2300A_MASK_SLEEP_TIMER_M_7_0 0xFF
/* ********** CMT2300A_CUS_SYS5 registers ********** */
#define CMT2300A_MASK_SLEEP_TIMER_M_10_8 0x70
#define CMT2300A_MASK_SLEEP_TIMER_R 0x0F
/* ********** CMT2300A_CUS_SYS6 registers ********** */
#define CMT2300A_MASK_RX_TIMER_T1_M_7_0 0xFF
/* ********** CMT2300A_CUS_SYS7 registers ********** */
#define CMT2300A_MASK_RX_TIMER_T1_M_10_8 0x70
#define CMT2300A_MASK_RX_TIMER_T1_R 0x0F
/* ********** CMT2300A_CUS_SYS8 registers ********** */
#define CMT2300A_MASK_RX_TIMER_T2_M_7_0 0xFF
/* ********** CMT2300A_CUS_SYS9 registers ********** */
#define CMT2300A_MASK_RX_TIMER_T2_M_10_8 0x70
#define CMT2300A_MASK_RX_TIMER_T2_R 0x0F
/* ********** CMT2300A_CUS_SYS10 registers ********** */
#define CMT2300A_MASK_COL_DET_EN 0x80
#define CMT2300A_MASK_COL_OFS_SEL 0x40
#define CMT2300A_MASK_RX_AUTO_EXIT_DIS 0x20
#define CMT2300A_MASK_DOUT_MUTE 0x10
#define CMT2300A_MASK_RX_EXTEND_MODE 0x0F
/* ********** CMT2300A_CUS_SYS11 registers ********** */
#define CMT2300A_MASK_PJD_TH_SEL 0x80
#define CMT2300A_MASK_CCA_INT_SEL 0x60
#define CMT2300A_MASK_RSSI_DET_SEL 0x18
#define CMT2300A_MASK_RSSI_AVG_MODE 0x07
/* ********** CMT2300A_CUS_SYS12 registers ********** */
#define CMT2300A_MASK_PJD_WIN_SEL 0xC0
#define CMT2300A_MASK_CLKOUT_EN 0x20
#define CMT2300A_MASK_CLKOUT_DIV 0x1F
/* ********** CMT2300A_CUS_RF1 registers ********** */
#define CMT2300A_MASK_FREQ_RX_N 0xFF
/* ********** CMT2300A_CUS_RF2 registers ********** */
#define CMT2300A_MASK_FREQ_RX_K_7_0 0xFF
/* ********** CMT2300A_CUS_RF3 registers ********** */
#define CMT2300A_MASK_FREQ_RX_K_15_8 0xFF
/* ********** CMT2300A_CUS_RF4 registers ********** */
#define CMT2300A_MASK_FREQ_PALDO_SEL 0x80
#define CMT2300A_MASK_FREQ_DIVX_CODE 0x70
#define CMT2300A_MASK_FREQ_RX_K_19_16 0x0F
/* ********** CMT2300A_CUS_RF5 registers ********** */
#define CMT2300A_MASK_FREQ_TX_N 0xFF
/* ********** CMT2300A_CUS_RF6 registers ********** */
#define CMT2300A_MASK_FREQ_TX_K_7_0 0xFF
/* ********** CMT2300A_CUS_RF7 registers ********** */
#define CMT2300A_MASK_FREQ_TX_K_15_8 0xFF
/* ********** CMT2300A_CUS_RF8 registers ********** */
#define CMT2300A_MASK_FSK_SWT 0x80
#define CMT2300A_MASK_FREQ_VCO_BANK 0x70
#define CMT2300A_MASK_FREQ_TX_K_19_16 0x0F
/* ********** CMT2300A_CUS_PKT1 registers ********** */
#define CMT2300A_MASK_RX_PREAM_SIZE 0xF8
#define CMT2300A_MASK_PREAM_LENG_UNIT 0x04
#define CMT2300A_MASK_DATA_MODE 0x03
/* CMT2300A_MASK_PREAM_LENG_UNIT options */
#define CMT2300A_PREAM_LENG_UNIT_8_BITS 0x00
#define CMT2300A_PREAM_LENG_UNIT_4_BITS 0x04
/* CMT2300A_MASK_DATA_MODE options */
#define CMT2300A_DATA_MODE_DIRECT 0x00
#define CMT2300A_DATA_MODE_PACKET 0x02
/* ********** CMT2300A_CUS_PKT2 registers ********** */
#define CMT2300A_MASK_TX_PREAM_SIZE_7_0 0xFF
/* ********** CMT2300A_CUS_PKT3 registers ********** */
#define CMT2300A_MASK_TX_PREAM_SIZE_15_8 0xFF
/* ********** CMT2300A_CUS_PKT4 registers ********** */
#define CMT2300A_MASK_PREAM_VALUE 0xFF
/* ********** CMT2300A_CUS_PKT5 registers ********** */
#define CMT2300A_MASK_SYNC_TOL 0x70
#define CMT2300A_MASK_SYNC_SIZE 0x0E
#define CMT2300A_MASK_SYNC_MAN_EN 0x01
/* ********** CMT2300A_CUS_PKT6 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_7_0 0xFF
/* ********** CMT2300A_CUS_PKT7 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_15_8 0xFF
/* ********** CMT2300A_CUS_PKT8 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_23_16 0xFF
/* ********** CMT2300A_CUS_PKT9 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_31_24 0xFF
/* ********** CMT2300A_CUS_PKT10 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_39_32 0xFF
/* ********** CMT2300A_CUS_PKT11 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_47_40 0xFF
/* ********** CMT2300A_CUS_PKT12 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_55_48 0xFF
/* ********** CMT2300A_CUS_PKT13 registers ********** */
#define CMT2300A_MASK_SYNC_VALUE_63_56 0xFF
/* ********** CMT2300A_CUS_PKT14 registers ********** */
#define CMT2300A_MASK_PAYLOAD_LENG_10_8 0x70
#define CMT2300A_MASK_AUTO_ACK_EN 0x08
#define CMT2300A_MASK_NODE_LENG_POS_SEL 0x04
#define CMT2300A_MASK_PAYLOAD_BIT_ORDER 0x02
#define CMT2300A_MASK_PKT_TYPE 0x01
/* CMT2300A_MASK_NODE_LENG_POS_SEL options */
#define CMT2300A_NODE_LENG_FIRST_NODE 0x00
#define CMT2300A_NODE_LENG_FIRST_LENGTH 0x04
/* CMT2300A_MASK_PAYLOAD_BIT_ORDER options */
#define CMT2300A_PAYLOAD_BIT_ORDER_MSB 0x00
#define CMT2300A_PAYLOAD_BIT_ORDER_LSB 0x02
/* CMT2300A_MASK_PKT_TYPE options */
#define CMT2300A_PKT_TYPE_FIXED 0x00
#define CMT2300A_PKT_TYPE_VARIABLE 0x01
/* ********** CMT2300A_CUS_PKT15 registers ********** */
#define CMT2300A_MASK_PAYLOAD_LENG_7_0 0xFF
/* ********** CMT2300A_CUS_PKT16 registers ********** */
#define CMT2300A_MASK_NODE_FREE_EN 0x20
#define CMT2300A_MASK_NODE_ERR_MASK 0x10
#define CMT2300A_MASK_NODE_SIZE 0x0C
#define CMT2300A_MASK_NODE_DET_MODE 0x03
/* CMT2300A_MASK_NODE_DET_MODE options */
#define CMT2300A_NODE_DET_NODE 0x00
#define CMT2300A_NODE_DET_VALUE 0x01
#define CMT2300A_NODE_DET_VALUE_0 0x02
#define CMT2300A_NODE_DET_VALUE_0_1 0x03
/* ********** CMT2300A_CUS_PKT17 registers ********** */
#define CMT2300A_MASK_NODE_VALUE_7_0 0xFF
/* ********** CMT2300A_CUS_PKT18 registers ********** */
#define CMT2300A_MASK_NODE_VALUE_15_8 0xFF
/* ********** CMT2300A_CUS_PKT19 registers ********** */
#define CMT2300A_MASK_NODE_VALUE_23_16 0xFF
/* ********** CMT2300A_CUS_PKT20 registers ********** */
#define CMT2300A_MASK_NODE_VALUE_31_24 0xFF
/* ********** CMT2300A_CUS_PKT21 registers ********** */
#define CMT2300A_MASK_FEC_TYPE 0x80
#define CMT2300A_MASK_FEC_EN 0x40
#define CMT2300A_MASK_CRC_BYTE_SWAP 0x20
#define CMT2300A_MASK_CRC_BIT_INV 0x10
#define CMT2300A_MASK_CRC_RANGE 0x08
#define CMT2300A_MASK_CRC_TYPE 0x06
#define CMT2300A_MASK_CRC_EN 0x01
/* CMT2300A_MASK_CRC_BYTE_SWAP options */
#define CMT2300A_CRC_ORDER_HBYTE 0x00
#define CMT2300A_CRC_ORDER_LBYTE 0x20
/* CMT2300A_MASK_CRC_RANGE options */
#define CMT2300A_CRC_RANGE_PAYLOAD 0x00
#define CMT2300A_CRC_RANGE_DATA 0x08
/* CMT2300A_MASK_CRC_TYPE options */
#define CMT2300A_CRC_TYPE_CCITT16 0x00
#define CMT2300A_CRC_TYPE_IBM16 0x02
#define CMT2300A_CRC_TYPE_ITuint16_t 0x04
/* ********** CMT2300A_CUS_PKT22 registers ********** */
#define CMT2300A_MASK_CRC_SEED_7_0 0xFF
/* ********** CMT2300A_CUS_PKT23 registers ********** */
#define CMT2300A_MASK_CRC_SEED_15_8 0xFF
/* ********** CMT2300A_CUS_PKT24 registers ********** */
#define CMT2300A_MASK_CRC_BIT_ORDER 0x80
#define CMT2300A_MASK_WHITEN_SEED_8_8 0x40
#define CMT2300A_MASK_WHITEN_SEED_TYPE 0x20
#define CMT2300A_MASK_WHITEN_TYPE 0x18
#define CMT2300A_MASK_WHITEN_EN 0x04
#define CMT2300A_MASK_MANCH_TYPE 0x02
#define CMT2300A_MASK_MANCH_EN 0x01
/* CMT2300A_MASK_CRC_BIT_ORDER options */
#define CMT2300A_CRC_BIT_ORDER_MSB 0x00
#define CMT2300A_CRC_BIT_ORDER_LSB 0x80
/* CMT2300A_MASK_WHITEN_SEED_TYPE options */
#define CMT2300A_WHITEN_SEED_TYPE_1 0x00
#define CMT2300A_WHITEN_SEED_TYPE_2 0x20
/* CMT2300A_MASK_WHITEN_TYPE options */
#define CMT2300A_WHITEN_TYPE_PN9_CCITT 0x00
#define CMT2300A_WHITEN_TYPE_PN9_IBM 0x08
#define CMT2300A_WHITEN_TYPE_PN7 0x10
/* CMT2300A_MASK_MANCH_TYPE options */
#define CMT2300A_MANCH_TYPE_ONE_01 0x00
#define CMT2300A_MANCH_TYPE_ONE_10 0x02
/* ********** CMT2300A_CUS_PKT25 registers ********** */
#define CMT2300A_MASK_WHITEN_SEED_7_0 0xFF
/* ********** CMT2300A_CUS_PKT26 registers ********** */
#define CMT2300A_MASK_TX_PREFIX_TYPE 0x03
/* ********** CMT2300A_CUS_PKT27 registers ********** */
#define CMT2300A_MASK_TX_PKT_NUM 0xFF
/* ********** CMT2300A_CUS_PKT28 registers ********** */
#define CMT2300A_MASK_TX_PKT_GAP 0xFF
/* ********** CMT2300A_CUS_PKT29 registers ********** */
#define CMT2300A_MASK_FIFO_AUTO_RES_EN 0x80
#define CMT2300A_MASK_FIFO_TH 0x7F
/* ********** CMT2300A_CUS_MODE_CTL registers ********** */
#define CMT2300A_MASK_CHIP_MODE_SWT 0xFF
/* CMT2300A_MASK_CHIP_MODE_SWT options */
#define CMT2300A_GO_EEPROM 0x01
#define CMT2300A_GO_STBY 0x02
#define CMT2300A_GO_RFS 0x04
#define CMT2300A_GO_RX 0x08
#define CMT2300A_GO_SLEEP 0x10
#define CMT2300A_GO_TFS 0x20
#define CMT2300A_GO_TX 0x40
#define CMT2300A_GO_SWITCH 0x80
/* ********** CMT2300A_CUS_MODE_STA registers ********** */
#define CMT2300A_MASK_RSTN_IN_EN 0x20
#define CMT2300A_MASK_CFG_RETAIN 0x10
#define CMT2300A_MASK_CHIP_MODE_STA 0x0F
/* CMT2300A_MASK_CHIP_MODE_STA options */
#define CMT2300A_STA_IDLE 0x00
#define CMT2300A_STA_SLEEP 0x01
#define CMT2300A_STA_STBY 0x02
#define CMT2300A_STA_RFS 0x03
#define CMT2300A_STA_TFS 0x04
#define CMT2300A_STA_RX 0x05
#define CMT2300A_STA_TX 0x06
#define CMT2300A_STA_EEPROM 0x07
#define CMT2300A_STA_ERROR 0x08
#define CMT2300A_STA_CAL 0x09
/* ********** CMT2300A_CUS_EN_CTL registers ********** */
#define CMT2300A_MASK_LOCKING_EN 0x20
/* ********** CMT2300A_CUS_FREQ_CHNL registers ********** */
#define CMT2300A_MASK_FH_CHANNEL 0xFF
/* ********** CMT2300A_CUS_FREQ_OFS registers ********** */
#define CMT2300A_MASK_FH_OFFSET 0xFF
/* ********** CMT2300A_CUS_IO_SEL registers ********** */
#define CMT2300A_MASK_GPIO4_SEL 0xC0
#define CMT2300A_MASK_GPIO3_SEL 0x30
#define CMT2300A_MASK_GPIO2_SEL 0x0C
#define CMT2300A_MASK_GPIO1_SEL 0x03
/* CMT2300A_MASK_GPIO4_SEL options */
#define CMT2300A_GPIO4_SEL_RSTIN 0x00
#define CMT2300A_GPIO4_SEL_INT1 0x40
#define CMT2300A_GPIO4_SEL_DOUT 0x80
#define CMT2300A_GPIO4_SEL_DCLK 0xC0
/* CMT2300A_MASK_GPIO3_SEL options */
#define CMT2300A_GPIO3_SEL_CLKO 0x00
#define CMT2300A_GPIO3_SEL_DOUT 0x10
#define CMT2300A_GPIO3_SEL_DIN 0x10
#define CMT2300A_GPIO3_SEL_INT2 0x20
#define CMT2300A_GPIO3_SEL_DCLK 0x30
/* CMT2300A_MASK_GPIO2_SEL options */
#define CMT2300A_GPIO2_SEL_INT1 0x00
#define CMT2300A_GPIO2_SEL_INT2 0x04
#define CMT2300A_GPIO2_SEL_DOUT 0x08
#define CMT2300A_GPIO2_SEL_DIN 0x08
#define CMT2300A_GPIO2_SEL_DCLK 0x0C
/* CMT2300A_MASK_GPIO1_SEL options */
#define CMT2300A_GPIO1_SEL_DOUT 0x00
#define CMT2300A_GPIO1_SEL_DIN 0x00
#define CMT2300A_GPIO1_SEL_INT1 0x01
#define CMT2300A_GPIO1_SEL_INT2 0x02
#define CMT2300A_GPIO1_SEL_DCLK 0x03
/* ********** CMT2300A_CUS_INT1_CTL registers ********** */
#define CMT2300A_MASK_RF_SWT1_EN 0x80
#define CMT2300A_MASK_RF_SWT2_EN 0x40
#define CMT2300A_MASK_INT_POLAR 0x20
#define CMT2300A_MASK_INT1_SEL 0x1F
/* CMT2300A_MASK_INT_POLAR options */
#define CMT2300A_INT_POLAR_SEL_0 0x00
#define CMT2300A_INT_POLAR_SEL_1 0x20
/* CMT2300A_MASK_INT1_SEL options */
#define CMT2300A_INT_SEL_RX_ACTIVE 0x00
#define CMT2300A_INT_SEL_TX_ACTIVE 0x01
#define CMT2300A_INT_SEL_RSSI_VLD 0x02
#define CMT2300A_INT_SEL_PREAM_OK 0x03
#define CMT2300A_INT_SEL_SYNC_OK 0x04
#define CMT2300A_INT_SEL_NODE_OK 0x05
#define CMT2300A_INT_SEL_CRC_OK 0x06
#define CMT2300A_INT_SEL_PKT_OK 0x07
#define CMT2300A_INT_SEL_SL_TMO 0x08
#define CMT2300A_INT_SEL_RX_TMO 0x09
#define CMT2300A_INT_SEL_TX_DONE 0x0A
#define CMT2300A_INT_SEL_RX_FIFO_NMTY 0x0B
#define CMT2300A_INT_SEL_RX_FIFO_TH 0x0C
#define CMT2300A_INT_SEL_RX_FIFO_FULL 0x0D
#define CMT2300A_INT_SEL_RX_FIFO_WBYTE 0x0E
#define CMT2300A_INT_SEL_RX_FIFO_OVF 0x0F
#define CMT2300A_INT_SEL_TX_FIFO_NMTY 0x10
#define CMT2300A_INT_SEL_TX_FIFO_TH 0x11
#define CMT2300A_INT_SEL_TX_FIFO_FULL 0x12
#define CMT2300A_INT_SEL_STATE_IS_STBY 0x13
#define CMT2300A_INT_SEL_STATE_IS_FS 0x14
#define CMT2300A_INT_SEL_STATE_IS_RX 0x15
#define CMT2300A_INT_SEL_STATE_IS_TX 0x16
#define CMT2300A_INT_SEL_LED 0x17
#define CMT2300A_INT_SEL_TRX_ACTIVE 0x18
#define CMT2300A_INT_SEL_PKT_DONE 0x19
/* ********** CMT2300A_CUS_INT2_CTL registers ********** */
#define CMT2300A_MASK_LFOSC_OUT_EN 0x40
#define CMT2300A_MASK_TX_DIN_INV 0x20
#define CMT2300A_MASK_INT2_SEL 0x1F
/* ********** CMT2300A_CUS_INT_EN registers ********** */
#define CMT2300A_MASK_SL_TMO_EN 0x80
#define CMT2300A_MASK_RX_TMO_EN 0x40
#define CMT2300A_MASK_TX_DONE_EN 0x20
#define CMT2300A_MASK_PREAM_OK_EN 0x10
#define CMT2300A_MASK_SYNC_OK_EN 0x08
#define CMT2300A_MASK_NODE_OK_EN 0x04
#define CMT2300A_MASK_CRC_OK_EN 0x02
#define CMT2300A_MASK_PKT_DONE_EN 0x01
/* ********** CMT2300A_CUS_FIFO_CTL registers ********** */
#define CMT2300A_MASK_TX_DIN_EN 0x80
#define CMT2300A_MASK_TX_DIN_SEL 0x60
#define CMT2300A_MASK_FIFO_AUTO_CLR_DIS 0x10
#define CMT2300A_MASK_FIFO_TX_RD_EN 0x08
#define CMT2300A_MASK_FIFO_RX_TX_SEL 0x04
#define CMT2300A_MASK_FIFO_MERGE_EN 0x02
#define CMT2300A_MASK_SPI_FIFO_RD_WR_SEL 0x01
/* CMT2300A_MASK_TX_DIN_SEL options */
#define CMT2300A_TX_DIN_SEL_GPIO1 0x00
#define CMT2300A_TX_DIN_SEL_GPIO2 0x20
#define CMT2300A_TX_DIN_SEL_GPIO3 0x40
/* ********** CMT2300A_CUS_INT_CLR1 registers ********** */
#define CMT2300A_MASK_SL_TMO_FLG 0x20
#define CMT2300A_MASK_RX_TMO_FLG 0x10
#define CMT2300A_MASK_TX_DONE_FLG 0x08
#define CMT2300A_MASK_TX_DONE_CLR 0x04
#define CMT2300A_MASK_SL_TMO_CLR 0x02
#define CMT2300A_MASK_RX_TMO_CLR 0x01
/* ********** CMT2300A_CUS_INT_CLR2 registers ********** */
#define CMT2300A_MASK_LBD_CLR 0x20
#define CMT2300A_MASK_PREAM_OK_CLR 0x10
#define CMT2300A_MASK_SYNC_OK_CLR 0x08
#define CMT2300A_MASK_NODE_OK_CLR 0x04
#define CMT2300A_MASK_CRC_OK_CLR 0x02
#define CMT2300A_MASK_PKT_DONE_CLR 0x01
/* ********** CMT2300A_CUS_FIFO_CLR registers ********** */
#define CMT2300A_MASK_FIFO_RESTORE 0x04
#define CMT2300A_MASK_FIFO_CLR_RX 0x02
#define CMT2300A_MASK_FIFO_CLR_TX 0x01
/* ********** CMT2300A_CUS_INT_FLAG registers ********** */
#define CMT2300A_MASK_LBD_FLG 0x80
#define CMT2300A_MASK_COL_ERR_FLG 0x40
#define CMT2300A_MASK_PKT_ERR_FLG 0x20
#define CMT2300A_MASK_PREAM_OK_FLG 0x10
#define CMT2300A_MASK_SYNC_OK_FLG 0x08
#define CMT2300A_MASK_NODE_OK_FLG 0x04
#define CMT2300A_MASK_CRC_OK_FLG 0x02
#define CMT2300A_MASK_PKT_OK_FLG 0x01
/* ********** CMT2300A_CUS_FIFO_FLAG registers ********** */
#define CMT2300A_MASK_RX_FIFO_FULL_FLG 0x40
#define CMT2300A_MASK_RX_FIFO_NMTY_FLG 0x20
#define CMT2300A_MASK_RX_FIFO_TH_FLG 0x10
#define CMT2300A_MASK_RX_FIFO_OVF_FLG 0x08
#define CMT2300A_MASK_TX_FIFO_FULL_FLG 0x04
#define CMT2300A_MASK_TX_FIFO_NMTY_FLG 0x02
#define CMT2300A_MASK_TX_FIFO_TH_FLG 0x01
/* ********** CMT2300A_CUS_RSSI_CODE registers ********** */
#define CMT2300A_MASK_RSSI_CODE 0xFF
/* ********** CMT2300A_CUS_RSSI_DBM registers ********** */
#define CMT2300A_MASK_RSSI_DBM 0xFF
/* ********** CMT2300A_CUS_LBD_RESULT registers ********** */
#define CMT2300A_MASK_LBD_RESULT 0xFF
#endif

View File

@ -0,0 +1,76 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) CMOSTEK SZ.
*/
/*!
* @file cmt2300a_hal.c
* @brief CMT2300A hardware abstraction layer
*
* @version 1.2
* @date Jul 17 2017
* @author CMOSTEK R@D
*/
#include "cmt2300a_hal.h"
#include "cmt_spi3.h"
#include <Arduino.h>
/*! ********************************************************
* @name CMT2300A_InitSpi
* @desc Initializes the CMT2300A SPI interface.
* *********************************************************/
void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
{
cmt_spi3_init(pin_sdio, pin_clk, pin_cs, pin_fcs, spi_speed);
}
/*! ********************************************************
* @name CMT2300A_ReadReg
* @desc Read the CMT2300A register at the specified address.
* @param addr: register address
* @return Register value
* *********************************************************/
uint8_t CMT2300A_ReadReg(const uint8_t addr)
{
return cmt_spi3_read(addr);
}
/*! ********************************************************
* @name CMT2300A_WriteReg
* @desc Write the CMT2300A register at the specified address.
* @param addr: register address
* dat: register value
* *********************************************************/
void CMT2300A_WriteReg(const uint8_t addr, const uint8_t dat)
{
cmt_spi3_write(addr, dat);
}
/*! ********************************************************
* @name CMT2300A_ReadFifo
* @desc Reads the contents of the CMT2300A FIFO.
* @param buf: buffer where to copy the FIFO read data
* len: number of bytes to be read from the FIFO
* *********************************************************/
void CMT2300A_ReadFifo(uint8_t buf[], const uint16_t len)
{
cmt_spi3_read_fifo(buf, len);
}
/*! ********************************************************
* @name CMT2300A_WriteFifo
* @desc Writes the buffer contents to the CMT2300A FIFO.
* @param buf: buffer containing data to be put on the FIFO
* len: number of bytes to be written to the FIFO
* *********************************************************/
void CMT2300A_WriteFifo(const uint8_t buf[], const uint16_t len)
{
cmt_spi3_write_fifo(buf, len);
}

View File

@ -0,0 +1,51 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) CMOSTEK SZ.
*/
/*!
* @file cmt2300a_hal.h
* @brief CMT2300A hardware abstraction layer
*
* @version 1.2
* @date Jul 17 2017
* @author CMOSTEK R@D
*/
#ifndef __CMT2300A_HAL_H
#define __CMT2300A_HAL_H
#include <stdint.h>
#include <Arduino.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ************************************************************************
* The following need to be modified by user
* ************************************************************************ */
#define CMT2300A_DelayMs(ms) delay(ms)
#define CMT2300A_DelayUs(us) delayMicroseconds(us)
#define CMT2300A_GetTickCount() millis()
/* ************************************************************************ */
void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);
uint8_t CMT2300A_ReadReg(const uint8_t addr);
void CMT2300A_WriteReg(const uint8_t addr, const uint8_t dat);
void CMT2300A_ReadFifo(uint8_t buf[], const uint16_t len);
void CMT2300A_WriteFifo(const uint8_t buf[], const uint16_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,214 @@
/*
;---------------------------------------
; CMT2300A Configuration File
; Generated by CMOSTEK RFPDK 1.46
; 2023.03.17 23:16
;---------------------------------------
; Mode = Advanced
; Part Number = CMT2300A
; Frequency = 860.000 MHz
; Xtal Frequency = 26.0000 MHz
; Demodulation = GFSK
; AGC = On
; Data Rate = 20.0 kbps
; Deviation = 20.0 kHz
; Tx Xtal Tol. = 20 ppm
; Rx Xtal Tol. = 20 ppm
; TRx Matching Network Type = 20 dBm
; Tx Power = +13 dBm
; Gaussian BT = 0.5
; Bandwidth = Auto-Select kHz
; CDR Type = Counting
; CDR DR Range = NA
; AFC = On
; AFC Method = Auto-Select
; Data Representation = 0:F-low 1:F-high
; Rx Duty-Cycle = Off
; Tx Duty-Cycle = Off
; Sleep Timer = Off
; Sleep Time = NA
; Rx Timer = Off
; Rx Time T1 = NA
; Rx Time T2 = NA
; Rx Exit State = STBY
; Tx Exit State = STBY
; SLP Mode = Disable
; RSSI Valid Source = PJD
; PJD Window = 8 Jumps
; LFOSC Calibration = On
; Xtal Stable Time = 155 us
; RSSI Compare TH = NA
; Data Mode = Packet
; Whitening = Disable
; Whiten Type = NA
; Whiten Seed Type = NA
; Whiten Seed = NA
; Manchester = Disable
; Manchester Type = NA
; FEC = Enable
; FEC Type = x^3+x^2+1
; Tx Prefix Type = 0
; Tx Packet Number = 1
; Tx Packet Gap = 32
; Packet Type = Variable Length
; Node-Length Position = First Node, then Length
; Payload Bit Order = Start from msb
; Preamble Rx Size = 2
; Preamble Tx Size = 30
; Preamble Value = 170
; Preamble Unit = 8-bit
; Sync Size = 4-byte
; Sync Value = 1296587336
; Sync Tolerance = None
; Sync Manchester = Disable
; Node ID Size = NA
; Node ID Value = NA
; Node ID Mode = None
; Node ID Err Mask = Disable
; Node ID Free = Disable
; Payload Length = 32
; CRC Options = IBM-16
; CRC Seed = 0 crc_seed
; CRC Range = Entire Payload
; CRC Swap = Start from MSB
; CRC Bit Invert = Normal
; CRC Bit Order = Start from bit 15
; Dout Mute = Off
; Dout Adjust Mode = Disable
; Dout Adjust Percentage = NA
; Collision Detect = Off
; Collision Detect Offset = NA
; RSSI Detect Mode = At PREAM_OK
; RSSI Filter Setting = 32-tap
; RF Performance = High
; LBD Threshold = 2.4 V
; RSSI Offset = 0
; RSSI Offset Sign = 0
*/
#ifndef __CMT2300A_PARAMS_860_H
#define __CMT2300A_PARAMS_860_H
#include "cmt2300a_defs.h"
#include <stdint.h>
/* [CMT Bank] with RSSI offset of +- 0 (and Tx power double bit not set) */
static uint8_t g_cmt2300aCmtBank_860[CMT2300A_CMT_BANK_SIZE] = {
0x00,
0x66,
0xEC,
0x1C,
0x70,
0x80,
0x14,
0x08,
0x11,
0x02,
0x02,
0x00,
};
/* [System Bank] */
static uint8_t g_cmt2300aSystemBank_860[CMT2300A_SYSTEM_BANK_SIZE] = {
0xAE,
0xE0,
0x35,
0x00,
0x00,
0xF4,
0x10,
0xE2,
0x42,
0x20,
0x0C,
0x81,
};
/* [Frequency Bank] 860 MHz */
static uint8_t g_cmt2300aFrequencyBank_860[CMT2300A_FREQUENCY_BANK_SIZE] = {
0x42,
0x32,
0xCF,
0x82,
0x42,
0x27,
0x76,
0x12,
};
/* [Data Rate Bank] */
static uint8_t g_cmt2300aDataRateBank_860[CMT2300A_DATA_RATE_BANK_SIZE] = {
0xA6,
0xC9,
0x20,
0x20,
0xD2,
0x35,
0x0C,
0x0A,
0x9F,
0x4B,
0x29,
0x29,
0xC0,
0x14,
0x05,
0x53,
0x10,
0x00,
0xB4,
0x00,
0x00,
0x01,
0x00,
0x00,
};
/* [Baseband Bank] - EU */
static uint8_t g_cmt2300aBasebandBank_860[CMT2300A_BASEBAND_BANK_SIZE] = {
0x12,
0x1E,
0x00,
0xAA,
0x06,
0x00,
0x00,
0x00,
0x00,
0x48,
0x5A,
0x48,
0x4D,
0x01,
0x1F,
0x00,
0x00,
0x00,
0x00,
0x00,
0xC3,
0x00,
0x00,
0x60,
0xFF,
0x00,
0x00,
0x1F,
0x10,
};
/* [Tx Bank] 13 dBm */
static uint8_t g_cmt2300aTxBank_860[CMT2300A_TX_BANK_SIZE] = {
0x70,
0x4D,
0x06,
0x00,
0x07,
0x50,
0x00,
0x53,
0x09,
0x3F,
0x7F,
};
#endif

View File

@ -0,0 +1,214 @@
/*
;---------------------------------------
; CMT2300A Configuration File
; Generated by CMOSTEK RFPDK 1.46
; 2023.03.17 23:16
;---------------------------------------
; Mode = Advanced
; Part Number = CMT2300A
; Frequency = 900.000 MHz
; Xtal Frequency = 26.0000 MHz
; Demodulation = GFSK
; AGC = On
; Data Rate = 20.0 kbps
; Deviation = 20.0 kHz
; Tx Xtal Tol. = 20 ppm
; Rx Xtal Tol. = 20 ppm
; TRx Matching Network Type = 20 dBm
; Tx Power = +13 dBm
; Gaussian BT = 0.5
; Bandwidth = Auto-Select kHz
; CDR Type = Counting
; CDR DR Range = NA
; AFC = On
; AFC Method = Auto-Select
; Data Representation = 0:F-low 1:F-high
; Rx Duty-Cycle = Off
; Tx Duty-Cycle = Off
; Sleep Timer = Off
; Sleep Time = NA
; Rx Timer = Off
; Rx Time T1 = NA
; Rx Time T2 = NA
; Rx Exit State = STBY
; Tx Exit State = STBY
; SLP Mode = Disable
; RSSI Valid Source = PJD
; PJD Window = 8 Jumps
; LFOSC Calibration = On
; Xtal Stable Time = 155 us
; RSSI Compare TH = NA
; Data Mode = Packet
; Whitening = Disable
; Whiten Type = NA
; Whiten Seed Type = NA
; Whiten Seed = NA
; Manchester = Disable
; Manchester Type = NA
; FEC = Enable
; FEC Type = x^3+x^2+1
; Tx Prefix Type = 0
; Tx Packet Number = 1
; Tx Packet Gap = 32
; Packet Type = Variable Length
; Node-Length Position = First Node, then Length
; Payload Bit Order = Start from msb
; Preamble Rx Size = 2
; Preamble Tx Size = 30
; Preamble Value = 170
; Preamble Unit = 8-bit
; Sync Size = 4-byte
; Sync Value = 1296587336
; Sync Tolerance = None
; Sync Manchester = Disable
; Node ID Size = NA
; Node ID Value = NA
; Node ID Mode = None
; Node ID Err Mask = Disable
; Node ID Free = Disable
; Payload Length = 32
; CRC Options = IBM-16
; CRC Seed = 0 crc_seed
; CRC Range = Entire Payload
; CRC Swap = Start from MSB
; CRC Bit Invert = Normal
; CRC Bit Order = Start from bit 15
; Dout Mute = Off
; Dout Adjust Mode = Disable
; Dout Adjust Percentage = NA
; Collision Detect = Off
; Collision Detect Offset = NA
; RSSI Detect Mode = At PREAM_OK
; RSSI Filter Setting = 32-tap
; RF Performance = High
; LBD Threshold = 2.4 V
; RSSI Offset = 0
; RSSI Offset Sign = 0
*/
#ifndef __CMT2300A_PARAMS_900_H
#define __CMT2300A_PARAMS_900_H
#include "cmt2300a_defs.h"
#include <stdint.h>
/* [CMT Bank] with RSSI offset of +- 0 (and Tx power double bit not set) */
static uint8_t g_cmt2300aCmtBank_900[CMT2300A_CMT_BANK_SIZE] = {
0x00,
0x66,
0xEC,
0x1C,
0x70,
0x80,
0x14,
0x08,
0x11,
0x02,
0x02,
0x00,
};
/* [System Bank] */
static uint8_t g_cmt2300aSystemBank_900[CMT2300A_SYSTEM_BANK_SIZE] = {
0xAE,
0xE0,
0x35,
0x00,
0x00,
0xF4,
0x10,
0xE2,
0x42,
0x20,
0x0C,
0x81,
};
/* [Frequency Bank] 900 MHz */
static uint8_t g_cmt2300aFrequencyBank_900[CMT2300A_FREQUENCY_BANK_SIZE] = {
0x45,
0x46,
0x0A,
0x84,
0x45,
0x3B,
0xB1,
0x13,
};
/* [Data Rate Bank] */
static uint8_t g_cmt2300aDataRateBank_900[CMT2300A_DATA_RATE_BANK_SIZE] = {
0xA6,
0xC9,
0x20,
0x20,
0xD2,
0x35,
0x0C,
0x0B,
0x9F,
0x4B,
0x29,
0x29,
0xC0,
0x14,
0x05,
0x53,
0x10,
0x00,
0xB4,
0x00,
0x00,
0x01,
0x00,
0x00,
};
/* [Baseband Bank] - EU */
static uint8_t g_cmt2300aBasebandBank_900[CMT2300A_BASEBAND_BANK_SIZE] = {
0x12,
0x1E,
0x00,
0xAA,
0x06,
0x00,
0x00,
0x00,
0x00,
0x48,
0x5A,
0x48,
0x4D,
0x01,
0x1F,
0x00,
0x00,
0x00,
0x00,
0x00,
0xC3,
0x00,
0x00,
0x60,
0xFF,
0x00,
0x00,
0x1F,
0x10,
};
/* [Tx Bank] 13 dBm */
static uint8_t g_cmt2300aTxBank_900[CMT2300A_TX_BANK_SIZE] = {
0x70,
0x4D,
0x06,
0x00,
0x07,
0x50,
0x00,
0x53,
0x09,
0x3F,
0x7F,
};
#endif

View File

@ -0,0 +1,330 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2023-2024 Thomas Basler and others
*/
#include "cmt2300wrapper.h"
#include "cmt2300a.h"
#include "cmt2300a_params_860.h"
#include "cmt2300a_params_900.h"
CMT2300A::CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t spi_speed)
{
_pin_sdio = pin_sdio;
_pin_clk = pin_clk;
_pin_cs = pin_cs;
_pin_fcs = pin_fcs;
_spi_speed = spi_speed;
}
bool CMT2300A::begin(void)
{
return _init_pins() && _init_radio();
}
bool CMT2300A::isChipConnected()
{
return CMT2300A_IsExist();
}
bool CMT2300A::startListening(void)
{
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
/* Must clear FIFO after enable SPI to read or write the FIFO */
CMT2300A_EnableReadFifo();
CMT2300A_ClearRxFifo();
if (!CMT2300A_GoRx()) {
return false;
} else {
return true;
}
}
bool CMT2300A::stopListening(void)
{
CMT2300A_ClearInterruptFlags();
return CMT2300A_GoSleep();
}
bool CMT2300A::available(void)
{
return (
CMT2300A_MASK_PREAM_OK_FLG |
CMT2300A_MASK_SYNC_OK_FLG |
CMT2300A_MASK_CRC_OK_FLG |
CMT2300A_MASK_PKT_OK_FLG
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
}
void CMT2300A::read(void* buf, const uint8_t len)
{
// Fetch the payload
CMT2300A_ReadFifo(static_cast<uint8_t*>(buf), len);
CMT2300A_ClearInterruptFlags();
}
bool CMT2300A::write(const uint8_t* buf, const uint8_t len)
{
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
/* Must clear FIFO after enable SPI to read or write the FIFO */
CMT2300A_EnableWriteFifo();
CMT2300A_ClearTxFifo();
CMT2300A_WriteReg(CMT2300A_CUS_PKT15, len); // set Tx length
/* The length need be smaller than 32 */
CMT2300A_WriteFifo(buf, len);
if (!(CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG) & CMT2300A_MASK_TX_FIFO_NMTY_FLG)) {
return false;
}
if (!CMT2300A_GoTx()) {
return false;
}
uint32_t timer = millis();
while (!(CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1))) {
if (millis() - timer > 95) {
return false;
}
}
CMT2300A_ClearInterruptFlags();
CMT2300A_GoSleep();
return true;
}
void CMT2300A::setChannel(const uint8_t channel)
{
CMT2300A_SetFrequencyChannel(channel);
}
uint8_t CMT2300A::getChannel(void)
{
return CMT2300A_ReadReg(CMT2300A_CUS_FREQ_CHNL);
}
uint8_t CMT2300A::getDynamicPayloadSize(void)
{
uint8_t result;
CMT2300A_ReadFifo(&result, 1); // first byte in FiFo is length
return result;
}
int CMT2300A::getRssiDBm()
{
return CMT2300A_GetRssiDBm();
}
bool CMT2300A::setPALevel(const int8_t level)
{
uint16_t Tx_dBm_word;
switch (level) {
// for TRx Matching Network Type: 20 dBm
case -10:
Tx_dBm_word = 0x0501;
break;
case -9:
Tx_dBm_word = 0x0601;
break;
case -8:
Tx_dBm_word = 0x0701;
break;
case -7:
Tx_dBm_word = 0x0801;
break;
case -6:
Tx_dBm_word = 0x0901;
break;
case -5:
Tx_dBm_word = 0x0A01;
break;
case -4:
Tx_dBm_word = 0x0B01;
break;
case -3:
Tx_dBm_word = 0x0C01;
break;
case -2:
Tx_dBm_word = 0x0D01;
break;
case -1:
Tx_dBm_word = 0x0E01;
break;
case 0:
Tx_dBm_word = 0x1002;
break;
case 1:
Tx_dBm_word = 0x1302;
break;
case 2:
Tx_dBm_word = 0x1602;
break;
case 3:
Tx_dBm_word = 0x1902;
break;
case 4:
Tx_dBm_word = 0x1C02;
break;
case 5:
Tx_dBm_word = 0x1F03;
break;
case 6:
Tx_dBm_word = 0x2403;
break;
case 7:
Tx_dBm_word = 0x2804;
break;
case 8:
Tx_dBm_word = 0x2D04;
break;
case 9:
Tx_dBm_word = 0x3305;
break;
case 10:
Tx_dBm_word = 0x3906;
break;
case 11:
Tx_dBm_word = 0x4107;
break;
case 12:
Tx_dBm_word = 0x4908;
break;
case 13:
Tx_dBm_word = 0x5309;
break;
case 14:
Tx_dBm_word = 0x5E0B;
break;
case 15:
Tx_dBm_word = 0x6C0C;
break;
case 16:
Tx_dBm_word = 0x7D0C;
break;
// the following values require the double bit:
case 17:
Tx_dBm_word = 0x4A0C;
break;
case 18:
Tx_dBm_word = 0x580F;
break;
case 19:
Tx_dBm_word = 0x6B12;
break;
case 20:
Tx_dBm_word = 0x8A18;
break;
default:
return false;
}
if (level > 16) { // set bit for double Tx value
CMT2300A_WriteReg(CMT2300A_CUS_CMT4, CMT2300A_ReadReg(CMT2300A_CUS_CMT4) | 0x01); // set bit0
} else {
CMT2300A_WriteReg(CMT2300A_CUS_CMT4, CMT2300A_ReadReg(CMT2300A_CUS_CMT4) & 0xFE); // reset bit0
}
CMT2300A_WriteReg(CMT2300A_CUS_TX8, Tx_dBm_word >> 8);
CMT2300A_WriteReg(CMT2300A_CUS_TX9, Tx_dBm_word & 0xFF);
return true;
}
bool CMT2300A::rxFifoAvailable()
{
return (
CMT2300A_MASK_PKT_OK_FLG
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
}
uint32_t CMT2300A::getBaseFrequency() const
{
return getBaseFrequency(_frequencyBand);
}
FrequencyBand_t CMT2300A::getFrequencyBand() const
{
return _frequencyBand;
}
void CMT2300A::setFrequencyBand(const FrequencyBand_t mode)
{
_frequencyBand = mode;
_init_radio();
}
void CMT2300A::flush_rx(void)
{
CMT2300A_ClearRxFifo();
}
bool CMT2300A::_init_pins()
{
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
return true; // assuming pins are connected properly
}
bool CMT2300A::_init_radio()
{
if (!CMT2300A_Init()) {
return false;
}
/* config registers */
switch (_frequencyBand) {
case FrequencyBand_t::BAND_900:
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_900, CMT2300A_CMT_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_900, CMT2300A_SYSTEM_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_900, CMT2300A_DATA_RATE_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_900, CMT2300A_BASEBAND_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_900, CMT2300A_TX_BANK_SIZE);
break;
default:
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_860, CMT2300A_CMT_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_860, CMT2300A_SYSTEM_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_860, CMT2300A_FREQUENCY_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_860, CMT2300A_DATA_RATE_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_860, CMT2300A_BASEBAND_BANK_SIZE);
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_860, CMT2300A_TX_BANK_SIZE);
break;
}
// xosc_aac_code[2:0] = 2
uint8_t tmp;
tmp = (~0x07) & CMT2300A_ReadReg(CMT2300A_CUS_CMT10);
CMT2300A_WriteReg(CMT2300A_CUS_CMT10, tmp | 0x02);
/* Config GPIOs */
CMT2300A_ConfigGpio(
CMT2300A_GPIO2_SEL_INT1 | CMT2300A_GPIO3_SEL_INT2);
/* Config interrupt */
CMT2300A_ConfigInterrupt(
CMT2300A_INT_SEL_TX_DONE, /* Config INT1 */
CMT2300A_INT_SEL_PKT_OK /* Config INT2 */
);
/* Enable interrupt */
CMT2300A_EnableInterrupt(
CMT2300A_MASK_TX_DONE_EN | CMT2300A_MASK_PREAM_OK_EN | CMT2300A_MASK_SYNC_OK_EN | CMT2300A_MASK_CRC_OK_EN | CMT2300A_MASK_PKT_DONE_EN);
CMT2300A_SetFrequencyStep(FH_OFFSET); // set FH_OFFSET (frequency = base freq + 2.5kHz*FH_OFFSET*FH_CHANNEL)
/* Use a single 64-byte FIFO for either Tx or Rx */
CMT2300A_EnableFifoMerge(true);
/* Go to sleep for configuration to take effect */
if (!CMT2300A_GoSleep()) {
return false; // CMT2300A not switched to sleep mode!
}
return true;
}

View File

@ -0,0 +1,138 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#define CMT2300A_ONE_STEP_SIZE 2500 // frequency channel step size for fast frequency hopping operation: One step size is 2.5 kHz.
#define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset
#define CMT_SPI_SPEED 4000000 // 4 MHz
#define CMT_BASE_FREQ_900 900000000
#define CMT_BASE_FREQ_860 860000000
enum FrequencyBand_t {
BAND_860,
BAND_900,
FrequencyBand_Max,
};
class CMT2300A {
public:
CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t _spi_speed = CMT_SPI_SPEED);
bool begin(void);
/**
* Checks if the chip is connected to the SPI bus
*/
bool isChipConnected();
bool startListening(void);
bool stopListening(void);
/**
* Check whether there are bytes available to be read
* @code
* if(radio.available()){
* radio.read(&data,sizeof(data));
* }
* @endcode
*
* @see available(uint8_t*)
*
* @return True if there is a payload available, false if none is
*/
bool available(void);
/**
* Read payload data from the RX FIFO buffer(s).
*
* The length of data read is usually the next available payload's length
* @see
* - getDynamicPayloadSize()
*
* @note I specifically chose `void*` as a data type to make it easier
* for beginners to use. No casting needed.
*
* @param buf Pointer to a buffer where the data should be written
* @param len Maximum number of bytes to read into the buffer. This
* value should match the length of the object referenced using the
* `buf` parameter. The absolute maximum number of bytes that can be read
* in one call is 32 (for dynamic payload lengths) or whatever number was
* previously passed to setPayloadSize() (for static payload lengths).
*/
void read(void* buf, const uint8_t len);
bool write(const uint8_t* buf, const uint8_t len);
/**
* Set RF communication channel. The frequency used by a channel is
* @param channel Which RF channel to communicate on, 0-254
*/
void setChannel(const uint8_t channel);
/**
* Get RF communication channel
* @return The currently configured RF Channel
*/
uint8_t getChannel(void);
/**
* Get Dynamic Payload Size
*
* For dynamic payloads, this pulls the size of the payload off
* the chip
*
* @return Payload length of last-received dynamic payload
*/
uint8_t getDynamicPayloadSize(void);
int getRssiDBm();
bool setPALevel(const int8_t level);
bool rxFifoAvailable();
uint32_t getBaseFrequency() const;
static constexpr uint32_t getBaseFrequency(FrequencyBand_t band)
{
switch (band) {
case FrequencyBand_t::BAND_900:
return CMT_BASE_FREQ_900;
break;
default:
return CMT_BASE_FREQ_860;
break;
}
}
FrequencyBand_t getFrequencyBand() const;
void setFrequencyBand(const FrequencyBand_t mode);
/**
* Empty the RX (receive) FIFO buffers.
*/
void flush_rx(void);
private:
/**
* initialize the GPIO pins
*/
bool _init_pins();
/**
* initialize radio.
* @warning This function assumes the SPI bus object's begin() method has been
* previously called.
*/
bool _init_radio();
int8_t _pin_sdio;
int8_t _pin_clk;
int8_t _pin_cs;
int8_t _pin_fcs;
uint32_t _spi_speed;
FrequencyBand_t _frequencyBand = FrequencyBand_t::BAND_860;
};

155
lib/CMT2300a/cmt_spi3.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "cmt_spi3.h"
#include <Arduino.h>
#include <driver/spi_master.h>
#include <SpiManager.h>
SemaphoreHandle_t paramLock = NULL;
#define SPI_PARAM_LOCK() \
do { \
} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)
static void IRAM_ATTR pre_cb(spi_transaction_t *trans) {
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 0);
}
static void IRAM_ATTR post_cb(spi_transaction_t *trans) {
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 1);
}
spi_device_handle_t spi;
gpio_num_t cs_reg, cs_fifo;
void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int32_t spi_speed)
{
paramLock = xSemaphoreCreateMutex();
auto bus_config = std::make_shared<SpiBusConfig>(
static_cast<gpio_num_t>(pin_sdio),
GPIO_NUM_NC,
static_cast<gpio_num_t>(pin_clk)
);
spi_device_interface_config_t device_config {
.command_bits = 0, // set by transactions individually
.address_bits = 0, // set by transactions individually
.dummy_bits = 0,
.mode = 0, // SPI mode 0
.duty_cycle_pos = 0,
.cs_ena_pretrans = 2, // only 1 pre and post cycle would be required for register access
.cs_ena_posttrans = static_cast<uint8_t>(2 * spi_speed / 1000000), // >2 us
.clock_speed_hz = spi_speed,
.input_delay_ns = 0,
.spics_io_num = -1, // CS handled by callbacks
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
.queue_size = 1,
.pre_cb = pre_cb,
.post_cb = post_cb,
};
spi = SpiManagerInst.alloc_device("", bus_config, device_config);
if (!spi)
ESP_ERROR_CHECK(ESP_FAIL);
cs_reg = static_cast<gpio_num_t>(pin_cs);
ESP_ERROR_CHECK(gpio_reset_pin(cs_reg));
ESP_ERROR_CHECK(gpio_set_level(cs_reg, 1));
ESP_ERROR_CHECK(gpio_set_direction(cs_reg, GPIO_MODE_OUTPUT));
cs_fifo = static_cast<gpio_num_t>(pin_fcs);
ESP_ERROR_CHECK(gpio_reset_pin(cs_fifo));
ESP_ERROR_CHECK(gpio_set_level(cs_fifo, 1));
ESP_ERROR_CHECK(gpio_set_direction(cs_fifo, GPIO_MODE_OUTPUT));
}
void cmt_spi3_write(const uint8_t addr, const uint8_t data)
{
spi_transaction_ext_t trans {
.base {
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
.cmd = 0,
.addr = addr,
.length = 8,
.rxlength = 0,
.user = &cs_reg, // CS for register access
.tx_buffer = &data,
.rx_buffer = nullptr,
},
.command_bits = 1,
.address_bits = 7,
.dummy_bits = 0,
};
SPI_PARAM_LOCK();
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
SPI_PARAM_UNLOCK();
}
uint8_t cmt_spi3_read(const uint8_t addr)
{
uint8_t data;
spi_transaction_ext_t trans {
.base {
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
.cmd = 1,
.addr = addr,
.length = 0,
.rxlength = 8,
.user = &cs_reg, // CS for register access
.tx_buffer = nullptr,
.rx_buffer = &data,
},
.command_bits = 1,
.address_bits = 7,
.dummy_bits = 0,
};
SPI_PARAM_LOCK();
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
SPI_PARAM_UNLOCK();
return data;
}
void cmt_spi3_write_fifo(const uint8_t* buf, const uint16_t len)
{
spi_transaction_t trans {
.flags = 0,
.cmd = 0,
.addr = 0,
.length = 8,
.rxlength = 0,
.user = &cs_fifo, // CS for FIFO access
.tx_buffer = nullptr,
.rx_buffer = nullptr,
};
SPI_PARAM_LOCK();
spi_device_acquire_bus(spi, portMAX_DELAY);
for (uint8_t i = 0; i < len; i++) {
trans.tx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
}
spi_device_release_bus(spi);
SPI_PARAM_UNLOCK();
}
void cmt_spi3_read_fifo(uint8_t* buf, const uint16_t len)
{
spi_transaction_t trans {
.flags = 0,
.cmd = 0,
.addr = 0,
.length = 0,
.rxlength = 8,
.user = &cs_fifo, // CS for FIFO access
.tx_buffer = nullptr,
.rx_buffer = nullptr,
};
SPI_PARAM_LOCK();
spi_device_acquire_bus(spi, portMAX_DELAY);
for (uint8_t i = 0; i < len; i++) {
trans.rx_buffer = buf + i;
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
}
spi_device_release_bus(spi);
SPI_PARAM_UNLOCK();
}

22
lib/CMT2300a/cmt_spi3.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __CMT_SPI3_H
#define __CMT_SPI3_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int32_t spi_speed);
void cmt_spi3_write(const uint8_t addr, const uint8_t dat);
uint8_t cmt_spi3_read(const uint8_t addr);
void cmt_spi3_write_fifo(const uint8_t* p_buf, const uint16_t len);
void cmt_spi3_read_fifo(uint8_t* p_buf, const uint16_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2024 Thomas Basler and others
*/
#include "CpuTemperature.h"
#include <Arduino.h>
#if defined(CONFIG_IDF_TARGET_ESP32)
// there is no official API available on the original ESP32
extern "C" {
uint8_t temprature_sens_read();
}
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
#include "driver/temp_sensor.h"
#endif
CpuTemperatureClass CpuTemperature;
float CpuTemperatureClass::read()
{
#ifdef CONFIG_IDF_TARGET_ESP32S2
// Disabling temperature reading for ESP32-S2 models as it might lead to WDT resets.
// See: https://github.com/espressif/esp-idf/issues/8088
return NAN;
#endif
std::lock_guard<std::mutex> lock(_mutex);
float temperature = NAN;
bool success = false;
#if defined(CONFIG_IDF_TARGET_ESP32)
uint8_t raw = temprature_sens_read();
ESP_LOGV(TAG, "Raw temperature value: %d", raw);
temperature = (raw - 32) / 1.8f;
success = (raw != 128);
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
temp_sensor_set_config(tsens);
temp_sensor_start();
#if defined(CONFIG_IDF_TARGET_ESP32S3) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 3))
#error \
"ESP32-S3 internal temperature sensor requires ESP IDF V4.4.3 or higher. See https://github.com/esphome/issues/issues/4271"
#endif
esp_err_t result = temp_sensor_read_celsius(&temperature);
temp_sensor_stop();
success = (result == ESP_OK);
#endif
if (success && std::isfinite(temperature)) {
return temperature;
} else {
ESP_LOGD(TAG, "Ignoring invalid temperature (success=%d, value=%.1f)", success, temperature);
return NAN;
}
}

View File

@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <mutex>
class CpuTemperatureClass {
public:
float read();
private:
std::mutex _mutex;
};
extern CpuTemperatureClass CpuTemperature;

3
lib/Frozen/AUTHORS Normal file
View File

@ -0,0 +1,3 @@
serge-sans-paille <sguelton@quarkslab.com>
Jérôme Dumesnil <jerome.dumesnil@gmail.com>
Chris Beck <chbeck@tesla.com>

202
lib/Frozen/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 Quarkslab
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

245
lib/Frozen/README.rst Normal file
View File

@ -0,0 +1,245 @@
Frozen
######
.. image:: https://travis-ci.org/serge-sans-paille/frozen.svg?branch=master
:target: https://travis-ci.org/serge-sans-paille/frozen
Header-only library that provides 0 cost initialization for immutable containers, fixed-size containers, and various algorithms.
Frozen provides:
- immutable (a.k.a. frozen), ``constexpr``-compatible versions of ``std::set``,
``std::unordered_set``, ``std::map`` and ``std::unordered_map``.
- fixed-capacity, ``constinit``-compatible versions of ``std::map`` and
``std::unordered_map`` with immutable, compile-time selected keys mapped
to mutable values.
- 0-cost initialization version of ``std::search`` for frozen needles using
Boyer-Moore or Knuth-Morris-Pratt algorithms.
The ``unordered_*`` containers are guaranteed *perfect* (a.k.a. no hash
collision) and the extra storage is linear with respect to the number of keys.
Once initialized, the container keys cannot be updated, and in exchange, lookups
are faster. And initialization is free when ``constexpr`` or ``constinit`` is
used :-).
Installation
------------
Just copy the ``include/frozen`` directory somewhere and points to it using the ``-I`` flag. Alternatively, using CMake:
.. code:: sh
> mkdir build
> cd build
> cmake -D CMAKE_BUILD_TYPE=Release ..
> make install
Installation via CMake populates configuration files into the ``/usr/local/share``
directory which can be consumed by CMake's ``find_package`` instrinsic function.
Requirements
------------
A C++ compiler that supports C++14. Clang version 5 is a good pick, GCC version
6 lags behind in terms of ``constexpr`` compilation time (At least on my
setup), but compiles correctly. Visual Studio 2017 also works correctly!
Note that gcc 5 isn't supported. (Here's an `old compat branch`_ where a small amount of stuff was ported.)
.. _old compat branch: https://github.com/cbeck88/frozen/tree/gcc5-support
Usage
-----
Compiled with ``-std=c++14`` flag:
.. code:: C++
#include <frozen/set.h>
constexpr frozen::set<int, 4> some_ints = {1,2,3,5};
constexpr bool letitgo = some_ints.count(8);
extern int n;
bool letitgoooooo = some_ints.count(n);
As the constructor and some methods are ``constexpr``, it's also possible to write weird stuff like:
.. code:: C++
#include <frozen/set.h>
template<std::size_t N>
std::enable_if_t< frozen::set<int, 3>{{1,11,111}}.count(N), int> foo();
String support is built-in:
.. code:: C++
#include <frozen/unordered_map.h>
#include <frozen/string.h>
constexpr frozen::unordered_map<frozen::string, int, 2> olaf = {
{"19", 19},
{"31", 31},
};
constexpr auto val = olaf.at("19");
The associative containers have different functionality with and without ``constexpr``.
With ``constexpr``, frozen maps have immutable keys and values. Without ``constexpr``, the
values can be updated in runtime (the keys, however, remain immutable):
.. code:: C++
#include <frozen/unordered_map.h>
#include <frozen/string.h>
static constinit frozen::unordered_map<frozen::string, frozen::string, 2> voice = {
{"Anna", "???"},
{"Elsa", "???"}
};
int main() {
voice.at("Anna") = "Kristen";
voice.at("Elsa") = "Idina";
}
You may also prefer a slightly more DRY initialization syntax:
.. code:: C++
#include <frozen/set.h>
constexpr auto some_ints = frozen::make_set<int>({1,2,3,5});
There are similar ``make_X`` functions for all frozen containers.
Exception Handling
------------------
For compatibility with STL's API, Frozen may eventually throw exceptions, as in
``frozen::map::at``. If you build your code without exception support, or
define the ``FROZEN_NO_EXCEPTIONS`` macro variable, they will be turned into an
``std::abort``.
Extending
---------
Just like the regular C++14 container, you can specialize the hash function,
the key equality comparator for ``unordered_*`` containers, and the comparison
functions for the ordered version.
It's also possible to specialize the ``frozen::elsa`` structure used for
hashing. Note that unlike `std::hash`, the hasher also takes a seed in addition
to the value being hashed.
.. code:: C++
template <class T> struct elsa {
// in case of collisions, different seeds are tried
constexpr std::size_t operator()(T const &value, std::size_t seed) const;
};
Ideally, the hash function should have nice statistical properties like *pairwise-independence*:
If ``x`` and ``y`` are different values, the chance that ``elsa<T>{}(x, seed) == elsa<T>{}(y, seed)``
should be very low for a random value of ``seed``.
Note that frozen always ultimately produces a perfect hash function, and you will always have ``O(1)``
lookup with frozen. It's just that if the input hasher performs poorly, the search will take longer and
your project will take longer to compile.
Troubleshooting
---------------
If you hit a message like this:
.. code:: none
[...]
note: constexpr evaluation hit maximum step limit; possible infinite loop?
Then either you've got a very big container and you should increase Clang's
thresholds, using ``-fconstexpr-steps=1000000000`` for instance, or the hash
functions used by frozen do not suit your data, and you should change them, as
in the following:
.. code:: c++
struct olaf {
constexpr std::size_t operator()(frozen::string const &value, std::size_t seed) const { return seed ^ value[0];}
};
constexpr frozen::unordered_set<frozen::string, 2, olaf/*custom hash*/> hans = { "a", "b" };
Tests and Benchmarks
--------------------
Using hand-written Makefiles crafted with love and care:
.. code:: sh
> # running tests
> make -C tests check
> # running benchmarks
> make -C benchmarks GOOGLE_BENCHMARK_PREFIX=<GOOGLE-BENCHMARK_INSTALL_DIR>
Using CMake to generate a static configuration build system:
.. code:: sh
> mkdir build
> cd build
> cmake -D CMAKE_BUILD_TYPE=Release \
-D frozen.benchmark=ON \
-G <"Unix Makefiles" or "Ninja"> ..
> # building the tests and benchmarks...
> make # ... with make
> ninja # ... with ninja
> cmake --build . # ... with cmake
> # running the tests...
> make test # ... with make
> ninja test # ... with ninja
> cmake --build . --target test # ... with cmake
> ctest # ... with ctest
> # running the benchmarks...
> make benchmark # ... with make
> ninja benchmark # ... with ninja
> cmake --build . --target benchmark # ... with cmake
Using CMake to generate an IDE build system with test and benchmark targets
.. code:: sh
> mkdir build
> cd build
> cmake -D frozen.benchmark=ON -G <"Xcode" or "Visual Studio 15 2017"> ..
> # using cmake to drive the IDE build, test, and benchmark
> cmake --build . --config Release
> cmake --build . --target test
> cmake --build . --target benchmark
Credits
-------
The perfect hashing is strongly inspired by the blog post `Throw away the keys:
Easy, Minimal Perfect Hashing <http://stevehanov.ca/blog/index.php?id=119>`_.
Thanks a lot to Jérôme Dumesnil for his high-quality reviews, and to Chris Beck
for his contributions on perfect hashing.
Contact
-------
Serge sans Paille ``<serge.guelton@telecom-bretagne.eu>``

View File

@ -0,0 +1,12 @@
target_sources(frozen-headers INTERFACE
"${prefix}/frozen/algorithm.h"
"${prefix}/frozen/map.h"
"${prefix}/frozen/random.h"
"${prefix}/frozen/set.h"
"${prefix}/frozen/string.h"
"${prefix}/frozen/unordered_map.h"
"${prefix}/frozen/unordered_set.h"
"${prefix}/frozen/bits/algorithms.h"
"${prefix}/frozen/bits/basic_types.h"
"${prefix}/frozen/bits/elsa.h"
"${prefix}/frozen/bits/pmh.h")

Some files were not shown because too many files have changed in this diff Show More