ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
sendspin_sensor.cpp
Go to the documentation of this file.
1#include "sendspin_sensor.h"
2
3#if defined(USE_ESP32) && defined(USE_SENDSPIN_METADATA) && defined(USE_SENSOR)
4
5#include <sendspin/metadata_role.h>
6
7namespace esphome::sendspin_ {
8
9static const char *const TAG = "sendspin.sensor";
10
11// --- SendspinTrackProgressSensor ---
12
14 LOG_SENSOR("", "Track Progress", this);
15 LOG_UPDATE_INTERVAL(this);
16}
17
18// THREAD CONTEXT: Main loop. The registered metadata callback also fires on the main loop
19// (SendspinHub dispatches metadata from client_->loop()).
21 this->parent_->add_metadata_update_callback([this](const sendspin::ServerMetadataStateObject &metadata) {
22 if (!metadata.progress.has_value()) {
23 return;
24 }
25 const auto &progress = metadata.progress.value();
26 if (progress.playback_speed == 0) {
27 // Paused: freeze progress at the reported position and stop polling to save cycles.
28 this->stop_poller();
29 this->publish_state(progress.track_progress);
30 } else {
31 // Resumed: publish the fresh interpolated position immediately so the frontend doesn't show a stale
32 // paused value until the next poll tick.
33 this->publish_state(this->parent_->get_track_progress_ms());
34 this->start_poller();
35 }
36 });
37}
38
39// THREAD CONTEXT: Main loop.
40// Sendspin only pushes progress on state changes (play/pause/seek/speed change), not continuously during
41// playback. The hub helper interpolates the current position from the last server update and the playback
42// speed, giving us a fresh value on every poll.
43void SendspinTrackProgressSensor::update() { this->publish_state(this->parent_->get_track_progress_ms()); }
44
45// --- SendspinMetadataSensor ---
46
48 switch (this->metadata_type_) {
50 LOG_SENSOR("", "Track Duration", this);
51 break;
53 LOG_SENSOR("", "Year", this);
54 break;
56 LOG_SENSOR("", "Track", this);
57 break;
58 }
59}
60
61std::optional<float> SendspinMetadataSensor::extract_value_(const sendspin::ServerMetadataStateObject &metadata) const {
62 switch (this->metadata_type_) {
64 if (metadata.progress.has_value())
65 return metadata.progress.value().track_duration;
66 return std::nullopt;
68 if (metadata.year.has_value())
69 return metadata.year.value();
70 return std::nullopt;
72 if (metadata.track.has_value())
73 return metadata.track.value();
74 return std::nullopt;
75 }
76 return std::nullopt;
77}
78
79// THREAD CONTEXT: Main loop. The registered metadata callback also fires on the main loop
80// (SendspinHub dispatches metadata from client_->loop()).
82 this->parent_->add_metadata_update_callback([this](const sendspin::ServerMetadataStateObject &metadata) {
83 if (auto value = this->extract_value_(metadata)) {
84 this->publish_if_changed_(*value);
85 }
86 });
87}
88
89// Dedup to avoid frontend churn; Sensor::publish_state always notifies without checking for changes.
91 if (this->get_raw_state() != value) {
92 this->publish_state(value);
93 }
94}
95
96} // namespace esphome::sendspin_
97
98#endif
SendspinNumericMetadataTypes metadata_type_
std::optional< float > extract_value_(const sendspin::ServerMetadataStateObject &metadata) const
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
float get_raw_state() const
Getter-syntax for .raw_state.
Definition sensor.h:100