/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2016 Alexander Lampret * * * * This file is part of guh. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; If not, see * * . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "devicepluginusbwde.h" #include "plugin/device.h" #include "devicemanager.h" #include "plugininfo.h" DevicePluginUsbWde::DevicePluginUsbWde() : m_bridgeDevice(0) { } DeviceManager::HardwareResources DevicePluginUsbWde::requiredHardware() const { return DeviceManager::HardwareResourceTimer; } DeviceManager::DeviceSetupStatus DevicePluginUsbWde::setupDevice(Device *device) { if (device->deviceClassId() == wdeBridgeDeviceClassId) { if (m_bridgeDevice != 0) { qCWarning(dcUsbWde) << "Only one USB WDE device can be configured."; return DeviceManager::DeviceSetupStatusFailure; } m_serialPort = new QSerialPort(this); m_serialPort->setPortName(device->paramValue(interfaceParamTypeId).toString()); m_serialPort->setBaudRate(device->paramValue(baudrateParamTypeId).toInt()); if (!m_serialPort->open(QIODevice::ReadOnly)) { qCWarning(dcUsbWde) << device->name() << "can't bind to interface" << device->paramValue(interfaceParamTypeId); return DeviceManager::DeviceSetupStatusFailure; } m_bridgeDevice = device; connect(m_serialPort, SIGNAL(readyRead()), SLOT(handleReadyRead())); connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError))); } else { m_deviceList.insert(device->paramValue(channelParamTypeId).toInt(), device); } return DeviceManager::DeviceSetupStatusSuccess; } void DevicePluginUsbWde::deviceRemoved(Device *device) { if (device->deviceClassId() == wdeBridgeDeviceClassId) { m_serialPort->close(); m_bridgeDevice = 0; } else { m_deviceList.remove(device->paramValue(channelParamTypeId).toInt()); } } void DevicePluginUsbWde::handleReadyRead() { m_readData.append(m_serialPort->readAll()); } void DevicePluginUsbWde::handleError(QSerialPort::SerialPortError serialPortError) { if (serialPortError == QSerialPort::ReadError) { qCWarning(dcUsbWde) << "An I/O error occurred while reading the data from port " << m_serialPort->portName() << ", error: " << m_serialPort->errorString(); } } void DevicePluginUsbWde::guhTimer() { if (!m_readData.isEmpty()) { // Handle data QList parts = m_readData.split(';'); QLocale german(QLocale::German); // Check if received string is valid (should start with $1 and ends with 0) if (parts.size() != 25 || !parts.at(0).contains("$1") || !parts.at(24).contains("0")) { m_readData.clear(); return; } // Loop through 8 possible sensor channels for (int i = 1; i < 9; i++) { if (!parts.at(2 + i).isEmpty()) { // Create new device if it does not exist if (!m_deviceList.contains(i)) { createNewSensor(i); } else { Device* device = m_deviceList.value(i); device->setStateValue(temperatureStateTypeId, german.toDouble(parts.at(2+i))); device->setStateValue(humidityStateTypeId, parts.at(2+i+8).toInt()); device->setStateValue(lastUpdateStateTypeId, QDateTime::currentDateTime().toTime_t()); } } } // Check if wind data is available if (!parts.at(19).isEmpty()) { // Create new device if it does not exist if (!m_deviceList.contains(9)) { createNewSensor(9); } else { Device* device = m_deviceList.value(9); device->setStateValue(temperatureStateTypeId, german.toDouble(parts.at(19))); device->setStateValue(humidityStateTypeId, parts.at(20).toInt()); device->setStateValue(windStrengthStateTypeId, german.toDouble(parts.at(21))); device->setStateValue(rainStrengthStateTypeId, german.toDouble(parts.at(22))); device->setStateValue(isRainStateTypeId, (parts.at(23) == "1")); device->setStateValue(lastUpdateStateTypeId, QDateTime::currentDateTime().toTime_t()); } } m_readData.clear(); } } void DevicePluginUsbWde::createNewSensor(int channel) { DeviceClassId createClassId; QString deviceName; QList deviceDescriptors; createClassId = temperatureSensorDeviceClassId; deviceName = "Sensor channel " + QString::number(channel); if (channel == 9) { createClassId = windRainSensorDeviceClassId; deviceName = "Weather station"; } DeviceDescriptor descriptor(createClassId, deviceName, deviceName); ParamList params; params.append(Param(nameParamTypeId, "Sensor " + QString::number(channel))); params.append(Param(channelParamTypeId, channel)); descriptor.setParams(params); deviceDescriptors.append(descriptor); emit autoDevicesAppeared(createClassId, deviceDescriptors); }