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

Issue-7: json: cannot unmarshal number #8

Merged
merged 3 commits into from
Oct 10, 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
50 changes: 33 additions & 17 deletions airgradient.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
package main

import (
"encoding/json"
"errors"
"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"`
Pm01 float64 `json:"pm01"`
Pm02 float64 `json:"pm02"`
Pm10 float64 `json:"pm10"`
Pm003Count float64 `json:"pm003Count"`
Atmp float64 `json:"atmp"`
Rhum int `json:"rhum"`
Rco2 int `json:"rco2"`
Rhum float64 `json:"rhum"`
Rco2 float64 `json:"rco2"`
Tvoc float64 `json:"tvoc"`
Wifi int `json:"wifi"`
Wifi float64 `json:"wifi"`
Timestamp time.Time `json:"timestamp"`
LedMode string `json:"ledMode"`
LedCo2Threshold1 int `json:"ledCo2Threshold1"`
LedCo2Threshold2 int `json:"ledCo2Threshold2"`
LedCo2ThresholdEnd int `json:"ledCo2ThresholdEnd"`
LedCo2Threshold1 float64 `json:"ledCo2Threshold1"`
LedCo2Threshold2 float64 `json:"ledCo2Threshold2"`
LedCo2ThresholdEnd float64 `json:"ledCo2ThresholdEnd"`
Serialno string `json:"serialno"`
FirmwareVersion any `json:"firmwareVersion"`
TvocIndex int `json:"tvocIndex"`
NoxIndex int `json:"noxIndex"`
FirmwareVersion string `json:"firmwareVersion"`
TvocIndex float64 `json:"tvocIndex"`
NoxIndex float64 `json:"noxIndex"`
}

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

req, err := http.NewRequest("GET", AIR_GRADIENT_API_URL, nil)
req, err := http.NewRequest("GET", airGradientAPIUrl, nil)
if err != nil {
logger.Error("Creating HTTP request", "error", err)
return nil, err
Expand All @@ -59,3 +59,19 @@ func fetchMeasures(token string) ([]byte, error) {

return body, nil
}

func getAirGradientMeasures(airGradientAPIUrl string, token string) (AirGradientMeasures, error) {
payload, err := fetchMeasures(airGradientAPIUrl, token)
if err != nil {
return nil, err
}

var airGradientMeasures AirGradientMeasures

err = json.Unmarshal(payload, &airGradientMeasures)
if err != nil {
return nil, errors.New("Error unmarshalling JSON")
}

return airGradientMeasures, nil
}
46 changes: 46 additions & 0 deletions airgradient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetAirGradientMeasures(t *testing.T) {
var testCases = []struct {
name string
payloadFile string
err error
}{
{
"correct-response",
"testdata/correct_response1.json",
nil,
},
{
"correct-response2",
"testdata/correct_response2.json",
nil,
},
{
"incorrect-response",
"testdata/incorrect_response1.json",
errors.New("Error unmarshalling JSON"),
},
}

for _, tC := range testCases {
t.Run(tC.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, tC.payloadFile)
}))
defer server.Close()

_, err := getAirGradientMeasures(server.URL, "SECRET-TOKEN")
assert.Equal(t, tC.err, err)
})
}
}
16 changes: 6 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"encoding/json"
"fmt"
"os"
"time"
Expand All @@ -12,6 +11,8 @@ import (
"github.com/progrium/macdriver/objc"
)

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

func main() {
macos.RunApp(launched)
}
Expand Down Expand Up @@ -45,18 +46,13 @@ func launched(app appkit.Application, delegate *appkit.ApplicationDelegate) {
for {
select {
case <-time.After(time.Duration(cfg.Interval) * time.Second):
payload, err := fetchMeasures(cfg.Token)
airGradientMeasures, err = getAirGradientMeasures(AIR_GRADIENT_API_URL, cfg.Token)
if err != nil {
logger.Error("Fetching measures", "error", err)
return
}

err = json.Unmarshal(payload, &airGradientMeasures)
if err != nil {
logger.Error("Parsing JSON payload", "error", err)
return
continue
}
}

if len(airGradientMeasures) == 0 {
logger.Error("No measurements found")
return
Expand All @@ -71,7 +67,7 @@ func launched(app appkit.Application, delegate *appkit.ApplicationDelegate) {

// updates to the ui should happen on the main thread to avoid segfaults
dispatch.MainQueue().DispatchAsync(func() {
item.Button().SetTitle(fmt.Sprintf("🌡️ %.2f 💨 %d 💦 %d 🫧 %d",
item.Button().SetTitle(fmt.Sprintf("🌡️ %.2f 💨 %.0f 💧 %.1f 🫧 %.0f",
temperature,
airGradientMeasures[0].Pm02,
airGradientMeasures[0].Rhum,
Expand Down
Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions testdata/correct_response1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"locationId":12345,"locationName":"Test Loc","pm01":null,"pm02":4,"pm10":null,"pm003Count":null,"atmp":24.3,"rhum":52,"rco2":548,"tvoc":93.979355,"wifi":-58,"timestamp":"2023-10-10T03:42:11.000Z","ledMode":"co2","ledCo2Threshold1":1000,"ledCo2Threshold2":2000,"ledCo2ThresholdEnd":4000,"serialno":"aabb12","firmwareVersion":null,"tvocIndex":100,"noxIndex":1}]
1 change: 1 addition & 0 deletions testdata/correct_response2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"locationId":12345,"locationName":"Test Loc","pm01":null,"pm02":4,"pm10":null,"pm003Count":null,"atmp":24.3,"rhum":53.5,"rco2":548,"tvoc":93.979355,"wifi":-58,"timestamp":"2023-10-10T03:42:11.000Z","ledMode":"co2","ledCo2Threshold1":1000,"ledCo2Threshold2":2000,"ledCo2ThresholdEnd":4000,"serialno":"aabb12","firmwareVersion":null,"tvocIndex":100,"noxIndex":1}]
10 changes: 10 additions & 0 deletions testdata/incorrect_response1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /public/api/v1/locations/measures/current1</pre>
</body>
</html>