Skip to content

Commit

Permalink
Minor changes (#3)
Browse files Browse the repository at this point in the history
* Temperature unit can be configured in config
* Tests for load config logic
* GitHub Actions
  • Loading branch information
ljagiello committed Oct 1, 2023
1 parent 73258f1 commit a4018b3
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 26 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Go

on: [pull_request]

jobs:

build:
runs-on: macos-13
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'

- name: Build
run: go build ./...

- name: Test
run: go test -v -race ./...
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Show AirGradient measurements in MacOS menu bar
![Screenshot 2023-09-30 at 13 49 17](https://github.com/ljagiello/airdash/assets/380707/0d569e90-2a96-49af-8c6f-6020a53a7766)

## Config
Configuration location - `~user/.airdash/config.yaml`
```yaml
➜ ~ cat .airdash/config.yaml
token: <secret-token>
interval: 60
```
Expand Down
24 changes: 24 additions & 0 deletions airgradient.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,34 @@ package main
import (
"io"
"net/http"
"time"
)

const AIR_GRADIENT_API_URL = "https://api.airgradient.com/public/api/v1/locations/measures/current"

type AirGradientMeasures []struct {
LocationID int `json:"locationId"`
LocationName string `json:"locationName"`
Pm01 any `json:"pm01"`
Pm02 int `json:"pm02"`
Pm10 any `json:"pm10"`
Pm003Count any `json:"pm003Count"`
Atmp float64 `json:"atmp"`
Rhum int `json:"rhum"`
Rco2 int `json:"rco2"`
Tvoc float64 `json:"tvoc"`
Wifi int `json:"wifi"`
Timestamp time.Time `json:"timestamp"`
LedMode string `json:"ledMode"`
LedCo2Threshold1 int `json:"ledCo2Threshold1"`
LedCo2Threshold2 int `json:"ledCo2Threshold2"`
LedCo2ThresholdEnd int `json:"ledCo2ThresholdEnd"`
Serialno string `json:"serialno"`
FirmwareVersion any `json:"firmwareVersion"`
TvocIndex int `json:"tvocIndex"`
NoxIndex int `json:"noxIndex"`
}

func fetchMeasures(token string) ([]byte, error) {
client := &http.Client{}

Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
type Config struct {
Token string `yaml:"token"`
Interval int `yaml:"interval"`
TempUnit string `yaml:"tempUnit"`
}

func LoadConfig(path string) (*Config, error) {
Expand Down
77 changes: 77 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main

import (
"fmt"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

func CreateTestConfig(configContent []byte) (*os.File, error) {
tmpfile, err := os.CreateTemp("", "*-pass")
if err != nil {
return nil, err
}

if _, err := tmpfile.Write(configContent); err != nil {
return nil, err
}
if err := tmpfile.Close(); err != nil {
return nil, err
}
return tmpfile, nil
}

func TestLoadConfig(t *testing.T) {
var testCases = []struct {
name string
configContent []byte
token string
interval int
tempUnit string
err error
}{
{
"full-token",
[]byte(fmt.Sprintf("token: \"1234567890\"\ninterval: 60\ntempUnit: \"C\"")),
"1234567890",
60,
"C",
nil,
},
{
"missing-interval",
[]byte(fmt.Sprintf("token: \"1234567890\"\ntempUnit: \"F\"")),
"1234567890",
0,
"F",
nil,
},
{
"invalid-config",
[]byte(`foobar-invalid`),
"",
0,
"",
&yaml.TypeError{Errors: []string{"line 1: cannot unmarshal !!str `foobar-...` into main.Config"}}},
}

for _, tC := range testCases {
t.Run(tC.name, func(t *testing.T) {
tempFile, err := CreateTestConfig(tC.configContent)
require.NoError(t, err)
defer os.Remove(tempFile.Name())

cfg, err := LoadConfig(tempFile.Name())
if err == nil {
assert.Equal(t, tC.token, cfg.Token)
assert.Equal(t, tC.interval, cfg.Interval)
assert.Equal(t, tC.tempUnit, cfg.TempUnit)
}
assert.Equal(t, tC.err, err)
})
}
}
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ go 1.21.1

require (
github.com/progrium/macdriver v0.5.0-preview.0.20230925233903-5cbb735647c0
github.com/stretchr/testify v1.8.4
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/progrium/macdriver v0.5.0-preview.0.20230925233903-5cbb735647c0 h1:1xYV/JnbBzLDLgQ8RG5JYIZ6zWdMqCjqCfu9w7mNrS4=
github.com/progrium/macdriver v0.5.0-preview.0.20230925233903-5cbb735647c0/go.mod h1:eGZ1EqLpM/E39G7m1QwqPWwP8lu1eLYKuMaZGqt7P3w=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
37 changes: 12 additions & 25 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,6 @@ import (
"github.com/progrium/macdriver/objc"
)

type AirGradientMeasures []struct {
LocationID int `json:"locationId"`
LocationName string `json:"locationName"`
Pm01 any `json:"pm01"`
Pm02 int `json:"pm02"`
Pm10 any `json:"pm10"`
Pm003Count any `json:"pm003Count"`
Atmp float64 `json:"atmp"`
Rhum int `json:"rhum"`
Rco2 int `json:"rco2"`
Tvoc float64 `json:"tvoc"`
Wifi int `json:"wifi"`
Timestamp time.Time `json:"timestamp"`
LedMode string `json:"ledMode"`
LedCo2Threshold1 int `json:"ledCo2Threshold1"`
LedCo2Threshold2 int `json:"ledCo2Threshold2"`
LedCo2ThresholdEnd int `json:"ledCo2ThresholdEnd"`
Serialno string `json:"serialno"`
FirmwareVersion any `json:"firmwareVersion"`
TvocIndex int `json:"tvocIndex"`
NoxIndex int `json:"noxIndex"`
}

func main() {
macos.RunApp(launched)
}
Expand Down Expand Up @@ -80,12 +57,22 @@ func launched(app appkit.Application, delegate *appkit.ApplicationDelegate) {
return
}
}
if len(airGradientMeasures) == 0 {
logger.Error("No measurements found")
return
}

logger.Debug("AirGradientMeasures", "measures", airGradientMeasures[0])

temperature := airGradientMeasures[0].Atmp
if cfg.TempUnit == "F" {
temperature = (airGradientMeasures[0].Atmp * 9 / 5) + 32
}

// updates to the ui should happen on the main thread to avoid segfaults
dispatch.MainQueue().DispatchAsync(func() {
item.Button().SetTitle(fmt.Sprintf("🌡️%.2fF 💨 %d 💦 %d 🫧 %d",
(airGradientMeasures[0].Atmp*9/5)+32,
item.Button().SetTitle(fmt.Sprintf("🌡️%.2f 💨 %d 💦 %d 🫧 %d",
temperature,
airGradientMeasures[0].Pm02,
airGradientMeasures[0].Rhum,
airGradientMeasures[0].Rco2,
Expand Down

0 comments on commit a4018b3

Please sign in to comment.