#include "CanController.h" #include #include #include #include #include #include #include #include #if defined(__linux__) #include #else #include #endif #include #include #include #include #include CanController::CanController(QObject* parent) : QObject{parent} { setupDrivers(); setupDefaultParameters(); auto& backend = Backend::instance(); connect(backend.getTrace(), &CanTrace::messageEnqueued, this, &CanController::handlePackage); QSettings settings("settings.ini", QSettings::IniFormat); auto sendParametersTimeout = settings.value("sendParametersTimeout", 50).toInt(); const auto sendParametersTimer = new QTimer(this); sendParametersTimer->start(sendParametersTimeout); connect(sendParametersTimer, &QTimer::timeout, this, &CanController::sendParameters); // auto statusTimer = new QTimer(this); // statusTimer->start(5000); // statusTimer->callOnTimeout([this] // { // QVariantMap statusMap; // statusMap.insert("time", QDateTime::currentDateTime().toString()); // statusMap.insert("status", "0x" + QString::number(0xff, 16).toUpper().rightJustified(2, '0')); // statusMap.insert("description", "asdfasdfasdf"); // statuses_.prepend(statusMap); // emit statusesChanged(); // }); QTimer::singleShot(0, this, &CanController::connectCan); } CanController::~CanController() { } QObject* CanController::qmlInstance(QQmlEngine* /*engine*/, QJSEngine* /*scriptEngine*/) { return new CanController; } void CanController::connectCan() { auto& backend = Backend::instance(); backend.clearTrace(); QSettings settings("settings.ini", QSettings::IniFormat); auto bitrate = settings.value("bitrate", 100000).toInt(); for (auto* network: backend.getSetup().getNetworks()) { for (auto* mi: network->interfaces()) { mi->setBitrate(bitrate); } } backend.startMeasurement(); } void CanController::disconnectCan() { Backend::instance().stopMeasurement(); } void CanController::vkuClosure() { CanMessage message(0x201); message.setLength(8); message.setByte(0, 0x01); auto& backend = Backend::instance(); for (const auto interfaceId: backend.getInterfaceList()) { auto interface = backend.getInterfaceById(interfaceId); if (interface) { interface->sendMessage(message); } } } void CanController::emergencyReset() { CanMessage message(0x201); message.setLength(8); message.setByte(0, 0x02); auto& backend = Backend::instance(); for (const auto interfaceId: backend.getInterfaceList()) { auto interface = backend.getInterfaceById(interfaceId); if (interface) { interface->sendMessage(message); } } } void CanController::sendParameters() { CanMessage message(0x202); message.setLength(8); const auto maximumCurrent = maximumCurrent_.toUInt(); message.setByte(0, maximumCurrent & 0xFF); const auto breakingDelay = breakingDelay_.toUInt(); message.setByte(1, (breakingDelay >> 8) & 0xFF); message.setByte(2, breakingDelay & 0xFF); const auto breakingCurrent = breakingCurrent_.toUInt(); message.setByte(3, breakingCurrent & 0xFF); const auto emergencyDelay = emergencyDelay_.toUInt(); message.setByte(4, emergencyDelay & 0xFF); const auto retriesAfterEmergencyBreak = retriesAfterEmergencyBreak_.toUInt(); message.setByte(5, retriesAfterEmergencyBreak & 0xFF); // qDebug() << "Sending parameters: " << maximumCurrent; auto& backend = Backend::instance(); for (const auto interfaceId: backend.getInterfaceList()) { auto interface = backend.getInterfaceById(interfaceId); if (interface) { interface->sendMessage(message); } } } void CanController::handlePackage(int index) { auto& backend = Backend::instance(); auto message = backend.getTrace()->getMessage(index); if (!message) { return; } if (message->getId() == 0x501) { handleCurrentState(message); } if (message->getId() == 0x502) { handleStatus(message); } } void CanController::handleCurrentState(const CanMessage* message) { quint16 inputVoltage = (message->getByte(0) << 8) + message->getByte(1); setProperty("inputVoltage", QString::number(inputVoltage)); quint16 outputVoltage = (message->getByte(2) << 8) + message->getByte(3); setProperty("outputVoltage", QString::number(outputVoltage)); quint8 outputCurrent = message->getByte(4); setProperty("outputCurrent", QString::number(outputCurrent)); qint16 radiatorTemperature = (message->getByte(5) << 8) + message->getByte(6); setProperty("radiatorTemperature", QString::number(radiatorTemperature)); } void CanController::handleStatus(const CanMessage* message) { QMap statusDescriptionMap = { {0x00, tr("Reset")}, {0x01, tr("No incoming messages via CAN interface")}, {0x03, tr("Waiting for a command for closing")}, {0x04, tr("Work via CAN")}, {0x05, tr("Work via button signal")}, {0x06, tr("Work via CAN or button signal")}, {0x20, tr("Exceeding input voltage")}, {0x22, tr("Exceeding maximum current")}, {0x18, tr("Exceeding radiator temperature")}, {0x02, tr("Pause after breaking")}, {0x80, tr("Blocking due to emergency")} }; quint8 status = message->getByte(0); auto statusDescription = statusDescriptionMap.value(status, tr("Unknown status")); QVariantMap statusMap; statusMap.insert("time", QDateTime::currentDateTime().toString()); statusMap.insert("status", "0x" + QString::number(status, 16).toUpper().rightJustified(2, '0')); statusMap.insert("description", statusDescription); if (statuses_.isEmpty() || statuses_.first().toMap()["status"] != statusMap["status"]) { statuses_.prepend(statusMap); emit statusesChanged(); } quint8 emergencyCounter = message->getByte(1); setProperty("emergencyCounter", QString::number(emergencyCounter)); bool isVkuClosed = (message->getByte(2) & 0x1) == 1; setProperty("isVkuClosed", isVkuClosed); } void CanController::setupDrivers() { auto& backend = Backend::instance(); #if defined(__linux__) backend.addCanDriver(*(new SocketCanDriver(backend))); #else backend.addCanDriver(*(new CandleApiDriver(backend))); #endif // backend.addCanDriver(*(new SLCANDriver(backend))); // backend.addCanDriver(*(new CANBlasterDriver(backend))); backend.setDefaultSetup(); } void CanController::setupDefaultParameters() { setProperty("maximumCurrent", QString::number(95)); setProperty("emergencyDelay", QString::number(2)); setProperty("breakingDelay", QString::number(0)); setProperty("retriesAfterEmergencyBreak", QString::number(2)); setProperty("breakingCurrent", QString::number(100)); }