Add speedwire test interface
parent
2b3a44cd6c
commit
cd9c048ebd
|
|
@ -84,8 +84,23 @@ void IntegrationPluginSma::discoverThings(ThingDiscoveryInfo *info)
|
|||
info->addThingDescriptors(descriptors);
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "plugintimer.h"
|
||||
#include "sunnywebbox.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include "speedwireinterface.h"
|
||||
|
||||
class IntegrationPluginSma: public IntegrationPlugin {
|
||||
Q_OBJECT
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
"id": "49304127-ce9b-45dd-8511-05030a4ac003",
|
||||
"name": "sunnyWebBox",
|
||||
"displayName": "Sunny WebBox",
|
||||
"createMethods": ["user", "discovery"],
|
||||
"interfaces": ["smartmeterproducer"],
|
||||
"createMethods": ["discovery", "user"],
|
||||
"interfaces": ["solarinverter"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "864d4162-e3ce-48b8-b8ac-c1b971b52d42",
|
||||
|
|
@ -85,6 +85,59 @@
|
|||
"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 += \
|
||||
integrationpluginsma.cpp \
|
||||
speedwireinterface.cpp \
|
||||
sunnywebbox.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginsma.h \
|
||||
speedwireinterface.h \
|
||||
sunnywebbox.h
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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…
Reference in New Issue