#pragma once #include #include "ByteArrayProvider.h" #include "ByteCommand.h" #include "ByteCommandQueue.h" #include "ReadCalibrationPointCommand.h" #include "ChannelGroupCalibrationInfo.h" #include "EDeviceCommandStatus.h" #include "DeviceChannelType.h" namespace Incart::DeviceComplexCommands { class ReadInnerChannelsCalibrationCommand final : public Usb::ComplexCommand { Q_OBJECT private: using InnerChannelType = DevicesInfo::InnerDeviceChannelTypes; static const int m_calibrationChannelTypeCount = 6; const uint8_t m_calibrationChannelTypes[m_calibrationChannelTypeCount] = { InnerChannelType::Ecg, InnerChannelType::Reo, InnerChannelType::Acc, InnerChannelType::Prs, InnerChannelType::Ton, InnerChannelType::Oxy }; Usb::ByteCommandQueue* m_commandQueue; std::vector> m_calibrationInfo; int m_readChannelGroup = 0; int m_readChannelIndex = 0; int m_readPointndex = 0; public: ReadInnerChannelsCalibrationCommand(uint32_t uid, Usb::ByteCommandQueue* const commandQueue, QObject* parent = nullptr) : Usb::ComplexCommand("ReadInnerChannelsCalibration", uid, parent) , m_commandQueue(commandQueue) { } signals: void answerIsReady(Usb::ComplexCommand* command, std::vector> calibrationInfo, std::shared_ptr status); public: std::shared_ptr execute() override { Common::JTerminal() << __PRETTY_FUNCTION__; m_readChannelGroup = 0; m_readChannelIndex = 0; m_readPointndex = 0; std::shared_ptr command = std::make_shared("GetCalibrationInfo", m_commandQueue->generateUid(), std::vector{ 0x7e, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xbd }); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &ReadInnerChannelsCalibrationCommand::handleCalibInfoCommandAnswerIsReady); m_commandQueue->enqueue(command); return std::make_shared(Usb::DeviceCommand::EStatus::OK); } private slots: void handleCalibrationPointIsRead(Usb::ComplexCommand* command, Usb::CalibrationPoint calibrationPoint, std::shared_ptr status) { removeExecutedInnerCommand(command); if (status->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, m_calibrationInfo, status); return; } std::shared_ptr calibrationInfo = m_calibrationInfo[m_readChannelGroup]; int32_t calibrationPointsCount = calibrationInfo->getCalibrationPointCount(); int32_t channelCount = calibrationInfo->getChannelsCount(); std::vector& calibrationPoints = calibrationInfo->getCalibrationPoints(); calibrationPoints[m_readChannelIndex * calibrationPointsCount + m_readPointndex] = calibrationPoint; m_readPointndex++; if (m_readPointndex >= calibrationPointsCount) { m_readChannelIndex++; m_readPointndex = 0; } if (m_readChannelIndex >= channelCount) { m_readChannelGroup++; m_readChannelIndex = 0; } if (m_readChannelGroup >= static_cast(m_calibrationInfo.size())) { std::cout << __PRETTY_FUNCTION__ ": channelCount=" << channelCount << " calibrationPointsCount=" << calibrationPointsCount << std::endl; std::cout << __PRETTY_FUNCTION__ ": m_readChannelGroup=" << m_readChannelGroup << " m_calibrationInfo.size=" << m_calibrationInfo.size() << std::endl; for (int ch = 0; ch < channelCount; ch++) { for (int cp = 0; cp < calibrationPointsCount; cp++) { std::cout << " ChannelType: " << static_cast(calibrationPoints[ch * calibrationPointsCount + cp].ChannelType) << std::endl; std::cout << " ChannelNumber: " << static_cast(calibrationPoints[ch * calibrationPointsCount + cp].ChannelNumber) << std::endl; std::cout << " PointIndex: " << static_cast(calibrationPoints[ch * calibrationPointsCount + cp].PointIndex) << std::endl; std::cout << " AdcValue: " << calibrationPoints[ch * calibrationPointsCount + cp].AdcValue << std::endl; std::cout << " PhysicalValue: " << calibrationPoints[ch * calibrationPointsCount + cp].PhysicalValue << std::endl; std::cout << " IsValid: " << calibrationPoints[ch * calibrationPointsCount + cp].IsValid << std::endl << std::endl; } } emit answerIsReady(this, m_calibrationInfo, std::make_shared(Usb::DeviceCommand::EStatus::OK)); } else { status = tryReadCalibrationPoint(); if (status->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, m_calibrationInfo, status); } } } void handleCalibInfoCommandAnswerIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { std::shared_ptr statusInfo; if ((status != Usb::DeviceCommand::EStatus::OK) || (answer.size() < 9) || (answer[4] != 0x00)) { if ((status == Usb::DeviceCommand::EStatus::OK) || (status == Usb::DeviceCommand::EStatus::WRONG_FRAME_FORMAT)) { statusInfo = std::make_shared>>(Usb::DeviceCommand::EStatus::WRONG_FRAME_FORMAT, answer); } else { statusInfo = std::make_shared((Usb::DeviceCommand::EStatus)status); } emit answerIsReady(this, m_calibrationInfo, statusInfo); return; } std::cout << __PRETTY_FUNCTION__ << " messageSize = " << std::dec << answer.size() << " message=" << std::hex; for (size_t i = 0; i < answer.size(); i++) { std::cout << " 0x" << static_cast(answer[i]); } std::cout << std::endl; parseCalibrationInfo(answer, 5, static_cast(answer.size()) - 8); statusInfo = tryReadCalibrationPoint(); if (statusInfo->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, m_calibrationInfo, statusInfo); } } private: std::shared_ptr tryReadCalibrationPoint() { uint8_t channelType = m_calibrationInfo[m_readChannelGroup]->getChannelType(); std::shared_ptr command = std::make_shared(m_commandQueue->generateUid(), m_readPointndex, channelType, m_readChannelIndex, false, m_commandQueue); addExecutedInnerCommand(command); connect(command.get(), &ReadCalibrationPointCommand::answerIsReady, this, &ReadInnerChannelsCalibrationCommand::handleCalibrationPointIsRead); return executeCommand(command); } void parseCalibrationInfo(const std::vector& answer, size_t offset, int length) { std::cout << __PRETTY_FUNCTION__ << " answer.size()=" << std::dec << answer.size() << " _offset=" << offset << " _length=" << length << std::endl; for (int i = static_cast(offset); i < length; i += 8) { int channelType = static_cast(static_cast(answer[i])); bool isNeedCalibration = false; for (int j = 0; j < m_calibrationChannelTypeCount; j++) { if (m_calibrationChannelTypes[j] == channelType) { isNeedCalibration = true; break; } } if (isNeedCalibration) { uint32_t m_discretPeriod = Common::ByteArrayProvider::getDWordFromArray(&answer[0], answer.size(), i + 4); std::shared_ptr info = std::make_shared(static_cast(answer[i]), static_cast(answer[i + 1]), static_cast(answer[i + 2]), static_cast(answer[i + 3]), m_discretPeriod); std::cout << "CChannelGroupCalibrationInfo:" << std::dec << std::endl; std::cout << " ChannelType:" << static_cast(info->getChannelType()) << std::endl; std::cout << " CalibrationPointCount:" << static_cast(info->getCalibrationPointCount()) << std::endl; std::cout << " ChannelsCount:" << info->getChannelsCount() << std::endl; std::cout << " BitCounts:" << info->getBitCounts() << std::endl; std::cout << " DiscretPeriod:" << info->getDiscretPeriod() << std::endl; m_calibrationInfo.push_back(info); } } } }; } // namespace Incart::DeviceComplexCommands