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  }