further implementeion of sunspec features
This commit is contained in:
parent
5a2be02340
commit
6a56838c8f
@ -40,7 +40,32 @@ IntegrationPluginSunSpec::IntegrationPluginSunSpec()
|
|||||||
|
|
||||||
void IntegrationPluginSunSpec::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginSunSpec::setupThing(ThingSetupInfo *info)
|
||||||
{
|
{
|
||||||
if (info->thing()->thingClassId() == sunspecInverterThingClassId) {
|
if (info->thing()->thingClassId() == sunspecConnectionThingClassId) {
|
||||||
|
QHostAddress address = QHostAddress(info->thing()->paramValue(sunspecConnectionThingIpAddressParamTypeId).toString());
|
||||||
|
SunSpec *sunSpec = new SunSpec(address, 502, this);
|
||||||
|
m_sunSpecConnections.insert(info->thing(), sunSpec);
|
||||||
|
if (!sunSpec->connectModbus()) {
|
||||||
|
QTimer::singleShot(2000, info, [this, info] {
|
||||||
|
setupThing(info);
|
||||||
|
});
|
||||||
|
qCWarning(dcSunSpec()) << "Error connecting to SunSpec device";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connect(sunSpec, &SunSpec::connectionStateChanged, info, [info] (bool status) {
|
||||||
|
qCDebug(dcSunSpec()) << "Modbus Inverter init finished" << status;
|
||||||
|
if (status) {
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
} else {
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(info, &ThingSetupInfo::aborted, sunSpec, [info, this] {
|
||||||
|
m_sunSpecConnections.take(info->thing())->deleteLater();
|
||||||
|
});
|
||||||
|
//connect(sunSpec, &SunSpecInverter::inverterDataReceived, this, &IntegrationPluginSunSpec::onInverterDataReceived);
|
||||||
|
|
||||||
|
} else if (info->thing()->thingClassId() == sunspecInverterThingClassId) {
|
||||||
QHostAddress address = QHostAddress(info->thing()->paramValue(sunspecInverterThingIpAddressParamTypeId).toString());
|
QHostAddress address = QHostAddress(info->thing()->paramValue(sunspecInverterThingIpAddressParamTypeId).toString());
|
||||||
SunSpecInverter *sunSpecInverter = new SunSpecInverter(address, 502, this);
|
SunSpecInverter *sunSpecInverter = new SunSpecInverter(address, 502, this);
|
||||||
m_sunSpecInverters.insert(info->thing(), sunSpecInverter);
|
m_sunSpecInverters.insert(info->thing(), sunSpecInverter);
|
||||||
@ -229,14 +254,14 @@ void IntegrationPluginSunSpec::executeAction(ThingActionInfo *info)
|
|||||||
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||||
}
|
}
|
||||||
} else if (action.actionTypeId() == sunspecStorageEnableChargingLimitActionTypeId) {
|
} else if (action.actionTypeId() == sunspecStorageEnableChargingLimitActionTypeId) {
|
||||||
int value = (action.param(sunspecStorageEnableChargingLimitActionEnableChargingLimitParamTypeId).value().toBool() << 1) | thing->stateValue(sunspecStorageEnableDischargingLimitStateTypeId).toBool();
|
/*int value = (action.param(sunspecStorageEnableChargingLimitActionEnableChargingLimitParamTypeId).value().toBool() << 1) | thing->stateValue(sunspecStorageEnableDischargingLimitStateTypeId).toBool();
|
||||||
QUuid requestId = sunSpecStorage->setStorageControlMode(value);
|
QUuid requestId = sunSpecStorage->setStorageControlMode(value);
|
||||||
if (requestId.isNull()) {
|
if (requestId.isNull()) {
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
} else {
|
} else {
|
||||||
m_asyncActions.insert(requestId, info);
|
m_asyncActions.insert(requestId, info);
|
||||||
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||||
}
|
}*/
|
||||||
} else if (action.actionTypeId() == sunspecStorageChargingRateActionTypeId) {
|
} else if (action.actionTypeId() == sunspecStorageChargingRateActionTypeId) {
|
||||||
QUuid requestId = sunSpecStorage->setChargingRate(action.param(sunspecStorageChargingRateActionChargingRateParamTypeId).value().toInt());
|
QUuid requestId = sunSpecStorage->setChargingRate(action.param(sunspecStorageChargingRateActionChargingRateParamTypeId).value().toInt());
|
||||||
if (requestId.isNull()) {
|
if (requestId.isNull()) {
|
||||||
@ -246,14 +271,14 @@ void IntegrationPluginSunSpec::executeAction(ThingActionInfo *info)
|
|||||||
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||||
}
|
}
|
||||||
} else if (action.actionTypeId() == sunspecStorageEnableDischargingLimitActionTypeId) {
|
} else if (action.actionTypeId() == sunspecStorageEnableDischargingLimitActionTypeId) {
|
||||||
int value = (action.param(sunspecStorageEnableDischargingLimitActionEnableDischargingLimitParamTypeId).value().toBool() << 1) | thing->stateValue(sunspecStorageEnableChargingLimitStateTypeId).toBool();
|
/*int value = (action.param(sunspecStorageEnableDischargingLimitActionEnableDischargingLimitParamTypeId).value().toBool() << 1) | thing->stateValue(sunspecStorageEnableChargingLimitStateTypeId).toBool();
|
||||||
QUuid requestId = sunSpecStorage->setStorageControlMode(value);
|
QUuid requestId = sunSpecStorage->setStorageControlMode(value);
|
||||||
if (requestId.isNull()) {
|
if (requestId.isNull()) {
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
} else {
|
} else {
|
||||||
m_asyncActions.insert(requestId, info);
|
m_asyncActions.insert(requestId, info);
|
||||||
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||||
}
|
}*/
|
||||||
} else if (action.actionTypeId() == sunspecStorageDischargingRateActionTypeId) {
|
} else if (action.actionTypeId() == sunspecStorageDischargingRateActionTypeId) {
|
||||||
QUuid requestId = sunSpecStorage->setDischargingRate(action.param(sunspecStorageDischargingRateActionDischargingRateParamTypeId).value().toInt());
|
QUuid requestId = sunSpecStorage->setDischargingRate(action.param(sunspecStorageDischargingRateActionDischargingRateParamTypeId).value().toInt());
|
||||||
if (requestId.isNull()) {
|
if (requestId.isNull()) {
|
||||||
@ -299,6 +324,23 @@ void IntegrationPluginSunSpec::onPluginConfigurationChanged(const ParamTypeId &p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginSunSpec::onConnectionStateChanged(bool status)
|
||||||
|
{
|
||||||
|
Q_UNUSED(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginSunSpec::onWriteRequestExecuted(QUuid requestId, bool success)
|
||||||
|
{
|
||||||
|
Q_UNUSED(requestId)
|
||||||
|
Q_UNUSED(success)
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginSunSpec::onWriteRequestError(QUuid requestId, const QString &error)
|
||||||
|
{
|
||||||
|
Q_UNUSED(requestId)
|
||||||
|
Q_UNUSED(error)
|
||||||
|
}
|
||||||
|
|
||||||
void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::InverterData &inverterData)
|
void IntegrationPluginSunSpec::onInverterDataReceived(const SunSpecInverter::InverterData &inverterData)
|
||||||
{
|
{
|
||||||
SunSpecInverter *inverter = static_cast<SunSpecInverter *>(sender());
|
SunSpecInverter *inverter = static_cast<SunSpecInverter *>(sender());
|
||||||
@ -413,6 +455,7 @@ void IntegrationPluginSunSpec::onStorageDataReceived(const SunSpecStorage::Stora
|
|||||||
|
|
||||||
void IntegrationPluginSunSpec::onMeterDataReceived(const SunSpecMeter::MeterData &meterData)
|
void IntegrationPluginSunSpec::onMeterDataReceived(const SunSpecMeter::MeterData &meterData)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(meterData)
|
||||||
SunSpecMeter *meter = static_cast<SunSpecMeter *>(sender());
|
SunSpecMeter *meter = static_cast<SunSpecMeter *>(sender());
|
||||||
Thing *thing = m_sunSpecMeters.key(meter);
|
Thing *thing = m_sunSpecMeters.key(meter);
|
||||||
|
|
||||||
@ -424,6 +467,7 @@ void IntegrationPluginSunSpec::onMeterDataReceived(const SunSpecMeter::MeterData
|
|||||||
|
|
||||||
void IntegrationPluginSunSpec::onTrackerDataReceived(const SunSpecTracker::TrackerData &trackerData)
|
void IntegrationPluginSunSpec::onTrackerDataReceived(const SunSpecTracker::TrackerData &trackerData)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(trackerData)
|
||||||
SunSpecTracker *tracker = static_cast<SunSpecTracker *>(sender());
|
SunSpecTracker *tracker = static_cast<SunSpecTracker *>(sender());
|
||||||
Thing *thing = m_sunSpecTrackers.key(tracker);
|
Thing *thing = m_sunSpecTrackers.key(tracker);
|
||||||
|
|
||||||
|
|||||||
@ -60,12 +60,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
PluginTimer *m_refreshTimer = nullptr;
|
PluginTimer *m_refreshTimer = nullptr;
|
||||||
QHash<QUuid, ThingActionInfo *> m_asyncActions;
|
QHash<QUuid, ThingActionInfo *> m_asyncActions;
|
||||||
|
QHash<Thing *, SunSpec *> m_sunSpecConnections;
|
||||||
|
|
||||||
QHash<Thing *, SunSpecInverter *> m_sunSpecInverters;
|
QHash<Thing *, SunSpecInverter *> m_sunSpecInverters;
|
||||||
QHash<Thing *, SunSpecStorage *> m_sunSpecStorages;
|
QHash<Thing *, SunSpecStorage *> m_sunSpecStorages;
|
||||||
QHash<Thing *, SunSpecMeter *> m_sunSpecMeters;
|
QHash<Thing *, SunSpecMeter *> m_sunSpecMeters;
|
||||||
QHash<Thing *, SunSpecTracker *> m_sunSpecTrackers;
|
QHash<Thing *, SunSpecTracker *> m_sunSpecTrackers;
|
||||||
void update(Thing *thing);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onRefreshTimer();
|
void onRefreshTimer();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "SunSpec",
|
"name": "SunSpec",
|
||||||
"displayName": "sunspec",
|
"displayName": "sunspec",
|
||||||
"id": "73c7efcc-80d5-4166-ad97-2cbbeb129d91",
|
"id": "cb4bdec6-cf2c-4a0f-9709-42d951ca2d8b",
|
||||||
"paramTypes":[
|
"paramTypes":[
|
||||||
{
|
{
|
||||||
"id": "52da5222-9a94-47a2-9adc-004541d2f5ed",
|
"id": "52da5222-9a94-47a2-9adc-004541d2f5ed",
|
||||||
@ -18,11 +18,61 @@
|
|||||||
"displayName": "SunSpec",
|
"displayName": "SunSpec",
|
||||||
"id": "c143a7b4-a16c-4fff-86a3-9ffab3d6841d",
|
"id": "c143a7b4-a16c-4fff-86a3-9ffab3d6841d",
|
||||||
"thingClasses": [
|
"thingClasses": [
|
||||||
|
{
|
||||||
|
"name": "sunspecConnection",
|
||||||
|
"displayName": "SunSpec Device",
|
||||||
|
"id": "f51853f3-8815-4cf3-b337-45cda1f3e6d5",
|
||||||
|
"createMethods": [ "User" ],
|
||||||
|
"interfaces": ["connectable"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "6be6abc4-e2b2-4687-9343-0e5164ed0ab2",
|
||||||
|
"name":"ipAddress",
|
||||||
|
"displayName": "IP address",
|
||||||
|
"type": "QString"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "04970315-ed3a-45ce-98fc-35ae3c4eb27b",
|
||||||
|
"name":"manufacturer",
|
||||||
|
"displayName": "Manufacturer",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true,
|
||||||
|
"defaultValue": "Unkown"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "58146c26-17d3-458e-a13f-d7f306c20c44",
|
||||||
|
"name":"deviceModel",
|
||||||
|
"displayName": "Device model",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true,
|
||||||
|
"defaultValue": "Unkown"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6ed498e1-37ca-4bb7-bac7-463509c7784e",
|
||||||
|
"name":"serialNumber",
|
||||||
|
"displayName": "Serial number",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true,
|
||||||
|
"defaultValue": "Unkown"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes":[
|
||||||
|
{
|
||||||
|
"id": "3e767ad0-b4b3-4398-94c1-00579ea09ca8",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "Connected",
|
||||||
|
"displayNameEvent": "Connected changed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false,
|
||||||
|
"cached": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sunspecInverter",
|
"name": "sunspecInverter",
|
||||||
"displayName": "SunSpec Inverter",
|
"displayName": "SunSpec Inverter",
|
||||||
"id": "2e4122ea-96a5-415c-b5e2-7d6012265a83",
|
"id": "2e4122ea-96a5-415c-b5e2-7d6012265a83",
|
||||||
"createMethods": [ "User" ],
|
"createMethods": [ "Auto" ],
|
||||||
"interfaces": ["connectable"],
|
"interfaces": ["connectable"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
@ -226,7 +276,7 @@
|
|||||||
"name": "sunspecMeter",
|
"name": "sunspecMeter",
|
||||||
"displayName": "SunSpec Meter",
|
"displayName": "SunSpec Meter",
|
||||||
"id": "68f822f9-ff30-4275-b229-39a3674fead7",
|
"id": "68f822f9-ff30-4275-b229-39a3674fead7",
|
||||||
"createMethods": [ "User" ],
|
"createMethods": [ "Auto" ],
|
||||||
"interfaces": ["connectable"],
|
"interfaces": ["connectable"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
@ -385,7 +435,7 @@
|
|||||||
"name": "sunspecTracker",
|
"name": "sunspecTracker",
|
||||||
"displayName": "SunSpec Tracker",
|
"displayName": "SunSpec Tracker",
|
||||||
"id": "9941da30-a6d6-475d-8244-3c2145b419e6",
|
"id": "9941da30-a6d6-475d-8244-3c2145b419e6",
|
||||||
"createMethods": [ "User" ],
|
"createMethods": [ "Auto" ],
|
||||||
"interfaces": ["connectable"],
|
"interfaces": ["connectable"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
@ -445,7 +495,7 @@
|
|||||||
"name": "sunspecStorage",
|
"name": "sunspecStorage",
|
||||||
"displayName": "SunSpec Storage",
|
"displayName": "SunSpec Storage",
|
||||||
"id": "9a643ba8-346c-4127-a2f8-956a7133d75e",
|
"id": "9a643ba8-346c-4127-a2f8-956a7133d75e",
|
||||||
"createMethods": [ "User" ],
|
"createMethods": [ "Auto" ],
|
||||||
"interfaces": ["connectable"],
|
"interfaces": ["connectable"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
@ -587,7 +637,7 @@
|
|||||||
"name": "sunspecStringCombiner",
|
"name": "sunspecStringCombiner",
|
||||||
"displayName": "SunSpec String Combiner",
|
"displayName": "SunSpec String Combiner",
|
||||||
"id": "7787f238-f5a3-4ba5-b3ec-7d513b87bf71",
|
"id": "7787f238-f5a3-4ba5-b3ec-7d513b87bf71",
|
||||||
"createMethods": [ "User" ],
|
"createMethods": [ "Auto" ],
|
||||||
"interfaces": ["connectable"],
|
"interfaces": ["connectable"],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -48,7 +48,6 @@ SunSpec::SunSpec(const QHostAddress &hostAddress, uint port, QObject *parent) :
|
|||||||
|
|
||||||
SunSpec::~SunSpec()
|
SunSpec::~SunSpec()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SunSpec::connectModbus()
|
bool SunSpec::connectModbus()
|
||||||
@ -56,6 +55,21 @@ bool SunSpec::connectModbus()
|
|||||||
return m_modbusTcpClient->connectDevice();;
|
return m_modbusTcpClient->connectDevice();;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SunSpec::manufacturer()
|
||||||
|
{
|
||||||
|
return m_manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SunSpec::deviceModel()
|
||||||
|
{
|
||||||
|
return m_deviceModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SunSpec::serialNumber()
|
||||||
|
{
|
||||||
|
return m_serialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
void SunSpec::findBaseRegister()
|
void SunSpec::findBaseRegister()
|
||||||
{
|
{
|
||||||
qCDebug(dcSunSpec()) << "find base register";
|
qCDebug(dcSunSpec()) << "find base register";
|
||||||
@ -109,7 +123,7 @@ void SunSpec::findModbusMap(const QList<BlockId> &ids, uint modbusAddressOffset)
|
|||||||
uint modbusAddress = unit.startAddress();
|
uint modbusAddress = unit.startAddress();
|
||||||
BlockId blockId = BlockId(unit.value(0));
|
BlockId blockId = BlockId(unit.value(0));
|
||||||
int blockLength = unit.value(1);
|
int blockLength = unit.value(1);
|
||||||
if (blockId > 800 || blockId == BlockId::End) {
|
if (blockId > 800 || blockId == BlockIdEnd) {
|
||||||
qCDebug(dcSunSpec()) << "Block id not found, Id:" << ids;
|
qCDebug(dcSunSpec()) << "Block id not found, Id:" << ids;
|
||||||
modbusMapSearchFinished(ids, 0, "Ids not found");
|
modbusMapSearchFinished(ids, 0, "Ids not found");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -88,84 +88,84 @@ public:
|
|||||||
Q_ENUM(SunSpecEvent1)
|
Q_ENUM(SunSpecEvent1)
|
||||||
|
|
||||||
enum BlockId {
|
enum BlockId {
|
||||||
Common = 1,
|
BlockIdCommon = 1,
|
||||||
BasicAggregator = 2,
|
BlockIdBasicAggregator = 2,
|
||||||
SecureDatasetReadRequest = 3,
|
BlockIdSecureDatasetReadRequest = 3,
|
||||||
SecureDatasetReadResponse = 4,
|
BlockIdSecureDatasetReadResponse = 4,
|
||||||
SecureWriteRequest = 5,
|
BlockIdSecureWriteRequest = 5,
|
||||||
SecureWriteSequentialRequest = 6,
|
BlockIdSecureWriteSequentialRequest = 6,
|
||||||
SecureWriteResponseModel = 7,
|
BlockIdSecureWriteResponseModel = 7,
|
||||||
GetDeviceSecurityCertificate = 8,
|
BlockIdGetDeviceSecurityCertificate = 8,
|
||||||
SetOperatorSecurityCertificate = 9,
|
BlockIdSetOperatorSecurityCertificate = 9,
|
||||||
CommunicationInterfaceHeader = 10,
|
BlockIdCommunicationInterfaceHeader = 10,
|
||||||
EthernetLinkLayer = 11,
|
BlockIdEthernetLinkLayer = 11,
|
||||||
IPv4 = 12,
|
BlockIdIPv4 = 12,
|
||||||
IPv6 = 13,
|
BlockIdIPv6 = 13,
|
||||||
ProxyServer = 14,
|
BlockIdProxyServer = 14,
|
||||||
InterfaceCountersModel = 15,
|
BlockIdInterfaceCountersModel = 15,
|
||||||
SimpleIpNetwork = 16,
|
BlockIdSimpleIpNetwork = 16,
|
||||||
SerialInterface = 17,
|
BlockIdSerialInterface = 17,
|
||||||
CellularLink = 18,
|
BlockIdCellularLink = 18,
|
||||||
PPPLink = 19,
|
BlockIdPPPLink = 19,
|
||||||
InverterSinglePhase = 101,
|
BlockIdInverterSinglePhase = 101,
|
||||||
InverterSplitPhase = 102,
|
BlockIdInverterSplitPhase = 102,
|
||||||
InverterThreePhase = 103,
|
BlockIdInverterThreePhase = 103,
|
||||||
InverterSinglePhaseFloat = 111,
|
BlockIdInverterSinglePhaseFloat = 111,
|
||||||
InverterSplitPhaseFloat = 112,
|
BlockIdInverterSplitPhaseFloat = 112,
|
||||||
InverterThreePhaseFloat = 113,
|
BlockIdInverterThreePhaseFloat = 113,
|
||||||
Nameplate = 120,
|
BlockIdNameplate = 120,
|
||||||
BasicSettings = 121,
|
BlockIdBasicSettings = 121,
|
||||||
MeasurementsStatus = 122,
|
BlockIdMeasurementsStatus = 122,
|
||||||
ImmediateControls = 123,
|
BlockIdImmediateControls = 123,
|
||||||
Storage = 124,
|
BlockIdStorage = 124,
|
||||||
Pricing = 125,
|
BlockIdPricing = 125,
|
||||||
StaticVoltVAR = 126,
|
BlockIdStaticVoltVAR = 126,
|
||||||
FreqWattParam = 127,
|
BlockIdFreqWattParam = 127,
|
||||||
DynamicReactiveCurrent = 128,
|
BlockIdDynamicReactiveCurrent = 128,
|
||||||
LVRTD = 129,
|
BlockIdLVRTD = 129,
|
||||||
HVRTD = 130,
|
BlockIdHVRTD = 130,
|
||||||
WattPF = 131,
|
BlockIdWattPF = 131,
|
||||||
VoltWatt = 132,
|
BlockIdVoltWatt = 132,
|
||||||
BasicScheduling = 133,
|
BlockIdBasicScheduling = 133,
|
||||||
FreqWattCrv = 134,
|
BlockIdFreqWattCrv = 134,
|
||||||
LFRT = 135,
|
BlockIdLFRT = 135,
|
||||||
HFRT = 136,
|
BlockIdHFRT = 136,
|
||||||
LVRTC = 137,
|
BlockIdLVRTC = 137,
|
||||||
HVRTC = 138,
|
BlockIdHVRTC = 138,
|
||||||
MultipleMPPTInverterExtensionModel = 160,
|
BlockIdMultipleMPPTInverterExtensionModel = 160,
|
||||||
SinglePhaseMeter = 201,
|
BlockIdSinglePhaseMeter = 201,
|
||||||
SplitSinglePhaseMeter = 202,
|
BlockIdSplitSinglePhaseMeter = 202,
|
||||||
WyeConnectThreePhaseMeter = 203,
|
BlockIdWyeConnectThreePhaseMeter = 203,
|
||||||
DeltaConnectThreePhaseMeter = 204,
|
BlockIdDeltaConnectThreePhaseMeter = 204,
|
||||||
SinglePhaseMeterFloat = 211,
|
BlockIdSinglePhaseMeterFloat = 211,
|
||||||
SplitSinglePhaseMeterFloat = 212,
|
BlockIdSplitSinglePhaseMeterFloat = 212,
|
||||||
WyeConnectThreePhaseMeterFloat = 213,
|
BlockIdWyeConnectThreePhaseMeterFloat = 213,
|
||||||
DeltaConnectThreePhaseMeterFloat = 214,
|
BlockIdDeltaConnectThreePhaseMeterFloat = 214,
|
||||||
SecureACMeterSelectedReadings = 220,
|
BlockIdSecureACMeterSelectedReadings = 220,
|
||||||
IrradianceModel = 302,
|
BlockIdIrradianceModel = 302,
|
||||||
BackOfModuleTemperatureModel = 303,
|
BlockIdBackOfModuleTemperatureModel = 303,
|
||||||
InclinometerModel = 304,
|
BlockIdInclinometerModel = 304,
|
||||||
GPS = 305,
|
BlockIdGPS = 305,
|
||||||
ReferencePointModel = 306,
|
BlockIdReferencePointModel = 306,
|
||||||
BaseMet = 307,
|
BlockIdBaseMet = 307,
|
||||||
MiniMetModel = 308,
|
BlockIdMiniMetModel = 308,
|
||||||
StringCombiner = 401,
|
BlockIdStringCombiner = 401,
|
||||||
StringCombinerAdvanced = 402,
|
BlockIdStringCombinerAdvanced = 402,
|
||||||
StringCombinerCurrent = 403,
|
BlockIdStringCombinerCurrent = 403,
|
||||||
StringCombinerCurrentAdvanced = 404,
|
BlockIdStringCombinerCurrentAdvanced = 404,
|
||||||
SolarModuleFloat = 501,
|
BlockIdSolarModuleFloat = 501,
|
||||||
SolarModule = 502,
|
BlockIdSolarModule = 502,
|
||||||
TrackerController = 601,
|
BlockIdTrackerController = 601,
|
||||||
EnergyStorageBaseModel = 801,
|
BlockIdEnergyStorageBaseModel = 801,
|
||||||
BatteryBaseModel = 802,
|
BlockIdBatteryBaseModel = 802,
|
||||||
LithiumIonBatteryModel = 803,
|
BlockIdLithiumIonBatteryModel = 803,
|
||||||
VerisStatusConfiguration = 64001,
|
BlockIdVerisStatusConfiguration = 64001,
|
||||||
MersenGreenString = 64020,
|
BlockIdMersenGreenString = 64020,
|
||||||
EltekInverterExtension = 64101,
|
BlockIdEltekInverterExtension = 64101,
|
||||||
OutBackAXSDevice = 64110,
|
BlockIdOutBackAXSDevice = 64110,
|
||||||
BasicChargeController = 64111,
|
BlockIdBasicChargeController = 64111,
|
||||||
OutBackFMChargeController = 64112,
|
BlockIdOutBackFMChargeController = 64112,
|
||||||
End = 65535
|
BlockIdEnd = 65535
|
||||||
};
|
};
|
||||||
Q_ENUM(BlockId)
|
Q_ENUM(BlockId)
|
||||||
|
|
||||||
@ -182,9 +182,9 @@ public:
|
|||||||
int m_slaveId = 1;
|
int m_slaveId = 1;
|
||||||
int m_baseRegister = 40000;
|
int m_baseRegister = 40000;
|
||||||
bool m_floatingPointRepresentation = false;
|
bool m_floatingPointRepresentation = false;
|
||||||
QString m_manufacturer = "unkown";
|
QString m_manufacturer = "Unknown";
|
||||||
QString m_deviceModel = "unknown";
|
QString m_deviceModel = "Unknown";
|
||||||
QString m_serialNumber = "unknown";
|
QString m_serialNumber = "Unknown";
|
||||||
|
|
||||||
void findBaseRegister();
|
void findBaseRegister();
|
||||||
void findModbusMap(const QList<BlockId> &mapIds, uint modbusAddressOffset = 69);
|
void findModbusMap(const QList<BlockId> &mapIds, uint modbusAddressOffset = 69);
|
||||||
@ -214,9 +214,6 @@ signals:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onModbusStateChanged(QModbusDevice::State state);
|
void onModbusStateChanged(QModbusDevice::State state);
|
||||||
|
|
||||||
void onRequestExecuted(QUuid requestId, bool success);
|
|
||||||
void onRequestError(QUuid requestId, const QString &error);
|
|
||||||
void onReceivedHoldingRegister(quint32 slaveAddress, quint32 modbusRegister, const QVector<quint16> &values);
|
void onReceivedHoldingRegister(quint32 slaveAddress, quint32 modbusRegister, const QVector<quint16> &values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -37,12 +37,12 @@ SunSpecInverter::SunSpecInverter(const QHostAddress &hostAddress, uint port, QOb
|
|||||||
if (state == QModbusDevice::ConnectedState) {
|
if (state == QModbusDevice::ConnectedState) {
|
||||||
qCDebug(dcSunSpec()) << "Inverter connected successfully";
|
qCDebug(dcSunSpec()) << "Inverter connected successfully";
|
||||||
QList<BlockId> mapIds;
|
QList<BlockId> mapIds;
|
||||||
mapIds.append(BlockId::InverterSinglePhase);
|
mapIds.append(BlockIdInverterSinglePhase);
|
||||||
mapIds.append(BlockId::InverterSplitPhase);
|
mapIds.append(BlockIdInverterSplitPhase);
|
||||||
mapIds.append(BlockId::InverterThreePhase);
|
mapIds.append(BlockIdInverterThreePhase);
|
||||||
mapIds.append(BlockId::InverterSinglePhaseFloat);
|
mapIds.append(BlockIdInverterSinglePhaseFloat);
|
||||||
mapIds.append(BlockId::InverterSplitPhaseFloat);
|
mapIds.append(BlockIdInverterSplitPhaseFloat);
|
||||||
mapIds.append(BlockId::InverterThreePhaseFloat);
|
mapIds.append(BlockIdInverterThreePhaseFloat);
|
||||||
findModbusMap(mapIds);
|
findModbusMap(mapIds);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -75,9 +75,9 @@ void SunSpecInverter::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength
|
|||||||
{
|
{
|
||||||
Q_UNUSED(mapLength)
|
Q_UNUSED(mapLength)
|
||||||
switch (mapId) {
|
switch (mapId) {
|
||||||
case BlockId::InverterSinglePhase:
|
case BlockIdInverterSinglePhase:
|
||||||
case BlockId::InverterSplitPhase:
|
case BlockIdInverterSplitPhase:
|
||||||
case BlockId::InverterThreePhase: {
|
case BlockIdInverterThreePhase: {
|
||||||
InverterData inverterData;
|
InverterData inverterData;
|
||||||
inverterData.acCurrent= convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
|
inverterData.acCurrent= convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
|
||||||
inverterData.acPower = convertValueWithSSF(data[Model10X::Model10XACPower], data[Model10X::Model10XWattScaleFactor]);
|
inverterData.acPower = convertValueWithSSF(data[Model10X::Model10XACPower], data[Model10X::Model10XWattScaleFactor]);
|
||||||
@ -99,9 +99,9 @@ void SunSpecInverter::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength
|
|||||||
emit inverterDataReceived(inverterData);
|
emit inverterDataReceived(inverterData);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case BlockId::InverterSinglePhaseFloat:
|
case BlockIdInverterSinglePhaseFloat:
|
||||||
case BlockId::InverterSplitPhaseFloat:
|
case BlockIdInverterSplitPhaseFloat:
|
||||||
case BlockId::InverterThreePhaseFloat: {
|
case BlockIdInverterThreePhaseFloat: {
|
||||||
InverterData inverterData;
|
InverterData inverterData;
|
||||||
inverterData.acCurrent = convertFloatValues(data[Model11X::Model11XAcCurrent], data[Model11X::Model11XAcCurrent+1]);
|
inverterData.acCurrent = convertFloatValues(data[Model11X::Model11XAcCurrent], data[Model11X::Model11XAcCurrent+1]);
|
||||||
|
|
||||||
|
|||||||
@ -100,14 +100,13 @@ public:
|
|||||||
void getInverterMap();
|
void getInverterMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockId m_id = BlockId::InverterThreePhase; //e.g. 103 for three phase inverter, 113 for three phase inverter with floating point representation
|
BlockId m_id = BlockIdInverterThreePhase; //e.g. 103 for three phase inverter, 113 for three phase inverter with floating point representation
|
||||||
uint m_mapLength = 0;
|
uint m_mapLength = 0;
|
||||||
uint m_mapModbusStartRegister = 40000;
|
uint m_mapModbusStartRegister = 40000;
|
||||||
|
|
||||||
void readInverterBlockHeader();
|
void readInverterBlockHeader();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onConnectionStateChanged();
|
|
||||||
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@ -37,14 +37,14 @@ SunSpecMeter::SunSpecMeter(const QHostAddress &hostAddress, uint port, QObject *
|
|||||||
if (state == QModbusDevice::ConnectedState) {
|
if (state == QModbusDevice::ConnectedState) {
|
||||||
qCDebug(dcSunSpec()) << "Meter connected successfully";
|
qCDebug(dcSunSpec()) << "Meter connected successfully";
|
||||||
QList<BlockId> mapIds;
|
QList<BlockId> mapIds;
|
||||||
mapIds.append(BlockId::SinglePhaseMeter);
|
mapIds.append(BlockIdSinglePhaseMeter);
|
||||||
mapIds.append(BlockId::SplitSinglePhaseMeter);
|
mapIds.append(BlockIdSplitSinglePhaseMeter);
|
||||||
mapIds.append(BlockId::WyeConnectThreePhaseMeter);
|
mapIds.append(BlockIdWyeConnectThreePhaseMeter);
|
||||||
mapIds.append(BlockId::DeltaConnectThreePhaseMeter);
|
mapIds.append(BlockIdDeltaConnectThreePhaseMeter);
|
||||||
mapIds.append(BlockId::SinglePhaseMeterFloat);
|
mapIds.append(BlockIdSinglePhaseMeterFloat);
|
||||||
mapIds.append(BlockId::SplitSinglePhaseMeterFloat);
|
mapIds.append(BlockIdSplitSinglePhaseMeterFloat);
|
||||||
mapIds.append(BlockId::WyeConnectThreePhaseMeterFloat);
|
mapIds.append(BlockIdWyeConnectThreePhaseMeterFloat);
|
||||||
mapIds.append(BlockId::DeltaConnectThreePhaseMeterFloat);
|
mapIds.append(BlockIdDeltaConnectThreePhaseMeterFloat);
|
||||||
findModbusMap(mapIds);
|
findModbusMap(mapIds);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -73,15 +73,14 @@ public:
|
|||||||
void geMeterMap();
|
void geMeterMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockId m_id = BlockId::DeltaConnectThreePhaseMeter;
|
BlockId m_id = BlockIdDeltaConnectThreePhaseMeter;
|
||||||
uint m_mapLength = 0;
|
uint m_mapLength = 0;
|
||||||
uint m_mapModbusStartRegister = 40000;
|
uint m_mapModbusStartRegister = 40000;
|
||||||
|
|
||||||
void readMeterBlockHeader();
|
void readMeterBlockHeader();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onConnectionStateChanged();
|
// void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
||||||
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void initFinished();
|
void initFinished();
|
||||||
|
|||||||
@ -37,7 +37,7 @@ SunSpecStorage::SunSpecStorage(const QHostAddress &hostAddress, uint port, QObje
|
|||||||
if (state == QModbusDevice::ConnectedState) {
|
if (state == QModbusDevice::ConnectedState) {
|
||||||
qCDebug(dcSunSpec()) << "Inverter connected successfully";
|
qCDebug(dcSunSpec()) << "Inverter connected successfully";
|
||||||
QList<BlockId> mapIds;
|
QList<BlockId> mapIds;
|
||||||
mapIds.append(BlockId::Storage);
|
mapIds.append(BlockIdStorage);
|
||||||
findModbusMap(mapIds);
|
findModbusMap(mapIds);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -112,7 +112,7 @@ void SunSpecStorage::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength,
|
|||||||
{
|
{
|
||||||
Q_UNUSED(mapLength)
|
Q_UNUSED(mapLength)
|
||||||
switch (mapId) {
|
switch (mapId) {
|
||||||
case BlockId::Storage: {
|
case BlockIdStorage: {
|
||||||
StorageData storageData;
|
StorageData storageData;
|
||||||
storageData.chargingState = ChargingState(data[Model124::Model124ChargeStatus]);
|
storageData.chargingState = ChargingState(data[Model124::Model124ChargeStatus]);
|
||||||
emit storageDataReceived(storageData);
|
emit storageDataReceived(storageData);
|
||||||
|
|||||||
@ -91,14 +91,13 @@ public:
|
|||||||
void getStorageMap();
|
void getStorageMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockId m_id = BlockId::EnergyStorageBaseModel;
|
BlockId m_id = BlockIdEnergyStorageBaseModel;
|
||||||
uint m_mapLength = 0;
|
uint m_mapLength = 0;
|
||||||
uint m_mapModbusStartRegister = 40000;
|
uint m_mapModbusStartRegister = 40000;
|
||||||
|
|
||||||
void readStorageBlockHeader();
|
void readStorageBlockHeader();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onConnectionStateChanged();
|
|
||||||
void onModbusMapReceived(BlockId mapId, uint mapLength, const QVector<quint16> &data);
|
void onModbusMapReceived(BlockId mapId, uint mapLength, const QVector<quint16> &data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@ -37,10 +37,10 @@ SunSpecStringCombiner::SunSpecStringCombiner(const QHostAddress &hostAddress, ui
|
|||||||
if (state == QModbusDevice::ConnectedState) {
|
if (state == QModbusDevice::ConnectedState) {
|
||||||
qCDebug(dcSunSpec()) << "String combiner connected successfully";
|
qCDebug(dcSunSpec()) << "String combiner connected successfully";
|
||||||
QList<BlockId> mapIds;
|
QList<BlockId> mapIds;
|
||||||
mapIds.append(BlockId::StringCombiner);
|
mapIds.append(BlockIdStringCombiner);
|
||||||
mapIds.append(BlockId::StringCombinerCurrent);
|
mapIds.append(BlockIdStringCombinerCurrent);
|
||||||
mapIds.append(BlockId::StringCombinerAdvanced);
|
mapIds.append(BlockIdStringCombinerAdvanced);
|
||||||
mapIds.append(BlockId::StringCombinerCurrentAdvanced);
|
mapIds.append(BlockIdStringCombinerCurrentAdvanced);
|
||||||
findModbusMap(mapIds);
|
findModbusMap(mapIds);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -71,15 +71,16 @@ void SunSpecStringCombiner::readStringCombinerMapHeader()
|
|||||||
|
|
||||||
void SunSpecStringCombiner::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength, QVector<quint16> data)
|
void SunSpecStringCombiner::onModbusMapReceived(SunSpec::BlockId mapId, uint mapLength, QVector<quint16> data)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(data);
|
||||||
|
|
||||||
switch (mapId) {
|
switch (mapId) {
|
||||||
case BlockId::StringCombiner: {
|
case BlockIdStringCombiner: {
|
||||||
int rbCount = (mapLength-14)/8;
|
int rbCount = (mapLength-14)/8;
|
||||||
qCDebug(dcSunSpec()) << "Map" << mapId << "Repeating Block Count" << rbCount;
|
qCDebug(dcSunSpec()) << "Map" << mapId << "Repeating Block Count" << rbCount;
|
||||||
} break;
|
} break;
|
||||||
case BlockId::StringCombinerCurrent:
|
case BlockIdStringCombinerCurrent:
|
||||||
case BlockId::StringCombinerAdvanced:
|
case BlockIdStringCombinerAdvanced:
|
||||||
case BlockId::StringCombinerCurrentAdvanced: {
|
case BlockIdStringCombinerCurrentAdvanced: {
|
||||||
//StringCombinerData stringCombinerData;
|
//StringCombinerData stringCombinerData;
|
||||||
//stringCombinerData.acCurrent= convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
|
//stringCombinerData.acCurrent= convertValueWithSSF(data[Model10X::Model10XAcCurrent], data[Model10X::Model10XAmpereScaleFactor]);
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -42,32 +42,32 @@ public:
|
|||||||
//Map401 length: 14 + (RB Count * 8)
|
//Map401 length: 14 + (RB Count * 8)
|
||||||
//Map403 length: 16 + (RB Count * 8)
|
//Map403 length: 16 + (RB Count * 8)
|
||||||
enum Map401 {
|
enum Map401 {
|
||||||
CurrentScaleFactor = 0,
|
Map401CurrentScaleFactor = 0,
|
||||||
AmpHourScaleFactor = 1,
|
Map401AmpHourScaleFactor = 1,
|
||||||
VoltageScaleFactor = 2,
|
Map401VoltageScaleFactor = 2,
|
||||||
MaximumDCCurrentRating = 3,
|
Map401MaximumDCCurrentRating = 3,
|
||||||
NumberOfInputs = 4,
|
Map401NumberOfInputs = 4,
|
||||||
Events = 5,
|
Map401Events = 5,
|
||||||
VendorDefniedEvents = 7,
|
Map401VendorDefniedEvents = 7,
|
||||||
TotalMeasuredCurrent = 9,
|
Map401TotalMeasuredCurrent = 9,
|
||||||
TotalMeteredAmpHours = 10,
|
Map401TotalMeteredAmpHours = 10,
|
||||||
OutputVoltage = 12,
|
Map401OutputVoltage = 12,
|
||||||
InternalOperatingTemperature = 13
|
Map401InternalOperatingTemperature = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Map402 {
|
enum Map402 {
|
||||||
CurrentScaleFactor,
|
Map402CurrentScaleFactor,
|
||||||
AmpHourScaleFactor,
|
Map402AmpHourScaleFactor,
|
||||||
VoltageScaleFactor
|
Map402VoltageScaleFactor,
|
||||||
PowerScale factor
|
Map402PowerScaleFactor,
|
||||||
EnergyScale factor
|
Map402EnergyScaleFactor,
|
||||||
Maximum DC Current Rating
|
Map402MaximumDCCurrentRating,
|
||||||
Number of Inputs
|
Map402NumberOfInputs,
|
||||||
Bitmask value. Events
|
Map402BitmaskValueEvents,
|
||||||
Bitmask value. Vendor defnied events
|
Map402BitmaskvalueVendorDefniedEvents,
|
||||||
Total measured current
|
Map402TotalMeasuredCurrent,
|
||||||
Total metered Amp-hours
|
Map402TotalMeteredAmpHours,
|
||||||
OutputVoltage
|
Map402OutputVoltage
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Map401RB { //Repeating block
|
enum Map401RB { //Repeating block
|
||||||
@ -111,14 +111,13 @@ public:
|
|||||||
void getStringCombinerMap();
|
void getStringCombinerMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockId m_id = BlockId::StringCombiner;
|
BlockId m_id = BlockIdStringCombiner;
|
||||||
uint m_mapLength = 0;
|
uint m_mapLength = 0;
|
||||||
uint m_mapModbusStartRegister = 40000;
|
uint m_mapModbusStartRegister = 40000;
|
||||||
|
|
||||||
void readStringCombinerMapHeader();
|
void readStringCombinerMapHeader();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onConnectionStateChanged();
|
|
||||||
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@ -60,15 +60,14 @@ public:
|
|||||||
void getTrackerMap();
|
void getTrackerMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockId m_id = BlockId::TrackerController;
|
BlockId m_id = BlockIdTrackerController;
|
||||||
uint m_mapLength = 0;
|
uint m_mapLength = 0;
|
||||||
uint m_mapModbusStartRegister = 40000;
|
uint m_mapModbusStartRegister = 40000;
|
||||||
|
|
||||||
void readTrackerBlockHeader();
|
void readTrackerBlockHeader();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onConnectionStateChanged();
|
//void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
||||||
void onModbusMapReceived(BlockId mapId, uint mapLength, QVector<quint16> data);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void initFinished();
|
void initFinished();
|
||||||
|
|||||||
Reference in New Issue
Block a user