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

Minor changes #3

Merged
merged 1 commit into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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