3. GEM 标准状态定义:DISABLED、INIT、COMM、WAITCINIT、ENABLED 详解
GEM 标准状态机是设备通信链路管理的核心模型,定义了设备从离线到完全在线、再到异常恢复的完整生命周期。理解这五个标准状态(DISABLED、INIT、COMM、WAITCINIT、ENABLED)是掌握链路重连与异常恢复的基础。
核心概念: GEM 状态机并非物理连接状态,而是逻辑通信能力的状态。即使 TCP/IP 连接存在,若状态机处于 DISABLED,设备也无法处理 GEM 消息。
3.1 状态总览与转换关系
下表列出了五个标准状态的定义、关键特征及典型触发条件:
| 状态名称 | 缩写 | 定义 | 关键特征 | 典型进入条件 |
|---|---|---|---|---|
| DISABLED | DS | 设备通信功能完全禁用 | 不响应任何 GEM 消息;可接受本地操作 | 上电初始、操作员禁用、严重故障 |
| INIT | IN | 设备正在初始化通信参数 | 建立内部资源;不对外通信 | 从 DISABLED 收到启用命令 |
| COMM | CM | 等待与主机建立通信 | 监听连接;可发送 S1F13 请求 | INIT 完成;连接断开后自动进入 |
| WAITCINIT | WC | 等待主机完成初始化 | 已连接;等待 S1F14 或 S1F15 | 收到 S1F13 后等待主机响应 |
| ENABLED | EN | 设备完全在线,可正常通信 | 处理所有 GEM 消息;采集数据 | 主机发送 S1F14 确认 |
关键记忆点: 状态转换是单向递增的(DS → IN → CM → WC → EN),但异常发生时,ENABLED 可直接回退到 COMM 或 DISABLED。
3.2 各状态详细说明
3.2.1 DISABLED(禁用状态)
DISABLED 是设备的初始状态和安全兜底状态。在此状态下,设备不参与任何 SECS/GEM 通信,所有 GEM 消息(包括 S1F13 建立连接请求)均被忽略。设备仅接受本地操作(如操作员面板、本地脚本)。
- 典型场景: 设备上电后、操作员按下“禁用通信”按钮、检测到不可恢复的协议错误。
- 退出条件: 收到本地启用命令(通常由设备应用层触发)。
- 异常恢复意义: 当链路反复重连失败时,设备应回到 DISABLED 状态,等待人工干预,避免无限重连。
3.2.2 INIT(初始化状态)
INIT 是一个瞬态状态,设备在此状态中完成通信所需的内部资源准备。例如:分配消息缓冲区、初始化定时器、加载通信配置参数(如连接超时时间 T3、重试次数)。
- 持续时间: 通常为毫秒级,完成后自动进入 COMM 状态。
- 异常处理: 若初始化失败(如内存不足),设备应返回 DISABLED 并报告错误。
3.2.3 COMM(等待连接状态)
COMM 是设备主动等待与主机建立 TCP/IP 连接的状态。设备在此状态下:
- 持续监听或尝试连接主机的 SECS/GEM 端口。
- 可主动发送 S1F13(Establish Communication Request)消息。
- 不处理除连接建立相关的任何其他 GEM 消息。
COMM 状态是链路重连的核心状态。当 ENABLED 状态下连接意外断开时,设备自动回到 COMM 状态,开始重连流程。
3.2.4 WAITCINIT(等待主机初始化状态)
当设备发送 S1F13 并收到主机的 TCP 确认后,进入 WAITCINIT 状态。此时:
- 设备已建立 TCP 连接,但尚未完成 GEM 通信握手。
- 设备等待主机发送 S1F14(Establish Communication Confirm)或 S1F15(Establish Communication Request,主机发起)。
- 若超时未收到响应,设备应断开连接并返回 COMM 状态。
常见陷阱: 许多实现错误地将 WAITCINIT 视为“已连接”状态,开始发送数据消息。这会导致协议违规,主机可能拒绝通信。
3.2.5 ENABLED(启用状态)
ENABLED 是设备的正常在线工作状态。在此状态下:
- 设备可以发送和接收所有 GEM 消息(S1、S2、S6 等流)。
- 数据采集、报警管理、远程控制等功能全部可用。
- 设备持续监控连接健康状态(如心跳检测)。
ENABLED 状态的退出通常由异常触发:
- 连接断开: 回到 COMM 状态,自动重连。
- 严重错误: 回到 DISABLED 状态,停止通信。
3.3 状态转换流程图
下图展示了 GEM 标准状态机的完整转换路径,包括正常流程和异常回退路径:
3.4 状态与链路重连的关系
在设备通信链路重连场景中,状态机的行为如下:
| 重连阶段 | 状态 | 设备行为 | 超时/失败处理 |
|---|---|---|---|
| 1. 检测断开 | EN → CM | 立即停止数据发送,进入等待连接 | 若重连次数超限,进入 DS |
| 2. 尝试连接 | COMM | 按配置间隔发送 S1F13 | 超时后重试,最多 N 次 |
| 3. 连接建立 | COMM → WC | 等待主机 S1F14 确认 | 超时后断开,回到 COMM |
| 4. 握手完成 | WC → EN | 恢复数据采集和消息处理 | — |
实现建议: 在 COMM 状态中,建议使用指数退避策略(如 1s、2s、4s、8s…)发送 S1F13,避免因频繁重连导致网络拥塞。最大重连间隔建议不超过 60 秒。
3.5 状态机实现示例(伪代码)
以下伪代码展示了状态机核心逻辑,重点关注状态转换和重连处理:
// GEM 状态机主循环
while (true) {
switch (currentState) {
case DISABLED:
if (localEnableReceived) {
currentState = INIT;
initializeCommunicationResources();
}
break;
case INIT:
if (initSuccess) {
currentState = COMM;
startConnectionTimer();
} else {
currentState = DISABLED;
reportError("INIT_FAILED");
}
break;
case COMM:
if (tcpConnectionEstablished) {
sendS1F13();
currentState = WAITCINIT;
startWaitTimer(T3_TIMEOUT);
} else if (connectionTimeout) {
retryCount++;
if (retryCount > MAX_RETRY) {
currentState = DISABLED;
reportError("MAX_RETRY_EXCEEDED");
} else {
applyBackoffDelay();
retryConnection();
}
}
break;
case WAITCINIT:
if (receivedS1F14) {
currentState = ENABLED;
resetRetryCount();
enableDataCollection();
} else if (waitTimerExpired) {
disconnectTcp();
currentState = COMM;
}
break;
case ENABLED:
if (tcpDisconnected) {
currentState = COMM;
startReconnectProcedure();
} else if (fatalError) {
currentState = DISABLED;
stopAllCommunication();
}
// 正常消息处理...
break;
}
}
关键实现细节: 在 ENABLED 状态下,必须实现心跳机制(通常使用 S1F1/S1F2 或 S9F1 链路测试)。若连续多次心跳无响应,应主动断开连接并进入 COMM 状态,而不是被动等待 TCP 超时(可能长达数分钟)。
3.6 状态机与异常恢复策略
理解状态机后,可以制定更精确的异常恢复策略:
- 快速恢复: 从 ENABLED 到 COMM 的回退应尽可能快(< 100ms),减少数据丢失窗口。
- 状态持久化: 在进入 DISABLED 前,应保存当前状态和未完成的事务,以便恢复后继续处理。
- 日志记录: 每次状态转换都应记录时间戳、原因和上下文,便于事后分析。
- 人工干预接口: DISABLED 状态应提供明确的本地操作接口,允许操作员手动恢复或诊断。