From cda3a87dd95d18bc4ce3673b2499cc4f5f8a692a Mon Sep 17 00:00:00 2001 From: Magnus Persson Date: Fri, 4 Feb 2022 16:22:27 +0100 Subject: [PATCH] Docs updated --- src_docs/source/functionallity.rst | 103 +++++++++++++++++------- src_docs/source/images/fermentation.png | Bin 0 -> 40553 bytes src_docs/source/index.rst | 59 ++++++++------ src_docs/source/intro.rst | 12 ++- src_docs/source/releases.rst | 6 ++ src_docs/source/services.rst | 2 +- 6 files changed, 121 insertions(+), 61 deletions(-) create mode 100644 src_docs/source/images/fermentation.png diff --git a/src_docs/source/functionallity.rst b/src_docs/source/functionallity.rst index 298f761..63aa34c 100644 --- a/src_docs/source/functionallity.rst +++ b/src_docs/source/functionallity.rst @@ -12,8 +12,12 @@ The main features angle/tile, temperature, calculates gravity and pushes the data to defined endpoints. In ``configuration mode`` the device is always active and the webserver is active. Here you can view the - angle/tilt values, change configuration options and more. When in this mode you can also interact with the device - via an REST API so data can be pushed to the device via scripts (see API section for more information). + angle/tilt values, change configuration, update the gravity formula. When in this mode you can also interact + with the device via an REST API so data can be pushed to the device via scripts (see API section for more information). + + .. image:: images/index.png + :width: 700 + :alt: UI example You can force the device into ``configuration mode`` while measuring gravity. This is useful when calibrating the device so you don't needs to wait for the device to wake up and push the data. The entire calibration @@ -21,61 +25,83 @@ The main features See the :ref:`setting-up-device` section for more information on how to trigger the configuration mode. -* **Can send data to multiple endpoints at once** +* **Can send data to multiple endpoints** The original iSpindle can only have one destination, this software will push data to all defined endpoints so - in theory you can use them all. However this will consume more battery power so use only as many as needed. + in theory you can use them all. However this will consume more battery power so use only as many as needed. Its much + more efficient to have the endpoints on your local network than on the internet. - Currently the device supports the following endpoints: http (2 different), influxdb2, Brewfather and MQTT. + Currently the device supports the following endpoints. - If you want additional targets please raise a feature request in the github repo. + * http or https + * influxdb v2 + * Brewfather + * MQTT + * Home Assistant + * Brew Spy + * Brewers Friend + * Fermentrack + * Ubidots + * Thingsspeak + + + Under the :ref:`services` section you can find guides for how to connect GravityMon to these services. For a + description of what data is transmitted you can see :ref:`data-formats`. + + The software support SSL endpoints but currently without CA validation, this means that the data is encrypted + but it does not validate if the remote endpoint is who it claims to be. + + if you require CA validation please leave a comment on GitHub and I will make that a priority. Adding this function + will dramatically reduce the battery life of the device. + +.. note:: + + Using SSL on a small device such as the esp8266 can be unstable since it requires a lot of RAM to work. And running out + of RAM will cause the device to crash. So enable SSL with caution and only when you really need it. GravityMon will try + to minimize the needed RAM but the remote service might not support that feature. * **Create gravity formulas on the device** 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. -.. note:: + Currently the device can handle 5 data points which should be enough to get a accurate formula. At least 3 data points + is needed to get an accurate formula. - This feature needs more testing to be validated. + 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 customize the data that is to be sent. This way you can easily adapt the software to new targets without coding. - If you have a good template please share it on the girhub repository and I will add it to the documentation - for other users to enjoy. See the :ref:`format-editor` for more information. - -.. note:: - - This feature needs more testing to be validated. + If you have a good template please share it on the github repository and I will add it to the documentation + for other users to enjoy. See the :ref:`format-editor` for more information. See :ref:`services` for a list of + services currently validated. * **Automatic temperature adjustment of gravity reading** If you want to correct gravity based on beer temperature you can do this in the formula but here is a nice feature that can correct the gravity as a second step making this independant of the formula. -.. note:: +* **OTA support from webserver** - This feature needs more testing to be validated. - -* **OTA support from local webserver** - - When starting up in configuration mode the device will check for a software update from a local 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. * **DS18B20 temperature adjustments** - You can adjust the temperature reading of the temperature sensor. + You can adjust the temperature reading of the temperature sensor. In normal cases this should not be needed since + the sensors should be calibrated. * **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. + 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. + the device will go into deep sleep for 60 seoncds and then retry later. This to conserve batter as much as possible. * **Use gyro temperature sensor** @@ -93,21 +119,36 @@ The main features :width: 800 :alt: Gyro temp vs DS18B20 -Other features --------------- +* **Celsius or Farenheigt** -* Support for Celcius and Farenheigt as temperature formats. + You can switch between different temperature formats. GravityMon will always use C for it's internal calculations and + convert to F when displayed. -* Support SG (Plato is not yet supported) +* **SG or Plato** -* Gyro data is read 50 times to ensure good accuracy + You can switch between different gravity formats. GravityMon will always use SG for it's internal calculations and + convert to Plato when displayed. -Experimental features ---------------------- +* **Stable gyro data** + + The device will read the gyro 50 times to get an accurate reading. If the standad deviation is to high it will not + use the data since this is inacurate and the device is probably moving, probably do to active fermentation or movement of + fermentation vessel. This sequence takes 900 ms seconds to execute and besides wifi connection this is what consumes the most + battery. With more testing this might be changes to either speed up or provide more stable readings. * **Performance measurements** - I've also create a small library to measure execution code in some areas of the code that i know is time consuming. This way I can find a good balance between performace and quality. + I've also create a small library to measure execution code in some areas of the code that i know is time consuming. This + way I can find a good balance between performace and quality. This is a lot of help trying to figure out where bottlenecks + are in the code and where to put optimization efforts. Examples of real measurements: + + * Reading the gyro: 885 ms + * Reading DS18B20 temperature sensor: 546 ms + * Connect to WIFI: 408 ms + * Send data to local influxdb v2: 25 ms + * Send data to local mqtt server: 35 ms + * Send data to local http server: 40 ms + * Send data to http server on internet: 0.2 - 5 seconds See the :ref:`compiling-the-software` for more information. diff --git a/src_docs/source/images/fermentation.png b/src_docs/source/images/fermentation.png new file mode 100644 index 0000000000000000000000000000000000000000..598abd68059e76a17a1100717a747cf4ad4ae9c0 GIT binary patch literal 40553 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 . +GravityMon is a replacement firmare for the iSpindle and uses the same hardware configuration and is 100% compatible. It +implements a lot of the features that has been requested in the orginal iSpindle project but has been rejected for +various reasons. Here is a list of :ref:`main_features`. I started GravityMon because i like to create software and wanted to do some low level programming. I had done a few projects based on esp8266 and also started to brew beer so this combination was quite natural. -The hardware design comes from the fantastic iSpindle project so that is not covered in this documentation. +The hardware design comes from the fantastic iSpindle project so that is not covered in this documentation. For more +information on this topic and function please visit `iSpindel Homepage `_ . -My approach to this software is a little different from that the original ispindle firmware. The github repository can -be found here; `GravityMon on Github `_ +My approach to this software is a little different from that the original ispindle firmware. The github repository +can be found here; `GravityMon on Github `_ -.. note:: - This software is in the early stages even though its more than one year old so if you find issues, please - open a ticket on github. - - I dont take responsibility for any errors that can cause problems with the use. I have tested v0.4 on 5+ brews - over the last 6 months without any issues. +.. note:: + I dont take responsibility for any errors or issues caused by the software. The software is provided as-is. I will however + try my best to fix issues that might occur. -The main differences: ---------------------- + I have tested this software over the last year on 20+ brews with good results. -* Operates in two modes gravity monitoring and configuration mode (simplify calibration) -* Modern web based UI for configuration (in config mode) -* REST API -* Send data to multiple endpoints when pushing data (2xhttp, brewfather, influxdb v2, mqtt supported) +.. _main_features: + +Main features: +-------------- + +* Operates in two modes gravity monitoring and configuration mode (simplify calibration). Gravity mode + is comparable to how the iSpindle works. +* Modern web based UI when in configuration mode. No need to start the access point changing settings. +* REST API to enable scripted configuration +* Send data to multiple endpoints and services at once +* Setup guides for how to send data to many popular services. Currently 8+ are documented. * Automatic temperature adjustment of gravity reading -* OTA support from local webserver -* Built in function to create gravity formulas, no need for additional software, just enter tilt/gravity. -* Visual graph showing how formula will be interpreted +* OTA support from webserver +* Built in function to create gravity formulas, no need for additional software, just enter tilt/gravity and + let GravityMon create the formula. +* Visual graph showing how formula will be interpreted based on entered values * Using the temperature sensor in gyro instead of DS18B20 (faster) -* Built in performance measurements (used to optimise code) * SSL support in standard HTTP and MQTT connections. * Option to customize data posted to endpoints using template from the UI. +* Built in performance measurements (used to optimise code) For a complete breakdown see the :ref:`functionallity` diff --git a/src_docs/source/intro.rst b/src_docs/source/intro.rst index a9d471b..972f094 100644 --- a/src_docs/source/intro.rst +++ b/src_docs/source/intro.rst @@ -40,8 +40,8 @@ Configuration - Device Settings - Device Name Give your device a good name. -Configuration - Device Settings - Calibration -+++++++++++++++++++++++++++++++++++++++++++++ +Configuration - Device Settings - Gyro Calibration +++++++++++++++++++++++++++++++++++++++++++++++++++ You need to place the device on a flat surface and then press the calibrate button. It will take a few seconds for this to complete and the angle should be close to 90 degress. Without @@ -49,8 +49,7 @@ calibration the device will not go into gravity mode. Configuration - Push Settings +++++++++++++++++++++++++++++ -Add the endpoints where you want data to be transmitted. All URLs that contain a -valid endpoint will receive the data. +Add the endpoints where you want data to be transmitted. All URLs that contain a valid endpoint will receive the data. Calibration +++++++++++ @@ -58,6 +57,11 @@ Calibration I recommend to use the calibration feature to create a gravity formula. If you have values from a previous calibration then you can add them here, if not follow the calibration guidelines on the iSpindle site. +There are several guides for how to calibrate the device (`iSpindle Calibration `_) + +This will get the data points needed to create the formula, and the datapoints will be stored on the device so you can +adjust them when needed. + Step 4 - Completed ------------------ diff --git a/src_docs/source/releases.rst b/src_docs/source/releases.rst index 58b741e..244ca1c 100644 --- a/src_docs/source/releases.rst +++ b/src_docs/source/releases.rst @@ -16,6 +16,12 @@ v0.8.0 * Logging the runtime, how long a measurement take (last 10 are stored). This can be used to check how good the wifi connection is and estimate the lifetime when on battery. Check the device page in the UI for this information. +* Refactored code to free up more RAM to make SSL more stable. +* Before connecting to an SSL endpoint the device will try to use a new SSL feature + called MFLN (Maximum Fragment Length Negotiation) that allow us to reduce the buffers + from 16k to 2k. This can make a huge difference on a device with only 40k RAM. Not all + servers might support this feature. +* Updated documentation pages. v0.7.1 ------ diff --git a/src_docs/source/services.rst b/src_docs/source/services.rst index c8f11ff..fe840e9 100644 --- a/src_docs/source/services.rst +++ b/src_docs/source/services.rst @@ -126,7 +126,7 @@ Brewer's friend is an all in one service that allows you to manage you recepies .. warning:: I dont have an account for brewers friend so I have not been able to verfy this completely. Its based on - the available documentation. + the available documentation. If this works please let You can find you API key when logged in to the service. Follow these `instructions `_