implement econet exporter
Build and Publish / go-binaries (push) Has been skipped
Build and Publish / container-images (push) Has been skipped
Build and Publish / helm-release (push) Successful in 19s
Build and Publish / check-chart (push) Successful in 52s

This commit is contained in:
2026-07-04 17:22:31 -04:00
parent 8198e8cfee
commit b2ec72352a
44 changed files with 2226 additions and 1281 deletions
+32
View File
@@ -0,0 +1,32 @@
package econetgrpc
import (
rheemcloud "github.com/kevinburke/rheemcloud-go"
"google.golang.org/protobuf/types/known/timestamppb"
pb "gitea.libretechconsulting.com/rmcguire/econet-exporter/api/econet/v1alpha1"
)
func deviceToProto(d *rheemcloud.Device) *pb.Device {
min, max := d.SetpointLimits()
return &pb.Device{
SerialNumber: d.SerialNumber(),
DeviceId: d.DeviceID(),
FriendlyName: d.FriendlyName(),
Type: d.Type().String(),
GenericType: d.GenericType(),
Connected: d.Connected(),
WifiSignal: int32(d.WiFiSignal()),
Mode: d.Mode().String(),
Enabled: d.Enabled(),
Running: d.Running(),
RunningState: d.RunningState(),
Setpoint: int32(d.Setpoint()),
SetpointMin: int32(min),
SetpointMax: int32(max),
HotWaterAvailability: int32(d.HotWaterAvailability()),
AlertCount: int32(d.AlertCount()),
Away: d.Away(),
LastUpdated: timestamppb.New(d.LastUpdated),
}
}
+72
View File
@@ -0,0 +1,72 @@
// Package econetgrpc implements the EconetService gRPC API over a shared
// rheemcloud.Client, exposing read-only device state.
package econetgrpc
import (
"context"
rheemcloud "github.com/kevinburke/rheemcloud-go"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
grpccodes "google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
pb "gitea.libretechconsulting.com/rmcguire/econet-exporter/api/econet/v1alpha1"
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/config"
)
type EconetGRPCServer struct {
tracer trace.Tracer
ctx context.Context
cfg *config.ServiceConfig
client *rheemcloud.Client
pb.UnimplementedEconetServiceServer
}
func NewEconetGRPCServer(ctx context.Context, cfg *config.ServiceConfig, client *rheemcloud.Client) *EconetGRPCServer {
return &EconetGRPCServer{
ctx: ctx,
cfg: cfg,
client: client,
tracer: otel.GetTracer(ctx, "econetGRPCServer"),
}
}
func (s *EconetGRPCServer) ListDevices(ctx context.Context, _ *pb.ListDevicesRequest) (
*pb.ListDevicesResponse, error,
) {
_, span := s.tracer.Start(ctx, "listDevices")
defer span.End()
devices := s.client.Devices()
resp := &pb.ListDevicesResponse{Devices: make([]*pb.Device, 0, len(devices))}
for _, d := range devices {
resp.Devices = append(resp.Devices, deviceToProto(d))
}
span.SetAttributes(attribute.Int("devices", len(resp.Devices)))
span.SetStatus(codes.Ok, "")
return resp, nil
}
func (s *EconetGRPCServer) GetDevice(ctx context.Context, req *pb.GetDeviceRequest) (
*pb.GetDeviceResponse, error,
) {
_, span := s.tracer.Start(ctx, "getDevice", trace.WithAttributes(
attribute.String("serialNumber", req.GetSerialNumber()),
))
defer span.End()
d := s.client.Device(req.GetSerialNumber())
if d == nil {
err := status.Errorf(grpccodes.NotFound, "no device with serial %q", req.GetSerialNumber())
span.SetStatus(codes.Error, err.Error())
return nil, err
}
span.SetStatus(codes.Ok, "")
return &pb.GetDeviceResponse{Device: deviceToProto(d)}, nil
}
+30
View File
@@ -0,0 +1,30 @@
package econetgrpc
import (
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
econetPb "gitea.libretechconsulting.com/rmcguire/econet-exporter/api/econet/v1alpha1"
)
func (s *EconetGRPCServer) GetDialOpts() []grpc.DialOption {
return []grpc.DialOption{
// NOTE: Necessary for grpc-gateway to connect to grpc server
// Update if grpc service has credentials, tls, etc..
grpc.WithTransportCredentials(insecure.NewCredentials()),
}
}
func (s *EconetGRPCServer) GetServices() []*opts.GRPCService {
return []*opts.GRPCService{
{
Name: "Econet Exporter",
Type: &econetPb.EconetService_ServiceDesc,
Service: s,
GwRegistrationFuncs: []opts.GwRegistrationFunc{
econetPb.RegisterEconetServiceHandler,
},
},
}
}