Cardane Posté(e) le 26 octobre 2018 Auteur Signaler Posté(e) le 26 octobre 2018 @Dragoniacs ah oui, l'API est très bien documentée maintenant. Au départ l'API n'était pas du tout officielle et donc non documentée. C'est en trouvant des bouts de code à gauche et à droite que je sis parvenu à faire le VD pour des actions simples. Quand Velux a réalisé que pas mal de monde utilisait cette api, ils ont décidé de la revoir, de le compléter et de le documenter. Problème, il n'a plus rien à voir avec l'ancien, et donc pas possible de simplement adapter mon VD, il faut tout réécrire, et je ne suis même pas certain que la HC2 supporte le protocole demandé. J'ai trouvé des exemples en Python, mais comme je n'ai plus fait de développement depuis 20 ans, je ne connais pas python :-) donc pour l'instant je rame un peu :-)
Cardane Posté(e) le 26 octobre 2018 Auteur Signaler Posté(e) le 26 octobre 2018 @Dragoniacs oui, c'est la nouvelle API
Dragoniacs Posté(e) le 26 octobre 2018 Signaler Posté(e) le 26 octobre 2018 @CardaneMerci pour tes réponses. Mince alors, il va me falloir trouver un prgrammeur pour pouvoir aller plus loin..... Je lance un appel à volontaire
Cardane Posté(e) le 27 octobre 2018 Auteur Signaler Posté(e) le 27 octobre 2018 @Dragoniacs j'ai ouvert un post à ce sujet il y a quelques jours
Dragoniacs Posté(e) le 31 octobre 2018 Signaler Posté(e) le 31 octobre 2018 @Cardane tu as ouvert un post sur le forum officiel ? Moi j'ai envoyé un mail au support. Ils ont répondu que c'était une bonne idée et qu'ils transmettrai aux développeurs...
Cardane Posté(e) le 31 octobre 2018 Auteur Signaler Posté(e) le 31 octobre 2018 (modifié) @Dragoniacsnon, ca fait longtemps que je ne ma fais plus d'illusion avec le support, et si même ils faisaient quelque chose, ce serait encore un plugin minimum, qui marchera une fois sur deux ;-) Je suis en train de regarder comment faire, je vais bosser dessus ce weekend, c'est juste le temps qui me manque Modifié le 31 octobre 2018 par Cardane
ikillou Posté(e) le 3 novembre 2018 Signaler Posté(e) le 3 novembre 2018 @Cardane J'ai commencé à étudier les scripts de la nouvelle API. J'ai fait la mise à jour de mon KLF200 et j'ai commencé à tester. Mon idée est de mettre le script python sur un serveur local et de le lancer par la HC2. Cela me parait plus simple que de le convertir en LUA, surtout avec mon niveau... Donc j'ai refait le script exemple pour faire des tests. J'ai tout mis les modules python dans un seul et j'ai enlevé le code en trop. Pour les tests je mets le n° de la scène en dur, ensuite il faudra le traiter en paramètre. Le problème maintenant, c'est comment démarrer ce script... J'essaie sur mon Synology mais sans succès pour l'instant... je n'y connais rien en Python, et je ne progresse pas tant vite. Donc, si quelqu'un a des idées, je suis preneur Voici mon script python qui lance la scène n° 1 : ## ====================================================== ## Script pour demarrer une scene de la box Velux KLF-200 ## ------------------------------------------------------ ## Version 0.1.1 - Last update : 03.11.18 by Christian R. ## ====================================================== import ssl, socket, time, struct from time import sleep # =============================================================================== # Variables # =============================================================================== SCENE_ID = 1 KLF200_ADDRESS = "192.168.0.12" PASSWORD = "Velux123" PORT = 51200 LoopDelay = 1 # =============================================================================== # slip # =============================================================================== END = b"\xC0" # SLIP escape character as per RFC 1055 ESC = b"\xDB" # SLIP escape character as per RFC 1055 ESC_END = b"\xDC" # SLIP escape character as per RFC 1055 ESC_ESC = b"\xDD" # SLIP escape character as per RFC 1055 def slip_pack(inputFrame): data = inputFrame data = data.replace(ESC, ESC + ESC_ESC) data = data.replace(END, ESC + ESC_END) return END + data + END def slip_unpack(inputFrame): data = inputFrame if(data[0:1]==END and data[-1:]==END): data = data.replace(ESC + ESC_END, END) data = data.replace(ESC + ESC_ESC, ESC) return data[1:-1] else: print("Error: No SLIP frame!\n") return inputFrame # error -> return input # =============================================================================== # toolbox # =============================================================================== def getIndex(sourceDict, value): return (k for k, v in sourceDict.items() if v == value).__next__() def toHex(s): return ":".join("{:02x}".format(c) for c in s) # =============================================================================== # ActivateScene # =============================================================================== def process_connection(conn): conn.settimeout(10.0) # 10 sec print("Send valid password") conn.write(bytes(ST_GW_PASSWORD_ENTER_REQ(PASSWORD))) print("Received: ", toHex(slip_unpack(conn.recv())), "\n") time.sleep(LoopDelay) print("Activate Scene with ID = ", SCENE_ID) conn.write(bytes(ST_GW_ACTIVATE_SCENE_REQ(bSceneID=SCENE_ID))) print("Received: ", toHex(slip_unpack(conn.recv()))) def main(): sock = socket.socket(socket.AF_INET) sock.settimeout(10.0) context = ssl.SSLContext(ssl.PROTOCOL_TLS) context.check_hostname = False #accept self-signed certificate context.verify_mode = ssl.CERT_NONE conn = context.wrap_socket(sock, server_hostname=KLF200_ADDRESS) try: conn.connect((KLF200_ADDRESS, PORT)) process_connection(conn) except BaseException as e: raise(e) finally: conn.close() # =============================================================================== # klf200api # =============================================================================== GW_ACTIVATE_SCENE_REQ = 0x0412 GW_ACTIVATE_SCENE_CFM = 0x0413 GW_PASSWORD_ENTER_REQ = 0x3000 GW_PASSWORD_ENTER_CFM = 0x3001 dictPriorityLevel = { 0: 'Human Protection', 1: 'Environment Protection', 2: 'User Level 1', 3: 'User Level 2', 4: 'Comfort Level 1', 5: 'Comfort Level 2', 6: 'Comfort Level 3', 7: 'Comfort Level 4', } dictCommandOriginator = { 0x00: "LOCAL_USER", # // User pressing button locally on actuator 0x01: "USER", # // User Remote control causing action on actuator 0x02: "RAIN", # // Sensor 0x03: "TIMER", # // Sensor 0x04: "SECURITY", # // SCD controlling actuator 0x05: "UPS", # // UPS unit 0x06: "SFC", # // Smart Function Controller 0x07: "LSC", # // Lifestyle Scenario Controller 0x08: "SAAC", # // Stand Alone Automatic Controls 0x09: "WIND", # // Wind detection 0x10: "MYSELF", # // Used when an actuator decides to move by itself 0xFE: "AUTOMATIC_CYCLE", # // Used in context with automatic cycle; 0xFF: "EMERGENCY" # // Used in context with emergency or security commands, # // -this command originator should never be disabled } dictVelocity = { 0: 'DEFAULT', 1: 'SILENT', 2: 'FAST', 255: 'VELOCITY_NOT_AVAILABLE', #Only used in status reply } # =============================================================================== class ST_GW_FRAME: def __init__(self, Command): self.DataLength = 0 self.Command = Command self.binary_output = b""; def __bytes__(self): self.binary_output = struct.pack("BB", 0, self.DataLength + 3) self.binary_output += struct.pack(">H", self.Command) self.binary_output += self.pack_data() self.binary_output += struct.pack("B", self.calc_crc()) return slip_pack(self.binary_output) def calc_crc(self): crc = 0 for sym in self.binary_output: crc = crc ^ int(sym) return crc def pack_data(self): return b"" class ST_GW_ACTIVATE_SCENE_REQ (ST_GW_FRAME): def __init__(self, wSessionID = 0x1234, CommandOriginator = 'USER', PriorityLevel = 'User Level 2', bSceneID = 0, Velocity = 'DEFAULT'): ST_GW_FRAME.__init__(self, GW_ACTIVATE_SCENE_REQ) self.DataLength = 6 self.wSessionID = wSessionID self.bCommandOriginator = getIndex(dictCommandOriginator, CommandOriginator) self.bPriorityLevel = getIndex(dictPriorityLevel, PriorityLevel) self.bSceneID = bSceneID self.bVelocity = getIndex(dictVelocity, Velocity) def pack_data(self): ret = struct.pack(">H", self.wSessionID) ret += bytes([self.bCommandOriginator]) ret += bytes([self.bPriorityLevel]) ret += bytes([self.bSceneID]) ret += bytes([self.bVelocity]) return ret class ST_GW_PASSWORD_ENTER_REQ (ST_GW_FRAME): def __init__(self, Password): ST_GW_FRAME.__init__(self, GW_PASSWORD_ENTER_REQ) self.DataLength = 32 self.Password = Password def pack_data(self): binary_data = bytes(self.Password,encoding='ascii') binary_len = len(binary_data) ret = binary_data[:self.DataLength if binary_len > self.DataLength else binary_len] while binary_len < self.DataLength: ret += b'\x00' binary_len = binary_len + 1 return ret # =============================================================================== # Start script # =============================================================================== main() print("Finished")
ikillou Posté(e) le 3 novembre 2018 Signaler Posté(e) le 3 novembre 2018 Je précise que ce script fonctionne très bien sur mon Mac depuis IDLE. Je cherche des idées pour : quel est le meilleur endroit où poser le script afin de pouvoir le lancer depuis la HC2 avec le n° de la scène en paramètre. J'ai un raspberry dans un tiroir J'ai un mac mini qui pourrait faire serveur J'ai un Synology avec Python installé dessus Peut-être que @Steven, non sûr que Steven a une idée pour moi Merci d'avance pour vos idées.
Cardane Posté(e) le 3 novembre 2018 Auteur Signaler Posté(e) le 3 novembre 2018 @ikillou il doit y avoir des exemples sur le forum de scripts qui sont démarrés à partir de la HC2 sur un Syno, je vais regarder dès que j'ai un peu de temps. L'idéal pour moi est de convertir en LUA, mais comme je ne connais pas Python, faut déjà que je comprenne ce que ca fait... mais passer par un script serait déjà un moindre mal Par contre, si le script contient tes paramètres, je te conseille vivement de très vite changer le mot de passe du KLF car ils ont tous le même par défaut, donc si quelqu'un passe devant chez toi il n'aura aucun mal à ouvrir tes velux
Dragoniacs Posté(e) le 3 novembre 2018 Signaler Posté(e) le 3 novembre 2018 Je vois que ça avance Je vous encourage à trouver un système juste en lua, ça m'arrangerait bien Je ne peux pas vous aider, je ne connais pas Python et je débute encore en lua.....
ikillou Posté(e) le 3 novembre 2018 Signaler Posté(e) le 3 novembre 2018 il y a 48 minutes, Cardane a dit : @ikillou il doit y avoir des exemples sur le forum de scripts qui sont démarrés à partir de la HC2 sur un Syno, je vais regarder dès que j'ai un peu de temps. L'idéal pour moi est de convertir en LUA, mais comme je ne connais pas Python, faut déjà que je comprenne ce que ca fait... mais passer par un script serait déjà un moindre mal Par contre, si le script contient tes paramètres, je te conseille vivement de très vite changer le mot de passe du KLF car ils ont tous le même par défaut, donc si quelqu'un passe devant chez toi il n'aura aucun mal à ouvrir tes velux j'ai mis le mot de passe par défaut dans le script ici comme exemple, non, ce n'est pas le miens, t'inquiète... Démarrer le script depuis la HC2 n'est pas mon problème actuellement, ça viendra après , je cherche des idées pour héberger le script Python... Je me suis battu cet après-midi avec mon Syno qui ne veux pas accepter le module SSL... je vais continuer... pfff
Cardane Posté(e) le 4 novembre 2018 Auteur Signaler Posté(e) le 4 novembre 2018 Salut @ikillou... bon, j'ai essayé le script que tu m'as envoyé, mais ca ne marche pas... je n'ai pas de message d'erreur spécifique, mais rien ne se passe... j'ai 9 programmes enregistrés sur mon klf, mais aucun ne s'active en utilisant ce script.... tu as une idée ? le retour du du recv() est 00:01:00:04:00, mais je ne sais pas à quoi il correspond. Est-ce que tu as le même ?
ikillou Posté(e) le 4 novembre 2018 Signaler Posté(e) le 4 novembre 2018 Quand j'execute le script sur IDLE sur mon Mac, j'ai ce retour dans le shell : Send valid password Received: 00:04:30:01:00:35 Activate Scene with ID = 1 Received: 00:06:04:13:00:12:34:37 Finished >>> Par contre, sur syno, il ne fonctionne pas à cause de SSL. Le problème est de lui dire quel environnement Python il doit prendre, il prend souvent la version par défaut qui est la 2.7 sans SSL... J'essaie de comprendre comment fonctionne Python que je ne connais pas... Sinon, tu es sur PC ou Mac ? Moi, j'ai installé la dernière version de Python depuis leur site, et SSL fonctionne directement sur Mac, mais je n'ai pas testé sur PC...
ikillou Posté(e) le 4 novembre 2018 Signaler Posté(e) le 4 novembre 2018 Je viens de tester sur un PC Win10 avec Python 3.71 64bits que je viens d'installer. ça fonctionne la même chose... L'update du firmware a bien fonctionné sur ton KLF200 ? N'hésite pas à faire un reboot du KLF avant de faire des tests, car j'ai eu des problèmes de connexion et en fait après un reboot, c'était bon... pfff
Cardane Posté(e) le 4 novembre 2018 Auteur Signaler Posté(e) le 4 novembre 2018 oui, l'update du klf est ok, j'y ai accès via l'interface web comme avant. Moi je reçois en premier lieu : 00:04:30:01:01:34 et ensuite : 00:04:00:00:0c:08 je suis aussi sur Mac avec la dernière version d'IDLE, je vais vérifier si j'ai la dernière version de Python
Cardane Posté(e) le 4 novembre 2018 Auteur Signaler Posté(e) le 4 novembre 2018 même problème que toi sur Syno, je ne vois pas comment le diriger vers la version avec SSL
ikillou Posté(e) le 5 novembre 2018 Signaler Posté(e) le 5 novembre 2018 Il y a 9 heures, Cardane a dit : oui, l'update du klf est ok, j'y ai accès via l'interface web comme avant. Moi je reçois en premier lieu : 00:04:30:01:01:34 et ensuite : 00:04:00:00:0c:08 je suis aussi sur Mac avec la dernière version d'IDLE, je vais vérifier si j'ai la dernière version de Python Fais attention à ne plus être connecté dans l’interface web en même temps, car il y a toujours qu’une seule connexion simultanée...
ikillou Posté(e) le 10 novembre 2018 Signaler Posté(e) le 10 novembre 2018 Bon, je me suis remis dessus aujourd'hui. Cela fonctionne avec le script sur mon Mac serveur. Je lance le script python depuis un VD sur la HC2, ça fonctionne parfaitement. Sur le Synology, cela ne fonctionne toujours pas à cause du package SSL. Je suis en train d'installer un Raspberry Pi, on verra comment ça fonctionne... Je vous tiens au jus...
ikillou Posté(e) le 14 novembre 2018 Signaler Posté(e) le 14 novembre 2018 (modifié) Bon, j'ai fait un nouveau script python que j'ai mis sur un raspberry. Cela fonctionne nickel. Donc, j'ai fait une scène (ou un VD) sur la HC2 qui lance le script du raspberry en passant les paramètres IPKLF200, password, SceneID. Cela fonctionne très bien, on peut voir le retour du script dans un debug. @Cardane Si tu veux faire des tests, j'ai partagé mon raspberry sur le net, donc tu pourrais lancer mon script depuis le net. Il faudrait juste ouvrir un port TCP dans ton routeur afin que mon script puisse accéder à ton KLF... Le script python se trouve en fichier joint. Sur le raspberry, j'ai installé Apache configuré pour accepter les scripts cgi (c'est pour cela que le script doit se trouver dans le répertoire "cgi-bin"). Il se lance comme ceci : http://192.168.xxx.xxx/cgi-bin/klf200.py?IP=192.168.xxx.xxx&PW=velux123&ID=1 L'URL de la version web de mon script n'est dispo que via MP, si désirée Depuis un VD, on peut faire un bouton par action comme ceci : local ip_module = fibaro:get(fibaro:getSelfId(), "IPAddress") KLF200 = Net.FHttp(ip_module) response = KLF200:GET("/cgi-bin/klf200.py?IP=192.168.xxx.xxx&PW=velux123&ID=1") fibaro:debug(response) fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Label1.value", "Véranda 1 monté..."); Je reste à dispo pour tout complément d'information... klf200.zip Modifié le 14 novembre 2018 par ikillou script corrigé
Dragoniacs Posté(e) le 18 novembre 2018 Signaler Posté(e) le 18 novembre 2018 Est ce que cela pourrait fonctionner en direct sur la HC2 sans raspberry ?
ikillou Posté(e) le 18 novembre 2018 Signaler Posté(e) le 18 novembre 2018 Oui, mais il faut convertir le script Python en Lua, ce qui n'est pas évident... C'est pour cela que j'ai choisi la version simple pour l'instant... Avec les bons dévs qu'il y a ici, on devrait y arriver.
Dragoniacs Posté(e) le 19 novembre 2018 Signaler Posté(e) le 19 novembre 2018 Je lance un appel sur le forum alors @pepite ou bien @ADN182 ?
Cardane Posté(e) le 19 novembre 2018 Auteur Signaler Posté(e) le 19 novembre 2018 @Dragoniacs j'ai commencé quelque chose, mais loin, très loin d'être fini, et pour le moment je suis en déplacement, donc pas moyen de faire avancer le truc. En plus, le script réalisé par @ikillou fonctionne bien mais j'ai toujours un code d'erreur en retour. J'ai pas eu le temps de faire de nouveaux tests, c'est un problème de mot de passe, mais je ne vois pas. Pour l'instant ca tourne sur mon Mac et un Raspberry, mais ce n'est pas la solution optimale. En plus comme il faut faire du SSL, je ne sais plus si ca marche ou pas avec la HC2 ( @Lazer tu aurais l'info ? est-ce que maintenant on peut faire du SSL dans un VD et dans une scène ?) Comme je suis absent pour pas mal de temps, je ne pourrai m'y remettre que fin décembre... on ne sait jamais, comme cadeau de Noël
Lazer Posté(e) le 19 novembre 2018 Signaler Posté(e) le 19 novembre 2018 Regarde le VD de l'aspirateur Xiaomi de @ADN182 je crois qu'il utilise du SSL, ça peut être une source d'inspiration :
ADN182 Posté(e) le 19 novembre 2018 Signaler Posté(e) le 19 novembre 2018 (modifié) Hello, Je me souviens plus si j'utilise la library SSL dans mon VD Xiaomi mais pk ne pas faire un appel HTTPS depuis une scène. Il me semble que cela fonctionne. Ou alors peut-être reverse proxy http to https à voir si ça fonctionne J'utilse ce code qui fonctionne : fibaro:debug("start") -- Appel HTTPS local http = net.HTTPClient() http:request("https://api.darksky.net/forecast/xxxxxx/5.901,5.41?lang=fr&units=ca&exclude=minutely,hourly,flags", { success = function(response) if response.status == 200 then if response.data and response.data ~= "" then --fibaro:debug('Retour : '.. response.data) local jsonTable = json.decode(response.data) fibaro:setGlobal("DarkSkyJson", response.data) else fibaro:debug("Error : empty response data") end else fibaro:debug("Erreur : status=" .. tostring(response.status) .." Message : " .. tostring(response.data)) end end, error = function(err) fibaro:debug("Erreur : " .. err) end, options = { method = 'GET', timeout = 5000, } }) Modifié le 19 novembre 2018 par ADN182 1
Messages recommandés