# websocket通讯格式逻辑说明

## 消息体以下格式
    1. 主机发送的请求 (0x01)
    2. 服务端对主机请求的响应 (0x02)

    3. 服务端对主机的消息推送 (0x03)
    4. 主机对服务器推送消息的响应 (0x04)

    5. 服务器端对主机推送的指令 (0x05)
    5. 主机对服务器推送的指令的响应 (0x06)

## 消息体的格式说明
    <<消息体类型/1byte, PacketId/4byte, Packet/任意长度>> 

## 特殊说明
   * 服务器端处理异常时，直接关闭websocket连接

## 消息类型说明

### register消息 

#### 请求
   <<0x01, PacketId:4, Method:1, Body:任意长度>> 

   PacketId: 4字节整数, 值必须大于0; 
   Method: 0x00
   Body: {uuid: string, salt: string, username: string, token: string}, json序列化后的二级制数据，明文

### 响应
   <<0x02, PacketId:4, Reply>>
   Reply: {code: 1, message: "ok"}

### create_session消息

#### 请求
<<0x01, PacketId:4, 0x01, PubKey:任意长度(公钥信息)>>

PacketId: 4字节整数, 值必须大于0;

#### 响应
<<0x02, PacketId:4, Reply>>
Reply: {a: bool, aes: "服务器生成的aes的值"}

### data数据上传(无响应)
<<0x01, PacketId:4, 0x02, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 
```text
   {
       "service_name": "从该设备端的哪个服务采集的数据",
       // 如果为空，就表明是微服务产生的数据，如果有值，表示是设备产生的数据
       "device_id": $uuid 非设备产生的device_id为空
       "at": int, 精确到毫秒
       // 该微服务采集的数据，是一个包含map的列表类型，map的内容可以由微服务自己指定
       // 目前一般的格式是"metric-name": $value样式的数据
       "fields": [
           {
               "key": "test"
               "value": 124,
               "unit": "U",
               "type": "AI：遥测值，DI：遥信值，SOE：事件",
               "timestamp": int
           }
       ],
       // 微服务自身可以生成tag，用于微服务指定自己的一些性质，目前使用得不多，以后可以扩展，
       // 是一个map[string]string类型的数据
       "tags": {
           "tag1": "value1",
           "tag2", "value2"
       }
       // todo 在insert数据到influxdb的时候需要增加service_name + host_uuid
   }

```

### ping数据上传(无响应)
<<0x01, PacketId:4, 0x03, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 
```text
   {
      // 硬件信息，目前有剩余内存，剩余磁盘和cpu负载
      // 剩余内存，单位为mb

      "memory": {
         "total": 1024, // 内存数，mb
         "used": "$int" // 剩余内存数
      },
      "disk": {
         "total": 1024, //  硬盘容量GB
         "used": "$int" // 剩余硬盘内容GB
      },

      "cpu_load":  $float, // 浮点数
      "cpu_temperature": $float // 稳定信息
      "cpu_core": $int,

      "boot_time": 2000, // 启动时间
      "efka_version": "1.0.0", // 客户端版本
      "kernel_arch": "arm64", // 客户端硬件架构
      "province": "", // 所在省
      "city": "", // 所在市
      "adcode": 100, // 所在城市的编号
      "ips": [
         "ip地址1",
         "ip地址2"
      ],
      // 接口信息
      "interfaces": [
         {
            "status": 0|1, "接口状态，0离线，1在线"
            "name": "接口名称",
            "desc": "接口描述",
         }
      ]
   }
```

### inform数据上传(无响应)
<<0x01, PacketId:4, 0x04, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 
```text
   {
     "at": $int64,
     // 微服务信息
     "services": [{
       "scene_id": $int "场景的编号",
       "name": "微服务名称",
       "version": "微服务版本",
       "version_copy": "微服务副本",
       // 微服务是否在线，0表示离线，1表示在线
       "status": 0|1
     }]
   }
```

### feedback_step数据上传(无响应)
<<0x01, PacketId:4, 0x05, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 
```text
       {
     "task_id": "任务的task id",
     // sc为step code，具体地：
     //  0代表该任务开始了，服务端创建该任务之后，是这个代码
     //  1代表任务被分发了，服务端向nats(mqtt)发送消息之后，是这个代码
     //  2代表任务被设备端接收到了
     //  3代表该任务已经被发送给微服务进行处理了
     //  4代表该任务已经被微服务收到了，微服务正在处理
     //  5代表任务已经完成，微服务已经处理完成。
     "code": $int
   }
```

### feedback_result数据上传(无响应)
<<0x01, PacketId:4, 0x06, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 

```text
   {
     "task_id": "任务id",
     // unix nano类型
     "time": $int,
     // 返回的结果码，0代表成功，其他代表出错
     "code": $int,
     "reason": "任务执行的结果",
     "error": "错误消息，当c为非0时，这个字段会表示出错消息",
     // 返回任务类型，1表示任务是微服务下发，0代表是命令下发
     "type": 0 | 1,
   } 
```

### 主机上传终端设备的相关事件
<<0x01, PacketId:4, 0x07, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 事件内容，AES加密

```text

设备的离在线状态

{
   "event_type": 1,
   "params": {
      "device_uuid": "",
      "status": 0 // 1在线， 0离线
   }
}

```

## 主机上传AI事件

<<0x01, PacketId:4, 0x08, Body:任意长度>>

PacketId: 4字节整数, 值为0;
Body: 事件内容，AES加密

```text

设备的离在线状态

{
   "event_type": 1, // 事件类型
   "params": {
      "device_uuid": "",
      "description": "垃圾溢满", 
      "datetime": "2023-06-10 12:00:00",
      "event_code": "事件编码，采集项下发的事件编码: 5位事件编码",  //1. 异物占道（异物识别） 20405 2.垃圾溢满 20453
      "attachments": [
          {
            "name": "垃圾溢满",
            "filename": "2023-12-10-xyz.hdc"
          },
          {
            "name": "垃圾溢满",
            "filename": "2023-12-10-xyz.hdc"
          }
      ]
   }
}

```

## 指令说明

### 指令返回格式说明(按照json_rpc 2.0的规范)

```text
   成功: {"result": map | array | string | any}
   
   失败: {"error": {code: int, message: "错误描述"}}
```

### 服务器对主机推送的指令格式

<<0x05, PacketId:4, Body:任意长度>>

PacketId: 4字节整数; 如果值为0，则不需要返回指令执行结果
Body: 事件内容，AES加密

#### 计费电表, 下发指令

```text
{
   "device_uuid": "xxxxxx", // 设备的device_uuid, 数组格式
   "version": "1.0",
   "directive_type": 0x01,    // 中电计费电表控制
   "timeout": 10,       // 指令执行超时时间
   "directive": {
      "type": "ctrl", // 遥控 
      "stype": int,   // 遥控类型，0: 遥控, 1: 遥调, 2: 置数
      "ctype": int,   // 遥控动作， 0: 打开，1: 闭合
      "value": double, // 控制参数
      "timestamp": 17031000000 // 发命令时间
   }
}

