Статья

Один из вариантов управления пылесосом 1C STYTJ01ZHM (dreame.vacuum.mc1808) из Home Assistant

Меня вполне устраивает основной принцип работы плагина пылесоса в приложении Mi Home, то есть выбор от одной до нескольких комнат и запуск пылесоса на "Уборку участка". При этом мощность всасывания и силу полива на тряпку я когда-то выставил в определенные значения и больше их не менял.

А поскольку мой "умный дом" уже больше года управляется HA, я решил соорудить что-то похожее в этой системе, чтобы пользоваться только одним приложением.

Многим известный компонент xiaomi_vacuum (https://github.com/Concentricc/xiaomi_vacuum) больше не поддерживается автором, поэтому я решил использовать альтернативную интеграцию Xiaomi Miot For HomeAssistant. Но сначала нам нужно добыть токен пылесоса.

Токен

Добавить устройство в интеграцию можно либо с помощью ввода логина и пароля от Mi аккаунта (т.е. через облако), либо локально (что предпочтительнее) через ввод токена устройства. Чтобы достать токен пылесоса, устанавливаем мод. приложение Mi Home от VEVS .https://www.vevs.me/. После ввода логина и пароля от Mi аккаунта, на странице, где расположены все устройства, нажимаем и удерживаем плитку с пылесосом, пока внизу экрана не появятся ярлыки действий.

Выбираем "Изменить имя". 
После этого откроется окно с информацией об устройстве, в т. ч. и токеном
Также токен можно найти, зайдя в плагин устройства - три точки - Дополнительные настройки - Информация о сети

Xiaomi Miot

GitHub - al-one/hass-xiaomi-miot: Automatic integrate all Xiaomi devices to HomeAssistant via miot-spec, support Wi-Fi, BLE, ZigBee devices.Automatic integrate all Xiaomi devices to HomeAssistant via miot-spec, support Wi-Fi, BLE, ZigBee devices. - GitHub - al-one/hass-xiaomi-miot: Automatic integrate all Xiaomi devices to HomeAssistant via miot-spec, support Wi-Fi, BLE, ZigBee devices.https://github.com/al-one/hass-xiaomi-miot

После установки компонента Xiaomi Miot одним из двух предлагаемых на github способом, заходим в "Настройки" - "Интеграции" и кликаем на кнопку "Добавить интеграцию". Находим в списке "Xiaomi Miot Auto" .

Выбираем локальный способ (с токеном).
В окне в соответствующие строки вписываем IP-адрес пылесоса, его токен и будущее имя. После успешного добавления, перезагружаем HA.
В системе появляется большое количество сущностей, связанных с пылесосом, которые можно будет использовать по своему усмотрению.

Принцип работы

У пылесоса есть два варианта уборки: "Зональная уборка" и "Уборка участка". Ниже приведены оба формата команды уборки. Зональная уборка:

yaml
Копировать
- service: xiaomi_miot.call_action
    data:
      entity_id: vacuum.alice_vacuum_mop
      siid: 18
      aiid: 1
      params:
        - piid: 1
          value: 19
        - piid: 21
          value: '-5975,-588,-5475,-88'
      force_params: true

Где во второй строке "value" прописаны координаты прямоугольной зоны уборки. Координаты пишутся в формате: X,Y вершина одного угла прямоугольника и X,Y вершина угла по диагонали. Отсчет координат (в мм) начинается в точке, где пылесос останавливается на секунду после выезда с докстанции. Направление оси X идет как раз к этой самой станции, а направление оси Y при этом идет влево (вверх на рисунке). См. рисунок.

Уборка участка:

yaml
Копировать
- service: xiaomi_miot.call_action
    data:
      entity_id: vacuum.alice_vacuum_mop
      siid: 18
      aiid: 1
      params:
        - piid: 1
          value: 18
        - piid: 21
          value: '{"selects":[[5,1,1,3,1]]}'
      force_params: true

Здесь в квадратных скобках прописаны: 5-номер комнаты; 1-либо доп. знакоместо для нумерации комнат, если не хватает первого (больше десяти), либо для количества повторов уборки, для другой модели пылесоса (наш вроде не поддерживает); 1-мощность всасывания (0-3); 3-сила полива на тряпку. Последняя цифра мною не изучена.

Как я писал вначале, меня интересуют только номера комнат, то есть только первая цифра.

Формат строки может быть и таким:

yaml
Копировать
value: '{"selects":[[5,1,1,3,1],[1,1,1,3,1],[3,1,1,3,1]]}'

В этом случае пылесос поедет убирать комнаты номер 5, 1 и 3, но последовательность уборки он определяет сам.

Таким образом в эту строку можно "запихнуть" от одной до всех комнат, что мне и нужно.

Реализация

Чтобы реализовать имитацию работы плагина пылесоса в Mi Home, создаем для каждой комнаты input boolean, и объединяем их в группу:

yaml
Копировать
input_boolean:
  bedroom_vacuum:
    name: "Спальня уборка"

  halfhallway_vacuum:
    name: "Полукоридор уборка"
  
  hallway_vacuum:
    name: "Коридор уборка"
  
  livingroom_vacuum:
    name: "Гостиная уборка"
  
  childrensroom_vacuum:
    name: "Детская уборка"
  
  kitchen_vacuum:
    name: "Кухня уборка"

group:
  all_rooms_for_vac_clean:
    name: All rooms for vacuum clean
    entities:
      - input_boolean.halfhallway_vacuum
      - input_boolean.hallway_vacuum
      - input_boolean.bedroom_vacuum
      - input_boolean.livingroom_vacuum
      - input_boolean.childrensroom_vacuum
      - input_boolean.kitchen_vacuum

Затем придумываем такой сенсор:

yaml
Копировать
sensor:
  select_rooms_for_clean:
    value_template: >
      {% set dfg = expand('group.all_rooms_for_vac_clean') | selectattr('state', 'eq', 'on')
      | map(attribute='entity_id') | list | join(',')
      | replace('input_boolean.halfhallway_vacuum','[2,1,1,3,1]')
      | replace('input_boolean.hallway_vacuum','[4,1,1,3,1]')
      | replace('input_boolean.bedroom_vacuum','[1,1,1,3,1]')
      | replace('input_boolean.livingroom_vacuum','[3,1,1,3,1]')
      | replace('input_boolean.childrensroom_vacuum','[5,1,1,3,1]')
      | replace('input_boolean.kitchen_vacuum','[6,1,1,3,1]') %}
        {"selects":[{{dfg}}]}
    friendly_name: "Выбранные комнаты для пылесоса"
    icon_template: mdi:vacuum

Он просматривает нашу группу на предмет включенных input boolean, затем забирает их названия, записывает их в строку, разделяя запятой, и, наконец, заменяет каждое имя в списке соотвестовующим набором цифр в квадратных скобках. Т.е. если у нас кухня - это комната 1, то активный input boolean "Кухня" будет заменен строкой [1,1,1,3,1] и так далее.

На выходе к набору цифр в скобках добавляются недостающие знаки для формирования полноценной строки. После перезагрузки HA появляется сенсор, формирующий нужную нам строку:

sensor.select_rooms_for_clean

Пишем скрипт, в который закидываем значение нашего датчика.

yaml
Копировать
clean_select_rooms:
  alias: Убрать выбранные комнаты
  sequence:
  - service: xiaomi_miot.call_action
    data_template:
      entity_id: vacuum.alice_vacuum_mop
      siid: 18
      aiid: 1
      params:
        - piid: 1
          value: 18
        - "{{ {'piid':21, 'value': states('sensor.select_rooms_for_clean') } }}"

В принципе, после этого достаточно вывести наши булеаны в интерфейс и всё будет работать.

Дополнитльно я написал автоматизацию, которая сбрасывает булеаны после окончания уборки:

yaml
Копировать
automation:
  - alias: 'reset_select_rooms'
    id: Reset select rooms
    trigger:
      - platform: state
        entity_id: vacuum.alice_vacuum_mop
        to: 'docked'
    condition: []
    action:
      - service: input_boolean.turn_off
        entity_id:
        - input_boolean.halfhallway_vacuum
        - input_boolean.hallway_vacuum
        - input_boolean.bedroom_vacuum
        - input_boolean.livingroom_vacuum
        - input_boolean.childrensroom_vacuum
        - input_boolean.kitchen_vacuum

Ну и наконец, делюсь идеей оформления карточки пылесоса. Поскольку моя цель была симитировать базовую функцию плагина Mi Home, я решил сделать нечто похожее. По виду - очень на любителя. При создании карточки, использовался один из множества мануалов по оформлению интерактивного 3д плана помещения для HA, поэтому нет смысла подробно его здесь описывать. В двух словах:

Создаем фоновый рисунок квартиры
Создаем рисунки каждой комнаты в отдельности
Создаем рисунки каждой отмеченной комнаты в отдельности (я сменил яркость и добавил галочки в кружочках)
Создаем рисунок прозрачного квадрата, который будем располагать примерно в центре каждой комнаты (для удобства, лучше дополнительно создать такой же квадрат, только с цветом, чтобы удобно было размещать, потом в эти координаты вставляем вместо цветного квадрата прозрачный)
Закидываем все рисунки в папку WWW

Дальше - код в lovelace.

Приведу пример кода для фона и одной комнаты:

yaml
Копировать
- title: Vacuum
    # path: floorplan
    # panel: true
    icon: mdi:vacuum
    cards:
      - type: picture-elements
        image: /local/plan_for_vacuum_3.png ###### План квартиры #######
        elements:
          - type: image ################ Спальня #################
            entity: input_boolean.bedroom_vacuum
            tap_action: none
            hold_action: none
            state_image:
              "on": /local/bedroom_check.png
              "off": /local/bedroom.png
            style:
              top: 50%
              left: 50%
              width: 100%
          


################### Кнопки помещений ###################
              
          - type: image ################ Кнопка спальни #################
            entity: input_boolean.bedroom_vacuum
            tap_action:
              action: toggle
            state_image:
              "on": /local/white_square.png
              "off": /local/transparent_square.png
            style:
              top: 71%
              left: 16%

Остальные иконки и показания датчиков ничего особенного из себя не представляют. Ниже приведены примеры оформления показания износа фильтра и кнопки пуск/стоп, в зависимости от состояния пылесоса. Если он на зарядке - запустится уборка выбранных участков, если стоит не на зарядке - снимется с паузы. Если ездит - встанет на паузу.

yaml
Копировать
################ Оставшиеся проценты фильтра #################
          - entity: sensor.dreame_mc1808_516a_filter_life_level
            style:
               font-family: Trebuchet MS
               font-size: 120%
               font-weight: bold
               left: 87%
               opacity: 1.0
               top: 58%
               transform: 'translate(0%,-50%)'
               color: blue
            type: state-label
           

          
          
          - type: conditional
            conditions:
              - entity: vacuum.alice_vacuum_mop
                state_not: "cleaning"
              - entity: vacuum.alice_vacuum_mop
                state_not: "docked"
            elements:
              - type: state-icon
                tap_action:
                  action: call-service
                  service: vacuum.start
                  service_data:
                    entity_id: vacuum.alice_vacuum_mop
                  confirmation: true
                entity: vacuum.alice_vacuum_mop
                icon: mdi:play
                style:
                  top: 92%
                  left: 40%
                  --mdc-icon-size: 40px
                  
          - type: conditional
            conditions:
              - entity: vacuum.alice_vacuum_mop
                state: "docked"
            elements:
              - type: state-icon
                tap_action:
                  action: call-service
                  service: script.clean_select_rooms
                  confirmation: true
                entity: vacuum.alice_vacuum_mop
                icon: mdi:play
                style:
                  top: 92%
                  left: 40%
                  --mdc-icon-size: 40px
                  
          - type: conditional
            conditions:
              - entity: vacuum.alice_vacuum_mop
                state: "cleaning"
            elements:
              - type: state-icon
                tap_action:
                  action: call-service
                  service: vacuum.pause
                  service_data:
                    entity_id: vacuum.alice_vacuum_mop
                entity: vacuum.alice_vacuum_mop
                icon: mdi:pause
                style:
                  top: 92%
                  left: 40%
                  --mdc-icon-size: 40px

На этом заканчиваю свою первую статью. Прошу сильно не ругать.


Статья очень хорошая, продолжай творить!
Спасибо.
Алексей, расскажи пожалуйста подробней о координатах комнат ( как их вычислить).
Вопрос, видимо, про номера комнат, а не про координаты, если что, уточни.

В приложении Mi Home, когда карта нарисована и комнаты подписаны, то им всем присвоен номер (первая цифра в квадратных скобках при "уборке участка" [1,1,1,3,1]).
Я в Хоум Ассистант поочередно запустил службу, меняя первую цифру в квадратных скобках.
Записал номера соответствующих комнат, куда он при этом поехал.

- service: xiaomi_miot.call_action
data:
entity_id: vacuum.alice_vacuum_mop
siid: 18
aiid: 1
params:
- piid: 1
value: 18
- piid: 21
value: '{"selects":[[1,1,1,3,1]]}'
force_params: true


...
value: '{"selects":[[2,1,1,3,1]]}'
...
value: '{"selects":[[3,1,1,3,1]]}'
...
value: '{"selects":[[4,1,1,3,1]]}'

и так далее.


Можно другим способом, подсмотреть код команды в файле в телефоне, но я этим не пользовался.
Собственно, способ описан Никитой Романенко на этом же сайте:

https://sprut.ai/article/priruchi-home-assistant-pylesos-upravlenie-interaktivnaya-karta-uvedomleniya

Этим способом можно увидеть и координаты "зональной уборки", как у него в примере, и номер комнаты в строке с "select...", если дашь команду "уборка участка" (тыкнуть по комнате и нажать "старт").
Спасибо за статью, давно искал верные параметры для этой интеграции. На mb1808 подходят, все отлично работает.
Рад, что статья оказалась полезной.
Интересно было ещё посмотреть на примеры связки всего этого дела с cloud map extractor + vacuum map card ( карта ещё в доработке у автора под эти пылесосы, но уже проверил, работает отлично)
Есть плагин для реализации карты https://github.com/PiotrMachowski/lovelace-xiaomi-vacuum-map-card где все это можно сделать сильно проще) Работает в связке с этим https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor (обратите внимание, что в мастере нет поддержки пыликов dreame*, она пока только в ветке https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor/tree/dreame_support)
а у вас получилось сделать множественный выбор комнат через карточку и запуск действий? можно работающий пример если есть, пожайлуста?
В скрипте пытаюсь сормировать строку с параметрами как вас в примере ('{"selects":[[5,1,1,3,1],[1,1,1,3,1],[3,1,1,3,1]]}'), но массивы значений формирую предвательно в своей переменной. на выходе получаю тачно такую же строку параметров, но сервис не отрабатывает. случайно не сталкивались с такой проблемой?
Когда настраивал синтаксис датчика в редакторе шаблонов в HA, строка формировалась нормально, но, когда дело дошло до автоматизации, оказалось, что система в конечную строку добавляет кавычки и, соответственно сервис "xiaomi_miot.call_action" не отрабатывает. Это можно было увидеть в журнале автоматизации. Я чего только не перепробовал, и убирал кавычки и добавлял тэги... Потом обратился на форум HA communuty, там мне посоветовали вместо кода:

params:
- piid: 1
value: 18
- piid: 21
value: "{{states('sensor.select_rooms_for_clean')}}"

Вписать:

params:
- piid: 1
value: 18
- "{{ {'piid':21, 'value': states('sensor.select_rooms_for_clean') } }}"

Это сработало. Может у вас что-то похОжее?
Да, не исключено! Спасибо за совет, попробую!
Сработала в итоге похожая, но немного другая конструкция:
params: >-
[
{
"piid": 1,
"value": 18
},
{
"piid": 21,
"value": "{\"selects\":[{{rooms}}]}"
}
]
Еще вопросик возник: а какие в теории параметры надо слать на пылесос чтобы сменить уровень воды и режим работы (скорость)?
Насколько я помню, когда я экспериментировал с библиотекой MIIO , с помощью которой общаются устройства "Xiaomi", во время команды на уборку замена чисел в скобках, кроме первой (которая определяет номер комнаты), не давала результата. Там третья цифра - мощность всасывания, а четвертая - сила полива. Я их менял, но пылик ехал убирать с предустановленными значениями мощности и полива. Подозреваю, что этот формат передачи инструкции пыликам универсальный, а у нашей модели не всё задействовано (она же первая из подобных). Могу ошибаться, конечно. Тем не менее мощность и полив можно сменить командой заранее. А значит в сценарии можно последовательно послать две или три команды, сначала преднастройки полива и всасывания, а потом старт уборки комнат. Примеры привожу. Мощность проверял. Работает. Воду надо, наверно, с вставленным баком проверять. (После строки 'data' у следующих строк по два пробела вначале. Сайт код ломает)

service: xiaomi_miot.set_miot_property
data:
entity_id: vacuum.alice_vacuum_mop
siid: 18
piid: 6
value: 1 # (0-3) - мощность
____________________________________________

service: xiaomi_miot.set_miot_property
data:
entity_id: vacuum.alice_vacuum_mop
siid: 18
piid: 20
value: 3 # (1-3) - полив воды
вот как-раз отдельными командами и интересовало. спасибо! попробую заранее их менять, как в родном приложении, и отдавать их же текущие значения в скрипт уборки комнат.
Здравствуйте.

После добавления этого:

sensor:
select_rooms_for_clean:
value_template: >
{% set dfg = expand('group.all_rooms_for_vac_clean') | selectattr('state', 'eq', 'on')
| map(attribute='entity_id') | list | join(',')
| replace('input_boolean.halfhallway_vacuum','[2,1,1,3,1]')
| replace('input_boolean.hallway_vacuum','[4,1,1,3,1]')
| replace('input_boolean.bedroom_vacuum','[1,1,1,3,1]')
| replace('input_boolean.livingroom_vacuum','[3,1,1,3,1]')
| replace('input_boolean.childrensroom_vacuum','[5,1,1,3,1]')
| replace('input_boolean.kitchen_vacuum','[6,1,1,3,1]') %}
{"selects":[{{dfg}}]}
friendly_name: "Выбранные комнаты для пылесоса"
icon_template: mdi:vacuum

HA ругается на конфиг:

Ошибка в конфигурации

Invalid config for [sensor]: required key not provided @ data['platform']. Got None. (See ?, line ?).

Что не так?


Добрый день!
Мой косяк. Выложил неполный код. Здесь скриншот оригинала.
Да, спасибо. Разобрался.
А вот эти параметры, что значат:
siid: 18
aiid: 1
params:
- piid: 1
value: 18
?

У меня пока пылесос ни как не реагирует.....
Это команды и параметры в рамках протокола Miio, на котором "общаются" устройства Xiaomi.
Если у вас пылесос не "dreame.vacuum.mc1808", параметры будут другими.
У меня vacuum.ijai_v2_1609_robot_cleaner Xiaomi Mijia LDS Vacuum Cleaner Robot 2 MJST1S
Где эти параметры брать?
Решение, описанное здесь, основано на интеграции "Xiaomi Miot For HomeAssistant". Подразумевается, что модель пылесоса должна поддерживаться самой интеграцией. Если поддерживается, то, методом проб и ошибок, наверно, можно добиться такого же функционала. К сожалению, я вашей модели у них не увидел.
Ссылку на список моделей привожу. Там же ссылки на параметры конкретной модели можно найти.
https://home.miot-spec.com/s/vacuum
Ясно. Спасибо за ответ.


Нашел для своего пылесоса нужные параметры. Могу отправлять на уборку одиночных комнат. А вот на уборку нескольких комнат - не получается.

За основу взят ваш скрипт.
Скрипт clean_select_rooms не получает значения из сенсора select_rooms_for_clean.
Что не так?
Скорее всего проблема в формате посылаемой команды. Она у всех пыликов своя. Приведу пример команды на уборку двух комнат для С1 в приложении MI HOME:
{"id":1771,"method":"action","params":{"did":"292143855","siid":18,"aiid":1,"in":[{"piid":1,"value":18},{"piid":21,"value":"{\"selects\":[[4,1,1,1,1],[3,1,1,1,1]}"}]}}.
Главная задача - сформировать такую строку со всеми "siid","aiid","piid","value"...
Какой формат команды для вашего пылесоса, я не знаю.


Я пробовал такой вариант:

В params указывал номер комнат через запятую и работало.

Поэтому, думаю, что если через states('sensor.select_rooms_for_clean') передать в скрипт, то должно работать.
Но в скрипт состояние states('sensor.select_rooms_for_clean') не передаётся =(
Я бы сравнил фактические отработки работающего и неработающего скриптов в "Трассировках". Наверняка дело в какой-нибудь дополнительной пунктуации, которую формирует интеграция при выполнении скрипта. Если почитаете комментарии выше, там был разговор о специфике передачи в скрипт данных с датчика.
Если не знаете, где:
Настройки -> Автоматизации и сцены -> Скрипты -> ищем свои скрипты -> напротив три точки -> Трассировка. И сравнить выходные данные при выполнении скриптов. Любые различия (кавычки и пр.) имеют значения.
Здравствуйте, удалось победить? У меня тоже затык на шаблоне(((


После обновления HA до версии 2022.11, перестали срабатывать "action: toggle", и визуально отмечаться комнаты при нажатии на прозрачные картинки. Вопросы разработчикам заданы, но пока они не отозвались. Решение нашли сами пользователи. В раздел "style" кнопок нужно добавить параметр "width:" (отвечает за диаметр пятна контакта для нажатия) со значением 1-100%, как кому удобно. Там, на экране ПК, виден диаметр пятна при нажатии. Пример кода в виде картинки привожу:
Здравствуйте! Только начал осваивать HA и возникают сложности во многом, можете подсказать, весь код прописывается в "configuration.yaml" или в "Groups.yaml", "scripts.yaml", "sensor.yaml"?
На мой взгляд, удобно было бы разместить весь код в Паккадже.
https://www.home-assistant.io/docs/configuration/packages/
К сожалению, документация только на английском.
А вот у вас там в размышлениях, когда вы разбирали код комнат. количество повторов уборки. Есть какая то команда или еще что нить, чтобы робот убирал например одну комнату 2 раза, потом ехал на вторую комнату или домой. ?
К сожалению, у этого пылесоса, по крайней мере на нынешней прошивке, количество уборок одной комнаты не настроить. Иначе это было бы в родном приложении. Мне тоже этого не хватает.
Не помню, пробовал или нет, в строке:
value: '{"selects":[[5,1,1,3,1],[1,1,1,3,1],[3,1,1,3,1]]}'
Поставить подряд два раза одну комнату. Может "сожрет"
value: '{"selects":[[5,1,1,3,1],[5,1,1,3,1]]}'
Позже попробую
P.S.
Проверил. Не сработало. Убрал один раз.
очень жаль.


Вдруг кому интересно будет.
После уборки мне удобно чистить пылесос в определенном месте квартиры (недалеко от мусорного ведра). При этом не хотелось таскать его с базы в это место. И придумал что-то вроде "костыля", чтобы он приезжал в одну точку для уборки. Для этого я определил участок 50 на 50см (меньшую зону не задать) в удобном для меня месте, и сделал сценарий, в котором, по нажатию кнопки, он едет на зонированную уборку, при этом в HA включается таймер на 41 секунду (экспериментально вычислено). После окончания отсчета следует команда "пауза".
В 99% он приезжает в одну точку, плюс/минус 20см. Иногда задевает шкаф в коридоре и останавливается, не доехав полметра.
После очистки жму "Домой" на пылике или даю команду Алисе, чтобы ехал на зарядку.


Еще я обратил внимание, что пылик периодически притормаживает, когда я обращаюсь к нему через интерфейс HA. Он, как будто спит, и не сразу начинает принимать команды. То есть, если мне надо убрать одну комнату, я выделяю ее в интерфейсе и жму "старт", но он с первого раза может не начать уборку. Не знаю, может это только у меня.
Чтобы его заранее "растормошить", я сделал автоматизацию, в которой, при выборе комнат уже идет посыл пылику (информация) о мощности всасывания и полива. И тогда, в момент нажатия кнопки "старт" он уже, что называется, на связи.
А такой еще вопросик.
я видел у других фото карточки, кроме как у вас расходных материалов, еще было типо сколько с последней уборке время прошло, зона последний уборки в м2 и тд.
эта инфа в родном приложение сразу сверху есть. можно ее как то в ХА?)
ДА и еще у меня мощность на китайском, немного не пофеншую по красоте, можно это как то исправить?
желательно с примером как это сделать)
А как понять что всё работает? я сделал всё как по инструкции, но пылесос убирается только в полной уборке, по комнатам не едет. как сделать так чтобы по комнатам ехал, выбрать комнаты и отправить на полную или как?
Добрый вечер, смогли решить данную проблему?

Вернуться назад
Вернуться назад