#pragma once #include "DeviceComplexJsonCommand.h" #include "UsbDeviceManager.h" #include "JsonCommandStatusCreator.h" #include "DeviceSeriesParser.h" #include #include namespace Incart::DeviceWebApi { // Адаптированно для прибора: КТ-07-АД-3 (тип 38) HW 1.00, SW 1.23, ревизия ПО 1.03, GuiVer: 4.7 class GetDeviceInfoJsonCommand final : public DeviceComplexJsonCommand { private: const uint16_t m_startAddressLastModDate = 0x040a; Usb::UsbDeviceManager* m_usbDeviceManager; Usb::DeviceInfo m_deviceInfo; uint32_t m_deviceNumber; uint32_t m_deviceGuiVersion; uint16_t m_revision; uint16_t m_setupCounter; std::string m_lastModDate; uint8_t m_deviceState; std::string m_deviceStateText; public: GetDeviceInfoJsonCommand(std::shared_ptr description, Usb::UsbDeviceManager* usbDeviceManager) : DeviceComplexJsonCommand(description) , m_usbDeviceManager(usbDeviceManager) , m_deviceInfo(m_usbDeviceManager->getConnectedDeviceInfo()) , m_lastModDate("?") { } GetDeviceInfoJsonCommand(Usb::UsbDeviceManager* usbDeviceManager) : GetDeviceInfoJsonCommand(createCommandDescription(), usbDeviceManager) { } public: static std::shared_ptr createCommandDescription() { return std::make_shared("GetDevInfo", std::make_shared(), std::make_shared(std::vector>{ std::make_shared("Name", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("Type", Net::WebApi::EJsonCommandUnitType::Int), std::make_shared("HardVer", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("SoftVer", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("VersionExtension", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("Number", Net::WebApi::EJsonCommandUnitType::Int), std::make_shared("GuiVersion", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("Revision", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("SetupCount", Net::WebApi::EJsonCommandUnitType::Int), std::make_shared("LastModDate", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("State", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("ServiceCounter", Net::WebApi::EJsonCommandUnitType::Int) }) ); } std::shared_ptr execute(std::shared_ptr launchedCommandInfo) override { uid = launchedCommandInfo->uid; Usb::UsbDeviceCommandSet* commandSet = m_usbDeviceManager->getCommandSet(); std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadNumber", commandQueue->generateUid(), std::vector{}); Usb::DeviceCommand::EStatus answerStatus = commandSet->createCommandBytes(commandInfo, commandBytes); if (answerStatus != Usb::DeviceCommand::EStatus::OK) { return std::make_shared(Usb::DeviceCommandStatusConverter::toText(answerStatus)); } std::shared_ptr getNumberCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(getNumberCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleGetNumberIsReady); commandQueue->enqueue(getNumberCommand); return std::make_shared(); } private slots: void handleGetNumberIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_deviceNumber = Common::ByteArrayProvider::getDWordFromArray(&answer[0], answer.size(), 4); Usb::UsbDeviceCommandSet* commandSet = m_usbDeviceManager->getCommandSet(); std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadGuiVersion", commandQueue->generateUid(), std::vector{}); answerStatus = commandSet->createCommandBytes(commandInfo, commandBytes); if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } std::shared_ptr readGuiVersionCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(readGuiVersionCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleGetGuiVersionIsReady); commandQueue->enqueue(readGuiVersionCommand); } void handleGetGuiVersionIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_deviceGuiVersion = parseGuiVersion(answer); Usb::UsbDeviceCommandSet* commandSet = m_usbDeviceManager->getCommandSet(); std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadRevision", commandQueue->generateUid(), std::vector{}); answerStatus = commandSet->createCommandBytes(commandInfo, commandBytes); if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } std::shared_ptr readRevisionCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(readRevisionCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleGetRevisionIsReady); commandQueue->enqueue(readRevisionCommand); } void handleGetRevisionIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_revision = parseRevision(answer); Usb::UsbDeviceCommandSet* commandSet = m_usbDeviceManager->getCommandSet(); std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadIdInv", commandQueue->generateUid(), std::vector{}); answerStatus = commandSet->createCommandBytes(commandInfo, commandBytes); if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } std::shared_ptr readIdInvCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(readIdInvCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleGetIdInvIsReady); commandQueue->enqueue(readIdInvCommand); } void handleGetIdInvIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_setupCounter = parseSetupCounter(answer); size_t readLength = 7; std::vector commandBytes = { 0x7e, 0x06, 0x00, 0x03, /* address */ 0x00, 0x00, /* memory type */ 0x00, 0x00, /* read data length*/ 0x00, 0x00, 0xff, 0xff, 0xbd }; Common::ByteArrayProvider::setWordToArray(m_startAddressLastModDate, &commandBytes[0], 4); Common::ByteArrayProvider::setWordToArray(0x0500, &commandBytes[0], 6); Common::ByteArrayProvider::setWordToArray(static_cast(readLength), &commandBytes[0], 8); Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr readEepromCommand = std::make_shared("ReadEeprom", commandQueue->generateUid(), std::move(commandBytes)); connect(readEepromCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleReadLastModDateIsReady); commandQueue->enqueue(readEepromCommand); } void handleReadLastModDateIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } if (answer.size() == 8) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(Usb::DeviceCommand::EStatus::WRONG_FRAME_FORMAT, answer)); return; } if (isValidLastModDate(answer)) { int year = answer[4] + 2000; int month = answer[5]; int day = answer[6]; int hours = answer[7]; int minutes = answer[8]; int seconds = answer[9]; m_lastModDate = ""; if (day < 10) { m_lastModDate += "0"; } m_lastModDate += std::to_string(day) + "."; if (month < 10) { m_lastModDate += "0"; } m_lastModDate += std::to_string(month) + "." + std::to_string(year) + " "; if (hours < 10) { m_lastModDate += "0"; } m_lastModDate += std::to_string(hours) + ":"; if (minutes < 10) { m_lastModDate += "0"; } m_lastModDate += std::to_string(minutes) + ":"; if (seconds < 10) { m_lastModDate += "0"; } m_lastModDate += std::to_string(seconds); } std::vector commandBytes = { 0x7e, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xbd }; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr readDeviceStateCommand = std::make_shared("ReadDeviceState", commandQueue->generateUid(), std::move(commandBytes)); connect(readDeviceStateCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleReadDeviceStateIsReady); commandQueue->enqueue(readDeviceStateCommand); } void handleReadDeviceStateIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_deviceState = answer[4]; if (m_deviceState == 1) // waiting { std::vector commandBytes = { 0x7e, 0x01, 0x00, 0x09, 0x2a, 0xff, 0xff, 0xbd }; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr readDeviceStateDetailsCommand = std::make_shared("ReadDeviceStateDetails", commandQueue->generateUid(), std::move(commandBytes)); connect(readDeviceStateDetailsCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetDeviceInfoJsonCommand::handleReadDeviceStateDetailsIsReady); commandQueue->enqueue(readDeviceStateDetailsCommand); } else { createDeviceStateText(m_deviceState, false, false, false); } } void handleReadDeviceStateDetailsIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } uint8_t deviceStateDetails = answer[5]; bool isPrepared = false; if (deviceStateDetails == 1) { isPrepared = true; } m_deviceStateText = getDeviceStateText(m_deviceState, isPrepared, false, false); createDeviceStateText(m_deviceState, isPrepared, false, false); } void createDeviceStateText(uint8_t deviceState, bool isPrepared, bool isFullMemory, bool stoppedByVoltage) { m_deviceStateText = getDeviceStateText(deviceState, isPrepared, isFullMemory, stoppedByVoltage); QJsonObject jsonRootObject; if ((m_deviceInfo.typeInfo.type != 0) || (m_deviceInfo.hardwareVersion != 0) || (m_deviceInfo.softwareVersion != 0)) { jsonRootObject.insert("Name", QString::fromStdString(m_deviceInfo.typeInfo.name)); std::string deviceSeries = DevicesInfo::DeviceSeriesParser::pack(m_deviceInfo.typeInfo.series); jsonRootObject.insert("Type", static_cast(m_deviceInfo.typeInfo.type)); jsonRootObject.insert("HardVer", Usb::DeviceBaseInfoAggregator::toVersionText(m_deviceInfo.hardwareVersion)); jsonRootObject.insert("SoftVer", Usb::DeviceBaseInfoAggregator::toVersionText(m_deviceInfo.softwareVersion)); jsonRootObject.insert("VersionExtension", QString::fromStdString(m_deviceInfo.deviceVersionExtension)); jsonRootObject.insert("Number", static_cast(m_deviceNumber)); jsonRootObject.insert("GuiVersion", Usb::DeviceBaseInfoAggregator::toVersionText(m_deviceGuiVersion)); jsonRootObject.insert("Revision", Usb::DeviceBaseInfoAggregator::toVersionText(m_revision)); jsonRootObject.insert("SetupCount", static_cast(m_setupCounter)); jsonRootObject.insert("LastModDate", QString::fromStdString(m_lastModDate)); jsonRootObject.insert("State", QString::fromStdString(m_deviceStateText)); jsonRootObject.insert("ServiceCounter", static_cast(0)); } QJsonDocument document(jsonRootObject); emit answerIsReady(this, document, std::make_shared()); } private: uint8_t getLastModDateCrc(const std::vector& data) const { uint8_t crc = 0x33; for (int i = 4; i + 1 < 11; i++) { crc += data[i]; } return crc; } bool isValidLastModDate(const std::vector& data) const { uint8_t crc = getLastModDateCrc(data); return data[10] == crc; } uint32_t parseGuiVersion(const std::vector& data) { size_t offset = 5; uint32_t versionValue = Common::ByteArrayProvider::getDWordFromArray(&data[0], data.size() - 3, offset); return Common::ByteArrayProvider::swapDWord(versionValue); } uint16_t parseRevision(const std::vector& data) { size_t offset = 5; uint16_t revisionValue = Common::ByteArrayProvider::getWordFromArray(data, offset); return Common::ByteArrayProvider::swapWord(revisionValue); } uint16_t parseSetupCounter(const std::vector& data) { size_t offset = 5; if (data.size() < offset + 6) { return 0; } return Common::ByteArrayProvider::toWord(data[offset + 4], data[offset + 5]); } std::string getDeviceStateText(uint8_t deviceState, bool isPrepared, bool isFullMemory, bool stoppedByVoltage) { std::string deviceStateText = ""; switch (deviceState) { case 1: deviceStateText += "Ожидание"; break; case 2: deviceStateText += "Запись"; break; } if (isPrepared) { deviceStateText += ", подготовлен к записи"; } if (isFullMemory) { deviceStateText += ", память заполнена"; } if (stoppedByVoltage) { deviceStateText += ", остановлен по питанию"; } return deviceStateText; } }; } // namespace Incart::DeviceWebApi