22static const char *
const TAG =
"sendspin.hub";
24#ifdef USE_SENDSPIN_ARTWORK
26static const char *
const IMAGE_SOURCE_NAMES[] = {
"ALBUM",
"ARTIST",
"NONE"};
27static const char *
const IMAGE_FORMAT_NAMES[] = {
"JPEG",
"PNG",
"BMP"};
32 this->
client_ = std::make_unique<sendspin::SendspinClient>(std::move(config));
37#ifdef USE_SENDSPIN_PLAYER
42 this->
client_->set_listener(
this);
43 this->
client_->set_network_provider(
this);
44 this->
client_->set_persistence_provider(
this);
46#ifdef USE_SENDSPIN_ARTWORK
51#ifdef USE_SENDSPIN_CONTROLLER
56#ifdef USE_SENDSPIN_METADATA
61#ifdef USE_SENDSPIN_PLAYER
65 if (!this->
client_->start_server()) {
66 ESP_LOGE(TAG,
"Failed to start Sendspin server");
75 char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
79 " Task stack in PSRAM: %s",
82#ifdef USE_SENDSPIN_ARTWORK
86 for (
const auto &preference : this->
artwork_config_.preferred_formats) {
87 ESP_LOGCONFIG(TAG,
" Artwork slot %u: %s as %s, %ux%u, display offset %" PRId32
" ms", slot++,
88 IMAGE_SOURCE_NAMES[
static_cast<uint8_t
>(preference.source)],
89 IMAGE_FORMAT_NAMES[
static_cast<uint8_t
>(preference.format)], preference.width, preference.height,
90 preference.display_offset_ms);
100 this->
client_->connect_to(url);
107 this->
client_->disconnect(reason);
114 this->
client_->update_state(state);
131 sendspin::SendspinClientConfig config;
133 char mac_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
137 config.manufacturer =
"ESPHome";
138 config.software_version = ESPHOME_VERSION;
181 ESP_LOGD(TAG,
"Persisted last played server hash: 0x%08" PRIX32, hash);
183 ESP_LOGW(TAG,
"Failed to persist last played server hash");
192 ESP_LOGI(TAG,
"Loaded last played server hash: 0x%08" PRIX32, pref.server_id_hash);
193 return pref.server_id_hash;
200#ifdef USE_SENDSPIN_ARTWORK
203 sendspin::SendspinImageFormat
format) {
224#ifdef USE_SENDSPIN_CONTROLLER
227 std::optional<bool> mute) {
229 sendspin::ClientCommandControllerObject obj = {
250#ifdef USE_SENDSPIN_METADATA
271#ifdef USE_SENDSPIN_PLAYER
275 return this->
client_->player();
285 ESP_LOGD(TAG,
"Persisted static delay: %u ms", delay_ms);
287 ESP_LOGW(TAG,
"Failed to persist static delay");
296 ESP_LOGI(TAG,
"Loaded static delay: %u ms", pref.delay_ms);
297 return pref.delay_ms;
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
const StringRef & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
void mark_failed()
Mark this component as failed.
ESPDEPRECATED("Use get_eth_mac_address_pretty_into_buffer() instead. Removed in 2026.9.0", "2026.3.0") std const char * get_eth_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
CallbackManager< void(uint8_t, const uint8_t *, size_t, sendspin::SendspinImageFormat)> artwork_image_decode_callbacks_
CallbackManager< void(uint8_t, uint32_t)> artwork_image_display_callbacks_
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
void on_controller_state_clear() override
CallbackManager< void(const sendspin::ServerMetadataStateObject &)> metadata_update_callbacks_
LazyCallbackManager< 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 on_release_high_performance() override
bool is_network_ready() 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 dump_config() override
sendspin::PlayerRole * get_player_role()
Child components call this to get the PlayerRole instance after setup, so they can push updates to it...
void on_image_clear(uint8_t slot) override
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::ArtworkRoleConfig artwork_config_
sendspin::SendspinClientConfig build_client_config_()
Builds the SendspinClientConfig from ESPHome configuration and platform info.
sendspin::ControllerRole * controller_role_
ESPPreferenceObject last_played_server_pref_
bool task_stack_in_psram_
uint32_t get_track_progress_ms() const
Returns the interpolated track progress in milliseconds, or 0 if the hub is not yet ready.
void send_client_command(sendspin::SendspinControllerCommand command, std::optional< uint8_t > volume=std::nullopt, std::optional< bool > mute=std::nullopt)
LazyCallbackManager< void()> controller_state_clear_callbacks_
void on_metadata_clear() override
ESPPreferenceObject static_delay_pref_
CallbackManager< void(uint8_t)> artwork_image_clear_callbacks_
sendspin::ArtworkRole * artwork_role_
void on_request_high_performance() override
void on_image_display(uint8_t slot, uint32_t lateness_ms) override
void on_image_decode(uint8_t slot, const uint8_t *data, size_t length, sendspin::SendspinImageFormat format) 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 artwork_frame_done(uint8_t slot)
Acknowledges the most recent artwork delivery (display or clear) for a slot.
bool request_high_performance()
Request high-performance mode (no power saving) for improved WiFi latency.
void release_roaming_suppression()
Release a roaming suppression request.
void request_roaming_suppression()
Request that post-connect roaming scans be suppressed.
bool release_high_performance()
Release a high-performance mode request.
EthernetComponent * global_eth_component
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
WiFiComponent * global_wifi_component
const char int const __FlashStringHelper * format
ESPPreferences * global_preferences
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
Application App
Global storage of Application pointer - only one Application can exist.
constexpr uint32_t fnv1a_hash(const char *str)
Calculate a FNV-1a hash of str.
ESPPreferenceObject make_preference(size_t, uint32_t, bool)
Persistent storage structure for last played server hash.
Persistent storage structure for player static delay.