etm-powersync-plugins/usbwde/devicepluginusbwde.cpp
2017-07-11 14:14:07 +02:00

147 lines
6.5 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Alexander Lampret <alexander.lampret@gmail.com> *
* *
* 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 *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#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<QByteArray> 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<DeviceDescriptor> 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);
}