T3 — Finite State Machine và Harel Statechart - congsinhv/fluxion GitHub Wiki

Finite State Machine và Harel Statechart trong Device Lifecycle

Issue: #15 — Nghiên cứu Finite State Machine (Harel Statechart) Tuần: 3 | 07/04 – 13/04/2026 Numbering chính thức: Mục 2.7 theo Master TOC (Chương 2)


2.7.1 Finite State Machine (FSM)

2.7.1.1 Định Nghĩa

Finite State Machine (FSM) — hay còn gọi là Finite Automaton — là mô hình tính toán toán học mô tả hành vi của một hệ thống thông qua một tập hữu hạn các trạng thái (states), chuyển đổi (transitions), và sự kiện kích hoạt (triggers/events).

Một FSM được định nghĩa hình thức bởi bộ 5 thành phần (quintuple) [1]:

M = (Q, Σ, δ, q₀, F)

Trong đó:

  • Q — tập hữu hạn các trạng thái
  • Σ — tập bảng chữ cái đầu vào (input alphabet / triggers)
  • δ: Q × Σ → Q — hàm chuyển đổi trạng thái
  • q₀ ∈ Q — trạng thái khởi đầu
  • F ⊆ Q — tập các trạng thái kết thúc (terminal states)

Trong kỹ thuật phần mềm, FSM được sử dụng rộng rãi để mô hình hoá lifecycle của các thực thể có trạng thái rõ ràng — giao thức mạng, quy trình nghiệp vụ, và vòng đời thiết bị trong hệ thống MDM.

Hai loại FSM chính:

  • Mealy Machine: Output phụ thuộc vào cả trạng thái hiện tại input
  • Moore Machine: Output chỉ phụ thuộc vào trạng thái hiện tại

Áp dụng trong Fluxion: Fluxion DeviceFSM là Moore Machine — trạng thái của thiết bị xác định các hành động có thể thực hiện, không phụ thuộc vào input cụ thể tại thời điểm truy vấn.

2.7.1.2 Ưu Điểm FSM Cho Device Lifecycle

Thuộc tính Mô tả Lợi ích trong Fluxion
Deterministic Mỗi (state, trigger) → duy nhất một state tiếp theo Không có trạng thái mơ hồ — device không thể ở "active" và "locked" cùng lúc
Auditable Mọi transition đều có thể log lại Audit trail đầy đủ lịch sử thay đổi trạng thái thiết bị
Visualizable State diagram dễ đọc, dễ communicate Stakeholder không kỹ thuật hiểu được lifecycle
Testable Có thể test từng transition độc lập Unit test cho từng trigger rõ ràng
Guard conditions Chỉ cho phép transition khi điều kiện thoả mãn Tránh lock thiết bị chưa enrolled

Bảng 2.7.1: Ưu điểm FSM cho device lifecycle management


2.7.2 Harel Statechart

2.7.2.1 Giới Thiệu

David Harel công bố Statecharts: A Visual Formalism for Complex Systems năm 1987 trên tạp chí Science of Computer Programming [5]. Statechart là mở rộng của FSM truyền thống với ba đặc điểm chính:

1. Hierarchical States (Trạng thái phân cấp) Statechart cho phép states lồng nhau (nested states) — một state "cha" có thể chứa nhiều states "con". Khi ở trong bất kỳ state con nào, thiết bị cũng được coi là đang ở state cha. Điều này giảm đáng kể số lượng transitions cần định nghĩa.

2. Parallel States (Trạng thái song song) Thiết bị có thể ở nhiều "region" song song cùng lúc — ví dụ: region connectivity (online/offline) song song với region management_state (enrolled/locked).

3. Guard Conditions (Điều kiện bảo vệ) Transitions chỉ xảy ra khi một biểu thức boolean (guard) là true. Ví dụ: transition enroll_complete chỉ valid khi device.certificate_valid == true.

2.7.2.2 So Sánh FSM và Harel Statechart

Đặc điểm FSM truyền thống Harel Statechart
States Phẳng (flat) Phân cấp (hierarchical)
Parallel regions Không
Guard conditions Không (hoặc manual) Tích hợp sẵn
Lịch sử (History) Không Deep/Shallow history states
Complexity Tăng theo bình phương số states Tăng tuyến tính nhờ hierarchy
Phù hợp cho Systems đơn giản, ít states Systems phức tạp, nhiều states lồng nhau

Bảng 2.7.2: So sánh FSM và Harel Statechart

2.7.2.3 Áp Dụng Trong Fluxion

DeviceFSM của Fluxion sử dụng FSM phẳng (flat FSM) với guard conditions — đủ để mô hình hoá 6 trạng thái thiết bị mà không cần độ phức tạp của full Statechart. Quyết định này tuân theo nguyên tắc KISS: Statechart mang lợi ích rõ ràng khi số lượng states và transitions tăng lên đáng kể.

Quyết định triển khai: Fluxion implement FSM theo hướng DB-driven — states và transitions được lưu trong database (bảng state, policy, action) thay vì hardcode trong code. Xem chi tiết schema tại mục 2.7.4.2.


2.7.3 DeviceFSM Trong Fluxion

2.7.3.1 Định Nghĩa States

State Mô tả Các action được phép
Idle Thiết bị được upload vào hệ thống, chưa đăng ký Register
Registered Đã đăng ký MDM, chưa hoàn tất enrollment Checkin
Enrolled Đang trong quá trình enrollment Activate
Active Đã enrolled đầy đủ, đang hoạt động bình thường Lock, Send Message, Release, Deregister
Locked Bị khóa bởi admin (khách trốn trả trả góp / mất / trộm) Unlock, Lock Message, Release, Deregister
Released Đã unenroll MDM — trigger khi khách hoàn thành hợp đồng trả góp (positive outcome). Data của khách giữ nguyên, máy trở thành 100% sở hữu khách (terminal — không có transition ra)

Bảng 2.7.3: DeviceFSM states trong Fluxion

2.7.3.2 Định Nghĩa Transitions (DB-Driven)

Transitions không hardcode trong code. Chúng được biểu diễn implicit qua quan hệ giữa 3 bảng DB:

Bảng Vai trò trong FSM
state Định nghĩa các trạng thái hợp lệ
action from_state_id = source state, apply_policy_id = destination (via policy)
policy state_id = state mà policy đại diện → destination state
action.from_state_id ──→ state (source)
action.apply_policy_id ──→ policy.state_id ──→ state (destination)
Action Source State Destination Policy → State
Upload NULL (initial) Idle → Idle
Register Idle Registered → Registered
Checkin Registered Enrolled → Enrolled
Activate Enrolled Active → Active
Lock Active Locked → Locked
Unlock Locked Active → Active
Send Message Active Active → Active (internal)
Lock Message Locked Locked → Locked (internal)
Release Active, Locked Released → Released
Deregister Active, Locked Idle → Idle

Lưu ý thiết kế:

  • Upload là initial action (from_state_id = NULL) — device được tạo với policy Idle
  • Release có 2 entries riêng cho Active và Locked (không dùng wildcard)
  • Deregister đưa device về Idle — cho phép re-enroll (khác với Release là terminal)
  • Send MessageLock Messageinternal transitionsapply_policy_id trỏ về cùng state
  • Xem chi tiết schema tại T5 — Thiết kế DeviceFSM mục 3.18

2.7.3.3 State Diagram

stateDiagram-v2
    [*] --> idle: device created

    idle --> registered: register_complete
    idle --> active: enroll_complete\n(fast-path DEP)

    registered --> enrolled: enroll_start
    registered --> active: enroll_complete\n(fast-path)

    enrolled --> active: enroll_complete

    active --> locked: lock\n[admin action]
    active --> released: release

    locked --> active: unlock
    locked --> released: release

    enrolled --> released: release
    registered --> released: release
    idle --> released: release

    released --> [*]

    note right of active
        Lệnh được phép:
        lock, notify, release
    end note

    note right of locked
        Lệnh được phép:
        unlock, release
    end note

    note right of released
        Terminal state
        Không có transition ra
    end note
Loading

Hình 2.5: DeviceFSM state diagram trong Fluxion

2.7.3.4 Guard Conditions

Guard conditions đảm bảo transitions chỉ xảy ra khi điều kiện thoả mãn:

Transition Guard Mô tả
enroll_complete device.mdm_certificate_valid == true Certificate hợp lệ trước khi active
lock device.state == 'active' Chỉ lock thiết bị đang active
unlock admin.has_permission('unlock_device') Chỉ admin có quyền mới unlock được
release device.pending_actions == 0 Không có lệnh đang chờ trước khi release
notify device.state == 'active' Internal transition — chỉ cho phép khi device đang active; không thay đổi state, không được phép khi locked

2.7.4 So Sánh Cách Triển Khai FSM

2.7.4.1 Custom Implementation vs Library

Custom FSM Library (transitions)
Kiểm soát Toàn quyền Phụ thuộc API của lib
Boilerplate Nhiều (if/else chains) Ít (declarative config)
Guard conditions Tự implement Built-in
Callbacks Tự implement Built-in (on_enter, on_exit)
Logging/audit Tự implement Có thể hook vào transitions
Visualize Không Có (graphviz export)
Phù hợp cho FSM đơn giản ≤3 states FSM phức tạp ≥5 states

Bảng 2.7.4: Custom FSM vs transitions library

2.7.4.2 Python transitions Library (Tham Khảo)

⚠️ Fluxion không sử dụng thư viện này. Mục này giữ lại như tham khảo học thuật. Implementation thực tế dùng DB-driven FSM — xem schema bên dưới.

transitions là thư viện FSM Python phổ biến, hỗ trợ:

  • Declarative state/transition definition
  • Callbacks: on_enter_<state>, on_exit_<state>, before_<trigger>, after_<trigger>
  • Guard conditions via conditions parameter
  • Hierarchical states (HierarchicalMachine)

Ưu điểm: Nhanh, ít boilerplate, visualize được. Nhược điểm: States hardcoded trong code — không linh hoạt khi cần quản lý qua UI hoặc đa tenant.

2.7.4.3 DB-driven FSM (Fluxion Implementation)

Fluxion lưu trữ toàn bộ FSM definition trong database — states và transitions là dữ liệu, không phải code:

Bảng Vai trò
services Loại dịch vụ (id smallint, name, is_enabled)
states Định nghĩa các trạng thái (id smallint, name)
policies Quy tắc áp dụng, gắn với state (id smallint, name, service_type_id, state_id, color)
actions Hành động kích hoạt transition (id uuid, name, action_type_id, from_state_id, service_type_id, apply_policy_id, configuration jsonb, ext_fields jsonb)
milestones Lịch sử thực thi — device history (id uuid, device_id, assigned_action_id, policy_id, ext_fields)

Lợi ích so với transitions library:

  • States/transitions có thể thay đổi mà không cần redeploy code
  • Hỗ trợ audit trail tự nhiên qua bảng milestone
  • action.configuration (JSONB) cho phép tham số hoá từng hành động

2.7.5 Tích Hợp Device State với action_executions

Device state (via current_policy_id) và action_executions FSM (command execution — mục 2.5.7) là hai FSM độc lập nhưng liên kết:

Admin gửi lệnh "Lock Device"
    → action_executions FSM: ACTION_PENDING → ACTION_SENT → ACTION_COMPLETED
    → (khi ACTION_COMPLETED) → Device: current_policy_id = action.apply_policy_id (locked)

Action Execution Flow (3-Layer):

  1. BE action-resolver: Validate assigned_action_id IS NULL + action.from_state_id == device.state_id
  2. BE action-trigger: INSERT action_executions (ACTION_PENDING), publish command → SNS
  3. OEM apns-sender: Cache command + send APNS silent push (wake device)
  4. OEM mdm-handler: Device polls → serve command from cache → device executes → device sends result → publish event → SNS
  5. BE checkin-handler: Nhận ACTION_COMPLETED event →
    • UPDATE devices SET current_policy_id = action.apply_policy_id, assigned_action_id = NULL
    • INSERT milestones
    • UPDATE action_executions SET status = ACTION_COMPLETED

Nguyên tắc: BE chỉ biết DB, OEM chỉ biết 3rd party. Xem chi tiết tại T5 — Command Pipeline


2.7.6 Tổng Hợp: Ánh Xạ Lý Thuyết — Thực Tiễn

Khái niệm lý thuyết Nguồn Biểu hiện trong Fluxion
FSM quintuple (Q, Σ, δ, q₀, F) [1] 6 states, 12 actions, δ = implicit via action → policy → state
Moore Machine [1] Device state (via current_policy_id) xác định actions được phép
Guard conditions Harel [5] action.from_state_id == device.state_id + busy check
Initial action Upload: from_state_id = NULL — tạo device với Idle policy
Terminal state [1] Released — không có transition ra
Non-terminal reset Deregister: Active/Locked → Idle — cho phép re-enroll
Two FSMs linked action_executions FSM (ACTION_COMPLETED) → update device.current_policy_id
DB-driven FSM Transitions implicit qua services + states + actions + policies tables
Multi-service services table cho phép phân loại actions theo service type (Inventory, Postpaid)

Bảng 2.7.5: Ánh xạ lý thuyết FSM — thực tiễn Fluxion


Kết Luận

Finite State Machine (FSM) cung cấp nền tảng toán học chặt chẽ để mô hình hoá vòng đời thiết bị trong hệ thống MDM. Định nghĩa hình thức qua bộ 5 thành phần M = (Q, Σ, δ, q₀, F) của Hopcroft et al. (2006) không chỉ là công cụ lý thuyết mà còn là bản thiết kế trực tiếp ánh xạ thành schema cơ sở dữ liệu trong Fluxion: tập trạng thái Q tương ứng bảng states, hàm chuyển đổi δ tương ứng bảng actions với from_state_id/to_state_id, và trạng thái đầu q₀ tương ứng policy Idle được gán khi thiết bị upload lần đầu.

Mô hình Harel Statechart (1987) mở rộng FSM phẳng với khả năng phân cấp (hierarchical states), song song hoá (concurrent regions), và lịch sử trạng thái (history states). Tuy nhiên, sau phân tích yêu cầu nghiệp vụ, Fluxion chọn FSM phẳng (flat FSM) với 6 trạng thái và 12 hành động. Quyết định này phản ánh nguyên tắc YAGNI (You Aren't Gonna Need It): vòng đời thiết bị MDM trong phạm vi đồ án không có nhu cầu về trạng thái lồng nhau hay song song — mọi yêu cầu nghiệp vụ đều có thể biểu diễn đầy đủ bằng FSM phẳng với guard conditions tại tầng cơ sở dữ liệu.

Đóng góp quan trọng nhất của module FSM trong Fluxion là cách triển khai dưới dạng DB-driven FSM: logic chuyển đổi không được hard-code trong ứng dụng mà được lưu trữ trong các bảng states, actions, policies, và services. Thiết kế này cho phép thay đổi cấu hình vòng đời thiết bị mà không cần deploy lại code, đồng thời tạo nền tảng cho kiểm tra tính nhất quán trạng thái (guard: action.from_state_id == device.state_id) tại runtime — một yêu cầu an toàn quan trọng trong hệ thống MDM quản lý thiết bị thực tế.


Tài Liệu Tham Khảo

[1] Hopcroft, J. E., Motwani, R., & Ullman, J. D. (2006). Introduction to Automata Theory, Languages, and Computation, 3rd ed. Pearson. https://www.pearson.com/en-us/subject-catalog/p/introduction-to-automata-theory-languages-and-computation/P200000003596

[5] Harel, D. (1987). Statecharts: A Visual Formalism for Complex Systems. Science of Computer Programming, 8(3), 231–274. Elsevier. https://www.sciencedirect.com/science/article/pii/0167642387900359

[6] pytransitions. (2024). transitions — A lightweight, object-oriented state machine library for Python. https://github.com/pytransitions/transitions

[7] Miro Samek. (2008). Practical UML Statecharts in C/C++: Event-Driven Programming for Embedded Systems, 2nd ed. Newnes. https://www.state-machine.com/qm/sm_intro.html


Các câu hỏi đã được giải đáp:

  1. Notify transition ✅ — notifyinternal transition: gửi push notification đến device mà không thay đổi state. Chỉ cho phép khi device.state == 'active'. Đã thêm vào guard conditions (mục 2.7.3.4).

  2. Concurrent states ✅ — Khi device locked, admin không được phép push notify. Guard condition device.state == 'active' loại bỏ hoàn toàn trường hợp này — thiết bị bị lock là thiết bị mất/trộm/vi phạm, không cần gửi notification.

  3. History states ✅ — releasedterminal state không thể quay lại. Trigger chính: khách hoàn thành hợp đồng trả góp → máy tự unenroll, trở thành sở hữu 100% của khách (graduation). Nếu sau này khách muốn mua máy trả góp tiếp, tạo device_id mới. Không cần track history state.

⚠️ **GitHub.com Fallback** ⚠️