Last active
December 23, 2025 10:22
-
-
Save shahonseven/13c19549ebe70286ad8cfadd87762042 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| alias: Washing Machine State Notification | |
| description: "" | |
| triggers: | |
| - entity_id: | |
| - sensor.front_load_washer_run_state | |
| for: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 30 | |
| trigger: state | |
| conditions: [] | |
| actions: | |
| - choose: | |
| - conditions: | |
| - condition: and | |
| conditions: | |
| - condition: state | |
| entity_id: sensor.front_load_washer_run_state | |
| state: "-" | |
| - condition: state | |
| entity_id: sensor.front_load_washer_time_remain | |
| state: "0:00:00" | |
| sequence: | |
| - action: rest_command.set_geekmagic_theme | |
| metadata: {} | |
| data: | |
| theme: 5 | |
| default: | |
| - action: rest_command.set_geekmagic_theme | |
| metadata: {} | |
| data: | |
| theme: 3 | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: 30 | |
| - action: rest_command.update_geekmagic_washing_machine_status | |
| metadata: {} | |
| data: | |
| status: "{{ states('sensor.front_load_washer_run_state') }}" | |
| mode: single |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| rest_command: | |
| set_geekmagic_theme: | |
| url: http://192.168.0.139/set?theme={{ theme }} | |
| method: GET | |
| update_geekmagic_washing_machine_status: | |
| url: https://192.168.0.175/washing-machine-status-updater.php?status={{ status }} | |
| method: GET |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // 1. CHANGE: Set the content-type to jpeg | |
| header('Content-Type: image/jpeg'); | |
| // 2. Configuration | |
| $width = 240; | |
| $height = 240; | |
| $status = isset($_GET['status']) ? strtolower($_GET['status']) : 'idle'; | |
| $status = filter_var($status, FILTER_SANITIZE_FULL_SPECIAL_CHARS); | |
| // 3. Create the canvas | |
| $im = imagecreatetruecolor($width, $height); | |
| // 4. Define Colors | |
| $white = imagecolorallocate($im, 255, 255, 255); | |
| $bg_gray = imagecolorallocate($im, 240, 240, 240); | |
| $machine_w = imagecolorallocate($im, 250, 250, 250); | |
| $outline = imagecolorallocate($im, 100, 100, 100); | |
| $panel_gray = imagecolorallocate($im, 200, 200, 200); | |
| $black = imagecolorallocate($im, 0, 0, 0); | |
| // Status Specific Colors | |
| $idle_gray = imagecolorallocate($im, 50, 50, 50); | |
| $wash_blue = imagecolorallocate($im, 100, 180, 255); | |
| $rinse_blue = imagecolorallocate($im, 135, 206, 250); | |
| $spin_blue = imagecolorallocate($im, 50, 100, 200); | |
| $dry_orange = imagecolorallocate($im, 255, 140, 0); | |
| $detect_purple = imagecolorallocate($im, 147, 112, 219); | |
| $pause_amber = imagecolorallocate($im, 255, 191, 0); | |
| $done_green = imagecolorallocate($im, 100, 200, 100); | |
| $error_red = imagecolorallocate($im, 220, 80, 80); | |
| // Enable anti-aliasing | |
| imageantialias($im, true); | |
| // 5. Draw Basic Structure (Background & Body) | |
| imagefilledrectangle($im, 0, 0, $width, $height, $bg_gray); | |
| $m_x = 40; $m_y = 20; | |
| $m_w = 160; $m_h = 200; | |
| // Body | |
| imagefilledrectangle($im, $m_x, $m_y, $m_x + $m_w, $m_y + $m_h, $machine_w); | |
| imagerectangle($im, $m_x, $m_y, $m_x + $m_w, $m_y + $m_h, $outline); | |
| // Control Panel | |
| imagefilledrectangle($im, $m_x + 5, $m_y + 5, $m_x + $m_w - 5, $m_y + 40, $panel_gray); | |
| // Knob | |
| imagefilledellipse($im, $m_x + 30, $m_y + 22, 20, 20, $white); | |
| imageellipse($im, $m_x + 30, $m_y + 22, 20, 20, $outline); | |
| // 6. Determine Logic for Status | |
| $status_text = "IDLE"; | |
| $window_color = $idle_gray; | |
| $text_color = $done_green; // Default LED color | |
| // Visual Flags | |
| $show_bubbles = false; | |
| $show_spin_lines = false; | |
| $show_rain = false; | |
| $show_heat = false; | |
| $show_target = false; | |
| $show_pause = false; | |
| switch ($status) { | |
| case 'pause': | |
| $status_text = "PAUSE"; | |
| $window_color = $pause_amber; | |
| $text_color = $pause_amber; | |
| $show_pause = true; | |
| break; | |
| case 'detecting load level': | |
| $status_text = "LOAD"; | |
| $window_color = $detect_purple; | |
| $show_target = true; | |
| $text_color = $white; | |
| break; | |
| case 'washing': | |
| $status_text = "WASH"; | |
| $window_color = $wash_blue; | |
| $show_bubbles = true; | |
| break; | |
| case 'rinsing': | |
| $status_text = "RINSE"; | |
| $window_color = $rinse_blue; | |
| $show_rain = true; | |
| break; | |
| case 'fresh care': | |
| $status_text = "FRESH CARE"; | |
| $window_color = $spin_blue; | |
| $show_spin_lines = true; | |
| break; | |
| case 'spinning': | |
| $status_text = "SPIN"; | |
| $window_color = $spin_blue; | |
| $show_spin_lines = true; | |
| break; | |
| case 'drying': | |
| $status_text = "DRY"; | |
| $window_color = $dry_orange; | |
| $text_color = $dry_orange; | |
| $show_heat = true; | |
| break; | |
| case 'finished': | |
| $status_text = "DONE"; | |
| $window_color = $done_green; | |
| break; | |
| case 'error': | |
| $status_text = "ERR!"; | |
| $window_color = $error_red; | |
| $text_color = $error_red; | |
| break; | |
| case 'off': | |
| $status_text = "OFF"; | |
| $window_color = $idle_gray; | |
| break; | |
| default: | |
| $status_text = "IDLE"; | |
| $window_color = $idle_gray; | |
| break; | |
| } | |
| // 7. Draw The Door | |
| $center_x = $width / 2; | |
| $center_y = $height / 2 + 20; | |
| $door_radius = 100; | |
| $window_radius = 80; | |
| // Door Frame | |
| imagefilledellipse($im, $center_x, $center_y, $door_radius, $door_radius, $panel_gray); | |
| imageellipse($im, $center_x, $center_y, $door_radius, $door_radius, $outline); | |
| // Glass Window (Inner) | |
| imagefilledellipse($im, $center_x, $center_y, $window_radius, $window_radius, $window_color); | |
| // 8. Render Status Effects | |
| // EFFECT: Pause (Two Vertical Bars) | |
| if ($show_pause) { | |
| imagefilledrectangle($im, $center_x - 20, $center_y - 25, $center_x - 5, $center_y + 25, $white); | |
| imagefilledrectangle($im, $center_x + 5, $center_y - 25, $center_x + 20, $center_y + 25, $white); | |
| } | |
| // EFFECT: Detecting Load (Crosshair) | |
| if ($show_target) { | |
| imagesetthickness($im, 2); | |
| imageline($im, $center_x - 30, $center_y, $center_x + 30, $center_y, $white); | |
| imageline($im, $center_x, $center_y - 30, $center_x, $center_y + 30, $white); | |
| imageellipse($im, $center_x, $center_y, 25, 25, $white); | |
| imagefilledellipse($im, $center_x - 20, $center_y - 20, 4, 4, $white); | |
| imagefilledellipse($im, $center_x + 20, $center_y + 20, 4, 4, $white); | |
| imagesetthickness($im, 1); | |
| } | |
| // EFFECT: Washing Bubbles | |
| if ($show_bubbles) { | |
| for($i=0; $i<12; $i++) { | |
| $bx = rand($center_x - 30, $center_x + 30); | |
| $by = rand($center_y - 10, $center_y + 35); | |
| $bs = rand(5, 14); | |
| imagefilledellipse($im, $bx, $by, $bs, $bs, $white); | |
| } | |
| } | |
| // EFFECT: Rinsing (Falling water lines) | |
| if ($show_rain) { | |
| imagesetthickness($im, 2); | |
| for($i=0; $i<15; $i++) { | |
| $rx = rand($center_x - 30, $center_x + 30); | |
| $ry = rand($center_y - 30, $center_y + 30); | |
| imageline($im, $rx, $ry, $rx, $ry + 10, $white); | |
| } | |
| imagesetthickness($im, 1); | |
| } | |
| // EFFECT: Spinning (Motion Blur Arcs) | |
| if ($show_spin_lines) { | |
| imagesetthickness($im, 3); | |
| imagearc($im, $center_x, $center_y, $window_radius-20, $window_radius-20, 0, 120, $white); | |
| imagearc($im, $center_x, $center_y, $window_radius-20, $window_radius-20, 180, 300, $white); | |
| imagesetthickness($im, 1); | |
| } | |
| // EFFECT: Drying (Rising Heat Waves) | |
| if ($show_heat) { | |
| imagesetthickness($im, 2); | |
| $offsets = [-20, 0, 20]; | |
| foreach($offsets as $offset) { | |
| $start_x = $center_x + $offset; | |
| for ($y = $center_y + 20; $y > $center_y - 30; $y -= 5) { | |
| $x_shift = ($y % 20 < 10) ? 3 : -3; | |
| imageline($im, $start_x + $x_shift, $y, $start_x - $x_shift, $y - 5, $white); | |
| } | |
| } | |
| imagesetthickness($im, 1); | |
| } | |
| // 9. Glass Reflection | |
| imagearc($im, $center_x, $center_y, $window_radius - 10, $window_radius - 10, 200, 260, $white); | |
| // 10. Draw LCD Text | |
| imagefilledrectangle($im, $m_x + 80, $m_y + 12, $m_x + 140, $m_y + 32, $black); | |
| $font = 4; | |
| $font_width = imagefontwidth($font); | |
| $font_height = imagefontheight($font); | |
| $text_width = strlen($status_text) * $font_width; | |
| $text_x = ($m_x + 80) + ((60 - $text_width) / 2); | |
| $text_y = ($m_y + 12) + ((20 - $font_height) / 2); | |
| imagestring($im, $font, (int)$text_x, (int)$text_y, $status_text, $text_color); | |
| // 11. CHANGE: Output as JPEG with 90% quality | |
| imagejpeg($im, NULL, 90); | |
| imagedestroy($im); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // 1. Capture and Sanitize the Input | |
| // We use a default value if 'status' is not provided. | |
| $status = isset($_GET['status']) ? $_GET['status'] : 'idle'; | |
| $status = filter_var($status, FILTER_SANITIZE_FULL_SPECIAL_CHARS); | |
| // Important: urlencode ensures special characters don't break the URL | |
| $encodedStatus = urlencode($status); | |
| // 2. Define Configuration | |
| $sourceUrl = "http://10.0.1.175/?status={$encodedStatus}"; | |
| $destinationUrl = "http://10.0.1.174/doUpload?dir=%2Fimage%2F"; | |
| $uploadFileName = "washing_machine_status.jpg"; | |
| // Define a temporary path to store the downloaded file | |
| $tempFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $uploadFileName; | |
| // --- STEP 1: Download the Image --- | |
| $chDownload = curl_init($sourceUrl); | |
| $fp = fopen($tempFilePath, 'wb'); | |
| curl_setopt($chDownload, CURLOPT_FILE, $fp); | |
| curl_setopt($chDownload, CURLOPT_HEADER, 0); | |
| curl_setopt($chDownload, CURLOPT_FOLLOWLOCATION, true); | |
| // Execute download | |
| curl_exec($chDownload); | |
| $downloadHttpCode = curl_getinfo($chDownload, CURLINFO_HTTP_CODE); | |
| curl_close($chDownload); | |
| fclose($fp); | |
| if ($downloadHttpCode !== 200) { | |
| die("Error: Failed to download image from source. HTTP Code: $downloadHttpCode"); | |
| } | |
| // --- STEP 2: Upload the Image --- | |
| // Prepare the file for upload using CURLFile (Standard for PHP 5.5+) | |
| // The MIME type is set to image/jpeg | |
| $cFile = new CURLFile($tempFilePath, 'image/jpeg', $uploadFileName); | |
| // NOTE: You must verify the input name the receiving server expects. | |
| // It is often 'file', 'image', or 'data'. We are assuming 'file' here. | |
| $postData = [ | |
| 'file' => $cFile | |
| ]; | |
| $chUpload = curl_init(); | |
| curl_setopt($chUpload, CURLOPT_URL, $destinationUrl); | |
| curl_setopt($chUpload, CURLOPT_POST, 1); | |
| curl_setopt($chUpload, CURLOPT_POSTFIELDS, $postData); | |
| curl_setopt($chUpload, CURLOPT_RETURNTRANSFER, true); | |
| // Execute upload | |
| $response = curl_exec($chUpload); | |
| $uploadHttpCode = curl_getinfo($chUpload, CURLINFO_HTTP_CODE); | |
| if (curl_errno($chUpload)) { | |
| echo 'Upload Error: ' . curl_error($chUpload); | |
| } else { | |
| echo "Upload Complete."; | |
| } | |
| curl_close($chUpload); | |
| // --- Cleanup --- | |
| // Delete the temporary file | |
| if (file_exists($tempFilePath)) { | |
| unlink($tempFilePath); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment