Compare commits

..

1 Commits

Author SHA1 Message Date
jomjol
2d6d89adc7 Update tflite 2025-04-06 09:42:36 +02:00
27 changed files with 77 additions and 184 deletions

View File

@@ -1,10 +1,6 @@
name: Build and Pack name: Build and Pack
on: on: [push, pull_request]
push:
pull_request:
release:
types: [released] # Only trigger on published releases (not drafts or pre-released)
jobs: jobs:
######################################################################################### #########################################################################################
@@ -308,7 +304,7 @@ jobs:
prepare-release: prepare-release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [pack-for-update, pack-for-manual_setup, pack-for-remote_setup] needs: [pack-for-update, pack-for-manual_setup, pack-for-remote_setup]
if: github.event_name == 'release' # Only run when the trigger is a release if: startsWith(github.ref, 'refs/tags/')
# Sets permissions of the GITHUB_TOKEN to allow updating the branches # Sets permissions of the GITHUB_TOKEN to allow updating the branches
permissions: permissions:
@@ -410,7 +406,7 @@ jobs:
######################################################################################### #########################################################################################
# Make sure to also update update-webinstaller.yml! # Make sure to also update update-webinstaller.yml!
update-web-installer: update-web-installer:
if: github.event_name == 'release' # Only run when the trigger is a release if: github.event_name == 'release' && github.event.action == 'published' # Only run on release but not on prerelease
needs: [prepare-release] needs: [prepare-release]
environment: environment:
name: github-pages name: github-pages
@@ -448,13 +444,13 @@ jobs:
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' webinstaller/manifest.json sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' webinstaller/manifest.json
- name: Setup Pages - name: Setup Pages
uses: actions/configure-pages@v5 uses: actions/configure-pages@v4
- name: Upload artifact - name: Upload artifact
uses: actions/upload-pages-artifact@v3 uses: actions/upload-pages-artifact@v2
with: with:
path: 'webinstaller' path: 'webinstaller'
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@v4.0.5 # Note: v4 does not work! uses: actions/deploy-pages@v3 # Note: v4 does not work!

View File

@@ -18,7 +18,7 @@ permissions:
jobs: jobs:
comment: comment:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -1,28 +1,4 @@
# [16.1.0-RC1] - 2025-12-29 # [16.0.0] - 2024-03-15
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v16.0.0...v16.1.0)
### Known issues
No software is perfect. We know that our software has some quirks. If you have an issue, please first check the [issues](https://github.com/jomjol/AI-on-the-edge-device/issues) and
[discussions](https://github.com/jomjol/AI-on-the-edge-device/discussions) before reporting a new issue.
### Core Changes and Bug fixes
- Various minor improvements and changes
- Various documentation corrections/improvements
- Parameter `ChangeRateThreshold` can now also be zero [#3668](https://github.com/jomjol/AI-on-the-edge-device/pull/3668)
- MQTT: Added a proper `device_class` (duration) to "uptime" [#3659](https://github.com/jomjol/AI-on-the-edge-device/pull/3659)
- MQTT: Added `default_entity_id` to MQTT HA autodiscovery payload [#3970](https://github.com/jomjol/AI-on-the-edge-device/pull/3970)
- Added new models
- Updated SDCard Manufacturer List [#3730](https://github.com/jomjol/AI-on-the-edge-device/pull/3730)
- Added option for gal/min rate for Home Assistant MQTT Autodiscovery[#3868](https://github.com/jomjol/AI-on-the-edge-device/pull/3868)
- Fixed Setup Wizard [#3906](https://github.com/jomjol/AI-on-the-edge-device/pull/3906)
- `checkDigitConsistency`: added ESP_LOG_DEBUG output [#3962](https://github.com/jomjol/AI-on-the-edge-device/pull/3962)
- Added "Draw from center" option to Analog ROI editor [#3975](https://github.com/jomjol/AI-on-the-edge-device/pull/3975)
- Enabled OV3660 support in sdkconfig.defaults [#3996](https://github.com/jomjol/AI-on-the-edge-device/pull/3996)
# [16.0.0] - 2025-03-15
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0) For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0)

View File

@@ -166,7 +166,6 @@ Various 3D-printable housings can be found here:
- ⚡ [Power Meter](https://www.thingiverse.com/thing:5028229) - ⚡ [Power Meter](https://www.thingiverse.com/thing:5028229)
- 🔥 [Gas Meter](https://www.thingiverse.com/thing:5224101) - 🔥 [Gas Meter](https://www.thingiverse.com/thing:5224101)
- 📷 [ESP32-cam housing only](https://www.thingiverse.com/thing:4571627) - 📷 [ESP32-cam housing only](https://www.thingiverse.com/thing:4571627)
- 📡 [Top cover and Antenna Holder](https://www.printables.com/model/452139-cover-for-esp32-cam-water-meter)
--- ---

View File

@@ -161,9 +161,6 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
else if (toUpper(splitted[1]) == "WATER_GAL") { else if (toUpper(splitted[1]) == "WATER_GAL") {
mqttServer_setMeterType("water", "gal", "h", "gal/h"); mqttServer_setMeterType("water", "gal", "h", "gal/h");
} }
else if (toUpper(splitted[1]) == "WATER_GAL_MIN") {
mqttServer_setMeterType("water", "gal", "min", "gal/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "GAS_M3") { else if (toUpper(splitted[1]) == "GAS_M3") {
mqttServer_setMeterType("gas", "", "h", "m³/h"); mqttServer_setMeterType("gas", "", "h", "m³/h");
} }

View File

@@ -758,8 +758,17 @@ string ClassFlowPostProcessing::ShiftDecimal(string in, int _decShift) {
} }
bool ClassFlowPostProcessing::doFlow(string zwtime) { bool ClassFlowPostProcessing::doFlow(string zwtime) {
string result = "";
string digit = "";
string analog = "";
string zwvalue; string zwvalue;
time_t imagetime = flowTakeImage->getTimeImageTaken(); string zw;
time_t imagetime = 0;
string rohwert;
// Update decimal point, as the decimal places can also change when changing from CNNType Auto --> xyz:
imagetime = flowTakeImage->getTimeImageTaken();
if (imagetime == 0) { if (imagetime == 0) {
time(&imagetime); time(&imagetime);
@@ -785,7 +794,6 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) {
// double LastValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastValue); // in seconds // double LastValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastValue); // in seconds
double LastPreValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastPreValue); // in seconds double LastPreValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastPreValue); // in seconds
// Update decimal point, as the decimal places can also change when changing from CNNType Auto --> xyz:
UpdateNachkommaDecimalShift(); UpdateNachkommaDecimalShift();
int previous_value = -1; int previous_value = -1;
@@ -876,15 +884,12 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) {
if (NUMBERS[j]->checkDigitIncreaseConsistency) { if (NUMBERS[j]->checkDigitIncreaseConsistency) {
if (flowDigit) { if (flowDigit) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Before checkDigitConsistency: value=" + std::to_string(NUMBERS[j]->Value));
NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue); NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "After checkDigitConsistency: value=" + std::to_string(NUMBERS[j]->Value));
} }
else { else {
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
ESP_LOGD(TAG, "checkDigitIncreaseConsistency = true - no digit numbers defined!"); ESP_LOGD(TAG, "checkDigitIncreaseConsistency = true - no digit numbers defined!");
#endif #endif
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "checkDigitIncreaseConsistency = true - no digit numbers defined!");
} }
} }
@@ -1123,7 +1128,6 @@ float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilams
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
ESP_LOGD(TAG, "checkDigitConsistency: pot=%d, decimalshift=%d", pot, _decilamshift); ESP_LOGD(TAG, "checkDigitConsistency: pot=%d, decimalshift=%d", pot, _decilamshift);
#endif #endif
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "checkDigitConsistency: pot=" + std::to_string(pot) + ", decimalshift=" + std::to_string(_decilamshift));
pot_max = ((int) log10(input)) + 1; pot_max = ((int) log10(input)) + 1;
@@ -1155,7 +1159,6 @@ float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilams
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
ESP_LOGD(TAG, "checkDigitConsistency: input=%f", input); ESP_LOGD(TAG, "checkDigitConsistency: input=%f", input);
#endif #endif
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "checkDigitConsistency: input=" + std::to_string(input));
pot++; pot++;
} }

View File

@@ -806,21 +806,11 @@ struct SDCard_Manufacturer_database sd_database[] = {
.id = 0x03, .id = 0x03,
.manufacturer = "SanDisk", .manufacturer = "SanDisk",
}, },
{
.type = "sd",
.id = 0x05,
.manufacturer = "Lenovo",
},
{ {
.type = "sd", .type = "sd",
.id = 0x08, .id = 0x08,
.manufacturer = "Silicon Power", .manufacturer = "Silicon Power",
}, },
{
.type = "sd",
.id = 0x09,
.manufacturer = "ATP",
},
{ {
.type = "sd", .type = "sd",
.id = 0x18, .id = 0x18,
@@ -904,27 +894,7 @@ struct SDCard_Manufacturer_database sd_database[] = {
{ {
.type = "sd", .type = "sd",
.id = 0x89, .id = 0x89,
.manufacturer = "Netac", .manufacturer = "Unknown",
},
{
.type = "sd",
.id = 0x9f,
.manufacturer = "Kingston/Kodak/Silicon Power",
},
{
.type = "sd",
.id = 0xad,
.manufacturer = "Amazon Basics/Lexar/OV",
},
{
.type = "sd",
.id = 0xdf,
.manufacturer = "Lenovo",
},
{
.type = "sd",
.id = 0xfe,
.manufacturer = "Bekit/Cloudisk/HP/Reletech",
}, },
}; };
@@ -1248,7 +1218,7 @@ bool replaceString(std::string &s, std::string const &toReplace, std::string con
if (logIt) if (logIt)
{ {
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'");
} }
return true; return true;

View File

@@ -72,7 +72,6 @@ bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
std::string topicFull; std::string topicFull;
std::string configTopic; std::string configTopic;
std::string payload; std::string payload;
std::string component;
configTopic = field; configTopic = field;
@@ -81,16 +80,6 @@ bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
name = group + " " + name; name = group + " " + name;
} }
if (field == "problem") { // Special case: Binary sensor which is based on error topic
component = "binary_sensor";
}
else if (field == "flowstart") { // Special case: Button
component = "button";
}
else {
component = "sensor";
}
/** /**
* homeassistant needs the MQTT discovery topic according to the following structure: * homeassistant needs the MQTT discovery topic according to the following structure:
* <discovery_prefix>/<component>/[<node_id>/]<object_id>/config * <discovery_prefix>/<component>/[<node_id>/]<object_id>/config
@@ -98,14 +87,21 @@ bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
* This means a maintopic "home/test/watermeter" is transformed to the discovery topic "homeassistant/sensor/watermeter/..." * This means a maintopic "home/test/watermeter" is transformed to the discovery topic "homeassistant/sensor/watermeter/..."
*/ */
std::string node_id = createNodeId(maintopic); std::string node_id = createNodeId(maintopic);
topicFull = "homeassistant/" + component + "/" + node_id + "/" + configTopic + "/config"; if (field == "problem") { // Special case: Binary sensor which is based on error topic
topicFull = "homeassistant/binary_sensor/" + node_id + "/" + configTopic + "/config";
}
else if (field == "flowstart") { // Special case: Button
topicFull = "homeassistant/button/" + node_id + "/" + configTopic + "/config";
}
else {
topicFull = "homeassistant/sensor/" + node_id + "/" + configTopic + "/config";
}
/* See https://www.home-assistant.io/docs/mqtt/discovery/ */ /* See https://www.home-assistant.io/docs/mqtt/discovery/ */
payload = string("{") + payload = string("{") +
"\"~\": \"" + maintopic + "\"," + "\"~\": \"" + maintopic + "\"," +
"\"unique_id\": \"" + maintopic + "-" + configTopic + "\"," + "\"unique_id\": \"" + maintopic + "-" + configTopic + "\"," +
"\"object_id\": \"" + maintopic + "_" + configTopic + "\"," + // Default entity ID; required for HA <= 2025.10 "\"object_id\": \"" + maintopic + "_" + configTopic + "\"," + // This used to generate the Entity ID
"\"default_entity_id\": \"" + component + "." + maintopic + "_" + configTopic + "\"," + // Default entity ID; required in HA >=2026.4
"\"name\": \"" + name + "\"," + "\"name\": \"" + name + "\"," +
"\"icon\": \"mdi:" + icon + "\","; "\"icon\": \"mdi:" + icon + "\",";

View File

@@ -635,7 +635,7 @@ void migrateConfiguration(void) {
CamZoom_value = false; CamZoom_value = false;
} }
else { else {
// ESP_LOGI(TAG, "splitted[1]: %s", splitted[1].c_str()); ESP_LOGE(TAG, "splitted[1]: %s", splitted[1].c_str());
CamZoom_value = alphanumericToBoolean(splitted[1]); CamZoom_value = alphanumericToBoolean(splitted[1]);
} }
CamZoom_found = true; CamZoom_found = true;
@@ -858,22 +858,22 @@ void migrateConfiguration(void) {
else { else {
configLines[CamZoom_lines] = ("CamZoom = false"); configLines[CamZoom_lines] = ("CamZoom = false");
} }
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Migrated Configfile line 'Zoom' to 'CamZoom'"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'Zoom' to 'CamZoom'");
migrated = true; migrated = true;
} }
if (CamZoomSize_lines > 0) { if (CamZoomSize_lines > 0) {
configLines[CamZoomSize_lines] = ("CamZoomSize = " + std::to_string(CamZoomSize_value)); configLines[CamZoomSize_lines] = ("CamZoomSize = " + std::to_string(CamZoomSize_value));
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Migrated Configfile line 'ZoomMode' to 'CamZoomSize'"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomMode' to 'CamZoomSize'");
migrated = true; migrated = true;
} }
if (CamZoomOffsetX_lines > 0) { if (CamZoomOffsetX_lines > 0) {
configLines[CamZoomOffsetX_lines] = ("CamZoomOffsetX = " + std::to_string(CamZoomOffsetX_value)); configLines[CamZoomOffsetX_lines] = ("CamZoomOffsetX = " + std::to_string(CamZoomOffsetX_value));
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Migrated Configfile line 'ZoomOffsetX' to 'CamZoomOffsetX'"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomOffsetX' to 'CamZoomOffsetX'");
migrated = true; migrated = true;
} }
if (CamZoomOffsetY_lines > 0) { if (CamZoomOffsetY_lines > 0) {
configLines[CamZoomOffsetY_lines] = ("CamZoomOffsetY = " + std::to_string(CamZoomOffsetY_value)); configLines[CamZoomOffsetY_lines] = ("CamZoomOffsetY = " + std::to_string(CamZoomOffsetY_value));
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Migrated Configfile line 'ZoomOffsetY' to 'CamZoomOffsetY'"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomOffsetY' to 'CamZoomOffsetY'");
migrated = true; migrated = true;
} }
} }

View File

@@ -158,7 +158,7 @@ CONFIG_CAMERA_CORE1=y
CONFIG_OV7670_SUPPORT=n CONFIG_OV7670_SUPPORT=n
CONFIG_OV7725_SUPPORT=n CONFIG_OV7725_SUPPORT=n
CONFIG_NT99141_SUPPORT=n CONFIG_NT99141_SUPPORT=n
CONFIG_OV3660_SUPPORT=y CONFIG_OV3660_SUPPORT=n
CONFIG_OV2640_SUPPORT=y CONFIG_OV2640_SUPPORT=y
CONFIG_OV5640_SUPPORT=y CONFIG_OV5640_SUPPORT=y
CONFIG_GC2145_SUPPORT=n CONFIG_GC2145_SUPPORT=n

View File

@@ -4,4 +4,4 @@ Default Value: `undefined`
Dedicated definition of the field for InfluxDB use for saving in the Influx database (e.g.: "watermeter/value"). Dedicated definition of the field for InfluxDB use for saving in the Influx database (e.g.: "watermeter/value").
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.Field`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.Field`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -4,4 +4,4 @@ Default Value: `undefined`
Field for InfluxDB v2 to use for saving. Field for InfluxDB v2 to use for saving.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.Field`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.Field`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -10,23 +10,19 @@ Alternatively you can set the parameter `DecimalShift` to `3` so the value is co
List of supported options: List of supported options:
- `other` - `other`
- `water_m3` (uses `m^3/h` as rate) - `water_m3` (uses `m^3/min` as rate)
- `water_l` (uses `l/h` as rate) **⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️** - `water_l` (uses `l/h` as rate, not officially supported by Homeassistant!)
- `water_gal` (uses `gal/h` as rate) **⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️** - `water_gal` (uses `gal/h` as rate, not officially supported by Homeassistant!)
- `water_gal_min` (uses `gal/min` as rate)
- `water_ft3` (uses `ft^3/min` as rate) - `water_ft3` (uses `ft^3/min` as rate)
- `gas_m3` (uses `m^3/h` as rate) - `gas_m3` (uses `m^3/min` as rate)
- `gas_ft3` (uses `ft^3/min` as rate) - `gas_ft3` (uses `ft^3/min` as rate)
- `energy_wh` (uses `W` as rate) - `energy_wh` (uses `W` as rate)
- `energy_kwh` (uses `KW` as rate) - `energy_kwh` (uses `KW` as rate)
- `energy_mwh` (uses `MW` as rate) - `energy_mwh` (uses `MW` as rate)
- `energy_gj` (uses `GJ/h` as rate) **⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️** - `energy_gj` (uses `GJ/h` as rate, not officially supported by Homeassistant!)
- `temperature_c` (uses `+C/min` as rate) - `temperature_c` (uses `+C/min` as rate)
- `temperature_f` (uses `°F/min` as rate) - `temperature_f` (uses `°F/min` as rate)
- `temperature_k` (uses `K/min` as rate) - `temperature_k` (uses `K/min` as rate)
!!! Note !!! Note
Not all options are supported by Homeassistant, see `SensorDeviceClass.VOLUME_FLOW_RATE` in [https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes](https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes)! Not all options are supported by Homeassistant, see `SensorDeviceClass.VOLUME_FLOW_RATE` in [https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes](https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes)!
!!! Warning
Since Homeassistant 2025.7, the unsupported options will no longer work, see change in Homeassistant: [Ensure MQTT sensor has a valid native unit of measurement](https://github.com/home-assistant/core/pull/146722).

View File

@@ -4,4 +4,4 @@ Default Value: `0`
The Idx number for the counter device. Can be obtained from the devices setup page on the Domoticz system. The Idx number for the counter device. Can be obtained from the devices setup page on the Domoticz system.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.DomoticzIDX`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.DomoticzIDX`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -7,4 +7,4 @@ Allow a meter to count backwards (decreasing values).
This is unusual (it means there is a negative rate) and not wanted in most cases! This is unusual (it means there is a negative rate) and not wanted in most cases!
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.AllowNegativeRates`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.AllowNegativeRates`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -9,4 +9,4 @@ See [here](../Watermeter-specific-analog---digit-transition) for details.
Range: `6.0` .. `9.9`. Range: `6.0` .. `9.9`.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.AnalogToDigitTransitionStart`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.AnalogToDigitTransitionStart`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -10,7 +10,7 @@ It is only applied to the last digit of the read value (See example below).
If the read value is within PreValue +/- Threshold, no further calculation is carried out and the Value/Prevalue remains at the old value. If the read value is within PreValue +/- Threshold, no further calculation is carried out and the Value/Prevalue remains at the old value.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.ChangeRateThreshold`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.ChangeRateThreshold`). `<NUMBER>` is the name of the number sequence defined in the ROI's.
## Example ## Example

View File

@@ -8,4 +8,4 @@ An additional consistency check.
It especially improves the zero crossing check between digits. It especially improves the zero crossing check between digits.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.CheckDigitIncreaseConsistency`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.CheckDigitIncreaseConsistency`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -5,4 +5,4 @@ Shift the decimal separator (positiv or negativ).
Eg. to move from `m³` to `liter` (`1 m³` equals `1000 liters`), you need to set it to `+3`. Eg. to move from `m³` to `liter` (`1 m³` equals `1000 liters`), you need to set it to `+3`.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.DecimalShift`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.DecimalShift`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -7,4 +7,4 @@ Use the decimal place of the last analog counter for increased accuracy.
This parameter is only supported on the `*-class*` and `*-const` models! See [Choosing-the-Model](../Choosing-the-Model) for details. This parameter is only supported on the `*-class*` and `*-const` models! See [Choosing-the-Model](../Choosing-the-Model) for details.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.ExtendedResolution`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.ExtendedResolution`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -6,4 +6,4 @@ This is only relevant for models which use `N`!
See [here](../Choosing-the-Model) for details. See [here](../Choosing-the-Model) for details.
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.IgnoreLeadingNaN`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.IgnoreLeadingNaN`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -5,4 +5,4 @@ Defines if the **Change Rate** is calculated as the difference between the last
as the difference normalized to the interval (`RateChange` = difference per minute). as the difference normalized to the interval (`RateChange` = difference per minute).
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.MaxRateType`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.MaxRateType`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -6,4 +6,4 @@ Maximum allowed change between two readings, if exceeded the last reading will b
If negative rate is disallowed and no maximum rate value is set, one false high reading will lead to a period of missing measurements until the measurement reaches the previous false high reading. E.g. if the counter is at `600,00` and it's read incorrectly as` 610,00`, all measurements will be skipped until the counter reaches `610,00`. Setting the MaxRateValue to `0,05` leads to a rejection of all readings with a difference `> 0,05`, in this case `610,00`. The rejection also applies to correct readings with a difference `> 0,05`! If negative rate is disallowed and no maximum rate value is set, one false high reading will lead to a period of missing measurements until the measurement reaches the previous false high reading. E.g. if the counter is at `600,00` and it's read incorrectly as` 610,00`, all measurements will be skipped until the counter reaches `610,00`. Setting the MaxRateValue to `0,05` leads to a rejection of all readings with a difference `> 0,05`, in this case `610,00`. The rejection also applies to correct readings with a difference `> 0,05`!
!!! Note !!! Note
If you edit the config file manually, you must prefix this parameter with `<NUMBER>` followed by a dot (eg. `main.MaxRateValue`). The reason is that this parameter is specific for each `<NUMBER>` (`<NUMBER>` is the name of the number sequence defined in the ROI's). This parameter must be prefixed with `<NUMBER>` followed by a dot (eg. `main.MaxRateValue`). `<NUMBER>` is the name of the number sequence defined in the ROI's.

View File

@@ -156,7 +156,6 @@ The following settings are only used for easier setup, they are <b>not</b> persi
<input type="checkbox" id="showall" name="showall" value="1" onclick="draw()" checked tabindex=9><label for="showall"> Show all ROIs</label><br> <input type="checkbox" id="showall" name="showall" value="1" onclick="draw()" checked tabindex=9><label for="showall"> Show all ROIs</label><br>
<input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label><br> <input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label><br>
<input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label><br> <input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label><br>
<input type="checkbox" id="drawFromCenter" name="drawFromCenter" value="1" onclick="changeDrawFromCenter()" checked tabindex=8><label for="drawFromCenter"> Draw from center</label><br>
<hr> <hr>
<table> <table>
@@ -197,7 +196,6 @@ The following settings are only used for easier setup, they are <b>not</b> persi
enhanceCon = false, enhanceCon = false,
lockAspectRatio = true, lockAspectRatio = true,
lockSizes = false, lockSizes = false,
drawFromCenter = true,
domainname = getDomainname(); domainname = getDomainname();
function doReboot() { function doReboot() {
@@ -321,10 +319,6 @@ The following settings are only used for easier setup, they are <b>not</b> persi
UpdateROIs(); UpdateROIs();
} }
function changeDrawFromCenter() {
drawFromCenter = document.getElementById("drawFromCenter").checked;
}
function changeCCW() { function changeCCW() {
var sel = document.getElementById("Numbers_value1"); var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text; var _number = sel.options[sel.selectedIndex].text;
@@ -806,10 +800,6 @@ The following settings are only used for easier setup, they are <b>not</b> persi
zw = getCoords(this) zw = getCoords(this)
rect.startX = e.pageX - zw.left; rect.startX = e.pageX - zw.left;
rect.startY = e.pageY - zw.top; rect.startY = e.pageY - zw.top;
if (drawFromCenter) {
rect.centerX = rect.startX;
rect.centerY = rect.startY;
}
document.getElementById("refx").value = rect.startX; document.getElementById("refx").value = rect.startX;
document.getElementById("refy").value = rect.startY; document.getElementById("refy").value = rect.startY;
drag = true; drag = true;
@@ -832,33 +822,16 @@ The following settings are only used for easier setup, they are <b>not</b> persi
} }
function mouseMove(e) { function mouseMove(e) {
const mouseX = e.pageX - zw.left;
const mouseY = e.pageY - zw.top;
if (drag) { if (drag) {
zw = getCoords(this) zw = getCoords(this)
if (drawFromCenter) {
if (lockAspectRatio) { if (lockAspectRatio) {
rect.h = Math.abs(mouseY - rect.centerY) * 2; rect.h = (e.pageY - zw.top) - rect.startY;
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]); rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
} else {
rect.w = Math.abs(mouseX - rect.centerX) * 2;
rect.h = Math.abs(mouseY - rect.centerY) * 2;
}
rect.startX = rect.centerX - rect.w / 2;
rect.startY = rect.centerY - rect.h / 2;
document.getElementById("refx").value = Math.round(rect.startX);
document.getElementById("refy").value = Math.round(rect.startY);
} else {
if (lockAspectRatio) {
rect.h = mouseY - rect.startY;
rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
} else {
rect.w = mouseX - rect.startX;
rect.h = mouseY - rect.startY;
} }
else {
rect.w = (e.pageX - zw.left) - rect.startX;
rect.h = (e.pageY - zw.top) - rect.startY;
} }
document.getElementById("refdx").value = rect.w; document.getElementById("refdx").value = rect.w;
document.getElementById("refdy").value = rect.h; document.getElementById("refdy").value = rect.h;
@@ -870,8 +843,8 @@ The following settings are only used for easier setup, they are <b>not</b> persi
var context = canvas.getContext('2d'); var context = canvas.getContext('2d');
zw = getCoords(this); zw = getCoords(this);
x = mouseX; x = e.pageX - zw.left;
y = mouseY; y = e.pageY - zw.top;
context.lineWidth = 2; context.lineWidth = 2;
context.strokeStyle = "#00FF00"; context.strokeStyle = "#00FF00";

View File

@@ -1183,16 +1183,15 @@
<select class="select_large" id="MQTT_MeterType_value1"> <!-- See https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes --> <select class="select_large" id="MQTT_MeterType_value1"> <!-- See https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes -->
<option value="other" selected>Other (no Units)</option> <option value="other" selected>Other (no Units)</option>
<option value="water_m3">Watermeter (Value: m³, Rate: m³/h)</option> <option value="water_m3">Watermeter (Value: m³, Rate: m³/h)</option>
<option value="water_l">Watermeter (Value: l, Rate: l/h) ⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️</option> <option value="water_l">Watermeter (Value: l, Rate: l/h) *Not officially supported by Homeassistant!*</option>
<option value="water_gal">Watermeter (Value: gal, Rate: gal/h) ⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️</option> <option value="water_gal">Watermeter (Value: gal, Rate: gal/h) *Not officially supported by Homeassistant!*</option>
<option value="water_gal_min">Watermeter (Value: gal, Rate: gal/min)</option>
<option value="water_ft3">Watermeter (Value: ft³, Rate: ft³/min)</option> <option value="water_ft3">Watermeter (Value: ft³, Rate: ft³/min)</option>
<option value="gas_m3">Gasmeter (Value: m³, Rate: m³/h)</option> <option value="gas_m3">Gasmeter (Value: m³, Rate: m³/h)</option>
<option value="gas_ft3">Gasmeter (Value: ft³, Rate: ft³/min)</option> <option value="gas_ft3">Gasmeter (Value: ft³, Rate: ft³/min)</option>
<option value="energy_wh">Energymeter (Value: Wh, Rate: W)</option> <option value="energy_wh">Energymeter (Value: Wh, Rate: W)</option>
<option value="energy_kwh">Energymeter (Value: kWh, Rate: kW)</option> <option value="energy_kwh">Energymeter (Value: kWh, Rate: kW)</option>
<option value="energy_mwh">Energymeter (Value: MWh, Rate: MW)</option> <option value="energy_mwh">Energymeter (Value: MWh, Rate: MW)</option>
<option value="energy_gj">Energymeter (Value: GJ, Rate: GJ/h) ⚠️ Not supported by Homeassistant 2025.7 and later! ⚠️</option> <option value="energy_gj">Energymeter (Value: GJ, Rate: GJ/h) *Not officially supported by Homeassistant!*</option>
<option value="temperature_c">Thermometer (Value: °C, Rate: °C/min)</option> <option value="temperature_c">Thermometer (Value: °C, Rate: °C/min)</option>
<option value="temperature_c">Thermometer (Value: °F, Rate: °F/min)</option> <option value="temperature_c">Thermometer (Value: °F, Rate: °F/min)</option>
<option value="temperature_c">Thermometer (Value: K, Rate: K/min)</option> <option value="temperature_c">Thermometer (Value: K, Rate: K/min)</option>
@@ -2677,19 +2676,7 @@ function saveTextAsFile() {
WriteConfigININew(); WriteConfigININew();
SaveConfigToServer(domainname); SaveConfigToServer(domainname);
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description') {
firework.launch('Configuration saved.', 'success', 2000);
}
else {
firework.launch('Configuration saved. It will get applied after the next reboot!<br><br>\n<a id="reboot_button" onclick="doReboot()">reboot now</a>', 'success', 5000); firework.launch('Configuration saved. It will get applied after the next reboot!<br><br>\n<a id="reboot_button" onclick="doReboot()">reboot now</a>', 'success', 5000);
}
}
else {
firework.launch('Configuration saved. It will get applied after the next reboot!<br><br>\n<a id="reboot_button" onclick="doReboot()">reboot now</a>', 'success', 5000);
}
if (changeCamValue == 1) { if (changeCamValue == 1) {
camSettingsSet(); camSettingsSet();
@@ -3344,7 +3331,7 @@ function openDescription() {
if(hash == 'description') { if(hash == 'description') {
document.getElementById("desc_details").open = true; document.getElementById("desc_details").open = true;
// document.getElementById("reboot").style.display = "none"; document.getElementById("reboot").style.display = "none";
document.getElementById("reboot_text").style.display = "none"; document.getElementById("reboot_text").style.display = "none";
} }
} }