Compare commits
124 Commits
v1.0.0-bet
...
v1.1.0-bet
Author | SHA1 | Date | |
---|---|---|---|
a5f7f0f8a4 | |||
7826e56d8a | |||
353d6d77e1 | |||
437873489e | |||
e34e73fae2 | |||
69a4c5607c | |||
d980fdae1a | |||
272e349375 | |||
34d46ef768 | |||
588ff2d1e0 | |||
5d1811d240 | |||
85e602d29b | |||
8ee882c522 | |||
51e7ee6867 | |||
70858ef841 | |||
83bd80ba28 | |||
d33576b2df | |||
5c9525c0c5 | |||
ad8704fc20 | |||
f1c1958f88 | |||
e5394113e4 | |||
6d4e713da8 | |||
36a858af2d | |||
77d2c15e39 | |||
9df072cc78 | |||
bedbda4662 | |||
76702dfc95 | |||
789eb32aa8 | |||
c0db4dd8da | |||
cb677e10ae | |||
b4c7566a08 | |||
70f391fa1a | |||
542beffe4c | |||
1a42bd332f | |||
c16108352c | |||
4b5df951de | |||
6bbb904427 | |||
66c6c44a38 | |||
e2fee1fb35 | |||
ae595ff50c | |||
50257e2805 | |||
c503ad88a9 | |||
5b7290c991 | |||
f7c43dad55 | |||
95654bac66 | |||
ffa7ac294d | |||
79a3274286 | |||
0c936cfb88 | |||
f366b78cb3 | |||
702eba515d | |||
a992e90bc3 | |||
8b4b89ba20 | |||
361d287a22 | |||
8e36453b13 | |||
ded06d15a1 | |||
67f60b817e | |||
6373923506 | |||
bf3a3de207 | |||
e6fd027d51 | |||
0cba58a0dd | |||
fd71a2d428 | |||
907e33ce2d | |||
18ba0b225f | |||
2a9472b453 | |||
0b23a0f69e | |||
9cba1db4e5 | |||
9d5d6a5a58 | |||
58fe408803 | |||
c2ae70bb1a | |||
7a3b048d80 | |||
ad3fbb7270 | |||
02df656343 | |||
f73f63fec3 | |||
bb09072520 | |||
5875ee83d8 | |||
6185d67d12 | |||
00f82f5c37 | |||
59ad285bb8 | |||
bc09d617fc | |||
a71f54b99f | |||
152ff89bf6 | |||
d9fb8291f4 | |||
030746e982 | |||
d4260c6380 | |||
50725407ea | |||
b4bac17114 | |||
cb433a4a91 | |||
095c1dc6a7 | |||
43e2d165f5 | |||
fca7294b61 | |||
390c0882d1 | |||
5e9e705b96 | |||
d67f72f123 | |||
f09aadaf66 | |||
c68f67a558 | |||
299e915bd2 | |||
06a1541090 | |||
a8b87140b2 | |||
1d738a14dd | |||
4e37b9329c | |||
9712e13c78 | |||
1b11e49883 | |||
cc6fecbdf8 | |||
971b210438 | |||
7b2a99c8a3 | |||
d6f8ff67a3 | |||
f173b205ae | |||
e0312ab3c5 | |||
7678bb1f43 | |||
403ed1d350 | |||
ced4c9f8fc | |||
7e1862390e | |||
a3cd3217ab | |||
7ede9a6d19 | |||
f27e8ac79f | |||
7874f1bcf2 | |||
9f87bf5432 | |||
5bbb7ebfaa | |||
328e7e71ae | |||
2912749f19 | |||
43b6881477 | |||
3a4cfb1ca5 | |||
a40c3528d4 | |||
87036d56e5 |
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. ...
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Software:**
|
||||
- Platform (esp8266, esp32)
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
17
.github/stale.yaml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- on-hold
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
8
.github/workflows/doc-build.yaml
vendored
@ -16,8 +16,12 @@ jobs:
|
||||
with:
|
||||
docs-folder: "src_docs/"
|
||||
pre-build-command: |
|
||||
pip install sphinx_rtd_theme
|
||||
pip install furo
|
||||
pip install --upgrade pip
|
||||
pip install sphinx==4.3.2
|
||||
pip install docutils==0.16
|
||||
pip install pygments==2.11.1
|
||||
pip install furo==2022.1.2
|
||||
pip list
|
||||
build-command: "sphinx-build -b html ./source ../docs"
|
||||
|
||||
- name: Commit documentation changes
|
||||
|
19
.github/workflows/pre-commit.yaml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: pre-commit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- name: clang format support
|
||||
run: |
|
||||
sudo apt install clang-format cppcheck
|
||||
- uses: pre-commit/action@v2.0.3
|
@ -4,7 +4,10 @@ repos:
|
||||
hooks:
|
||||
- id: clang-format
|
||||
files: ^src/
|
||||
exclude: 'lib/'
|
||||
- id: cpplint
|
||||
files: ^src/
|
||||
exclude: 'lib/'
|
||||
- id: cppcheck
|
||||
files: ^src/
|
||||
exclude: 'lib/'
|
||||
|
35
CONTRIBUTING.md
Normal file
@ -0,0 +1,35 @@
|
||||
## How to contribute to GravityMon
|
||||
|
||||
#### **Did you find a bug?**
|
||||
|
||||
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/mp-se/gravitymon/issues). Dont forget to look under closed issues. There might be a fix but not yet included in the released version.
|
||||
|
||||
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/mp-se/gravitymon/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, Use the function on the device to extract configuration and device information (does not contain any sensitive data). This can help to pinpoint the issue.
|
||||
|
||||
#### **Did you write a patch that fixes a bug?**
|
||||
|
||||
* Open a new GitHub pull request with the patch.
|
||||
|
||||
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
||||
|
||||
* Before submitting, please use `pre-commit` to validate that your code contribution complies with the formatting standards for C++ and C.
|
||||
|
||||
* Check the contribution section under the documentation for additional information.
|
||||
|
||||
#### **Do you intend to add a new feature or change an existing one?**
|
||||
|
||||
* Suggest your change in the [Discussion forums](https://github.com/mp-se/gravitymon/discussions) and start writing code.
|
||||
|
||||
* Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
|
||||
|
||||
#### **Do you have questions about the source software?**
|
||||
|
||||
* Start a discussion in the [Discussion forums](https://github.com/mp-se/gravitymon/discussions) and start writing code.
|
||||
|
||||
#### **Do you want to contribute to the documentation?**
|
||||
|
||||
* Open a new GitHub pull request with the updated documentation changes.
|
||||
|
||||
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
||||
|
||||
Thanks!
|
15
README.md
@ -12,9 +12,11 @@ GravityMon is a replacement firmware for the iSpindle firmware. It's 100% compat
|
||||
|
||||
Now also works with ESP32 (use ESP32 d1 mini which is compatible with ESP8266)
|
||||
|
||||
Installation can be made using https://www.brewflasher.com
|
||||
Installation can be made using https://www.brewflasher.com or https://web.brewflasher.com
|
||||
|
||||
Note! If its being flagged as malware, try the older version.
|
||||
The documenation can be found here: https://mp-se.github.io/gravitymon/index.html
|
||||
|
||||
Note! If Brewflasher being flagged as malware by your antivirus software, try the web version.
|
||||
|
||||
The main differences:
|
||||
---------------------
|
||||
@ -23,17 +25,14 @@ The main differences:
|
||||
* Efficient software, long lifespan (+45 days with 5min update frequencey)
|
||||
* Send data to multiple endpoints (http-post, http-get, influxdb v2, mqtt)
|
||||
* Instructions for service such as; Brewfather, Fermentrack, Ubidots, Home Assistant, Brewers Friend, Brewspy, Thingspeak, Blynk.
|
||||
* SSL support in standard HTTP and MQTT connections.
|
||||
* SSL support for all remote endpoints
|
||||
* ESP32 support with Bluetooth push
|
||||
* Customize data format to be pushed
|
||||
* Automatic temperature adjustment of gravity when enabled
|
||||
* Use the temperature sensor in gyro instead of DS18B20
|
||||
* Built in function to create gravity formulas, no need for additional software, just enter tilt/gravity.
|
||||
* Visual graph showing how gravity formula will be interpreted
|
||||
* OTA support
|
||||
* Built in performance measurements (used to optimise code)
|
||||
* REST API for scripting
|
||||
* OTA support or firmware upload via web interface
|
||||
* REST API for scripting
|
||||
|
||||
No code has been reused from the iSpindle project.
|
||||
|
||||
The documenation can be found here: https://mp-se.github.io/gravitymon/index.html
|
||||
|
BIN
bin/firmware.bin
@ -1 +1 @@
|
||||
{ "project":"gravmon", "version":"1.0.0", "html": [ ] }
|
||||
{ "project":"gravmon", "version":"1.1.0", "html": [ ] }
|
@ -97,7 +97,8 @@
|
||||
<div class="row mb-3">
|
||||
<label for="angle1" class="col-sm-1 col-form-label">1.</label>
|
||||
<div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a1" id="a1" data-bs-toggle="tooltip" title="Enter the angle for the gravity. Zero value will be ignored"></div>
|
||||
<div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g1" id="g1" data-bs-toggle="tooltip" title="Enter the gravity for the angle."></div>
|
||||
<input hidden type="number" name="g1" id="g1">
|
||||
<div class="col-sm-4"><input disabled type="number" class="form-control" name="g1a" id="g1a" data-bs-toggle="tooltip" title="The first value is reserved for water gravity."></div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
@ -369,6 +370,7 @@
|
||||
if(isPlato()) {
|
||||
$("#gravity-header").text("Gravity (Plato):");
|
||||
$("#g1").val( parseFloat(cfg["g1"]).toFixed(1) );
|
||||
$("#g1a").val( "0.0" );
|
||||
$("#g2").val( parseFloat(cfg["g2"]).toFixed(1) );
|
||||
$("#g3").val( parseFloat(cfg["g3"]).toFixed(1) );
|
||||
$("#g4").val( parseFloat(cfg["g4"]).toFixed(1) );
|
||||
@ -381,6 +383,7 @@
|
||||
} else {
|
||||
$("#gravity-header").text("Gravity (SG):");
|
||||
$("#g1").val( parseFloat(cfg["g1"]).toFixed(4) );
|
||||
$("#g1a").val( "1.0000" );
|
||||
$("#g2").val( parseFloat(cfg["g2"]).toFixed(4) );
|
||||
$("#g3").val( parseFloat(cfg["g3"]).toFixed(4) );
|
||||
$("#g4").val( parseFloat(cfg["g4"]).toFixed(4) );
|
||||
|
192
html/config.htm
@ -105,15 +105,15 @@
|
||||
<input type="text" name="id" id="id1" hidden>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="mdns" class="col-sm-2 col-form-label">Device name:</label>
|
||||
<label for="mdns" class="col-sm-2 col-form-label">Device name</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" maxlength="12" class="form-control" name="mdns" id="mdns" data-bs-toggle="tooltip" title="Name of the device. Will be used for identifying the device when pushing data and on the local network.">
|
||||
<input type="text" maxlength="63" class="form-control" name="mdns" id="mdns" placeholder="gravmon" data-bs-toggle="tooltip" title="Name of the device. Will be used for identifying the device when pushing data and on the local network.">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<fieldset class="form-group row">
|
||||
<legend class="col-form-label col-sm-2 float-sm-left pt-0">Temperature Format:</legend>
|
||||
<legend class="col-form-label col-sm-2 float-sm-left pt-0">Temperature Format</legend>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="temp-format" id="temp-format-c" value="C" checked data-bs-toggle="tooltip" title="Temperature format used with displaying data">
|
||||
@ -121,16 +121,16 @@
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="temp-format" id="temp-format-f" value="F" data-bs-toggle="tooltip" title="Temperature format used with displaying data">
|
||||
<label class="form-check-label" for="temp-format-f">Farenheight</label>
|
||||
<label class="form-check-label" for="temp-format-f">Fahrenheit</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="sleep-interval" class="col-sm-2 col-form-label">Interval (seconds):</label>
|
||||
<label for="sleep-interval" class="col-sm-2 col-form-label">Interval (seconds)</label>
|
||||
<div class="col-sm-2">
|
||||
<input type="number" min="10" max="3600" class="form-control" name="sleep-interval" id="sleep-interval" data-bs-toggle="tooltip" title="The number of seconds that the device will sleep between gravity readings. Recommended value is 300s">
|
||||
<input type="number" min="10" max="3600" class="form-control" name="sleep-interval" id="sleep-interval" placeholder="300" data-bs-toggle="tooltip" title="The number of seconds that the device will sleep between gravity readings. Recommended value is 300s">
|
||||
</div>
|
||||
<label for="sleep-interval" class="col-sm-4 col-form-label" id="sleep-interval-info"></label>
|
||||
</div>
|
||||
@ -145,7 +145,7 @@
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="calibrate-btn" class="col-sm-2 col-form-label">Current calibration:</label>
|
||||
<label for="calibrate-btn" class="col-sm-2 col-form-label">Current calibration</label>
|
||||
<label for="calibrate-btn" class="col-sm-2 col-form-label" id="gyro-calibration-data">Loading...</label>
|
||||
<label for="gyro-calibration-data" class="col-sm-2 col-form-label" id="angle">Loading...</label>
|
||||
<div class="col-sm-8 offset-sm-2">
|
||||
@ -174,7 +174,7 @@
|
||||
<input type="text" name="http-push2-h2" id="http-push2-h2" hidden>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="http-push" class="col-sm-2 col-form-label">HTTP 1 (POST):</label>
|
||||
<label for="http-push" class="col-sm-2 col-form-label">HTTP 1 (POST)</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push" id="http-push" placeholder="http://www.internet.com/path" data-bs-toggle="tooltip" title="URL to push target, use format http://servername.com/resource (Supports http and https)">
|
||||
</div>
|
||||
@ -184,7 +184,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="http-push2" class="col-sm-2 col-form-label">HTTP 2 (POST):</label>
|
||||
<label for="http-push2" class="col-sm-2 col-form-label">HTTP 2 (POST)</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push2" id="http-push2" placeholder="http://www.internet.com/path" data-bs-toggle="tooltip" title="URL to push target, use format http://servername.com/resource (Supports http and https)">
|
||||
</div>
|
||||
@ -194,21 +194,21 @@
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="token" class="col-sm-2 col-form-label">Token:</label>
|
||||
<label for="token" class="col-sm-2 col-form-label">Token</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="50" class="form-control" name="token" id="token" data-bs-toggle="tooltip" title="Token can be used in the format template as a variable, some services use this for authentication">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="http-push3" class="col-sm-2 col-form-label">HTTP 3 (GET):</label>
|
||||
<label for="http-push3" class="col-sm-2 col-form-label">HTTP 3 (GET)</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push3" id="http-push3" placeholder="http://www.internet.com/path" data-bs-toggle="tooltip" title="URL to push target, use format http://servername.com/resource (Supports http and https). Do not add the query string, that will be added via the format template">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="token2" class="col-sm-2 col-form-label">Token 2:</label>
|
||||
<label for="token2" class="col-sm-2 col-form-label">Token 2</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="50" class="form-control" name="token2" id="token2" data-bs-toggle="tooltip" title="Token can be used in the format template as a variable, some services use this for authentication">
|
||||
</div>
|
||||
@ -246,28 +246,28 @@
|
||||
<input type="text" name="section" value="collapsePush2" hidden>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="influxdb2-push" class="col-sm-2 col-form-label">InfluxDB v2 URL:</label>
|
||||
<label for="influxdb2-push" class="col-sm-2 col-form-label">InfluxDB v2 URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="40" class="form-control" name="influxdb2-push" placeholder="http://www.internet.com" id="influxdb2-push" data-bs-toggle="tooltip" title="URL to push target, use format http://servername.com (Supports http and https)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="influxdb2-org" class="col-sm-2 col-form-label">InfluxDB v2 Org:</label>
|
||||
<label for="influxdb2-org" class="col-sm-2 col-form-label">InfluxDB v2 Org</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="50" class="form-control" name="influxdb2-org" id="influxdb2-org" data-bs-toggle="tooltip" title="Identifier to what organisation to use">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="influxdb2-bucket" class="col-sm-2 col-form-label">InfluxDB v2 Bucket:</label>
|
||||
<label for="influxdb2-bucket" class="col-sm-2 col-form-label">InfluxDB v2 Bucket</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="50" class="form-control" name="influxdb2-bucket" id="influxdb2-bucket" data-bs-toggle="tooltip" title="Identifier for the data bucket to use">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="influxdb2-auth" class="col-sm-2 col-form-label">InfluxDB v2 Auth:</label>
|
||||
<label for="influxdb2-auth" class="col-sm-2 col-form-label">InfluxDB v2 Auth</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="100" class="form-control" name="influxdb2-auth" id="influxdb2-auth" data-bs-toggle="tooltip" title="Authentication token for accessing data bucket">
|
||||
</div>
|
||||
@ -276,28 +276,28 @@
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="mqtt-push" class="col-sm-2 col-form-label">MQTT Server:</label>
|
||||
<label for="mqtt-push" class="col-sm-2 col-form-label">MQTT Server</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="40" class="form-control" name="mqtt-push" id="mqtt-push" placeholder="www.internet.com" data-bs-toggle="tooltip" title="Name of server to connect to, use format servername.com">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="mqtt-topic" class="col-sm-2 col-form-label">MQTT Port:</label>
|
||||
<label for="mqtt-topic" class="col-sm-2 col-form-label">MQTT Port</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="number" min="1" max="65535" class="form-control" name="mqtt-port" id="mqtt-port" placeholder="1138" data-bs-toggle="tooltip" title="Port number to use, 1138 is standard. Ports higher than 8000 will assume to use SSL">
|
||||
<input type="number" min="1" max="65535" class="form-control" name="mqtt-port" id="mqtt-port" placeholder="1883" data-bs-toggle="tooltip" title="Port number to use, 1883 is standard. Ports higher than 8000 will assume to use SSL">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="mqtt-user" class="col-sm-2 col-form-label">MQTT User:</label>
|
||||
<label for="mqtt-user" class="col-sm-2 col-form-label">MQTT User</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="20" class="form-control" name="mqtt-user" id="mqtt-user" data-bs-toggle="tooltip" title="Username to use. Leave blank if authentication is disabled">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="mqtt-pass" class="col-sm-2 col-form-label">MQTT Password:</label>
|
||||
<label for="mqtt-pass" class="col-sm-2 col-form-label">MQTT Password</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="20" class="form-control" name="mqtt-pass" id="mqtt-pass" data-bs-toggle="tooltip" title="Password to use. Leave blank if authentication is disabled">
|
||||
</div>
|
||||
@ -335,7 +335,7 @@
|
||||
|
||||
<div class="row mb-3">
|
||||
<fieldset class="form-group row">
|
||||
<legend class="col-form-label col-sm-2 float-sm-left pt-0">Gravity Format:</legend>
|
||||
<label for="gravity-format" class="col-sm-2 col-form-label">Gravity Format</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="gravity-format" id="gravity-format-g" value="G" checked data-bs-toggle="tooltip" title="Present gravity in SG format">
|
||||
@ -352,12 +352,12 @@
|
||||
<div class="row mb-3">
|
||||
<label for="gravity-formula" class="col-sm-2 col-form-label">Formula</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" maxlength="200" class="form-control" name="gravity-formula" id="gravity-formula" checked data-bs-toggle="tooltip" title="Formula used to convert angle to gravity">
|
||||
<input type="text" maxlength="200" class="form-control" name="gravity-formula" id="gravity-formula" placeholder="0.0*tilt^2+0.01*tilt+0.2" checked data-bs-toggle="tooltip" title="Formula used to convert angle to gravity">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 offset-sm-2">
|
||||
<div class="col-sm-3 offset-sm-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="gravity-temp-adjustment" id="gravity-temp-adjustment" checked data-bs-toggle="tooltip" title="Adjust the calculated gravity based on the current temperature. Assumes that calibration is done using 20C / 68F">
|
||||
<label class="form-check-label" for="gravity-temp-adjustment">Temperature adjust gravity</label>
|
||||
@ -388,22 +388,29 @@
|
||||
<input type="text" name="id" id="id4" hidden>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="voltage-factor" class="col-sm-2 col-form-label">Voltage factor:</label>
|
||||
<label for="voltage-factor" class="col-sm-2 col-form-label">Voltage factor</label>
|
||||
<div class="col-sm-2">
|
||||
<input type="number" step=".01" class="form-control" name="voltage-factor" id="voltage-factor" data-bs-toggle="tooltip" title="Factor used to calculate the battery voltage. When running on battery, the voltage should be less than 4.15V">
|
||||
<input type="number" step=".01" class="form-control" name="voltage-factor" id="voltage-factor" placeholder="1.59" data-bs-toggle="tooltip" title="Factor used to calculate the battery voltage. Can vary depending on the R2 value">
|
||||
</div>
|
||||
<label for="voltage-factor" class="col-sm-3 col-form-label" id="battery">Loading...</label>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="temp-adjustment-value" class="col-sm-2 col-form-label">Temp Sensor Adj:</label>
|
||||
<label for="voltage-config" class="col-sm-2 col-form-label">Config voltage</label>
|
||||
<div class="col-sm-2">
|
||||
<input type="number" step=".1" class="form-control" name="temp-adjustment-value" id="temp-adjustment-value" data-bs-toggle="tooltip" title="This value will be added to the sensor value in case the sensor dont show the correct temperature">
|
||||
<input type="number" step=".01" min="3.00" max="6.00" class="form-control" name="voltage-config" id="voltage-config" placeholder="4.16" data-bs-toggle="tooltip" title="Over this level the device will always go into configuration mode, some batteries might have a higher voltage when fully charged">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 offset-sm-2">
|
||||
<label for="temp-adjustment-value" class="col-sm-2 col-form-label">Temp Sensor Adj</label>
|
||||
<div class="col-sm-2">
|
||||
<input type="number" step=".1" class="form-control" name="temp-adjustment-value" id="temp-adjustment-value" placeholder="0" data-bs-toggle="tooltip" title="This value will be added to the sensor value in case the sensor dont show the correct temperature">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 offset-sm-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="gyro-temp" id="gyro-temp" data-bs-toggle="tooltip" title="Use the temperature sensor in the gyro instead of DS18B20, require 300s update interval to be accurate">
|
||||
<label class="form-check-label" for="gyro-temp">Use gyro temperature</label>
|
||||
@ -411,6 +418,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 offset-sm-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="storage-sleep" id="storage-sleep" data-bs-toggle="tooltip" title="If enabled and the device is placed on its cap (less than 5 degress) it will go into sleep for 2000 minutes">
|
||||
<label class="form-check-label" for="storage-sleep">Enable storage mode when placed on cap</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label class="col-sm-2 col-form-label" for="ble">Bluetooth tilt color:</label>
|
||||
<div class="col-sm-2">
|
||||
@ -429,7 +445,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="ota-url" class="col-sm-2 col-form-label">OTA base URL:</label>
|
||||
<label for="ota-url" class="col-sm-2 col-form-label">OTA base URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="90" class="form-control" name="ota-url" id="ota-url" placeholder="http://www.local.com/path/" data-bs-toggle="tooltip" title="Base URL to where firmware and version.json file can be found. Needs to end with '/', example: http://www.mysite.com/firmware/">
|
||||
</div>
|
||||
@ -453,45 +469,72 @@
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingAdvanced">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseAdvanced" aria-expanded="false" aria-controls="collapseAdvanced">
|
||||
<b>Advanced Settings (use with caution)</b>
|
||||
<b>Advanced Software Settings (use with caution)</b>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseAdvanced" class="accordion-collapse collapse" aria-labelledby="headingAdvanced" data-bs-parent="#accordion">
|
||||
<div class="accordion-body">
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4">
|
||||
<div class="form-check">
|
||||
<input checked class="form-check-input" type="checkbox" name="adv-config" id="adv-config" data-bs-toggle="tooltip" title="Enable the advanced software settings.">
|
||||
<label class="form-check-label" for="adv-config">Disable advanced software settings</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="/api/config/advanced" method="post">
|
||||
<input type="text" name="id" id="id6" hidden>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="gyro-read-count" class="col-sm-3 col-form-label">Gyro reads:</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="10" max="100" class="form-control" name="gyro-read-count" id="gyro-read-count" checked data-bs-toggle="tooltip" title="How many times should we read the gyro to get an accurate angle. More reads = better accuracy but higher battery drain">
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="10" max="100" class="form-control" name="gyro-read-count" id="gyro-read-count" placeholder="50" checked data-bs-toggle="tooltip" title="How many times should we read the gyro to get an accurate angle. More reads = better accuracy but higher battery drain">
|
||||
</div>
|
||||
<div class="col-sm-5">(10-100) - default 50</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="gyro-moving-threashold" class="col-sm-3 col-form-label">Gyro moving theashold:</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="50" max="1000" class="form-control" name="gyro-moving-threashold" id="gyro-moving-threashold" checked data-bs-toggle="tooltip" title="How much deviation between gyro reads are acceptable in order to regard this as a valid angle">
|
||||
<label for="gyro-moving-threashold" class="col-sm-3 col-form-label">Gyro moving theashold</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="50" max="1000" class="form-control" name="gyro-moving-threashold" id="gyro-moving-threashold" placeholder="500" checked data-bs-toggle="tooltip" title="How much deviation between gyro reads are acceptable in order to regard this as a valid angle">
|
||||
</div>
|
||||
<div class="col-sm-5">(50-1000) - default 500</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="formula-max-deviation" class="col-sm-3 col-form-label">Formula max deviation (SG):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" step=".1" min="1" max="10" class="form-control" name="formula-max-deviation" id="formula-max-deviation" checked data-bs-toggle="tooltip" title="When validating the derived formula this is the maximum accepted deviation for the supplied values">
|
||||
<label for="formula-max-deviation" class="col-sm-3 col-form-label">Formula max deviation (SG)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" step=".1" min="1" max="10" class="form-control" name="formula-max-deviation" id="formula-max-deviation" placeholder="3" checked data-bs-toggle="tooltip" title="When validating the derived formula this is the maximum accepted deviation for the supplied values">
|
||||
</div>
|
||||
<div class="col-sm-5">(1 - 10) - default 1.6 SG</div>
|
||||
<div class="col-sm-5">(1 - 10) - default 3 SG</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3 offset-sm-3">
|
||||
<div class="form-check">
|
||||
<input disabled class="form-check-input" type="checkbox" class="form-control" name="ignore-low-angles" id="ignore-low-angles" data-bs-toggle="tooltip" title="When active, angles below water will be ignored. Note! Angle must be defined under calibration, first field.">
|
||||
<label class="form-check-label" for="ignore-low-angles">Ignore angles below water</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5" name="water-angle" id="water-angle"></div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="formula-calibration-temp" class="col-sm-3 col-form-label">Gravity calibration temp</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" step=".01" min="0" max="100" class="form-control" name="formula-calibration-temp" id="formula-calibration-temp" placeholder="20" checked data-bs-toggle="tooltip" title="Calibration temperature, used in temperatur correction formula, default 20C/68F">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 100) - default 20C/68F</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="tempsensor-resolution" class="col-sm-3 col-form-label">DS18B20 resolution (bits):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="9" max="12" class="form-control" name="tempsensor-resolution" id="tempsensor-resolution" checked data-bs-toggle="tooltip" title="Resolution when reading the DS18B20 temperature sensor, higher resolution give better accuracy but takes longer">
|
||||
<label for="tempsensor-resolution" class="col-sm-3 col-form-label">DS18B20 resolution (bits)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="9" max="12" class="form-control" name="tempsensor-resolution" id="tempsensor-resolution" placeholder="9" checked data-bs-toggle="tooltip" title="Resolution when reading the DS18B20 temperature sensor, higher resolution give better accuracy but takes longer">
|
||||
</div>
|
||||
<div class="col-sm-5">(9 - 12) - default 9 bits</div>
|
||||
</div>
|
||||
@ -499,17 +542,17 @@
|
||||
<hr>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="wifi-connect-timeout" class="col-sm-3 col-form-label">Wifi connect timeout (s):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="1" max="60" class="form-control" name="wifi-connect-timeout" id="wifi-connect-timeout" checked data-bs-toggle="tooltip" title="Max time waiting for a wifi connection before going back to sleep">
|
||||
<label for="wifi-connect-timeout" class="col-sm-3 col-form-label">Wifi connect timeout (s)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="1" max="60" class="form-control" name="wifi-connect-timeout" id="wifi-connect-timeout" placeholder="20" checked data-bs-toggle="tooltip" title="Max time waiting for a wifi connection before going back to sleep">
|
||||
</div>
|
||||
<div class="col-sm-5">(1 - 60) - default 20 s</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="wifi-portal-timeout" class="col-sm-3 col-form-label">Wifi portal timeout (s):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="10" max="240" class="form-control" name="wifi-portal-timeout" id="wifi-portal-timeout" checked data-bs-toggle="tooltip" title="Max time the wifi portal is active before existing">
|
||||
<label for="wifi-portal-timeout" class="col-sm-3 col-form-label">Wifi portal timeout (s)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="10" max="240" class="form-control" name="wifi-portal-timeout" id="wifi-portal-timeout" placeholder="120" checked data-bs-toggle="tooltip" title="Max time the wifi portal is active before existing">
|
||||
</div>
|
||||
<div class="col-sm-5">(10 - 240) - default 120 s</div>
|
||||
</div>
|
||||
@ -518,40 +561,40 @@
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="int-http1" class="col-sm-3 col-form-label">Skip interval - HTTP 1 (POST):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http1" id="int-http1" checked data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http1" id="int-http1" placeholder="0" checked data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 5) - default 0</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="int-http2" class="col-sm-3 col-form-label">Skip interval - HTTP 2 (POST):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http2" id="int-http2" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
<label for="int-http2" class="col-sm-3 col-form-label">Skip interval - HTTP 2 (POST)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http2" id="int-http2" placeholder="0" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 5) - default 0</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="int-http3" class="col-sm-3 col-form-label">Skip interval - HTTP 3 (GET):</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http3" id="int-http3" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
<label for="int-http3" class="col-sm-3 col-form-label">Skip interval - HTTP 3 (GET)</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-http3" id="int-http3" placeholder="0" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 5) - default 0</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="int-influx" class="col-sm-3 col-form-label">Skip interval - InfluxDB v2:</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-influx" id="int-influx" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
<label for="int-influx" class="col-sm-3 col-form-label">Skip interval - InfluxDB v2</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-influx" id="int-influx" placeholder="0" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 5) - default 0</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="int-mqtt" class="col-sm-3 col-form-label">Skip interval - MQTT:</label>
|
||||
<div class="col-sm-2">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-mqtt" id="int-mqtt" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
<label for="int-mqtt" class="col-sm-3 col-form-label">Skip interval - MQTT</label>
|
||||
<div class="col-sm-3">
|
||||
<input disabled type="number" min="0" max="5" class="form-control" name="int-mqtt" id="int-mqtt" placeholder="0" data-bs-toggle="tooltip" title="Defines how many sleep cycles to skip between pushing data to this target, 1 = every second cycle">
|
||||
</div>
|
||||
<div class="col-sm-5">(0 - 5) - default 0</div>
|
||||
</div>
|
||||
@ -563,15 +606,6 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-4 offset-sm-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="adv-config" id="adv-config" checked data-bs-toggle="tooltip" title="Enabled the advanced configuration settings.">
|
||||
<label class="form-check-label" for="adv-config">Enable advanced configuration</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -747,19 +781,21 @@
|
||||
|
||||
function checkAdvancedSection( b ) {
|
||||
var b = $("#adv-config").is(":checked");
|
||||
|
||||
|
||||
$("#advanced-btn").prop("disabled", b);
|
||||
$("#gyro-read-count").prop("disabled", b);
|
||||
$("#gyro-moving-threashold").prop("disabled", b);
|
||||
$("#formula-max-deviation").prop("disabled", b);
|
||||
$("#wifi-portal-timeout").prop("disabled", b);
|
||||
$("#wifi-connect-timeout").prop("disabled", b);
|
||||
$("#formula-calibration-temp").prop("disabled", b);
|
||||
$("#int-http1").prop("disabled", b);
|
||||
$("#int-http2").prop("disabled", b);
|
||||
$("#int-http3").prop("disabled", b);
|
||||
$("#int-influx").prop("disabled", b);
|
||||
$("#int-mqtt").prop("disabled", b);
|
||||
$("#tempsensor-resolution").prop("disabled", b);
|
||||
$("#ignore-low-angles").prop("disabled", b);
|
||||
}
|
||||
|
||||
// Get the advanced values from the API
|
||||
@ -778,11 +814,18 @@
|
||||
$("#wifi-portal-timeout").val(cfg["wifi-portal-timeout"]);
|
||||
$("#wifi-connect-timeout").val(cfg["wifi-connect-timeout"]);
|
||||
$("#tempsensor-resolution").val(cfg["tempsensor-resolution"]);
|
||||
$("#ignore-low-angles").prop( "checked", cfg["ignore-low-angles"] );
|
||||
$("#formula-calibration-temp").val(cfg["formula-calibration-temp"]);
|
||||
$("#int-http1").val(cfg["int-http1"]);
|
||||
$("#int-http2").val(cfg["int-http2"]);
|
||||
$("#int-http3").val(cfg["int-http3"]);
|
||||
$("#int-influx").val(cfg["int-influx"]);
|
||||
$("#int-mqtt").val(cfg["int-mqtt"]);
|
||||
|
||||
if ( cfg["gyro-read-count"] != 50 || cfg["gyro-moving-threashold"] != 500 || cfg["formula-max-deviation"] != 3 || cfg["wifi-portal-timeout"] != 120 || cfg["wifi-connect-timeout"] != 20 || cfg["tempsensor-resolution"] != 9 ||
|
||||
cfg["int-http1"] != 0 || cfg["int-http2"] != 0 || cfg["int-http3"] != 0 || cfg["int-influx"] != 0 || cfg["int-mqtt"] != 0 || cfg["ignore-low-angles"] != false || (cfg["formula-calibration-temp"] != 20 && cfg["formula-calibration-temp"] != 68)) {
|
||||
$("#adv-config").attr("checked", false );
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
showError('Unable to get data from the device.');
|
||||
@ -839,14 +882,17 @@
|
||||
$("#mqtt-pass").val(cfg["mqtt-pass"]);
|
||||
$("#sleep-interval").val(cfg["sleep-interval"]);
|
||||
$("#voltage-factor").val(cfg["voltage-factor"]);
|
||||
$("#voltage-config").val(cfg["voltage-config"]);
|
||||
$("#gravity-formula").val(cfg["gravity-formula"]);
|
||||
$("#temp-adjustment-value").val(cfg["temp-adjustment-value"]);
|
||||
$("#gravity-temp-adjustment").prop( "checked", cfg["gravity-temp-adjustment"] );
|
||||
$("#gyro-temp").prop( "checked", cfg["gyro-temp"] );
|
||||
$("#storage-sleep").prop( "checked", cfg["storage-sleep"] );
|
||||
$("#gyro-calibration-data").text( cfg["gyro-calibration-data"]["ax"] + "," + cfg["gyro-calibration-data"]["ay"] + "," + cfg["gyro-calibration-data"]["az"] + "," + cfg["gyro-calibration-data"]["gx"] + "," + cfg["gyro-calibration-data"]["gy"] + "," + cfg["gyro-calibration-data"]["gz"] );
|
||||
$("#battery").text(cfg["battery"] + " V");
|
||||
$("#angle").text(cfg["angle"]);
|
||||
$("#runtime-average").val(cfg["runtime-average"]);
|
||||
$("#water-angle").text( "(Water angle: " + cfg["formula-calculation-data"]["a1"] + ") - default off");
|
||||
//$("#gravity").text(cfg["gravity"] + " SG");
|
||||
})
|
||||
.fail(function () {
|
||||
|
@ -96,13 +96,15 @@
|
||||
|
||||
<script>
|
||||
let formatTemplates = [
|
||||
{ "id": "GravityMon-Post", "format": "%7B%0A%20%22name%22%20%3A%20%22%24%7Bmdns%7D%22%2C%0A%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%0A%20%22token%22%20%3A%20%22gravmon%22%2C%0A%20%22interval%22%3A%20%24%7Bsleep-interval%7D%2C%0A%20%22temperature%22%3A%20%24%7Btemp%7D%2C%0A%20%22temp_units%22%3A%20%22%24%7Btemp-unit%7D%22%2C%0A%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%0A%20%22angle%22%3A%20%24%7Bangle%7D%2C%0A%20%22battery%22%3A%20%24%7Bbattery%7D%2C%0A%20%22RSSI%22%3A%20%24%7Brssi%7D%2C%0A%20%22corr-gravity%22%3A%20%24%7Bcorr-gravity%7D%2C%0A%20%22gravity-unit%22%3A%20%22%24%7Bgravity-unit%7D%22%2C%0A%20%22run-time%22%3A%20%24%7Brun-time%7D%0A%7D" },
|
||||
{ "id": "GravityMon-Post", "format": "%7B%20%22name%22%20%3A%20%22%24%7Bmdns%7D%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22%24%7Btoken%7D%22%2C%20%22interval%22%3A%20%24%7Bsleep-interval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp_units%22%3A%20%22%24%7Btemp-unit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22RSSI%22%3A%20%24%7Brssi%7D%2C%20%22corr-gravity%22%3A%20%24%7Bcorr-gravity%7D%2C%20%22gravity-unit%22%3A%20%22%24%7Bgravity-unit%7D%22%2C%20%22run-time%22%3A%20%24%7Brun-time%7D%7D" },
|
||||
{ "id": "GravityMon-Get", "format": "%3Fname%3D%24%7Bmdns%7D%26id%3D%24%7Bid%7D%26token%3D%24%7Btoken2%7D%26interval%3D%24%7Bsleep-interval%7D%26temperature%3D%24%7Btemp%7D%26%0Atemp-units%3D%24%7Btemp-unit%7D%26gravity%3D%24%7Bgravity%7D%26angle%3D%24%7Bangle%7D%26battery%3D%24%7Bbattery%7D%26rssi%3D%24%7Brssi%7D%26%0Acorr-gravity%3D%24%7Bcorr-gravity%7D%26gravity-unit%3D%24%7Bgravity-unit%7D%26run-time%3D%24%7Brun-time%7D" },
|
||||
{ "id": "iSpindle-Post", "format": "%7B%0A%20%22name%22%20%3A%20%22%24%7Bmdns%7D%22%2C%0A%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%0A%20%22token%22%20%3A%20%22gravmon%22%2C%0A%20%22interval%22%3A%20%24%7Bsleep-interval%7D%2C%0A%20%22temperature%22%3A%20%24%7Btemp%7D%2C%0A%20%22temp_units%22%3A%20%22%24%7Btemp-unit%7D%22%2C%0A%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%0A%20%22angle%22%3A%20%24%7Bangle%7D%2C%0A%20%22battery%22%3A%20%24%7Bbattery%7D%2C%0A%20%22RSSI%22%3A%20%24%7Brssi%7D%0A%7D" },
|
||||
{ "id": "BrewFatherCustom-Post", "format": "%7B%0A%20%20%20%22name%22%3A%20%22%24%7Bmdns%7D%22%2C%0A%20%20%20%22temp%22%3A%20%24%7Btemp%7D%2C%0A%20%20%20%22aux_temp%22%3A%200%2C%0A%20%20%20%22ext_temp%22%3A%200%2C%0A%20%20%20%22temp_unit%22%3A%20%22%24%7Btemp-unit%7D%22%2C%0A%20%20%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%0A%20%20%20%22gravity_unit%22%3A%20%22%24%7Bgravity-unit%7D%22%2C%0A%20%20%20%22pressure%22%3A%200%2C%0A%20%20%20%22pressure_unit%22%3A%20%22PSI%22%2C%0A%20%20%20%22ph%22%3A%200%2C%0A%20%20%20%22bpm%22%3A%200%2C%0A%20%20%20%22comment%22%3A%20%22%22%2C%0A%20%20%20%22beer%22%3A%20%22%22%2C%0A%20%20%20%22battery%22%3A%20%24%7Bbattery%7D%0A%7D" },
|
||||
{ "id": "iSpindle-Post", "format": "%7B%20%22name%22%20%3A%20%22%24%7Bmdns%7D%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22%24%7Btoken%7D%22%2C%20%22interval%22%3A%20%24%7Bsleep-interval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp_units%22%3A%20%22%24%7Btemp-unit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22RSSI%22%3A%20%24%7Brssi%7D%7D" },
|
||||
{ "id": "BrewFatherCustom-Post", "format": "%7B%20%20%20%22name%22%3A%20%22%24%7Bmdns%7D%22%2C%20%20%20%22temp%22%3A%20%24%7Btemp%7D%2C%20%20%20%22aux_temp%22%3A%200%2C%20%20%20%22ext_temp%22%3A%200%2C%20%20%20%22temp_unit%22%3A%20%22%24%7Btemp-unit%7D%22%2C%20%20%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%20%20%22gravity_unit%22%3A%20%22%24%7Bgravity-unit%7D%22%2C%20%20%20%22pressure%22%3A%200%2C%20%20%20%22pressure_unit%22%3A%20%22PSI%22%2C%20%20%20%22ph%22%3A%200%2C%20%20%20%22bpm%22%3A%200%2C%20%20%20%22comment%22%3A%20%22%22%2C%20%20%20%22beer%22%3A%20%22%22%2C%20%20%20%22battery%22%3A%20%24%7Bbattery%7D%7D" },
|
||||
{ "id": "iSpindle-Mqtt", "format": "ispindel%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Bangle%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2Ftemp_units%3A%24%7Btemp-unit%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2Fbattery%3A%24%7Bbattery%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2Fgravity%3A%24%7Bgravity%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2Finterval%3A%24%7Bsleep-interval%7D%7C%0Aispindel%2F%24%7Bmdns%7D%2FRSSI%3A%24%7Brssi%7D%7C" },
|
||||
{ "id": "HomeAssistant-Mqtt", "format": "gravmon%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Bangle%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Ftemp_units%3A%24%7Btemp-unit%7D%7C" },
|
||||
{ "id": "UBIDots1-Post", "format": "%7B%0A%20%20%20%22temperature%22%3A%20%24%7Btemp%7D%2C%0A%20%20%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%0A%20%20%20%22angle%22%3A%20%24%7Bangle%7D%2C%0A%20%20%20%22battery%22%3A%20%24%7Bbattery%7D%2C%0A%20%20%20%22rssi%22%3A%20%24%7Brssi%7D%0A%7D" } ];
|
||||
{ "id": "HomeAssistant-Mqtt", "format": "gravmon%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Fgravity%3A%24%7Bgravity%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Frssi%3A%24%7Brssi%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Btilt%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Fbattery%3A%24%7Bbattery%7D%7C%0A" },
|
||||
{ "id": "HomeAssistant-Mqtt2", "format": "gravmon%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Fgravity%3A%24%7Bgravity%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Frssi%3A%24%7Brssi%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Btilt%7D%7C%0Agravmon%2F%24%7Bmdns%7D%2Fbattery%3A%24%7Bbattery%7D%7C%0Ahomeassistant%2Fsensor%2Fgravmon_%24%7Bid%7D%2Ftemperature%2Fconfig%3A%7B%22dev%22%3A%7B%22name%22%3A%22%24%7Bmdns%7D%22%2C%22mdl%22%3A%22gravmon%22%2C%22sw%22%3A%22%24%7Bapp-ver%7D%22%2C%22ids%22%3A%22%24%7Bid%7D%22%7D%2C%22uniq_id%22%3A%22%24%7Bid%7D_temp%22%2C%22name%22%3A%22temperature%22%2C%22dev_cla%22%3A%22temperature%22%2C%22unit_of_meas%22%3A%22%24%7Btemp-unit%7D%22%2C%22stat_t%22%3A%22gravmon%2F%24%7Bmdns%7D%2Ftemperature%22%7D%7C%0Ahomeassistant%2Fsensor%2Fgravmon_%24%7Bid%7D%2Fgravity%2Fconfig%3A%7B%22dev%22%3A%7B%22name%22%3A%22%24%7Bmdns%7D%22%2C%22mdl%22%3A%22gravmon%22%2C%22sw%22%3A%22%24%7Bapp-ver%7D%22%2C%22ids%22%3A%22%24%7Bid%7D%22%7D%2C%22uniq_id%22%3A%22%24%7Bid%7D_grav%22%2C%22name%22%3A%22gravity%22%2C%22dev_cla%22%3A%22temperature%22%2C%22unit_of_meas%22%3A%22%20%24%7Bgravity-unit%7D%22%2C%22stat_t%22%3A%22gravmon%2F%24%7Bmdns%7D%2Fgravity%22%7D%7C%0Ahomeassistant%2Fsensor%2Fgravmon_%24%7Bid%7D%2Frssi%2Fconfig%3A%7B%22dev%22%3A%7B%22name%22%3A%22%24%7Bmdns%7D%22%2C%22mdl%22%3A%22gravmon%22%2C%22sw%22%3A%22%24%7Bapp-ver%7D%22%2C%22ids%22%3A%22%24%7Bid%7D%22%7D%2C%22uniq_id%22%3A%22%24%7Bid%7D_rssi%22%2C%22name%22%3A%22rssi%22%2C%22dev_cla%22%3A%22temperature%22%2C%22unit_of_meas%22%3A%22dBm%22%2C%22stat_t%22%3A%22gravmon%2F%24%7Bmdns%7D%2Frssi%22%7D%7C%0Ahomeassistant%2Fsensor%2Fgravmon_%24%7Bid%7D%2Ftilt%2Fconfig%3A%7B%22dev%22%3A%7B%22name%22%3A%22%24%7Bmdns%7D%22%2C%22mdl%22%3A%22gravmon%22%2C%22sw%22%3A%22%24%7Bapp-ver%7D%22%2C%22ids%22%3A%22%24%7Bid%7D%22%7D%2C%22uniq_id%22%3A%22%24%7Bid%7D_tilt%22%2C%22name%22%3A%22tilt%22%2C%22dev_cla%22%3A%22temperature%22%2C%22stat_t%22%3A%22gravmon%2F%24%7Bmdns%7D%2Ftilt%22%7D%7C%0Ahomeassistant%2Fsensor%2Fgravmon_%24%7Bid%7D%2Fbattery%2Fconfig%3A%7B%22dev%22%3A%7B%22name%22%3A%22%24%7Bmdns%7D%22%2C%22mdl%22%3A%22gravmon%22%2C%22sw%22%3A%22%24%7Bapp-ver%7D%22%2C%22ids%22%3A%22%24%7Bid%7D%22%7D%2C%22uniq_id%22%3A%22%24%7Bid%7D_batt%22%2C%22name%22%3A%22battery%22%2C%22dev_cla%22%3A%22temperature%22%2C%22unit_of_meas%22%3A%22V%22%2C%22stat_t%22%3A%22gravmon%2F%24%7Bmdns%7D%2Fbattery%22%7D%7C%0A" },
|
||||
{ "id": "Brewblox-Mqtt", "format": "brewcast%2Fhistory%3A%7B%22key%22%3A%22%24%7Bmdns%7D%22%2C%22data%22%3A%7B%22Temperature%5BdegC%5D%22%3A%20%24%7Btemp-c%7D%2C%22Temperature%5BdegF%5D%22%3A%20%24%7Btemp-f%7D%2C%22Battery%5BV%5D%22%3A%24%7Bbattery%7D%2C%22Tilt%5Bdeg%5D%22%3A%24%7Bangle%7D%2C%22Rssi%5BdBm%5D%22%3A%24%7Brssi%7D%2C%22SG%22%3A%24%7Bgravity-sg%7D%2C%22Plato%22%3A%24%7Bgravity-plato%7D%7D%7D%7C" },
|
||||
{ "id": "UBIDots-Post", "format": "%7B%0A%20%20%20%22temperature%22%3A%20%24%7Btemp%7D%2C%0A%20%20%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%0A%20%20%20%22angle%22%3A%20%24%7Bangle%7D%2C%0A%20%20%20%22battery%22%3A%20%24%7Bbattery%7D%2C%0A%20%20%20%22rssi%22%3A%20%24%7Brssi%7D%0A%7D" } ];
|
||||
</script>
|
||||
|
||||
<div class="row mb-3">
|
||||
@ -115,9 +117,12 @@
|
||||
<option value="GravityMon-Post">GravityMon (POST)</option>
|
||||
<option value="iSpindle-Mqtt">iSpindle (MQTT)</option>
|
||||
<option value="HomeAssistant-Mqtt">Home Assistant (MQTT)</option>
|
||||
<option value="UBIDots1-Post">UBIdots - Alternative 1 (POST)</option>
|
||||
<option value="BrewFatherCustom-Post">Brewfather Custom Endpoint (POST)</option>
|
||||
<option value="HomeAssistant-Mqtt2">Home Assistant - Auto register sensor (MQTT)</option>
|
||||
<option value="UBIDots-Post">UBIdots (POST)</option>
|
||||
<option value="BrewFatherCustom-Post">Brewfather - Custom Endpoint (POST)</option>
|
||||
<option value="iSpindle-Post">Brewfather - iSpindle Endpoint (POST)</option>
|
||||
<option value="GravityMon-Get">GravityMon (GET)</option>
|
||||
<option value="Brewblox-Mqtt">BrewBlox (MQTT)</option>
|
||||
</select>
|
||||
<div class="col-sm-4">
|
||||
<button class="btn btn-secondary" id="copy-btn" data-bs-toggle="tooltip" title="Copy the selected format template to the selected push target">Copy format</button>
|
||||
@ -235,13 +240,15 @@
|
||||
doc = doc.replaceAll("${corr-gravity}", cfg["gravity"]);
|
||||
doc = doc.replaceAll("${angle}", cfg["angle"]);
|
||||
doc = doc.replaceAll("${tilt}", cfg["angle"]);
|
||||
doc = doc.replaceAll("${app-ver}", cfg["app-ver"]);
|
||||
doc = doc.replaceAll("${app-build}", cfg["app-build"]);
|
||||
|
||||
// Format in a readable json string.
|
||||
try {
|
||||
var json = JSON.parse(doc);
|
||||
doc = JSON.stringify(json, null, 2);
|
||||
} catch(e) {
|
||||
console.log("Not a javascript object!")
|
||||
console.log("Not a JSON object!")
|
||||
}
|
||||
|
||||
$("#preview").text(doc);
|
||||
|
206
html/index.htm
@ -73,66 +73,6 @@
|
||||
</script>
|
||||
|
||||
<div class="accordion" id="accordion">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingSoftware">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSoftware" aria-expanded="true" aria-controls="collapseSoftware">
|
||||
<b>Device</b>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseSoftware" class="accordion-collapse collapse show" aria-labelledby="headingSoftware" data-bs-parent="#accordion">
|
||||
<div class="accordion-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Current version:</div>
|
||||
<div class="col-md-4 bg-light" id="app-ver">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3" id="h-app-ver-new" hidden>
|
||||
<div class="col-md-4 bg-light">New version:</div>
|
||||
<div class="col-md-4 bg-light" id="app-ver-new">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Host name:</div>
|
||||
<div class="col-md-4 bg-light" id="mdns">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Device ID:</div>
|
||||
<div class="col-md-4 bg-light" id="id">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Platform:</div>
|
||||
<div class="col-md-4 bg-light" id="platform">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">SSID:</div>
|
||||
<div class="col-md-4 bg-light" id="wifi-ssid">Loading...</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$("#log-btn").click(function(e){
|
||||
loadLog();
|
||||
});
|
||||
setInterval(function() {
|
||||
loadLog();
|
||||
}, 3000); //5 seconds
|
||||
|
||||
function loadLog() {
|
||||
$("#logContent").load("/log");
|
||||
//$("#logContent").load("/test/status.json");
|
||||
};
|
||||
</script>
|
||||
|
||||
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLog" aria-expanded="false" aria-controls="collapseLog" data-bs-toggle="tooltip" title="Load and show the last 10 errors that has occured on the device">
|
||||
View error log
|
||||
</button>
|
||||
|
||||
<div class="collapse row-margin-10" id="collapseLog">
|
||||
<div class="card card-body">
|
||||
<pre><code class="card-text" id="logContent"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="accordion-header" id="headingData">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseData" aria-expanded="true" aria-controls="collapseData">
|
||||
@ -173,12 +113,158 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingSoftware">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSoftware" aria-expanded="true" aria-controls="collapseSoftware">
|
||||
<b>Device</b>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseSoftware" class="accordion-collapse collapse show" aria-labelledby="headingSoftware" data-bs-parent="#accordion">
|
||||
<div class="accordion-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Current version:</div>
|
||||
<div class="col-md-4 bg-light" id="app-ver">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3" id="h-app-ver-new" hidden>
|
||||
<div class="col-md-4 bg-light">New version:</div>
|
||||
<div class="col-md-4 bg-light" id="app-ver-new">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Host name:</div>
|
||||
<div class="col-md-4 bg-light" id="mdns">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Device ID:</div>
|
||||
<div class="col-md-4 bg-light" id="id">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">Platform:</div>
|
||||
<div class="col-md-4 bg-light" id="platform">Loading...</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4 bg-light">SSID:</div>
|
||||
<div class="col-md-4 bg-light" id="wifi-ssid">Loading...</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$("#log-btn").click(function(e){
|
||||
loadLog();
|
||||
});
|
||||
setInterval(function() {
|
||||
loadLog();
|
||||
}, 5000);
|
||||
|
||||
function loadLog() {
|
||||
$("#logContent").load("/log");
|
||||
//$("#logContent").load("/test/log");
|
||||
};
|
||||
</script>
|
||||
|
||||
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLog" aria-expanded="false" aria-controls="collapseLog" data-bs-toggle="tooltip" title="Load and show the last 10 errors that has occured on the device">
|
||||
View error log
|
||||
</button>
|
||||
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="tooltip" name="github-btn" id="github-btn" title="Go to github and place a issue">
|
||||
Submit a issue on github
|
||||
</button>
|
||||
|
||||
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSupport" aria-expanded="false" aria-controls="collapseSupport" data-bs-toggle="tooltip" name="support-btn" id="support-btn" title="Collect data relevant for a support case">
|
||||
Gather support information
|
||||
</button>
|
||||
|
||||
<div class="collapse row-margin-10" id="collapseLog">
|
||||
<div class="card card-body">
|
||||
<pre><code class="card-text" id="logContent"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapse row-margin-10" id="collapseSupport">
|
||||
<div class="card card-body">
|
||||
<pre><code class="card-text" id="supportContent"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var debug = {};
|
||||
|
||||
window.onload = start;
|
||||
|
||||
$("#github-btn").click(function(e){
|
||||
window.location.href = "https://github.com/mp-se/gravitymon/issues";
|
||||
});
|
||||
|
||||
$("#support-btn").click(function(e){
|
||||
$('#spinner').show();
|
||||
|
||||
var url = "/api/config";
|
||||
//var url = "/test/config.json";
|
||||
$.getJSON(url, function (cfg) {
|
||||
debug = {};
|
||||
debug["mdns"] = cfg["mdns"];
|
||||
debug["id"] = cfg["id"];
|
||||
|
||||
debug["sleep-interval"] = cfg["sleep-interval"];
|
||||
debug["temp-format"] = cfg["temp-format"];
|
||||
|
||||
debug["gravity-format"] = cfg["gravity-format"];
|
||||
debug["gravity-temp-adjustment"] = cfg["gravity-temp-adjustment"];
|
||||
|
||||
debug["voltage-factor"] = cfg["voltage-factor"];
|
||||
debug["platform"] = cfg["platform"];
|
||||
debug["ble"] = cfg["ble"];
|
||||
debug["gyro-temp"] = cfg["gyro-temp"];
|
||||
debug["gyro-calibration-data"] = cfg["gyro-calibration-data"];
|
||||
debug["temp-adjustment-value"] = cfg["temp-adjustment-value"];
|
||||
|
||||
var url = "/api/status";
|
||||
//var url = "/test/status.json";
|
||||
$.getJSON(url, function (cfg) {
|
||||
debug["runtime-average"] = cfg["runtime-average"];
|
||||
debug["rssi"] = cfg["rssi"];
|
||||
debug["app-ver"] = cfg["app-ver"];
|
||||
debug["app-build"] = cfg["app-build"];
|
||||
});
|
||||
|
||||
var url = "/api/config/format";
|
||||
//var url = "/test/format.json";
|
||||
$.getJSON(url, function (cfg) {
|
||||
debug["formats"] = cfg;
|
||||
|
||||
var url = "/api/config/advanced";
|
||||
//var url = "/test/adv.json";
|
||||
$.getJSON(url, function (cfg) {
|
||||
debug["advanced"] = cfg;
|
||||
|
||||
var url = "/api/upload";
|
||||
//var url = "/test/upload.json";
|
||||
$.getJSON(url, function (cfg) {
|
||||
debug["files"] = cfg;
|
||||
|
||||
var url = "/log";
|
||||
//var url = "/test/log";
|
||||
$.ajax({url: url, method: 'get', success: function (data) {
|
||||
debug["log"] = data.split("\n");
|
||||
var s = JSON.stringify(debug, null, 2);
|
||||
$("#supportContent").text( s );
|
||||
$('#spinner').hide();
|
||||
//navigator.clipboard.writeText(s);
|
||||
//alert("Support information copied to clipboard");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$("#sleep-mode").click(function(e){
|
||||
console.log( "Blocking sleep mode = " + $("#sleep-mode").is(":checked"));
|
||||
$.ajax( {
|
||||
|
399
lib/ESP_DoubleResetDetector/ESP_DoubleResetDetector.h
Normal file
@ -0,0 +1,399 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_DoubleResetDetector.h
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_DoubleResetDetector is a library for the ESP8266/Arduino platform
|
||||
to enable trigger configure mode by resetting ESP32 / ESP8266 twice.
|
||||
|
||||
Forked from DataCute https://github.com/datacute/DoubleResetDetector
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_DoubleResetDetector
|
||||
Licensed under MIT license
|
||||
Version: 1.3.1
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 15/12/2019 Initial coding
|
||||
1.0.1 K Hoang 30/12/2019 Now can use EEPROM or SPIFFS for both ESP8266 and ESP32. RTC still OK for ESP8266
|
||||
1.0.2 K Hoang 10/04/2020 Fix bug by left-over cpp file and in example.
|
||||
1.0.3 K Hoang 13/05/2020 Update to use LittleFS for ESP8266 core 2.7.1+
|
||||
1.1.0 K Hoang 04/12/2020 Add support to LittleFS for ESP32 using LITTLEFS Library
|
||||
1.1.1 K Hoang 28/12/2020 Suppress all possible compiler warnings
|
||||
1.1.2 K Hoang 10/10/2021 Update `platform.ini` and `library.json`
|
||||
1.2.0 K Hoang 26/11/2021 Auto detect ESP32 core and use either built-in LittleFS or LITTLEFS library
|
||||
1.2.1 K Hoang 26/11/2021 Fix compile error for ESP32 core v1.0.5-
|
||||
1.3.0 K Hoang 10/02/2022 Add support to new ESP32-S3
|
||||
1.3.1 K Hoang 04/03/2022 Add waitingForDRD() function to signal in DRD wating period
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ESP_DoubleResetDetector_H
|
||||
#define ESP_DoubleResetDetector_H
|
||||
|
||||
#ifndef DOUBLERESETDETECTOR_DEBUG
|
||||
#define DOUBLERESETDETECTOR_DEBUG false
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO) && (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
#ifndef ESP_DOUBLE_RESET_DETECTOR_VERSION
|
||||
#define ESP_DOUBLE_RESET_DETECTOR_VERSION "ESP_DoubleResetDetector v1.3.1"
|
||||
|
||||
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_MAJOR 1
|
||||
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_MINOR 3
|
||||
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_PATCH 1
|
||||
|
||||
#define ESP_DOUBLE_RESET_DETECTOR_VERSION_INT 1003001
|
||||
#endif
|
||||
|
||||
#define ESP_DOUBLERESETDETECTOR_VERSION ESP_DOUBLE_RESET_DETECTOR_VERSION
|
||||
|
||||
//#define ESP_DRD_USE_EEPROM false
|
||||
//#define ESP_DRD_USE_LITTLEFS false
|
||||
//#define ESP_DRD_USE_SPIFFS false
|
||||
//#define ESP8266_DRD_USE_RTC false //true
|
||||
|
||||
#ifdef ESP32
|
||||
#if (!ESP_DRD_USE_EEPROM && !ESP_DRD_USE_SPIFFS && !ESP_DRD_USE_LITTLEFS)
|
||||
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
#warning Neither EEPROM, SPIFFS nor LittleFS selected. Default to EEPROM
|
||||
#endif
|
||||
|
||||
#ifdef ESP_DRD_USE_EEPROM
|
||||
#undef ESP_DRD_USE_EEPROM
|
||||
#define ESP_DRD_USE_EEPROM true
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#if (!ESP8266_DRD_USE_RTC && !ESP_DRD_USE_EEPROM && !ESP_DRD_USE_SPIFFS && !ESP_DRD_USE_LITTLEFS)
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
#warning Neither RTC, EEPROM, LITTLEFS nor SPIFFS selected. Default to EEPROM
|
||||
#endif
|
||||
|
||||
#ifdef ESP_DRD_USE_EEPROM
|
||||
#undef ESP_DRD_USE_EEPROM
|
||||
#define ESP_DRD_USE_EEPROM true
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//default to use EEPROM, otherwise, use LITTLEFS (higher priority), then SPIFFS
|
||||
#if ESP_DRD_USE_EEPROM
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define FLAG_DATA_SIZE 4
|
||||
|
||||
#ifndef EEPROM_SIZE
|
||||
#define EEPROM_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_START
|
||||
#define EEPROM_START 256
|
||||
#endif
|
||||
|
||||
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
#if ESP_DRD_USE_LITTLEFS
|
||||
// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
|
||||
//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2)
|
||||
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
#warning Using ESP32 Core 1.0.6 or 2.0.0+
|
||||
#endif
|
||||
|
||||
// The library has been merged into esp32 core from release 1.0.6
|
||||
#include <LittleFS.h>
|
||||
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
#warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
|
||||
#endif
|
||||
|
||||
// The library has been merged into esp32 core from release 1.0.6
|
||||
#include <LITTLEFS.h> // https://github.com/lorol/LITTLEFS
|
||||
|
||||
#define FileFS LITTLEFS
|
||||
#define FS_Name "LittleFS"
|
||||
#endif
|
||||
#else
|
||||
#include "SPIFFS.h"
|
||||
// ESP32 core 1.0.4 still uses SPIFFS
|
||||
#define FileFS SPIFFS
|
||||
#endif
|
||||
|
||||
#else
|
||||
// From ESP8266 core 2.7.1
|
||||
#include <LittleFS.h>
|
||||
|
||||
#if ESP_DRD_USE_LITTLEFS
|
||||
#define FileFS LittleFS
|
||||
#else
|
||||
#define FileFS SPIFFS
|
||||
#endif
|
||||
|
||||
#endif // #if ESP_DRD_USE_EEPROM
|
||||
|
||||
|
||||
|
||||
#define DRD_FILENAME "/drd.dat"
|
||||
|
||||
#endif //#if ESP_DRD_USE_EEPROM
|
||||
|
||||
|
||||
|
||||
#define DOUBLERESETDETECTOR_FLAG_SET 0xD0D01234
|
||||
#define DOUBLERESETDETECTOR_FLAG_CLEAR 0xD0D04321
|
||||
|
||||
class DoubleResetDetector
|
||||
{
|
||||
public:
|
||||
DoubleResetDetector(int timeout, int address)
|
||||
{
|
||||
#if ESP_DRD_USE_EEPROM
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.printf("EEPROM size = %d, start = %d\n", EEPROM_SIZE, EEPROM_START);
|
||||
#endif
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
||||
// LittleFS / SPIFFS code
|
||||
if (!FileFS.begin())
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
|
||||
#if ESP_DRD_USE_LITTLEFS
|
||||
Serial.println("LittleFS failed!. Please use SPIFFS or EEPROM.");
|
||||
#else
|
||||
Serial.println("SPIFFS failed!. Please use LittleFS or EEPROM.");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
//RTC only for ESP8266
|
||||
#endif
|
||||
#endif
|
||||
|
||||
this->timeout = timeout * 1000;
|
||||
this->address = address;
|
||||
doubleResetDetected = false;
|
||||
waitingForDoubleReset = false;
|
||||
};
|
||||
|
||||
bool detectDoubleReset()
|
||||
{
|
||||
doubleResetDetected = detectRecentlyResetFlag();
|
||||
|
||||
if (doubleResetDetected)
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("doubleResetDetected");
|
||||
#endif
|
||||
|
||||
clearRecentlyResetFlag();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("No doubleResetDetected");
|
||||
#endif
|
||||
|
||||
setRecentlyResetFlag();
|
||||
waitingForDoubleReset = true;
|
||||
}
|
||||
|
||||
return doubleResetDetected;
|
||||
|
||||
};
|
||||
|
||||
bool waitingForDRD()
|
||||
{
|
||||
return waitingForDoubleReset;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (waitingForDoubleReset && millis() > timeout)
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Stop doubleResetDetecting");
|
||||
#endif
|
||||
|
||||
stop();
|
||||
}
|
||||
};
|
||||
|
||||
void stop()
|
||||
{
|
||||
clearRecentlyResetFlag();
|
||||
waitingForDoubleReset = false;
|
||||
};
|
||||
|
||||
bool doubleResetDetected;
|
||||
|
||||
|
||||
private:
|
||||
uint32_t DOUBLERESETDETECTOR_FLAG;
|
||||
unsigned long timeout;
|
||||
int address;
|
||||
bool waitingForDoubleReset;
|
||||
|
||||
bool detectRecentlyResetFlag()
|
||||
{
|
||||
#if (ESP_DRD_USE_EEPROM)
|
||||
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
||||
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG;
|
||||
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.printf("EEPROM Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
||||
#endif
|
||||
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
||||
// LittleFS / SPIFFS code
|
||||
if (FileFS.exists(DRD_FILENAME))
|
||||
{
|
||||
// if config file exists, load
|
||||
File file = FileFS.open(DRD_FILENAME, "r");
|
||||
|
||||
if (!file)
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Loading config file failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
file.readBytes((char *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
||||
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG;
|
||||
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
|
||||
#if ESP_DRD_USE_LITTLEFS
|
||||
Serial.printf("LittleFS Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
||||
#else
|
||||
Serial.printf("SPIFFS Flag read = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
//RTC only for ESP8266
|
||||
ESP.rtcUserMemoryRead(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
doubleResetDetected = (doubleResetDetectorFlag == DOUBLERESETDETECTOR_FLAG_SET);
|
||||
return doubleResetDetected;
|
||||
};
|
||||
|
||||
void setRecentlyResetFlag()
|
||||
{
|
||||
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG_SET;
|
||||
|
||||
DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_SET;
|
||||
|
||||
#if (ESP_DRD_USE_EEPROM)
|
||||
EEPROM.put(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
||||
EEPROM.commit();
|
||||
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
delay(1000);
|
||||
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
||||
|
||||
Serial.printf("SetFlag write = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
||||
#endif
|
||||
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
||||
// LittleFS / SPIFFS code
|
||||
File file = FileFS.open(DRD_FILENAME, "w");
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file...");
|
||||
#endif
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
||||
file.close();
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file OK");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file failed");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
//RTC only for ESP8266
|
||||
ESP.rtcUserMemoryWrite(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void clearRecentlyResetFlag()
|
||||
{
|
||||
doubleResetDetectorFlag = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
||||
DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
||||
|
||||
#if (ESP_DRD_USE_EEPROM)
|
||||
//DOUBLERESETDETECTOR_FLAG = DOUBLERESETDETECTOR_FLAG_CLEAR;
|
||||
EEPROM.put(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
||||
EEPROM.commit();
|
||||
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
delay(1000);
|
||||
EEPROM.get(EEPROM_START, DOUBLERESETDETECTOR_FLAG);
|
||||
|
||||
Serial.printf("ClearFlag write = 0x%X\n", DOUBLERESETDETECTOR_FLAG);
|
||||
#endif
|
||||
#elif ( ESP_DRD_USE_LITTLEFS || ESP_DRD_USE_SPIFFS )
|
||||
// LittleFS / SPIFFS code
|
||||
File file = FileFS.open(DRD_FILENAME, "w");
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file...");
|
||||
#endif
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t *) &DOUBLERESETDETECTOR_FLAG, sizeof(DOUBLERESETDETECTOR_FLAG));
|
||||
file.close();
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file OK");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (DOUBLERESETDETECTOR_DEBUG)
|
||||
Serial.println("Saving config file failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
//RTC only for ESP8266
|
||||
ESP.rtcUserMemoryWrite(address, &doubleResetDetectorFlag, sizeof(doubleResetDetectorFlag));
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
uint32_t doubleResetDetectorFlag;
|
||||
};
|
||||
#endif // ESP_DoubleResetDetector_H
|
2122
lib/ESP_WifiManager/ESP_WiFiManager-Impl.h
Normal file
72
lib/ESP_WifiManager/ESP_WiFiManager.h
Normal file
@ -0,0 +1,72 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_WiFiManager.h
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/Arduino platform
|
||||
(https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal
|
||||
inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Version: 1.9.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
1.3.0 K Hoang 04/12/2020 Add LittleFS support to ESP32 using LITTLEFS Library
|
||||
1.4.1 K Hoang 22/12/2020 Fix staticIP not saved. Add functions. Add complex examples. Sync with ESPAsync_WiFiManager
|
||||
1.4.2 K Hoang 14/01/2021 Fix examples' bug not using saved WiFi Credentials after losing all WiFi connections.
|
||||
1.4.3 K Hoang 23/01/2021 Fix examples' bug not saving Static IP in certain cases.
|
||||
1.5.0 K Hoang 12/02/2021 Add support to new ESP32-S2
|
||||
1.5.1 K Hoang 26/03/2021 Fix compiler error if setting Compiler Warnings to All. Retest with esp32 core v1.0.6
|
||||
1.5.2 K Hoang 08/04/2021 Fix example misleading messages.
|
||||
1.5.3 K Hoang 13/04/2021 Add dnsServer error message.
|
||||
1.6.0 K Hoang 20/04/2021 Add support to new ESP32-C3 using SPIFFS or EEPROM
|
||||
1.6.1 K Hoang 25/04/2021 Fix MultiWiFi bug. Fix captive-portal bug if CP AP address is not default 192.168.4.1
|
||||
1.7.0 K Hoang 06/05/2021 Set _timezoneName. Add support to new ESP32-S2 (METRO_ESP32S2, FUNHOUSE_ESP32S2, etc.)
|
||||
1.7.1 K Hoang 08/05/2021 Fix Json bug. Fix timezoneName not displayed in Info page.
|
||||
1.7.2 K Hoang 08/05/2021 Fix warnings with ESP8266 core v3.0.0
|
||||
1.7.3 K Hoang 29/07/2021 Fix MultiWiFi connection issue with ESP32 core v2.0.0-rc1+
|
||||
1.7.4 K Hoang 13/08/2021 Add WiFi scanning of hidden SSIDs
|
||||
1.7.5 K Hoang 10/10/2021 Update `platform.ini` and `library.json`
|
||||
1.7.6 K Hoang 26/11/2021 Auto detect ESP32 core and use either built-in LittleFS or LITTLEFS library
|
||||
1.7.7 K Hoang 26/11/2021 Fix compile error for ESP32 core v1.0.5-
|
||||
1.7.8 K Hoang 30/11/2021 Fix bug to permit using HTTP port different from 80. Fix bug
|
||||
1.8.0 K Hoang 29/12/2021 Fix `multiple-definitions` linker error and weird bug related to src_cpp
|
||||
1.9.0 K Hoang 17/01/2022 Enable compatibility with old code to include only ESP_WiFiManager.h
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ESP_WiFiManager_h
|
||||
#define ESP_WiFiManager_h
|
||||
|
||||
#include <ESP_WiFiManager.hpp> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
#include <ESP_WiFiManager-Impl.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
#endif // ESP_WiFiManager_h
|
||||
|
728
lib/ESP_WifiManager/ESP_WiFiManager.hpp
Normal file
128
lib/ESP_WifiManager/ESP_WiFiManager_Debug.h
Normal file
@ -0,0 +1,128 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_WiFiManager_Debug.h
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/Arduino platform
|
||||
(https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal
|
||||
inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Version: 1.9.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
1.3.0 K Hoang 04/12/2020 Add LittleFS support to ESP32 using LITTLEFS Library
|
||||
1.4.1 K Hoang 22/12/2020 Fix staticIP not saved. Add functions. Add complex examples. Sync with ESPAsync_WiFiManager
|
||||
1.4.2 K Hoang 14/01/2021 Fix examples' bug not using saved WiFi Credentials after losing all WiFi connections.
|
||||
1.4.3 K Hoang 23/01/2021 Fix examples' bug not saving Static IP in certain cases.
|
||||
1.5.0 K Hoang 12/02/2021 Add support to new ESP32-S2
|
||||
1.5.1 K Hoang 26/03/2021 Fix compiler error if setting Compiler Warnings to All. Retest with esp32 core v1.0.6
|
||||
1.5.2 K Hoang 08/04/2021 Fix example misleading messages.
|
||||
1.5.3 K Hoang 13/04/2021 Add dnsServer error message.
|
||||
1.6.0 K Hoang 20/04/2021 Add support to new ESP32-C3 using SPIFFS or EEPROM
|
||||
1.6.1 K Hoang 25/04/2021 Fix MultiWiFi bug. Fix captive-portal bug if CP AP address is not default 192.168.4.1
|
||||
1.7.0 K Hoang 06/05/2021 Set _timezoneName. Add support to new ESP32-S2 (METRO_ESP32S2, FUNHOUSE_ESP32S2, etc.)
|
||||
1.7.1 K Hoang 08/05/2021 Fix Json bug. Fix timezoneName not displayed in Info page.
|
||||
1.7.2 K Hoang 08/05/2021 Fix warnings with ESP8266 core v3.0.0
|
||||
1.7.3 K Hoang 29/07/2021 Fix MultiWiFi connection issue with ESP32 core v2.0.0-rc1+
|
||||
1.7.4 K Hoang 13/08/2021 Add WiFi scanning of hidden SSIDs
|
||||
1.7.5 K Hoang 10/10/2021 Update `platform.ini` and `library.json`
|
||||
1.7.6 K Hoang 26/11/2021 Auto detect ESP32 core and use either built-in LittleFS or LITTLEFS library
|
||||
1.7.7 K Hoang 26/11/2021 Fix compile error for ESP32 core v1.0.5-
|
||||
1.7.8 K Hoang 30/11/2021 Fix bug to permit using HTTP port different from 80. Fix bug
|
||||
1.8.0 K Hoang 29/12/2021 Fix `multiple-definitions` linker error and weird bug related to src_cpp
|
||||
1.9.0 K Hoang 17/01/2022 Enable compatibility with old code to include only ESP_WiFiManager.h
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ESP_WiFiManager_Debug_H
|
||||
#define ESP_WiFiManager_Debug_H
|
||||
|
||||
#ifdef WIFIMGR_DEBUG_PORT
|
||||
#define WM_DBG_PORT WIFIMGR_DEBUG_PORT
|
||||
#else
|
||||
#define WM_DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _WIFIMGR_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _WIFIMGR_LOGLEVEL_
|
||||
#define _WIFIMGR_LOGLEVEL_ 0
|
||||
#endif
|
||||
|
||||
const char WM_MARK[] = "[WM] ";
|
||||
const char WM_SP[] = " ";
|
||||
|
||||
#define WM_PRINT WM_DBG_PORT.print
|
||||
#define WM_PRINTLN WM_DBG_PORT.println
|
||||
|
||||
#define WM_PRINT_MARK WM_PRINT(WM_MARK)
|
||||
#define WM_PRINT_SP WM_PRINT(WM_SP)
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#define LOGERROR(x) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINTLN(x); }
|
||||
#define LOGERROR0(x) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT(x); }
|
||||
#define LOGERROR1(x,y) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); }
|
||||
#define LOGERROR2(x,y,z) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); }
|
||||
#define LOGERROR3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#define LOGWARN(x) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINTLN(x); }
|
||||
#define LOGWARN0(x) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT(x); }
|
||||
#define LOGWARN1(x,y) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); }
|
||||
#define LOGWARN2(x,y,z) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); }
|
||||
#define LOGWARN3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#define LOGINFO(x) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINTLN(x); }
|
||||
#define LOGINFO0(x) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT(x); }
|
||||
#define LOGINFO1(x,y) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); }
|
||||
#define LOGINFO2(x,y,z) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); }
|
||||
#define LOGINFO3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#define LOGDEBUG(x) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINTLN(x); }
|
||||
#define LOGDEBUG0(x) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT(x); }
|
||||
#define LOGDEBUG1(x,y) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); }
|
||||
#define LOGDEBUG2(x,y,z) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); }
|
||||
#define LOGDEBUG3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#endif //ESP_WiFiManager_Debug_H
|
2150
lib/ESP_WifiManager/utils/TZ.h
Normal file
@ -195,11 +195,7 @@ uint8_t OneWire::reset(void)
|
||||
// Write a bit. Port and bit is used to cut lookup time and provide
|
||||
// more certain timing.
|
||||
//
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
void IRAM_ATTR OneWire::write_bit(uint8_t v)
|
||||
#else
|
||||
void OneWire::write_bit(uint8_t v)
|
||||
#endif
|
||||
{
|
||||
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
|
||||
volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
|
||||
@ -227,11 +223,7 @@ void OneWire::write_bit(uint8_t v)
|
||||
// Read a bit. Port and bit is used to cut lookup time and provide
|
||||
// more certain timing.
|
||||
//
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
uint8_t IRAM_ATTR OneWire::read_bit(void)
|
||||
#else
|
||||
uint8_t OneWire::read_bit(void)
|
||||
#endif
|
||||
{
|
||||
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
|
||||
volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
|
||||
@ -585,4 +577,4 @@ uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
@ -99,18 +99,10 @@ class OneWire
|
||||
|
||||
// Write a bit. The bus is always left powered at the end, see
|
||||
// note in write() about that.
|
||||
#if defined (ARDUINO_ARCH_ESP32)
|
||||
void IRAM_ATTR write_bit(uint8_t v);
|
||||
#else
|
||||
void write_bit(uint8_t v);
|
||||
#endif
|
||||
|
||||
// Read a bit.
|
||||
#if defined (ARDUINO_ARCH_ESP32)
|
||||
uint8_t IRAM_ATTR read_bit(void);
|
||||
#else
|
||||
uint8_t read_bit(void);
|
||||
#endif
|
||||
|
||||
// Stop forcing power onto the bus. You only need to do this if
|
||||
// you used the 'power' flag to write() or used a write_bit() call
|
||||
@ -187,4 +179,4 @@ class OneWire
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // OneWire_h
|
||||
#endif // OneWire_h
|
@ -127,10 +127,14 @@
|
||||
static inline __attribute__((always_inline))
|
||||
IO_REG_TYPE directRead(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
return (GPIO.in.val >> pin) & 0x1;
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
return (GPIO.in >> pin) & 0x1;
|
||||
else if ( pin < 40 )
|
||||
else if ( pin < 46 )
|
||||
return (GPIO.in1.val >> (pin - 32)) & 0x1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -138,38 +142,38 @@ IO_REG_TYPE directRead(IO_REG_TYPE pin)
|
||||
static inline __attribute__((always_inline))
|
||||
void directWriteLow(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1tc = ((uint32_t)1 << pin);
|
||||
else if ( pin < 34 )
|
||||
else if ( pin < 46 )
|
||||
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directWriteHigh(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
|
||||
#else // plain ESP32
|
||||
if ( pin < 32 )
|
||||
GPIO.out_w1ts = ((uint32_t)1 << pin);
|
||||
else if ( pin < 34 )
|
||||
else if ( pin < 46 )
|
||||
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directModeInput(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
GPIO.enable_w1tc.val = ((uint32_t)1 << (pin));
|
||||
#else
|
||||
if ( digitalPinIsValid(pin) )
|
||||
{
|
||||
#if defined(ESP_ARDUINO_VERSION)
|
||||
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0)
|
||||
int pin_io = rtc_io_number_get((gpio_num_t)pin);
|
||||
uint32_t rtc_reg(rtc_io_desc[pin_io].reg);
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
{
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin_io].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin_io].pullup | rtc_io_desc[pin_io].pulldown);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
|
||||
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
@ -177,40 +181,25 @@ void directModeInput(IO_REG_TYPE pin)
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// Input
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1tc = ((uint32_t)1 << pin);
|
||||
else
|
||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
|
||||
uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
|
||||
pinFunction |= FUN_IE; // input enable but required for output as well?
|
||||
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
|
||||
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
|
||||
|
||||
GPIO.pin[pin].val = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void directModeOutput(IO_REG_TYPE pin)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
GPIO.enable_w1ts.val = ((uint32_t)1 << (pin));
|
||||
#else
|
||||
if ( digitalPinIsValid(pin) && pin <= 33 ) // pins above 33 can be only inputs
|
||||
{
|
||||
#if defined(ESP_ARDUINO_VERSION)
|
||||
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0)
|
||||
int pin_io = rtc_io_number_get((gpio_num_t)pin);
|
||||
uint32_t rtc_reg(rtc_io_desc[pin_io].reg);
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
{
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin_io].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin_io].pullup | rtc_io_desc[pin_io].pulldown);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4
|
||||
uint32_t rtc_reg(rtc_gpio_desc[pin].reg);
|
||||
|
||||
if ( rtc_reg ) // RTC pins PULL settings
|
||||
@ -218,21 +207,14 @@ void directModeOutput(IO_REG_TYPE pin)
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// Output
|
||||
if ( pin < 32 )
|
||||
GPIO.enable_w1ts = ((uint32_t)1 << pin);
|
||||
else // already validated to pins <= 33
|
||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
|
||||
uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
|
||||
pinFunction |= FUN_IE; // input enable but required for output as well?
|
||||
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
|
||||
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
|
||||
|
||||
GPIO.pin[pin].val = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DIRECT_READ(base, pin) directRead(pin)
|
||||
@ -445,6 +427,20 @@ void directWriteHigh(IO_REG_TYPE mask)
|
||||
#define DIRECT_MODE_INPUT(base, mask) directModeInput(mask)
|
||||
#define DIRECT_MODE_OUTPUT(base, mask) directModeOutput(mask)
|
||||
|
||||
#elif defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
|
||||
#define delayMicroseconds(time) busy_wait_us(time)
|
||||
#define PIN_TO_BASEREG(pin) (0)
|
||||
#define PIN_TO_BITMASK(pin) (pin)
|
||||
#define IO_REG_TYPE unsigned int
|
||||
#define IO_REG_BASE_ATTR
|
||||
#define IO_REG_MASK_ATTR
|
||||
#define DIRECT_READ(base, pin) digitalRead(pin)
|
||||
#define DIRECT_WRITE_LOW(base, pin) digitalWrite(pin, LOW)
|
||||
#define DIRECT_WRITE_HIGH(base, pin) digitalWrite(pin, HIGH)
|
||||
#define DIRECT_MODE_INPUT(base, pin) pinMode(pin,INPUT)
|
||||
#define DIRECT_MODE_OUTPUT(base, pin) pinMode(pin,OUTPUT)
|
||||
#warning "OneWire. RP2040 in Fallback mode. Using API calls for pinMode,digitalRead and digitalWrite."
|
||||
|
||||
#else
|
||||
#define PIN_TO_BASEREG(pin) (0)
|
||||
#define PIN_TO_BITMASK(pin) (pin)
|
||||
@ -460,4 +456,4 @@ void directWriteHigh(IO_REG_TYPE mask)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
@ -282,7 +282,8 @@ int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8
|
||||
useWire->beginTransmission(devAddr);
|
||||
useWire->write(regAddr);
|
||||
useWire->endTransmission();
|
||||
useWire->beginTransmission(devAddr);
|
||||
// See: https://github.com/espressif/arduino-esp32/issues/6674
|
||||
// useWire->beginTransmission(devAddr);
|
||||
useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH));
|
||||
|
||||
for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) {
|
||||
@ -1485,4 +1486,4 @@ uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
|
||||
return rxBufferLength - rxBufferIndex;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
@ -308,4 +308,4 @@ class I2Cdev {
|
||||
|
||||
#endif // I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
|
||||
|
||||
#endif /* _I2CDEV_H_ */
|
||||
#endif /* _I2CDEV_H_ */
|
@ -2556,8 +2556,8 @@ void MPU6050_Base::setClockSource(uint8_t source) {
|
||||
* -------------+------------------
|
||||
* 0 | 1.25 Hz
|
||||
* 1 | 2.5 Hz
|
||||
* 2 | 5 Hz
|
||||
* 3 | 10 Hz
|
||||
* 2 | 20 Hz
|
||||
* 3 | 40 Hz
|
||||
* </pre>
|
||||
*
|
||||
* For further information regarding the MPU-60X0's power modes, please refer to
|
||||
@ -3371,25 +3371,27 @@ void MPU6050_Base::PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops){
|
||||
resetDMP();
|
||||
}
|
||||
|
||||
void MPU6050_Base::PrintActiveOffsets() {
|
||||
uint8_t AOffsetRegister = (getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77;
|
||||
int16_t Data[3];
|
||||
//Serial.print(F("Offset Register 0x"));
|
||||
//Serial.print(AOffsetRegister>>4,HEX);Serial.print(AOffsetRegister&0x0F,HEX);
|
||||
Serial.print(F("\n// X Accel Y Accel Z Accel X Gyro Y Gyro Z Gyro\n// OFFSETS "));
|
||||
if(AOffsetRegister == 0x06) I2Cdev::readWords(devAddr, AOffsetRegister, 3, (uint16_t *)Data, I2Cdev::readTimeout, wireObj);
|
||||
else {
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister, 1, (uint16_t *)Data, I2Cdev::readTimeout, wireObj);
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister+3, 1, (uint16_t *)Data+1, I2Cdev::readTimeout, wireObj);
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister+6, 1, (uint16_t *)Data+2, I2Cdev::readTimeout, wireObj);
|
||||
}
|
||||
// A_OFFSET_H_READ_A_OFFS(Data);
|
||||
Serial.print((float)Data[0], 5); Serial.print(", ");
|
||||
Serial.print((float)Data[1], 5); Serial.print(", ");
|
||||
Serial.print((float)Data[2], 5); Serial.print(", ");
|
||||
I2Cdev::readWords(devAddr, 0x13, 3, (uint16_t *)Data, I2Cdev::readTimeout, wireObj);
|
||||
// XG_OFFSET_H_READ_OFFS_USR(Data);
|
||||
Serial.print((float)Data[0], 5); Serial.print(", ");
|
||||
Serial.print((float)Data[1], 5); Serial.print(", ");
|
||||
Serial.print((float)Data[2], 5); Serial.print("\n");
|
||||
int16_t * MPU6050_Base::GetActiveOffsets() {
|
||||
uint8_t AOffsetRegister = (getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77;
|
||||
if(AOffsetRegister == 0x06) I2Cdev::readWords(devAddr, AOffsetRegister, 3, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj);
|
||||
else {
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister, 1, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj);
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister+3, 1, (uint16_t *)(offsets+1), I2Cdev::readTimeout, wireObj);
|
||||
I2Cdev::readWords(devAddr, AOffsetRegister+6, 1, (uint16_t *)(offsets+2), I2Cdev::readTimeout, wireObj);
|
||||
}
|
||||
I2Cdev::readWords(devAddr, 0x13, 3, (uint16_t *)(offsets+3), I2Cdev::readTimeout, wireObj);
|
||||
return offsets;
|
||||
}
|
||||
|
||||
void MPU6050_Base::PrintActiveOffsets() {
|
||||
GetActiveOffsets();
|
||||
// A_OFFSET_H_READ_A_OFFS(Data);
|
||||
Serial.print((float)offsets[0], 5); Serial.print(",\t");
|
||||
Serial.print((float)offsets[1], 5); Serial.print(",\t");
|
||||
Serial.print((float)offsets[2], 5); Serial.print(",\t");
|
||||
|
||||
// XG_OFFSET_H_READ_OFFS_USR(Data);
|
||||
Serial.print((float)offsets[3], 5); Serial.print(",\t");
|
||||
Serial.print((float)offsets[4], 5); Serial.print(",\t");
|
||||
Serial.print((float)offsets[5], 5); Serial.print("\n\n");
|
||||
}
|
@ -832,12 +832,16 @@ class MPU6050_Base {
|
||||
void CalibrateAccel(uint8_t Loops = 15);// Fine tune after setting offsets with less Loops.
|
||||
void PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops); // Does the math
|
||||
void PrintActiveOffsets(); // See the results of the Calibration
|
||||
int16_t * GetActiveOffsets();
|
||||
|
||||
protected:
|
||||
uint8_t devAddr;
|
||||
void *wireObj;
|
||||
uint8_t buffer[14];
|
||||
uint32_t fifoTimeout = MPU6050_FIFO_DEFAULT_TIMEOUT;
|
||||
|
||||
private:
|
||||
int16_t offsets[6];
|
||||
};
|
||||
|
||||
#ifndef I2CDEVLIB_MPU6050_TYPEDEF
|
||||
@ -845,4 +849,4 @@ class MPU6050_Base {
|
||||
typedef MPU6050_Base MPU6050;
|
||||
#endif
|
||||
|
||||
#endif /* _MPU6050_H_ */
|
||||
#endif /* _MPU6050_H_ */
|
@ -15,7 +15,7 @@ include_dir = lib
|
||||
[common_env_data]
|
||||
upload_speed = 921600
|
||||
monitor_speed = 115200
|
||||
platform = espressif8266 @ 3.2.0
|
||||
platform = espressif8266 @ 4.0.1
|
||||
framework = arduino
|
||||
board = d1_mini
|
||||
build_unflags =
|
||||
@ -33,16 +33,16 @@ build_flags =
|
||||
-D EMBED_HTML # If this is not used the html files needs to be on the file system (can be uploaded)
|
||||
-D USER_SSID=\""\"" # =\""myssid\""
|
||||
-D USER_SSID_PWD=\""\"" # =\""mypwd\""
|
||||
-D CFG_APPVER="\"1.0.0\""
|
||||
-D CFG_GITREV=\""beta-1\""
|
||||
-D CFG_APPVER="\"1.1.0\""
|
||||
-D CFG_GITREV=\""beta-2\""
|
||||
#!python script/git_rev.py
|
||||
lib_deps = # Switched to forks for better version control.
|
||||
# Using local copy of these libraries
|
||||
#https://github.com/jrowberg/i2cdevlib.git#<document>
|
||||
#https://github.com/PaulStoffregen/OneWire
|
||||
#https://github.com/milesburton/Arduino-Temperature-Control-Library
|
||||
https://github.com/mp-se/ESP_WiFiManager#v1.9.0 # https://github.com/khoih-prog/ESP_WiFiManager
|
||||
https://github.com/mp-se/ESP_DoubleResetDetector#v1.2.1 # https://github.com/khoih-prog/ESP_DoubleResetDetector
|
||||
#https://github.com/mp-se/i2cdevlib.git#<document>
|
||||
#https://github.com/mp-se/OneWire # Using this version; https://github.com/arendst/Tasmota/tree/development/lib/lib_basic/OneWire-Stickbreaker
|
||||
#https://github.com/mp-se/Arduino-Temperature-Control-Library
|
||||
#https://github.com/khoih-prog/ESP_WiFiManager
|
||||
#https://github.com/khoih-prog/ESP_DoubleResetDetector
|
||||
https://github.com/mp-se/tinyexpr # https://github.com/codeplea/tinyexpr
|
||||
https://github.com/mp-se/incbin # https://github.com/graphitemaster/incbin
|
||||
https://github.com/mp-se/Arduino-Log#1.1.1 # https://github.com/thijse/Arduino-Log
|
||||
@ -128,7 +128,7 @@ board_build.filesystem = littlefs
|
||||
|
||||
[env:gravity32-release]
|
||||
framework = arduino
|
||||
platform = espressif32 @ 3.5.0
|
||||
platform = espressif32 @ 5.0.0
|
||||
upload_speed = ${common_env_data.upload_speed}
|
||||
monitor_speed = ${common_env_data.monitor_speed}
|
||||
extra_scripts =
|
||||
@ -153,8 +153,8 @@ build_flags =
|
||||
-D MAIN_DISABLE_LOGGING
|
||||
lib_deps =
|
||||
${common_env_data.lib_deps}
|
||||
https://github.com/lorol/LITTLEFS#1.0.6
|
||||
https://github.com/mp-se/NimBLE-Arduino#1.3.8 # https://github.com/h2zero/NimBLE-Arduino
|
||||
lib_ignore =
|
||||
board = featheresp32
|
||||
build_type = release
|
||||
board_build.partitions = part32.csv
|
||||
@ -163,7 +163,7 @@ monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:gravity32-perf]
|
||||
framework = arduino
|
||||
platform = espressif32 @ 3.5.0
|
||||
platform = espressif32 @ 5.0.0
|
||||
upload_speed = ${common_env_data.upload_speed}
|
||||
monitor_speed = ${common_env_data.monitor_speed}
|
||||
extra_scripts =
|
||||
@ -179,35 +179,9 @@ build_flags =
|
||||
-D LOG_LEVEL=5
|
||||
lib_deps =
|
||||
${common_env_data.lib_deps}
|
||||
https://github.com/lorol/LITTLEFS#1.0.6
|
||||
https://github.com/mp-se/NimBLE-Arduino#1.3.8 # https://github.com/h2zero/NimBLE-Arduino
|
||||
board = featheresp32
|
||||
build_type = release
|
||||
board_build.partitions = part32.csv
|
||||
board_build.filesystem = littlefs
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
#[env:gravity32-release2]
|
||||
#framework = arduino
|
||||
#platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip # build fails
|
||||
#platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.2/platform-tasmota-espressif32-2.0.2.zip
|
||||
#platform = espressif32 @ 4.1.0
|
||||
#upload_speed = ${common_env_data.upload_speed}
|
||||
#monitor_speed = ${common_env_data.monitor_speed}
|
||||
#extra_scripts =
|
||||
# script/copy_html.py
|
||||
# script/copy_firmware.py
|
||||
# script/create_versionjson.py
|
||||
#build_unflags =
|
||||
# ${common_env_data.build_unflags}
|
||||
#build_flags =
|
||||
# ${common_env_data.build_flags}
|
||||
# -D ESPRESSIF32_20 # v2.0 framework
|
||||
# -D LOG_LEVEL=5
|
||||
#lib_deps =
|
||||
# ${common_env_data.lib_deps}
|
||||
# https://github.com/mp-se/NimBLE-Arduino#1.3.8 # https://github.com/h2zero/NimBLE-Arduino
|
||||
#board = featheresp32
|
||||
#build_type = release
|
||||
#board_build.partitions = part32.csv
|
||||
#board_build.filesystem = littlefs
|
||||
|
42
src/calc.cpp
@ -35,7 +35,8 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
||||
int noAngles = 0;
|
||||
RawFormulaData fd2;
|
||||
|
||||
// Check how many valid values we have got and make sure we have a full series.
|
||||
// Check how many valid values we have got and make sure we have a full
|
||||
// series.
|
||||
for (int i = 0; i < FORMULA_DATA_SIZE; i++) {
|
||||
if (fd.a[i]) {
|
||||
fd2.a[noAngles] = fd.a[i];
|
||||
@ -50,7 +51,7 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
||||
order, noAngles);
|
||||
#endif
|
||||
|
||||
if (noAngles <3) {
|
||||
if (noAngles < 3) {
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(F("CALC: Not enough values for deriving formula"));
|
||||
return ERR_FORMULA_NOTENOUGHVALUES;
|
||||
@ -62,7 +63,8 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
||||
// Returned value is 0 if no error
|
||||
if (ret == 0) {
|
||||
#if LOG_LEVEL == 6 && !defined(CALC_DISABLE_LOGGING)
|
||||
Log.verbose(F("CALC: Finshied processing data points, order = %d." CR), order);
|
||||
Log.verbose(F("CALC: Finshied processing data points, order = %d." CR),
|
||||
order);
|
||||
#endif
|
||||
|
||||
// Print the formula based on 'order'
|
||||
@ -96,18 +98,18 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
||||
|
||||
// If the deviation is more than 2 degress we mark it as failed.
|
||||
if (dev * 1000 > myAdvancedConfig.getMaxFormulaCreationDeviation()) {
|
||||
char s[20];
|
||||
snprintf(&s[0], sizeof(s), "%.8f", dev);
|
||||
Log.error(F("CALC: Deviation to large: %s" CR), &s[0]);
|
||||
char s[120];
|
||||
snprintf(&s[0], sizeof(s),
|
||||
"CALC: Validation failed on angle %f, deviation too large "
|
||||
"%.2f SG, formula order %d",
|
||||
fd.a[i], dev * 1000, order);
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(&s[0]);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(
|
||||
F("CALC: Error validating created formula. Deviation to large, "
|
||||
"formula rejected."));
|
||||
return ERR_FORMULA_UNABLETOFFIND;
|
||||
}
|
||||
|
||||
@ -173,16 +175,15 @@ double calculateGravity(double angle, double temp, const char *tempFormula) {
|
||||
//
|
||||
// Source: https://homebrewacademy.com/hydrometer-temperature-correction/
|
||||
//
|
||||
double gravityTemperatureCorrectionC(double gravity, double tempC,
|
||||
double gravityTemperatureCorrectionC(double gravitySG, double tempC,
|
||||
double calTempC) {
|
||||
#if LOG_LEVEL == 6 && !defined(CALC_DISABLE_LOGGING)
|
||||
Log.verbose(F("CALC: Adjusting gravity based on temperature, gravity %F, "
|
||||
"temp %F, calTemp %F." CR),
|
||||
gravity, tempC, calTempC);
|
||||
gravitySG, tempC, calTempC);
|
||||
#endif
|
||||
// float tempF = convertCtoF(tempC);
|
||||
// float calTempF = convertCtoF(calTempC);
|
||||
|
||||
double tempF = convertCtoF(tempC);
|
||||
double calTempF = convertCtoF(calTempC);
|
||||
const char *formula =
|
||||
"gravity*((1.00130346-0.000134722124*temp+0.00000204052596*temp^2-0."
|
||||
"00000000232820948*temp^3)/"
|
||||
@ -191,7 +192,7 @@ double gravityTemperatureCorrectionC(double gravity, double tempC,
|
||||
|
||||
// Store variable names and pointers.
|
||||
te_variable vars[] = {
|
||||
{"gravity", &gravity}, {"temp", &tempC}, {"cal", &calTempC}};
|
||||
{"gravity", &gravitySG}, {"temp", &tempF}, {"cal", &calTempF}};
|
||||
|
||||
int err;
|
||||
// Compile the expression with variables.
|
||||
@ -202,9 +203,10 @@ double gravityTemperatureCorrectionC(double gravity, double tempC,
|
||||
te_free(expr);
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(CALC_DISABLE_LOGGING)
|
||||
char s[10];
|
||||
snprintf(&s[0], sizeof(s), "%.8f", g);
|
||||
Log.verbose(F("CALC: Corrected gravity is %s." CR), &s[0]);
|
||||
char s[80];
|
||||
snprintf(&s[0], sizeof(s), "Corrected gravity=%.8f, input gravity=%.8f", g,
|
||||
gravitySG);
|
||||
Log.verbose(F("CALC: %s." CR), &s[0]);
|
||||
#endif
|
||||
return g;
|
||||
}
|
||||
@ -213,7 +215,7 @@ double gravityTemperatureCorrectionC(double gravity, double tempC,
|
||||
errLog.addEntry(
|
||||
"CALC: Failed to parse expression for gravity temperature correction " +
|
||||
String(err));
|
||||
return gravity;
|
||||
return gravitySG;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
@ -32,9 +32,8 @@ SOFTWARE.
|
||||
|
||||
double calculateGravity(double angle, double tempC,
|
||||
const char *tempFormula = 0);
|
||||
double gravityTemperatureCorrectionC(
|
||||
double gravity, double tempC,
|
||||
double calTempC = myAdvancedConfig.getDefaultCalibrationTemp());
|
||||
double gravityTemperatureCorrectionC(double gravity, double tempC,
|
||||
double calTempC);
|
||||
int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
||||
int formulaBufferSize, int order);
|
||||
|
||||
|
@ -86,12 +86,14 @@ void Config::createJson(DynamicJsonDocument& doc) {
|
||||
doc[PARAM_PUSH_MQTT_USER] = getMqttUser();
|
||||
doc[PARAM_PUSH_MQTT_PASS] = getMqttPass();
|
||||
doc[PARAM_SLEEP_INTERVAL] = getSleepInterval();
|
||||
doc[PARAM_VOLTAGEFACTOR] = getVoltageFactor();
|
||||
doc[PARAM_VOLTAGE_FACTOR] = getVoltageFactor();
|
||||
doc[PARAM_VOLTAGE_CONFIG] = getVoltageConfig();
|
||||
doc[PARAM_GRAVITY_FORMULA] = getGravityFormula();
|
||||
doc[PARAM_GRAVITY_FORMAT] = String(getGravityFormat());
|
||||
doc[PARAM_TEMP_ADJ] = getTempSensorAdjC();
|
||||
doc[PARAM_GRAVITY_TEMP_ADJ] = isGravityTempAdj();
|
||||
doc[PARAM_GYRO_TEMP] = isGyroTemp();
|
||||
doc[PARAM_STORAGE_SLEEP] = isStorageSleep();
|
||||
|
||||
JsonObject cal = doc.createNestedObject(PARAM_GYRO_CALIBRATION);
|
||||
cal["ax"] = _gyroCalibration.ax;
|
||||
@ -148,7 +150,7 @@ bool Config::saveFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
DynamicJsonDocument doc(CFG_JSON_BUFSIZE);
|
||||
DynamicJsonDocument doc(3000);
|
||||
createJson(doc);
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(DISABLE_LOGGING)
|
||||
@ -190,7 +192,7 @@ bool Config::loadFile() {
|
||||
Log.notice(F("CFG : Size of configuration file=%d bytes." CR),
|
||||
configFile.size());
|
||||
|
||||
DynamicJsonDocument doc(CFG_JSON_BUFSIZE);
|
||||
DynamicJsonDocument doc(3000);
|
||||
DeserializationError err = deserializeJson(doc, configFile);
|
||||
#if LOG_LEVEL == 6
|
||||
serializeJson(doc, Serial);
|
||||
@ -253,14 +255,18 @@ bool Config::loadFile() {
|
||||
|
||||
if (!doc[PARAM_SLEEP_INTERVAL].isNull())
|
||||
setSleepInterval(doc[PARAM_SLEEP_INTERVAL].as<int>());
|
||||
if (!doc[PARAM_VOLTAGEFACTOR].isNull())
|
||||
setVoltageFactor(doc[PARAM_VOLTAGEFACTOR].as<float>());
|
||||
if (!doc[PARAM_VOLTAGE_FACTOR].isNull())
|
||||
setVoltageFactor(doc[PARAM_VOLTAGE_FACTOR].as<float>());
|
||||
if (!doc[PARAM_VOLTAGE_CONFIG].isNull())
|
||||
setVoltageConfig(doc[PARAM_VOLTAGE_CONFIG].as<float>());
|
||||
if (!doc[PARAM_GRAVITY_FORMULA].isNull())
|
||||
setGravityFormula(doc[PARAM_GRAVITY_FORMULA]);
|
||||
if (!doc[PARAM_GRAVITY_TEMP_ADJ].isNull())
|
||||
setGravityTempAdj(doc[PARAM_GRAVITY_TEMP_ADJ].as<bool>());
|
||||
if (!doc[PARAM_GYRO_TEMP].isNull())
|
||||
setGyroTemp(doc[PARAM_GYRO_TEMP].as<bool>());
|
||||
if (!doc[PARAM_STORAGE_SLEEP].isNull())
|
||||
setStorageSleep(doc[PARAM_STORAGE_SLEEP].as<bool>());
|
||||
if (!doc[PARAM_GRAVITY_FORMAT].isNull()) {
|
||||
String s = doc[PARAM_GRAVITY_FORMAT];
|
||||
setGravityFormat(s.charAt(0));
|
||||
@ -390,7 +396,8 @@ bool AdvancedConfig::saveFile() {
|
||||
doc[PARAM_HW_PUSH_INTERVAL_HTTP3] = this->getPushIntervalHttp3();
|
||||
doc[PARAM_HW_PUSH_INTERVAL_INFLUX] = this->getPushIntervalInflux();
|
||||
doc[PARAM_HW_PUSH_INTERVAL_MQTT] = this->getPushIntervalMqtt();
|
||||
doc[PARAM_HW_TEMPSENSOR_RESOLUTION] = this->getTempSensorResolution();
|
||||
doc[PARAM_HW_TEMPSENSOR_RESOLUTION] = this->getTempSensorResolution();
|
||||
doc[PARAM_HW_IGNORE_LOW_ANGLES] = this->isIgnoreLowAnges();
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(DISABLE_LOGGING)
|
||||
serializeJson(doc, Serial);
|
||||
@ -478,7 +485,10 @@ bool AdvancedConfig::loadFile() {
|
||||
if (!doc[PARAM_HW_PUSH_INTERVAL_MQTT].isNull())
|
||||
this->setPushIntervalMqtt(doc[PARAM_HW_PUSH_INTERVAL_MQTT].as<int>());
|
||||
if (!doc[PARAM_HW_TEMPSENSOR_RESOLUTION].isNull())
|
||||
this->setTempSensorResolution(doc[PARAM_HW_TEMPSENSOR_RESOLUTION].as<int>());
|
||||
this->setTempSensorResolution(
|
||||
doc[PARAM_HW_TEMPSENSOR_RESOLUTION].as<int>());
|
||||
if (!doc[PARAM_HW_IGNORE_LOW_ANGLES].isNull())
|
||||
setIgnoreLowAnges(doc[PARAM_HW_IGNORE_LOW_ANGLES].as<bool>());
|
||||
|
||||
Log.notice(F("CFG : Configuration file " CFG_HW_FILENAME " loaded." CR));
|
||||
return true;
|
||||
|
@ -27,8 +27,6 @@ SOFTWARE.
|
||||
#include <helper.hpp>
|
||||
#include <resources.hpp>
|
||||
|
||||
#define CFG_JSON_BUFSIZE 3192
|
||||
|
||||
#define CFG_APPNAME "GravityMon" // Name of firmware
|
||||
#define CFG_FILENAME "/gravitymon.json" // Name of config file
|
||||
#define CFG_HW_FILENAME "/hardware.json" // Name of config file for hw
|
||||
@ -56,12 +54,12 @@ struct RawFormulaData {
|
||||
|
||||
class AdvancedConfig {
|
||||
private:
|
||||
int _wifiPortalTimeout = 120;
|
||||
int _wifiConnectTimeout = 20;
|
||||
float _maxFormulaCreationDeviation = 1.6;
|
||||
float _defaultCalibrationTemp = 20.0;
|
||||
int _wifiPortalTimeout = 120; // seconds
|
||||
int _wifiConnectTimeout = 20; // seconds
|
||||
float _maxFormulaCreationDeviation = 3; // SG
|
||||
float _defaultCalibrationTemp = 20.0; // C
|
||||
int _gyroSensorMovingThreashold = 500;
|
||||
int _tempSensorResolution = 9;
|
||||
int _tempSensorResolution = 9; // bits
|
||||
int _gyroReadCount = 50;
|
||||
int _gyroReadDelay = 3150; // us, empirical, to hold sampling to 200 Hz
|
||||
int _pushTimeout = 10; // seconds
|
||||
@ -70,6 +68,7 @@ class AdvancedConfig {
|
||||
int _pushIntervalHttp3 = 0;
|
||||
int _pushIntervalInflux = 0;
|
||||
int _pushIntervalMqtt = 0;
|
||||
bool _IgnoreLowAnges = false;
|
||||
|
||||
public:
|
||||
int getWifiPortalTimeout() { return _wifiPortalTimeout; }
|
||||
@ -86,9 +85,8 @@ class AdvancedConfig {
|
||||
}
|
||||
|
||||
int getTempSensorResolution() { return _tempSensorResolution; }
|
||||
void setTempSensorResolution(int t) {
|
||||
if (t>=9 && t<=12)
|
||||
_tempSensorResolution = t;
|
||||
void setTempSensorResolution(int t) {
|
||||
if (t >= 9 && t <= 12) _tempSensorResolution = t;
|
||||
}
|
||||
|
||||
float getDefaultCalibrationTemp() { return _defaultCalibrationTemp; }
|
||||
@ -128,6 +126,9 @@ class AdvancedConfig {
|
||||
: true;
|
||||
}
|
||||
|
||||
const bool isIgnoreLowAnges() { return _IgnoreLowAnges; }
|
||||
void setIgnoreLowAnges(bool b) { _IgnoreLowAnges = b; }
|
||||
|
||||
bool saveFile();
|
||||
bool loadFile();
|
||||
};
|
||||
@ -143,9 +144,11 @@ class Config {
|
||||
String _otaURL = "";
|
||||
char _tempFormat = 'C';
|
||||
float _voltageFactor = 1.59;
|
||||
float _voltageConfig = 4.15;
|
||||
float _tempSensorAdjC = 0;
|
||||
int _sleepInterval = 900;
|
||||
bool _gyroTemp = false;
|
||||
bool _storageSleep = false;
|
||||
|
||||
// Wifi Config
|
||||
String _wifiSSID[2] = {"", ""};
|
||||
@ -181,7 +184,8 @@ class Config {
|
||||
|
||||
// Gyro calibration and formula calculation data
|
||||
RawGyroData _gyroCalibration = {0, 0, 0, 0, 0, 0};
|
||||
RawFormulaData _formulaData = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}};
|
||||
RawFormulaData _formulaData = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
|
||||
|
||||
void formatFileSystem();
|
||||
|
||||
@ -203,6 +207,12 @@ class Config {
|
||||
_saveNeeded = true;
|
||||
}
|
||||
|
||||
const bool isStorageSleep() { return _storageSleep; }
|
||||
void setStorageSleep(bool b) {
|
||||
_storageSleep = b;
|
||||
_saveNeeded = true;
|
||||
}
|
||||
|
||||
const char* getOtaURL() { return _otaURL.c_str(); }
|
||||
void setOtaURL(String s) {
|
||||
_otaURL = s;
|
||||
@ -367,6 +377,16 @@ class Config {
|
||||
_saveNeeded = true;
|
||||
}
|
||||
|
||||
float getVoltageConfig() { return _voltageConfig; }
|
||||
void setVoltageConfig(float f) {
|
||||
_voltageConfig = f;
|
||||
_saveNeeded = true;
|
||||
}
|
||||
void setVoltageConfig(String s) {
|
||||
_voltageConfig = s.toFloat();
|
||||
_saveNeeded = true;
|
||||
}
|
||||
|
||||
float getTempSensorAdjC() { return _tempSensorAdjC; }
|
||||
void setTempSensorAdjC(float f) {
|
||||
_tempSensorAdjC = f;
|
||||
|
@ -43,7 +43,9 @@ bool GyroSensor::setup() {
|
||||
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having
|
||||
// compilation difficulties
|
||||
|
||||
if (!accelgyro.testConnection()) {
|
||||
uint8_t id = accelgyro.getDeviceID();
|
||||
|
||||
if (id != 0x34 && id != 0x38) { // Allow both MPU6050 and MPU6000
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(F("GYRO: Failed to connect to gyro, is it connected?"));
|
||||
_sensorConnected = false;
|
||||
|
@ -194,14 +194,8 @@ void printBuildOptions() {
|
||||
#ifdef SKIP_SLEEPMODE
|
||||
"SKIP_SLEEP "
|
||||
#endif
|
||||
#ifdef EMBED_HTML
|
||||
"EMBED_HTML "
|
||||
#endif
|
||||
#ifdef COLLECT_PERFDATA
|
||||
"PERFDATA "
|
||||
#endif
|
||||
#ifdef ACTIVATE_OTA
|
||||
"OTA "
|
||||
#endif
|
||||
CR),
|
||||
CFG_APPVER, CFG_GITREV, LOG_LEVEL);
|
||||
@ -318,7 +312,9 @@ void PerfLogging::pushInflux() {
|
||||
if (!myConfig.isInfluxDb2Active()) return;
|
||||
|
||||
if (myConfig.isInfluxSSL()) {
|
||||
Log.warning(F("PERF: InfluxDB2 with SSL is not supported when pushing performance data, skipping" CR));
|
||||
Log.warning(
|
||||
F("PERF: InfluxDB2 with SSL is not supported when pushing performance "
|
||||
"data, skipping" CR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
55
src/main.cpp
@ -32,13 +32,13 @@ SOFTWARE.
|
||||
#include <webserver.hpp>
|
||||
#include <wifi.hpp>
|
||||
|
||||
//#define FORCE_GRAVITY_MODE
|
||||
// #define FORCE_GRAVITY_MODE
|
||||
|
||||
// Define constats for this program
|
||||
#ifdef DEACTIVATE_SLEEPMODE
|
||||
const int interval = 1000; // ms, time to wait between changes to output
|
||||
#else
|
||||
int interval = 200; // ms, time to wait between changes to output
|
||||
int interval = 200; // ms, time to wait between changes to output
|
||||
#endif
|
||||
bool sleepModeAlwaysSkip =
|
||||
false; // Flag set in web interface to override normal behaviour
|
||||
@ -50,9 +50,6 @@ uint32_t stableGyroMillis; // Used to calculate the total time since last
|
||||
|
||||
RunMode runMode = RunMode::gravityMode;
|
||||
|
||||
//
|
||||
// Check if we should be in sleep mode
|
||||
//
|
||||
void checkSleepMode(float angle, float volt) {
|
||||
#if defined(SKIP_SLEEPMODE)
|
||||
runMode = RunMode::configurationMode;
|
||||
@ -83,8 +80,12 @@ void checkSleepMode(float angle, float volt) {
|
||||
Log.notice(F("MAIN: Sleep mode disabled from web interface." CR));
|
||||
#endif
|
||||
runMode = RunMode::configurationMode;
|
||||
} else if ((volt < 4.15 && (angle > 85 && angle < 95)) || (volt > 4.15)) {
|
||||
} else if ((volt < myConfig.getVoltageConfig() &&
|
||||
(angle > 85 && angle < 95)) ||
|
||||
(volt > myConfig.getVoltageConfig())) {
|
||||
runMode = RunMode::configurationMode;
|
||||
} else if (angle < 5 && myConfig.isStorageSleep()) {
|
||||
runMode = RunMode::storageMode;
|
||||
} else {
|
||||
runMode = RunMode::gravityMode;
|
||||
}
|
||||
@ -104,12 +105,26 @@ void checkSleepMode(float angle, float volt) {
|
||||
volt);
|
||||
#endif
|
||||
break;
|
||||
case RunMode::storageMode:
|
||||
#if !defined(MAIN_DISABLE_LOGGING)
|
||||
Log.notice(F("MAIN: run mode STORAGE (angle=%F)." CR), angle);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
// If we are in storage mode, just go back to sleep
|
||||
if (runMode == RunMode::storageMode) {
|
||||
Log.notice(
|
||||
F("Main: Storage mode entered, going to sleep for maximum time." CR));
|
||||
#if defined(ESP8266)
|
||||
ESP.deepSleep(ESP.deepSleepMax());
|
||||
#else
|
||||
#warning "Check and test the max deep sleep for esp32"
|
||||
deepSleep(70 * 60); // quick search on internet suggest max time is 70 min
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
void setup() {
|
||||
LOG_PERF_START("run-time");
|
||||
LOG_PERF_START("main-setup");
|
||||
@ -264,7 +279,12 @@ bool loopReadGravity() {
|
||||
LOG_PERF_STOP("loop-temp-read");
|
||||
|
||||
float gravitySG = calculateGravity(angle, tempC);
|
||||
float corrGravitySG = gravityTemperatureCorrectionC(gravitySG, tempC);
|
||||
float corrGravitySG = gravityTemperatureCorrectionC(
|
||||
gravitySG, tempC, myAdvancedConfig.getDefaultCalibrationTemp());
|
||||
|
||||
if (myConfig.isGravityTempAdj()) {
|
||||
gravitySG = corrGravitySG;
|
||||
}
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
||||
Log.verbose(F("Main: Sensor values gyro angle=%F, temp=%FC, gravity=%F, "
|
||||
@ -275,6 +295,14 @@ bool loopReadGravity() {
|
||||
bool pushExpired = (abs((int32_t)(millis() - pushMillis)) >
|
||||
(myConfig.getSleepInterval() * 1000));
|
||||
|
||||
if (myAdvancedConfig.isIgnoreLowAnges() &&
|
||||
(angle < myConfig.getFormulaData().a[0])) {
|
||||
Log.warning(
|
||||
F("Main: Angle is lower than water, so we regard this as faulty and "
|
||||
"dont send any data." CR));
|
||||
pushExpired = false;
|
||||
}
|
||||
|
||||
if (pushExpired || runMode == RunMode::gravityMode) {
|
||||
pushMillis = millis();
|
||||
LOG_PERF_START("loop-push");
|
||||
@ -350,11 +378,12 @@ void goToSleep(int sleepInterval) {
|
||||
deepSleep(sleepInterval);
|
||||
}
|
||||
|
||||
//
|
||||
// Main loops
|
||||
//
|
||||
void loop() {
|
||||
switch (runMode) {
|
||||
case RunMode::storageMode:
|
||||
// This point is never reached, just here to remove warning.
|
||||
break;
|
||||
|
||||
case RunMode::configurationMode:
|
||||
if (myWifi.isConnected()) myWebServerHandler.loop();
|
||||
|
||||
|
14
src/main.hpp
@ -29,7 +29,12 @@ SOFTWARE.
|
||||
#include <ArduinoLog.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum RunMode { gravityMode = 0, configurationMode = 1, wifiSetupMode = 2 };
|
||||
enum RunMode {
|
||||
gravityMode = 0,
|
||||
configurationMode = 1,
|
||||
wifiSetupMode = 2,
|
||||
storageMode = 3
|
||||
};
|
||||
extern RunMode runMode;
|
||||
|
||||
#if defined(ESP8266)
|
||||
@ -41,13 +46,8 @@ extern RunMode runMode;
|
||||
#define PIN_LED 2
|
||||
// #define PIN_A0 A0
|
||||
#else // defined (ESP32)
|
||||
#if defined(ESPRESSIF32_20)
|
||||
#include <LittleFS.h>
|
||||
#else
|
||||
#include <LITTLEFS.h>
|
||||
#define LittleFS LITTLEFS
|
||||
#endif
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#define ESPhttpUpdate httpUpdate
|
||||
#define ESP_RESET ESP.restart
|
||||
#define ESP8266WebServer WebServer
|
||||
|
@ -108,8 +108,8 @@ void PushIntervalTracker::save() {
|
||||
void PushTarget::sendAll(float angle, float gravitySG, float corrGravitySG,
|
||||
float tempC, float runTime) {
|
||||
printHeap("PUSH");
|
||||
_http.setReuse(false);
|
||||
_httpSecure.setReuse(false);
|
||||
_http.setReuse(true);
|
||||
_httpSecure.setReuse(true);
|
||||
|
||||
TemplatingEngine engine;
|
||||
engine.initialize(angle, gravitySG, corrGravitySG, tempC, runTime);
|
||||
@ -204,9 +204,11 @@ void PushTarget::sendInfluxDb2(TemplatingEngine& engine, bool isSecure) {
|
||||
String auth = "Token " + String(myConfig.getInfluxDb2PushToken());
|
||||
|
||||
if (isSecure) {
|
||||
#if defined( ESP8266 )
|
||||
#if defined(ESP8266)
|
||||
if (runMode == RunMode::configurationMode) {
|
||||
Log.notice(F("PUSH: Skipping InfluxDB since SSL is enabled and we are in config mode." CR));
|
||||
Log.notice(
|
||||
F("PUSH: Skipping InfluxDB since SSL is enabled and we are in config "
|
||||
"mode." CR));
|
||||
_lastCode = -100;
|
||||
return;
|
||||
}
|
||||
@ -217,8 +219,7 @@ void PushTarget::sendInfluxDb2(TemplatingEngine& engine, bool isSecure) {
|
||||
probeMaxFragement(serverPath);
|
||||
_httpSecure.setTimeout(myAdvancedConfig.getPushTimeout() * 1000);
|
||||
_httpSecure.begin(_wifiSecure, serverPath);
|
||||
_httpSecure.addHeader(F("Authorization"), auth.c_str());
|
||||
_httpSecure.setReuse(true);
|
||||
_httpSecure.addHeader(F("Authorization"), auth.c_str());
|
||||
_lastCode = _httpSecure.POST(doc);
|
||||
} else {
|
||||
_http.setTimeout(myAdvancedConfig.getPushTimeout() * 1000);
|
||||
@ -293,9 +294,11 @@ void PushTarget::sendHttpPost(TemplatingEngine& engine, bool isSecure,
|
||||
#endif
|
||||
|
||||
if (isSecure) {
|
||||
#if defined( ESP8266 )
|
||||
#if defined(ESP8266)
|
||||
if (runMode == RunMode::configurationMode) {
|
||||
Log.notice(F("PUSH: Skipping HTTP since SSL is enabled and we are in config mode." CR));
|
||||
Log.notice(
|
||||
F("PUSH: Skipping HTTP since SSL is enabled and we are in config "
|
||||
"mode." CR));
|
||||
_lastCode = -100;
|
||||
return;
|
||||
}
|
||||
@ -370,9 +373,11 @@ void PushTarget::sendHttpGet(TemplatingEngine& engine, bool isSecure) {
|
||||
#endif
|
||||
|
||||
if (isSecure) {
|
||||
#if defined( ESP8266 )
|
||||
#if defined(ESP8266)
|
||||
if (runMode == RunMode::configurationMode) {
|
||||
Log.notice(F("PUSH: Skipping HTTP since SSL is enabled and we are in config mode." CR));
|
||||
Log.notice(
|
||||
F("PUSH: Skipping HTTP since SSL is enabled and we are in config "
|
||||
"mode." CR));
|
||||
_lastCode = -100;
|
||||
return;
|
||||
}
|
||||
@ -424,9 +429,11 @@ void PushTarget::sendMqtt(TemplatingEngine& engine, bool isSecure) {
|
||||
int port = myConfig.getMqttPort();
|
||||
|
||||
if (myConfig.isMqttSSL()) {
|
||||
#if defined( ESP8266 )
|
||||
#if defined(ESP8266)
|
||||
if (runMode == RunMode::configurationMode) {
|
||||
Log.notice(F("PUSH: Skipping MQTT since SSL is enabled and we are in config mode." CR));
|
||||
Log.notice(
|
||||
F("PUSH: Skipping MQTT since SSL is enabled and we are in config "
|
||||
"mode." CR));
|
||||
_lastCode = -100;
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class PushTarget {
|
||||
void sendHttpPost(TemplatingEngine& engine, bool isSecure, int index);
|
||||
void sendHttpGet(TemplatingEngine& engine, bool isSecure);
|
||||
void addHttpHeader(HTTPClient& http, String header);
|
||||
void probeMaxFragement( String& serverPath );
|
||||
void probeMaxFragement(String& serverPath);
|
||||
|
||||
public:
|
||||
void sendAll(float angle, float gravitySG, float corrGravitySG, float tempC,
|
||||
@ -68,7 +68,7 @@ class PushTarget {
|
||||
|
||||
class PushIntervalTracker {
|
||||
private:
|
||||
int _counters[5] = { 0, 0, 0, 0, 0 };
|
||||
int _counters[5] = {0, 0, 0, 0, 0};
|
||||
void update(const int index, const int defaultValue);
|
||||
|
||||
public:
|
||||
|
@ -53,13 +53,15 @@ SOFTWARE.
|
||||
#define PARAM_PUSH_MQTT_PORT "mqtt-port"
|
||||
#define PARAM_SLEEP_INTERVAL "sleep-interval"
|
||||
#define PARAM_TEMPFORMAT "temp-format"
|
||||
#define PARAM_VOLTAGEFACTOR "voltage-factor"
|
||||
#define PARAM_VOLTAGE_FACTOR "voltage-factor"
|
||||
#define PARAM_VOLTAGE_CONFIG "voltage-config"
|
||||
#define PARAM_GRAVITY_FORMULA "gravity-formula"
|
||||
#define PARAM_GRAVITY_FORMAT "gravity-format"
|
||||
#define PARAM_GRAVITY_TEMP_ADJ "gravity-temp-adjustment"
|
||||
#define PARAM_TEMP_ADJ "temp-adjustment-value"
|
||||
#define PARAM_GYRO_CALIBRATION "gyro-calibration-data"
|
||||
#define PARAM_GYRO_TEMP "gyro-temp"
|
||||
#define PARAM_STORAGE_SLEEP "storage-sleep"
|
||||
#define PARAM_FORMULA_DATA "formula-calculation-data"
|
||||
#define PARAM_FILES "files"
|
||||
#define PARAM_FILE_NAME "file-name"
|
||||
@ -90,6 +92,7 @@ SOFTWARE.
|
||||
#define PARAM_HW_PUSH_INTERVAL_HTTP3 "int-http3"
|
||||
#define PARAM_HW_PUSH_INTERVAL_INFLUX "int-influx"
|
||||
#define PARAM_HW_PUSH_INTERVAL_MQTT "int-mqtt"
|
||||
#define PARAM_HW_IGNORE_LOW_ANGLES "ignore-low-angles"
|
||||
#define PARAM_FORMAT_HTTP1 "http-1"
|
||||
#define PARAM_FORMAT_HTTP2 "http-2"
|
||||
#define PARAM_FORMAT_HTTP3 "http-3"
|
||||
|
@ -130,6 +130,9 @@ void TemplatingEngine::initialize(float angle, float gravitySG,
|
||||
setVal(TPL_GRAVITY_CORR_P, convertToPlato(corrGravitySG), 1);
|
||||
setVal(TPL_GRAVITY_UNIT, myConfig.getGravityFormat());
|
||||
|
||||
setVal(TPL_APP_VER, CFG_APPVER);
|
||||
setVal(TPL_APP_BUILD, CFG_GITREV);
|
||||
|
||||
#if LOG_LEVEL == 6
|
||||
// dumpAll();
|
||||
#endif
|
||||
|
@ -53,6 +53,8 @@ SOFTWARE.
|
||||
#define TPL_GRAVITY_CORR_G "${corr-gravity-sg}"
|
||||
#define TPL_GRAVITY_CORR_P "${corr-gravity-plato}"
|
||||
#define TPL_GRAVITY_UNIT "${gravity-unit}" // G or P
|
||||
#define TPL_APP_VER "${app-ver}"
|
||||
#define TPL_APP_BUILD "${app-build}"
|
||||
|
||||
#define TPL_FNAME_HTTP1 "/http-1.tpl"
|
||||
#define TPL_FNAME_HTTP2 "/http-2.tpl"
|
||||
@ -73,7 +75,7 @@ class TemplatingEngine {
|
||||
String val;
|
||||
};
|
||||
|
||||
KeyVal items[21] = {{TPL_MDNS, ""}, {TPL_ID, ""},
|
||||
KeyVal items[23] = {{TPL_MDNS, ""}, {TPL_ID, ""},
|
||||
{TPL_SLEEP_INTERVAL, ""}, {TPL_TEMP, ""},
|
||||
{TPL_TEMP_C, ""}, {TPL_TEMP_F, ""},
|
||||
{TPL_TEMP_UNITS, ""}, {TPL_BATTERY, ""},
|
||||
@ -83,7 +85,8 @@ class TemplatingEngine {
|
||||
{TPL_GRAVITY_P, ""}, {TPL_GRAVITY_CORR, ""},
|
||||
{TPL_GRAVITY_CORR_G, ""}, {TPL_GRAVITY_CORR_P, ""},
|
||||
{TPL_GRAVITY_UNIT, ""}, {TPL_TOKEN, ""},
|
||||
{TPL_TOKEN2, ""}};
|
||||
{TPL_TOKEN2, ""}, {TPL_APP_VER, ""},
|
||||
{TPL_APP_BUILD, ""}};
|
||||
|
||||
char buffer[20];
|
||||
String baseTemplate;
|
||||
|
@ -51,10 +51,10 @@ void TempSensor::setup() {
|
||||
|
||||
if (mySensors.getDS18Count()) {
|
||||
#if !defined(TSEN_DISABLE_LOGGING)
|
||||
Log.notice(F("TSEN: Found %d temperature sensor(s). Using %d resolution" CR),
|
||||
mySensors.getDS18Count(), myAdvancedConfig.getTempSensorResolution());
|
||||
Log.notice(
|
||||
F("TSEN: Found %d temperature sensor(s). Using %d resolution" CR),
|
||||
mySensors.getDS18Count(), myAdvancedConfig.getTempSensorResolution());
|
||||
#endif
|
||||
mySensors.setResolution(myAdvancedConfig.getTempSensorResolution());
|
||||
}
|
||||
|
||||
// Set the temp sensor adjustment values
|
||||
@ -94,6 +94,7 @@ float TempSensor::getValue(bool useGyro) {
|
||||
}
|
||||
|
||||
// Read the sensors
|
||||
mySensors.setResolution(myAdvancedConfig.getTempSensorResolution());
|
||||
mySensors.requestTemperatures();
|
||||
|
||||
float c = 0;
|
||||
|
@ -44,10 +44,14 @@ void WebServerHandler::webHandleConfig() {
|
||||
LOG_PERF_START("webserver-api-config");
|
||||
Log.notice(F("WEB : webServer callback for /api/config(get)." CR));
|
||||
|
||||
DynamicJsonDocument doc(CFG_JSON_BUFSIZE);
|
||||
DynamicJsonDocument doc(2000);
|
||||
myConfig.createJson(doc);
|
||||
|
||||
doc[PARAM_PASS] = ""; // dont show the wifi password
|
||||
doc[PARAM_PASS2] = "";
|
||||
|
||||
doc[PARAM_APP_VER] = String(CFG_APPVER);
|
||||
doc[PARAM_APP_BUILD] = String(CFG_GITREV);
|
||||
|
||||
double angle = 0;
|
||||
|
||||
@ -68,8 +72,8 @@ void WebServerHandler::webHandleConfig() {
|
||||
doc[PARAM_TEMP_ADJ] = reduceFloatPrecision(myConfig.getTempSensorAdjC(), 1);
|
||||
|
||||
if (myConfig.isGravityTempAdj()) {
|
||||
gravity =
|
||||
gravityTemperatureCorrectionC(gravity, tempC, myConfig.getTempFormat());
|
||||
gravity = gravityTemperatureCorrectionC(
|
||||
gravity, tempC, myAdvancedConfig.getDefaultCalibrationTemp());
|
||||
}
|
||||
|
||||
if (myConfig.isGravityPlato()) {
|
||||
@ -96,8 +100,9 @@ void WebServerHandler::webHandleConfig() {
|
||||
#endif
|
||||
|
||||
String out;
|
||||
out.reserve(CFG_JSON_BUFSIZE);
|
||||
out.reserve(2000);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-config");
|
||||
}
|
||||
@ -159,6 +164,7 @@ void WebServerHandler::webHandleUpload() {
|
||||
String out;
|
||||
out.reserve(300);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-upload");
|
||||
}
|
||||
@ -324,7 +330,7 @@ void WebServerHandler::webHandleStatus() {
|
||||
LOG_PERF_START("webserver-api-status");
|
||||
Log.notice(F("WEB : webServer callback for /api/status(get)." CR));
|
||||
|
||||
DynamicJsonDocument doc(512);
|
||||
DynamicJsonDocument doc(500);
|
||||
|
||||
double angle = 0;
|
||||
|
||||
@ -336,7 +342,8 @@ void WebServerHandler::webHandleStatus() {
|
||||
doc[PARAM_ID] = myConfig.getID();
|
||||
doc[PARAM_ANGLE] = reduceFloatPrecision(angle);
|
||||
if (myConfig.isGravityTempAdj()) {
|
||||
gravity = gravityTemperatureCorrectionC(gravity, tempC);
|
||||
gravity = gravityTemperatureCorrectionC(
|
||||
gravity, tempC, myAdvancedConfig.getDefaultCalibrationTemp());
|
||||
}
|
||||
if (myConfig.isGravityPlato()) {
|
||||
doc[PARAM_GRAVITY] = reduceFloatPrecision(convertToPlato(gravity), 1);
|
||||
@ -375,8 +382,9 @@ void WebServerHandler::webHandleStatus() {
|
||||
#endif
|
||||
|
||||
String out;
|
||||
out.reserve(300);
|
||||
out.reserve(500);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-status");
|
||||
}
|
||||
@ -575,6 +583,9 @@ void WebServerHandler::webHandleConfigGravity() {
|
||||
myConfig.setGravityTempAdj(
|
||||
_server->arg(PARAM_GRAVITY_TEMP_ADJ).equalsIgnoreCase("on") ? true
|
||||
: false);
|
||||
else
|
||||
myConfig.setGravityTempAdj(false);
|
||||
|
||||
myConfig.saveFile();
|
||||
_server->sendHeader("Location", "/config.htm#collapseGravity", true);
|
||||
_server->send(302, "text/plain", "Gravity config updated");
|
||||
@ -601,8 +612,10 @@ void WebServerHandler::webHandleConfigHardware() {
|
||||
Log.verbose(F("WEB : %s." CR), getRequestArguments().c_str());
|
||||
#endif
|
||||
|
||||
if (_server->hasArg(PARAM_VOLTAGEFACTOR))
|
||||
myConfig.setVoltageFactor(_server->arg(PARAM_VOLTAGEFACTOR).toFloat());
|
||||
if (_server->hasArg(PARAM_VOLTAGE_FACTOR))
|
||||
myConfig.setVoltageFactor(_server->arg(PARAM_VOLTAGE_FACTOR).toFloat());
|
||||
if (_server->hasArg(PARAM_VOLTAGE_CONFIG))
|
||||
myConfig.setVoltageConfig(_server->arg(PARAM_VOLTAGE_CONFIG).toFloat());
|
||||
if (_server->hasArg(PARAM_TEMP_ADJ)) {
|
||||
if (myConfig.isTempC()) {
|
||||
myConfig.setTempSensorAdjC(_server->arg(PARAM_TEMP_ADJ));
|
||||
@ -618,6 +631,15 @@ void WebServerHandler::webHandleConfigHardware() {
|
||||
if (_server->hasArg(PARAM_GYRO_TEMP))
|
||||
myConfig.setGyroTemp(
|
||||
_server->arg(PARAM_GYRO_TEMP).equalsIgnoreCase("on") ? true : false);
|
||||
else
|
||||
myConfig.setGyroTemp(false);
|
||||
if (_server->hasArg(PARAM_STORAGE_SLEEP))
|
||||
myConfig.setStorageSleep(
|
||||
_server->arg(PARAM_STORAGE_SLEEP).equalsIgnoreCase("on") ? true
|
||||
: false);
|
||||
else
|
||||
myConfig.setStorageSleep(false);
|
||||
|
||||
myConfig.saveFile();
|
||||
_server->sendHeader("Location", "/config.htm#collapseHardware", true);
|
||||
_server->send(302, "text/plain", "Hardware config updated");
|
||||
@ -656,9 +678,11 @@ void WebServerHandler::webHandleConfigAdvancedWrite() {
|
||||
if (_server->hasArg(PARAM_HW_FORMULA_DEVIATION))
|
||||
myAdvancedConfig.setMaxFormulaCreationDeviation(
|
||||
_server->arg(PARAM_HW_FORMULA_DEVIATION).toFloat());
|
||||
if (_server->hasArg(PARAM_HW_FORMULA_CALIBRATION_TEMP))
|
||||
myAdvancedConfig.SetDefaultCalibrationTemp(
|
||||
_server->arg(PARAM_HW_FORMULA_CALIBRATION_TEMP).toFloat());
|
||||
if (_server->hasArg(PARAM_HW_FORMULA_CALIBRATION_TEMP)) {
|
||||
float t = _server->arg(PARAM_HW_FORMULA_CALIBRATION_TEMP).toFloat();
|
||||
if (myConfig.isTempF()) t = convertFtoC(t);
|
||||
myAdvancedConfig.SetDefaultCalibrationTemp(t);
|
||||
}
|
||||
if (_server->hasArg(PARAM_HW_WIFI_PORTAL_TIMEOUT))
|
||||
myAdvancedConfig.setWifiPortalTimeout(
|
||||
_server->arg(PARAM_HW_WIFI_PORTAL_TIMEOUT).toInt());
|
||||
@ -686,6 +710,13 @@ void WebServerHandler::webHandleConfigAdvancedWrite() {
|
||||
if (_server->hasArg(PARAM_HW_TEMPSENSOR_RESOLUTION))
|
||||
myAdvancedConfig.setTempSensorResolution(
|
||||
_server->arg(PARAM_HW_TEMPSENSOR_RESOLUTION).toInt());
|
||||
if (_server->hasArg(PARAM_HW_IGNORE_LOW_ANGLES))
|
||||
myAdvancedConfig.setIgnoreLowAnges(
|
||||
_server->arg(PARAM_HW_IGNORE_LOW_ANGLES).equalsIgnoreCase("on")
|
||||
? true
|
||||
: false);
|
||||
else
|
||||
myAdvancedConfig.setIgnoreLowAnges(false);
|
||||
|
||||
myAdvancedConfig.saveFile();
|
||||
_server->sendHeader("Location", "/config.htm#collapseAdvanced", true);
|
||||
@ -700,7 +731,7 @@ void WebServerHandler::webHandleConfigAdvancedRead() {
|
||||
LOG_PERF_START("webserver-api-config-advanced");
|
||||
Log.notice(F("WEB : webServer callback for /api/config/advanced(get)." CR));
|
||||
|
||||
DynamicJsonDocument doc(512);
|
||||
DynamicJsonDocument doc(500);
|
||||
|
||||
doc[PARAM_HW_GYRO_READ_COUNT] = myAdvancedConfig.getGyroReadCount();
|
||||
// doc[PARAM_HW_GYRO_READ_DELAY] = myAdvancedConfig.getGyroReadDelay();
|
||||
@ -711,8 +742,9 @@ void WebServerHandler::webHandleConfigAdvancedRead() {
|
||||
doc[PARAM_HW_WIFI_PORTAL_TIMEOUT] = myAdvancedConfig.getWifiPortalTimeout();
|
||||
doc[PARAM_HW_WIFI_CONNECT_TIMEOUT] = myAdvancedConfig.getWifiConnectTimeout();
|
||||
doc[PARAM_HW_PUSH_TIMEOUT] = myAdvancedConfig.getPushTimeout();
|
||||
float t = myAdvancedConfig.getDefaultCalibrationTemp();
|
||||
doc[PARAM_HW_FORMULA_CALIBRATION_TEMP] =
|
||||
myAdvancedConfig.getDefaultCalibrationTemp();
|
||||
myConfig.isTempC() ? t : reduceFloatPrecision(convertCtoF(t), 1);
|
||||
doc[PARAM_HW_PUSH_INTERVAL_HTTP1] = myAdvancedConfig.getPushIntervalHttp1();
|
||||
doc[PARAM_HW_PUSH_INTERVAL_HTTP2] = myAdvancedConfig.getPushIntervalHttp2();
|
||||
doc[PARAM_HW_PUSH_INTERVAL_HTTP3] = myAdvancedConfig.getPushIntervalHttp3();
|
||||
@ -720,6 +752,7 @@ void WebServerHandler::webHandleConfigAdvancedRead() {
|
||||
doc[PARAM_HW_PUSH_INTERVAL_MQTT] = myAdvancedConfig.getPushIntervalMqtt();
|
||||
doc[PARAM_HW_TEMPSENSOR_RESOLUTION] =
|
||||
myAdvancedConfig.getTempSensorResolution();
|
||||
doc[PARAM_HW_IGNORE_LOW_ANGLES] = myAdvancedConfig.isIgnoreLowAnges();
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(WEB_DISABLE_LOGGING)
|
||||
serializeJson(doc, Serial);
|
||||
@ -727,8 +760,9 @@ void WebServerHandler::webHandleConfigAdvancedRead() {
|
||||
#endif
|
||||
|
||||
String out;
|
||||
out.reserve(512);
|
||||
out.reserve(500);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-config-advanced");
|
||||
}
|
||||
@ -740,7 +774,7 @@ void WebServerHandler::webHandleFormulaRead() {
|
||||
LOG_PERF_START("webserver-api-formula-read");
|
||||
Log.notice(F("WEB : webServer callback for /api/formula(get)." CR));
|
||||
|
||||
DynamicJsonDocument doc(512);
|
||||
DynamicJsonDocument doc(500);
|
||||
const RawFormulaData& fd = myConfig.getFormulaData();
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(WEB_DISABLE_LOGGING)
|
||||
@ -758,10 +792,13 @@ void WebServerHandler::webHandleFormulaRead() {
|
||||
doc[PARAM_ERROR] = "Internal error creating formula.";
|
||||
break;
|
||||
case ERR_FORMULA_NOTENOUGHVALUES:
|
||||
doc[PARAM_ERROR] = "Not enough values to create formula.";
|
||||
doc[PARAM_ERROR] =
|
||||
"Not enough values to create formula, need at least 3 angles.";
|
||||
break;
|
||||
case ERR_FORMULA_UNABLETOFFIND:
|
||||
doc[PARAM_ERROR] = "Unable to find an accurate formula based on input.";
|
||||
doc[PARAM_ERROR] =
|
||||
"Unable to find an accurate formula based on input, check error log "
|
||||
"and graph below.";
|
||||
break;
|
||||
default:
|
||||
doc[PARAM_GRAVITY_FORMULA] = myConfig.getGravityFormula();
|
||||
@ -809,8 +846,9 @@ void WebServerHandler::webHandleFormulaRead() {
|
||||
#endif
|
||||
|
||||
String out;
|
||||
out.reserve(256);
|
||||
out.reserve(500);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-formula-read");
|
||||
}
|
||||
@ -885,7 +923,8 @@ void WebServerHandler::webHandleTestPush() {
|
||||
float angle = myGyro.getAngle();
|
||||
float tempC = myTempSensor.getTempC(myConfig.isGyroTemp());
|
||||
float gravitySG = calculateGravity(angle, tempC);
|
||||
float corrGravitySG = gravityTemperatureCorrectionC(gravitySG, tempC);
|
||||
float corrGravitySG = gravityTemperatureCorrectionC(
|
||||
gravitySG, tempC, myAdvancedConfig.getDefaultCalibrationTemp());
|
||||
|
||||
TemplatingEngine engine;
|
||||
engine.initialize(angle, gravitySG, corrGravitySG, tempC, 2.1);
|
||||
@ -920,6 +959,7 @@ void WebServerHandler::webHandleTestPush() {
|
||||
String out;
|
||||
out.reserve(100);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(WEB_DISABLE_LOGGING)
|
||||
serializeJson(doc, Serial);
|
||||
@ -982,7 +1022,7 @@ void WebServerHandler::webHandleConfigFormatRead() {
|
||||
LOG_PERF_START("webserver-api-config-format-read");
|
||||
Log.notice(F("WEB : webServer callback for /api/config/formula(get)." CR));
|
||||
|
||||
DynamicJsonDocument doc(2048);
|
||||
DynamicJsonDocument doc(5000);
|
||||
|
||||
doc[PARAM_ID] = myConfig.getID();
|
||||
|
||||
@ -1022,8 +1062,9 @@ void WebServerHandler::webHandleConfigFormatRead() {
|
||||
#endif
|
||||
|
||||
String out;
|
||||
out.reserve(2048);
|
||||
out.reserve(3000);
|
||||
serializeJson(doc, out);
|
||||
doc.clear();
|
||||
_server->send(200, "application/json", out.c_str());
|
||||
LOG_PERF_STOP("webserver-api-config-format-read");
|
||||
}
|
||||
@ -1084,6 +1125,7 @@ void WebServerHandler::webHandleFormulaWrite() {
|
||||
fd.g[9] = _server->arg("g10").toDouble();
|
||||
}
|
||||
|
||||
fd.g[0] = 1; // force first point to SG gravity of water
|
||||
myConfig.setFormulaData(fd);
|
||||
|
||||
int e;
|
||||
@ -1129,17 +1171,17 @@ const char* WebServerHandler::getHtmlFileName(HtmlFile item) {
|
||||
Log.notice(F("WEB : Looking up filename for %d." CR), item);
|
||||
|
||||
switch (item) {
|
||||
case HTML_INDEX:
|
||||
case HtmlFile::HTML_INDEX:
|
||||
return "index.min.htm";
|
||||
case HTML_CONFIG:
|
||||
case HtmlFile::HTML_CONFIG:
|
||||
return "config.min.htm";
|
||||
case HTML_CALIBRATION:
|
||||
case HtmlFile::HTML_CALIBRATION:
|
||||
return "calibration.min.htm";
|
||||
case HTML_FORMAT:
|
||||
case HtmlFile::HTML_FORMAT:
|
||||
return "format.min.htm";
|
||||
case HTML_ABOUT:
|
||||
case HtmlFile::HTML_ABOUT:
|
||||
return "about.min.htm";
|
||||
case HTML_TEST:
|
||||
case HtmlFile::HTML_TEST:
|
||||
return "test.min.htm";
|
||||
}
|
||||
|
||||
@ -1181,6 +1223,37 @@ bool WebServerHandler::setupWebServer() {
|
||||
MDNS.begin(myConfig.getMDNS());
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
|
||||
// Show files in the filessytem at startup
|
||||
#if defined(ESP8266)
|
||||
FSInfo fs;
|
||||
LittleFS.info(fs);
|
||||
Log.notice(F("WEB : File system Total=%d, Used=%d." CR), fs.totalBytes,
|
||||
fs.usedBytes);
|
||||
Dir dir = LittleFS.openDir("/");
|
||||
while (dir.next()) {
|
||||
Log.notice(F("WEB : File=%s, %d bytes" CR), dir.fileName().c_str(),
|
||||
dir.fileSize());
|
||||
if (!dir.fileSize()) {
|
||||
Log.notice(F("WEB : Empty file detected, removing file." CR));
|
||||
LittleFS.remove(dir.fileName().c_str());
|
||||
}
|
||||
}
|
||||
#else // defined( ESP32 )
|
||||
File root = LittleFS.open("/");
|
||||
File f = root.openNextFile();
|
||||
while (f) {
|
||||
Log.notice(F("WEB : File=%s, %d bytes" CR), f.name(), f.size());
|
||||
if (!f.size()) {
|
||||
Log.notice(F("WEB : Empty file detected, removing file." CR));
|
||||
LittleFS.remove(f.name());
|
||||
}
|
||||
|
||||
f = root.openNextFile();
|
||||
}
|
||||
f.close();
|
||||
root.close();
|
||||
#endif
|
||||
|
||||
// Static content
|
||||
#if defined(EMBED_HTML)
|
||||
_server->on("/", std::bind(&WebServerHandler::webReturnIndexHtm, this));
|
||||
@ -1197,18 +1270,6 @@ bool WebServerHandler::setupWebServer() {
|
||||
_server->on("/test.htm",
|
||||
std::bind(&WebServerHandler::webReturnTestHtm, this));
|
||||
#else
|
||||
// Show files in the filessytem at startup
|
||||
|
||||
FSInfo fs;
|
||||
LittleFS.info(fs);
|
||||
Log.notice(F("WEB : File system Total=%d, Used=%d." CR), fs.totalBytes,
|
||||
fs.usedBytes);
|
||||
Dir dir = LittleFS.openDir("/");
|
||||
while (dir.next()) {
|
||||
Log.notice(F("WEB : File=%s, %d bytes" CR), dir.fileName().c_str(),
|
||||
dir.fileSize());
|
||||
}
|
||||
|
||||
// Check if the html files exist, if so serve them, else show the static
|
||||
// upload page.
|
||||
if (checkHtmlFile(HTML_INDEX) && checkHtmlFile(HTML_CONFIG) &&
|
||||
|
@ -28,12 +28,12 @@ SOFTWARE.
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#define MAX_SKETCH_SPACE 1044464
|
||||
#define MAX_SKETCH_SPACE 1044464
|
||||
#else // defined (ESP32)
|
||||
#include <ESPmDNS.h>
|
||||
#include <Update.h>
|
||||
#include <WebServer.h>
|
||||
#include <WiFi.h>
|
||||
#include <Update.h>
|
||||
#define MAX_SKETCH_SPACE 1835008
|
||||
#endif
|
||||
#include <incbin.h>
|
||||
|
28
src/wifi.cpp
@ -74,10 +74,7 @@ bool WifiConnection::hasConfig() {
|
||||
if (strlen(userSSID)) return true;
|
||||
|
||||
// Check if there are stored WIFI Settings we can use.
|
||||
#if defined(ESP32)
|
||||
#warning \
|
||||
"Cant read SSID on ESP32 until a connection has been made, this part will not work, change to WifiManager"
|
||||
#endif
|
||||
#if defined(ESP8266)
|
||||
String ssid = WiFi.SSID();
|
||||
if (ssid.length()) {
|
||||
Log.notice(F("WIFI: Found credentials in EEPORM." CR));
|
||||
@ -88,6 +85,10 @@ bool WifiConnection::hasConfig() {
|
||||
myConfig.saveFile();
|
||||
return true;
|
||||
}
|
||||
#else // defined( ESP32 )
|
||||
#warning "Cant read SSID property on ESP32 until a connection has been made!"
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -279,16 +280,19 @@ bool WifiConnection::connect() {
|
||||
if (!waitForConnection(timeout)) {
|
||||
Log.warning(F("WIFI: Failed to connect to first SSID %s." CR),
|
||||
myConfig.getWifiSSID(0));
|
||||
connectAsync(1);
|
||||
|
||||
if (waitForConnection(timeout)) {
|
||||
Log.notice(
|
||||
F("WIFI: Connected to second SSID %s, making secondary default." CR),
|
||||
myConfig.getWifiSSID(1));
|
||||
if (strlen(myConfig.getWifiSSID(1))) {
|
||||
connectAsync(1);
|
||||
|
||||
myConfig.swapPrimaryWifi();
|
||||
myConfig.saveFile();
|
||||
return true;
|
||||
if (waitForConnection(timeout)) {
|
||||
Log.notice(F("WIFI: Connected to second SSID %s, making secondary "
|
||||
"default." CR),
|
||||
myConfig.getWifiSSID(1));
|
||||
|
||||
myConfig.swapPrimaryWifi();
|
||||
myConfig.saveFile();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Log.warning(F("WIFI: Failed to connect to any SSID." CR));
|
||||
|
@ -19,6 +19,10 @@ To reduce the need for adding custom endpoints for various services there is an
|
||||
You enter the format data in the text field and the test button will show an example on what the output would look like. If the data cannot be formatted in json it will just be displayed as a long string.
|
||||
The save button will save the current formla and reload the data from the device.
|
||||
|
||||
You can also select a template from the list and copy that to the current endpoint.
|
||||
|
||||
Saving an empty formula will reset it to the default value.
|
||||
|
||||
.. tip::
|
||||
|
||||
If you save a blank string the default template will be loaded.
|
||||
@ -95,4 +99,10 @@ These are the format keys available for use in the format.
|
||||
* - ${gravity-unit}
|
||||
- Gravity format, `G` or `P`
|
||||
- G
|
||||
* - ${app-ver}
|
||||
- Software version
|
||||
- 1.1.0
|
||||
* - ${app-build}
|
||||
- Software revision (git hash)
|
||||
- ..e456743
|
||||
|
||||
|
@ -58,23 +58,9 @@ Other parameters are the same as in the configuration guide.
|
||||
},
|
||||
"formula-calculation-data": {
|
||||
"a1":25,
|
||||
"a2":30,
|
||||
"a3":35,
|
||||
"a4":40,
|
||||
"a5":45,
|
||||
"a5":0,
|
||||
"a6":0,
|
||||
"a7":0,
|
||||
"a8":0,
|
||||
"a10":0,
|
||||
"g1":1,
|
||||
"g2":1.01,
|
||||
"g3":1.02,
|
||||
"g4":1.03,
|
||||
"g4":1.04,
|
||||
"g5":1,
|
||||
"g6":1,
|
||||
"g7":1,
|
||||
"g8":1
|
||||
"g10":1
|
||||
},
|
||||
"angle": 90.93,
|
||||
"gravity": 1.105,
|
||||
@ -109,6 +95,7 @@ Other parameters are the same as in the configuration guide.
|
||||
"temp-c": 0,
|
||||
"temp-f": 32,
|
||||
"battery": 0,
|
||||
"wifi-ssid": "connected SSID",
|
||||
"temp-format": "C",
|
||||
"sleep-mode": false,
|
||||
"token": "token",
|
||||
@ -127,8 +114,8 @@ GET: /api/config/formula
|
||||
|
||||
Retrive the data used for formula calculation data via an HTTP GET command. Payload is in JSON format.
|
||||
|
||||
* ``a1``-``a8`` are the angles/tilt readings (up to 8 are currently supported)
|
||||
* ``g1``-``g8`` are the corresponding gravity reaadings in SG or Plato depending on the device-format.
|
||||
* ``a1``-``a10`` are the angles/tilt readings (up to 10 are currently supported)
|
||||
* ``g1``-``g10`` are the corresponding gravity reaadings in SG or Plato depending on the device-format.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
@ -142,6 +129,8 @@ Retrive the data used for formula calculation data via an HTTP GET command. Payl
|
||||
"a6": 0,
|
||||
"a7": 0,
|
||||
"a8": 0,
|
||||
"a9": 0,
|
||||
"a10": 0,
|
||||
"g1": 1.000,
|
||||
"g2": 1.053,
|
||||
"g3": 1.062,
|
||||
@ -150,6 +139,8 @@ Retrive the data used for formula calculation data via an HTTP GET command. Payl
|
||||
"g6": 1,
|
||||
"g7": 1,
|
||||
"g8": 1,
|
||||
"g9": 1,
|
||||
"g10": 1,
|
||||
"error": "Potential error message",
|
||||
"gravity-format": "G",
|
||||
"gravity-formula": "0.0*tilt^3+0.0*tilt^2+0.0017978*tilt+0.9436"
|
||||
@ -165,11 +156,13 @@ Used for adjusting some internal constants and other advanced settings. Should b
|
||||
|
||||
{
|
||||
"gyro-read-count": 50,
|
||||
"gyro-read-delay": 3150,
|
||||
"tempsensor-resolution": 9,
|
||||
"gyro-moving-threashold": 500,
|
||||
"formula-max-deviation": 1.6,
|
||||
"wifi-portaltimeout": 120,
|
||||
"wifi-portal-timeout": 120,
|
||||
"wifi-connect-timeout": 20,
|
||||
"formula-calibration-temp": 20,
|
||||
"ignore-low-angles": false,
|
||||
"int-http1": 0,
|
||||
"int-http2": 0,
|
||||
"int-http3": 0,
|
||||
@ -182,8 +175,11 @@ POST: /api/config/advanced
|
||||
|
||||
Same parameters as above.
|
||||
|
||||
Payload should be in standard format used for posting a form
|
||||
Payload should be in standard format used for posting a form.
|
||||
|
||||
.. note::
|
||||
``ignore-low-angles`` is defined as "on" or "off" when posting since this is the output values
|
||||
from a checkbox, when reading data it's sent as boolean (true,false).
|
||||
|
||||
GET: /api/clearwifi
|
||||
===================
|
||||
@ -324,8 +320,8 @@ POST: /api/config/formula
|
||||
|
||||
Used to update formula calculation data via an HTTP POST command. Payload is in JSON format.
|
||||
|
||||
* ``a1``-``a8`` are the angles/tilt readings (up to 5 are currently supported)
|
||||
* ``g1``-``g8`` are the corresponding gravity reaadings (in SG)
|
||||
* ``a1``-``a10`` are the angles/tilt readings (up to 10 are currently supported)
|
||||
* ``g1``-``g10`` are the corresponding gravity reaadings (in SG)
|
||||
|
||||
Payload should be in standard format used for posting a form. Such as as: `id=value&mdns=value` etc. Key value pairs are shown below.
|
||||
|
||||
@ -340,6 +336,8 @@ Payload should be in standard format used for posting a form. Such as as: `id=va
|
||||
a6=0
|
||||
a7=0
|
||||
a8=0
|
||||
a9=0
|
||||
a19=0
|
||||
g1=1.000
|
||||
g2=1.053
|
||||
g3=1.062
|
||||
@ -348,6 +346,8 @@ Payload should be in standard format used for posting a form. Such as as: `id=va
|
||||
g6=1
|
||||
g7=1
|
||||
g8=1
|
||||
g9=1
|
||||
g10=1
|
||||
|
||||
|
||||
Calling the API's from Python
|
||||
@ -433,6 +433,8 @@ The requests package converts the json to standard form post format.
|
||||
"a6": 0,
|
||||
"a7": 0,
|
||||
"a8": 0,
|
||||
"a9": 0,
|
||||
"a10": 0,
|
||||
"g1": 1.000,
|
||||
"g2": 1.053,
|
||||
"g3": 1.062,
|
||||
@ -440,6 +442,8 @@ The requests package converts the json to standard form post format.
|
||||
"g5": 1,
|
||||
"g6": 1,
|
||||
"g7": 1,
|
||||
"g8": 1
|
||||
"g8": 1,
|
||||
"g9": 1,
|
||||
"g10": 1
|
||||
}
|
||||
set_config( url, json )
|
||||
|
@ -29,8 +29,9 @@ In the platformio config there are 3 targets defined
|
||||
|
||||
* gravity-debug; Maximum logging for trouble shooting, deep sleep is disabled.
|
||||
* gravity-release; Standard release
|
||||
* gravity-perf; Standard release but contains code for measuring performance
|
||||
* gravity32-perf: Experimental version for ESP32.
|
||||
* gravity-perf; Standard release but contains code for measuring performance.
|
||||
* gravity32-release: Version for ESP32.
|
||||
* gravity32-perf: Version for ESP32 but contains code for measuring performance.
|
||||
|
||||
.. note::
|
||||
There is an experimental ESP32 target but since platformio only supports SDK 1.0.6 and the WIFI connection is really slow compared to ESP8266,
|
||||
@ -68,8 +69,6 @@ Source structure
|
||||
- Source code for software
|
||||
* - /src_docs
|
||||
- Source code for documentation
|
||||
* - /stl
|
||||
- 3d models
|
||||
* - /test
|
||||
- Test data for developing html files
|
||||
|
||||
|
@ -22,7 +22,7 @@ copyright = '2021-2022, Magnus Persson'
|
||||
author = 'Magnus Persson'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '1.0.0'
|
||||
release = '1.1.0'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
@ -55,7 +55,8 @@ Device Setting
|
||||
|
||||
* **Device name:**
|
||||
|
||||
This is unique name for the device. It will be used in pushing data as well as mDNS name on the network (<name>.local)
|
||||
This is unique name for the device. It will be used in pushing data as well as mDNS name on the network (<name>.local).
|
||||
The limitation is 63 chars but using long names might break endpoints that data is sent to if they have other limitations.
|
||||
|
||||
* **Temperature format:**
|
||||
|
||||
@ -233,6 +234,11 @@ Hardware Settings
|
||||
|
||||
Factor used to calcualate the battery voltage. If you get a too low/high voltage you can adjust this value.
|
||||
|
||||
* **Config voltage:**
|
||||
|
||||
Defines the level of voltage when the device should enter config mode due to charging. This might vary between different battery manufacturers.
|
||||
If you dont what the device to go into configuration mode when charging, set this to 6V.
|
||||
|
||||
* **Temperature correction:**
|
||||
|
||||
This value will be added to the temperature reading (negative value will reduce temperature reading). This is applied
|
||||
@ -245,6 +251,12 @@ longer battery life (this is an experimental feature). The value used is the fir
|
||||
device is activated, since the gyro should be cool this is reflecting the surronding temperature. After it has
|
||||
been running the value would be totally off.
|
||||
|
||||
* **Enable storage mode when placed on cap**
|
||||
|
||||
When place on the cap (<5 degres tilt) the device will go into max sleep. In order to wake it up you need to do a reset (or wait for the device
|
||||
to wake up). One option is to attach a magnetic reed switch (default open) to the reset pin and use a magnet to force a reset without opening
|
||||
the tube. The reed switch is typically an electronic component of 14 mm long incapsulated in a small glass tube.
|
||||
|
||||
* **Bluetooth: (Only ESP32)**
|
||||
|
||||
If the build is using an ESP32 then you can send data over BLE, simulating a Tilt device. Choose the color that you want the device to simulate.
|
||||
@ -282,7 +294,45 @@ Advanded Settings
|
||||
:width: 800
|
||||
:alt: Advanced Settings
|
||||
|
||||
* **Header:**
|
||||
.. warning::
|
||||
|
||||
To be described
|
||||
Changeing these parameters with caution. The wrong values might cause the device to become unresponsive.
|
||||
|
||||
|
||||
* **Gyro reads:**
|
||||
|
||||
This defines how many gyro reads will be done before an angle is calculated. More reads will give better accuracy and also allow detection of
|
||||
movement. Too many reads will take time and affecte batterylife. 50 takes about 800 ms to execute.
|
||||
|
||||
* **Gyro moving threashold:**
|
||||
|
||||
This is the max amount of deviation allowed for a stable reading.
|
||||
|
||||
* **Formula deviation:**
|
||||
|
||||
This is the maximum devation on the formlula allowed for it to be accepted. Once the formula has been derived it will be validated against the supplied
|
||||
data and of the deviation on any point is bigger the formula will be rejected.
|
||||
|
||||
* **Ignore angles below water:**
|
||||
|
||||
If this option is checked any angles below that of SG 1 will be discarded as invalid and never sent to any server. Default = off.
|
||||
|
||||
* **DS18B20 Resolution:**
|
||||
|
||||
Define the resolution used on the temp sensor. 9 bits is default and will give an accuracy of 0.5C, 12 bits will give an accuracy of 0.0625C but will also
|
||||
take longer time to measure..
|
||||
|
||||
* **Wifi connect timeout:**
|
||||
|
||||
This is the amount of time allowed for a wifi connect.
|
||||
|
||||
* **Wifi portal timeout:**
|
||||
|
||||
If the wifi portal is triggered (can be triggerd by reset) then this is the amount of time allowed before it exists again.
|
||||
|
||||
* **Skip Interval (...):**
|
||||
|
||||
These options allow the user to have variable push intervals for the diffrent endpoints. 0 means that every wakeup will send data to that endpoint. If you enter another number then that defines how many sleep cycles will be skipped.
|
||||
|
||||
If the sleep interval is 300s and MQTT is set to 0 and HTTP1 is set to 2 then MQTT will be sent every 300s while HTTP1 would be sent 900s. This is great if you want to send data to a local mqtt server often but brewfather will only
|
||||
accept data every 15 min.
|
||||
|
@ -1,5 +1,33 @@
|
||||
Contributing
|
||||
############
|
||||
|
||||
Anyone is welcome to contribute to this project or create their own variant of it. I would appreciate a PR if your feature would be of benefit other users.
|
||||
|
||||
In order to keep the source code in good condition I use `pre-commit <https://pre-commit.com/>`_ to validate and format the code using their standards for C++/C.
|
||||
|
||||
.. note::
|
||||
|
||||
If you are using Windows as a base platform I would suggest that you install pre-commit under wsl (Windows Subssytem for Windows) and run it from there, I have found
|
||||
that this approach works fine.
|
||||
|
||||
|
||||
The following command will run pre-commit on all the source files. Assuming you are inte project directory.
|
||||
|
||||
.. code-block::
|
||||
|
||||
pre-commit run --files src/*
|
||||
|
||||
|
||||
Design goals
|
||||
------------
|
||||
|
||||
This section is under construction.
|
||||
My goals with this software has been the following:
|
||||
|
||||
* Create an open software for the excellent iSpindle hardware platform that is open and available for anyone.
|
||||
* Add user requested features that have not made it into the iSpindle project.
|
||||
* Focus on long battery life and stability.
|
||||
* Explore new technologies and create the next generation gravity monitoring for home brewers.
|
||||
|
||||
I will do my best to assist users and respond to new features, pr and suggestions. But keep in mind I'm doing this on my spare time.
|
||||
|
||||
Regards, Magnus
|
||||
|
@ -40,7 +40,7 @@ This is the format template used to create the json above.
|
||||
{
|
||||
"name" : "${mdns}",
|
||||
"ID": "${id}",
|
||||
"token" : "gravmon",
|
||||
"token" : "${token}",
|
||||
"interval": ${sleep-interval},
|
||||
"temperature": ${temp},
|
||||
"temp_units": "${temp-unit}",
|
||||
@ -129,15 +129,6 @@ This is the format template used to create the json above.
|
||||
ispindel/${mdns}/interval:${sleep-interval}|
|
||||
ispindel/${mdns}/RSSI:${rssi}|
|
||||
|
||||
This is a format template that is compatible with v0.6. Just replace the `topic` with the topic you want to post data to.
|
||||
|
||||
.. code-block::
|
||||
|
||||
topic:{"name":"gravmon", "ID":"${id}", "token":"gravmon", "interval": ${sleep-interval},
|
||||
"temperature": ${temp}, "temp_units": "${temp-unit}", "gravity":${gravity},
|
||||
"angle": ${angle}, "battery":${battery}, "rssi": ${rssi}, "corr-gravity":${corr-gravity},
|
||||
"gravity-unit": "${gravity-unit}", "run-time": ${run-time}}|
|
||||
|
||||
|
||||
version.json
|
||||
============
|
||||
@ -150,13 +141,6 @@ they can be uploaded manually afterwards.
|
||||
|
||||
{
|
||||
"project":"gravmon",
|
||||
"version":"0.7.0",
|
||||
"html": [
|
||||
"index.min.htm",
|
||||
"test.min.htm",
|
||||
"config.min.htm",
|
||||
"format.min.htm",
|
||||
"calibration.min.htm",
|
||||
"about.min.htm"
|
||||
]
|
||||
"version":"1.0.0",
|
||||
"html": [ ]
|
||||
}
|
||||
|
@ -7,10 +7,33 @@ Create formula
|
||||
:width: 800
|
||||
:alt: Formula data
|
||||
|
||||
Here you can enter up to 5 values (angles + gravity) that is then used to create the formula. Angles equal to zero will be regarded as empty even if there is a gravity reading.
|
||||
Here you can enter up to 10 values (angles + gravity) that is then used to create the formula. Angles equal to zero will be regarded as empty even if there is a gravity reading.
|
||||
|
||||
When you submit the values the device will try create a forumla with increasing level of complexity. It will start
|
||||
with a order 2 formula and then try 3 and 4.
|
||||
|
||||
Once the formula has been created it will validate the formula against the supplied angles/gravity and if there is a too
|
||||
high difference, it will fail. You can adjust the sensitivity under advanced settings if you have issues.
|
||||
|
||||
Under the Error Log you will also find hints to what problem the formula creator encountered. Here is an example:
|
||||
|
||||
`CALC: Validation failed on angle 33.430000, deviation too large 5.86, formula order 4`
|
||||
|
||||
`CALC: Validation failed on angle 33.430000, deviation too large 3.14, formula order 2`
|
||||
|
||||
This means that the angle 33.43 had a deviation of 5.8 SG and since the default threashold is 3, it will fail. You
|
||||
can also see that it has failed on that point in both a order 2 and 4 formula.
|
||||
|
||||
.. image:: images/qa_1.png
|
||||
:width: 400
|
||||
:alt: Example of deviating value
|
||||
|
||||
So in this case you can either increase the threashold or remove the angle that has an issue. You can also
|
||||
use the graph on the calibration page to identify angles that is probably not correct.
|
||||
|
||||
.. image:: images/formula2.png
|
||||
:width: 800
|
||||
:alt: Formula graph
|
||||
|
||||
Once the formula is created a graph over the entered values and a simulation of the formula will give you a nice overview on how the formula will work.
|
||||
|
||||
|
@ -33,10 +33,10 @@ The main features
|
||||
|
||||
Currently the device supports the following endpoints.
|
||||
|
||||
* http or https
|
||||
* influxdb v2
|
||||
* http (ssl optional)
|
||||
* influxdb v2 (ssl optional)
|
||||
* MQTT (ssl optional)
|
||||
* Brewfather
|
||||
* MQTT
|
||||
* Home Assistant
|
||||
* Brew Spy
|
||||
* Brewers Friend
|
||||
@ -65,11 +65,9 @@ The main features
|
||||
Another big difference is that this software can create the gravity formula in the device, just enter the
|
||||
angle/gravity data that you have collected. You will also see a graph simulating how the formula would work.
|
||||
|
||||
Currently the device can handle 5 data points which should be enough to get a accurate formula. At least 3 data points
|
||||
Currently the device can handle 10 data points which should be enough to get a accurate formula. At least 3 data points
|
||||
is needed to get an accurate formula.
|
||||
|
||||
If there is a need for more data points, raise a comment on github.
|
||||
|
||||
* **Customize the data format beeing sent to push targets**
|
||||
|
||||
In order to make it easier to support more targets there is a built in format editor that can be used to
|
||||
@ -86,7 +84,8 @@ The main features
|
||||
* **OTA support from webserver**
|
||||
|
||||
When starting up in configuration mode the device will check for a software update from a webserver. This is an easily
|
||||
way to keep the software up to date. In the future I might add a hosted endpoint for providing updates.
|
||||
way to keep the software up to date. In the future I might add a hosted endpoint for providing updates. OTA can also be
|
||||
done over a SSL connection.
|
||||
|
||||
* **DS18B20 temperature adjustments**
|
||||
|
||||
@ -95,13 +94,14 @@ The main features
|
||||
|
||||
* **Gyro Movement**
|
||||
|
||||
The software will detect if the gyro is moving and if this is the case it will go back to sleep for 60seconds.
|
||||
This way we should avoid faulty measurements and peaks in the graphs.
|
||||
The software will detect if the gyro is moving and if this is the case it will go back to sleep for 60 seconds.
|
||||
This way we should avoid faulty measurements and peaks in the graphs.
|
||||
|
||||
* **WIFI connection issues**
|
||||
|
||||
The software will not wait indefiently for a wifi connection. If it takes longer than 20 seconds to connect then
|
||||
the device will go into deep sleep for 60 seoncds and then retry later. This to conserve batter as much as possible.
|
||||
the device will try the seconday wifi configuration, and that also failes it will go into deep sleep for 60 seconds and then
|
||||
retry later. This to conserve batter as much as possible.
|
||||
|
||||
* **Use gyro temperature sensor**
|
||||
|
||||
|
@ -24,3 +24,22 @@ need to adjust the voltage factor so the battery reading is correct.
|
||||
:width: 500
|
||||
:alt: Mounting esp32
|
||||
|
||||
Schema for esp8266 build
|
||||
------------------------
|
||||
|
||||
.. image:: images/schema_esp8266.png
|
||||
:width: 700
|
||||
:alt: Schema esp8266
|
||||
|
||||
Schema for esp32 build
|
||||
----------------------
|
||||
|
||||
.. note::
|
||||
This schema assumes that an ESP32 D1 Mini (pin compatible with ESP8266 D1 Mini is used)
|
||||
The ESP32 has two rows of pins but only the inner row is used. The main difference is the added resistor R3 so we
|
||||
get a voltage divider for measuring battery. The ESP8266 has a built in resistor thats not visible on the schema.
|
||||
|
||||
|
||||
.. image:: images/schema_esp32.png
|
||||
:width: 700
|
||||
:alt: Schema esp32
|
||||
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 37 KiB |
BIN
src_docs/source/images/config5.png
Normal file
After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 7.4 MiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 71 KiB |
BIN
src_docs/source/images/qa_1.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src_docs/source/images/schema_esp32.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
src_docs/source/images/schema_esp8266.png
Normal file
After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 73 KiB |
@ -7,7 +7,10 @@ Welcome to GravityMon's documentation!
|
||||
######################################
|
||||
|
||||
.. note::
|
||||
This documentation reflects **v1.0**. Last updated 2022-04-26
|
||||
This documentation reflects **v1.1 BETA 2**. Last updated 2022-07-23
|
||||
|
||||
* Docs for: `v1.0 <https://mp-se.github.io/gravitymon/v1.0/index.html>`_
|
||||
* Docs for: `v0.9 <https://mp-se.github.io/gravitymon/v0.9/index.html>`_
|
||||
|
||||
.. image:: images/gravitymon.gif
|
||||
:width: 800
|
||||
|
@ -13,7 +13,8 @@ Brewflasher
|
||||
===========
|
||||
|
||||
The prefered option for flashing GravityMon is using BrewFlasher, its a tools that support many brewing related firmwares for ESP8266 and ESP32. This works
|
||||
on both Windows and Mac. You can download the latest version from here: `Brewflasher <https://www.brewflasher.com/>`_
|
||||
on both Windows and Mac. You can download the latest version from here: `Brewflasher <https://www.brewflasher.com/>`_ there is also a web based version
|
||||
available here `Brewflasher WEB <https://web.brewflasher.com/>`_.
|
||||
|
||||
.. image:: images/brewflasher.png
|
||||
:width: 600
|
||||
@ -34,7 +35,8 @@ In the /bin directory you will find 3 different firmware builds;
|
||||
|
||||
* **firmware32.bin**
|
||||
|
||||
This is the standard release build for an ESP32 variant
|
||||
This is the standard release build for an ESP32 variant. When flashing an ESP32 you also need the **partition32.bin** file that outlines the flash memory structure. Due to
|
||||
the size of the firmware we are using a custom partition setup.
|
||||
|
||||
In these versions all the html files are embedded in the binaries. The file system is currently only used for storing
|
||||
the configuration file.
|
||||
@ -90,7 +92,6 @@ browser and select the firmware.bin file that corresponds to the version you wan
|
||||
``http://<device_name>/firmware.htm``
|
||||
|
||||
|
||||
|
||||
.. _serial_monitoring:
|
||||
|
||||
Serial Monitoring
|
||||
@ -120,6 +121,14 @@ in the browser: **http://192.168.4.1**
|
||||
Before pressing save on the network infomration, make a note of the devicename that is shown on the screen, this will be the name that is used
|
||||
in the next step to access the configuration pages. The link would look like this: **http://gravitymon56EA34.local**
|
||||
|
||||
.. note::
|
||||
When selecting a SSID in the list this will be populated in both wifi fields. This is the behaviour of the wifi manager library that I'm using,
|
||||
in the future this is planned to be moved to the normal UI.
|
||||
|
||||
Under wifi settings you can define a primary and seconday wifi SSID. The seconday will be used in case the primary fails. If the seconday is
|
||||
successful then it will be used as primary. *The second wifi setting is optional and not needed.*
|
||||
|
||||
|
||||
.. image:: images/wifi.png
|
||||
:width: 200
|
||||
:alt: Wifi page
|
||||
|
@ -19,6 +19,12 @@ Step 2 - Setup WIFI
|
||||
When the device starts up the first time it will first start an WIFI access point so that the WIFI Settings
|
||||
can be configured. The instructions for that can be found here :ref:`setup_wifi`
|
||||
|
||||
.. note::
|
||||
Since the user interface is built using modern frameworks the device requires access to the internet
|
||||
for the UI to render and data to be populated. The sites that are needed are; https://cdn.jsdelivr.net/npm/bootstrap
|
||||
and https://code.jquery.com
|
||||
|
||||
|
||||
Step 3 - Configuration
|
||||
----------------------
|
||||
|
||||
|
@ -12,3 +12,36 @@ My device reports a temperature of -273C or -491F
|
||||
-------------------------------------------------
|
||||
- The DS18B20 temperature sensor cannot be found and this is the default value reported in this case.
|
||||
- Check the orienation of the sensor and soldering.
|
||||
|
||||
Calibration error (unable to find a valid formula)
|
||||
--------------------------------------------------
|
||||
If you have issues to get a calibration formula. When a formula has been created the device always tries to validate the formula against the supplied values and if there is a to high deviation on any of the values then the formula will be rejected.
|
||||
|
||||
The image here shows such a case, one of the values is out of bounds.
|
||||
|
||||
.. image:: images/qa_1.png
|
||||
:width: 500
|
||||
:alt: Calibration Error
|
||||
|
||||
To fix these this you can;
|
||||
|
||||
- remove the value from the list (setting the angle to zero will do that)
|
||||
- change the advanced setting (Formula max deviation) to a higher value and save the values again.
|
||||
|
||||
In the case above this paramater was changed from 1.6 SG to 4 SG and the formula was accepted. The deviation on this point was just above 3 SG.
|
||||
|
||||
User interface does not render correctly
|
||||
----------------------------------------
|
||||
|
||||
Since the user interface is built using bootstrap v5 the device requires access to the internet
|
||||
to download required javascripts and css files. Due to size it would not be possible to store these
|
||||
on the device. Make sure the device can access: https://cdn.jsdelivr.net/npm/bootstrap
|
||||
|
||||
Data is not popoulated in the fields
|
||||
------------------------------------
|
||||
|
||||
The user interface uses JQuery to fetch data from the device. This javascript library needs to be downloaded
|
||||
from the internet. Due to size it would not be possible to store these on the device. Make sure the
|
||||
device can access: https://code.jquery.com
|
||||
|
||||
Also ensure that any security tools does not block the execution of these features.
|
||||
|
@ -3,26 +3,97 @@
|
||||
Releases
|
||||
########
|
||||
|
||||
v1.1.0 - beta 2
|
||||
===============
|
||||
|
||||
Documentation
|
||||
+++++++++++++
|
||||
* Fixed errors in data format section
|
||||
* Added q&a on formula creation and value deviation
|
||||
* Added documentation for Brewpiless as target
|
||||
* Updated docs for ubidots service integration.
|
||||
* Added brewblox as new service
|
||||
* (beta2) Updated docs for HA integration since method was depricated
|
||||
|
||||
User interface
|
||||
++++++++++++++
|
||||
* Under format options its now possible to select brewfather ispindle format to avoid mixing endpoints.
|
||||
* Added brewblox as format under format options.
|
||||
* User can now edit the voltage level that forces the device into config mode (charging)
|
||||
* (beta2) Calibration temperature (for temp adjustment) can now be set under advanced settings.
|
||||
* (beta2) Changes length of device name from 12 to 63 chars. 63 is the max limit according to mdns.
|
||||
|
||||
Features
|
||||
++++++++
|
||||
* Added storage mode which is activated under hardware setting. When place on the cap (<5 degres tilt) the device will go into storage mode and sleep for the max allowed time.
|
||||
* Added ${app-ver} and ${app-build} to format template as new variables.
|
||||
* Added format templates for HA auto registration
|
||||
* (beta2) Improved error messages when creating formula so the meaasurement points can be identified.
|
||||
* (beta2) Changed defaule validation threashold from 1.6 SG to 3.0 SG, this should allow for some more variance when creating formula.
|
||||
* (beta2) Updated format template for Home Assistant for using manual configuration (Aligned with new mqtt configuration format)
|
||||
* (beta2) Added format template for Home Assistant with automatic device registration
|
||||
|
||||
Other
|
||||
+++++
|
||||
* Upgraded framework for ESP8266 to v5.0.0
|
||||
* Upgraded framework for ESP32 to v2.0.2
|
||||
* Updated OneWire library to be complaint with new ESP32 SDK
|
||||
* Fixed issue in i2cdev connected to wrong usage of TwoWire on ESP32 (Gyro initialization hang).
|
||||
|
||||
Issues adressed
|
||||
++++++++++++++++
|
||||
* BUG: Copy format templates used an old format for iSpindle and Gravmon where the token was not used.
|
||||
* BUG: Gravity correction formula not calculating correctly.
|
||||
* (beta2) BUG: Temp corrected gravity was not used when pushing data to removed
|
||||
* (beta2) BUG: Low memory in format api which resulted in mqtt template to be set to null
|
||||
* (beta2) BUG: Large format templates could be saved but when loading it's only blank. Increased total memory from 3kb to 5kb
|
||||
|
||||
v1.0.0
|
||||
------
|
||||
* Upgraded to bootstrap v5.1 for web pages.
|
||||
* Added tooltips to all fields in user interface
|
||||
* Removed brewfather option (can use standard HTTP options), the old apporach can still be used via changing format template.
|
||||
* Added 5 more points for formula creation, so a total of 10 angles/gravity values can be stored.
|
||||
* Added function on format page so that it's easy to copy a format template from the docs (simplify service integration).
|
||||
* Added https support for Influxdb
|
||||
* Added possibility to have variable push intervals for different endpoints so that different frequency can be used, for example; 5min mqtt, 15min brewfather.
|
||||
* Added advanced settings to configuration for adjusting some internal values (gyro reads, accepted formula deviation, timeouts, moving detection etc).
|
||||
* Added additional http error codes to troubleshooting documentation
|
||||
======
|
||||
|
||||
Documentation
|
||||
+++++++++++++
|
||||
* Update documentation to match v1.0
|
||||
* Installation instructions updated on how to find the device after wifi has been configured.
|
||||
* Documentation on brewfather has been updated to adress SG/Plato conversion
|
||||
* BUG: Fixed issue in formula calculation in case there were a gap in the data series
|
||||
* BUG: Field name for wifi strenght changed from "rssi" to "RSSI"
|
||||
* Added circuit diagram for esp8266 and esp32
|
||||
* Added additional http error codes to troubleshooting documentation
|
||||
|
||||
* TODO: Fix documentation for advanced settings.
|
||||
User interface
|
||||
++++++++++++++
|
||||
* Upgraded to bootstrap v5.1 for web pages.
|
||||
* Added button on indexpage to direct to github issues.
|
||||
* Added button to extract important information for support requests.
|
||||
* First point in gravity formula is now reserved for water gravity, this to allow detection of angles below water that can be filtered out.
|
||||
* Changed layout on index page with measured data on top.
|
||||
* Added tooltips to all fields in user interface
|
||||
* Added function on format page so that it's easy to copy a format template from the docs (simplify service integration).
|
||||
|
||||
Features
|
||||
++++++++
|
||||
* Added advanced setting to ignore angles that are lower than water. This is disabled by default.
|
||||
* Added support for MPU6500 (standard is MPU6050).
|
||||
* Removed brewfather option (can use standard HTTP options), the old apporach can still be used via changing format template.
|
||||
* Added 5 more points for formula creation, so a total of 10 angles/gravity values can be stored.
|
||||
* Added https support for Influxdb v2
|
||||
* Added possibility to set 2 wifi ssid where the second acts as a fallback in case it fails to connect. If succesful the seconday becomes the new primary.
|
||||
* SSL connections are skipped on ESP8266 when in config mode since there is a high probability it will crash due to low memory.
|
||||
* Advanced settings: Added possibility to have variable push intervals for different endpoints so that different frequency can be used, for example; 5min mqtt, 15min brewfather.
|
||||
* Advanced settings: Changes how many times the gyro is read (less reads, quicker but less accurate)
|
||||
* Advanced settings: Set amount of gyro movement is allowed for a accurate read.
|
||||
* Advanced settings: What deviation is acceptable for creating formula deviation
|
||||
* Advanced settings: Various timeouts, wifi connect, wifi portal, http connects.
|
||||
* Advanced settings: Adjust resolution of temp sensor (9 bits to 12 bits), higher resolution takes longer thus reducing batterylife
|
||||
|
||||
Issues adressed
|
||||
++++++++++++++++
|
||||
* BUG: Fixed issue in formula calculation in case there were a gap in the data series
|
||||
* BUG: Field name for wifi strength changed from "rssi" to "RSSI"
|
||||
* BUG: Fixed issue with probing MFLN on non standard ports
|
||||
* BUG: Changed http connection to keep-alive so that server does not close port before the client has had a chance to read the response.
|
||||
|
||||
v0.9.0
|
||||
------
|
||||
======
|
||||
* Added one http push target that uses HTTP GET. This can be used with ubidots or blynk api's.
|
||||
* Added function to test push targets from configuration page. It will send data and show the return code as a first step.
|
||||
* Added documetation on how to integrate with Blynk.io using http get.
|
||||
@ -47,8 +118,7 @@ v0.9.0
|
||||
* BUG: Entering wifi setup and a timeout occured the wifi settings could be deleted.
|
||||
|
||||
v0.8.0
|
||||
------
|
||||
|
||||
======
|
||||
* Added option to set http headers (2 per http endpoint), these can be used for
|
||||
other http formats than json (default) and for adding authentication headers.
|
||||
* Added possibility to view last 10 errors on device page.
|
||||
@ -68,8 +138,7 @@ v0.8.0
|
||||
* Tested batterylife, 47 days using an update frequency of 5 min
|
||||
|
||||
v0.7.1
|
||||
------
|
||||
|
||||
======
|
||||
* Added instructions for how to configure integration with Fermentrack
|
||||
* Added instructions for how to configure integration with Ubidots
|
||||
* Added instructions for how to configure integration with HomeAssistant
|
||||
@ -79,8 +148,7 @@ v0.7.1
|
||||
* BUG: Fixed issue with default template so it now includes the device name correctly.
|
||||
|
||||
v0.7.0
|
||||
------
|
||||
|
||||
======
|
||||
Latest stable version. `Release v0.7 on Github <https://github.com/mp-se/gravitymon/releases/tag/v0.7.0>`_
|
||||
|
||||
* SSL support for HTTP targets
|
||||
@ -106,10 +174,7 @@ Latest stable version. `Release v0.7 on Github <https://github.com/mp-se/gravity
|
||||
the behaviour in v0.6 is wanted this can be done via the format editor.
|
||||
|
||||
v0.6.0
|
||||
------
|
||||
|
||||
`Release v0.6 on Github <https://github.com/mp-se/gravitymon/releases/tag/v0.6.0>`_
|
||||
|
||||
======
|
||||
* Changed the wifi manager and refactored wifi.cpp
|
||||
* LED is now turned on when Wifi Portal is open
|
||||
* Refactored main.cpp to make it easier to read
|
||||
@ -122,10 +187,7 @@ v0.6.0
|
||||
* Bug: MPU init sometimes caused crash during startup.
|
||||
|
||||
v0.5.0
|
||||
------
|
||||
|
||||
`Release v0.5 on Github <https://github.com/mp-se/gravitymon/releases/tag/v0.5.0>`_
|
||||
|
||||
======
|
||||
* Added feature to calcuate formula on device
|
||||
* Total rewrite of documentation
|
||||
* WIFI settings are now stored in config file
|
||||
@ -134,8 +196,5 @@ v0.5.0
|
||||
* Refactor code from C to C++
|
||||
|
||||
v0.4.0
|
||||
------
|
||||
|
||||
`Release v0.4 on Github <https://github.com/mp-se/gravitymon/releases/tag/v0.4.0>`_
|
||||
|
||||
* First release
|
||||
======
|
||||
* First public release
|
@ -75,7 +75,9 @@ GravityMon can be installed and used as an iSpindle. Just register the device as
|
||||
UBIdots
|
||||
+++++++
|
||||
|
||||
`UBIdots <https://www.ubidots.com>`_ is a IoT service that display data collected various sources.
|
||||
`UBIdots <https://www.ubidots.com>`_ is a IoT service that display data collected various sources. There is a limitation on this service where it can only handle 10 variables per device so
|
||||
you might need to reduce the number of values sent to the service. It will also treat every parameter as a number unless you create a custom device type and explicit define the string values
|
||||
as text. This will require a paid subscription (as I interpret the documentation). The example format below will only send numbers so that should work fine with the paid subscription.
|
||||
|
||||
For this service there are two options to configure the integration. First you will need your default token which is found under `API Credentials` (<api-tokem> in the example below).
|
||||
Swap the text <devicename> with the name you want to show in ubidots.
|
||||
@ -120,14 +122,14 @@ format template that can be used. For information on customizing the format see
|
||||
"gravity": ${gravity},
|
||||
"angle": ${angle},
|
||||
"battery": ${battery},
|
||||
"rssi": ${rssi}
|
||||
"RSSI": ${rssi}
|
||||
}
|
||||
|
||||
|
||||
Home Assistant
|
||||
+++++++++++++++
|
||||
|
||||
`HomeAssistant <https://www.homeassistant.com>`_ is a platform for home automation and can collect sensor data
|
||||
`HomeAssistant <https://www.homeassistant.io>`_ is a platform for home automation and can collect sensor data
|
||||
from multiple devices.
|
||||
|
||||
This setup uses the MQTT integration with home assistant to collect values from the device.
|
||||
@ -137,27 +139,50 @@ device is named `gravmon2`
|
||||
|
||||
::
|
||||
|
||||
mqtt:
|
||||
sensor:
|
||||
- platform: mqtt
|
||||
name: "gravmon2_gravity"
|
||||
state_topic: "gravmon/gravmon2/gravity"
|
||||
- platform: mqtt
|
||||
name: "gravmon2_battery"
|
||||
state_topic: "gravmon/gravmon2/battery"
|
||||
- platform: mqtt
|
||||
name: "gravmon2_rssi"
|
||||
state_topic: "gravmon/gravmon2/rssi"
|
||||
- name: "Gravmon2-Gravity"
|
||||
state_topic: "gravmon/gravmon2/gravity"
|
||||
unique_id: gravmon2_grav
|
||||
unit_of_measurement: "SG"
|
||||
- name: "Gravmon2-RSSI"
|
||||
state_topic: "gravmon/gravmon2/rssi"
|
||||
unique_id: gravmon2_rssi
|
||||
unit_of_measurement: "dBm"
|
||||
|
||||
|
||||
Enter the name of the MQTT server in Home Assistant in the URL. You might need to install that option
|
||||
first. This is the format needed to submit the data to the correct topics as needed above. You can add as
|
||||
many sensors / topics as you want.
|
||||
many sensors / topics as you want. It's also possible that you will need to create a user and supply the
|
||||
username / password to be able to publish messages on a topic.
|
||||
|
||||
::
|
||||
|
||||
gravmon/${mdns}/gravity:${gravity}|
|
||||
gravmon/${mdns}/rssi:${rssi}|
|
||||
gravmon/${mdns}/battery:${battery}|
|
||||
|
||||
|
||||
It's also possible to allow home assistant to do autodisovery and automatically create the sensor. This format
|
||||
template will create two sensors and update the values for them.
|
||||
|
||||
.. warning::
|
||||
This will only work on 1.1+ since the the memory allocation on previous versions are not enough to handle this large payload.
|
||||
Earlier version can handle 2 of the values.
|
||||
|
||||
|
||||
::
|
||||
|
||||
gravmon/${mdns}/tilt:${angle}|
|
||||
gravmon/${mdns}/temperature:${temp}|
|
||||
gravmon/${mdns}/temp_units:${temp-unit}|
|
||||
gravmon/${mdns}/gravity:${gravity}|
|
||||
gravmon/${mdns}/rssi:${rssi}|
|
||||
gravmon/${mdns}/tilt:${tilt}|
|
||||
gravmon/${mdns}/battery:${battery}|
|
||||
homeassistant/sensor/gravmon_${id}/temperature/config:{"dev":{"name":"${mdns}","mdl":"gravmon","sw":"${app-ver}","ids":"${id}"},"uniq_id":"${id}_temp","name":"temperature","dev_cla":"temperature","unit_of_meas":"${temp-unit}","stat_t":"gravmon/${mdns}/temperature"}|
|
||||
homeassistant/sensor/gravmon_${id}/gravity/config:{"dev":{"name":"${mdns}","mdl":"gravmon","sw":"${app-ver}","ids":"${id}"},"uniq_id":"${id}_grav","name":"gravity","dev_cla":"temperature","unit_of_meas":" ${gravity-unit}","stat_t":"gravmon/${mdns}/gravity"}|
|
||||
homeassistant/sensor/gravmon_${id}/rssi/config:{"dev":{"name":"${mdns}","mdl":"gravmon","sw":"${app-ver}","ids":"${id}"},"uniq_id":"${id}_rssi","name":"rssi","dev_cla":"temperature","unit_of_meas":"dBm","stat_t":"gravmon/${mdns}/rssi"}|
|
||||
homeassistant/sensor/gravmon_${id}/tilt/config:{"dev":{"name":"${mdns}","mdl":"gravmon","sw":"${app-ver}","ids":"${id}"},"uniq_id":"${id}_tilt","name":"tilt","dev_cla":"temperature","stat_t":"gravmon/${mdns}/tilt"}|
|
||||
homeassistant/sensor/gravmon_${id}/battery/config:{"dev":{"name":"${mdns}","mdl":"gravmon","sw":"${app-ver}","ids":"${id}"},"uniq_id":"${id}_batt","name":"battery","dev_cla":"temperature","unit_of_meas":"V","stat_t":"gravmon/${mdns}/battery"}|
|
||||
|
||||
|
||||
Brewer's Friend
|
||||
@ -194,7 +219,7 @@ format for the endpoint. Just add you API key after token.
|
||||
"gravity": ${gravity},
|
||||
"angle": ${angle},
|
||||
"battery": ${battery},
|
||||
"rssi": ${rssi}
|
||||
"RSSI": ${rssi}
|
||||
}
|
||||
|
||||
|
||||
@ -261,3 +286,43 @@ starting with a ``?``. This string will be added to the URL above when doing the
|
||||
|
||||
?token=${token2}&v1=${temp}&v2=${gravity}&v3=${angle}
|
||||
|
||||
|
||||
Brewpiless
|
||||
++++++++++
|
||||
|
||||
If you connect the device to the brewpiless access point there is not way to access the user interface for configuration so it's recommended to connect the device to your normal network.
|
||||
|
||||
The device need to have a name starting with iSpindle, for example `iSpindel000`. Set the URL for one of the http POST targets to `http://ip/gravity` where ip is the ip adress of Brewpiless.
|
||||
|
||||
|
||||
BrewBlox
|
||||
++++++++++
|
||||
|
||||
To send iSpindel data to brewblox over mqtt you need to modify the format template to match the expected format. Once you have configured the mqtt information you also need to update the format template
|
||||
for this target.
|
||||
|
||||
This format template will post the expected json document on the topic, dont forget the `|` character at the end of the line which is needed to parse the payload. The first to words are the topic
|
||||
name and after the first `:` this is the json playload. Text within the brackets will be used as the unit for the value and degC is displayed as °C. You can add other parameters under the data section
|
||||
in the json document if you need other values as well.
|
||||
|
||||
.. code-block::
|
||||
|
||||
brewcast/history:{"key":"${mdns}","data":{"Temperature[degC]": ${temp-c},"Temperature[degF]": ${temp-f},"Battery[V]":${battery},"Tilt[deg]":${angle},"Rssi[dBm]":${rssi},"SG":${gravity-sg},"Plato":${gravity-plato}}}|
|
||||
|
||||
|
||||
The json message on the mqtt topic would look like this:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"key": "gravitymon",
|
||||
"data": {
|
||||
"Temperature[degC]": 27,
|
||||
"Temperature[degF]": 80,
|
||||
"Battery[V]": 4.1,
|
||||
"Tilt[deg]": 25,
|
||||
"Rssi[dBm]": -78,
|
||||
"SG": 1,
|
||||
"Plato": 0
|
||||
}
|
||||
}
|
||||
|
@ -53,9 +53,15 @@ Log errors
|
||||
* -9 - Error encoding
|
||||
* -10 - Error writing to stream
|
||||
* -11 - Read timeout
|
||||
* -100 - Endpoint skipped since its SSL and the device is in gravity mode
|
||||
|
||||
* MQTT push on <topic> failed error
|
||||
|
||||
* -1 - Buffer to short
|
||||
* -2 - Overflow
|
||||
* -3 - Network failed connected
|
||||
* -4 - Network timeout
|
||||
* -5 - Network read failed
|
||||
* -6 - Network write failed
|
||||
* -10 - Connection denied
|
||||
|
||||
* -11 - Failed subscription
|
||||
|
@ -1,15 +1,16 @@
|
||||
{
|
||||
"gyro-read-count": 51,
|
||||
"gyro-moving-threashold": 501,
|
||||
"formula-max-deviation": 1.7,
|
||||
"wifi-portal-timeout": 121,
|
||||
"wifi-connect-timeout": 21,
|
||||
"formula-calibration-temp": 21,
|
||||
"tempsensor-resolution": 12,
|
||||
"gyro-read-count": 50,
|
||||
"gyro-moving-threashold": 500,
|
||||
"formula-max-deviation": 1.6,
|
||||
"wifi-portal-timeout": 120,
|
||||
"wifi-connect-timeout": 20,
|
||||
"push-timeout": 10,
|
||||
"int-http1": 1,
|
||||
"int-http2": 2,
|
||||
"int-http3": 3,
|
||||
"int-influx": 4,
|
||||
"int-mqtt": 5
|
||||
"formula-calibration-temp": 20,
|
||||
"int-http1": 0,
|
||||
"int-http2": 0,
|
||||
"int-http3": 0,
|
||||
"int-influx": 0,
|
||||
"int-mqtt": 0,
|
||||
"tempsensor-resolution": 9,
|
||||
"ignore-low-angles": false
|
||||
}
|
@ -20,8 +20,10 @@
|
||||
"mqtt-port": 1883,
|
||||
"mqtt-user": "user",
|
||||
"mqtt-pass": "pass",
|
||||
"storage-sleep": true,
|
||||
"sleep-interval": 30,
|
||||
"voltage-factor": 1.59,
|
||||
"voltage-config": 4.15,
|
||||
"gravity-formula": "0.0*tilt^3+0.0*tilt^2+0.0017978*tilt+0.9436",
|
||||
"gravity-format": "G",
|
||||
"temp-adjustment-value": 0,
|
||||
@ -35,10 +37,34 @@
|
||||
"gy": -6,
|
||||
"gz": 4
|
||||
},
|
||||
"formula-calculation-data": {
|
||||
"a1": 25,
|
||||
"a3": 35,
|
||||
"a2": 45,
|
||||
"a4": 55,
|
||||
"a5": 30,
|
||||
"a6": 30,
|
||||
"a7": 30,
|
||||
"a8": 30,
|
||||
"a9": 30,
|
||||
"a10": 30,
|
||||
"g1": 1.000,
|
||||
"g3": 1.010,
|
||||
"g2": 1.025,
|
||||
"g4": 1.040,
|
||||
"g5": 1.005,
|
||||
"g6": 1.005,
|
||||
"g7": 1.005,
|
||||
"g8": 1.005,
|
||||
"g9": 1.005,
|
||||
"g10": 1.005
|
||||
},
|
||||
"angle": 90.93,
|
||||
"gravity": 1.105,
|
||||
"battery": 0.04,
|
||||
"runtime-average": 3.0,
|
||||
"ble": "pink",
|
||||
"app-ver": "0.1.0",
|
||||
"app-build": "build",
|
||||
"platform": "esp32"
|
||||
}
|
@ -21,5 +21,6 @@
|
||||
"g8": 1.005,
|
||||
"g9": 1.005,
|
||||
"g10": 1.005,
|
||||
"error": ""
|
||||
"error": "",
|
||||
"gravity-format": "P"
|
||||
}
|
@ -1,8 +1,22 @@
|
||||
{
|
||||
"index": false,
|
||||
"index": true,
|
||||
"config": false,
|
||||
"calibration": false,
|
||||
"format": false,
|
||||
"calibration": true,
|
||||
"format": true,
|
||||
"about": false,
|
||||
"test": false,
|
||||
"about": true
|
||||
"files": [
|
||||
{
|
||||
"file-name": "calibration.min.htm",
|
||||
"file-size": 0
|
||||
},
|
||||
{
|
||||
"file-name": "drd.dat",
|
||||
"file-size": 4
|
||||
},
|
||||
{
|
||||
"file-name": "error.log",
|
||||
"file-size": 839
|
||||
}
|
||||
]
|
||||
}
|