Nik Afiq 8f7024edfa
All checks were successful
CI / changes (push) Successful in 19s
CI / test (push) Successful in 24s
CI / build-ai-gateway (push) Successful in 1m6s
CI / build-ha-gateway (push) Successful in 1m3s
CI / build-discord-bot (push) Successful in 1m4s
CI / build-alexa-bridge (push) Successful in 1m15s
CI / build-tts-gateway (push) Successful in 1m5s
CI / build-tts-sidecar (push) Has been skipped
CI / build-tts-model (push) Has been skipped
feat(climate): add SetTemperature method to ClimateService
- Implemented SetTemperature in ClimateService for setting an absolute target temperature.
- Updated ClimateServiceClient and ClimateServiceServer interfaces to include SetTemperature.
- Added corresponding handler and tests for SetTemperature in ClimateGRPC.
- Modified ClimateApp to handle SetTemperature requests without clamping.
- Updated climate.proto to define SetTemperatureRequest message.
- Adjusted Dockerfiles to include alexa-bridge dependencies.
2026-07-25 12:08:24 +09:00

49 lines
1.4 KiB
Go

package entities
import (
"strings"
"sync/atomic"
"gitea.nik4nao.com/nik/home-services/alexa-bridge/internal/core/domain"
)
// Resolver implements driven.EntityResolver via an atomically-swapped
// snapshot map, so an in-flight Alexa request never observes a half-built
// map while a refresh is in progress.
type Resolver struct {
snapshot atomic.Pointer[map[string]domain.Entity]
}
// NewResolver constructs a Resolver with an empty snapshot; call Replace
// (directly, or via Refresher.Start) to populate it before serving requests.
func NewResolver() *Resolver {
r := &Resolver{}
empty := map[string]domain.Entity{}
r.snapshot.Store(&empty)
return r
}
// Replace rebuilds the lookup map, keyed by normalized friendly name, and
// swaps it in atomically.
func (r *Resolver) Replace(list []domain.Entity) {
m := make(map[string]domain.Entity, len(list))
for _, e := range list {
m[normalize(e.FriendlyName)] = e
}
r.snapshot.Store(&m)
}
// Resolve implements driven.EntityResolver. Matching is exact-match only on
// the normalized (lowercased, trimmed) friendly name — see
// alexa-bridge/plan.md's Decisions on open questions #5 for why fuzzy
// matching isn't implemented here.
func (r *Resolver) Resolve(friendlyName string) (domain.Entity, bool) {
m := *r.snapshot.Load()
e, ok := m[normalize(friendlyName)]
return e, ok
}
func normalize(s string) string {
return strings.ToLower(strings.TrimSpace(s))
}