BenjyNet Posté(e) le 8 février 2014 Signaler Posté(e) le 8 février 2014 (modifié) Virtual Device pour amplificateur ONKYO TX-NR626 - v1.1.0 Je viens d'acquérir un nouveau jouet : un amplificateur home-cinéma ONKYO TX-NR626 et vous trouverez ci-dessous un Virtual Device pour le commander. Avant de continuer, je tiens à remercier @Krikroff pour son aide précieuse et l'utilisation d'une grosse partie du code de son Virtual Device. Il a fallut adapter, non sans mal ! Cet amplificateur est connectable au réseau en wifi ou ethernet et peut être commandé à l'aide du protocole ISCP over ethernet (eISCP) consultable dans ce document. Des infos ici aussi. Avant toute chose, mea culpa pour les éventuelles erreurs de codage, je ne suis pas du tout codeur et ce ne sera certainement pas optimisé ou réglementaire. Je pense que ce Virtual Device doit fonctionner avec pas mal d'amplificateur Onkyo dit "connectable". Le Virtual Device : Le Home : N'oubliez pas de paramétrer l'IP de votre amplificateur (XXX.XXX.XXX.XXX). Le port est généralement 60128, vous n'avez pas besoin de le changer. Vous trouverez le Virtual Device dans le fichier ZIP en pièce jointe avec l'icône de l'amplificateur et un fichier README_FIRST.txt Si ce fichier s'appelle comme ça c'est qu'il y a une raison. Il faut donc ABSOLUMENT le LIRE avant de jouer avec ce Virtual Device ! Ce post sera modifié en fonction des évolutions du Virtual Device. Onkyo_TX-NR626_v1.1.0.zip Modifié le 14 mai 2014 par Yohan 1
Krikroff Posté(e) le 13 février 2014 Signaler Posté(e) le 13 février 2014 Tu peux essayer ce code qui devrait logiquement faire un mute sur un ampli Onkyo ? --[[ %% properties %% globals --]] fibaro:log("Start process"); local _deviceIp = "192.168.1.49"; local _devicePort = 60128; local _maxRetryProcess = 2; local function _process(retry) retry = retry or 0; --open the socket local tcpSocket = Net.FTcpSocket(_deviceIp, _devicePort); --set the read timeout tcpSocket:setReadTimeout(250); --notify user fibaro:log("Try Mute on, #" .. retry .. " please wait..."); fibaro:sleep(250); --send packet local bytes, errorCode = tcpSocket:write("ISCP\0\0\0\16\0\0\0\9\1\0\0\0!1AMT00\r"); --check for error if errorCode == 0 then --cli should return the string sent if success local result = tcpSocket:read(); -- could compare to the encoded version of the call to confirm success fibaro:log(result); fibaro:sleep(1000); return true; else if retry < _maxRetryProcess then fibaro:log("Retry process, please wait..."); fibaro:sleep(1000); return _process(retry + 1); end return false; end end local f, result = pcall(_process); if (f) then if (result == true) then fibaro:log("Command successufully transmited."); else fibaro:log("Cannot send command!"); end else fibaro:log("Error: " .. f); end Adaptation de mon code par fuuss et rafal_II du fofo inter fibaro. c'est par ici: http://forum.fibaro.com/viewtopic.php?t=2974 rafal_II a publié un VD qui pourrait t'aider
BenjyNet Posté(e) le 14 février 2014 Auteur Signaler Posté(e) le 14 février 2014 Ahah, on doit avoir des connexions neuronales JC. J'étais hier soir sur le sujet du forum, je suis allé me coucher en pensant bosser ça today. Je me lève ce matin et que vois-je ? Ton message... j'ai bien ri
BenjyNet Posté(e) le 14 février 2014 Auteur Signaler Posté(e) le 14 février 2014 Bon, miam miam ça marche comme je le veux mais j'ai pas de retour d'état. Est-ce que tu pourrais m'en dire plus làdessus JC pour pouvoir récupérer les infos (je connais la commande àenvoyer en ISCP). Si tu regardes dans le fichier excel, dans l'onglet communication il parle de la réponse de l'ampli dans les 50ms après l'envoie de la commande. C'est cette info que j'aimerai récupérer. J'aurai voulu aussi ne pas mettre en dur dans chaque bouton l'IP et le port de l'ampli. J'ai regardé comment t'avais fait mais j'ai rien compris. Faut-il fixer 2 variables globales ? Merci par avance
BenjyNet Posté(e) le 14 février 2014 Auteur Signaler Posté(e) le 14 février 2014 Bon je me réponds àmoi-même pour l'adresse IP et le Port, j'avais pas vu que tu récupérais ça sur le virtualdevice. J'ai rien dit
Krikroff Posté(e) le 14 février 2014 Signaler Posté(e) le 14 février 2014 Salut Benjy , oui pour l'IP et le Port il faut utiliser fibaro:get(fibaro:getSelfId(), "IPAddress") et fibaro:get(fibaro:getSelfId(), "TCPPort") ... Je vais essayer de jeter un œil sur le retour d'info dans la soirée si possible
Shad Posté(e) le 14 février 2014 Signaler Posté(e) le 14 février 2014 Comment interfacer un onkyo avec mon bose ^^ A méditer 1
BenjyNet Posté(e) le 14 février 2014 Auteur Signaler Posté(e) le 14 février 2014 (modifié) Bon alors voilà où j'en suis Faut pas le dire hein, mais j'ai pompé sur Krikroff Le VD marche très bien, le numéro du slider correspond au numéro de volume sur l'ampli (au dessus de 75 l'ampli est à fond alors attention, si vous ne voulez pas détériorer vos enceintes dans les paramètres de l'ampli fixez un volume maximum genre 50). Seul hic, c'est unidirectionnel, je n'ai pas le retour d'état de l'ampli et j'ai beau m'interroger sur le problème, je ne vois pas d'où ça vient. Normalement avec tcpsocket:read() je devrais l'obtenir non ? Parce que sinon j'ai toujours en réponse d'une commande : "ISCP" ; alors que d'après le document il devrait renvoyer le message complet (je pense qu'il ignore ce qui est après \). Onkyo_TX-NR626_v1.0.vfib Modifié le 15 février 2014 par BenjyNet
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Bon j'avance un peu... Effectivement le tcpsocket.read renvoie une chaine qui est mal interprétée si on l'affiche directement, on ne voit que l'entête ISCP. J'ai tenté de faire un string.gsub(result, "%A", ".") histoire de voir si j'obtenais quelque chose et effectivement le message change. Donc c'est bien dans la récupération de cette variable que ça merdouille mais je ne suis pas assez calé en traitement des strings/variables pour obtenir quelque chose de correct. Je continue mes tests, je vais bien finir par trouver quand même !
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Oh yeah, bon j'ai trouvé pour récupérer les infos qui m'intéresse comme par exemple savoir si l'ampli était connecté ou pas. Il faut faire sur le retour un string.sub(result, 22, 23) Bon ok tout le monde s'en fout, je parle à moi-même mais c'est pas grave Dès que j'ai quelque chose de concluant et que tout fonctionne je post le VD ici (si Yohan a fait son job !). Edit: Il faut aussi que je pense à clore le socket parce qu'en faisant pleins de tests là , l'ampli il sait plus où il habite ! 1
Krikroff Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 T’inquiètes Benjy, il y a des oreilles pour t’écouter . C'est cool que ça avance bien ! Je me demande pourquoi le string.sub(result, 22, 23) marche et pas le reste, un problème d’échappement dans la chaine peut-être ? un fibaro:debug ne sortait rien ?
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Le fibaro:debug me sortait uniquement le début de la chaîne qui est constituée de cette sorte : "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1COMMAND\r" (à la place de COMMAND tu mets ce qui est dans le fichier excel). J'avais donc "ISCP" qui s'affichait et c'est tout. Alors j'ai ouvert en même temps un telnet sur l'ampli qui affiche à chaque fois les commandes reçues/envoyées. Moi je pense que le retour est de la même forme et donc pour récupérer l'info intéressante il faudrait récupérer entre ! et \r Si je prends l'exemple de l'allumage, pour l'interroger et connaître l'état, il faut faire : "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWRQSTN\r" Ce qui retourne "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWR01\r" si allumé ou "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWR00\r" si éteint. Donc je récupère que l'information à la 22eme et 23eme position soit 00 ou 01 (je pense même que seule la 23 position est utile). Par contre ce qui m’étonne, d'après le document (et ce que j'ai pu observer sur le terminal), lorsque j'envoie une commande pour allumer l'ampli genre "ISCP\0\0\0\9\0\0\0\11\1\0\0\0!1PWR01\r" je devrai avoir en retour la même chaîne et ça n'a pas l'air d'être le cas car j'ai rien en position 22/23. C'est con qu'on n'ai pas de terminal pour voir l'état des variables en brut.
Domomat Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Non non, il y a bien un public sur ce fil, certe discret mais attentif ! Bravo pour ce boulot... :-) "Envoyé depuis mon S510 avec Tapatalk"
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Mouais :/ Bah non ça marche pas. L'ampli envoie pleins de données et j'ai l'impression que ça se mélange les pinceaux (enfin pas de son côté, lui il sait ce qu'il fait ). J'arrive à le piloter c'est déjà pas mal.
Krikroff Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Encore en déplacement aujourd'hui je ne vais donc pas pouvoir d'aider pour l'instant ! Mais je suis certain que c'est un problème d’échappement cf. la sorite du debug... j'ai ma petite idée sur la question , peut être dans la soirée ou demain.
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Il n'y a rien d'urgent Krikroff... moi ce qui m'agace le plus c'est de ne pas trouver la solution. J'aime pas avoir un problème et ne pas pouvoir le résoudre. Si tu veux voir comment réagit le telnet sur l'ampli il faudra que je te file la main sur l'ordi, parce qu'en fait il envoie plein de données tout le temps. J'ai récupéré une appli chrome qui a une fenêtre debug, ça permet de voir les échanges entre l'ampli et l'appli et c'est dingue tout ce qu'il y a comme transfert. Je ne vois vraiment pas comment traiter toutes ces infos. Merci de ton aide en tout cas.
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Bon je dois être fatigué mais je trouve pas pourquoi je reste bloqué sur ma boucle qui regarde si la réponse est conforme àce que j'attends. Une idée ? fibaro:debug('Start process ON/OFF v1.0.1'); fibaro:log('Try to turn ON/OFF'); local _deviceIp = fibaro:get(fibaro:getSelfId(), "IPAddress"); local _devicePort = fibaro:get(fibaro:getSelfId(), "TCPPort"); local _maxRetryProcess = 5; local function _checkPowerState(retry) retry = retry or 0; --notify user fibaro:debug("Request Power status, #" .. retry .. " please wait..."); --send packet bytes, errorCode = _tcpSocket:write("ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWRQSTN\r"); -- check for error if errorCode == 0 then fibaro:debug("Power status command successufully transmited."); -- amplifier sould return the string sent if success local result = _tcpSocket:read(); local cmd_value = string.sub(result, 22,23) -- check if result is equal than command to confirm success fibaro:debug("Check result of command : " .. cmd_value); if ((tonumber(cmd_value) ~= 0 or tonumber(cmd_value) ~= 1) and retry < _maxRetryProcess) then --<- je sus bloqué ici fibaro:sleep(1000); return _checkPowerState(retry + 1); else return nil end return tonumber(cmd_value); else if retry < _maxRetryProcess then fibaro:debug("Retry process, please wait..."); fibaro:sleep(2000); return _checkPowerState(retry + 1); end return nil; end end --open a local socket _tcpSocket = Net.FTcpSocket(_deviceIp, _devicePort); --set the read timeout _tcpSocket:setReadTimeout(250); local f, result = pcall(_checkPowerState); -- close socket _tcpSocket:disconnect(); -- destroy object _tcpSocket = nil; if (f) then if (result ~= nil) then fibaro:debug(result); if (result == 0) then fibaro:sleep(1000); fibaro:call(fibaro:getSelfId(), "pressButton", 2); fibaro:debug("Power is Off, try to turn On"); elseif (result == 1) then fibaro:sleep(1000); fibaro:call(fibaro:getSelfId(), "pressButton", 3); fibaro:debug("Power is On, try to turn Off"); end else fibaro:debug("Cannot send command!"); end else fibaro:debug("Error: " .. f); end
Shad Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Je t'aiderais bien mais jamais essayer, mais faudrait que tu montre un peu les retour de ton ampli pour qu'on puisse t'aider
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Bah làc'est pas un problème de retour d'info c'est un problème de boucle, de test dans la boucle je pense. Parce que les valeurs de mes variables sont bonnes. Mais je ferais une video de ce que l'ampli retourne parce qu'avec des copies d'ecran vous allez pas comprendre.
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Alors j'ai changé ma ligne qui me posait problème en if ((tonumber(cmd_value) ~= 0 and retry < _maxRetryProcess) or (tonumber(cmd_value) ~= 1 and retry < _maxRetryProcess)) then J'ai ma variable cmd_value qui vaut soit 0 soit 1 mais ça persiste à rentrer dans la boucle si retry est plus petit que 5 (valeur de _maxRetryProcess).
Krikroff Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Benjy, il me semble que le code return tonumber(cmd_value); ne sera jamais exécuté car avant tu as un return dans ton if mais aussi dans ton else ...
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Arf oui attend j'ai changé un peu le code... voilà(je mets que la partie intéressante) fibaro:debug("Check result of command : " .. cmd_value); if (((tonumber(cmd_value) ~= 0) and (retry < _maxRetryProcess)) or ((tonumber(cmd_value) ~= 1) and (retry < _maxRetryProcess))) then fibaro:sleep(1000); return _checkPowerState(retry + 1); else return tonumber(cmd_value); end else En fait je voudrais que si dans ma variable cmd_valeur j'ai autre chose que 0 ou 1, je veux qu'il retente l'envoie de la commande.
Krikroff Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Et pourquoi pas : if (tonumber(cmd_value) > 1 and retry < _maxRetryProcess) then return _checkPowerState(retry + 1); else return tonumber(cmd_value); end mais quelles sont valeurs possibles pour cmd_value ? PS: aussi, pour "catcher" plus facilement le code en phase de conception tu peux enlever le pcall
BenjyNet Posté(e) le 15 février 2014 Auteur Signaler Posté(e) le 15 février 2014 Alors en fait je t'explique, ce que j'aimerai c'est récupérer dans la réponse (result) ce qu'il y a entre ! et le \n. Une réponse est de la forme ISCP\0\0\0\16\0\0\0\9\1\0\0\0!1PWR01\r Le 9 représente le nombre de caractères entre ! et \n (y compris) En fait dans la réponse ce qui est important c'est d'identifier la partie PWR01 car c'est là que j'aurai l'info que je cherche. Ici par exemple je sais que l'ampli est allumé. Après le soucis c'est que l'ampli communique en permanence et dans la reponse je peux avoir une trame qui ne correspond pas à ma demande parce qu'il envoie par exemple le décompte du temps d'écoute de la station de radio si je suis sur la source NET. Je te met dessous une copie d'écran expliquant comment est formé le message (j'ai pas tout saisi aux remarques du bas d'ailleurs).
Krikroff Posté(e) le 15 février 2014 Signaler Posté(e) le 15 février 2014 Je ferais un truc comme ça pour la logique de traitement local on = "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWR01\r"; local off = "ISCP\0\0\0\16\0\0\0\11\1\0\0\0!1PWR00\r"; parsePowerState = function(str) if (str ~= nil and string.len(str) == 24) then local r = str:match('!1PWR(.+)\r'); if (r ~= nil) then return tonumber(r); end end return 0; end fibaro:debug(parsePowerState(on)); fibaro:debug(parsePowerState(off)); local result = on; if (parsePowerState(result) == 1) then fibaro:debug("Ampli sur ON"); elseif (parsePowerState(result) == 0) then fibaro:debug("Ampli sur OFF"); else -- TODO end
Messages recommandés