Skip to content

Commit

Permalink
Add OUTPUT_STATE text sensor #68
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Dec 28, 2024
1 parent 0b408e3 commit e6052a7
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 32 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ The following `type` are supported by the `text_sensor` component:
| `OFF_REASON` | | | | X | | | | X | | | | | X |
| `ERROR_CODE` | | | | | | | | X | | | | | |
| `WARNING_REASON` | | | | | | | | X | | | | | |
| `OUTPUT_STATE` | | | | | | | | X | | | | | |
| `ALARM` | | | | | | | | | | | X | | |
| `BALANCER_STATUS` | | | | | X | | | | | | | | |

Expand Down
3 changes: 3 additions & 0 deletions components/victron_ble/text_sensor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"WARNING_REASON": {
CONF_TYPE: VICTRON_TEXT_SENSOR_TYPE.WARNING_REASON,
},
"OUTPUT_STATE": {
CONF_TYPE: VICTRON_TEXT_SENSOR_TYPE.OUTPUT_STATE,
},
"BALANCER_STATUS": {
CONF_TYPE: VICTRON_TEXT_SENSOR_TYPE.BALANCER_STATUS,
},
Expand Down
82 changes: 52 additions & 30 deletions components/victron_ble/text_sensor/victron_text_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ void VictronTextSensor::register_callback() {
case VICTRON_BLE_RECORD_TYPE::AC_CHARGER:
this->publish_state_(msg->data.ac_charger.charger_error);
break;
case VICTRON_BLE_RECORD_TYPE::SMART_BATTERY_PROTECT:
this->publish_state_(msg->data.smart_battery_protect.error_code);
break;
case VICTRON_BLE_RECORD_TYPE::MULTI_RS:
this->publish_state_(msg->data.multi_rs.charger_error);
break;
Expand Down Expand Up @@ -170,6 +167,18 @@ void VictronTextSensor::register_callback() {
}
break;

case VICTRON_TEXT_SENSOR_TYPE::OUTPUT_STATE:
switch (msg->record_type) {
case VICTRON_BLE_RECORD_TYPE::SMART_BATTERY_PROTECT:
this->publish_state_(msg->data.smart_battery_protect.output_state);
break;
default:
ESP_LOGW(TAG, "[%s] Device has no `output state` field.", this->parent_->address_str().c_str());
this->publish_state("");
break;
}
break;

case VICTRON_TEXT_SENSOR_TYPE::BALANCER_STATUS:
switch (msg->record_type) {
case VICTRON_BLE_RECORD_TYPE::SMART_LITHIUM:
Expand All @@ -189,56 +198,56 @@ void VictronTextSensor::register_callback() {
}

void VictronTextSensor::publish_state_(VE_REG_ALARM_REASON val) {
if ((u_int16_t) val == (u_int16_t) VE_REG_ALARM_REASON::NO_ALARM) {
if (val == VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("");
return;
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::LOW_VOLTAGE) != 0) {
if ((val & VE_REG_ALARM_REASON::LOW_VOLTAGE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Low Voltage");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::HIGH_VOLTAGE) != 0) {
if ((val & VE_REG_ALARM_REASON::HIGH_VOLTAGE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("High Voltage");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::LOW_SOC) != 0) {
if ((val & VE_REG_ALARM_REASON::LOW_SOC) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Low SOC");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::LOW_STARTER_VOLTAGE) != 0) {
if ((val & VE_REG_ALARM_REASON::LOW_STARTER_VOLTAGE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Low Starter Voltage");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::HIGH_STARTER_VOLTAGE) != 0) {
if ((val & VE_REG_ALARM_REASON::HIGH_STARTER_VOLTAGE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("High Starter Voltage");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::LOW_TEMPERATURE) != 0) {
if ((val & VE_REG_ALARM_REASON::LOW_TEMPERATURE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Low Temperature");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::HIGH_TEMPERATURE) != 0) {
if ((val & VE_REG_ALARM_REASON::HIGH_TEMPERATURE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("High Temperature");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::MID_VOLTAGE) != 0) {
if ((val & VE_REG_ALARM_REASON::MID_VOLTAGE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Mid Voltage");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::OVERLOAD) != 0) {
if ((val & VE_REG_ALARM_REASON::OVERLOAD) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Overload");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::DC_RIPPLE) != 0) {
if ((val & VE_REG_ALARM_REASON::DC_RIPPLE) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("DC-ripple");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::LOW_V_AC_OUT) != 0) {
if ((val & VE_REG_ALARM_REASON::LOW_V_AC_OUT) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Low V AC out");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::HIGH_V_AC_OUT) != 0) {
if ((val & VE_REG_ALARM_REASON::HIGH_V_AC_OUT) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("High V AC out");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::SHORT_CIRCUIT) != 0) {
if ((val & VE_REG_ALARM_REASON::SHORT_CIRCUIT) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Short Circuit");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::BMS_LOCKOUT) != 0) {
if ((val & VE_REG_ALARM_REASON::BMS_LOCKOUT) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("BMS Lockout");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::UNKNOWN_A) != 0) {
if ((val & VE_REG_ALARM_REASON::UNKNOWN_A) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Unknown error (0x4000)");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_ALARM_REASON::UNKNOWN_B) != 0) {
if ((val & VE_REG_ALARM_REASON::UNKNOWN_B) != VE_REG_ALARM_REASON::NO_ALARM) {
this->publish_state("Unknown error (0x8000)");
}
}
Expand Down Expand Up @@ -529,35 +538,35 @@ void VictronTextSensor::publish_state_(VE_REG_CHR_ERROR_CODE val) {
}

void VictronTextSensor::publish_state_(VE_REG_DEVICE_OFF_REASON_2 val) {
if ((u_int16_t) val == (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
if (val == VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("");
return;
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::NO_INPUT_POWER) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::NO_INPUT_POWER) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("No input power");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::SWITCHED_OFF_SWITCH) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::SWITCHED_OFF_SWITCH) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Switched off (power switch)");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::SWITCHED_OFF_REGISTER) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::SWITCHED_OFF_REGISTER) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Switched off (device mode register)");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::REMOTE_INPUT) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::REMOTE_INPUT) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Remote input");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::PROTECTION) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::PROTECTION) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Protection active");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::PAYGO) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::PAYGO) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Paygo");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::BMS) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::BMS) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("BMS");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::ENGINE) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::ENGINE) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Engine shutdown detection");
}
if (((u_int16_t) val & (u_int16_t) VE_REG_DEVICE_OFF_REASON_2::INPUT_VOLTATE) != 0) {
if ((val & VE_REG_DEVICE_OFF_REASON_2::INPUT_VOLTATE) != VE_REG_DEVICE_OFF_REASON_2::NOTHING) {
this->publish_state("Analysing input voltage");
}
}
Expand Down Expand Up @@ -616,5 +625,18 @@ void VictronTextSensor::publish_state_(VE_REG_BALANCER_STATUS val) {
}
}

void VictronTextSensor::publish_state_(VE_REG_DC_OUTPUT_STATUS val) {
switch (val) {
case VE_REG_DC_OUTPUT_STATUS::OFF:
this->publish_state("Off");
break;
case VE_REG_DC_OUTPUT_STATUS::ON:
this->publish_state("On");
break;
default:
break;
}
}

} // namespace victron_ble
} // namespace esphome
2 changes: 2 additions & 0 deletions components/victron_ble/text_sensor/victron_text_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum class VICTRON_TEXT_SENSOR_TYPE {
ERROR_CODE,
OFF_REASON,
WARNING_REASON,
OUTPUT_STATE,
BALANCER_STATUS,
};

Expand Down Expand Up @@ -82,6 +83,7 @@ class VictronTextSensor : public text_sensor::TextSensor, public Parented<Victro
void publish_state_(VE_REG_AC_IN_ACTIVE val);
void publish_state_(VE_REG_ALARM_NOTIFICATION val);
void publish_state_(VE_REG_BALANCER_STATUS val);
void publish_state_(VE_REG_DC_OUTPUT_STATUS val);
};
} // namespace victron_ble
} // namespace esphome
10 changes: 8 additions & 2 deletions components/victron_ble/victron_ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,10 +727,16 @@ struct VICTRON_BLE_RECORD_AC_CHARGER { // NOLINT(readability-identifier-naming,
vic_9bit_0_1_positive ac_current : 9;
} __attribute__((packed));

// source:
// - https://github.com/Fabian-Schmidt/esphome-victron_ble/issues/68
enum class VE_REG_DC_OUTPUT_STATUS : u_int8_t{
OFF = 0,
ON = 1,
};

struct VICTRON_BLE_RECORD_SMART_BATTERY_PROTECT { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
VE_REG_DEVICE_STATE device_state;
// TODO
u_int8_t output_state;
VE_REG_DC_OUTPUT_STATUS output_state;
VE_REG_CHR_ERROR_CODE error_code;
VE_REG_ALARM_REASON alarm_reason;
// Warnings always represent the current status of the measured parameter.
Expand Down

0 comments on commit e6052a7

Please sign in to comment.