Merge remote-tracking branch 'upstream/dev' into integration

This commit is contained in:
J. Nick Koston
2026-03-27 11:24:23 -10:00
26 changed files with 118 additions and 161 deletions
+2 -2
View File
@@ -58,7 +58,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -86,6 +86,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
with:
category: "/language:${{matrix.language}}"
+2 -2
View File
@@ -550,8 +550,8 @@ float ATM90E32Component::get_phase_harmonic_active_power_(uint8_t phase) {
}
float ATM90E32Component::get_phase_angle_(uint8_t phase) {
uint16_t val = this->read16_(ATM90E32_REGISTER_PANGLE + phase) / 10.0;
return (val > 180) ? (float) (val - 360.0f) : (float) val;
float val = this->read16_(ATM90E32_REGISTER_PANGLE + phase) / 10.0f;
return (val > 180.0f) ? val - 360.0f : val;
}
float ATM90E32Component::get_phase_peak_current_(uint8_t phase) {
-1
View File
@@ -134,7 +134,6 @@ class ATM90E32Component : public PollingComponent,
void set_freq_status_text_sensor(text_sensor::TextSensor *sensor) { this->freq_status_text_sensor_ = sensor; }
#endif
uint16_t calculate_voltage_threshold(int line_freq, uint16_t ugain, float multiplier);
int32_t last_periodic_millis = millis();
protected:
#ifdef USE_NUMBER
+7 -1
View File
@@ -690,9 +690,15 @@ ARDUINO_IDF_VERSION_LOOKUP = {
ESP_IDF_FRAMEWORK_VERSION_LOOKUP = {
"recommended": cv.Version(5, 5, 3, "1"),
"latest": cv.Version(5, 5, 3, "1"),
"dev": cv.Version(5, 5, 3, "1"),
"dev": cv.Version(5, 5, 4),
}
ESP_IDF_PLATFORM_VERSION_LOOKUP = {
cv.Version(
6, 0, 0
): "https://github.com/pioarduino/platform-espressif32.git#prep_IDF6",
cv.Version(
5, 5, 4
): "https://github.com/pioarduino/platform-espressif32.git#develop",
cv.Version(5, 5, 3, "1"): cv.Version(55, 3, 37),
cv.Version(5, 5, 3): cv.Version(55, 3, 37),
cv.Version(5, 5, 2): cv.Version(55, 3, 37),
@@ -350,7 +350,7 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
// For V3_WITHOUT_CACHE, we already set fast params before connecting
// No need to update them again here
this->log_event_("Searching for services");
esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr);
esp_ble_gattc_search_service(esp_gattc_if, param->open.conn_id, nullptr);
break;
}
case ESP_GATTC_CONNECT_EVT: {
@@ -159,7 +159,7 @@ void BLEService::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t g
break;
}
case ESP_GATTS_STOP_EVT: {
if (param->start.service_handle == this->handle_) {
if (param->stop.service_handle == this->handle_) {
this->state_ = STOPPED;
}
break;
+9 -9
View File
@@ -8,17 +8,17 @@ namespace max44009 {
static const char *const TAG = "max44009.sensor";
// REGISTERS
static const uint8_t MAX44009_REGISTER_CONFIGURATION = 0x02;
static const uint8_t MAX44009_LUX_READING_HIGH = 0x03;
static const uint8_t MAX44009_LUX_READING_LOW = 0x04;
static constexpr uint8_t MAX44009_REGISTER_CONFIGURATION = 0x02;
static constexpr uint8_t MAX44009_LUX_READING_HIGH = 0x03;
static constexpr uint8_t MAX44009_LUX_READING_LOW = 0x04;
// CONFIGURATION MASKS
static const uint8_t MAX44009_CFG_CONTINUOUS = 0x80;
static constexpr uint8_t MAX44009_CFG_CONTINUOUS = 0x80;
// ERROR CODES
static const uint8_t MAX44009_OK = 0;
static const uint8_t MAX44009_ERROR_WIRE_REQUEST = -10;
static const uint8_t MAX44009_ERROR_OVERFLOW = -20;
static const uint8_t MAX44009_ERROR_HIGH_BYTE = -30;
static const uint8_t MAX44009_ERROR_LOW_BYTE = -31;
static constexpr int8_t MAX44009_OK = 0;
static constexpr int8_t MAX44009_ERROR_WIRE_REQUEST = -10;
static constexpr int8_t MAX44009_ERROR_OVERFLOW = -20;
static constexpr int8_t MAX44009_ERROR_HIGH_BYTE = -30;
static constexpr int8_t MAX44009_ERROR_LOW_BYTE = -31;
void MAX44009Sensor::setup() {
bool state_ok = false;
+2 -2
View File
@@ -28,8 +28,8 @@ class MAX44009Sensor : public sensor::Sensor, public PollingComponent, public i2
uint8_t read_(uint8_t reg);
void write_(uint8_t reg, uint8_t value);
int error_;
MAX44009Mode mode_;
int8_t error_{0};
MAX44009Mode mode_{MAX44009_MODE_AUTO};
};
} // namespace max44009
+3 -1
View File
@@ -6,6 +6,8 @@ namespace mcp23008 {
static const char *const TAG = "mcp23008";
static constexpr uint8_t IOCON_ODR = 0x04; // Open-drain output for INT pin
void MCP23008::setup() {
uint8_t iocon;
if (!this->read_reg(mcp23x08_base::MCP23X08_IOCON, &iocon)) {
@@ -18,7 +20,7 @@ void MCP23008::setup() {
if (this->open_drain_ints_) {
// enable open-drain interrupt pins, 3.3V-safe
this->write_reg(mcp23x08_base::MCP23X08_IOCON, 0x04);
this->write_reg(mcp23x08_base::MCP23X08_IOCON, iocon | IOCON_ODR);
}
}
+4 -2
View File
@@ -6,6 +6,8 @@ namespace mcp23017 {
static const char *const TAG = "mcp23017";
static constexpr uint8_t IOCON_ODR = 0x04; // Open-drain output for INT pin
void MCP23017::setup() {
uint8_t iocon;
if (!this->read_reg(mcp23x17_base::MCP23X17_IOCONA, &iocon)) {
@@ -19,8 +21,8 @@ void MCP23017::setup() {
if (this->open_drain_ints_) {
// enable open-drain interrupt pins, 3.3V-safe
this->write_reg(mcp23x17_base::MCP23X17_IOCONA, 0x04);
this->write_reg(mcp23x17_base::MCP23X17_IOCONB, 0x04);
this->write_reg(mcp23x17_base::MCP23X17_IOCONA, iocon | IOCON_ODR);
this->write_reg(mcp23x17_base::MCP23X17_IOCONB, iocon | IOCON_ODR);
}
}
+10 -5
View File
@@ -6,6 +6,11 @@ namespace mcp23s08 {
static const char *const TAG = "mcp23s08";
// IOCON register bits
static constexpr uint8_t IOCON_SEQOP = 0x20; // Sequential operation mode
static constexpr uint8_t IOCON_HAEN = 0x08; // Hardware address enable
static constexpr uint8_t IOCON_ODR = 0x04; // Open-drain output for INT pin
void MCP23S08::set_device_address(uint8_t device_addr) {
if (device_addr != 0) {
this->device_opcode_ |= ((device_addr & 0x03) << 1);
@@ -15,19 +20,19 @@ void MCP23S08::set_device_address(uint8_t device_addr) {
void MCP23S08::setup() {
this->spi_setup();
// Enable HAEN (broadcast to all chips since HAEN isn't active yet)
this->enable();
uint8_t cmd = 0b01000000;
this->transfer_byte(cmd);
this->transfer_byte(0b01000000);
this->transfer_byte(mcp23x08_base::MCP23X08_IOCON);
this->transfer_byte(0b00011000); // Enable HAEN pins for addressing
this->transfer_byte(IOCON_SEQOP | IOCON_HAEN);
this->disable();
// Read current output register state
this->read_reg(mcp23x08_base::MCP23X08_OLAT, &this->olat_);
if (this->open_drain_ints_) {
// enable open-drain interrupt pins, 3.3V-safe
this->write_reg(mcp23x08_base::MCP23X08_IOCON, 0x04);
// enable open-drain interrupt pins, 3.3V-safe (addressed, only this chip)
this->write_reg(mcp23x08_base::MCP23X08_IOCON, IOCON_SEQOP | IOCON_HAEN | IOCON_ODR);
}
}
+13 -9
View File
@@ -6,6 +6,11 @@ namespace mcp23s17 {
static const char *const TAG = "mcp23s17";
// IOCON register bits
static constexpr uint8_t IOCON_SEQOP = 0x20; // Sequential operation mode
static constexpr uint8_t IOCON_HAEN = 0x08; // Hardware address enable
static constexpr uint8_t IOCON_ODR = 0x04; // Open-drain output for INT pin
void MCP23S17::set_device_address(uint8_t device_addr) {
if (device_addr != 0) {
this->device_opcode_ |= ((device_addr & 0b111) << 1);
@@ -15,18 +20,17 @@ void MCP23S17::set_device_address(uint8_t device_addr) {
void MCP23S17::setup() {
this->spi_setup();
// Enable HAEN (broadcast to addresses 0 and 4 since HAEN isn't active yet)
this->enable();
uint8_t cmd = 0b01000000;
this->transfer_byte(cmd);
this->transfer_byte(0b01000000);
this->transfer_byte(mcp23x17_base::MCP23X17_IOCONA);
this->transfer_byte(0b00011000); // Enable HAEN pins for addressing
this->transfer_byte(IOCON_SEQOP | IOCON_HAEN);
this->disable();
this->enable();
cmd = 0b01001000;
this->transfer_byte(cmd);
this->transfer_byte(0b01001000);
this->transfer_byte(mcp23x17_base::MCP23X17_IOCONA);
this->transfer_byte(0b00011000); // Enable HAEN pins for addressing
this->transfer_byte(IOCON_SEQOP | IOCON_HAEN);
this->disable();
// Read current output register state
@@ -34,9 +38,9 @@ void MCP23S17::setup() {
this->read_reg(mcp23x17_base::MCP23X17_OLATB, &this->olat_b_);
if (this->open_drain_ints_) {
// enable open-drain interrupt pins, 3.3V-safe
this->write_reg(mcp23x17_base::MCP23X17_IOCONA, 0x04);
this->write_reg(mcp23x17_base::MCP23X17_IOCONB, 0x04);
// enable open-drain interrupt pins, 3.3V-safe (addressed, only this chip)
this->write_reg(mcp23x17_base::MCP23X17_IOCONA, IOCON_SEQOP | IOCON_HAEN | IOCON_ODR);
this->write_reg(mcp23x17_base::MCP23X17_IOCONB, IOCON_SEQOP | IOCON_HAEN | IOCON_ODR);
}
}
+3 -3
View File
@@ -126,21 +126,21 @@ void MMC5603Component::update() {
int32_t raw_x = 0;
raw_x |= buffer[0] << 12;
raw_x |= buffer[1] << 4;
raw_x |= buffer[2] << 0;
raw_x |= buffer[2] & 0x0F;
const float x = 0.00625 * (raw_x - 524288);
int32_t raw_y = 0;
raw_y |= buffer[3] << 12;
raw_y |= buffer[4] << 4;
raw_y |= buffer[5] << 0;
raw_y |= buffer[5] & 0x0F;
const float y = 0.00625 * (raw_y - 524288);
int32_t raw_z = 0;
raw_z |= buffer[6] << 12;
raw_z |= buffer[7] << 4;
raw_z |= buffer[8] << 0;
raw_z |= buffer[8] & 0x0F;
const float z = 0.00625 * (raw_z - 524288);
@@ -15,7 +15,7 @@ class ModbusFloatOutput : public output::FloatOutput, public Component, public S
this->register_type = ModbusRegisterType::HOLDING;
this->start_address = start_address;
this->offset = offset;
this->bitmask = bitmask;
this->bitmask = 0xFFFFFFFF;
this->register_count = register_count;
this->sensor_value_type = value_type;
this->skip_updates = 0;
@@ -47,7 +47,7 @@ class ModbusBinaryOutput : public output::BinaryOutput, public Component, public
ModbusBinaryOutput(uint16_t start_address, uint8_t offset) {
this->register_type = ModbusRegisterType::COIL;
this->start_address = start_address;
this->bitmask = bitmask;
this->bitmask = 0xFFFFFFFF;
this->sensor_value_type = SensorValueType::BIT;
this->skip_updates = 0;
this->register_count = 1;
+6 -8
View File
@@ -841,10 +841,10 @@ void Nextion::process_nextion_commands_() {
if (this->max_q_age_ms_ > 0 && !this->nextion_queue_.empty() &&
ms - this->nextion_queue_.front()->queue_time > this->max_q_age_ms_) {
for (size_t i = 0; i < this->nextion_queue_.size(); i++) {
NextionComponentBase *component = this->nextion_queue_[i]->component;
if (ms - this->nextion_queue_[i]->queue_time > this->max_q_age_ms_) {
if (this->nextion_queue_[i]->queue_time == 0) {
for (auto it = this->nextion_queue_.begin(); it != this->nextion_queue_.end();) {
NextionComponentBase *component = (*it)->component;
if (ms - (*it)->queue_time > this->max_q_age_ms_) {
if ((*it)->queue_time == 0) {
ESP_LOGD(TAG, "Remove old queue '%s':'%s' (t=0)", component->get_queue_type_string().c_str(),
component->get_variable_name().c_str());
}
@@ -863,10 +863,8 @@ void Nextion::process_nextion_commands_() {
delete component; // NOLINT(cppcoreguidelines-owning-memory)
}
delete this->nextion_queue_[i]; // NOLINT(cppcoreguidelines-owning-memory)
this->nextion_queue_.erase(this->nextion_queue_.begin() + i);
i--;
delete *it; // NOLINT(cppcoreguidelines-owning-memory)
it = this->nextion_queue_.erase(it);
} else {
break;
+6 -6
View File
@@ -1,16 +1,16 @@
#pragma once
#include <deque>
#include <list>
#include <vector>
#include "esphome/components/display/display.h"
#include "esphome/components/display/display_color_utils.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/defines.h"
#include "esphome/core/time.h"
#include "esphome/components/uart/uart.h"
#include "nextion_base.h"
#include "nextion_component.h"
#include "esphome/components/display/display.h"
#include "esphome/components/display/display_color_utils.h"
#ifdef USE_NEXTION_TFT_UPLOAD
#ifdef USE_ESP32
@@ -1391,8 +1391,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
void process_pending_in_queue_();
#endif // USE_NEXTION_COMMAND_SPACING
std::deque<NextionQueue *> nextion_queue_;
std::deque<NextionQueue *> waveform_queue_;
std::list<NextionQueue *> nextion_queue_;
std::list<NextionQueue *> waveform_queue_;
uint16_t recv_ret_string_(std::string &response, uint32_t timeout, bool recv_flag);
void all_components_send_state_(bool force_update = false);
uint32_t comok_sent_ = 0;
+2 -2
View File
@@ -101,10 +101,10 @@ PIDAutotuner::PIDAutotuneResult PIDAutotuner::update(float setpoint, float proce
if (!zc_symmetrical || !amplitude_convergent) {
// The frequency/amplitude is not fully accurate yet, try to wait
// until the fault clears, or terminate after a while anyway
if (zc_symmetrical) {
if (!zc_symmetrical) {
ESP_LOGVV(TAG, "%s: ZC is not symmetrical", this->id_.c_str());
}
if (amplitude_convergent) {
if (!amplitude_convergent) {
ESP_LOGVV(TAG, "%s: Amplitude is not convergent", this->id_.c_str());
}
uint32_t phase = this->relay_function_.phase_count;
-1
View File
@@ -3,7 +3,6 @@
#include "esphome/core/component.h"
#include "esphome/core/optional.h"
#include "pid_controller.h"
#include "pid_simulator.h"
#include <vector>
-77
View File
@@ -1,77 +0,0 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/output/float_output.h"
#include <vector>
namespace esphome {
namespace pid {
class PIDSimulator : public PollingComponent, public output::FloatOutput {
public:
PIDSimulator() : PollingComponent(1000) {}
float surface = 1; /// surface area in m²
float mass = 3; /// mass of simulated object in kg
float temperature = 21; /// current temperature of object in °C
float efficiency = 0.98; /// heating efficiency, 1 is 100% efficient
float thermal_conductivity = 15; /// thermal conductivity of surface are in W/(m*K), here: steel
float specific_heat_capacity = 4.182; /// specific heat capacity of mass in kJ/(kg*K), here: water
float heat_power = 500; /// Heating power in W
float ambient_temperature = 20; /// Ambient temperature in °C
float update_interval = 1; /// The simulated updated interval in seconds
std::vector<float> delayed_temps; /// storage of past temperatures for delaying temperature reading
size_t delay_cycles = 15; /// how many update cycles to delay the output
float output_value = 0.0; /// Current output value of heating element
sensor::Sensor *sensor = new sensor::Sensor();
float delta_t(float power) {
// P = Q / t
// Q = c * m * 𝚫t
// 𝚫t = (P*t) / (c*m)
float c = this->specific_heat_capacity;
float t = this->update_interval;
float p = power / 1000; // in kW
float m = this->mass;
return (p * t) / (c * m);
}
float update_temp() {
float value = clamp(output_value, 0.0f, 1.0f);
// Heat
float power = value * heat_power * efficiency;
temperature += this->delta_t(power);
// Cool
// Q = k_w * A * (T_mass - T_ambient)
// P = Q / t
float dt = temperature - ambient_temperature;
float cool_power = (thermal_conductivity * surface * dt) / update_interval;
temperature -= this->delta_t(cool_power);
// Delay temperature readings
delayed_temps.push_back(temperature);
if (delayed_temps.size() > delay_cycles)
delayed_temps.erase(delayed_temps.begin());
float prev_temp = this->delayed_temps[0];
float alpha = 0.1f;
float ret = (1 - alpha) * prev_temp + alpha * prev_temp;
return ret;
}
void setup() override { sensor->publish_state(this->temperature); }
void update() override {
float new_temp = this->update_temp();
sensor->publish_state(new_temp);
}
protected:
void write_state(float state) override { this->output_value = state; }
};
} // namespace pid
} // namespace esphome
@@ -1,5 +1,6 @@
#include "gobox_protocol.h"
#include "esphome/core/log.h"
#include <cinttypes>
namespace esphome {
namespace remote_base {
@@ -25,7 +26,7 @@ void GoboxProtocol::encode(RemoteTransmitData *dst, const GoboxData &data) {
dst->set_carrier_frequency(38000);
dst->reserve((HEADER_SIZE + CODE_SIZE + 1) * 2);
uint64_t code = (HEADER << CODE_SIZE) | (data.code & ((1UL << CODE_SIZE) - 1));
ESP_LOGI(TAG, "Send Gobox: code=0x%Lx", code);
ESP_LOGI(TAG, "Send Gobox: code=0x%016" PRIx64, code);
for (int16_t i = (HEADER_SIZE + CODE_SIZE - 1); i >= 0; i--) {
if (code & ((uint64_t) 1 << i)) {
dst->item(BIT_MARK_US, BIT_ONE_SPACE_US);
+23 -16
View File
@@ -44,20 +44,27 @@ def validate_sensors(config):
return config
GAS_SENSOR = cv.Schema(
{
cv.Optional(CONF_ALGORITHM_TUNING): cv.Schema(
{
cv.Optional(CONF_INDEX_OFFSET, default=100): cv.int_,
cv.Optional(CONF_LEARNING_TIME_OFFSET_HOURS, default=12): cv.int_,
cv.Optional(CONF_LEARNING_TIME_GAIN_HOURS, default=12): cv.int_,
cv.Optional(CONF_GATING_MAX_DURATION_MINUTES, default=720): cv.int_,
cv.Optional(CONF_STD_INITIAL, default=50): cv.int_,
cv.Optional(CONF_GAIN_FACTOR, default=230): cv.int_,
}
)
}
)
def _gas_sensor_schema(index_offset_default: int):
return cv.Schema(
{
cv.Optional(CONF_ALGORITHM_TUNING): cv.Schema(
{
cv.Optional(
CONF_INDEX_OFFSET, default=index_offset_default
): cv.int_,
cv.Optional(CONF_LEARNING_TIME_OFFSET_HOURS, default=12): cv.int_,
cv.Optional(CONF_LEARNING_TIME_GAIN_HOURS, default=12): cv.int_,
cv.Optional(CONF_GATING_MAX_DURATION_MINUTES, default=720): cv.int_,
cv.Optional(CONF_STD_INITIAL, default=50): cv.int_,
cv.Optional(CONF_GAIN_FACTOR, default=230): cv.int_,
}
)
}
)
VOC_SENSOR = _gas_sensor_schema(100)
NOX_SENSOR = _gas_sensor_schema(1)
CONFIG_SCHEMA = cv.All(
cv.Schema(
@@ -68,13 +75,13 @@ CONFIG_SCHEMA = cv.All(
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
).extend(GAS_SENSOR),
).extend(VOC_SENSOR),
cv.Optional(CONF_NOX): sensor.sensor_schema(
icon=ICON_RADIATOR,
accuracy_decimals=0,
device_class=DEVICE_CLASS_AQI,
state_class=STATE_CLASS_MEASUREMENT,
).extend(GAS_SENSOR),
).extend(NOX_SENSOR),
cv.Optional(CONF_STORE_BASELINE, default=True): cv.boolean,
cv.Optional(CONF_VOC_BASELINE): cv.hex_uint16_t,
cv.Optional(CONF_COMPENSATION): cv.Schema(
+1 -1
View File
@@ -25,7 +25,7 @@ void SM2135::setup() {
this->data_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->clock_pin_->setup();
this->clock_pin_->digital_write(false);
this->data_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->clock_pin_->pin_mode(gpio::FLAG_OUTPUT);
this->data_pin_->pin_mode(gpio::FLAG_PULLUP);
this->clock_pin_->pin_mode(gpio::FLAG_PULLUP);
+2 -2
View File
@@ -309,8 +309,8 @@ void SX1509Component::set_debounce_keypad_(uint8_t time, uint8_t num_rows, uint8
set_debounce_time_(time);
for (uint16_t i = 0; i < num_rows; i++)
set_debounce_pin_(i);
for (uint16_t i = 0; i < (8 + num_cols); i++)
set_debounce_pin_(i);
for (uint16_t i = 0; i < num_cols; i++)
set_debounce_pin_(i + 8);
}
} // namespace sx1509
@@ -105,8 +105,8 @@ class TuyaClimate : public climate::Climate, public Component {
optional<uint8_t> sleep_id_{};
optional<float> eco_temperature_{};
TuyaDatapointType eco_type_{};
uint8_t active_state_;
uint8_t fan_state_;
uint8_t active_state_{0};
uint8_t fan_state_{0};
optional<uint8_t> swing_vertical_id_{};
optional<uint8_t> swing_horizontal_id_{};
optional<uint8_t> fan_speed_id_{};
@@ -119,9 +119,9 @@ class TuyaClimate : public climate::Climate, public Component {
bool swing_horizontal_{false};
bool heating_state_{false};
bool cooling_state_{false};
float manual_temperature_;
bool eco_;
bool sleep_;
float manual_temperature_{NAN};
bool eco_{false};
bool sleep_{false};
bool reports_fahrenheit_{false};
};
+4
View File
@@ -102,6 +102,7 @@ def clone_or_update(
username: str = None,
password: str = None,
submodules: list[str] | None = None,
subpath: Path | None = None,
_recover_broken: bool = True,
) -> tuple[Path, Callable[[], None] | None]:
key = f"{url}@{ref}"
@@ -112,6 +113,9 @@ def clone_or_update(
)
repo_dir = _compute_destination_path(key, domain)
if subpath:
repo_dir = repo_dir / subpath
if not repo_dir.is_dir():
_LOGGER.info("Cloning %s", key)
_LOGGER.debug("Location: %s", repo_dir)
+8 -1
View File
@@ -83,11 +83,18 @@ async def test_uart_mock_ld2450(
],
)
# Signal when we see recovery frame values (target 1 distance ≈ 500mm)
# Signal when we see all recovery frame values
# Must wait for ALL values to avoid race where some arrive after the waiter fires
recovery_received = collector.add_waiter(
lambda: (
pytest.approx(500.0, abs=1.0)
in collector.sensor_states["target_1_distance"]
and pytest.approx(300.0) in collector.sensor_states["target_1_x"]
and pytest.approx(400.0) in collector.sensor_states["target_1_y"]
and pytest.approx(30.0) in collector.sensor_states["target_1_speed"]
and pytest.approx(1.0) in collector.sensor_states["target_count"]
and pytest.approx(1.0) in collector.sensor_states["moving_target_count"]
and pytest.approx(0.0) in collector.sensor_states["still_target_count"]
)
)