├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── compile-arduino.yml
│ ├── compile-platformio.yml
│ └── spell-check.yml
├── .gitignore
├── LICENSE
├── README.md
├── SolarTracerBlynk
├── SolarTracerBlynk.ino
├── config.h
└── src
│ ├── board
│ ├── esp32_config.h
│ └── esp8266_config.h
│ ├── core
│ ├── BaseSync.cpp
│ ├── BaseSync.h
│ ├── Controller.cpp
│ ├── Controller.h
│ ├── Environment.cpp
│ ├── Environment.h
│ ├── Text.h
│ ├── Util.cpp
│ ├── Util.h
│ ├── VariableDefiner.cpp
│ ├── VariableDefiner.h
│ ├── datetime.h
│ ├── debug.cpp
│ └── debug.h
│ ├── feature
│ ├── BlynkSync.cpp
│ ├── BlynkSync.h
│ ├── MqttHASync.cpp
│ ├── MqttHASync.h
│ ├── MqttSync.cpp
│ ├── MqttSync.h
│ ├── arduino_ota.h
│ └── wifi_manager.h
│ ├── incl
│ ├── communication_protocol_all.h
│ ├── config_persistence.h
│ ├── include.h
│ ├── include_all_blynk_vpin.h
│ ├── include_all_core.h
│ ├── include_all_feature.h
│ ├── include_all_lib.h
│ ├── include_all_mqtt_topic.h
│ ├── solartracer_all.h
│ └── status_all.h
│ └── solartracer
│ ├── SolarTracer.cpp
│ ├── SolarTracer.h
│ ├── dummy
│ └── DummySolarTracer.h
│ ├── epever
│ ├── EPEVERSolarTracer.cpp
│ ├── EPEVERSolarTracer.h
│ ├── EPEVER_modbus_address.h
│ └── epever_config.h
│ ├── incl
│ └── solar_config.h
│ └── overwrite
│ ├── LoadCurrentOverWrite.cpp
│ └── LoadCurrentOverwrite.h
├── docs
├── 1733_modbus_protocol.pdf
├── Esp32_max485_epever_rj45.md
├── Esp8266_max485_epever_rj45.md
├── Sw_getting_started.md
├── esp32.md
├── esp8266.md
├── sw_getting_started_blynk_iot.md
├── sw_getting_started_blynk_legacy.md
├── sw_getting_started_ha.md
└── sw_getting_started_mqtt.md
├── images
├── blynk-app-qr-code.png
├── blynk-app-qr-code_v3.png
├── blynk-app-qr-code_v3_blynkcloud.png
├── epever_rj45_specs.png
├── esp32_d1_mini_pins.png
├── esp32_wroom_38_pin.jpg
├── esp8266_bin_flash.png
├── esp8266_hw_serial.png
├── esp8266_sw_serial.png
├── esp_tool_bin_flash_10000.png
├── esp_tool_bin_flash_new.png
├── esp_tool_board_select.png
├── eth_t568b.png
├── max485_module.jpg
├── mppt-triton.png
├── mppt-xtra.png
├── nodemcu_pins.png
├── schematic.png
├── screenshot-blynk.png
├── screenshot-blynk_v3_battery.png
├── screenshot-blynk_v3_pv.png
├── screenshot-blynk_v3_realtime.png
├── screenshot-blynk_v3_settings.png
├── tracer-a.png
├── tracer-b.png
├── wifi_manager.png
├── wifi_manager_config.png
├── wifi_manager_home.png
├── wifi_manager_mqtt_settings.png
├── wifi_manager_update.png
└── wifi_manager_update_upload.png
├── platformio.ini
└── script
├── binDeploy.cmd
├── binTest.cmd
└── esp32_binary_merger
├── LICENSE
└── merge_bin_esp.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: bettapro
2 | liberapay: bettapro
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: Bettapro
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/compile-arduino.yml:
--------------------------------------------------------------------------------
1 | name: Compile Arduino
2 |
3 | on:
4 | push:
5 | paths:
6 | - ".github/workflows/compile-arduino.yml"
7 | - "SolarTracerBlynk/**"
8 | pull_request:
9 | paths:
10 | - ".github/workflows/compile-arduino.yml"
11 | - "SolarTracerBlynk/**"
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
17 | jobs:
18 | # This workflow contains a single job called "build"
19 | build:
20 | # The type of runner that the job will run on
21 | runs-on: ubuntu-latest
22 |
23 | env:
24 | # libraries to install for all boards
25 | shared_libraries: |
26 | - name: ArduinoOTA
27 | - name : WiFi
28 | - name: Blynk
29 | version: 1.1.0
30 | - name: WiFiManager
31 | - name: ArduinoJson
32 | - source-url : https://github.com/Bettapro/ModbusMaster.git
33 | - name: PubSubClient
34 | - source-url : https://github.com/Bettapro/SimpleTimer.git
35 | - source-url : https://github.com/dawidchyrzynski/arduino-home-assistant.git
36 | version : 2.1.0
37 | - source-url : https://github.com/Bettapro/LinearSensHallCurrent.git
38 | - source-url : https://github.com/RobTillaart/ADS1X15.git
39 | - source-url : https://github.com/khoih-prog/ESP_DoubleResetDetector.git
40 | - source-url : https://github.com/plerup/espsoftwareserial.git
41 | version : 8.0.3
42 | # sketch paths to compile (recursive) for all boards
43 | sketch_paths: |
44 | - SolarTracerBlynk
45 |
46 | strategy:
47 | matrix:
48 | board:
49 | - fqbn: esp8266:esp8266:arduino-esp8266
50 | type: esp8266
51 | - fqbn: esp32:esp32:esp32
52 | type: esp32
53 |
54 | include:
55 | # ESP8266 boards
56 | - board:
57 | type: esp8266
58 | platforms: |
59 | - name: esp8266:esp8266@3.0.2
60 | source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
61 | libraries:
62 | # ESP32 boards
63 | - board:
64 | type: esp32
65 | platforms: |
66 | - name: esp32:esp32
67 | source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
68 | libraries:
69 |
70 | steps:
71 | - name: Checkout
72 | uses: actions/checkout@v2
73 | - name: Compile Sketches
74 | uses: arduino/compile-sketches@v1
75 | with:
76 | github-token: ${{ secrets.GITHUB_TOKEN }}
77 | platforms: ${{ matrix.platforms }}
78 | fqbn: ${{ matrix.board.fqbn }}
79 | sketch-paths: |
80 | ${{ env.sketch_paths }}
81 | libraries: |
82 | ${{ env.shared_libraries }}
83 | ${{ matrix.libraries }}
84 | enable-deltas-report: "true"
85 | sketches-report-path: sketches-reports
86 | cli-compile-flags: |
87 | - --warnings="all"
88 | # - --build-property
89 | # - compiler.cpp.extra_flag="-Wno-unused-function"
90 | - name: Report Arduino Sketch Size Deltas
91 | uses: arduino/report-size-deltas@v1.0.0
92 | with:
93 | # When run from scheduled workflow, name of the workflow artifact that contains sketches reports. When run from a pull request triggered workflow, path to the folder containing sketches reports.
94 | sketches-reports-source: sketches-reports
95 | # GitHub access token used to comment the memory usage comparison results to the PR thread
96 | github-token: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/compile-platformio.yml:
--------------------------------------------------------------------------------
1 | name: Compile Platformio
2 |
3 | on:
4 | push:
5 | paths:
6 | - ".github/workflows/compile-arduino.yml"
7 | - "SolarTracerBlynk/**"
8 | pull_request:
9 | paths:
10 | - ".github/workflows/compile-arduino.yml"
11 | - "SolarTracerBlynk/**"
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
17 | jobs:
18 | # This workflow contains a single job called "build"
19 | test_builds:
20 | runs-on: ubuntu-latest
21 |
22 | strategy:
23 | matrix:
24 | test-platform:
25 | # Base Environments
26 | - esp32dev
27 | - esp8266
28 |
29 | steps:
30 | - name: Check out the PR
31 | uses: actions/checkout@v2
32 |
33 | - name: Cache pip
34 | uses: actions/cache@v2
35 | with:
36 | path: ~/.cache/pip
37 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
38 | restore-keys: |
39 | ${{ runner.os }}-pip-
40 |
41 | - name: Cache PlatformIO
42 | uses: actions/cache@v2
43 | with:
44 | path: ~/.platformio
45 | key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
46 |
47 | - name: Select Python 3.7
48 | uses: actions/setup-python@v2
49 | with:
50 | python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
51 | architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
52 |
53 | - name: Install PlatformIO
54 | run: |
55 | pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
56 | platformio update
57 |
58 | - name: Run ${{ matrix.test-platform }} Tests
59 | run: |
60 | pio run -e ${{ matrix.test-platform }}
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/.github/workflows/spell-check.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Spell Check
3 |
4 | on:
5 | push:
6 | pull_request:
7 |
8 | # Allows you to run this workflow manually from the Actions tab
9 | workflow_dispatch:
10 |
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v2
18 | - name: Spell check
19 | uses: codespell-project/actions-codespell@master
20 | with:
21 | skip: ./docs/1733_modbus_protocol.pdf
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Platformio
2 | .pio
3 |
4 | # Visual Studio Code
5 | .vscode
6 | *.code-workspace
7 |
8 | #build folder
9 | binFiles
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Solar-tracer-Blynk-V3
3 |
4 | [](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/actions/workflows/compile-arduino.yml)
5 | [](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/actions/workflows/compile-platformio.yml)
6 | [](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/actions/workflows/spell-check.yml)
7 |
8 |
9 | ### An Arduino project to connect one MPPT Solar Controllers to an `ESP8266/ESP32` and monitor it!
10 |
11 | You can take a look to the previous version of this software:
12 | * *v1* [Tracer-RS485-Modbus-Blynk](https://github.com/jaminNZx/Tracer-RS485-Modbus-Blynk)
13 | * *v2* [Tracer-RS485-Modbus-Blynk-V2](https://github.com/tekk/Tracer-RS485-Modbus-Blynk-V2)
14 |
15 | What you got with v3:
16 | 1. **lots of data** from you solar controller (temps, charging/discharging/battery status, stats ... and more)
17 | 2. wide range of **customization** using a single file (*config.h*)
18 | 3. automatic **time sync** between the ESP and the controller on each boot, using NTP time
19 | 4. **platformio** support
20 | 5. **ESP32** support
21 | 6. **Configuration over wifi**, no needs to compile the code (if you don't want to)
22 | 7. ready for future expansion (more solar charge controllers with different communication protocol/channel)
23 |
24 | Feel free to make pull requests if you wish to help improving.
25 | There is also a support forum on the Blynk community forums: http://community.blynk.cc/t/epsolar-tracer-2210a-charge-controller-blynk-epic-solar-monitor/10596
26 |
27 | You are welcome for suggestions, bugreports, and of course any further improvements of this code.
28 |
29 | ## Solar Controller Supported
30 |
31 | 
32 | 
33 | 
34 | 
35 |
36 | ## Tutorial
37 | Supported board:
38 | - [ESP8266](docs/esp8266.md)
39 | - [ESP32](docs/esp32.md)
40 |
41 | Available sync. options:
42 | - [Blynk legacy](docs/sw_getting_started_blynk_legacy.md)
43 | - [Blynk IOT](docs/sw_getting_started_blynk_iot.md)
44 | - [Home assistant-MQTT](docs/sw_getting_started_ha.md)
45 | - [MQTT](docs/sw_getting_started_mqtt.md)
46 |
47 |
48 | Some examples:
49 | - [ESP8266 + MAX485 + EPEVER Solar Tracer](docs/Esp8266_max485_epever_rj45.md)
50 | - [ESP32 + MAX485 + EPEVER Solar Tracer](docs/Esp32_max485_epever_rj45.md)
51 |
52 | ## Sample screenshot
53 |
54 | 
55 | 
56 |
57 | ## Credits
58 |
59 | - `@jaminNZx:`
60 | - Thanks to subtafuge on [Reddit](https://www.reddit.com/r/esp8266/comments/59dt00/using_esp8266_to_connect_rs485_modbus_protocol/) for lending me his working Tracer RS485 code!
61 |
62 | - `@tekk:`
63 | - Feel free to contact me about my code changes in this version
64 | - Thanks to [@jaminNZx](https://github.com/jaminNZx) for the original code. Big up!
65 |
66 | - `@bettapro:`
67 | - Thanks to [@tekk](https://github.com/tekk) for his work. Big up!
68 | - Feel free to contact me about my code changes in this version
69 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/board/esp32_config.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifdef ESP32
25 |
26 | #ifndef BOARD_DEBUG_SERIAL_STREAM
27 | #define BOARD_DEBUG_SERIAL_STREAM Serial
28 | #endif
29 |
30 | #ifndef BOARD_DEBUG_SERIAL_STREAM_BAUDRATE
31 | #define BOARD_DEBUG_SERIAL_STREAM_BAUDRATE 115200
32 | #endif
33 |
34 | #if defined USE_PIN_AP_CONFIGURATION_TRIGGER and ! defined(PIN_AP_TRIGGER_PIN)
35 | #define PIN_AP_TRIGGER_PIN 19
36 | #endif
37 |
38 | #if defined(USE_SERIAL_STREAM) && !defined(BOARD_ST_SERIAL_STREAM)
39 | #define BOARD_ST_SERIAL_STREAM Serial2
40 | #endif
41 |
42 | #if defined(USE_SERIAL_STREAM) && !defined(BOARD_ST_SERIAL_PRETRANSMIT_WAIT)
43 | #define BOARD_ST_SERIAL_PRETRANSMIT_WAIT 0
44 | #endif
45 |
46 | #if defined(USE_SERIAL_MAX485) && !defined(MAX485_DE)
47 | #define MAX485_DE 13
48 | #endif
49 |
50 | #if defined(USE_SERIAL_MAX485) && !defined(MAX485_RE_NEG)
51 | #define MAX485_RE_NEG 13
52 | #endif
53 |
54 | #if defined(USE_WIFI_AP_CONFIGURATION) && defined(USE_HALL_AP_CONFIGURATION_TRIGGER)
55 | #if !defined(HALL_AP_CONFIGURATION_BASE_VALUE)
56 | #define HALL_AP_CONFIGURATION_BASE_VALUE 75
57 | #endif
58 | #if !defined(HALL_AP_CONFIGURATION_THR_VALUE)
59 | #define HALL_AP_CONFIGURATION_THR_VALUE 30
60 | #endif
61 | #endif
62 |
63 | #define WIFI_STATION_MODE_DISCONNECTED WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED
64 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/board/esp8266_config.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifdef ESP8266
25 |
26 | #ifndef BOARD_DEBUG_SERIAL_STREAM
27 | #define BOARD_DEBUG_SERIAL_STREAM Serial
28 | #endif
29 |
30 | #ifndef BOARD_DEBUG_SERIAL_STREAM_BAUDRATE
31 | #define BOARD_DEBUG_SERIAL_STREAM_BAUDRATE 115200
32 | #endif
33 |
34 | #if defined USE_PIN_AP_CONFIGURATION_TRIGGER and ! defined(PIN_AP_TRIGGER_PIN)
35 | #define PIN_AP_TRIGGER_PIN 16
36 | #endif
37 |
38 | #ifdef USE_SOFTWARE_SERIAL
39 | #ifndef BOARD_ST_SERIAL_PIN_MAPPING_TX
40 | #define BOARD_ST_SERIAL_PIN_MAPPING_TX 4
41 | #endif
42 | #ifndef BOARD_ST_SERIAL_PIN_MAPPING_RX
43 | #define BOARD_ST_SERIAL_PIN_MAPPING_RX 2
44 | #endif
45 | #else
46 | #define BOARD_ST_SERIAL_DECLARATION
47 | #endif
48 |
49 |
50 | #if defined(USE_SERIAL_STREAM) && !defined(BOARD_ST_SERIAL_STREAM) && !defined(USE_SOFTWARE_SERIAL)
51 | #define BOARD_ST_SERIAL_STREAM Serial
52 | #endif
53 |
54 | #if defined(USE_SERIAL_STREAM) && !defined(BOARD_ST_SERIAL_PRETRANSMIT_WAIT)
55 | #define BOARD_ST_SERIAL_PRETRANSMIT_WAIT 10
56 | #endif
57 |
58 | #if defined(USE_SERIAL_MAX485) && !defined(MAX485_DE)
59 | #define MAX485_DE 5
60 | #endif
61 |
62 | #if defined(USE_SERIAL_MAX485) && !defined(MAX485_RE_NEG)
63 | #define MAX485_RE_NEG 5
64 | #endif
65 |
66 |
67 | #define WIFI_STATION_MODE_DISCONNECTED WiFiEvent_t::WIFI_EVENT_STAMODE_DISCONNECTED
68 |
69 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/BaseSync.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "BaseSync.h"
23 |
24 | #include "../core/Controller.h"
25 | #include "../core/VariableDefiner.h"
26 | #include "../core/debug.h"
27 |
28 | #define VALUE_CACHES_UNTIL_COUNT 100;
29 |
30 | BaseSync::BaseSync() {
31 | this->renewValuesCount = new uint8_t[Variable::VARIABLES_COUNT]();
32 | this->lastValuesCache = new void *[Variable::VARIABLES_COUNT]();
33 |
34 | uint8_t varSize;
35 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
36 | this->renewValuesCount[index] = 0;
37 | varSize = VariableDefiner::getInstance().getVariableSize((Variable)index);
38 | if (varSize > 0) {
39 | this->lastValuesCache[index] = malloc(varSize);
40 | memset(this->lastValuesCache[index], 0, varSize);
41 | }
42 | }
43 | }
44 |
45 | void BaseSync::applyUpdateToVariable(Variable variable, const void *value, bool silent) {
46 | SolarTracer *solarT = Controller::getInstance().getSolarController();
47 | const VariableDefinition *def = VariableDefiner::getInstance().getDefinition(variable);
48 | if (def != nullptr) {
49 | if (!silent) {
50 | debugPrint("WRITE REQUEST ");
51 | switch (def->datatype) {
52 | case VariableDatatype::DT_FLOAT:
53 | debugPrintf(false, "\"%s\" to %.4f ", def->text, *(const float *)value);
54 | break;
55 | case VariableDatatype::DT_BOOL:
56 | debugPrintf(false, "\"%s\" to %i ", def->text, *(const bool *)value);
57 | break;
58 | case VariableDatatype::DT_STRING:
59 | debugPrintf(false, "\"%s\" to \"%s\" ", def->text, (const char *)value);
60 | break;
61 | }
62 | }
63 | bool writeDone = solarT->writeValue(variable, value);
64 | if (!silent) {
65 | writeDone ? debugPrintln(Text::ok) : debugPrintf(true, Text::errorWithCode, solarT->getLastControllerCommunicationStatus());
66 | }
67 | }
68 | }
69 |
70 | uint8_t BaseSync::sendUpdateAllBySource(VariableSource allowedSource, bool silent) {
71 | SolarTracer *solarT = Controller::getInstance().getSolarController();
72 | uint8_t varNotReady = 0;
73 | const VariableDefinition *def;
74 |
75 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
76 | def = VariableDefiner::getInstance().getDefinition((Variable)index);
77 | if (def->source == allowedSource && this->isVariableAllowed(def) && (solarT->isVariableEnabled(def->variable) || solarT->isVariableOverWritten(def->variable))) {
78 | if (!solarT->isVariableReadReady(def->variable) || !this->syncVariable(def, solarT->getValue(def->variable))) {
79 | #ifdef USE_DEBUG_SERIAL_VERBOSE_SYNC_ERROR_VARIABLE
80 | debugPrintf(true, Text::syncErrorWithVariable, def->text);
81 | #endif
82 | varNotReady++;
83 | }
84 | }
85 | }
86 |
87 | if (!silent && varNotReady > 0) {
88 | debugPrintf(true, Text::syncErrorWithCountAndType, varNotReady, allowedSource == VariableSource::SR_STATS ? "ST" : "RT");
89 | }
90 | Controller::getInstance().setErrorFlag(allowedSource == VariableSource::SR_STATS ? STATUS_ERR_SOLAR_TRACER_NO_SYNC_ST : STATUS_ERR_SOLAR_TRACER_NO_SYNC_RT, varNotReady > 0);
91 |
92 | return varNotReady;
93 | }
94 |
95 | bool BaseSync::syncVariable(const VariableDefinition *def, const void *value) {
96 | uint8_t *cachedUntil = &(this->renewValuesCount[def->variable]);
97 | if (this->isVariableAllowed(def)) {
98 | if (!(
99 | this->renewValueCount == 1 || (*cachedUntil) <= 0 // sync always enabled?
100 | || !VariableDefiner::getInstance().isValueEqual(def->variable, value, this->lastValuesCache[def->variable]) // value has changed?
101 | || (this->renewValueCount > 1 && ((*cachedUntil)--) <= 0) // renew required?
102 | ) // -> should sync evaluation?
103 | || this->sendUpdateToVariable(def, value)) {
104 | memcpy(this->lastValuesCache[def->variable], value, VariableDefiner::getInstance().getVariableSize(def->variable));
105 | if (this->renewValueCount > 1 || (*cachedUntil) <= 0) {
106 | (*cachedUntil) = this->renewValueCount + 1;
107 | }
108 | return true;
109 | }
110 | }
111 | return false;
112 | }
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/BaseSync.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef BASE_SYNC_H
25 | #define BASE_SYNC_H
26 |
27 | #include "../core/VariableDefiner.h"
28 |
29 | #define BASE_SYNC_RENEW_VALUE_COUNT 20;
30 |
31 | class BaseSync {
32 | public:
33 | BaseSync();
34 | virtual void setup() = 0;
35 | virtual void connect(bool blocking = true) = 0;
36 | virtual void loop() = 0;
37 | /**
38 | * @brief Send the update to remote server
39 | *
40 | * @param def variable definition
41 | * @param value value
42 | * @return true if the update has been sent with success, false otherwise
43 | */
44 | virtual bool sendUpdateToVariable(const VariableDefinition *def, const void *value) = 0;
45 | virtual bool isVariableAllowed(const VariableDefinition *def) = 0;
46 | void applyUpdateToVariable(Variable variable, const void *value, bool silent = true);
47 |
48 | bool syncVariable(const VariableDefinition *def, const void *value);
49 |
50 | uint8_t sendUpdateAllBySource(VariableSource allowedSource, bool silent = true);
51 |
52 | protected:
53 | /**
54 | * 0 sync on change only
55 | * 1 sync always
56 | * .. use renew count
57 | */
58 | uint8_t renewValueCount = BASE_SYNC_RENEW_VALUE_COUNT;
59 |
60 | private:
61 | void **lastValuesCache;
62 |
63 | uint8_t *renewValuesCount;
64 | };
65 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Controller.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "Controller.h"
23 |
24 | bool Controller::getErrorFlag(const uint32_t status) {
25 | return (this->internalStatus & status) > 0;
26 | }
27 |
28 | void Controller::setErrorFlag(const uint32_t status, bool error) {
29 | if (this->getErrorFlag(status) != error) {
30 | uint32_t tStatus = this->internalStatus + (error ? 1 : -1) * status;
31 | #ifdef USE_STATUS_LED
32 | notifyStatusLed(tStatus);
33 | #endif
34 | this->internalStatus = tStatus;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Controller.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef CONTROLLER_H
25 | #define CONTROLLER_H
26 |
27 | #include "../incl/include_all_lib.h"
28 | #include "../solartracer/SolarTracer.h"
29 |
30 | class Controller {
31 | public:
32 | static Controller &getInstance() {
33 | static Controller instance;
34 | return instance;
35 | }
36 |
37 | void setup(SolarTracer *tracer, SimpleTimer *timer) {
38 | this->mainTimer = timer;
39 | this->thisController = tracer;
40 | }
41 |
42 | void loop() {
43 | this->mainTimer->run();
44 | }
45 |
46 | bool getErrorFlag(uint32_t status);
47 |
48 | void setErrorFlag(uint32_t status, bool error);
49 |
50 | inline uint32_t getStatus();
51 |
52 | inline SolarTracer *getSolarController();
53 |
54 | inline SimpleTimer *getMainTimer();
55 |
56 | private:
57 | SimpleTimer *mainTimer;
58 | SolarTracer *thisController;
59 | uint32_t internalStatus = 0;
60 | };
61 |
62 | uint32_t Controller::getStatus() {
63 | return this->internalStatus;
64 | }
65 |
66 | SolarTracer *Controller::getSolarController() {
67 | return this->thisController;
68 | }
69 |
70 | SimpleTimer *Controller::getMainTimer() {
71 | return this->mainTimer;
72 | }
73 |
74 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Environment.cpp:
--------------------------------------------------------------------------------
1 | #include "Environment.h"
2 |
3 | struct EnvironrmentData Environment::envData;
4 |
5 | void Environment::loadEnvData() {
6 | envData.serialDebug = true;
7 | // default from config.h
8 | strcpy(envData.wifiSSID, WIFI_SSID);
9 | strcpy(envData.wifiPassword, WIFI_PASS);
10 |
11 | strcpy(envData.wifiIp, WIFI_IP_ADDRESS);
12 | strcpy(envData.wifiGateway, WIFI_GATEWAY);
13 | strcpy(envData.wifiSubnet, WIFI_SUBNET);
14 | strcpy(envData.wifiDns1, WIFI_DNS1);
15 | strcpy(envData.wifiDns2, WIFI_DNS2);
16 |
17 | #ifdef USE_WIFI_AP_CONFIGURATION
18 | strcpy(envData.wmApSSID, WIFI_AP_CONFIGURATION_HOSTNAME);
19 | strcpy(envData.wmApPassword, WIFI_AP_CONFIGURATION_PASSWORD);
20 | #endif
21 |
22 | #ifdef USE_BLYNK
23 | #ifndef USE_BLYNK_2
24 | #ifdef USE_BLYNK_LOCAL_SERVER
25 | strcpy(envData.blynkServerHostname, BLYNK_SERVER);
26 | envData.blynkServerPort = BLYNK_PORT;
27 | #else
28 | strcpy(envData.blynkServerHostname, "");
29 | envData.blynkServerPort = 0;
30 | #endif
31 | #endif
32 | #if defined USE_BLYNK
33 | strcpy(envData.blynkAuth, BLYNK_AUTH);
34 | #endif
35 | #endif
36 | #ifdef USE_MQTT
37 | strcpy(envData.mqttServerHostname, MQTT_SERVER);
38 | strcpy(envData.mqttUsername, MQTT_USERNAME);
39 | strcpy(envData.mqttPassword, MQTT_PASSWORD);
40 | strcpy(envData.mqttClientId, MQTT_CLIENT_ID);
41 | envData.mqttServerPort = MQTT_PORT;
42 | #endif
43 | #ifdef USE_MQTT_HOME_ASSISTANT
44 | strcpy(envData.mqttHADeviceId, MQTT_HOME_ASSISTANT_DEVICE_ID);
45 | strcpy(envData.mqttHADeviceName, MQTT_HOME_ASSISTANT_DEVICE_NAME);
46 | #endif
47 |
48 | #ifdef USE_OTA_UPDATE
49 | strcpy(envData.otaHostname, OTA_HOSTNAME);
50 | strcpy(envData.otaPassword, OTA_PASS);
51 | #endif
52 |
53 | #ifdef USE_NTP_SERVER
54 | strcpy(envData.ntpServer, NTP_SERVER_CONNECT_TO);
55 | strcpy(envData.ntpTimezone, CURRENT_TIMEZONE);
56 | #endif
57 |
58 | // END OF LOAD FROM config.h
59 |
60 | #if defined USE_WIFI_AP_CONFIGURATION
61 | if (!LittleFS.begin()) {
62 | LittleFS.format();
63 | }
64 | // load from file
65 | if (!LittleFS.exists(CONFIG_PERSISTENCE)) {
66 | // no file found
67 | debugPrintln("No configuration file found");
68 | } else {
69 | debugPrintln("Restoring configuration from file");
70 | // file exists, reading and loading
71 | File configFile = LittleFS.open(CONFIG_PERSISTENCE, "r");
72 | if (!configFile) {
73 | debugPrintln("ERROR: cannot open config file");
74 | } else {
75 | size_t size = configFile.size();
76 | DynamicJsonDocument doc(size * 3);
77 | DeserializationError error = deserializeJson(doc, configFile);
78 | if (error) {
79 | debugPrintln("ERROR: Cannot deserialize settings from file");
80 | debugPrintln(error.c_str());
81 | } else {
82 | if (doc.containsKey(CONFIG_SERIAL_DEBUG)) {
83 | envData.serialDebug = doc[CONFIG_SERIAL_DEBUG];
84 | }
85 |
86 | loadStringToEnvIfExist(doc, CONFIG_WIFI_SSID, envData.wifiSSID);
87 | loadStringToEnvIfExist(doc, CONFIG_WIFI_PASSWORD, envData.wifiPassword);
88 |
89 | loadStringToEnvIfExist(doc, CONFIG_WIFI_IP_ADDRESS, envData.wifiIp);
90 | loadStringToEnvIfExist(doc, CONFIG_WIFI_GATEWAY, envData.wifiGateway);
91 | loadStringToEnvIfExist(doc, CONFIG_WIFI_SUBNET, envData.wifiSubnet);
92 | loadStringToEnvIfExist(doc, CONFIG_WIFI_DNS1, envData.wifiDns1);
93 | loadStringToEnvIfExist(doc, CONFIG_WIFI_DNS2, envData.wifiDns2);
94 |
95 | loadStringToEnvIfExist(doc, CONFIG_WM_AP_SSID, envData.wmApSSID);
96 | loadStringToEnvIfExist(doc, CONFIG_WM_AP_PASSWORD, envData.wmApPassword);
97 |
98 | #if defined USE_BLYNK
99 | loadStringToEnvIfExist(doc, CONFIG_BLYNK_AUTH, envData.blynkAuth);
100 | #ifndef USE_BLYNK_2
101 | loadStringToEnvIfExist(doc, CONFIG_BLYNK_HOSTNAME, envData.blynkServerHostname);
102 |
103 | if (doc.containsKey(CONFIG_BLYNK_PORT)) {
104 | envData.blynkServerPort = doc[CONFIG_BLYNK_PORT];
105 | }
106 | #endif
107 | #endif
108 | #ifdef USE_MQTT
109 | loadStringToEnvIfExist(doc, CONFIG_MQTT_HOSTNAME, envData.mqttServerHostname);
110 | loadStringToEnvIfExist(doc, CONFIG_MQTT_PASSWORD, envData.mqttPassword);
111 | loadStringToEnvIfExist(doc, CONFIG_MQTT_USERNAME, envData.mqttUsername);
112 | loadStringToEnvIfExist(doc, CONFIG_MQTT_CLIENT_ID, envData.mqttClientId);
113 | if (doc.containsKey(CONFIG_MQTT_PORT))
114 | envData.mqttServerPort = doc[CONFIG_MQTT_PORT];
115 |
116 | #endif
117 | #ifdef USE_MQTT_HOME_ASSISTANT
118 | loadStringToEnvIfExist(doc, CONFIG_MQTT_HA_DEVICE_ID, envData.mqttHADeviceId);
119 | loadStringToEnvIfExist(doc, CONFIG_MQTT_HA_DEVICE_NAME, envData.mqttHADeviceName);
120 | #endif
121 |
122 | #ifdef USE_OTA_UPDATE
123 | loadStringToEnvIfExist(doc, CONFIG_OTA_HOSTNAME, envData.otaHostname);
124 | loadStringToEnvIfExist(doc, CONFIG_OTA_PASSWORD, envData.otaPassword);
125 | #endif
126 |
127 | #ifdef USE_NTP_SERVER
128 | loadStringToEnvIfExist(doc, CONFIG_NTP_SERVER, envData.ntpServer);
129 | loadStringToEnvIfExist(doc, CONFIG_NTP_TIMEZONE, envData.ntpTimezone);
130 | #endif
131 | }
132 | }
133 | }
134 | LittleFS.end();
135 | #endif
136 | }
137 |
138 | void Environment::loadStringToEnvIfExist(DynamicJsonDocument doc, const char *envKey, char *envValue) {
139 | if (doc.containsKey(envKey)) strcpy(envValue, doc[envKey]);
140 | }
141 |
142 | void Environment::resetEnvData() {
143 | LittleFS.begin();
144 | // load from file
145 | if (LittleFS.exists(CONFIG_PERSISTENCE)) {
146 | LittleFS.remove(CONFIG_PERSISTENCE);
147 | }
148 | LittleFS.end();
149 | }
150 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Environment.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef ENVIRONMENT_H
25 | #define ENVIRONMENT_H
26 |
27 | #include "../core/debug.h"
28 | #include "../incl/include_all_core.h"
29 | #include "../incl/include_all_lib.h"
30 |
31 | struct EnvironrmentData {
32 | bool serialDebug = false;
33 | // wifi
34 | char wifiSSID[CONFIG_WIFI_SSID_LEN + 1] = WIFI_SSID;
35 | char wifiPassword[CONFIG_WIFI_PASSWORD_LEN + 1];
36 | char wifiIp[CONFIG_WIFI_IP_ADDRESS_LEN + 1];
37 | char wifiGateway[CONFIG_WIFI_GATEWAY_LEN + 1];
38 | char wifiSubnet[CONFIG_WIFI_SUBNET_LEN + 1];
39 | char wifiDns1[CONFIG_WIFI_DNS1_LEN + 1];
40 | char wifiDns2[CONFIG_WIFI_DNS2_LEN + 1];
41 | // wifi manager
42 | #ifdef USE_WIFI_AP_CONFIGURATION
43 | char wmApSSID[CONFIG_WM_AP_SSID_LEN + 1];
44 | char wmApPassword[CONFIG_WM_AP_PASSWORD_LEN + 1];
45 | #endif
46 | // blynk
47 | #ifdef USE_BLYNK
48 | #ifndef USE_BLYNK_2
49 | char blynkServerHostname[CONFIG_BLYNK_HOSTNAME_LEN + 1];
50 | uint16_t blynkServerPort;
51 | #endif
52 | char blynkAuth[CONFIG_BLYNK_AUTH_LEN + 1];
53 | #endif
54 | // mqtt
55 | #ifdef USE_MQTT
56 | char mqttServerHostname[CONFIG_MQTT_HOSTNAME_LEN + 1];
57 | uint16_t mqttServerPort;
58 | char mqttUsername[CONFIG_MQTT_USERNAME_LEN + 1];
59 | char mqttPassword[CONFIG_MQTT_PASSWORD_LEN + 1];
60 | char mqttClientId[CONFIG_MQTT_CLIENT_ID_LEN + 1];
61 | #endif
62 | #ifdef USE_MQTT_HOME_ASSISTANT
63 | char mqttHADeviceId[CONFIG_MQTT_HA_DEVICE_ID_LEN + 1];
64 | char mqttHADeviceName[CONFIG_MQTT_HA_DEVICE_NAME_LEN + 1];
65 | #endif
66 | #ifdef USE_OTA_UPDATE
67 | char otaHostname[CONFIG_OTA_HOSTNAME_LEN + 1];
68 | char otaPassword[CONFIG_OTA_PASSWORD_LEN + 1];
69 | #endif
70 | #ifdef USE_NTP_SERVER
71 | char ntpServer[CONFIG_NTP_SERVER_LEN + 1];
72 | char ntpTimezone[CONFIG_NTP_TIMEZONE_LEN + 1];
73 | #endif
74 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
75 | float heavyLoadCurrentZeroV = EXTERNAL_HEAVY_LOAD_CURRENT_METER_VOLTAGE_ZERO_AMP_VOLT;
76 | #endif
77 | };
78 |
79 | class Environment {
80 | public:
81 | static void loadEnvData();
82 |
83 | static void resetEnvData();
84 |
85 | static const EnvironrmentData *getData() {
86 | return &envData;
87 | }
88 |
89 | private:
90 | static void loadStringToEnvIfExist(DynamicJsonDocument doc, const char *envKey, char *envValue);
91 |
92 | static EnvironrmentData envData;
93 | };
94 |
95 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Text.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef TEXT_H
25 | #define TEXT_H
26 |
27 | class Text {
28 | public:
29 | static constexpr const char *ok = "OK";
30 | static constexpr const char *ko = "KO";
31 | static constexpr const char *dot = ".";
32 | static constexpr const char *password = "Password";
33 | static constexpr const char *connecting = "Connecting ";
34 | static constexpr const char *setupWithName = "++ SETTING UP %s";
35 | static constexpr const char *errorWithCode = "Error[%i]";
36 | static constexpr const char *errorWithCodeText = "Error[%i] %s";
37 | static constexpr const char *errorWithCodeInt = "Error[%i] %i";
38 | static constexpr const char *port = "Port";
39 | static constexpr const char *server = "Server";
40 | static constexpr const char *syncErrorWithCountAndType = "WARNING %i %s var. are not synced";
41 | static constexpr const char *syncErrorWithVariable = "WARNING \"%s\" is not synced";
42 | };
43 |
44 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Util.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
5 | * Copyright (c) 2021 Alberto Bettin
6 | *
7 | * Based on the work of @jaminNZx and @tekk.
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 |
24 | #include "Util.h"
25 |
26 | #define UTIL_MAX_DEC_DIV 1000
27 |
28 | uint8_t Util::digits(int number) {
29 | if (number < 0) return Util::digits(-number);
30 | if (number < 10) return 1;
31 | return 1 + Util::digits(number / 10);
32 | }
33 |
34 | char *Util::sharedBuffer = new char[256];
35 |
36 | char *Util::intToChar(int v, char *buf) {
37 | itoa(v, buf, 10);
38 | return buf;
39 | }
40 |
41 | char *Util::floatToChar(float v, char *buf) {
42 | uint8_t index = 0;
43 | if (v < 0) {
44 | buf[index++] = '-';
45 | }
46 |
47 | int iValue = (int)v;
48 | int dValue = (v - iValue) * UTIL_MAX_DEC_DIV;
49 | dValue = dValue < 0 ? -dValue : dValue;
50 |
51 | itoa(iValue, buf + index, 10);
52 | index += Util::digits(iValue);
53 |
54 | if (dValue >= 1) {
55 | buf[index++] = '.';
56 | int decMissPosition = Util::digits(UTIL_MAX_DEC_DIV) - Util::digits(dValue);
57 | while (--decMissPosition > 0) {
58 | buf[index++] = '0';
59 | }
60 | itoa(dValue, buf + index, 10);
61 | }
62 | return buf;
63 | }
64 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/Util.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef UTIL_H
25 | #define UTIL_H
26 |
27 | #include
28 |
29 | class Util {
30 | public:
31 | static char *intToChar(int v, char *buf);
32 | static char *intToChar(int v) {
33 | return intToChar(v, sharedBuffer);
34 | }
35 | static char *floatToChar(float v, char *buf);
36 | static char *floatToChar(float v) {
37 | return floatToChar(v, sharedBuffer);
38 | }
39 |
40 | static uint8_t digits(int number);
41 |
42 | /**
43 | * Shared buffer, use it with caution as it will be reused
44 | *
45 | */
46 | static char *sharedBuffer;
47 | };
48 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/VariableDefiner.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef VariableDefiner_h
25 | #define VariableDefiner_h
26 |
27 | #include "../incl/include_all_blynk_vpin.h"
28 | #include "../incl/include_all_core.h"
29 | #include "../incl/include_all_mqtt_topic.h"
30 |
31 | typedef enum {
32 | SR_REALTIME,
33 | SR_STATS,
34 | SR_INTERNAL
35 | } VariableSource;
36 |
37 | typedef enum {
38 | MD_READ,
39 | MD_READWRITE
40 | } VariableMode;
41 |
42 | typedef enum {
43 | DT_UNDEFINED,
44 | DT_STRING,
45 | DT_FLOAT,
46 | DT_BOOL,
47 | DT_UINT16
48 | } VariableDatatype;
49 |
50 | typedef enum {
51 | UOM_UNDEFINED,
52 | UOM_STATUS,
53 | UOM_TRIGGER,
54 | UOM_PERCENT,
55 | UOM_VOLT,
56 | UOM_WATT,
57 | UOM_KILOWATTHOUR,
58 | UOM_AMPERE,
59 | UOM_AMPEREHOUR,
60 | UOM_TEMPERATURE_C,
61 | UOM_MINUTE
62 | } VariableUOM;
63 |
64 | typedef enum {
65 | PV_VOLTAGE,
66 | PV_POWER,
67 | PV_CURRENT,
68 | LOAD_CURRENT,
69 | LOAD_POWER,
70 | BATTERY_TEMP,
71 | BATTERY_VOLTAGE,
72 | BATTERY_SOC,
73 | CONTROLLER_TEMP,
74 | BATTERY_CHARGE_CURRENT,
75 | BATTERY_CHARGE_POWER,
76 | BATTERY_OVERALL_CURRENT,
77 | REALTIME_CLOCK,
78 | LOAD_FORCE_ONOFF,
79 | LOAD_MANUAL_ONOFF,
80 | REMOTE_BATTERY_TEMP,
81 | GENERATED_ENERGY_TODAY,
82 | GENERATED_ENERGY_MONTH,
83 | GENERATED_ENERGY_YEAR,
84 | GENERATED_ENERGY_TOTAL,
85 | MAXIMUM_PV_VOLTAGE_TODAY,
86 | MINIMUM_PV_VOLTAGE_TODAY,
87 | MAXIMUM_BATTERY_VOLTAGE_TODAY,
88 | MINIMUM_BATTERY_VOLTAGE_TODAY,
89 | BATTERY_BOOST_VOLTAGE,
90 | BATTERY_EQUALIZATION_VOLTAGE,
91 | BATTERY_FLOAT_VOLTAGE,
92 | BATTERY_FLOAT_MIN_VOLTAGE,
93 | BATTERY_CHARGING_LIMIT_VOLTAGE,
94 | BATTERY_DISCHARGING_LIMIT_VOLTAGE,
95 | BATTERY_LOW_VOLTAGE_DISCONNECT,
96 | BATTERY_LOW_VOLTAGE_RECONNECT,
97 | BATTERY_OVER_VOLTAGE_DISCONNECT,
98 | BATTERY_OVER_VOLTAGE_RECONNECT,
99 | BATTERY_UNDER_VOLTAGE_SET,
100 | BATTERY_UNDER_VOLTAGE_RESET,
101 | BATTERY_STATUS_TEXT,
102 | CHARGING_EQUIPMENT_STATUS_TEXT,
103 | DISCHARGING_EQUIPMENT_STATUS_TEXT,
104 | CHARGING_DEVICE_ONOFF,
105 | HEATSINK_TEMP,
106 | BATTERY_RATED_VOLTAGE, // 0 - auto detect, otherwise specify the voltage of the battery
107 | BATTERY_TYPE, // 0 - custom, 1 - Sealed / AGM, 2 - GEL, 3 - Flooded / Wet Cell
108 | BATTERY_CAPACITY,
109 | BATTERY_EQUALIZATION_DURATION,
110 | BATTERY_BOOST_DURATION,
111 | BATTERY_TEMPERATURE_COMPENSATION_COEFFICIENT,
112 | BATTERY_MANAGEMENT_MODE, // 0 - voltage compensation, 1 - SOC
113 | CONSUMED_ENERGY_TODAY,
114 | CONSUMED_ENERGY_MONTH,
115 | CONSUMED_ENERGY_YEAR,
116 | CONSUMED_ENERGY_TOTAL,
117 | //----------------
118 | INTERNAL_STATUS,
119 | INTERNAL_DEBUG,
120 | //----------------
121 | UPDATE_ALL_CONTROLLER_DATA,
122 | //----------------
123 | VARIABLES_COUNT
124 | } Variable;
125 |
126 | struct VariableDefinition {
127 | Variable variable;
128 | const char *text;
129 | VariableDatatype datatype;
130 | VariableUOM uom;
131 | VariableSource source;
132 | VariableMode mode;
133 | const uint8_t *blynkVPin;
134 | const char *mqttTopic;
135 | };
136 |
137 | class VariableDefiner {
138 | public:
139 | static VariableDefiner &getInstance() {
140 | static VariableDefiner instance;
141 | return instance;
142 | }
143 |
144 | const VariableDefinition *getDefinition(Variable variable);
145 |
146 | const VariableDefinition *getDefinitionByBlynkVPin(uint8_t pin);
147 |
148 | const VariableDefinition *getDefinitionByMqttTopic(const char *mqttTopic);
149 |
150 | VariableDatatype getDatatype(Variable variable);
151 |
152 | bool isFromScc(const Variable variable) {
153 | return this->variables[variable].source != VariableSource::SR_INTERNAL;
154 | }
155 |
156 | bool isValueEqual(Variable variable, const void *val1, const void *val2) {
157 | uint8_t valueSize = this->getVariableSize(variable);
158 | if (valueSize > 0) {
159 | return memcmp(val1, val2, valueSize) == 0;
160 | }
161 | return false;
162 | }
163 |
164 | uint8_t getVariableSize(Variable variable);
165 |
166 | private:
167 | VariableDefiner();
168 |
169 | void initializeVariable(Variable variable, const char *text, VariableDatatype datatype, VariableUOM uom, VariableSource source, VariableMode mode, uint8_t *blynkPin, const char *mqttTopic);
170 |
171 | VariableDefinition *variables = new VariableDefinition[Variable::VARIABLES_COUNT]();
172 | };
173 |
174 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/datetime.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef DATETIME_H
25 | #define DATETIME_H
26 |
27 | #include "../core/Environment.h"
28 | #include "../incl/include_all_core.h"
29 |
30 | class Datetime {
31 | public:
32 | #ifdef USE_NTP_SERVER
33 | static bool setupDatetimeFromNTP() {
34 | uint8_t maxCount = 20;
35 | debugPrint(Text::connecting);
36 | configTzTime(Environment::getData()->ntpTimezone, Environment::getData()->ntpServer);
37 |
38 | while (time(nullptr) < 100000ul && --maxCount > 0) {
39 | debugPrint(Text::dot);
40 | delay(500);
41 | }
42 | debugPrintln(maxCount > 0 ? Text::ok : Text::ko);
43 | return maxCount > 0;
44 | }
45 | #endif
46 |
47 | static struct tm *getMyNowTm() {
48 | time_t tnow = time(nullptr) + 1;
49 | return tnow <= 100000ul ? nullptr : localtime(&tnow);
50 | }
51 | };
52 |
53 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/debug.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "debug.h"
23 | #include // vsnprintf
24 |
25 | #include "../incl/include_all_core.h"
26 |
27 | #define DEBUG_REGISTER_CALLBACKS_MAX 2
28 |
29 | bool debugEnabled = true;
30 |
31 | void setDebugEnabled(bool enabled)
32 | {
33 | debugEnabled = enabled;
34 | }
35 |
36 | uint8_t regCallbacksIndex = 0;
37 | void (*regCallbacks[DEBUG_REGISTER_CALLBACKS_MAX])(String);
38 |
39 | void debugAddRegisterCallback(void (*regCallback)(String))
40 | {
41 | if (regCallbacksIndex < DEBUG_REGISTER_CALLBACKS_MAX)
42 | {
43 | regCallbacks[regCallbacksIndex++] = regCallback;
44 | }
45 | }
46 |
47 | void debugDispactMessageRegisterCallback(String msg)
48 | {
49 | for (uint8_t index = 0; index < regCallbacksIndex; index++)
50 | {
51 | (*regCallbacks[index])(msg);
52 | }
53 | }
54 |
55 | void debugPrint(String message)
56 | {
57 | if (debugEnabled)
58 | {
59 | BOARD_DEBUG_SERIAL_STREAM.print(message);
60 | }
61 | for (uint8_t index = 0; index < regCallbacksIndex; index++)
62 | {
63 | (*regCallbacks[index])(message);
64 | }
65 | }
66 |
67 | void debugPrintln()
68 | {
69 | debugPrint("\r\n");
70 | }
71 |
72 | void debugPrintln(String msgString)
73 | {
74 | debugPrint(msgString + "\r\n");
75 | }
76 |
77 | void debugPrintln(const char *msgChar)
78 | {
79 | debugPrintln(String(msgChar));
80 | }
81 |
82 | void debugPrint(const char *msgChar)
83 | {
84 | debugPrint(String(msgChar));
85 | }
86 |
87 | void debugPrintln(int num)
88 | {
89 | debugPrintln(String(num));
90 | }
91 |
92 | void debugPrint(const int num)
93 | {
94 | debugPrint(String(num));
95 | }
96 |
97 | void debugPrintln(unsigned char num)
98 | {
99 | debugPrintln(String(num));
100 | }
101 |
102 | void debugPrint(unsigned char num)
103 | {
104 | debugPrint(String(num));
105 | }
106 |
107 | void debugPrintf(bool newLine, const char *format, ...)
108 | {
109 | va_list args;
110 | va_start(args, format);
111 | vsnprintf(Util::sharedBuffer, 256, format, args);
112 | newLine ? debugPrintln(String(Util::sharedBuffer)) : debugPrint(String(Util::sharedBuffer));
113 | va_end(args);
114 | }
115 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/core/debug.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef DEBUG_H
25 | #define DEBUG_H
26 |
27 | #include "../incl/include_all_core.h"
28 | void setDebugEnabled(bool enable);
29 | void debugAddRegisterCallback(void (*regCallback)(String));
30 | void debugDispactMessageRegisterCallback(String msg);
31 | void debugPrint(String message);
32 | void debugPrintln();
33 | void debugPrintln(const String msgString);
34 | void debugPrintln(const char *msgChar);
35 | void debugPrint(const char *msgChar);
36 | void debugPrintln(int num);
37 | void debugPrint(int num);
38 | void debugPrintln(unsigned char num);
39 | void debugPrint(unsigned char num);
40 | void debugPrintf(bool newLine, const char *format, ...);
41 |
42 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/BlynkSync.cpp:
--------------------------------------------------------------------------------
1 | #include "BlynkSync.h"
2 |
3 | #include "../incl/include_all_core.h"
4 |
5 | #ifdef USE_BLYNK
6 |
7 | #include "../core/Environment.h"
8 | #include "../core/datetime.h"
9 | #include "../incl/include_all_lib.h"
10 |
11 | // reducing Blynk footprint
12 | #define BLYNK_NO_BUILTIN // Disable built-in analog & digital pin operations
13 | #define BLYNKTIMER_H // no blynk timer - using simple timer
14 | #if defined USE_BLYNK
15 | #if defined ESP32
16 | #include
17 | #elif defined ESP8266
18 | #include
19 | #endif
20 | #endif
21 |
22 | #ifndef BLYNK_CONNECT_ATTEMPT
23 | #define BLYNK_CONNECT_ATTEMPT 10
24 | #endif
25 |
26 | #ifdef vPIN_INTERNAL_DEBUG_TERMINAL
27 | void blynkDebugCallback(String message) {
28 | Blynk.virtualWrite(vPIN_INTERNAL_DEBUG_TERMINAL, message);
29 | }
30 | #endif
31 |
32 | BlynkSync::BlynkSync() {
33 | this->renewValueCount = BLYNK_VALUE_CACHES_UNTIL_COUNT;
34 | }
35 |
36 | void BlynkSync::setup() {
37 | #ifndef BLYNK_CONNECTION_REQUIRED
38 | this->connect(true);
39 | #else
40 | this->connect(false);
41 | #endif
42 | #ifdef vPIN_INTERNAL_DEBUG_TERMINAL
43 | debugAddRegisterCallback(blynkDebugCallback);
44 | #endif
45 | }
46 |
47 | void BlynkSync::connect(bool blocking) {
48 | debugPrintf(true, Text::setupWithName, "BLYNK");
49 | debugPrint(Text::connecting);
50 |
51 | #ifdef USE_BLYNK_2
52 | Blynk.config(Environment::getData()->blynkAuth);
53 | #else
54 |
55 | Blynk.config(
56 | Environment::getData()->blynkAuth,
57 | strlen(Environment::getData()->blynkServerHostname) ? Environment::getData()->blynkServerHostname : BLYNK_DEFAULT_DOMAIN,
58 | Environment::getData()->blynkServerPort ? Environment::getData()->blynkServerPort : BLYNK_DEFAULT_PORT);
59 |
60 | #endif
61 |
62 | uint8_t counter = 0;
63 |
64 | while (( blocking || counter < BLYNK_CONNECT_ATTEMPT) && !Blynk.connect()) {
65 | delay(500);
66 | debugPrint(Text::dot);
67 |
68 | counter++;
69 | }
70 |
71 | debugPrintln(Blynk.connected() ? Text::ok : Text::ko);
72 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_BLYNK_CONNECTION, false);
73 | }
74 |
75 | void BlynkSync::loop() {
76 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_BLYNK_CONNECTION, !Blynk.connected());
77 | Blynk.run();
78 | }
79 |
80 | bool BlynkSync::sendUpdateToVariable(const VariableDefinition *def, const void *value) {
81 | if (def->blynkVPin != nullptr) {
82 | switch (def->datatype) {
83 | case VariableDatatype::DT_BOOL: {
84 | Blynk.virtualWrite(*def->blynkVPin, *(bool *)value);
85 | return true;
86 | } break;
87 | case VariableDatatype::DT_FLOAT: {
88 | Blynk.virtualWrite(*def->blynkVPin, *(float *)value);
89 | return true;
90 | } break;
91 | case VariableDatatype::DT_UINT16: {
92 | Blynk.virtualWrite(*def->blynkVPin, *(uint16_t *)value);
93 | return true;
94 | } break;
95 | case VariableDatatype::DT_STRING: {
96 | Blynk.virtualWrite(*def->blynkVPin, (const char *)value);
97 | return true;
98 | }
99 | }
100 | }
101 | return false;
102 | }
103 |
104 | // upload values stats
105 | void BlynkSync::uploadStatsToBlynk() {
106 | if (!Blynk.connected()) {
107 | return;
108 | }
109 |
110 | BlynkSync::getInstance().sendUpdateAllBySource(VariableSource::SR_STATS, false);
111 | }
112 |
113 | // upload values realtime
114 | void BlynkSync::uploadRealtimeToBlynk() {
115 | if (!Blynk.connected()) {
116 | return;
117 | }
118 |
119 | #ifdef vPIN_INTERNAL_STATUS
120 | uint16_t status = Controller::getInstance().getStatus();
121 | this->sendUpdateToVariable(VariableDefiner::getInstance().getDefinition(Variable::INTERNAL_STATUS), &(status));
122 | #endif
123 | this->sendUpdateAllBySource(VariableSource::SR_REALTIME, false);
124 | }
125 |
126 | BLYNK_WRITE_DEFAULT() {
127 | const VariableDefinition *def = VariableDefiner::getInstance().getDefinitionByBlynkVPin(request.pin);
128 | if (def != nullptr) {
129 | if (def->source == VariableSource::SR_INTERNAL) {
130 | switch (def->variable) {
131 | case Variable::REALTIME_CLOCK: {
132 | if (param.asInt() > 0) {
133 | debugPrintln("UPDATE CONTROLLER DATETIME");
134 | if (Datetime::getMyNowTm() != nullptr) {
135 | Controller::getInstance().getSolarController()->syncRealtimeClock(Datetime::getMyNowTm());
136 | }
137 | Blynk.virtualWrite(*def->blynkVPin, 0);
138 | }
139 | } break;
140 | case Variable::UPDATE_ALL_CONTROLLER_DATA: {
141 | if (param.asInt() > 0) {
142 | debugPrintln("REQUEST ALL VALUES TO CONTROLLER");
143 | Controller::getInstance().getSolarController()->fetchAllValues();
144 | BlynkSync::getInstance().uploadRealtimeToBlynk();
145 | BlynkSync::getInstance().uploadStatsToBlynk();
146 |
147 | Blynk.virtualWrite(*def->blynkVPin, 0);
148 | }
149 | } break;
150 | }
151 | } else if (Controller::getInstance().getSolarController()->isVariableEnabled(def->variable)) {
152 | switch (def->datatype) {
153 | case VariableDatatype::DT_UINT16: {
154 | uint16_t newState = param.asInt();
155 | BlynkSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
156 | } break;
157 | case VariableDatatype::DT_FLOAT: {
158 | float newState = param.asFloat();
159 | BlynkSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
160 | } break;
161 | case VariableDatatype::DT_BOOL: {
162 | bool newState = param.asInt() > 0;
163 | BlynkSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
164 | } break;
165 | }
166 | }
167 | }
168 | }
169 |
170 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/BlynkSync.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef BLYNK_SYNC_H
25 | #define BLYNK_SYNC_H
26 |
27 | #include "../incl/include_all_core.h"
28 |
29 | #ifdef USE_BLYNK
30 |
31 | #include "../core/BaseSync.h"
32 | #include "../core/Controller.h"
33 | #include "../core/VariableDefiner.h"
34 | #include "../incl/include_all_lib.h"
35 |
36 | #define BLYNK_CONNECT_ATTEMPT 3
37 | #define BLYNK_VALUE_CACHES_UNTIL_COUNT 15
38 |
39 | #ifdef vPIN_INTERNAL_DEBUG_TERMINAL
40 | void blynkDebugCallback(String message);
41 | #endif
42 |
43 | class BlynkSync : public BaseSync {
44 | public:
45 | static BlynkSync &getInstance() {
46 | static BlynkSync instance;
47 | return instance;
48 | }
49 |
50 | void setup();
51 | void connect(bool blocking = true);
52 | void loop();
53 | inline bool isVariableAllowed(const VariableDefinition *def);
54 | bool sendUpdateToVariable(const VariableDefinition *def, const void *value);
55 | // upload values stats
56 | void uploadStatsToBlynk();
57 | // upload values realtime
58 | void uploadRealtimeToBlynk();
59 |
60 | private:
61 | BlynkSync();
62 | };
63 |
64 | bool BlynkSync::isVariableAllowed(const VariableDefinition *def) {
65 | return def->blynkVPin != nullptr;
66 | }
67 |
68 | #endif
69 | #endif
70 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/MqttHASync.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "MqttHASync.h"
23 |
24 | #include "../core/datetime.h"
25 | #include "../incl/include_all_core.h"
26 |
27 | #ifdef USE_MQTT_HOME_ASSISTANT
28 |
29 | char mqttPublishBuffer[20];
30 |
31 | #define RETAIN_ALL_MSG false
32 | #define MQTT_CONNECT_ATTEMPT 3
33 |
34 | // every setValue/setState will trigger mqttCallbacks,
35 | bool ignoreCallback = false;
36 |
37 | inline const char *getVariableUOM(VariableUOM uom) {
38 | switch (uom) {
39 | case UOM_TEMPERATURE_C:
40 | return "°C";
41 | case UOM_WATT:
42 | return "W";
43 | case UOM_KILOWATTHOUR:
44 | return "kWh";
45 | case UOM_PERCENT:
46 | return "%";
47 | case UOM_AMPERE:
48 | return "A";
49 | case UOM_VOLT:
50 | return "V";
51 | case UOM_MINUTE:
52 | return "min";
53 | }
54 | return nullptr;
55 | }
56 |
57 | void onMqttNumberCallback(HANumeric value, HANumber *el) {
58 | if (!ignoreCallback) {
59 | MqttHASync haSync = MqttHASync::getInstance();
60 | Variable var = haSync.findVariableBySensor(el);
61 | if (var < Variable::VARIABLES_COUNT) {
62 | switch (VariableDefiner::getInstance().getDatatype(var)) {
63 | case DT_UINT16: {
64 | uint16_t rValue = value.toUInt16();
65 | haSync.applyUpdateToVariable(var, &rValue, false);
66 | } break;
67 | case DT_FLOAT: {
68 | float rValue = value.toFloat();
69 | haSync.applyUpdateToVariable(var, &rValue, false);
70 | } break;
71 | }
72 | }
73 | }
74 | }
75 |
76 | void onMqttBoolButtonCallback(HAButton *el) {
77 | if (!ignoreCallback) {
78 | MqttHASync haSync = MqttHASync::getInstance();
79 | Variable var = haSync.findVariableBySensor(el);
80 | if (var < Variable::VARIABLES_COUNT) {
81 | switch (var) {
82 | case Variable::REALTIME_CLOCK:
83 | debugPrintln("UPDATE CONTROLLER DATETIME");
84 | if (Datetime::getMyNowTm() != nullptr) {
85 | Controller::getInstance().getSolarController()->syncRealtimeClock(Datetime::getMyNowTm());
86 | }
87 | break;
88 | case Variable::UPDATE_ALL_CONTROLLER_DATA:
89 | debugPrintln("REQUEST ALL VALUES TO CONTROLLER");
90 | Controller::getInstance().getSolarController()->fetchAllValues();
91 | MqttHASync::getInstance().uploadRealtimeToMqtt();
92 | MqttHASync::getInstance().uploadStatsToMqtt();
93 | break;
94 | }
95 | }
96 | }
97 | }
98 |
99 | void onMqttBoolSwitchCallback(bool value, HASwitch *el) {
100 | if (!ignoreCallback) {
101 | MqttHASync haSync = MqttHASync::getInstance();
102 | Variable var = haSync.findVariableBySensor(el);
103 | if (var < Variable::VARIABLES_COUNT) {
104 | haSync.applyUpdateToVariable(var, &value, false);
105 | }
106 | }
107 | }
108 |
109 | void setupHASensor(HASensor *sensor, const VariableUOM *uom) {
110 | switch (*uom) {
111 | case UOM_TEMPERATURE_C:
112 | sensor->setDeviceClass("temperature");
113 | break;
114 | case UOM_WATT:
115 | sensor->setDeviceClass("power");
116 | break;
117 | case UOM_KILOWATTHOUR:
118 | sensor->setDeviceClass("energy");
119 | break;
120 | case UOM_PERCENT:
121 | sensor->setUnitOfMeasurement("%");
122 | break;
123 | case UOM_AMPERE:
124 | sensor->setDeviceClass("current");
125 | break;
126 | case UOM_VOLT:
127 | sensor->setDeviceClass("voltage");
128 | break;
129 | }
130 | sensor->setUnitOfMeasurement(getVariableUOM(*uom));
131 | sensor->setValue(nullptr);
132 | }
133 |
134 | MqttHASync::MqttHASync() : BaseSync() {
135 | this->renewValueCount = 0;
136 |
137 | WiFiClient *wifiClient = new WiFiClient;
138 |
139 | device = new HADevice(Environment::getData()->mqttClientId);
140 | mqtt = new HAMqtt(*wifiClient, *device, VARIABLES_COUNT);
141 | }
142 |
143 | void MqttHASync::setup() {
144 | // set device's details
145 |
146 | device->setName(Environment::getData()->mqttHADeviceName);
147 | device->setManufacturer(PROJECT_AUTHOR);
148 | device->setModel(PROJECT_NAME);
149 | device->setSoftwareVersion(PROJECT_VERSION);
150 | device->setConfigurationUrl(WiFi.localIP().toString().c_str());
151 | device->enableSharedAvailability();
152 | device->enableLastWill();
153 |
154 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
155 | const VariableDefinition *def = VariableDefiner::getInstance().getDefinition((Variable)index);
156 |
157 | if (def->mqttTopic != nullptr && (def->source == VariableSource::SR_INTERNAL || Controller::getInstance().getSolarController()->isVariableEnabled(def->variable) || Controller::getInstance().getSolarController()->isVariableOverWritten(def->variable))) {
158 | haSensors[index] = nullptr;
159 | switch (def->datatype) {
160 | case DT_BOOL:
161 | if (def->mode == MD_READWRITE) {
162 | if (def->uom == UOM_TRIGGER) {
163 | HAButton *haButton = new HAButton(def->mqttTopic);
164 | haButton->onCommand(onMqttBoolButtonCallback);
165 | haSensors[index] = haButton;
166 | } else {
167 | HASwitch *haSwitch = new HASwitch(def->mqttTopic);
168 | haSwitch->onCommand(onMqttBoolSwitchCallback);
169 | haSensors[index] = haSwitch;
170 | }
171 | } else {
172 | haSensors[index] = new HABinarySensor(def->mqttTopic);
173 | }
174 | break;
175 | case DT_UINT16:
176 | case DT_FLOAT:
177 | if (def->mode == MD_READWRITE) {
178 | HANumber *haNumber = new HANumber(
179 | def->mqttTopic,
180 | def->datatype == DT_FLOAT ? HABaseDeviceType::PrecisionP2 : HABaseDeviceType::PrecisionP0);
181 | haNumber->onCommand(onMqttNumberCallback);
182 | haNumber->setStep(def->datatype == DT_FLOAT ? 0.01 : 1);
183 | haNumber->setUnitOfMeasurement(getVariableUOM(def->uom));
184 | haSensors[index] = haNumber;
185 | } else {
186 | HASensorNumber *hASensor = new HASensorNumber(
187 | def->mqttTopic,
188 | def->datatype == DT_FLOAT ? HABaseDeviceType::PrecisionP2 : HABaseDeviceType::PrecisionP0);
189 | setupHASensor(hASensor, &(def->uom));
190 | haSensors[index] = hASensor;
191 | }
192 | break;
193 | default:
194 | if (def->mode == MD_READWRITE) {
195 | HANumber *haNumber = new HANumber(def->mqttTopic);
196 | haNumber->onCommand(onMqttNumberCallback);
197 | haNumber->setStep(def->datatype == DT_FLOAT ? 0.01 : 1);
198 | haNumber->setUnitOfMeasurement(getVariableUOM(def->uom));
199 | haSensors[index] = haNumber;
200 | } else {
201 | HASensor *hASensor = new HASensor(def->mqttTopic);
202 | setupHASensor(hASensor, &(def->uom));
203 | haSensors[index] = hASensor;
204 | }
205 | }
206 |
207 | haSensors[index]->setName(def->text);
208 |
209 | if (strlen(Environment::getData()->mqttHADeviceId) <= 0) {
210 | haSensors[index]->setObjectId(def->mqttTopic);
211 | } else {
212 | char *idName = new char[strlen(Environment::getData()->mqttHADeviceId) + strlen(def->text) + 2];
213 | strcpy(idName, Environment::getData()->mqttHADeviceId);
214 | strcat(idName, " ");
215 | strcat(idName, def->text);
216 | haSensors[index]->setObjectId(idName);
217 | }
218 | }
219 | }
220 | this->connect();
221 | }
222 |
223 | Variable MqttHASync::findVariableBySensor(HABaseDeviceType *haSensor) {
224 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
225 | if (haSensors[index] == haSensor) {
226 | return (Variable)index;
227 | }
228 | }
229 | return Variable::VARIABLES_COUNT;
230 | }
231 |
232 | void MqttHASync::connect(bool blocking) {
233 | if (this->initialized) {
234 | mqtt->disconnect();
235 | }
236 | this->initialized = false;
237 | debugPrintf(true, Text::setupWithName, "MQTT-HA");
238 |
239 | uint8_t counter;
240 |
241 | do {
242 | counter = 0;
243 | debugPrint(Text::connecting);
244 | if (!initialized) {
245 | initialized = mqtt->begin(
246 | Environment::getData()->mqttServerHostname,
247 | Environment::getData()->mqttServerPort,
248 | strlen(Environment::getData()->mqttUsername) > 0 ? Environment::getData()->mqttUsername : nullptr,
249 | strlen(Environment::getData()->mqttPassword) > 0 ? Environment::getData()->mqttPassword : nullptr);
250 | }
251 | mqtt->loop();
252 |
253 | while (!mqtt->isConnected() && counter < 10) {
254 | debugPrint(Text::dot);
255 | delay(500);
256 | counter++;
257 | }
258 | if (mqtt->getState() != HAMqtt::StateConnected) {
259 | debugPrintf(true, Text::errorWithCode, mqtt->getState());
260 | } else {
261 | debugPrintln(Text::ok);
262 | }
263 | } while (blocking && !mqtt->isConnected());
264 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_MQTT_CONNECTION, !mqtt->isConnected());
265 | }
266 | void MqttHASync::loop() {
267 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_MQTT_CONNECTION, !mqtt->isConnected());
268 | mqtt->loop();
269 | }
270 | bool MqttHASync::isVariableAllowed(const VariableDefinition *def) {
271 | return def->mqttTopic != nullptr;
272 | }
273 | bool MqttHASync::sendUpdateToVariable(const VariableDefinition *def, const void *value) {
274 | HABaseDeviceType *sensor = haSensors[def->variable];
275 | bool result = false;
276 | ignoreCallback = true;
277 | switch (def->datatype) {
278 | case VariableDatatype::DT_UINT16:
279 | result = def->mode == MD_READ
280 | ? ((HASensorNumber *)sensor)->setValue(*(uint16_t *)value)
281 | : ((HANumber *)sensor)->setState(*(uint16_t *)value);
282 | break;
283 | case VariableDatatype::DT_FLOAT:
284 | result = def->mode == MD_READ
285 | ? ((HASensorNumber *)sensor)->setValue(*(float *)value)
286 | : ((HANumber *)sensor)->setState(*(float *)value);
287 | break;
288 | case VariableDatatype::DT_BOOL:
289 | result = def->uom != UOM_TRIGGER
290 | ? def->mode == MD_READ
291 | ? ((HASwitch *)sensor)->setState(*(bool *)value)
292 | : ((HABinarySensor *)sensor)->setState(*(bool *)value)
293 | : false;
294 | break;
295 | default:
296 | result = ((HASensor *)sensor)->setValue((const char *)value);
297 | break;
298 | }
299 | ignoreCallback = false;
300 | return result;
301 | }
302 |
303 | // upload values stats
304 | void MqttHASync::uploadStatsToMqtt() {
305 | if (!this->mqtt->isConnected()) {
306 | return;
307 | }
308 |
309 | this->sendUpdateAllBySource(VariableSource::SR_STATS, false);
310 | }
311 |
312 | // upload values realtime
313 | void MqttHASync::uploadRealtimeToMqtt() {
314 | if (!this->mqtt->isConnected()) {
315 | return;
316 | }
317 |
318 | #ifdef MQTT_TOPIC_INTERNAL_STATUS
319 | uint16_t status = Controller::getInstance().getStatus();
320 | this->syncVariable(VariableDefiner::getInstance().getDefinition(Variable::INTERNAL_STATUS), &(status));
321 | #endif
322 | this->sendUpdateAllBySource(VariableSource::SR_REALTIME, false);
323 | }
324 |
325 | #endif
326 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/MqttHASync.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #include "../incl/include_all_core.h"
25 |
26 | #ifdef USE_MQTT_HOME_ASSISTANT
27 |
28 | #include "../core/BaseSync.h"
29 | #include "../core/Controller.h"
30 | #include "../core/VariableDefiner.h"
31 | #include "../incl/include_all_lib.h"
32 |
33 | class MqttHASync : public BaseSync {
34 | public:
35 | static MqttHASync &getInstance() {
36 | static MqttHASync instance;
37 | return instance;
38 | }
39 |
40 | void setup();
41 | void connect(bool blocking = true);
42 | void loop();
43 | inline bool isVariableAllowed(const VariableDefinition *def);
44 | bool sendUpdateToVariable(const VariableDefinition *def, const void *value);
45 | // upload values stats
46 | void uploadStatsToMqtt();
47 | // upload values realtime
48 | void uploadRealtimeToMqtt();
49 |
50 | Variable findVariableBySensor(HABaseDeviceType *haSensor);
51 |
52 | private:
53 | MqttHASync();
54 |
55 | HADevice *device;
56 | HAMqtt *mqtt;
57 | HABaseDeviceType *haSensors[Variable::VARIABLES_COUNT];
58 |
59 | bool initialized;
60 | };
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/MqttSync.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "MqttSync.h"
23 |
24 | #include "../incl/include_all_core.h"
25 |
26 | #if defined(USE_MQTT) && !defined(USE_MQTT_HOME_ASSISTANT)
27 |
28 | #include "../core/datetime.h"
29 |
30 | #define RETAIN_ALL_MSG false
31 | #define MQTT_CONNECT_ATTEMPT 3
32 |
33 | #if defined(USE_MQTT_RPC_SUBSCRIBE)
34 | DynamicJsonDocument json(1024);
35 | #endif
36 | void mqttCallback(char *topic, uint8_t *bytes, unsigned int length) {
37 | String payload;
38 | for (int i = 0; i < length; i++) {
39 | payload += (char)bytes[i];
40 | }
41 |
42 | #ifdef USE_MQTT_RPC_SUBSCRIBE
43 | deserializeJson(json, payload);
44 | const char *constTopic = json["method"].as();
45 | payload = json["params"].as();
46 | #else
47 | const char *constTopic = topic;
48 | #endif
49 |
50 | const VariableDefinition *def = VariableDefiner::getInstance().getDefinitionByMqttTopic(topic);
51 |
52 | if (def != nullptr && def->mode == MD_READWRITE) {
53 | if (def->source == VariableSource::SR_INTERNAL) {
54 | switch (def->variable) {
55 | case Variable::REALTIME_CLOCK: {
56 | if (payload.toInt() > 0) {
57 | debugPrintln("UPDATE CONTROLLER DATETIME");
58 | if (Datetime::getMyNowTm() != nullptr) {
59 | Controller::getInstance().getSolarController()->syncRealtimeClock(Datetime::getMyNowTm());
60 | }
61 | }
62 | } break;
63 | case Variable::UPDATE_ALL_CONTROLLER_DATA: {
64 | if (payload.toInt() > 0) {
65 | debugPrintln("REQUEST ALL VALUES TO CONTROLLER");
66 | Controller::getInstance().getSolarController()->fetchAllValues();
67 | MqttSync::getInstance().uploadRealtimeToMqtt();
68 | MqttSync::getInstance().uploadStatsToMqtt();
69 | }
70 | } break;
71 | }
72 | } else {
73 | switch (def->datatype) {
74 | case VariableDatatype::DT_UINT16: {
75 | uint16_t newState = payload.toInt();
76 | MqttSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
77 | }
78 | case VariableDatatype::DT_FLOAT: {
79 | float newState = payload.toFloat();
80 | MqttSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
81 | }
82 | case VariableDatatype::DT_BOOL: {
83 | bool newState = payload.toInt() > 0;
84 | MqttSync::getInstance().applyUpdateToVariable(def->variable, &newState, false);
85 | } break;
86 | }
87 | }
88 | }
89 | }
90 |
91 | MqttSync::MqttSync() {
92 | WiFiClient *espClient = new WiFiClient();
93 | this->mqttClient = new PubSubClient(*espClient);
94 | }
95 |
96 | void MqttSync::setup() {
97 | this->mqttClient->setServer(Environment::getData()->mqttServerHostname, Environment::getData()->mqttServerPort);
98 |
99 | mqttClient->setCallback(mqttCallback);
100 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
101 | const VariableDefinition *def = VariableDefiner::getInstance().getDefinition((Variable)index);
102 | if (def->mqttTopic != nullptr && def->mode == MD_READWRITE && (def->source == VariableSource::SR_INTERNAL || Controller::getInstance().getSolarController()->isVariableEnabled(def->variable))) {
103 | this->mqttClient->subscribe(def->mqttTopic);
104 | }
105 | }
106 |
107 | this->connect();
108 | }
109 |
110 | void MqttSync::connect(bool blocking) {
111 | debugPrintf(true, Text::setupWithName, "MQTT");
112 | debugPrint(Text::connecting);
113 |
114 | uint8_t counter = 0;
115 |
116 | do {
117 | mqttClient->connect(
118 |
119 | Environment::getData()->mqttClientId,
120 | strlen(Environment::getData()->mqttUsername) > 0 ? Environment::getData()->mqttUsername : nullptr,
121 | strlen(Environment::getData()->mqttPassword) > 0 ? Environment::getData()->mqttPassword : nullptr);
122 | while (!mqttClient->connected() && counter < 10) {
123 | debugPrint(Text::dot);
124 | delay(500);
125 | counter++;
126 | }
127 |
128 | if (mqttClient->state() != MQTT_CONNECTED) {
129 | debugPrintf(true, Text::errorWithCode, mqttClient->state());
130 | } else {
131 | debugPrintln(Text::ok);
132 | }
133 |
134 | } while (blocking && !mqttClient->connected());
135 |
136 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_MQTT_CONNECTION, !mqttClient->connected());
137 | }
138 | void MqttSync::loop() {
139 | Controller::getInstance().setErrorFlag(STATUS_ERR_NO_MQTT_CONNECTION, !mqttClient->connected());
140 | mqttClient->loop();
141 | }
142 | bool MqttSync::isVariableAllowed(const VariableDefinition *def) {
143 | return def->mqttTopic != nullptr;
144 | }
145 | bool MqttSync::sendUpdateToVariable(const VariableDefinition *def, const void *value) {
146 | switch (def->datatype) {
147 | case VariableDatatype::DT_UINT16:
148 | #ifdef USE_MQTT_JSON_PUBLISH
149 | syncJson[def->mqttTopic] = *(uint16_t *)value;
150 | return true;
151 | #else
152 | dtostrf(*(uint16_t *)value, 0, 0, mqttPublishBuffer);
153 | #endif
154 | case VariableDatatype::DT_FLOAT:
155 | #ifdef USE_MQTT_JSON_PUBLISH
156 | syncJson[def->mqttTopic] = *(float *)value;
157 | return true;
158 | #else
159 | dtostrf(*(float *)value, 0, 4, mqttPublishBuffer);
160 | return mqttClient->publish(def->mqttTopic, mqttPublishBuffer, RETAIN_ALL_MSG);
161 | #endif
162 | case VariableDatatype::DT_BOOL:
163 | #ifdef USE_MQTT_JSON_PUBLISH
164 | syncJson[def->mqttTopic] = *(bool *)value;
165 | return true;
166 | #else
167 | return mqttClient->publish(def->mqttTopic, (*(const bool *)value) ? "1" : "0", RETAIN_ALL_MSG);
168 | #endif
169 | case VariableDatatype::DT_STRING:
170 | #ifdef USE_MQTT_JSON_PUBLISH
171 | syncJson[def->mqttTopic] = *(const char *)value;
172 | return true;
173 | #else
174 | return mqttClient->publish(def->mqttTopic, (const char *)value, RETAIN_ALL_MSG);
175 | #endif
176 | }
177 | return false;
178 | }
179 |
180 | // upload values stats
181 | void MqttSync::uploadStatsToMqtt() {
182 | if (!this->mqttClient->connected()) {
183 | return;
184 | }
185 |
186 | MqttSync::getInstance().sendUpdateAllBySource(VariableSource::SR_STATS, false);
187 | #ifdef USE_MQTT_JSON_PUBLISH
188 | String output;
189 | serializeJson(syncJson, output);
190 | if (syncJson.size() > 0) {
191 | mqttClient->publish(MQTT_JSON_PUBLISH_TOPIC, output.c_str());
192 | }
193 | #endif
194 | }
195 |
196 | // upload values realtime
197 | void MqttSync::uploadRealtimeToMqtt() {
198 | if (!this->mqttClient->connected()) {
199 | return;
200 | }
201 |
202 | #ifdef MQTT_TOPIC_INTERNAL_STATUS
203 | float status = Controller::getInstance().getStatus();
204 | this->sendUpdateToVariable(VariableDefiner::getInstance().getDefinition(Variable::INTERNAL_STATUS), &(status));
205 | #endif
206 | this->sendUpdateAllBySource(VariableSource::SR_REALTIME, false);
207 | #ifdef USE_MQTT_JSON_PUBLISH
208 | String output;
209 | serializeJson(syncJson, output);
210 | if (syncJson.size() > 0) {
211 | mqttClient->publish(MQTT_JSON_PUBLISH_TOPIC, output.c_str());
212 | }
213 | #endif
214 | }
215 |
216 | #endif
217 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/MqttSync.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #include "../incl/include_all_core.h"
25 |
26 | #if defined(USE_MQTT) && !defined(USE_MQTT_HOME_ASSISTANT)
27 |
28 | #include "../core/BaseSync.h"
29 | #include "../core/Controller.h"
30 | #include "../core/VariableDefiner.h"
31 | #include "../incl/include_all_lib.h"
32 |
33 | class MqttSync : public BaseSync {
34 | public:
35 | static MqttSync &getInstance() {
36 | static MqttSync instance;
37 | return instance;
38 | }
39 |
40 | void setup();
41 | void connect(bool blocking = true);
42 | void loop();
43 | inline bool isVariableAllowed(const VariableDefinition *def);
44 | bool sendUpdateToVariable(const VariableDefinition *def, const void *value);
45 | // upload values stats
46 | void uploadStatsToMqtt();
47 | // upload values realtime
48 | void uploadRealtimeToMqtt();
49 |
50 | private:
51 | MqttSync();
52 |
53 | PubSubClient *mqttClient;
54 |
55 | char mqttPublishBuffer[20];
56 |
57 | #if defined(USE_MQTT_RPC_SUBSCRIBE) || defined(USE_MQTT_JSON_PUBLISH)
58 | DynamicJsonDocument syncJson(1024);
59 | #endif
60 |
61 | bool initialized;
62 | };
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/arduino_ota.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef ARDUINO_OTA_H
25 | #define ARDUINO_OTA_H
26 |
27 | #include "../incl/include_all_core.h"
28 |
29 | #ifdef USE_OTA_UPDATE
30 |
31 | #include "../core/Environment.h"
32 | #include "../incl/include_all_lib.h"
33 |
34 | inline void arduinoOtaSetup() {
35 | ArduinoOTA.setHostname(Environment::getData()->otaHostname);
36 | ArduinoOTA.setPassword(Environment::getData()->otaPassword);
37 |
38 | ArduinoOTA.onStart([]() {
39 | String type;
40 | if (ArduinoOTA.getCommand() == U_FLASH) {
41 | type = "sketch";
42 | } else { // U_SPIFFS
43 | type = "filesystem";
44 | }
45 |
46 | // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
47 | debugPrintln("Start updating " + type);
48 | });
49 |
50 | ArduinoOTA.onEnd([]() { debugPrintln("\nEnd of update"); });
51 |
52 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { debugPrintf(false, "Progress: %u%%\r", (progress / (total / 100))); });
53 |
54 | ArduinoOTA.onError([](ota_error_t error) {
55 | debugPrintf(false, "Error[%u]: ", error);
56 | if (error == OTA_AUTH_ERROR) {
57 | debugPrintln("Auth Failed");
58 | } else if (error == OTA_BEGIN_ERROR) {
59 | debugPrintln("Begin Failed");
60 | } else if (error == OTA_CONNECT_ERROR) {
61 | debugPrintln("Connect Failed");
62 | } else if (error == OTA_RECEIVE_ERROR) {
63 | debugPrintln("Receive Failed");
64 | } else if (error == OTA_END_ERROR) {
65 | debugPrintln("End Failed");
66 | }
67 | });
68 |
69 | ArduinoOTA.begin();
70 | }
71 |
72 | #endif
73 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/feature/wifi_manager.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef WIFI_MANAGER_H
25 | #define WIFI_MANAGER_H
26 |
27 | #include "../incl/include_all_core.h"
28 |
29 | #ifdef USE_WIFI_AP_CONFIGURATION
30 |
31 | #include "../core/Environment.h"
32 | #include "../incl/include_all_lib.h"
33 |
34 | class WifiManagerSTB {
35 | public:
36 | static void startWifiConfigurationAP(bool tryConnection) {
37 | bool shouldSaveConfig = false;
38 |
39 | // making sure to be connected to wifi from settings to get WiFi.SSID and WiFi.psk
40 | if (tryConnection) {
41 | WiFi.waitForConnectResult();
42 | }
43 |
44 | WiFiManager wifiManager;
45 | wifiManager.setTitle("Solar-tracer-Blynk-V3");
46 | wifiManager.setBreakAfterConfig(true);
47 | wifiManager.setSaveParamsCallback([&shouldSaveConfig, &wifiManager]() {
48 | shouldSaveConfig = true;
49 | wifiManager.stopConfigPortal(); });
50 | wifiManager.setSaveConfigCallback([&shouldSaveConfig]() { shouldSaveConfig = true; });
51 | wifiManager.setConfigResetCallback([]() { Environment::resetEnvData(); });
52 | wifiManager.setParamsPage(true);
53 | wifiManager.setConfigPortalBlocking(true);
54 | wifiManager.setDebugOutput(false);
55 |
56 | WiFiManagerParameter customDebug(
57 | CONFIG_SERIAL_DEBUG,
58 | "Serial debug",
59 | CONFIG_SERIAL_DEBUG, 15,
60 | Environment::getData()->serialDebug ? "type=\"checkbox\" checked" : "type=\"checkbox\"");
61 | wifiManager.addParameter(&customDebug);
62 |
63 | WiFiManagerParameter customWIFIText("WIFI:
");
64 | wifiManager.addParameter(&customWIFIText);
65 |
66 | WiFiManagerParameter customWIFIIpAddress(CONFIG_WIFI_IP_ADDRESS, "IP", Environment::getData()->wifiIp, CONFIG_WIFI_IP_ADDRESS_LEN);
67 | wifiManager.addParameter(&customWIFIIpAddress);
68 | WiFiManagerParameter customWIFIGateway(CONFIG_WIFI_GATEWAY, "Gateway", Environment::getData()->wifiGateway, CONFIG_WIFI_GATEWAY_LEN);
69 | wifiManager.addParameter(&customWIFIGateway);
70 | WiFiManagerParameter customWIFISubnet(CONFIG_WIFI_SUBNET, "Subnet", Environment::getData()->wifiSubnet, CONFIG_WIFI_SUBNET_LEN);
71 | wifiManager.addParameter(&customWIFISubnet);
72 | WiFiManagerParameter customWIFIDns1(CONFIG_WIFI_DNS1, "Dns1", Environment::getData()->wifiDns1, CONFIG_WIFI_DNS1_LEN);
73 | wifiManager.addParameter(&customWIFIDns1);
74 | WiFiManagerParameter customWIFIDns2(CONFIG_WIFI_DNS2, "Dns2", Environment::getData()->wifiDns2, CONFIG_WIFI_DNS2_LEN);
75 | wifiManager.addParameter(&customWIFIDns2);
76 |
77 | #ifdef USE_BLYNK
78 | WiFiManagerParameter customBlynkText("BLYNK:
");
79 | wifiManager.addParameter(&customBlynkText);
80 |
81 | WiFiManagerParameter customBlynkAuth(CONFIG_BLYNK_AUTH, "API key", Environment::getData()->blynkAuth, CONFIG_BLYNK_AUTH_LEN);
82 | wifiManager.addParameter(&customBlynkAuth);
83 |
84 | #ifndef USE_BLYNK_2
85 |
86 | WiFiManagerParameter customBlynkServerHostname(CONFIG_BLYNK_HOSTNAME, Text::server, Environment::getData()->blynkServerHostname, CONFIG_BLYNK_HOSTNAME_LEN);
87 | WiFiManagerParameter customBlynkServerPort(CONFIG_BLYNK_PORT, Text::port, Util::intToChar(Environment::getData()->blynkServerPort), 5, "type=\"number\" min=\"0\"");
88 |
89 | wifiManager.addParameter(&customBlynkServerHostname);
90 | wifiManager.addParameter(&customBlynkServerPort);
91 | #endif
92 | #endif
93 |
94 | #ifdef USE_MQTT
95 | WiFiManagerParameter customMqttText("MQTT:
");
96 | wifiManager.addParameter(&customMqttText);
97 |
98 | WiFiManagerParameter customMqttServer(CONFIG_MQTT_HOSTNAME, Text::server, Environment::getData()->mqttServerHostname, CONFIG_MQTT_HOSTNAME_LEN);
99 | wifiManager.addParameter(&customMqttServer);
100 | char portString[5];
101 | WiFiManagerParameter customMqttServerPort(CONFIG_MQTT_PORT, Text::port, Util::intToChar(Environment::getData()->mqttServerPort), 5, "type=\"number\" min=\"0\"");
102 | wifiManager.addParameter(&customMqttServerPort);
103 | WiFiManagerParameter customMqttClientId(CONFIG_MQTT_CLIENT_ID, "Client ID", Environment::getData()->mqttClientId, CONFIG_MQTT_CLIENT_ID_LEN);
104 | wifiManager.addParameter(&customMqttClientId);
105 | WiFiManagerParameter customMqttUsername(CONFIG_MQTT_USERNAME, "Username", Environment::getData()->mqttUsername, CONFIG_MQTT_USERNAME_LEN);
106 | wifiManager.addParameter(&customMqttUsername);
107 | WiFiManagerParameter customMqttPassword(CONFIG_MQTT_PASSWORD, Text::password, Environment::getData()->mqttPassword, CONFIG_MQTT_PASSWORD_LEN);
108 | wifiManager.addParameter(&customMqttPassword);
109 | #endif
110 | #ifdef USE_MQTT_HOME_ASSISTANT
111 | WiFiManagerParameter customMqttHAText("MQTT-HA:
");
112 | wifiManager.addParameter(&customMqttHAText);
113 |
114 | WiFiManagerParameter customMqttHADeviceId(CONFIG_MQTT_HA_DEVICE_ID, "Device ID", Environment::getData()->mqttHADeviceId, CONFIG_MQTT_HA_DEVICE_ID_LEN);
115 | wifiManager.addParameter(&customMqttHADeviceId);
116 |
117 | WiFiManagerParameter customMqttHADeviceName(CONFIG_MQTT_HA_DEVICE_NAME, "Device Name", Environment::getData()->mqttHADeviceName, CONFIG_MQTT_HA_DEVICE_NAME_LEN);
118 | wifiManager.addParameter(&customMqttHADeviceName);
119 | #endif
120 |
121 | #ifdef USE_OTA_UPDATE
122 | WiFiManagerParameter customOtaUpdateText("OTA:
");
123 |
124 | WiFiManagerParameter customOtaHostname(CONFIG_OTA_HOSTNAME, "Hostname", Environment::getData()->otaHostname, CONFIG_OTA_HOSTNAME_LEN);
125 | WiFiManagerParameter customOtaPassword(CONFIG_OTA_PASSWORD, Text::password, Environment::getData()->otaPassword, CONFIG_OTA_PASSWORD_LEN);
126 |
127 | wifiManager.addParameter(&customOtaUpdateText);
128 | wifiManager.addParameter(&customOtaHostname);
129 | wifiManager.addParameter(&customOtaPassword);
130 | #endif
131 |
132 | #ifdef USE_NTP_SERVER
133 | WiFiManagerParameter customNtpText("NTP:
");
134 |
135 | WiFiManagerParameter customNtpServer(CONFIG_NTP_SERVER, Text::server, Environment::getData()->ntpServer, CONFIG_NTP_SERVER_LEN);
136 | WiFiManagerParameter customNtpTimezone(CONFIG_NTP_TIMEZONE, "Timezone", Environment::getData()->ntpTimezone, CONFIG_NTP_TIMEZONE_LEN);
137 |
138 | wifiManager.addParameter(&customNtpText);
139 | wifiManager.addParameter(&customNtpServer);
140 | wifiManager.addParameter(&customNtpTimezone);
141 | #endif
142 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
143 | WiFiManagerParameter customExtLoadMeter("EXT. LOAD METER:
");
144 |
145 | char hlVoltOffsetString[8];
146 | WiFiManagerParameter customExtZeroVOff(CONFIG_EXTERNAL_HEAVY_LOAD_CURRENT_METER_VOLTAGE_ZERO_AMP_VOLT, "Volt off.", Util::floatToChar(Environment::getData()->heavyLoadCurrentZeroV), 8, "type=\"number\" step=\"0.001\"");
147 |
148 | wifiManager.addParameter(&customExtLoadMeter);
149 | wifiManager.addParameter(&customExtZeroVOff);
150 | #endif
151 |
152 | WiFiManagerParameter customWmText("ACCESS POINT:
");
153 | WiFiManagerParameter customWmSSID(CONFIG_WM_AP_SSID, "SSID", Environment::getData()->wmApSSID, CONFIG_WM_AP_SSID_LEN);
154 | WiFiManagerParameter customWmPassword(CONFIG_WM_AP_PASSWORD, Text::password, Environment::getData()->wmApPassword, CONFIG_WM_AP_PASSWORD_LEN);
155 |
156 | wifiManager.addParameter(&customWmText);
157 | wifiManager.addParameter(&customWmSSID);
158 | wifiManager.addParameter(&customWmPassword);
159 |
160 | wifiManager.setConfigPortalTimeout(WIFI_AP_TIMEOUT);
161 | wifiManager.startConfigPortal(Environment::getData()->wmApSSID, Environment::getData()->wmApPassword);
162 |
163 | if (shouldSaveConfig) {
164 | debugPrintln("Saving wifimanager parameters... ");
165 |
166 | if (!LittleFS.begin()) {
167 | debugPrintf(true, Text::errorWithCode, STATUS_ERR_LITTLEFS_BEGIN_FAILED);
168 | if (!LittleFS.format() || !LittleFS.begin()) {
169 | debugPrintf(true, Text::errorWithCode, STATUS_ERR_LITTLEFS_FORMAT_FAILED);
170 | }
171 | return;
172 | }
173 |
174 | DynamicJsonDocument doc(1024);
175 | doc[CONFIG_SERIAL_DEBUG] = strcmp(customDebug.getValue(), CONFIG_SERIAL_DEBUG) == 0;
176 | doc[CONFIG_WIFI_SSID] = WiFi.SSID();
177 | doc[CONFIG_WIFI_PASSWORD] = WiFi.psk();
178 |
179 | doc[CONFIG_WIFI_IP_ADDRESS] = customWIFIIpAddress.getValue();
180 | doc[CONFIG_WIFI_GATEWAY] = customWIFIGateway.getValue();
181 | doc[CONFIG_WIFI_SUBNET] = customWIFISubnet.getValue();
182 | doc[CONFIG_WIFI_DNS1] = customWIFIDns1.getValue();
183 | doc[CONFIG_WIFI_DNS2] = customWIFIDns2.getValue();
184 |
185 | doc[CONFIG_WM_AP_SSID] = customWmSSID.getValue();
186 | doc[CONFIG_WM_AP_PASSWORD] = customWmPassword.getValue();
187 | #ifdef USE_BLYNK
188 | doc[CONFIG_BLYNK_AUTH] = customBlynkAuth.getValue();
189 | #ifndef USE_BLYNK_2
190 | doc[CONFIG_BLYNK_HOSTNAME] = customBlynkServerHostname.getValue();
191 | doc[CONFIG_BLYNK_PORT] = strlen(customBlynkServerPort.getValue()) > 0
192 | ? atoi(customBlynkServerPort.getValue())
193 | : 0;
194 | #endif
195 | #endif
196 | #ifdef USE_MQTT
197 | doc[CONFIG_MQTT_HOSTNAME] = customMqttServer.getValue();
198 | doc[CONFIG_MQTT_PORT] = strlen(customMqttServerPort.getValue()) > 0
199 | ? atoi(customMqttServerPort.getValue())
200 | : 0;
201 | doc[CONFIG_MQTT_USERNAME] = customMqttUsername.getValue();
202 | doc[CONFIG_MQTT_PASSWORD] = customMqttPassword.getValue();
203 | doc[CONFIG_MQTT_CLIENT_ID] = customMqttClientId.getValue();
204 | #endif
205 | #ifdef USE_MQTT_HOME_ASSISTANT
206 | doc[CONFIG_MQTT_HA_DEVICE_ID] = customMqttHADeviceId.getValue();
207 | doc[CONFIG_MQTT_HA_DEVICE_NAME] = customMqttHADeviceName.getValue();
208 | #endif
209 |
210 | #ifdef USE_OTA_UPDATE
211 | doc[CONFIG_OTA_HOSTNAME] = customOtaHostname.getValue();
212 | doc[CONFIG_OTA_PASSWORD] = customOtaPassword.getValue();
213 | #endif
214 |
215 | #ifdef USE_NTP_SERVER
216 | doc[CONFIG_NTP_SERVER] = customNtpServer.getValue();
217 | doc[CONFIG_NTP_TIMEZONE] = customNtpTimezone.getValue();
218 | #endif
219 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
220 | doc[CONFIG_EXTERNAL_HEAVY_LOAD_CURRENT_METER_VOLTAGE_ZERO_AMP_VOLT] = strlen(customExtZeroVOff.getValue()) > 0
221 | ? atof(customExtZeroVOff.getValue())
222 | : 0;
223 | #endif
224 | File configFile = LittleFS.open(CONFIG_PERSISTENCE, "w");
225 | if (!configFile) {
226 | LittleFS.end();
227 | } else {
228 | serializeJson(doc, configFile);
229 | configFile.flush();
230 | configFile.close();
231 | LittleFS.end();
232 | debugPrintln(Text::ok);
233 | }
234 |
235 | ESP.restart();
236 | }
237 | }
238 | };
239 |
240 | #endif
241 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/communication_protocol_all.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #define COMMUNICATION_PROTOCOL_MODBUS_RTU 0x00001
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/config_persistence.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #define CONFIG_PERSISTENCE "/config.json"
25 |
26 | //settings
27 | #define CONFIG_SERIAL_DEBUG "debug"
28 |
29 | #define CONFIG_WIFI_SSID "ssid"
30 | #define CONFIG_WIFI_SSID_LEN 20
31 |
32 | #define CONFIG_WIFI_PASSWORD "passw"
33 | #define CONFIG_WIFI_PASSWORD_LEN 30
34 |
35 | #define CONFIG_WM_AP_SSID "wmSsid"
36 | #define CONFIG_WM_AP_SSID_LEN 15
37 |
38 | #define CONFIG_WM_AP_PASSWORD "wmPassw"
39 | #define CONFIG_WM_AP_PASSWORD_LEN 30
40 |
41 | #define CONFIG_BLYNK_AUTH "blynkToken"
42 | #define CONFIG_BLYNK_AUTH_LEN 32
43 |
44 | #define CONFIG_BLYNK_HOSTNAME "blynkHostname"
45 | #define CONFIG_BLYNK_HOSTNAME_LEN 20
46 |
47 | #define CONFIG_BLYNK_PORT "blynkPort"
48 |
49 | #define CONFIG_MQTT_HOSTNAME "mqttSrv"
50 | #define CONFIG_MQTT_HOSTNAME_LEN 20
51 |
52 | #define CONFIG_MQTT_PORT "mqttPort"
53 |
54 | #define CONFIG_MQTT_CLIENT_ID "mqttClnt"
55 | #define CONFIG_MQTT_CLIENT_ID_LEN 15
56 |
57 | #define CONFIG_MQTT_USERNAME "mqttUsr"
58 | #define CONFIG_MQTT_USERNAME_LEN 15
59 |
60 | #define CONFIG_MQTT_PASSWORD "mqttPassw"
61 | #define CONFIG_MQTT_PASSWORD_LEN 64
62 |
63 | #define CONFIG_OTA_HOSTNAME "otaHostname"
64 | #define CONFIG_OTA_HOSTNAME_LEN 15
65 |
66 | #define CONFIG_MQTT_HA_DEVICE_ID "haDeviceId"
67 | #define CONFIG_MQTT_HA_DEVICE_ID_LEN 15
68 |
69 | #define CONFIG_MQTT_HA_DEVICE_NAME "haDeviceName"
70 | #define CONFIG_MQTT_HA_DEVICE_NAME_LEN 15
71 |
72 | #define CONFIG_OTA_PASSWORD "otaPassword"
73 | #define CONFIG_OTA_PASSWORD_LEN 15
74 |
75 |
76 | #define CONFIG_NTP_SERVER "ntpServer"
77 | #define CONFIG_NTP_SERVER_LEN 22
78 |
79 | #define CONFIG_NTP_TIMEZONE "ntpTimezone"
80 | #define CONFIG_NTP_TIMEZONE_LEN 47
81 |
82 | #define CONFIG_WIFI_IP_ADDRESS "ipAddr"
83 | #define CONFIG_WIFI_IP_ADDRESS_LEN 15
84 |
85 | #define CONFIG_WIFI_SUBNET "subnet"
86 | #define CONFIG_WIFI_SUBNET_LEN 15
87 |
88 | #define CONFIG_WIFI_GATEWAY "gateway"
89 | #define CONFIG_WIFI_GATEWAY_LEN 15
90 |
91 | #define CONFIG_WIFI_DNS1 "dns1"
92 | #define CONFIG_WIFI_DNS1_LEN 15
93 |
94 | #define CONFIG_WIFI_DNS2 "dns2"
95 | #define CONFIG_WIFI_DNS2_LEN 15
96 |
97 | #define CONFIG_EXTERNAL_HEAVY_LOAD_CURRENT_METER_VOLTAGE_ZERO_AMP_VOLT "hlZeroVOff"
98 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | // INCL all core dependendecies
23 | #include "include_all_core.h"
24 | // INCL all third party libs
25 | #include "include_all_lib.h"
26 | // EXCEPTION: SoftwareSerial
27 | #ifdef USE_SOFTWARE_SERIAL
28 | SoftwareSerial softSerial;
29 | #define BOARD_ST_SERIAL_STREAM softSerial
30 | #endif
31 |
32 | // INCL main components
33 | #include "../core/datetime.h"
34 | #include "../core/Controller.h"
35 | // INCL optional features
36 | #include "include_all_feature.h"
37 |
38 |
39 | #if !defined(ESP8266) && !defined(ESP32)
40 | #error "Your board is not supported"
41 | #endif
42 |
43 | #if defined(USE_SOFTWARE_SERIAL) & !defined(BOARD_ST_SERIAL_PIN_MAPPING_RX)
44 | #error "USE_SOFTWARE_SERIAL requires BOARD_ST_SERIAL_PIN_MAPPING_RX"
45 | #endif
46 |
47 | #if defined(USE_SOFTWARE_SERIAL) & !defined(BOARD_ST_SERIAL_PIN_MAPPING_TX)
48 | #error "USE_SOFTWARE_SERIAL requires BOARD_ST_SERIAL_PIN_MAPPING_TX"
49 | #endif
50 |
51 | // DIRECTIVE VALIDATION FOR ESP8266 ONLY
52 | #ifdef ESP8266
53 | #if defined(USE_HALL_AP_CONFIGURATION_TRIGGER)
54 | #error "This board has no hall sensor to use! [ disable USE_HALL_AP_CONFIGURATION_TRIGGER ]"
55 | #endif
56 |
57 | #if !defined(USE_SOFTWARE_SERIAL) && ( defined(BOARD_ST_SERIAL_PIN_MAPPING_RX) | defined(BOARD_ST_SERIAL_PIN_MAPPING_TX) )
58 | #error "This board does not support HW serial pin mapping! [ disable BOARD_ST_SERIAL_PIN_MAPPING_RX, BOARD_ST_SERIAL_PIN_MAPPING_TX ]"
59 | #endif
60 | #endif
61 |
62 | // DIRECTIVE VALIDATION FOR ESP32 ONLY
63 | #ifdef ESP32
64 | #ifdef USE_SOFTWARE_SERIAL
65 | #error "ESP32 does not need to use a sof. serial emulation [disable USE_SOFTWARE_SERIAL]"
66 | #endif
67 | #endif
68 |
69 | // DIRECTIVE VALIDATION FOR SOLAR TRACER
70 | #if !defined(USE_SERIAL_STREAM) && (SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_A | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_B | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_TRITON | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_XTRA)
71 | #error You must enable USE_SERIAL_STREAM !
72 | #endif
73 |
74 | #if defined(USE_SERIAL_STREAM) && !defined(BOARD_ST_SERIAL_STREAM)
75 | #error You must specify a serial in BOARD_ST_SERIAL_STREAM!
76 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include_all_blynk_vpin.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #include "../incl/include_all_core.h"
25 |
26 | /**
27 | * BLYNK
28 | *
29 | */
30 | #ifndef vPIN_PV_POWER
31 | #define vPIN_PV_POWER_DF nullptr
32 | #else
33 | #define vPIN_PV_POWER_DF new uint8_t(vPIN_PV_POWER)
34 | #endif
35 | #ifndef vPIN_PV_CURRENT
36 | #define vPIN_PV_CURRENT_DF nullptr
37 | #else
38 | #define vPIN_PV_CURRENT_DF new uint8_t(vPIN_PV_CURRENT)
39 | #endif
40 | #ifndef vPIN_PV_VOLTAGE
41 | #define vPIN_PV_VOLTAGE_DF nullptr
42 | #else
43 | #define vPIN_PV_VOLTAGE_DF new uint8_t(vPIN_PV_VOLTAGE)
44 | #endif
45 | #ifndef vPIN_LOAD_CURRENT
46 | #define vPIN_LOAD_CURRENT_DF nullptr
47 | #else
48 | #define vPIN_LOAD_CURRENT_DF new uint8_t(vPIN_LOAD_CURRENT)
49 | #endif
50 | #ifndef vPIN_LOAD_POWER
51 | #define vPIN_LOAD_POWER_DF nullptr
52 | #else
53 | #define vPIN_LOAD_POWER_DF new uint8_t(vPIN_LOAD_POWER)
54 | #endif
55 | #ifndef vPIN_BATT_TEMP
56 | #define vPIN_BATT_TEMP_DF nullptr
57 | #else
58 | #define vPIN_BATT_TEMP_DF new uint8_t(vPIN_BATT_TEMP)
59 | #endif
60 | #ifndef vPIN_BATT_VOLTAGE
61 | #define vPIN_BATT_VOLTAGE_DF nullptr
62 | #else
63 | #define vPIN_BATT_VOLTAGE_DF new uint8_t(vPIN_BATT_VOLTAGE)
64 | #endif
65 | #ifndef vPIN_BATT_REMAIN
66 | #define vPIN_BATT_REMAIN_DF nullptr
67 | #else
68 | #define vPIN_BATT_REMAIN_DF new uint8_t(vPIN_BATT_REMAIN)
69 | #endif
70 | #ifndef vPIN_CONTROLLER_TEMP
71 | #define vPIN_CONTROLLER_TEMP_DF nullptr
72 | #else
73 | #define vPIN_CONTROLLER_TEMP_DF new uint8_t(vPIN_CONTROLLER_TEMP)
74 | #endif
75 | #ifndef vPIN_BATTERY_CHARGE_CURRENT
76 | #define vPIN_BATTERY_CHARGE_CURRENT_DF nullptr
77 | #else
78 | #define vPIN_BATTERY_CHARGE_CURRENT_DF new uint8_t(vPIN_BATTERY_CHARGE_CURRENT)
79 | #endif
80 | #ifndef vPIN_BATTERY_CHARGE_POWER
81 | #define vPIN_BATTERY_CHARGE_POWER_DF nullptr
82 | #else
83 | #define vPIN_BATTERY_CHARGE_POWER_DF new uint8_t(vPIN_BATTERY_CHARGE_POWER)
84 | #endif
85 | #ifndef vPIN_BATTERY_OVERALL_CURRENT
86 | #define vPIN_BATTERY_OVERALL_CURRENT_DF nullptr
87 | #else
88 | #define vPIN_BATTERY_OVERALL_CURRENT_DF new uint8_t(vPIN_BATTERY_OVERALL_CURRENT)
89 | #endif
90 | #ifndef vPIN_LOAD_ENABLED
91 | #define vPIN_LOAD_ENABLED_DF nullptr
92 | #else
93 | #define vPIN_LOAD_ENABLED_DF new uint8_t(vPIN_LOAD_ENABLED)
94 | #endif
95 | #ifndef vPIN_CHARGE_DEVICE_ENABLED
96 | #define vPIN_CHARGE_DEVICE_ENABLED_DF nullptr
97 | #else
98 | #define vPIN_CHARGE_DEVICE_ENABLED_DF new uint8_t(vPIN_CHARGE_DEVICE_ENABLED)
99 | #endif
100 | #ifndef vPIN_BATTERY_STATUS_TEXT
101 | #define vPIN_BATTERY_STATUS_TEXT_DF nullptr
102 | #else
103 | #define vPIN_BATTERY_STATUS_TEXT_DF new uint8_t(vPIN_BATTERY_STATUS_TEXT)
104 | #endif
105 | #ifndef vPIN_CHARGING_EQUIPMENT_STATUS_TEXT
106 | #define vPIN_CHARGING_EQUIPMENT_STATUS_TEXT_DF nullptr
107 | #else
108 | #define vPIN_CHARGING_EQUIPMENT_STATUS_TEXT_DF new uint8_t(vPIN_CHARGING_EQUIPMENT_STATUS_TEXT)
109 | #endif
110 | #ifndef vPIN_DISCHARGING_EQUIPMENT_STATUS_TEXT
111 | #define vPIN_DISCHARGING_EQUIPMENT_STATUS_TEXT_DF nullptr
112 | #else
113 | #define vPIN_DISCHARGING_EQUIPMENT_STATUS_TEXT_DF new uint8_t(vPIN_DISCHARGING_EQUIPMENT_STATUS_TEXT)
114 | #endif
115 | #ifndef vPIN_CONTROLLER_HEATSINK_TEMP
116 | #define vPIN_CONTROLLER_HEATSINK_TEMP_DF nullptr
117 | #else
118 | #define vPIN_CONTROLLER_HEATSINK_TEMP_DF new uint8_t(vPIN_CONTROLLER_HEATSINK_TEMP)
119 | #endif
120 | #ifndef vPIN_STAT_ENERGY_GENERATED_TODAY
121 | #define vPIN_STAT_ENERGY_GENERATED_TODAY_DF nullptr
122 | #else
123 | #define vPIN_STAT_ENERGY_GENERATED_TODAY_DF new uint8_t(vPIN_STAT_ENERGY_GENERATED_TODAY)
124 | #endif
125 | #ifndef vPIN_STAT_ENERGY_GENERATED_THIS_MONTH
126 | #define vPIN_STAT_ENERGY_GENERATED_THIS_MONTH_DF nullptr
127 | #else
128 | #define vPIN_STAT_ENERGY_GENERATED_THIS_MONTH_DF new uint8_t(vPIN_STAT_ENERGY_GENERATED_THIS_MONTH)
129 | #endif
130 | #ifndef vPIN_STAT_ENERGY_GENERATED_THIS_YEAR
131 | #define vPIN_STAT_ENERGY_GENERATED_THIS_YEAR_DF nullptr
132 | #else
133 | #define vPIN_STAT_ENERGY_GENERATED_THIS_YEAR_DF new uint8_t(vPIN_STAT_ENERGY_GENERATED_THIS_YEAR)
134 | #endif
135 | #ifndef vPIN_STAT_ENERGY_GENERATED_TOTAL
136 | #define vPIN_STAT_ENERGY_GENERATED_TOTAL_DF nullptr
137 | #else
138 | #define vPIN_STAT_ENERGY_GENERATED_TOTAL_DF new uint8_t(vPIN_STAT_ENERGY_GENERATED_TOTAL)
139 | #endif
140 | #ifndef vPIN_MIN_BATTERY_VOLTAGE_TODAY
141 | #define vPIN_MIN_BATTERY_VOLTAGE_TODAY_DF nullptr
142 | #else
143 | #define vPIN_MIN_BATTERY_VOLTAGE_TODAY_DF new uint8_t(vPIN_MIN_BATTERY_VOLTAGE_TODAY)
144 | #endif
145 | #ifndef vPIN_MAX_BATTERY_VOLTAGE_TODAY
146 | #define vPIN_MAX_BATTERY_VOLTAGE_TODAY_DF nullptr
147 | #else
148 | #define vPIN_MAX_BATTERY_VOLTAGE_TODAY_DF new uint8_t(vPIN_MAX_BATTERY_VOLTAGE_TODAY)
149 | #endif
150 | #ifndef vPIN_MIN_PV_VOLTAGE_TODAY
151 | #define vPIN_MIN_PV_VOLTAGE_TODAY_DF nullptr
152 | #else
153 | #define vPIN_MIN_PV_VOLTAGE_TODAY_DF new uint8_t(vPIN_MIN_PV_VOLTAGE_TODAY)
154 | #endif
155 | #ifndef vPIN_MAX_PV_VOLTAGE_TODAY
156 | #define vPIN_MAX_PV_VOLTAGE_TODAY_DF nullptr
157 | #else
158 | #define vPIN_MAX_PV_VOLTAGE_TODAY_DF new uint8_t(vPIN_MAX_PV_VOLTAGE_TODAY)
159 | #endif
160 | #ifndef vPIN_BATTERY_BOOST_VOLTAGE
161 | #define vPIN_BATTERY_BOOST_VOLTAGE_DF nullptr
162 | #else
163 | #define vPIN_BATTERY_BOOST_VOLTAGE_DF new uint8_t(vPIN_BATTERY_BOOST_VOLTAGE)
164 | #endif
165 | #ifndef vPIN_BATTERY_EQUALIZATION_VOLTAGE
166 | #define vPIN_BATTERY_EQUALIZATION_VOLTAGE_DF nullptr
167 | #else
168 | #define vPIN_BATTERY_EQUALIZATION_VOLTAGE_DF new uint8_t(vPIN_BATTERY_EQUALIZATION_VOLTAGE)
169 | #endif
170 | #ifndef vPIN_BATTERY_FLOAT_VOLTAGE
171 | #define vPIN_BATTERY_FLOAT_VOLTAGE_DF nullptr
172 | #else
173 | #define vPIN_BATTERY_FLOAT_VOLTAGE_DF new uint8_t(vPIN_BATTERY_FLOAT_VOLTAGE)
174 | #endif
175 | #ifndef vPIN_BATTERY_FLOAT_MIN_VOLTAGE
176 | #define vPIN_BATTERY_FLOAT_MIN_VOLTAGE_DF nullptr
177 | #else
178 | #define vPIN_BATTERY_FLOAT_MIN_VOLTAGE_DF new uint8_t(vPIN_BATTERY_FLOAT_MIN_VOLTAGE)
179 | #endif
180 | #ifndef vPIN_BATTERY_CHARGING_LIMIT_VOLTAGE
181 | #define vPIN_BATTERY_CHARGING_LIMIT_VOLTAGE_DF nullptr
182 | #else
183 | #define vPIN_BATTERY_CHARGING_LIMIT_VOLTAGE_DF new uint8_t(vPIN_BATTERY_CHARGING_LIMIT_VOLTAGE)
184 | #endif
185 | #ifndef vPIN_BATTERY_DISCHARGING_LIMIT_VOLTAGE
186 | #define vPIN_BATTERY_DISCHARGING_LIMIT_VOLTAGE_DF nullptr
187 | #else
188 | #define vPIN_BATTERY_DISCHARGING_LIMIT_VOLTAGE_DF new uint8_t(vPIN_BATTERY_DISCHARGING_LIMIT_VOLTAGE)
189 | #endif
190 | #ifndef vPIN_BATTERY_LOW_VOLTAGE_DISCONNECT
191 | #define vPIN_BATTERY_LOW_VOLTAGE_DISCONNECT_DF nullptr
192 | #else
193 | #define vPIN_BATTERY_LOW_VOLTAGE_DISCONNECT_DF new uint8_t(vPIN_BATTERY_LOW_VOLTAGE_DISCONNECT)
194 | #endif
195 | #ifndef vPIN_BATTERY_LOW_VOLTAGE_RECONNECT
196 | #define vPIN_BATTERY_LOW_VOLTAGE_RECONNECT_DF nullptr
197 | #else
198 | #define vPIN_BATTERY_LOW_VOLTAGE_RECONNECT_DF new uint8_t(vPIN_BATTERY_LOW_VOLTAGE_RECONNECT)
199 | #endif
200 | #ifndef vPIN_BATTERY_OVER_VOLTAGE_DISCONNECT
201 | #define vPIN_BATTERY_OVER_VOLTAGE_DISCONNECT_DF nullptr
202 | #else
203 | #define vPIN_BATTERY_OVER_VOLTAGE_DISCONNECT_DF new uint8_t(vPIN_BATTERY_OVER_VOLTAGE_DISCONNECT)
204 | #endif
205 | #ifndef vPIN_BATTERY_OVER_VOLTAGE_RECONNECT
206 | #define vPIN_BATTERY_OVER_VOLTAGE_RECONNECT_DF nullptr
207 | #else
208 | #define vPIN_BATTERY_OVER_VOLTAGE_RECONNECT_DF new uint8_t(vPIN_BATTERY_OVER_VOLTAGE_RECONNECT)
209 | #endif
210 | #ifndef vPIN_BATTERY_UNDER_VOLTAGE_RESET
211 | #define vPIN_BATTERY_UNDER_VOLTAGE_RESET_DF nullptr
212 | #else
213 | #define vPIN_BATTERY_UNDER_VOLTAGE_RESET_DF new uint8_t(vPIN_BATTERY_UNDER_VOLTAGE_RESET)
214 | #endif
215 | #ifndef vPIN_BATTERY_UNDER_VOLTAGE_SET
216 | #define vPIN_BATTERY_UNDER_VOLTAGE_SET_DF nullptr
217 | #else
218 | #define vPIN_BATTERY_UNDER_VOLTAGE_SET_DF new uint8_t(vPIN_BATTERY_UNDER_VOLTAGE_SET)
219 | #endif
220 | #ifndef vPIN_INTERNAL_STATUS
221 | #define vPIN_INTERNAL_STATUS_DF nullptr
222 | #else
223 | #define vPIN_INTERNAL_STATUS_DF new uint8_t(vPIN_INTERNAL_STATUS)
224 | #endif
225 | #ifndef vPIN_INTERNAL_DEBUG_TERMINAL
226 | #define vPIN_INTERNAL_DEBUG_TERMINAL_DF nullptr
227 | #else
228 | #define vPIN_INTERNAL_DEBUG_TERMINAL_DF new uint8_t(vPIN_INTERNAL_DEBUG_TERMINAL)
229 | #endif
230 | #ifndef vPIN_UPDATE_CONTROLLER_DATETIME
231 | #define vPIN_UPDATE_CONTROLLER_DATETIME_DF nullptr
232 | #else
233 | #define vPIN_UPDATE_CONTROLLER_DATETIME_DF new uint8_t(vPIN_UPDATE_CONTROLLER_DATETIME)
234 | #endif
235 | #ifndef vPIN_UPDATE_ALL_CONTROLLER_DATA
236 | #define vPIN_UPDATE_ALL_CONTROLLER_DATA_DF nullptr
237 | #else
238 | #define vPIN_UPDATE_ALL_CONTROLLER_DATA_DF new uint8_t(vPIN_UPDATE_ALL_CONTROLLER_DATA)
239 | #endif
240 | #ifndef vPIN_BATTERY_RATED_VOLTAGE
241 | #define vPIN_BATTERY_RATED_VOLTAGE_DF nullptr
242 | #else
243 | #define vPIN_BATTERY_RATED_VOLTAGE_DF new uint8_t(vPIN_BATTERY_RATED_VOLTAGE)
244 | #endif
245 | #ifndef vPIN_BATTERY_TYPE
246 | #define vPIN_BATTERY_TYPE_DF nullptr
247 | #else
248 | #define vPIN_BATTERY_TYPE_DF new uint8_t(vPIN_BATTERY_TYPE)
249 | #endif
250 | #ifndef vPIN_BATTERY_CAPACITY
251 | #define vPIN_BATTERY_CAPACITY_DF nullptr
252 | #else
253 | #define vPIN_BATTERY_CAPACITY_DF new uint8_t(vPIN_BATTERY_CAPACITY)
254 | #endif
255 | #ifndef vPIN_BATTERY_EQUALIZATION_DURATION
256 | #define vPIN_BATTERY_EQUALIZATION_DURATION_DF nullptr
257 | #else
258 | #define vPIN_BATTERY_EQUALIZATION_DURATION_DF new uint8_t(vPIN_BATTERY_EQUALIZATION_DURATION)
259 | #endif
260 | #ifndef vPIN_BATTERY_BOOST_DURATION
261 | #define vPIN_BATTERY_BOOST_DURATION_DF nullptr
262 | #else
263 | #define vPIN_BATTERY_BOOST_DURATION_DF new uint8_t(vPIN_BATTERY_BOOST_DURATION)
264 | #endif
265 | #ifndef vPIN_BATTERY_TEMPERATURE_COMPENSATION_COEFF
266 | #define vPIN_BATTERY_TEMPERATURE_COMPENSATION_COEFF_DF nullptr
267 | #else
268 | #define vPIN_BATTERY_TEMPERATURE_COMPENSATION_COEFF_DF new uint8_t(vPIN_BATTERY_TEMPERATURE_COMPENSATION_COEFF)
269 | #endif
270 | #ifndef vPIN_BATTERY_MANAGEMENT_MODE
271 | #define vPIN_BATTERY_MANAGEMENT_MODE_DF nullptr
272 | #else
273 | #define vPIN_BATTERY_MANAGEMENT_MODE_DF new uint8_t(vPIN_BATTERY_MANAGEMENT_MODE)
274 | #endif
275 | #ifndef vPIN_STAT_ENERGY_CONSUMED_TODAY
276 | #define vPIN_STAT_ENERGY_CONSUMED_TODAY_DF nullptr
277 | #else
278 | #define vPIN_STAT_ENERGY_CONSUMED_TODAY_DF new uint8_t(vPIN_STAT_ENERGY_CONSUMED_TODAY)
279 | #endif
280 | #ifndef vPIN_STAT_ENERGY_CONSUMED_THIS_MONTH
281 | #define vPIN_STAT_ENERGY_CONSUMED_THIS_MONTH_DF nullptr
282 | #else
283 | #define vPIN_STAT_ENERGY_CONSUMED_THIS_MONTH_DF new uint8_t(vPIN_STAT_ENERGY_CONSUMED_THIS_MONTH)
284 | #endif
285 | #ifndef vPIN_STAT_ENERGY_CONSUMED_THIS_YEAR
286 | #define vPIN_STAT_ENERGY_CONSUMED_THIS_YEAR_DF nullptr
287 | #else
288 | #define vPIN_STAT_ENERGY_CONSUMED_THIS_YEAR_DF new uint8_t(vPIN_STAT_ENERGY_CONSUMED_THIS_YEAR)
289 | #endif
290 | #ifndef vPIN_STAT_ENERGY_CONSUMED_TOTAL
291 | #define vPIN_STAT_ENERGY_CONSUMED_TOTAL_DF nullptr
292 | #else
293 | #define vPIN_STAT_ENERGY_CONSUMED_TOTAL_DF new uint8_t(vPIN_STAT_ENERGY_CONSUMED_TOTAL)
294 | #endif
295 |
296 |
297 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include_all_core.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef INCLUDE_ALL_CORE_H
25 | #define INCLUDE_ALL_CORE_H
26 |
27 | #define PROJECT_NAME "Solar-Tracer-Blynk-V3"
28 | #define PROJECT_AUTHOR "Bettapro"
29 | #define PROJECT_VERSION "v3.0.9"
30 | #define PROJECT_SUBVERSION 17
31 |
32 |
33 | #include
34 |
35 | /**
36 | * Main defs
37 | */
38 | #include "solartracer_all.h"
39 | #include "communication_protocol_all.h"
40 | #include "status_all.h"
41 | #include "config_persistence.h"
42 |
43 |
44 | /**
45 | * Include user + board + solar tracer configs
46 | */
47 | #include "../../config.h"
48 |
49 | // disable advanced features not needed in the startup build
50 | #ifdef STARTUP_BUILD
51 | #undef USE_BLYNK
52 | #undef USE_MQTT
53 | #undef USE_SERIAL_STREAM
54 |
55 | #undef SOLAR_TRACER_MODEL
56 | #define SOLAR_TRACER_MODEL DUMMY_SOLAR_TRACER
57 | #endif
58 |
59 |
60 |
61 | /**
62 | * Conditional includes depending on the BOARD
63 | */
64 | #if defined ESP32
65 | #include "../board/esp32_config.h"
66 | #elif defined ESP8266
67 | #include "../board/esp8266_config.h"
68 | #else
69 | #error Your board is not supported.
70 | #endif
71 |
72 | /**
73 | * Conditional includes depending on the SOLAR CHARGE CONTROLLER
74 | */
75 | #if (SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_A | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_B | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_TRITON | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_XTRA)
76 | #include "../solartracer/epever/epever_config.h"
77 | #elif (SOLAR_TRACER_MODEL == DUMMY_SOLAR_TRACER)
78 | #else
79 | #error This Solar Tracer is not supported.
80 | #endif
81 |
82 | /**
83 | * Include only not-external-dependant headers
84 | */
85 | #include "../core/Util.h"
86 | #include "../core/debug.h"
87 | #include "../core/Text.h"
88 | #include "../core/VariableDefiner.h"
89 |
90 |
91 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include_all_feature.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef INCLUDE_ALL_FEATURE_H
25 | #define INCLUDE_ALL_FEATURE_H
26 |
27 | #include "include_all_core.h"
28 |
29 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
30 | #include "../solartracer/overwrite/LoadCurrentOverwrite.h"
31 | #endif
32 |
33 | #ifdef USE_STATUS_LED
34 | #include "../feature/status_led.h"
35 | #endif
36 |
37 | #ifdef USE_OTA_UPDATE
38 | #include "../feature/arduino_ota.h"
39 | #endif
40 |
41 | #if defined USE_WIFI_AP_CONFIGURATION
42 | #include "../feature/wifi_manager.h"
43 | #endif
44 |
45 | #if defined USE_BLYNK
46 | #include "../feature/BlynkSync.h"
47 | #endif
48 | #if defined(USE_MQTT) && !defined(USE_MQTT_HOME_ASSISTANT)
49 | #include "../feature/MqttSync.h"
50 | #endif
51 | #if defined(USE_MQTT) && defined(USE_MQTT_HOME_ASSISTANT)
52 | #include "../feature/MqttHASync.h"
53 | #endif
54 |
55 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include_all_lib.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef INCLUDE_ALL_LIB_H
25 | #define INCLUDE_ALL_LIB_H
26 |
27 | #include "include_all_core.h"
28 |
29 | #if defined ESP32
30 | #define USE_WIFI_NINA false
31 | #define USE_WIFI101 false
32 | #include
33 | #elif defined ESP8266
34 | #include
35 | #endif
36 |
37 | #ifdef USE_SOFTWARE_SERIAL
38 | #include
39 | #endif
40 |
41 | #include
42 |
43 | #ifdef USE_DOUBLE_RESET_TRIGGER
44 | #include
45 | #define ESP_DRD_USE_LITTLEFS true
46 | #include
47 | #endif
48 |
49 | #ifdef USE_OTA_UPDATE
50 | #include
51 | #endif
52 |
53 | #include
54 | #if defined USE_WIFI_AP_CONFIGURATION
55 | #include
56 | // disable WM all logs
57 | // #define WM_NODEBUG
58 | #include
59 | #endif
60 |
61 | #if defined(USE_MQTT) && !defined(USE_MQTT_HOME_ASSISTANT)
62 | #include
63 | #endif
64 | #if defined(USE_MQTT) && defined(USE_MQTT_HOME_ASSISTANT)
65 | #include
66 | #endif
67 |
68 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
69 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER_ADS1015_ADC
70 | #include "ADS1X15.h"
71 | #endif
72 | #include
73 | #endif
74 |
75 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/include_all_mqtt_topic.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #include "../incl/include_all_core.h"
25 |
26 |
27 | /**
28 | * MQTT
29 | *
30 | */
31 |
32 |
33 | #ifndef MQTT_TOPIC_PV_POWER
34 | #define MQTT_TOPIC_PV_POWER_DF nullptr
35 | #else
36 | #define MQTT_TOPIC_PV_POWER_DF MQTT_TOPIC_PV_POWER
37 | #endif
38 | #ifndef MQTT_TOPIC_PV_CURRENT
39 | #define MQTT_TOPIC_PV_CURRENT_DF nullptr
40 | #else
41 | #define MQTT_TOPIC_PV_CURRENT_DF MQTT_TOPIC_PV_CURRENT
42 | #endif
43 | #ifndef MQTT_TOPIC_PV_VOLTAGE
44 | #define MQTT_TOPIC_PV_VOLTAGE_DF nullptr
45 | #else
46 | #define MQTT_TOPIC_PV_VOLTAGE_DF MQTT_TOPIC_PV_VOLTAGE
47 | #endif
48 | #ifndef MQTT_TOPIC_LOAD_CURRENT
49 | #define MQTT_TOPIC_LOAD_CURRENT_DF nullptr
50 | #else
51 | #define MQTT_TOPIC_LOAD_CURRENT_DF MQTT_TOPIC_LOAD_CURRENT
52 | #endif
53 | #ifndef MQTT_TOPIC_LOAD_POWER
54 | #define MQTT_TOPIC_LOAD_POWER_DF nullptr
55 | #else
56 | #define MQTT_TOPIC_LOAD_POWER_DF MQTT_TOPIC_LOAD_POWER
57 | #endif
58 | #ifndef MQTT_TOPIC_BATT_TEMP
59 | #define MQTT_TOPIC_BATT_TEMP_DF nullptr
60 | #else
61 | #define MQTT_TOPIC_BATT_TEMP_DF MQTT_TOPIC_BATT_TEMP
62 | #endif
63 | #ifndef MQTT_TOPIC_BATT_VOLTAGE
64 | #define MQTT_TOPIC_BATT_VOLTAGE_DF nullptr
65 | #else
66 | #define MQTT_TOPIC_BATT_VOLTAGE_DF MQTT_TOPIC_BATT_VOLTAGE
67 | #endif
68 | #ifndef MQTT_TOPIC_BATT_REMAIN
69 | #define MQTT_TOPIC_BATT_REMAIN_DF nullptr
70 | #else
71 | #define MQTT_TOPIC_BATT_REMAIN_DF MQTT_TOPIC_BATT_REMAIN
72 | #endif
73 | #ifndef MQTT_TOPIC_CONTROLLER_TEMP
74 | #define MQTT_TOPIC_CONTROLLER_TEMP_DF nullptr
75 | #else
76 | #define MQTT_TOPIC_CONTROLLER_TEMP_DF MQTT_TOPIC_CONTROLLER_TEMP
77 | #endif
78 | #ifndef MQTT_TOPIC_BATTERY_CHARGE_CURRENT
79 | #define MQTT_TOPIC_BATTERY_CHARGE_CURRENT_DF nullptr
80 | #else
81 | #define MQTT_TOPIC_BATTERY_CHARGE_CURRENT_DF MQTT_TOPIC_BATTERY_CHARGE_CURRENT
82 | #endif
83 | #ifndef MQTT_TOPIC_BATTERY_CHARGE_POWER
84 | #define MQTT_TOPIC_BATTERY_CHARGE_POWER_DF nullptr
85 | #else
86 | #define MQTT_TOPIC_BATTERY_CHARGE_POWER_DF MQTT_TOPIC_BATTERY_CHARGE_POWER
87 | #endif
88 | #ifndef MQTT_TOPIC_BATTERY_OVERALL_CURRENT
89 | #define MQTT_TOPIC_BATTERY_OVERALL_CURRENT_DF nullptr
90 | #else
91 | #define MQTT_TOPIC_BATTERY_OVERALL_CURRENT_DF MQTT_TOPIC_BATTERY_OVERALL_CURRENT
92 | #endif
93 | #ifndef MQTT_TOPIC_LOAD_ENABLED
94 | #define MQTT_TOPIC_LOAD_ENABLED_DF nullptr
95 | #else
96 | #define MQTT_TOPIC_LOAD_ENABLED_DF MQTT_TOPIC_LOAD_ENABLED
97 | #endif
98 | #ifndef MQTT_TOPIC_CHARGE_DEVICE_ENABLED
99 | #define MQTT_TOPIC_CHARGE_DEVICE_ENABLED_DF nullptr
100 | #else
101 | #define MQTT_TOPIC_CHARGE_DEVICE_ENABLED_DF MQTT_TOPIC_CHARGE_DEVICE_ENABLED
102 | #endif
103 | #ifndef MQTT_TOPIC_BATTERY_STATUS_TEXT
104 | #define MQTT_TOPIC_BATTERY_STATUS_TEXT_DF nullptr
105 | #else
106 | #define MQTT_TOPIC_BATTERY_STATUS_TEXT_DF MQTT_TOPIC_BATTERY_STATUS_TEXT
107 | #endif
108 | #ifndef MQTT_TOPIC_CHARGING_EQUIPMENT_STATUS_TEXT
109 | #define MQTT_TOPIC_CHARGING_EQUIPMENT_STATUS_TEXT_DF nullptr
110 | #else
111 | #define MQTT_TOPIC_CHARGING_EQUIPMENT_STATUS_TEXT_DF MQTT_TOPIC_CHARGING_EQUIPMENT_STATUS_TEXT
112 | #endif
113 | #ifndef MQTT_TOPIC_DISCHARGING_EQUIPMENT_STATUS_TEXT
114 | #define MQTT_TOPIC_DISCHARGING_EQUIPMENT_STATUS_TEXT_DF nullptr
115 | #else
116 | #define MQTT_TOPIC_DISCHARGING_EQUIPMENT_STATUS_TEXT_DF MQTT_TOPIC_DISCHARGING_EQUIPMENT_STATUS_TEXT
117 | #endif
118 | #ifndef MQTT_TOPIC_CONTROLLER_HEATSINK_TEMP
119 | #define MQTT_TOPIC_CONTROLLER_HEATSINK_TEMP_DF nullptr
120 | #else
121 | #define MQTT_TOPIC_CONTROLLER_HEATSINK_TEMP_DF MQTT_TOPIC_CONTROLLER_HEATSINK_TEMP
122 | #endif
123 | #ifndef MQTT_TOPIC_STAT_ENERGY_GENERATED_TODAY
124 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_TODAY_DF nullptr
125 | #else
126 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_TODAY_DF MQTT_TOPIC_STAT_ENERGY_GENERATED_TODAY
127 | #endif
128 | #ifndef MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_MONTH
129 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_MONTH_DF nullptr
130 | #else
131 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_MONTH_DF MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_MONTH
132 | #endif
133 | #ifndef MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_YEAR
134 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_YEAR_DF nullptr
135 | #else
136 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_YEAR_DF MQTT_TOPIC_STAT_ENERGY_GENERATED_THIS_YEAR
137 | #endif
138 | #ifndef MQTT_TOPIC_STAT_ENERGY_GENERATED_TOTAL
139 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_TOTAL_DF nullptr
140 | #else
141 | #define MQTT_TOPIC_STAT_ENERGY_GENERATED_TOTAL_DF MQTT_TOPIC_STAT_ENERGY_GENERATED_TOTAL
142 | #endif
143 | #ifndef MQTT_TOPIC_MIN_BATTERY_VOLTAGE_TODAY
144 | #define MQTT_TOPIC_MIN_BATTERY_VOLTAGE_TODAY_DF nullptr
145 | #else
146 | #define MQTT_TOPIC_MIN_BATTERY_VOLTAGE_TODAY_DF MQTT_TOPIC_MIN_BATTERY_VOLTAGE_TODAY
147 | #endif
148 | #ifndef MQTT_TOPIC_MAX_BATTERY_VOLTAGE_TODAY
149 | #define MQTT_TOPIC_MAX_BATTERY_VOLTAGE_TODAY_DF nullptr
150 | #else
151 | #define MQTT_TOPIC_MAX_BATTERY_VOLTAGE_TODAY_DF MQTT_TOPIC_MAX_BATTERY_VOLTAGE_TODAY
152 | #endif
153 | #ifndef MQTT_TOPIC_MIN_PV_VOLTAGE_TODAY
154 | #define MQTT_TOPIC_MIN_PV_VOLTAGE_TODAY_DF nullptr
155 | #else
156 | #define MQTT_TOPIC_MIN_PV_VOLTAGE_TODAY_DF MQTT_TOPIC_MIN_PV_VOLTAGE_TODAY
157 | #endif
158 | #ifndef MQTT_TOPIC_MAX_PV_VOLTAGE_TODAY
159 | #define MQTT_TOPIC_MAX_PV_VOLTAGE_TODAY_DF nullptr
160 | #else
161 | #define MQTT_TOPIC_MAX_PV_VOLTAGE_TODAY_DF MQTT_TOPIC_MAX_PV_VOLTAGE_TODAY
162 | #endif
163 | #ifndef MQTT_TOPIC_BATTERY_BOOST_VOLTAGE
164 | #define MQTT_TOPIC_BATTERY_BOOST_VOLTAGE_DF nullptr
165 | #else
166 | #define MQTT_TOPIC_BATTERY_BOOST_VOLTAGE_DF MQTT_TOPIC_BATTERY_BOOST_VOLTAGE
167 | #endif
168 | #ifndef MQTT_TOPIC_BATTERY_EQUALIZATION_VOLTAGE
169 | #define MQTT_TOPIC_BATTERY_EQUALIZATION_VOLTAGE_DF nullptr
170 | #else
171 | #define MQTT_TOPIC_BATTERY_EQUALIZATION_VOLTAGE_DF MQTT_TOPIC_BATTERY_EQUALIZATION_VOLTAGE
172 | #endif
173 | #ifndef MQTT_TOPIC_BATTERY_FLOAT_VOLTAGE
174 | #define MQTT_TOPIC_BATTERY_FLOAT_VOLTAGE_DF nullptr
175 | #else
176 | #define MQTT_TOPIC_BATTERY_FLOAT_VOLTAGE_DF MQTT_TOPIC_BATTERY_FLOAT_VOLTAGE
177 | #endif
178 | #ifndef MQTT_TOPIC_BATTERY_FLOAT_MIN_VOLTAGE
179 | #define MQTT_TOPIC_BATTERY_FLOAT_MIN_VOLTAGE_DF nullptr
180 | #else
181 | #define MQTT_TOPIC_BATTERY_FLOAT_MIN_VOLTAGE_DF MQTT_TOPIC_BATTERY_FLOAT_MIN_VOLTAGE
182 | #endif
183 | #ifndef MQTT_TOPIC_BATTERY_CHARGING_LIMIT_VOLTAGE
184 | #define MQTT_TOPIC_BATTERY_CHARGING_LIMIT_VOLTAGE_DF nullptr
185 | #else
186 | #define MQTT_TOPIC_BATTERY_CHARGING_LIMIT_VOLTAGE_DF MQTT_TOPIC_BATTERY_CHARGING_LIMIT_VOLTAGE
187 | #endif
188 | #ifndef MQTT_TOPIC_BATTERY_DISCHARGING_LIMIT_VOLTAGE
189 | #define MQTT_TOPIC_BATTERY_DISCHARGING_LIMIT_VOLTAGE_DF nullptr
190 | #else
191 | #define MQTT_TOPIC_BATTERY_DISCHARGING_LIMIT_VOLTAGE_DF MQTT_TOPIC_BATTERY_DISCHARGING_LIMIT_VOLTAGE
192 | #endif
193 | #ifndef MQTT_TOPIC_BATTERY_LOW_VOLTAGE_DISCONNECT
194 | #define MQTT_TOPIC_BATTERY_LOW_VOLTAGE_DISCONNECT_DF nullptr
195 | #else
196 | #define MQTT_TOPIC_BATTERY_LOW_VOLTAGE_DISCONNECT_DF MQTT_TOPIC_BATTERY_LOW_VOLTAGE_DISCONNECT
197 | #endif
198 | #ifndef MQTT_TOPIC_BATTERY_LOW_VOLTAGE_RECONNECT
199 | #define MQTT_TOPIC_BATTERY_LOW_VOLTAGE_RECONNECT_DF nullptr
200 | #else
201 | #define MQTT_TOPIC_BATTERY_LOW_VOLTAGE_RECONNECT_DF MQTT_TOPIC_BATTERY_LOW_VOLTAGE_RECONNECT
202 | #endif
203 | #ifndef MQTT_TOPIC_BATTERY_OVER_VOLTAGE_DISCONNECT
204 | #define MQTT_TOPIC_BATTERY_OVER_VOLTAGE_DISCONNECT_DF nullptr
205 | #else
206 | #define MQTT_TOPIC_BATTERY_OVER_VOLTAGE_DISCONNECT_DF MQTT_TOPIC_BATTERY_OVER_VOLTAGE_DISCONNECT
207 | #endif
208 | #ifndef MQTT_TOPIC_BATTERY_OVER_VOLTAGE_RECONNECT
209 | #define MQTT_TOPIC_BATTERY_OVER_VOLTAGE_RECONNECT_DF nullptr
210 | #else
211 | #define MQTT_TOPIC_BATTERY_OVER_VOLTAGE_RECONNECT_DF MQTT_TOPIC_BATTERY_OVER_VOLTAGE_RECONNECT
212 | #endif
213 | #ifndef MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_RESET
214 | #define MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_RESET_DF nullptr
215 | #else
216 | #define MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_RESET_DF MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_RESET
217 | #endif
218 | #ifndef MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_SET
219 | #define MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_SET_DF nullptr
220 | #else
221 | #define MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_SET_DF MQTT_TOPIC_BATTERY_UNDER_VOLTAGE_SET
222 | #endif
223 | #ifndef MQTT_TOPIC_INTERNAL_STATUS
224 | #define MQTT_TOPIC_INTERNAL_STATUS_DF nullptr
225 | #else
226 | #define MQTT_TOPIC_INTERNAL_STATUS_DF MQTT_TOPIC_INTERNAL_STATUS
227 | #endif
228 | #ifndef MQTT_TOPIC_INTERNAL_DEBUG_TERMINAL
229 | #define MQTT_TOPIC_INTERNAL_DEBUG_TERMINAL_DF nullptr
230 | #else
231 | #define MQTT_TOPIC_INTERNAL_DEBUG_TERMINAL_DF MQTT_TOPIC_INTERNAL_DEBUG_TERMINAL
232 | #endif
233 | #ifndef MQTT_TOPIC_UPDATE_CONTROLLER_DATETIME
234 | #define MQTT_TOPIC_UPDATE_CONTROLLER_DATETIME_DF nullptr
235 | #else
236 | #define MQTT_TOPIC_UPDATE_CONTROLLER_DATETIME_DF MQTT_TOPIC_UPDATE_CONTROLLER_DATETIME
237 | #endif
238 | #ifndef MQTT_TOPIC_UPDATE_ALL_CONTROLLER_DATA
239 | #define MQTT_TOPIC_UPDATE_ALL_CONTROLLER_DATA_DF nullptr
240 | #else
241 | #define MQTT_TOPIC_UPDATE_ALL_CONTROLLER_DATA_DF MQTT_TOPIC_UPDATE_ALL_CONTROLLER_DATA
242 | #endif
243 | #ifndef MQTT_TOPIC_BATTERY_RATED_VOLTAGE
244 | #define MQTT_TOPIC_BATTERY_RATED_VOLTAGE_DF nullptr
245 | #else
246 | #define MQTT_TOPIC_BATTERY_RATED_VOLTAGE_DF MQTT_TOPIC_BATTERY_RATED_VOLTAGE
247 | #endif
248 | #ifndef MQTT_TOPIC_BATTERY_TYPE
249 | #define MQTT_TOPIC_BATTERY_TYPE_DF nullptr
250 | #else
251 | #define MQTT_TOPIC_BATTERY_TYPE_DF MQTT_TOPIC_BATTERY_TYPE
252 | #endif
253 | #ifndef MQTT_TOPIC_BATTERY_CAPACITY
254 | #define MQTT_TOPIC_BATTERY_CAPACITY_DF nullptr
255 | #else
256 | #define MQTT_TOPIC_BATTERY_CAPACITY_DF MQTT_TOPIC_BATTERY_CAPACITY
257 | #endif
258 | #ifndef MQTT_TOPIC_BATTERY_EQUALIZATION_DURATION
259 | #define MQTT_TOPIC_BATTERY_EQUALIZATION_DURATION_DF nullptr
260 | #else
261 | #define MQTT_TOPIC_BATTERY_EQUALIZATION_DURATION_DF MQTT_TOPIC_BATTERY_EQUALIZATION_DURATION
262 | #endif
263 | #ifndef MQTT_TOPIC_BATTERY_BOOST_DURATION
264 | #define MQTT_TOPIC_BATTERY_BOOST_DURATION_DF nullptr
265 | #else
266 | #define MQTT_TOPIC_BATTERY_BOOST_DURATION_DF MQTT_TOPIC_BATTERY_BOOST_DURATION
267 | #endif
268 | #ifndef MQTT_TOPIC_BATTERY_TEMPERATURE_COMPENSATION_COEFF
269 | #define MQTT_TOPIC_BATTERY_TEMPERATURE_COMPENSATION_COEFF_DF nullptr
270 | #else
271 | #define MQTT_TOPIC_BATTERY_TEMPERATURE_COMPENSATION_COEFF_DF MQTT_TOPIC_BATTERY_TEMPERATURE_COMPENSATION_COEFF
272 | #endif
273 | #ifndef MQTT_TOPIC_BATTERY_MANAGEMENT_MODE
274 | #define MQTT_TOPIC_BATTERY_MANAGEMENT_MODE_DF nullptr
275 | #else
276 | #define MQTT_TOPIC_BATTERY_MANAGEMENT_MODE_DF MQTT_TOPIC_BATTERY_MANAGEMENT_MODE
277 | #endif
278 | #ifndef MQTT_TOPIC_STAT_ENERGY_CONSUMED_TODAY
279 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_TODAY_DF nullptr
280 | #else
281 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_TODAY_DF MQTT_TOPIC_STAT_ENERGY_CONSUMED_TODAY
282 | #endif
283 | #ifndef MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_MONTH
284 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_MONTH_DF nullptr
285 | #else
286 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_MONTH_DF MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_MONTH
287 | #endif
288 | #ifndef MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_YEAR
289 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_YEAR_DF nullptr
290 | #else
291 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_YEAR_DF MQTT_TOPIC_STAT_ENERGY_CONSUMED_THIS_YEAR
292 | #endif
293 | #ifndef MQTT_TOPIC_STAT_ENERGY_CONSUMED_TOTAL
294 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_TOTAL_DF nullptr
295 | #else
296 | #define MQTT_TOPIC_STAT_ENERGY_CONSUMED_TOTAL_DF MQTT_TOPIC_STAT_ENERGY_CONSUMED_TOTAL
297 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/solartracer_all.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #define DUMMY_SOLAR_TRACER 0xF001
25 |
26 | #define EPEVER_SOLAR_TRACER_A 0x0001
27 | #define EPEVER_SOLAR_TRACER_B 0x0002
28 | #define EPEVER_SOLAR_TRACER_TRITON 0x0003
29 | #define EPEVER_SOLAR_TRACER_XTRA 0x0004
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/incl/status_all.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #define STATUS_ERR_SOLAR_TRACER_NO_SYNC_ST 1
25 | #define STATUS_ERR_SOLAR_TRACER_NO_SYNC_RT 2
26 | #define STATUS_ERR_SOLAR_TRACER_NO_SYNC 3
27 | #define STATUS_ERR_NO_CONNECTION 4 // not used!
28 | #define STATUS_RUN_BOOTING 8
29 | #define STATUS_ERR_SOLAR_TRACER_NO_COMMUNICATION 16
30 | #define STATUS_ERR_NO_BLYNK_CONNECTION 32
31 | #define STATUS_ERR_NO_WIFI_CONNECTION 64
32 | #define STATUS_ERR_NO_MQTT_CONNECTION 128
33 | #define STATUS_ERR_LITTLEFS_BEGIN_FAILED 256
34 | #define STATUS_ERR_LITTLEFS_FORMAT_FAILED 512
35 | #define STATUS_ERR_CONFIGURATION_CANNOT_READ 1024
36 | #define STATUS_ERR_CONFIGURATION_CANNOT_PARSE 2048
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/SolarTracer.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "SolarTracer.h"
23 |
24 | SolarTracer::SolarTracer() {
25 | this->variableDefine = new SolarTracerVariableDefinition *[Variable::VARIABLES_COUNT]();
26 | SolarTracerVariableDefinition *value;
27 | uint8_t varSize;
28 |
29 | for (uint8_t varIndex = 0; varIndex < Variable::VARIABLES_COUNT; varIndex++) {
30 | value = nullptr;
31 | if (VariableDefiner::getInstance().isFromScc((Variable)varIndex)) {
32 | varSize = VariableDefiner::getInstance().getVariableSize((Variable)varIndex);
33 | if (varSize > 0) {
34 | value = new SolarTracerVariableDefinition{0, malloc(varSize)};
35 | }
36 | }
37 | this->variableDefine[varIndex] = value;
38 | }
39 | }
40 |
41 | void SolarTracer::setVariableEnable(Variable variable, bool enable) {
42 | if (variable < Variable::VARIABLES_COUNT && this->variableDefine[variable] != nullptr && this->isVariableEnabled(variable) != enable) {
43 | this->variableDefine[variable]->status += enable ? 1 : -1;
44 | }
45 | }
46 |
47 | bool SolarTracer::isVariableEnabled(Variable variable) {
48 | return variable < Variable::VARIABLES_COUNT && this->variableDefine[variable] != nullptr && (this->variableDefine[variable]->status & 1) > 0;
49 | }
50 |
51 | void SolarTracer::setVariableReadReady(Variable variable, bool enable) {
52 | if (variable < Variable::VARIABLES_COUNT && this->isVariableReadReady(variable) != enable) {
53 | this->variableDefine[variable]->status += enable ? 2 : -2;
54 | }
55 | }
56 |
57 | void SolarTracer::setVariableReadReady(uint8_t count, bool ready, ...) {
58 | va_list args;
59 | va_start(args, ready);
60 |
61 | for (uint8_t i = 1; i <= count; i++) {
62 | this->setVariableReadReady((Variable)va_arg(args, int), ready);
63 | }
64 |
65 | va_end(args);
66 | }
67 |
68 | bool SolarTracer::isVariableReadReady(Variable variable) {
69 | return variable < Variable::VARIABLES_COUNT && (this->variableDefine[variable]->status & 2) > 0;
70 | }
71 |
72 | bool SolarTracer::isVariableOverWritten(Variable variable) {
73 | return variable < Variable::VARIABLES_COUNT && this->variableDefine[variable] != nullptr && (this->variableDefine[variable]->status & 4) > 0;
74 | }
75 |
76 | void SolarTracer::setVariableOverWritten(Variable variable, bool enable) {
77 | if (variable < Variable::VARIABLES_COUNT && this->isVariableOverWritten(variable) != enable) {
78 | this->variableDefine[variable]->status += enable ? 4 : -4;
79 | }
80 | }
81 |
82 | const void *SolarTracer::getValue(Variable variable) {
83 | return this->variableDefine[variable]->value;
84 | }
85 |
86 | bool SolarTracer::setVariableValue(Variable variable, const void *value, bool ignoreOverWriteLock) {
87 | if (!ignoreOverWriteLock && this->isVariableOverWritten(variable)) {
88 | return true;
89 | }
90 | bool valueOk = value != nullptr;
91 | if (valueOk) {
92 | uint8_t vSize = VariableDefiner::getInstance().getVariableSize(variable);
93 | if (vSize > 0) {
94 | memcpy(this->variableDefine[variable]->value, value, vSize);
95 | }
96 | }
97 | this->setVariableReadReady(variable, valueOk);
98 |
99 | return valueOk;
100 | }
101 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/SolarTracer.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #ifndef SOLARTRACER_H
23 | #define SOLARTRACER_H
24 |
25 | #include "../core/VariableDefiner.h"
26 |
27 | typedef void (*OnUpdateRunCompletedCallback)();
28 |
29 | struct SolarTracerVariableDefinition {
30 | /**
31 | * byte 0 - enabled
32 | * byte 1 - ready
33 | * byte 2 - overwritten
34 | */
35 | uint8_t status;
36 | void *value;
37 | };
38 |
39 | class SolarTracer {
40 | public:
41 | SolarTracer();
42 |
43 | /**
44 | * Check if the variable is supporter by the SCC
45 | */
46 | bool isVariableEnabled(Variable variable);
47 |
48 | /**
49 | * Check if variable is ready to be read (value has been fetched from the scc)
50 | */
51 | bool isVariableReadReady(Variable variable);
52 |
53 | /**
54 | * Check if variable has been overwritten
55 | */
56 | bool isVariableOverWritten(Variable variable);
57 |
58 | /**
59 | * Set variable as overwritten (not managed by the scc)
60 | */
61 | void setVariableOverWritten(Variable variable, bool enable);
62 |
63 | /**
64 | * Get the value of the variable, null if variable is not ready
65 | */
66 | virtual const void *getValue(Variable variable);
67 |
68 | /**
69 | * Set the value of the variable
70 | */
71 | bool setVariableValue(Variable variable, const void *value, bool ignoreOverWriteLock = false);
72 |
73 | void setOnUpdateRunCompleted(OnUpdateRunCompletedCallback fn) {
74 | this->onUpdateRunCompleted = fn;
75 | }
76 |
77 | /**
78 | * Return last status code, 0 means the controller is responding to requests correctly.
79 | */
80 | inline const uint16_t getLastControllerCommunicationStatus();
81 |
82 | virtual bool fetchValue(Variable variable) = 0;
83 | virtual bool syncRealtimeClock(struct tm *ti) = 0;
84 | virtual void fetchAllValues() = 0;
85 | virtual bool updateRun() = 0;
86 | virtual bool writeValue(Variable variable, const void *value) = 0;
87 | virtual bool testConnection() = 0;
88 |
89 | protected:
90 | inline bool setFloatVariable(Variable variable, float value);
91 |
92 | void updateRunCompleted() {
93 | if (this->onUpdateRunCompleted) {
94 | this->onUpdateRunCompleted();
95 | }
96 | }
97 |
98 | void setVariableEnable(Variable variable, bool enable = true);
99 |
100 | void setVariableReadReady(Variable variable, bool enable);
101 |
102 | void setVariableReadReady(uint8_t count, bool ready, ...);
103 |
104 | uint16_t lastControllerCommunicationStatus;
105 |
106 | private:
107 | OnUpdateRunCompletedCallback onUpdateRunCompleted = nullptr;
108 | SolarTracerVariableDefinition **variableDefine;
109 | };
110 |
111 | inline const uint16_t SolarTracer::getLastControllerCommunicationStatus() {
112 | return this->lastControllerCommunicationStatus;
113 | }
114 |
115 | inline bool SolarTracer::setFloatVariable(Variable variable, float value) {
116 | return this->setVariableValue(variable, &value);
117 | }
118 |
119 | #endif
120 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/dummy/DummySolarTracer.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #ifndef DUMMYSOLARTRACER_H
23 | #define DUMMYSOLARTRACER_H
24 |
25 | #include "../../core/VariableDefiner.h"
26 | #include "../SolarTracer.h"
27 |
28 | class DummySolarTracer : public SolarTracer {
29 | public:
30 | DummySolarTracer() : SolarTracer() {
31 | this->dummyTextValue = new char[20];
32 |
33 | bool enabled;
34 | for (uint8_t index = 0; index < Variable::VARIABLES_COUNT; index++) {
35 | if (VariableDefiner::getInstance().isFromScc((Variable)index)) {
36 | this->setVariableEnable((Variable)index, true);
37 | this->setVariableReadReady((Variable)index, true);
38 | }
39 | }
40 | };
41 |
42 | virtual bool fetchValue(Variable variable) {
43 | return true;
44 | };
45 | virtual bool syncRealtimeClock(struct tm *ti) {
46 | return true;
47 | }
48 | virtual void fetchAllValues(){};
49 | virtual bool updateRun() {
50 | return true;
51 | };
52 | virtual bool writeValue(Variable variable, const void *value) {
53 | return true;
54 | };
55 | virtual bool testConnection() {
56 | return true;
57 | };
58 |
59 | virtual const void *getValue(Variable variable) {
60 | switch (VariableDefiner::getInstance().getDatatype(variable)) {
61 | case VariableDatatype::DT_BOOL:
62 | this->dummyBoolValue = random(2) > 0;
63 | return &this->dummyBoolValue;
64 | case VariableDatatype::DT_FLOAT:
65 | this->dummyFloatValue = random(10000) / 100.00;
66 | return &this->dummyFloatValue;
67 | case VariableDatatype::DT_STRING:
68 | strcpy(this->dummyTextValue, "Text");
69 | return this->dummyTextValue;
70 | case VariableDatatype::DT_UINT16:
71 | this->dummyUInt16 = random(100) > 0;
72 | return &this->dummyUInt16;
73 | }
74 | return nullptr;
75 | }
76 |
77 | private:
78 | bool dummyBoolValue;
79 | float dummyFloatValue;
80 | char *dummyTextValue;
81 | uint16_t dummyUInt16;
82 | };
83 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/epever/EPEVERSolarTracer.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #ifndef EPEVERSolarTracer_h
23 | #define EPEVERSolarTracer_h
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | #include "../SolarTracer.h"
30 |
31 | class EPEVERSolarTracer : public SolarTracer, public ModbusMasterCallable {
32 | public:
33 | EPEVERSolarTracer(Stream &serialCom, uint16_t serialTimeoutMs, uint8_t slave, uint8_t max485_de, uint8_t max485_re_neg, uint16_t preTransmitWait);
34 | EPEVERSolarTracer(Stream &serialCom, uint16_t serialTimeoutMs, uint8_t slave, uint16_t preTransmitWait);
35 |
36 | virtual bool syncRealtimeClock(struct tm *ti);
37 |
38 | virtual void fetchAllValues();
39 |
40 | virtual bool updateRun();
41 |
42 | virtual bool fetchValue(Variable variable);
43 |
44 | virtual bool writeValue(Variable variable, const void *value);
45 |
46 | bool readControllerSingleCoil(uint16_t address);
47 |
48 | void AddressRegistry_3100();
49 |
50 | void AddressRegistry_3110();
51 |
52 | void AddressRegistry_311A();
53 |
54 | void AddressRegistry_331B();
55 |
56 | void AddressRegistry_9003();
57 |
58 | void AddressRegistry_9067();
59 |
60 | void AddressRegistry_906B();
61 |
62 | void fetchAddressStatusVariables();
63 |
64 | void updateStats();
65 |
66 | /*
67 | Implementation of ModbusMasterCallable
68 | */
69 | virtual void onModbusPreTransmission();
70 |
71 | virtual void onModbusIdle();
72 |
73 | virtual void onModbusPostTransmission();
74 |
75 | virtual bool testConnection();
76 |
77 | protected:
78 | uint8_t max485_re_neg, max485_de;
79 | uint16_t preTransmitWaitMs;
80 |
81 | bool rs485readSuccess;
82 |
83 | uint16_t globalUpdateCounter = 0;
84 | uint8_t currentRealtimeUpdateCounter = 0;
85 |
86 | ModbusMaster node;
87 |
88 | // MODBUS FUNCTION
89 |
90 | bool writeControllerSingleCoil(uint16_t address, bool value);
91 | bool writeControllerHoldingRegister(uint16_t address, uint16_t value);
92 | bool replaceControllerHoldingRegister(uint16_t address, uint16_t value, uint16_t fromAddress, uint8_t count);
93 |
94 | static constexpr const float ONE_HUNDRED_FLOAT = 100;
95 |
96 | private:
97 | static const uint8_t voltageLevels[];
98 |
99 | void onPreNodeRequest() {
100 | if (this->preTransmitWaitMs > 0) {
101 | delay(this->preTransmitWaitMs);
102 | }
103 | }
104 |
105 | static uint16_t getBatteryVoltageLevelFromVoltage(uint16_t voltage) {
106 | uint8_t index = 0;
107 | while (true) {
108 | if (voltageLevels[index] == 0) {
109 | return 0;
110 | }
111 | if (voltageLevels[index] == voltage) {
112 | return index + 1;
113 | }
114 | index++;
115 | }
116 | }
117 |
118 | static uint16_t getVoltageFromBatteryVoltageLevel(uint16_t index) {
119 | return voltageLevels[index];
120 | }
121 | };
122 |
123 | #endif
124 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/epever/EPEVER_modbus_address.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #ifndef EPEVER_modbus_address_h
23 | #define EPEVER_modbus_address_h
24 |
25 | #define MODBUS_ADDRESS_PV_VOLTAGE 0x3100
26 | #define MODBUS_ADDRESS_PV_POWER 0x3102
27 | #define MODBUS_ADDRESS_PV_CURRENT 0x3101
28 | #define MODBUS_ADDRESS_LOAD_CURRENT 0x310D
29 | #define MODBUS_ADDRESS_LOAD_POWER 0x310E
30 | #define MODBUS_ADDRESS_BATT_TEMP 0x3110
31 | #define MODBUS_ADDRESS_BATT_VOLTAGE 0x3104
32 | #define MODBUS_ADDRESS_BATT_SOC 0x311A
33 | #define MODBUS_ADDRESS_BATTERY_CHARGE_CURRENT 0x3105
34 | #define MODBUS_ADDRESS_BATTERY_CHARGE_POWER 0x3106
35 | #define MODBUS_ADDRESS_BATTERY_OVERALL_CURRENT 0x331B
36 | #define MODBUS_ADDRESS_LOAD_FORCE_ONOFF 0x0006
37 | #define MODBUS_ADDRESS_LOAD_MANUAL_ONOFF 0x0002
38 | #define MODBUS_ADDRESS_BATTERY_CHARGE_ONOFF 0x0000
39 | #define MODBUS_ADDRESS_BATTERY_STATUS 0x3200
40 | #define MODBUS_ADDRESS_CHARGING_EQUIPMENT_STATUS 0x3200
41 | #define MODBUS_ADDRESS_DISCHARGING_EQUIPMENT_STATUS 0x3200
42 | #define MODBUS_ADDRESS_STAT_MAX_PV_VOLTAGE_TODAY 0x3300
43 | #define MODBUS_ADDRESS_STAT_CONSUMED_ENERGY_TODAY 0x3304
44 | #define MODBUS_ADDRESS_STAT_CONSUMED_ENERGY_MONTH 0x3306
45 | #define MODBUS_ADDRESS_STAT_CONSUMED_ENERGY_YEAR 0x3308
46 | #define MODBUS_ADDRESS_STAT_GENERATED_ENERGY_TODAY 0x330C
47 | #define MODBUS_ADDRESS_STAT_GENERATED_ENERGY_MONTH 0x330E
48 | #define MODBUS_ADDRESS_STAT_GENERATED_ENERGY_YEAR 0x3310
49 | #define MODBUS_ADDRESS_CONTROLLER_TEMP 0x3111
50 | #define MODBUS_ADDRESS_REMOTE_BATTERY_TEMP 0x311B
51 | #define MODBUS_ADDRESS_REALTIME_CLOCK 0x9013
52 | #define MODBUS_ADDRESS_BATTERY_TYPE 0x9000
53 | #define MODBUS_ADDRESS_BATTERY_CAPACITY 0x9001
54 | #define MODBUS_ADDRESS_BATTERY_TEMP_COEFF 0x9002
55 | #define MODBUS_ADDRESS_HIGH_VOLTAGE_DISCONNECT 0x9003
56 | #define MODBUS_ADDRESS_CHARGING_LIMIT_VOLTAGE 0x9004
57 | #define MODBUS_ADDRESS_OVER_VOLTAGE_RECONNECT 0x9005
58 | #define MODBUS_ADDRESS_EQUALIZATION_VOLTAGE 0x9006
59 | #define MODBUS_ADDRESS_BOOST_VOLTAGE 0x9007
60 | #define MODBUS_ADDRESS_FLOAT_VOLTAGE 0x9008
61 | #define MODBUS_ADDRESS_BOOST_RECONNECT_VOLTAGE 0x9009
62 | #define MODBUS_ADDRESS_LOW_VOLTAGE_RECONNECT 0x900A
63 | #define MODBUS_ADDRESS_UNDER_VOLTAGE_RECOVER 0x900B
64 | #define MODBUS_ADDRESS_UNDER_VOLTAGE_WARNING 0x900C
65 | #define MODBUS_ADDRESS_LOW_VOLTAGE_DISCONNECT 0x900D
66 | #define MODBUS_ADDRESS_DISCHARGING_LIMIT_VOLTAGE 0x900E
67 | #define MODBUS_ADDRESS_BATTERY_RATED_LEVEL 0x9067
68 | #define MODBUS_ADDRESS_EQUALIZE_DURATION 0x906B
69 | #define MODBUS_ADDRESS_BOOST_DURATION 0x906C
70 | #define MODBUS_ADDRESS_CHARGING_MODE 0x9070
71 |
72 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/epever/epever_config.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #include "../../incl/include_all_core.h"
25 |
26 | #ifndef BOARD_ST_SERIAL_STREAM_BAUDRATE
27 | #define BOARD_ST_SERIAL_STREAM_BAUDRATE 115200
28 | #endif
29 |
30 | #ifndef MODBUS_SLAVE_ID
31 | #define MODBUS_SLAVE_ID 1
32 | #endif
33 |
34 | #ifndef CONTROLLER_UPDATE_MS_PERIOD
35 | #define CONTROLLER_UPDATE_MS_PERIOD 2000L
36 | #endif
37 |
38 | #ifndef SERIAL_COMMUNICATION_TIMEOUT
39 | // will use the default value from library
40 | #define SERIAL_COMMUNICATION_TIMEOUT 0
41 | #endif
42 |
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/incl/solar_config.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #include "../epever/epever_config.h"
23 |
24 | #if (SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_A | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_B | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_TRITON | SOLAR_TRACER_MODEL == EPEVER_SOLAR_TRACER_XTRA)
25 | #include "../epever/EPEVERSolarTracer.h"
26 | #ifdef USE_SERIAL_MAX485
27 | #define SOLAR_TRACER_INSTANCE EPEVERSolarTracer(BOARD_ST_SERIAL_STREAM, SERIAL_COMMUNICATION_TIMEOUT, MODBUS_SLAVE_ID, MAX485_DE, MAX485_RE_NEG, BOARD_ST_SERIAL_PRETRANSMIT_WAIT)
28 | #else
29 | #define SOLAR_TRACER_INSTANCE EPEVERSolarTracer(BOARD_ST_SERIAL_STREAM, SERIAL_COMMUNICATION_TIMEOUT, MODBUS_SLAVE_ID, BOARD_ST_SERIAL_PRETRANSMIT_WAIT)
30 | #endif
31 | #elif (SOLAR_TRACER_MODEL == DUMMY_SOLAR_TRACER)
32 | #include "../dummy/DummySolarTracer.h"
33 | #define SOLAR_TRACER_INSTANCE DummySolarTracer()
34 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/overwrite/LoadCurrentOverWrite.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "../../incl/include_all_core.h"
3 |
4 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
5 |
6 | #include "LoadCurrentOverwrite.h"
7 |
8 | float LoadCurrentOverwrite::totalLoadEnergy = 0;
9 | LinearSensHallCurrent *LoadCurrentOverwrite::sensor = nullptr;
10 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER_ADS1015_ADC
11 | ADS1015 *LoadCurrentOverwrite::ads1015 = nullptr;
12 | #endif
13 | unsigned long LoadCurrentOverwrite::lastRunMillis = 0;
14 |
15 | #endif
--------------------------------------------------------------------------------
/SolarTracerBlynk/src/solartracer/overwrite/LoadCurrentOverwrite.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Solar Tracer Blynk V3 [https://github.com/Bettapro/Solar-Tracer-Blynk-V3]
3 | * Copyright (c) 2021 Alberto Bettin
4 | *
5 | * Based on the work of @jaminNZx and @tekk.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | *
20 | */
21 |
22 | #pragma once
23 |
24 | #ifndef LOAD_CURRENT_OVERWRITE_H
25 | #define LOAD_CURRENT_OVERWRITE_H
26 |
27 | #include "../../incl/include_all_core.h"
28 |
29 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER
30 |
31 | #include "../../core/Environment.h"
32 | #include "../../incl/include_all_lib.h"
33 | #include "../SolarTracer.h"
34 |
35 | class LoadCurrentOverwrite {
36 | public:
37 | static void setup(SolarTracer *tracer) {
38 | totalLoadEnergy = 0;
39 | lastRunMillis = 0;
40 |
41 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER_ADS1015_ADC
42 | ads1015 = new ADS1015(0x48);
43 | ads1015->begin();
44 |
45 | ads1015->setGain(0);
46 |
47 | sensor = new LinearSensHallCurrent(LinearSensHallCurrentType::CUSTOM, 0, 6.144, 11);
48 | sensor->setRawReadFn([]() {
49 | int adp_value = ads1015->readADC(ADS1015_LOAD_CURRENT_CHANNEL);
50 | return adp_value; });
51 | #endif
52 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_ADC
53 | sensor = new LinearSensHallCurrent(LinearSensHallCurrentType::CUSTOM, ADC_LOAD_CURRENT_PIN, 3.3, 12);
54 | #endif
55 |
56 | sensor->setZeroVout(Environment::getData()->heavyLoadCurrentZeroV);
57 | sensor->setSampleNumber(EXTERNAL_HEAVY_LOAD_CURRENT_METER_SAMPLES_NUMBER);
58 | sensor->setSampleDelay(EXTERNAL_HEAVY_LOAD_CURRENT_METER_SAMPLE_INTERVAL);
59 | sensor->setVASensitivity(EXTERNAL_HEAVY_LOAD_CURRENT_METER_VOLTAGE_AMP_VOLT);
60 |
61 | tracer->setVariableOverWritten(Variable::LOAD_CURRENT, true);
62 | tracer->setVariableOverWritten(Variable::LOAD_POWER, tracer->isVariableEnabled(Variable::BATTERY_VOLTAGE));
63 | tracer->setVariableOverWritten(Variable::CONSUMED_ENERGY_TODAY, tracer->isVariableEnabled(Variable::BATTERY_VOLTAGE));
64 | tracer->setVariableOverWritten(Variable::CONSUMED_ENERGY_MONTH, tracer->isVariableEnabled(Variable::BATTERY_VOLTAGE));
65 | tracer->setVariableOverWritten(Variable::CONSUMED_ENERGY_YEAR, tracer->isVariableEnabled(Variable::BATTERY_VOLTAGE));
66 | tracer->setVariableOverWritten(Variable::CONSUMED_ENERGY_TOTAL, tracer->isVariableEnabled(Variable::BATTERY_VOLTAGE));
67 | tracer->setVariableOverWritten(Variable::BATTERY_OVERALL_CURRENT, tracer->isVariableEnabled(Variable::BATTERY_CHARGE_CURRENT));
68 | }
69 |
70 | static void overWrite(SolarTracer *tracer) {
71 | float current = sensor->readCurrent();
72 | if (current > 1000) {
73 | // not happening
74 | return;
75 | }
76 | if (current < 0) {
77 | // loads do not produce any current, must be a false reading
78 | current = 0;
79 | }
80 | tracer->setVariableValue(Variable::LOAD_CURRENT, ¤t, true);
81 |
82 | if (tracer->isVariableReadReady(Variable::BATTERY_CHARGE_CURRENT)) {
83 | const void *chargingCurrent = tracer->getValue(Variable::BATTERY_CHARGE_CURRENT);
84 | float overallCurrent = *(float *)chargingCurrent - current;
85 | tracer->setVariableValue(Variable::BATTERY_OVERALL_CURRENT, &overallCurrent, true);
86 | }
87 |
88 | const void *loadVoltage = tracer->getValue(Variable::BATTERY_VOLTAGE);
89 |
90 | if (!tracer->isVariableReadReady(Variable::BATTERY_VOLTAGE) || loadVoltage == nullptr) {
91 | return;
92 | }
93 |
94 | unsigned long currentRunMillis = millis();
95 |
96 | float loadPower = current * *((float *)loadVoltage);
97 | float loadEnergy = lastRunMillis > 0 ? (currentRunMillis - lastRunMillis) / 3600000000.0 * loadPower : 0;
98 | lastRunMillis = currentRunMillis;
99 |
100 | tracer->setVariableValue(Variable::LOAD_POWER, &loadPower, true);
101 |
102 | totalLoadEnergy += loadEnergy;
103 | tracer->setVariableValue(Variable::CONSUMED_ENERGY_TODAY, &totalLoadEnergy, true);
104 | tracer->setVariableValue(Variable::CONSUMED_ENERGY_MONTH, &totalLoadEnergy, true);
105 | tracer->setVariableValue(Variable::CONSUMED_ENERGY_YEAR, &totalLoadEnergy, true);
106 | tracer->setVariableValue(Variable::CONSUMED_ENERGY_TOTAL, &totalLoadEnergy, true);
107 | }
108 |
109 | private:
110 | static float totalLoadEnergy;
111 | static LinearSensHallCurrent *sensor;
112 | #ifdef USE_EXTERNAL_HEAVY_LOAD_CURRENT_METER_ADS1015_ADC
113 | static ADS1015 *ads1015;
114 | #endif
115 | static unsigned long lastRunMillis;
116 | };
117 |
118 | #endif
119 | #endif
--------------------------------------------------------------------------------
/docs/1733_modbus_protocol.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/docs/1733_modbus_protocol.pdf
--------------------------------------------------------------------------------
/docs/Esp32_max485_epever_rj45.md:
--------------------------------------------------------------------------------
1 | # Connect ESP32 to EPEVER A/B Series ( + MAX485)
2 |
3 | Here the material involved:
4 | * ESP 32 MODULE, below the modules tested:
5 | * [ESP32 D1 MINI](https://www.aliexpress.com/premium/esp32-d1-mini.html?d=y&origin=y&catId=0&initiative_id=SB_20210919083440&SearchText=esp32%20d1%20mini)
6 | * [ESP32 WROOM DEV MODULE](https://it.aliexpress.com/wholesale?catId=0&initiative_id=SB_20210919092741&isPremium=y&SearchText=esp+wroom-32+38+pin+devkit)
7 | * or any esp32 module you like
8 | * [EPSolar/EPEver Tracer A/B-Series](https://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20170114172728&SearchText=tracer+mppt+rs485)
9 | * [MAX 485 UART Module](https://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20210919083609&isPremium=y&SearchText=max485+module)
10 | * An old ethernet cable with RJ45 connector you are happy to cut open
11 |
12 |
13 | ## ESP32 <-> MAX485 module
14 |
15 | 
16 |
17 | It's powered from `+5V` from ESP32 module, and wired as following:
18 |
19 | ### ESP32 D1 MINI
20 | - `DI` -> `IO17` / `GPIO17` / `TX2`
21 | - `RO` -> `IO16` / `GPIO16` / `RX2`
22 | - `DE` and `RE` are interconnected with a jumper and then connected to pin `TCK` / `GPIO13`
23 | - `VCC` to `+3.3V` / `3V3` on ESP32
24 |
25 |
26 | 
27 |
28 | ### ESP32 WRROOM 38 PIN
29 | - `DI` -> `28` / `GPIO17` / `TX2`
30 | - `RO` -> `27` / `GPIO16` / `RX2`
31 | - `DE` and `RE` are interconnected with a jumper and then connected to pin `15` / `GPIO13`
32 | - `VCC` to `+3.3V` / `3.3v` on ESP32
33 |
34 | 
35 |
36 | ## MAX485 module <-> EPEVER CONTROLLER (RJ45)
37 |
38 | Cut open your ethernet cable and split out pin 4, 6, 8 (B, A, GND). Refer to [Tracer Modbus PDF](../docs/1733_modbus_protocol.pdf) for additional info.
39 |
40 | Connect wires as follows (make sure your cable matches the color schema below - otherwise refer to pin numbers only):
41 | - Ethernet green / pin `6` -> `A`
42 | - Ethernet blue / pin `4` -> `B`
43 | - Ethernet brown / pin `8` -> `GND` on module **and** ESP8266 `GND` pin
44 | - -> to prevent ground loops - **important!**
45 | - **DON' T** use pin `1` or `2` to feed the ESP8266 (they supply 7,5/5V - 50mA maximum)
46 |
47 | 
48 | 
49 |
50 | ## BASE SW CONFIGURATION
51 |
52 | Edits required on *src/config.h*:
53 | - `#define BOARD_ST_SERIAL_STREAM Serial2` [default]
54 | - Uncomment `#define USE_SERIAL_MAX485`
55 | - `#define MAX485_DE 13`
56 | - `#define MAX485_RE_NEG 13`
57 |
58 | Edit on *platformio.ini* (Platformio only):
59 | - **ESP32 MINI D1 - only**
60 | - `platformio.default_envs = wemos_d1_mini32` (usb/serial fw flash) or `platformio.default_envs = wemos_d1_mini32_ota` (ota fw flash)
61 | - **ESP32 DEV MODULE - only**
62 | - `platformio.default_envs = esp32dev` (usb/serial fw flash) or `platformio.default_envs = esp32dev_ota` (ota fw flash)
63 |
64 | You may need to make more changes according to your needs (ntp syn/led status/ data to monitor ...).
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/Esp8266_max485_epever_rj45.md:
--------------------------------------------------------------------------------
1 | # Connect ESP8266 to EPEVER A/B Series ( + MAX485)
2 |
3 | Here the material involved:
4 | * [ESP8266 Dev Board](https://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20170114172938&SearchText=esp8266+mini)
5 | * [EPSolar/EPEver Tracer A/B-Series](https://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20170114172728&SearchText=tracer+mppt+rs485)
6 | * [RS485 UART Module](https://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20170114172807&SearchText=uart+rs485) (~~not the MAX485 chip!~~ - `@tekk:` I'm using [MAX485 cheapo module](../images/max485_module.jpg) and it works fine!)
7 | * An old ethernet cable with RJ45 connector you are happy to cut open
8 |
9 |
10 | ## ESP8266 <-> MAX485 module
11 |
12 | Required connections:
13 | - `DI` -> `D10` / `GPIO1` / `TX`
14 | - `RO` -> `D9` / `GPIO3` / `RX`
15 | - `DE` and `RE` are interconnected with a jumper and then connected to pin `D1` / `GPIO5`
16 | - `VCC` to `3.3V` on ESP8266
17 |
18 | 
19 |
20 | ## ESP8266 <-> MAX485 module + SOFTWARE SERIAL (since v3.0.7)
21 |
22 | Required connections:
23 | - `DI` -> `D2` / `GPIO4`
24 | - `RO` -> `D4` / `GPIO2`
25 | - `DE` and `RE` are interconnected with a jumper and then connected to pin `D1` / `GPIO5`
26 | - `VCC` to `3.3V` on ESP8266
27 |
28 | 
29 |
30 | ## MAX485 module <-> EPEVER CONTROLLER (RJ45)
31 |
32 | Cut open your ethernet cable and split out pin 4, 6, 8 (B, A, GND). Refer to [Tracer Modbus PDF](../docs/1733_modbus_protocol.pdf) for additional info.
33 |
34 | Connect wires as follows (make sure your cable matches the color schema below - otherwise refer to pin numbers only):
35 | - Ethernet green / pin `6` -> `A`
36 | - Ethernet blue / pin `4` -> `B`
37 | - Ethernet brown / pin `8` -> `GND` on module **and** ESP8266 `GND` pin
38 | - -> to prevent ground loops - **important!**
39 | - **DON' T** use pin `1` or `2` to feed the ESP8266 (they supply 7,5/5V - 50mA maximum)
40 |
41 | 
42 | 
43 |
44 |
--------------------------------------------------------------------------------
/docs/Sw_getting_started.md:
--------------------------------------------------------------------------------
1 | # SW getting started
2 |
3 | ## 1a. Flash a pre-built firmware
4 | Download the most recent version of the firmware https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases .
5 |
6 | Download the correct bif file depending on the board you're gonna use:
7 | - SolarTracerBlynk_3.x.x_esp32dev_FULL.bin - full bin file to use on a ESP32 (it includes all the bin needed eg: bootloader, firmware ...), use it on the very first setup.
8 | - SolarTracerBlynk_3.x.x_esp8266.bin - bin file to use on a ESP8266.
9 |
10 | Download [esp_flash_download_tool](https://www.espressif.com/en/support/download/other-tools).
11 |
12 | Start esp_flash_download_tool and select the correct board
13 |
14 | 
15 |
16 | Load the bin downloaded, set the address to 0x0000, and press START.
17 |
18 | 
19 |
20 | **You board is ready!**
21 |
22 | ## 1b. Build manually
23 | Download the most recent version of this project https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases
24 |
25 | Open you favorite IDE:
26 | - Arduino IDE: open *SolarTracerBlynk* folder, then open *SolarTracerBlynk.ino* .
27 | - Platformio: import the project using *platformio.ini* .
28 |
29 | ### Libraries to include in Arduino IDE
30 |
31 |
32 |
33 | * [ArduinoOTA](https://github.com/esp8266/Arduino/tree/master/libraries/ArduinoOTA)
34 | * [ModbusMaster](https://github.com/Bettapro/ModbusMaster)
35 | * [WiFiManager](https://github.com/tzapu/WiFiManager)
36 | * [ArduinoJson](https://github.com/bblanchon/ArduinoJson)
37 | * [PubSubClient](https://github.com/knolleary/pubsubclient) - MQTT ONLY
38 | * [Blynk Library](https://github.com/blynkkk/blynk-library) - BLYNK ONLY
39 | * [SimpleTimer](https://github.com/Bettapro/SimpleTimer) - MQTT ONLY
40 |
41 |
42 | ### Edit `config.h` library
43 | Open `SolarTracerBlynk\config.h`
44 |
45 | * Enter your WiFi credentials in `WIFI_SSID` and `WIFI_PASS`.
46 | * Send yourself the generated auth code from the mobile app
47 | * Paste your auth code into `BLYNK_AUTH`
48 |
49 | You can customize further more modifying config.h (eg. status LED, ntp time sync, blynk serve ...), each option is documented on the config.h file.
50 | Please refer to the notes written on it.
51 |
52 | ### Upload firmware
53 |
54 | Upload the sketch to your ESP8266 / ESP32, if you are using platformio you should edit `default_envs` accordingly (eg: *esp8266* to use a esp8266, *esp8266_ota* to update ESP8266 via OTA, *esp32dev* to use and ESP32, .... )
55 |
56 | **You board is ready!**
57 |
58 | ## 2. Mobile App
59 |
60 | Get the Mobile App ([iOS](https://itunes.apple.com/us/app/blynk-iot-for-arduino-rpi/id808760481?mt=8) & [Android](https://play.google.com/store/apps/details?id=cc.blynk&hl=en))
61 |
62 | Open the Blynk mobile app and create a new project by scanning the following QR code.
63 |
64 | Click PLAY on you mobile app, you should start receiving updates from your solar tracer!.
65 |
66 |
67 | ### Legacy app (v3) - SUGGESTED
68 | Current version of the app, complete overview of the solar charge controller. ENERGY REQUIRED: 14300
69 |
70 | 
71 |
72 | ### Legacy app (v2)
73 | Original version of the mobile app, shows a small set of data. ENERGY REQUIRED: 4400
74 |
75 | 
76 |
77 |
78 | ## 3. Wifi Configuration (SETUP MODE)
79 |
80 | You can configure your board via a web interface.
81 |
82 | Device will try to connect to your wifi network, if the connection fails, it will turn to AP mode and create a new wifi network.
83 | You can trigger the setup mode by putting in HIGH status (3.3v) pin 19 for few seconds(default value, check your config.h) just after you pressed the reset button.
84 |
85 | **NOTE:** ESP32 could switch to this mode using the hall sensor, just press the reset button and keep a magnet close to the board (please make sure this feature is enabled in your firmware)
86 |
87 | Default values:
88 | - WIFI SSID: SolarTracerAP
89 | - WIFI PASSWORD: admin1234
90 |
91 | Connect to this Wifi network, then open a web browser and go to http://192.168.4.1 .
92 |
93 | 
94 |
95 | Click on Configure and fill the form with your data.
96 |
97 | 
98 |
99 |
100 | ## 4.Update
101 | You can update your board just by compiling and flashing the new firmware as explained in point **1b** .
102 |
103 | Otherwise, you should trigger the setup mode manually and you the UPDATE button.
104 |
105 | Download the most recent version of the firmware https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases .
106 | - SolarTracerBlynk_3.x.x_esp32dev.bin - ESP32 only
107 | - SolarTracerBlynk_3.x.x_esp8266.bin - ESP8266 only
108 |
109 | Load the bin file into the form shown and press update.
110 |
111 |
--------------------------------------------------------------------------------
/docs/esp32.md:
--------------------------------------------------------------------------------
1 | # ESP32
2 |
3 | ## HOW TO FLASH
4 |
5 | You need:
6 | - one bin file, the firmware you want to install on your ESP32
7 | - [esp flasher tool](https://www.espressif.com/en/support/download/other-tools)
8 |
9 | **NOTE:** The board has to be prepared the first time you use it, by flashing a particular bin file as described [below](#first-time-setup). This has to be done only once, then, you can install the firmware via [COM](#com-firmware-upgrade) or [WEB](#wifi-firmware-upgrade).
10 |
11 | ---
12 | ### First time setup
13 |
14 | The very first time you process with the firmware flash, you must prepare your board.
15 |
16 | You need one additional bin file, you can download it [here](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases/download/v3.0.4/SolarTracerBlynk_3.0.4_esp32dev_FULL.bin)
17 | This bin file contains a complete image of the flash memory.
18 |
19 | Start esp_flash_download_tool and select the correct board (ESP32):
20 | 
21 |
22 | Load the bin "SolarTracerBlynk_3.0.4_esp32dev_FULL.bin", set the address to 0x0000.
23 | 
24 |
25 | Select the correct COM port and then press START, it should take some time the complete the process.
26 | Reboot board, you should see a new access point named "Solar tracer", if so, you are ready to upgrade to the REAL firmware.
27 |
28 | ---
29 | ### COM firmware upgrade
30 | You will upgrade your firmware using the COM serial port.
31 |
32 | Start esp_flash_download_tool and select the correct board (ESP32):
33 | 
34 |
35 | Load the bin set the address to 0x10000.
36 | 
37 |
38 | Select the correct COM port and then press START, it should take some time the complete the process.
39 | Reboot board, upgrade completed!
40 |
41 | ---
42 | ### WIFI firmware upgrade
43 | You will upgrade your firmware using the web interface.
44 |
45 | Start your ESP32 in configuration mode, the board will create an access point (normally named "Solar tracer").
46 |
47 | Connect to the AP, open a new tab on your web browser and go to http://192.168.4.1 .
48 |
49 | Click INFO.
50 | 
51 |
52 | Click UPDATE.
53 | 
54 |
55 | Load the bin file and start the update.
56 | 
57 |
58 | Reboot board, upgrade completed!
--------------------------------------------------------------------------------
/docs/esp8266.md:
--------------------------------------------------------------------------------
1 | # ESP8266
2 |
3 | ## HOW TO FLASH
4 |
5 | You need:
6 | - one bin file, the firmware you want to install on your ESP8266
7 | - [esp flasher tool](https://www.espressif.com/en/support/download/other-tools)
8 |
9 | ---
10 | ### COM firmware upgrade
11 | You will upgrade your firmware using the COM serial port.
12 |
13 | Start esp_flash_download_tool and select the correct board (ESP8266):
14 | 
15 |
16 | Load the bin set the address to 0x0.
17 | 
18 |
19 | Select the correct COM port and then press START, it should take some time the complete the process.
20 | Reboot board, upgrade completed!
21 |
22 | ---
23 | ### WIFI firmware upgrade
24 | You will upgrade your firmware using the web interface.
25 |
26 | Start your ESP8266 in configuration mode, the board will create an access point (normally named "Solar tracer").
27 |
28 | Connect to the AP, open a new tab on your web browser and go to http://192.168.4.1 .
29 |
30 | Click INFO.
31 | 
32 |
33 | Click UPDATE.
34 | 
35 |
36 | Load the bin file and start the update.
37 | 
38 |
39 | Reboot board, upgrade completed!
--------------------------------------------------------------------------------
/docs/sw_getting_started_blynk_iot.md:
--------------------------------------------------------------------------------
1 | # SW getting started Blynk LEGACY
2 |
3 |
4 | Blynk IOT requires *TEMPLATE_ID* to be defined at compilation time, for this reason, there's no pre-build firmware for it.
5 |
6 | Download/Clone this project, then, using Arduino IDE or VSC(Platformio) check the file named *config.h*.
7 |
8 | - Make sure `#define USE_BLYNK` is enabled/un-commented
9 | - Make sure `#define USE_BLYNK_2` is enabled/un-commented
10 | - Make sure `#define USE_MQTT` is disabled/commented
11 | - Insert your `BLYNK_TEMPLATE_ID` [blynk docs](https://docs.blynk.io/en/getting-started/activating-devices/manual-device-activation#step-2-getting-template-id)
12 | - Insert your `BLYNK_DEVICE_NAME`
13 | - Insert your `BLYNK_AUTH` [blynk docs](https://docs.blynk.io/en/getting-started/activating-devices/manual-device-activation#step-3-getting-auth-token)
14 |
15 |
16 | Compile the sketch and upload to your ESP module.
17 |
--------------------------------------------------------------------------------
/docs/sw_getting_started_blynk_legacy.md:
--------------------------------------------------------------------------------
1 | # SW getting started Blynk LEGACY
2 |
3 |
4 | *!This sync should be consider as deprecated, as blynk IOT replaced it, you must have a working blynk (local) server!*
5 |
6 | Download the latest version of this firmware from [here](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases/latest).
7 | Choose the correct bin file according to your board (esp8266, esp32):
8 | - *SolarTracerBlynk_xxxx_esp32dev_blynk.bin*: ESP32 only
9 | - *SolarTracerBlynk_xxxx_esp8266_blynk.bin*: ESP8266 only
10 |
11 | Flash the firmware on your EPS8266/ESP32, more information how to flash firmware are available [ESP32](esp32.md#how-to-flash) [ESP8266](esp8266.md#how-to-flash)
12 |
13 | ## Mobile App
14 |
15 | Get the Mobile App ([Android](https://www.apkmirror.com/apk/blynk-inc/blynk-legacy/blynk-legacy-2-27-34-release/blynk-legacy-2-27-34-android-apk-download/))
16 |
17 | Open the Blynk mobile app and create a new project by scanning one of the following QR code.
18 |
19 | ### Legacy app (v3) - SUGGESTED
20 | Current version of the app, complete overview of the solar charge controller. ENERGY REQUIRED: 14300
21 |
22 | 
23 |
24 | ### Legacy app (v2)
25 | Original version of the mobile app, shows a small set of data. ENERGY REQUIRED: 4400
26 |
27 | 
28 |
29 | ## Back to ESP board
30 |
31 | Boot the ESP in Configuration mode and double check all the settings, double check the mqtt section and make sure that mqtt settings are correct.
32 | 
33 |
34 | That's all! your mobile app will get updated with the data from your SCC.
35 |
36 | ## Sample screenshot
37 |
38 | 
39 | 
40 | 
41 | 
42 |
--------------------------------------------------------------------------------
/docs/sw_getting_started_ha.md:
--------------------------------------------------------------------------------
1 | # SW getting started Home Assistant
2 |
3 | *!You must have a working mqtt broker and also the mqtt integration in you home assistant integration!*
4 |
5 | Download the latest version of this firmware from [here](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases/latest).
6 | Choose the correct bin file according to your board (esp8266, esp32):
7 | - *SolarTracerBlynk_xxxx_esp32dev_mqttHA.bin*: ESP32 only
8 | - *SolarTracerBlynk_xxxx_esp8266_mqttHA.bin*: ESP8266 only
9 |
10 | Flash the firmware on your EPS8266/ESP32, more information how to flash firmware are available [ESP32](esp32.md#how-to-flash) [ESP8266](esp8266.md#how-to-flash)
11 |
12 |
13 | Boot the ESP in Configuration mode and double check all the settings, double check the mqtt section and make sure that settings are correct.
14 | 
15 |
16 | If everything is working your mqtt integration will discover and configure the solar tracer.
17 | 
18 |
19 | 
20 |
21 | You can now proceed and display all the data you need on your widgets (and even on the Energy monitoring page!)
22 | 
23 | 
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/docs/sw_getting_started_mqtt.md:
--------------------------------------------------------------------------------
1 | # SW getting started MQTT
2 |
3 | *!You must have a working mqtt broker!*
4 |
5 | Download the latest version of this firmware from [here](https://github.com/Bettapro/Solar-Tracer-Blynk-V3/releases/latest).
6 | Choose the correct bin file according to your board (esp8266, esp32):
7 | - *SolarTracerBlynk_xxxx_esp32dev_mqtt.bin*: ESP32 only
8 | - *SolarTracerBlynk_xxxx_esp8266_mqtt.bin*: ESP8266 only
9 |
10 | Flash the firmware on your EPS8266/ESP32, more information how to flash firmware are available [ESP32](esp32.md#how-to-flash) [ESP8266](esp8266.md#how-to-flash)
11 |
12 |
13 | Boot the ESP in Configuration mode and double check all the settings, double check the MQTT section and make sure that settings are correct.
14 | 
15 |
16 | On you MQTT broker you will find a new main topic named *solarTracer/values/* containing a topic for each value for your controller.
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/images/blynk-app-qr-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/blynk-app-qr-code.png
--------------------------------------------------------------------------------
/images/blynk-app-qr-code_v3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/blynk-app-qr-code_v3.png
--------------------------------------------------------------------------------
/images/blynk-app-qr-code_v3_blynkcloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/blynk-app-qr-code_v3_blynkcloud.png
--------------------------------------------------------------------------------
/images/epever_rj45_specs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/epever_rj45_specs.png
--------------------------------------------------------------------------------
/images/esp32_d1_mini_pins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp32_d1_mini_pins.png
--------------------------------------------------------------------------------
/images/esp32_wroom_38_pin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp32_wroom_38_pin.jpg
--------------------------------------------------------------------------------
/images/esp8266_bin_flash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp8266_bin_flash.png
--------------------------------------------------------------------------------
/images/esp8266_hw_serial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp8266_hw_serial.png
--------------------------------------------------------------------------------
/images/esp8266_sw_serial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp8266_sw_serial.png
--------------------------------------------------------------------------------
/images/esp_tool_bin_flash_10000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp_tool_bin_flash_10000.png
--------------------------------------------------------------------------------
/images/esp_tool_bin_flash_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp_tool_bin_flash_new.png
--------------------------------------------------------------------------------
/images/esp_tool_board_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/esp_tool_board_select.png
--------------------------------------------------------------------------------
/images/eth_t568b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/eth_t568b.png
--------------------------------------------------------------------------------
/images/max485_module.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/max485_module.jpg
--------------------------------------------------------------------------------
/images/mppt-triton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/mppt-triton.png
--------------------------------------------------------------------------------
/images/mppt-xtra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/mppt-xtra.png
--------------------------------------------------------------------------------
/images/nodemcu_pins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/nodemcu_pins.png
--------------------------------------------------------------------------------
/images/schematic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/schematic.png
--------------------------------------------------------------------------------
/images/screenshot-blynk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/screenshot-blynk.png
--------------------------------------------------------------------------------
/images/screenshot-blynk_v3_battery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/screenshot-blynk_v3_battery.png
--------------------------------------------------------------------------------
/images/screenshot-blynk_v3_pv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/screenshot-blynk_v3_pv.png
--------------------------------------------------------------------------------
/images/screenshot-blynk_v3_realtime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/screenshot-blynk_v3_realtime.png
--------------------------------------------------------------------------------
/images/screenshot-blynk_v3_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/screenshot-blynk_v3_settings.png
--------------------------------------------------------------------------------
/images/tracer-a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/tracer-a.png
--------------------------------------------------------------------------------
/images/tracer-b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/tracer-b.png
--------------------------------------------------------------------------------
/images/wifi_manager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager.png
--------------------------------------------------------------------------------
/images/wifi_manager_config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager_config.png
--------------------------------------------------------------------------------
/images/wifi_manager_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager_home.png
--------------------------------------------------------------------------------
/images/wifi_manager_mqtt_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager_mqtt_settings.png
--------------------------------------------------------------------------------
/images/wifi_manager_update.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager_update.png
--------------------------------------------------------------------------------
/images/wifi_manager_update_upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bettapro/Solar-Tracer-Blynk-V3/eb5d45b5a7472bf3e52c6d0c939759880faa9249/images/wifi_manager_update_upload.png
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [platformio]
12 | default_envs = esp32dev
13 | src_dir = SolarTracerBlynk
14 |
15 | [env]
16 | framework = arduino
17 | monitor_speed = 115200
18 | lib_deps =
19 | https://github.com/blynkkk/blynk-library.git#v1.1.0
20 | https://github.com/Bettapro/ModbusMaster.git
21 | https://github.com/schinken/SimpleTimer.git
22 | https://github.com/tzapu/WiFiManager.git#v2.0.17
23 | https://github.com/bblanchon/ArduinoJson.git
24 | knolleary/PubSubClient@^2.8
25 | https://github.com/dawidchyrzynski/arduino-home-assistant.git#2.1.0
26 | https://github.com/Bettapro/LinearSensHallCurrent.git
27 | https://github.com/RobTillaart/ADS1X15.git
28 | https://github.com/khoih-prog/ESP_DoubleResetDetector.git
29 | https://github.com/plerup/espsoftwareserial.git#8.2.0
30 | #build_type = debug
31 | build_flags =
32 | # stop first error
33 | -fmax-errors=1
34 | -DCORE_DEBUG_LEVEL=0
35 | #lib_ldf_mode = deep+
36 |
37 | [extra]
38 | ota_hostname=SOLAR-MODBUS.local
39 | ota_password=admin
40 |
41 | [env:esp32dev]
42 | platform = espressif32
43 | board = esp32dev
44 | upload_speed = 460800
45 | monitor_filters = esp32_exception_decoder
46 | # OTA
47 | #upload_protocol = espota
48 | #upload_port = ${extra.ota_hostname}
49 | #upload_flags = --auth=${extra.ota_password}
50 |
51 |
52 | [env:esp8266]
53 | platform = espressif8266
54 | board = esp12e
55 | monitor_filters = esp8266_exception_decoder
56 | # OTA
57 | #upload_protocol = espota
58 | #upload_port = ${extra.ota_hostname}
59 | #upload_flags = --auth=${extra.ota_password}
60 |
--------------------------------------------------------------------------------
/script/binDeploy.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | SETLOCAL EnableDelayedExpansion
3 |
4 | rmdir "binFiles" /S /Q
5 |
6 | set VERSION_number="3.0.9"
7 |
8 | set esp32_build_flag_base=-DUSE_HALL_AP_CONFIGURATION_TRIGGER
9 | set esp32_build_flag_minimum=-DUSE_NOT_BLYNK -DSTARTUP_BUILD
10 | set esp8266_build_flag_base=
11 |
12 | set buildRun[0].env=esp32dev
13 | set buildRun[0].fileSuffix=blynk
14 | set buildRun[0].buildFlags=%esp32_build_flag_base%
15 |
16 | set buildRun[1].env=esp32dev
17 | set buildRun[1].fileSuffix=mqtt
18 | set buildRun[1].buildFlags=%esp32_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT
19 |
20 | set buildRun[2].env=esp32dev
21 | set buildRun[2].fileSuffix=mqttHA
22 | set buildRun[2].buildFlags=%esp32_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT -DUSE_MQTT_HOME_ASSISTANT
23 |
24 | set buildRun[3].env=esp8266
25 | set buildRun[3].fileSuffix=blynk
26 | set buildRun[3].buildFlags=%esp8266_build_flag_base%
27 |
28 | set buildRun[4].env=esp8266
29 | set buildRun[4].fileSuffix=mqtt
30 | set buildRun[4].buildFlags=%esp8266_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT
31 |
32 | set buildRun[5].env=esp8266
33 | set buildRun[5].fileSuffix=mqttHA
34 | set buildRun[5].buildFlags=%esp8266_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT -DUSE_MQTT_HOME_ASSISTANT
35 |
36 | set buildRun[6].env=esp8266
37 | set buildRun[6].fileSuffix=blynk_swser
38 | set buildRun[6].buildFlags=%esp8266_build_flag_base% -DUSE_SOFTWARE_SERIAL
39 |
40 | set buildRun[7].env=esp8266
41 | set buildRun[7].fileSuffix=mqtt_swser
42 | set buildRun[7].buildFlags=%esp8266_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT -DUSE_SOFTWARE_SERIAL
43 |
44 | set buildRun[8].env=esp8266
45 | set buildRun[8].fileSuffix=mqttHA_swser
46 | set buildRun[8].buildFlags=%esp8266_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT -DUSE_MQTT_HOME_ASSISTANT -DUSE_SOFTWARE_SERIAL
47 |
48 |
49 | set esp32devEnv=esp32dev
50 | call set PLATFORMIO_BUILD_FLAGS=%esp32_build_flag_minimum%
51 | call %userprofile%\.platformio\penv\Scripts\pio.exe run -e %esp32devEnv%
52 | echo F| xcopy ".pio\build\%esp32devEnv%\firmware.bin" "binFiles\%esp32devEnv%\firmware.bin" /v /f /y
53 | echo F| xcopy ".pio\build\%esp32devEnv%\partitions.bin" "binFiles\%esp32devEnv%\partitions.bin" /v /f /y
54 | echo F| xcopy ".pio\build\%esp32devEnv%\bootloader.bin" "binFiles\%esp32devEnv%\bootloader.bin" /v /f /y
55 | echo F| xcopy "%userprofile%\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin" "binFiles\%esp32devEnv%\boot_app0.bin" /v /f /y
56 | python script\esp32_binary_merger\merge_bin_esp.py --output_folder binFiles\ --output_name "SolarTracerBlynk_%VERSION_NUMBER%_%esp32devEnv%_0x0.bin" --bin_path "binFiles\%esp32devEnv%\bootloader.bin" "binFiles\%esp32devEnv%\partitions.bin" "binFiles\%esp32devEnv%\boot_app0.bin" "binFiles\%esp32devEnv%\firmware.bin" --bin_address 0x1000 0x8000 0xe000 0x10000
57 |
58 | set "x=0"
59 |
60 | :SymLoop
61 | if defined buildRun[%x%].env (
62 | set currEnv=%%buildRun[%x%].env%%
63 | set currFileSuffix=%%buildRun[%x%].fileSuffix%%
64 | set currBuildFlags=%%buildRun[%x%].buildFlags%%
65 | call echo "ENV !currEnv! - file !currFileSuffix! - flag !currBuildFlags!"
66 |
67 | call set PLATFORMIO_BUILD_FLAGS=!currBuildFlags!
68 | rem call set PLATFORMIO_DEFAULT_ENVS=!currEnv!
69 | call %userprofile%\.platformio\penv\Scripts\pio.exe run -e !currEnv!
70 |
71 | call echo F| call xcopy ".pio\build\!currEnv!\firmware.bin" "binFiles\SolarTracerBlynk_%VERSION_NUMBER%_!currEnv!_!currFileSuffix!.bin" /v /f /y
72 |
73 | set /a "x+=1"
74 | GOTO :SymLoop
75 | )
76 |
--------------------------------------------------------------------------------
/script/binTest.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | SETLOCAL EnableDelayedExpansion
3 |
4 | rmdir "binFiles" /S /Q
5 |
6 | set esp32_build_flag_base=-DUSE_HALL_AP_CONFIGURATION_TRIGGER
7 | set esp8266_build_flag_base=
8 |
9 |
10 | set buildRun[0].env=esp32dev
11 | set buildRun[0].fileSuffix=run
12 | set buildRun[0].buildFlags=%esp32_build_flag_base% -DUSE_NOT_BLYNK -DUSE_MQTT -DUSE_MQTT_HOME_ASSISTANT -DUSE_EXTERNAL_HEAVY_LOAD_CURRENT_METER -DUSE_HALL_AP_CONFIGURATION_TRIGGER
13 |
14 |
15 | set "x=0"
16 |
17 | :SymLoop
18 | if defined buildRun[%x%].env (
19 | set currEnv=%%buildRun[%x%].env%%
20 | set currFileSuffix=%%buildRun[%x%].fileSuffix%%
21 | set currBuildFlags=%%buildRun[%x%].buildFlags%%
22 | call echo "ENV !currEnv! - file !currFileSuffix! - flag !currBuildFlags!"
23 |
24 | call set PLATFORMIO_BUILD_FLAGS=!currBuildFlags!
25 | rem call set PLATFORMIO_DEFAULT_ENVS=!currEnv!
26 | call %userprofile%\.platformio\penv\Scripts\pio.exe run -e !currEnv!
27 | call echo F| call xcopy ".pio\build\!currEnv!\firmware.bin" "binFiles\SolarTracerBlynk_!currEnv!_!currFileSuffix!.bin" /v /f /y
28 |
29 | set /a "x+=1"
30 | GOTO :SymLoop
31 | )
32 |
--------------------------------------------------------------------------------
/script/esp32_binary_merger/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Tony Martinet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/script/esp32_binary_merger/merge_bin_esp.py:
--------------------------------------------------------------------------------
1 | import os
2 | import argparse
3 |
4 | class bin():
5 | def __init__(self, file_path, addr):
6 | self.file_path = file_path
7 | self.file_name = os.path.basename(file_path)
8 | self.addr = addr
9 | self.size = self.get_size()
10 |
11 | def get_size(self):
12 | return int(os.path.getsize(self.file_path))
13 |
14 | class multiple_bin():
15 | def __init__(self, name, output_folder):
16 | self.name = name
17 | self.output_folder = output_folder
18 | try:
19 | os.makedirs(os.path.realpath(self.output_folder))
20 | except:
21 | pass
22 | self.output_path = os.path.realpath(os.path.join(self.output_folder,self.name))
23 | self.bin_array = []
24 |
25 | def add_bin(self, file_path, addr):
26 | self.bin_array.append(bin(file_path, addr))
27 |
28 | def sort_bin(self):
29 | swapped = True
30 | while swapped:
31 | swapped = False
32 | for i in range(len(self.bin_array) - 1):
33 | if self.bin_array[i].addr > self.bin_array[i + 1].addr:
34 | self.bin_array[i], self.bin_array[i + 1] = self.bin_array[i + 1], self.bin_array[i]
35 | swapped = True
36 |
37 | def add_bin_to_other_bin(self, previous, binary):
38 | with open(self.output_path, "ab") as output_file:
39 | output_file.write( b'\xff' * (binary.addr-previous))
40 | print ("Add %s from 0x%x to 0x%x (0x%x)"%(binary.file_name, binary.addr, binary.addr+binary.size, binary.size))
41 | with open(self.output_path, "ab") as output_file, open(binary.file_path, "rb") as bin_file:
42 | output_file.write(bin_file.read())
43 | return binary.addr+binary.size
44 |
45 | def create_bin(self):
46 | new_start = 0
47 | open(self.output_path, "wb").close
48 | for b in self.bin_array:
49 | new_start = self.add_bin_to_other_bin(new_start, b)
50 |
51 | def check_if_possible(self):
52 | for i in range(1, len(self.bin_array)):
53 | if(self.bin_array[i].addr < (self.bin_array[i-1].addr+self.bin_array[i-1].size)):
54 | print (self.bin_array[i].addr, (self.bin_array[i-1].addr+self.bin_array[i-1].size))
55 | raise Exception("Not possible to create this bin, overlapping between %s and %s"%(self.bin_array[i].file_name, self.bin_array[i-1].file_name))
56 |
57 | def main():
58 | parser = argparse.ArgumentParser(description='Script to merge *.bin file at different position')
59 | parser.add_argument(
60 | '--output_name',
61 | help = 'Output file name', default = "output.bin")
62 | parser.add_argument(
63 | '--output_folder', default = "output",
64 | help = 'Output folder path')
65 | parser.add_argument(
66 | '--input_folder', default = "",
67 | help = 'Input folder path')
68 | parser.add_argument(
69 | '--bin_path',nargs='+',required=True,
70 | help = 'List of bin path, same order as bin_address (space separated)')
71 | parser.add_argument(
72 | '--bin_address',nargs='+',type=lambda x: int(x,0),required=True,
73 | help = 'List of addr, same order as bin_path (space separated)')
74 | parser.add_argument
75 | args = parser.parse_args()
76 | mb = multiple_bin(args.output_name, args.output_folder)
77 | for path,address in zip(args.bin_path, args.bin_address):
78 | mb.add_bin(os.path.join(args.input_folder, path), address)
79 | mb.sort_bin()
80 | mb.check_if_possible()
81 | mb.create_bin()
82 | print ("%s generated with success ! (size %u)"%(args.output_name, int(os.path.getsize(mb.output_path))))
83 |
84 | if __name__ == "__main__":
85 | exit(main())
86 |
--------------------------------------------------------------------------------