Nous vous avons montré par le passé comment utiliser un écran Yoctopuce pour afficher des informations venant d'Internet, comme un flux RSS ou les événements d'un calendrier Google. Aujourd'hui nous allons voir comment un Yocto-Display peut être utilisé pour faire un panneau de contrôle actif pour le media center XBMC.
Pour fabriquer le panneau de contrôle, nous avons besoin d'un Yocto-Display et de six boutons pour les actions haut,bas, gauche, droite, ok, retour.
Le Yocto-Display et le Yocto-MaxiDisplay ne sont pas que des écrans: ils embarquent l'équivalent d'un Yocto-Knob. En plus de la fonction display (qui permet de d’interagir avec l'écran) et de la fonction files (qui permet d'uploader des images ou des fonts), ils disposent aussi de 6 fonctions anButton qui permettent de mesurer l'état de composant résistifs (interrupteurs, boutons poussoir, potentiomètres, etc.). Ces 6 fonctions peuvent être utilisées avec les mini boutons présents sur le board. Il est aussi possible de souder ses propres boutons sur les pads prévus.
Le Yocto-Display avec 6 boutons externes
Pour réaliser ce panneau de contrôle, nous allons écrire un petit script Python qui récupère le titre du film en lecture, l'affiche sur le Yocto-Display, et qui transmet à XBMC les commandes de navigation quand un bouton est pressé.
L'API de XBMC
Pour interagir avec XBMC, nous allons utiliser l'API JSON-RPC qui est installée automatiquement. Cette API permet de simuler n'importe quel bouton d'une télécommande, mais aussi de récupérer des informations sur le film (ou mp3) qui est diffusé. Cette API suit le protocole JSON-RPC, et est documenté sur la page web du projet (http://kodi.wiki/view/JSON-RPC_API). Par défaut cette API est désactivée, pour l'utiliser il faut activer l'option "Allow control of XBMC via HTTP" dans le menu "Webserver" (disponible dans la section "Service" des paramètres).
Pour utiliser l'API JSON-RPC il faut activer l'option Allow control of XBMC via HTTP
Il existe plusieurs librairies Python qui implémentent uniquement ce protocole, mais nous avons décidé d'utiliser la librairie requests qui permet d'écrire n'importe quelle requête basée sur le protocole HTTP.
Une requête JSON-RPC n'est rien de plus qu'une requête HTTP POST avec une structure JSON qui contient le nom de la fonction à appeler (champ "method") et les paramètres de cette fonction (champ "params").
Pour communiquer avec XBMC, on implémente une classe SimpleXMBC qui contient une méthode json_rpc_request qui prend en argument le nom de la fonction XBMC et ses paramètres, et qui retourne le résultat de la requête. Cette classe contient les méthodes up(), down(), right(), left(), ok(), back() et get_player_info() qui appellent la méthode json_rpc_request avec les bons paramètres.
def __init__(self, host, port, user, password):
self._url = 'http://%s:%d/jsonrpc' % (host, port)
def json_rpc_request(self, method, params):
headers = {'content-type': 'application/json'}
payload = {
"method": method,
"params": params,
"jsonrpc": "2.0",
"id": 0,
}
response = requests.post(
self._url, data=json.dumps(payload), headers=headers).json()
if 'error' in response:
print(response['error'])
return response
def up(self):
self.json_rpc_request('Input.Up', {})
....
xbmc_interface = SimpleXMBC('localhost', 80, 'xbmc', 'password')
xbmc_interface.up()
Le script Python
Le reste du script est assez semblable à l'exemple Prog-EventBased qui est fournit avec la librairie Python Yoctopuce. On enregistre les fonctions de callback qui sont appelées chaque fois qu'un module est branché et à chaque changement de valeur d'une fonction. Si vous n'avez jamais utilisé les fonctions RegisterDeviceArrivalCallback() ou registerValueCallback(), il est fortement conseillé lire l'article suivant qui décrit l'utilisation de callack de l'API Yoctopuce.
Pour transmettre les commandes ("up", "down", etc) à XBMC chaque fois qu'un bouton est pressé, il faut appeler la méthode correspondante de notre objet xbmc_interface depuis la fonction an_button_callback().
La fonction principale est composé d'une boucle sans fin qui appel YAPI.UpdateDeviceList() et YAPI.Sleep(). Dans cette boucle sans fin, on récupère le titre à l'aide de l'appel xbmc_interface.get_info_to_display(), et on rafraîchit l'écran avec ces informations. La fonction principale va donc effectuer les tâches suivantes en boucle:
- afficher sur l'écran le titre du film
- vérifier si il faut appeler les callbacks de connexion/déconnexion
- vérifier pendant 1 seconde si il faut appeler les callbacks de changement de valeurs.
L'écran n'est rafraîchi qu'une fois par seconde, mais pour ce genre d’application c'est amplement suffisant.
Ce script fonctionne donc à la fois en "polling" et en "callback". La gestion des boutons est traité en "callback", alors que l'écran est mit à jour en "polling".
if (anbutton.get_isPressed() == YAnButton.ISPRESSED_TRUE):
last = anbutton.get_userData()
if last == YAnButton.ISPRESSED_FALSE:
funcid = anbutton.get_functionId()
if funcid == 'anButton1':
xbmc_interface.up()
elif funcid == 'anButton2':
xbmc_interface.down()
elif funcid == 'anButton3':
xbmc_interface.left()
elif funcid == 'anButton4':
xbmc_interface.right()
elif funcid == 'anButton5':
xbmc_interface.ok()
elif funcid == 'anButton6':
xbmc_interface.back()
anbutton.set_userData(anbutton.get_isPressed())
....
def main():
errmsg = YRefParam()
YAPI.RegisterDeviceArrivalCallback(device_arrival)
YAPI.RegisterDeviceRemovalCallback(device_removal)
if YAPI.RegisterHub("usb", errmsg) < 0:
print("Unable register usb :" + str(errmsg))
return -1
while True:
progress, title = xbmc_interface.get_info_to_display()
for display in display_list:
w = display.get_displayWidth()
h = display.get_displayHeight()
layer0 = display.get_displayLayer(0)
layer0.selectGrayPen(0)
layer0.drawBar(0, 0, w - 1, h - 1)
layer0.selectGrayPen(255)
layer0.drawText(w / 2, h / 2, YDisplayLayer.ALIGN.CENTER, title)
if progress > 0:
layer0.drawBar(0, h - 1, int(progress * w / 100), h - 1)
display.swapLayerContent(0, 1)
YAPI.UpdateDeviceList()
YAPI.Sleep(1000)
Le code complet est disponible sur GitHub à l'adresse http://github.com/yoctopuce-examples/xbmc_remote.
Conclusion
Et voilà la preuve que ça marche :-) |
En moins de 200 lignes, nous avons implémenté un panneau de contrôle pour XBMC. Et comme la librairie Yoctopuce n'a pas besoin de driver, il fonctionne d'emblée sur n'importe quel OS (Windows, Linux et OSX). Trop facile :-)