- Added detailed comments to clarify the purpose of various functions and types in the Discord bot and HA gateway. - Introduced new methods in the CommandApp for handling light and switch operations, including HandleLightOn, HandleLightOff, HandleLightToggle, and their respective autocomplete functions. - Updated the HAClient interface to include methods for fetching states and calling services, enhancing the interaction with Home Assistant. - Improved the structure of entity and light domain models to include additional attributes and clearer documentation. - Implemented logging enhancements in both the Discord bot and HA gateway to ensure better traceability and context in logs. - Refactored the configuration loading process to streamline environment variable handling and defaults. - Stubbed out switch control methods in the gRPC adapter, indicating future implementation plans. - Enhanced telemetry setup to ensure proper initialization and shutdown procedures for observability.
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package grpc
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
hav1 "gitea.nik4nao.com/nik/home-services/gen/ha/v1"
|
|
"gitea.nik4nao.com/nik/home-services/ha-gateway/internal/core/domain"
|
|
"gitea.nik4nao.com/nik/home-services/ha-gateway/internal/core/ports/driving"
|
|
)
|
|
|
|
type EntityGRPC struct {
|
|
hav1.UnimplementedEntityServiceServer
|
|
svc driving.EntityService
|
|
}
|
|
|
|
// NewEntityGRPC constructs the gRPC adapter for EntityService.
|
|
func NewEntityGRPC(svc driving.EntityService) *EntityGRPC {
|
|
return &EntityGRPC{svc: svc}
|
|
}
|
|
|
|
// GetState translates a protobuf request into a domain call and back again.
|
|
func (h *EntityGRPC) GetState(ctx context.Context, req *hav1.GetStateRequest) (*hav1.GetStateResponse, error) {
|
|
s, err := h.svc.GetState(ctx, domain.EntityID(req.EntityId))
|
|
if err != nil {
|
|
return nil, grpcError(err)
|
|
}
|
|
return &hav1.GetStateResponse{State: domainStateToProto(s)}, nil
|
|
}
|
|
|
|
// ListStates translates repeated protobuf IDs and filters into the domain call.
|
|
func (h *EntityGRPC) ListStates(ctx context.Context, req *hav1.ListStatesRequest) (*hav1.ListStatesResponse, error) {
|
|
ids := make([]domain.EntityID, len(req.EntityIds))
|
|
for i, id := range req.EntityIds {
|
|
ids[i] = domain.EntityID(id)
|
|
}
|
|
|
|
states, err := h.svc.ListStates(ctx, ids, req.Domain)
|
|
if err != nil {
|
|
return nil, grpcError(err)
|
|
}
|
|
|
|
proto := make([]*hav1.EntityState, len(states))
|
|
for i, s := range states {
|
|
proto[i] = domainStateToProto(s)
|
|
}
|
|
return &hav1.ListStatesResponse{States: proto}, nil
|
|
}
|
|
|
|
// grpcError maps domain errors to appropriate gRPC status codes.
|
|
func grpcError(err error) error {
|
|
if errors.Is(err, ErrNotFound) {
|
|
return status.Errorf(codes.NotFound, "%v", err)
|
|
}
|
|
if errors.Is(err, ErrNotImplemented) {
|
|
return status.Errorf(codes.Unimplemented, "%v", err)
|
|
}
|
|
return status.Errorf(codes.Internal, "%v", err)
|
|
}
|
|
|
|
// ErrNotFound is returned by the app layer when an entity does not exist.
|
|
var ErrNotFound = errors.New("not found")
|
|
|
|
// ErrNotImplemented is returned by handlers that are stubbed pending full implementation.
|
|
var ErrNotImplemented = errors.New("not implemented")
|