added dimmer switch

master
Bernhard Trinnes 2018-06-12 21:47:48 +02:00 committed by Michael Zanetti
parent 7ce42f2eca
commit 6a5ff5f8cc
6 changed files with 333 additions and 43 deletions

View File

@ -104,6 +104,17 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device)
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == dimmerSwitchDeviceClassId) {
m_usedDigitalInputs.insert(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString(), device);
DimmerSwitch* dimmerSwitch = new DimmerSwitch(this);
connect(dimmerSwitch, &DimmerSwitch::pressed, this, &DevicePluginUniPi::onDimmerSwitchPressed);
connect(dimmerSwitch, &DimmerSwitch::longPressed, this, &DevicePluginUniPi::onDimmerSwitchLongPressed);
connect(dimmerSwitch, &DimmerSwitch::doublePressed, this, &DevicePluginUniPi::onDimmerSwitchDoublePressed);
connect(dimmerSwitch, &DimmerSwitch::dimValueChanged, this, &DevicePluginUniPi::onDimmerSwitchDimValueChanged);
m_dimmerSwitches.insert(dimmerSwitch, device);
}
return DeviceManager::DeviceSetupStatusFailure;
}
@ -287,7 +298,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI
if (m_usedRelais.contains(circuit)){
continue;
}
DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit);
DeviceDescriptor descriptor(deviceClassId, "Light", QString("Relay %1").arg(circuit));
ParamList parameters;
parameters.append(Param(lightOutputParamTypeId, circuit));
parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::relay));
@ -302,7 +313,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI
if (m_usedDigitalOutputs.contains(circuit)){
continue;
}
DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit);
DeviceDescriptor descriptor(deviceClassId, "Light", QString("Digital output %1").arg(circuit));
ParamList parameters;
parameters.append(Param(lightOutputParamTypeId, circuit));
parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::digitalOutput));
@ -312,6 +323,26 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI
emit devicesDiscovered(deviceClassId, deviceDescriptors);
return DeviceManager::DeviceErrorAsync;
}
if (deviceClassId == dimmerSwitchDeviceClassId) {
// Create the list of available digital inputs
QList<DeviceDescriptor> deviceDescriptors;
for (int i = 0; i < m_digitalInputs.count(); i++) {
const QString circuit = m_digitalInputs.at(i);
// Offer only digital inputs which arn't in use already
if (m_usedDigitalInputs.contains(circuit)){
continue;
}
DeviceDescriptor descriptor(deviceClassId, "Dimmer switch", QString("Digital Input %1").arg(circuit));
ParamList parameters;
parameters.append(Param(digitalInputDigitalInputNumberParamTypeId, circuit));
descriptor.setParams(parameters);
deviceDescriptors.append(descriptor);
}
emit devicesDiscovered(deviceClassId, deviceDescriptors);
return DeviceManager::DeviceErrorAsync;
}
}
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
@ -355,11 +386,11 @@ void DevicePluginUniPi::deviceRemoved(Device *device)
} else if(device->deviceClassId() == digitalOutputDeviceClassId) {
m_usedDigitalOutputs.remove(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString());
} else if(device->deviceClassId() == digitalInputDeviceClassId) {
m_usedDigitalOutputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString());
m_usedDigitalInputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString());
} else if (device->deviceClassId() == analogOutputDeviceClassId) {
m_usedDigitalOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString());
m_usedAnalogOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString());
} else if (device->deviceClassId() == analogInputDeviceClassId) {
m_usedDigitalOutputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString());
m_usedAnalogInputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString());
} else if (device->deviceClassId() == shutterDeviceClassId) {
if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) {
@ -380,6 +411,9 @@ void DevicePluginUniPi::deviceRemoved(Device *device)
} else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) {
m_usedDigitalOutputs.remove(device->paramValue(lightOutputParamTypeId).toString());
}
} else if (device->deviceClassId() == dimmerSwitchDeviceClassId) {
m_usedDigitalInputs.remove(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString());
m_dimmerSwitches.remove(m_dimmerSwitches.key(device));
}
if (myDevices().isEmpty()) {
@ -393,9 +427,9 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons
if (device->deviceClassId() == relayOutputDeviceClassId) {
if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) {
if (action.actionTypeId() == relayOutputPowerActionTypeId) {
QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString();
int stateValue = action.param(relayOutputRelayStatusActionParamTypeId).value().toInt();
int stateValue = action.param(relayOutputPowerActionParamTypeId).value().toInt();
setOutput(relayNumber, stateValue);
return DeviceManager::DeviceErrorNoError;
@ -403,11 +437,10 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons
return DeviceManager::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == digitalOutputDeviceClassId) {
if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) {
if (action.actionTypeId() == digitalOutputPowerActionTypeId) {
QString digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString();
bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool();
bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool();
setOutput(digitalOutputNumber, stateValue);
return DeviceManager::DeviceErrorNoError;
@ -464,7 +497,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons
if (device->deviceClassId() == lightDeviceClassId) {
QString circuit = device->paramValue(lightOutputParamTypeId).toString();
bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool();
bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool();
setOutput(circuit, stateValue);
return DeviceManager::DeviceErrorNoError;
@ -535,13 +568,10 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
//New Device detected
m_relais.append(circuit);
} else {
foreach (Device *device, myDevices()) {
if (m_usedRelais.contains(circuit)) {
Device *device = m_usedRelais.value(circuit);
if (device->deviceClassId() == relayOutputDeviceClassId) {
if (circuit == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) {
device->setStateValue(relayOutputRelayStatusStateTypeId, value);
break;
}
device->setStateValue(relayOutputPowerStateTypeId, value);
} else if (device->deviceClassId() == shutterDeviceClassId) {
if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) {
if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) {
@ -551,8 +581,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
} else {
qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString();
}
break;
}
if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) {
if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) {
@ -566,10 +594,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
}
} else if (device->deviceClassId() == lightDeviceClassId) {
if (circuit == device->paramValue(lightOutputParamTypeId).toString()) {
device->setStateValue(lightPowerStateTypeId, value);
break;
}
device->setStateValue(lightPowerStateTypeId, value);
}
}
}
@ -578,13 +603,32 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
//New Device detected
m_digitalOutputs.append(obj["circuit"].toString());
} else {
foreach (Device *device, myDevices()) {
if (m_usedDigitalOutputs.contains(obj["circuit"].toString())) {
Device *device = m_usedDigitalOutputs.value(obj["circuit"].toString());
if (device->deviceClassId() == digitalOutputDeviceClassId) {
if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) {
device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool());
device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool());
} else if (device->deviceClassId() == shutterDeviceClassId) {
if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) {
if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) {
device->setStateValue(shutterStatusStateTypeId, "close");
} else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) {
device->setStateValue(shutterStatusStateTypeId, "stop");
} else {
qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString();
}
}
if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) {
if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) {
device->setStateValue(shutterStatusStateTypeId, "close");
} else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) {
device->setStateValue(shutterStatusStateTypeId, "stop");
} else {
qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString();
}
break;
}
} else if (device->deviceClassId() == lightDeviceClassId) {
device->setStateValue(lightPowerStateTypeId, QVariant(obj["value"].toInt()).toBool());
}
}
}
@ -598,13 +642,15 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
//New Device detected
m_digitalInputs.append(obj["circuit"].toString());
} else {
foreach (Device *device, myDevices()) {
if (m_usedDigitalInputs.contains(obj["circuit"].toString())) {
bool value = QVariant(obj["value"].toInt()).toBool();
Device *device = m_usedDigitalInputs.value(obj["circuit"].toString());
if (device->deviceClassId() == digitalInputDeviceClassId) {
if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) {
device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool());
break;
}
device->setStateValue(digitalInputDigitalInputStatusStateTypeId, value);
} else if (device->deviceClassId() == dimmerSwitchDeviceClassId) {
device->setStateValue(dimmerSwitchStatusStateTypeId, value);
DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device);
dimmerSwitch->setPower(value);
}
}
}
@ -648,7 +694,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
}
}
if (obj["dev"] == "led") {
if (obj["dev"] == "led") { //TODO cant discover leds without toggling it from another client
qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt();
if (!m_leds.contains(obj["circuit"].toString())){
@ -657,7 +703,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
}
}
if (obj["dev"] == "sensor") {
if (obj["dev"] == "sensor") { //TODO not yet implemented
qCDebug(dcUniPi()) << "Sensor:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt();
if (!m_sensors.contains(obj["circuit"].toString())){
@ -672,3 +718,31 @@ void DevicePluginUniPi::onRefreshTimer()
{
connectToEvok();
}
void DevicePluginUniPi::onDimmerSwitchPressed()
{
DimmerSwitch *dimmerSwitch = static_cast<DimmerSwitch *>(sender());
Device *device = m_dimmerSwitches.value(dimmerSwitch);
emit emitEvent(Event(dimmerSwitchPressedEventTypeId, device->id()));
}
void DevicePluginUniPi::onDimmerSwitchLongPressed()
{
DimmerSwitch *dimmerSwitch = static_cast<DimmerSwitch *>(sender());
Device *device = m_dimmerSwitches.value(dimmerSwitch);
emit emitEvent(Event(dimmerSwitchLongPressedEventTypeId, device->id()));
}
void DevicePluginUniPi::onDimmerSwitchDoublePressed()
{
DimmerSwitch *dimmerSwitch = static_cast<DimmerSwitch *>(sender());
Device *device = m_dimmerSwitches.value(dimmerSwitch);
emit emitEvent(Event(dimmerSwitchDoublePressedEventTypeId, device->id()));
}
void DevicePluginUniPi::onDimmerSwitchDimValueChanged(int dimValue)
{
DimmerSwitch *dimmerSwitch = static_cast<DimmerSwitch *>(sender());
Device *device = m_dimmerSwitches.value(dimmerSwitch);
device->setStateValue(dimmerSwitchDimValueStateTypeId, dimValue);
}

View File

@ -28,6 +28,7 @@
#include "devicemanager.h"
#include <QtWebSockets/QtWebSockets>
#include "plugintimer.h"
#include "dimmerswitch.h"
class DevicePluginUniPi : public DevicePlugin
{
@ -66,6 +67,8 @@ private:
QHash<QString, Device*> m_usedSensors;
QHash<QString, Device*> m_usedLeds;
QHash<DimmerSwitch *, Device*> m_dimmerSwitches;
QList<QString> m_relais;
QList<QString> m_digitalOutputs;
QList<QString> m_digitalInputs;
@ -86,6 +89,11 @@ private slots:
void onWebSocketDisconnected();
void onWebSocketTextMessageReceived(QString message);
void onRefreshTimer();
void onDimmerSwitchPressed();
void onDimmerSwitchLongPressed();
void onDimmerSwitchDoublePressed();
void onDimmerSwitchDimValueChanged(int dimValue);
};
#endif // DEVICEPLUGINUNIPI_H

View File

@ -23,7 +23,7 @@
"displayName": "Relay output",
"deviceIcon": "Power",
"createMethods": ["discovery"],
"interfaces": [ ],
"interfaces": ["power"],
"basicTags": ["Device"],
"paramTypes": [
{
@ -36,8 +36,8 @@
"stateTypes": [
{
"id": "f9c01e7b-0523-4cac-905a-d5b20028e021",
"name": "relayStatus",
"displayName": "Relay",
"name": "power",
"displayName": "Power",
"displayNameEvent": "Relay power changed",
"displayNameAction": "Set relay power",
"type": "bool",
@ -73,13 +73,66 @@
}
]
},
{
"id": "71e03d00-1b62-412b-b55d-ab90ad2eddff",
"name": "dimmerSwitch",
"displayName": "Dimmer switch",
"deviceIcon": "Switch",
"createMethods": ["discovery"],
"interfaces": ["longpressbutton"],
"basicTags": ["Sensor"],
"paramTypes": [
{
"id": "2344dedb-3e21-4f59-a016-0fc6233a38ac",
"name": "inputNumber",
"displayName": "Input number",
"type": "QString"
}
],
"stateTypes": [
{
"id": "b39a84ff-45c8-4ec1-b3a9-b99aeefc7221",
"name": "status",
"displayName": "Digital input",
"displayNameEvent": "Digital input changed",
"type": "bool",
"defaultValue": false
},
{
"id": "3e566b7c-11e6-4e97-9d9f-9636c465639e",
"name": "dimValue",
"displayName": "Dim value",
"displayNameEvent": "Dim value changed",
"type": "int",
"defaultValue": 0,
"unit": "Percentage"
}
],
"eventTypes": [
{
"id": "44be91cd-cbeb-477b-bb8c-6a6d4f9aaaf3",
"name": "pressed",
"displayName": "Pressed"
},
{
"id": "a4748afe-dcd6-45ea-8574-7b9c0e925f35",
"name": "longPressed",
"displayName": "Long pressed"
},
{
"id": "7e7b36f5-b871-43a3-a7f0-6cef1e550ad7",
"name": "doublePressed",
"displayName": "Double pressed"
}
]
},
{
"id": "f3a3c5ed-461a-4ca8-930b-df3af821b9e0",
"name": "digitalOutput",
"displayName": "Digital output",
"deviceIcon": "Power",
"createMethods": ["discovery"],
"interfaces": [ ],
"interfaces": ["power"],
"basicTags": ["Device"],
"paramTypes": [
{
@ -92,8 +145,8 @@
"stateTypes": [
{
"id": "470a0e30-a170-47ed-9ed3-c41db919555f",
"name": "digitalOutputStatus",
"displayName": "digital output",
"name": "power",
"displayName": "Power",
"displayNameAction": "set digital output",
"displayNameEvent": "digital output changed",
"type": "bool",
@ -266,6 +319,30 @@
"writable": true
}
]
},
{
"id": "fe3d7d2f-3cee-4f2b-b6f8-4381ff1a2825",
"name": "temperatureSensor",
"displayName": "1-Wire Temperature Sensor",
"deviceIcon": "Thermometer",
"createMethods": ["discovery"],
"interfaces": ["temperaturesensor"],
"basicTags": ["Actuator"],
"paramTypes": [
{
}
],
"stateTypes":[
{
"id": "a11e8108-d16e-4972-820a-f3611ba6fe24",
"name": "temperature",
"displayName": "Temperature",
"displayNameEvent": "Temperature changed",
"type": "double",
"defaultValue": 0,
"unit": "DegreeCelsius"
}
]
}
]
}

87
unipi/dimmerswitch.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "dimmerswitch.h"
DimmerSwitch::DimmerSwitch(QObject *parent) : QObject(parent)
{
m_longPressedTimer = new QTimer(this);
m_longPressedTimer->setSingleShot(true);
connect(m_longPressedTimer, SIGNAL(timeout()), this, SLOT(onLongPressedTimeout()));
m_doublePressedTimer = new QTimer(this);
m_doublePressedTimer->setSingleShot(true);
m_dimmerTimer = new QTimer(this);
connect(m_dimmerTimer, SIGNAL(timeout()), this, SLOT(onDimmerTimeout()));
}
DimmerSwitch::~DimmerSwitch()
{
m_longPressedTimer->deleteLater();
m_doublePressedTimer->deleteLater();
m_dimmerTimer->deleteLater();
}
void DimmerSwitch::setPower(const bool power)
{
if (m_power == power) {
return;
}
m_power = power;
if(power){
m_dimmerTimer->start(150);
m_longPressedTimer->start(2000);
if (m_doublePressedTimer->isActive()) {
m_doublePressedTimer->stop();
emit doublePressed();
} else {
m_doublePressedTimer->start(1000);
emit pressed();
}
} else {
m_dimmerTimer->stop();
m_longPressedTimer->stop();
}
}
bool DimmerSwitch::getPower()
{
return m_power;
}
void DimmerSwitch::setDimValue(const int dimValue)
{
m_dimValue = dimValue;
emit dimValueChanged(m_dimValue);
}
int DimmerSwitch::getDimValue()
{
return m_dimValue;
}
void DimmerSwitch::onDimmerTimeout()
{
if (m_countingUp) {
m_dimValue += 3;
if(m_dimValue >= 100) {
m_dimValue = 100;
m_countingUp = false;
}
} else {
m_dimValue -= 3;
if(m_dimValue <= 0) {
m_dimValue = 0;
m_countingUp = true;
}
}
emit dimValueChanged(m_dimValue);
}
void DimmerSwitch::onLongPressedTimeout()
{
emit longPressed();
}

42
unipi/dimmerswitch.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef DIMMERSWITCH_H
#define DIMMERSWITCH_H
#include <QObject>
#include <QTimer>
class DimmerSwitch : public QObject
{
Q_OBJECT
public:
explicit DimmerSwitch(QObject *parent = 0);
~DimmerSwitch();
void setPower(const bool power);
bool getPower();
void setDimValue(const int dimValue);
int getDimValue();
QTimer *m_doublePressedTimer = nullptr;
QTimer *m_longPressedTimer = nullptr;
QTimer *m_dimmerTimer = nullptr;
private:
bool m_power;
int m_dimValue = 0;
bool m_countingUp = true;
bool m_powerWasLow = false; //flag to indicate the power was low within the double pressed time frame
signals:
void pressed();
void longPressed();
void doublePressed();
void dimValueChanged(int dimValue);
private slots:
void onLongPressedTimeout();
void onDimmerTimeout();
};
#endif // DIMMERSWITCH_H

View File

@ -3,9 +3,11 @@ include(../plugins.pri)
TARGET = $$qtLibraryTarget(nymea_devicepluginunipi)
SOURCES += \
devicepluginunipi.cpp
devicepluginunipi.cpp \
dimmerswitch.cpp
HEADERS += \
devicepluginunipi.h
devicepluginunipi.h \
dimmerswitch.h