OpenDTU console gets spammed with "WifiGeneric::hostByName() error when first trying to resolve the hostname via DNS. So reverse order: first try mDNS, if that fails try DNS. Also ensure that https bool is passed correctly to HTTPClient::begin(). Lastly, concatenate strings for building Digest authorization using "+" and not via snprintf.
this change utilizes some of the features from library "frozen", which
was included upstream for the grid profile parser. to improve code
maintainability, a couple of std::maps mapping strings to values or the
other way around were introduced in OpenDTU-OnBattery-specific code at
the expense of some flash and computing overhead.
library "frozen" offers constexpr versions of map and string, which
saves initialization code and offers slightly faster lookups. this
brings the binary size down by ~25kB and should provide a small
performance improvement at runtime.
Added ability to deal with local host names (mDNS), remove use of FirebasedJson to save ~20kB build size, some changes to PowerLimiter to avoid setting new inverter power limits when not needed (=current limit as reported by inverter is within hysteresis)
this battery provider implementation subscribes to a user-configurable
MQTT topic to retrieve the battery SoC value. the value is not
re-published under a different topic. there is no card created in the
web app's live view, since the SoC is already part of the totals at the
top of the live view. that is the only info this battery provider
implements.
closes#293.
relates to #581.
MQTT message callbacks are executed in the MQTT thread context. when
processing topics that control the DPL, we must avoid executing methods
that are not thread-safe. this change binds the methods to be called to
the respective parameters and executes them in the TaskScheduler
context, such that they no longer need to be thread-safe.
* bind the callback to a topic (enum value) such that there is no need
to tokenize the full topic (string) to find out what value is being
processed. tokenizing is expensive.
* get rid of using the config in the callback, which improves
thread-safety since the MQTT callback is running in the MQTT thread.
* prefer C++ method stof to convert MQTT value to a float, which saves
us from using new and delete for a buffer in particular.
* prefer switch statements over if-else-trees.
* split long lines.
* get rid of topic #defines.
* fix indention.
MQTT message callbacks are executed in the MQTT thread context. when
processing topics that control the huawei AC charger, we must avoid
executing methods that are not thread-safe. this change bound the
methods to be called to the respective parameters and executes them
in the TaskScheduler context, such that they no longer need to be
thread-safe.
there are more interesting values available to display in the live view.
however, adding them made the list of values very long. this can be
mitigated by using a new column/card, which uses the available screen
space nicely on bigger screens.
this commit re-introduces the changes from #418, which were effectively
reverted with d49481097 (merge commit introducing TaskScheduler).
these adjustments are important to guarantee unmangled log messages and
more importantly, to guarantee that all messages from a particular
component are printed to the web console, which most people use to copy
messages from when reporting issues.
* use dynamic memory to allow handling of arbitrary message lenghts.
* keep a message buffer for every task so no task ever mangles the
message of another task.
* every complete line is written to the serial console and moved to
a line buffer for sending them through the websocket.
* the websocket is always fed complete lines.
* make sure to feed only as many lines as possible to the websocket
handler, so that no lines are dropped.
* lock all MessageOutput state against concurrent access.
* respect HardwareSerial buffer size: the MessageOutput class buffers
whole lines of output printed by any task in order to avoid mangling
of text. that means we hand over full lines to the HardwareSerial
instance, which might be too much in one call to write(buffer, size).
we now check the return value of write(buffer, size) and call the
function again with the part of the message that could not yet be
written by HardwareSerial.
* Optimize Sun data calculation
* Remove not required enum
* Split config struct into different sub structs
* Feature: Allow configuration of LWT QoS
* Made resetreason methods static
* Feature: Implement offset cache for "YieldDay"
Thanks to @broth-itk for the idea!
Fix: #1258#1397
* Add Esp32-Stick-PoE-A
* remove broken LilyGO_T_ETH_POE config, use device profile instead
* Feature: High resolution Icon and PWA (Progressive Web App) functionality
Fix: #1289
* webapp: Update dependencies
* Initialize TaskScheduler
* Migrate SunPosition to TaskScheduler
* Migrate Datastore to TaskScheduler
* Migrate MqttHandleInverterTotal to TaskSchedule
* Migrate MqttHandleHass to TaskScheduler
* Migrate MqttHandleDtu to TaskScheduler
* Migrate MqttHandleInverter to TaskScheduler
* Migrate LedSingle to TaskScheduler
* Migrate NetworkSettings to TaskScheduler
* Migrate InverterSettings to TaskScheduler
* Migrate MessageOutput to TaskScheduler
* Migrate Display_Graphic to TaskScheduler
* Migrate WebApi to TaskScheduler
* Split InverterSettings into multiple tasks
* Calculate SunPosition only every 5 seconds
* Split LedSingle into multiple tasks
* Upgrade espMqttClient from 1.4.5 to 1.5.0
* Doc: Correct amount of MPP-Tracker
* Added HMT-1600-4T and HMT-1800-4T to DevInfoParser
Fix#1524
* Adjusted inverter names for HMS-1600/1800/2000-4T
* Add channel count to description of detected inverter type (DevInfoParser)
* Adjust device web api endpoint for dynamic led count
* Feature: Added ability to change the brightness of the LEDs
Based on the idea of @moritzlerch with several modifications like pwmTable and structure
* webapp: Update dependencies
* Update olikraus/U8g2 from 2.35.7 to 2.35.8
* Remove not required onWebsocketEvent
* Remove code nesting
* Introduce several const statements
* Remove not required AsyncEventSource
* Doc: Added byte specification to each command
* Feature: Added basic Grid Profile parser which shows the used profile and version
Other values are still outstanding.
* Optimize AlarmLogParser to save memory
* Add libfrozen to project to create constexpr maps
* Feature: First version of GridProfile Parser which shows all values contained in the profile.
* webapp: Update dependencies
* Apply better variable names
* Remove not required casts
* Add additional compiler flags to prevent errors
* Add const statement to several variables
* Replace NULL by nullptr
* Update bblanchon/ArduinoJson from 6.21.3 to 6.21.4
* Add const keyword to method parameters
* Add const keyword to methods
* Use references instead of pointers whenver possible
* Adjust member variable names in MqttSettings
* Adjust member variable names in NetworkSettings
* webapp: Update timezone database to latest version
* webapp: Beautify and unify form footers
* Feature: Allow setting of an inverter limit of 0% and 0W
Thanks to @madmartin in #1270
* Feature: Allow links in device profiles
These links will be shown on the hardware settings page.
* Doc: Added hint regarding HMS-xxxx-xT-NA inverters
* Feature: Added DeviceProfile for CASmo-DTU
Based on #1565
* Upgrade actions/upload-artifact from v3 to v4
* Upgrade actions/download-artifact from v3 to v4
* webapp: add app.js.gz
* Gridprofileparser: Added latest known values
Thanks to @stefan123t and @noone2k
* webapp: Fix lint errors
* Feature: Add DTU to Home Assistant Auto Discovery
This is based on PR 1365 from @CFenner with several fixes and optimizations
* Fix: Remove debug output as it floods the console
* Fix: Gridprofileparser: Add additional error handling if profile is unknown
* webapp: add app.js.gz
* Fix: Offset cache for "YieldDay" did not work correctly
* webapp: update dependencies
* webapp: add app.js.gz
* Fix: yarn.lock was outdated
* Fix: yarn build error
* Fix: Reset Yield day correction in combination with Zero Yield Day on Midnight lead to wrong values.
* Fix: Allow negative values in GridProfileParser
* Correct variable name
* Fix#1579: Static IP in Ethernet mode did not work correctly
* Feature: Added diagram to display
This is based on the idea of @Henrik-Ingenieur and was discussed in #1504
* webapp: update dependencies
* webapp: add app.js.gz
---------
Co-authored-by: Thomas Basler <thomas@familie-basler.net>
Co-authored-by: Pierre Kancir <pierre.kancir.emn@gmail.com>
* add more values to web app live view. this should add all interesting
values for the web app live view. those include important values and
values that change frequently.
* add more interesting JK BMS dummy messages: one has 0% SoC and an
alarm (discharge undervoltage) set. the other has the undertemperature
alarm set.
* add alarms and warnings to live view
* publish alarm and status bits through MQTT individually
* publish cell voltages to MQTT broker
* remove trailing spaces in BatteryStats class
* VE.Direct: return non-nullptr as a fallback
the changed return statement was supposed to return a shared_ptr to a
new and valid MPPT data struct as a fallback. however, it did return a
new shared_ptr that was initialized to nullptr.
* VE.Direct: make liveview total use total MPPT values
this change makes the call to VictronMppt.getData() obsolete, which in
turn will therefore not cause an error message on the console if
VE.Direct (MPPT) is not enabled. this change also takes care that once
multiple VE.Direct MPPT charge controllers are supported, the sums of
the respective total values are used in the web app totals.
* introduce VictronMpptClass
this solves a design issue where the loop() method of a static instance
of VeDirectMpptController, which is part of library code, is called as
part of the main loop() implementation. that is a problem because the
call to this loop() must be handled differently from all other calls:
the lib does not know whether or not the feature is enabled at all.
also, the instance would not be initialized when enabling the feature
during normal operation. that would even lead to a nullptr exception
since the pointer to the serial implementation is still uninitialized.
this new intermediate class is implemented with the support for multiple
Victron charge controllers in mind. adding support for more charge
controllers should be more viable than ever.
fixes#481.
related to #397#129.
* VE.Direct: move get.*AsString methods to respective structs
those structs, which hold the data to be translated into strings, know
best how to translate them. this change also simplifies access to those
translation, as no parameter must be handed to the respective methods:
they now act upon the data of the instance they are called for. adds
constness to those methods.
* VE.Direct: simplify and clean up get.*AsString methods
use a map, which is much easier to maintain and which reads much easier.
move the strings to flash memory to save RAM.
* DPL: use VictronMpptClass::getPowerOutputWatts method
remove redundant calculation of output power from DPL. consider
separation of concern: VictronMpptClass will provide the total solar
output power. the DPL shall not concern itself about how that value is
calculated and it certainly should be unaware about how many MPPT charge
controllers there actually are.
* VE.Direct: avoid shadowing struct member "P"
P was part of the base struct for both MPPT and SmartShunt controller.
however, P was also part of the SmartShunt controller data struct,
shadowing the member in the base struct.
since P has slightly different meaning in MPPT versus SmartShunt, and
since P is calculated for MPPT controllers but read from SmartShunts, P
now lives in both derived structs, but not in the base struct.
* VE.Direct: isDataValid(): avoid copying data structs
pass a const reference to the base class implementation of isDataValid()
rather than a copy of the whole struct.
* VE.Direct: unify logging of text events
* VE.Direct: stop processing text event if handled by base
in case the base class processed a text event, do not try to match it
against values that are only valid in the derived class -- none will
match.
* VE.Direct MPPT: manage data in a shared_ptr
instead of handing out a reference to a struct which is part of a class
instance that may disappear, e.g., on a config change, we now manage the
lifetime of said data structure using a shared_ptr and hand out copies
of that shared_ptr. this makes sure that users have a valid copy of the
data as long as they hold the shared_ptr.
* VE.Direct MPPT: implement getDataAgeMillis()
this works even if millis() wraps around.
* VE.Direct: process frame end event only for valid frames
save a parameters, save a level of indention, save a function call for
invalid frames.
avoid staleness in case the same power limit is calculated over and over
again, hence no new power limit value is calculated and hence no power
limit command is sent to the inverter. staleness occurs in this case if
the first power limit command to establish the respective limit was not
received by the inverter. one can easily simulate a situation where the
same power limit is caluclated over and over again: with a battery above
the start threshold, set a very low upper power limit for the inverter
(DPL setting). that value will be used as the limit as long as the power
meter reading is larger than that.
we could also check the limit reported by the inverter. however, that
value is in percent of the inverter's max AC output, and is often not
the same value as we requested as the limit, but slightly off. we then
would have to decide how much deviation is okay, which is unreasonably
complicated.
closes#478.
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.
* Move Mppt logic to subclass
* Added Definitions for Shunts and restructering
* First integration of SmartShunt data into Web Interface
* Code cleanup
* VE.Direct: whitespace cleanup
* VE.Direct: manage HardwareSerial in unique_ptr
* VE.Direct: _efficiency is only needed by MPPT
* VE.Direct: keep as many members private as possible
* VE.Direct: use int8_t for pins (as before)
* VictronSmartShunt: _verboseLogging is not used
* VE.Direct: OR (off reason) is MPPT specific
it also applies to Phoenix inverters and Smart BuckBoost, but since
there is no support for those, the code is moved to the MPPT controller.
* Added Shunt alarms to liveview
Changed from double to int for several readings
* Update build.yml to allow manual builds
---------
Co-authored-by: Philipp Sandhaus <philipp.sandhaus@cewe.de>
Co-authored-by: Bernhard Kirchen <schlimmchen@posteo.net>
* JK BMS: avoid trailing whitespace in debug output
* JK BMS: publish data points through MQTT
* JK BMS: updateFrom: skip data points with equal value
this changes the interpretation of the timestamp in data containers that
are merely updated from other data containers: this is the oldest
timestamp known where the value was as recorded by the data point in its
respective container.
the data container constructed from an answer will -- naturally -- have
the timetamps of its data points set to the time they were constructed.
* JK BMS: only publish changed values to MQTT broker
all values are still published once every minute if the MQTT retain flag
is NOT set. otherwise, the constant values are only published once on
startup.
* JK BMS: avoid trailing whitespace in debug output
* JK BMS: publish data points through MQTT
* JK BMS: updateFrom: skip data points with equal value
this changes the interpretation of the timestamp in data containers that
are merely updated from other data containers: this is the oldest
timestamp known where the value was as recorded by the data point in its
respective container.
the data container constructed from an answer will -- naturally -- have
the timetamps of its data points set to the time they were constructed.
* JK BMS: only publish changed values to MQTT broker
all values are still published once every minute if the MQTT retain flag
is NOT set. otherwise, the constant values are only published once on
startup.
* thread-safety and dynamic memory for MessageOutput
* use dynamic memory to allow handling of arbitrary message lenghts.
* keep a message buffer for every task so no task ever mangles the
message of another task.
* every complete line is written to the serial console and moved to
a line buffer for sending them through the websocket.
* the websocket is always fed complete lines.
* make sure to feed only as many lines as possible to the websocket
handler, so that no lines are dropped.
* lock all MessageOutput state against concurrent access.
* MessageOutput: respect HardwareSerial buffer size
the MessageOutput class buffers whole lines of output printed by any
task in order to avoid mangling of text. that means we hand over full
lines to the HardwareSerial instance, which might be too much in one
call to write(buffer, size). we now check the return value of
write(buffer, size) and call the function again with the part of the
message that could not yet be written by HardwareSerial.
* VE.Direct: reset state machine on timeout
there will never be a large gap between two bytes of the same frame.
if such a large gap is observed, reset the state machine so it tries
to decode a new frame once more data arrives.
this is helpful in case of corrupted data that prevents the state
machine of transitioning to the final state even though the VE.Direct
data producer is done sending bytes that belong to the same frame.
* VE.Direct: print problems to MessageOutput
this includes the web console in particular, where many users have
access to while the serial console is not attached or monitored.
* VE.Direct: collect serial input into buffer and print
should help debug issues for users.
* VE.Direct: implement and use verbose logging switch
* add Icons for Battery and Victron device sensors in Home Assistant
overriding the boring default icon for many sensors
Signed-off-by: Martin Dummer <martin.dummer@gmx.net>