Comando per bambini per speaker Sonos
TL;DR
Utilizzando un ESP32 e Home Assistant con ESPhome è possibile controllare senza applicazione degli speaker Sonos (o altri media player). Questo è il mio progetto per permettere a mia figlia di gestire la musica a casa nostra (quando vogliamo).
Intro
Stiamo sistemando una casa ed è arrivato il tempo di fare grandi pulizie tra tutte le cose che abbiamo accumulato. In un raid di pulizia è stato scoperto un vecchio registratore a cassette per bambini, purtroppo non è più funzionante (lo farò funzionare prima o poi). Questo ritrovamento ci ha reso attenti sul fatto che la nostra bambina non può facilmente ascoltare la musica visto che ora è tutta in streaming e servono delle app sul telefono per poterla ascoltare. Non come ai nostri tempi, quando eravamo giovani…
La bambina potrebbe gestire tranquillamente lo smartphone, ma è un po’ troppo presto. Così ho sviluppato una soluzione alternativa, creando una scatola che permettesse di gestire semplicemente degli speaker Sonos.
Hardware
La casa è equipaggiata con varie speaker Sonos nelle stanze importanti, una di queste è quella della bambina. Nella sua stanza ho installato una scatola in legno con dei pulsanti e un lettore di carte RFID (rc522). Il tutto è gestito da un ESP32. In un primo tempo ho provato a collegare l’ESP a una batteria, ma ho rinunciato perché la durata di una carica era di poche settimane. Appena ho un po’ di tempo però mi occuperò di sistemare anche questo aspetto.
Software
Home Assistant è una piattaforma fantastica e permette di interconnettere vari sistemi tra di loro. Spesso un produttore sviluppa un proprio sistema pensando solo ai propri prodotti. Raramente la piattaforma è aperta e permette un utilizzo da un sistema esterno. Ad esempio le lampade IKEA sono controllabili solo da interruttori IKEA. Mentre gli speaker Sonos sono gestibili sono con l’applicazione dello stesso produttore. Home Assistant distrugge queste bariere e permette (quasi sempre) di collegare tutto con tutto.
ESPhome
L’ESP32 nella scatola di comando è programmato tramite ESPhome. Nella scatola ho aggiunto questi switch:
- play / pausa
- prossima canzone
- aumenter volume
- ridurre volume
- carta RFID presente
I primi quattro comandi sono chiari, mentre l’ultimo deve essere un po’ spiegato. Ho aggiunto uno switch per sapere quando è inserita una carta RFID per poter risparmiare il cosumo d’energia e attivare il lettore solo quando necessario.
Questa è la configurazione di ESPhome:
substitutions:
display_name: Ci Player
esphome:
name: ci-player-power
platform: ESP32
board: firebeetle32
logger:
api:
password: !secret esphome_secret
ota:
password: !secret esphome_secret
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
rc522_spi:
cs_pin: GPIO21
reset_pin: GPIO22
binary_sensor:
- platform: gpio
pin:
number: 25
id: ci_player_power_play
name: ${display_name} Play
filters:
- delayed_off: 10ms
- platform: gpio
pin:
number: 26
id: ci_player_power_next
name: ${display_name} Next
filters:
- delayed_off: 10ms
- platform: gpio
pin:
number: 14
id: ci_player_power_volume_up
name: ${display_name} Volume up
filters:
- delayed_off: 10ms
- platform: gpio
pin:
number: 27
id: ci_player_power_volume_down
name: ${display_name} Volume down
filters:
- delayed_off: 10ms
- platform: gpio
pin:
number: 4
id: ci_player_power_card_presence
name: ${display_name} Card presence
filters:
- delayed_off: 10ms
- platform: rc522
uid: AB-35-B5-22
name: ${display_name} Playlist 1
- platform: rc522
uid: 1B-8E-B6-22
name: ${display_name} Playlist 2
- platform: rc522
uid: 5B-AE-A2-22
name: ${display_name} Playlist 3
- platform: rc522
uid: 20-25-5C-2F
name: ${display_name} Playlist 4
Automazioni in Home Assistant
Il collegamento tra il box di comando e gli speaker Sonos è fatto da due automazioni di Home Assistant. L’esperienza e la gestione sono rese migliori grazie alle seguenti variabili:
- input_boolean.ci_player_blocco: è un interruttore per bloccare la possibilità di comandare gli speaker. Utile quando la bambina non fa la brava o deve dormire.
- input_number.ci_player_volume_min: il valore minimo del volume. Attualmente è possibile solo il volume minimo o massimo.
- input_number.ci_player_volume_max: il valore massimo del volume
- input_number.ci_player_delay: ritardo d’esecuzione tra un comando e l’altro. Così la bimba riesce ad ascoltare qualcosa
- input_select.ci_player_playlist: ultima playlist ascoltata
- input_select.ci_player_speaker: scegliere lo speaker da comandare con la scatola di comando
La prima automazione si occupa di gestire i comandi (gli interruttori) e la seconda modifica la playlist da ascoltare in base alla scheda RFID inserita.
Il contenuto delle playlist è gestito tramite l’app di Sonos e devono essere visibili come sorgente audio quando si aggiunge la card media player in Lovelance della cassa Sonos.
Gestione comandi
alias: Ci-player POWER - comandi
description: PLAY - NEXT - VOLUME
trigger:
- platform: state
entity_id: binary_sensor.ci_player_power_play
from: 'off'
to: 'on'
id: play
- platform: state
entity_id: binary_sensor.ci_player_power_next
from: 'off'
to: 'on'
id: next
- platform: state
entity_id: binary_sensor.ci_player_power_volume_down
from: 'off'
to: 'on'
id: volume_down
- platform: state
entity_id: binary_sensor.ci_player_power_volume_up
from: 'off'
to: 'on'
id: volume_up
condition:
- condition: state
entity_id: input_boolean.ci_player_blocco
state: 'off'
action:
- choose:
- conditions:
- condition: state
state: 'on'
entity_id: binary_sensor.ci_player_power_play
sequence:
- choose:
- conditions:
- condition: template
value_template: >-
{{ is_state(states('input_select.ci_player_speaker'),
'playing') }}
sequence:
- service: media_player.media_play_pause
data_template:
entity_id: '{{ states (''input_select.ci_player_speaker'') }}'
default:
- service: media_player.select_source
data_template:
source: '{{ states(''input_select.ci_player_playlist'') }}'
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_next
state: 'on'
sequence:
- service: media_player.media_next_track
data_template:
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_volume_down
state: 'on'
sequence:
- service: media_player.volume_set
data_template:
volume_level: '{{ states(''input_number.ci_player_volume_min'') }}'
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_volume_up
state: 'on'
sequence:
- service: media_player.volume_set
data_template:
volume_level: '{{ states(''input_number.ci_player_volume_max'') }}'
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
default: []
- delay: >-
00:00:{% if states('input_number.ci_player_delay') | int <
10-%}0{{states('input_number.ci_player_delay') | int}} {% else
%}{{states('input_number.ci_player_delay') | int}} {% endif %}
mode: single
Selezione playlist
alias: Ci-player POWER - playlist
description: Selezione delle playlist
trigger:
- platform: state
entity_id: binary_sensor.ci_player_power_card_presence
from: 'off'
to: 'on'
condition:
- condition: state
entity_id: input_boolean.ci_player_blocco
state: 'off'
action:
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
- choose:
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_playlist_1
state: 'on'
sequence:
- service: media_player.select_source
data_template:
source: Z_Playlist 1
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- service: input_select.select_option
data:
option: Z_Playlist 1
entity_id: input_select.ci_player_playlist
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_playlist_2
state: 'on'
sequence:
- service: media_player.select_source
data_template:
source: Z_Playlist 2
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- service: input_select.select_option
data:
option: Z_Playlist 2
entity_id: input_select.ci_player_playlist
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_playlist_3
state: 'on'
sequence:
- service: media_player.select_source
data_template:
source: Z_Playlist 3
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- service: input_select.select_option
data:
option: Z_Playlist 3
entity_id: input_select.ci_player_playlist
- conditions:
- condition: state
entity_id: binary_sensor.ci_player_power_playlist_4
state: 'on'
sequence:
- service: media_player.select_source
data_template:
source: Z_Playlist 4
entity_id: '{{ states(''input_select.ci_player_speaker'' ) }}'
- service: input_select.select_option
data:
option: Z_Playlist 4
entity_id: input_select.ci_player_playlist
default: []
mode: single
Conclusione
Grazie al box la bambina riesce a fare il piccolo dj, facendo partire e fermando la musica quando vuole. Oppure cambiare la playlist scegliendo la musica che preferisce.