ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
sendspin_hub.h
Go to the documentation of this file.
1#pragma once
2
4
5#ifdef USE_ESP32
6
11
12#include <sendspin/client.h>
13#include <sendspin/config.h>
14#include <sendspin/types.h>
15
16#ifdef USE_SENDSPIN_CONTROLLER
17#include <sendspin/controller_role.h>
18#endif
19#ifdef USE_SENDSPIN_METADATA
20#include <sendspin/metadata_role.h>
21#endif
22#ifdef USE_SENDSPIN_PLAYER
23#include <sendspin/player_role.h>
24#endif
25
26#include <functional>
27#include <memory>
28#include <optional>
29
30namespace esphome::sendspin_ {
31
37namespace sendspin_priority {
38// AFTER_WIFI so the hub runs after the wifi/ethernet drivers are up and we can read the active
39// interface's MAC for client_id.
41inline constexpr float CHILD = HUB - 1.0f;
42} // namespace sendspin_priority
43
48
49#ifdef USE_SENDSPIN_PLAYER
52 uint16_t delay_ms;
53};
54#endif
55
71class SendspinHub final : public Component,
72#ifdef USE_SENDSPIN_CONTROLLER
73 public sendspin::ControllerRoleListener,
74#endif
75#ifdef USE_SENDSPIN_METADATA
76 public sendspin::MetadataRoleListener,
77#endif
78 public sendspin::SendspinClientListener,
79 public sendspin::SendspinNetworkProvider,
80 public sendspin::SendspinPersistenceProvider {
81 public:
82 float get_setup_priority() const override { return sendspin_priority::HUB; }
83 void setup() override;
84 void loop() override;
85 void dump_config() override;
86
92 void connect_to_server(const std::string &url);
93
103 void disconnect_from_server(sendspin::SendspinGoodbyeReason reason);
104
112 void update_state(sendspin::SendspinClientState state);
113
114 // --- Configuration setters (called from codegen) ---
115
116 template<typename F> void add_group_update_callback(F &&callback) {
117 this->group_update_callbacks_.add(std::forward<F>(callback));
118 }
119
120 void set_task_stack_in_psram(bool task_stack_in_psram) { this->task_stack_in_psram_ = task_stack_in_psram; }
121
122 // --- Sendspin role specific methods ---
123
124#ifdef USE_SENDSPIN_CONTROLLER
125 void send_client_command(sendspin::SendspinControllerCommand command, std::optional<uint8_t> volume = std::nullopt,
126 std::optional<bool> mute = std::nullopt);
127
128 template<typename F> void add_controller_state_callback(F &&callback) {
129 this->controller_state_callbacks_.add(std::forward<F>(callback));
130 }
131#endif
132
133#ifdef USE_SENDSPIN_METADATA
134 template<typename F> void add_metadata_update_callback(F &&callback) {
135 this->metadata_update_callbacks_.add(std::forward<F>(callback));
136 }
137
140#endif
141
142#ifdef USE_SENDSPIN_PLAYER
143 void set_listener(sendspin::PlayerRoleListener *listener) { this->player_listener_ = listener; }
144 void set_player_config(const sendspin::PlayerRoleConfig &config) { this->player_config_ = config; }
145
147 sendspin::PlayerRole *get_player_role();
148#endif
149
150 protected:
152 sendspin::SendspinClientConfig build_client_config_();
153
156 static const char *get_client_id_into_buffer(std::span<char, MAC_ADDRESS_PRETTY_BUFFER_SIZE> buf);
157
158 // --- SendspinClientListener overrides ---
159 void on_group_update(const sendspin::GroupUpdateObject &group) override;
160
161 void on_request_high_performance() override;
162
163 void on_release_high_performance() override;
164
165 // --- SendspinNetworkProvider override ---
166 bool is_network_ready() override;
167
168 // --- SendspinPersistenceProvider overrides ---
169 bool save_last_server_hash(uint32_t hash) override;
170 std::optional<uint32_t> load_last_server_hash() override;
171
172 // --- Sendspin role specific methods/overrides/member variables ---
173
174#ifdef USE_SENDSPIN_CONTROLLER
175 sendspin::ControllerRole *controller_role_{nullptr};
176
177 void on_controller_state(const sendspin::ServerStateControllerObject &state) override;
178
179 // Callback fan-out to child components; they filter as needed
180 CallbackManager<void(const sendspin::ServerStateControllerObject &)> controller_state_callbacks_{};
181#endif
182
183#ifdef USE_SENDSPIN_METADATA
184 sendspin::MetadataRole *metadata_role_{nullptr};
185
186 void on_metadata(const sendspin::ServerMetadataStateObject &metadata) override;
187
188 // Callback fan-out to child components; they filter as needed
189 CallbackManager<void(const sendspin::ServerMetadataStateObject &)> metadata_update_callbacks_{};
190#endif
191
192#ifdef USE_SENDSPIN_PLAYER
193 sendspin::PlayerRoleListener *player_listener_{nullptr};
194 sendspin::PlayerRoleConfig player_config_{};
195
196 // Part of SendspinPersistenceProvider overrides
198 std::optional<uint16_t> load_static_delay() override;
199 bool save_static_delay(uint16_t delay_ms) override;
200#endif
201
202 // --- Core member variables ---
203
205
206 std::unique_ptr<sendspin::SendspinClient> client_;
207
208 // Callback fan-out to child components
209 CallbackManager<void(const sendspin::GroupUpdateObject &)> group_update_callbacks_{};
210
212};
213
220class SendspinChild : public Component, public Parented<SendspinHub> {
221 public:
222 float get_setup_priority() const override { return sendspin_priority::CHILD; }
223};
224
230class SendspinPollingChild : public PollingComponent, public Parented<SendspinHub> {
231 public:
232 float get_setup_priority() const override { return sendspin_priority::CHILD; }
233};
234
235} // namespace esphome::sendspin_
236
237#endif // USE_ESP32
Helper class to easily give an object a parent of type T.
Definition helpers.h:1861
This class simplifies creating components that periodically check a state.
Definition component.h:602
Base class for all sendspin subcomponents.
float get_setup_priority() const override
Thin adapter over sendspin::SendspinClient.
sendspin::PlayerRoleListener * player_listener_
void update_state(sendspin::SendspinClientState state)
Updates the client's reported playback state on the server.
bool save_last_server_hash(uint32_t hash) override
bool save_static_delay(uint16_t delay_ms) override
CallbackManager< void(const sendspin::ServerMetadataStateObject &)> metadata_update_callbacks_
CallbackManager< void(const sendspin::ServerStateControllerObject &)> controller_state_callbacks_
static const char * get_client_id_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Writes the active network interface's MAC into buf and returns its data pointer.
void add_group_update_callback(F &&callback)
void on_release_high_performance() override
sendspin::MetadataRole * metadata_role_
CallbackManager< void(const sendspin::GroupUpdateObject &)> group_update_callbacks_
sendspin::PlayerRoleConfig player_config_
void on_metadata(const sendspin::ServerMetadataStateObject &metadata) override
void set_player_config(const sendspin::PlayerRoleConfig &config)
sendspin::PlayerRole * get_player_role()
Child components call this to get the PlayerRole instance after setup, so they can push updates to it...
void set_listener(sendspin::PlayerRoleListener *listener)
void disconnect_from_server(sendspin::SendspinGoodbyeReason reason)
Disconnects the underlying client from the current server.
std::optional< uint16_t > load_static_delay() override
std::unique_ptr< sendspin::SendspinClient > client_
sendspin::SendspinClientConfig build_client_config_()
Builds the SendspinClientConfig from ESPHome configuration and platform info.
sendspin::ControllerRole * controller_role_
ESPPreferenceObject last_played_server_pref_
uint32_t get_track_progress_ms() const
Returns the interpolated track progress in milliseconds, or 0 if the hub is not yet ready.
void add_controller_state_callback(F &&callback)
void send_client_command(sendspin::SendspinControllerCommand command, std::optional< uint8_t > volume=std::nullopt, std::optional< bool > mute=std::nullopt)
ESPPreferenceObject static_delay_pref_
void set_task_stack_in_psram(bool task_stack_in_psram)
void on_request_high_performance() override
float get_setup_priority() const override
std::optional< uint32_t > load_last_server_hash() override
void on_controller_state(const sendspin::ServerStateControllerObject &state) override
void connect_to_server(const std::string &url)
Connects the underlying client to the given Sendspin server.
void on_group_update(const sendspin::GroupUpdateObject &group) override
void add_metadata_update_callback(F &&callback)
Base class for sendspin subcomponents that need polling behavior.
float get_setup_priority() const override
bool state
Definition fan.h:2
constexpr float AFTER_WIFI
For components that should be initialized after WiFi is connected.
Definition component.h:53
static void uint32_t
Persistent storage structure for last played server hash.
Persistent storage structure for player static delay.