github.com/simpleiot/simpleiot@v0.18.3/client/point.go (about) 1 package client 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "time" 8 9 "github.com/nats-io/nats.go" 10 "github.com/simpleiot/simpleiot/data" 11 ) 12 13 // SendNodePoint sends a node point using the nats protocol 14 func SendNodePoint(nc *nats.Conn, nodeID string, point data.Point, ack bool) error { 15 points := data.Points{point} 16 return SendNodePoints(nc, nodeID, points, ack) 17 } 18 19 // SendEdgePoint sends a edge point using the nats protocol 20 func SendEdgePoint(nc *nats.Conn, nodeID, parentID string, point data.Point, ack bool) error { 21 points := data.Points{point} 22 return SendEdgePoints(nc, nodeID, parentID, points, ack) 23 } 24 25 // SendNodePoints sends node points using the nats protocol 26 func SendNodePoints(nc *nats.Conn, nodeID string, points data.Points, ack bool) error { 27 return SendPoints(nc, SubjectNodePoints(nodeID), points, ack) 28 } 29 30 // SendEdgePoints sends points using the nats protocol 31 func SendEdgePoints(nc *nats.Conn, nodeID, parentID string, points data.Points, ack bool) error { 32 if parentID == "" { 33 parentID = "none" 34 } 35 return SendPoints(nc, SubjectEdgePoints(nodeID, parentID), points, ack) 36 } 37 38 // SendPoints sends points to specified subject 39 func SendPoints(nc *nats.Conn, subject string, points data.Points, ack bool) error { 40 for i := range points { 41 if points[i].Time.IsZero() { 42 points[i].Time = time.Now() 43 } 44 } 45 data, err := points.ToPb() 46 47 if err != nil { 48 return err 49 } 50 51 if ack { 52 msg, err := nc.Request(subject, data, time.Second) 53 54 if err != nil { 55 return err 56 } 57 58 if len(msg.Data) > 0 { 59 return errors.New(string(msg.Data)) 60 } 61 62 } else { 63 if err := nc.Publish(subject, data); err != nil { 64 return err 65 } 66 } 67 68 return err 69 } 70 71 // SubscribePoints subscripts to point updates for a node and executes a callback 72 // when new points arrive. stop() can be called to clean up the subscription 73 func SubscribePoints(nc *nats.Conn, id string, callback func(points []data.Point)) (stop func(), err error) { 74 psub, err := nc.Subscribe(SubjectNodePoints(id), func(msg *nats.Msg) { 75 points, err := data.PbDecodePoints(msg.Data) 76 if err != nil { 77 log.Println("Error decoding points:", err) 78 return 79 } 80 81 callback(points) 82 }) 83 84 return func() { 85 err := psub.Unsubscribe() 86 if err != nil { 87 log.Println("Unsubscribe points error:", err) 88 } 89 }, err 90 } 91 92 // SubscribeEdgePoints subscripts to edge point updates for a node and executes a callback 93 // when new points arrive. stop() can be called to clean up the subscription 94 func SubscribeEdgePoints(nc *nats.Conn, id, parent string, callback func(points []data.Point)) (stop func(), err error) { 95 psub, err := nc.Subscribe(SubjectEdgePoints(id, parent), func(msg *nats.Msg) { 96 points, err := data.PbDecodePoints(msg.Data) 97 if err != nil { 98 log.Println("Error decoding points:", err) 99 return 100 } 101 102 callback(points) 103 }) 104 105 return func() { 106 err := psub.Unsubscribe() 107 if err != nil { 108 log.Println("Unsubscribe points error:", err) 109 } 110 }, err 111 } 112 113 // NewPoints is used to pass new points through channels in client drivers 114 type NewPoints struct { 115 ID string 116 Parent string 117 Points data.Points 118 } 119 120 func (np NewPoints) String() string { 121 ret := fmt.Sprintf("New Points: ID:%v", np.ID) 122 if np.Parent != "" { 123 ret += fmt.Sprintf(" Parent:%v", np.Parent) 124 } 125 ret += "\n" 126 ret += np.Points.String() 127 return ret 128 }