55
66from spotifyaio .models import AudioFeatures
77
8- from homeassistant .components .sensor import SensorEntity , SensorEntityDescription
8+ from homeassistant .components .sensor import (
9+ SensorDeviceClass ,
10+ SensorEntity ,
11+ SensorEntityDescription ,
12+ )
13+ from homeassistant .const import PERCENTAGE
914from homeassistant .core import HomeAssistant
1015from homeassistant .helpers .entity_platform import AddEntitiesCallback
1116
1722class SpotifyAudioFeaturesSensorEntityDescription (SensorEntityDescription ):
1823 """Describes Spotify sensor entity."""
1924
20- value_fn : Callable [[AudioFeatures ], float ]
25+ value_fn : Callable [[AudioFeatures ], float | str | None ]
26+
27+
28+ def _get_key (audio_features : AudioFeatures ) -> str | None :
29+ if audio_features .key is None :
30+ return None
31+ key_name = audio_features .key .name
32+ base = key_name [0 ]
33+ if len (key_name ) > 1 :
34+ base = f"{ base } ♯"
35+ return base
2136
2237
2338AUDIO_FEATURE_SENSORS : tuple [SpotifyAudioFeaturesSensorEntityDescription , ...] = (
@@ -28,6 +43,86 @@ class SpotifyAudioFeaturesSensorEntityDescription(SensorEntityDescription):
2843 suggested_display_precision = 0 ,
2944 value_fn = lambda audio_features : audio_features .tempo ,
3045 ),
46+ SpotifyAudioFeaturesSensorEntityDescription (
47+ key = "danceability" ,
48+ translation_key = "danceability" ,
49+ native_unit_of_measurement = PERCENTAGE ,
50+ suggested_display_precision = 0 ,
51+ value_fn = lambda audio_features : audio_features .danceability * 100 ,
52+ entity_registry_enabled_default = False ,
53+ ),
54+ SpotifyAudioFeaturesSensorEntityDescription (
55+ key = "energy" ,
56+ translation_key = "energy" ,
57+ native_unit_of_measurement = PERCENTAGE ,
58+ suggested_display_precision = 0 ,
59+ value_fn = lambda audio_features : audio_features .energy * 100 ,
60+ entity_registry_enabled_default = False ,
61+ ),
62+ SpotifyAudioFeaturesSensorEntityDescription (
63+ key = "mode" ,
64+ translation_key = "mode" ,
65+ device_class = SensorDeviceClass .ENUM ,
66+ options = ["major" , "minor" ],
67+ value_fn = lambda audio_features : audio_features .mode .name .lower (),
68+ entity_registry_enabled_default = False ,
69+ ),
70+ SpotifyAudioFeaturesSensorEntityDescription (
71+ key = "speechiness" ,
72+ translation_key = "speechiness" ,
73+ native_unit_of_measurement = PERCENTAGE ,
74+ suggested_display_precision = 0 ,
75+ value_fn = lambda audio_features : audio_features .speechiness * 100 ,
76+ entity_registry_enabled_default = False ,
77+ ),
78+ SpotifyAudioFeaturesSensorEntityDescription (
79+ key = "acousticness" ,
80+ translation_key = "acousticness" ,
81+ native_unit_of_measurement = PERCENTAGE ,
82+ suggested_display_precision = 0 ,
83+ value_fn = lambda audio_features : audio_features .acousticness * 100 ,
84+ entity_registry_enabled_default = False ,
85+ ),
86+ SpotifyAudioFeaturesSensorEntityDescription (
87+ key = "instrumentalness" ,
88+ translation_key = "instrumentalness" ,
89+ native_unit_of_measurement = PERCENTAGE ,
90+ suggested_display_precision = 0 ,
91+ value_fn = lambda audio_features : audio_features .instrumentalness * 100 ,
92+ entity_registry_enabled_default = False ,
93+ ),
94+ SpotifyAudioFeaturesSensorEntityDescription (
95+ key = "liveness" ,
96+ translation_key = "liveness" ,
97+ native_unit_of_measurement = PERCENTAGE ,
98+ suggested_display_precision = 0 ,
99+ value_fn = lambda audio_features : audio_features .liveness * 100 ,
100+ entity_registry_enabled_default = False ,
101+ ),
102+ SpotifyAudioFeaturesSensorEntityDescription (
103+ key = "valence" ,
104+ translation_key = "valence" ,
105+ native_unit_of_measurement = PERCENTAGE ,
106+ suggested_display_precision = 0 ,
107+ value_fn = lambda audio_features : audio_features .valence * 100 ,
108+ entity_registry_enabled_default = False ,
109+ ),
110+ SpotifyAudioFeaturesSensorEntityDescription (
111+ key = "time_signature" ,
112+ translation_key = "time_signature" ,
113+ device_class = SensorDeviceClass .ENUM ,
114+ options = ["3/4" , "4/4" , "5/4" , "6/4" , "7/4" ],
115+ value_fn = lambda audio_features : f"{ audio_features .time_signature } /4" ,
116+ entity_registry_enabled_default = False ,
117+ ),
118+ SpotifyAudioFeaturesSensorEntityDescription (
119+ key = "key" ,
120+ translation_key = "key" ,
121+ device_class = SensorDeviceClass .ENUM ,
122+ options = ["C" , "C♯" , "D" , "D♯" , "E" , "F" , "F♯" , "G" , "G♯" , "A" , "A♯" , "B" ],
123+ value_fn = _get_key ,
124+ entity_registry_enabled_default = False ,
125+ ),
31126)
32127
33128
@@ -63,7 +158,7 @@ def __init__(
63158 self .entity_description = entity_description
64159
65160 @property
66- def native_value (self ) -> float | None :
161+ def native_value (self ) -> float | str | None :
67162 """Return the state of the sensor."""
68163 if (audio_features := self .coordinator .data .audio_features ) is None :
69164 return None
0 commit comments