Reliable Automation Execution Core v1 Design

Date: 2026-05-10
Status: Approved (conversation-level), pending file review gate

1. Goal

Thiết kế lại runtime automation để đạt mức production-ready core cho bài toán điều khiển thiết bị tự động, với ưu tiên số 1 là correctness/reliability.

Hệ thống sau khi hoàn thiện phải:

  • điều khiển thiết bị thật qua MQTT RPC một cách bền vững
  • chống duplicate command khi telemetry hoặc worker bị replay
  • có retry/timeout/idempotency rõ ràng
  • có khả năng recovery sau process restart
  • phân biệt được các trạng thái đã gửi, device đã ack, và device đã áp dụng state
  • cung cấp audit trail và observability đủ để debug ngoài thực địa

2. Scope

In scope

  • harden runtime cho luồng telemetry -> rule evaluation -> command dispatch -> ack/reconcile
  • thêm durable event/command state bằng DB + Redis
  • chuẩn hóa firmware/device contract cho command correlation và applied-state reporting
  • nâng execution audit, retry policy, dedupe, timeout handling, command serialization, reconciliation
  • bổ sung test strategy và done criteria cho reliability

Out of scope

  • manual UI control unification
  • scheduler/time-based automation
  • multi-rule conflict engine nâng cao
  • visual dead-letter/replay console hoàn chỉnh
  • distributed automation platform đầy đủ

Tên scope chính xác của phase này là:

Reliable Automation Execution Core v1

3. Current State

Hiện tại repo đã có:

  • endpoint catalog theo device_profile_endpoints
  • endpoint instance theo device_instance_endpoints
  • farm-scoped automation rules
  • telemetry normalization thành endpoint events ở runtime
  • MQTT RPC dispatch cơ bản
  • execution audit ở mức MVP

Điểm yếu hiện tại:

  • telemetry ingestion còn gọi rule engine inline
  • event runtime chưa có persistence riêng để replay/dedupe an toàn
  • command dispatch chưa có durable command ledger
  • correlation với device response còn yếu
  • chưa có applied-state reconciliation đáng tin cậy
  • retry/timeout/restart recovery chưa đạt production-grade

4. Selected Approach

Chọn kiến trúc staged runtime with durable command ledger.

Flow mới:

MQTT telemetry
-> persist telemetry
-> persist normalized endpoint event
-> evaluator worker creates command intent
-> dispatcher worker publishes MQTT RPC with commandId
-> device ack/result
-> reconcile worker marks applied / failed / retrying / uncertain

Lý do chọn:

  • giữ nguyên domain model endpoint/rule đã đầu tư
  • tách ingestion khỏi dispatch để giảm coupling và tăng recoverability
  • cho phép idempotency và retry policy có state rõ ràng
  • tăng khả năng audit và vận hành mà chưa cần full automation platform

5. Architecture

5.1. Telemetry Ingestion

TelemetryService chỉ còn chịu trách nhiệm:

  1. validate device/source
  2. persist telemetry
  3. normalize thành automation endpoint events

Không dispatch command trực tiếp trong cùng call stack của ingestion nữa.

5.2. Endpoint Event Persistence

Mỗi telemetry sau normalize tạo ra một hoặc nhiều automation endpoint events bền vững trong DB.

Mỗi event phải có:

  • identity ổn định
  • dedupe key
  • payload snapshot đủ để audit và replay
  • processing status để worker có thể resume sau restart

5.3. Rule Evaluator Worker

Worker này:

  • lấy pending endpoint events
  • resolve rules active cùng farmId
  • evaluate condition
  • áp safety gates
  • tạo automation command intents idempotent
  • cập nhật automation_rule_executions

Worker không publish MQTT trực tiếp.

5.4. Command Dispatcher Worker

Đây là nơi duy nhất được phép gửi MQTT RPC.

Dispatcher sẽ:

  • lock/lease command intent
  • kiểm tra stale rule và target availability lần cuối
  • build payload theo endpoint binding
  • gán deviceCommandId
  • publish MQTT RPC
  • mark intent sang dispatched
  • khởi tạo timeout/retry tracking

5.5. Ack/Reconcile Worker

Worker này nhận:

  • RPC ack/result
  • telemetry/status follow-up
  • timeout signals

Nó quyết định state cuối:

  • acknowledged
  • applied
  • retrying
  • failed
  • expired
  • uncertain

applied chỉ được set khi có bằng chứng state thực tế đã đổi đúng mong muốn, không chỉ vì publish thành công.

6. Data Model Additions

6.1. automation_endpoint_events

Fields chính:

  • id
  • organizationId
  • farmId
  • deviceId
  • deviceInstanceEndpointId
  • sourceTelemetryId
  • eventTimestamp
  • normalizedValue
  • rawPayloadSnapshot
  • dedupeKey
  • processingStatus: pending, processed, discarded, failed

Vai trò:

  • source of truth cho evaluation runtime
  • replay/recovery point
  • event dedupe boundary

6.2. automation_command_intents

Fields chính:

  • id
  • ruleExecutionId
  • ruleId
  • targetDeviceId
  • targetDeviceEndpointId
  • targetSerialNumber
  • commandMethod
  • commandParams
  • targetValue
  • idempotencyKey
  • desiredStateFingerprint
  • status: pending_dispatch, dispatched, acknowledged, applied, retrying, failed, expired, uncertain
  • attemptCount
  • maxAttempts
  • nextAttemptAt
  • lastError
  • mqttRequestId
  • deviceCommandId
  • createdAt
  • updatedAt

Vai trò:

  • durable command ledger
  • retry/state machine anchor
  • correlation root cho MQTT request/response

6.3. automation_rule_executions

Giữ lại bảng hiện có nhưng nâng trách nhiệm thành execution envelope.

Mỗi execution cần liên kết được tới:

  • triggering endpoint event
  • evaluated rule
  • command intent được tạo
  • final outcome và failure reason

6.4. device_command_receipts

Fields chính:

  • id
  • commandIntentId
  • deviceId
  • serialNumber
  • receiptType: rpc_ack, rpc_result, state_report, timeout_mark, retry_mark
  • payload
  • receivedAt
  • correlationKey

Vai trò:

  • lưu raw evidence cho debugging và postmortem

7. Reliability Model

7.1. Event Dedupe

Mỗi endpoint event cần dedupeKey theo tổ hợp:

  • deviceId
  • deviceInstanceEndpointId
  • eventTimestamp
  • normalizedValue
  • telemetry fingerprint

Redelivery cùng event không được tạo thêm command intent mới.

7.2. Command Dedupe

Mỗi command intent cần idempotencyKey theo tổ hợp:

  • ruleId
  • targetDeviceEndpointId
  • targetValue
  • triggeringEventId

Một rule execution không được sinh nhiều command giống nhau.

7.3. Command State Machine

Luồng chuẩn:

pending_dispatch -> dispatched -> acknowledged -> applied

Nhánh lỗi:

dispatched -> retrying -> dispatched
dispatched -> failed
acknowledged -> uncertain
retrying -> expired

Ý nghĩa:

  • pending_dispatch: rule engine đã quyết định điều khiển
  • dispatched: backend đã publish MQTT thành công
  • acknowledged: device trả correlation hợp lệ
  • applied: có bằng chứng state thật đã đổi
  • retrying: đang chờ attempt tiếp
  • failed: xác định không thành công
  • expired: vượt retry budget/SLA
  • uncertain: có tín hiệu nhưng chưa chứng minh được applied state

7.4. Retry Policy

Chỉ retry với lỗi tạm thời:

  • publish transient error
  • command timeout
  • device offline ngắn hạn

Không retry với lỗi cấu hình:

  • binding invalid
  • endpoint not writable
  • target retired/maintenance
  • invalid target value

Khuyến nghị policy mặc định:

  • maxAttempts = 3
  • exponential backoff với jitter
  • mốc tham khảo: 5s, 15s, 45s

7.5. Restart Recovery

Sau process restart:

  • pending_dispatch phải được worker pick up lại
  • dispatched quá timeout window phải được reconcile sang retrying, failed, hoặc uncertain
  • duplicate ack/result từ device phải không gây double transition

8. Firmware / Device Contract

Thiết bị phải hỗ trợ RPC payload có correlation chuẩn:

{
  "commandId": "cmd_01...",
  "method": "setIO",
  "params": {
    "io1": true
  },
  "sentAt": "2026-05-10T10:00:00.000Z",
  "deadlineAt": "2026-05-10T10:00:05.000Z"
}

8.1. Required RPC Ack/Result

Thiết bị phải trả:

{
  "commandId": "cmd_01...",
  "status": "accepted",
  "resultCode": "ok",
  "message": null
}

8.2. Required Applied-State Report

Thiết bị phải publish follow-up state:

{
  "commandId": "cmd_01...",
  "reportedState": {
    "io1": true
  },
  "appliedAt": "2026-05-10T10:00:02.100Z"
}

8.3. Firmware Requirements

  • command phải idempotent theo commandId
  • nhận lại cùng commandId thì không apply lặp, chỉ replay ack/result
  • trả lỗi rõ ràng: busy, invalid_param, hardware_fault, not_supported
  • state report phải phản ánh state thực tế sau khi apply

9. Safety Rules

Ngoài validation authoring hiện có, runtime phải re-check:

  • rule còn active
  • target endpoint còn isEnabled
  • target endpoint còn isWritable
  • target device còn trong cùng farm
  • target device không maintenance hoặc retired
  • target value vẫn nằm trong endpoint constraints
  • target device còn online theo freshness window
  • không có command xung đột đang inflight trên cùng device/endpoint

Command serialization tối thiểu phải ở scope:

  • deviceId + targetDeviceEndpointId

để tránh race giữa các command cùng endpoint.

10. Reconciliation Rules

acknowledged chưa đủ để kết luận thành công.

Một command chỉ được mark applied khi có ít nhất một trong các bằng chứng hợp lệ:

  • telemetry field đổi sang target value
  • attribute/state report cho biết state đã được áp dụng
  • status topic chuyên dụng xác nhận applied state

Nếu có ack nhưng không thấy applied evidence trong reconciliation window:

  • mark uncertain

Nếu state report mâu thuẫn với desired state:

  • mark failed hoặc uncertain tùy loại lỗi thiết bị trả về

11. Redis Responsibilities

Redis chỉ là coordination layer, không phải source of truth.

Redis được dùng cho:

  • distributed worker lease/lock
  • inflight command cache theo deviceCommandId
  • retry scheduling index
  • short-TTL dedupe cache
  • correlation cache giữa MQTT request và command intent

DB vẫn là nơi lưu trạng thái bền vững cuối cùng.

12. Observability

12.1. Structured Logs

Mọi stage phải log với các key:

  • eventId
  • ruleId
  • ruleExecutionId
  • commandIntentId
  • deviceCommandId
  • deviceId
  • serialNumber

12.2. Metrics

Cần có ít nhất:

  • event ingest rate
  • rule match rate
  • dispatch success rate
  • ack latency
  • applied latency
  • timeout rate
  • retry rate
  • uncertain rate
  • backlog per worker/state

12.3. Diagnostics

Cần có khả năng truy vết:

  • timeline của một rule execution
  • timeline của một device command
  • danh sách commands đang retrying
  • danh sách commands uncertain
  • top devices có timeout nhiều nhất

13. Testing Strategy

13.1. Unit Tests

  • operator evaluation
  • dedupe key generation
  • retry eligibility
  • state machine transitions
  • reconciliation decision logic

13.2. Integration Tests

  • telemetry -> endpoint event persistence
  • endpoint event -> rule execution -> command intent
  • dispatch -> ack -> applied
  • timeout -> retry -> success/failure
  • duplicate telemetry / duplicate ack handling

13.3. Contract Tests

  • backend payload contract với firmware mock
  • response schema validation
  • error code mapping
  • applied-state report parsing

13.4. E2E/System Tests

  • device simulator publish telemetry
  • backend evaluate rule và publish RPC
  • simulator ack + publish applied state
  • assert final execution outcome chính xác

14. Completion Criteria

Phase này được coi là hoàn thành khi:

  • telemetry ingestion không còn dispatch command inline
  • endpoint events được persist và dedupe an toàn
  • command intents là durable source of truth cho dispatch lifecycle
  • MQTT command có commandId, correlation, timeout, retry policy rõ ràng
  • firmware/device trả ack/result theo contract mới
  • backend chỉ mark thành công cuối cùng khi có applied evidence hoặc reconciliation policy rõ ràng
  • duplicate telemetry, duplicate ack, và process restart không gây bắn trùng lệnh
  • có command serialization trên cùng device/endpoint
  • có observability đủ để debug production incidents
  • có test coverage cho happy path, timeout, retry, duplicate, recovery, inconsistent state

15. Deferred Work

Các hạng mục cố ý để phase sau:

  • manual control dùng chung exact runtime path này
  • time-based scheduler
  • multi-condition/multi-action orchestration hoàn chỉnh
  • conflict resolution giữa nhiều rule
  • dead-letter UI và replay UX đầy đủ
  • full automation operations platform

16. Recommendation

Triển khai phase này như một chương trình hardening đa bước, nhưng giữ ranh giới:

  • không phá mô hình endpoint/rule hiện có
  • không làm platform work vượt quá execution core
  • ưu tiên correctness hơn feature breadth

Nếu cần đặt tên roadmap/epic, nên dùng:

Reliable Automation Execution Core v1