Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Gravity Velocity" as a measure #201

Open
achtnullzwei opened this issue Oct 31, 2024 · 5 comments
Open

Add "Gravity Velocity" as a measure #201

achtnullzwei opened this issue Oct 31, 2024 · 5 comments

Comments

@achtnullzwei
Copy link

achtnullzwei commented Oct 31, 2024

Is your feature request related to a problem? Please describe.
Gravity measurements at individual timepoints may provide a basis for doing automations, they still fluctuate and wouldnt be too reliable to understand the current state the fermentation is in. I understand that calculating the fermentation state by understanding how many gravity points per day the ferment is dropping is a common practice but its a manual effort if you dont have an app or script that does the job for you after you get the gravity measurement from a hydrometer. Kegland recently posted a nice video on this and i rly like the idea to have the hydrometer do the work for you.

Describe the solution you'd like
I therefore propose adding such a measure to Gravitymon as well. This would greatly benefit automating fermentations even further.

Proposal how to measure this (also based on what Kegland discloses in their video, and some considerations I made):

  • Measure in points/day
  • Take hourly reading of current gravity
  • Fit a linear curve with least squares to reduce outliers
  • Sliding window for measurement points: 6h, 12h, 24h as options. Calculation can start after 2 measurments, in this case 1h, but gets more precise reaching end full window
  • Calculate gravity velocity hourly based on the current curve for timeframe of 24h to get points/day

To avoid weird values in the beginning of fermentation:

  • Measure starts at 0
  • If measure is negative, set to 0

Describe alternatives you've considered
Using nodered to deal with it. Its not a great user experience and requires tinkering and e.g. using nodered as a proxy to send the current reading including this measure to any integration/service.

Additional context
Reference video from Kegland: https://youtu.be/oVNjjFeZWxk?si=D7PUPJszUSMETb7k

Thx a lot for considering the suggestion. :-)

@mp-se
Copy link
Owner

mp-se commented Oct 31, 2024

HI, thanks for the feature request and it would be an interesting feature to have. I see a few challenges on implementing this on the device itself,

  1. The device does not do any timesync so I dont know when the data was captured. Adding time sync is possible but would reduce the battery power quite a lot so this is a feature that I have dropped in the past.
  2. Will require writing data to the device that will reduce the lifespan of the flash (has limited writes)
  3. Finding some good libraries for doing the math and calculations, need to investigate how much time these calculation would require.
  4. Having something that can read and show the value submitted. Most services limit use to the standard iSpindle format...

My first thought was that this feature would be much easier to implement in a server side (receiver) software and there show the trends and data (you will still need something that can display it). I guess kegland has their own app or service that does this.

However I will investigate this further and try it out server side first. I have another project I use for collecting data from my iot projects which I can test out the principle first to see if its feasible to do on the device.

@achtnullzwei
Copy link
Author

achtnullzwei commented Nov 1, 2024

Thx a lot for the consideration! I agree that there are some challenges. Some consderations from my side on your comments.

The device does not do any timesync so I dont know when the data was captured. Adding time sync is possible but would reduce the battery power quite a lot so this is a feature that I have dropped in the past.

I think we dont need timesync in this case. We need to have measurement points every 3600 seconds. The timer can be used similar than already in use for sending every X seconds to the integrations. From there we can count measurement points to understand how many hours passed for e.g. sliding window. Points per day can also be calculated "sliding" meaning we dont need specific points in time, just relative.

Will require writing data to the device that will reduce the lifespan of the flash (has limited writes)

Agreed. Could we keep this just in RAM? I am not completely sure about deep sleep but i think it preserves RAM right? I mean, if the hydrometer shuts off completely then measurement process starts from fresh. After a period of time it gets the same accuracy as before it turned off. I dont think that this is a big issue. between fermentations its fine to turn if off and start fresh. If this happens while fermenting its an issue anyway if the device resets due to any issue or turns-off/on again.

Finding some good libraries for doing the math and calculations, need to investigate how much time these calculation would require.

I can look more into the math in general. I was more conceptualizing this at the moment and trying to envision how to replicate it, and put my thoughts in. I can work it out a little more, but I am not any good in writing C. I could do it in python though ^^

Having something that can read and show the value submitted. Most services limit use to the standard iSpindle format...

Indeed. I think this one rly depends on the respective integrations. For generic HTTP/S and MQTT it works i think with no issues. Maybe a check box to incude/exlude it would be an idea. For other "fixed" integrations i think it depends if a completely fixed JSON object is expected, respectively if integration breaks on receiving end if additional key/value pairs are sent. Brewfather custom stream should e.g. not be an issue at all. This one might require more assessment in general and testing though. I could only test a few like http, mqtt and brewfather.

My first thought was that this feature would be much easier to implement in a server side (receiver) software and there show the trends and data (you will still need something that can display it). I guess kegland has their own app or service that does this.

Was exactly my first thought as well and just do it in nodered. However, sometimes integrations on receiving end also change due to changes on sending end. So also possible, after sth like that is implemented to raise enhancement requests there as well. Regarding Kegland, i would suspect they do this on the device as well but of course there is a chance its server calculated. Some settings for this measurement are on device settings though as far as i can see. I dont have one to test, but they offer bluetooth and wifi. If i had one, i could check the bluetooth data to see if its added there or not.

Thx again for considering :)

@mp-se
Copy link
Owner

mp-se commented Nov 1, 2024

I think we dont need timesync in this case. We need to have measurement points every 3600 seconds. The timer can be used similar than already in use for sending every X seconds to the integrations. From there we can count measurement points to understand how many hours passed for e.g. sliding window. Points per day can also be calculated "sliding" meaning we dont need specific points in time, just relative.

Well there is no guarantee that measurements will be in a fixed interval, connection issues etc can throw that off. I dont know how much that would affect the calculations, but it needs to be considered. The only way to know the interval is to have timestamp which means an NTP sync is required.

Agreed. Could we keep this just in RAM? I am not completely sure about deep sleep but i think it preserves RAM right? I mean, if the hydrometer shuts off completely then measurement process starts from fresh. After a period of time it gets the same accuracy as before it turned off. I dont think that this is a big issue. between fermentations its fine to turn if off and start fresh. If this happens while fermenting its an issue anyway if the device resets due to any issue or turns-off/on again.

There would not be enough memory on an esp8266, its already at the limitations as of now. Ram is no preserved while doing a deep sleep. its basically a full restart of the device. so writing to Flash is the only option.

I can look more into the math in general. I was more conceptualizing this at the moment and trying to envision how to replicate it, and put my thoughts in. I can work it out a little more, but I am not any good in writing C. I could do it in python though ^^

If you want to help with the calc that if fine, python is perfect. My data collector is written in python. So that would be a good place to test it. Javascript could also be an option depending on if this is UI presentation feature or needs to be persisted in the backend.

Indeed. I think this one rly depends on the respective integrations. For generic HTTP/S and MQTT it works i think with no issues. Maybe a check box to incude/exlude it would be an idea. For other "fixed" integrations i think it depends if a completely fixed JSON object is expected, respectively if integration breaks on receiving end if additional key/value pairs are sent. Brewfather custom stream should e.g. not be an issue at all. This one might require more assessment in general and testing though. I could only test a few like http, mqtt and brewfather.

Home Assistant and others can display the data but i dont see that brewfather or similiar can handle.

Was exactly my first thought as well and just do it in nodered. However, sometimes integrations on receiving end also change due to changes on sending end. So also possible, after sth like that is implemented to raise enhancement requests there as well. Regarding Kegland, i would suspect they do this on the device as well but of course there is a chance its server calculated. Some settings for this measurement are on device settings though as far as i can see. I dont have one to test, but they offer bluetooth and wifi. If i had one, i could check the bluetooth data to see if its added there or not.

I think kegland has its own cloud service so its likely that they do the calculation there. But I see one option and that is to put this logic in the gravitymon-gateway that is always running or in the brewlogger software that I'm working on. Links below

@achtnullzwei
Copy link
Author

achtnullzwei commented Nov 5, 2024

Took me a while to respond, didnt have too much time.

I think kegland has its own cloud service so its likely that they do the calculation there.

I looked a bit into that. I still think its calculated on then device somehow. See below. From firmware 2.0 onwards, gravity velocity is part of the BLE packet that is sent out. Also in BLE only mode.

https://gitlab.com/rapt.io/public/-/wikis/Pill%20Hydrometer%20Bluetooth%20Transmissions

There would not be enough memory on an esp8266, its already at the limitations as of now. Ram is no preserved while doing a deep sleep. its basically a full restart of the device. so writing to Flash is the only option.

Very valid. Maybe this is down to the way how the manage energy consumption. Could be they dont use the traditional "deep sleep" method. Could be that they actually limit energy consumption in a different albeit not so effective way. IIRC battery run time on wifi is less on the pill than on sth like iSpindle and Gravitmon. Additionally, probably uses esp32 or sth comparable. But i could be incorrect.

In any case, when I have some more time, i will look into a proposal for calculation and post it. I dont have any "urgency", was more of a nice to have anyway :-)

@mp-se
Copy link
Owner

mp-se commented Nov 12, 2024

I did some quick analysis on some of my previous brews and I dont think they do something advanced such as linear regression. I believe they just calculate how many points the gravity is changing per day (or time period).

For example the gravity drops from 1.0341 to 1.0318 a change of -3.30, this is probably the value that is reported. The value if one do a linear regression on the same data would be -4.258468889416096e-11

If this is the case then the amount of data that is stored would be of great significance so that the calculation is not totally off. Even faulty data values would have big impact on that calculation. So how to avoid having faulty measurements impacting the calculation would be a challenge.

The pros is that it does not really require any advanced linear regression library (even i if I have found one that works).

Here is an example from my last brew.

dump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants