Шторы Mr6c v2

Здравствуйте
вопрос такой
Mr6c v2 подключены фазные шторы к 1-2 каналу
включен режим штор
Как через Wb-engine/scripts сделать устройстро шторы?
я так понимаю логика там для фазореверсных моторов а у меня фазные

или подскажите путь как через HA прокинуть в УДЯ штору

Добрый день.

Вот тут не очень понятно, что имеете в виду?

Это несложно. Достаточно сконфигурировать устройство cover и описать его топики скриптом.


в этом скрипте фазореверсный мотор?!
в mr6c есть режим штор
через выключатель работают отлично
а как их прокинуть в УДЯ?

попробую если вернусь с результатом так как не программист )

Вот это, то что показываете на скриншоте - это что за интерфейс? Я не могу определить. Если это что-то стороннее, не относящееся к штатному ПО контроллера - то что?

Пробовал разные “автоматизации” - но, к сожалению не понравилась ни одна.
Тут принцип довольно простой - если хочется чтобы работало точно так как хочется - надо делать самому.
Поэтому использую HA Discovery через MQTT.
Публикую описание скриптом в брокер, для примера ворота, но сущность та же:

mosquitto_pub -r -h 127.0.0.1 -p 1883 -t "homeassistant/cover/my_cover/config" -m ' 
{
    "name": "Основные ворота",
    "command_topic": "homeassistant/cover/my_cover/set",
    "state_topic": "homeassistant/cover/my_cover/state",
    "position_topic": "homeassistant/cover/my_cover/position",
    "availability_topic": "homeassistant/cover/my_cover/avail",
    "unique_id": "my_cover_id",
    "device": {
        "identifiers": ["my_cover_device"],
        "name": "Ворота на улицу",
        "manufacturer": "DIY slide gate",
        "model": "Model 1",
        "sw_version": "0.9"
    },
    "payload_open": "OPEN",
    "payload_close": "CLOSE",
    "payload_stop": "STOP",
    "state_open": "open",
    "state_closed": "closed"
}'

И обрабатываю взаимодействие..
Описание - это просто сопоставление методов объекта сущности с реальными топиками.

Это wb-engine внизу скрипт с созданием теплых полов штор

вот мой скрипт

Шторы.js (7,6 КБ)

в HA появились шторы
с ВБ они ими можно управлять и в НА это отображается
Но в НА не работает открытие закрытие

Помогите разобраться

Это стороннее ПО, у меня в нем явно недостаточно компетенций.
Опишите пожалуйста какого типа объекты autodiscovery он создает, что и в кой топик записывается.

Движок не позволяет скачивать файлы js, вставьте код текстом, отформатировав как код пожалуйста.

var HA_PREFIX = "homeassistant/cover/";

// ===== КОНФИГУРАЦИЯ ШТОР =====
// Добавляйте новые шторы в этот массив
var CURTAINS = [
    {
        id: "curtain_3_1",
        name: "Штора 3_1",
        relay_up: "wb-mr6c_103/Curtain 1 Open",
        relay_down: "wb-mr6c_103/Curtain 1 Close",
        time_up: 12,    // время подъема в секундах
        time_down: 12    // время опускания в секундах
    },
];

// ===== ОСНОВНОЙ КОД =====

// Хранилище состояния всех штор
var curtainsState = {};

// Инициализация всех штор
CURTAINS.forEach(function(curtain) {
    var id = curtain.id;
    var name = curtain.name;
    
    // Создаем виртуальное устройство для каждой шторы
    defineVirtualDevice(id, {
        title: name,
        cells: {
            position: {
                type: "range",
                value: 0,
                min: 0,
                max: 100,
                readonly: false
            },
            state: {
                type: "text",
                value: "stopped",
                readonly: true
            }
        }
    });
    
    // Инициализируем состояние
    curtainsState[id] = {
        position: 0,
        timer: null,
        direction: null,
        config: curtain
    };
    
    // MQTT топики
    var cmdTopic = "wb/curtains/" + id + "/set";
    var posTopic = "wb/curtains/" + id + "/set_position";
    var stateTopic = "wb/curtains/" + id + "/state";
    var positionTopic = "wb/curtains/" + id + "/position";
    
    // Отправка discovery в Home Assistant
    setTimeout(function(curtainId, curtainName, cmdT, posT, stateT, positionT) {
        return function() {
            var discovery = {
                name: curtainName,
                unique_id: "wb_" + curtainId,
                device_class: "curtain",
                command_topic: cmdT,
                position_command_topic: posT,
                state_topic: stateT,
                position_topic: positionT,
                payload_open: "OPEN",
                payload_close: "CLOSE",
                payload_stop: "STOP",
                state_opening: "opening",
                state_closing: "closing",
                state_stopped: "stopped",
                position_open: 100,
                position_closed: 0,
                optimistic: false,
                retain: true
            };
            
            publish(HA_PREFIX + curtainId + "/config", JSON.stringify(discovery), 1, {retain: true});
            publish(positionT, "0", 1, {retain: true});
            publish(stateT, "stopped", 1, {retain: true});
        };
    }(id, name, cmdTopic, posTopic, stateTopic, positionTopic), 3000 + (CURTAINS.indexOf(curtain) * 1000));
    
    // Функция остановки движения
    function stopMovement(curtainId) {
        return function() {
            var state = curtainsState[curtainId];
            if (state.timer) {
                clearInterval(state.timer);
                state.timer = null;
            }
            
            dev[state.config.relay_up] = false;
            dev[state.config.relay_down] = false;
            state.direction = null;
            
            var newState = state.position === 100 ? "open" : (state.position === 0 ? "closed" : "stopped");
            dev[curtainId].state = newState;
            
            var stateTopic = "wb/curtains/" + curtainId + "/state";
            var positionTopic = "wb/curtains/" + curtainId + "/position";
            publish(stateTopic, newState, 1, {retain: true});
            publish(positionTopic, state.position.toString(), 1, {retain: true});
        };
    }(id);
    
    // Функция начала движения
    function startMovement(curtainId, target) {
        return function() {
            var state = curtainsState[curtainId];
            var config = state.config;
            
            target = parseInt(target);
            if (isNaN(target)) return;
            if (target < 0) target = 0;
            if (target > 100) target = 100;
            
            if (target === state.position) return;
            
            if (state.timer) {
                clearInterval(state.timer);
                state.timer = null;
            }
            
            state.direction = target > state.position ? "up" : "down";
            
            if (state.direction === "up") {
                dev[config.relay_up] = true;
                dev[config.relay_down] = false;
            } else {
                dev[config.relay_up] = false;
                dev[config.relay_down] = true;
            }
            
            var movementState = state.direction === "up" ? "opening" : "closing";
            dev[curtainId].state = movementState;
            
            var stateTopic = "wb/curtains/" + curtainId + "/state";
            publish(stateTopic, movementState, 1, {retain: true});
            
            var speed = (state.direction === "up" ? config.time_up : config.time_down) * 1000 / 100;
            
            state.timer = setInterval(function() {
                if (state.direction === "up") {
                    state.position++;
                    if (state.position > 100) state.position = 100;
                } else {
                    state.position--;
                    if (state.position < 0) state.position = 0;
                }
                
                dev[curtainId].position = state.position;
                
                var positionTopic = "wb/curtains/" + curtainId + "/position";
                publish(positionTopic, state.position.toString(), 1, {retain: true});
                
                if ((state.direction === "up" && state.position >= target) ||
                    (state.direction === "down" && state.position <= target)) {
                    var stopFunc = stopMovement(curtainId);
                    stopFunc();
                }
            }, speed);
        };
    }(id);
    
    // Обработка ползунка в WB
    defineRule("wb_slider_" + id, {
        whenChanged: id + "/position",
        then: function(newValue) {
            var pos = parseInt(newValue);
            var state = curtainsState[id];
            if (!isNaN(pos) && Math.abs(pos - state.position) > 2) {
                var moveFunc = startMovement(id, pos);
                moveFunc();
            } else {
                dev[id].position = state.position;
            }
        }
    });
    
    // Синхронизация состояния
    defineRule("sync_state_" + id, {
        when: function() { return true; },
        every: 30 * 1000,
        then: function() {
            var state = curtainsState[id];
            var positionTopic = "wb/curtains/" + id + "/position";
            var stateTopic = "wb/curtains/" + id + "/state";
            
            publish(positionTopic, state.position.toString(), 1, {retain: true});
            var newState = state.position === 100 ? "open" : (state.position === 0 ? "closed" : "stopped");
            publish(stateTopic, newState, 1, {retain: true});
        }
    });
    
    log("Initialized curtain: " + id);
});

log("=================================");
log("Curtain manager loaded - " + CURTAINS.length + " curtains configured");
log("=================================");

А для чего перепубликовывать целиком?

А что и куда публикуется при открытии/закрытии в HA?
То есть если в самом HA инициализировать - то в cmdTopic что пишется? Сконфигурированное в payload_*?
И где это обрабатывается (не нашел)?

повторюсь так как не программист

я в разные ИИ закинул свой скрипт ваш скрипт

вот это выдало

То есть - не сможете рассказать как работает код?
Я воспроизвел (то есть сделал стенд, поднял экзеемпляр HA, настроил связь). Изучил код, понял что нет реализации обработки командного топика.
И получается что это делал зря…

Получается могу сказать только минимум
движение и виртдев в вб
а дальше не смогу

поэтому и обратился за помощью

Я рекомендую дописать в код скрипта обработку публикуемых HA значений в командные топики. Сейчас оно не реализовано никак.
Техподдержка не пишет скрипты, это не входит в наш функционал. Ну и предлагать для использования код который может работать некорректно - это означает брать на себя ответственность за последствия его работы. То есть я могу предложить какой-то код, примером, указав что это демонстрация.

Заказной разработкой занимаются интеграторы.

Могу дать ссылки на документацию, помочь в том случае если ожидаемое поведение отличается от фактического.
Но выступать интегратором - нет, слишком рискованно.