diff --git a/i2cdevices/i2cdevices.pro b/i2cdevices/i2cdevices.pro index b6b22cbd..4fd043c3 100644 --- a/i2cdevices/i2cdevices.pro +++ b/i2cdevices/i2cdevices.pro @@ -3,10 +3,12 @@ include(../plugins.pri) HEADERS += \ integrationplugini2cdevices.h \ ads1115channel.h \ - pi16adcchannel.h + pi16adcchannel.h \ + sht30.h SOURCES += \ integrationplugini2cdevices.cpp \ ads1115channel.cpp \ - pi16adcchannel.cpp + pi16adcchannel.cpp \ + sht30.cpp diff --git a/i2cdevices/integrationplugini2cdevices.cpp b/i2cdevices/integrationplugini2cdevices.cpp index e3f3b0b6..727d809a 100644 --- a/i2cdevices/integrationplugini2cdevices.cpp +++ b/i2cdevices/integrationplugini2cdevices.cpp @@ -33,6 +33,7 @@ #include "pi16adcchannel.h" #include "ads1115channel.h" +#include "sht30.h" #include @@ -117,6 +118,18 @@ void IntegrationPluginI2CDevices::discoverThings(ThingDiscoveryInfo *info) info->addThingDescriptor(descriptor); } } + + if (info->thingClassId() == sht3xThingClassId) { + // The SHT3x has selectable addresses 0x44 or 0x45 + if (scanResult.address == 0x44 || scanResult.address == 0x45) { + ThingDescriptor descriptor(sht3xThingClassId, "SHT3x HT Sensor", QString("%1: 0x%2").arg(scanResult.portName).arg(scanResult.address, 0, 16)); + ParamList params; + params << Param(sht3xThingI2cPortParamTypeId, scanResult.portName); + params << Param(sht3xThingI2cAddressParamTypeId, scanResult.address); + descriptor.setParams(params); + info->addThingDescriptor(descriptor); + } + } } info->finish(Thing::ThingErrorNoError); @@ -200,6 +213,30 @@ void IntegrationPluginI2CDevices::setupThing(ThingSetupInfo *info) } info->finish(Thing::ThingErrorNoError); } + + if (info->thing()->thingClassId() == sht3xThingClassId) { + + QString i2cPortName = info->thing()->paramValue(sht3xThingI2cPortParamTypeId).toString(); + int i2cAddress = info->thing()->paramValue(sht3xThingI2cAddressParamTypeId).toInt(); + Q_UNUSED(i2cAddress) + + SHT30 *sht3x = new SHT30(i2cPortName, i2cAddress, this); + if (!hardwareManager()->i2cManager()->open(sht3x)) { + delete sht3x; + info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Failed to open I2C port.")); + return; + } + + Thing *thing = info->thing(); + connect(sht3x, &SHT30::measurementAvailable, thing, [thing](double temperature, double humidity){ + thing->setStateValue(sht3xTemperatureStateTypeId, temperature); + thing->setStateValue(sht3xHumidityStateTypeId, humidity); + }); + + hardwareManager()->i2cManager()->startReading(sht3x, 5000); + m_i2cDevices.insert(sht3x, thing); + info->finish(Thing::ThingErrorNoError); + } } void IntegrationPluginI2CDevices::thingRemoved(Thing *thing) diff --git a/i2cdevices/integrationplugini2cdevices.json b/i2cdevices/integrationplugini2cdevices.json index 1f2105a3..3b46acf0 100644 --- a/i2cdevices/integrationplugini2cdevices.json +++ b/i2cdevices/integrationplugini2cdevices.json @@ -451,6 +451,59 @@ ] } ] + }, + { + "id": "168bdbec-56b7-4eaf-bda8-0c5846a79c07", + "name": "sensirion", + "displayName": "Sensirion", + "thingClasses": [ + { + "id": "0e05888f-bc77-408d-bc31-cd1cba720c2d", + "name": "sht3x", + "displayName": "SHT3x HT Sensor", + "createMethods": ["discovery"], + "interfaces": [ "temperaturesensor", "humiditysensor" ], + "setupMethod": "justAdd", + "paramTypes": [ + { + "id": "e0cec363-9679-4347-8bb4-b30f9ab72ae8", + "name": "i2cPort", + "displayName": "I2C port", + "type": "QString" + }, + { + "id": "7b83703b-210e-42ae-ab33-878bf1e358a5", + "name": "i2cAddress", + "displayName": "I2C address", + "type": "int" + } + ], + "stateTypes": [ + { + "id": "6d536826-9938-4457-901f-f4cc401edcc8", + "name": "temperature", + "displayName": "Temperature", + "displayNameEvent": "Temperature changed", + "type": "double", + "unit": "DegreeCelsius", + "defaultValue": 0, + "filter": "adaptive" + }, + { + "id": "6722a1f5-10c8-4bc7-b921-c10fe45aefe8", + "name": "humidity", + "displayName": "Humidity", + "displayNameEvent": "Humidity changed", + "type": "double", + "unit": "Percentage", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0, + "filter": "adaptive" + } + ] + } + ] } ] } diff --git a/i2cdevices/sht30.cpp b/i2cdevices/sht30.cpp new file mode 100644 index 00000000..ac41c78f --- /dev/null +++ b/i2cdevices/sht30.cpp @@ -0,0 +1,72 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project 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 project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "sht30.h" +#include "extern-plugininfo.h" + +#include +#include + +SHT30::SHT30(const QString &portName, int address, QObject *parent) : + I2CDevice(portName, address, parent) +{ + +} + +QByteArray SHT30::readData(int fileDescriptor) +{ + // Send measurement command: 0x2C + // High repeatability measurement: 0x06 + char config[2] = {0}; + config[0] = 0x2C; + config[1] = 0x06; + if (write(fileDescriptor, config, 2) != 2) { + qCWarning(dcI2cDevices()) << "SHT30: could not configure sensor."; + QThread::msleep(500); + return QByteArray(); + } + QThread::msleep(500); + + // Read 6 bytes of data + // Temperature msb, Temperature lsb, Temperature CRC, Humididty msb, Humidity lsb, Humidity CRC + char data[6] = {0}; + if (read(fileDescriptor, data, 6) != 6) { + qCWarning(dcI2cDevices()) << "SHT30: could not read sensor values."; + QThread::msleep(500); + return QByteArray(); + } + + // Convert the data + int temperatureRaw = (data[0] << 8) | data[1]; + double temperature = -45 + (175 * temperatureRaw / 65535.0); + double humidity = 100 * ((data[3] << 8) | data[4]) / 65535.0; + emit measurementAvailable(temperature, humidity); + return QByteArray(data, 6); +} diff --git a/i2cdevices/sht30.h b/i2cdevices/sht30.h new file mode 100644 index 00000000..844ccd94 --- /dev/null +++ b/i2cdevices/sht30.h @@ -0,0 +1,51 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project 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 project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef SHT30_H +#define SHT30_H + +#include + +#include + +class SHT30 : public I2CDevice +{ + Q_OBJECT +public: + explicit SHT30(const QString &portName, int address, QObject *parent = nullptr); + + QByteArray readData(int fileDescriptor) override; + +signals: + void measurementAvailable(double temperature, double humidity); + +}; + +#endif // SHT30_H