1. 0x36 上报数据格式
-------------------------------------------------------------------
P0： 系统锁状态
  0x00：未锁定
  0x01：锁定
P1~P6： 保留
P7： 上报设备数量
P8~P13： 设备参数，描述一个设备参数固定为6Byte,具体格式如下：
  DevType：设备类型– 1Byte
  DevAddr：设备地址– 1Byte
  DevLoop：设备回路– 2Byte
  DevData：设备状态– 2Byte
P14： 上报设备故障数量
P15~P20： 上报设备故障数量
  DevType：设备类型– 1Byte
  DevAddr：设备地址– 1Byte
  DevLoop：设备回路– 2Byte
  ErrorType：故障类型– 1Byte
  ErrorData：故障内容– 1Byte
-------------------------------------------------------------------
上报设备的状态具体参数需要查看备数*6Byte，如果故障设备数为0，则没有设备故障参数。
故障参数解析：
故障类型   故障内容
  0x01      0:在线 1:离线
  0x02      0~100电量
  0x03      电流(10mA)
  0x04      1901故障检测次数
  0x05      设备回路故障具体设备，不同类型的设备上报状态的描述是不同的。
具体有多少设备状态需要上报，设备参数所占用的字节=设备数*6Byte
同样设备故障参数所占用的字节=设
2. 0x0F 下发数据格式
-------------------------------------------------------------------
P0：控制设备总数
P1 ~P495：设备控制参数，描述一个设备控制参数固定为6Byte，具体格式如下
   DevType：控制设备类型 - 1Byte
   DevAddr：控制设备地址 - 1Byte
   Loop：控制设备的回路地址 - 2Byte
   Type：控制设备的输出类型 - 2Byte
     Type_L：执行方式
     Type_H：执行内容
-------------------------------------------------------------------
该命令一般用于服务下发控制数据
3. 0x0F 上报数据格式
ACK (待补充)

4. 数据表结构

不可为空字段：
  日志产生时间（ts_ms）
  入库时间（write_ts_ms）
  酒店（index）
  房间（index）
  方向（上传/下发）（index）
  命令字（index）
  通讯帧号
  UDP消息原文
  记录行为类型（ACK、下发控制、主动控制、设备回路状态）（index），通过设备类型区分
可为空字段：
  系统锁状态
  本次上报数量
  DevType：设备类型– 1Byte
  DevAddr：设备地址– 1Byte
  DevLoop：设备回路– 2Byte
  DevData：设备状态– 2Byte
  本次故障数量
  DevType：设备类型– 1Byte
  DevAddr：设备地址– 1Byte
  DevLoop：设备回路– 2Byte
  ErrorType：故障类型– 1Byte
  ErrorData：故障内容– 1Byte
  
一条命令可能会有多条状态，每个状态生成一条记录，通过命令字和帧号来做串联。
即：一条UDP通讯可能对照多条数据库记录


5. 队列结构
  队列分区数：6
  Topic：blwlog4Nodejs-rcu-action-topic


6. 入库前特殊操作
 - 定期从temporary_project表中读取数据并保存到`内存`中（以全局变量的形式），每天凌晨1点从数据库更新一次。
 - 每条数据写库之前，需要根据项目ID从内存中读取项目信息。
 - 我需要在现有数据表`rcu_action_events`里，添加一个字段：`loop_name`，用于存储回路名称。
 - 查询`loop_name`的方法是：
  - 根据要插入的数据中的`device_id`在`rooms`表中找出对应的房间 -> 得到 `room_type_id`。
  - 根据 `room_type_id` 和 `loop_address` 在 `loops` 表中查找对应的 `loop_name`。
  - `loop_address` 的生成规则：将数据的 `dev_type`、`dev_addr`、`dev_loop` 分别转换为 3 位字符串（不足前方补 0），然后拼接。
    - 例如：`dev_type=1, dev_addr=23, dev_loop=12` -> `001` + `023` + `012` -> `001023012`。
  - **兜底逻辑**：如果根据上述规则在 `loops` 缓存中未找到对应的 `loop_name`，则使用 `dev_type` 对应的设备名称（配置在 `ACTION_TYPE_DEV_TYPE_RULES` 中）默认名称。
    - 格式：`[dev_type名称+'-'+dev_addr+'-'+dev_loop]`
    - 例如：`dev_type=35` (名称: TimeCtrl), `addr=14`, `loop=21` -> `[35TimeCtrl-14-21]`
  - 最后将找到的或生成的 `loop_name` 写入 `rcu_action_events` 表。
    - 注意，所有查库操作都要通过内存缓存来实现。


