feat(sense): implement Control API v1 [T-011]
Harness governance / validate (push) Has been cancelled
Harness governance / validate (pull_request) Has been cancelled

This commit is contained in:
QiuSW
2026-08-07 20:54:41 +08:00
parent 0d3d7a22ed
commit a0d239811f
45 changed files with 4844 additions and 83 deletions
+17
View File
@@ -8,6 +8,7 @@ import (
"net/url"
"time"
"yovision/sense/internal/device"
"yovision/sense/internal/onvif"
"yovision/sense/internal/store"
)
@@ -22,6 +23,7 @@ type Repository interface {
type MediaPaths interface {
EnsurePath(ctx context.Context, name, source string) (bool, error)
DeletePath(ctx context.Context, name string) error
}
type Reconciler struct {
@@ -60,6 +62,15 @@ func (r *Reconciler) RunOnce(ctx context.Context) error {
}
func (r *Reconciler) reconcileOne(ctx context.Context, candidate store.ReconcileCandidate, now time.Time) error {
if candidate.Device.DesiredState == device.DesiredDisabled {
if err := r.media.DeletePath(ctx, candidate.Device.PathName); err == nil {
return r.repository.MarkReconciled(ctx, candidate.Device.ID, candidate.Device.Generation, now)
} else if ctx.Err() != nil {
return ctx.Err()
} else {
return r.persistFailure(ctx, candidate, now, err)
}
}
result, err := r.discovery.Probe(ctx, onvif.Target{
EndpointRef: candidate.Device.EndpointRef, CredentialRef: candidate.Device.CredentialRef,
})
@@ -75,6 +86,12 @@ func (r *Reconciler) reconcileOne(ctx context.Context, candidate store.Reconcile
if ctx.Err() != nil {
return ctx.Err()
}
return r.persistFailure(ctx, candidate, now, err)
}
func (r *Reconciler) persistFailure(
ctx context.Context, candidate store.ReconcileCandidate, now time.Time, err error,
) error {
failureCount := candidate.FailureCount + 1
nextAttempt := now.Add(r.backoff(failureCount))
errorCode := string(onvif.CodeOf(err))