[sendspin] Use register_apply_action for the switch, static delay and transition_finished actions (#19608)

This commit is contained in:
J. Nick Koston
2026-09-25 10:18:52 -04:00
committed by GitHub
parent cc5ed93247
commit 6fa56e18bd
9 changed files with 35 additions and 148 deletions
+4 -21
View File
@@ -21,8 +21,8 @@ from esphome.const import (
CONF_VERSION,
CONF_WIDTH,
)
from esphome.core import CORE, ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.core import CORE
from esphome.cpp_generator import MockObj
from esphome.types import ConfigType
# mdns for autodiscovery
@@ -109,13 +109,6 @@ SendspinHub = sendspin_ns.class_(
)
SendspinSwitchCommandAction = sendspin_ns.class_(
"SendspinSwitchCommandAction",
automation.Action,
cg.Parented.template(SendspinHub),
)
@dataclass
class SendspinConfiguration:
artwork_support: bool = False
@@ -240,21 +233,11 @@ SENDSPIN_SIMPLE_ACTION_SCHEMA = cv.All(
)
@automation.register_action(
automation.register_apply_action(
"sendspin.switch",
SendspinSwitchCommandAction,
SENDSPIN_SIMPLE_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("switch_client()"),
)
async def sendspin_switch_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_ESP32
#include "esphome/core/automation.h"
#include "sendspin_hub.h"
namespace esphome::sendspin_ {
#ifdef USE_SENDSPIN_CONTROLLER
template<typename... Ts> class SendspinSwitchCommandAction final : public Action<Ts...>, public Parented<SendspinHub> {
public:
void play(const Ts &...x) override {
// Clear any EXTERNAL_SOURCE state so the switch command is followed
this->parent_->update_state(sendspin::SendspinClientState::SYNCHRONIZED);
this->parent_->send_client_command(sendspin::SendspinControllerCommand::SWITCH);
}
};
#endif // USE_SENDSPIN_CONTROLLER
} // namespace esphome::sendspin_
#endif // USE_ESP32
+2 -20
View File
@@ -16,7 +16,6 @@ from esphome.const import (
CONF_WIDTH,
)
from esphome.core import ID
from esphome.cpp_generator import TemplateArgsType
from esphome.types import ConfigType
from .. import (
@@ -198,16 +197,8 @@ async def to_code(config: ConfigType) -> None:
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
SendspinImageTransitionFinishedAction = sendspin_ns.class_(
"SendspinImageTransitionFinishedAction",
automation.Action,
cg.Parented.template(SendspinImageSlot),
)
@automation.register_action(
automation.register_apply_action(
"sendspin.image.transition_finished",
SendspinImageTransitionFinishedAction,
automation.maybe_simple_id(
cv.Schema(
{
@@ -215,14 +206,5 @@ SendspinImageTransitionFinishedAction = sendspin_ns.class_(
}
)
),
synchronous=True,
automation.ApplyCall("transition_finished()"),
)
async def sendspin_image_transition_finished_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> cg.MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@@ -1,20 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#if defined(USE_ESP32) && defined(USE_SENDSPIN_ARTWORK)
#include "esphome/core/automation.h"
#include "sendspin_image.h"
namespace esphome::sendspin_ {
template<typename... Ts>
class SendspinImageTransitionFinishedAction final : public Action<Ts...>, public Parented<SendspinImageSlot> {
public:
void play(const Ts &...x) override { this->parent_->transition_finished(); }
};
} // namespace esphome::sendspin_
#endif
@@ -8,8 +8,6 @@ from esphome.const import (
CONF_SAMPLE_RATE,
CONF_TASK_STACK_IN_PSRAM,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
from .. import (
@@ -41,18 +39,6 @@ SendspinMediaSource = sendspin_ns.class_(
media_source.MediaSource,
)
EnableStaticDelayAdjustmentAction = sendspin_ns.class_(
"EnableStaticDelayAdjustmentAction",
automation.Action,
cg.Parented.template(SendspinMediaSource),
)
DisableStaticDelayAdjustmentAction = sendspin_ns.class_(
"DisableStaticDelayAdjustmentAction",
automation.Action,
cg.Parented.template(SendspinMediaSource),
)
def _resolve_codecs(config: ConfigType) -> ConfigType:
"""Validate the codec preference list, filling in the default when it is not set."""
@@ -144,25 +130,16 @@ SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA = automation.maybe_simple_id(
)
)
@automation.register_action(
"sendspin.media_source.enable_static_delay_adjustment",
EnableStaticDelayAdjustmentAction,
SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sendspin.media_source.disable_static_delay_adjustment",
DisableStaticDelayAdjustmentAction,
SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA,
synchronous=True,
)
async def sendspin_static_delay_adjustment_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
for _name, _call in (
(
"sendspin.media_source.enable_static_delay_adjustment",
"set_static_delay_adjustable(true)",
),
(
"sendspin.media_source.disable_static_delay_adjustment",
"set_static_delay_adjustable(false)",
),
):
automation.register_apply_action(
_name, SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA, automation.ApplyCall(_call)
)
@@ -1,26 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#if defined(USE_ESP32) && defined(USE_SENDSPIN_PLAYER) && defined(USE_SENDSPIN_CONTROLLER)
#include "esphome/core/automation.h"
#include "sendspin_media_source.h"
namespace esphome::sendspin_ {
template<typename... Ts>
class EnableStaticDelayAdjustmentAction final : public Action<Ts...>, public Parented<SendspinMediaSource> {
public:
void play(const Ts &...x) override { this->parent_->set_static_delay_adjustable(true); }
};
template<typename... Ts>
class DisableStaticDelayAdjustmentAction final : public Action<Ts...>, public Parented<SendspinMediaSource> {
public:
void play(const Ts &...x) override { this->parent_->set_static_delay_adjustable(false); }
};
} // namespace esphome::sendspin_
#endif
@@ -284,6 +284,13 @@ void SendspinHub::send_client_command(sendspin::SendspinControllerCommand comman
}
}
// THREAD CONTEXT: Main loop (invoked from the sendspin.switch action)
void SendspinHub::switch_client() {
// Clear any EXTERNAL_SOURCE state so the switch command is followed
this->update_state(sendspin::SendspinClientState::SYNCHRONIZED);
this->send_client_command(sendspin::SendspinControllerCommand::SWITCH);
}
// THREAD CONTEXT: Main loop (ControllerRoleListener override, fired from client_->loop())
void SendspinHub::on_controller_state(const sendspin::ServerStateControllerObject &state) {
this->controller_state_callbacks_.call(state);
@@ -181,6 +181,9 @@ class SendspinHub final : public Component,
void send_client_command(sendspin::SendspinControllerCommand command, std::optional<uint8_t> volume = std::nullopt,
std::optional<bool> mute = std::nullopt);
/// @brief Sends the SWITCH controller command; exposed as the sendspin.switch action.
void switch_client();
template<typename F> void add_controller_state_callback(F &&callback) {
this->controller_state_callbacks_.add(std::forward<F>(callback));
}
@@ -9,3 +9,9 @@ media_source:
static_delay_adjustable: true
fixed_delay: 480us
decode_memory: internal
wifi:
on_connect:
then:
- sendspin.media_source.enable_static_delay_adjustment: media_source_id
- sendspin.media_source.disable_static_delay_adjustment: media_source_id