Inspiration du week-end en domotique (2e édition)

Domotique pour le jardin

Et si on transformait notre potager en une version ludique, gérée par la domotique, open-source ? C’est le concept derrière Farm.bot

Non, ce n’est pas imprimante 3D à plante…

Radiateurs connectés

Le blog de Heatzy a publié un comparatif (rapide) mais intéressant sur des radiateurs connectés :

Les deux derniers nécessitent l’achat d’une Cozytouch… à 100€ pièce. .https://heatzy.com/blog/4-radiateurs-connecte-2018

En résumé, les radiateurs Heatzy ont l’air bien… mais il faudrait pour ça qu’ils soient disponibles à la vente 😉

Bon dimanche à tous!

Informer l’utilisateur des besoins d’entretien du robot Xiaomi depuis jeedom

Edit du 22/01/2019 : Ajout d’un événement spécifique pour prendre en compte le démarrage du robot « manuellement ».

Pour ceux qui ne le savent pas, je possède un robot aspirateur Xiaomi Roborock. C’est un excellent robot, qui fait bien son job quasiment aussi bien que le Neato que j’avais avant.

version 1 du robot.

L’application Xiaomi est pratique, mais pas très intelligente. On ne peut sélectionner que des jours de passages. Pour lui, les vacances ou les jours de télétravail, il s’en fiche un peu.

Pour compenser, j’ai réalisé via jeedom (non ?!!!!) des scénarios pour contrôler de manière plus intelligente le passage de notre robot ménager, en utilisant le plugin de Lunarok.

L’application Xiaomi avait deux avantages sur jeedom : la présence de compteurs pour demander le nettoyage capteurs, le changement des brosses etc et une notification pour demander le remplacement / entretien. Bon, elle permet aussi de visualiser un plan 3D du lieu de passage du robot mais à part faire mumuse, ça ne sert à rien dans la vie de tous les jours. En tout cas, je n’ai pas trouvé 😉

Cet article va expliquer comment réaliser un scénario pour remplacer cette fonction

Prérequis

  • Une installation de jeedom qui fonctionne
  • Le plugin Xiaomi de Lunarok
  • Un robot Xiaomi relié au plugin Jeedom
  • En option, le plugin virtuel

Principe

Le principe va être de faire la différence entre le moment ou le robot part de sa base (début de nettoyage) et le moment ou le robot rentre à sa base (fin de nettoyage, recharge etc.) et d’ajouter ce temps à des compteurs distincts pour les matériels.

J’ai donc créé deux scénarios, le premier s’occupe de démarrer le robot aux heures / moment qui nous intéressent et le second s’occupe du moment ou le robot rentre à sa base.

Scénario de démarrage du robot

Dans mon cas c’est assez simple : j’ai un déclencheur temporel qui le lance tous les jours sauf le dimanche à 9h30. Pas trop compliqué. En cas de présence, on peut utiliser des fonctions pour éviter que le robot se lance.

Mais il faut prendre en compte les lancements manuels (via le bouton). Dans ce cas là j’ai ajouté un déclencheur :

[Maison][Robot blanc][Statut]# != "En charge" && #[Maison][Robot blanc][Batterie]# <= 98 && variable(robot_start) = 0

Seul défaut de ce déclencheur, s’il y a une longue coupure de courant, et ben… le robot se déclenche. Même en pleine nuit … Enfin, bon, 2% de batterie, c’est environ 30 min de décharge. C’est assez rare chez moi. Dans l’idéal, il faudrait pouvoir récupérer le statut d’un onduleur relié à jeedom, chose que je n’ai pas fait chez moi.

Pour autoriser le démarrage, j’ai ensuite rajouté un second déclencheur non visible :

[Maison][Robot blanc][Statut]# != « En charge » && #[Maison][Robot blanc][Statut]# != « Retour à la base » && #[Maison][Robot blanc][Batterie]# <= 98 && variable(robot_start) = 0

Dans la partie scénario, je demande au robot de démarrer son cycle, je m’envoi un message et je note dans une variable au bout de 2 min que le robot a démarré. Cette variable sert surtout pour éviter les problèmes de coupures de courant…

Scénario de retour du robot à la base

La on rentre dans un cas plus compliqué. Pour le déclenchement, soit on demande au robot de retourner à la base, soit le robot se met en charge ET le robot a bien été démarré.

Au niveau du scénario : on commence par réinitialiser la variable de démarrage puis on ajoute le temps passé a chacun des compteurs : robot_filtre, robot_brosses et robot_capteur. J’utilise la formule suivante qui se base sur le temps d’exécution du scénario de début. On divise par 60 pour avoir le temps en minutes.

variable(robot_filtre) + floor(lastScenarioExecution(#[Maison][Robot][Robot_demarrage]#)/60)

A vous d’adapter cette partie. Ensuite j’envoi via IFTTT un message d’information. Bon, vous êtes pas obligé d’utiliser IFTTT, un mail / un message dans telegram fera aussi bien l’affaire.

J’ai rajouté ensuite des tests pour chacun des compteurs, et j’envoi un message différencié selon le capteur a nettoyé / changé.

Pour les valeurs des compteurs nous avons choisi les valeurs suivantes :

  • nettoyage capteur toutes les 3000 min (50 h)
  • Filtre => 12000 min (200 h)
  • Brosses 18000 min (300 h)
  • Vidage du bac : à chaque fois !

Gestion des cas d’erreurs

Alors après plusieurs essais, nous avons eu des soucis de robot coincé sur des jouets… j’ai donc ajouté un scénario se déclenchant sur une erreur.

Sa seule action est de renvoyer le robot à sa base s’il a bien démarré. Donc en le renvoyant, cela va démarrer le scénario de fin.

Si le robot a démarré, on le renvoie à la niche!

Option : virtuel pour visualiser réinitialiser les compteurs

Ce n’est pas obligatoire, mais je vous recommande de créer un virtuel pour réinitaliser les compteurs. Il vous faut donc le plugin virtuel.

Commencer par créer un nouveau virtuel et n’oubliez pas de l’activer et de le rendre visible.

Puis configurer les commandes pour afficher les informations des différents compteurs. J’en ai mis trois mais vous pouvez en mettre autant que vous voulez.


Ensuite, ajouter des « boutons » d’actions. Lorsque vous allez les créer cela va ajouter automatiquement des informations supplémentaires, qui sont affichées.

Mais l’action ne fait ici « rien du tout » alors pas besoin d’afficher le virtuel.

On configure chacune des actions pour réinitialiser un compteur : cliquer sur l’icône en forme de roue crantées, puis onglet configuration, et ajouter « action après exécution de la commande. Et ensuite, réinitialiser la variable.

Il ne reste plus qu’à « ranger » votre virtuel à votre sauce. Personnellement je met le mien au format tableau, et j’affiche chacune des infos virtuelles avec le widget « tile(core) ».

Pour conclure

Après quelques semaines d’utilisations, les compteurs marchent très bien. Mais évidemment, je ne me suis pas arrêté en si bon chemin et je me suis dit « et s’il était possible de rajouter une tâche dans ma todo-list pour penser à changer / nettoyer les différents capteurs ? Et bien, je l’ai fait, cela fonctionne trèèèès bien mais ce sera le sujet d’un prochain article.

Piloter une TV Philips ambilight récente par ligne de commande

Les TV Philips récentes sous Android TV (> 2016) utilisent une API basée sur JointSpace

C’est beau tout de même!

MAIS, pour faire simple, Philips a décidé de masquer cet API via d’une part un changement de port, l’utilisation du https au lieu du http… et en prime, cela nécessite un appairage, intégré aux applications philips… Mais pas accessible ailleurs.

Heureusement, il existe sur github un script permettant de réaliser « facilement » cet appairage. Enfin, facilement…

https://github.com/suborb/philips_android_tv

Je vais décrire le process pour installer ce script.

Prérequis

  • Avoir un pc / serveur (linux de préférence) avec python d’installé.
  • Avoir git d’installé : rappel sur ubuntu
sudo apt-get install git

  • Connaître l’adresse IP de votre télé philips. Si vous ne la connaissez pas, elle est indiquée dans le menu android!

Installation du script et appairage

Sur votre PC/Serveur, dans le dossier de votre choix, on commence par récupérer le script :

git clone https://github.com/suborb/philips_android_tv.git <votre_dossier>
cd <votre dossier>

ensuite, on installe les pré-requis du scripts :

sudo pip install -r requirements.txt

Il faut ensuite démarrer votre téléviseur puis lancer l’appairage de votre TV via le script

python philips.py --host <adresse IP Philips TV> pair

Le script vous demande un code affiché à l’écran, puis il va vous fournir un utilisateur et un mot de passe. Ces deux éléments sont essentiels et à conserver absolument. Rassurer vous, on peut toujours relancer l’appairage si on les oublie…

Utilisation du script

On peut utiliser le script pour récupérer des infos … mais surtout réaliser quelques actions (limitées… très limitées…)

Pour cela on exécute le script ainsi :

python philips.py --host <adresse IP TV> --user <VOTRE USER> --pass <VOTRE PASS> <command>

Avec <command> ayant pour valeur possible : get_volume, get ou standby

Bon, le script est pas super complet… Donc, j’ai réalisé quelques modifications pour avoir quelques commandes supplémentaires.

Sur demande, je peux fournir un patch… en attendant, faute de mieux, remplacer les lignes > 99

if args.command.startswith("get"):
if args.command == "get_ambilight_cached":
config['path'] = "6/ambilight/cached"
elif args.command == "get_ambilight":
config['path'] = "6/ambilight/currentconfiguration"
elif args.command == "get_ambilight_mode":
config['path'] = "6/ambilight/mode"
elif args.command == "get_ambilight_topology":
config['path'] = "6/ambilight/topology"
elif args.command == "get_applications":
config['path'] = "6/applications"
elif args.command == "get_channeldb_tv":
config['path'] = "6/channeldb/tv"
elif args.command == "get_channeldb_channellists":
config['path'] = "6/channeldb/tv/channelLists/all"
elif args.command == "get_menuitems_settings":
config['path'] = "6/menuitems/settings/structure"
elif args.command == "get_powerstate":
config['path'] = "6/powerstate"
elif args.command == "get_recordings":
config['path'] = "6/recordings/list"
elif args.command == "get_system":
config['path'] = "6/system"
elif args.command == "get_system_epgsource":
config['path'] = "6/system/epgsource"
elif args.command == "get_system_storage":
config['path'] = "6/system/storage"
elif args.command == "get_system_timestamp":
config['path'] = "6/system/timestamp"
elif args.command == "get_volume":
config['path'] = "6/audio/volume"
else:
print("Invalid get command (see source for details)")
return
get_command(config)
if args.command.startswith("post"):
if args.command == "post_standby":
config['path'] = "6/input/key"
config['body'] = { "key" : "Standby" }
elif args.command == "post_home":
config['path'] = "6/input/key"
config['body'] = { "key" : "Home" }
elif args.command == "post_mute":
config['path'] = "6/input/key"
config['body'] = { "key" : "Mute" }
else:
print("Invalid post command")
return
post_command(config)
main()

Cela me permet d’avoir des commandes intéressantes du point de vue domotique

  • post_standy => arrêt / mise en route de la télé
  • post_home => mise en route du menu home
  • post_mute => mute …
  • get_powerstate => status de la télé (allumée, eteinte)

Bon, après tout ça, c’est TOUJOURS pas user friendly, mais ça permet d’interroger la télévision, de lui demander de s’allumer, de s’éteindre…

Mais ensuite, il reste à intégrer tout ça dans Jeedom, et cela fera partie d’un deuxième article.