Oct 31

Gestion d’une Cave à vins avec Tasker et Python

winecellar

Je suis un grand amateur de vin et après m’être essayé au livre de cave papier (rébarbatif il va s’en dire) pour gérer le stocks de bouteilles de ma cave à vin, j’ai cherché et essayé nombre d’application (sous Linux il va s’en dire).
Malheureusement, je n’ai jamais trouvé mon bonheur, même si OpenCellar était quand même ce que j’avais trouvé de mieux.
J’ai donc profité de mon week-end pour mettre en place une gestion de cave à vins qui convient à mes besoins (et aux vôtres aussi peut être :))

J’attendais plusieurs choses d’une « application » de gestion de cave à vins et je suis surpris de ne rien trouver d’adéquat (ou alors j’ai mal cherché et je suis ouvert à vos suggestions :))

– une application légère (donc en mode web)
– fonctionnant sous Linux (donc le prérequis précédent convient)
– fonctionnant en local (pas de cloud machin truc)
– permettant l’ajout et le retrait de bouteille avec son smartphone (car se rendre dans la cave à vin, choisir la bouteille, puis aller sur son pc ou son portable, ouvrir le site web, retirer la bouteille, c’est un peu lourd, alors que le smartphone, on l’a souvent avec soi)

N’étant pas un grand développeur web dans l’âme (ni avec mes doigts d’ailleurs), j’ai d’abord cherché une base de site sur laquelle commencer car je n’avais pas vraiment envie de passer plusieurs heures a faire du css, du div et toute la joie inhérente à ce genre d’application.

J’ai trouvé les projets de Christophe Coenraets sur Github qui à écrit plusieurs articles et applications pour gérer sa cave à vin (je vous invite d’ailleurs à lire ses billets à ce sujet (http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/ , http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/ , http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/).
Mon choix s’est porté sur sa version PHP, plus léger pour moi à mettre en œuvre.
Le plus de son application, c’est la présence d’une API permettant d’ajouter, mettre à jour ou lister le contenu de sa cave (oh voui j’adore ça lister mes vins avec un curl -i -X GET http://localhost/cellar/api/wines 😀 )

Je ne vous ferais pas l’affront de la mise en place du dépôt sous votre serveur web fétiche (penser à activer les méthodes PUT,DELETE et POST), cela coule de source.

On peuple la base et voila le premier résultat (a peu près, la c’est ma version modifiée)

screenwine1

Car oui j’ai d’abord modifié quelques fonctions.
Pour gérer les bouteilles avec mon smartphone, j’ai d’abord pensé à des étiquettes RFID, mais avec le nombre de précieux flacons, j’allais exploser mon budget « loisir« .
Donc mon choix s’est plutôt tourné vers un élément que l’on retrouve « presque » sur toutes les bouteilles, le code barre (ou EAN 13 pour les puristes).
Dans l’ensemble, j’ai très peu de bouteilles sans, principalement des achats direct au producteur, donc ne saisir qu’une infime quantité de stock à la mimine m’allait parfaitement (au pire, je pourrais faire du RFID avec elles).

NB: Dans ma folie habituelle, je vous avouerais être d’abord parti sur de la reconnaissance de l’étiquette avec OpenCV et de l’OCR mais vu l’ampleur du projet, je me suis vite raisonné 😀

Mes premières modifications apportées sur le code : ajout du champ EAN, traduction des champs, modification de la recherche sur la région en plus du nom et ajout d’un champ quantité.

Mes premiers tests de l’API était sympa mais il m’en fallait plus.
Etant plus à l’aise avec Python que PHP ou JavaScript, j’ai rapidement codé ma propre API.

Celle ci permet plusieurs choses :
– POSTer le code EAN d’une bouteille et la créer si besoin (en mettant la quantité à 1 par défaut et en lui affectant l’image ‘codeEAN’.png), si le code existe, ajouter +1 à la quantité. Possibilité également de faire -1 sur la quantité.

class addean:
def POST(self,uri):
try :
ID = web.data()
except:
return web.badrequest()
con = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb);
cur = con.cursor()
print ID
cur.execute("""SELECT * from wine where EAN=%s""", (ID,))
result = cur.fetchone()
if result is None:
print "no bottle"
print ID
data = {'EAN': ID, 'picture': ID+'.png'}
data = json.dumps(data)
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
else:
cur.execute("""UPDATE wine SET nombre=(nombre+1) where EAN=%s""", (ID,))
con.commit()
print "Number of rows updated: %d" % cur.rowcount
con.close()
 
class removeean:
def POST(self,uri):
try :
ID = web.data()
except:
return web.badrequest()
con = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb);
cur = con.cursor()
print ID
cur.execute("""SELECT * from wine where EAN=%s""", (ID,))
result = cur.fetchone()
if result is None:
print "new bottle"
print ID
data = {'EAN': ID, 'picture': ID+'.png'}
data = json.dumps(data)
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
else:
cur.execute("""UPDATE wine SET nombre=(nombre-1) where EAN=%s""", (ID,))
con.commit()
print "Number of rows updated: %d" % cur.rowcount
con.close()

– POSTer la photo de l’étiquette et l’inclure dans la fiche.

class index:
def POST(self,uri):
try:
web.cookies().filename
filenamereceived = web.cookies().filename
except:
filenamereceived == "generic"
try :
data = web.data()
except:
return web.badrequest()
if data == "":
return web.badrequest()
print filenamereceived
b64response = base64.b64encode(data)
fh = open(winepics+filenamereceived+".png", "wb")
fh.write(b64response.decode('base64'))
fh.close()
return "200 STORED"

Maintenant que mon API était prête, il fallait pouvoir utiliser le smartphone.

La meilleure application d’automatisation sous android est pour moi Tasker. De plus, de nombreux plugins existent et l’un des maîtres du plugin Tasker est sûrement João Dias alias joaomgcd.
J’utilise quasiment tout ses plugins (qui ne coûte pas grand chose pour une efficacité redoutable, dont le fameux AutoRemote) et en cherchant un plugin « barcode » (code barre) pour Tasker, et bien il existe AutoBarcode ! Magique, ce type est un génie 😀

Un peu de « codage » Tasker pour réaliser ce que je veux :

Lancer un scan de code barre,

Screenshot_20161030-212503

une fois effectué, lancer une « scène » Tasker me demandant si je veux ajouter ou retirer cette bouteille :

Screenshot_20161030-212537

– je retire, je fais -1 sur la quantité
– j’ajoute, je fais +1 si le code EAN existe, sinon j’appelle l’API du site pour créer la bouteille avec son code EAN. Je continue en demandant si je veux ajouter une photo, si non, je sors, si oui, je lance l’appareil photo qui me permet de photographier l’étiquette et de la POSTer en la nommant ‘codeEAN’.png.

Screenshot_20161030-212547
Bien sur la création de la bouteille lie automatiquement l’image à l’url ../pics/’codeEAN’.png.

Il ne me reste alors qu’a me rendre sur le site web pour compléter la fiche de la bouteille.

screenwine2
En quelques heures, j’ai enfin pu me créer un site de gestion de ma cave à vin efficace et qui répond à mes besoins.
L’ajout ou le retrait d’une bouteille se fait avec le smartphone en premier lieu (on peut le faire sur le site aussi).

Si vous voulez vous aussi déployer ce genre d’application chez vous, j’ai bien évidemment tout mis sur mon Github en forkant le projet de Christophe et en y ajoutant les éléments nécessaires 😀

Amusez vous bien 🙂

Classé dans geekerie | Taggé , | 7 Commentaires
Mai 23

Voyager dans les yeux de Morgan

morgan

J’avoue qu’il est assez rare que j’écrive des billets sur d’autres choses que mes passions primaires :p, mais cela arrive parfois.

J’ai connu Morgan par Twitter, au début sans trop y faire attention et puis je regarde son profil et découvre son site.

Et là, c’est un peu le choc pour moi. Morgan s’est donné un objectif, visiter 50 pays avant ses 50 ans.

En soi, c’est déjà un petit exploit et surtout un vieux rêve enfoui pour moi qui approche doucement de la cinquantaine.

Rien que ce « challenge » m’a remis en question.
J’ai bien vécu, j’ai fait des tas de boulots divers et variés, rencontré des tas de personnes formidables, fondé une famille, vécu des expériences inédites et indicibles pour certaines, visité quelques pays mais lire cet objectif m’a définitivement remis en place.
Oui, je suis passé à côté de quelque chose.
Ce constat que j’ai pris en pleine gueule m’a fait encore plus apprécier l’individu.

Et puis, j’ai lu, relu et vécu ses voyages. Car ce monsieur écrit bien, très bien même. Des récits de voyages, j’en ai dévoré pourtant plusieurs, mais Morgan à cette touche personnelle d’écriture qui fait que l’on vit avec lui son voyage, ses découvertes, ses déconvenues et ses sensations.

Alors oui il est doué, très doué même. Il s’est donné le courage et la volonté de vivre sa passion et d’atteindre son ambition mais surtout, et c’est pour moi
le plus important, il nous l’a fait vivre avec ses mots à lui, son regard et son cœur.

Je ne le connais pas encore réellement (ça devrait venir, parce que parmi toutes ses qualités, il est breton 😀 et donc on se retrouvera forcément autour d’un verre à Brest même !), mais vivre à travers ses écrits ses voyages me rapproche de lui, de mes vieux rêves regréttés et me fait découvrir le monde comme j’aurais aimais le découvrir moi même.

Alors ce billet n’est qu’anecdotique, n’est là que pour exprimer mes sincères remerciements à Morgan pour le temps qu’il passe à nous faire partager ses voyages, mais surtout, je vis à travers ses écrits des histoires dont j’aimerais être le héros. Et après tout, pourquoi pas 50 pays avant mes 70 ans…

Pour le découvrir, c’est ici : https://lesvoyagesdemorgan.fr/

PS: je suis les voyages d’un autre couple qui fait le tour du monde, Chloé et Romain sur http://www.playingtheworld.com/ , à lire également et avec eux trois, prenez un vrai bol d’air…

Classé dans Non classé | 2 Commentaires
Sep 06

Jouons avec le WD Tv Live et UPNP

wdtvlive

Depuis des années je dispose d’un boîtier WD TV Live qui me permet de lire sur la télévision les vidéos stockées sur mon NAS Synology.
Efficace, ce petit boîtier fonctionne parfaitement bien et a trouver naturellement sa place dans le meuble TV.

J’avais un peu oublié sa présence jusqu’à me rendre compte que mon système domotique ne le connaissait pas.
Qu’a cela ne tienne, c’était le moment de jouer avec 🙂

Sur mon téléphone Android, je dispose d’une application, WD TV Remote, qui permet de contrôler le boitier par wifi.
Cela suffit à se dire qu’il doit être possible d’interagir avec lui par le réseau local.

Qui dit boîtier multimédia, dit forcement UPNP. Une petite découverte via l’outil gssdp-discover du projet gupnp-tools nous donne les points d’entrées du boîtier (je vous passe l’ensemble des équipements trouvés pour se concentrer sur le WD) :

gssdp-discover -i eth0.8 --timeout=5
Using network interface eth0.8
Scanning for all resources
resource available
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::upnp:rootdevice
Location: http://wdtvlive:10184/
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77
Location: http://wdtvlive:10184/
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:device:MediaRenderer:1
Location: http://wdtvlive:10184/
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:AVTransport:1
Location: http://wdtvlive:10184/
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:ConnectionManager:1
Location: http://wdtvlive:10184/
resource available
USN:      uuid:5e881b94-0090-a9c7-b3b0-56fc82ddce77::urn:schemas-upnp-org:service:RenderingControl:1
Location: http://wdtvlive:10184/

Une visite sur l’url http://wdtvlive:10184/ nous donne un joli arbre xml

...
<serviceList><service><serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType><serviceId>urn:upnp-org:serviceId:AVTransport</serviceId><SCPDURL>MediaRenderer_AVTransport/scpd.xml</SCPDURL><controlURL>MediaRenderer_AVTransport/control</controlURL><eventSubURL>MediaRenderer_AVTransport/event</eventSubURL></service>
...

Déformation professionnelle oblige, je lance un tcpdump sur mon téléphone et j’agis sur la télécommande WD TV Remote.

On retrouve bien le POST http sur le point d’entrée du boîtier et la réponse de se dernier.

POST /MediaRenderer_AVTransport/control HTTP/1.1
Accept: */*
User-Agent: Twonky-NMC/7.3-Android (Android/4.4.2 (Build KOT49H); samsung/GT-I9505) DLNADOC/1.50
Host: wdtvlive:10184
SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo"
Content-Type: text/xml; charset="utf-8"
Content-Length: 312
 
<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:GetTransportInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:GetTransportInfo></s:Body></s:Envelope>HTTP/1.1 200 OK
 
Transfer-Encoding: chunked
EXT:
CONTENT-TYPE: text/xml; charset="utf-8"
SERVER: POSIX, UPnP/1.0, Intel MicroStack/1.0.1497
1BF
 
<?xml version="1.0" encoding="utf-8"?>
 
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:GetTransportInfoResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><CurrentTransportState>PAUSED_PLAYBACK</CurrentTransportState><CurrentTransportStatus>OK</CurrentTransportStatus><CurrentSpeed>1</CurrentSpeed></u:GetTransportInfoResponse></s:Body></s:Envelope>

Génial 🙂

Ne reste plus qu’a tester tout cela avec une belle requête curl (accrochez-vous à votre clavier..) :

curl -H "Content-Type: text/xml" -H 'SOAPACTION: urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo"' -XPOST -d '<s:Envelope xmlns: s="http://schemas.xmlsoap.org/soap/envelope" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding"><s:Body><u:GetTransportInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:GetTransportInfo></s:Body></s:Envelope>' http://wdtvlive:10184/MediaRenderer_AVTransport/control
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:GetTransportInfoResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><CurrentTransportState>PAUSED_PLAYBACK</CurrentTransportState><CurrentTransportStatus>OK</CurrentTransportStatus><CurrentSpeed>1</CurrentSpeed></u:GetTransportInfoResponse></s:Body></s:Envelope>

Elle est pas belle la vie ? :p

On voit dans la réponse le mode actuel du boîtier :
PAUSED_PLAYBACK

En remplacant la méthode « GetTransportInfo » par « GetPositionInfo », le WD Tv nous donne tout un tas d’information dont le film actuellement joué :

curl -H "Content-Type: text/xml" -H 'SOAPACTION: urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo"' -XPOST -d '<s:Envelope xmlns: s="http://schemas.xmlsoap.org/soap/envelope" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding"><s:Body><u:GetPositionInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:GetPositionInfo></s:Body></s:Envelope>' http://wdtvlive:10184/MediaRenderer_AVTransport/control
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:GetPositionInfoResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><Track>1</Track><TrackDuration>00:22:46</TrackDuration><TrackMetaData>&lt;DIDL-Lite xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot;&gt;&lt;item id=&quot;BROWSE_TYPE_KEYvideo*~&gt;_&lt;~*BROWSE_SORT_KEY8*~&gt;_&lt;~*BROWSE_GROUP_KEY0*~&gt;_&lt;~*BROWSE_FILTER_KEYBROWSE_FILTER_TERM_STARTfilepath:&lt;_EQUALS_&gt;:/tmp/media/nfs/NAS/FILMS/Naruto/Naruto.Shippuden.Saison.7BROWSE_FILTER_TERM_END*~&gt;_&lt;~*Naruto Shippuden 170.mkv&quot; parentID=&quot;BROWSE_TYPE_KEYvideo*~&gt;_&lt;~*BROWSE_SORT_KEY8*~&gt;_&lt;~*BROWSE_GROUP_KEY0*~&gt;_&lt;~*BROWSE_FILTER_KEYBROWSE_FILTER_TERM_STARTfilepath:&lt;_EQUALS_&gt;:/tmp/media/nfs/NAS/FILMS/Naruto/Naruto.Shippuden.Saison.7BROWSE_FILTER_TERM_ENDBROWSE_FILTER_TERM_STARTname:&lt;_EQUALS_&gt;:Naruto Shippuden 170.mkvBROWSE_FILTER_TERM_END*~&gt;_&lt;~*&quot; restricted=&quot;0&quot;&gt;&lt;dc:title&gt;Naruto Shippuden 170.mkv&lt;/dc:title&gt;&lt;upnp:class&gt;object.item.videoItem&lt;/upnp:class&gt;&lt;dc:creator&gt;&lt;/dc:creator&gt;&lt;upnp:genre&gt;Unknown&lt;/upnp:genre&gt;&lt;upnp:album&gt;&lt;/upnp:album&gt;&lt;res bitrate=&quot;1230&quot;  protocolInfo=&quot;file-get:*:video/x-matroska::DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=00000000001000000000000000000000&quot; protection=&quot;&quot; tokenType=&quot;0&quot; duration=&quot;&quot; size=&quot;210161304&quot; colorDepth=&quot;0&quot; ifoFileURI=&quot;&quot; resolution=&quot;--&quot;&gt;file:///tmp/media/nfs/NAS/FILMS/Naruto/Naruto.Shippuden.Saison.7/Naruto%20Shippuden%20170.mkv&lt;/res&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</TrackMetaData><TrackURI>file:///tmp/media/nfs/NAS/FILMS/Naruto/Naruto.Shippuden.Saison.7/Naruto%20Shippuden%20170.mkv</TrackURI><RelTime>00:08:00</RelTime><AbsTime>NOT_IMPLEMENTED</AbsTime><RelCount>2147483647</RelCount><AbsCount>2147483647</AbsCount></u:GetPositionInfoResponse></s:Body></s:Envelope>

Ici je vois que Junior regarde le fichier « Naruto Shippuden 20170.mkv » (ok pas très instructif comme film…) et ce depuis 8 minutes.

Python disposant de l’excellent module lxml pour parser les fichiers XML, un coup de scripting tout simple permet d’isoler les informations importantes :

from lxml import etree
 
tree = etree.parse('le fichier xml')
for element in tree.iter('CurrentTransportState'):
result = element.text
print "WD TV Live status: "+result
 
tree = etree.parse('le fichier xml')
for element in tree.iter('TrackURI'):
film = element.text
print "WD TV Live joue : "+film
 
WD TV Live status: PLAYING
WD TV joue: file:///tmp/media/nfs/NAS/FILMS/Naruto/Naruto.Shippuden.Saison.7/Naruto%20Shippuden%20170.mkv

Toutes les commandes disponibles sont référencées sur l’upnp database.

Maintenant le serveur domotique connait l’état du boitier WD TV Live ainsi que le fichier joué sur le téléviseur.
Ce qui nous permet par exemple de programmer une surveillance de ce que Junior regarde…

tree = etree.parse('le fichier xml')
for element in tree.iter('TrackURI'):
film = element.text
if "Pr0n_A_Papa" in film:
# power off immédiat de la télévision

J’espère que ce petit billet vous donnera envie d’aller explorer un peu les points d’entrée UPNP des différents équipements de votre domicile 😉

EDIT : Pour éteindre et allumer votre WD TV Live par une simpe requête http, il suffit d’envoyer le POST suivant :
curl -XPOST -d ‘{« remote »: »w »}’ http://wdtvlive/cgi-bin/toServerValue.cgi

Amusez-vous bien 🙂

Classé dans domotique | Taggé , | 6 Commentaires
Août 01

l’API Domogeek, clap de fin

closedapi

EDIT DU 06/08/2015 : Bonne nouvelle ! Le groupe Entropia SA basé au Luxembourg m’a offert gracieusement l’hébergement de l’API. Domogeek renait donc de ses cendres 😀
Temporairement, l’url de l’API est http://domogeek.entropialux.com

 

C’est avec un grand regret que je vais cesser d’offrir publiquement l’accès à l’API Domogeek, après 1 an d’existence.

Le succès a était au rendez vous puisque ses dernière semaines, le nombre d’appels à l’API dépassait largement les 500 000 par jour.
J’ai tout fait pour supporter la charge (le taux de disponibilité (affiché publiquement par les sondes PingDom) a toujours était supérieur à 99,5%)a et pour cela j’ai du investir du temps mais surtout de l’argent pour payer la location des serveurs chez OVH.

D’une mentalité d’entraide et de partage innée chez moi, j’ai donc sollicité les utilisateurs pour faire un modeste don afin de m’aider à régler ses frais.
En deux appels, j’ai récolté la somme faramineuse de… 50 euros, avec en prime une suppression de mon post sur le forum Jeedom pour la raison que les appels aux dons sur le forum d’un produit à vocation commerciale n’avait pas lieu d’être. Soit. Je me suis longuement expliqué avec l’équipe et je concois que cela entrave le fonctionnement de leur businness-plan, mais bon, les plugins open, c’est un peu la force de Jeedom aussi…
Après, j’avais une position difficile, je ne suis pas l’auteur du plugin (c’est tmartinez, qui d’ailleurs a était parmi les premiers a faire un don pour l’api), et donc je ne suis qu’un fournisseur de service sans lien avec Jeedom mais j’ai eu un peu de mal à avaler la pastille, moi qui le premier revendique le partage, l’entraide et la transparence.

Je ne peux que remercier chaleureusement les  7 (:p) utilisateurs qui ont voulu m’aider : tmartinez, Kheops37, Stéphane (lademan ?), Mickael (Mika ?), edreams, mamatdv, lionel

Le code source est toujours disponible sur GitHub et vous pouvez donc l’héberger localement pour continuer à utiliser le plugin de tmartinez (pour les utilisateurs de Jeedom) ou en direct pour les autres.

Je suis de cette génération de barbu qui a toujours offert de l’entraide, qui a toujours partagé ses découvertes, ses modestes développements et je suis aujourd’hui déçu que cette mentalité tend a disparaître de plus en plus.
Sur IRC, sur les forums, je voyais déjà cette aide bénévole se transformait en assistanat (les gens ne cherche plus et attende la réponse tout de suite avec un merci donné du bout des doigts, quand il existe) et cette aventure m’a malheureusement démontré qu’on ne peut plus solliciter financièrement un coup de main, il faut obligatoirement faire payer le service.

Je salue les quelques irréductibles qui continue à offrir des services à la communauté en payant de leur personne et de leur porte-monnaie les infrastructures nécessaire (j’en oublierais sûrement donc spécial coup de chapeau à domotics du forum toute la domotique, à Jean-Philippe Encausse pour son projet SARAH, à l’équipe Domogik, à l’équipe Imperihome etc… J’en oublie plein mais ils se reconnaîtrons forcément :D)

A vous tous les utilisateurs de tout ses programmes, ses services, ses aides gratuites, n’oubliez jamais que derrière il y a souvent 1 ou quelques personnes qui vous offrent bénévolement de leur temps et souvent de leur argent pour vous rendre la vie agréable, alors un coup de main, même minime, cela donne toujours beaucoup de chaleur et de reconnaissance…

« La valeur d’un homme tient dans sa capacité à donner et non dans sa capacité à recevoir. »  Albert Einstein

Classé dans domotique | 26 Commentaires