diff --git a/cairquality.cpp b/cairquality.cpp index bafdf7d..7769da0 100644 --- a/cairquality.cpp +++ b/cairquality.cpp @@ -1,14 +1,39 @@ #include "cairquality.h" +#include "ctinkerforge.h" -cAirQuality::cAirQuality(cTinkerForge* tinkerForge, const QString& uid) : +cAirQuality::cAirQuality(cTinkerForge* tinkerForge, const QString& uid, QObject *object) : + QObject(object), m_tinkerForge(tinkerForge), - m_uid(uid) + m_uid(uid), + m_lastError(0), + m_iaqIndex(0), + m_temperature(0.0), + m_humidity(0.0), + m_airPressure(0.0), + m_iaqIndexAccuracy(""), + m_apiVersion(""), + m_temperatureOffset(0.0), + m_backgroundCalibrationDuration(0), + m_errorCountAckChecksum(0), + m_errorCountMessageChecksum(0), + m_errorCountFrame(0), + m_errorCountOverflow(0), + m_bootloaderMode(0), + m_statusLEDConfig(0), + m_chipTemperature(0.0), + m_uid1(""), + m_connectedUID(""), + m_position(""), + m_hardwareVersion(""), + m_firmwareVersion(""), + m_deviceIdentifier(0) { if(!m_tinkerForge) return; air_quality_create(&m_airQuality, m_uid.toLocal8Bit().data(), m_tinkerForge->connection()); + tinkerForge->add(this); } cAirQuality::~cAirQuality() @@ -16,61 +41,243 @@ cAirQuality::~cAirQuality() air_quality_destroy(&m_airQuality); } +qint16 cAirQuality::collect() +{ + uint8_t iaq_index_acuracy; + int32_t temperature; + int32_t humidity; + int32_t air_pressure; + uint8_t api_version[3]; + int32_t offset; + uint8_t duration; + uint32_t error_count_ack_checksum; + uint32_t error_count_message_checksum; + uint32_t error_count_frame; + uint32_t error_count_overflow; + uint8_t mode; + uint8_t config; + int16_t chip_temperature; + char uid[8]; + char connected_uid[8]; + char position; + uint8_t hardware_version[3]; + uint8_t firmware_version[3]; + uint16_t device_identifier; + + m_lastError = 0; + + if(air_quality_get_all_values(&m_airQuality, &m_iaqIndex, &iaq_index_acuracy, &temperature, &humidity, &air_pressure) >= 0) + { + switch(iaq_index_acuracy) + { + case AIR_QUALITY_ACCURACY_UNRELIABLE: + m_iaqIndexAccuracy = "Unreliable"; + break; + case AIR_QUALITY_ACCURACY_LOW: + m_iaqIndexAccuracy = "Low"; + break; + case AIR_QUALITY_ACCURACY_MEDIUM: + m_iaqIndexAccuracy = "Medium"; + break; + case AIR_QUALITY_ACCURACY_HIGH: + m_iaqIndexAccuracy = "High"; + break; + default: + m_iaqIndexAccuracy = "Unreliable"; + break; + } + + m_temperature = (double)temperature / 100.0; + m_humidity = (double)humidity / 100.0; + m_airPressure = (double)air_pressure / 100.0; + } + else + { + m_lastError |= IAQ_INDEX; + m_lastError |= IAQ_INDEX_ACURACY; + m_lastError |= TEMPERATURE; + m_lastError |= HUMIDITY; + m_lastError |= AIR_PRESSURE; + } + + if(air_quality_get_api_version(&m_airQuality, api_version) >= 0) + m_apiVersion = QString("%1.%2.%3").arg(api_version[0]).arg(api_version[1]).arg(api_version[2]); + else + m_lastError |= API_VERSION; + + if(air_quality_get_temperature_offset(&m_airQuality, &offset) >= 0) + m_temperatureOffset = (double)offset/(100.0); + else + m_lastError |= TEMPERATURE_OFFSET; + + if(air_quality_get_background_calibration_duration(&m_airQuality, &duration) >= 0) + m_backgroundCalibrationDuration = duration; + else + m_lastError |= BACKGROUND_CALIBRATION_DURATION; + + if(air_quality_get_spitfp_error_count(&m_airQuality, &error_count_ack_checksum, &error_count_message_checksum, &error_count_frame, &error_count_overflow) >= 0) + { + m_errorCountAckChecksum = error_count_ack_checksum; + m_errorCountMessageChecksum = error_count_message_checksum; + m_errorCountFrame = error_count_frame; + m_errorCountOverflow = error_count_overflow; + } + else + { + m_lastError |= ERROR_COUNT_ACK_CHECKSUM; + m_lastError |= ERROR_COUNT_MESSAGE_CHECKSUM; + m_lastError |= ERROR_COUNT_FRAME; + m_lastError |= ERROR_COUNT_OVERFLOW; + } + + if(air_quality_get_bootloader_mode(&m_airQuality, &mode) >= 0) + m_bootloaderMode = mode; + else + m_lastError |= BOOTLOADER_MODE; + + if(air_quality_get_status_led_config(&m_airQuality, &config) >= 0) + m_statusLEDConfig = config; + else + m_lastError |= STATUS_LED_CONFIG; + + if(air_quality_get_chip_temperature(&m_airQuality, &chip_temperature) >= 0) + m_chipTemperature = (double)chip_temperature; + else + m_lastError |= CHIP_TEMPERATURE; + + if(air_quality_get_identity(&m_airQuality, uid, connected_uid, &position, hardware_version, firmware_version, &device_identifier) >= 0) + { + m_uid1 = QString(uid); + m_connectedUID = QString(connected_uid); + m_position = QString(position); + m_hardwareVersion = QString("%1.%2.%3").arg(hardware_version[0]).arg(hardware_version[1]).arg(hardware_version[2]); + m_firmwareVersion = QString("%1.%2.%3").arg(firmware_version[0]).arg(firmware_version[1]).arg(firmware_version[2]); + m_deviceIdentifier = device_identifier; + } + else + { + m_lastError |= UID; + m_lastError |= CONNECTED_UID; + m_lastError |= POSITION; + m_lastError |= HARDWARE_VERSION; + m_lastError |= FIRMWARE_VERSION; + m_lastError |= DEVICE_IDENTIFIER; + } + + return(m_lastError); +} + +QString cAirQuality::uid() +{ + return(m_uid); +} + +qint32 cAirQuality::lastError() +{ + return(m_lastError); +} + qint32 cAirQuality::iaqIndex() { - int32_t iaq_index; - uint8_t iaq_index_acuracy; - - if(air_quality_get_iaq_index(&m_airQuality, &iaq_index, &iaq_index_acuracy) < 0) - return(0.0); - return(iaq_index); + return(m_iaqIndex); } double cAirQuality::temperature() { - int32_t temperature; - - if(air_quality_get_temperature(&m_airQuality, &temperature) < 0) - return(0.0); - return((double)temperature/100.0); + return(m_temperature); } double cAirQuality::humidity() { - int32_t humidity; - - if(air_quality_get_humidity(&m_airQuality, &humidity) < 0) - return(0.0); - return((double)humidity/100.0); + return(m_humidity); } double cAirQuality::airPressure() { - int32_t airPressure; - - if(air_quality_get_air_pressure(&m_airQuality, &airPressure) < 0) - return(0.0); - return((double)airPressure/100.0); + return(m_airPressure); } QString cAirQuality::iaqIndexAccuracy() { - int32_t iaq_index; - uint8_t iaq_index_acuracy; - - if(air_quality_get_iaq_index(&m_airQuality, &iaq_index, &iaq_index_acuracy) < 0) - return("IAQ Index Accuracy: Unreliable"); - - switch(iaq_index_acuracy) - { - case AIR_QUALITY_ACCURACY_UNRELIABLE: - return("Unreliable"); - case AIR_QUALITY_ACCURACY_LOW: - return("Low"); - case AIR_QUALITY_ACCURACY_MEDIUM: - return("Medium"); - case AIR_QUALITY_ACCURACY_HIGH: - return("High"); - } - return("Unreliable"); + return(m_iaqIndexAccuracy); +} + +QString cAirQuality::apiVersion() +{ + return(m_apiVersion); +} + +double cAirQuality::temperatureOffset() +{ + return(m_temperatureOffset); +} + +quint8 cAirQuality::backgroundCalibrationDuration() +{ + return(m_backgroundCalibrationDuration); +} + +quint32 cAirQuality::errorCountAckChecksum() +{ + return(m_errorCountAckChecksum); +} + +quint32 cAirQuality::errorCountMessageChecksum() +{ + return(m_errorCountMessageChecksum); +} + +quint32 cAirQuality::errorCountFrame() +{ + return(m_errorCountFrame); +} + +quint32 cAirQuality::errorCountOverflow() +{ + return(m_errorCountOverflow); +} + +quint8 cAirQuality::bootloaderMode() +{ + return(m_bootloaderMode); +} + +quint8 cAirQuality::statusLEDConfig() +{ + return(m_statusLEDConfig); +} + +double cAirQuality::chipTemperature() +{ + return(m_chipTemperature); +} + +QString cAirQuality::uid1() +{ + return(m_uid1); +} + +QString cAirQuality::connectedUID() +{ + return(m_connectedUID); +} + +QString cAirQuality::position() +{ + return(m_position); +} + +QString cAirQuality::hardwareVersion() +{ + return(m_hardwareVersion); +} + +QString cAirQuality::firmwareVersion() +{ + return(m_firmwareVersion); +} + +quint16 cAirQuality::deviceIdentifier() +{ + return(m_deviceIdentifier); } diff --git a/cairquality.h b/cairquality.h index 4c4fc9b..57f3196 100644 --- a/cairquality.h +++ b/cairquality.h @@ -2,25 +2,101 @@ #define CAIRQUALITY_H -#include "ctinkerforge.h" #include "tinkerforge/bricklet_air_quality.h" +#include +#include -class cAirQuality + +class cTinkerForge; + +class cAirQuality : public QObject { + Q_OBJECT + public: - cAirQuality(cTinkerForge* tinkerForge, const QString& uid); + enum errorCode + { + IAQ_INDEX = 0x00000001, + IAQ_INDEX_ACURACY = 0x00000002, + TEMPERATURE = 0x00000004, + HUMIDITY = 0x00000008, + AIR_PRESSURE = 0x00000010, + API_VERSION = 0x00000020, + TEMPERATURE_OFFSET = 0x00000040, + BACKGROUND_CALIBRATION_DURATION = 0x00008000, + ERROR_COUNT_ACK_CHECKSUM = 0x00010000, + ERROR_COUNT_MESSAGE_CHECKSUM = 0x00020000, + ERROR_COUNT_FRAME = 0x00040000, + ERROR_COUNT_OVERFLOW = 0x00080000, + BOOTLOADER_MODE = 0x00100000, + STATUS_LED_CONFIG = 0x00200000, + CHIP_TEMPERATURE = 0x00400000, + UID = 0x00800000, + CONNECTED_UID = 0x01000000, + POSITION = 0x02000000, + HARDWARE_VERSION = 0x04000000, + FIRMWARE_VERSION = 0x08000000, + DEVICE_IDENTIFIER = 0x10000000, + }; + + cAirQuality(cTinkerForge* tinkerForge, const QString& uid, QObject* object = nullptr); ~cAirQuality(); + qint16 collect(); + + QString uid(); + qint32 lastError(); qint32 iaqIndex(); double temperature(); double humidity(); double airPressure(); QString iaqIndexAccuracy(); + QString apiVersion(); + double temperatureOffset(); + quint8 backgroundCalibrationDuration(); + quint32 errorCountAckChecksum(); + quint32 errorCountMessageChecksum(); + quint32 errorCountFrame(); + quint32 errorCountOverflow(); + quint8 bootloaderMode(); + quint8 statusLEDConfig(); + double chipTemperature(); + QString uid1(); + QString connectedUID(); + QString position(); + QString hardwareVersion(); + QString firmwareVersion(); + quint16 deviceIdentifier(); + private: cTinkerForge* m_tinkerForge; QString m_uid; + qint32 m_lastError; AirQuality m_airQuality; + qint32 m_iaqIndex; + double m_temperature; + double m_humidity; + double m_airPressure; + QString m_iaqIndexAccuracy; + QString m_apiVersion; + double m_temperatureOffset; + quint8 m_backgroundCalibrationDuration; + quint32 m_errorCountAckChecksum; + quint32 m_errorCountMessageChecksum; + quint32 m_errorCountFrame; + quint32 m_errorCountOverflow; + quint8 m_bootloaderMode; + quint8 m_statusLEDConfig; + double m_chipTemperature; + QString m_uid1; + QString m_connectedUID; + QString m_position; + QString m_hardwareVersion; + QString m_firmwareVersion; + quint16 m_deviceIdentifier; }; +Q_DECLARE_METATYPE(cAirQuality*) + #endif // CAIRQUALITY_H diff --git a/cdisplayvalues.cpp b/cdisplayvalues.cpp new file mode 100644 index 0000000..f676fe1 --- /dev/null +++ b/cdisplayvalues.cpp @@ -0,0 +1,90 @@ +#include "cdisplayvalues.h" +#include "cmainwindow.h" +#include "ui_cmainwindow.h" + + +cDisplayValues::cDisplayValues(cMainWindow* mainWindow, cTinkerForge *tinkerForge, QObject* object) : + QThread(object), + m_mainWindow(mainWindow), + m_tinkerForge(tinkerForge) +{ +} + +void cDisplayValues::execute(qint16 interval) +{ + startTimer(interval); +} + +void cDisplayValues::timerEvent(QTimerEvent */*event*/) +{ + Ui::cMainWindow* ui = m_mainWindow->getUI(); + QList brickList = m_tinkerForge->brickList(); + + for(int x = 0;x < brickList.count();x++) + { + cAirQuality* lpAirQuality = brickList[x].value(); + cOutdoorWeather* lpOutdoorWeather = brickList[x].value(); + + if(lpAirQuality) + { +// qDebug() << "last Error: " << lpAirQuality->lastError(); +// qDebug() << "UID: " << lpAirQuality->uid(); +// qDebug() << "Index: " << lpAirQuality->iaqIndex(); +// qDebug() << "Index Genauigkeit: " << lpAirQuality->iaqIndexAccuracy(); +// qDebug() << "Temperatur: " << lpAirQuality->temperature(); +// qDebug() << "Luftfeuchte: " << lpAirQuality->humidity(); +// qDebug() << "Luftdruck: " << lpAirQuality->airPressure(); +// qDebug() << "API Version: " << lpAirQuality->apiVersion(); +// qDebug() << "Temperatur Offset: " << lpAirQuality->temperatureOffset(); +// qDebug() << "Kalibrierung Zeit: " << lpAirQuality->backgroundCalibrationDuration(); +// qDebug() << "ACK Checksum Fehler: " << lpAirQuality->errorCountAckChecksum(); +// qDebug() << "Message Fehler: " << lpAirQuality->errorCountMessageChecksum(); +// qDebug() << "Frame Fehler: " << lpAirQuality->errorCountFrame(); +// qDebug() << "Overflow Fehler: " << lpAirQuality->errorCountOverflow(); +// qDebug() << "Bootloader Modus: " << lpAirQuality->bootloaderMode(); +// qDebug() << "Status LED Config: " << lpAirQuality->statusLEDConfig(); +// qDebug() << "Chip Temperatur: " << lpAirQuality->chipTemperature(); +// qDebug() << "UID 1: " << lpAirQuality->uid1(); +// qDebug() << "verbundene UID: " << lpAirQuality->connectedUID(); +// qDebug() << "Position: " << lpAirQuality->position(); +// qDebug() << "Hardware Version: " << lpAirQuality->hardwareVersion(); +// qDebug() << "Firmware Version: " << lpAirQuality->firmwareVersion(); +// qDebug() << "Device Identifier: " << lpAirQuality->deviceIdentifier(); + } + else if(lpOutdoorWeather) + { + ui->m_uid->setText(lpOutdoorWeather->uid()); + ui->m_station->setText(QString("%1").arg(lpOutdoorWeather->station())); + ui->m_isStation->setChecked(lpOutdoorWeather->isStation()); + ui->m_lastError->setText(QString("%1").arg(lpOutdoorWeather->lastError())); + ui->m_temperature->setText(QString("%1°C").arg(lpOutdoorWeather->temperature())); + ui->m_humidity->setText(QString("%1\%").arg(lpOutdoorWeather->humidity())); + ui->m_windSpeed->setText(QString("%1m/s").arg(lpOutdoorWeather->windSpeed())); + ui->m_gustSpeed->setText(QString("%1m/s").arg(lpOutdoorWeather->gustSpeed())); + ui->m_windDirection->setText(QString("%1°").arg(lpOutdoorWeather->windDirection())); + ui->m_rain->setText(QString("%1mm").arg(lpOutdoorWeather->rain())); + ui->m_batteryLow->setChecked(lpOutdoorWeather->batteryLow()); + ui->m_lastChange->setText(QString("%1s").arg(lpOutdoorWeather->lastChange())); + ui->m_apiVersion->setText(lpOutdoorWeather->apiVersion()); +// qDebug() << "Identifier Low Level Länge: " << lpOutdoorWeather->identifiersLengthLowLevel(); +// qDebug() << "Identifier Chunk Offset Low Level: " << lpOutdoorWeather->identifiersChunkOffsetLowLevel(); +// qDebug() << "Identifier Data Low Level: " << lpOutdoorWeather->identifiersChunkDataLowLevel(); +// qDebug() << "Identifier Länge: " << lpOutdoorWeather->identifiersLength(); +// qDebug() << "Identifier Chunk Offset: " << lpOutdoorWeather->identifiersChunkOffset(); +// qDebug() << "Identifier Data: " << lpOutdoorWeather->identifiersChunkData(); + ui->m_acknowledgeError->setText(QString("%1").arg(lpOutdoorWeather->errorCountAckChecksum())); + ui->m_messageError->setText(QString("%1").arg(lpOutdoorWeather->errorCountMessageChecksum())); + ui->m_frameError->setText(QString("%1").arg(lpOutdoorWeather->errorCountFrame())); + ui->m_overflowError->setText(QString("%1").arg(lpOutdoorWeather->errorCountOverflow())); + ui->m_bootloaderMode->setText(QString("%1").arg(lpOutdoorWeather->bootloaderMode())); + ui->m_statusLEDConfig->setText(QString("%1").arg(lpOutdoorWeather->statusLEDConfig())); + ui->m_chipTemperature->setText(QString("%1").arg(lpOutdoorWeather->chipTemperature())); +// qDebug() << "UID 1: " << lpOutdoorWeather->uid1(); + ui->m_connectedUID->setText(QString("%1").arg(lpOutdoorWeather->connectedUID())); + ui->m_position->setText(QString("%1").arg(lpOutdoorWeather->position())); + ui->m_hardwareVersion->setText(lpOutdoorWeather->hardwareVersion()); + ui->m_firmwareVersion->setText(lpOutdoorWeather->firmwareVersion()); + ui->m_deviceIdentifier->setText(QString("%1").arg(lpOutdoorWeather->deviceIdentifier())); + } + } +} diff --git a/cdisplayvalues.h b/cdisplayvalues.h new file mode 100644 index 0000000..f45be2d --- /dev/null +++ b/cdisplayvalues.h @@ -0,0 +1,31 @@ +#ifndef CDISPLAYVALUES_H +#define CDISPLAYVALUES_H + +#include +#include +#include + +#include "ctinkerforge.h" + + +class cMainWindow; + +class cDisplayValues : public QThread +{ + Q_OBJECT + +public: + cDisplayValues(cMainWindow* mainWindow, cTinkerForge* tinkerForge, QObject* object = nullptr); + + void execute(qint16 interval); + +private: + cMainWindow* m_mainWindow; + cTinkerForge* m_tinkerForge; +protected: + void timerEvent(QTimerEvent *event) override; +}; + +Q_DECLARE_METATYPE(cDisplayValues*) + +#endif // CDISPLAYVALUES_H diff --git a/cmainwindow.cpp b/cmainwindow.cpp index a3f1020..3855c26 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -8,28 +8,38 @@ cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::cMainWindow), m_tinkerForge(0), - m_airQuality(0) + m_airQuality(0), + m_displayValues(nullptr) { ui->setupUi(this); - m_tinkerForge = new cTinkerForge("192.168.0.208", 4223); - m_airQuality = new cAirQuality(m_tinkerForge, "QqD"); + m_tinkerForge = new cTinkerForge("192.168.0.208", 4223); + m_airQuality = new cAirQuality(m_tinkerForge, "QqD"); + m_outdoorWeather = new cOutdoorWeather(m_tinkerForge, "SwS", 84); - qDebug() << "Temperatur: " << m_airQuality->temperature(); - qDebug() << "Luftfeuchte: " << m_airQuality->humidity(); - qDebug() << "Luftdruck: " << m_airQuality->airPressure(); - qDebug() << "Index: " << m_airQuality->iaqIndex(); - qDebug() << "Genauigkeit: " << m_airQuality->iaqIndexAccuracy(); + m_tinkerForge->execute(5000); + + m_displayValues = new cDisplayValues(this, m_tinkerForge, this); + m_displayValues->execute(1000); } cMainWindow::~cMainWindow() { + m_tinkerForge->exit(); + if(m_airQuality) delete m_airQuality; + if(m_outdoorWeather) + delete m_outdoorWeather; + if(m_tinkerForge) delete m_tinkerForge; delete ui; } +Ui::cMainWindow* cMainWindow::getUI() +{ + return(ui); +} diff --git a/cmainwindow.h b/cmainwindow.h index 359b026..acca237 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -5,6 +5,9 @@ #include "ctinkerforge.h" #include "cairquality.h" +#include "coutdoorweather.h" + +#include "cdisplayvalues.h" QT_BEGIN_NAMESPACE @@ -19,10 +22,15 @@ public: cMainWindow(QWidget *parent = nullptr); ~cMainWindow(); + Ui::cMainWindow *getUI(); + private: Ui::cMainWindow *ui; cTinkerForge* m_tinkerForge; cAirQuality* m_airQuality; + cOutdoorWeather* m_outdoorWeather; + cDisplayValues* m_displayValues; }; + #endif // CMAINWINDOW_H diff --git a/cmainwindow.ui b/cmainwindow.ui index 7dddbe4..a8ab5f5 100644 --- a/cmainwindow.ui +++ b/cmainwindow.ui @@ -7,14 +7,331 @@ 0 0 800 - 600 + 480 cMainWindow - - + + + + + + Outdoor + + + + + + Values + + + + + + Wind Direction: + + + + + + + Temperature: + + + + + + + + + + Humidity: + + + + + + + + + + + + + Wind Speed: + + + + + + + Gust Speed: + + + + + + + + + + + + + Rain: + + + + + + + + + + + + + Error Count + + + + + + Overflow: + + + + + + + Message: + + + + + + + + + + Frame: + + + + + + + + + + Acknowledge: + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + System + + + + + + StatusLED Config: + + + + + + + Connected UID: + + + + + + + + + + Chip Temperature: + + + + + + + + + + + + + + + + + + + + + + Position: + + + + + + + API Version: + + + + + + + UID: + + + + + + + + + + Hardware Version: + + + + + + + true + + + + + + + Last Change: + + + + + + + Firmware Version: + + + + + + + Bootloader Mode: + + + + + + + true + + + + + + + + + + Device Identifier: + + + + + + + + + + + + + Station: + + + + + + + true + + + + + + + Last Error: + + + + + + + Battery Low + + + + + + + is Station + + + + + + + + + + + + + + + 0 + 0 + 800 + 21 + + + diff --git a/coutdoorweather.cpp b/coutdoorweather.cpp new file mode 100644 index 0000000..a4f7238 --- /dev/null +++ b/coutdoorweather.cpp @@ -0,0 +1,375 @@ +#include "coutdoorweather.h" +#include "ctinkerforge.h" + + +cOutdoorWeather::cOutdoorWeather(cTinkerForge* tinkerForge, const QString& uid, const quint8& station, bool isStation, QObject *object) : + QObject(object), + m_tinkerForge(tinkerForge), + m_uid(uid), + m_station(station), + m_isStation(isStation) +{ + if(!m_tinkerForge) + return; + + outdoor_weather_create(&m_outdoorWeather, m_uid.toLocal8Bit().data(), m_tinkerForge->connection()); + tinkerForge->add(this); +} + +cOutdoorWeather::~cOutdoorWeather() +{ + outdoor_weather_destroy(&m_outdoorWeather); +} + +qint32 cOutdoorWeather::collect() +{ + int16_t temperature; + uint8_t humidity; + uint32_t wind_speed; + uint32_t gust_speed; + uint32_t rain; + uint8_t wind_direction; + bool battery_low; + uint16_t last_change; + uint8_t api_version[3]; + uint8_t identifiers; + uint16_t identifiers_length; + uint16_t identifiers_chunk_offset; + uint8_t identifiers_chunk_data[60]; + uint32_t error_count_ack_checksum; + uint32_t error_count_message_checksum; + uint32_t error_count_frame; + uint32_t error_count_overflow; + uint8_t mode; + uint8_t config; + int16_t chip_temperature; + char uid[8]; + char connected_uid[8]; + char position; + uint8_t hardware_version[3]; + uint8_t firmware_version[3]; + uint16_t device_identifier; + + m_lastError = 0; + + if(m_isStation) + { + if(outdoor_weather_get_station_data(&m_outdoorWeather, m_station, &temperature, &humidity, &wind_speed, &gust_speed, &rain, &wind_direction, &battery_low, &last_change) >= 0) + { + m_temperature = (double)temperature/10.0; + m_humidity = (double)humidity/10.0; + m_windSpeed = (double)wind_speed/10.0; + m_gustSpeed = (double)gust_speed/10.0; + m_rain = (double)rain/10.0; + m_batteryLow = battery_low; + m_lastChange = last_change; + + if(wind_direction < 255) + m_windDirection = (double)wind_direction*22.5; + else + m_windDirection = -1.0; + } + else + { + m_lastError |= TEMPERATURE; + m_lastError |= HUMIDITY; + m_lastError |= WIND_SPEED; + m_lastError |= GUST_SPEED; + m_lastError |= WIND_DIRECTION; + m_lastError |= RAIN; + m_lastError |= BATTERY_LOW; + m_lastError |= LAST_CHANGE; + } + + if(outdoor_weather_get_station_identifiers_low_level(&m_outdoorWeather, &identifiers_length, &identifiers_chunk_offset, &identifiers_chunk_data[60]) >= 0) + { + m_identifiersChunkDataLowLevel.clear(); + m_identifiersLengthLowLevel = identifiers_length; + m_identifiersChunkOffsetLowLevel = identifiers_chunk_offset; + for(int x = 0;x < m_identifiersLengthLowLevel;x++) + m_identifiersChunkDataLowLevel.append(identifiers_chunk_data[x]); + } + else + { + m_lastError |= IDENTIFIERS_LENGTH_LOW_LEVEL; + m_lastError |= IDENTIFIERS_CHUNK_OFFSET_LOW_LEVEL; + m_lastError |= IDENTIFIERS_CHUNK_DATA_LOW_LEVEL; + } + + if(outdoor_weather_get_station_identifiers(&m_outdoorWeather, &identifiers, &identifiers_length) >= 0) + { + m_identifiersChunkData.clear(); + m_identifiersLength = identifiers_length; + m_identifiersChunkOffset = identifiers_chunk_offset; + for(int x = 0;x < m_identifiersLength;x++) + m_identifiersChunkData.append(identifiers_chunk_data[x]); + } + else + { + m_lastError |= IDENTIFIERS_LENGTH; + m_lastError |= IDENTIFIERS_CHUNK_OFFSET; + m_lastError |= IDENTIFIERS_CHUNK_DATA; + } + } + else + { + if(outdoor_weather_get_sensor_data(&m_outdoorWeather, m_station, &temperature, &humidity, &last_change) >= 0) + { + m_temperature = (double)temperature/10.0; + m_humidity = (double)humidity/10.0; + m_lastChange = last_change; + } + else + { + m_lastError |= TEMPERATURE; + m_lastError |= HUMIDITY; + m_lastError |= LAST_CHANGE; + } + + if(outdoor_weather_get_sensor_identifiers_low_level(&m_outdoorWeather, &identifiers_length, &identifiers_chunk_offset, &identifiers_chunk_data[60]) >= 0) + { + m_identifiersChunkDataLowLevel.clear(); + m_identifiersLengthLowLevel = identifiers_length; + m_identifiersChunkOffsetLowLevel = identifiers_chunk_offset; + for(int x = 0;x < m_identifiersLengthLowLevel;x++) + m_identifiersChunkDataLowLevel.append(identifiers_chunk_data[x]); + } + else + { + m_lastError |= IDENTIFIERS_LENGTH; + m_lastError |= IDENTIFIERS_CHUNK_OFFSET; + m_lastError |= IDENTIFIERS_CHUNK_DATA; + } + + if(outdoor_weather_get_sensor_identifiers(&m_outdoorWeather, &identifiers, &identifiers_length) >= 0) + { + m_identifiersChunkData.clear(); + m_identifiersLength = identifiers_length; + m_identifiersChunkOffset = identifiers_chunk_offset; + for(int x = 0;x < m_identifiersLength;x++) + m_identifiersChunkData.append(identifiers_chunk_data[x]); + } + else + { + m_lastError |= IDENTIFIERS_LENGTH; + m_lastError |= IDENTIFIERS_CHUNK_OFFSET; + m_lastError |= IDENTIFIERS_CHUNK_DATA; + } + } + + if(outdoor_weather_get_api_version(&m_outdoorWeather, api_version) >= 0) + m_apiVersion = QString("%1.%2.%3").arg(api_version[0]).arg(api_version[1]).arg(api_version[2]); + else + m_lastError |= API_VERSION; + + if(outdoor_weather_get_spitfp_error_count(&m_outdoorWeather, &error_count_ack_checksum, &error_count_message_checksum, &error_count_frame, &error_count_overflow) >= 0) + { + m_errorCountAckChecksum = error_count_ack_checksum; + m_errorCountMessageChecksum = error_count_message_checksum; + m_errorCountFrame = error_count_frame; + m_errorCountOverflow = error_count_overflow; + } + else + { + m_lastError |= ERROR_COUNT_ACK_CHECKSUM; + m_lastError |= ERROR_COUNT_MESSAGE_CHECKSUM; + m_lastError |= ERROR_COUNT_FRAME; + m_lastError |= ERROR_COUNT_OVERFLOW; + } + + if(outdoor_weather_get_bootloader_mode(&m_outdoorWeather, &mode) >= 0) + m_bootloaderMode = mode; + else + m_lastError |= BOOTLOADER_MODE; + + if(outdoor_weather_get_status_led_config(&m_outdoorWeather, &config) >= 0) + m_statusLEDConfig = config; + else + m_lastError |= STATUS_LED_CONFIG; + + if(outdoor_weather_get_chip_temperature(&m_outdoorWeather, &chip_temperature) >= 0) + m_chipTemperature = (double)chip_temperature; + else + m_lastError |= CHIP_TEMPERATURE; + + if(outdoor_weather_get_identity(&m_outdoorWeather, uid, connected_uid, &position, hardware_version, firmware_version, &device_identifier) >= 0) + { + m_uid1 = QString(uid); + m_connectedUID = QString(connected_uid); + m_position = QString(position); + m_hardwareVersion = QString("%1.%2.%3").arg(hardware_version[0]).arg(hardware_version[1]).arg(hardware_version[2]); + m_firmwareVersion = QString("%1.%2.%3").arg(firmware_version[0]).arg(firmware_version[1]).arg(firmware_version[2]); + m_deviceIdentifier = device_identifier; + } + else + { + m_lastError |= UID; + m_lastError |= CONNECTED_UID; + m_lastError |= POSITION; + m_lastError |= HARDWARE_VERSION; + m_lastError |= FIRMWARE_VERSION; + m_lastError |= DEVICE_IDENTIFIER; + } + + return(m_lastError); +} + +QString cOutdoorWeather::uid() +{ + return(m_uid); +} + +quint8 cOutdoorWeather::station() +{ + return(m_station); +} + +bool cOutdoorWeather::isStation() +{ + return(m_isStation); +} + +qint32 cOutdoorWeather::lastError() +{ + return(m_lastError); +} + +double cOutdoorWeather::temperature() +{ + return(m_temperature); +} + +double cOutdoorWeather::humidity() +{ + return(m_humidity); +} + +double cOutdoorWeather::windSpeed() +{ + return(m_windSpeed); +} + +double cOutdoorWeather::gustSpeed() +{ + return(m_gustSpeed); +} + +double cOutdoorWeather::windDirection() +{ + return(m_windDirection); +} + +double cOutdoorWeather::rain() +{ + return(m_rain); +} + +bool cOutdoorWeather::batteryLow() +{ + return(m_batteryLow); +} + +qint16 cOutdoorWeather::lastChange() +{ + return(m_lastChange); +} + +QString cOutdoorWeather::apiVersion() +{ + return(m_apiVersion); +} + +quint16 cOutdoorWeather::identifiersLengthLowLevel() +{ + return(m_identifiersLengthLowLevel); +} + +quint16 cOutdoorWeather::identifiersChunkOffsetLowLevel() +{ + return(m_identifiersChunkOffsetLowLevel); +} + +QList cOutdoorWeather::identifiersChunkDataLowLevel() +{ + return(m_identifiersChunkDataLowLevel); +} + +quint16 cOutdoorWeather::identifiersLength() +{ + return(m_identifiersLength); +} + +quint16 cOutdoorWeather::identifiersChunkOffset() +{ + return(m_identifiersChunkOffset); +} + +QList cOutdoorWeather::identifiersChunkData() +{ + return(m_identifiersChunkData); +} + +quint32 cOutdoorWeather::errorCountAckChecksum() +{ + return(m_errorCountAckChecksum); +} + +quint32 cOutdoorWeather::errorCountMessageChecksum() +{ + return(m_errorCountMessageChecksum); +} + +quint32 cOutdoorWeather::errorCountFrame() +{ + return(m_errorCountFrame); +} + +quint32 cOutdoorWeather::errorCountOverflow() +{ + return(m_errorCountOverflow); +} + +quint8 cOutdoorWeather::bootloaderMode() +{ + return(m_bootloaderMode); +} + +quint8 cOutdoorWeather::statusLEDConfig() +{ + return(m_statusLEDConfig); +} + +double cOutdoorWeather::chipTemperature() +{ + return(m_chipTemperature); +} + +QString cOutdoorWeather::uid1() +{ + return(m_uid1); +} + +QString cOutdoorWeather::connectedUID() +{ + return(m_connectedUID); +} + +QString cOutdoorWeather::position() +{ + return(m_position); +} + +QString cOutdoorWeather::hardwareVersion() +{ + return(m_hardwareVersion); +} + +QString cOutdoorWeather::firmwareVersion() +{ + return(m_firmwareVersion); +} + +quint16 cOutdoorWeather::deviceIdentifier() +{ + return(m_deviceIdentifier); +} diff --git a/coutdoorweather.h b/coutdoorweather.h new file mode 100644 index 0000000..248394a --- /dev/null +++ b/coutdoorweather.h @@ -0,0 +1,127 @@ +#ifndef COUTDOORWEATHER_H +#define COUTDOORWEATHER_H + + +#include "tinkerforge/bricklet_outdoor_weather.h" + +#include +#include + + +class cTinkerForge; + +class cOutdoorWeather : public QObject +{ + Q_OBJECT + +public: + enum errorCode + { + TEMPERATURE = 0x00000001, + HUMIDITY = 0x00000002, + WIND_SPEED = 0x00000004, + GUST_SPEED = 0x00000008, + WIND_DIRECTION = 0x00000010, + RAIN = 0x00000020, + BATTERY_LOW = 0x00000040, + LAST_CHANGE = 0x00000080, + API_VERSION = 0x00000020, + IDENTIFIERS_LENGTH_LOW_LEVEL = 0x00000040, + IDENTIFIERS_CHUNK_OFFSET_LOW_LEVEL = 0x00000080, + IDENTIFIERS_CHUNK_DATA_LOW_LEVEL = 0x00000100, + IDENTIFIERS_LENGTH = 0x00000200, + IDENTIFIERS_CHUNK_OFFSET = 0x00000400, + IDENTIFIERS_CHUNK_DATA = 0x00000800, + ERROR_COUNT_ACK_CHECKSUM = 0x00010000, + ERROR_COUNT_MESSAGE_CHECKSUM = 0x00020000, + ERROR_COUNT_FRAME = 0x00040000, + ERROR_COUNT_OVERFLOW = 0x00080000, + BOOTLOADER_MODE = 0x00100000, + STATUS_LED_CONFIG = 0x00200000, + CHIP_TEMPERATURE = 0x00400000, + UID = 0x00800000, + CONNECTED_UID = 0x01000000, + POSITION = 0x02000000, + HARDWARE_VERSION = 0x04000000, + FIRMWARE_VERSION = 0x08000000, + DEVICE_IDENTIFIER = 0x10000000, + }; + + cOutdoorWeather(cTinkerForge* tinkerForge, const QString& uid, const quint8 &station, bool isStation = true, QObject* object = nullptr); + ~cOutdoorWeather(); + + qint32 collect(); + + QString uid(); + quint8 station(); + bool isStation(); + qint32 lastError(); + double temperature(); + double humidity(); + double windSpeed(); + double gustSpeed(); + double windDirection(); + double rain(); + bool batteryLow(); + qint16 lastChange(); + QString apiVersion(); + quint16 identifiersLengthLowLevel(); + quint16 identifiersChunkOffsetLowLevel(); + QList identifiersChunkDataLowLevel(); + quint16 identifiersLength(); + quint16 identifiersChunkOffset(); + QList identifiersChunkData(); + quint32 errorCountAckChecksum(); + quint32 errorCountMessageChecksum(); + quint32 errorCountFrame(); + quint32 errorCountOverflow(); + quint8 bootloaderMode(); + quint8 statusLEDConfig(); + double chipTemperature(); + QString uid1(); + QString connectedUID(); + QString position(); + QString hardwareVersion(); + QString firmwareVersion(); + quint16 deviceIdentifier(); + +private: + cTinkerForge* m_tinkerForge; + QString m_uid; + quint8 m_station; + bool m_isStation; + qint32 m_lastError; + OutdoorWeather m_outdoorWeather; + double m_temperature; + double m_humidity; + double m_windSpeed; + double m_gustSpeed; + double m_rain; + double m_windDirection; + bool m_batteryLow; + qint16 m_lastChange; + QString m_apiVersion; + quint16 m_identifiersLengthLowLevel; + quint16 m_identifiersChunkOffsetLowLevel; + QList m_identifiersChunkDataLowLevel; + quint16 m_identifiersLength; + quint16 m_identifiersChunkOffset; + QList m_identifiersChunkData; + quint32 m_errorCountAckChecksum; + quint32 m_errorCountMessageChecksum; + quint32 m_errorCountFrame; + quint32 m_errorCountOverflow; + quint8 m_bootloaderMode; + quint8 m_statusLEDConfig; + double m_chipTemperature; + QString m_uid1; + QString m_connectedUID; + QString m_position; + QString m_hardwareVersion; + QString m_firmwareVersion; + quint16 m_deviceIdentifier; +}; + +Q_DECLARE_METATYPE(cOutdoorWeather*) + +#endif // COUTDOORWEATHER_H diff --git a/ctinkerforge.cpp b/ctinkerforge.cpp index 9f75301..a4c5af0 100644 --- a/ctinkerforge.cpp +++ b/ctinkerforge.cpp @@ -1,7 +1,10 @@ #include "ctinkerforge.h" +#include -cTinkerForge::cTinkerForge(const QString& host, const int& port) + +cTinkerForge::cTinkerForge(const QString& host, const int& port, QObject* object) : + QThread(object) { ipcon_create(&m_ipConnection); @@ -15,7 +18,47 @@ cTinkerForge::~cTinkerForge() ipcon_destroy(&m_ipConnection); } +void cTinkerForge::collect() +{ + for(int x = 0;x < m_brickList.count();x++) + { + cAirQuality* lpAirQuality = m_brickList[x].value(); + cOutdoorWeather* lpOutdoorWeather = m_brickList[x].value(); + + if(lpAirQuality) + lpAirQuality->collect(); + else if(lpOutdoorWeather) + lpOutdoorWeather->collect(); + } +} + +void cTinkerForge::timerEvent(QTimerEvent */*event*/) +{ + collect(); +} + IPConnection* cTinkerForge::connection() { return(&m_ipConnection); } + +void cTinkerForge::add(cAirQuality* lpAirQuality) +{ + m_brickList.append(QVariant::fromValue(lpAirQuality)); +} + +void cTinkerForge::add(cOutdoorWeather* lpOutdoorWeather) +{ + m_brickList.append(QVariant::fromValue(lpOutdoorWeather)); +} + +void cTinkerForge::execute(qint16 interval) +{ + collect(); + startTimer(interval); +} + +QList cTinkerForge::brickList() +{ + return(m_brickList); +} diff --git a/ctinkerforge.h b/ctinkerforge.h index 60ef466..16a8d98 100644 --- a/ctinkerforge.h +++ b/ctinkerforge.h @@ -4,18 +4,46 @@ #include "tinkerforge/ip_connection.h" +#include "cairquality.h" +#include "coutdoorweather.h" + +#include #include +#include +#include + +#include +#include -class cTinkerForge +class cTinkerForge : public QThread { + Q_OBJECT + public: - cTinkerForge(const QString& host, const int &port); + cTinkerForge(const QString& host, const int &port, QObject* object = nullptr); ~cTinkerForge(); IPConnection* connection(); + + void add(cAirQuality* lpAirQuality); + void add(cOutdoorWeather* lpOutdoorWeather); + + void execute(qint16 interval); + + QList brickList(); + private: IPConnection m_ipConnection; + QList m_brickList; + + void collect(); + +protected: + void timerEvent(QTimerEvent *event) override; }; +Q_DECLARE_METATYPE(cTinkerForge*) + + #endif // CTINKERFORGE_H diff --git a/weatherStation.pro b/weatherStation.pro index bdd8f43..6ed1a71 100644 --- a/weatherStation.pro +++ b/weatherStation.pro @@ -10,6 +10,8 @@ CONFIG += c++11 SOURCES += \ cairquality.cpp \ + cdisplayvalues.cpp \ + coutdoorweather.cpp \ ctinkerforge.cpp \ main.cpp \ cmainwindow.cpp \ @@ -20,7 +22,9 @@ SOURCES += \ HEADERS += \ cairquality.h \ + cdisplayvalues.h \ cmainwindow.h \ + coutdoorweather.h \ ctinkerforge.h \ tinkerforge/brick_master.h \ tinkerforge/bricklet_air_quality.h \