From db0a3da803a7c843f939d15149962b1bd88846f8 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Fri, 24 Jun 2022 17:49:14 +0200 Subject: [PATCH] Generate a second class abstraction to support different inverter types in future --- lib/Hoymiles/src/Hoymiles.cpp | 9 +----- lib/Hoymiles/src/HoymilesRadio.cpp | 26 ++++++---------- lib/Hoymiles/src/HoymilesRadio.h | 5 +-- lib/Hoymiles/src/inverters/HM_1CH.cpp | 2 +- lib/Hoymiles/src/inverters/HM_1CH.h | 4 +-- lib/Hoymiles/src/inverters/HM_2CH.cpp | 2 +- lib/Hoymiles/src/inverters/HM_2CH.h | 4 +-- lib/Hoymiles/src/inverters/HM_4CH.cpp | 2 +- lib/Hoymiles/src/inverters/HM_4CH.h | 4 +-- lib/Hoymiles/src/inverters/HM_Abstract.cpp | 31 +++++++++++++++++++ lib/Hoymiles/src/inverters/HM_Abstract.h | 9 ++++++ lib/Hoymiles/src/inverters/InverterAbstract.h | 1 + 12 files changed, 63 insertions(+), 36 deletions(-) create mode 100644 lib/Hoymiles/src/inverters/HM_Abstract.cpp create mode 100644 lib/Hoymiles/src/inverters/HM_Abstract.h diff --git a/lib/Hoymiles/src/Hoymiles.cpp b/lib/Hoymiles/src/Hoymiles.cpp index 38141c72..f6cdc242 100644 --- a/lib/Hoymiles/src/Hoymiles.cpp +++ b/lib/Hoymiles/src/Hoymiles.cpp @@ -27,14 +27,7 @@ void HoymilesClass::loop() Serial.println(iv->serial()); iv->clearRxFragmentBuffer(); - - time_t now; - time(&now); - if (now > 0) { - _radio->sendTimePacket(iv, now); - } else { - Serial.println(F("Cancled. Time not yet synced.")); - } + _radio->sendTimePacket(iv); } if (++inverterPos >= getNumInverters()) { diff --git a/lib/Hoymiles/src/HoymilesRadio.cpp b/lib/Hoymiles/src/HoymilesRadio.cpp index 942834d5..8616b23a 100644 --- a/lib/Hoymiles/src/HoymilesRadio.cpp +++ b/lib/Hoymiles/src/HoymilesRadio.cpp @@ -250,29 +250,21 @@ void HoymilesRadio::sendEsbPacket(serial_u target, uint8_t mainCmd, uint8_t subC _rxTimeout.set(timeout); } -void HoymilesRadio::sendTimePacket(std::shared_ptr iv, time_t ts) +void HoymilesRadio::sendTimePacket(std::shared_ptr iv) { - uint8_t payload[16] = { 0 }; + inverter_transaction_t payload; + if (iv->getStatsRequest(&payload)) { + serial_u s; + s.u64 = iv->serial(); + _activeSerial.u64 = iv->serial(); - payload[0] = 0x0b; - payload[1] = 0x00; - u32CpyLittleEndian(&payload[2], ts); // sets the 4 following elements {2, 3, 4, 5} - payload[9] = 0x05; - - uint16_t crc = crc16(&payload[0], 14); - payload[14] = (crc >> 8) & 0xff; - payload[15] = (crc)&0xff; - - serial_u s; - s.u64 = iv->serial(); - _activeSerial.u64 = iv->serial(); - - sendEsbPacket(s, 0x15, 0x80, payload, sizeof(payload) / sizeof(uint8_t), 200); + sendEsbPacket(s, payload.mainCmd, payload.subCmd, payload.payload, payload.len, payload.timeout); + } } void HoymilesRadio::sendRetransmitPacket(uint8_t fragment_id) { - sendEsbPacket(_activeSerial, 0x15, (uint8_t)(0x80 + fragment_id), 0, 0, 60); + sendEsbPacket(_activeSerial, currentTransaction.mainCmd, (uint8_t)(0x80 + fragment_id), 0, 0, 60); } void HoymilesRadio::sendLastPacketAgain() diff --git a/lib/Hoymiles/src/HoymilesRadio.h b/lib/Hoymiles/src/HoymilesRadio.h index 21588735..534cd7f5 100644 --- a/lib/Hoymiles/src/HoymilesRadio.h +++ b/lib/Hoymiles/src/HoymilesRadio.h @@ -24,10 +24,12 @@ public: bool isIdle(); void sendEsbPacket(serial_u target, uint8_t mainCmd, uint8_t subCmd, uint8_t payload[], uint8_t len, uint32_t timeout, bool resend = false); - void sendTimePacket(std::shared_ptr iv, time_t ts); + void sendTimePacket(std::shared_ptr iv); void sendRetransmitPacket(uint8_t fragment_id); void sendLastPacketAgain(); + static void u32CpyLittleEndian(uint8_t dest[], uint32_t src); + private: void ARDUINO_ISR_ATTR handleIntr(); static serial_u convertSerialToRadioId(serial_u serial); @@ -39,7 +41,6 @@ private: void openWritingPipe(serial_u serial); bool checkFragmentCrc(fragment_t* fragment); void dumpBuf(const char* info, uint8_t buf[], uint8_t len); - void u32CpyLittleEndian(uint8_t dest[], uint32_t src); std::unique_ptr _radio; uint8_t _rxChLst[5] = { 3, 23, 40, 61, 75 }; diff --git a/lib/Hoymiles/src/inverters/HM_1CH.cpp b/lib/Hoymiles/src/inverters/HM_1CH.cpp index fca6299c..f4a31d60 100644 --- a/lib/Hoymiles/src/inverters/HM_1CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_1CH.cpp @@ -1,7 +1,7 @@ #include "HM_1CH.h" HM_1CH::HM_1CH(uint64_t serial) - : InverterAbstract(serial) {}; + : HM_Abstract(serial) {}; bool HM_1CH::isValidSerial(uint64_t serial) { diff --git a/lib/Hoymiles/src/inverters/HM_1CH.h b/lib/Hoymiles/src/inverters/HM_1CH.h index 21383d7f..9a728704 100644 --- a/lib/Hoymiles/src/inverters/HM_1CH.h +++ b/lib/Hoymiles/src/inverters/HM_1CH.h @@ -1,8 +1,8 @@ #pragma once -#include "InverterAbstract.h" +#include "HM_Abstract.h" -class HM_1CH : public InverterAbstract { +class HM_1CH : public HM_Abstract { public: HM_1CH(uint64_t serial); static bool isValidSerial(uint64_t serial); diff --git a/lib/Hoymiles/src/inverters/HM_2CH.cpp b/lib/Hoymiles/src/inverters/HM_2CH.cpp index 869cb406..2ec32d55 100644 --- a/lib/Hoymiles/src/inverters/HM_2CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_2CH.cpp @@ -1,7 +1,7 @@ #include "HM_2CH.h" HM_2CH::HM_2CH(uint64_t serial) - : InverterAbstract(serial) {}; + : HM_Abstract(serial) {}; bool HM_2CH::isValidSerial(uint64_t serial) { diff --git a/lib/Hoymiles/src/inverters/HM_2CH.h b/lib/Hoymiles/src/inverters/HM_2CH.h index f7cd6613..da06bd4e 100644 --- a/lib/Hoymiles/src/inverters/HM_2CH.h +++ b/lib/Hoymiles/src/inverters/HM_2CH.h @@ -1,8 +1,8 @@ #pragma once -#include "InverterAbstract.h" +#include "HM_Abstract.h" -class HM_2CH : public InverterAbstract { +class HM_2CH : public HM_Abstract { public: HM_2CH(uint64_t serial); static bool isValidSerial(uint64_t serial); diff --git a/lib/Hoymiles/src/inverters/HM_4CH.cpp b/lib/Hoymiles/src/inverters/HM_4CH.cpp index abd0d1cd..0773d9ad 100644 --- a/lib/Hoymiles/src/inverters/HM_4CH.cpp +++ b/lib/Hoymiles/src/inverters/HM_4CH.cpp @@ -1,7 +1,7 @@ #include "HM_4CH.h" HM_4CH::HM_4CH(uint64_t serial) - : InverterAbstract(serial) {}; + : HM_Abstract(serial) {}; bool HM_4CH::isValidSerial(uint64_t serial) { diff --git a/lib/Hoymiles/src/inverters/HM_4CH.h b/lib/Hoymiles/src/inverters/HM_4CH.h index b2a48f4e..4a871e45 100644 --- a/lib/Hoymiles/src/inverters/HM_4CH.h +++ b/lib/Hoymiles/src/inverters/HM_4CH.h @@ -1,8 +1,8 @@ #pragma once -#include "InverterAbstract.h" +#include "HM_Abstract.h" -class HM_4CH : public InverterAbstract { +class HM_4CH : public HM_Abstract { public: HM_4CH(uint64_t serial); static bool isValidSerial(uint64_t serial); diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.cpp b/lib/Hoymiles/src/inverters/HM_Abstract.cpp new file mode 100644 index 00000000..d52ed67a --- /dev/null +++ b/lib/Hoymiles/src/inverters/HM_Abstract.cpp @@ -0,0 +1,31 @@ +#include "HM_Abstract.h" +#include "HoymilesRadio.h" +#include "crc.h" + +HM_Abstract::HM_Abstract(uint64_t serial) + : InverterAbstract(serial) {}; + +bool HM_Abstract::getStatsRequest(inverter_transaction_t* payload) +{ + time_t now; + time(&now); + + memset(payload->payload, 0, MAX_RF_PAYLOAD_SIZE); + + payload->mainCmd = 0x15; + payload->subCmd = 0x80; + payload->timeout = 200; + payload->len = 16; + + payload->payload[0] = 0x0b; + payload->payload[1] = 0x00; + + HoymilesRadio::u32CpyLittleEndian(&payload->payload[2], now); // sets the 4 following elements {2, 3, 4, 5} + payload->payload[9] = 0x05; + + uint16_t crc = crc16(&payload->payload[0], 14); + payload->payload[14] = (crc >> 8) & 0xff; + payload->payload[15] = (crc)&0xff; + + return now > 0; +} \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.h b/lib/Hoymiles/src/inverters/HM_Abstract.h new file mode 100644 index 00000000..9114f379 --- /dev/null +++ b/lib/Hoymiles/src/inverters/HM_Abstract.h @@ -0,0 +1,9 @@ +#pragma once + +#include "InverterAbstract.h" + +class HM_Abstract : public InverterAbstract { +public: + HM_Abstract(uint64_t serial); + bool getStatsRequest(inverter_transaction_t* payload); +}; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index 8d3e8e7b..3f47e7b7 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -111,6 +111,7 @@ public: const char* getUnit(uint8_t channel, uint8_t fieldId); const char* getName(uint8_t channel, uint8_t fieldId); + virtual bool getStatsRequest(inverter_transaction_t* payload) = 0; uint32_t getLastStatsUpdate(); private: