defineVirtualDevice("projector_screen", { title: "Экран проектора", cells: { position: { type: "range", value: 0, min: 0, max: 100, readonly: false }, moving: { type: "switch", value: false }, open: { type: "pushbutton" }, close: { type: "pushbutton" }, stop: { type: "pushbutton" } } }); var moveTimer = null; var moveStartPos = 0; var moveStartTime = 0; var moveDirection = null; var moveDuration = 44; // секунд на полный ход function stopMovement() { dev["projector_screen/moving"] = false; dev["wb-mr6c_XX/K5"] = false; // заменить на реальные каналы dev["wb-mr6c_XX/K6"] = false; moveDirection = null; if (moveTimer) { clearTimeout(moveTimer); moveTimer = null; } } function startMovement(dir) { stopMovement(); moveDirection = dir; dev["projector_screen/moving"] = true; moveStartPos = dev["projector_screen/position"]; moveStartTime = Date.now(); if (dir == "up") dev["wb-mr6c_XX/K5"] = true; // открыть if (dir == "down") dev["wb-mr6c_XX/K6"] = true; // закрыть moveTimer = setInterval(function() { var elapsed = (Date.now() - moveStartTime) / 1000; var delta = (elapsed / moveDuration) * 100; var newPos = moveDirection == "up" ? moveStartPos + delta : moveStartPos - delta; newPos = Math.max(0, Math.min(100, newPos)); dev["projector_screen/position"] = newPos; if (newPos == 0 || newPos == 100) { stopMovement(); } }, 500); // обновление каждые 0.5 с } // кнопки управления defineRule("screen_open", { whenChanged: "projector_screen/open", then: function() { startMovement("up"); } }); defineRule("screen_close", { whenChanged: "projector_screen/close", then: function() { startMovement("down"); } }); defineRule("screen_stop", { whenChanged: "projector_screen/stop", then: function() { stopMovement(); } }); // слайдер defineRule("screen_set_position", { whenChanged: "projector_screen/position", then: function(newValue, devName, cellName) { if (dev["projector_screen/moving"]) return; // игнор, если движется var cur = dev["projector_screen/position"]; if (newValue > cur) startMovement("up"); else if (newValue < cur) startMovement("down"); } });