mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-09 21:17:06 +03:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04f2f23931 | ||
|
|
c6cfe73e23 | ||
|
|
914cfceedf | ||
|
|
f1a836a407 | ||
|
|
55f78dce6d | ||
|
|
304b9e0c32 | ||
|
|
f4d086508d | ||
|
|
e23c89ae57 | ||
|
|
53a764abc8 | ||
|
|
4f07c88769 | ||
|
|
fa406d8989 | ||
|
|
1ca54f39f8 | ||
|
|
5867e90f69 | ||
|
|
e87b91f6eb | ||
|
|
4b52e61755 | ||
|
|
eb48212630 | ||
|
|
961662f483 | ||
|
|
306b1a75a5 | ||
|
|
7350864150 | ||
|
|
16d0758ea3 | ||
|
|
877a1b14e5 | ||
|
|
a122b37c81 | ||
|
|
ad137b329b | ||
|
|
85905a7045 | ||
|
|
9847f95c93 | ||
|
|
e9e13588f6 | ||
|
|
6c8a45f2dc | ||
|
|
e7d28f9bde | ||
|
|
33015351d6 | ||
|
|
0a461b2bd0 | ||
|
|
ecf1e78208 | ||
|
|
a8b9acf170 | ||
|
|
45a3138d28 | ||
|
|
7e997889aa | ||
|
|
6c51af7107 | ||
|
|
8be7beab9a | ||
|
|
62ec8d76c6 | ||
|
|
7a634797c4 |
36
.github/label-commenter-config.yml
vendored
Normal file
36
.github/label-commenter-config.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Reply Bot Configuration
|
||||
# See https://github.com/peaceiris/actions-label-commenter
|
||||
|
||||
labels:
|
||||
#######################################################################
|
||||
# Bot Response: Web Console
|
||||
#######################################################################
|
||||
- name: bot-reply Web Console
|
||||
labeled:
|
||||
issue:
|
||||
body: |
|
||||
You can use the [Web Console](https://jomjol.github.io/AI-on-the-edge-device/index.html) to get USB log from the device.
|
||||
The USB log contains more information about the startup and operation of the device than the normal Web UI log
|
||||
discussion:
|
||||
body: |
|
||||
You can use the [Web Console](https://jomjol.github.io/AI-on-the-edge-device/index.html) to get USB log from the device.
|
||||
The USB log contains more information about the startup and operation of the device than the normal Web UI log
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Bot Response: Rolling Build
|
||||
#######################################################################
|
||||
- name: bot-reply Rolling Build
|
||||
labeled:
|
||||
issue:
|
||||
body: |
|
||||
You can use the latest [Automatic Build](https://github.com/jomjol/AI-on-the-edge-device/actions/workflows/build.yaml?query=branch%3Arolling) of the the `rolling` branch. It might already contain a fix for your issue.
|
||||
Pick the most top passing entry (it has a green circle with a tick in it), then scoll down to the **Artifacts** and download the file named `update_*`.
|
||||
discussion:
|
||||
body: |
|
||||
You can use the latest [Automatic Build](https://github.com/jomjol/AI-on-the-edge-device/actions/workflows/build.yaml?query=branch%3Arolling) of the the `rolling` branch. It might already contain a fix for your issue.
|
||||
Pick the most top passing entry (it has a green circle with a tick in it), then scoll down to the **Artifacts** and download the file named `update_*`.
|
||||
|
||||
|
||||
|
||||
|
||||
91
.github/workflows/build.yaml
vendored
91
.github/workflows/build.yaml
vendored
@@ -54,60 +54,10 @@ jobs:
|
||||
key: ${{ github.run_number }}
|
||||
|
||||
|
||||
|
||||
#########################################################################################
|
||||
## Pack for old OTA (v1)
|
||||
## Pack for new OTA
|
||||
#########################################################################################
|
||||
pack-for-OTA-v1:
|
||||
# Old OTA concept
|
||||
# firmware__*.zip needs to be unpacked before attaching to the release!
|
||||
# The bin filename can contain versioning.
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Get generated files from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./code/.pio/build/esp32cam/firmware.bin
|
||||
./code/.pio/build/esp32cam/partitions.bin
|
||||
./code/.pio/build/esp32cam/bootloader.bin
|
||||
./sd-card/html/version.txt
|
||||
key: ${{ github.run_number }}
|
||||
|
||||
- name: Set Variables
|
||||
id: vars
|
||||
run: |
|
||||
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
echo "branch=$(echo ${{ github.ref_name }} | tr / __)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Rename firmware file to contain versioning (old ota)
|
||||
run: |
|
||||
mkdir -p ./dist_old_ota
|
||||
cp "./code/.pio/build/esp32cam/firmware.bin" "./dist_old_ota/firmware__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }}).bin"
|
||||
|
||||
- name: Upload Firmware artifact (old OTA concept)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
# name: "firmware__${{ github.ref_name }}__(${{ steps.vars.outputs.sha_short }})__(extract_before_upload__only_needed_for_migration_from_11.3.1)"
|
||||
name: "firmware__(extract_before_upload)__${{ steps.vars.outputs.branch }}__(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./dist_old_ota/*
|
||||
|
||||
- name: Upload Web interface artifact (old OTA concept)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "html__${{ steps.vars.outputs.branch }}__(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./sd-card/html/*
|
||||
|
||||
|
||||
|
||||
#########################################################################################
|
||||
## Pack for new OTA (v2)
|
||||
#########################################################################################
|
||||
pack-for-OTA-v2:
|
||||
pack-for-OTA:
|
||||
# New OTA concept
|
||||
# update__version.zip file with following content:
|
||||
# - /firmware.bin
|
||||
@@ -140,21 +90,9 @@ jobs:
|
||||
mkdir -p ./dist
|
||||
cp "./code/.pio/build/esp32cam/firmware.bin" "dist/firmware.bin"
|
||||
|
||||
# - name: Upload update.zip Artifact (Firmware only)
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: "update_firmware_only__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
# path: ./dist/*
|
||||
|
||||
- name: Add Web UI to dist
|
||||
run: cp -r ./sd-card/html ./dist/
|
||||
|
||||
# - name: Upload update.zip artifact (Firmware + Web UI)
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: "update_firmware+webinterface__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
# path: ./dist/*
|
||||
|
||||
- name: Add CNN to dist
|
||||
run: |
|
||||
mkdir ./dist/config/
|
||||
@@ -171,7 +109,7 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: dist
|
||||
key: ${{ github.run_number }}-pack-for-OTA-v2
|
||||
key: ${{ github.run_number }}-pack-for-OTA
|
||||
|
||||
|
||||
|
||||
@@ -235,7 +173,7 @@ jobs:
|
||||
#########################################################################################
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [pack-for-OTA-v2, pack-for-fresh-install]
|
||||
needs: [pack-for-OTA, pack-for-fresh-install]
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
@@ -245,22 +183,12 @@ jobs:
|
||||
run: |
|
||||
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get generated files from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./code/.pio/build/esp32cam/firmware.bin
|
||||
./code/.pio/build/esp32cam/partitions.bin
|
||||
./code/.pio/build/esp32cam/bootloader.bin
|
||||
./sd-card/html/version.txt
|
||||
key: ${{ github.run_number }}
|
||||
|
||||
# import the changes from
|
||||
- name: Get generated files from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: dist
|
||||
key: ${{ github.run_number }}-pack-for-OTA-v2
|
||||
key: ${{ github.run_number }}-pack-for-OTA
|
||||
|
||||
# import cached artifacts from pack-for-fresh-install
|
||||
- name: Get generated files from cache
|
||||
@@ -269,23 +197,16 @@ jobs:
|
||||
path: firmware
|
||||
key: ${{ github.run_number }}-pack-for-fresh-install
|
||||
|
||||
|
||||
|
||||
- name: Prepare artifacts for release
|
||||
run: |
|
||||
mkdir -p release
|
||||
mkdir -p dist
|
||||
# create a update.zip like "update__rolling"
|
||||
pwd
|
||||
ls ./dist
|
||||
cd ./dist
|
||||
zip -r ../release/update.zip .
|
||||
cd ../firmware
|
||||
zip -r ../release/initial_esp32_setup.zip .
|
||||
cd ../sd-card/html
|
||||
zip -r ../../firmware/html-from-11.3.1.zip .
|
||||
|
||||
|
||||
# extract the version used in next step
|
||||
- id: get_version
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
@@ -318,8 +239,6 @@ jobs:
|
||||
body: ${{ steps.extract-release-notes.outputs.release_notes }}
|
||||
files: |
|
||||
release/*
|
||||
firmware/firmware.bin
|
||||
firmware/html-from-11.3.1.zip
|
||||
|
||||
|
||||
# Commit&Push Changelog to master branch. Must be manually merged back to rolling
|
||||
|
||||
42
.github/workflows/reply-bot.yml
vendored
Normal file
42
.github/workflows/reply-bot.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# Reply Bot
|
||||
# It uses the configuration in .github/label-commenter-config.yml
|
||||
# See https://github.com/peaceiris/actions-label-commenter
|
||||
|
||||
name: Reply-Bot
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
discussion:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
discussions: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Remove 'Web Console' label again (issues only)
|
||||
if: github.event.label.name == 'bot-reply Web Console'
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
labels: 'bot-reply Web Console'
|
||||
|
||||
- name: Remove 'Rolling Build' label again (issues only)
|
||||
if: github.event.label.name == 'bot-reply Rolling Build'
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: 'remove-labels'
|
||||
labels: 'bot-reply Rolling Build'
|
||||
|
||||
- name: Write Response
|
||||
uses: peaceiris/actions-label-commenter@c2d00660c86f2b9ed0fb35b372c451558eba85b3
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
89
Changelog.md
89
Changelog.md
@@ -5,19 +5,26 @@
|
||||
**Home Assistant MQTT Discovery Support**
|
||||
|
||||
### Update Procedure
|
||||
:bangbang: **Make sure to read the instructions below carfully!**.
|
||||
|
||||
:bangbang: **Make sure to read the instructions below carfully!**
|
||||
|
||||
1. Backup your configuration (use the `System -> Backup/Restore` page)!
|
||||
1. You should update to `12.0.1` before you update to this release. All other migrations are untested.
|
||||
1. Upload and update the `update-*.zip` file from this release.
|
||||
1. Let it restart and check on the `System -> Info` page that the Firmware as well as the Web UI got updated. If only one got updated, redo the update. If it fails several times, you also can update the Firmware and the Web UI separately.
|
||||
1. Safe way:
|
||||
1. Update first the `firmware.bin` (extract from zip file) and do the Reboot
|
||||
1. Update with the full zip file (`update-*.zip`, ignore the version warning after the reboot)
|
||||
|
||||
1. Please go to `Settings -> Configuration` and address the changed parameters:
|
||||
* DataLogging (storing the values for data graph)
|
||||
* Debug (extended by different debug reporting levels)
|
||||
2. You should update to `12.0.1` before you update to this release. All other migrations are untested.
|
||||
|
||||
3. Upload and update the `update-*.zip` file from this release.
|
||||
|
||||
4. Let it restart and check on the `System -> Info` page that the Firmware as well as the Web UI got updated. If only one got updated, redo the update. If it fails several times, you also can update the Firmware and the Web UI separately.
|
||||
|
||||
5. Safe way:
|
||||
1. Update first the `firmware.bin` (extract it from one of the provided zip files) and do the Reboot
|
||||
2. Update with the full zip file (`update-*.zip`, ignore the version warning after the reboot)
|
||||
|
||||
6. Please go to `Settings -> Configuration` and address the changed parameters:
|
||||
- DataLogging (storing the values for data graph)
|
||||
- Debug (extended by different debug reporting levels)
|
||||
|
||||
7. Make sure it starts to do the digitalization (check the Error field on the overview page). If it does not start a round within a minute, restart the device.
|
||||
|
||||
If anything breaks you can try to enforce manual update as following:
|
||||
|
||||
@@ -28,7 +35,6 @@ If anything breaks you can try to enforce manual update as following:
|
||||
**Initial Setup:**
|
||||
1. Use the initial_esp32_setup.zip ( <https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation> ) as alternative to have a clean install.
|
||||
|
||||
|
||||
### Added
|
||||
|
||||
- Implementation of [Home Assistant MQTT Discovery](https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery)
|
||||
@@ -38,16 +44,16 @@ If anything breaks you can try to enforce manual update as following:
|
||||
- Format: csv - comma separated
|
||||
- Content: `time`, `name-of-number`, `raw-value`, `return-value`, `pre-value`, `change-rate`, `change-absolute`, `error-text`, `cnn-digital`, `cnn-analog`
|
||||
- Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller))
|
||||
|
||||
- Using new data logging (see above)
|
||||
- Possibility to choose different values and switch between different numbers (if present)
|
||||
|
||||
|
||||
Note: You need to activate data logging for this feature to work, see above!
|
||||
- PreValue is now contained in `/json` ([#1154](https://github.com/jomjol/AI-on-the-edge-device/issues/1154))
|
||||
- SD card info into the `System>Info` menu (thanks to [@Slider007]( https://github.com/Slider0007))
|
||||
- SD card info into the `System>Info` menu (thanks to [@Slider007](https://github.com/Slider0007))
|
||||
- Version check (Firmware vs. Web UI)
|
||||
- Various minor new features
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated tflite (`dig-cont_0600_s3.tflite`)
|
||||
@@ -55,23 +61,54 @@ If anything breaks you can try to enforce manual update as following:
|
||||
- Updated Espressif library to `espressif32@v5.2.0`
|
||||
- [#1176](https://github.com/jomjol/AI-on-the-edge-device/discussions/1176) accept minor negative values (-0.2) if extended resolution is enabled
|
||||
- [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter `AnalogDigitalTransitionStart`. It can setup very early and very late digit transition starts.
|
||||
- New version of `dig-class100` (v1.4.0): added images of heliowatt powermeter
|
||||
- New version of `dig-class100` (v1.4.0): added images of heliowatt powermeter
|
||||
- NEW v13.0.2: Update Tool "Logfile downloader and combiner" to handle the new csv file format.
|
||||
- NEW v13.0.2: MQTT: Added MQTT topic `status` (Digitalization Status), Timezone to MQTT topic `timestamp`.#
|
||||
- NEW v13.0.2: Logging: Disable heap logs by default, cleanup
|
||||
- NEW v13.0.7:
|
||||
- log NTP server name
|
||||
- Improved log messages
|
||||
- Various preparations for next release
|
||||
- **NEW v13.0.8**:
|
||||
- Continue booting on PSRAM issues, Web UI will show an error
|
||||
- Updated models
|
||||
- Various UI enhancements
|
||||
- Various internal improvements
|
||||
- Show uptime in log
|
||||
- Show uptime and round on overview page
|
||||
|
||||
### Fixed
|
||||
|
||||
- [#1116](https://github.com/jomjol/AI-on-the-edge-device/issues/1116) precision problem at setting prevalue
|
||||
- [#1119](https://github.com/jomjol/AI-on-the-edge-device/issues/1119) renamed `firmware.bin` not working in OTA
|
||||
- [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) changed postprocess for `analog->digit` (lowest digit processing)
|
||||
- [#1280](https://github.com/jomjol/AI-on-the-edge-device/issues/1280) check ROIs name for unsupported characters
|
||||
- [#983](https://github.com/jomjol/AI-on-the-edge-device/issues/983) old log files did not get deleted
|
||||
- Failed NTP time sync during startup gets now retried every round if needed
|
||||
- Whitespaces and `=` in MQTT and InfluxDB passwords
|
||||
- Various minor fixes and improvements
|
||||
- [#1280](https://github.com/jomjol/AI-on-the-edge-device/issues/1280) check ROIs name for unsupported characters
|
||||
- [#983](https://github.com/jomjol/AI-on-the-edge-device/issues/983) old log files did not get deleted
|
||||
- Failed NTP time sync during startup gets now retried every round if needed
|
||||
- Whitespaces and `=` in MQTT and InfluxDB passwords
|
||||
- Various minor fixes and improvements
|
||||
- NEW v13.0.2: Corrected Version comparison between firmware and Web UI.
|
||||
- NEW v13.0.3: Re-updated build environment to v5.2.0 (from accidental downgrad to v4.4.0)
|
||||
- NEW v13.0.4: Fix for reboot in case of MQTT not used
|
||||
- NEW v13.0.5: No reboot in case of missing NTP-connection
|
||||
- NEW v13.0.7:
|
||||
- Prevent autoreboot on cam framebuffer init error
|
||||
- Properly protect `wlan.ini` against deletion
|
||||
- Fixed various MQTT topic content issues
|
||||
- Fix Digit detected as 10 (https://github.com/jomjol/AI-on-the-edge-device/pull/1525)
|
||||
- Fix frozen time in datafile on error
|
||||
- Various minor fixes
|
||||
- **NEW v13.0.8**:
|
||||
- Fix Rate Problem ([#1578](https://github.com/jomjol/AI-on-the-edge-device/issues/1578), [#1572](https://github.com/jomjol/AI-on-the-edge-device/issues/1572))
|
||||
- Stabilized MQTT
|
||||
- Fixed redundant calls in OTA
|
||||
- Block REST API calls till resource is ready
|
||||
- Fixed number renaming ([#1635](https://github.com/jomjol/AI-on-the-edge-device/issues/1635))
|
||||
|
||||
### Removed
|
||||
|
||||
- n.a.
|
||||
|
||||
|
||||
## [12.0.1] 2022-09-29
|
||||
|
||||
Improve **u**ser e**x**perience
|
||||
@@ -741,7 +778,15 @@ External Illumination
|
||||
|
||||
- Initial Version
|
||||
|
||||
[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...HEAD
|
||||
[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/13.0.7...HEAD
|
||||
|
||||
[13.0.7]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.7
|
||||
|
||||
[13.0.5]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.5
|
||||
|
||||
[13.0.4]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.4
|
||||
|
||||
[13.0.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.1
|
||||
|
||||
[12.0.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/11.3.1...12.0.1
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@
|
||||
|
||||
|
||||
____
|
||||
#### #34 implement state and Roi for water leak detection
|
||||
for example see Roi on the next picture..
|
||||

|
||||
in case of position change between the measurments set this state to true, if there is no change set it back to false.
|
||||
In a defined time window this movement can lead into an alarm state / water leak..
|
||||
haveing this state in the mqtt broker can trigger functions like closing the ater pipe walve and so on...
|
||||
|
||||
|
||||
|
||||
#### #33 Implement MATTER protocoll
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ There are different ways to flash your ESP32:
|
||||
|
||||
See the [Wiki](https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation) for more information.
|
||||
|
||||
### Flashing the SD-Card
|
||||
The SD-Card must be flashed separately, see the [Wiki](https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation) for details.
|
||||
|
||||
## Casing
|
||||
|
||||
A 3d-printable housing can be found here:
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
#include "ClassLogFile.h"
|
||||
#include "configFile.h"
|
||||
#include "Helper.h"
|
||||
#include "interface_mqtt.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
static const char *TAG = "GPIO";
|
||||
QueueHandle_t gpio_queue_handle = NULL;
|
||||
|
||||
#define DEBUG_DETAIL_ON
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
GpioPin::GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType, uint8_t dutyResolution, std::string mqttTopic, bool httpEnable)
|
||||
{
|
||||
@@ -83,12 +85,14 @@ static void gpioHandlerTask(void *arg) {
|
||||
}
|
||||
|
||||
void GpioPin::gpioInterrupt(int value) {
|
||||
#ifdef ENABLE_MQTT
|
||||
if (_mqttTopic != "") {
|
||||
ESP_LOGD(TAG, "gpioInterrupt %s %d", _mqttTopic.c_str(), value);
|
||||
|
||||
MQTTPublish(_mqttTopic, value ? "true" : "false");
|
||||
currentState = value;
|
||||
MQTTPublish(_mqttTopic, value ? "true" : "false");
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
currentState = value;
|
||||
}
|
||||
|
||||
void GpioPin::init()
|
||||
@@ -114,10 +118,12 @@ void GpioPin::init()
|
||||
gpio_isr_handler_add(_gpio, gpio_isr_handler, (void*)&_gpio);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
if ((_mqttTopic != "") && ((_mode == GPIO_PIN_MODE_OUTPUT) || (_mode == GPIO_PIN_MODE_OUTPUT_PWM) || (_mode == GPIO_PIN_MODE_BUILT_IN_FLASH_LED))) {
|
||||
std::function<bool(std::string, char*, int)> f = std::bind(&GpioPin::handleMQTT, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
MQTTregisterSubscribeFunction(_mqttTopic, f);
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
}
|
||||
|
||||
bool GpioPin::getValue(std::string* errorText)
|
||||
@@ -138,9 +144,11 @@ void GpioPin::setValue(bool value, gpio_set_source setSource, std::string* error
|
||||
} else {
|
||||
gpio_set_level(_gpio, value);
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
if ((_mqttTopic != "") && (setSource != GPIO_SET_SOURCE_MQTT)) {
|
||||
MQTTPublish(_mqttTopic, value ? "true" : "false");
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +156,14 @@ void GpioPin::publishState() {
|
||||
int newState = gpio_get_level(_gpio);
|
||||
if (newState != currentState) {
|
||||
ESP_LOGD(TAG,"publish state of GPIO %d new state %d", _gpio, newState);
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTPublish(_mqttTopic, newState ? "true" : "false");
|
||||
#endif //ENABLE_MQTT
|
||||
currentState = newState;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
bool GpioPin::handleMQTT(std::string, char* data, int data_len) {
|
||||
ESP_LOGD(TAG, "GpioPin::handleMQTT data %.*s", data_len, data);
|
||||
|
||||
@@ -174,7 +185,7 @@ bool GpioPin::handleMQTT(std::string, char* data, int data_len) {
|
||||
|
||||
return (errorText == "");
|
||||
}
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
esp_err_t callHandleHttpRequest(httpd_req_t *req)
|
||||
{
|
||||
@@ -236,8 +247,10 @@ void GpioHandler::init()
|
||||
it->second->init();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
std::function<void()> f = std::bind(&GpioHandler::handleMQTTconnect, this);
|
||||
MQTTregisterConnectFunction("gpio-handler", f);
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
if (xHandleTaskGpio == NULL) {
|
||||
gpio_queue_handle = xQueueCreate(10,sizeof(GpioResult));
|
||||
@@ -261,7 +274,7 @@ void GpioHandler::taskHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
void GpioHandler::handleMQTTconnect()
|
||||
{
|
||||
if (gpioMap != NULL) {
|
||||
@@ -271,9 +284,12 @@ void GpioHandler::handleMQTTconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
void GpioHandler::deinit() {
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTunregisterConnectFunction("gpio-handler");
|
||||
#endif //ENABLE_MQTT
|
||||
clear();
|
||||
if (xHandleTaskGpio != NULL) {
|
||||
vTaskDelete(xHandleTaskGpio);
|
||||
@@ -316,6 +332,7 @@ bool GpioHandler::readConfig()
|
||||
|
||||
// ESP_LOGD(TAG, "readConfig - Start 3");
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
// std::string mainTopicMQTT = "";
|
||||
std::string mainTopicMQTT = GetMQTTMainTopic();
|
||||
if (mainTopicMQTT.length() > 0)
|
||||
@@ -323,7 +340,7 @@ bool GpioHandler::readConfig()
|
||||
mainTopicMQTT = mainTopicMQTT + "/GPIO";
|
||||
ESP_LOGD(TAG, "MAINTOPICMQTT found");
|
||||
}
|
||||
|
||||
#endif // ENABLE_MQTT
|
||||
bool registerISR = false;
|
||||
while (configFile.getNextLine(&line, disabledLine, eof) && !configFile.isNewParagraph(line))
|
||||
{
|
||||
@@ -345,7 +362,9 @@ bool GpioHandler::readConfig()
|
||||
gpio_pin_mode_t pinMode = resolvePinMode(toLower(zerlegt[1]));
|
||||
gpio_int_type_t intType = resolveIntType(toLower(zerlegt[2]));
|
||||
uint16_t dutyResolution = (uint8_t)atoi(zerlegt[3].c_str());
|
||||
#ifdef ENABLE_MQTT
|
||||
bool mqttEnabled = toLower(zerlegt[4]) == "true";
|
||||
#endif // ENABLE_MQTT
|
||||
bool httpEnabled = toLower(zerlegt[5]) == "true";
|
||||
char gpioName[100];
|
||||
if (zerlegt.size() >= 7) {
|
||||
@@ -353,7 +372,11 @@ bool GpioHandler::readConfig()
|
||||
} else {
|
||||
sprintf(gpioName, "GPIO%d", gpioNr);
|
||||
}
|
||||
#ifdef ENABLE_MQTT
|
||||
std::string mqttTopic = mqttEnabled ? (mainTopicMQTT + "/" + gpioName) : "";
|
||||
#else // ENABLE_MQTT
|
||||
std::string mqttTopic = "";
|
||||
#endif // ENABLE_MQTT
|
||||
GpioPin* gpioPin = new GpioPin(gpioNr, gpioName, pinMode, intType,dutyResolution, mqttTopic, httpEnabled);
|
||||
(*gpioMap)[gpioNr] = gpioPin;
|
||||
|
||||
@@ -682,3 +705,4 @@ GpioHandler* gpio_handler_get()
|
||||
{
|
||||
return gpioHandler;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,9 @@ public:
|
||||
void init();
|
||||
bool getValue(std::string* errorText);
|
||||
void setValue(bool value, gpio_set_source setSource, std::string* errorText);
|
||||
#ifdef ENABLE_MQTT
|
||||
bool handleMQTT(std::string, char* data, int data_len);
|
||||
#endif //ENABLE_MQTT
|
||||
void publishState();
|
||||
void gpioInterrupt(int value);
|
||||
gpio_int_type_t getInterruptType() { return _interruptType; }
|
||||
@@ -77,7 +79,9 @@ public:
|
||||
void gpioInterrupt(GpioResult* gpioResult);
|
||||
void flashLightEnable(bool value);
|
||||
bool isEnabled() { return _isEnabled; }
|
||||
#ifdef ENABLE_MQTT
|
||||
void handleMQTTconnect();
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
private:
|
||||
std::string _configFile;
|
||||
@@ -109,4 +113,5 @@ GpioHandler* gpio_handler_get();
|
||||
|
||||
|
||||
|
||||
#endif //SERVER_GPIO_H
|
||||
#endif //SERVER_GPIO_H
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -281,7 +282,6 @@ void CCamera::EnableAutoExposure(int flashdauer)
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
|
||||
{
|
||||
string ftype;
|
||||
@@ -425,7 +425,7 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
|
||||
nm = FormatFileName(nm);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Save Camera to : %s", nm.c_str());
|
||||
ESP_LOGD(TAG, "Save Camera to: %s", nm.c_str());
|
||||
#endif
|
||||
|
||||
ftype = toUpper(getFileType(nm));
|
||||
@@ -543,6 +543,7 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void CCamera::LightOnOff(bool status)
|
||||
{
|
||||
GpioHandler* gpioHandler = gpio_handler_get();
|
||||
@@ -578,6 +579,7 @@ void CCamera::LightOnOff(bool status)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCamera::LEDOnOff(bool status)
|
||||
{
|
||||
// Init the GPIO
|
||||
@@ -638,6 +640,7 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
framesize_t CCamera::TextToFramesize(const char * _size)
|
||||
{
|
||||
if (strcmp(_size, "QVGA") == 0)
|
||||
@@ -669,21 +672,25 @@ CCamera::CCamera()
|
||||
ledc_init();
|
||||
}
|
||||
|
||||
|
||||
esp_err_t CCamera::InitCam()
|
||||
{
|
||||
ESP_LOGD(TAG, "Init Camera");
|
||||
ActualQuality = camera_config.jpeg_quality;
|
||||
ActualResolution = camera_config.frame_size;
|
||||
//initialize the camera
|
||||
esp_camera_deinit(); // De-init in case it was already initialized
|
||||
esp_err_t err = esp_camera_init(&camera_config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Camera Init Failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
CameraInitSuccessful = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void CCamera::SetLEDIntensity(float _intrel)
|
||||
{
|
||||
_intrel = min(_intrel, (float) 100);
|
||||
@@ -693,3 +700,9 @@ void CCamera::SetLEDIntensity(float _intrel)
|
||||
ESP_LOGD(TAG, "Set led_intensity to %d of 8191", led_intensity);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CCamera::getCameraInitSuccessful()
|
||||
{
|
||||
return CameraInitSuccessful;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ class CCamera {
|
||||
int led_intensity = 4095;
|
||||
|
||||
void ledc_init(void);
|
||||
bool CameraInitSuccessful = false;
|
||||
|
||||
public:
|
||||
int image_height, image_width;
|
||||
@@ -42,6 +43,7 @@ class CCamera {
|
||||
void SetLEDIntensity(float _intrel);
|
||||
|
||||
void EnableAutoExposure(int flashdauer);
|
||||
bool getCameraInitSuccessful();
|
||||
|
||||
|
||||
framesize_t TextToFramesize(const char * text);
|
||||
|
||||
@@ -17,7 +17,8 @@ char scratch2[SCRATCH_BUFSIZE2];
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
void PowerResetCamera(){
|
||||
void PowerResetCamera()
|
||||
{
|
||||
ESP_LOGD(TAG, "Resetting camera by power down line");
|
||||
gpio_config_t conf;
|
||||
conf.intr_type = GPIO_INTR_DISABLE;
|
||||
@@ -37,182 +38,223 @@ void PowerResetCamera(){
|
||||
|
||||
esp_err_t handler_lightOn(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
Camera.LightOnOff(true);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
Camera.LightOnOff(true);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera Light On API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_lightOff(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
||||
#endif
|
||||
Camera.LightOnOff(false);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
#endif
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
Camera.LightOnOff(false);
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera Light Off API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||
#endif
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
esp_err_t ressult;
|
||||
ressult = Camera.CaptureToHTTP(req);
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera Capture API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture_with_ligth(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
|
||||
#endif
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
int delay = 2500;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
|
||||
#endif
|
||||
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
int delay = 2500;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
Camera.SetQualitySize(quality, res);
|
||||
Camera.LightOnOff(true);
|
||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
esp_err_t ressult;
|
||||
ressult = Camera.CaptureToHTTP(req);
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToHTTP(req);
|
||||
|
||||
Camera.LightOnOff(false);
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera Capture + flashlight API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||
#endif
|
||||
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
int delay = 0;
|
||||
char filename[100];
|
||||
std::string fn = "/sdcard/";
|
||||
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
if (Camera.getCameraInitSuccessful())
|
||||
{
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
||||
char _query[100];
|
||||
char _delay[10];
|
||||
int delay = 0;
|
||||
char filename[100];
|
||||
std::string fn = "/sdcard/";
|
||||
|
||||
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
fn.append(filename);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
||||
#endif
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
||||
{
|
||||
fn.append(filename);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fn.append("noname.jpg");
|
||||
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
fn.append("noname.jpg");
|
||||
|
||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||
#endif
|
||||
delay = atoi(_delay);
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
}
|
||||
esp_err_t result;
|
||||
result = Camera.CaptureToFile(fn, delay);
|
||||
|
||||
const char* resp_str = (const char*) fn.c_str();
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
fn.append("noname.jpg");
|
||||
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
esp_err_t ressult;
|
||||
ressult = Camera.CaptureToFile(fn, delay);
|
||||
|
||||
const char* resp_str = (const char*) fn.c_str();
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||
#endif
|
||||
|
||||
return ressult;
|
||||
};
|
||||
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera Capture + save API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server)
|
||||
|
||||
@@ -39,7 +39,9 @@ extern "C" {
|
||||
#include "server_tflite.h"
|
||||
|
||||
#include "server_help.h"
|
||||
#include "interface_mqtt.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
#include "server_GPIO.h"
|
||||
|
||||
#include "Helper.h"
|
||||
@@ -219,9 +221,9 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
|
||||
ESP_LOGD(TAG, "entrypath: <%s>", entrypath);
|
||||
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", dirpath);
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat dir: " + std::string(dirpath) + "!");
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Directory does not exist");
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -278,11 +280,11 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
|
||||
strlcpy(entrypath + dirpath_len, entry->d_name, sizeof(entrypath) - dirpath_len);
|
||||
ESP_LOGD(TAG, "Entrypath: %s", entrypath);
|
||||
if (stat(entrypath, &entry_stat) == -1) {
|
||||
ESP_LOGE(TAG, "Failed to stat %s : %s", entrytype, entry->d_name);
|
||||
ESP_LOGE(TAG, "Failed to stat %s: %s", entrytype, entry->d_name);
|
||||
continue;
|
||||
}
|
||||
sprintf(entrysize, "%ld", entry_stat.st_size);
|
||||
ESP_LOGI(TAG, "Found %s : %s (%s bytes)", entrytype, entry->d_name, entrysize);
|
||||
ESP_LOGI(TAG, "Found %s: %s (%s bytes)", entrytype, entry->d_name, entrysize);
|
||||
|
||||
/* Send chunk of HTML file containing table entries with file name and size */
|
||||
httpd_resp_sendstr_chunk(req, "<tr><td><a href=\"");
|
||||
@@ -361,15 +363,15 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
|
||||
|
||||
fd = OpenFileAndWait(currentfilename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: " + std::string(filepath) +"!");
|
||||
/* Respond with 404 Error */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
// ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", &filename, file_stat.st_size);
|
||||
// ESP_LOGI(TAG, "Sending file: %s (%ld bytes)...", &filename, file_stat.st_size);
|
||||
set_content_type_from_file(req, filename);
|
||||
|
||||
if (!send_full_file) { // Send only last part of file
|
||||
@@ -446,15 +448,15 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
|
||||
|
||||
fd = OpenFileAndWait(currentfilename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: " + std::string(filepath) +"!");
|
||||
/* Respond with 404 Error */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
// ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", &filename, file_stat.st_size);
|
||||
// ESP_LOGI(TAG, "Sending file: %s (%ld bytes)...", &filename, file_stat.st_size);
|
||||
set_content_type_from_file(req, filename);
|
||||
|
||||
if (!send_full_file) { // Send only last part of file
|
||||
@@ -506,7 +508,7 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
|
||||
|
||||
/* Close file after sending complete */
|
||||
fclose(fd);
|
||||
ESP_LOGI(TAG, "File sending complete");
|
||||
ESP_LOGD(TAG, "File sending complete");
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
@@ -534,8 +536,8 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
||||
|
||||
if (!filename) {
|
||||
ESP_LOGE(TAG, "Filename is too long");
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
/* Respond with 414 Error */
|
||||
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -566,23 +568,23 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
||||
|
||||
/* If file not present on SPIFFS check if URI
|
||||
* corresponds to one of the hardcoded paths */
|
||||
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat file: " + std::string(filepath) + "!");
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
fd = OpenFileAndWait(filepath, "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: " + std::string(filepath) +"!");
|
||||
/* Respond with 404 Error */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename, file_stat.st_size);
|
||||
ESP_LOGD(TAG, "Sending file: %s (%ld bytes)...", filename, file_stat.st_size);
|
||||
set_content_type_from_file(req, filename);
|
||||
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
@@ -599,7 +601,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
||||
/* Abort sending file */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file");
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -608,7 +610,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
||||
|
||||
/* Close file after sending complete */
|
||||
fclose(fd);
|
||||
ESP_LOGI(TAG, "File successfully sent");
|
||||
ESP_LOGD(TAG, "File successfully sent");
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
@@ -628,20 +630,21 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||
const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
|
||||
req->uri + sizeof("/upload") - 1, sizeof(filepath));
|
||||
if (!filename) {
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
/* Respond with 413 Error */
|
||||
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Filename cannot have a trailing '/' */
|
||||
if (filename[strlen(filename) - 1] == '/') {
|
||||
ESP_LOGE(TAG, "Invalid filename : %s", filename);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
|
||||
ESP_LOGE(TAG, "Invalid filename: %s", filename);
|
||||
/* Respond with 400 Bad Request */
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (stat(filepath, &file_stat) == 0) {
|
||||
ESP_LOGE(TAG, "File already exists : %s", filepath);
|
||||
ESP_LOGE(TAG, "File already exists: %s", filepath);
|
||||
/* Respond with 400 Bad Request */
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File already exists");
|
||||
return ESP_FAIL;
|
||||
@@ -649,7 +652,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||
|
||||
/* File cannot be larger than a limit */
|
||||
if (req->content_len > MAX_FILE_SIZE) {
|
||||
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
|
||||
ESP_LOGE(TAG, "File too large: %d bytes", req->content_len);
|
||||
/* Respond with 400 Bad Request */
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST,
|
||||
"File size must be less than "
|
||||
@@ -661,13 +664,13 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||
|
||||
fd = OpenFileAndWait(filepath, "w");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
|
||||
ESP_LOGE(TAG, "Failed to create file: %s", filepath);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create file");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Receiving file : %s...", filename);
|
||||
ESP_LOGI(TAG, "Receiving file: %s...", filename);
|
||||
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
char *buf = ((struct file_server_data *)req->user_ctx)->scratch;
|
||||
@@ -679,7 +682,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
|
||||
|
||||
while (remaining > 0) {
|
||||
|
||||
ESP_LOGI(TAG, "Remaining size : %d", remaining);
|
||||
ESP_LOGI(TAG, "Remaining size: %d", remaining);
|
||||
/* Receive the file part by part into a buffer */
|
||||
if ((received = httpd_req_recv(req, buf, MIN(remaining, SCRATCH_BUFSIZE))) <= 0) {
|
||||
if (received == HTTPD_SOCK_ERR_TIMEOUT) {
|
||||
@@ -790,8 +793,8 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
|
||||
const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
|
||||
req->uri + sizeof("/delete") - 1, sizeof(filepath));
|
||||
if (!filename) {
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
/* Respond with 414 Error */
|
||||
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
zw = std::string(filename);
|
||||
@@ -824,19 +827,26 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
|
||||
|
||||
/* Filename cannot have a trailing '/' */
|
||||
if (filename[strlen(filename) - 1] == '/') {
|
||||
ESP_LOGE(TAG, "Invalid filename : %s", filename);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
|
||||
ESP_LOGE(TAG, "Invalid filename: %s", filename);
|
||||
/* Respond with 400 Bad Request */
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (strcmp(filename, "wlan.ini") == 0) {
|
||||
ESP_LOGE(TAG, "Trying to delete protected file : %s", filename);
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Not allowed to delete wlan.ini");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (stat(filepath, &file_stat) == -1) {
|
||||
ESP_LOGE(TAG, "File does not exist : %s", filename);
|
||||
ESP_LOGE(TAG, "File does not exist: %s", filename);
|
||||
/* Respond with 400 Bad Request */
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Deleting file : %s", filename);
|
||||
ESP_LOGI(TAG, "Deleting file: %s", filename);
|
||||
/* Delete file */
|
||||
unlink(filepath);
|
||||
|
||||
@@ -878,7 +888,7 @@ void delete_all_in_directory(std::string _directory)
|
||||
std::string filename;
|
||||
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", _directory.c_str());
|
||||
ESP_LOGE(TAG, "Failed to stat dir: %s", _directory.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -887,7 +897,7 @@ void delete_all_in_directory(std::string _directory)
|
||||
if (!(entry->d_type == DT_DIR)){
|
||||
if (strcmp("wlan.ini", entry->d_name) != 0){ // auf wlan.ini soll nicht zugegriffen werden !!!
|
||||
filename = _directory + "/" + std::string(entry->d_name);
|
||||
ESP_LOGI(TAG, "Deleting file : %s", filename.c_str());
|
||||
ESP_LOGI(TAG, "Deleting file: %s", filename.c_str());
|
||||
/* Delete file */
|
||||
unlink(filename.c_str());
|
||||
}
|
||||
@@ -925,7 +935,11 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
|
||||
|
||||
// Get and print information about each file in the archive.
|
||||
int numberoffiles = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
for (sort_iter = 0; sort_iter < 2; sort_iter++)
|
||||
ESP_LOGI(TAG, "Numbers of files to be extrated: %d", numberoffiles);
|
||||
|
||||
|
||||
sort_iter = 0;
|
||||
// for (sort_iter = 0; sort_iter < 2; sort_iter++)
|
||||
{
|
||||
memset(&zip_archive, 0, sizeof(zip_archive));
|
||||
status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
|
||||
|
||||
@@ -36,13 +36,13 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
|
||||
{
|
||||
FILE *fd = OpenFileAndWait(filename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filename.c_str());
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||
ESP_LOGE(TAG, "Failed to read existing file: %s", filename.c_str());
|
||||
/* Respond with 404 Error */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str());
|
||||
ESP_LOGD(TAG, "Sending file: %s ...", filename.c_str());
|
||||
// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
set_content_type_from_file(req, filename.c_str());
|
||||
|
||||
@@ -69,7 +69,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
|
||||
|
||||
/* Close file after sending complete */
|
||||
fclose(fd);
|
||||
ESP_LOGI(TAG, "File sending complete");
|
||||
ESP_LOGD(TAG, "File sending complete");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#include "server_tflite.h"
|
||||
#include "server_file.h"
|
||||
#include "server_GPIO.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
@@ -55,6 +58,18 @@ esp_err_t handler_reboot(httpd_req_t *req);
|
||||
std::string _file_name_update;
|
||||
|
||||
|
||||
|
||||
static void infinite_loop(void)
|
||||
{
|
||||
int i = 0;
|
||||
ESP_LOGI(TAG, "When a new firmware is available on the server, press the reset button to download it");
|
||||
while(1) {
|
||||
ESP_LOGI(TAG, "Waiting for a new firmware... %d", ++i);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void task_do_Update_ZIP(void *pvParameter)
|
||||
{
|
||||
std::string filetype = toUpper(getFileType(_file_name_update));
|
||||
@@ -107,26 +122,14 @@ void CheckUpdate()
|
||||
BaseType_t xReturned;
|
||||
int _i = configMINIMAL_STACK_SIZE;
|
||||
xReturned = xTaskCreate(&task_do_Update_ZIP, "task_do_Update_ZIP", configMINIMAL_STACK_SIZE * 35, NULL, tskIDLE_PRIORITY+1, NULL);
|
||||
TickType_t xDelay;
|
||||
xDelay = 2000000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "Wait for Update to be finished: sleep for: %ldms", (long) xDelay);
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void infinite_loop(void)
|
||||
{
|
||||
int i = 0;
|
||||
ESP_LOGI(TAG, "When a new firmware is available on the server, press the reset button to download it");
|
||||
while(1) {
|
||||
ESP_LOGI(TAG, "Waiting for a new firmware... %d", ++i);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
while(1) { // wait until reboot within task_do_Update_ZIP
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static bool ota_update_task(std::string fn)
|
||||
{
|
||||
esp_err_t err;
|
||||
@@ -530,7 +533,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
int _result = stat(fn.c_str(), &file_stat);
|
||||
ESP_LOGD(TAG, "Ergebnis %d\n", _result);
|
||||
if (_result == 0) {
|
||||
ESP_LOGD(TAG, "Deleting file : %s", fn.c_str());
|
||||
ESP_LOGD(TAG, "Deleting file: %s", fn.c_str());
|
||||
/* Delete file */
|
||||
unlink(fn.c_str());
|
||||
}
|
||||
@@ -601,6 +604,9 @@ void doReboot(){
|
||||
xTaskCreate(&task_reboot, "reboot", configMINIMAL_STACK_SIZE * 64, NULL, 10, NULL);
|
||||
// KillTFliteTasks(); // kills itself
|
||||
gpio_handler_destroy();
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTdestroy_client();
|
||||
#endif //ENABLE_MQTT
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
hard_restart();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "FLOW CLASS";
|
||||
static const char *TAG = "CLASS";
|
||||
|
||||
|
||||
void ClassFlow::SetInitialParameter(void)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
|
||||
static const char *TAG = "FLOW ALIGN";
|
||||
static const char *TAG = "ALIGN";
|
||||
|
||||
bool AlignmentExtendedDebugging = true;
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
|
||||
result = (ergebnis_vorkomma + 1) % 10;
|
||||
else
|
||||
// Akt. digit und Vorgänger haben Nulldurchgang
|
||||
result = ergebnis_vorkomma;
|
||||
result = ergebnis_vorkomma % 10;
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "ZeigerEvalHybridNeu - KEIN Analoger Vorgänger, Nulldurchgang hat stattgefunden = " + std::to_string(result) +
|
||||
" zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe));
|
||||
return result;
|
||||
@@ -191,7 +191,7 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
|
||||
// Vorlauf (else - Zweig) passiert nicht bereits ab 9.
|
||||
if (DigitalUebergangsbereichVorlauf>=zahl_vorgaenger || ergebnis_nachkomma >= 4)
|
||||
// aktuelles digit hat genauso wie das Vorgängerdigit noch keinen Nulldurchgang.
|
||||
result = ergebnis_vorkomma;
|
||||
result = ergebnis_vorkomma % 10;
|
||||
else
|
||||
// aktuelles digit läuft dem kleineren digit (9.x) vor. Also schon >=x.0 während das vorherige Digit noch
|
||||
// keinen Nulldurchgang hat. Daher wird um 1 reduziert.
|
||||
@@ -211,7 +211,8 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vor
|
||||
bool roundedUp = false;
|
||||
|
||||
// Innerhalb der digitalen Unschaefe
|
||||
if (ergebnis_nachkomma >= (10-DigitalUnschaerfe * 10)) { // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
|
||||
if ((ergebnis_nachkomma >= (10-DigitalUnschaerfe * 10)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
|
||||
|| (eval_vorgaenger <= 4 && ergebnis_nachkomma>=6)) { // oder digit läuft nach (analog =0..4, digit >=6)
|
||||
result = (int) (round(zahl) + 10) % 10;
|
||||
roundedUp = true;
|
||||
// vor/nachkomma neu berechnen, da wir anhand der Unschaefe die Zahl anpassen.
|
||||
@@ -230,11 +231,7 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vor
|
||||
// Kein Nulldurchgang hat stattgefunden.
|
||||
// Nur eval_vorgaenger verwendet, da ziffer_vorgaenger hier falsch sein könnte.
|
||||
// ziffer_vorgaenger<=0.1 & eval_vorgaenger=9 entspricht analog wurde zurückgesetzt wegen vorhergehender analog, die noch nicht auf 0 sind.
|
||||
if ((eval_vorgaenger>=6 && (ziffer_vorgaenger>analogDigitalTransitionStart || ziffer_vorgaenger<=0.2) && roundedUp)
|
||||
// digit läuft dem Analog vor. Darf aber erst passieren, wenn
|
||||
// digit wirklich schnon los läuft, deshalb 9
|
||||
|| (eval_vorgaenger>9 && ziffer_vorgaenger>analogDigitalTransitionStart && ergebnis_nachkomma<=1))
|
||||
|
||||
if ((eval_vorgaenger>=6 && (ziffer_vorgaenger>analogDigitalTransitionStart || ziffer_vorgaenger<=0.2) && roundedUp))
|
||||
{
|
||||
result = ((ergebnis_vorkomma+10) - 1) % 10;
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "ZeigerEvalAnalogToDigitNeu - Nulldurchgang noch nicht stattgefunden = " + std::to_string(result) +
|
||||
@@ -623,19 +620,22 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
tflite->MakeAllocate();
|
||||
|
||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
||||
for (int n = 0; n < GENERAL.size(); ++n) // For each NUMBER
|
||||
{
|
||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Processing Number '" + GENERAL[n]->name + "'");
|
||||
for (int roi = 0; roi < GENERAL[n]->ROI.size(); ++roi) // For each ROI
|
||||
{
|
||||
ESP_LOGD(TAG, "General %d - TfLite", i);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "ROI #" + std::to_string(roi) + " - TfLite");
|
||||
//ESP_LOGD(TAG, "General %d - TfLite", i);
|
||||
|
||||
switch (CNNType) {
|
||||
case Analogue:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: Analogue");
|
||||
{
|
||||
float f1, f2;
|
||||
f1 = 0; f2 = 0;
|
||||
|
||||
tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
tflite->LoadInputImageBasis(GENERAL[n]->ROI[roi]->image);
|
||||
tflite->Invoke();
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Nach Invoke");
|
||||
|
||||
@@ -643,39 +643,41 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
f2 = tflite->GetOutputValue(1);
|
||||
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
|
||||
|
||||
if(GENERAL[_ana]->ROI[i]->CCW)
|
||||
GENERAL[_ana]->ROI[i]->result_float = 10 - (result * 10);
|
||||
if(GENERAL[n]->ROI[roi]->CCW)
|
||||
GENERAL[n]->ROI[roi]->result_float = 10 - (result * 10);
|
||||
else
|
||||
GENERAL[_ana]->ROI[i]->result_float = result * 10;
|
||||
GENERAL[n]->ROI[roi]->result_float = result * 10;
|
||||
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
||||
if (isLogImage)
|
||||
LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
LogImage(logPath, GENERAL[n]->ROI[roi]->name, &GENERAL[n]->ROI[roi]->result_float, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
} break;
|
||||
|
||||
case Digital:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: Digital");
|
||||
{
|
||||
GENERAL[_ana]->ROI[i]->result_klasse = 0;
|
||||
GENERAL[_ana]->ROI[i]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
ESP_LOGD(TAG, "Result General(Digit)%i: %d", i, GENERAL[_ana]->ROI[i]->result_klasse);
|
||||
GENERAL[n]->ROI[roi]->result_klasse = 0;
|
||||
GENERAL[n]->ROI[roi]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[n]->ROI[roi]->image);
|
||||
ESP_LOGD(TAG, "Result General(Digit)%i: %d", roi, GENERAL[n]->ROI[roi]->result_klasse);
|
||||
|
||||
if (isLogImage)
|
||||
{
|
||||
string _imagename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name;
|
||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||
if (isLogImageSelect)
|
||||
{
|
||||
if (LogImageSelect.find(GENERAL[_ana]->ROI[i]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogImage(logPath, _imagename, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
/*
|
||||
case DigitalHyprid:
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: DigitalHyprid");
|
||||
int _num, _nachkomma;
|
||||
|
||||
tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
@@ -716,6 +718,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
/*
|
||||
case DigitalHyprid10:
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: DigitalHyprid10");
|
||||
int _num, _nachkomma;
|
||||
|
||||
tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
@@ -753,12 +756,13 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
|
||||
case DoubleHyprid10:
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: DoubleHyprid10");
|
||||
int _num, _numplus, _numminus;
|
||||
float _val, _valplus, _valminus;
|
||||
float _fit;
|
||||
float _result_save_file;
|
||||
|
||||
tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
tflite->LoadInputImageBasis(GENERAL[n]->ROI[roi]->image);
|
||||
tflite->Invoke();
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Nach Invoke");
|
||||
|
||||
@@ -798,7 +802,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
|
||||
if (_fit < CNNGoodThreshold)
|
||||
{
|
||||
GENERAL[_ana]->ROI[i]->isReject = true;
|
||||
GENERAL[n]->ROI[roi]->isReject = true;
|
||||
result = -1;
|
||||
_result_save_file+= 100; // Für den Fall, dass fit nicht ausreichend, soll trotzdem das Ergebnis mit "-10x.y" abgespeichert werden.
|
||||
string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + "Threshold: " + to_string(CNNGoodThreshold) + ")";
|
||||
@@ -806,24 +810,24 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
else
|
||||
{
|
||||
GENERAL[_ana]->ROI[i]->isReject = false;
|
||||
GENERAL[n]->ROI[roi]->isReject = false;
|
||||
}
|
||||
|
||||
|
||||
GENERAL[_ana]->ROI[i]->result_float = result;
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i: %f", i, GENERAL[_ana]->ROI[i]->result_float);
|
||||
GENERAL[n]->ROI[roi]->result_float = result;
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i: %f", roi, GENERAL[n]->ROI[roi]->result_float);
|
||||
|
||||
if (isLogImage)
|
||||
{
|
||||
string _imagename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name;
|
||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||
if (isLogImageSelect)
|
||||
{
|
||||
if (LogImageSelect.find(GENERAL[_ana]->ROI[i]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -831,37 +835,38 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
case Digital100:
|
||||
case Analogue100:
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: Digital100 or Analogue100");
|
||||
int _num;
|
||||
float _result_save_file;
|
||||
|
||||
tflite->LoadInputImageBasis(GENERAL[_ana]->ROI[i]->image);
|
||||
tflite->LoadInputImageBasis(GENERAL[n]->ROI[roi]->image);
|
||||
tflite->Invoke();
|
||||
|
||||
_num = tflite->GetOutClassification();
|
||||
|
||||
if(GENERAL[_ana]->ROI[i]->CCW)
|
||||
GENERAL[_ana]->ROI[i]->result_float = 10 - ((float)_num / 10.0);
|
||||
if(GENERAL[n]->ROI[roi]->CCW)
|
||||
GENERAL[n]->ROI[roi]->result_float = 10 - ((float)_num / 10.0);
|
||||
else
|
||||
GENERAL[_ana]->ROI[i]->result_float = (float)_num / 10.0;
|
||||
GENERAL[n]->ROI[roi]->result_float = (float)_num / 10.0;
|
||||
|
||||
_result_save_file = GENERAL[_ana]->ROI[i]->result_float;
|
||||
_result_save_file = GENERAL[n]->ROI[roi]->result_float;
|
||||
|
||||
|
||||
GENERAL[_ana]->ROI[i]->isReject = false;
|
||||
GENERAL[n]->ROI[roi]->isReject = false;
|
||||
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
|
||||
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
||||
|
||||
if (isLogImage)
|
||||
{
|
||||
string _imagename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name;
|
||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||
if (isLogImageSelect)
|
||||
{
|
||||
if (LogImageSelect.find(GENERAL[_ana]->ROI[i]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ extern "C" {
|
||||
#include "time_sntp.h"
|
||||
#include "Helper.h"
|
||||
#include "server_ota.h"
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#include "server_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
//#include "CImg.h"
|
||||
|
||||
@@ -27,8 +30,7 @@ extern "C" {
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
static const char* TAG = "FLOW CTRL";
|
||||
|
||||
static const char* TAG = "CTRL";
|
||||
|
||||
|
||||
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
|
||||
@@ -49,12 +51,17 @@ std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _
|
||||
if ((_stepname.compare("[Analog]") == 0) || (_stepname.compare(";[Analog]") == 0)){
|
||||
_classname = "ClassFlowCNNGeneral";
|
||||
}
|
||||
#ifdef ENABLE_MQTT
|
||||
if ((_stepname.compare("[MQTT]") == 0) || (_stepname.compare(";[MQTT]") == 0)){
|
||||
_classname = "ClassFlowMQTT";
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
if ((_stepname.compare("[InfluxDB]") == 0) || (_stepname.compare(";[InfluxDB]") == 0)){
|
||||
_classname = "ClassFlowInfluxDB";
|
||||
}
|
||||
#endif //ENABLE_INFLUXDB
|
||||
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
if (FlowControll[i]->name().compare(_classname) == 0){
|
||||
@@ -77,14 +84,18 @@ std::string ClassFlowControll::TranslateAktstatus(std::string _input)
|
||||
return ("Aligning");
|
||||
if (_input.compare("ClassFlowCNNGeneral") == 0)
|
||||
return ("Digitalization of ROIs");
|
||||
#ifdef ENABLE_MQTT
|
||||
if (_input.compare("ClassFlowMQTT") == 0)
|
||||
return ("Sending MQTT");
|
||||
#endif //ENABLE_MQTT
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
if (_input.compare("ClassFlowInfluxDB") == 0)
|
||||
return ("Sending InfluxDB");
|
||||
#endif //ENABLE_INFLUXDB
|
||||
if (_input.compare("ClassFlowPostProcessing") == 0)
|
||||
return ("Processing");
|
||||
return ("Post-Processing");
|
||||
if (_input.compare("ClassFlowWriteList") == 0)
|
||||
return ("Processing");
|
||||
return ("Writing List");
|
||||
|
||||
return "Unkown Status";
|
||||
}
|
||||
@@ -129,7 +140,7 @@ t_CNNType ClassFlowControll::GetTypeAnalog()
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
string ClassFlowControll::GetMQTTMainTopic()
|
||||
{
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
@@ -139,7 +150,16 @@ string ClassFlowControll::GetMQTTMainTopic()
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowControll::StartMQTTService() {
|
||||
/* Start the MQTT service */
|
||||
for (int i = 0; i < FlowControll.size(); ++i) {
|
||||
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) {
|
||||
return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoIntervall);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
void ClassFlowControll::SetInitialParameter(void)
|
||||
{
|
||||
@@ -186,12 +206,14 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
|
||||
cfc = new ClassFlowCNNGeneral(flowalignment);
|
||||
flowdigit = (ClassFlowCNNGeneral*) cfc;
|
||||
}
|
||||
#ifdef ENABLE_MQTT
|
||||
if (toUpper(_type).compare("[MQTT]") == 0)
|
||||
cfc = new ClassFlowMQTT(&FlowControll);
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
if (toUpper(_type).compare("[INFLUXDB]") == 0)
|
||||
cfc = new ClassFlowInfluxDB(&FlowControll);
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
if (toUpper(_type).compare("[WRITELIST]") == 0)
|
||||
cfc = new ClassFlowWriteList(&FlowControll);
|
||||
|
||||
@@ -275,7 +297,12 @@ void ClassFlowControll::doFlowMakeImageOnly(string time){
|
||||
if (FlowControll[i]->name() == "ClassFlowMakeImage") {
|
||||
// zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
zw_time = gettimestring("%H:%M:%S");
|
||||
aktstatus = TranslateAktstatus(FlowControll[i]->name()) + " (" + zw_time + ")";
|
||||
std::string flowStatus = TranslateAktstatus(FlowControll[i]->name());
|
||||
aktstatus = flowStatus + " (" + zw_time + ")";
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
FlowControll[i]->doFlow(time);
|
||||
}
|
||||
}
|
||||
@@ -302,14 +329,16 @@ bool ClassFlowControll::doFlow(string time)
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
{
|
||||
zw_time = gettimestring("%H:%M:%S");
|
||||
aktstatus = TranslateAktstatus(FlowControll[i]->name()) + " (" + zw_time + ")";
|
||||
std::string flowStatus = TranslateAktstatus(FlowControll[i]->name());
|
||||
aktstatus = flowStatus + " (" + zw_time + ")";
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
// zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
// aktstatus = zw_time + ": " + FlowControll[i]->name();
|
||||
|
||||
|
||||
string zw = "FlowControll.doFlow - " + FlowControll[i]->name();
|
||||
LogFile.WriteHeapInfo(zw);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo(zw);
|
||||
#endif
|
||||
|
||||
if (!FlowControll[i]->doFlow(time)){
|
||||
repeat++;
|
||||
@@ -333,7 +362,11 @@ bool ClassFlowControll::doFlow(string time)
|
||||
|
||||
}
|
||||
zw_time = gettimestring("%H:%M:%S");
|
||||
aktstatus = "Flow finished (" + zw_time + ")";
|
||||
std::string flowStatus = "Flow finished";
|
||||
aktstatus = flowStatus + " (" + zw_time + ")";
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
|
||||
#endif //ENABLE_MQTT
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -547,12 +580,6 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Start the MQTT service */
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0)
|
||||
return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoIntervall);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -560,10 +587,10 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
int ClassFlowControll::CleanTempFolder() {
|
||||
const char* folderPath = "/sdcard/img_tmp";
|
||||
|
||||
ESP_LOGI(TAG, "Clean up temporary folder to avoid damage of sdcard sectors : %s", folderPath);
|
||||
ESP_LOGD(TAG, "Clean up temporary folder to avoid damage of sdcard sectors: %s", folderPath);
|
||||
DIR *dir = opendir(folderPath);
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", folderPath);
|
||||
ESP_LOGE(TAG, "Failed to stat dir: %s", folderPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -575,14 +602,14 @@ int ClassFlowControll::CleanTempFolder() {
|
||||
if (unlink(path.c_str()) == 0) {
|
||||
deleted ++;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "can't delete file : %s", path.c_str());
|
||||
ESP_LOGE(TAG, "can't delete file: %s", path.c_str());
|
||||
}
|
||||
} else if (entry->d_type == DT_DIR) {
|
||||
deleted += removeFolder(path.c_str(), TAG);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
ESP_LOGI(TAG, "%d files deleted", deleted);
|
||||
ESP_LOGD(TAG, "%d files deleted", deleted);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -670,10 +697,10 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
|
||||
if (_send)
|
||||
{
|
||||
ESP_LOGI(TAG, "Sending file : %s ...", _fn.c_str());
|
||||
ESP_LOGD(TAG, "Sending file: %s ...", _fn.c_str());
|
||||
set_content_type_from_file(req, _fn.c_str());
|
||||
result = _send->SendJPGtoHTTP(req);
|
||||
ESP_LOGI(TAG, "File sending complete");
|
||||
ESP_LOGD(TAG, "File sending complete");
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
}
|
||||
@@ -692,7 +719,7 @@ string ClassFlowControll::getNumbersName()
|
||||
return flowpostprocessing->getNumbersName();
|
||||
}
|
||||
|
||||
string ClassFlowControll::getJSON(std::string _id, std::string _mac)
|
||||
string ClassFlowControll::getJSON()
|
||||
{
|
||||
return flowpostprocessing->GetJSON(_id, _mac);
|
||||
return flowpostprocessing->GetJSON();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
#ifndef __FLOWCONTROLL__
|
||||
#define __FLOWCONTROLL__
|
||||
|
||||
@@ -8,8 +10,12 @@
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowCNNGeneral.h"
|
||||
#include "ClassFlowPostProcessing.h"
|
||||
#include "ClassFlowMQTT.h"
|
||||
#include "ClassFlowInfluxDB.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "ClassFlowMQTT.h"
|
||||
#endif //ENABLE_MQTT
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#include "ClassFlowInfluxDB.h"
|
||||
#endif //ENABLE_INFLUXDB
|
||||
#include "ClassFlowCNNGeneral.h"
|
||||
#include "ClassFlowWriteList.h"
|
||||
|
||||
@@ -50,12 +56,13 @@ public:
|
||||
string UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
|
||||
string GetPrevalue(std::string _number = "");
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
string getJSON(std::string _id = "", std::string _mac = "");
|
||||
string getJSON();
|
||||
string getNumbersName();
|
||||
|
||||
string TranslateAktstatus(std::string _input);
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
string GetMQTTMainTopic();
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
|
||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||
@@ -71,6 +78,9 @@ public:
|
||||
|
||||
t_CNNType GetTypeDigital();
|
||||
t_CNNType GetTypeAnalog();
|
||||
#ifdef ENABLE_MQTT
|
||||
bool StartMQTTService();
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
int CleanTempFolder();
|
||||
|
||||
@@ -80,3 +90,4 @@ public:
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
#include "CImageBasis.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* TAG = "FLOW IMG";
|
||||
static const char* TAG = "IMG";
|
||||
|
||||
ClassFlowImage::ClassFlowImage(const char* logTag)
|
||||
{
|
||||
@@ -93,7 +93,7 @@ void ClassFlowImage::RemoveOldLogs()
|
||||
if (!isLogImage)
|
||||
return;
|
||||
|
||||
ESP_LOGI(TAG, "remove old images");
|
||||
ESP_LOGD(TAG, "remove old images");
|
||||
if (logfileRetentionInDays == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ void ClassFlowImage::RemoveOldLogs()
|
||||
|
||||
DIR *dir = opendir(LogImageLocation.c_str());
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", LogImageLocation.c_str());
|
||||
ESP_LOGE(TAG, "Failed to stat dir: %s", LogImageLocation.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ void ClassFlowImage::RemoveOldLogs()
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "Image folder deleted: %d | Image folder not deleted: %d", deleted, notDeleted);
|
||||
ESP_LOGD(TAG, "Image folder deleted: %d | Image folder not deleted: %d", deleted, notDeleted);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#include <sstream>
|
||||
#include "ClassFlowInfluxDB.h"
|
||||
#include "Helper.h"
|
||||
@@ -5,6 +6,7 @@
|
||||
|
||||
#include "time_sntp.h"
|
||||
#include "interface_influxdb.h"
|
||||
|
||||
#include "ClassFlowPostProcessing.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
@@ -162,3 +164,5 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#pragma once
|
||||
#include "ClassFlow.h"
|
||||
|
||||
@@ -29,3 +30,4 @@ public:
|
||||
string name(){return "ClassFlowInfluxDB";};
|
||||
};
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "ClassFlowMQTT.h"
|
||||
@@ -17,7 +19,7 @@
|
||||
|
||||
#define __HIDE_PASSWORD
|
||||
|
||||
static const char *TAG = "FLOW MQTT";
|
||||
static const char *TAG = "MQTT";
|
||||
#define LWT_TOPIC "connection"
|
||||
#define LWT_CONNECTED "connected"
|
||||
#define LWT_DISCONNECTED "connection lost"
|
||||
@@ -187,28 +189,26 @@ string ClassFlowMQTT::GetMQTTMainTopic()
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowMQTT::Start(float AutoIntervall) {
|
||||
|
||||
bool ClassFlowMQTT::Start(float AutoIntervall)
|
||||
{
|
||||
roundInterval = AutoIntervall; // Minutes
|
||||
keepAlive = roundInterval * 60 * 2.5; // Seconds, make sure it is greater thatn 2 rounds!
|
||||
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << "Digitizer interval is " << roundInterval <<
|
||||
" minutes => setting MQTT LWT timeout to " << ((float)keepAlive/60) << " minutes.";
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, stream.str());
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, stream.str());
|
||||
|
||||
mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
|
||||
|
||||
MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED, LWT_DISCONNECTED,
|
||||
keepAlive, SetRetainFlag, (void *)&GotConnected);
|
||||
bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED,
|
||||
LWT_DISCONNECTED, keepAlive, SetRetainFlag, (void *)&GotConnected);
|
||||
|
||||
if (!MQTT_Init()) {
|
||||
if (!MQTT_Init()) { // Retry
|
||||
return false;
|
||||
}
|
||||
if (!MQTTConfigCheck) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (MQTT_Init() == 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
std::string result;
|
||||
std::string resulterror = "";
|
||||
std::string resultraw = "";
|
||||
std::string resultpre = "";
|
||||
std::string resultrate = ""; // Always Unit / Minute
|
||||
std::string resultRatePerTimeUnit = ""; // According to selection
|
||||
std::string resulttimestamp = "";
|
||||
@@ -226,16 +227,17 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
|
||||
publishSystemData();
|
||||
|
||||
if (flowpostprocessing)
|
||||
if (flowpostprocessing && getMQTTisConnected())
|
||||
{
|
||||
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Publishing MQTT topics...");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing MQTT topics...");
|
||||
|
||||
for (int i = 0; i < (*NUMBERS).size(); ++i)
|
||||
{
|
||||
result = (*NUMBERS)[i]->ReturnValue;
|
||||
resultraw = (*NUMBERS)[i]->ReturnRawValue;
|
||||
resultpre = (*NUMBERS)[i]->ReturnPreValue;
|
||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||
resultrate = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
|
||||
resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
|
||||
@@ -278,43 +280,32 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
if (resulttimestamp.length() > 0)
|
||||
MQTTPublish(namenumber + "timestamp", resulttimestamp, SetRetainFlag);
|
||||
|
||||
std::string json = "";
|
||||
|
||||
if (result.length() > 0)
|
||||
json += "{\"value\":"+result;
|
||||
else
|
||||
json += "{\"value\":\"\"";
|
||||
|
||||
json += ",\"raw\":\""+resultraw;
|
||||
json += "\",\"error\":\""+resulterror;
|
||||
|
||||
if (resultrate.length() > 0)
|
||||
json += "\",\"rate\":"+resultrate;
|
||||
else
|
||||
json += "\",\"rate\":\"\"";
|
||||
|
||||
json += ",\"timestamp\":\""+resulttimestamp+"\"}";
|
||||
|
||||
std::string json = flowpostprocessing->getJsonFromNumber(i, "\n");
|
||||
MQTTPublish(namenumber + "json", json, SetRetainFlag);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
zw = (*ListFlowControll)[i]->getReadout();
|
||||
if (zw.length() > 0)
|
||||
{
|
||||
if (result.length() == 0)
|
||||
result = zw;
|
||||
else
|
||||
result = result + "\t" + zw;
|
||||
}
|
||||
}
|
||||
MQTTPublish(topic, result, SetRetainFlag);
|
||||
}
|
||||
|
||||
/* Disabled because this is no longer a use case */
|
||||
// else
|
||||
// {
|
||||
// for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
// {
|
||||
// zw = (*ListFlowControll)[i]->getReadout();
|
||||
// if (zw.length() > 0)
|
||||
// {
|
||||
// if (result.length() == 0)
|
||||
// result = zw;
|
||||
// else
|
||||
// result = result + "\t" + zw;
|
||||
// }
|
||||
// }
|
||||
// MQTTPublish(topic, result, SetRetainFlag);
|
||||
// }
|
||||
|
||||
OldValue = result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
#pragma once
|
||||
#include "ClassFlow.h"
|
||||
|
||||
@@ -33,3 +34,4 @@ public:
|
||||
string name(){return "ClassFlowMQTT";};
|
||||
};
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* TAG = "FLOW POSTPROC";
|
||||
static const char* TAG = "POSTPROC";
|
||||
|
||||
//#define SERIAL_DEBUG // testing debug on serial enabled
|
||||
|
||||
|
||||
#define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S"
|
||||
#define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z"
|
||||
#define PREVALUE_TIME_FORMAT_INPUT "%d-%d-%dT%d:%d:%d"
|
||||
|
||||
|
||||
@@ -37,42 +37,51 @@ std::string ClassFlowPostProcessing::getNumbersName()
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string ClassFlowPostProcessing::GetJSON(std::string _id, std::string _mac, std::string _lineend)
|
||||
std::string ClassFlowPostProcessing::GetJSON(std::string _lineend)
|
||||
{
|
||||
std::string json="{" + _lineend;
|
||||
|
||||
for (int i = 0; i < NUMBERS.size(); ++i)
|
||||
{
|
||||
json += "\"" + NUMBERS[i]->name + "\":" + _lineend;
|
||||
json += " {" + _lineend;
|
||||
|
||||
if (_id.length() > 0)
|
||||
json += " \"ID\": \"" + _id + "\"," + _lineend;
|
||||
if (_mac.length() > 0)
|
||||
json += " \"MAC\": \"" + _mac + "\"," + _lineend;
|
||||
json += getJsonFromNumber(i, _lineend) + _lineend;
|
||||
|
||||
if (NUMBERS[i]->ReturnValue.length() > 0)
|
||||
json += " \"value\": \"" + NUMBERS[i]->ReturnValue + "\"," + _lineend;
|
||||
else
|
||||
json += " \"value\": \"\"," + _lineend;
|
||||
json += " \"raw\": \"" + NUMBERS[i]->ReturnRawValue + "\"," + _lineend;
|
||||
json += " \"error\": \"" + NUMBERS[i]->ErrorMessageText + "\"," + _lineend;
|
||||
if (NUMBERS[i]->ReturnRateValue.length() > 0)
|
||||
json += " \"rate\": " + NUMBERS[i]->ReturnRateValue + "," + _lineend;
|
||||
else
|
||||
json += " \"rate\": \"\"," + _lineend;
|
||||
|
||||
json += " \"timestamp\": \"" + NUMBERS[i]->timeStamp + "\"" + _lineend;
|
||||
if ((i+1) < NUMBERS.size())
|
||||
json += " }," + _lineend;
|
||||
else
|
||||
json += " }" + _lineend;
|
||||
json += "," + _lineend;
|
||||
}
|
||||
json += "}";
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowPostProcessing::getJsonFromNumber(int i, std::string _lineend) {
|
||||
std::string json = "";
|
||||
|
||||
json += " {" + _lineend;
|
||||
|
||||
if (NUMBERS[i]->ReturnValue.length() > 0)
|
||||
json += " \"value\": \"" + NUMBERS[i]->ReturnValue + "\"," + _lineend;
|
||||
else
|
||||
json += " \"value\": \"\"," + _lineend;
|
||||
|
||||
json += " \"raw\": \"" + NUMBERS[i]->ReturnRawValue + "\"," + _lineend;
|
||||
json += " \"pre\": \"" + NUMBERS[i]->ReturnPreValue + "\"," + _lineend;
|
||||
json += " \"error\": \"" + NUMBERS[i]->ErrorMessageText + "\"," + _lineend;
|
||||
|
||||
if (NUMBERS[i]->ReturnRateValue.length() > 0)
|
||||
json += " \"rate\": \"" + NUMBERS[i]->ReturnRateValue + "\"," + _lineend;
|
||||
else
|
||||
json += " \"rate\": \"\"," + _lineend;
|
||||
|
||||
json += " \"timestamp\": \"" + NUMBERS[i]->timeStamp + "\"" + _lineend;
|
||||
json += " }" + _lineend;
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowPostProcessing::GetPreValue(std::string _number)
|
||||
{
|
||||
std::string result;
|
||||
@@ -698,6 +707,8 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
NUMBERS[j]->ReturnValue = "";
|
||||
NUMBERS[j]->ErrorMessageText = "";
|
||||
NUMBERS[j]->Value = -1;
|
||||
/* TODO to be discussed, see https://github.com/jomjol/AI-on-the-edge-device/issues/1617 */
|
||||
// NUMBERS[j]->lastvalue = imagetime; // must only be set in case of good value !!! --> move to the end
|
||||
|
||||
UpdateNachkommaDecimalShift();
|
||||
|
||||
@@ -752,6 +763,11 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
}
|
||||
else
|
||||
{
|
||||
string _zw = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText;
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
/* TODO to be discussed, see https://github.com/jomjol/AI-on-the-edge-device/issues/1617 */
|
||||
NUMBERS[j]->lastvalue = imagetime;
|
||||
|
||||
WriteDataLog(j);
|
||||
continue; // es gibt keinen Zahl, da noch ein N vorhanden ist.
|
||||
}
|
||||
@@ -809,6 +825,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + zwvalue + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " ";
|
||||
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
|
||||
NUMBERS[j]->ReturnValue = "";
|
||||
|
||||
string _zw = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText;
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
WriteDataLog(j);
|
||||
continue;
|
||||
}
|
||||
@@ -833,10 +852,15 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
|
||||
if (abs(_ratedifference) > abs(NUMBERS[j]->MaxRateValue))
|
||||
{
|
||||
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
|
||||
WriteDataLog(j);
|
||||
|
||||
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + RundeOutput(_ratedifference, NUMBERS[j]->Nachkomma);
|
||||
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
|
||||
NUMBERS[j]->ReturnValue = "";
|
||||
NUMBERS[j]->ReturnRateValue = "";
|
||||
|
||||
string _zw = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText;
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
WriteDataLog(j);
|
||||
continue;
|
||||
}
|
||||
@@ -844,10 +868,11 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
#ifdef SERIAL_DEBUG
|
||||
ESP_LOGD(TAG, "After MaxRateCheck: Value %f", NUMBERS[j]->Value);
|
||||
#endif
|
||||
NUMBERS[j]->ReturnChangeAbsolute = RundeOutput(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
|
||||
NUMBERS[j]->lastvalue = imagetime;
|
||||
NUMBERS[j]->ReturnChangeAbsolute = RundeOutput(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
|
||||
NUMBERS[j]->PreValue = NUMBERS[j]->Value;
|
||||
NUMBERS[j]->PreValueOkay = true;
|
||||
NUMBERS[j]->lastvalue = imagetime;
|
||||
|
||||
|
||||
|
||||
NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma);
|
||||
@@ -856,7 +881,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
NUMBERS[j]->ErrorMessageText = "no error";
|
||||
UpdatePreValueINI = true;
|
||||
|
||||
string _zw = "PostProcessing - Raw: " + NUMBERS[j]->ReturnRawValue + " Value: " + NUMBERS[j]->ReturnValue + " Error: " + NUMBERS[j]->ErrorMessageText;
|
||||
string _zw = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText;
|
||||
ESP_LOGD(TAG, "%s", zw.c_str());
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
WriteDataLog(j);
|
||||
|
||||
@@ -61,10 +61,11 @@ public:
|
||||
string getReadoutRate(int _number = 0);
|
||||
string getReadoutTimeStamp(int _number = 0);
|
||||
void SavePreValue();
|
||||
string getJsonFromNumber(int i, std::string _lineend);
|
||||
string GetPreValue(std::string _number = "");
|
||||
void SetPreValue(double zw, string _numbers, bool _extern = false);
|
||||
|
||||
std::string GetJSON(std::string _id = "", std::string _mac = "", std::string _lineend = "\n");
|
||||
std::string GetJSON(std::string _lineend = "\n");
|
||||
std::string getNumbersName();
|
||||
|
||||
void UpdateNachkommaDecimalShift();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -35,6 +36,8 @@ static const char* TAG = "HELPER";
|
||||
|
||||
using namespace std;
|
||||
|
||||
unsigned int systemStatus = 0;
|
||||
|
||||
sdmmc_cid_t SDCardCid;
|
||||
sdmmc_csd_t SDCardCsd;
|
||||
|
||||
@@ -304,7 +307,7 @@ size_t findDelimiterPos(string input, string delimiter)
|
||||
|
||||
bool RenameFile(string from, string to)
|
||||
{
|
||||
// ESP_LOGI(logTag, "Deleting file : %s", fn.c_str());
|
||||
// ESP_LOGI(logTag, "Deleting file: %s", fn.c_str());
|
||||
/* Delete file */
|
||||
FILE* fpSourceFile = OpenFileAndWait(from.c_str(), "rb");
|
||||
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
|
||||
@@ -321,7 +324,7 @@ bool RenameFile(string from, string to)
|
||||
|
||||
bool DeleteFile(string fn)
|
||||
{
|
||||
// ESP_LOGI(logTag, "Deleting file : %s", fn.c_str());
|
||||
// ESP_LOGI(logTag, "Deleting file: %s", fn.c_str());
|
||||
/* Delete file */
|
||||
FILE* fpSourceFile = OpenFileAndWait(fn.c_str(), "rb");
|
||||
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
|
||||
@@ -512,7 +515,7 @@ int removeFolder(const char* folderPath, const char* logTag) {
|
||||
|
||||
DIR *dir = opendir(folderPath);
|
||||
if (!dir) {
|
||||
ESP_LOGE(logTag, "Failed to stat dir : %s", folderPath);
|
||||
ESP_LOGE(logTag, "Failed to stat dir: %s", folderPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -525,7 +528,7 @@ int removeFolder(const char* folderPath, const char* logTag) {
|
||||
if (unlink(path.c_str()) == 0) {
|
||||
deleted ++;
|
||||
} else {
|
||||
ESP_LOGE(logTag, "can't delete file : %s", path.c_str());
|
||||
ESP_LOGE(logTag, "can't delete file: %s", path.c_str());
|
||||
}
|
||||
} else if (entry->d_type == DT_DIR) {
|
||||
deleted += removeFolder(path.c_str(), logTag);
|
||||
@@ -534,7 +537,7 @@ int removeFolder(const char* folderPath, const char* logTag) {
|
||||
|
||||
closedir(dir);
|
||||
if (rmdir(folderPath) != 0) {
|
||||
ESP_LOGE(logTag, "can't delete folder : %s", folderPath);
|
||||
ESP_LOGE(logTag, "can't delete folder: %s", folderPath);
|
||||
}
|
||||
ESP_LOGD(logTag, "%d files in folder %s deleted.", deleted, folderPath);
|
||||
|
||||
@@ -770,6 +773,38 @@ string getMac(void) {
|
||||
return macFormated;
|
||||
}
|
||||
|
||||
|
||||
void setSystemStatusFlag(SystemStatusFlag_t flag) {
|
||||
systemStatus = systemStatus | flag; // set bit
|
||||
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "0x%08X", getSystemStatus());
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf));
|
||||
}
|
||||
|
||||
void clearSystemStatusFlag(SystemStatusFlag_t flag) {
|
||||
systemStatus = systemStatus | ~flag; // clear bit
|
||||
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "0x%08X", getSystemStatus());
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf));
|
||||
}
|
||||
|
||||
int getSystemStatus(void) {
|
||||
return systemStatus;
|
||||
}
|
||||
|
||||
bool isSetSystemStatusFlag(SystemStatusFlag_t flag) {
|
||||
//ESP_LOGE(TAG, "Flag (0x%08X) is set (0x%08X): %d", flag, systemStatus , ((systemStatus & flag) == flag));
|
||||
|
||||
if ((systemStatus & flag) == flag) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string getResetReason(void) {
|
||||
std::string reasonText;
|
||||
|
||||
@@ -791,3 +826,38 @@ string getResetReason(void) {
|
||||
}
|
||||
return reasonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current uptime formated ad xxf xxh xxm [xxs]
|
||||
*/
|
||||
std::string getFormatedUptime(bool compact) {
|
||||
char buf[20];
|
||||
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||
|
||||
int uptime = (uint32_t)(esp_timer_get_time()/1000/1000); // in seconds
|
||||
|
||||
int days = int(floor(uptime / (3600*24)));
|
||||
int hours = int(floor((uptime - days * 3600*24) / (3600)));
|
||||
int minutes = int(floor((uptime - days * 3600*24 - hours * 3600) / (60)));
|
||||
int seconds = uptime - days * 3600*24 - hours * 3600 - minutes * 60;
|
||||
|
||||
if (compact) {
|
||||
snprintf(buf, sizeof(buf), "%dd%02dh%02dm%02ds", days, hours, minutes, seconds);
|
||||
}
|
||||
else {
|
||||
snprintf(buf, sizeof(buf), "%3dd %02dh %02dm %02ds", days, hours, minutes, seconds);
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
const char* get404(void) {
|
||||
return
|
||||
"<pre>\n\n\n\n"
|
||||
" _\n"
|
||||
" .__(.)< ( oh oh! This page does not exist! )\n"
|
||||
" \\___)\n"
|
||||
"\n\n"
|
||||
" You could try your <a href=index.html target=_parent>luck</a> here!</pre>\n"
|
||||
"<script>document.cookie = \"page=overview.html\"</script>"; // Make sure we load the overview page
|
||||
}
|
||||
|
||||
@@ -63,4 +63,28 @@ string getSDCardCapacity();
|
||||
string getSDCardSectorSize();
|
||||
|
||||
string getMac(void);
|
||||
string getResetReason(void);
|
||||
|
||||
|
||||
/* Error bit fields
|
||||
One bit per error
|
||||
Make sure it matches https://github.com/jomjol/AI-on-the-edge-device/wiki/Error-Codes */
|
||||
enum SystemStatusFlag_t { // One bit per error
|
||||
// First Byte
|
||||
SYSTEM_STATUS_PSRAM_BAD = 1 << 0, // 1, Critical Error
|
||||
SYSTEM_STATUS_HEAP_TOO_SMALL = 1 << 1, // 2, Critical Error
|
||||
SYSTEM_STATUS_CAM_BAD = 1 << 2, // 4, Critical Error
|
||||
|
||||
// Second Byte
|
||||
SYSTEM_STATUS_CAM_FB_BAD = 1 << (0+8), // 8, Flow still might work
|
||||
SYSTEM_STATUS_NTP_BAD = 1 << (1+8), // 9, Flow will work but time will be wrong
|
||||
};
|
||||
|
||||
void setSystemStatusFlag(SystemStatusFlag_t flag);
|
||||
void clearSystemStatusFlag(SystemStatusFlag_t flag);
|
||||
int getSystemStatus(void);
|
||||
bool isSetSystemStatusFlag(SystemStatusFlag_t flag);
|
||||
|
||||
string getResetReason(void);
|
||||
std::string getFormatedUptime(bool compact);
|
||||
|
||||
const char* get404(void);
|
||||
|
||||
@@ -12,6 +12,7 @@ static const char* TAG = "c_align_and_cut_image";
|
||||
//#define GET_MEMORY malloc
|
||||
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
|
||||
|
||||
@@ -453,7 +453,7 @@ CImageBasis::CImageBasis(std::string _image)
|
||||
RGBImageRelease();
|
||||
|
||||
zwld = esp_get_free_heap_size();
|
||||
ESP_LOGD(TAG, "freeheapsize after : %ld", zwld);
|
||||
ESP_LOGD(TAG, "freeheapsize after: %ld", zwld);
|
||||
|
||||
std::string zw = "Image Load failed:" + _image;
|
||||
if (rgb_image == NULL)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#include "interface_influxdb.h"
|
||||
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
@@ -111,4 +112,4 @@ void InfluxDBInit(std::string _uri, std::string _database, std::string _measurem
|
||||
void InfluxDBdestroy() {
|
||||
}
|
||||
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#ifndef INTERFACE_INFLUXDB_H
|
||||
#define INTERFACE_INFLUXDB_H
|
||||
|
||||
@@ -11,3 +12,4 @@ void InfluxDBdestroy();
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp);
|
||||
|
||||
#endif //INTERFACE_INFLUXDB_H
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -23,10 +23,10 @@ ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt", "/sdcard/log/dat
|
||||
void ClassLogFile::WriteHeapInfo(std::string _id)
|
||||
{
|
||||
std::string _zw = _id;
|
||||
if (loglevel > ESP_LOG_WARN)
|
||||
if (loglevel >= ESP_LOG_DEBUG) {
|
||||
_zw = _zw + "\t" + getESPHeapInfo();
|
||||
|
||||
WriteToFile(ESP_LOG_DEBUG, "HEAP", _zw);
|
||||
WriteToFile(ESP_LOG_DEBUG, "HEAP", _zw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, esp_log_level_t level,
|
||||
{
|
||||
FILE* pFile;
|
||||
std::string zwtime;
|
||||
std::string logline = "";
|
||||
std::string ntpTime = "";
|
||||
|
||||
if (level > loglevel) {// Only write to file if loglevel is below threshold
|
||||
return;
|
||||
@@ -138,7 +138,7 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, esp_log_level_t level,
|
||||
strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo);
|
||||
|
||||
zwtime = std::string(buffer);
|
||||
logline = zwtime;
|
||||
ntpTime = zwtime;
|
||||
}
|
||||
|
||||
std::string loglevelString;
|
||||
@@ -163,9 +163,11 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, esp_log_level_t level,
|
||||
loglevelString = "NONE";
|
||||
break;
|
||||
}
|
||||
|
||||
logline = logline + "\t<" + loglevelString + ">\t" + message.c_str() + "\n";
|
||||
fputs(logline.c_str(), pFile);
|
||||
|
||||
std::string formatedUptime = getFormatedUptime(true);
|
||||
|
||||
ntpTime = "[" + formatedUptime + "] " + ntpTime + "\t<" + loglevelString + ">\t" + message + "\n";
|
||||
fputs(ntpTime.c_str(), pFile);
|
||||
fclose(pFile);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Can't open log file %s", _fn.c_str());
|
||||
@@ -296,7 +298,7 @@ void ClassLogFile::RemoveOldLogFile()
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Remove old log files");
|
||||
ESP_LOGD(TAG, "Remove old log files");
|
||||
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
@@ -313,7 +315,7 @@ void ClassLogFile::RemoveOldLogFile()
|
||||
|
||||
DIR *dir = opendir(logroot.c_str());
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", logroot.c_str());
|
||||
ESP_LOGE(TAG, "Failed to stat dir: %s", logroot.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -322,14 +324,14 @@ void ClassLogFile::RemoveOldLogFile()
|
||||
int notDeleted = 0;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_type == DT_REG) {
|
||||
//ESP_LOGD(TAG, "compare log file : %s to %s", entry->d_name, cmpfilename);
|
||||
//ESP_LOGD(TAG, "compare log file: %s to %s", entry->d_name, cmpfilename);
|
||||
if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) < 0)) {
|
||||
//ESP_LOGD(TAG, "delete log file : %s", entry->d_name);
|
||||
//ESP_LOGD(TAG, "delete log file: %s", entry->d_name);
|
||||
std::string filepath = logroot + "/" + entry->d_name;
|
||||
if (unlink(filepath.c_str()) == 0) {
|
||||
deleted ++;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "can't delete file : %s", entry->d_name);
|
||||
ESP_LOGE(TAG, "can't delete file: %s", entry->d_name);
|
||||
notDeleted ++;
|
||||
}
|
||||
} else {
|
||||
@@ -337,7 +339,7 @@ void ClassLogFile::RemoveOldLogFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "log files deleted: %d | files not deleted (incl. leer.txt): %d", deleted, notDeleted);
|
||||
ESP_LOGD(TAG, "log files deleted: %d | files not deleted (incl. leer.txt): %d", deleted, notDeleted);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
@@ -348,7 +350,7 @@ void ClassLogFile::RemoveOldDataLog()
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Remove old data files");
|
||||
ESP_LOGD(TAG, "Remove old data files");
|
||||
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
@@ -364,7 +366,7 @@ void ClassLogFile::RemoveOldDataLog()
|
||||
|
||||
DIR *dir = opendir(dataroot.c_str());
|
||||
if (!dir) {
|
||||
ESP_LOGE(TAG, "Failed to stat dir : %s", dataroot.c_str());
|
||||
ESP_LOGE(TAG, "Failed to stat dir: %s", dataroot.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -373,14 +375,14 @@ void ClassLogFile::RemoveOldDataLog()
|
||||
int notDeleted = 0;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_type == DT_REG) {
|
||||
//ESP_LOGD(TAG, "Compare data file : %s to %s", entry->d_name, cmpfilename);
|
||||
//ESP_LOGD(TAG, "Compare data file: %s to %s", entry->d_name, cmpfilename);
|
||||
if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) < 0)) {
|
||||
//ESP_LOGD(TAG, "delete data file : %s", entry->d_name);
|
||||
//ESP_LOGD(TAG, "delete data file: %s", entry->d_name);
|
||||
std::string filepath = dataroot + "/" + entry->d_name;
|
||||
if (unlink(filepath.c_str()) == 0) {
|
||||
deleted ++;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "can't delete file : %s", entry->d_name);
|
||||
ESP_LOGE(TAG, "can't delete file: %s", entry->d_name);
|
||||
notDeleted ++;
|
||||
}
|
||||
} else {
|
||||
@@ -388,7 +390,7 @@ void ClassLogFile::RemoveOldDataLog()
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "data files deleted: %d | files not deleted (incl. leer.txt): %d", deleted, notDeleted);
|
||||
ESP_LOGD(TAG, "data files deleted: %d | files not deleted (incl. leer.txt): %d", deleted, notDeleted);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES tflite-lib mqtt jomjol_tfliteclass jomjol_helper jomjol_mqtt jomjol_wlan)
|
||||
REQUIRES tflite-lib mqtt jomjol_tfliteclass jomjol_helper jomjol_mqtt jomjol_wlan)
|
||||
|
||||
@@ -1,95 +1,111 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#include "esp_log.h"
|
||||
#include "connect_wlan.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "server_tflite.h"
|
||||
|
||||
#define __HIDE_PASSWORD
|
||||
|
||||
static const char *TAG = "MQTT INTERFACE";
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
static const char *TAG = "MQTT IF";
|
||||
|
||||
std::map<std::string, std::function<void()>>* connectFunktionMap = NULL;
|
||||
std::map<std::string, std::function<bool(std::string, char*, int)>>* subscribeFunktionMap = NULL;
|
||||
|
||||
|
||||
int failedOnRound = -1;
|
||||
|
||||
esp_mqtt_event_id_t esp_mmqtt_ID = MQTT_EVENT_ANY;
|
||||
|
||||
esp_mqtt_event_id_t esp_mqtt_ID = MQTT_EVENT_ANY;
|
||||
// ESP_EVENT_ANY_ID
|
||||
|
||||
bool mqtt_enabled = false;
|
||||
bool mqtt_configOK = false;
|
||||
bool mqtt_initialized = false;
|
||||
bool mqtt_connected = false;
|
||||
|
||||
esp_mqtt_client_handle_t client = NULL;
|
||||
std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic;
|
||||
int keepalive, SetRetainFlag;
|
||||
void (*callbackOnConnected)(std::string, int) = NULL;
|
||||
|
||||
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag) {
|
||||
int msg_id;
|
||||
std::string zw;
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag)
|
||||
{
|
||||
if (!mqtt_enabled) { // MQTT sevice not started / configured (MQTT_Init not called before)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (failedOnRound == getCountFlowRounds()) { // we already failed in this round, do not retry until the next round
|
||||
if (failedOnRound == getCountFlowRounds()) { // we already failed in this round, do not retry until the next round
|
||||
return true; // Fail quietly
|
||||
}
|
||||
|
||||
LogFile.WriteHeapInfo("MQTT Publish");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("MQTT Publish");
|
||||
#endif
|
||||
|
||||
if (!mqtt_connected) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Not connected, trying to re-connect...");
|
||||
if (!MQTT_Init()) {
|
||||
if (!MQTT_Init()) { // Retry
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to init, skipping all MQTT publishings in this round!");
|
||||
MQTT_Init(); // Re-Init client if not initialized yet/anymore
|
||||
|
||||
if (mqtt_initialized && mqtt_connected) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
long long int starttime = esp_timer_get_time();
|
||||
#endif
|
||||
int msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Publish msg_id %d in %lld ms", msg_id, (esp_timer_get_time() - starttime)/1000);
|
||||
#endif
|
||||
if (msg_id == -1) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Failed to publish topic '" + _key + "', re-trying...");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
starttime = esp_timer_get_time();
|
||||
#endif
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Publish msg_id %d in %lld ms", msg_id, (esp_timer_get_time() - starttime)/1000);
|
||||
#endif
|
||||
if (msg_id == -1) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to publish topic '" + _key + "', skipping all MQTT publishings in this round!");
|
||||
failedOnRound = getCountFlowRounds();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
if (msg_id < 0) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Failed to publish topic '" + _key + "', re-trying...");
|
||||
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
if (msg_id < 0) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to publish topic '" + _key + "', skipping all MQTT publishings in this round!");
|
||||
mqtt_connected = false; // Force re-init on next call
|
||||
failedOnRound = getCountFlowRounds();
|
||||
return false;
|
||||
if (_content.length() > 80) { // Truncate message if too long
|
||||
_content.resize(80);
|
||||
_content.append("..");
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Published topic: " + _key + ", content: " + _content + " (msg_id=" + std::to_string(msg_id) + ")");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_content.length() > 80) { // Truncate message if too long
|
||||
_content.resize(80);
|
||||
_content.append("..");
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publish skipped. Client not initalized or not connected. (topic: " + _key + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
zw = "Published topic: " + _key + ", content: " + _content + " (msg_id=" + std::to_string(msg_id) + ")";
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
|
||||
{
|
||||
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) {
|
||||
int msg_id;
|
||||
std::string topic = "";
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_BEFORE_CONNECT:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_BEFORE_CONNECT");
|
||||
mqtt_initialized = true;
|
||||
break;
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_CONNECTED");
|
||||
mqtt_initialized = true;
|
||||
mqtt_connected = true;
|
||||
MQTTconnected();
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Disconnected! Going to re-connect...");
|
||||
mqtt_connected = false; // Force re-init on next call
|
||||
esp_mqtt_client_reconnect(client);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Disconnected from broker");
|
||||
mqtt_connected = false;
|
||||
break;
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
@@ -117,8 +133,16 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
|
||||
}
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_ERROR");
|
||||
mqtt_connected = false; // Force re-init on next call
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_ERROR - esp_mqtt_error_codes:");
|
||||
ESP_LOGD(TAG, "error_type:%d", event->error_handle->error_type);
|
||||
ESP_LOGD(TAG, "connect_return_code:%d", event->error_handle->connect_return_code);
|
||||
ESP_LOGD(TAG, "esp_transport_sock_errno:%d", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGD(TAG, "esp_tls_last_esp_err:%d", event->error_handle->esp_tls_last_esp_err);
|
||||
ESP_LOGD(TAG, "esp_tls_stack_err:%d", event->error_handle->esp_tls_stack_err);
|
||||
ESP_LOGD(TAG, "esp_tls_cert_verify_flags:%d", event->error_handle->esp_tls_cert_verify_flags);
|
||||
#endif
|
||||
mqtt_connected = false;
|
||||
break;
|
||||
default:
|
||||
ESP_LOGD(TAG, "Other event id:%d", event->event_id);
|
||||
@@ -133,16 +157,14 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
}
|
||||
|
||||
|
||||
void MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
|
||||
bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
|
||||
std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
|
||||
int _keepalive, int _SetRetainFlag, void *_callbackOnConnected){
|
||||
#ifdef __HIDE_PASSWORD
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "URI: " + _mqttURI + ", clientname: " + _clientid +
|
||||
", user: " + _user + ", password: XXXXXXXX, maintopic: " + _maintopic + ", last-will-topic: " + _maintopic + "/" + _lwt + ", keepAlive: " + std::to_string(_keepalive));
|
||||
#else
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "URI: " + _mqttURI + ", clientname: " + _clientid +
|
||||
", user: " + _user + ", password: " + _password + ", maintopic: " + _maintopic + ", last-will-topic: " + _maintopic + "/" + _lwt + ", keepAlive: " + std::to_string(_keepalive));
|
||||
#endif
|
||||
int _keepalive, int _SetRetainFlag, void *_callbackOnConnected) {
|
||||
if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0))
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init aborted! Config error (URI, MainTopic or ClientID missing)");
|
||||
return false;
|
||||
}
|
||||
|
||||
uri = _mqttURI;
|
||||
client_id = _clientid;
|
||||
@@ -158,74 +180,120 @@ void MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us
|
||||
user = _user;
|
||||
password = _password;
|
||||
}
|
||||
|
||||
#ifdef __HIDE_PASSWORD
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + ", password: XXXXXXXX, maintopic: "
|
||||
+ maintopic + ", last-will-topic: " + lwt_topic + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag));
|
||||
#else
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "URI: " + uri + ", clientname: " + client_id + ", user: " + user + ", password: " + password + ", maintopic: "
|
||||
+ maintopic + ", last-will-topic: " + lwt_topic + ", keepAlive: " + std::to_string(keepalive) + ", RetainFlag: " + std::to_string(SetRetainFlag));
|
||||
#endif
|
||||
|
||||
mqtt_configOK = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MQTT_Init() {
|
||||
esp_err_t ret;
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, std::string("Init"));
|
||||
|
||||
int MQTT_Init() {
|
||||
if (mqtt_initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mqtt_configOK) {
|
||||
mqtt_enabled = true;
|
||||
} else {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init called, but client is not yet configured.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!getWIFIisConnected()) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init called, but WIFI is not yet connected.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Init");
|
||||
MQTTdestroy_client();
|
||||
|
||||
std::string lw = lwt_disconnected;
|
||||
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.uri = uri.c_str(),
|
||||
.client_id = client_id.c_str(),
|
||||
.lwt_topic = lwt_topic.c_str(),
|
||||
.lwt_msg = lw.c_str(),
|
||||
.lwt_msg = lwt_disconnected.c_str(),
|
||||
.lwt_retain = 1,
|
||||
.lwt_msg_len = (int)(lw.length()),
|
||||
.keepalive = keepalive
|
||||
.lwt_msg_len = (int)(lwt_disconnected.length()),
|
||||
.keepalive = keepalive,
|
||||
.disable_auto_reconnect = false, // Reconnection routine active (Default: false)
|
||||
.buffer_size = 1536, // size of MQTT send/receive buffer (Default: 1024)
|
||||
.reconnect_timeout_ms = 15000, // Try to reconnect to broker (Default: 10000ms)
|
||||
.network_timeout_ms = 20000, // Network Timeout (Default: 10000ms)
|
||||
.message_retransmit_timeout = 3000 // Tiem after message resent when broker not acknowledged (QoS1, QoS2)
|
||||
|
||||
};
|
||||
|
||||
if (user.length() && password.length()){
|
||||
mqtt_cfg.username = user.c_str();
|
||||
mqtt_cfg.password = password.c_str();
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("MQTT Client Init");
|
||||
#endif
|
||||
|
||||
LogFile.WriteHeapInfo("MQTT Client Init");
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
if (client)
|
||||
{
|
||||
ret = esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client);
|
||||
esp_err_t ret = esp_mqtt_client_register_event(client, esp_mqtt_ID, mqtt_event_handler, client);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not register event (ret=" + std::to_string(ret) + ")!");
|
||||
return false;
|
||||
mqtt_initialized = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogFile.WriteHeapInfo("MQTT Client Start");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("MQTT Client Start");
|
||||
#endif
|
||||
ret = esp_mqtt_client_start(client);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Could not start client (ret=" + std::to_string(ret) + "), retrying...");
|
||||
ret = esp_mqtt_client_start(client);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not start client (ret=" + std::to_string(ret) + ")!");
|
||||
return false;
|
||||
}
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Client start failed (retval=" + std::to_string(ret) + ")!");
|
||||
mqtt_initialized = false;
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Client started, waiting for established connection...");
|
||||
mqtt_initialized = true;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not init client!");
|
||||
return false;
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init failed, no handle created!");
|
||||
mqtt_initialized = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Init successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MQTTdestroy_client() {
|
||||
if (client != NULL) {
|
||||
if (client) {
|
||||
if (mqtt_connected) {
|
||||
esp_mqtt_client_disconnect(client);
|
||||
mqtt_connected = false;
|
||||
}
|
||||
esp_mqtt_client_stop(client);
|
||||
esp_mqtt_client_destroy(client);
|
||||
client = NULL;
|
||||
mqtt_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MQTTisConnected() {
|
||||
bool getMQTTisEnabled() {
|
||||
return mqtt_enabled;
|
||||
}
|
||||
|
||||
bool getMQTTisConnected() {
|
||||
return mqtt_connected;
|
||||
}
|
||||
|
||||
@@ -275,7 +343,7 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::st
|
||||
|
||||
void MQTTconnected(){
|
||||
if (mqtt_connected) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Connected");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Connected to broker");
|
||||
|
||||
MQTTPublish(lwt_topic, lwt_connected, true);
|
||||
|
||||
@@ -313,3 +381,4 @@ void MQTTdestroySubscribeFunction(){
|
||||
subscribeFunktionMap = NULL;
|
||||
}
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
#ifndef INTERFACE_MQTT_H
|
||||
#define INTERFACE_MQTT_H
|
||||
|
||||
@@ -5,15 +6,16 @@
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
void MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
|
||||
std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
|
||||
int _keepalive, int SetRetainFlag, void *callbackOnConnected);
|
||||
bool MQTT_Init();
|
||||
bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
|
||||
std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
|
||||
int _keepalive, int SetRetainFlag, void *callbackOnConnected);
|
||||
int MQTT_Init();
|
||||
void MQTTdestroy_client();
|
||||
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag = 1); // retained Flag as Standart
|
||||
|
||||
bool MQTTisConnected();
|
||||
bool getMQTTisEnabled();
|
||||
bool getMQTTisConnected();
|
||||
|
||||
void MQTTregisterConnectFunction(std::string name, std::function<void()> func);
|
||||
void MQTTunregisterConnectFunction(std::string name);
|
||||
@@ -21,4 +23,6 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::st
|
||||
void MQTTdestroySubscribeFunction();
|
||||
void MQTTconnected();
|
||||
|
||||
#endif //INTERFACE_MQTT_H
|
||||
void MQTTdisable();
|
||||
#endif //INTERFACE_MQTT_H
|
||||
#endif //#ENABLE_MQTT
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@@ -127,7 +128,10 @@ void sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
|
||||
MQTTPublish(topicFull, payload, true);
|
||||
}
|
||||
|
||||
void MQTThomeassistantDiscovery() {
|
||||
void MQTThomeassistantDiscovery() {
|
||||
if (!getMQTTisConnected())
|
||||
return;
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "MQTT - Sending Homeassistant Discovery Topics (Meter Type: " + meterType + ", Value Unit: " + valueUnit + " , Rate Unit: " + rateUnit + ")...");
|
||||
|
||||
// Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category
|
||||
@@ -139,6 +143,9 @@ void MQTThomeassistantDiscovery() {
|
||||
sendHomeAssistantDiscoveryTopic("", "CPUtemp", "CPU Temperature", "thermometer", "°C", "temperature", "measurement", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic("", "interval", "Interval", "clock-time-eight-outline", "min", "" , "measurement", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic("", "IP", "IP", "network-outline", "", "", "", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic("", "status", "Status", "list-status", "", "", "", "diagnostic");
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < (*NUMBERS).size(); ++i) {
|
||||
std::string group = (*NUMBERS)[i]->name;
|
||||
@@ -150,20 +157,19 @@ void MQTThomeassistantDiscovery() {
|
||||
// sendHomeAssistantDiscoveryTopic(group, "rate", "Rate (Unit/Minute)", "swap-vertical", "", "", "", ""); // Legacy, always Unit per Minute
|
||||
sendHomeAssistantDiscoveryTopic(group, "rate_per_time_unit", "Rate (" + rateUnit + ")", "swap-vertical", rateUnit, "", "", "");
|
||||
sendHomeAssistantDiscoveryTopic(group, "rate_per_digitalization_round", "Change since last digitalization round", "arrow-expand-vertical", valueUnit, "", "measurement", ""); // correctly the Unit is Uint/Interval!
|
||||
/* The timestamp string misses the Timezone, see PREVALUE_TIME_FORMAT_OUTPUT!
|
||||
We need to know the timezone and append it! Until we do this, we simply
|
||||
do not set the device class to "timestamp" to avoid errors in Homeassistant! */
|
||||
// sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "timestamp", "", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "", "", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "timestamp", "", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic(group, "json", "JSON", "code-json", "", "", "", "diagnostic");
|
||||
sendHomeAssistantDiscoveryTopic(group, "problem", "Problem", "alert-outline", "", "", "", ""); // Special binary sensor which is based on error topic
|
||||
sendHomeAssistantDiscoveryTopic(group, "problem", "Problem", "alert-outline", "", "problem", "", ""); // Special binary sensor which is based on error topic
|
||||
}
|
||||
}
|
||||
|
||||
void publishSystemData() {
|
||||
if (!getMQTTisConnected())
|
||||
return;
|
||||
|
||||
char tmp_char[50];
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Publishing system MQTT topics...");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing system MQTT topics...");
|
||||
|
||||
sprintf(tmp_char, "%ld", (long)getUpTime());
|
||||
MQTTPublish(maintopic + "/" + "uptime", std::string(tmp_char), retainFlag);
|
||||
@@ -180,7 +186,10 @@ void publishSystemData() {
|
||||
|
||||
|
||||
void publishStaticData() {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Publishing static MQTT topics...");
|
||||
if (!getMQTTisConnected())
|
||||
return;
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing static MQTT topics...");
|
||||
MQTTPublish(maintopic + "/" + "MAC", getMac(), retainFlag);
|
||||
MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), retainFlag);
|
||||
MQTTPublish(maintopic + "/" + "hostname", hostname, retainFlag);
|
||||
@@ -204,6 +213,7 @@ esp_err_t sendDiscovery_and_static_Topics(httpd_req_t *req) {
|
||||
}
|
||||
|
||||
void GotConnected(std::string maintopic, int retainFlag) {
|
||||
vTaskDelay(10000 / portTICK_PERIOD_MS); // Delay execution by 10s after connection got established
|
||||
if (HomeassistantDiscovery) {
|
||||
MQTThomeassistantDiscovery();
|
||||
}
|
||||
@@ -240,3 +250,9 @@ void setMqtt_Server_Retain(int _retainFlag) {
|
||||
void mqttServer_setMainTopic( std::string _maintopic) {
|
||||
maintopic = _maintopic;
|
||||
}
|
||||
|
||||
std::string mqttServer_getMainTopic() {
|
||||
return maintopic;
|
||||
}
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
|
||||
#include "ClassFlowDefineTypes.h"
|
||||
|
||||
#define LWT_TOPIC "connection"
|
||||
@@ -10,10 +12,13 @@ void mqttServer_setParameter(std::vector<NumberPost*>* _NUMBERS, int interval, f
|
||||
void mqttServer_setMeterType(std::string meterType, std::string valueUnit, std::string timeUnit,std::string rateUnit);
|
||||
void setMqtt_Server_Retain(int SetRetainFlag);
|
||||
void mqttServer_setMainTopic( std::string maintopic);
|
||||
std::string mqttServer_getMainTopic();
|
||||
|
||||
void register_server_mqtt_uri(httpd_handle_t server);
|
||||
|
||||
void publishSystemData();
|
||||
|
||||
std::string getTimeUnit(void);
|
||||
void GotConnected(std::string maintopic, int SetRetainFlag);
|
||||
void GotConnected(std::string maintopic, int SetRetainFlag);
|
||||
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -8,7 +8,7 @@
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
static const char *TAG = "C TFLITE";
|
||||
static const char *TAG = "TFLITE";
|
||||
|
||||
float CTfLiteClass::GetOutputValue(int nr)
|
||||
{
|
||||
@@ -179,6 +179,8 @@ void CTfLiteClass::MakeAllocate()
|
||||
static tflite::AllOpsResolver resolver;
|
||||
|
||||
// ESP_LOGD(TAG, "%s", LogFile.getESPHeapInfo().c_str());
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Make Allocate");
|
||||
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
|
||||
// ESP_LOGD(TAG, "%s", LogFile.getESPHeapInfo().c_str());
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "server_file.h"
|
||||
#include "connect_wlan.h"
|
||||
|
||||
#define DEBUG_DETAIL_ON
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
ClassFlowControll tfliteflow;
|
||||
@@ -31,6 +31,7 @@ ClassFlowControll tfliteflow;
|
||||
TaskHandle_t xHandleblink_task_doFlow = NULL;
|
||||
TaskHandle_t xHandletask_autodoFlow = NULL;
|
||||
|
||||
bool FlowInitDone = false;
|
||||
bool flowisrunning = false;
|
||||
|
||||
long auto_intervall = 0;
|
||||
@@ -39,7 +40,7 @@ bool auto_isrunning = false;
|
||||
|
||||
int countRounds = 0;
|
||||
|
||||
static const char *TAG = "TFLITE";
|
||||
static const char *TAG = "TFLITE SERVER";
|
||||
|
||||
|
||||
int getCountFlowRounds() {
|
||||
@@ -47,17 +48,18 @@ int getCountFlowRounds() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.GetJPGStream(_filename, req);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.SendRawJPG(req);
|
||||
}
|
||||
|
||||
|
||||
bool isSetupModusActive() {
|
||||
return tfliteflow.getStatusSetupModus();
|
||||
return false;
|
||||
@@ -66,66 +68,72 @@ bool isSetupModusActive() {
|
||||
|
||||
void KillTFliteTasks()
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Handle: xHandleblink_task_doFlow: %ld", (long) xHandleblink_task_doFlow);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Handle: xHandleblink_task_doFlow: %ld", (long) xHandleblink_task_doFlow);
|
||||
#endif
|
||||
if (xHandleblink_task_doFlow != NULL)
|
||||
{
|
||||
TaskHandle_t xHandleblink_task_doFlowTmp = xHandleblink_task_doFlow;
|
||||
xHandleblink_task_doFlow = NULL;
|
||||
vTaskDelete(xHandleblink_task_doFlowTmp);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Killed: xHandleblink_task_doFlow");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Killed: xHandleblink_task_doFlow");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Handle: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Handle: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
|
||||
#endif
|
||||
if (xHandletask_autodoFlow != NULL)
|
||||
{
|
||||
TaskHandle_t xHandletask_autodoFlowTmp = xHandletask_autodoFlow;
|
||||
xHandletask_autodoFlow = NULL;
|
||||
vTaskDelete(xHandletask_autodoFlowTmp);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Killed: xHandletask_autodoFlow");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Killed: xHandletask_autodoFlow");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void doInit(void)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Start tfliteflow.InitFlow(config);");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Start tfliteflow.InitFlow(config);");
|
||||
#endif
|
||||
tfliteflow.InitFlow(CONFIG_FILE);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Finished tfliteflow.InitFlow(config);");
|
||||
#endif
|
||||
FlowInitDone = true;
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Finished tfliteflow.InitFlow(config);");
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
tfliteflow.StartMQTTService();
|
||||
#endif //ENABLE_MQTT
|
||||
}
|
||||
|
||||
|
||||
bool doflow(void)
|
||||
{
|
||||
|
||||
{
|
||||
std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT);
|
||||
ESP_LOGD(TAG, "doflow - start %s", zw_time.c_str());
|
||||
flowisrunning = true;
|
||||
tfliteflow.doFlow(zw_time);
|
||||
flowisrunning = false;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "doflow - end %s", zw_time.c_str());
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "doflow - end %s", zw_time.c_str());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void blink_task_doFlow(void *pvParameter)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "blink_task_doFlow");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "blink_task_doFlow");
|
||||
#endif
|
||||
if (!flowisrunning)
|
||||
{
|
||||
flowisrunning = true;
|
||||
@@ -139,10 +147,10 @@ void blink_task_doFlow(void *pvParameter)
|
||||
|
||||
esp_err_t handler_init(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Start");
|
||||
ESP_LOGD(TAG, "handler_doinit uri: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Start");
|
||||
ESP_LOGD(TAG, "handler_doinit uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
const char* resp_str = "Init started<br>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
@@ -154,18 +162,19 @@ esp_err_t handler_init(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_init - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_doflow(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Start");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "handler_doFlow uri: %s", req->uri);
|
||||
|
||||
@@ -184,199 +193,208 @@ esp_err_t handler_doflow(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_doflow - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_json(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_json - Start");
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_json - Start");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "handler_JSON uri: %s", req->uri);
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
std::string zw = tfliteflow.getJSON();
|
||||
if (zw.length() > 0)
|
||||
|
||||
if (FlowInitDone)
|
||||
{
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
std::string zw = tfliteflow.getJSON();
|
||||
if (zw.length() > 0)
|
||||
{
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
httpd_resp_send(req, NULL, 0);
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "JSON API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_JSON - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_JSON - Done");
|
||||
#endif
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
|
||||
#endif
|
||||
|
||||
bool _rawValue = false;
|
||||
bool _noerror = false;
|
||||
bool _all = false;
|
||||
std::string _type = "value";
|
||||
string zw;
|
||||
|
||||
ESP_LOGD(TAG, "handler_wasserzaehler uri: %s", req->uri);
|
||||
|
||||
char _query[100];
|
||||
char _size[10];
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
if (FlowInitDone)
|
||||
{
|
||||
// ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK)
|
||||
bool _rawValue = false;
|
||||
bool _noerror = false;
|
||||
bool _all = false;
|
||||
std::string _type = "value";
|
||||
string zw;
|
||||
|
||||
ESP_LOGD(TAG, "handler_wasserzaehler uri: %s", req->uri);
|
||||
|
||||
char _query[100];
|
||||
char _size[10];
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found%s", _size);
|
||||
#endif
|
||||
_all = true;
|
||||
// ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found%s", _size);
|
||||
#endif
|
||||
_all = true;
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found: %s", _size);
|
||||
#endif
|
||||
_type = std::string(_size);
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "rawvalue is found: %s", _size);
|
||||
#endif
|
||||
_rawValue = true;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "noerror is found: %s", _size);
|
||||
#endif
|
||||
_noerror = true;
|
||||
}
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (_all)
|
||||
{
|
||||
httpd_resp_set_type(req, "text/plain");
|
||||
ESP_LOGD(TAG, "TYPE: %s", _type.c_str());
|
||||
int _intype = READOUT_TYPE_VALUE;
|
||||
if (_type == "prevalue")
|
||||
_intype = READOUT_TYPE_PREVALUE;
|
||||
if (_type == "raw")
|
||||
_intype = READOUT_TYPE_RAWVALUE;
|
||||
if (_type == "error")
|
||||
_intype = READOUT_TYPE_ERROR;
|
||||
|
||||
|
||||
zw = tfliteflow.getReadoutAll(_intype);
|
||||
ESP_LOGD(TAG, "ZW: %s", zw.c_str());
|
||||
if (zw.length() > 0)
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "all is found: %s", _size);
|
||||
#endif
|
||||
_type = std::string(_size);
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "rawvalue is found: %s", _size);
|
||||
#endif
|
||||
_rawValue = true;
|
||||
}
|
||||
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "noerror is found: %s", _size);
|
||||
#endif
|
||||
_noerror = true;
|
||||
}
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (_all)
|
||||
{
|
||||
httpd_resp_set_type(req, "text/plain");
|
||||
ESP_LOGD(TAG, "TYPE: %s", _type.c_str());
|
||||
int _intype = READOUT_TYPE_VALUE;
|
||||
if (_type == "prevalue")
|
||||
_intype = READOUT_TYPE_PREVALUE;
|
||||
if (_type == "raw")
|
||||
_intype = READOUT_TYPE_RAWVALUE;
|
||||
if (_type == "error")
|
||||
_intype = READOUT_TYPE_ERROR;
|
||||
|
||||
|
||||
zw = tfliteflow.getReadoutAll(_intype);
|
||||
ESP_LOGD(TAG, "ZW: %s", zw.c_str());
|
||||
zw = tfliteflow.getReadout(_rawValue, _noerror);
|
||||
if (zw.length() > 0)
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
zw = tfliteflow.getReadout(_rawValue, _noerror);
|
||||
if (zw.length() > 0)
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
|
||||
string query = std::string(_query);
|
||||
// ESP_LOGD(TAG, "Query: %s, query.c_str());
|
||||
if (query.find("full") != std::string::npos)
|
||||
{
|
||||
string txt, zw;
|
||||
|
||||
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg_roi.jpg\"> <p>\n";
|
||||
txt = txt + "Digital Counter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfodig;
|
||||
htmlinfodig = tfliteflow.GetAllDigital();
|
||||
|
||||
for (int i = 0; i < htmlinfodig.size(); ++i)
|
||||
string query = std::string(_query);
|
||||
// ESP_LOGD(TAG, "Query: %s, query.c_str());
|
||||
if (query.find("full") != std::string::npos)
|
||||
{
|
||||
if (tfliteflow.GetTypeDigital() == Digital)
|
||||
{
|
||||
if (htmlinfodig[i]->val == 10)
|
||||
zw = "NaN";
|
||||
else
|
||||
zw = to_string((int) htmlinfodig[i]->val);
|
||||
string txt, zw;
|
||||
|
||||
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg_roi.jpg\"> <p>\n";
|
||||
txt = txt + "Digital Counter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfodig;
|
||||
htmlinfodig = tfliteflow.GetAllDigital();
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"> " + zw;
|
||||
for (int i = 0; i < htmlinfodig.size(); ++i)
|
||||
{
|
||||
if (tfliteflow.GetTypeDigital() == Digital)
|
||||
{
|
||||
if (htmlinfodig[i]->val == 10)
|
||||
zw = "NaN";
|
||||
else
|
||||
zw = to_string((int) htmlinfodig[i]->val);
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"> " + zw;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfodig[i]->val;
|
||||
zw = stream.str();
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"> " + zw;
|
||||
}
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfodig[i];
|
||||
}
|
||||
else
|
||||
htmlinfodig.clear();
|
||||
|
||||
txt = " <p> Analog Meter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfoana;
|
||||
htmlinfoana = tfliteflow.GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfoana.size(); ++i)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfodig[i]->val;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfoana[i]->val;
|
||||
zw = stream.str();
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfodig[i]->filename + "\"> " + zw;
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfoana[i]->filename + "\"> " + zw;
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfoana[i];
|
||||
}
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfodig[i];
|
||||
}
|
||||
htmlinfodig.clear();
|
||||
|
||||
txt = " <p> Analog Meter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfoana;
|
||||
htmlinfoana = tfliteflow.GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfoana.size(); ++i)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfoana[i]->val;
|
||||
zw = stream.str();
|
||||
htmlinfoana.clear();
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfoana[i]->filename + "\"> " + zw;
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfoana[i];
|
||||
}
|
||||
htmlinfoana.clear();
|
||||
}
|
||||
|
||||
}
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Value API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
|
||||
#endif
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Start");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "handler_editflow uri: %s", req->uri);
|
||||
|
||||
@@ -388,9 +406,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "task is found: %s", _valuechar);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "task is found: %s", _valuechar);
|
||||
#endif
|
||||
_task = string(_valuechar);
|
||||
}
|
||||
}
|
||||
@@ -423,10 +441,10 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
httpd_query_key_value(_query, "out", _valuechar, 30);
|
||||
out = string(_valuechar);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "in: %s", in.c_str());
|
||||
ESP_LOGD(TAG, "out: %s", out.c_str());
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "in: %s", in.c_str());
|
||||
ESP_LOGD(TAG, "out: %s", out.c_str());
|
||||
#endif
|
||||
|
||||
in = "/sdcard" + in;
|
||||
out = "/sdcard" + out;
|
||||
@@ -465,14 +483,14 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
zw = string(_valuechar);
|
||||
dy = stoi(zw);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "in: %s", in.c_str());
|
||||
ESP_LOGD(TAG, "out: %s", out.c_str());
|
||||
ESP_LOGD(TAG, "x: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "y: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "dx: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "dy: %s", zw.c_str());
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "in: %s", in.c_str());
|
||||
ESP_LOGD(TAG, "out: %s", out.c_str());
|
||||
ESP_LOGD(TAG, "x: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "y: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "dx: %s", zw.c_str());
|
||||
ESP_LOGD(TAG, "dy: %s", zw.c_str());
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
|
||||
{
|
||||
@@ -566,103 +584,144 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Done");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_editflow - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
if (FlowInitDone)
|
||||
{
|
||||
const char* resp_str;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
#endif
|
||||
|
||||
string* zw = tfliteflow.getActStatus();
|
||||
resp_str = zw->c_str();
|
||||
string* zw = tfliteflow.getActStatus();
|
||||
resp_str = zw->c_str();
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Flowstatus API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_cputemp(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
char cputemp[20];
|
||||
|
||||
sprintf(cputemp, "CPU Temp: %4.1f°C", temperatureRead());
|
||||
sprintf(cputemp, "%4.1f°C", temperatureRead());
|
||||
|
||||
resp_str = cputemp;
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - End");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_rssi(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - Start");
|
||||
#endif
|
||||
|
||||
if (getWIFIisConnected())
|
||||
{
|
||||
const char* resp_str;
|
||||
char rssi[20];
|
||||
|
||||
sprintf(rssi, "%idBm", get_WIFI_RSSI());
|
||||
|
||||
resp_str = rssi;
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "RSSI API not yet initialized. Please retry later...");
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_uptime(httpd_req_t *req)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - Start");
|
||||
LogFile.WriteHeapInfo("handler_uptime - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
char rssi[20];
|
||||
|
||||
sprintf(rssi, "RSSI: %idBm", get_WIFI_RSSI());
|
||||
|
||||
resp_str = rssi;
|
||||
|
||||
std::string formatedUptime = getFormatedUptime(false);
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
httpd_resp_send(req, formatedUptime.c_str(), strlen(formatedUptime.c_str()));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - End");
|
||||
LogFile.WriteHeapInfo("handler_uptime - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
#endif
|
||||
|
||||
char _query[100];
|
||||
char _size[10] = "";
|
||||
@@ -670,15 +729,15 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Value: %s", _size);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Value: %s", _size);
|
||||
#endif
|
||||
}
|
||||
|
||||
httpd_query_key_value(_query, "numbers", _numbers, 50);
|
||||
@@ -702,12 +761,13 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - End");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void task_autodoFlow(void *pvParameter)
|
||||
{
|
||||
@@ -717,6 +777,7 @@ void task_autodoFlow(void *pvParameter)
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Restarted due to an Exception/panic! Postponing first round start by 5 minutes to allow for an OTA or to fetch the log!");
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Setting logfile level to DEBUG until the next reboot!");
|
||||
LogFile.setLogLevel(ESP_LOG_DEBUG);
|
||||
//MQTTPublish(GetMQTTMainTopic() + "/" + "status", "Postponing first round", false);
|
||||
vTaskDelay(60*5000 / portTICK_RATE_MS); // Wait 5 minutes to give time to do an OTA or fetch the log
|
||||
}
|
||||
|
||||
@@ -734,37 +795,39 @@ void task_autodoFlow(void *pvParameter)
|
||||
while (auto_isrunning)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "----------------------------------------------------------------"); // Clear separation between runs
|
||||
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
|
||||
std::string _zw = "Round #" + std::to_string(++countRounds) + " started";
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
|
||||
fr_start = esp_timer_get_time();
|
||||
|
||||
if (flowisrunning)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is already running!");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is already running!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is started");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Autoflow: doFlow is started");
|
||||
#endif
|
||||
flowisrunning = true;
|
||||
doflow();
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Remove older log files");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Remove older log files");
|
||||
#endif
|
||||
LogFile.RemoveOldLogFile();
|
||||
LogFile.RemoveOldDataLog();
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "task_autodoFlow - round #" + std::to_string(countRounds) + " done");
|
||||
//CPU Temp
|
||||
float cputmp = temperatureRead();
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << cputmp;
|
||||
string zwtemp = "CPU Temperature: " + stream.str();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, zwtemp);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zwtemp);
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Round #" + std::to_string(countRounds) + " completed");
|
||||
|
||||
fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000;
|
||||
if (auto_intervall > fr_delta_ms)
|
||||
{
|
||||
@@ -778,6 +841,7 @@ void task_autodoFlow(void *pvParameter)
|
||||
ESP_LOGD(TAG, "task_autodoFlow: end");
|
||||
}
|
||||
|
||||
|
||||
void TFliteDoAutoStart()
|
||||
{
|
||||
BaseType_t xReturned;
|
||||
@@ -795,15 +859,15 @@ void TFliteDoAutoStart()
|
||||
ESP_LOGD(TAG, "ERROR task_autodoFlow konnte nicht erzeugt werden!");
|
||||
}
|
||||
ESP_LOGD(TAG, "getESPHeapInfo: %s", getESPHeapInfo().c_str());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
std::string GetMQTTMainTopic()
|
||||
{
|
||||
return tfliteflow.GetMQTTMainTopic();
|
||||
}
|
||||
|
||||
#endif//ENABLE_MQTT
|
||||
|
||||
|
||||
void register_server_tflite_uri(httpd_handle_t server)
|
||||
@@ -866,6 +930,11 @@ void register_server_tflite_uri(httpd_handle_t server)
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/uptime";
|
||||
camuri.handler = handler_uptime;
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/editflow";
|
||||
camuri.handler = handler_editflow;
|
||||
camuri.user_ctx = (void*) "EditFlow";
|
||||
|
||||
@@ -15,7 +15,9 @@ void TFliteDoAutoStart();
|
||||
|
||||
bool isSetupModusActive();
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
std::string GetMQTTMainTopic();
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
int getCountFlowRounds();
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ bool setup_time()
|
||||
|
||||
// Is time set? If not, tm_year will be (1970 - 1900).
|
||||
if (!getTimeIsSet()) {
|
||||
ESP_LOGI(TAG, "Time is not set yet. Getting time over NTP.");
|
||||
initialize_sntp();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is not set yet. Getting time over NTP server " + std::string(sntp_getservername(0)));
|
||||
if (!obtain_time()) {
|
||||
success = false;
|
||||
}
|
||||
@@ -103,9 +103,9 @@ static bool obtain_time(void)
|
||||
bool success = true;
|
||||
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
localtime_r(&now, &timeinfo);
|
||||
|
||||
ESP_LOGI(TAG, "Waiting until we get a time from the NTP server...");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Waiting until we get a time from the NTP server " + std::string(sntp_getservername(0)));
|
||||
while (true) {
|
||||
retry++;
|
||||
|
||||
@@ -118,7 +118,7 @@ static bool obtain_time(void)
|
||||
sntp_sync_status_t status = sntp_get_sync_status();
|
||||
logNtpStatus(status);
|
||||
if (status == SNTP_SYNC_STATUS_COMPLETED) {
|
||||
ESP_LOGI(TAG, "Time is synced with NTP Server");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is synced with NTP Server " + std::string(sntp_getservername(0)));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -133,23 +133,23 @@ static bool obtain_time(void)
|
||||
|
||||
void logNtpStatus(sntp_sync_status_t status) {
|
||||
if (status == SNTP_SYNC_STATUS_COMPLETED) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "NTP Status OK");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status OK");
|
||||
}
|
||||
else if (status == SNTP_SYNC_STATUS_IN_PROGRESS) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "NTP Status: In Progress");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status: In Progress");
|
||||
}
|
||||
else { // SNTP_SYNC_STATUS_RESET
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "NTP Status: Reset");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status: Reset");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reset_servername(std::string _servername)
|
||||
{
|
||||
ESP_LOGD(TAG, "Set SNTP-Server: %s", _servername.c_str());
|
||||
sntp_stop();
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, _servername.c_str());
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Set SNTP-Server to " + std::string(sntp_getservername(0)));
|
||||
sntp_init();
|
||||
obtain_time();
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES nvs_flash jomjol_helper)
|
||||
REQUIRES nvs_flash jomjol_helper jomjol_mqtt)
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@@ -38,6 +41,7 @@ static EventGroupHandle_t s_wifi_event_group;
|
||||
static const char *TAG = "WIFI";
|
||||
|
||||
static int s_retry_num = 0;
|
||||
bool WIFIConnected = false;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
#define BLINK_GPIO GPIO_NUM_33
|
||||
@@ -113,9 +117,11 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
WIFIConnected = false;
|
||||
LEDBlinkTask(200, 1, true);
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
WIFIConnected = false;
|
||||
// if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
@@ -131,6 +137,14 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
s_retry_num = 0;
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
LEDBlinkTask(1000, 5, true);
|
||||
|
||||
WIFIConnected = true;
|
||||
#ifdef ENABLE_MQTT
|
||||
if (getMQTTisEnabled()) {
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
MQTT_Init(); // Init when WIFI is getting connected
|
||||
}
|
||||
#endif //ENABLE_MQTT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,17 +263,17 @@ void wifi_init_sta(const char *_ssid, const char *_password, const char *_hostna
|
||||
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||
* happened. */
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
#ifdef __HIDE_PASSWORD
|
||||
ESP_LOGI(TAG, "connected to ap SSID: %s, password: XXXXXXX", _ssid);
|
||||
#else
|
||||
ESP_LOGI(TAG, "connected to ap SSID: %s, password: %s", _ssid, _password);
|
||||
#endif
|
||||
#ifdef __HIDE_PASSWORD
|
||||
ESP_LOGI(TAG, "connected to ap SSID: %s, password: XXXXXXX", _ssid);
|
||||
#else
|
||||
ESP_LOGI(TAG, "connected to ap SSID: %s, password: %s", _ssid, _password);
|
||||
#endif
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
#ifdef __HIDE_PASSWORD
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID: %s, password: XXXXXXXX", _ssid);
|
||||
#else
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID: %s, password: %s", _ssid, _password);
|
||||
#endif
|
||||
#ifdef __HIDE_PASSWORD
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID: %s, password: XXXXXXXX", _ssid);
|
||||
#else
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID: %s, password: %s", _ssid, _password);
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||
}
|
||||
@@ -289,3 +303,7 @@ void wifi_init_sta(const char *_ssid, const char *_password)
|
||||
wifi_init_sta(_ssid, _password, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
bool getWIFIisConnected() {
|
||||
return WIFIConnected;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ void wifi_init_sta(const char *_ssid, const char *_password);
|
||||
std::string* getIPAddress();
|
||||
std::string* getSSID();
|
||||
int get_WIFI_RSSI();
|
||||
bool getWIFIisConnected();
|
||||
|
||||
extern std::string hostname;
|
||||
extern std::string std_hostname;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
manifest_hash: 45994dbfed009907994c31f6d279c5861a1eacbf219ce8b58e74e39b3393816a
|
||||
manifest_hash: 4e37bb0f9273c4de05f38688720fe32aa6e5b892452694a4f7a2ca1659f02cf6
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
|
||||
@@ -41,9 +41,9 @@ const char* GIT_BRANCH=\"${GIT_BRANCH}\";
|
||||
const char* BUILD_TIME=\"${BUILD_TIME}\";")
|
||||
|
||||
if ("${GIT_TAG}" STREQUAL "") # Tag not set, show branch
|
||||
set(VERSION_HTML "Development-Branch: ${GIT_BRANCH} (Commit: ${GIT_REV}${GIT_DIFF})")
|
||||
set(VERSION_HTML "Development-Branch: ${GIT_BRANCH} (Commit: ${GIT_REV}${GIT_DIFF})\n${GIT_REV}")
|
||||
else() # Tag is set, ignore branch
|
||||
set(VERSION_HTML "Release: ${GIT_TAG} (Commit: ${GIT_REV}${GIT_DIFF})")
|
||||
set(VERSION_HTML "Release: ${GIT_TAG} (Commit: ${GIT_REV}${GIT_DIFF})\n${GIT_REV}")
|
||||
endif()
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp)
|
||||
@@ -65,5 +65,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/main/*.*)
|
||||
# idf_component_register(SRCS ${app_sources})
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
INCLUDE_DIRS "."
|
||||
# REQUIRES esp_psram) # comming in IDF 5.0
|
||||
)
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "sdkconfig.h"
|
||||
//#include "esp_psram.h" // Comming in IDF 5.0, see https://docs.espressif.com/projects/esp-idf/en/v5.0-beta1/esp32/migration-guides/release-5.x/system.html?highlight=esp_psram_get_size
|
||||
#include "esp32/spiram.h"
|
||||
|
||||
// SD-Card ////////////////////
|
||||
#include "nvs_flash.h"
|
||||
@@ -27,7 +29,9 @@
|
||||
#include "ClassControllCamera.h"
|
||||
#include "server_main.h"
|
||||
#include "server_camera.h"
|
||||
#include "server_mqtt.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "server_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
#include "Helper.h"
|
||||
|
||||
extern const char* GIT_TAG;
|
||||
@@ -35,7 +39,8 @@ extern const char* GIT_REV;
|
||||
extern const char* GIT_BRANCH;
|
||||
extern const char* BUILD_TIME;
|
||||
|
||||
extern const char* getHTMLversion(void);
|
||||
extern std::string getHTMLversion(void);
|
||||
extern std::string getHTMLcommit(void);
|
||||
|
||||
#define __HIDE_PASSWORD
|
||||
|
||||
@@ -119,7 +124,7 @@ bool Init_NVS_SDCard()
|
||||
return true;
|
||||
}
|
||||
|
||||
void task_NoSDBlink(void *pvParameter)
|
||||
void task_MainInitError_blink(void *pvParameter)
|
||||
{
|
||||
gpio_pad_select_gpio(BLINK_GPIO);
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
@@ -144,7 +149,6 @@ void task_NoSDBlink(void *pvParameter)
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
TickType_t xDelay;
|
||||
bool initSucessful = true;
|
||||
|
||||
ESP_LOGI(TAG, "\n\n\n\n\n"); // Add mark on log to see when it restarted
|
||||
|
||||
@@ -157,9 +161,9 @@ extern "C" void app_main(void)
|
||||
|
||||
if (!Init_NVS_SDCard())
|
||||
{
|
||||
xTaskCreate(&task_NoSDBlink, "task_NoSDBlink", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, NULL);
|
||||
return;
|
||||
};
|
||||
xTaskCreate(&task_MainInitError_blink, "task_MainInitError_blink", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, NULL);
|
||||
return; // No way to continue without SD-Card!
|
||||
}
|
||||
|
||||
string versionFormated = "Branch: '" + std::string(GIT_BRANCH) + \
|
||||
"', Revision: " + std::string(GIT_REV) +", Date/Time: " + std::string(BUILD_TIME) + \
|
||||
@@ -169,26 +173,16 @@ extern "C" void app_main(void)
|
||||
string versionFormated = "Tag: '" + std::string(GIT_TAG) + "', " + versionFormated;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "=============================================================================================");
|
||||
ESP_LOGD(TAG, "%s", versionFormated.c_str());
|
||||
ESP_LOGD(TAG, "=============================================================================================");
|
||||
ESP_LOGD(TAG, "Reset reason: %s", getResetReason().c_str());
|
||||
|
||||
LogFile.CreateLogDirectories();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "==================== Startup ====================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, versionFormated);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reset reason: " + getResetReason());
|
||||
|
||||
CheckOTAUpdate();
|
||||
|
||||
LogFile.CreateLogDirectories();
|
||||
CheckUpdate();
|
||||
/*
|
||||
int mk_ret = mkdir("/sdcard/new_fd_mkdir", 0775);
|
||||
ESP_LOGI(TAG, "mkdir ret %d", mk_ret);
|
||||
mk_ret = mkdir("/sdcard/new_fd_mkdir/test", 0775);
|
||||
ESP_LOGI(TAG, "mkdir ret %d", mk_ret);
|
||||
MakeDir("/sdcard/test2");
|
||||
MakeDir("/sdcard/test2/intern");
|
||||
*/
|
||||
|
||||
|
||||
char *ssid = NULL, *passwd = NULL, *hostname = NULL, *ip = NULL, *gateway = NULL, *netmask = NULL, *dns = NULL;
|
||||
LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns);
|
||||
@@ -204,7 +198,7 @@ extern "C" void app_main(void)
|
||||
ESP_LOGD(TAG, "No SSID and PASSWORD set!!!");
|
||||
|
||||
if (hostname != NULL)
|
||||
ESP_LOGD(TAG, "Hostename: %s", hostname);
|
||||
ESP_LOGD(TAG, "Hostname: %s", hostname);
|
||||
else
|
||||
ESP_LOGD(TAG, "Hostname not set");
|
||||
|
||||
@@ -222,32 +216,49 @@ extern "C" void app_main(void)
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
if (!setup_time()) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed. Will restart in 5 minutes!");
|
||||
initSucessful = false;
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed!");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_NTP_BAD);
|
||||
}
|
||||
|
||||
setBootTime();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=============================================================================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================== Main Started ============================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=============================================================================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, versionFormated);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reset reason: " + getResetReason());
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================== Main Started =================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
|
||||
if (std::string(getHTMLversion()) != std::string(GIT_REV)) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Web UI version does not match firmware version!");
|
||||
if (getHTMLcommit().substr(0, 7) != std::string(GIT_REV).substr(0, 7)) { // Compare the first 7 characters of both hashes
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Web UI version (") + getHTMLcommit() + ") does not match firmware version (" + std::string(GIT_REV) + ") !");
|
||||
}
|
||||
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
ESP_LOGD(TAG, "time %s", zw.c_str());
|
||||
|
||||
/* Check if PSRAM can be initalized */
|
||||
esp_err_t ret;
|
||||
ret = esp_spiram_init();
|
||||
if (ret == ESP_FAIL) { // Failed to init PSRAM, most likely not available or broken
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize PSRAM (" + std::to_string(ret) + ")!");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Either your device misses the PSRAM chip or it is broken!");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
}
|
||||
else { // PSRAM init ok
|
||||
/* Check if PSRAM provides at least 4 MB */
|
||||
size_t psram_size = esp_spiram_get_size();
|
||||
// size_t psram_size = esp_psram_get_size(); // comming in IDF 5.0
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "The device has " + std::to_string(psram_size/1024/1024) + " MBytes of PSRAM");
|
||||
if (psram_size < (4*1024*1024)) { // PSRAM is below 4 MBytes
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "At least 4 MBytes are required!");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Does the device really have a 4 Mbytes PSRAM?");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check available Heap memory */
|
||||
size_t _hsize = getESPHeapSize();
|
||||
if (_hsize < 4000000)
|
||||
{
|
||||
std::string _zws = "Not enough PSRAM available. Expected 4.194.304 MByte - available: " + std::to_string(_hsize);
|
||||
_zws = _zws + "\nEither not initialized, too small (2MByte only) or not present at all. Firmware cannot start!!";
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, _zws);
|
||||
} else { // Bad Camera Status, retry init
|
||||
if (_hsize < 4000000) { // Check available Heap memory for a bit less than 4 MB (a test on a good device showed 4187558 bytes to be available)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Not enough Heap memory available. Expected around 4 MBytes, but only " + std::to_string(_hsize) + " Bytes are available! That is not enough for this firmware!");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_HEAP_TOO_SMALL);
|
||||
} else { // Heap memory is ok
|
||||
if (camStatus != ESP_OK) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Failed to initialize camera module, retrying...");
|
||||
|
||||
@@ -259,15 +270,18 @@ extern "C" void app_main(void)
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
if (camStatus != ESP_OK) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize camera module. Will restart in 5 minutes!");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize camera module!");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Check that your camera module is working and connected properly!");
|
||||
initSucessful = false;
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_BAD);
|
||||
}
|
||||
} else { // Test Camera
|
||||
camera_fb_t * fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera Framebuffer cannot be initialzed. Will restart in 5 minutes!");
|
||||
initSucessful = false;
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera Framebuffer cannot be initialized!");
|
||||
/* Easiest would be to simply restart here and try again,
|
||||
how ever there seem to be systems where it fails at startup but still work corectly later.
|
||||
Therefore we treat it still as successed! */
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD);
|
||||
}
|
||||
else {
|
||||
esp_camera_fb_return(fb);
|
||||
@@ -276,8 +290,6 @@ extern "C" void app_main(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
xDelay = 2000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "main: sleep for: %ldms", (long) xDelay*10);
|
||||
vTaskDelay( xDelay );
|
||||
@@ -289,24 +301,33 @@ extern "C" void app_main(void)
|
||||
register_server_tflite_uri(server);
|
||||
register_server_file_uri(server, "/sdcard");
|
||||
register_server_ota_sdcard_uri(server);
|
||||
register_server_mqtt_uri(server);
|
||||
#ifdef ENABLE_MQTT
|
||||
register_server_mqtt_uri(server);
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
gpio_handler_create(server);
|
||||
|
||||
ESP_LOGD(TAG, "vor reg server main");
|
||||
register_server_main_uri(server, "/sdcard");
|
||||
|
||||
if (initSucessful) {
|
||||
|
||||
/* Testing */
|
||||
//setSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD);
|
||||
//setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
|
||||
/* Main Init has successed or only an error which allows to continue operation */
|
||||
if (getSystemStatus() == 0) { // No error flag is set
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Initialization completed successfully!");
|
||||
ESP_LOGD(TAG, "vor do autostart");
|
||||
TFliteDoAutoStart();
|
||||
}
|
||||
else { // Initialization failed
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Will restart in 5 minutes!");
|
||||
vTaskDelay(60*4000 / portTICK_RATE_MS); // Wait 4 minutes to give time to do an OTA or fetch the log
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Will restart in 1 minute!");
|
||||
vTaskDelay(60*1000 / portTICK_RATE_MS); // Wait 1 minute to give time to do an OTA or fetch the log
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Will restart now!");
|
||||
doReboot();
|
||||
else if (isSetSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD) || // Non critical errors occured, we try to continue...
|
||||
isSetSystemStatusFlag(SYSTEM_STATUS_NTP_BAD)) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Initialization completed with errors, but trying to continue...");
|
||||
ESP_LOGD(TAG, "vor do autostart");
|
||||
TFliteDoAutoStart();
|
||||
}
|
||||
else { // Any other error is critical and makes running the flow impossible.
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Not starting flows!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
||||
}
|
||||
else if (_task.compare("HTMLVersion") == 0)
|
||||
{
|
||||
httpd_resp_sendstr_chunk(req, getHTMLversion());
|
||||
httpd_resp_sendstr_chunk(req, getHTMLversion().c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -128,6 +128,14 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
else if (_task.compare("Round") == 0)
|
||||
{
|
||||
char formated[10] = "";
|
||||
snprintf(formated, sizeof(formated), "%d", getCountFlowRounds());
|
||||
httpd_resp_sendstr_chunk(req, formated);
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
else if (_task.compare("SDCardPartitionSize") == 0)
|
||||
{
|
||||
std::string zw;
|
||||
@@ -230,9 +238,33 @@ esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
if (filetosend == "/sdcard/html/index.html" && isSetupModusActive()) {
|
||||
ESP_LOGD(TAG, "System is in setup mode --> index.html --> setup.html");
|
||||
filetosend = "/sdcard/html/setup.html";
|
||||
if (filetosend == "/sdcard/html/index.html") {
|
||||
if (isSetSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD) || // Initialization failed with crritical errors!
|
||||
isSetSystemStatusFlag(SYSTEM_STATUS_CAM_BAD)) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "We have a critical error, not serving main page!");
|
||||
|
||||
char buf[20];
|
||||
std::string message = "<h1>AI on the Edge Device</h1><b>We have one or more critical errors:</b><br>";
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (isSetSystemStatusFlag((SystemStatusFlag_t)(1<<i))) {
|
||||
snprintf(buf, sizeof(buf), "0x%08X", 1<<i);
|
||||
message += std::string(buf) + "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
message += "<br>Please check <a href=\"https://github.com/jomjol/AI-on-the-edge-device/wiki/Error-Codes\" target=_blank>github.com/jomjol/AI-on-the-edge-device/wiki/Error-Codes</a> for more information!";
|
||||
message += "<br><br><button onclick=\"window.location.href='/reboot';\">Reboot</button>";
|
||||
message += " <button onclick=\"window.open('/ota_page.html');\">OTA Update</button>";
|
||||
message += " <button onclick=\"window.open('/log.html');\">Log Viewer</button>";
|
||||
message += " <button onclick=\"window.open('/info.html');\">Show System Info</button>";
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, message.c_str());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
else if (isSetupModusActive()) {
|
||||
ESP_LOGD(TAG, "System is in setup mode --> index.html --> setup.html");
|
||||
filetosend = "/sdcard/html/setup.html";
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Filename: %s", filename);
|
||||
@@ -241,8 +273,8 @@ esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
|
||||
if (!filename) {
|
||||
ESP_LOGE(TAG, "Filename is too long");
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
/* Respond with 414 Error */
|
||||
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -427,9 +459,9 @@ httpd_handle_t start_webserver(void)
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = { };
|
||||
|
||||
config.task_priority = tskIDLE_PRIORITY+1; // 20210924 --> vorher +5
|
||||
config.task_priority = tskIDLE_PRIORITY+3; //20221211: before: tskIDLE_PRIORITY+1; // 20210924 --> vorher +5
|
||||
config.stack_size = 32768; //20210921 --> vorher 32768 // bei 32k stürzt das Programm beim Bilderaufnehmen ab
|
||||
config.core_id = tskNO_AFFINITY;
|
||||
config.core_id = 0; //20221211 --> force all not flow related tasks to CPU0, before: tskNO_AFFINITY;
|
||||
config.server_port = 80;
|
||||
config.ctrl_port = 32768;
|
||||
config.max_open_sockets = 5; //20210921 --> vorher 7
|
||||
@@ -437,8 +469,8 @@ httpd_handle_t start_webserver(void)
|
||||
config.max_resp_headers = 8;
|
||||
config.backlog_conn = 5;
|
||||
config.lru_purge_enable = true; // dadurch werden alte Verbindungen gekappt, falls neue benögt werden.
|
||||
config.recv_wait_timeout = 5; // default: 5 20210924 --> vorher 30
|
||||
config.send_wait_timeout = 5; // default: 5 20210924 --> vorher 30
|
||||
config.recv_wait_timeout = 5; // default: 5 20210924 --> vorher 30
|
||||
config.send_wait_timeout = 5; // default: 5 20210924 --> vorher 30
|
||||
config.global_user_ctx = NULL;
|
||||
config.global_user_ctx_free_fn = NULL;
|
||||
config.global_transport_ctx = NULL;
|
||||
|
||||
@@ -38,20 +38,35 @@ const char* libfive_git_branch(void)
|
||||
}
|
||||
|
||||
|
||||
char _char_getHTMLversion[100]="?\0";
|
||||
|
||||
const char* getHTMLversion(void){
|
||||
std::string getHTMLversion(void){
|
||||
char buf[100]="?\0";
|
||||
FILE* pFile;
|
||||
string fn = FormatFileName("/sdcard/html/version.txt");
|
||||
pFile = fopen(fn.c_str(), "r");
|
||||
|
||||
if (pFile == NULL)
|
||||
return _char_getHTMLversion;
|
||||
return std::string(buf);
|
||||
|
||||
fgets(_char_getHTMLversion, sizeof(_char_getHTMLversion), pFile);
|
||||
fgets(buf, sizeof(buf), pFile); // Line 1: Version
|
||||
fclose(pFile);
|
||||
|
||||
return _char_getHTMLversion;
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
std::string getHTMLcommit(void){
|
||||
char buf[100]="?\0";
|
||||
FILE* pFile;
|
||||
string fn = FormatFileName("/sdcard/html/version.txt");
|
||||
pFile = fopen(fn.c_str(), "r");
|
||||
|
||||
if (pFile == NULL)
|
||||
return std::string(buf);
|
||||
|
||||
fgets(buf, sizeof(buf), pFile); // Line 1: Version -> ignored
|
||||
fgets(buf, sizeof(buf), pFile); // Line 2: Commit
|
||||
fclose(pFile);
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
#endif // _VERSION_H
|
||||
@@ -13,31 +13,33 @@
|
||||
src_dir = main
|
||||
|
||||
[env:esp32cam]
|
||||
platform = espressif32@4.4.0
|
||||
;platform = espressif32@5.1.0
|
||||
;platform = espressif32
|
||||
platform = espressif32@5.2.0
|
||||
board = esp32cam
|
||||
;board = m5stack-core-esp32
|
||||
framework = espidf
|
||||
|
||||
;Add macro definition ENABLE_MQTT, ENABLE_INFLUXDB
|
||||
build_flags = -D ENABLE_MQTT -D ENABLE_INFLUXDB
|
||||
|
||||
;board_build.partitions = partitions_singleapp.csv
|
||||
board_build.partitions = partitions.csv
|
||||
|
||||
lib_deps =
|
||||
jomjol_configfile
|
||||
jomjol_helper
|
||||
jomjol_wlan
|
||||
jomjol_image_proc
|
||||
jomjol_controlcamera
|
||||
jomjol_flowcontroll
|
||||
jomjol_tfliteclass
|
||||
tflite-lib
|
||||
jomjol_fileserver_ota
|
||||
jomjol_time_sntp
|
||||
jomjol_logfile
|
||||
jomjol_mqtt
|
||||
jomjol_influxdb
|
||||
jomjol_controlGPIO
|
||||
;lib_deps not needed
|
||||
;lib_deps =
|
||||
; jomjol_configfile
|
||||
; jomjol_helper
|
||||
; jomjol_wlan
|
||||
; jomjol_image_proc
|
||||
; jomjol_controlcamera
|
||||
; jomjol_flowcontroll
|
||||
; jomjol_tfliteclass
|
||||
; tflite-lib
|
||||
; jomjol_fileserver_ota
|
||||
; jomjol_time_sntp
|
||||
; jomjol_logfile
|
||||
; jomjol_mqtt
|
||||
; jomjol_influxdb
|
||||
; jomjol_controlGPIO
|
||||
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -34,30 +34,33 @@ CONFIG_SPIRAM_BOOT_INIT=y
|
||||
CONFIG_SPIRAM_USE_MALLOC=y
|
||||
CONFIG_SPIRAM_MEMTEST=y
|
||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=40960
|
||||
CONFIG_SPIRAM_CACHE_WORKAROUND=y
|
||||
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
|
||||
|
||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
||||
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
|
||||
|
||||
CONFIG_HTTPD_PURGE_BUF_LEN=16
|
||||
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
|
||||
|
||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16
|
||||
|
||||
CONFIG_FATFS_LFN_HEAP=y
|
||||
|
||||
CONFIG_FATFS_MAX_LFN=255
|
||||
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
|
||||
|
||||
CONFIG_FMB_TIMER_PORT_ENABLED=y
|
||||
|
||||
CONFIG_MQTT_MSG_ID_INCREMENTAL=y
|
||||
CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED=y
|
||||
CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED=y
|
||||
CONFIG_MQTT_USE_CORE_0=y
|
||||
|
||||
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=n
|
||||
|
||||
CONFIG_CAMERA_CORE0=n
|
||||
CONFIG_CAMERA_CORE1=y
|
||||
CONFIG_OV7670_SUPPORT=n
|
||||
CONFIG_OV7725_SUPPORT=n
|
||||
CONFIG_NT99141_SUPPORT=n
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "test_flow_postrocess_helper.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "FLOW CTRL POSTPROC TEST";
|
||||
static const char *TAG = "POSTPROC TEST";
|
||||
|
||||
UnderTestPost* setUpClassFlowPostprocessing(t_CNNType digType, t_CNNType anaType)
|
||||
{
|
||||
|
||||
@@ -522,4 +522,24 @@ void test_doFlowPP3() {
|
||||
delete undertestPost;
|
||||
}
|
||||
|
||||
void test_doFlowPP4() {
|
||||
|
||||
// Fehler V13.0.4
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/1503#issuecomment-1343335855
|
||||
std::vector<float> digits = { 0.0, 0.0, 6.9, 1.0, 6.6}; // 716.0199 als falsches Ergebnis.
|
||||
// Test ist nur erfolgreich mit Veränderung des AnalogdigitTransistionStart
|
||||
std::vector<float> analogs = {9.9, 1.8, 6.6, 5.8};
|
||||
const char* expected = "717.0165";
|
||||
const char* expected_extended= "717.01658";
|
||||
|
||||
// extendResolution=false
|
||||
std::string result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ void test_getReadoutRawString() {
|
||||
gen_analog->ROI.push_back(anaROI);
|
||||
|
||||
result = _undertestPost->flowAnalog->getReadoutRawString(0);
|
||||
TEST_ASSERT_EQUAL_STRING("\t5.5", result.c_str());
|
||||
TEST_ASSERT_EQUAL_STRING(",5.5", result.c_str());
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "driver/sdmmc_defs.h"
|
||||
static const char *TAG = "MAIN TEST";
|
||||
//static const char *TAG = "MAIN TEST";
|
||||
#define __SD_USE_ONE_LINE_MODE__
|
||||
#include "server_GPIO.h"
|
||||
|
||||
@@ -117,6 +117,7 @@ extern "C" void app_main()
|
||||
RUN_TEST(test_doFlowPP1);
|
||||
RUN_TEST(test_doFlowPP2);
|
||||
RUN_TEST(test_doFlowPP3);
|
||||
RUN_TEST(test_doFlowPP4);
|
||||
|
||||
// getReadoutRawString test
|
||||
RUN_TEST(test_getReadoutRawString);
|
||||
|
||||
25
docs/.gitignore
vendored
25
docs/.gitignore
vendored
@@ -1,25 +0,0 @@
|
||||
# Remove if certain files are committed on purpose
|
||||
.pio/
|
||||
.vscode/
|
||||
.code-workspace
|
||||
/sd-card/htm./.vscode/
|
||||
/code/build
|
||||
/code/.helper
|
||||
/sd-card/html/debug/
|
||||
/firmware/
|
||||
version.txt
|
||||
/dist/
|
||||
/dist_release/
|
||||
/dist_old_ota
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
code/edgeAI.code-workspace
|
||||
.DS_Store
|
||||
9
docs/.gitmodules
vendored
9
docs/.gitmodules
vendored
@@ -1,9 +0,0 @@
|
||||
[submodule "code/components/esp32-camera"]
|
||||
path = code/components/esp32-camera
|
||||
url = https://github.com/espressif/esp32-camera.git
|
||||
[submodule "code/components/esp-nn"]
|
||||
path = code/components/esp-nn
|
||||
url = https://github.com/espressif/esp-nn.git
|
||||
[submodule "code/components/tflite-micro-esp-examples"]
|
||||
path = code/components/tflite-micro-esp-examples
|
||||
url = https://github.com/espressif/tflite-micro-esp-examples.git
|
||||
@@ -27,6 +27,7 @@
|
||||
<p>Notes:</p>
|
||||
<ul>
|
||||
<li>For the installation, make sure to switch the ESP32 to Bootloader mode!</li>
|
||||
<li>The SD-Card still must be flashed separately on a PC (See in the <a href=https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation>Wiki</a>)!</li>
|
||||
<li>After the installation, a manual reset might be required!</li>
|
||||
<li>Please note that not all webbrowsers and operating systems support the needed access to USB!</li>
|
||||
<li>Check the <a href=https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation>Wiki</a> for additional information.</li>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "AI-on-the-edge",
|
||||
"version": "12.0.1",
|
||||
"version": "13.0.7",
|
||||
"funding_url": "https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL",
|
||||
"new_install_prompt_erase": false,
|
||||
"builds": [
|
||||
@@ -16,10 +16,10 @@
|
||||
"offset": 32768
|
||||
},
|
||||
{
|
||||
"path": "releases/download/v12.0.1/firmware.bin",
|
||||
"path": "releases/download/v13.0.7/firmware.bin",
|
||||
"offset": 65536
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
BIN
docs/releases/download/v12.0.5/firmware.bin
Normal file
BIN
docs/releases/download/v12.0.5/firmware.bin
Normal file
Binary file not shown.
BIN
docs/releases/download/v13.0.5/firmware.bin
Normal file
BIN
docs/releases/download/v13.0.5/firmware.bin
Normal file
Binary file not shown.
BIN
docs/releases/download/v13.0.7/firmware.bin
Normal file
BIN
docs/releases/download/v13.0.7/firmware.bin
Normal file
Binary file not shown.
BIN
sd-card/config/ana-class100_0154_s1_q.tflite
Normal file
BIN
sd-card/config/ana-class100_0154_s1_q.tflite
Normal file
Binary file not shown.
BIN
sd-card/config/ana-cont_1104_s2_q.tflite
Normal file
BIN
sd-card/config/ana-cont_1104_s2_q.tflite
Normal file
Binary file not shown.
@@ -94,7 +94,7 @@ LogfileRetentionInDays = 3
|
||||
|
||||
[System]
|
||||
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
|
||||
;TimeServer = undefined
|
||||
;TimeServer = pool.ntp.org
|
||||
;AutoAdjustSummertime = false
|
||||
;Hostname = undefined
|
||||
SetupMode = true
|
||||
|
||||
BIN
sd-card/config/dig-class100-0150_s2_q.tflite
Normal file
BIN
sd-card/config/dig-class100-0150_s2_q.tflite
Normal file
Binary file not shown.
@@ -100,6 +100,6 @@ function compareVersions() {
|
||||
console.log("FW Hash: " + fWGitHash + ", Web UI Hash: " + webUiHash);
|
||||
|
||||
if (fWGitHash != webUiHash) {
|
||||
alert("The Version of the Web Interface does not match the Firmware Version! It is suggested to keep them on the same version!");
|
||||
alert("The Version of the Web Interface (" + webUiHash + ") does not match the Firmware Version (" + fWGitHash + ")! It is suggested to keep them on the same version!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
#log {
|
||||
#data {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: small;
|
||||
}
|
||||
@@ -37,54 +37,36 @@
|
||||
<button onClick="reload();">Reload</button>
|
||||
<button onClick="window.open('datafileact');">Show full data</button>
|
||||
<button onClick="window.location.href = 'fileserver/log/data/'">Show older data files</button>
|
||||
<a href="graph.html" target="_self">Show graph</a>
|
||||
</div>
|
||||
<div class="row content" id="log"><br><br><br><b>Loading Logfile, please wait...</b></div>
|
||||
<div class="row content" id="data"><br><br><br><b>Loading Data file, please wait...</b></div>
|
||||
<div class="row footer">
|
||||
<button onClick="reload();">Reload</button>
|
||||
<button onClick="window.open('datafileact');">Show full data</button>
|
||||
<button onClick="window.location.href = 'fileserver/log/data/'">Show older data files</button>
|
||||
<a href="graph.html" target="_self">Show graph</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function reload() {
|
||||
// document.getElementById('log').innerHTML += "<br><b>Reloading...<b><br><br>";
|
||||
document.getElementById('log').innerHTML += "<b>Reloading...</b>";
|
||||
document.getElementById('data').innerHTML += "<br><b>Reloading...<b><br><br>";
|
||||
window.scrollBy(0,document.body.scrollHeight);
|
||||
funcRequest('log');
|
||||
funcRequest('data');
|
||||
}
|
||||
|
||||
|
||||
function processLogLine(line, index, arr) {
|
||||
if (line.includes("<WRN>")) {
|
||||
arr[index] = "<span style=\"color:#e83c00\">" + line + "</span>";
|
||||
}
|
||||
else if (line.includes("<ERR>")) {
|
||||
arr[index] = "<span style=\"color:red\"><b>" + line + "</b></span>";
|
||||
}
|
||||
else if (line.includes("<DBG>")) {
|
||||
arr[index] = "<span style=\"color:gray\">" + line + "</span>";
|
||||
}
|
||||
|
||||
arr[index] += "<br>";
|
||||
}
|
||||
|
||||
async function funcRequest(url){
|
||||
await fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
document.getElementById("log").innerHTML = "HTTP error " + res.status;
|
||||
document.getElementById("data").innerHTML = "HTTP error " + res.status;
|
||||
}
|
||||
|
||||
return res.text();
|
||||
})
|
||||
.then((log) => {
|
||||
log = log.replace(/</g, "<").replace(/>/g, ">");
|
||||
logArr = log.split("\n");
|
||||
logArr.forEach(processLogLine);
|
||||
|
||||
document.getElementById('log').innerHTML = "<br>" + logArr.join("\n") + " ";
|
||||
.then((data) => {
|
||||
document.getElementById('data').innerHTML = "<br>" + data.split("\n").join("\n<br>") + " ";
|
||||
|
||||
window.scrollBy(0,document.body.scrollHeight);
|
||||
|
||||
|
||||
@@ -1268,7 +1268,7 @@ textarea {
|
||||
<input type="number" id="AutoTimer_Intervall_value1" size="13" min="3" step="any">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
Interval in which the number(s) are read (in minutes). If a run takes longer than this interval, the next run gets postponed until the current run completes.
|
||||
Interval in which the number(s) are read (in minutes). If a digitalization round takes longer than this interval, the next run gets postponed until the current run completes.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ function getbasepath(){
|
||||
{
|
||||
// host = "http://192.168.2.219"; // jomjol interner test
|
||||
// host = "http://192.168.178.46"; // jomjol interner test
|
||||
host = "http://192.168.178.44"; // jomjol interner Real
|
||||
host = "http://192.168.178.46"; // jomjol interner Real
|
||||
// host = "http://192.168.43.191";
|
||||
// host = "."; // jomjol interner localhost
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script>
|
||||
async function loadPage(page) {
|
||||
console.log("loadPage(" + page + ")");
|
||||
document.cookie = page;
|
||||
document.cookie = "page="+page;
|
||||
document.getElementById('maincontent').src = page;
|
||||
|
||||
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
|
||||
@@ -28,6 +28,22 @@
|
||||
el.style.visibility = 'visible';
|
||||
});
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
@@ -63,7 +79,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<li><a href="#" onclick="loadPage('wasserzaehler.html?full');">Recognition</a></li>
|
||||
<li><a href="#" onclick="loadPage('value?full');">Recognition</a></li>
|
||||
<li><a href="#" onclick="loadPage('graph.html');">Data Graph</a></li>
|
||||
<li><a href="#" onclick="loadPage('fileserver/');">File Server</a></li>
|
||||
<li><a>System <i class="arrow down"></i></a>
|
||||
@@ -88,11 +104,11 @@
|
||||
LoadFwVersion();
|
||||
LoadWebUiVersion();
|
||||
|
||||
if (document.cookie == "" || document.cookie == "reboot_page.html") {
|
||||
document.cookie = "overview.html";
|
||||
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html") {
|
||||
document.cookie = "page=overview.html";
|
||||
}
|
||||
console.log("Loading page: " + document.cookie);
|
||||
document.getElementById('maincontent').src = document.cookie;
|
||||
console.log("Loading page: " + getCookie("page"));
|
||||
document.getElementById('maincontent').src = getCookie("page");
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -37,6 +37,16 @@ div {
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Uptime:
|
||||
</td>
|
||||
<td>
|
||||
<div id="uptime">
|
||||
<object data="/uptime"></object>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Build Info</h3>
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
|
||||
|
||||
function processLogLine(line, index, arr) {
|
||||
/* Make sure the whitespaces in the uptime field get persevered */
|
||||
uptimePart = line.slice(0, line.indexOf("]")).replace(/ /g, " ");
|
||||
line = uptimePart + line.slice(line.indexOf("]"))
|
||||
|
||||
if (line.includes("<WRN>")) {
|
||||
arr[index] = "<span style=\"color:#e83c00\">" + line + "</span>";
|
||||
}
|
||||
@@ -66,7 +70,10 @@
|
||||
else if (line.includes("<DBG>")) {
|
||||
arr[index] = "<span style=\"color:gray\">" + line + "</span>";
|
||||
}
|
||||
|
||||
else {
|
||||
arr[index] = line;
|
||||
}
|
||||
|
||||
arr[index] += "<br>";
|
||||
}
|
||||
|
||||
@@ -80,7 +87,8 @@
|
||||
return res.text();
|
||||
})
|
||||
.then((log) => {
|
||||
log = log.replace(/</g, "<").replace(/>/g, ">");
|
||||
log = log.replace(/</g, "<");
|
||||
log = log.replace(/>/g, ">");
|
||||
logArr = log.split("\n");
|
||||
logArr.forEach(processLogLine);
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ function extract() {
|
||||
document.getElementById("status").innerText = "Status: Update completed!";
|
||||
document.getElementById("doUpdate").disabled = true;
|
||||
document.getElementById("newfile").disabled = false;
|
||||
document.cookie = "overview.html"; // Make sure after the reboot we go to the overview page
|
||||
document.cookie = "page=overview.html"; // Make sure after the reboot we go to the overview page
|
||||
|
||||
if (xhttp.responseText.startsWith("reboot"))
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
.tg {border-collapse:collapse;border-spacing:0;width:100%;color: darkslategray;border: inset;height:585px;}
|
||||
.tg td{font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
|
||||
.tg th{height: 50px;font-size:24px;font-weight:bold;text-align:left;padding:0px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;background-color:#f0f0f0}
|
||||
.tg .tg-1{width:77%;font-size:20px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
|
||||
.tg .tg-1{width:700px;font-size:20px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
|
||||
.tg .tg-2{font-size:20px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
|
||||
.tg .tg-3{height: 15px;font-size:14px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
|
||||
</style>
|
||||
@@ -46,7 +46,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="th">Error:</th>
|
||||
<th class="th">Status:</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tg-2">
|
||||
@@ -58,7 +58,11 @@
|
||||
<div id="timestamp" ></div>
|
||||
<div id="statusflow" ></div>
|
||||
<div id="cputemp" ></div>
|
||||
<div id="rssi" ></div>
|
||||
<div id="rssi" ></div>
|
||||
<div>
|
||||
<span id="uptime" ></span>
|
||||
<span id="round" ></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -87,6 +91,8 @@ function addZero(i) {
|
||||
loadStatus();
|
||||
loadCPUTemp();
|
||||
loadRSSI();
|
||||
loadUptime();
|
||||
loadRoundCounter();
|
||||
refresh();
|
||||
});
|
||||
|
||||
@@ -116,12 +122,11 @@ function refresh() {
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
_rsp = "Status: " + _rsp;
|
||||
$('#statusflow').html(_rsp);
|
||||
$('#statusflow').html("Status: " + _rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadCPUTemp() {
|
||||
@@ -130,11 +135,11 @@ function refresh() {
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#cputemp').html(_rsp);
|
||||
$('#cputemp').html("CPU Temperature: " +_rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadRSSI() {
|
||||
@@ -143,15 +148,41 @@ function refresh() {
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#rssi').html(_rsp);
|
||||
$('#rssi').html("RSSI: " + _rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadUptime() {
|
||||
url = basepath + '/uptime';
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#uptime').html("Uptime: " + _rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadRoundCounter() {
|
||||
url = basepath + '/info?type=Round';
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#round').html("(Round: " + _rsp + ")");
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadValue(_type, _div, _style) {
|
||||
url = basepath + '/wasserzaehler.html?all=true&type=' + _type;
|
||||
url = basepath + '/value?all=true&type=' + _type;
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
@@ -199,6 +230,8 @@ function refresh() {
|
||||
loadStatus();
|
||||
loadCPUTemp();
|
||||
loadRSSI();
|
||||
loadUptime();
|
||||
loadRoundCounter();
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
@@ -706,7 +706,7 @@ function getNUMBERInfo(){
|
||||
}
|
||||
|
||||
function RenameNUMBER(_alt, _neu){
|
||||
if ((_neu.search(".") >= 0) || (_neu.search(",") >= 0) || (_neu.search(" ") >= 0) || (_neu.search("\"") >= 0))
|
||||
if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0))
|
||||
{
|
||||
return "Name must not contain ',', '.', ' ' or '\"' - please change name";
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var basepath = "http://192.168.178.22";
|
||||
function testinit(){
|
||||
basepath = getbasepath();
|
||||
url = basepath + '/wasserzaehler.html?all=true';
|
||||
url = basepath + '/value?all=true';
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript" src="./html/gethost.js">
|
||||
// Achtung dieses Script wird mit /fileserver aufgerufen, daher muss hier /html/gethost.js verwendet werden!
|
||||
<script type="text/javascript" src="/fileserver/html/gethost.js">
|
||||
</script>
|
||||
<script language="JavaScript">
|
||||
function setpath() {
|
||||
|
||||
@@ -1,546 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Base>True</Base>
|
||||
<AppType>Application</AppType>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<MainSource>Gasmeter_Logdownloader.dpr</MainSource>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<ProjectGuid>{EF2C2455-2FD5-4992-8408-A473425308BD}</ProjectGuid>
|
||||
<ProjectVersion>18.7</ProjectVersion>
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||
<Base_Win32>true</Base_Win32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
||||
<Cfg_1_Win32>true</Cfg_1_Win32>
|
||||
<CfgParent>Cfg_1</CfgParent>
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
|
||||
<Cfg_2_Win32>true</Cfg_2_Win32>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<SanitizedProjectName>Gasmeter_Logdownloader</SanitizedProjectName>
|
||||
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
|
||||
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
|
||||
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;WclBluetoothFrameworkR;DBXInterBaseDriver;vclactnband;vclFireDAC;dacfmx260;RSVML;tethering;svnui;FireDACADSDriver;vcltouch;vcldb;bindcompfmx;svn;IcsFmxD103Run;inetdb;IcsVclD103Run;FmxTeeUI;fmx;FireDACIBDriver;fmxdae;frxTee26;RSCommon;dacvcl260;fs26;IndyCore;dbexpress;vclx;frxIntIO26;dsnap;FireDACCommon;RSVclCommon;RESTBackendComponents;VCLRESTComponents;TMSVCLUIPackPkgWizDXE12;soapserver;fsTee26;TMSVCLUIPackPkgDXE12;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACMySQLDriver;frx26;FireDACCommonODBC;FireDACCommonDriver;frxIntIOIndy26;inet;S0586_TRVclComponents;bindcompdbx;IndyIPCommon;vcl;IndyIPServer;frxDB26;IndySystem;fsADO26;frxDBX26;dsnapcon;sdac260;FireDACMSAccDriver;fsDB26;fmxFireDAC;vclimg;S0606_BMVclComponents;S0628_EWVclComponents;FireDAC;TeeDB;dOPCP;frxe26;FireDACSqliteDriver;FireDACPgDriver;tdstream260;sdacvcl260;crcontrols260;TMSVCLUIPackPkgXlsDXE12;FMXTee;soaprtl;DbxCommonDriver;Tee;xmlrtl;soapmidas;dac260;vclwinx;fmxobj;rtl;frxADO26;DbxClientDriver;CustomIPTransport;vcldsnap;SynEditDR;bindcomp;appanalytics;TMSVCLUIPackPkgExDXE12;RSFMXSVG;IndyIPClient;IcsCommonD103Run;sdacfmx260;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;sbridge260;dsnapxml;dbrtl;IndyProtocols;inetdbxpress;RSVclSVG;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<DCC_DebugDCUs>true</DCC_DebugDCUs>
|
||||
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
|
||||
<DCC_Optimize>false</DCC_Optimize>
|
||||
<DCC_RemoteDebug>true</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<DCC_RemoteDebug>false</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="uMain.pas">
|
||||
<Form>Form1</Form>
|
||||
<FormType>dfm</FormType>
|
||||
</DCCReference>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
<Borland.ProjectType>Application</Borland.ProjectType>
|
||||
<BorlandProject>
|
||||
<Delphi.Personality>
|
||||
<Source>
|
||||
<Source Name="MainSource">Gasmeter_Logdownloader.dpr</Source>
|
||||
</Source>
|
||||
</Delphi.Personality>
|
||||
<Deployment Version="3">
|
||||
<DeployFile LocalName="Win32\Debug\Gasmeter_Logdownloader.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>Gasmeter_Logdownloader.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidClassesDexFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidGDBServer">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeMipsFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashImageDef">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStyles">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_DefaultAppIcon">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon144">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage426">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage470">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage640">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage960">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyFramework">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="DependencyPackage">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="File">
|
||||
<Platform Name="Android">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1024">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1536">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2048">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch768">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch320">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch640">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch640x1136">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSInfoPList">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXEntitlements">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXInfoPList">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
|
||||
</Deployment>
|
||||
<Platforms>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
|
||||
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
program Gasmeter_Logdownloader;
|
||||
program Gasmeter_Value_History;
|
||||
|
||||
uses
|
||||
Vcl.Forms,
|
||||
186
tools/logfile-tool/Gasmeter_Value_History.dproj
Normal file
186
tools/logfile-tool/Gasmeter_Value_History.dproj
Normal file
@@ -0,0 +1,186 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Base>True</Base>
|
||||
<AppType>Application</AppType>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<MainSource>Gasmeter_Value_History.dpr</MainSource>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<ProjectGuid>{EF2C2455-2FD5-4992-8408-A473425308BD}</ProjectGuid>
|
||||
<ProjectVersion>18.7</ProjectVersion>
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||
<Base_Win32>true</Base_Win32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
||||
<Cfg_1_Win32>true</Cfg_1_Win32>
|
||||
<CfgParent>Cfg_1</CfgParent>
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
|
||||
<Cfg_2_Win32>true</Cfg_2_Win32>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<SanitizedProjectName>Gasmeter_Value_History</SanitizedProjectName>
|
||||
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
|
||||
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
|
||||
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;WclBluetoothFrameworkR;DBXInterBaseDriver;vclactnband;vclFireDAC;dacfmx260;RSVML;tethering;svnui;FireDACADSDriver;vcltouch;vcldb;bindcompfmx;svn;IcsFmxD103Run;inetdb;IcsVclD103Run;FmxTeeUI;fmx;FireDACIBDriver;fmxdae;frxTee26;RSCommon;dacvcl260;fs26;IndyCore;dbexpress;vclx;frxIntIO26;dsnap;FireDACCommon;RSVclCommon;RESTBackendComponents;VCLRESTComponents;TMSVCLUIPackPkgWizDXE12;soapserver;fsTee26;TMSVCLUIPackPkgDXE12;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACMySQLDriver;frx26;FireDACCommonODBC;FireDACCommonDriver;frxIntIOIndy26;inet;S0586_TRVclComponents;bindcompdbx;IndyIPCommon;vcl;IndyIPServer;frxDB26;IndySystem;fsADO26;frxDBX26;dsnapcon;sdac260;FireDACMSAccDriver;fsDB26;fmxFireDAC;vclimg;S0606_BMVclComponents;S0628_EWVclComponents;FireDAC;TeeDB;dOPCP;frxe26;FireDACSqliteDriver;FireDACPgDriver;tdstream260;sdacvcl260;crcontrols260;TMSVCLUIPackPkgXlsDXE12;FMXTee;soaprtl;DbxCommonDriver;Tee;xmlrtl;soapmidas;dac260;vclwinx;fmxobj;rtl;frxADO26;DbxClientDriver;CustomIPTransport;vcldsnap;SynEditDR;bindcomp;appanalytics;TMSVCLUIPackPkgExDXE12;RSFMXSVG;IndyIPClient;IcsCommonD103Run;sdacfmx260;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;sbridge260;dsnapxml;dbrtl;IndyProtocols;inetdbxpress;RSVclSVG;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<DCC_DebugDCUs>true</DCC_DebugDCUs>
|
||||
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
|
||||
<DCC_Optimize>false</DCC_Optimize>
|
||||
<DCC_RemoteDebug>true</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<DCC_RemoteDebug>false</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="uMain.pas">
|
||||
<Form>Form1</Form>
|
||||
<FormType>dfm</FormType>
|
||||
</DCCReference>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
<Borland.ProjectType>Application</Borland.ProjectType>
|
||||
<BorlandProject>
|
||||
<Delphi.Personality>
|
||||
<Source>
|
||||
<Source Name="MainSource">Gasmeter_Value_History.dpr</Source>
|
||||
</Source>
|
||||
</Delphi.Personality>
|
||||
<Deployment Version="3">
|
||||
<DeployFile LocalName="Win32\Debug\Gasmeter_Value_History.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>Gasmeter_Value_History.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyFramework">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="DependencyPackage">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="File">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
|
||||
</Deployment>
|
||||
<Platforms>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
|
||||
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
|
||||
</Project>
|
||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
[MAIN]
|
||||
URL=http://192.168.178.62/fileserver/log/message/
|
||||
CountLogfiles=3
|
||||
Log=C:\Users\Muell\Downloads
|
||||
CsvFile=C:\Users\Muell\Downloads\values.csv
|
||||
URL=http://192.168.10.65/fileserver/log/
|
||||
CountLogfiles=30
|
||||
Log=D:\Daten\Dropbox\Eigene Dateien\Elektronik\Gasz<73>hler\Auswertung\Log-Downloads\
|
||||
CsvFile=D:\Daten\Dropbox\Eigene Dateien\Elektronik\Gasz<73>hler\Auswertung\Tagesstand.csv
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<h2><strong>Gasmeter Log-Downloader</strong></h2>
|
||||
<p>This small tool downloads the logfiles from your ESP32 and stores the last value of the day in an *.csv file.</p>
|
||||
<p>To use this tool you need to <strong>activate the debug logfile</strong> in your configuration (Configuration / Debug / Logfile). I go with 30 days of retention in days.</p>
|
||||
<p>It downloads only the past logfiles (yesterday and older).</p>
|
||||
<p>You can define the max. number of Logfiles to download (beginning from newest [yesterday]).</p>
|
||||
<h2><strong>Gasmeter Value History Downloader</strong></h2>
|
||||
<p>This small tool downloads the datafiles (*.txt, before V13.0.1) or valuefiles (*.csv, since V13.0.1) from your ESP32 and stores the last value of the day in a *.csv file.</p>
|
||||
<p>To use this tool you need to <strong>activate the DataLogging</strong> in your configuration (Configuration / Data Logging / DataLogActive). I go with 30 days of retention in days.</p>
|
||||
<p>It downloads only the past datafiles (yesterday and older, not the actual day).</p>
|
||||
<p>You can define the max. number of datafiles to download (beginning from newest [yesterday]).</p>
|
||||
<p>I wrote this tool to get a chart of the daily gas consumption to optimize my gas powered heating.</p>
|
||||
<p><strong>Variables to define by yourself:</strong></p>
|
||||
<ul>
|
||||
<li><strong>URL to Logfile-Path on Device:</strong> "http://ESP32-IP-Address/fileserver/log/message/"</li>
|
||||
<li><strong>Download Logfiles to:</strong> enter a valid directory, e.g. "D:\Gaszaehler\Auswertung\Log-Downloads\"</li>
|
||||
<li><strong>URL to Logfile-Path on Device:</strong> "http://ESP32-IP-Address/fileserver/log/"</li>
|
||||
<li><strong>Download datafiles to:</strong> enter a valid directory, e.g. "D:\Gaszaehler\Auswertung\Log-Downloads\"</li>
|
||||
<li><strong>Output CSV-File:</strong> enter a valid directory, e.g. "D:\Gaszaehler\Auswertung\DailyValues.csv"</li>
|
||||
<li><strong>Download Logfiles from past # days:</strong> enter the max. number of logfiles you want to download (<= your logfile retention value in your device configuration)</li>
|
||||
<li><strong>Download past # days:</strong> enter the max. number of days you want to download (<= your datafiles retention value in your device configuration)</li>
|
||||
</ul>
|
||||
<p>Feel free to optimize and modify it.</p>
|
||||
@@ -1,9 +1,9 @@
|
||||
object Form1: TForm1
|
||||
Left = 0
|
||||
Top = 0
|
||||
Caption = 'Gasmeter Log-Downloader'
|
||||
ClientHeight = 521
|
||||
ClientWidth = 513
|
||||
Caption = 'Gasmeter Value-History'
|
||||
ClientHeight = 523
|
||||
ClientWidth = 453
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
@@ -16,7 +16,7 @@ object Form1: TForm1
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object lblImpressum: TLabel
|
||||
Left = 376
|
||||
Left = 316
|
||||
Top = 468
|
||||
Width = 68
|
||||
Height = 13
|
||||
@@ -31,25 +31,25 @@ object Form1: TForm1
|
||||
EditLabel.Height = 13
|
||||
EditLabel.Caption = 'URL to Logfile-Path on Device:'
|
||||
TabOrder = 0
|
||||
Text = 'http://192.168.10.65/fileserver/log/message/'
|
||||
Text = 'http://192.168.10.65/fileserver/log/'
|
||||
end
|
||||
object btnDownloadLogfiles: TButton
|
||||
Left = 28
|
||||
Top = 174
|
||||
Width = 273
|
||||
Height = 25
|
||||
Caption = 'Download Logfiles and generate CSV'
|
||||
Caption = 'Download datafiles and generate CSV'
|
||||
TabOrder = 1
|
||||
OnClick = btnDownloadLogfilesClick
|
||||
end
|
||||
object lbledtMaxLogfilesOnServer: TLabeledEdit
|
||||
Left = 323
|
||||
Top = 36
|
||||
Width = 121
|
||||
Width = 114
|
||||
Height = 21
|
||||
EditLabel.Width = 173
|
||||
EditLabel.Width = 112
|
||||
EditLabel.Height = 13
|
||||
EditLabel.Caption = 'Download logfiles from past # days:'
|
||||
EditLabel.Caption = 'Download past # days:'
|
||||
TabOrder = 2
|
||||
Text = '30'
|
||||
end
|
||||
@@ -58,11 +58,11 @@ object Form1: TForm1
|
||||
Top = 84
|
||||
Width = 273
|
||||
Height = 21
|
||||
EditLabel.Width = 103
|
||||
EditLabel.Width = 108
|
||||
EditLabel.Height = 13
|
||||
EditLabel.Caption = 'Download Logfiles to:'
|
||||
EditLabel.Caption = 'Download datafiles to:'
|
||||
TabOrder = 3
|
||||
Text = 'C:\Temp\Gas\'
|
||||
Text = 'C:\Temp\Gas\Log\'
|
||||
end
|
||||
object lbledtCsvFile: TLabeledEdit
|
||||
Left = 28
|
||||
|
||||
@@ -43,7 +43,8 @@ implementation
|
||||
procedure TForm1.btnDownloadLogfilesClick(Sender: TObject);
|
||||
var
|
||||
lclDateString: string;
|
||||
lclFilename: string;
|
||||
lclFilenameCsv: string;
|
||||
lclFilenameTxtOld: string;
|
||||
i: Integer;
|
||||
lclValue: Extended;
|
||||
begin
|
||||
@@ -51,13 +52,19 @@ begin
|
||||
LoadCSV(lbledtCsvFile.Text);
|
||||
for i := StrToInt(lbledtMaxLogfilesOnServer.Text) downto 1 do
|
||||
begin
|
||||
DateTimeToString(lclDateString, 'yyyy-mm-dd', incDay(Now, -i));
|
||||
lclFilename := 'log_' + lclDateString + '.txt';
|
||||
DateTimeToString(lclDateString, 'yyyy-mm-dd', incDay(Now, - i));
|
||||
lclFilenameCsv := 'data_' + lclDateString + '.csv'; // http://192.168.10.65/fileserver/log/data/data_2022-11-28.csv
|
||||
lclFilenameTxtOld := 'log_' + lclDateString + '.txt'; // http://192.168.10.65/fileserver/log/message/log_2022-11-10.txt
|
||||
if (redtLog.FindText(lclDateString, 0, Length(redtLog.Lines.Text), [stWholeWord]) = -1) then
|
||||
begin
|
||||
if DownloadFile(lbledtURL.Text + lclFilename, lbledtTargetDirectory.Text + lclFilename) then
|
||||
if DownloadFile(lbledtURL.Text + 'data/' + lclFilenameCsv, lbledtTargetDirectory.Text + lclFilenameCsv) then
|
||||
begin
|
||||
lclValue := LoadValue(lbledtTargetDirectory.Text + lclFilename);
|
||||
lclValue := LoadValue(lbledtTargetDirectory.Text + lclFilenameCsv);
|
||||
redtLog.Lines.Add(lclDateString + ';' + FloatToStrF(lclValue, ffFixed, 8, 2));
|
||||
end
|
||||
else if DownloadFile(lbledtURL.Text + 'message/' + lclFilenameTxtOld, lbledtTargetDirectory.Text + lclFilenameTxtOld) then
|
||||
begin
|
||||
lclValue := LoadValue(lbledtTargetDirectory.Text + lclFilenameTxtOld);
|
||||
redtLog.Lines.Add(lclDateString + ';' + FloatToStrF(lclValue, ffFixed, 8, 2));
|
||||
end;
|
||||
end;
|
||||
@@ -99,24 +106,45 @@ function TForm1.LoadValue(const pFileName: string): Extended;
|
||||
var
|
||||
Txt: TextFile;
|
||||
s: string;
|
||||
lclStringList: TStringList;
|
||||
lclStartPos: Integer;
|
||||
lclEndPos: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
AssignFile(Txt, pFileName);
|
||||
Reset(Txt);
|
||||
while not Eof(Txt) do
|
||||
begin
|
||||
Readln(Txt, s);
|
||||
if (AnsiPos('Value: ', s) <> 0) and (AnsiPos(' Error: no error', s) <> 0) then
|
||||
lclStringList := TStringList.Create;
|
||||
try
|
||||
AssignFile(Txt, pFileName);
|
||||
Reset(Txt);
|
||||
while not Eof(Txt) do
|
||||
begin
|
||||
lclStartPos := AnsiPos('Value: ', s) + 7;
|
||||
lclEndPos := AnsiPos(' Error: no error', s) - lclStartPos;
|
||||
s := StringReplace(s, '.', ',', [rfReplaceAll, rfIgnoreCase]);
|
||||
Result := StrToFloat(Copy(s, lclStartPos, lclEndPos));
|
||||
Readln(Txt, s);
|
||||
if ExtractFileExt(pFileName) = '.csv' then
|
||||
begin
|
||||
if (AnsiPos('no error', s) <> 0) then
|
||||
begin
|
||||
lclStringList.Clear;
|
||||
lclStringList.Delimiter := ';';
|
||||
s := StringReplace(s, ',', ';', [rfReplaceAll, rfIgnoreCase]);
|
||||
s := StringReplace(s, '.', ',', [rfReplaceAll, rfIgnoreCase]);
|
||||
lclStringList.DelimitedText := s;
|
||||
Result := lclStringList[2].ToExtended;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (AnsiPos('Value: ', s) <> 0) and (AnsiPos(' Error: no error', s) <> 0) then
|
||||
begin
|
||||
lclStartPos := AnsiPos('Value: ', s) + 7;
|
||||
lclEndPos := AnsiPos(' Error: no error', s) - lclStartPos;
|
||||
s := StringReplace(s, '.', ',', [rfReplaceAll, rfIgnoreCase]);
|
||||
Result := StrToFloat(Copy(s, lclStartPos, lclEndPos));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
CloseFile(Txt);
|
||||
FreeAndNil(lclStringList);
|
||||
end;
|
||||
CloseFile(Txt);
|
||||
end;
|
||||
|
||||
procedure TForm1.SaveCSV(const pFileName: string);
|
||||
|
||||
Reference in New Issue
Block a user