[Store] Aspirateur Xiaomi

Discussion et échanges de scripts pour la box eedomus

Re: [Store] Aspirateur Xiaomi

Messagepar jluc2808 » 07 Nov 2023 09:36

je pense que vous êtes victimes de l'authentification à 2 facteurs, qui devaient être étendues fin 2022 et qui doit maintenant être obligatoire.

Le plugin eedomus ne le prend pas en charge
jluc2808
 
Messages : 511
Inscription : 30 Jan 2021

Re: [Store] Aspirateur Xiaomi

Messagepar fred54 » 08 Nov 2023 09:59

je pense aussi, personne n'a reussi a modifier le plugin ?
Eedomus +,google home, ifttt, ipx800v3+X880, karotz, Fibaro Roller Shutter 2, FGK-101, FGBS-001, FGFS-101, OWL 160, FGSS-001, THGR 122 NX, THN 132 N, mir:or, TCW181B-CM, RM pro, ecodevice, connexoon.
fred54
 
Messages : 150
Inscription : 05 Juin 2016

Re: [Store] Aspirateur Xiaomi

Messagepar ricercar » 14 Déc 2023 11:30

J'ai 3 aspirateurs xiaomi qui fonctionnent plutôt bien avec eedomus (du basique : démarrer le nettoyage).
De temps en temps, je perds la connexion sans explication. Après vérification, l'IP et le token sont bons.
J'ai trouvé un "truc" pour que ça marche à nouveau : effacer le plugin xiaomi sur la box et le recréer en simulant l'ajout d'un nouvel aspi.
Jusqu'ici ça a marché à tous les coups (plus d'une demi-douzaine de foix). Je n'ai aucune explication rationnelle à ce tour de passe passe, juste que ça fonctionne pour moi.
Ca vaut la peine d'essayer pour ceux qui auraient le mm problème de perte d'accès aux robots.
--John
plus qu'1 box eedomus/2, reste 207 périphériques zwave+zigbee+x10, plus de 200 règles à migrer vers une box où on ne se fout pas de moi
ricercar
 
Messages : 59
Inscription : 08 Août 2018

Re: [Store] Aspirateur Xiaomi

Messagepar Djay78 » 07 Mars 2026 06:43

Hello les amis,

Soyons clair , je ne connais RIEN de RIEN au PHP mais l'IA Claude d'Anthropic dans sa version de mars 2026 gratuite manifestement oui!!! :shock:

Alors voilà un script corrigé a minima avec moi :D : état et actions fonctionnent à nouveau, pour mes deux robots. Mes IPs et token sont inchangés.

Créez un fichier "Xiaomivacuumapp.php"
Aller dans Configuration / Ajouter ou supprimer un périphérique / Store eedomus / Gérer les scripts sur
Sélectionner" Xiaomivacuumapp.php" puis Envoyer

Enjoy et merci Claude bis!

----Xiaomivacuumapp.php----
<?php
# Copyright (C) 2018-2019 @Darboo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with This program. If not, see <http://www.gnu.org/licenses/>.
#
# Version : v1.5
# ChangeLog:
# 1.0 : version initiale
# 1.1 : Ajout commande status pour récupérer l'état
# 1.2 : Ajout Commande custom
# 1.5 : Ajout du retour pour les commandes custom
# Fix global $commandId manquant dans sdk_sendCommandRetrieve
# Fix null-bytes non retirés après mcrypt_decrypt (garbage XML)
# Fix initialisation robuste de $commandId

$adressIp = getArg('ip');
$token = getArg('token');
$action = getArg('action');

$adressPort = 54321;

// Convert hexstring (ex: "6A45D63E") in bin string
function sdk_hexbin($str){
$result = "";
for ($i=0; $i< strlen($str)/2; $i++){
$result.= chr(hexdec(substr($str,2*$i,2)));
}
return $result;
}

// Convert binstring in hexstring
function sdk_binhex($str){
$result = "";
for ($i=0; $i< strlen($str); $i++){
$result.= sprintf("%02x",ord(substr($str,$i,1)));
}
return $result;
}

// Transform binstring to display it
function sdk_bindisplay($str){
$result = "";
for ($i=0; $i< strlen($str); $i++){
$val = ord(substr($str,$i,1));
if (($val < 32) || ($val > 126))
$result.= sprintf("\x%02x",$val);
elseif (substr($str,$i,1) == '\\')
$result.= '\\\\';
elseif (substr($str,$i,1) == '\'')
$result.= '\\\'';
else
$result.= substr($str,$i,1);
}
return $result;
}

// Encrypt the data string
function sdk_encrypt($plaintext, $token){
$block = 16;
$pad = $block - (strlen($plaintext) % $block);
$padded_plaintext = $plaintext;
$padded_plaintext .= str_repeat(chr($pad), $pad);
$key = md5($token, true);
$iv = md5($key.$token, true);

// FIX: mcrypt ajoute son propre null-padding si la taille n'est pas un multiple de 16.
// On s'assure que $padded_plaintext est déjà un multiple exact → mcrypt ne touche plus au padding.
// On utilise MCRYPT_RIJNDAEL_128 avec un plaintext dont la taille est déjà alignée.
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $padded_plaintext, MCRYPT_MODE_CBC, $iv);
return $result;
}

// Remove PKCS7 padding after decryption
function sdk_unpad($str){
$pad = ord(substr($str, -1));
if ($pad < 1 || $pad > 16) return $str;
return substr($str, 0, strlen($str) - $pad);
}

// Send a command
function sdk_sendCommand($method, $params = "[]"){
global $deviceId;
global $commandId;
global $token;
global $differenceTimestamp;

// Construct Data
$commandId++;
$plaintext = '{"id": '.$commandId.', "method": "'.$method.'", "params": '.$params.'}'.chr(0);
// Do encryption
$ciphertext = sdk_encrypt($plaintext, $token);
// Contruct Message
$length = strlen($ciphertext) + 32;

$message = sdk_hexbin("2131"); // Magic Number
$message .= sdk_hexbin(sprintf("%04x",$length)); // length
$message .= sdk_hexbin("00000000"); //unknown
$message .= $deviceId; //deviceid
$message .= sdk_hexbin(sprintf("%08x",time() + $differenceTimestamp));; //stamp

// Calculate checksum
$checksumPayload = $message;
$checksumPayload .= $token;
$checksumPayload .= $ciphertext;
$checksum = md5($checksumPayload, true);

// Finish construct message
$message .= $checksum;
$message .= $ciphertext;
// Send Message
return sdk_sendUDPRequest($message);
}

// Send command with retry if it false and increment id
function sdk_sendCommandRetrieve($method, $params = "[]"){
global $commandId; // FIX: sans ce global, les increments n'affectaient pas le vrai compteur
$receiveData = sdk_sendCommand($method, $params);
if ($receiveData == ''){
$commandId+=2;
$receiveData = sdk_sendCommand($method, $params);
if ($receiveData == ''){
$commandId+=9;
$receiveData = sdk_sendCommand($method, $params);
if ($receiveData == ''){
$commandId+=49;
$receiveData = sdk_sendCommand($method, $params);
if ($receiveData == ''){
$commandId+=99;
$receiveData = sdk_sendCommand($method, $params);
}
}
}
}
return $receiveData;
}

// Send discovery request
function sdk_sendDiscovery(){
return sdk_sendUDPRequest(sdk_hexbin('21310020ffffffffffffffffffffffffffffffffffffffffffffffffffffffff'));
}

// Send UDP request
function sdk_sendUDPRequest($data){
global $adressIp;
global $adressPort;

//Create a UDP socket
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("Couldn't create socket: [$errorcode] $errormsg \n");
}
// Not available
// socket_set_timeout($sock,10);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0));
socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>5, "usec"=>0));
//open socket
$result = socket_connect($sock, $adressIp , $adressPort);
if ($result === false) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("socket_connect() failed: [$errorcode] $errormsg \n");
}
socket_write($sock, $data, strlen($data));

$buf = '';
$bytes = socket_recvfrom($sock, $buf, 1024, MSG_WAITALL, $name, $port);
socket_close($sock);
if ($bytes != ''){
return $buf;
}else{
return false;
}
}

// Proccess a command request
function sdk_doCommand($method, $params = "[]"){
global $deviceId;
global $differenceTimestamp;
global $token;
//Do Discovery
$receiveData = sdk_sendDiscovery();
$deviceId = substr($receiveData,8,4);
if ($deviceId != ''){
$deviceTimestamp = hexdec(sdk_binhex(substr($receiveData,12,4)));
$differenceTimestamp = $deviceTimestamp - time();
//Send Action
$receiveData = sdk_sendCommandRetrieve($method, $params);
// Keep only message bytes, to improve : check others bytes
$receiveData = substr($receiveData,32);

$key = md5($token, true);
$iv = md5($key.$token, true);
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $receiveData, MCRYPT_MODE_CBC, $iv);
// FIX: mcrypt ajoute des null-bytes en fin de buffer → on coupe au premier \0 après le JSON
$nullPos = strpos($result, "\x00");
if ($nullPos !== false) $result = substr($result, 0, $nullPos);
return $result;
}
}

$token = sdk_hexbin($token);
$commandId = intval(loadVariable('commandId')); // FIX: évite null/false
if ($commandId <= 0) $commandId = 1;

if ($action == 'start'){
sdk_doCommand("app_start");
}elseif ($action == 'pause'){
sdk_doCommand("app_pause");
}elseif ($action == 'home'){
sdk_doCommand("app_pause");
sdk_doCommand("app_charge");
}elseif ($action == 'zone'){
$zones = getArg('zones'); // ex [[x1,y1,x2,y2, iterations],[x1,y1,x2,y2, iterations]]
sdk_doCommand("app_zoned_clean", $zones);
}elseif ($action == 'findme'){
sdk_doCommand("find_me");
}elseif ($action == 'playsound'){
sdk_doCommand("test_sound_volume");
}elseif ($action == 'status'){
$result = sdk_doCommand("get_status");
echo jsonToXML($result);
}elseif ($action == 'custom'){
$command = getArg('command'); // ex [[x1,y1,x2,y2, iterations],[x1,y1,x2,y2, iterations]]
$params = getArg('params'); // ex [[x1,y1,x2,y2, iterations],[x1,y1,x2,y2, iterations]]
if ($params == ''){
$result = sdk_doCommand($command);
}else{
$result = sdk_doCommand($command, $params);
}
echo jsonToXML($result);
}elseif ($action == 'findid'){
$startId = getArg('start', false);
if (!empty($startId))
$commandId = $startId;
$receiveData = sdk_sendDiscovery();
$deviceId = substr($receiveData,8,4);
$deviceTimestamp = hexdec(sdk_binhex(substr($receiveData,12,4)));
$differenceTimestamp = $deviceTimestamp - time();
//Send Action
$receiveData = '';
$nbtry = 0;
while (($receiveData == '') && ($nbtry < 20)){
if ($nbtry != 0)
$commandId += 20;
$receiveData = sdk_sendCommand("test_sound_volume");
$nbtry++;
}
if ($receiveData == ''){
echo 'id not found';
}else{
echo 'id found:'.$commandId;
}
}elseif ($action == 'resetid'){
$commandId = 0;
}
saveVariable('commandId', $commandId);
?>
Onduleur APC | Aspirateur Xiaomi | Weather Underground | Mes temporisations | Nuki | Tuya SmartLife | Concaténateur | Sonos | Spotify | TV Samsung | Cozytouch2
Djay78
 
Messages : 9
Inscription : 30 Mai 2019

Précédent

Retour vers Scripts & Périphériques du store

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 117 invité(s)