#pragma once #include #include #include #include "MQTTAsync.h" using namespace std; class MqttClient { public: int init(string addr, string client_id, string username, string password, std::vector vecTopic); void subscribe(std::vector topics, std::function callback); int publish(string topic, string text); void onConnectionLost(char* cause); int onMessageArrived(char* topic, int len, MQTTAsync_message* msg); void onDeliveryComplete(MQTTAsync_token token); void onConnectSuccess(MQTTAsync_successData* resp); void onConnectFaiure(MQTTAsync_failureData* resp); public: MQTTAsync client = nullptr; std::vector vecTopic; std::string addr; // "tcp://localhost:1883" int qos {1}; std::string clientId; bool isConnected {false}; bool isSubscribed {false}; }; // <数据方向>/<数据格式>/<厂家ID>/<指令>/<设备标识,上行可选> // Topic 字段说明 // 数据方向 : //·down:下行,用于管理平台向厂家平台发送指令 // up :上行,用于厂家平台向管理平台推送设备应答或主报数据数据格式:基础格式为json,其他格式均为对json字符串进行二次编码 // json : body内的数据采用json编码 // base64 : body内数据先采用ison编码,然后再使用base64编码的字符串 // rsa : body内数据先采用json编码,然后采用 rsa 算法加密的base64字符串(rsa 密钥由管理平台提供) // sm2 : body内数据先采用json编码,然后采用 sm2 算法加密的base64字符串(sm2 密钥由管理平台提供) //·厂家ID : 由管理平台定义 //·命令ID : 用于指定读取/设置/控制的具体内容,如读取数据,读取时钟等等,具体参考 交互类指令协议设备标识 : 用于标识设备的唯一id,具体定义见3.2中的 context.dev_id 说明,上行时可不提供。 // <数据方向>/<数据格式>/<厂家ID>/<指令>/<设备标识,上行可选> #define TOPIC_PCS_YC "up/json/预制舱01/PCS_YC" #define TOPIC_PCS_YC "up/json/预制舱01/PCS_YC" #define MQTT_TOPIC_NOTIFY_STATION "notification_stationInfo" // 充(换)电站信息变化推送 #define MQTT_TOPIC_QUERY_STATION "query_stations_info" // 查询充(换)电站信息 #define MQTT_TOPIC_NOTIFY_ALARM "notification_alarmInfo" // 告警信息推送 #define MQTT_TOPIC_NOTIFY_CHARGE_STATUS "notification_connectorStatus" //充电设备状态变化推送 #define MQTT_TOPIC_NOTIFY_SWAP_STATUS "notification_swapStatus" //换电设备状态变化推送 #define MQTT_TOPIC_QUERY_STATUS "query_station_status" //查询站内设备接口状态 #define MQTT_TOPIC_NOTIFY_CHARGE_ORDER "notification_orderInfo" //充电电量信息推送 #define MQTT_TOPIC_QUERY_ORDER "query_order_info" //查询充电电量信息 #define MQTT_TOPIC_NOTIFY_SWAP_ORDER "notification_swapInfo" //换电记录信息推送 #define MQTT_TOPIC_QUERY_SWAP_ORDER "query_swap_info" //查询换电电量信息 namespace mqtt { // 充(换)电运营商信息 struct OperatorInfo { string OperatorID; // 运营商ID 组织机构代码 是 字符串 9 字符 string OperatorName; // 运营商名称 机构全称 是 字符串 <= 64 字符 string OperatorTel1; // 运营商电话1 运营商客服电话 1 是 字符串 <= 32 字符 string OperatorTel2; // 运营商电话2 运营商客服电话 2 否 字符串 <= 32 字符 string OperatorRegAddress; // 运营商注册地址 运营商注册地址 否 字符串 <= 64 字符 string OperatorNote; // 备注 备注信息 否 字符串 <= 255 字符 }; // 充(换)电站信息 struct StationInfo { string StationID; // 充(换)电站 ID 运营商自定义的唯一编码 是 字符串 <= 20 字 符 string OperatorID; // 运营商 ID 电动汽车充(换)电服务平台的运营商 ID 是 字符串 9 字符 string EquipmentOwnerID; // 设备所属方 ID 设备所属方组织机构代码,所属方为个人时可不填 否 字符串 9 字符 string StationName; // 充(换)电站名称 充(换)电站名称的描述 是 字符串 <= 50 字 string CountryCode; // 充(换)电站国家代码 比如 CN 是 字符串 2 字符 string AreaCode; // 充(换)电站省市辖区编码 填写内容为参照 GB / T2260,以民政部发布最新数据为准 是 字符串 <= 20 字符 string Address; // 详细地址 是 字符串<= 100字符 string StationTel; // 站点电话 能够联系场站工作人员进行协助的联系电话 否 字符串<= 30 字符 string ServiceTel; // 服务电话 平台服务电话,例如 400 电话 是 字符串<= 30字符 string ServiceType; // *服务类型 1:充电 2:换电 3:充换电 255:其他 是 整型 string StationType; // 站点类型 1:公共充(换)电站 2:专用充(换)电站 3:居民充电站 255:其他 是 整型 string StationStatus; // 站点状态 0:未知 1:建设中 5:关闭下线 6:维护中 50:正常使用 是 整型 string ParkNums; // 车位数量 可停放进行充电的车位总数, 默认:0 未知 是 整型 float StationLng; // 经度 GCJ - 02 坐标系 是 浮点型 保留小数点后6 位 float StationLat; // 纬度 GCJ - 02 坐标系 是 浮点型保留小数点后6 位 string SiteGuide; // 站点引导描述性文字,用于引导车主找到充电车位 否 字符串<= 255字符 int Construction; // 建设场所 //101:公共服务场所 //102:公共停车场 //103:城市交通节点 //104:加油站 //105:具备停车条件的充电区域 //106:高速服务区 //201:政府机关 //202:公共机构 //203:企业事业单位 //204:公交 //205:环卫 //206:物流 //207:出租车 //208:港口码头 //209:重卡换电场所 //210:矿卡换电场所 //301:居民(小)区 //255:其他 // 是 整型 string Pictures; // 站点照片 充(换)电设备照片、充(换)电车位照片、停车场入口照片 是 字符串数组 无照片时可传空数组 string MatchCars; // 服务车型描述 描述该站点可充(换)电服务 的车辆类型:如大巴、物流车、私家乘用车、出租车、重卡型卡车等 否 字符串<= 255字符 string ParkInfo; // 车位楼层及数量描述车位楼层以及数量信息 否 字符串<= 100字符 int OpenAllDay; // *全天开放 0:否 1:是 是 整型 string OpenForBusinessDate; // *投运日期 站点投运日期 yyyy - MM - dd 格式 是 字符串 string BusineHours; // 营业时间 营业时间描述 否 字符串<=255字符 string ElectricityFee; // *电费费率 示例 [{"StartTime":"000000","Price":"1.0000"},{"StartTime":"120000","Price":"1.2000"}] 否 字符串 <= 2000 字符 string ServiceFee; // *服务费率 示例[{"StartTime":"000000","Price":"1.0000"},{"StartTime":"120000","Price":"1.2000"}] 否 字符串 <= 2000 字符 string ParkOwner; // *停车场产权方 停车场产权人 否 字符串 string ParkManager; // *停车场管理方 停车场管理人(如:XX 物业) 否 字符串 int ParkType; // 停车费类型 0:免费 1:不免费 2:限时免费停车 3:充电限时减免 255:参考场地实际收费标准 否 整型 string ParkFee; // 停车费描述 停车费率描述 否 字符串 <= 255字符 string Payment; // 支付方式 支付方式: 刷卡、线上、现金其中电子钱包类卡为刷卡,身份鉴权卡、微信 / 支付宝等在线支付、APP 支付为线上否 字符串<= 20 字符 int SupportOrder; // 是否支持预约 0:不支持预约 1:支持预约。不填默认为 0 否 整型 string Remark; // 备注 其他备注信息 否 字符串<= 100字符 string EquipmentInfos; // 充电设备信息列表 该充(换)电站所有充电设备 信息对象数组 是 EquipmentInfos[],参照 4.4 string SwapEquipmentInfos; // *换电设备信息列表 该充(换)电站所有换电设备。换电站以及充换电站提供此数据,充电站默认空数组。 是 SwapEquipmentInfo[],参照 4.6 换电工位信息 int BatteryNo; // *备用电池数量换电站内可提供更换最大电池数量。换电站以及充换电站提供此数据,充电站默认填0。 是 整型 }; // 充电设备信息 struct EquipmentInfo { string EquipmentID; string ManufacturerID; string EquipmentModel; string ProductionDate; string OpenForBusinessDate; int EquipmentType; int EquipmentStatus; vector ConnectorInfos; float EquipmentLng; float EquipmentLat; float Power; string EquipmentName; }; // 充电设备接口信息 struct ConnectorInfo { string ConnectorID; // 充电设备接口编码 充电设备接口编码,同一运营商内唯一 是 字符串 <= 64 字符 string ConnectorName; // 充电设备接口名称 否 字符串 <= 30 字符 int ConnectorType; // 充电设备接口类型 //1:家用插座(模式 2) //2:交流接口插座(模式 3,连接方式 B ) //3:交流接口插头(带枪线,模式 3,连接方式 C) //4:直流接口枪头(带枪线,模式 4) //5:无线充电座 //6:其他 //7:对换电站电池箱的接口 //是 整型 int VoltageUpperLimits; // 额定电压上限 单位:V 是 整型 int VoltageLowerLimits; // 额定电压下限 单位:V 交流可与额定电压上限相同 是 整型 int ConstantVoltageUpperLimits; // *恒功率电压上限 单位:V 否 整型 int ConstantVoltageLowerLimits; // *恒功率电压下限 单位:V 否 整型 int Current; // 额定电流 单位:A 是 整型 float Power; // 额定功率 单位:kW 是 浮点型 保留小数点后一位 string ParkNo; // 车位号 停车场车位编号,或充电架编号 否 字符串 <= 10 字符 int NationalStandard; // 国家标准 1:2011 2 : 2015 3 : 兼容 2011 和 2015 是 整型 }; // 换电设备信息(SwapEquipmentInfo) class SwapEquipmentInfo { string EquipmentID; // 设备编码 换电设备唯一编码,同一运营商下唯一 是 字符串 <= 64 字符 string ManufacturerID; // 设备生产商组织机构代码 设备生产商组织机构代码 否 字符串 9 字符 string EquipmentModel; // 设备型号 由设备生厂商定义的设备型号 否 字符串 <= 20 字符 string ProductionDate; // 设备生产日期 YYYY - MM - DD 否 字符串 10 字符 string OpenForBusinessDate; // *投运日期 充电桩投运日期 yyyy - MM - dd 格式 是 字符串 string OpreateStatus; // 运营状态 0:未知 1:建设中 5:关闭下线 6:维护中 50:正常使用 是 整型 int EquipmentType; // 换电设备类型 填写内容为参照GB29317 - 2021 4.3节中的描述 1:侧向换电 2:底部换电 3:顶部换电 4:端部换电 5:中置换电 255:其他 是 整型 string MatchCars; // 服务车型描述 描述该设备可服务的车辆类型以及 型号等 否 字符串<= 1000 字符 string SupplyBattery; // 提供电池描述 描述该设备提供的电池类型以及型号等 否 字符串<= 100 字符 }; //电池箱信息 struct BatteryInfo { string BatteryNo; // 电池箱编号 运营商自定义唯一编码 是 字符串 <= 32 字 string BatteryOwnerID; // 电池所属方ID 设备所属方组织机构代码,所属方为个人时可不填 否 字符串 9 字符 string ManufacturerID; // 设备生产商组织机构代码 设备生产商组织机构代码 否 字符串 9 字符 string BatteryModel; // 电池型号 由设备生厂商定义的设备型号 否 字符串 <= 20 字符 string ProductionDate; // 设备生产日期 YYYY - MM - DD 否 字符串 10 字符 string OpenForBusinessDate; // 投运日期 电池投运日期 yyyy - MM - dd 格式 是 字符串 int CellNum; // 电池箱所含单体电池个数 电池箱所含单体个数 是 整型 int SeriesNum; // 单体电池串联总数 串联总数 否 整型 int ParallelNum; // 单体电池并联总数 并联总数 否 整型 int BatteryType; // 电池类型 //1:磷酸铁锂电池 //2:锰酸锂电池 //3:钴酸锂电池 //4:三元材料电池 //5:聚合物锂离子电池 //6:钛酸锂电池 //7:燃料电池 //255:其它 //是 整型 float RatedCapacity; // 电池箱额定容量 单位:Ah,小数点后 1 位 是 浮点型 float RatedVoltage; // 电池箱额定电压 单位:V,小数点后 1 位 是 浮点型 }; // 充电设备接口状态 struct ConnectorStatusInfo { string ConnectorID; // 充电设备接口编码 充电设备接口编码,同一运营商内唯一 是 字符串<= 64 字符 string UpdateTime; // 状态更新时间 本次状态变化的时间,格式“yyyy -MM - dd HH : mm:ss” 是 字符串 <= 20 字符 int Status; // 接口状态 0:离线 1:空闲 2:占用(未充电) 3:占用(充电中) 4:占用(预约锁定) 255:故障 是 整型 int ParkStatus; // 车位状态 0:未知 10:空闲 50:占用 否 整型 int LockStatus; // 地锁状态 0:未知 10:已解锁 50:已上锁 否 整型 int CurrentA; // A 相电流 单位:A,默认:0 含直流(输出) 是 整型 int CurrentB; // B 相电流 单位:A,默认:0 否 整型 int CurrentC; // C 相电流 单位:A,默认:0 否 整型 int VoltageA; // A 相电压 单位:V,默认:0 含直流(输出) 是 整型 int VoltageB; // B 相电压 单位:V,默认:0 否 整型 int VoltageC; // C 相电压 单位:V,默认:0 否 整型 float SOC; // *剩余电量 默认:0 交流充电桩采集不到SOC 值的填 0 是 浮点型 string Begin_time; // *开始充电时间 格式 为 yyyy-MM-dd HH:mm:ss 是 字符串 float Current_kwh; // *本次已充电量 单位:kWh 是 浮点型 float Current_meter; // *当前电表读数 单位:kWh 否 浮点型 string Vin; // *车架号 否 字符串 <= 20 字符 //BatteryStatusInfo //*电池状态信息 充电设备有电池情况下需上报 是 BatteryStatusInfo,参照4.9 }; // 电池箱状态 struct BatteryStatusInfo { string BatteryNo; // 电池箱编号 (充电设备有电池情况下需上报) 是 字符串<= 32 字符 string UpdateTime; // 状态更新时间 本次状态变化的时间,格式“yyyy -MM - dd HH : mm:ss” 是 字符串 <= 20 字符 float Voltage; // 当前电压 单位:V,小数点后 2 位 (充电设备有电池情况下需上报) 是 浮点型 float Current; // 当前电流 单位:V,小数点后 2 位 (充电设备有电池情况下需上报) 是 浮点型 float SOC; // 当前 Soc 当前电池电量百分比,范围:0~100,小数点后 1 位 (充电设备有电池情况下需上报) 是 浮点型 float SOH; // 当前 Soh 当前电池健康度,范围:0~100,小数点后 1 位(充电设备有电池情况下需上报)是 浮点型 int BatteryIsFault; // 电池箱是否故障 0:未知 1:是 2:否 (充电设备有电池情况下需上报) 是 整型 int MaxVoltageBatteryNo; // 最高电压单体电池编号 充电设备有电池情况下需上报 否 整型 float MaxVoltage; // 最高电压单体电池电压值单位: V,小数点后3位 充电设备有电池情况下需上报 否 浮点型 int MinVoltageBatteryNo; // 最低电压单体电池编号 充电设备有电池情况下需上报 否 整型 float MinVoltage; // 最低电压单体电池电压值 单位: V,小数点后 3 位 充电设备有电池情况下需上报 否 浮点型 float MaxTempBatteryNo; // 最高温度测温点编号 充电设备有电池情况下需上报 否 整型 int MaxTemp; // 最高温度测温点温度值 单位:℃ 充电设备有电池情况下需上报 否 整型 int MinTempBatteryNo; // 最低温度测温点编号 充电设备有电池情况下需上报 否 整型 int MinTemp; // 最低温度测温点温度值 单位:℃ 充电设备有电池情况下需上报 否 整型 }; // 换电设备状态(SwapEquipmentStatusInfo) struct SwapEquipmentStatusInfo { string EquipmentID; // 换电设备编码 换电设备编码,同一运营商内唯一 是 字符串 <= 64 字符 string UpdateTime; // 状态更新时间 本次状态变化的时间,格式“yyyy - MM - dd HH : mm:ss” 是 字符串 <= 20 字符 int Status; // 换电设备状态 0:离线 1:空闲 2:工作 255:故障 是 整型 int SwapMode; // 换电模式 0:手动模式 1:半自动模式 2:全自动模式 3:检修模式 否 整型 }; // 充(换)电站状态(StationStatusInfo) struct StationStatusInfo { string StationID; // 充(换)电站 ID 运营商自定义的唯一编码 是 字符串 <= 20 字符 string ConnectorStatusInfos; // 充电设备接口状态列表 充(换)电站下所有充电设备接口的状态对象数组 是 ConnectorStatusInfos[], 参照 5.6 string SwapEquipmentStatusInfo; // 换电设备状态列 所有充电设备接口的是 SwapEquipmentStatusInfo[]表 状态 ,参照4.10 }; //充电电量信息(OrderInfo) struct OrderInfo { string OperatorID; // 运营商 ID 统一社会信用代码 是 字符串 9 字符 string ConnectorID; // 充电设备接口编码 充电设备接口编码,同一充(换)电运营平台内唯一 是 字符串 <= 26 字符 string StartChargeSeq; // 充电业务编号 运营商充电业务编号 是 字符串 <= 32 字符 int UserChargeType; // 用户发起充电类型 1:充(换)电运营平台注册用户 2 : 监管平台注册用户 3 : 其他 否 整型 string MobileNumber; // 用户手机号 若用户发起充电类型为APP,用户手机号必填否 字符串 float Money; // 本次充电消费总金额 单位:元 若通过苏e充APP启动,此字段为必填项。 否 浮点型 float ElectMoney; // 本次充电电费总金额 单位:元 若通过苏e充APP启动,此字段为必填项。 否 浮点型 float ServiceMoney; // 本次充电服务费金额 单位:元 若通过苏e充APP启动,此字段为必填项。 否 浮点型 float Elect; // 本次充电电量 单位 kWh,精度0.001,如果不设置峰谷电价,平电量等于本次充电电量,其他分电量为零。 是 浮点型 float CuspElect; // *尖阶段电量 单位 kWh,精度0.001 是 浮点型 float PeakElect; // *峰阶段电量 单位 kWh,精度0.001 是 浮点型 float FlatElect; // *平阶段电量 单位 kWh,精度0.001, 是 浮点型 float ValleyElect; // *谷阶段电量 单位 kWh,精度0.001 是 浮点型 float StartTime; // 本次充电开始时间 格式“yyyy - MM - ddHH : mm:ss” 是 字符串 float EndTime; // 本次充电结束时间 格式“yyyy - MM - ddHH : mm: ss” 是 字符串 float PaymentAmount; // 支付金额 支付金额 若通过苏e充APP启动,此字段为必填项。 否 浮点型 保留小数点后 2 位 float MeterValueStart; // *电表总起值 单位 kWh,精度0.001 是 浮点型 保留小数点后三位 float MeterValueEnd; // *电表总止值 单位 kWh,精度0.001 是 浮点型 保留小数点后三位 float Vin; // *本次充电车架号 充电设备有车辆VIN码需上报 否 字符串 <= 64 字符 float BatteryNo; // *本次充电电池编号 充电设备有电池情况下需上报 否 字符串 <= 64 字符 float ExchangeChargeSeq;// *换电记录编号 格式“运营商 ID + 唯一编号”,27 字符,如果有对应的换电记录需要填写是 字符串 <= 40 字符 }; // 换电记录信息(SwapInfo) struct SwapInfo { string OperatorID; //运营商 ID 统一社会信用代码 是 字符串 9 字符 string EquipmentID; // 换电设备编码 换电设备接口编码,同一充(换)电运营平台内唯一 是 字符串 <= 40 字符 string ExchangeChargeSeq; // 换电记录编号 格式“运营商 ID + 唯一编号”,27 字 符 是 字符串 string SwapMode; // 换电模式 0:手动模式 1:半自动模式 2:全自动模式 3:检修模式 否 整型 string CarNo; // 车牌号 否 字符串 <= 16 字符 string Vin; // 车辆VIN码 车辆识别码;见GB - T - 27930 - 2015国标PGN512 BMS 和车辆辨识报文(BRM)约定 否 字符串 string RepDownBatteryNo;// 换下电池箱编号 运营商自定义唯一 编码, 是 字符串 <= 32 字符 string RepDownBatterySoc;// 换下电池箱SOC 电池电量百分比,范围:0~100, 是 整型 string RepOnBatteryNo;//换上电池箱编号 运营商自定义唯一编码,是 字符串 <= 32 字符 int RepOnBatterySoc; //换上电池箱SOC 电池电量百分比,范围:0~100 是 整型 float TotalPower; //换上电池箱总充入电量 单位:度(kWh) 是 浮点型 保留小数点后两位 string StartTime; //换电开始时间 格式“yyyy - MM - dd HH : mm:ss” 是 字符串 string EndTime; //换电结束时间 格式“yyyy - MM - dd HH : mm: ss” 是 字符串 }; // 充(换)电设备告警信息(AlarmInfo) struct AlarmInfo { string EquipmentID; // 设备编码 充电接口唯一编码,对同一运营商,保证唯一 是 字符串 23 字符 int EquipmentType; //设备类型 1:充电设备 2:换电设备 整型 string Alert_time; //告警时间 格 式 为 yyyy - MMdd HH : mm:ss 是 字符串 int Alert_code; //告警代码 告警代码 是 整型 string Describe; //描述 文字描述,最大长度 256字符。是 字符串 256 字符 int Status; //状态 告警发生:0;告警 恢复: 1,默认为 0。是 整型 }; } class MQTT { public: static string packEquipmentInfo(mqtt::EquipmentInfo& info); static string packSwapEquipmentStatusInfo(string node_name); // 充(换)电站信息变化推送 static string packNotifyStationInfo(); // 告警信息推送 static string packNotifyAlarm(); // 充电设备状态变化推送, 充电启停或者离线状态改变时推送,充电过程中每分钟一次推送 static string packNotifyChargeStatus(); // 换电设备状态变化推送 static string packNotifySwapStatus(); // 充电电量信息推送(chon), 充电结束后5分钟内推送 static string packNotifyChargeOrder(); // 换电记录信息推送, 换电结束后5分钟内推送 static string packNotifySwapOrder(); };