#pragma once #include "DeviceChannelTypeInfo.h" #include "FrameDecoder.h" #include "MessagePacker.h" #include "AdcViewerChannel.h" #include "SignalLsbInfo.h" #include "PushButtonEventMessagePacker.h" #include "CalibrationInfo.h" #include "DateTimeObject.h" #include #include #include namespace Incart::Usb { /* Ecg, Reo, ... - channels Ecg0, Ecg1, ... - signals */ // содержит все группы сигналов, которые содержат каналы, получаемые frameDecoder class AdcViewerMessage { private: Common::MessagePacker m_messagePacker; DevicesInfo::DeviceChannelTypeInfo m_leadChannel; // (default: ecg) - this channel determines the moment of creating a new blo size_t m_pointCounter = 0; // curr point's count of lead channel size_t m_blockSize = 0; // point's count of lead channel at the moment of creating a new block std::vector> m_channels; std::string m_resetTime; public: AdcViewerMessage(DevicesInfo::DeviceChannelTypeInfo leadChannel_, size_t blockSize_) : m_leadChannel(leadChannel_) , m_blockSize(blockSize_) { } void setChannels(const std::vector>& channels_) { m_channels = channels_; } void setSignalCount(const DevicesInfo::DeviceChannelTypeInfo& channelTypeInfo_, uint8_t signalCount_) { auto channelInfo = getChannelInfo(channelTypeInfo_); if (channelInfo == nullptr) { return; } channelInfo->frameDecoder->setSignalCount(channelTypeInfo_, signalCount_); channelInfo->signalCount = signalCount_; channelInfo->data.clear(); channelInfo->data.resize(channelInfo->signalCount * channelInfo->blockSize); } void resetPointCounter() { m_pointCounter = 0; for (size_t channelIndex = 0; channelIndex < m_channels.size(); ++channelIndex) { m_channels[channelIndex]->blockSize = 0; m_channels[channelIndex]->data.clear(); } } void reset(const Common::DateTimeObject& time_) { m_resetTime = getTimeText(time_); m_pointCounter = 0; for (size_t channelIndex = 0; channelIndex < m_channels.size(); ++channelIndex) { auto channelInfo = m_channels[channelIndex]; channelInfo->blockSize = 0; channelInfo->pointCounter = 0; channelInfo->data.clear(); } } // channelData = data - firstCalibPoint // return: blockIsReady bool addPoint(DevicesInfo::DeviceChannelTypeInfo channelTypeInfo_, const std::vector& channelData_) { auto channelInfo = getChannelInfo(channelTypeInfo_); if (channelInfo == nullptr) { return false; } channelInfo->blockSize++; size_t actualPointSize = channelInfo->signalCount * channelInfo->blockSize; if (channelInfo->data.size() < actualPointSize) { channelInfo->data.resize(actualPointSize); } size_t pointIndex = (channelInfo->blockSize - 1) * channelInfo->signalCount; for (size_t signalIndex = 0; signalIndex < channelInfo->signalCount; ++signalIndex) { channelInfo->data[pointIndex + signalIndex] = channelData_[signalIndex]; } if (channelTypeInfo_ == m_leadChannel) { ++m_pointCounter; if (m_pointCounter == m_blockSize) { m_pointCounter = 0; return true; } } return false; } QByteArray getButtonLabelBson(std::shared_ptr frameDecoder_) // метка "Кнопка" { Common::MessagePacker messagePacker; messagePacker.start_map(2); messagePacker.add_value("type", std::string("event")); messagePacker.add_array_value("data", 1); PushButtonEventMessagePacker eventMessagePacker(frameDecoder_->getFrameNumber()); eventMessagePacker.pack(messagePacker); return messagePacker.pack(); } QByteArray getAdcBson() // кадр визуализации { m_messagePacker.clear(); m_messagePacker.start_map(3); m_messagePacker.add_value("type", std::string("adc")); m_messagePacker.add_value("time", m_resetTime); m_messagePacker.add_array_value("channels", static_cast(m_channels.size())); //!!! это именно количество каналов, а не сигналов for (size_t channelIndex = 0; channelIndex < m_channels.size(); ++channelIndex) { m_messagePacker.start_map(5); m_messagePacker.add_value("name", m_channels[channelIndex]->name); // "Ecg","Acc" // это имя канала m_messagePacker.add_value("blockSize", m_channels[channelIndex]->blockSize); m_messagePacker.add_value("pointCounter", m_channels[channelIndex]->pointCounter); m_messagePacker.add_value("signalCount", m_channels[channelIndex]->signalCount); m_messagePacker.add_value("data", m_channels[channelIndex]->data); // это значения канала // frameCounter is obtained from the 2 bytes of the frame, so it has a maximum value = 65535 m_channels[channelIndex]->pointCounter = m_channels[channelIndex]->pointCounter + m_channels[channelIndex]->blockSize; } return m_messagePacker.pack(); } private: std::string getTimeText(const Common::DateTimeObject& time_) { std::stringstream text; text << toLeadZeroText(time_.date.getYear(), 4) << "-" << toLeadZeroText(time_.date.getMonth(), 2) << "-" << toLeadZeroText(time_.date.getDay(), 2) << "T" << toLeadZeroText(time_.time.getHours(), 2) << ":" << toLeadZeroText(time_.time.getMinutes(), 2) << ":" << toLeadZeroText(time_.time.getSeconds(), 2) << "z03"; return text.str(); } static std::string toLeadZeroText(int number_, size_t length_) { std::string text = std::to_string(number_); while (text.size() < length_) { text = "0" + text; } return text; } std::shared_ptr getChannelInfo(const DevicesInfo::DeviceChannelTypeInfo& typeInfo_) { for (size_t channelIndex = 0; channelIndex < m_channels.size(); ++channelIndex) { if (m_channels[channelIndex]->id == typeInfo_) { return m_channels[channelIndex]; } } return nullptr; } }; } // namespace Incart::Usb