Add initial sources

This commit is contained in:
2024-06-24 18:07:06 +02:00
committed by GitHub
parent 37557f821e
commit 41abea549c
3 changed files with 165 additions and 0 deletions

18
README.md Normal file
View File

@ -0,0 +1,18 @@
# fronius-goecontroller-adapter
This little command line tool will fetch the solar power values from a fronius inverter and apply it via MQTT to a go-e controller.
The idea is that it will add the power to category "HOME" and "SOLAR".
## Build instructions
At the moment the IP of the inverter and the hostname of the MQTT server and the serial number of the go-e controller are all hardcoded. Patch these before compiling!
Tested on a raspberry pi with a proper OS (not dumbian).
```
git clone https://github.com/0xFEEDC0DE64/fronius-goecontroller-adapter.git
cd fronius-goecontroller-adapter
qmake6
make
./fronius-goecontroller-adapter
```

View File

@ -0,0 +1,3 @@
QT += core network mqtt
SOURCES += main.cpp

144
main.cpp Normal file
View File

@ -0,0 +1,144 @@
#include <QCoreApplication>
#include <QDebug>
#include <QMqttClient>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication app{argc, argv};
QMqttClient client;
client.setHostname("localhost");
client.setPort(1883);
QNetworkAccessManager manager;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&](){
QNetworkRequest request{QUrl{"http://192.168.1.110/solar_api/v1/GetPowerFlowRealtimeData.fcgi"}};
auto reply = manager.get(request);
QObject::connect(reply, &QNetworkReply::finished, [&,reply](){
struct Helper {
~Helper() { reply->deleteLater(); }
QNetworkReply *reply;
} helper { reply };
auto content = reply->readAll();
if (reply->error() != QNetworkReply::NoError)
{
qCritical() << "request failed:" << reply->error();
qDebug() << content;
}
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(content, &error);
if (error.error != QJsonParseError::NoError)
{
qCritical() << "json parsing failed:" << error.errorString();
qDebug() << content;
return;
}
if (!doc.isObject())
{
qCritical() << "json is not an object";
qDebug() << content;
return;
}
const auto &rootObj = doc.object();
qDebug() << "finished";
if (!rootObj.contains("Body"))
{
qCritical() << "json does not contain Body";
qDebug() << content;
return;
}
const auto &body = rootObj.value("Body");
if (!body.isObject())
{
qCritical() << "json Body is not an object";
qDebug() << content;
return;
}
const auto &bodyObj = body.toObject();
if (!bodyObj.contains("Data"))
{
qCritical() << "json does not contain Data";
qDebug() << content;
return;
}
const auto &data = bodyObj.value("Data");
if (!data.isObject())
{
qCritical() << "json Data is not an object";
qDebug() << content;
return;
}
const auto &dataObj = data.toObject();
if (!dataObj.contains("Site"))
{
qCritical() << "json does not contain Site";
qDebug() << content;
return;
}
const auto &site = dataObj.value("Site");
if (!site.isObject())
{
qCritical() << "json Site is not an object";
qDebug() << content;
return;
}
const auto &siteObj = site.toObject();
if (!siteObj.contains("P_PV"))
{
qCritical() << "json does not contain P_PV";
qDebug() << content;
return;
}
const auto &p_pv = siteObj.value("P_PV").toDouble();
qDebug() << "P_PV" << p_pv;
client.publish(QMqttTopicName{"go-eController/909648/ecp/set"}, QString{"[%0,null,null,null,%0]"}.arg(p_pv).toUtf8());
});
});
timer.setInterval(1000);
QObject::connect(&client, &QMqttClient::connected, &timer, qOverload<>(&QTimer::start));
QObject::connect(&client, &QMqttClient::connected, &timer, [](){
qDebug() << "mqtt connected";
});
QObject::connect(&client, &QMqttClient::disconnected, &timer, &QTimer::stop);
QObject::connect(&client, &QMqttClient::disconnected, &timer, [](){
qDebug() << "mqtt disconnected";
});
QObject::connect(&client, &QMqttClient::errorChanged, [](QMqttClient::ClientError error){
qCritical() << "mqtt error:" << error;
});
qDebug() << "connecting to mqtt...";
client.connectToHost();
return app.exec();
}