Antworten

Feb 10, 2025 - 17:47

Feb 10, 2025 - 18:35

Feb 11, 2025 - 12:13
Ich benutze persönlich um SwitchBot aus NEO zu schalten IP-Symcon, das über das NEO Plugin IP-Symcon an NEO angebunden ist.
Für die Ansteuerung aus IP-Symcon nutze ich das SwitchBot Modul sowie eine eigene SwitchBot Klasse für SwitchBot Szenen.
Das ist meine SwitchBot Klasse, die ich in IP-Symcon für SwitchBot Szenen benutze:
SwitchBot Klasse
class SwitchBotAPI {
private $api_token;
private $secret;
public function __construct($api_token, $secret) {
$this->api_token = $api_token;
$this->secret = $secret;
}
// Funktion zur Authentifizierung und Header-Erstellung
private function getHeaders() {
$nonce = $this->generateGUIDv4();
$t = time() * 1000;
$data = utf8_encode($this->api_token . $t . $nonce);
$sign = hash_hmac('sha256', $data, $this->secret, true);
$sign = strtoupper(base64_encode($sign));
return [
"Content-Type: application/json",
"Authorization: " . $this->api_token,
"sign: " . $sign,
"nonce: " . $nonce,
"t: " . $t
];
}
// Funktion zur Generierung einer UUID
private function generateGUIDv4() {
$data = random_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
// Allgemeine Funktion zur Ausführung eines API-Requests
private function sendRequest($url, $method = 'GET', $data = null) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
$headers = $this->getHeaders();
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if ($data !== null) {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response, true);
}
// Funktion zur Abfrage aller Geräte
public function getDevices() {
$url = "https://api.switch-bot.com/v1.1/devices";
return $this->sendRequest($url);
}
// Funktion zum Senden eines IR-Befehls
public function sendIRCommand($device_id, $command, $parameter = "default", $commandType = "command") {
$url = "https://api.switch-bot.com/v1.1/devices/$device_id/commands";
$data = [
"command" => $command,
"parameter" => $parameter,
"commandType" => $commandType
];
return $this->sendRequest($url, 'POST', $data);
}
// Beispiel zum Ein- und Ausschalten eines IR-Geräts
public function turnOn($device_id) {
return $this->sendIRCommand($device_id, "turnOn");
}
public function turnOff($device_id) {
return $this->sendIRCommand($device_id, "turnOff");
}
// **Szenen abrufen**
public function getScenes() {
$url = "https://api.switch-bot.com/v1.1/scenes";
return $this->sendRequest($url);
}
// **Szene ausführen**
public function executeScene($scene_id) {
$url = "https://api.switch-bot.com/v1.1/scenes/$scene_id/execute";
return $this->sendRequest($url, 'POST');
}
}
Mit diesem Skript lese ich in IP-Symcon sämtliche Szenen aus dem SwitchBot Hub aus und lege für jede Szene ein Skript an:
include('50605.ips.php'); // SwitchBot Klasse einbinden
// API Token und Secret aus IP-Symcon Variablen laden
$api_token = GetValue(57122); // API Token
$secret = GetValue(32014); // API Secret
// Kategorie-ID, unter der die Skripte abgelegt werden sollen
$category_id = 21254; // Deine Kategorie-ID in Symcon
$switchBot = new SwitchBotAPI($api_token, $secret);
// **Funktion zur Überprüfung, ob ein Skript existiert**
function getScriptIDByName($script_name, $category_id) {
$existing_scripts = IPS_GetChildrenIDs($category_id);
foreach ($existing_scripts as $script_id) {
if (IPS_GetName($script_id) === $script_name) {
return $script_id;
}
}
return false;
}
// **Funktion zum Erstellen eines Skripts, falls es nicht existiert**
function createScript($script_name, $script_content, $category_id) {
$script_id = getScriptIDByName($script_name, $category_id);
if ($script_id) {
echo "Skript '$script_name' existiert bereits. ID: $script_id\n";
return $script_id;
}
$script_id = IPS_CreateScript(0); // 0 = PHP-Skript
IPS_SetParent($script_id, $category_id);
IPS_SetName($script_id, $script_name);
IPS_SetScriptContent($script_id, $script_content);
echo "Skript '$script_name' erstellt. ID: $script_id\n";
return $script_id;
}
// **Universelles Szenen-Ausführungs-Skript**
$execute_scene_script_name = "SwitchBot Szene ausführen";
$execute_scene_script_content = <<include('50605.ips.php'); // SwitchBot Klasse einbinden
\$api_token = GetValue(57122); // API Token
\$secret = GetValue(32014); // API Secret
\$switchBot = new SwitchBotAPI(\$api_token, \$secret);
// Szene-ID aus dem aufrufenden Skript erhalten
\$scene_id = \$_IPS['SceneID'];
if (!\$scene_id) {
echo "Keine Szene-ID übergeben.";
return;
}
\$result = \$switchBot->executeScene(\$scene_id);
print_r(\$result);
?>
PHP;
$execute_scene_script_id = createScript($execute_scene_script_name, $execute_scene_script_content, $category_id);
// **Szenen-Abfrage-Skript**
$get_scenes_script_name = "SwitchBot Szenen abrufen";
$get_scenes_script_content = <<include('50605.ips.php'); // SwitchBot Klasse einbinden
\$api_token = GetValue(57122); // API Token
\$secret = GetValue(32014); // API Secret
\$switchBot = new SwitchBotAPI(\$api_token, \$secret);
// Szenen abrufen und ausgeben
\$scenes = \$switchBot->getScenes();
print_r(\$scenes);
?>
PHP;
$get_scenes_script_id = createScript($get_scenes_script_name, $get_scenes_script_content, $category_id);
// **Szenen abrufen und individuelle Skripte erstellen**
$scenes = $switchBot->getScenes();
if ($scenes && $scenes['statusCode'] === 100) {
foreach ($scenes['body'] as $scene) {
$scene_id = $scene['sceneId'];
$scene_name = $scene['sceneName'];
// **Skript für die spezifische Szene erstellen**
$scene_script_content = <<IPS_RunScriptEx($execute_scene_script_id, ['SceneID' => '$scene_id']);
?>
PHP;
createScript($scene_name, $scene_script_content, $category_id);
}
} else {
echo "Fehler beim Abrufen der Szenen: " . json_encode($scenes);
}
?>
Der API Token und das API Secret sind bei mir in einer Variable gespeichert. Bevor das Skript ausgeführt wird, muss eine Kategorie angelegt werden, unter der die Skripte abgelegt werden sollen. Dann muss die Objekt ID für die beiden Variablen, die Kategorie und die Klasse individuell im Skript angepasst werden, an die tatsächlichen Objekt IDs im Objektbaum, bevor das Skript erstmalig ausgeführt wird.
Anschließend importiere ich die erzeugten Szenen Skripte im AIO CREATOR NEO im Gerätemanager und kann dann jede einzelne Szene des SwitchBot Hub aus NEO aufrufen.
Einen SwitchBot Bot kann man auch ohne Szenen direkt über das SwitchBot Modul in IP-Symcon schalten und dieses dann als Gerät im AIO CREATOR NEO importieren.
Von
Hi, danke. Aber bei sowas bin ich raus. Davon habe ich keine Ahnung.
Neuen Kommentar hinzufügen