Add speedwire test interface
This commit is contained in:
parent
2b3a44cd6c
commit
cd9c048ebd
@ -84,8 +84,23 @@ void IntegrationPluginSma::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
info->addThingDescriptors(descriptors);
|
info->addThingDescriptors(descriptors);
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
});
|
});
|
||||||
}
|
} else if (info->thingClassId() == speedwireInverterThingClassId) {
|
||||||
|
SpeedwireInterface *speedwireDiscovery = new SpeedwireInterface(info);
|
||||||
|
if (!speedwireDiscovery->initialize()) {
|
||||||
|
qCWarning(dcSma()) << "Could not discovery inverter. The speedwire interface initialization failed.";
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Unable to discover the network."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(speedwireDiscovery, &SpeedwireInterface::discoveryFinished, this, [=](){
|
||||||
|
qCDebug(dcSma()) << "Speed wire discovery finished.";
|
||||||
|
|
||||||
|
speedwireDiscovery->deleteLater();
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
});
|
||||||
|
|
||||||
|
speedwireDiscovery->startDiscovery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegrationPluginSma::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginSma::setupThing(ThingSetupInfo *info)
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
#include "plugintimer.h"
|
#include "plugintimer.h"
|
||||||
#include "sunnywebbox.h"
|
#include "sunnywebbox.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include "speedwireinterface.h"
|
||||||
|
|
||||||
class IntegrationPluginSma: public IntegrationPlugin {
|
class IntegrationPluginSma: public IntegrationPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@ -12,8 +12,8 @@
|
|||||||
"id": "49304127-ce9b-45dd-8511-05030a4ac003",
|
"id": "49304127-ce9b-45dd-8511-05030a4ac003",
|
||||||
"name": "sunnyWebBox",
|
"name": "sunnyWebBox",
|
||||||
"displayName": "Sunny WebBox",
|
"displayName": "Sunny WebBox",
|
||||||
"createMethods": ["user", "discovery"],
|
"createMethods": ["discovery", "user"],
|
||||||
"interfaces": ["smartmeterproducer"],
|
"interfaces": ["solarinverter"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
"id": "864d4162-e3ce-48b8-b8ac-c1b971b52d42",
|
"id": "864d4162-e3ce-48b8-b8ac-c1b971b52d42",
|
||||||
@ -85,6 +85,59 @@
|
|||||||
"defaultValue": "None"
|
"defaultValue": "None"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0c5097af-e136-4430-9fb4-0ccbb30c3e1c",
|
||||||
|
"name": "speedwireInverter",
|
||||||
|
"displayName": "SMA Inverter Speedwire",
|
||||||
|
"createMethods": ["discovery", "user"],
|
||||||
|
"interfaces": ["solarinverter"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "d90193e6-a996-4e49-bf6d-564d596d7e74",
|
||||||
|
"name": "host",
|
||||||
|
"displayName": "Host address",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "IPv4Address",
|
||||||
|
"defaultValue": "192.168.0.168"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2780eab7-1f1c-4cc7-a789-a8790329ca9e",
|
||||||
|
"name": "macAddress",
|
||||||
|
"displayName": "hardware address",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"readOnly": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "35733d27-4fe0-439a-be71-7c1597481659",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "Connected",
|
||||||
|
"displayNameEvent": "Connected changed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "015868bd-cc35-44cf-b631-78ea7c73b967",
|
||||||
|
"name": "currentPower",
|
||||||
|
"displayName": "Current power",
|
||||||
|
"displayNameEvent": "Current power changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Watt",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f29b6283-873b-45f5-8a14-622d34f11d4f",
|
||||||
|
"name": "totalEnergyProduced",
|
||||||
|
"displayName": "Total energy produced",
|
||||||
|
"displayNameEvent": "Total energy produced changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "KiloWattHour",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,10 @@ QT += network
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
integrationpluginsma.cpp \
|
integrationpluginsma.cpp \
|
||||||
|
speedwireinterface.cpp \
|
||||||
sunnywebbox.cpp
|
sunnywebbox.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
integrationpluginsma.h \
|
integrationpluginsma.h \
|
||||||
|
speedwireinterface.h \
|
||||||
sunnywebbox.h
|
sunnywebbox.h
|
||||||
|
|||||||
111
sma/speedwireinterface.cpp
Normal file
111
sma/speedwireinterface.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "speedwireinterface.h"
|
||||||
|
#include "extern-plugininfo.h"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
SpeedwireInterface::SpeedwireInterface(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
m_socket = new QUdpSocket(this);
|
||||||
|
connect(m_socket, &QUdpSocket::readyRead, this, &SpeedwireInterface::readPendingDatagrams);
|
||||||
|
connect(m_socket, &QUdpSocket::stateChanged, this, &SpeedwireInterface::onSocketStateChanged);
|
||||||
|
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpeedwireInterface::~SpeedwireInterface()
|
||||||
|
{
|
||||||
|
if (m_initialized) {
|
||||||
|
if (!m_socket->leaveMulticastGroup(m_multicastAddress)) {
|
||||||
|
qCWarning(dcSma()) << "SpeedwireInterface: Failed to leave multicast group" << m_multicastAddress.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_socket->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpeedwireInterface::initialize()
|
||||||
|
{
|
||||||
|
// If we already initialized the socket, we are done
|
||||||
|
if (m_initialized)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_socket->close();
|
||||||
|
m_initialized = false;
|
||||||
|
|
||||||
|
if (!m_socket->bind(QHostAddress::AnyIPv4, m_port, QAbstractSocket::ShareAddress)) {
|
||||||
|
qCWarning(dcSma()) << "SpeedwireInterface: Cannot bind to port" << m_port << m_socket->errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_socket->joinMulticastGroup(m_multicastAddress)) {
|
||||||
|
qCWarning(dcSma()) << "SpeedwireInterface: Failed to join multicast group" << m_multicastAddress.toString() << m_socket->errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpeedwireInterface::initialized() const
|
||||||
|
{
|
||||||
|
return m_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpeedwireInterface::startDiscovery()
|
||||||
|
{
|
||||||
|
if (m_discoveryRunning)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Start discovering network...";
|
||||||
|
if (!m_initialized) {
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Failed to start discovery because the socket has not been initialized successfully.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discovery message
|
||||||
|
QByteArray discoveryDatagram = QByteArray::fromHex("534d4100000402a0ffffffff0000002000000000");
|
||||||
|
if (m_socket->write(discoveryDatagram) < 0) {
|
||||||
|
qCWarning(dcSma()) << "SpeedwireInterface: Failed to send discovery datagram to multicast address" << m_multicastAddress.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_discoveryRunning = true;
|
||||||
|
QTimer::singleShot(10000, this, [=](){
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Discovey finished.";
|
||||||
|
m_discoveryRunning = false;
|
||||||
|
emit discoveryFinished();
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpeedwireInterface::discoveryRunning() const
|
||||||
|
{
|
||||||
|
return m_discoveryRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedwireInterface::readPendingDatagrams()
|
||||||
|
{
|
||||||
|
QUdpSocket *socket= qobject_cast<QUdpSocket *>(sender());
|
||||||
|
|
||||||
|
QByteArray datagram;
|
||||||
|
QHostAddress senderAddress;
|
||||||
|
quint16 senderPort;
|
||||||
|
|
||||||
|
while (socket->hasPendingDatagrams()) {
|
||||||
|
datagram.resize(socket->pendingDatagramSize());
|
||||||
|
socket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Data received from" << senderAddress.toString() << datagram.toHex();
|
||||||
|
//emit datagramReceived(senderAddress, datagram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedwireInterface::onSocketError(QAbstractSocket::SocketError error)
|
||||||
|
{
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Socket error" << error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedwireInterface::onSocketStateChanged(QAbstractSocket::SocketState socketState)
|
||||||
|
{
|
||||||
|
qCDebug(dcSma()) << "SpeedwireInterface: Socket state changed" << socketState;
|
||||||
|
}
|
||||||
37
sma/speedwireinterface.h
Normal file
37
sma/speedwireinterface.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef SPEEDWIREINTERFACE_H
|
||||||
|
#define SPEEDWIREINTERFACE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUdpSocket>
|
||||||
|
|
||||||
|
class SpeedwireInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SpeedwireInterface(QObject *parent = nullptr);
|
||||||
|
~SpeedwireInterface();
|
||||||
|
|
||||||
|
bool initialize();
|
||||||
|
bool initialized() const;
|
||||||
|
|
||||||
|
bool startDiscovery();
|
||||||
|
bool discoveryRunning() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void discoveryFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUdpSocket *m_socket = nullptr;
|
||||||
|
QHostAddress m_multicastAddress = QHostAddress("239.12.255.254");
|
||||||
|
quint16 m_port = 9522;
|
||||||
|
bool m_initialized = false;
|
||||||
|
bool m_discoveryRunning = false;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void readPendingDatagrams();
|
||||||
|
void onSocketError(QAbstractSocket::SocketError error);
|
||||||
|
void onSocketStateChanged(QAbstractSocket::SocketState socketState);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPEEDWIREINTERFACE_H
|
||||||
Loading…
x
Reference in New Issue
Block a user