mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-01-29 20:10:56 -08:00
feat(brewfather): unit conversion routines
functions available to template documentation tests
This commit is contained in:
parent
4fc1811efa
commit
0b4f3e1771
|
@ -19,7 +19,7 @@ This example uses the default segment template to show a rendition of detail app
|
|||
Additionally, the background of the segment will turn red if the latest reading is over 4 hours old - possibly helping indicate
|
||||
an issue if, for example there is a Tilt or similar device that is supposed to be logging to Brewfather every 15 minutes.
|
||||
|
||||
NOTE: Temperature units are in degrees C and specific gravity is expressed as `1.XYZ` values.
|
||||
NOTE: Temperature units are in degrees C and specific gravity is expressed as `X.XXX` values.
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -132,6 +132,41 @@ to build your own. For reference, the built-in template looks like this:
|
|||
}
|
||||
````
|
||||
|
||||
### Unit conversion
|
||||
|
||||
By default temperature readings are provided in degrees C, gravity readings in decimal Specific Gravity unts (X.XXX).
|
||||
|
||||
The following conversion functions are available to the template to convert to other units:
|
||||
|
||||
#### Temperature
|
||||
|
||||
- DegCToF - input: `float` degrees in C; output `float` degrees in F (1 decimal place).
|
||||
- DegCToKelvin- input: `float` degrees in C; output `float` Kelvin (1 decimal place).
|
||||
|
||||
#### Gravity
|
||||
|
||||
- SGToBrix - input `float` SG in x.xxx decimal; output `float` Brix (2 decimal places)
|
||||
- SGToPlato - input `float` SG in x.xxx decimal; output `float` Plato (2 decimal places)
|
||||
|
||||
*(These use the polynomial conversions from [Wikipedia][wikipedia_gravity_page])*
|
||||
|
||||
#### Example
|
||||
|
||||
```` json
|
||||
{
|
||||
"template":"{{if .Reading}}{{.SGToBrix .Reading.Gravity}}°Bx, {{.DegCToF .Reading.Temperature}}°F{{end}}"
|
||||
}
|
||||
````
|
||||
|
||||
To display gravity as SG in XXXX format (e.g. "1020" instead of "1.020"), use the `mulf` template function
|
||||
|
||||
```` json
|
||||
{
|
||||
"template":"{{if .Reading}}{{.mulf 1000 .Reading.Gravity}}, {{.DegCToF .Reading.Temperature}}°F{{end}}"
|
||||
}
|
||||
````
|
||||
|
||||
[go-text-template]: https://golang.org/pkg/text/template/
|
||||
[sprig]: https://masterminds.github.io/sprig/
|
||||
[brewfather]: http://brewfather.app
|
||||
[wikipedia_gravity_page]:https://en.wikipedia.org/wiki/Brix#Specific_gravity_2
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
@ -315,6 +316,25 @@ func (bf *brewfather) getResult() (*Batch, error) {
|
|||
return &batch, nil
|
||||
}
|
||||
|
||||
// Unit conversion functions available to template.
|
||||
func (bf *brewfather) DegCToF(degreesC float64) float64 {
|
||||
return math.Round(10*((degreesC*1.8)+32)) / 10 // 1 decimal place
|
||||
}
|
||||
|
||||
func (bf *brewfather) DegCToKelvin(degreesC float64) float64 {
|
||||
return math.Round(10*(degreesC+273.15)) / 10 // 1 decimal place, only addition, but just to be sure
|
||||
}
|
||||
|
||||
func (bf *brewfather) SGToBrix(sg float64) float64 {
|
||||
// from https://en.wikipedia.org/wiki/Brix#Specific_gravity_2
|
||||
return math.Round(100*((182.4601*sg*sg*sg)-(775.6821*sg*sg)+(1262.7794*sg)-669.5622)) / 100
|
||||
}
|
||||
|
||||
func (bf *brewfather) SGToPlato(sg float64) float64 {
|
||||
// from https://en.wikipedia.org/wiki/Brix#Specific_gravity_2
|
||||
return math.Round(100*((135.997*sg*sg*sg)-(630.272*sg*sg)+(1111.14*sg)-616.868)) / 100 // 2 decimal places
|
||||
}
|
||||
|
||||
func (bf *brewfather) init(props properties, env environmentInfo) {
|
||||
bf.props = props
|
||||
bf.env = env
|
||||
|
|
|
@ -49,7 +49,7 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Planning","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[]`,
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " Fake Beer 1.3%",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
|
@ -58,7 +58,7 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Brewing","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[]`,
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " Fake Beer 1.3%",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
|
@ -67,7 +67,7 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[]`,
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 19d Fake Beer 1.3%",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
|
@ -76,17 +76,17 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}]`,
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 19d Fake Beer 1.3%: 1.066 19.5 →",
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 19d Fake Beer 1.3%: 1.066 19.5° →",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
{
|
||||
Case: "Fermenting Status, two readings, temp trending up",
|
||||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}, {"id":"manual","temp":21,"comment":"","sg":1.063,"time":` + FakeReading2DateString + `,"type":"manual"}]`, // nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 19d Fake Beer 1.3%: 1.063 21 ↗",
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}, {"id":"manual","temp":21,"comment":"","sg":1.063,"time":` + FakeReading2DateString + `,"type":"manual"}]`, // nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 19d Fake Beer 1.3%: 1.063 21° ↗",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
{
|
||||
|
@ -94,15 +94,15 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}, {"id":"manual","temp":21,"comment":"","sg":1.063,"time":` + FakeReading2DateString + `,"type":"manual"}, {"id":"manual","temp":15,"comment":"","sg":1.050,"time":` + FakeReading3DateString + `,"type":"manual"}]`, // nolint:lll
|
||||
Template: "{{.StatusIcon}} {{.ReadingAge}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 451 19d Fake Beer 1.3%: 1.05 15 ↓↓",
|
||||
Template: "{{.StatusIcon}} {{.ReadingAge}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 451 19d Fake Beer 1.3%: 1.05 15° ↓↓",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
{
|
||||
Case: "Bad batch json, readings fine",
|
||||
BatchJSONResponse: ``,
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}, {"id":"manual","temp":21,"comment":"","sg":1.063,"time":` + FakeReading2DateString + `,"type":"manual"}, {"id":"manual","temp":15,"comment":"","sg":1.050,"time":` + FakeReading3DateString + `,"type":"manual"}]`, // nolint:lll
|
||||
Template: "{{.StatusIcon}} {{.ReadingAge}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
Template: "{{.StatusIcon}} {{.ReadingAge}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: "",
|
||||
ExpectedEnabled: false,
|
||||
},
|
||||
|
@ -111,10 +111,28 @@ func TestBrewfatherSegment(t *testing.T) {
|
|||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Conditioning","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":19.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}, {"id":"manual","temp":21,"comment":"","sg":1.063,"time":` + FakeReading2DateString + `,"type":"manual"}, {"id":"manual","temp":15,"comment":"","sg":1.050,"time":` + FakeReading3DateString + `,"type":"manual"}]`, // nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}\ue33e {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
Template: "{{.StatusIcon}} {{if .DaysBottledOrFermented}}{{.DaysBottledOrFermented}}d {{end}}{{.Recipe.Name}} {{.MeasuredAbv}}%{{ if and (.Reading) (eq .Status \"Fermenting\")}}: {{.Reading.Gravity}} {{.Reading.Temperature}}° {{.TemperatureTrendIcon}}{{end}}", //nolint:lll
|
||||
ExpectedString: " 5d Fake Beer 1.3%",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
{
|
||||
Case: "Fermenting Status, test all unit conversions",
|
||||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":34.5,"comment":"","sg":1.066,"time":` + FakeReading1DateString + `,"type":"manual"}]`,
|
||||
Template: "{{ if and (.Reading) (eq .Status \"Fermenting\") }}SG: ({{.Reading.Gravity}} Bx:{{.SGToBrix .Reading.Gravity}} P:{{.SGToPlato .Reading.Gravity}}), Temp: (C:{{.Reading.Temperature}} F:{{.DegCToF .Reading.Temperature}} K:{{.DegCToKelvin .Reading.Temperature}}){{end}}", //nolint:lll
|
||||
ExpectedString: "SG: (1.066 Bx:16.13 P:16.13), Temp: (C:34.5 F:94.1 K:307.7)",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
{
|
||||
Case: "Fermenting Status, test all unit conversions 2",
|
||||
BatchJSONResponse: `
|
||||
{"batchNo":18,"status":"Fermenting","brewDate":` + FakeBrewDateString + `,"bottlingDate":` + FakeBottlingDateString + `,"recipe":{"name":"Fake Beer"},"fermentationStartDate":` + FakeFermStartDateString + `,"name":"Batch","measuredAbv": 1.3}`, // nolint:lll
|
||||
BatchReadingsJSONResponse: `[{"id":"manual","temp":3.5,"comment":"","sg":1.004,"time":` + FakeReading1DateString + `,"type":"manual"}]`,
|
||||
Template: "{{ if and (.Reading) (eq .Status \"Fermenting\") }}SG: ({{.Reading.Gravity}} Bx:{{.SGToBrix .Reading.Gravity}} P:{{.SGToPlato .Reading.Gravity}}), Temp: (C:{{.Reading.Temperature}} F:{{.DegCToF .Reading.Temperature}} K:{{.DegCToKelvin .Reading.Temperature}}){{end}}", //nolint:lll
|
||||
ExpectedString: "SG: (1.004 Bx:1.03 P:1.03), Temp: (C:3.5 F:38.3 K:276.7)",
|
||||
ExpectedEnabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
|
|
Loading…
Reference in a new issue