Алиса и PLC из планшета
И вдумчивое отношение к инструкции
Мы не несём никакой ответственности за правильное или неправильное применение, или неприменение, и/или неспособность применить данное руководство.
Телефон вызова экстренных служб - 112.
Содержание
Преамбула
Практически у каждого из нас дома валяется один или даже несколько редко используемых гаджетов (планшет или старый смартфон), основной функцией которых является сбор пыли и медленная разрядка аккумуляторной батареи. В очередной раз наполняя энергией, разряженные до околокритического уровня аккумуляторы своих забытых гаджетов, мне захотелось сделать хотя бы один из них частью интеллекта своего, едва начавшего умнеть, дома. Выбор пал на планшет известной китайской компании, работающий под андроидом 10 версии (забегая вперёд - скажу, что сгодится совершенно любой гаджет на андроиде 8+) - ребёнок интерес к нему давно уже не проявляет и миллиарды китайских транзисторов, некогда обрабатывавшие около триллиона операций в минуту, день за днём забывают - каково это - иметь почётное в микроэлектронике звание полупроводников электрического тока.
Не желая ввергать уважаемого Читателя сего манускрипта в пучину грусти и тоски - процесс поиска хоть сколько-нибудь дружелюбного софта, способного вдохнуть в мой планшет дух Программируемого Логического Контроллера (он же - PLC), я опущу и представлю на суд - не побоюсь этого слова - (барабанная дробь) "бриллиант" юзер-фрэндли эфбиди программирования (с использованием функциональных блоков). Имея возможность подключения к умному дому Яндекса с возможностью управления любыми подключенными устройствами (любых производителей) мы получаем безграничные возможности создания самых гибких сценариев работы устройств умного дома!
Подопытные хомячки, любезно согласившиеся на бесчеловечные эксперименты, смогли пройти путь, описанный в данной статье чуть больше чем за 2 часа. Но у них были очень короткие лапки и электроды, прикреплённые к голове, на столько сильно им мешали, что на нескольких этапах мне пришлось им подсказывать - на какую кнопку необходимо нажать (не беспокойтесь - все хомячки выжили, получили вкусняшку и массу положительных эмоций от осознания своего интеллектуального роста). Но я уверен, что уважаемый Читатель будет проводить свои эксперименты в более комфортной обстановке и сможет справиться гораздо быстрее! Впереди нас ждёт несколько этапов авторизаций, которые из реальных объектов потребуют только Ваше имя, номер телефона и адрес Вашей электронной почты (звонить Вам не будут). Так что если у Вас есть пара часов свободного времени, заброшенный гаджет на андроиде 8+ и подключенные к Умному Дому Яндекса устройства, я предлагаю начать возноситься к новым знаниям! Внимательный Читатель, читающий даже блоки комментариев до последнего предложения пусть будет вознаграждён знанием о том, что в самом конце статьи есть ссылка на создаваемый здесь проект, с которым можно свериться, если что-то будет не получаться!
Амбула
Процесс разработки будет производиться на ПК под Windows 11 (можно использовать ОС Windows 7+). Скачать софт можно по ссылке (ссылка) - страница описания там очень длинная и ссылка находится в самом низу - большая зелёная кнопка с текущей версией софта. Устанавливаем его со всеми параметрами по умолчанию, запускаем и сворачиваем!
Теперь сформируем запрос на получение apk-файла для нашего планшета - для этого достаточно на сайте разработчика заполнить очень короткую форму (ссылка). Высылают apk достаточно оперативно и пока мы занимаемся разработкой проекта - он у нас уже будет точно!
Перед началом работы нам осталось выгрузить информацию о наших устройствах из умного дома Яндекса. Будем считать, что все нужные нам устройства уже подключены.
Список устройств
- Умная розетка (любого производителя), которой мы будем периодически заряжать наш планшет - мы же не хотим, чтобы умный дом лишился в один "прекрасный" момент такого замечательного помощника.
- Умная лампочка с возможностью менять как яркость, так и цвет (желательно от Яндекса - YNDX-00018) - с её помощью мы научимся легко просыпаться каждое утро! Любителям детальных мануалов - на всякий случай уточню - лампочку нужно воткнуть в какой-нибудь светильник, стоящий в комнате, в которой мы обычно спим.
Выгрузка данных
Если на каком-либо этапе выгрузки вы столкнётесь с проблемами - можете обратиться на страницу поддержки данного сайта - там всё детально разъяснено.
Открываем сайт, подготавливающий данные к выгрузке (ссылка), нажимаем большую черную кнопку:
Перед Вами откроется список всех устройств, подключенных к Вашему аккаунту Умного Дома Яндекса:
Ставим галочку в первой строке - перед словом "Устройства" и жмём зелёную кнопку "Скачать блоки". В результате у нас появится файл "SmartHomeIoT.culib", который мы будем использовать в недавно установленной и свёрнутой программе. Перед тем как вернуться в неё и продолжить нашу работу - сделаем последнюю манипуляцию в открытом сайте - перейдём в раздел "Токен" и нажмём кнопку "Копировать":
На какое-то время можно вставить токен в любой текстовый редактор, чтобы не потерять - нам он понадобится немного позже.
Создание проекта
Работу с сайтом мы завершили - можно смело его закрывать и возвращаться к свёрнутой программе. При первом запуске она попросит пройти простую процедуру авторизации, в которой достаточно указать реальный адрес своей электронной почты, на которую придёт ключ активации.
В верхнем меню нажимаем кнопку "Новый" - будет открыто диалоговое окно с выбором места сохранения нашего нового проекта - я сохранил свой проект в "Мои документы" и, поскольку я планирую на базе данного проекта сделать в будущем существенное расширение функционала своего умного дома - название проекту дал "MySmartHome". Желательно сразу же после создания проекта выбрать тип контроллера, который мы будем использовать - называется он NEON.
Пусть Читателя не смущает английский язык интерфейса скриншотов - мне, в силу специфики моей работы, комфортнее работать на англоязычном софте. Русская версия ничем кроме названий элементов не отличается!
Поскольку планшет будет "всегда" на зарядке (точнее - умной розеткой мы всегда его зарядим, когда нужно) - можем выбрать достаточно маленькое значение для пункта "Период исполнения" - изначально там стоит 300 мс - установим 20.
Для ускорения разработки в данном ПО предусмотрена возможность использования виртуального контроллера (функциональностью ничем не отличающегося от того, который будет впоследствии с помощью высланного apk-файла развёрнут на планшете). Для этого в верхнем меню выберем вместо "Ethernet" - "Virtual PLC" и нажмём кнопку "Подключиться".
Процесс подключения занимает всего пару секунд и в результате в нижней части экрана у нас должны периодически моргать индикаторы Tx и Rx, отображающие процесс обмена данными между ПЛК (в данном случае виртуальным) и Студией (ПО, в котором мы разрабатываем наш проект).
Подключение выгруженных блоков
Для начала работы с устройствами Умного Дома Яндекса нам необходимо загрузить файл, сформированный на этапе "Выгрузка данных" чуть выше. Для этого открываем раздел "Библиотека проекта", выделяем корневой каталог "Библиотека проекта" и нажимаем кнопку "Загрузить элемент".
Далее выбираем наш файл, жмем "Открыть" и разворачиваем корневой каталог "Библиотека проекта" - в нем должны появиться наши блоки:
Программа 1 - Зарядка планшета
Хотя основной задачей в рамках данной статьи является создание очень умного светильника - в первую очередь стоит позаботиться о том, чтобы планшет, помогающий светильнику стать умнее, однажды не разрядился! Для этого переходим в раздел "Структура проекта", выделяем корневой раздел и создаём две новых программы - "Системная" (как не трудно догадаться - в ней будут лежать важные системные блоки) и "Зарядка неона" (неон - название программного контроллера, который мы используем).
При создании программ - они автоматически открываются в основном окне Студии - каждая в своей вкладке:
Программа "Системная" будет состоять всего из одного блока и одной переменной - переключимся в её вкладку, откроем в Студии раздел "Библиотека проекта" и вынесем из него в свободное место блок "Access token" (перетянем (drag & drop)).
Теперь необходимо создать переменную, которая будет хранить токен для только что вынесенного блока - открываем раздел "Переменные" (в верхнем меню)
Выделяем корневой раздел списка переменных, нажимаем кнопку "Добавить переменную", задаём ей какое угодно имя (допускаются как русские, так и английские символы), обязательно как на скриншоте ниже: тип данных, тип памяти, галочка "Массив" и значение размерности массива, а в поле значение - скопируем тот токен, который мы получили на последнем шаге этапа "Выгрузка данных".
Обратите внимание - раздел переменных открылся новой вкладкой, с ней нам еще предстоит работа чуть позже.
Возвращаемся на вкладку программы "Системная", нажимаем правой кнопкой мыши в свободном месте программы, не далеко от блока "Access token", в появившемся меню выбираем пункт "Добавить переменную" и в открывшемся списке выбираем созданную переменную "Токен". Переменная будет добавлена в указанное место в программе - перенесём её таким образом, чтобы она находилась левее блока "Access token". Для передачи значения переменной в блок - необходимо соединить её выход с входом блока. Для этого нажмите левой кнопкой мыши по выходу переменной - появится черная линия, соединяющая указатель мышки и выход переменной - наведите мышку на вход блока и нажмите левую кнопку мыши еще раз. Должна образоваться связь между переменной и блоком.
С программой "Системная" мы закончили - займёмся непосредственно анализом уровня заряда аккумулятора планшета и управлением умной розеткой, отвечающей за зарядку планшета. Переходим в программу "Зарядка неона". Для начала вынесем блок "Зарядка Неона (R)" из Библиотеки проекта в открытую программу "Зарядка неона". Этот блок будет считывать с умной розетки текущий статус - включена она или нет. Для активации процесса чтения на вход Update блока необходимо подать сигнал True - сигнал должен быть не постоянным - необходимо отправлять импульс, который начнет процесс чтения. Для этого в основной библиотеке BASE существует триггер "PULSE GENERATOR". Библиотека BASE находится в правой части окна Студии - необходимо её раскрыть, в ней раскрыть каталог Триггеры и перетянуть блок "PULSE GENERATOR" в открытую программу, расположив блок слева от блока "Зарядка Неона (R)". Далее необходимо соединить выход PULSE и вход Update данных блоков, после чего нажать правой кнопкой мыши по входу PERIOD генератора импульсов и, выбрав пункт в выпавшем меню "Константа", задать нужную нам периодичность генерации импульсов в миллисекундах. Не стоит здесь указывать число меньше 1000 мс (1 секунда), если на это нет острой необходимости. Аналогично константой зададим вход EN генератора импульсов во включенное положение.
Для хранения прочитанных значений создадим 2 переменные: "Зарядка Онлайн" и "Зарядка Статус". Для этого вернёмся во вкладку переменных пользователя, выделим корневой раздел, в котором будем создавать переменные и создадим две переменные типа Bool в памяти типа RAM.
Вернувшись в программу "Зарядка неона", вынесем эти переменные (правая кнопка мыши - добавить переменную) и подключим к их входам выходы блока "Зарядка Неона (R)".
Переменная "Зарядка Онлайн" теперь хранит значение того - на связи ли розетка - эту переменную обязательно нужно учитывать при решении о необходимости включать или отключать её. Переменная "Зарядка Статус" отображает - включена ли розетка (значение можно использовать только если "Зарядка Онлайн" включена).
Далее необходимо вынести в программу "Зарядка неона" блок, читающий значение уровня заряда аккумулятора нашего планшета. Этот блок находится в библиотеке SYS (в правой части интерфейса Студии) - в каталоге Neon, блок называется "U Battery". Выносим его ниже связки пульс-генератора и блока чтения статуса розетки (программа в контроллере будет исполнятся последовательно одна за другой, начиная с верхних блоков - вниз - поэтому необходимо соблюдать логическую связь между операциями). На выходе этого блока будет отображаться заряд аккумулятора планшета в процентах (1-100).
Получив процент заряда аккумулятора нам необходимо принять решение о том - необходимо ли его заряжать или, если зарядка идет - пора ли прекратить зарядку. Будем считать, что уровнем заряда, на котором необходимо включать розетку, будет 30%. Для сравнения текущего заряда и критического воспользуемся блоком из библиотеки BASE - Операции сравнения - Byte - A < B. Выносим его в программу и соединяем выход блока "U Battery" с входом А блока сравнения. Вход В зададим константой - значение 30. Дополнительно вынесем (или скопируем (выделить с зажатым ctrl, а затем ctrl+c, ctrl+v) уже вынесенные выше) 2 переменные: "Зарядка Онлайн" и "Зарядка Статус". Логическим соединением получившихся трех значений будет следующее: если Зарядка Онлайн = True (в русской версии Вкл) И Зарядка Статус = False (Откл) И Заряд < 30%, тогда включаем розетку. За битовую операцию И отвечает блок из библиотеки BASE - Битовые операции - Логика - AND. Выносим его и соединяем с блоком сравнения и двумя переменными. Поскольку входов у блока AND изначально всего 2 - нам необходимо его расширить - эта операция допустима с входами, являющимися массивами (у блока AND вход - как раз массив). Жмем правой кнопкой мыши по входу блока AND, выбираем пункт меню "Кол-во элементов" и указываем значение 3. Подключаем входы следующим образом:
Обратите внимание - у входа Х.1 стоит белый кружок - признак инверсии входа, аналог логической операции NOT. Чтобы его установить - необходимо нажать по нужному входу правой кнопкой мыши и выбрать пункт "Инверсия".
Появление сигнала True (Вкл) на выходе блока AND будет свидетельствовать о необходимости включения умной розетки для зарядки планшета. Аналогичную логическую конструкцию необходимо построить и для отключения розетки - делать это будем при уровне заряда 100%, при этом обязательным условием должен быть статус розетки - незачем отключать уже отключенную розетку, равно как и незачем слать сигнал отключения на розетку, недоступную для управления (не Онлайн). Получается следующая конструкция:
Появление сигнала True (Вкл) на выходе данного блока AND будет свидетельствовать о необходимости отключения умной розетки. Для непосредственного управления розеткой необходимо использовать блок "Зарядка Неона (on_off.on W)". Сигнал на запись значения, также как и с чтением, должен быть не постоянным, а импульсным - это обязательно нужно будет учесть. Вынесем блок управления розеткой и блок генератора импульсов и соединим их также как и при чтении, только не будем включать вход EN генератора импульсов константой - им мы будем управлять с помощью не хитрой логики, которую опишем чуть позже. А пока вот что у нас должно быть в программе "Зарядка неона" в целом:
Поскольку блок управления розеткой должен записывать новое значение в розетку при возникновении сигнала на любом из блоков AND (8 и 13 на скриншоте выше), то достаточно их объединить блоком логической операции ИЛИ (блок OR в библиотеке BASE в разделе Логика), выход которого подать на вход EN генератора импульсов. Таким образом мы завершим всю логическую цепочку управления входом Write блока управления розеткой.
Логика управления входом Value сложнее не на много. Есть в библиотеке BASE интересный раздел Переключатели, в котором в свою очередь есть подраздел Bit - возьмём в нашу программу из него блок BOOL SWITCH BOOL. Этот блок хорош, когда нам нужно выбрать из двух булевых значений одно, в зависимости от условия. Если кратко, то этот блок отображает на выходе значение входа IN1, если вход SEL = True, в противном случае - на выход подаётся значение входа IN0 (в Студии присутствует достаточно подробная справка почти по каждому блоку - достаточно встать на его строку и нажать F1). В нашем случае - если необходимо включить розетку, то на выходе блока переключателя должен быть сигнал True, в противном случае - False. Общая конструкция управления блоком "Зарядка Неона (on_off.on W)" принимает следующий вид:
На этом работа с программой "Зарядка неона" завершена - было не сложно, правда? Не стесняйтесь перемещать в Студии блоки и переменные - связи при этом не разрываются, можете выставить их так, как вам нравится больше, учитываете только общее правило, что в целом блоки, находящиеся выше исполняются раньше блоков, расположенных ниже, а те, что расположены на одном уровне исполняются слева направо. Индексы над каждым блоком - как раз отображают порядок исполнения блоков, но до тех пор, пока мы не произвели сборку проекта (компиляцию) - индексы выставляются последовательно - в том порядке, в котором мы выносили в программу блоки и переменные. После сборки индексы выстроятся в реальном порядке исполнения - можем провести сборку и увидим как переиндексировал наши блоки компилятор:
Новый порядок исполнения:
Создадим программу "Управление светильником" и продолжим работу в ней.
Программа 2 - Управление светильником
В первую очередь вынесем в программу блок чтения состояния светильника "Светильник (R)", также как и у розетки на вход Update подключим генератор импульсов с параметрами, заданными константами. Для хранения и анализа прочитанных значений создадим 4 переменные (две из них типа Bool, две - Float, память для всех RAM).
Для управления режимом работы светильника необходимо манипулировать тремя его параметрами - яркость, температура и статус (вкл/откл). Поэтому нам дополнительно потребуются 3 переменные "Светильник Яркость Расчет", "Светильник Температура Расчет" и "Светильник Статус Расчет" (первые две - тип данных Float, последняя - Bool; тип памяти у всех троих - RAM). В простейшем случае, если светильник не планируется использовать ни для чего кроме "будильника", схема управления его яркостью (с использованием блока "Светильник (range.brightness W)") была бы следующей:
Здесь блок 9 ("А = В" библиотека BASE - Операции сравнения - Float) сравнивает расчётное значение яркости (его расчёт мы реализуем чуть позже) с прочитанным со светильника, блок 10 ("CHANGED" библиотека BASE - Операции сравнения - Float) сравнивает текущее рассчитанное значение с его же предыдущим значением и в случае, если оно изменилось - генерирует импульс на выходе, блок 11 ("RS" библиотека BASE - Триггеры) хранит полученное значение импульса с блока CHANGED до тех пор, пока расчётное значение яркости не станет равным прочитанному со светильника - и пока это условие действует блок генератора импульсов будет ежесекундно подавать команду на запись рассчитанного значения яркости в светильник.
Но данный способ будет ограничивать нас в использовании светильника для других нужд, поэтому сделаем логику записи значения яркости "немного" сложнее:
Так же, как и в примере выше блок "RS" хранит импульс от изменения расчётного значения яркости, пока она не совпадает с яркостью, прочитанной из светильника, но сигнал на запись нового значения не идет сразу, а лишь спустя 5 секунд (блок 14 - "TON" библиотека BASE - Таймеры) непрерывного состояния True и только при условии, что светильник на связи и "режим будильника" включен (необходимо создать еще одну переменную типа Bool в RAM памяти - "Будильник Статус"). Режим будильника мы будем отключать, если кто-то внес изменения в работу светильника, например вручную (через приложение Умного Дома Яндекс) изменил яркость светильника, его температуру света или просто выключил его. Поскольку в данном участке программы мы управляем яркостью - анализ ручного вмешательства здесь производится по яркости - если яркость светильника изменилась (блок 20 "CHANGED") и при этом нет активного задания на изменение яркости по расчёту (блок 13 "RS"), то значение переменной "Будильник Статус" необходимо перевести в False (блок записи 22). Для того, чтобы вынести переменную таким образом, как показано на скриншоте выше (блок 22) - необходимо в свободном месте программы нажать правой кнопкой мыши и в выпавшем меню выбрать строку "Добавить запись", после чего необходимо выбрать переменную (в данном случае - "Будильник Статус"). Константа False, которая подключается к блоку 22, выводится в программу похожим образом - правой кнопкой мыши в свободном месте - "Добавить константу", после чего необходимо дважды кликнуть по ней левой кнопкой, выбирать тип Bool и оставить чек-бокс без галочки.
Аналогичную структуру реализуем и для управления температурой - можно выделить с зажатой клавишей Ctrl все блоки и переменные, которые необходимо скопировать (все кроме блока "Светильник (range.brightness W)"), нажать Ctrl+C, Ctrl+V - блоки размножатся в программе вместе со всеми связями - их достаточно будет просто перенести ниже. После этого можно заменить скопированные переменные яркости на переменные температуры - для этого дважды кликните по скопированной переменной яркости и выберите соответствующую переменную температуры. После замены переменных выносим блок управления температурой ("Светильник (color_setting.temperature_k W)") и подключаем его также как и блок управления яркостью. В результате должна получиться следующая структура:
По аналогии со структурой яркости - если кто-то изменит температуру света во время работы будильника - режим будильника будет отключен.
Большинство умных ламп (в т.ч. YNDX-00018, которую использую я) включаются при изменении уровня яркости или температуры свечения, но нам необходимо предусмотреть и возможность использования других ламп - для которых необходимо отправлять сигнал на включение. В этом же участке программы реализуем отключение режима будильника для нашего светильника в случае, если пользователь сам выключил лампу (через приложение или голосовой командой):
Здесь мы ожидаем состояния, когда светильник находится в режиме будильника, но при этом он выключен (блок 47) и если данное состояние обнаружено и оно не проходит в течении 10 секунд - включаем светильник. И независимо от этого - если обнаруживается переход светильника из включенного состояния в выключенное (блок 44 "FE" библиотека BASE - Триггеры), то режим будильника отключается и в течении 10 секунд отправляется команда на отключение светильника. Последнее делается для того, чтобы компенсировать возможное "ошибочное" включение светильника сразу после его отключения, в случае если контроллер уже отправляет очередной запрос на изменение яркости или температуры, при получении которого светильник автоматически включится. Таким образом, если пользователь во время работы режима будильника вручную выключит светильник (через приложение), то он возможно автоматически включится обратно, но тут же будет автоматикой отключен. Момент не приятный, но, к сожалению, его не избежать - слишком велики задержки в коммуникации между устройством и управляющими им приложением и планшетом. Кроме того блоки 49 и 50 анализируют - не произошло ли отключение режима будильника, чтобы выключить светильник.
На этом управляющая часть программы окончена - осталось описать расчёт яркости и логику включения режима будильника. Для расчёта нам потребуются несколько дополнительных переменных - минимальное и максимальное значение яркости и температуры (с какой температуры свечения и яркости мы начнем и какой закончим), а также необходимо учесть рабочие, не рабочие и праздничные дни (мы же не хотим в субботу просыпаться в 6 утра).
В первую очередь - необходимо понять - рабочий день сегодня или выходной. В библиотеке BASE в разделе Дата/Время есть блок "GET DATE EXT" - у него есть выход WDAY, который несёт в себе день недели и значение 6 или 7 говорит о том, что сейчас выходной день. Почти всегда. Но, поскольку я хочу сделать свой дом настолько умным, чтобы мне не пришлось просыпаться в любой дополнительный праздничный день и чтобы будильник сработал и в воскресенье, если оно является рабочим, то придется реализовать "инверсию календаря".
Мы создадим массив дат, которые при наступлении инвертируют базовый статус рабочий/выходной (Пн-Пт/Сб-Вс). Создаём переменную "Инверсия календаря", тип данных Дата, тип памяти FRAM (энергонезависимая), устанавливаем галочку "Массив" задаем не слишком большое число (сильно далеко загадывать мы не можем, а переносов дат каждый год на самом деле совсем не много (я создаю массив из 32 элементов дат). Не закрывая окна создания переменной - сразу внесем значения праздничных будних и рабочих выходных - встаем в поле значения, нажимаем кнопку календаря:
Вносим следующие даты (взяты из производственного календаря на 2023 год):
- 01.05.2023
- 08.05.2023
- 09.05.2023
- 12.06.2023
- 06.11.2023
Можно добавить даты с 1 по 5 января 2024 года - сильно маловероятно, что они будут рабочими. Создадим переменную типа Bool в памяти RAM "Рабочий день" и вынесем нужные нам переменные и блоки следующим образом:
Расположение блоков в библиотеке BASE:
- Блок 58 ("A <= X <= B"): Операции сравнения - Byte
- Блок 60 ("A[..any..] = B"): Операции сравнения - Массивы - DateTime (У блока изменена размерность входного массива и отключена галочка Развернут на входе А)
- Блок 61 ("XOR") - Битовые операции - Логика
Теперь нам необходимо создать 7 переменных в энергонезависимой памяти (FRAM), в которых мы будем хранить следующие параметры режима будильника для нашего светильника:
- Минимальные яркость и температура - с которых светильник начнет разгораться
- Максимальные яркость и температура - до которых светильник будет разгораться и на которых он будет работать дальше до выключения
- Время на которое светильник должен быть в конечной (максимальной) стадии - это то время на которое заведен наш реальный будильник
- Интервал в минутах, в течении которого светильник разгорается от минимального до максимального состояния
- Интервал в минутах, в течении которого светильник остается в конечной стадии, дожидаясь отключения (автоматическое отключение, если вдруг мы его забыли выключить по какой-то причине)
Чтобы избежать слишком длинных наименований переменных, которые и так будут весьма длинными, и, поскольку речь идёт о режиме будильника для светильника - все переменные будут начинаться с сокращения "СРБ" и дальше будет указан параметр в названии переменной. Созданные переменные (обратите внимание на столбец со значениями - стоит их указать при создании переменных, чтобы они были "значениями по умолчанию" при первичной загрузке алгоритма - дальше их можно будет свободно менять):
Осталось лишь реализовать расчёт значений яркости, температуры и статуса режима будильник (вкл/откл). Расчёт будет несколько громоздким и непривыкшего к подобным логико-математическим конструкциям из функциональных блоков читателя может даже немного напугать, но поверьте, потратив несколько минут на изучение картинки расположения блоков и их связей, можно очень хорошо разобраться в данном расчёте. И всё-таки начнём с простого - реализуем для начала отключение светильника, если он горит в конечной точке режима дольше заданного в переменной "СРБ Интервал Горения" времени:
Расположение блоков в библиотеке BASE:
- Блоки 66 и 67: Дата/Время
- Блок 64: Математика - Int - Inline (Данный блок имеет не изменяемое количество входов, в отличии от похожего блока, располагающегося уровнем выше)
- Блок 68: Операции сравнения - Int
И, наконец, самый большой сегмент расчёта яркости и температуры света, а также необходимости включения режима будильника:
Расположение блоков в библиотеке BASE:
- Блоки 75 и 78: Преобразование типов
- Блоки 79, 80. 81. 83 и 93: Математика - Float
- Блоки 82 и 92: Аналоговые датчики - Физические величины
Давайте разберёмся в этом маленьком комке связей и блоков!
Первое, что стоит понять - ветка блоков 74-85-86-88 - на данном участке мы анализируем необходимость включения режима будильника. Он будет включен, если текущее время планшета меньше времени будильника (на выходе 74-го блока положительное число), но достаточное, чтобы войти в интервал разгорания (блок 77 переводит сохранённую настройку в минутах в миллисекунды, умножая их сначала на 60 и затем еще на 1000 - умножение реализована в два этапа для лучшей читаемости программы). Другими словами, например, если интервал разгорания задан в 30 минут и время будильника установлено на 6:00, то режим будильника включится ровно в 5:30.
Блоки 75 и 78 переводят значения из целочисленных в дробные, чтобы последующие математические операции учитывали и дробные части результатов для более точного расчёта. Забегая немного вперёд - обращу Ваше внимание на то, что блоки 89 и 94, являющиеся "Записями", а не обычными переменными - принимают в себя значения только если включен режим будильника. Это в свою очередь происходит только в том случае, если выход блока 74 положительный и он не больше, чем выход блока 77, хранящий интервал разгорания в миллисекундах. Таким образом, значение блока 75 при наших расчётах будет стремиться к нулю, а блок 78 всегда будет иметь максимально возможное для блока 75 значение (в значимом для данного сегмента временном интервале). В результате не хитрых математических операций блоков 79, 80 и 81 - мы получаем процент прохождения интервала разгорания (от 0 до 100), в соответствии с которым с помощью блоков расчета линейной зависимости аргументов с предельными значениями - мы находим нужное значение яркости и температуры света в данный момент времени. Найденные значения мы округляем по стандартным правилам округления и записываем их в переменные расчёта.
При расчёте мы полагаем, что яркость и температура должны увеличиваться линейно от минимального до максимального значения, заданных в соответствующих переменных.
Если умственных и душевных сил уважаемого читателя хватило, чтобы добраться до этой строки, то с радостью сообщаю, что работа с проектом полностью завершена! Мы можем произвести его сборку и загрузку в виртуальный контроллер и поиграть со значениями переменных как нам хочется, чтобы в живую увидеть результаты всех этапов расчёта. Для этого необходимо убедиться, что у нашего виртуального контроллера не вышел таймаут подключения (2 часа - если вышел, то будет доступна кнопка Подключиться - просто нажмите её и контроллер снова будет на связи), и нажать кнопку Сборка - Сборка, Загрузка и Опрос:
На этом этапе мы увидим действующие значения всех переменных и выходов блоков - для изменения значений переменных - достаточно дважды кликнуть по ним левой кнопкой мыши, ввести новое значение и нажать ОК. Попробуйте установить СРБ Время Будильника таким образом на текущее +20 минут - наш светильник должен будет включиться.
Если Вы хотите внести какие-то корректировки в проект, то обязательно нужно остановить опрос контроллера, нажав кнопку Отмена:
Теперь нас ждёт заключительный этап - осталось лишь установить уже присланный apk-файл в планшет, активировать контроллер и загрузить в него наш проект!
Установка APK в устройство
Свернём Студию с нашим замечательным проектом и откроем почту, которую указали при запросе apk-файла. В письме будет ссылка на скачивание архива (пароль указывают в самом письме), в котором и находится нужный нам файл (их на самом деле 2 - графический интерфейс настройки и непосредственно служба контроллера). Выгружаем содержимое архива на локальный диск нашего ПК, подключаем планшет (или любой другой гаджет на андроид 8+) в режиме обмена данными - переносим файлы apk в планшет (я создал в корне файловой системы планшета каталог АРК, в который файлы и сохранил).
Устанавливаем сначала службу (файл runtime) и графический интерфейс (файл gui), настраиваем службу (runtime) в соответствии с инструкцией, которую высылают ссылкой в письме (после слов "Как активировать" - ключевые этапы: дать доступ службе к файловой системе и местоположению, отключить ограничение фоновой активности, включить автозапуск и лично я на всякий случай "блокирую процесс от выгрузки" - если на экране многозадачности удерживать нажатым службу - появится меню, где я активировал замочек). После завершения инструкции по активации от разработчика - следует перезагрузить устройство перед первым использованием.
После загрузки дожидаемся успешного автоматического старта нашей службы, открываем ГУИ - в разделе Информация - смотрим адрес подключения - возвращаемся на ПК в Студию.
Если виртуальный контроллер подключен - отключаемся от него, выбираем подключение Ethernet, указываем адрес (если последний сегмент IP-адреса трехзначный, то знак двоеточия писать не нужно - он встанет автоматически - просто продолжайте писать номер порта):
Нажимаем Подключиться, выполняем сборку и загрузку алгоритма в проект (лучше с опросом, чтобы увидеть успешный результат).
ВСЁ! Теперь планшет за 30 минут до будильника (или какой интервал Вы указали) будет медленно разжигать светильник и при включении реального будильника - наш организм проснётся с невероятной лёгкостью, поскольку мозг за отведённое время адаптировался к искусственному рассвету и вполне созрел к тому, чтобы проснуться!
Любителям читов предлагаю созданный проект скачать с моего Яндекс-диска, только учтите, что он не содержит ни одного блока опроса умных устройств - эти блоки Вам придется самостоятельно подготовить, выгрузить и загрузить в проект по инструкции выше. Не забудьте в правильном порядке (перепроверьте!) подключить все связи к Вашим блокам и задайте корректное значение для переменной Токен - без него Ваши блоки не достучатся до Ваших устройств. Ссылка