add: sensors
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
|||||||
"connectrpc.com/connect"
|
"connectrpc.com/connect"
|
||||||
pb "github.com/chathaway-codes/home-sensors/v2/gen"
|
pb "github.com/chathaway-codes/home-sensors/v2/gen"
|
||||||
servicepb "github.com/chathaway-codes/home-sensors/v2/gen/genconnect"
|
servicepb "github.com/chathaway-codes/home-sensors/v2/gen/genconnect"
|
||||||
|
"github.com/chathaway-codes/home-sensors/v2/internal/sensors"
|
||||||
"github.com/chathaway-codes/home-sensors/v2/internal/video"
|
"github.com/chathaway-codes/home-sensors/v2/internal/video"
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
"github.com/pion/webrtc/v3/pkg/media"
|
"github.com/pion/webrtc/v3/pkg/media"
|
||||||
@@ -37,6 +38,11 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("failed to get default video")
|
log.Fatal().Err(err).Msg("failed to get default video")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sensors, err := sensors.Default.Get()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("failed to get default sensor")
|
||||||
|
}
|
||||||
client := servicepb.NewSignalerServiceClient(http.DefaultClient, "http://192.168.0.65:8080/")
|
client := servicepb.NewSignalerServiceClient(http.DefaultClient, "http://192.168.0.65:8080/")
|
||||||
authToken, err := client.CreateAuthToken(ctx, connect.NewRequest(&pb.CreateAuthTokenRequest{
|
authToken, err := client.CreateAuthToken(ctx, connect.NewRequest(&pb.CreateAuthTokenRequest{
|
||||||
Home: "home1234",
|
Home: "home1234",
|
||||||
@@ -54,6 +60,14 @@ func main() {
|
|||||||
go vid.Run()
|
go vid.Run()
|
||||||
defer vid.Done()
|
defer vid.Done()
|
||||||
|
|
||||||
|
go sensors.Run()
|
||||||
|
defer sensors.Done()
|
||||||
|
|
||||||
|
sensorCh, sensorDone := sensors.Join()
|
||||||
|
defer sensorDone()
|
||||||
|
|
||||||
|
go handleSensor(ctx, client, token, sensorCh)
|
||||||
|
|
||||||
// Create a new RTCPeerConnection
|
// Create a new RTCPeerConnection
|
||||||
log.Info().Msg("waiting for connections")
|
log.Info().Msg("waiting for connections")
|
||||||
|
|
||||||
@@ -67,6 +81,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleSensor(ctx context.Context, client servicepb.SignalerServiceClient, token string, ch <-chan *pb.Sample) {
|
||||||
|
for {
|
||||||
|
var sample *pb.Sample
|
||||||
|
select {
|
||||||
|
case sample = <-ch:
|
||||||
|
// proceed
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := client.CreateSample(ctx, withAuth(token, &pb.CreateSampleRequest{
|
||||||
|
Sample: sample,
|
||||||
|
})); err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to create sample")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleSession(ctx context.Context, client servicepb.SignalerServiceClient, token string, session *connect.Response[pb.Session], vid *video.Video) {
|
func handleSession(ctx context.Context, client servicepb.SignalerServiceClient, token string, session *connect.Response[pb.Session], vid *video.Video) {
|
||||||
var err error
|
var err error
|
||||||
log.Debug().Msg("new session")
|
log.Debug().Msg("new session")
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ const (
|
|||||||
// SignalerServicePopIceMessageProcedure is the fully-qualified name of the SignalerService's
|
// SignalerServicePopIceMessageProcedure is the fully-qualified name of the SignalerService's
|
||||||
// PopIceMessage RPC.
|
// PopIceMessage RPC.
|
||||||
SignalerServicePopIceMessageProcedure = "/signaler.SignalerService/PopIceMessage"
|
SignalerServicePopIceMessageProcedure = "/signaler.SignalerService/PopIceMessage"
|
||||||
|
// SignalerServiceCreateSampleProcedure is the fully-qualified name of the SignalerService's
|
||||||
|
// CreateSample RPC.
|
||||||
|
SignalerServiceCreateSampleProcedure = "/signaler.SignalerService/CreateSample"
|
||||||
|
// SignalerServiceListSamplesProcedure is the fully-qualified name of the SignalerService's
|
||||||
|
// ListSamples RPC.
|
||||||
|
SignalerServiceListSamplesProcedure = "/signaler.SignalerService/ListSamples"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignalerServiceClient is a client for the signaler.SignalerService service.
|
// SignalerServiceClient is a client for the signaler.SignalerService service.
|
||||||
@@ -72,6 +78,12 @@ type SignalerServiceClient interface {
|
|||||||
//
|
//
|
||||||
// If there are no messages, this blocks until one becomes available.
|
// If there are no messages, this blocks until one becomes available.
|
||||||
PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error)
|
PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error)
|
||||||
|
// CreateSample creates a sample for the given camera.
|
||||||
|
// If called without an auth token indicating a camera, an error
|
||||||
|
// is returned.
|
||||||
|
// TODO: this should be moved to a seperate service
|
||||||
|
CreateSample(context.Context, *connect.Request[gen.CreateSampleRequest]) (*connect.Response[gen.Sample], error)
|
||||||
|
ListSamples(context.Context, *connect.Request[gen.ListSamplesRequest]) (*connect.Response[gen.ListSamplesResponse], error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSignalerServiceClient constructs a client for the signaler.SignalerService service. By
|
// NewSignalerServiceClient constructs a client for the signaler.SignalerService service. By
|
||||||
@@ -114,6 +126,16 @@ func NewSignalerServiceClient(httpClient connect.HTTPClient, baseURL string, opt
|
|||||||
baseURL+SignalerServicePopIceMessageProcedure,
|
baseURL+SignalerServicePopIceMessageProcedure,
|
||||||
opts...,
|
opts...,
|
||||||
),
|
),
|
||||||
|
createSample: connect.NewClient[gen.CreateSampleRequest, gen.Sample](
|
||||||
|
httpClient,
|
||||||
|
baseURL+SignalerServiceCreateSampleProcedure,
|
||||||
|
opts...,
|
||||||
|
),
|
||||||
|
listSamples: connect.NewClient[gen.ListSamplesRequest, gen.ListSamplesResponse](
|
||||||
|
httpClient,
|
||||||
|
baseURL+SignalerServiceListSamplesProcedure,
|
||||||
|
opts...,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +147,8 @@ type signalerServiceClient struct {
|
|||||||
popSession *connect.Client[gen.PopSessionRequest, gen.Session]
|
popSession *connect.Client[gen.PopSessionRequest, gen.Session]
|
||||||
createIceMessage *connect.Client[gen.CreateIceMessageRequest, gen.IceMessage]
|
createIceMessage *connect.Client[gen.CreateIceMessageRequest, gen.IceMessage]
|
||||||
popIceMessage *connect.Client[gen.PopIceMessageRequest, gen.IceMessage]
|
popIceMessage *connect.Client[gen.PopIceMessageRequest, gen.IceMessage]
|
||||||
|
createSample *connect.Client[gen.CreateSampleRequest, gen.Sample]
|
||||||
|
listSamples *connect.Client[gen.ListSamplesRequest, gen.ListSamplesResponse]
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAuthToken calls signaler.SignalerService.CreateAuthToken.
|
// CreateAuthToken calls signaler.SignalerService.CreateAuthToken.
|
||||||
@@ -157,6 +181,16 @@ func (c *signalerServiceClient) PopIceMessage(ctx context.Context, req *connect.
|
|||||||
return c.popIceMessage.CallUnary(ctx, req)
|
return c.popIceMessage.CallUnary(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSample calls signaler.SignalerService.CreateSample.
|
||||||
|
func (c *signalerServiceClient) CreateSample(ctx context.Context, req *connect.Request[gen.CreateSampleRequest]) (*connect.Response[gen.Sample], error) {
|
||||||
|
return c.createSample.CallUnary(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSamples calls signaler.SignalerService.ListSamples.
|
||||||
|
func (c *signalerServiceClient) ListSamples(ctx context.Context, req *connect.Request[gen.ListSamplesRequest]) (*connect.Response[gen.ListSamplesResponse], error) {
|
||||||
|
return c.listSamples.CallUnary(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
// SignalerServiceHandler is an implementation of the signaler.SignalerService service.
|
// SignalerServiceHandler is an implementation of the signaler.SignalerService service.
|
||||||
type SignalerServiceHandler interface {
|
type SignalerServiceHandler interface {
|
||||||
CreateAuthToken(context.Context, *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error)
|
CreateAuthToken(context.Context, *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error)
|
||||||
@@ -176,6 +210,12 @@ type SignalerServiceHandler interface {
|
|||||||
//
|
//
|
||||||
// If there are no messages, this blocks until one becomes available.
|
// If there are no messages, this blocks until one becomes available.
|
||||||
PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error)
|
PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error)
|
||||||
|
// CreateSample creates a sample for the given camera.
|
||||||
|
// If called without an auth token indicating a camera, an error
|
||||||
|
// is returned.
|
||||||
|
// TODO: this should be moved to a seperate service
|
||||||
|
CreateSample(context.Context, *connect.Request[gen.CreateSampleRequest]) (*connect.Response[gen.Sample], error)
|
||||||
|
ListSamples(context.Context, *connect.Request[gen.ListSamplesRequest]) (*connect.Response[gen.ListSamplesResponse], error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSignalerServiceHandler builds an HTTP handler from the service implementation. It returns the
|
// NewSignalerServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||||
@@ -214,6 +254,16 @@ func NewSignalerServiceHandler(svc SignalerServiceHandler, opts ...connect.Handl
|
|||||||
svc.PopIceMessage,
|
svc.PopIceMessage,
|
||||||
opts...,
|
opts...,
|
||||||
)
|
)
|
||||||
|
signalerServiceCreateSampleHandler := connect.NewUnaryHandler(
|
||||||
|
SignalerServiceCreateSampleProcedure,
|
||||||
|
svc.CreateSample,
|
||||||
|
opts...,
|
||||||
|
)
|
||||||
|
signalerServiceListSamplesHandler := connect.NewUnaryHandler(
|
||||||
|
SignalerServiceListSamplesProcedure,
|
||||||
|
svc.ListSamples,
|
||||||
|
opts...,
|
||||||
|
)
|
||||||
return "/signaler.SignalerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return "/signaler.SignalerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case SignalerServiceCreateAuthTokenProcedure:
|
case SignalerServiceCreateAuthTokenProcedure:
|
||||||
@@ -228,6 +278,10 @@ func NewSignalerServiceHandler(svc SignalerServiceHandler, opts ...connect.Handl
|
|||||||
signalerServiceCreateIceMessageHandler.ServeHTTP(w, r)
|
signalerServiceCreateIceMessageHandler.ServeHTTP(w, r)
|
||||||
case SignalerServicePopIceMessageProcedure:
|
case SignalerServicePopIceMessageProcedure:
|
||||||
signalerServicePopIceMessageHandler.ServeHTTP(w, r)
|
signalerServicePopIceMessageHandler.ServeHTTP(w, r)
|
||||||
|
case SignalerServiceCreateSampleProcedure:
|
||||||
|
signalerServiceCreateSampleHandler.ServeHTTP(w, r)
|
||||||
|
case SignalerServiceListSamplesProcedure:
|
||||||
|
signalerServiceListSamplesHandler.ServeHTTP(w, r)
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
}
|
}
|
||||||
@@ -260,3 +314,11 @@ func (UnimplementedSignalerServiceHandler) CreateIceMessage(context.Context, *co
|
|||||||
func (UnimplementedSignalerServiceHandler) PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error) {
|
func (UnimplementedSignalerServiceHandler) PopIceMessage(context.Context, *connect.Request[gen.PopIceMessageRequest]) (*connect.Response[gen.IceMessage], error) {
|
||||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.PopIceMessage is not implemented"))
|
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.PopIceMessage is not implemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (UnimplementedSignalerServiceHandler) CreateSample(context.Context, *connect.Request[gen.CreateSampleRequest]) (*connect.Response[gen.Sample], error) {
|
||||||
|
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.CreateSample is not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (UnimplementedSignalerServiceHandler) ListSamples(context.Context, *connect.Request[gen.ListSamplesRequest]) (*connect.Response[gen.ListSamplesResponse], error) {
|
||||||
|
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.ListSamples is not implemented"))
|
||||||
|
}
|
||||||
|
|||||||
+531
-189
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
|||||||
|
package sensors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
pb "github.com/chathaway-codes/home-sensors/v2/gen"
|
||||||
|
"github.com/chathaway-codes/home-sensors/v2/internal/pipespy"
|
||||||
|
"github.com/chathaway-codes/home-sensors/v2/internal/watcher/config"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Default = &Mod{}
|
||||||
|
|
||||||
|
type Sensors struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
ctx context.Context
|
||||||
|
readCmd *exec.Cmd
|
||||||
|
cancelFunc func()
|
||||||
|
ticker time.Ticker
|
||||||
|
|
||||||
|
listeners map[string]chan<- *pb.Sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cfg *config.Config) (*Sensors, error) {
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
readCmd := exec.CommandContext(ctx, cfg.SensorCmd.Binary, cfg.SensorCmd.Arguments...)
|
||||||
|
|
||||||
|
ticker := time.NewTicker(time.Duration(cfg.SensorRateMS) * time.Millisecond)
|
||||||
|
return &Sensors{
|
||||||
|
ctx: ctx,
|
||||||
|
cancelFunc: cancelFunc,
|
||||||
|
readCmd: readCmd,
|
||||||
|
ticker: *ticker,
|
||||||
|
// it would be better if sensors.Run handled sending to the server; to do that,
|
||||||
|
// it needs a connection and the auth token. I don't have a clean way of getting that
|
||||||
|
// right now.
|
||||||
|
listeners: make(map[string]chan<- *pb.Sample),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Sensors) Run() {
|
||||||
|
pipe := pipespy.New()
|
||||||
|
snoop := pipe.Add(pipespy.NewCmd(v.readCmd)).Snoop()
|
||||||
|
defer snoop.Close()
|
||||||
|
|
||||||
|
cleanUp := pipe.Start()
|
||||||
|
defer func() {
|
||||||
|
errs := cleanUp()
|
||||||
|
for _, err := range errs {
|
||||||
|
log.Err(err).Send()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(snoop)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.Split(line, " ")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
log.Error().Str("line", line).Msg("malformed line; expected 3 floats: humidity pressure temperature_c")
|
||||||
|
}
|
||||||
|
humidity, err := strconv.ParseFloat(parts[0], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("val", parts[0]).Msg("failed to parse humidity")
|
||||||
|
}
|
||||||
|
pressure, err := strconv.ParseFloat(parts[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("val", parts[1]).Msg("failed to parse pressure")
|
||||||
|
}
|
||||||
|
temperatureC, err := strconv.ParseFloat(parts[2], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("val", parts[2]).Msg("failed to parse temperature_c")
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-v.ticker.C:
|
||||||
|
func() {
|
||||||
|
v.mu.Lock()
|
||||||
|
defer v.mu.Unlock()
|
||||||
|
|
||||||
|
samples := []*pb.Sample{
|
||||||
|
{
|
||||||
|
Type: pb.Sample_HUMIDITY,
|
||||||
|
Reading: humidity,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: pb.Sample_PRESSURE,
|
||||||
|
Reading: pressure,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: pb.Sample_TEMPERATURE_C,
|
||||||
|
Reading: temperatureC,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, listener := range v.listeners {
|
||||||
|
for _, sample := range samples {
|
||||||
|
listener <- sample
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
default:
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join will connect to a running stream.
|
||||||
|
func (v *Sensors) Join() (<-chan *pb.Sample, func()) {
|
||||||
|
v.mu.Lock()
|
||||||
|
defer v.mu.Unlock()
|
||||||
|
|
||||||
|
myID := uuid.New().String()
|
||||||
|
ch := make(chan *pb.Sample)
|
||||||
|
v.listeners[myID] = ch
|
||||||
|
|
||||||
|
return ch, func() {
|
||||||
|
v.mu.Lock()
|
||||||
|
defer v.mu.Unlock()
|
||||||
|
|
||||||
|
delete(v.listeners, myID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done stops the processing.
|
||||||
|
func (v *Sensors) Done() {
|
||||||
|
v.cancelFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mod struct{}
|
||||||
|
|
||||||
|
func (m *Mod) Get() (*Sensors, error) {
|
||||||
|
cfg, err := config.Default.Get()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return New(cfg)
|
||||||
|
}
|
||||||
@@ -17,8 +17,10 @@ type Cmd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
H264Cmd *Cmd `yaml:"h264"`
|
H264Cmd *Cmd `yaml:"h264"`
|
||||||
IVFCmd *Cmd `yaml:"ivf"`
|
IVFCmd *Cmd `yaml:"ivf"`
|
||||||
|
SensorCmd *Cmd `yaml:"sensor"`
|
||||||
|
SensorRateMS int64 `yaml:"sensor_rate_ms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(source []byte) (*Config, error) {
|
func New(source []byte) (*Config, error) {
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ type Server struct {
|
|||||||
|
|
||||||
sessionsByCamera map[string]chan *session
|
sessionsByCamera map[string]chan *session
|
||||||
sessionsById map[string]*session
|
sessionsById map[string]*session
|
||||||
|
|
||||||
|
// Most recent sample
|
||||||
|
samplesByCamera map[string]map[pb.Sample_Type]*pb.Sample
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *Server {
|
func New() *Server {
|
||||||
@@ -44,6 +47,7 @@ func New() *Server {
|
|||||||
camerasByHome: make(map[string]map[string]*camera),
|
camerasByHome: make(map[string]map[string]*camera),
|
||||||
sessionsByCamera: make(map[string]chan *session),
|
sessionsByCamera: make(map[string]chan *session),
|
||||||
sessionsById: make(map[string]*session),
|
sessionsById: make(map[string]*session),
|
||||||
|
samplesByCamera: make(map[string]map[pb.Sample_Type]*pb.Sample),
|
||||||
}
|
}
|
||||||
go s.cleanup()
|
go s.cleanup()
|
||||||
return s
|
return s
|
||||||
@@ -160,9 +164,11 @@ func (s *Server) PopSession(ctx context.Context, request *connect.Request[pb.Pop
|
|||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
|
||||||
if _, ok := s.camerasByHome[authToken.Home]; !ok {
|
if _, ok := s.camerasByHome[authToken.Home]; !ok {
|
||||||
|
s.mu.Unlock()
|
||||||
return nil, status.Errorf(codes.NotFound, "home %q not found", authToken.Home)
|
return nil, status.Errorf(codes.NotFound, "home %q not found", authToken.Home)
|
||||||
}
|
}
|
||||||
if _, ok := s.camerasByHome[authToken.Home][authToken.Uid]; !ok {
|
if _, ok := s.camerasByHome[authToken.Home][authToken.Uid]; !ok {
|
||||||
|
s.mu.Unlock()
|
||||||
return nil, status.Errorf(codes.Unauthenticated, "you are not a camera")
|
return nil, status.Errorf(codes.Unauthenticated, "you are not a camera")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +244,65 @@ func (s *Server) PopIceMessage(ctx context.Context, request *connect.Request[pb.
|
|||||||
return connect.NewResponse(msg), nil
|
return connect.NewResponse(msg), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) CreateSample(ctx context.Context, request *connect.Request[pb.CreateSampleRequest]) (*connect.Response[pb.Sample], error) {
|
||||||
|
authToken, err := getAuthToken(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
if _, ok := s.camerasByHome[authToken.Home]; !ok {
|
||||||
|
return nil, status.Errorf(codes.NotFound, "home %q not found", authToken.Home)
|
||||||
|
}
|
||||||
|
cam, ok := s.camerasByHome[authToken.Home][authToken.Uid]
|
||||||
|
if !ok {
|
||||||
|
return nil, status.Errorf(codes.Unauthenticated, "you are not a camera")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := s.samplesByCamera[authToken.Uid]; !ok {
|
||||||
|
s.samplesByCamera[authToken.Uid] = make(map[pb.Sample_Type]*pb.Sample)
|
||||||
|
}
|
||||||
|
|
||||||
|
sample := request.Msg.GetSample()
|
||||||
|
s.samplesByCamera[authToken.Uid][sample.Type] = &pb.Sample{
|
||||||
|
Type: sample.Type,
|
||||||
|
Reading: sample.Reading,
|
||||||
|
|
||||||
|
CameraId: &pb.Camera_Identifier{
|
||||||
|
Id: cam.id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return connect.NewResponse(s.samplesByCamera[authToken.Uid][sample.Type]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ListSamples(ctx context.Context, request *connect.Request[pb.ListSamplesRequest]) (*connect.Response[pb.ListSamplesResponse], error) {
|
||||||
|
authToken, err := getAuthToken(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
if _, ok := s.camerasByHome[authToken.Home]; !ok {
|
||||||
|
return nil, status.Errorf(codes.NotFound, "home %q not found", authToken.Home)
|
||||||
|
}
|
||||||
|
|
||||||
|
var samples []*pb.Sample
|
||||||
|
for camera := range s.camerasByHome[authToken.Home] {
|
||||||
|
if sample, ok := s.samplesByCamera[camera]; ok {
|
||||||
|
for _, sample := range sample {
|
||||||
|
samples = append(samples, sample)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connect.NewResponse(&pb.ListSamplesResponse{
|
||||||
|
Samples: samples,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) cleanup() {
|
func (s *Server) cleanup() {
|
||||||
ticker := time.NewTicker(time.Minute * 5)
|
ticker := time.NewTicker(time.Minute * 5)
|
||||||
for t := range ticker.C {
|
for t := range ticker.C {
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ service SignalerService {
|
|||||||
// If there are no messages, this blocks until one becomes available.
|
// If there are no messages, this blocks until one becomes available.
|
||||||
rpc PopIceMessage(PopIceMessageRequest) returns (IceMessage);
|
rpc PopIceMessage(PopIceMessageRequest) returns (IceMessage);
|
||||||
|
|
||||||
|
// CreateSample creates a sample for the given camera.
|
||||||
|
// If called without an auth token indicating a camera, an error
|
||||||
|
// is returned.
|
||||||
|
// TODO: this should be moved to a seperate service
|
||||||
|
rpc CreateSample(CreateSampleRequest) returns (Sample);
|
||||||
|
rpc ListSamples(ListSamplesRequest) returns (ListSamplesResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateAuthTokenRequest{
|
message CreateAuthTokenRequest{
|
||||||
@@ -85,6 +91,17 @@ message PopIceMessageRequest {
|
|||||||
Session.Identifier session_identifier = 1;
|
Session.Identifier session_identifier = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message CreateSampleRequest{
|
||||||
|
Sample sample = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSamplesRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSamplesResponse {
|
||||||
|
repeated Sample samples = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message Camera {
|
message Camera {
|
||||||
message Identifier {
|
message Identifier {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
@@ -127,3 +144,17 @@ message Session {
|
|||||||
message AuthToken {
|
message AuthToken {
|
||||||
string token = 1;
|
string token = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Sample{
|
||||||
|
enum Type {
|
||||||
|
UNSPECIFIED = 0;
|
||||||
|
TEMPERATURE_C = 1;
|
||||||
|
HUMIDITY = 2;
|
||||||
|
PRESSURE = 3;
|
||||||
|
}
|
||||||
|
Type type = 1;
|
||||||
|
double reading = 2;
|
||||||
|
|
||||||
|
// Read-only; will be ignored in CreateSample.
|
||||||
|
Camera.Identifier camera_id = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
h264:
|
||||||
|
binary: "/usr/bin/libcamera-vid"
|
||||||
|
arguments:
|
||||||
|
- "-n"
|
||||||
|
- "-t"
|
||||||
|
- "0"
|
||||||
|
- "--codec"
|
||||||
|
- "h264"
|
||||||
|
- "--mode"
|
||||||
|
- "1640:1232"
|
||||||
|
- "--denoise"
|
||||||
|
- "off"
|
||||||
|
- "--inline"
|
||||||
|
- "-o"
|
||||||
|
- "-"
|
||||||
|
ivf:
|
||||||
|
binary: "/usr/bin/ffmpeg"
|
||||||
|
arguments:
|
||||||
|
- "-i"
|
||||||
|
- "-"
|
||||||
|
- "-g"
|
||||||
|
- "30"
|
||||||
|
- "-b:v"
|
||||||
|
- "2M"
|
||||||
|
- "-f"
|
||||||
|
- "ivf"
|
||||||
|
- "-"
|
||||||
|
sensor:
|
||||||
|
binary: "/usr/bin/python3"
|
||||||
|
arguments:
|
||||||
|
- "/home/charles/temperature.py"
|
||||||
|
sensor_rate_ms: 10000
|
||||||
@@ -14,3 +14,9 @@ ivf:
|
|||||||
- "-f"
|
- "-f"
|
||||||
- "ivf"
|
- "ivf"
|
||||||
- "-"
|
- "-"
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
binary: "/usr/bin/yes"
|
||||||
|
arguments:
|
||||||
|
- "44.33889713096721 1015.1977693083448 23.60542243081727"
|
||||||
|
sensor_rate_ms: 10000
|
||||||
@@ -14,6 +14,10 @@ import 'dart:core' as $core;
|
|||||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
|
import 'signaler_service.pbenum.dart';
|
||||||
|
|
||||||
|
export 'signaler_service.pbenum.dart';
|
||||||
|
|
||||||
class CreateAuthTokenRequest_Camera extends $pb.GeneratedMessage {
|
class CreateAuthTokenRequest_Camera extends $pb.GeneratedMessage {
|
||||||
factory CreateAuthTokenRequest_Camera({
|
factory CreateAuthTokenRequest_Camera({
|
||||||
$core.String? id,
|
$core.String? id,
|
||||||
@@ -658,6 +662,134 @@ class PopIceMessageRequest extends $pb.GeneratedMessage {
|
|||||||
Session_Identifier ensureSessionIdentifier() => $_ensure(0);
|
Session_Identifier ensureSessionIdentifier() => $_ensure(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CreateSampleRequest extends $pb.GeneratedMessage {
|
||||||
|
factory CreateSampleRequest({
|
||||||
|
Sample? sample,
|
||||||
|
}) {
|
||||||
|
final $result = create();
|
||||||
|
if (sample != null) {
|
||||||
|
$result.sample = sample;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
CreateSampleRequest._() : super();
|
||||||
|
factory CreateSampleRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory CreateSampleRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'CreateSampleRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'signaler'), createEmptyInstance: create)
|
||||||
|
..aOM<Sample>(1, _omitFieldNames ? '' : 'sample', subBuilder: Sample.create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
CreateSampleRequest clone() => CreateSampleRequest()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
CreateSampleRequest copyWith(void Function(CreateSampleRequest) updates) => super.copyWith((message) => updates(message as CreateSampleRequest)) as CreateSampleRequest;
|
||||||
|
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static CreateSampleRequest create() => CreateSampleRequest._();
|
||||||
|
CreateSampleRequest createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<CreateSampleRequest> createRepeated() => $pb.PbList<CreateSampleRequest>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static CreateSampleRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateSampleRequest>(create);
|
||||||
|
static CreateSampleRequest? _defaultInstance;
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
Sample get sample => $_getN(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set sample(Sample v) { setField(1, v); }
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasSample() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearSample() => clearField(1);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
Sample ensureSample() => $_ensure(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListSamplesRequest extends $pb.GeneratedMessage {
|
||||||
|
factory ListSamplesRequest() => create();
|
||||||
|
ListSamplesRequest._() : super();
|
||||||
|
factory ListSamplesRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory ListSamplesRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ListSamplesRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'signaler'), createEmptyInstance: create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
ListSamplesRequest clone() => ListSamplesRequest()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
ListSamplesRequest copyWith(void Function(ListSamplesRequest) updates) => super.copyWith((message) => updates(message as ListSamplesRequest)) as ListSamplesRequest;
|
||||||
|
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static ListSamplesRequest create() => ListSamplesRequest._();
|
||||||
|
ListSamplesRequest createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<ListSamplesRequest> createRepeated() => $pb.PbList<ListSamplesRequest>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static ListSamplesRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ListSamplesRequest>(create);
|
||||||
|
static ListSamplesRequest? _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListSamplesResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ListSamplesResponse({
|
||||||
|
$core.Iterable<Sample>? samples,
|
||||||
|
}) {
|
||||||
|
final $result = create();
|
||||||
|
if (samples != null) {
|
||||||
|
$result.samples.addAll(samples);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
ListSamplesResponse._() : super();
|
||||||
|
factory ListSamplesResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory ListSamplesResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ListSamplesResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'signaler'), createEmptyInstance: create)
|
||||||
|
..pc<Sample>(1, _omitFieldNames ? '' : 'samples', $pb.PbFieldType.PM, subBuilder: Sample.create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
ListSamplesResponse clone() => ListSamplesResponse()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
ListSamplesResponse copyWith(void Function(ListSamplesResponse) updates) => super.copyWith((message) => updates(message as ListSamplesResponse)) as ListSamplesResponse;
|
||||||
|
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static ListSamplesResponse create() => ListSamplesResponse._();
|
||||||
|
ListSamplesResponse createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<ListSamplesResponse> createRepeated() => $pb.PbList<ListSamplesResponse>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static ListSamplesResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ListSamplesResponse>(create);
|
||||||
|
static ListSamplesResponse? _defaultInstance;
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<Sample> get samples => $_getList(0);
|
||||||
|
}
|
||||||
|
|
||||||
class Camera_Identifier extends $pb.GeneratedMessage {
|
class Camera_Identifier extends $pb.GeneratedMessage {
|
||||||
factory Camera_Identifier({
|
factory Camera_Identifier({
|
||||||
$core.String? id,
|
$core.String? id,
|
||||||
@@ -1219,6 +1351,86 @@ class AuthToken extends $pb.GeneratedMessage {
|
|||||||
void clearToken() => clearField(1);
|
void clearToken() => clearField(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Sample extends $pb.GeneratedMessage {
|
||||||
|
factory Sample({
|
||||||
|
Sample_Type? type,
|
||||||
|
$core.double? reading,
|
||||||
|
Camera_Identifier? cameraId,
|
||||||
|
}) {
|
||||||
|
final $result = create();
|
||||||
|
if (type != null) {
|
||||||
|
$result.type = type;
|
||||||
|
}
|
||||||
|
if (reading != null) {
|
||||||
|
$result.reading = reading;
|
||||||
|
}
|
||||||
|
if (cameraId != null) {
|
||||||
|
$result.cameraId = cameraId;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
Sample._() : super();
|
||||||
|
factory Sample.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory Sample.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Sample', package: const $pb.PackageName(_omitMessageNames ? '' : 'signaler'), createEmptyInstance: create)
|
||||||
|
..e<Sample_Type>(1, _omitFieldNames ? '' : 'type', $pb.PbFieldType.OE, defaultOrMaker: Sample_Type.UNSPECIFIED, valueOf: Sample_Type.valueOf, enumValues: Sample_Type.values)
|
||||||
|
..a<$core.double>(2, _omitFieldNames ? '' : 'reading', $pb.PbFieldType.OD)
|
||||||
|
..aOM<Camera_Identifier>(3, _omitFieldNames ? '' : 'cameraId', subBuilder: Camera_Identifier.create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
Sample clone() => Sample()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
Sample copyWith(void Function(Sample) updates) => super.copyWith((message) => updates(message as Sample)) as Sample;
|
||||||
|
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static Sample create() => Sample._();
|
||||||
|
Sample createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<Sample> createRepeated() => $pb.PbList<Sample>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static Sample getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Sample>(create);
|
||||||
|
static Sample? _defaultInstance;
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
Sample_Type get type => $_getN(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set type(Sample_Type v) { setField(1, v); }
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasType() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearType() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.double get reading => $_getN(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set reading($core.double v) { $_setDouble(1, v); }
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasReading() => $_has(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
void clearReading() => clearField(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
Camera_Identifier get cameraId => $_getN(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set cameraId(Camera_Identifier v) { setField(3, v); }
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasCameraId() => $_has(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
void clearCameraId() => clearField(3);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
Camera_Identifier ensureCameraId() => $_ensure(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
|
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
|
||||||
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
|
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
|
||||||
|
|||||||
@@ -9,3 +9,28 @@
|
|||||||
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
||||||
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
||||||
|
|
||||||
|
import 'dart:core' as $core;
|
||||||
|
|
||||||
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
|
class Sample_Type extends $pb.ProtobufEnum {
|
||||||
|
static const Sample_Type UNSPECIFIED = Sample_Type._(0, _omitEnumNames ? '' : 'UNSPECIFIED');
|
||||||
|
static const Sample_Type TEMPERATURE_C = Sample_Type._(1, _omitEnumNames ? '' : 'TEMPERATURE_C');
|
||||||
|
static const Sample_Type HUMIDITY = Sample_Type._(2, _omitEnumNames ? '' : 'HUMIDITY');
|
||||||
|
static const Sample_Type PRESSURE = Sample_Type._(3, _omitEnumNames ? '' : 'PRESSURE');
|
||||||
|
|
||||||
|
static const $core.List<Sample_Type> values = <Sample_Type> [
|
||||||
|
UNSPECIFIED,
|
||||||
|
TEMPERATURE_C,
|
||||||
|
HUMIDITY,
|
||||||
|
PRESSURE,
|
||||||
|
];
|
||||||
|
|
||||||
|
static final $core.Map<$core.int, Sample_Type> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
|
static Sample_Type? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
|
const Sample_Type._($core.int v, $core.String n) : super(v, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names');
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ class SignalerServiceClient extends $grpc.Client {
|
|||||||
'/signaler.SignalerService/PopIceMessage',
|
'/signaler.SignalerService/PopIceMessage',
|
||||||
($0.PopIceMessageRequest value) => value.writeToBuffer(),
|
($0.PopIceMessageRequest value) => value.writeToBuffer(),
|
||||||
($core.List<$core.int> value) => $0.IceMessage.fromBuffer(value));
|
($core.List<$core.int> value) => $0.IceMessage.fromBuffer(value));
|
||||||
|
static final _$createSample = $grpc.ClientMethod<$0.CreateSampleRequest, $0.Sample>(
|
||||||
|
'/signaler.SignalerService/CreateSample',
|
||||||
|
($0.CreateSampleRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.Sample.fromBuffer(value));
|
||||||
|
static final _$listSamples = $grpc.ClientMethod<$0.ListSamplesRequest, $0.ListSamplesResponse>(
|
||||||
|
'/signaler.SignalerService/ListSamples',
|
||||||
|
($0.ListSamplesRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.ListSamplesResponse.fromBuffer(value));
|
||||||
|
|
||||||
SignalerServiceClient($grpc.ClientChannel channel,
|
SignalerServiceClient($grpc.ClientChannel channel,
|
||||||
{$grpc.CallOptions? options,
|
{$grpc.CallOptions? options,
|
||||||
@@ -75,6 +83,14 @@ class SignalerServiceClient extends $grpc.Client {
|
|||||||
$grpc.ResponseFuture<$0.IceMessage> popIceMessage($0.PopIceMessageRequest request, {$grpc.CallOptions? options}) {
|
$grpc.ResponseFuture<$0.IceMessage> popIceMessage($0.PopIceMessageRequest request, {$grpc.CallOptions? options}) {
|
||||||
return $createUnaryCall(_$popIceMessage, request, options: options);
|
return $createUnaryCall(_$popIceMessage, request, options: options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$grpc.ResponseFuture<$0.Sample> createSample($0.CreateSampleRequest request, {$grpc.CallOptions? options}) {
|
||||||
|
return $createUnaryCall(_$createSample, request, options: options);
|
||||||
|
}
|
||||||
|
|
||||||
|
$grpc.ResponseFuture<$0.ListSamplesResponse> listSamples($0.ListSamplesRequest request, {$grpc.CallOptions? options}) {
|
||||||
|
return $createUnaryCall(_$listSamples, request, options: options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@$pb.GrpcServiceName('signaler.SignalerService')
|
@$pb.GrpcServiceName('signaler.SignalerService')
|
||||||
@@ -124,6 +140,20 @@ abstract class SignalerServiceBase extends $grpc.Service {
|
|||||||
false,
|
false,
|
||||||
($core.List<$core.int> value) => $0.PopIceMessageRequest.fromBuffer(value),
|
($core.List<$core.int> value) => $0.PopIceMessageRequest.fromBuffer(value),
|
||||||
($0.IceMessage value) => value.writeToBuffer()));
|
($0.IceMessage value) => value.writeToBuffer()));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.CreateSampleRequest, $0.Sample>(
|
||||||
|
'CreateSample',
|
||||||
|
createSample_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.CreateSampleRequest.fromBuffer(value),
|
||||||
|
($0.Sample value) => value.writeToBuffer()));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.ListSamplesRequest, $0.ListSamplesResponse>(
|
||||||
|
'ListSamples',
|
||||||
|
listSamples_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.ListSamplesRequest.fromBuffer(value),
|
||||||
|
($0.ListSamplesResponse value) => value.writeToBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.AuthToken> createAuthToken_Pre($grpc.ServiceCall call, $async.Future<$0.CreateAuthTokenRequest> request) async {
|
$async.Future<$0.AuthToken> createAuthToken_Pre($grpc.ServiceCall call, $async.Future<$0.CreateAuthTokenRequest> request) async {
|
||||||
@@ -150,10 +180,20 @@ abstract class SignalerServiceBase extends $grpc.Service {
|
|||||||
return popIceMessage(call, await request);
|
return popIceMessage(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.Sample> createSample_Pre($grpc.ServiceCall call, $async.Future<$0.CreateSampleRequest> request) async {
|
||||||
|
return createSample(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.ListSamplesResponse> listSamples_Pre($grpc.ServiceCall call, $async.Future<$0.ListSamplesRequest> request) async {
|
||||||
|
return listSamples(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
$async.Future<$0.AuthToken> createAuthToken($grpc.ServiceCall call, $0.CreateAuthTokenRequest request);
|
$async.Future<$0.AuthToken> createAuthToken($grpc.ServiceCall call, $0.CreateAuthTokenRequest request);
|
||||||
$async.Future<$0.ListCamerasResponse> listCameras($grpc.ServiceCall call, $0.ListCamerasRequest request);
|
$async.Future<$0.ListCamerasResponse> listCameras($grpc.ServiceCall call, $0.ListCamerasRequest request);
|
||||||
$async.Future<$0.Session> createSession($grpc.ServiceCall call, $0.CreateSessionRequest request);
|
$async.Future<$0.Session> createSession($grpc.ServiceCall call, $0.CreateSessionRequest request);
|
||||||
$async.Future<$0.Session> popSession($grpc.ServiceCall call, $0.PopSessionRequest request);
|
$async.Future<$0.Session> popSession($grpc.ServiceCall call, $0.PopSessionRequest request);
|
||||||
$async.Future<$0.IceMessage> createIceMessage($grpc.ServiceCall call, $0.CreateIceMessageRequest request);
|
$async.Future<$0.IceMessage> createIceMessage($grpc.ServiceCall call, $0.CreateIceMessageRequest request);
|
||||||
$async.Future<$0.IceMessage> popIceMessage($grpc.ServiceCall call, $0.PopIceMessageRequest request);
|
$async.Future<$0.IceMessage> popIceMessage($grpc.ServiceCall call, $0.PopIceMessageRequest request);
|
||||||
|
$async.Future<$0.Sample> createSample($grpc.ServiceCall call, $0.CreateSampleRequest request);
|
||||||
|
$async.Future<$0.ListSamplesResponse> listSamples($grpc.ServiceCall call, $0.ListSamplesRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,41 @@ final $typed_data.Uint8List popIceMessageRequestDescriptor = $convert.base64Deco
|
|||||||
'ChRQb3BJY2VNZXNzYWdlUmVxdWVzdBJLChJzZXNzaW9uX2lkZW50aWZpZXIYASABKAsyHC5zaW'
|
'ChRQb3BJY2VNZXNzYWdlUmVxdWVzdBJLChJzZXNzaW9uX2lkZW50aWZpZXIYASABKAsyHC5zaW'
|
||||||
'duYWxlci5TZXNzaW9uLklkZW50aWZpZXJSEXNlc3Npb25JZGVudGlmaWVy');
|
'duYWxlci5TZXNzaW9uLklkZW50aWZpZXJSEXNlc3Npb25JZGVudGlmaWVy');
|
||||||
|
|
||||||
|
@$core.Deprecated('Use createSampleRequestDescriptor instead')
|
||||||
|
const CreateSampleRequest$json = {
|
||||||
|
'1': 'CreateSampleRequest',
|
||||||
|
'2': [
|
||||||
|
{'1': 'sample', '3': 1, '4': 1, '5': 11, '6': '.signaler.Sample', '10': 'sample'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `CreateSampleRequest`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List createSampleRequestDescriptor = $convert.base64Decode(
|
||||||
|
'ChNDcmVhdGVTYW1wbGVSZXF1ZXN0EigKBnNhbXBsZRgBIAEoCzIQLnNpZ25hbGVyLlNhbXBsZV'
|
||||||
|
'IGc2FtcGxl');
|
||||||
|
|
||||||
|
@$core.Deprecated('Use listSamplesRequestDescriptor instead')
|
||||||
|
const ListSamplesRequest$json = {
|
||||||
|
'1': 'ListSamplesRequest',
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `ListSamplesRequest`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List listSamplesRequestDescriptor = $convert.base64Decode(
|
||||||
|
'ChJMaXN0U2FtcGxlc1JlcXVlc3Q=');
|
||||||
|
|
||||||
|
@$core.Deprecated('Use listSamplesResponseDescriptor instead')
|
||||||
|
const ListSamplesResponse$json = {
|
||||||
|
'1': 'ListSamplesResponse',
|
||||||
|
'2': [
|
||||||
|
{'1': 'samples', '3': 1, '4': 3, '5': 11, '6': '.signaler.Sample', '10': 'samples'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `ListSamplesResponse`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List listSamplesResponseDescriptor = $convert.base64Decode(
|
||||||
|
'ChNMaXN0U2FtcGxlc1Jlc3BvbnNlEioKB3NhbXBsZXMYASADKAsyEC5zaWduYWxlci5TYW1wbG'
|
||||||
|
'VSB3NhbXBsZXM=');
|
||||||
|
|
||||||
@$core.Deprecated('Use cameraDescriptor instead')
|
@$core.Deprecated('Use cameraDescriptor instead')
|
||||||
const Camera$json = {
|
const Camera$json = {
|
||||||
'1': 'Camera',
|
'1': 'Camera',
|
||||||
@@ -284,3 +319,32 @@ const AuthToken$json = {
|
|||||||
final $typed_data.Uint8List authTokenDescriptor = $convert.base64Decode(
|
final $typed_data.Uint8List authTokenDescriptor = $convert.base64Decode(
|
||||||
'CglBdXRoVG9rZW4SFAoFdG9rZW4YASABKAlSBXRva2Vu');
|
'CglBdXRoVG9rZW4SFAoFdG9rZW4YASABKAlSBXRva2Vu');
|
||||||
|
|
||||||
|
@$core.Deprecated('Use sampleDescriptor instead')
|
||||||
|
const Sample$json = {
|
||||||
|
'1': 'Sample',
|
||||||
|
'2': [
|
||||||
|
{'1': 'type', '3': 1, '4': 1, '5': 14, '6': '.signaler.Sample.Type', '10': 'type'},
|
||||||
|
{'1': 'reading', '3': 2, '4': 1, '5': 1, '10': 'reading'},
|
||||||
|
{'1': 'camera_id', '3': 3, '4': 1, '5': 11, '6': '.signaler.Camera.Identifier', '10': 'cameraId'},
|
||||||
|
],
|
||||||
|
'4': [Sample_Type$json],
|
||||||
|
};
|
||||||
|
|
||||||
|
@$core.Deprecated('Use sampleDescriptor instead')
|
||||||
|
const Sample_Type$json = {
|
||||||
|
'1': 'Type',
|
||||||
|
'2': [
|
||||||
|
{'1': 'UNSPECIFIED', '2': 0},
|
||||||
|
{'1': 'TEMPERATURE_C', '2': 1},
|
||||||
|
{'1': 'HUMIDITY', '2': 2},
|
||||||
|
{'1': 'PRESSURE', '2': 3},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `Sample`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List sampleDescriptor = $convert.base64Decode(
|
||||||
|
'CgZTYW1wbGUSKQoEdHlwZRgBIAEoDjIVLnNpZ25hbGVyLlNhbXBsZS5UeXBlUgR0eXBlEhgKB3'
|
||||||
|
'JlYWRpbmcYAiABKAFSB3JlYWRpbmcSOAoJY2FtZXJhX2lkGAMgASgLMhsuc2lnbmFsZXIuQ2Ft'
|
||||||
|
'ZXJhLklkZW50aWZpZXJSCGNhbWVyYUlkIkYKBFR5cGUSDwoLVU5TUEVDSUZJRUQQABIRCg1URU'
|
||||||
|
'1QRVJBVFVSRV9DEAESDAoISFVNSURJVFkQAhIMCghQUkVTU1VSRRAD');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user