github.com/simpleiot/simpleiot@v0.18.3/api/client.go (about) 1 package api 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "io" 8 "log" 9 "net/http" 10 "time" 11 12 "github.com/simpleiot/simpleiot/data" 13 ) 14 15 // Point is a custom value of data.Point with Time set to a pointer. This allows 16 // omitempty to work for zero timestamps to avoid bloating JSON packets. 17 type Point struct { 18 // Type of point (voltage, current, key, etc) 19 Type string `json:"type,omitempty" influx:"type,tag"` 20 21 // Key of the device that provided the point 22 Key string `json:"key,omitempty" influx:"key,tag"` 23 24 // Average OR 25 // Instantaneous analog or digital value of the point. 26 // 0 and 1 are used to represent digital values 27 Value float64 `json:"value,omitempty" influx:"value"` 28 29 // Time the point was taken 30 Time *time.Time `json:"time,omitempty" gob:"-" influx:"time"` 31 32 // Duration over which the point was taken 33 Duration time.Duration `json:"duration,omitempty" influx:"duration"` 34 } 35 36 // NewPoint converts a data.Point to Point and rounds floating point 37 // values to 3 dec places. 38 func NewPoint(s data.Point) Point { 39 var time *time.Time 40 41 if !s.Time.IsZero() { 42 time = &s.Time 43 } 44 45 return Point{ 46 Type: s.Type, 47 Key: s.Key, 48 Value: s.Value, 49 Time: time, 50 } 51 } 52 53 // NewPoints converts []data.Sample to []Sample 54 func NewPoints(points []data.Point) []Point { 55 ret := make([]Point, len(points)) 56 57 for i, p := range points { 58 ret[i] = NewPoint(p) 59 } 60 61 return ret 62 } 63 64 // NewSendPoints returns a function that can be used to send points 65 // to a SimpleIoT portal instance 66 func NewSendPoints(portalURL, deviceID, authToken string, timeout time.Duration, debug bool) func(data.Points) error { 67 var netClient = &http.Client{ 68 Timeout: timeout, 69 } 70 71 return func(points data.Points) error { 72 pointURL := portalURL + "/v1/devices/" + deviceID + "/points" 73 74 tempJSON, err := json.Marshal(NewPoints(points)) 75 if err != nil { 76 return err 77 } 78 79 if debug { 80 log.Println("Sending points:", string(tempJSON)) 81 } 82 83 req, err := http.NewRequest("POST", pointURL, bytes.NewBuffer(tempJSON)) 84 if err != nil { 85 return err 86 } 87 88 req.Header.Set("Content-Type", "application/json") 89 req.Header.Set("Authorization", authToken) 90 resp, err := netClient.Do(req) 91 92 if err != nil { 93 return err 94 } 95 96 defer resp.Body.Close() 97 98 if resp.StatusCode != http.StatusOK { 99 errstring := "Server error: " + resp.Status + " " + pointURL 100 body, _ := io.ReadAll(resp.Body) 101 errstring += " " + string(body) 102 return errors.New(errstring) 103 } 104 105 return nil 106 } 107 }