feat(hass): add PlayAlbum voice command
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
6936895cf9
commit
98c27b1051
9 changed files with 184 additions and 40 deletions
|
@ -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<PlayAlbumData>(
|
||||||
|
"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<SpotifyplusSearchAlbumsResponse>(_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"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
namespace Spotify;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public record AlbumItem
|
||||||
|
{
|
||||||
|
public string? AlbumType { get; set; }
|
||||||
|
public List<Artist>? Artists { get; set; }
|
||||||
|
public List<string?>? 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<Image>? 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<AlbumItem>? Items { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SpotifyplusSearchAlbumsResponse
|
||||||
|
{
|
||||||
|
public UserProfile? UserProfile { get; set; }
|
||||||
|
public AlbumResult? Result { get; set; }
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ using NetDaemon.HassModel;
|
||||||
using NetDaemon.HassModel.Integration;
|
using NetDaemon.HassModel.Integration;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
record ServiceData(string? criteria);
|
record PlayArtistData(string? artist);
|
||||||
|
|
||||||
[NetDaemonApp]
|
[NetDaemonApp]
|
||||||
public class PlayArtist
|
public class PlayArtist
|
||||||
|
@ -19,7 +19,7 @@ public class PlayArtist
|
||||||
|
|
||||||
public PlayArtist(IHaContext ha)
|
public PlayArtist(IHaContext ha)
|
||||||
{
|
{
|
||||||
ha.RegisterServiceCallBack<ServiceData>(
|
ha.RegisterServiceCallBack<PlayArtistData>(
|
||||||
"spotify_play_artist",
|
"spotify_play_artist",
|
||||||
async (e) =>
|
async (e) =>
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ public class PlayArtist
|
||||||
"search_artists",
|
"search_artists",
|
||||||
data: new SpotifyplusSearchArtistsParameters
|
data: new SpotifyplusSearchArtistsParameters
|
||||||
{
|
{
|
||||||
Criteria = e?.criteria,
|
Criteria = e?.artist,
|
||||||
Limit = 1,
|
Limit = 1,
|
||||||
EntityId = "media_player.spotifyplus"
|
EntityId = "media_player.spotifyplus"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,7 @@ namespace Spotify;
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public record ExternalUrls
|
public record ArtistItem
|
||||||
{
|
|
||||||
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 ExternalUrls? External_urls { get; init; }
|
public ExternalUrls? External_urls { get; init; }
|
||||||
public Followers? Followers { get; init; }
|
public Followers? Followers { get; init; }
|
||||||
|
@ -35,7 +17,7 @@ public record Item
|
||||||
public string? Uri { get; init; }
|
public string? Uri { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Result
|
public record ArtistResult
|
||||||
{
|
{
|
||||||
public string? Href { get; init; }
|
public string? Href { get; init; }
|
||||||
public int Limit { get; init; }
|
public int Limit { get; init; }
|
||||||
|
@ -43,22 +25,11 @@ public record Result
|
||||||
public int Offset { get; set; }
|
public int Offset { get; set; }
|
||||||
public object? Previous { get; init; }
|
public object? Previous { get; init; }
|
||||||
public int Total { get; init; }
|
public int Total { get; init; }
|
||||||
public List<Item>? Items { get; init; }
|
public List<ArtistItem>? Items { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public record SpotifyplusSearchArtistsResponse
|
public record SpotifyplusSearchArtistsResponse
|
||||||
{
|
{
|
||||||
public UserProfile? UserProfile { get; init; }
|
public UserProfile? UserProfile { get; init; }
|
||||||
public Result? Result { get; init; }
|
public ArtistResult? 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; }
|
|
||||||
}
|
}
|
|
@ -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 { }
|
|
@ -5,19 +5,43 @@
|
||||||
PlayArtist.data = [
|
PlayArtist.data = [
|
||||||
{
|
{
|
||||||
sentences = [
|
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 = {
|
lists = {
|
||||||
artist.wildcard = true;
|
artist.wildcard = true;
|
||||||
|
album.wildcard = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.intents = {
|
responses.intents = {
|
||||||
PlayArtist.default = ''
|
PlayArtist.default = ''
|
||||||
Searching for {{ slots.artist }} on Spotify and playing their top songs.
|
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.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ in {
|
||||||
name = "spotify-files";
|
name = "spotify-files";
|
||||||
text = ''
|
text = ''
|
||||||
mkdir -p ${WorkingDirectory}/custom_sentences/en
|
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
|
cp -f ${creds} ${WorkingDirectory}/.storage/SpotifyWebApiPython_librespot_credentials.json
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
|
@ -40,7 +40,20 @@ in {
|
||||||
action = [
|
action = [
|
||||||
{
|
{
|
||||||
service = "netdaemon.spotify_play_artist";
|
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 }}";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,7 +52,7 @@ in {
|
||||||
name = "timer-files";
|
name = "timer-files";
|
||||||
text = ''
|
text = ''
|
||||||
mkdir -p ${WorkingDirectory}/custom_sentences/en
|
mkdir -p ${WorkingDirectory}/custom_sentences/en
|
||||||
cp -f ${timer} ${WorkingDirectory}/custom_sentences/en
|
cp -f ${timer} ${WorkingDirectory}/custom_sentences/en/assist_timers.yaml
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue