Блог о Gentoo и около-линуксовым штукам

9 января 2022 г.

Wireguard 'сервер' в OpenWRT

18:47 Опубликовал Дмитрий Исаенко , Нет комментариев

Сегодня настраиваем Wireguard через luci на OpenWRT чтобы ходить в домашнюю локальную сеть и дальше в интернеты. 

В первую очередь с андроедо-фона, так что на его примере и разберём. OpenWRT у нас версии 21.02.01. На старых (15ых, например) скорее всего беда, так как вряд ли в те времена в ядре была поддержка.
К сути!
Спрева заходим на http://openwrt. Далее "Система" -> Software", жмём "Update lists" и устанавливаем:
* wireguard-tools
* kmod-wireguard
* luci-app-wireguard
* luci-proto-wireguard
* qrencode
И локализацию заодно:
* luci-i18n-wireguard-ru

 

Утанавливаем, перезагружаем.
Заходим в "Сеть" -> "Интерфейсы"

Жмём "Добавить новый интерфейс". Название даём какое-угодно. Wireguard например, или wg.
Протокол выбираем "Wireguard VPN" (у меня эта опция в списке появился после перезагрузки).
"Устройство" − без изменений.
Жмём "Создать интерфейс" и открывается окно изменений-настроек.
В новом окне отмечаем "Запустить при загрузке".
Жмём "Сгенерировать ключ". Поле "Приватный ключ" теперь заполнено
"Порт для входящих соединений" ставим - 51820 (по-умолчанию именно он выделен для wireguard)
"IP-адреса" ставим 192.168.42.1/32 (тут я не особо разбирался почему надо указывать подсеть и почему бы не влепить /24).
"Не создавать маршруты" оставляем пустым.

Переходим в "Дополнительные настройки"
И.. в общем тут всё ок. Хотя я отключил делегирование IPv6 префиксов потому что оно не очень нужно =)

Далее "Настройки межсетевого экрана"
Тут в выпадающем меню объеденяем wireguard и lan в одну зону.

На вкладке "DHCP-сервер" можно отметить (оставить отмеченным?) "Игнорировать интерфейс".
"Настройки IPv6" по прежнему не интересно.
Сохраняем, применяем. Пока здесь всё.

Настроки Firewall

Открываем "Сеть" -> "Межсетевой экран"

Заходим во вкладку "Traffic Rules" (или как она называется, если ставить локализацию.. см. картинку).

Крутим вниз, жмём "добавить"
"Название" -  "WireGuard-Allow-Input" или "Kittens-jumps-over-the-rainbow"
"Протокол" - "UDP"
"Source zone" -  "WAN"
"Зона назначения" - "Устройство (ввод)"
"Порт назначения" - "51820"
"Action" - "ACCEPT"
Сохраняем, применяем


Настройки Android устройства здесь и там

Заходим в "Состояние" -> "WireGuard"
Жмём "Показать/скрыть QR-код". Для этого мы и ставили пакет "qrencode".
Берём телефончик. Ставим Wireguard на андроед. Запускаем, жмём "+" -> "Сканировать QR-код" и.. сканируем!
Вводим название туннеля.
Открываем только что созданную запись и жмём кнопку правки вверху
Вводим адрес в блоке "Интерфейс": 192.168.42.3/32 (или 192.168.42.4 или 192.168.42.254 или ещё какой. Его надо запомнить, чуть позже он нам пригодится)
Переходим к блоку "Пир"
Вводим адрес роутера OpenWRT на котором всё это настраивалось в поле "Конечная точка" и порт 51820.
Например example.com:51820
Жмём на поле "Публичный ключ" чтобы он скопировался.
Жмём сохранить.

Возвращаемся в интерфейс OpenWRT.
Вновь заходим а "Сеть"->"Интерфейсы"
Находм Wireguard в списке
Жмём "Изменить"
Переходим в последнюю вкладку "Узлы (peers)"
Жмём "Добавить узел (peer)"
Вводим "Публичный ключ" который мы скопирвали в телефоне. Сами придумайте как.. Лучше перепечатать. Хуже всего отправить себе письмом.
Отмечаем "Маршрутизировать разрешенные IP-адреса"
Указываем IP адрес в поле "Разрешенные IP-адреса" (тот же, что указан на клиенте в блоке "Интерфейс").
Сохраняем, применяем.

Дальше всё должно работать :)


26 февраля 2019 г.

NS-USBloader v0.2.2 [EN]

22:59 Опубликовал Дмитрий Исаенко , , 11 коммент.
New version of NS-USBloader released.
What's new? GoldLeaf support. And UI improvements of course. Actually I don't really like GoldLeaf since USB support is weak/unstable for now and have some bugs, so I would strongly recommend get TinFoil and use it for now.
Why v0.2.2? That's because I got some feedback regarding how v0.2 worked. So in v0.2.1 I changed a bit progress bar behaviour and in v0.2.2 fixed some dependency issues that didn't allow using it in macOS. Thanks to reddit users who helped me with this.
So as I learned, the requirements to use Java8+ is not good enough, and actually people have to get 8u60 or higher. It contains missed methods of the JavaFX elements.. and it's wired thing. Oracle decided to 'detach' JavaFX to separate project (openJFX) and in JRE/JDK 11 (for example) java code uses embedded libraries that are self-described and awesome by itself. But it's all just my thoughts.
Sooooooooo, new version. Here you go:
Yeah, new white theme. Disabled by-default but I like it =)

When I looked on GoldLeaf I asked myself 'WHY?' realized, that there is no way to transfer multiple files at once (this project is actively growth so maybe, in future they will add such feature). That's why table appeared. It's sort of limitation to leave ability for multiple files selection and in same time restrict their number for GoldLeaf. Restriction is useless (?) but possible for TinFoil.
Looking on it now, I see a lack of "select all/unselect all" checkbox on column level. Maybe it would be good to add it and set inactive when 'GoldLeaf' selected.
Also, obviously it should be great to add drag-and-drop files ability.. Anyway all these restrictions are non-critical.

Another thing added is settings storage. NS-USBloader can remember user settings such as selected backend application, theme, opened with NSP files. It uses internal Java's feature that bla-bla-bla create files/windows registry entry for application. As I know, in Linux file with settings located at ~/.java/.userPrefs/NS-USBloader/prefs.xml. In windows it's somewhere near HKEY_CURRENT_USER\SOFTWARE\... . No idea where is it on macOS. Somewhere in /Library I guess.

Well, this is all I wanted to tell.

https://github.com/developersu/ns-usbloader/releases

11 февраля 2019 г.

NS-USBloader [EN]

17:31 Опубликовал Дмитрий Исаенко , , 1 коммент.
Sooo, NS-USBloader. What is all about and how to use?
First of all, if you don't know what is 'Nintendo Switch' and 'tinfoil' just skip this article.
Otherwise, let's move on!
This application developed to replace tinfoil default python script (because it's python, it doesn't have GUI, I'm noob that script didn't worked for me returning OVERFLOW something-something).

Let's begin already!

First of all, go get JRE (Java runtime environment). And install it. The version you need it 8u60 or higher. If you're on mac, see section below (you will need JDK not JRE).
Oracle JRE (or JDK) is good. OpenJDK is good. Others, most likely, also should be good.

Download NS-USBloader JAR file from GitHub (should be in 'release' state): https://github.com/developersu/ns-usbloader/releases

Now, take a look where you are:

Situation: "I'm Windows user and never used/heard about python script for TinFoil"

Now go get Zadig. Open it.
Take you Switch.
Open TinFoil.
Select 'Title Managment'
Select 'USB Install NSP'
You will see next message (in Switch):
Waiting for USB to be ready...
Plug USB cord to your Switch and PC
You will see next message (in Switch):
Waiting for USB to be ready...
USB is ready. Waiting for header...
Open Zadig.
Click 'Options' → 'List All Devices'
Select in drop-down 'Nintendo Switch'
Select 'libusbK (v3.0.7.0)' in.. Here is the picture
Click 'Install Driver'
In the end driver should be installed.. somehow..

Verify: unplug USB cord and plug it in again. Take a look on 'Zadig'. 'Driver' field should be 'libusbK (v3.0.7.0)' instead of '(NONE)'.
You're good now.

Check next 'Situation'.

Situation: "I'm windows user and I already installed libusbK"

Start NS-USBloader (jar file) as regular application.
(If it doesn't work: open cmd.exe, type: java -jar C:\path\to\NS-USBLoader.jar)

That's all. You're all set.
BTW, do you wanna see screenshots? Scroll down then ( ^-^)

Situation: "I'm on Linux"

No special configuration needed if you're about to start this application from 'root' .
# java -jar /path/to/application/NS-USBloader.jar

If you want to use app as regular user, do next (as root):
# vim /etc/udev/rules.d/99-NintendoSwitch.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
# udevadm control --reload-rules && udevadm trigger
Done! Now you can start application from any user who is in the 'plugdev' groups. You should be there, and all linux-human-users should be there.

Also, did you know how to make file association for *.jar files in KDE? For opening them by double-clicking in Dolphin and so on.. Anyway, here is the picture of system settings. Take a look on 'Command field' in 'Application' tab.

Situation: "I'm on Mac"  

Double-click on downloaded JAR file and follow instructions to install Java JDK.
When installed and all security options set, just double-click on it, or:
# java -jar /path/to/application/NS-USBloader.jar
If you want to start it by clicking:
# sudo chmod +x filename.jar

Application work illustration

So after you opened tinfoil in 'USB Install NSP' mode, start application, click 'Select .NSP files' button.

Select files (multiple selection allowed)
Click 'Upload to NS'
Take your NS. Select what do you want to install like this:
In application you will see something like this after transfer finishes:

And in Switch:

P.S. BTW, you can't use application without graphical environment. (Tell me in comments if you need such feature.)

And that's all I have for you =)
Enjoy!

EDIT: other posts regarding NS-USBloader could be found here.

7 января 2019 г.

Пара слов о Gentoo, openJDK, JavaFX и idea

03:30 Опубликовал Дмитрий Исаенко , 9 коммент.
Сегодня разберёмся как с Gentoo поставить OpenJDK 11 или любой последней версии, настроить idea на работу с ней. Поставим и настроим JavaFX (openJFX SDK). Прикрутим её к IDEA и обозначим подводные камни при сборке всё-в-одном-jar для десктопного приложения используя Maven.

Итак, в списке доступных без плясок Gentoo Java VM есть icedtea (версии 8, т. е. условно тот самый openJDK 8) и страшно бесящий при обновлении oracle-jdk (его блобы нужно каждый раз качать с офф-сайта oracle и ложить в distfiles). OpenJDK как бы и доступен, но обёртки в виде 'eselect' прописывающие все полезные переменные окружения а-ля $JAVA_HOME спрятаны в USE-флаг 'gentoo-vm', который замаскирован. Если интересны подробности таких стрессов, можно почитать что пишут по этому поводу (даже) в самом ebuild:
$ vim -R /usr/portage/dev-java/openjdk/openjdk-11.0.1_p13.ebuild 
C openJFX вообще всё странно. Пакета нет, хотя в багзилле тикету пошел четвёртый год https://bugs.gentoo.org/547918. Intellij Idea традиционно обновляется один-два раза в год.. впрочем это уже другая печальная история со счастливым workaround.

Начинаем!

Для начала включим пакету gentoo-vm USE:
# echo 'dev-java/openjdk-bin gentoo-vm' >> /etc/portage/package.use/all
Теперь ставим собственно JDK (binary):
# emerge  openjdk-bin
Выбираем его для пользователя (нужно зайти в терминал пользователем):
$ eselect java-vm list 
Available Java Virtual Machines:
 [1]   icedtea-bin-8   system-vm
 [2]   openjdk-bin-11

$ eselect java-vm set user 2
Проверяем:
$ eselect java-vm list
Available Java Virtual Machines: 
  [1]   icedtea-bin-8  system-vm
  [2]   openjdk-bin-11  user-vm
Посмотрим переменные для пользователя:
$ file $JAVA_HOME 
/home/username/.gentoo/java-config-2/current-user-vm: symbolic link to /usr/lib/jvm//openjdk-bin-11 

IntelliJ IDEA

Сначала качаем JavaFX SDK: http://gluonhq.com/download/javafx-11-0-1-sdk-linux/
И разархивируем, например, в домашнюю папку.

Заходим в idea. Открываем RunEdit Configuration...
Переходим в TemplatesApplication
И прописываем для 'VM Options:'
--module-path /home/<USERNAME>/javafx-sdk-11.0.1/lib --add-modules=javafx.controls,javafx.fxml


Такое же можно (нужно) прописать для уже существующих записей в 'Application'.

Maven

Для десктоп-приложений можно засунуть всё что касается JavaFX прямо в приложение. Для этого прописываем в POM зависимости:
<dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>11</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
            <scope>compile</scope>
</dependency>
На счёт необходимости засовывания "javafx-media" я не уверен.
И на этом всё!

p.s.
А теперь немного не по теме. При переходе с 8ки на 11ку (в которой уже давно есть понятие модулей), мой готовый JAR со всеми зависимостями отказался запускаться выдавая:
Error: JavaFX runtime components are missing, and are required to run this application
Тут конечно можно сделать всё нормально, через испоьзование более в новых языковых конструктов (ключевые слова: modules, module-info.java) а можно добавить надстройку над основным классом (который с main() и который наследуется от Application).
package simplepackage;

public class Main {
    public static void main(String[] args){ MainFX.main(args); }
}
Где MainFX — класс, наследуемый от Application.

Ну и прописать его в манифесте основным. Для POM выглядит это так:
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-assembly-plugin</artifactId>
 <version>3.1.0</version>
 <configuration>
  <archive>
<manifest>
 <mainClass>simplepackage.Main</mainClass>
</manifest>
  </archive>
  <descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
  </descriptorRefs>
 </configuration>
 <executions>
  <execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
 <goal>single</goal>
</goals>
  </execution>
 </executions>
</plugin>
И никаких проблем.

UPD: Как теперь быть с падающим Android-studio?

После перехода на JDK11 у меня начал падать android-studio поставленый из портажей. Код ошибки приводить не буду, но чтобы исправить можно сделать так:

Сначала смотрим что у нас в /usr/lib/jvm/
ls /usr/lib/jvm/
Далее пишем алиас для android-studio:
$ vim ~/.bashrc
alias android-studio="JAVA_HOME=/usr/lib/jvm/icedtea-bin-8 JDK_HOME=/usr/lib/jvm/icedtea-bin-8 JAVAC=/usr/lib/jvm/icedtea-bin-8/bin/javac android-studio"
После этого студия начинает работать как надо. В новом терминале разумеется.

Ссылки:
https://wiki.openjdk.java.net/display/OpenJFX/Using+an+IDE#UsinganIDE-UsingIntelliJIDEA
https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11/52470141#52470141

13 июня 2018 г.

Заметка по настройке exim4 на работу с Gmail @ Debian

02:21 Опубликовал Дмитрий Исаенко , Нет комментариев
При сбоях в работе демонов часто внутри них есть возможность слать письма. Мне бы хотелось бы получать отчёты на почту в случае чего-то непредвиденного. Раньше я пользовался ssmtp и он действительно хорош для embedded-систем, но Debian советует использовать exim4. Ну что же, я его попробовал и он действительно хорош. 
Ниже краткая заметка (конспект с материалов сайта wiki Debian, см.в конце) как быстро прикрутить зарегестрированный адрес в gmail для передачи сообщений в мир.

Для начала ставим exim4:
# aptitude install exim4-daemon-light exim4-config
Настраиваем exim4:
# dpkg-reconfigure exim4-config
1. Общий тип почтовой конфигурации: «отправка почты через smarthost; приём по SMTP или через fetchmail»
2. Почтовое имя системы: «localhost»
3. IP-адреса, с которых следует ожидать входящие соединения SMTP: «127.0.0.1»
4.Другие места назначения, для которых должна приниматься почта: оставить пустым
5. Машины, для которых доступна релейная передача почты:
 оставить пустым
6. IP-адрес или имя хоста являющегося исходящим smarthost: «smtp.gmail.com::587»
7. Скрывать локальное почтовое имя в исходящей почте? НЕТ
8. Сокращать количество DNS-запросов до минимума (дозвон по требованию)? НЕТ
9. Метод доставки локальной почты: mbox формат в /var/mail/
10. Разделить конфигурацию на маленькие файлы? ДА (или НЕТ)
Редактируем пароль для аккаунта в gmail
# vim /etc/exim4/passwd.client
 *.google.com:имя_пользователя_gmail@gmail.com:y0uRpaSsw0RD

Добавим правило для перезаписи имени отправителя (/etc/email-addresses ):
(В данный момент это не требуется, но мейнтейнеры exim говорят, что будет не лишним.)
# echo 'локальное_имя_пользователя: имя_пользователя_gmail@gmail.com' >> /etc/email-addresses
# echo 'локальное_имя_пользователя@localhost: имя_пользователя_gmail@gmail.com' >> /etc/email-addresses
# echo 'локальное_имя_пользователя@hostname1: имя_пользователя_gmail@gmail.com' >> /etc/email-addresses
# echo 'локальное_имя_пользователя@hostname1.localdomain: имя_пользователя_gmail@gmail.com' >> /etc/email-addresses
Применяем изменения:
# update-exim4.conf
# invoke-rc.d exim4 restart
# exim4 -qff
Говорим что вся почта, которую система будет генерировать и пытаться отправить root должна посылаться на адрес gmail (например на тот же, с которого происходит отправка. Или другой.):
vim /etc/aliases
root: имя_пользователя_gmail@gmail.com
Протестируем:
echo "Мудрое сообщение"|mail -s 'Значимый заголовок' root
Также может понадобиться разрешить gmail работу с непроверенными источниками. Это та фича, которая при попытке привязать новый почтовый клиент спрашивает разрешения. При её отключении спрашивать перестанет.

Всё. Проще чем казалось :)

Ссылки:
https://wiki.debian.org/GmailAndExim4

10 апреля 2018 г.

NoWOL: питание ПК через интернет. Часть 2.

05:55 Опубликовал Дмитрий Исаенко , , Нет комментариев
Продолжаем! Для проекта NoWOL есть Android-приложение с виджетом.

Вообще, там всё весьма просто. Как будет возможность (не лень), загружу исходники в GitHub. Пока же там лежит вполне готовая к использованию APK'шка.
Из ключевых моментов: внутри используется библиотека Volley; работает приложение под Android 4.0 и выше (minSdkVersion 14, target 26).

UPD: Исходники https://github.com/developersu/NoWOL-APK
Архитектура проста донельзя. Приложение отправляет HTTP-запросы по указанному адресу и парсит ответы.

А теперь скриншоты!

После установки станет доступно основное приложение, а в разделе виджетов появится новый виджет с одноимённым названием «NoWOL».

Что касается приложения, то в нём доступно несколько состояний: неизвестно, онлайн, офлайн, нет ответа (от хоста). Обновить состояние можно нажав на кнопочку в верхней панели.


Если нажать на шестерёнку на верхней панели, всплывёт окно для указания IP хоста в сети. Следует обратить внимание на формат записи. Защиты от дурака там, к сожалению, не так много как хотелось бы. Вот хороший пример:

  

При добавлении виджета появится окно конфигуратора. Как видно, в нём нет указателя на адрес хоста. Он настраивается внутри приложения, поэтому сперва стоит запустить его.
Зато в конфигураторе можно выбрать задний фон (белый или чёрный) с альфа-каналом и уровень его прозрачности.
UI немного неочевиден и меняется в зависимости от выбора "галочки". Я знаю, так делать нехорошо.


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

Забавный момент: если ПК в режиме ожидания, то статус будет или "онлайн" или "офлайн" в зависимости от того, мигнула ли лампочка в момент запроса состояния :)

Принудительно обновить статус можно ловко попав по верхнему правому углу, или через приложение — оно передаст полученные данные в виджет. 
Вообще, статус обновляется сам каждые пол часа (если мне не изменяет память, но уж точно не чаще). Сделано это только для того, чтобы не сажать батарею телефона почём зря.


В общем-то на этом всё. Надеюсь, вам понравилось =)

NoWOL: питание ПК через интернет. Часть 1.

04:28 Опубликовал Дмитрий Исаенко , , , Нет комментариев
Ох, давно хотел уже задокументировать это здесь, да всё времени не было. И вот, спустя полтора года…

Какую проблему решаем?

Стоит задача включать и выключать ПК нажимая на кнопки включения\выключения и сброса не руками, а через интернет (ну или через тоннель в интранет). В идеале спросонья через виджет в телефоне а-ля узнал погоду за бортом, включил ПК и можно идти ставить кофе.

Для этого было решено пилить какой-то контроллер Atmega с каким-то ethernet-свистком, чтобы он через оптопары замыкал кнопки включения. А заодно сообщал об успехе или неуспехе затеи.

Немного покопавшись я решил закупить основанную на enc28j60 приблуду для ардуины, а заодно и саму ардуину. Изучив особенности программирования enc28j60 руками (без высокоуровневых IDE и готовых библиотек) и бегло осмотрев errata, который, надо отметить, чуть ли не больше даташита, стало ясно, что на низком уровне рулить “этим” сущий ад и боль. Поэтому, будем собирать всё на базе добротного китайского клона Arduino nano или функционального аналога (лучше просто взять arduino, правда).

В итоге система будет состоять из основного модуля в виде связки Arduino+enc28j60 и выносного блока с оптопарами и резисторами.

В целом выглядеть и подключаться всё будет так:

Но перед тем, как начать…

Поставим себе пару пакетов:
1. dev-embedded/arduino
2. sci-electronics/eagle (ветка 7.x.x и лучше из нестабильной ветки) 
Все необходимые файлы лежат в проекте на GitHub:
https://github.com/developersu/NoWOL

Про выносной модуль

Файлы для Eagle CAD находятся в директории eagle_files/m2Board/ .
Необходимые библиотеки в eagle_files/lib/ .

Для выносного модуля понадобится:

Part Value Device Package Library Sheet
IC2 КР293КП4А DIL08 ic-package 1
IC3 КР293КП4А DIL08 ic-package 1
IN PINHD-1X6 1X06 pinhead 1
OUT PINHD-1X6 1X06 pinhead 1
R1 450Ω или 470Ω R-EU_0204/5 0204/5 resistor 1
R2 450Ω или 470Ω R-EU_0204/5 0204/5 resistor 1
R3 330Ω R-EU_0204/5 0204/5 resistor 1
TO_MCU PINHD-1X5 1X05 pinhead 1

По-поводу R1 и R2 резисторов, я собрал две пары, чтобы получилось 450 Ом в каждой. Думаю, что если взять просто пару штук на 470 Ом всё тоже будет работать. Но всё же обещать не буду.

Его принципиальная схема выглядит весьма просто:

Разводка выполняется на односторонней плате:


* 'cuz soviet works better
Если присмотреться, разводка слегка отличается от той, что приведена на первом рисунке. Тут я убрал перемычку.

Как вы уже поняли, в качестве оптопар используется отечественная схема КР293КП4А в корпусе DIP8. Внутри каждой микросхемы находится 2 оптопары. Одна из схем замыкает и размыкает кнопки (питание и сброс), а вторая говорит микроконтроллеру включена ли система, определяя это по светодиоду-индикатору питания. Если первую микросхему замыкает МК, то вторую — ПК. Через отдельный пин микроконтроллер зажигает индикатор питания сам, когда понимает, что и система (ПК) тоже его зажгла. Уж не знаю.. может это несколько избыточно и можно было сделать проще. Впрочем, получилось как получилось.

Примечание: наверное надо было навесить на вторую оптопару какие-то резисторы.. но блин, datasheet по ним такой немногословный. В общем как-то работает уже больше года, так что, пока всё не сгорело, имеет право на жизнь.

Если всё спаять и приправить должным количеством пыли, получится примерно следующее:


Про программирование Arduino

Теперь перейдём к программированию Arduino. Как говорилось ранее, предполагается использование Arduino Nano.
Я уже не помню что куда нажимать и подключать, чтобы это дело прошить но у меня есть скетч!
Для этого скетча понадобится библиотека ehtercard. И скетч и библиотека находятся в директории arduino_sketchbook/.

А вот и сам код:
#include <EtherCard.h>

#define PWR_PIN 6
#define RST_PIN 7
#define PWR_LED_IN 8
#define PWR_LED_OUT 5


int i;
// Зададим MAC адрес устройства
static byte mymac[] = { 0xDE,0xAD,0xBE,0xEE,0xEE,0xEF };
 
// Чем больше данных отображается на странице, тем больше требуется буфер для них
byte Ethernet::buffer[900];
BufferFiller bfill;
 
//Массив задействованных контактов для управления оптопарами
int LedPins[] = {PWR_PIN,RST_PIN};
 
//Массив для фиксации изменений
boolean PinUpdate = 0;      //100-reset 200-power 5050-powerOFF
 
const char http_OK[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"Pragma: no-cache\r\n\r\n"
"\r\n"
"<html>"
  "<head><title>"
    "noWOL"
  "</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><style>"
  "body { font-family: monospace;\n"
   "background-color: #000000;\n"
   "font-size: 30px;\n"
   "font-weight: bold;\n"
   "color: #b2b2b2;}\n"
   "a:link, a:visited {  display: inline-block;\n"
  "color: #b2b2b2;\n"
  "font-weight: 700;\n"
  "text-decoration: none;\n"
  "padding: .3em 2em;\n"
  "outline: none;\n"
  "border: 2px solid;\n"
  "border-radius: 15px;\n"
  "transition: 0.2s;}\n"
  "a:hover {color: #fefefe;}\n"
  "</style></head>"
  "<body><center>"
;
const char http_Found[] PROGMEM =
"HTTP/1.0 302 Found\r\n"
"Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
"HTTP/1.0 401 Unauthorized\r\n"
"Content-Type: text/html\r\n\r\n"
"401 Unauthorized";
 
void homePage()
{
bfill.emit_p(PSTR("$F"
  " "
  "$F<p>"
  "<a href='?RESET=on'>  RESET   </a><p>"  //D6
  "<a href='?POWER0=on'>  POWER   </a><p>" //D7 short
  "<a href='?POWER1=on'>POWER 5sec</a><br />"),  //D7 long
  //"PWR LED out D5 : $F <br /></body></html>"),
  
  http_OK,
  (digitalRead(PWR_LED_IN) == HIGH)?PSTR("<span style=\"color: #AA0000\">          ▄▄▄▄▄▄</span>"):PSTR("<span style=\"color: #00c600\">          ▄▄▄▄▄▄</span>")),//⬤
//  (bitRead(PORTD,PWR_LED_OUT) == HIGH)?PSTR("HIGH"):PSTR("LOW")),

"</center></body>"
"</html>"
  ;
}

void pick_pin(int pin, int del) {
      digitalWrite(pin,HIGH);
        delay(del);
        digitalWrite(pin,LOW);
        PinUpdate = 0;
}
 
void setup()
{
// SET UART
//  Serial.begin(9600);
//Change default ethercard CS - pin 8 to 10
  //if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)

//  Serial.println( "Access to Ethernet controller failed");
    ether.begin(sizeof Ethernet::buffer, mymac, 10);
    ether.dhcpSetup();
//  if (!ether.dhcpSetup())
//       Serial.println("DHCP routine failed");
    //Print over UART configuration recieved:
//  ether.printIp("IP:  ", ether.myip);          
//  ether.printIp("GW:  ", ether.gwip);  
//  ether.printIp("DNS: ", ether.dnsip);  

  for(i = 0; i < 2; i++) {
    pinMode(LedPins[i],OUTPUT);
  }
  
    pinMode(PWR_LED_OUT,OUTPUT);
    pinMode(PWR_LED_IN,INPUT_PULLUP); // LED-питания как вход
}
 
void loop()
{
    delay(1);

        if (digitalRead(PWR_LED_IN) == HIGH) {        // если мать выключена
            if (bitRead(PORTD,PWR_LED_OUT) == HIGH) digitalWrite(PWR_LED_OUT,LOW);
        }
        else if (bitRead(PORTD,PWR_LED_OUT) == LOW) {
          digitalWrite(PWR_LED_OUT,HIGH);
        }

        switch (PinUpdate) {
          case 0:
            break;
          case 1:
            pick_pin(RST_PIN, 200);
            break;
          case 2:
            pick_pin(PWR_PIN, 200);
            break;
          case 3:
            pick_pin(PWR_PIN, 5050);
            break;
        }

    word len = ether.packetReceive(); //Проверить ethernet пакеты
    word pos = ether.packetLoop(len); //Проверить TCP пакеты
    if (pos) {
        bfill = ether.tcpOffset();
        char *data = (char *) Ethernet::buffer + pos;
        if (strncmp("GET /", data, 5) != 0) {
            bfill.emit_p(http_Unauthorized);
        }
        else {
            data += 5;
            if (data[0] == ' ') {
                    homePage(); //Если обнаружено изменения на станице, то запускаем функцию
            }
            //"10" = количество символов "?RESET=on ".
            else if (strncmp("?RESET=on ", data, 10) == 0) {
                bfill.emit_p(http_Found);
                                PinUpdate = 1;
            }
 
            else if (strncmp("?POWER0=on ", data, 11) == 0) {
                  bfill.emit_p(http_Found);
                                PinUpdate = 2;
            }
 
            else if (strncmp("?POWER1=on ", data, 11) == 0) {
                    bfill.emit_p(http_Found);
                                PinUpdate = 3;
            }

            else {
                //Страница не найдена
                bfill.emit_p(http_Unauthorized);
            }
        }
        ether.httpServerReply(bfill.position());
    }
}
Теперь, когда всё что надо прошито, соединяем как указано на рисунке в начале публикации и подключаем это дело к сети. На машрутизаторе должен быть настроен DHCP сервер.
Мак-адрес нового устройства, как ясно из исходного кода, будет de:ad:be:ee:ee:ef. Лучше сразу назначить постоянную аренду. В OpenWRT с LuCI идём в:
«Сеть» → «DHCP и DNS» → вкладка «Основные настройки» → «Постоянные аренды» → «Добавить».
Пишем там как показано на рисунке:


Когда всё настроено и подключено, заходим на адрес http://192.168.1.100 и видим следующее:


Только вот квадратик будет красным, а не зеленым. Это и есть индикатор питания.
Назначение кнопок пояснять нет смысла. Последняя симулирует долгое нажатие, что приводит к принудительному отключению.

То, что всё это находится в интрасети и не отсвечивает в мир меня вполне устраивает, ведь при подключении по VPN доступ появляется и в Android-приложении и через WEB-интерфейс. Ах да! Для всего этого дела есть ещё и Android-приложение :) Но о нём во второй части.

Вредные советы

Как бы не использовать Arduino?

Лучше таки его использовать.
Но можно и спаять свою ардуину, с блекджеком и профусетками, чтобы она была поменьше и конкретно под этот проект.
Сразу оговорюсь, я наделал кучу ошибок и паял отдельные костыли чтобы всё сошлось.. потом переделал схему, потом ещё пару раз, и уже не помню на сколько там правильная разводка. Так что лучше внимательно изучить и прислать мне фидбек в виде линки на исправленную версию. Или апробировать, если всё правильно =)

Используется двусторонний текстолит. Перемычки тут не помогут.

Находится всё в директории eagle_files/atmegaBoard/ .

Список компонентов:

Part Value Device Package Library Sheet
C1 22pF C-EUC0603 C0603 resistor 1
C2 22pF C-EUC0603 C0603 resistor 1
C3 10uF CC0603 C0603 eagle-ltspice 1
C4 22uF CC0603 C0603 eagle-ltspice 1
IC1 atmega328p atmega328p TQFP32-08 avr-6 1
IC3 LM1117IMPX-3.3 LM1117IMPX-3.3 SOT223 lm1117 1
JP1
PINHD-2X5 2X05 pinhead 1
JP3 PINHD-1X2 1X02 pinhead 1
Q1 16MHz XTAL/S QS special 1
SV1 MA05-1 MA05-1 con-lstb 1
U1 USB"" USB-MICRO-SMD MicroUSB 1

Схема принципиальная:


Сама разводка:


Что тут добавить.. земля на гребёнке справа. JP3 нужен для прошивки схемы. Прошивается она через Arduino IDE.. Кажется с помощью самой ардуины. Ну или через USBasp программатор. В общем, главное ничего не перепутать. А настройки должны быть вроде таких:

1)
 

2)


В следующей части будет обзор Android-приложения. APK файл находится в папке Android_APK.

Итого

У меня вся эта разработка шла не очень гладко, но получилось вполне сносно. Вот конечный результат в корпусе из спичек. Для антуража покрашено йодом.



Что касается дальнейшего развития этой инициативы, то я планирую добавить сюда ещё один выносной модуль для ещё одного ПК.

--
Особая благодарность Unyuu за неоценимый вклад. Во многом благодаря его советам этот проект стал возможен.


Лицензия Creative Commons
Текстовый материал распространяется по лицензии Creative Commons С указанием авторства-Некоммерческая-С сохранением условий 4.0 Всемирная.
Обратите внимание: это ограничение не касается графических изображений и исходного кода. Если на самом изображении не указано иного, они доступны по лицензии Creative Commons С указанием авторства 4.0 Всемирная.