Ignore the above code.
It occurred to me that I was now trying to use both sensors AND binary sensors in a Custom Sensor. Logic suggests that I now need 2 include files, one with public Sensor and one with public BinarySensor so that what I did.
Code for the Custom Sensor is here:
// *****************************************************************
// * ESPHome Custom Component Modbus sniffer for *
// * Ampinvt MPPT Solar Controller *
// * Original code credits: *
// * https://github.com/htvekov/ *
// * https://github.com/assembly12/ *
// *****************************************************************
#include "esphome.h"
class ampinvtbinarysensor : public PollingComponent, public BinarySensor, public UARTDevice {
public:
ampinvtbinarysensor(UARTComponent *parent) : PollingComponent(600), UARTDevice(parent) {}
//37 bytes total - 25 bytes used, 12 bytes unused
Sensor *op_status = new Sensor(); // 1 bit ~ byte 3 (0=Normal, 1=Abnormal - Battery Automatic Recognition Error)
Sensor *battery_status = new Sensor(); // 1 bit ~ byte 3 (0=Normal, 1=Over Discharge Protection)
Sensor *fan_status = new Sensor(); // 1 bit ~ byte 3 (0=Normal, 1=Fan Failure)
Sensor *temp_status = new Sensor(); // 1 bit ~ byte 3 (0=Normal, 1=Over Temperature Protection)
Sensor *dcoutput_status = new Sensor(); // 1 bit ~ byte 3 (0=Normal, 1=DC Output SHort / Over Current Protection)
Sensor *inttemp1_status = new Sensor(); // 1 bit ~ byte 3 (0=Close, 1=Fault)
Sensor *inttemp2_status = new Sensor(); // 1 bit ~ byte 3 (0=Close, 1=Fault)
Sensor *exttemp_status = new Sensor(); // 1 bit ~ byte 3 (0=Close, 1=Fault)
Sensor *chg_status = new Sensor(); // 1 bit ~ byte 4 (0=Not Charging, 1=Charging)
Sensor *equalchg_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *track_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *floatchg_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *chgcurrentlimit_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *chgderating_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *remoteprohibchg_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *pvovervolt_status = new Sensor(); // 1 bit ~ byte 4 (1=True)
Sensor *chgoutputrelay_status = new Sensor(); // 1 bit ~ byte 5 (0=Close, 1=Open)
Sensor *loadoutput_status = new Sensor(); // 1 bit ~ byte 5 (0=Close, 1=Open)
Sensor *fanrelay_status = new Sensor(); // 1 bit ~ byte 5 (0=Close, 1=Open)
Sensor *overchgprotect_status = new Sensor(); // 1 bit ~ byte 5 (0=Normal, 1=Overcharge Protection)
Sensor *overvoltprotect_status = new Sensor(); // 1 bit ~ byte 5 (0=Normal, 1=Overvoltage Protection)
void setup() override {
}
std::vector<uint8_t> bytes;
void update() {
while(available() > 0) {
bytes.push_back(read());
if(bytes.size() < 37){
continue;
}
else {
}
if(bytes.size() == 37) {
#define BIT_OPERATING_STATUS 0x1 // 00000001
#define BIT_BATTERY_STATUS 0x2 // 00000010
#define BIT_FAN_STATUS 0x3 // 00000100
#define BIT_TEMPERATURE_STATUS 0x4 // 00001000
#define BIT_DCOUTPUT_STATUS 0x5 // 00010000
#define BIT_INTTEMP1_STATUS 0x6 // 00100000
#define BIT_INTTEMP2_STATUS 0x7 // 01000000
#define BIT_EXTTEMP_STATUS 0x8 // 10000000
uint8_t op_status_byte = (uint8_t)(bytes[3]);
id(op_status).publish_state((bool)((op_status_byte & BIT_OPERATING_STATUS) == 1));
id(battery_status).publish_state((bool)((op_status_byte & BIT_BATTERY_STATUS) == 1));
id(fan_status).publish_state((bool)((op_status_byte & BIT_FAN_STATUS) == 1));
id(temp_status).publish_state((bool)((op_status_byte & BIT_TEMPERATURE_STATUS) == 1));
id(dcoutput_status).publish_state((bool)((op_status_byte & BIT_DCOUTPUT_STATUS) == 1));
id(inttemp1_status).publish_state((bool)((op_status_byte & BIT_INTTEMP1_STATUS) == 1));
id(inttemp2_status).publish_state((bool)((op_status_byte & BIT_INTTEMP2_STATUS) == 1));
id(exttemp_status).publish_state((bool)((op_status_byte & BIT_EXTTEMP_STATUS) == 1));
#define BIT_CHARGING_STATUS 0x1 // 00000001
#define BIT_EQUALCHG_STATUS 0x2 // 00000010
#define BIT_TRACK_STATUS 0x3 // 00000100
#define BIT_FLOATCHG_STATUS 0x4 // 00001000
#define BIT_CHGCURRENTLIMIT_STATUS 0x5 // 00010000
#define BIT_CHGDERATING_STATUS 0x6 // 00100000
#define BIT_REMOTEPROHIBCHG_STATUS 0x7 // 01000000
#define BIT_PVOVERVOLT_STATUS 0x8 // 10000000
uint8_t chg_status_byte = (uint8_t)(bytes[4]);
id(chg_status).publish_state((bool)((chg_status_byte & BIT_CHARGING_STATUS) == 1));
id(equalchg_status).publish_state((bool)((chg_status_byte & BIT_EQUALCHG_STATUS) == 1));
id(track_status).publish_state((bool)((chg_status_byte & BIT_TRACK_STATUS) == 1));
id(floatchg_status).publish_state((bool)((chg_status_byte & BIT_FLOATCHG_STATUS) == 1));
id(chgcurrentlimit_status).publish_state((bool)((chg_status_byte & BIT_CHGCURRENTLIMIT_STATUS) == 1));
id(chgderating_status).publish_state((bool)((chg_status_byte & BIT_CHGDERATING_STATUS) == 1));
id(remoteprohibchg_status).publish_state((bool)((chg_status_byte & BIT_REMOTEPROHIBCHG_STATUS) == 1));
id(pvovervolt_status).publish_state((bool)((chg_status_byte & BIT_PVOVERVOLT_STATUS) == 1));
#define BIT_CHGOUTRLY_STATUS 0x1 // 00000001
#define BIT_LOADOUTPUT_STATUS 0x2 // 00000010
#define BIT_FANRLY_STATUS 0x3 // 00000100
#define BIT_SPARE1_STATUS 0x4 // 00001000
#define BIT_OVERCHGPROTECT_STATUS 0x5 // 00010000
#define BIT_OVERVOLTPROTECT_STATUS 0x6 // 00100000
#define BIT_SPARE2_STATUS 0x7 // 01000000
#define BIT_SPARE3_STATUS 0x8 // 10000000
uint8_t ctl_status_byte = (uint8_t)(bytes[5]);
id(chgoutputrelay_status).publish_state((bool)((ctl_status_byte & BIT_CHGOUTRLY_STATUS) == 1));
id(loadoutput_status).publish_state((bool)((ctl_status_byte & BIT_LOADOUTPUT_STATUS) == 1));
id(fanrelay_status).publish_state((bool)((ctl_status_byte & BIT_FANRLY_STATUS) == 1));
id(overchgprotect_status).publish_state((bool)((ctl_status_byte & BIT_OVERCHGPROTECT_STATUS) == 1));
id(overvoltprotect_status).publish_state((bool)((ctl_status_byte & BIT_OVERVOLTPROTECT_STATUS) == 1));
bytes.clear();
}
else {
}
}
}
typedef union
{
unsigned char Byte[2];
uint8_t UInt8;
unsigned char UChar;
char Char;
}TwoByte;};
Code from the yaml is here:
binary_sensor:
- platform: custom
lambda: |-
auto ampinvtbinarysensors = new ampinvtbinarysensor(id(uart_bus));
App.register_component(ampinvtbinarysensors);
return {\
ampinvtbinarysensors->op_status, \
ampinvtbinarysensors->battery_status, \
ampinvtbinarysensors->fan_status, \
ampinvtbinarysensors->temp_status, \
ampinvtbinarysensors->dcoutput_status, \
ampinvtbinarysensors->inttemp1_status, \
ampinvtbinarysensors->inttemp2_status, \
ampinvtbinarysensors->exttemp_status, \
ampinvtbinarysensors->chg_status, \
ampinvtbinarysensors->equalchg_status, \
ampinvtbinarysensors->track_status, \
ampinvtbinarysensors->floatchg_status, \
ampinvtbinarysensors->chgcurrentlimit_status, \
ampinvtbinarysensors->chgderating_status, \
ampinvtbinarysensors->remoteprohibchg_status, \
ampinvtbinarysensors->pvovervolt_status, \
ampinvtbinarysensors->chgoutputrelay_status, \
ampinvtbinarysensors->loadoutput_status, \
ampinvtbinarysensors->fanrelay_status, \
ampinvtbinarysensors->overchgprotect_status, \
ampinvtbinarysensors->overvoltprotect_status, \
};
binary_sensors:
- name: "Operating Status"
id: "op_status"
- name: "Battery Status"
id: "battery_status"
- name: "Fan Status"
id: "fan_status"
- name: "DC Output Status"
id: "dcoutput_status"
- name: "Internal Temperature 1 Status"
id: "inttemp1_status"
- name: "Internal Temperature 2 Status"
id: "inttemp2_status"
- name: "External Temperature Status"
id: "exttemp_status"
- name: "Charging Status"
id: "chg_status"
- name: "Equal Charging Status"
id: "equalchg_status"
- name: "MPPT Tracking Status"
id: "track_status"
- name: "Float Charging Status"
id: "floatchg_status"
- name: "Charge Current Limit Status"
id: "chgcurrentlimit_status"
- name: "Charge Derating Status"
id: "chgderating_status"
- name: "Remote Prohibit Charging Status"
id: "remoteprohibchg_status"
- name: "Panel Overvoltage Status"
id: "pvovervolt_status"
- name: "Charging Output Relay Status"
id: "chgoutputrelay_status"
- name: "Load Output Status"
id: "loadoutput_status"
- name: "Fan Relay Status"
id: "fanrelay_status"
- name: "Overcharge Protection Status"
id: "overchargeprotect_status"
- name: "Overvoltage Protection Status"
id: "overvoltprotect_status"
But when I try to load it up, I get these errors:
/config/esphome/esp32_barn_controller.yaml: In lambda function:
/config/esphome/esp32_barn_controller.yaml:166:7: error: could not convert '{ampinvtbinarysensors->ampinvtbinarysensor::op_status, ampinvtbinarysensors->ampinvtbinarysensor::battery_status, ampinvtbinarysensors->ampinvtbinarysensor::fan_status, ampinvtbinarysensors->ampinvtbinarysensor::temp_status, ampinvtbinarysensors->ampinvtbinarysensor::dcoutput_status, ampinvtbinarysensors->ampinvtbinarysensor::inttemp1_status, ampinvtbinarysensors->ampinvtbinarysensor::inttemp2_status, ampinvtbinarysensors->ampinvtbinarysensor::exttemp_status, ampinvtbinarysensors->ampinvtbinarysensor::chg_status, ampinvtbinarysensors->ampinvtbinarysensor::equalchg_status, ampinvtbinarysensors->ampinvtbinarysensor::track_status, ampinvtbinarysensors->ampinvtbinarysensor::floatchg_status, ampinvtbinarysensors->ampinvtbinarysensor::chgcurrentlimit_status, ampinvtbinarysensors->ampinvtbinarysensor::chgderating_status, ampinvtbinarysensors->ampinvtbinarysensor::remoteprohibchg_status, ampinvtbinarysensors->ampinvtbinarysensor::pvovervolt_status, ampinvtbinarysensors->ampinvtbinarysensor::chgoutputrelay_status, ampinvtbinarysensors->ampinvtbinarysensor::loadoutput_status, ampinvtbinarysensors->ampinvtbinarysensor::fanrelay_status, ampinvtbinarysensors->ampinvtbinarysensor::overchgprotect_status, ampinvtbinarysensors->ampinvtbinarysensor::overvoltprotect_status}' from '<brace-enclosed initializer list>' to 'std::vector<esphome::binary_sensor::BinarySensor*>'
};
^
*** [/data/esp32-barn-controller/.pioenvs/esp32-barn-controller/src/main.cpp.o] Error 1
========================== [FAILED] Took 5.24 seconds ==========================
The errors suggest to me that the cause is in the breakout in the code in the include file but I can’t see why.