diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs new file mode 100644 index 00000000..ce8fd77f --- /dev/null +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs @@ -0,0 +1,54 @@ +namespace Spotify; + +using HomeAssistantGenerated; +using NetDaemon.AppModel; +using NetDaemon.HassModel; +using NetDaemon.HassModel.Integration; +using System.Text.Json; + +record PlayAlbumData(string? artist, string? album); + +[NetDaemonApp] +public class PlayAlbum +{ + // Snake-case json options + private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower + }; + + public PlayAlbum(IHaContext ha) + { + ha.RegisterServiceCallBack( + "spotify_play_album", + async (e) => + { + var result = (await ha.CallServiceWithResponseAsync( + "spotifyplus", + "search_albums", + data: new SpotifyplusSearchAlbumsParameters + { + Criteria = $"{e?.artist} {e?.album}", + Limit = 1, + EntityId = "media_player.spotifyplus" + } + )).Value.Deserialize(_jsonOptions); + + string? uri = result?.Result?.Items?[0]?.Uri; + + if (uri is not null) + { + ha.CallService( + "spotifyplus", + "player_media_play_context", + data: new SpotifyplusPlayerMediaPlayContextParameters + { + ContextUri = uri, + EntityId = "media_player.spotifyplus" + } + ); + } + } + ); + } +} diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.yaml b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.yaml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.yaml @@ -0,0 +1 @@ + diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/SpotifyplusSearchAlbumsResponse.cs b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/SpotifyplusSearchAlbumsResponse.cs new file mode 100644 index 00000000..49d79951 --- /dev/null +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/SpotifyplusSearchAlbumsResponse.cs @@ -0,0 +1,39 @@ +namespace Spotify; + +using System.Collections.Generic; + +public record AlbumItem +{ + public string? AlbumType { get; set; } + public List? Artists { get; set; } + public List? AvailableMarkets { get; set; } + public ExternalUrls? ExternalUrls { get; set; } + public string? Href { get; set; } + public string? Id { get; set; } + public string? ImageUrl { get; set; } + public List? Images { get; set; } + public string? Name { get; set; } + public string? ReleaseDate { get; set; } + public string? ReleaseDatePrecision { get; set; } + public Restrictions? Restrictions { get; set; } + public int TotalTracks { get; set; } + public string? Type { get; set; } + public string? Uri { get; set; } +} + +public record AlbumResult +{ + public string? Href { get; set; } + public int Limit { get; set; } + public string? Next { get; set; } + public int Offset { get; set; } + public object? Previous { get; set; } + public int Total { get; set; } + public List? Items { get; set; } +} + +public class SpotifyplusSearchAlbumsResponse +{ + public UserProfile? UserProfile { get; set; } + public AlbumResult? Result { get; set; } +} diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs index 3f681496..18756922 100644 --- a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs @@ -6,7 +6,7 @@ using NetDaemon.HassModel; using NetDaemon.HassModel.Integration; using System.Text.Json; -record ServiceData(string? criteria); +record PlayArtistData(string? artist); [NetDaemonApp] public class PlayArtist @@ -19,7 +19,7 @@ public class PlayArtist public PlayArtist(IHaContext ha) { - ha.RegisterServiceCallBack( + ha.RegisterServiceCallBack( "spotify_play_artist", async (e) => { @@ -28,7 +28,7 @@ public class PlayArtist "search_artists", data: new SpotifyplusSearchArtistsParameters { - Criteria = e?.criteria, + Criteria = e?.artist, Limit = 1, EntityId = "media_player.spotifyplus" } diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyTypes.cs b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyplusSearchArtistsResponse.cs similarity index 53% rename from devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyTypes.cs rename to devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyplusSearchArtistsResponse.cs index ce60c36b..18e92f54 100644 --- a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyTypes.cs +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/SpotifyplusSearchArtistsResponse.cs @@ -2,25 +2,7 @@ namespace Spotify; using System.Collections.Generic; -public record ExternalUrls -{ - public string? Spotify { get; init; } -} - -public record Followers -{ - public string? Href { get; init; } - public int Total { get; init; } -} - -public record Image -{ - public string? Url { get; init; } - public int Height { get; init; } - public int Width { get; init; } -} - -public record Item +public record ArtistItem { public ExternalUrls? External_urls { get; init; } public Followers? Followers { get; init; } @@ -35,7 +17,7 @@ public record Item public string? Uri { get; init; } } -public record Result +public record ArtistResult { public string? Href { get; init; } public int Limit { get; init; } @@ -43,22 +25,11 @@ public record Result public int Offset { get; set; } public object? Previous { get; init; } public int Total { get; init; } - public List? Items { get; init; } + public List? Items { get; init; } } public record SpotifyplusSearchArtistsResponse { public UserProfile? UserProfile { get; init; } - public Result? Result { get; init; } -} - -public record UserProfile -{ - public string? Country { get; init; } - public string? DisplayName { get; init; } - public string? Email { get; init; } - public string? Id { get; init; } - public string? Product { get; init; } - public string? Type { get; init; } - public string? Uri { get; init; } + public ArtistResult? Result { get; init; } } diff --git a/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/Types.cs b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/Types.cs new file mode 100644 index 00000000..d0a098d9 --- /dev/null +++ b/devices/homie/modules/home-assistant/netdaemon/apps/Spotify/Types.cs @@ -0,0 +1,42 @@ +namespace Spotify; + +public record UserProfile +{ + public string? Country { get; init; } + public string? DisplayName { get; init; } + public string? Email { get; init; } + public string? Id { get; init; } + public string? Product { get; init; } + public string? Type { get; init; } + public string? Uri { get; init; } +} + +public record Artist +{ + public ExternalUrls? ExternalUrls { get; set; } + public string? Href { get; set; } + public string? Id { get; set; } + public string? Name { get; set; } + public string? Type { get; set; } + public string? Uri { get; set; } +} + +public record ExternalUrls +{ + public string? Spotify { get; init; } +} + +public record Followers +{ + public string? Href { get; init; } + public int Total { get; init; } +} + +public record Image +{ + public string? Url { get; init; } + public int Height { get; init; } + public int Width { get; init; } +} + +public record Restrictions { } diff --git a/devices/homie/modules/home-assistant/spotify-sentences.nix b/devices/homie/modules/home-assistant/spotify-sentences.nix index ba773424..a5208ed5 100644 --- a/devices/homie/modules/home-assistant/spotify-sentences.nix +++ b/devices/homie/modules/home-assistant/spotify-sentences.nix @@ -5,19 +5,43 @@ PlayArtist.data = [ { sentences = [ - "play [some] music from [artist] {artist}" + "play[ing] [some] music from [the] [artist] {artist}" + "play[ing] [the] artist {artist}" ]; } ]; + + PlayAlbum.data = [ + { + sentences = [ + "play[ing] [the] album {album} from [the] [artist] {artist}" + ]; + } + { + sentences = [ + "play[ing] [the] album {album}" + ]; + slots.artist = ""; + } + ]; }; lists = { artist.wildcard = true; + album.wildcard = true; }; responses.intents = { PlayArtist.default = '' Searching for {{ slots.artist }} on Spotify and playing their top songs. ''; + + PlayAlbum.default = '' + Searching for the album {{ slots.album }} + {% if slots.artist != "" %} + by {{ slots.artist }} + {% endif %} + on Spotify and playing it. + ''; }; } diff --git a/devices/homie/modules/home-assistant/spotify.nix b/devices/homie/modules/home-assistant/spotify.nix index 1ab4e699..a62079bb 100644 --- a/devices/homie/modules/home-assistant/spotify.nix +++ b/devices/homie/modules/home-assistant/spotify.nix @@ -17,7 +17,7 @@ in { name = "spotify-files"; text = '' mkdir -p ${WorkingDirectory}/custom_sentences/en - cp -f ${spotify} ${WorkingDirectory}/custom_sentences/en + cp -f ${spotify} ${WorkingDirectory}/custom_sentences/en/assist_spotify.yaml cp -f ${creds} ${WorkingDirectory}/.storage/SpotifyWebApiPython_librespot_credentials.json ''; }); @@ -40,7 +40,20 @@ in { action = [ { service = "netdaemon.spotify_play_artist"; - data.criteria = "{{ artist }}"; + data.artist = "{{ artist }}"; + } + ]; + }; + + PlayAlbum = { + async_action = "false"; + action = [ + { + service = "netdaemon.spotify_play_album"; + data = { + artist = "{{ artist }}"; + album = "{{ album }}"; + }; } ]; }; diff --git a/devices/homie/modules/home-assistant/timer.nix b/devices/homie/modules/home-assistant/timer.nix index 5f718058..e92a918a 100644 --- a/devices/homie/modules/home-assistant/timer.nix +++ b/devices/homie/modules/home-assistant/timer.nix @@ -52,7 +52,7 @@ in { name = "timer-files"; text = '' mkdir -p ${WorkingDirectory}/custom_sentences/en - cp -f ${timer} ${WorkingDirectory}/custom_sentences/en + cp -f ${timer} ${WorkingDirectory}/custom_sentences/en/assist_timers.yaml ''; });