generated from rmcguire/go-server-with-otel
implement econet exporter
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// Package econet provides EconetService, a service.AppService that connects
|
||||
// to the Rheem EcoNet cloud and exposes device state via gRPC, an MCP tool,
|
||||
// and OTEL metrics served for Prometheus scraping.
|
||||
package econet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
rheemcloud "github.com/kevinburke/rheemcloud-go"
|
||||
|
||||
optsgrpc "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts"
|
||||
optshttp "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/http/opts"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/config"
|
||||
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/econet/econetgrpc"
|
||||
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/econet/econetmcp"
|
||||
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/econet/econetmetrics"
|
||||
"gitea.libretechconsulting.com/rmcguire/econet-exporter/pkg/service"
|
||||
)
|
||||
|
||||
type EconetService struct {
|
||||
ctx context.Context
|
||||
config *config.ServiceConfig
|
||||
client *rheemcloud.Client
|
||||
grpc *econetgrpc.EconetGRPCServer
|
||||
mcp *econetmcp.EconetMCPServer
|
||||
metrics *econetmetrics.Collector
|
||||
}
|
||||
|
||||
func (e *EconetService) Init(ctx context.Context, cfg *config.ServiceConfig) (service.ShutdownFunc, error) {
|
||||
e.ctx = ctx
|
||||
e.config = cfg
|
||||
|
||||
client, err := connect(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e.client = client
|
||||
|
||||
e.grpc = econetgrpc.NewEconetGRPCServer(ctx, cfg, client)
|
||||
e.mcp = econetmcp.NewEconetMCPServer(ctx, cfg, e.grpc)
|
||||
e.metrics = econetmetrics.NewCollector(ctx, cfg, client)
|
||||
if err := e.metrics.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return e.shutdown, nil
|
||||
}
|
||||
|
||||
func connect(ctx context.Context, cfg *config.ServiceConfig) (*rheemcloud.Client, error) {
|
||||
if cfg.EconetEmail == "" || cfg.EconetPassword == "" {
|
||||
return nil, fmt.Errorf("econet: email and password required (set ECONET_EMAIL / ECONET_PASSWORD)")
|
||||
}
|
||||
client, err := rheemcloud.Connect(ctx, cfg.EconetEmail, cfg.EconetPassword, &rheemcloud.Config{
|
||||
Logger: slog.Default(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("econet: connect failed: %w", err)
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (e *EconetService) shutdown(_ context.Context) (string, error) {
|
||||
e.metrics.Stop()
|
||||
return "EconetService", e.client.Close()
|
||||
}
|
||||
|
||||
func (e *EconetService) GetGRPC() *optsgrpc.AppGRPC {
|
||||
return &optsgrpc.AppGRPC{
|
||||
Services: e.grpc.GetServices(),
|
||||
GRPCDialOpts: e.grpc.GetDialOpts(),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EconetService) GetHTTP() *optshttp.AppHTTP {
|
||||
return &optshttp.AppHTTP{
|
||||
Ctx: e.ctx,
|
||||
Handlers: e.mcp.GetHandlers(),
|
||||
HealthChecks: e.healthChecks(),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EconetService) healthChecks() []optshttp.HealthCheckFunc {
|
||||
return []optshttp.HealthCheckFunc{
|
||||
func(_ context.Context) error {
|
||||
if len(e.client.Devices()) == 0 {
|
||||
return fmt.Errorf("econet: no devices loaded")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user