#pragma once #include #include "deviceBase.h" #include "Crc.h" using namespace std; // 煤气驱鸟炮 #define EXPEL_DATA_HEAD (0xFE) // 数据头 #define EXPEL_HEART_BEAT (0x01) // 心跳 #define EXPEL_GENERAL_ACK (0X02) // 通用应答 #define EXPEL_SYS_STATE (0x14) // 获取设备信息 #define EXPEL_SYS_STATE_ACK (0X15) // 获取设备信息应答 #define EXPEL_POWER_OUTPUT_CTRL (0X16) // 电源输出控制 <-: 通用应答 #define EXPEL_POWER_OUTPUT_ON (0x01) // 电源开启 #define EXPEL_POWER_OUTPUT_OFF (0x00) // 电源关闭 #define EXPEL_BOMB_CTRL (0X17) // 煤气炮控制 <-: 通用应答 #define EXPEL_BOMB_ON (0X01) // 煤气炮开炮 #define EXPEL_GET_BOMB_STATE (0X18) // 获取开炮结果 #define EXPEL_GET_BOMB_STATE_ACK (0X19) // 煤气炮开炮应答 <-:通用应答(因为状态为阶段状态,过时会丢失状态。需确认应答收到,未收到应带会重传3次 class deviceGasV1:public deviceBase { private: unsigned short voltage; short current; short pressure; uint8_t power_out_state; private: enum RECV_STEP{ STEP_HEAD = 0, STEP_LEN = 1, STEP_SEQ = 2, STEP_SAddr = 3, STEP_DAddr = 4, STEP_MSGId = 5, STEP_DATA = 6 }; typedef struct { uint8_t dataCount; uint8_t dataLength; uint8_t dataCheckSum; uint8_t data[15]; enum RECV_STEP step = STEP_HEAD; }ExpelComm; ExpelComm _comm; public: deviceGasV1():deviceBase() { this->setDeviceToken(serial); this->setDeviceInfo("北京大兴机场 民航小板协议"); this->setBaudRate(115200); } ~deviceGasV1(){} void setVoltage(unsigned short Voltage){ voltage = Voltage; } void setCurent(short Current){ current = Current; } void setPressure(short Pressure){ pressure = Pressure; } void setPowerOutState(uint8_t PowerOutState){ power_out_state = PowerOutState; } unsigned short getVoltage(){ return voltage; } short getCurent(){ return current; } short getPressure(){ return pressure; } uint8_t getPowerOutState(){ return power_out_state; } void serialization(){} bool Consumer(uint8_t *data, int len, int &msg_id) { bool ReceiveSuccessful = false; if(this->Type != 1 && len > 0) return true; for (int i = 0; i < len; i++) { switch(_comm.step){ case STEP_HEAD: if(data[i] == EXPEL_DATA_HEAD){ _comm.data[0] = EXPEL_DATA_HEAD; _comm.step = STEP_LEN; } break; case STEP_LEN: _comm.data[1] = data[i]; _comm.dataLength = data[i]; _comm.step = STEP_SEQ; break; case STEP_SEQ: _comm.data[2] = data[i]; _comm.step = STEP_SAddr; break; case STEP_SAddr: _comm.data[3] = data[i]; _comm.step = STEP_DAddr; break; case STEP_DAddr: _comm.data[4] = data[i]; _comm.step = STEP_MSGId; break; case STEP_MSGId: _comm.data[5] = data[i]; _comm.step = STEP_DATA; _comm.dataCount = 6; break; case STEP_DATA: _comm.data[_comm.dataCount++] = data[i]; if(_comm.dataCount == _comm.dataLength + 2 + 6){ ReceiveSuccessful = true; _comm.step = STEP_HEAD; } break; default: _comm.step = STEP_HEAD; break; } } if(!ReceiveSuccessful) return false; return deserialization(_comm.data, _comm.dataLength + 2 + 6, msg_id); } static void serialization(const GasV1Control gasControl, char* data){ data[0] = EXPEL_DATA_HEAD; data[1] = 0x01; data[2] = 0x01; data[3] = 0xAC; data[4] = (char)gasControl.deviceId; data[5] = gasControl.msgId; data[6] = gasControl.data; int16_t checksum = Crc::crc_calculate((uint8_t *)(data + 1), data[1] + 4 + 1); data[7] = (char)(checksum&0x00ff); data[8] = (char)(checksum >> 8); data[9] = 0x0D; data[10] = 0x0A; } bool deserialization(){ return true; } bool deserialization(const uint8_t *data, int len, int &msg_id){ if(data[0] != EXPEL_DATA_HEAD) return false; int16_t checksum = Crc::crc_calculate((uint8_t *)(data + 1), data[1] + 4 + 1); if(data[len - 2] != (uint8_t)(checksum&0x00ff) || data[len - 1] != (uint8_t)(checksum >> 8)){ return false; } setDeviceId(std::to_string(data[4])); msg_id = data[5]; if(msg_id == EXPEL_SYS_STATE_ACK){ // 获取系统状态 voltage = data[6] + (data[7]*255); current = data[8] + (data[9]*255); pressure = data[10] + (data[11]*255); power_out_state = data[12]; } return true; } /** * @description: 打开 * @param {int} deivceId * @return {*} */ int32_t Open(std::string DeviceId, uint8_t* data, int& length){ GasV1Control gasControl; gasControl.deviceId = atoi(DeviceId.c_str()); gasControl.msgId = EXPEL_POWER_OUTPUT_CTRL; gasControl.data = EXPEL_POWER_OUTPUT_ON; length = 11; serialization(gasControl, (char*)data); return 0; } /** * @description: 关闭 * @param {int} deivceId * @return {*} */ int32_t Close(std::string DeviceId, uint8_t* data, int& length){ GasV1Control gasControl; gasControl.deviceId = atoi(DeviceId.c_str()); gasControl.msgId = EXPEL_POWER_OUTPUT_CTRL; gasControl.data = EXPEL_POWER_OUTPUT_OFF; length = 11; serialization(gasControl, (char*)data); return 0; } /** * @description: 开炮 * @param {int} deivceId * @return {*} */ int32_t Fire(std::string DeviceId, uint8_t* data, int& length){ // GasV1Control gasControl; // gasControl.deviceId = atoi(DeviceId.c_str()); // gasControl.msgId = EXPEL_BOMB_CTRL; // gasControl.data = EXPEL_BOMB_ON; // length = 11; // serialization(gasControl, (char*)data); //return Status(DeviceId, data, length); return Open(DeviceId, data, length); } /** * @description: 状态 * @param {int} deivceId * @return {*} */ int32_t Status(std::string DeviceId, uint8_t* data, int& length){ GasV1Control gasControl; gasControl.deviceId = atoi(DeviceId.c_str()); gasControl.msgId = EXPEL_SYS_STATE; gasControl.data = 0x00; length = 11; serialization(gasControl, (char*)data); return 0; } /** * @description: 判定msg是否为status * @param {int} &msg_id * @return {*} */ bool getStatusMsg(int &msg_id){ if(msg_id != EXPEL_SYS_STATE_ACK) return false; return true; } /** * @description: 构建设备信息 * @param {SendDevice&} sendDevice * @return {*} */ void BuildDeviceInfo(SendDevice& sendDevice){ sendDevice.deviceId = atoi(this->getDeviceId().c_str()); sendDevice.commandCode = "1"; sendDevice.status = 1; sendDevice.workStatus = 1; sendDevice.powerStatus = 1; sendDevice.batteryStatus = 1; sendDevice.num = 0; sendDevice.oxyPressure = 0; sendDevice.gasPressure = 0; sendDevice.remark = ""; sendDevice.attr1 = std::to_string(this->getVoltage()); // 电压 sendDevice.attr2 = std::to_string(this->getCurent()); // 电流 sendDevice.attr3 = std::to_string(this->getPressure()); // 声压 } };