-
Notifications
You must be signed in to change notification settings - Fork 6
/
enphase.go
120 lines (105 loc) · 2.97 KB
/
enphase.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
"github.com/parnurzeal/gorequest"
)
const uriBase = "https://api.enphaseenergy.com/api/v2"
const PV_PO_DF = "2.1.1.6"
type Enphase struct {
APIKey string
UserID string
req *gorequest.SuperAgent
sysNum uint64
}
type enphaseSystem struct {
SystemID uint64 `json:"system_id"`
SystemName string `json:"system_name"`
SystemPublicName string `json:"system_public_name"`
Status string `json:"status"`
Timezone string `json:"timezone"`
Country string `json:"country"`
State string `json:"state"`
City string `json:"city"`
}
type indexResult struct {
Systems []enphaseSystem `json:"systems"`
}
type Summary struct {
CurrentPower uint64 `json:"current_power"`
EnergyLifetime uint64 `json:"energy_lifetime"`
EnergyToday uint64 `json:"energy_today"`
Modules uint64 `json:"modules"`
OperationalAt uint64 `json:"operational_at"`
SizeWatts uint64 `json:"size_w"`
Source string `json:"source"`
Status string `json:"status"`
SummaryDate string `json:"summary_date"`
SystemID uint64 `json:"system_id"`
}
func NewEnphase(apiKey string, userID string, sysName string) (*Enphase, error) {
request := gorequest.New()
resp, body, errs := request.Get(uriBase + "/systems").
Query("key=" + apiKey).
Query("user_id=" + userID).
EndBytes()
if errs != nil {
return nil, fmt.Errorf("System index request failed: %v", errs)
} else if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("System index request failed: %v", resp.Status)
}
defer resp.Body.Close()
var rslt indexResult
err := json.Unmarshal(body, &rslt)
if err != nil {
return nil, fmt.Errorf("System index request failed: %v", err)
}
for _, system := range rslt.Systems {
if system.SystemName == sysName {
return &Enphase{
APIKey: apiKey,
UserID: userID,
req: request,
sysNum: system.SystemID,
}, nil
}
}
return nil, errors.New("No system with specified name found")
}
func (enphase *Enphase) ReadSummary() (*Summary, error) {
resp, body, errs := enphase.req.Get(fmt.Sprintf("%s/systems/%d/summary", uriBase, enphase.sysNum)).
Query("key=" + enphase.APIKey).
Query("user_id=" + enphase.UserID).
EndBytes()
if errs != nil {
return nil, fmt.Errorf("Summary request failed: %v", errs)
}
defer resp.Body.Close()
var summ Summary
err := json.Unmarshal(body, &summ)
if err != nil {
return nil, errors.New("Received invalid summary as response")
} else if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Summary request failed: %v", err)
}
return &summ, nil
}
func (enphase *Enphase) PollSummary(dur time.Duration) chan *Summary {
summCh := make(chan *Summary)
go func() {
for {
summary, err := enphase.ReadSummary()
if err != nil {
fmt.Printf("Error polling enphase data: %v\n", err)
close(summCh)
return
}
summCh <- summary
time.Sleep(dur)
}
}()
return summCh
}