Aller au contenu
Krikroff

Fibaro Hc2 Vd Sonos Remote: Télécommande Pour Diffuseur Sonos

Recommended Posts

SONOS Remote V1.0.1 RC pour Fibaro HC2

Télécommande avec retour d’informations pour diffuseur SONOS, prise en charge du TTS (Text-to-Speech) et lecture de stream depuis vos scènes et périphériques virtuels.

 
gallery_3_74_7729.png
 
- Les fonctions : Play,  Pause,  Stop,  Prev,  Next,  Seek, Volume, Mute, Loudness, Accès direct aux 5 premières radios de “Mes radiosâ€.
- Les informations : Zone, Etat du diffuseur, Position, Titre ou Nom de la radio, Artiste, Album, Volume, Loudness, dernière commande émise.
 

capture home 0.0.5


 
Installation :

 

A partir de la version 1.0.0 beta:

 

1. Télécharger puis importer le vd.

2. Renseigner l’adresse IP du diffuseur SONOS (le coordinateur) dans le vd ainsi que le port 1400

3. Pour utiliser la fonction TTS VoiceRSS il faut une API Key, pour l'enregistrement (gratuit) c'est ici http://www.voicerss.org/registration.aspx

4. Renseigner la variable voiceRssApiKey avec la clé, choisir un niveau de qualité sonore pour la generation avec voiceRssSoundQuality: low, medium, high

UserParams = {
  -- Voice RSS API Key (Free Registration: http://www.voicerss.org/registration.aspx)
  voiceRssApiKey = "000000000000000000000000000",
  -- Sound quality: low, medium, high
  voiceRssSoundQuality = "medium"
}

5. Enregistrer les modifications, c'est bon...

 

Utilisation :
 
TTS : Pour utiliser le TTS depuis une scène ou un périphérique virtuel il faut juste exécuter le code LUA suivant avec les bons paramètres.

-- 408 is the Virtual Device ID
-- 28 is the Process button ID
local sid, bid = 408, 28
-- Create TTS params object
local params = {
  -- TTS Message
  message = "La température extérieure actuelle est de 21,2°C",  
  duration = 'auto',	-- Duration: "auto", xx seconds
  language = "fr-FR",	-- Language: fr-FR
  volume = 10			-- Volume
}
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { tts = params })
_f:call(sid, "pressButton", bid)

Les options de l'objet params:

 

- message: le message tts

- language: la source du flux (http ou local, local est attribué par défaut)

- duration: durée du tts. (en secondes ou "auto")

- volume: le volume utilisé pour la lecture du tts si différent du volume en cours d'utilisation

 

Le programme en cours de diffusion au moment de la demande reprendra après la diffusion complète du TTS. Reprise de la radio, de la piste à  l’endroit précis avant arrêt, reprise de l’état du diffuseur : Volume, Mute, Play, Stop.
 

STREAM: Pour utiliser la lecture de Stream depuis une scène ou un périphérique virtuel il faut exécuter le code LUA suivant avec les bons paramètres.

-- 408 is the Virtual Device ID
-- 28 is the Process button ID
local sid, bid = 408, 28
-- Create STREAM params object
local params = {
  -- stream: the file / uri
  stream = "//s3.amazonaws.com/smartapp-media/sonos/bell1.mp3",
  -- source: "local" or "http", "local" is setted by default
  source = "http",
  -- duration: play duration in seconds (option) or "auto"
  duration = 8,
  -- volume: the volume for playing the stream
  volume = 10
}
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { stream = params })
_f:call(sid, "pressButton", bid)

Les options de l'objet params:

 

- stream: le chemin du flux

- source: la source du flux (http ou local, local est attribué par défaut)

- duration: durée du stream. (en secondes ou "auto")

- volume: le volume utilisé pour la lecture du flux si différent du volume en cours d'utilisation

 

Quelques exemples:

Annoncer la température dans une scène :

--[[
%% properties
 
 
%% globals
--]]
 
 
-- 408 is the Virtual Device ID
-- 28 is the Process button ID
local sid, bid = 811, 28
-- Create TTS params object
local ValeurTemp = fibaro:getValue(61, "value")
local degre = string.gsub(ValeurTemp, '[,]' , ' degret ')
local degre = string.gsub(degre, '[.]' , ' degret ')
local degre = string.gsub(degre, '[-]' , ' moins ')
local notification = "Il fait " .. degre .. " dans le salon "
fibaro:debug(notification)
local params = {
  -- TTS Message
 
  message = notification,  
  duration = 'auto', -- Duration: "auto", xx seconds
  language = "fr-FR", -- Language: fr-FR
  volume = 23 -- Volume
}
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { tts = params })
_f:call(sid, "pressButton", bid)

Annoncer la valeur d'une variable :

--[[
%% properties
%% globals
--]]
 
 
local sid, bid = 813, 28
-- Create TTS params object
local couleur = fibaro:getGlobalValue("le nom de ta variable")
local notification = ("La couleur de demain sera "..couleur.." Bonne journée")
fibaro:debug(notification)
local params = {
  -- TTS Message
 
  message = notification,  
  duration = 'auto', -- Duration: "auto", xx seconds
  language = "fr-FR", -- Language: fr-FR
  volume = 23 -- Volume
}
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { tts = params })
_f:call(sid, "pressButton", bid) 

Annoncer la date du jour, la température extérieure et la météo :

-- 239 is the Virtual Device ID
-- 28 is the Process button ID
local sid, bid = 239, 28
 
local cond = fibaro:getValue(3, "WeatherConditionConverted");
local tempext = fibaro:getValue(33, "value"); -- température extérieure
fibaro:debug ("Température extérieure : "..tempext)
local degre = string.gsub(tempext, '[,]' , ' degré ')
local degre = string.gsub(degre, '[.]' , ' degré ')
local degre = string.gsub(degre, '[-]' , ' moins ')
 
local currentDate = os.date("*t")
local jourL = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"}
local jour = jourL[currentDate.wday]
fibaro:debug ("Jour : "..jour)
 
local moisL = {"janvier", "février", "mars", "avril", "mai", "juin",
               "juillet", "aout", "septembre", "octobre", "novembre", "décembre"}
local mois = moisL[currentDate.month]
fibaro:debug ("Mois : "..mois)
 
local condfr ="";
if( cond == "clear" ) then condfr = "clair"; end
if( cond == "cloudy" ) then condfr = "nuageux"; end
if( cond == "rain" ) then condfr = "pluvieux"; end
if( cond == "snow" ) then condfr = "neigeux"; end
if( cond == "storm" ) then condfr = "tempete"; end
if( cond == "fog" ) then condfr = "brouillard"; end
fibaro:debug ("Conditions météorologiques : "..condfr)
 
fibaro:debug ("Création du TTS")
-- Create TTS params object
local params = {
  -- TTS Message
  message = "Bonjour a vous. Nous sommes le "..jour .." "..currentDate.day .." "..mois ..
            ". Il est ".. currentDate.hour .." heure et ".. currentDate.min .." minutes. "..
            "Le thermomètre extérieur est a "..degre ..
            ", et le temps est  "..condfr ..". ",  
  duration = 'auto',    -- Duration: "auto", xx seconds
  language = "fr-FR",    -- Language: fr-FR
  volume = 40            -- Volume
}
local _f = fibaro
local _x ={root="x_sonos_object",load=function(b)local c=_f:getGlobalValue(b.root)if string.len(c)>0 then local d=json.decode(c)if d and type(d)=="table"then return d else _f:debug("Unable to process data, check variable")end else _f:debug("No data found!")end end,set=function(b,e,d)local f=b:load()if f[e]then for g,h in pairs(d)do f[e][g]=h end else f[e]=d end;_f:setGlobal(b.root,json.encode(f))end,get=function(b,e)local f=b:load()if f and type(f)=="table"then for g,h in pairs(f)do if tostring(g)==tostring(e or"")then return h end end end;return nil end}
-- Make a request to the remote to process params object instantly
_x:set(tostring(sid), { tts = params })
_f:call(sid, "pressButton", bid) 

Notes de versions:

 

Version 1.0.1 Rc

- Correction: régression introduite avec la V4.080 impactant la création automatique de la variable globale

 

Version 1.0.0 beta

 

ATTENTION: Le passage d'une version antérieure à  la v1.0.0 pour la v1.0.0 ou supérieure nécessite la réécriture des commandes TTS pour fonctionner avec le nouveau module. L'ancien module reste cependant fonctionnel et peut cohabiter logiquement avec la nouvelle version. En cas de passage définitif en V1.0.0 ou supérieure toutes les variables globales déclarées précédemment en V0.0.7 ou V0.0.8 peuvent être supprimées.

- Amélioration : Configuration automatique, pas de déclaration de variables globales

- Amélioration : Support natif de multiples instances du périphérique virtuel

- Amélioration : Faible latence lors du déclenchement des commandes

- Amélioration : Révision et amélioration du code / Refactoring

- Ajout: Le TTS utilise le service Voice RSS (avec une API Key (enregistrement gratuit)) ou ResponsiveVoice API. Options: durée, volume, auto resume

- Ajout: Lancement de Stream (http / local) depuis scéne / vd. Options: durée, volume, auto resume

 

Version 0.0.8

- Amélioration : La lecture d'un TTS en mode Auto Stop est maintenant stable
- Amélioration : La lecture d'un TTS avec une durée définie est maintenant stable
- L'image principale du vd réapparaît maintenant automatiquement après l'appui sur un bouton (Labomatik & JM13, merci  ;))
- Correction d'un bug avec l'analyse xml de BrowseDirectChildren
- Attention: Pour utiliser les raccourcis "boutons radios favorites" vous devez ajouter au moins deux radios depuis l'application SONOS "Desktop/IOS etc..."

 

Version 0.0.7

- Amélioration notable de la stabilité, le vd est plus réactif.
- Patch line 892: attempt to index local 'value' (a function value)
- Patch line 1256: attempt to concatenate a nil value
- Préparation au support de nouvelles fonctionnalités

 
Fichier Zip : SONOS_Remote_v1.0.1.vfib

SONOS_Remote_v1.0.0.vfib

  • Like 1
  • Sad 1
  • Upvote 48

Partager ce message


Lien à poster
Partager sur d’autres sites

variables crées!! en attente du fichier  B)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Super boulot encore une fois !

 

Pour les pièces tu peux y aller j'ai augmenter la taille des fichiers.

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors moi krikroff j'ai un truc àte demander. Où tu trouves toutes les polices que tu utilises dans tes VD ? J'ai cherché une table de caractères ou un truc du genre mais pas trouvé !

Partager ce message


Lien à poster
Partager sur d’autres sites

Son framework je suppose.

Partager ce message


Lien à poster
Partager sur d’autres sites

Super boulot @Krikroff  :60:

 

Il y a en effet un petit peu de latence aléatoire, due à  l'exécution des commandes dans le main loop, mais ce n'est pas bien important.

Du coup, je trouve le TTS un peu lent à  la détente (main loop + Google), comparé à  une synthèse effectuée en local (j'utilise le serveur Paw sous Android)

 

Mais encore une fois, bravo..... et MERCI  !

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors moi krikroff j'ai un truc à  te demander. Où tu trouves toutes les polices que tu utilises dans tes VD ? J'ai cherché une table de caractères ou un truc du genre mais pas trouvé !

Pour le fainéant que je suis  ;)

- je lance Word par exemple

- je vais chercher "insérer les caractères spéciaux" en police Arial

- je trouves les symboles utilisés par JC et d'autres

- et un petit "copier coller" dans le label du bouton virtuel... utilisé dans mon module virtuel Yamaha  :lol:

Partager ce message


Lien à poster
Partager sur d’autres sites

@Benjy, tu peux effectivement trouver dans Word les caractères spéciaux et faire des copier/coller comme la judicieusement proposé i-magin ;) , tu trouveras aussi sur la toile la table des codes ASCII et leur correspondance et aussi les symboles etc...

 

http://www.table-ascii.com/

http://www.toutimages.com/codes_caracteres.htm

...

 

@I-magin, oui il y a une latence vraiment énervante due je pense à  la gestion du cache en mode radio par le SONOS, la solution est d'utiliser un serveur pour mettre en cache le retour de l'API google et ensuite faire jouer le fichier par le SONOS.

Ce qui ajoute aussi de la latence est le fait que je récupère l'état complet du SONOS avant le TTS : état, volume, titre joué, position du transport etc afin de relancer dans l'état exacte avant la demande TTS lorsque celui-ci est terminé.

 

J'utilise encore mon framework ici à  cause de certaines limites de la surcouche logiciel proposée par Fibaro à  ce jour.

 

Et voila... Après avoir passé quelques heures sur ce développement forcement je veux mettre du SONOS partout dans la maison :rolleyes:

Partager ce message


Lien à poster
Partager sur d’autres sites

Excellent travail JC (comme d'ab) :D

Et merci encore !

Je vais le tester, ma version est basic, play/pause/mute ^^

 

Par contre, concernant le TTS, je ne me suis jamais interrogé sur la question, meme pas testé Isabelle, ha non Lili pardon :D

 

Donc le TTS, c'est quelque chose a installer en plus ? Comment fonctionne t-il ? Enfin plutot quel est le bouton qui permet de... parler ?

Bon Benjy tu t'abstiens de commentaire hein :D Y en a qui bosse et qui ne suivent pas tout  :lol:

Partager ce message


Lien à poster
Partager sur d’autres sites

Ah non mais je dis rien, j'ai repris le boulot :P

Partager ce message


Lien à poster
Partager sur d’autres sites

TTS : Text To Speech permet de transformer un texte écrit en "un texte parlé."

C'est de la synthèse vocale, mais pas de la reconnaissance vocale comme le fait LILI ou S.A.R.A.H.

 

Tu peux donc intégrer dans tes scènes ou modules virtuels, des messages écrits qui seront restitués dans notre cas sur des périphériques Sonos

Dans le main loop du module de @Krikroff, la variable "SonosTTS" est vérifiée. Si celle-ci n'est pas vide, son contenu est alors traité

C'est pourquoi, @Krikroff précise : 

Pour utiliser le TTS depuis une scène ou un périphérique virtuel il faut juste exécuter la ligne suivante en LUA avec les bons paramètres.

Ex : fibaro:setGlobal("SonosTTS", "lng=fr|dr=auto|vol=10|txt=Ceci est un test de TTS, veuillez attendre la reprise de la musique. . .|");

 

Rien à  installer d'autre, puisque que c'est l'API de Google Text-To-Speech qui est utilisée

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci Krikroff :60: pour ce superbe travail. Je trouve super que l'on puisse choisir la radio de 1 à  5. Est-ce qu'il serait difficile d'avoir la possibilité de choisir entre 1 à  3 liste de lecture : genre : liste 1, liste 2, liste 3 ? Peut-être que cela n'est pas faisable, auquel cas je vais arrêter de me creuser la tête à  comprendre ce que tu as codé et juste en profiter.

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui c'est faisable, je prépare cela pour la prochaine mise àjour ;).

Partager ce message


Lien à poster
Partager sur d’autres sites

Désolé de n'être là  que pour demander de nouvelles choses ! Mais le travail est remarquable.... J'utilise mes sonos pour diffuser des messages via PLAYTTS et maintenant via ce nouveau module. Je vais chercher ce que j'ai enregistré dans mes notifications et je diffuse en fonction du problème : ex. Attention hygrométrie supérieur à  80%, etc.... Par contre je n'ai pas réussi à  utiliser mes variables dans la ligne suivante :

fibaro:setGlobal("SonosTTS", "lng=fr|dr=auto|vol=10|txt=Ceci est un test de TTS, veuillez attendre la reprise de la musique. . .|");

j'ai essayé : 

fibaro:setGlobal("SonosTTS", "lng=fr|dr=auto|vol=10|txt=" ..getNotification(NotificationId).. ". . .|");

en recopiant bien sur la partie de code du Playtts mais meme avec une variable et un peu de texte cela ne marche pas.

 

Aurais-tu une idée JC ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Oulalala ! J e m'y colle rapidement !

Tres interessant.

Partager ce message


Lien à poster
Partager sur d’autres sites

@Arnaud78, j'ai fait le test suivant

tempint = fibaro:getGlobalValue("netatmo_int") -- température intérieure Netatmo
message = ("Bonjour, il fait "..tempint.." degre, a demain !")
fibaro:setGlobal("SonosTTS", "lng=fr|dr=auto|vol=25|txt="..message..". . .|");

Je préfère formater mon message avant de l'inclure dans la commande TTS

J'attire ton attention sur le fait que je n'utilise pas de caractère accentué (pour l'instant)

Si tu l'as fait, vérifie par le debug de ton module virtuel Sonos que tu n'as pas un message d'erreur

Si c'est le cas, il risque d'être bloqué... sauvegarde le pour permettre sa relance

Partager ce message


Lien à poster
Partager sur d’autres sites

Ah, au fait ! moi aussi, j'ai une proposition à  formuler,  JC 

 

Une paramètre supplémentaire pour le TTS : adresse IP du périphérique SONOS, pour avoir le choix de la diffusion

 

Et puis, comme tu n'as pas grand chose à  faire ...  :rolleyes:

  • Upvote 3

Partager ce message


Lien à poster
Partager sur d’autres sites

J'ai mieux que ça encore àlui proposer...gestion du mulitiroom ;)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

@Lionel, exacte c'est dans "limitations et problème connus" ;).

 

@I-magin, c'est une très bonne idée l'adresse IP pour le TTS, merci.

 

Pour l'encodage du message j'utilise une méthode rudimentaire qui n'est visiblement pas adaptée, je corrige cela dans la prochaine maj.

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour Krikroff, si je veux utiliser le module virtuel pour chaque sonos, je suppose que je dois créer des variables genre :

 

Type:  Variable

Nom:  SonosLastCmdBureau

 

Type:  Variable
Nom:  SonosTTSBureau

 

Type:  Variable

Nom:  SonosLastCmdSalon

 

Type:  Variable
Nom:  SonosTTSSalon

 

et ce pour chaque Sonos. Je suppose également que je dois modifier les boutons dans le module virtuel pour adapter les bonnes variables. Mais y-a t-il un endroit en particulier ou je peux changer les variables dans le main loop ou sont-elles éparpiller au travers de tout le code ? et donc dans ce cas je recopie et réédite le code pour mettre les nouvelles variables ? 

 

La vrai question, c'est est-ce que cela devrait fonctionner ou y-at-il des incompatibilités à  utiliser plusieurs modules virtuels SONOS et est-ce que cela ne va pas faire écrouler les performances du HC2 ?

 

Merci d'avance.

Partager ce message


Lien à poster
Partager sur d’autres sites
Bonjour, désolé, je suis encore nouveau ici. Comment puis-je créer des variables globales? J'ai aucune idée de comment absolue. Merci! 

 

"IMPORTANT: Avant d'importer l'appareil, il est essentiel de créer le nécessaire pour le bon fonctionnement des variables globales virtuelles de l'appareil. 

 

Type: Nom de la variable: SonosLastCmd 

Type: Nom de la variable: SonosTTS "

Partager ce message


Lien à poster
Partager sur d’autres sites

VD importé, il a l'air d'afficher l'état parcontre aucune commande possible.

Je possède un play3 et play1 + hub

j'ai tenté avec l'ip du play 3 sans succes.

 

c'est normal:

DémarrerArrêterNettoyer [DEBUG] 12:27:43: -------------------------------------------------------------------------
[DEBUG] 12:27:43: -- HC2 Toolkit Framework version 1.0.5
[DEBUG] 12:27:43: -- Current interpreter version is Lua 5.1
[DEBUG] 12:27:43: -- Total memory in use by Lua: 304.78 Kbytes
[DEBUG] 12:27:43: -------------------------------------------------------------------------
[DEBUG] 12:27:43: Toolkit.Debug loaded in memory...
[DEBUG] 12:27:43: Benchmark [Toolkit.Debug lib]: elapsed time: 0.000 cpu secs
[DEBUG] 12:27:43: Toolkit.Collections.Queue loaded in memory...
[DEBUG] 12:27:43: Benchmark [Toolkit.Collections.Queue lib]: elapsed time: 0.000 cpu secs
[DEBUG] 12:27:43: Toolkit.Net loaded in memory...
[DEBUG] 12:27:43: Benchmark [Toolkit.Net lib]: elapsed time: 0.000 cpu secs
[DEBUG] 12:27:43: Toolkit.Xml loaded in memory...
[DEBUG] 12:27:43: Benchmark [Toolkit.Xml lib]: elapsed time: 0.000 cpu secs
[DEBUG] 12:27:43: HC2 start script at Wed Mar 19 12:27:43 2014
[DEBUG] 12:27:43: Get mute state request
[DEBUG] 12:27:43: mute: false
[DEBUG] 12:27:43: Get volume request
[DEBUG] 12:27:43: volume: 17
[DEBUG] 12:27:43: Get loudness request
[DEBUG] 12:27:43: Loudness is ON
[DEBUG] 12:27:43: get transport state request
[DEBUG] 12:27:43: transport state: PLAYING
[DEBUG] 12:27:43: get current track request
[DEBUG] 12:27:43: Collect Garbage at Wed Mar 19 12:27:43 2014
[DEBUG] 12:27:43: Get loudness request
[ERROR] 12:27:43: line 891: attempt to index local 'value' (a function value)

Christophe

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

×