Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P176] Add plugin Communication - Victron VE.Direct #5148

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4cd1d80
[P176] Add plugin Communication - Victron VE.Direct
tonhuisman Oct 25, 2024
9dd301b
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Oct 26, 2024
0aecf3b
[P176] Add some features and code improvements
tonhuisman Oct 26, 2024
9d8135e
[P176] Fix ESP8266 build issue
tonhuisman Oct 26, 2024
d67d8e6
[P176] Update taskvalues at receiving data, other improvements
tonhuisman Oct 27, 2024
78d6a2c
[P176] Fix use of plugin compiletime feature flags
tonhuisman Oct 27, 2024
8c3eb08
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Oct 28, 2024
f5068aa
[P176] Move Led initialization to DataStruct initialization function
tonhuisman Oct 28, 2024
3e862bc
[P176] Add documentation
tonhuisman Oct 28, 2024
7a5f744
[P176] Refactorings to optimize performance (lower load), remove RX T…
tonhuisman Oct 29, 2024
9ca8f79
[P176] Update documentation
tonhuisman Oct 29, 2024
88f7940
[P176] Simplify handling temporary values before checksum checked
TD-er Oct 29, 2024
f2a01e6
[P176] Avoid calling serial->available() too often, uncrustify some r…
tonhuisman Oct 30, 2024
8f475f1
[P176] Update changelog (and GH Actions failed)
tonhuisman Oct 30, 2024
21ff328
[P176] Handle ON and OFF values as 1 and 0
tonhuisman Oct 30, 2024
7de795e
[P176] Fix checksum validation, was ignoring the first line after rec…
tonhuisman Nov 2, 2024
c8d6e45
Merge branch 'mega' into feature/P176-add-plugin-victron-ve.direct
TD-er Nov 4, 2024
ed33fd0
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Nov 8, 2024
7954406
[P176] Add variables `successcount`, `errorcount` and `ischanged`
tonhuisman Nov 8, 2024
90c4a2f
[P176] Rename variable `ischanged` to `updated`
tonhuisman Nov 10, 2024
78cf151
Merge branch 'mega' into feature/P176-add-plugin-victron-ve.direct
TD-er Nov 13, 2024
db133eb
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Nov 24, 2024
bbda83d
[P176] Add Events only when updated option and docs
tonhuisman Nov 24, 2024
d39c3f9
[P176] Fix bug in screenshot :-)
tonhuisman Nov 24, 2024
9c29abe
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Dec 4, 2024
a7704c8
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Dec 9, 2024
eaface4
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions src/_P176_VE_Direct.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include "_Plugin_Helper.h"
#ifdef USES_P176

// #######################################################################################################
// ############################# Plugin 176: Communication - Victron VE.Direct ###########################
// #######################################################################################################

/**
* 2024-10-22 tonhuisman: Add checksum handling,
* Add conversion factors to get more usable values like V, A, Ah, %. Based on VE.Direct protocol manual v. 3.3
* 2024-10-20 tonhuisman: Start plugin for Victron VE.Direct protocol reader
* Using entity fields as documented here: https://github.com/KinDR007/VictronMPPT-ESPHOME
**/

# define PLUGIN_176
# define PLUGIN_ID_176 176
# define PLUGIN_NAME_176 "Communication - Victron VE.Direct"
# define PLUGIN_VALUENAME1_176 "V" // battery_voltage
# define PLUGIN_VALUENAME2_176 "I" // battery_current
# define PLUGIN_VALUENAME3_176 "P" // instantaneous_power
# define PLUGIN_VALUENAME4_176 "ERR" // error_code

# include "./src/PluginStructs/P176_data_struct.h"

# include <GPIO_Direct_Access.h>

boolean Plugin_176(uint8_t function, struct EventStruct *event, String& string)
{
boolean success = false;

switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_176;
Device[deviceCount].Type = DEVICE_TYPE_SERIAL;
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_QUAD;
Device[deviceCount].Ports = 0;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 4;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].TimerOptional = true;
Device[deviceCount].PluginStats = true;

break;
}

case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_176);

break;
}

case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_176));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_176));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_176));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_176));

break;
}

case PLUGIN_SET_DEFAULTS:
{
CONFIG_PORT = static_cast<int>(ESPEasySerialPort::serial1); // Serial1 port
int rxPin = 0;
int txPin = 0;
const ESPEasySerialPort port = static_cast<ESPEasySerialPort>(CONFIG_PORT);

ESPeasySerialType::getSerialTypePins(port, rxPin, txPin);
CONFIG_PIN1 = rxPin;
CONFIG_PIN2 = txPin;
P176_SERIAL_BAUDRATE = P176_DEFAULT_BAUDRATE;
P176_RX_WAIT = P176_DEFAULT_RX_WAIT;
P176_SET_LED_PIN(-1);
}

case PLUGIN_WEBFORM_SHOW_CONFIG:
{
string += serialHelper_getSerialTypeLabel(event);
success = true;
break;
}

case PLUGIN_GET_DEVICEGPIONAMES:
{
serialHelper_getGpioNames(event);
break;
}

case PLUGIN_WEBFORM_SHOW_GPIO_DESCR:
{
string = strformat(F("LED: %s"), formatGpioLabel(P176_GET_LED_PIN, false).c_str());

if (validGpio(P176_GET_LED_PIN) && P176_GET_LED_INVERTED) {
string += F(" (inv)");
}
success = true;
break;
}

case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(F("Baud Rate"), F("pbaud"), P176_SERIAL_BAUDRATE, 0);
uint8_t serialConfChoice = serialHelper_convertOldSerialConfig(P176_SERIAL_CONFIG);
serialHelper_serialconfig_webformLoad(event, serialConfChoice);

addFormNumericBox(F("RX Receive Timeout"), F("prxwait"), P176_RX_WAIT, 0, 200);
addUnit(F("mSec"));
# if P176_FAIL_CHECKSUM
addFormCheckBox(F("Ignore data on checksum error"), F("pchksm"), P176_GET_FAIL_CHECKSUM);
# endif // if P176_FAIL_CHECKSUM

{ // Led settings
addFormSubHeader(F("Led"));

addFormPinSelect(PinSelectPurpose::Generic_output, F("Led pin"), F("pledpin"), P176_GET_LED_PIN);
addFormCheckBox(F("Led inverted"), F("pledinv"), P176_GET_LED_INVERTED);
}

{
P176_data_struct *P176_data = static_cast<P176_data_struct *>(getPluginTaskData(event->TaskIndex));

if ((nullptr != P176_data) && (P176_data->plugin_size_current_data() > 0)) {
addFormSubHeader(F("Current data"));
addRowLabel(F("Recently received data"));
P176_data->plugin_show_current_data();
}
}
success = true;
break;
}

case PLUGIN_WEBFORM_SAVE:
{
P176_SERIAL_BAUDRATE = getFormItemInt(F("pbaud"));
P176_SERIAL_CONFIG = serialHelper_serialconfig_webformSave();
P176_RX_WAIT = getFormItemInt(F("prxwait"));
P176_SET_LED_PIN(getFormItemInt(F("pledpin")));
P176_SET_LED_INVERTED(isFormItemChecked(F("pledinv")));
# if P176_FAIL_CHECKSUM
P176_SET_FAIL_CHECKSUM(isFormItemChecked(F("pchksm")));
# endif // if P176_FAIL_CHECKSUM

success = true;
break;
}

case PLUGIN_INIT:
{
initPluginTaskData(event->TaskIndex, new (std::nothrow) P176_data_struct(event));
P176_data_struct *P176_data = static_cast<P176_data_struct *>(getPluginTaskData(event->TaskIndex));

success = (nullptr != P176_data) && P176_data->init();
int8_t _ledPin = P176_GET_LED_PIN;

if (validGpio(_ledPin)) {
DIRECT_PINMODE_OUTPUT(_ledPin);
DIRECT_pinWrite(_ledPin, P176_GET_LED_INVERTED ? 1 : 0); // Led off
}

break;
}

case PLUGIN_READ:
{
P176_data_struct *P176_data = static_cast<P176_data_struct *>(getPluginTaskData(event->TaskIndex));

success = (nullptr != P176_data) && P176_data->plugin_read(event);

break;
}

case PLUGIN_TEN_PER_SECOND:
{
P176_data_struct *P176_data = static_cast<P176_data_struct *>(getPluginTaskData(event->TaskIndex));

success = (nullptr != P176_data) && P176_data->plugin_ten_per_second(event);

break;
}

case PLUGIN_GET_CONFIG_VALUE:
{
P176_data_struct *P176_data = static_cast<P176_data_struct *>(getPluginTaskData(event->TaskIndex));

success = (nullptr != P176_data) && P176_data->plugin_get_config_value(event, string);

break;
}
}
return success;
}

#endif // USES_P176
6 changes: 6 additions & 0 deletions src/src/CustomBuild/define_plugin_sets.h
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,9 @@ To create/register a plugin, you have to :
#if !defined(USES_P148) && defined(ESP32)
#define USES_P148 // Sonoff POWR3xxD and THR3xxD display
#endif
#if !defined(USES_P176) && defined(ESP32)
#define USES_P176 // Communication - Victron VE.Direct
#endif

#endif // ifdef PLUGIN_ENERGY_COLLECTION

Expand Down Expand Up @@ -2482,6 +2485,9 @@ To create/register a plugin, you have to :
#ifndef USES_P173
#define USES_P173 // Environment - SHTC3
#endif
#ifndef USES_P176
#define USES_P176 // Communication - Victron VE.Direct
#endif

// Controllers
#ifndef USES_C015
Expand Down
Loading