2018年12月23日日曜日

GitLab API で Personal Access Token でプロジェクトの情報を取得してみた

はじめに

https://docs.gitlab.com/ee/api/ を参照すると GitLab の API を利用する方法として以下の三つがあるようです。

  • OAuth2 tokens
  • Personal access tokens
  • Session cookie

これらのうち、Personal access tokens で GitLab API をたたいてみました。

Personal Access Token 取得

  1. GitLab アカウントの [Settings] - [Access Tokens]
  2. [Personal Access Tokens] で以下を入力
  • Name: この Access Token を識別する任意の名前
  • Expires at: ここで入力した日付の AM 00:00 にこの Access Token が失効するようです。(つまり、この日の前日まで使えるようです。)
  • Scopes: [api] のみチェックしてみました
  1. [Create personal access token] をクリック
  2. 次の画面で [Your New Personal Access Token] が表示されました。この Access Token を控えておきます。(画面を閉じると再度表示することはできないようです)

プロジェクトに関する情報を取得

以下のように GitLab API をたたくと自分のプロジェクトに関する情報を取得できました

$ curl \
https://gitlab.com/api/v4/users/<User>/projects?private_token=<Personal access token> \
| python3 -mjson.tool

2018年12月5日水曜日

Raspberry Pi で OctoPrint で WebCam で 3D プリンタを遠隔チェック

はじめに

Raspi にインストールした OctoPrint に WebCam の設定をしてプリント中の 3D プリンタを遠隔から監視できるようにしてみました。

なお Raspi に OctoPrint はすでにインストールされ、カメラもすでに使える状態になっているところから始めています。

環境

  • Raspberry Pi 3 model B
  • Raspbian GNU/Linux 9.4 (stretch)
  • オフィシャル Raspi カメラ V2.1
  • OctoPrint Version 1.3.9

Raspi のカメラが使えることを確認

以下のコマンドを実行。

$ raspivid -o ./test.h264

Raspi カメラで 5秒間程度動画撮影し、カレントディレクトリに動画ファイル test.h264 ができました。

このままでは Windows で再生できなのでフォーマットを変換します。

まずは必要なパッケージをインストール。

$ sudo apt install gpac

フォーマットを変換。

$ MP4Box -add ./test.h264 ./test.mp4

カレントディレクトリにできた test.mp4 を Windows に移動して再生できることを確認しました。

MJPG-Streamer コンパイル

必要なパッケージインストール

$ sudo apt install \
subversion \
libjpeg62-turbo-dev \
imagemagick \
ffmpeg \
libv4l-dev \
cmake

MJPG-Streamer をダウンロードしてコンパイル

$ cd ~
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental
$ export LD_LIBRARY_PATH=.
$ make

試しに WebCam サーバー起動

MJPG-Streamer をコンパイルしたディレクトリに移動

$ cd ~/mjpg-streamer/mjpg-streamer-experimental

MJPG-Streamer を実行 - オフィシャル Raspi カメラでない場合はコマンドが異なるようです

$ ./mjpg_streamer \
-i './input_raspicam.so -fps 5' \
-o './output_http.so'

ブラウザで以下の URL にアクセスすると Raspi カメラで撮影されたストリーミング動画を見ることができました。 - http://<your Raspi's IP>:8080/?action=stream

Ctrl + C で MJPG-Streamer を停止

OctoPrint で WebCam サーバーを起動/停止できるようにスクリプト設置

以下のファイルを設置しました。

/home/pi/scripts/webcam

#!/bin/bash
# Start / stop streamer daemon

case "$1" in
    start)
        /home/pi/scripts/webcamDaemon >/dev/null 2>&1 &
        echo "$0: started"
        ;;
    stop)
        pkill -x webcamDaemon
        pkill -x mjpg_streamer
        echo "$0: stopped"
        ;;
    *)
        echo "Usage: $0 {start|stop}" >&2
        ;;
esac

/home/pi/scripts/webcamDaemon

#!/bin/bash

MJPGSTREAMER_HOME=/home/pi/mjpg-streamer/mjpg-streamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"

# init configuration
camera="auto"
camera_usb_options="-r 640x480 -f 10"
camera_raspi_options="-fps 10"

if [ -e "/boot/octopi.txt" ]; then
    source "/boot/octopi.txt"
fi

# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
    input=$1
    pushd $MJPGSTREAMER_HOME
    echo Running ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    popd
}

# starts up the RasPiCam
function startRaspi {
    logger "Starting Raspberry Pi camera"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}

# starts up the USB webcam
function startUsb {
    logger "Starting USB webcam"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}

# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version

# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
echo raspi options: $camera_raspi_options

# keep mjpg streamer running if some camera is attached
while true; do
    if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
        startUsb
    elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; }; then
        startRaspi
    fi

    sleep 120
done

軽く webcamDaemon スクリプトを読んでみたところ、camera="auto" となっているので USB カメラか Raspi カメラ かを自動判定しているようです。camera="usb" とすると USB カメラ (接続されて使えるようになっていれば) を指定でき、camera="raspi" とすると Raspi カメラを指定できるようです。

また、/boot/octopi.txt が存在すれば source コマンドで読み込むので、webcamDaemon スクリプトを修正しなくてもこのファイルで camera 変数の値を変更することができそうです。

作成したスクリプトに実行権限付与

$ chmod +x /home/pi/scripts/webcam
$ chmod +x /home/pi/scripts/webcamDaemon

設置したスクリプトで WebCam サーバーの起動/停止ができることを確認

まずは起動していないことを確認

$ ps -efwww | grep mjpg_streamer | grep -v grep
$

なにも表示されないので起動していないことが確認できました。

WebCam サーバー起動

$ /home/pi/scripts/webcam start
/home/pi/scripts/webcam: started

$ ps -efwww | grep mjpg_streamer | grep -v grep
pi        4759  4751  2 00:10 pts/2    00:00:00 ./mjpg_streamer -o output_http.so -w ./www -i input_raspicam.so -fps 10

mjpg_streamer プロセスが起動しているのがわかります。

また、プロセスの引数が -i input_raspicam.so となっているのでカメラの自動認識で Raspi カメラを認識できていることがわかります。

ブラウザで以下の URL にアクセスすると Raspi カメラで撮影されたストリーミング動画を見ることができました。 - http://<your Raspi's IP>:8080/?action=stream

WebCam サーバー停止

$ /home/pi/scripts/webcam stop
/home/pi/scripts/webcam: stopped

$ ps -efwww | grep mjpg_streamer | grep -v grep
$

なにも表示されないので停止したことが確認できました。

OctoPrint システムメニューで WebCam サ ーバーを起動/停止できるように設定ファイル修正

/home/pi/.octoprint/config.yaml の最後に以下追加 - 今まで一度も OctoPrint を起動していない場合はこの .octoprint/ ディレクトリは まだ作成されていないかもしれません

system:
  actions:
    - action: streamon
      command: /home/pi/scripts/webcam start
      confirm: false
      name: Start video stream
    - action: streamoff
      command: /home/pi/scripts/webcam stop
      confirm: false
      name: Stop video stream

参考ページでは command: sudo /home/pi/scripts/webcam stop というように停止時は sudo により root 権限で stop させる ようになっています。これは別ユーザーが WebCam サーバーを起動した場合でも OctoPrint から WebCam サーバーを停止できるようにするためだと思われますが、パスワード無しで sudo できることが前提です。Raspbian のデフォルトでは確かパスワード無しで sudo できたはずですが、私の Raspi は sudo 時にパスワードが必要なように設定を変更しています。このため sudo をつけると OctoPrint から WebCam サーバーを停止で きないので command: /home/pi/scripts/webcam stop というように sudo を付けないように変更しています。別ユーザーが起動し た WebCam サーバーは OctoPrint で停止できませんが、私の使い方ではそのような状況にはならないかなと考えています。

OctoPrint で WebCam サーバー起動/停止

/home/pi/.octoprint/config.yaml を修正したので OctoPrint が起動している場合は念のため OctoPrint 再起動

ブラウザで OctoPrint にアクセスし、電源アイコン (System) のプルダウンから Start video stream を選択して WebCam サーバー起動

ブラウザで以下の URL にアクセスすると Raspi カメラで撮影されたストリーミング動画を見ることができました。 - http://<your Raspi's IP>:8080/?action=stream

電源アイコン (System) のプルダウンから stop video stream を選択して WebCam サーバー停止

OctoPrint の画面で WebCam のストリーミングを確認できるよ うにする

WebCam サーバーが起動していない場合は起動

スパナのアイコン (Settings) をクリック

WebCam & Timelapse をクリック

Stream URL に http://<your Raspi's IP>:8080/?action=stream を設定

参考ページには Stream URL に /webcam/?action=stream を設定するようにと書かれていましたが、私の環境ではこれではだめ でした。

Test をクリックして WebCam のストリーム動画が表示されることを確認

Save をクリック

OctoPrint を再起動し、ブラウザのキャッシュをクリアし、OctoPrint ページをリロード

WebCam サーバーを起動

Control タブに WebCam のストリーミング画像が表示されるようになりました。

参考

  • https://discourse.octoprint.org/t/setting-up-octoprint-on-a-raspberry-pi-running-raspbian/2337
  • https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspivid.md

2018年11月16日金曜日

Raspberry Pi で Samba

Raspberry Pi に保存したファイルを Windows に移動させたかったので Raspberry Pi に Samba を入れま した。

環境

  • Raspberry Pi 3 Model B
  • Raspbian GNU/Linux 9.4 (stretch)

Samba インストール

$ sudo apt install samba

設定

設定ファイルを確認すると以下の様にすでにホームディレクトリの設定が有効になっていました。

$ cat /etc/samba/smb.conf
... snip ...
[homes]
   comment = Home Directories
   browseable = no

# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
   read only = yes

# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
   create mask = 0700

# Directory creation mask is set to 0700 for security reasons. If you want to
# create dirs. with group=rw permissions, set next parameter to 0775.
   directory mask = 0700

# By default, \\server\username shares can be connected to by anyone
# with access to the samba server.
# The following parameter makes sure that only "username" can connect
# to \\server\username
# This might need tweaking when using external authentication schemes
   valid users = %S

# Un-comment the following and create the netlogon directory for Domain Logons
# (you need to configure Samba to act as a domain controller too.)
;[netlogon]
... snip ...

pi ユーザーを smbpasswd に登録してパスワードを設定

$ sudo smbpasswd -a pi
New SMB password:
Retype new SMB password:
Added user pi.

接続

\\XX.XX.XX.XX\pi で Windows から接続できました。(XX.XX.XX.XX は Raspberry Pi の IP アドレスです)

2018年11月14日水曜日

apt-file でどのパッケージに指定したファイルが含まれているか探す

環境

  • Raspberry Pi 3 model B
  • Raspbian GNU/Linux 9.4 (stretch)

apt-file インストール

$ sudo apt-get install apt-file

パッケージ情報を更新

$ sudo apt update

グルると更新のために $ sudo apt-file update を実行と記載されていたりしますが、man を調べると

$ man apt-file
... snip ...
       update
           Deprecated action that just calls "apt update".
... snip ...

と書かれているので、パッケージ情報の更新は $ sudo apt update で良いようです。

試しに検索

例えば /usr/bin/pip2 を含むパッケージを探すと

$ apt-file search /usr/bin/pip2
python-pip: /usr/bin/pip2

となり、/usr/bin/pip2 ファイルは python-pip パッケージに含まていることがわかりました。

2018年9月9日日曜日

JupyterLab をインストールしてみた

環境

  • Azure 上の Ubuntu 18.04.1 Server
  • Python 3.6.5

JupyterLab インストール

インストールしてバージョン確認

$ pip3 install jupyterlab
$ jupyter --version
4.4.0

Jupyter のバージョンが 5.3 より古い場合は以下実行する必要があるとのこと。

$ jupyter serverextension enable --py jupyterlab --sys-prefix
Enabling: jupyterlab
- Writing config: /home/worker/tmp/venv/etc/jupyter
    - Validating...
      jupyterlab 0.34.7 OK

NoteBook を RestructuredText にエクスポートする場合は pandoc が必要なのでインストール

$ sudo apt install pandoc

JupyterLab 起動

実行

$ jupyter lab
[I 09:13:48.928 LabApp] JupyterLab extension loaded from /home/worker/tmp/venv/lib/python3.6/site-packages/jupyterlab
[I 09:13:48.928 LabApp] JupyterLab application directory is /home/worker/tmp/venv/share/jupyter/lab
[W 09:13:48.932 LabApp] JupyterLab server extension not enabled, manually loading...
[I 09:13:48.933 LabApp] JupyterLab extension loaded from /home/worker/tmp/venv/lib/python3.6/site-packages/jupyterlab
[I 09:13:48.934 LabApp] JupyterLab application directory is /home/worker/tmp/venv/share/jupyter/lab
[I 09:13:48.936 LabApp] Serving notebooks from local directory: /home/worker/tmp
[I 09:13:48.937 LabApp] The Jupyter Notebook is running at:
[I 09:13:48.937 LabApp] http://localhost:8888/?token=fbdeaae80c3df681a58f38b44a39b15b0c4f10ea5ed7e570
[I 09:13:48.937 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 09:13:48.938 LabApp] No web browser found: could not locate runnable browser.
[C 09:13:48.938 LabApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=fbdeaae80c3df681a58f38b44a39b15b0c4f10ea5ed7e570

ブラウザから JupyterLab に接続

JupyterLab を起動した時のメッセージによると、ブラウザから以下の URL に接続するようにとのこと

http://localhost:8888/?token=fbdeaae80c3df681a58f38b44a39b15b0c4f10ea5ed7e570

ssh で Ubuntu にログインしているので、ローカル側の localhost:8888 をサーバー側の localhost:8888 にポート転送

ローカル側のブラウザで指定の URL に接続


JupyterLab 終了

以下のどちらかの方法で終了することができます。

ブラウザから終了する方法

ブラウザの JupyterLab 画面のメニューで [File] - [Quit]

コンソールで終了する方法

JupyterLab を起動したコンソールで Ctrl + C を入力。

Shutdown this notebook server (y/[n])? と聞いてくるので、y を入力。 数秒以内に入力しないと Ctrl + C がキャンセルされます。


このブログのアイコンを作った

Twitter Card のデフォルト画像にする予定。

2018年7月29日日曜日

ラズパイで PWM で Python3 でサーボモーターを制御

環境

  • Raspberry Pi 3 Model B
  • Raspbian GNU/Linux 9.4 (stretch)
  • サーボモーター: SG90

wiringpi2 インストール

$ sudo pip3 install wiringpi2

Python3 コード

SG90 の信号線は Raspberry Pi の GPIO18 に接続しています。

DUTY_MIN, DUTY_MAX の値は適当に。。。

あと、このスクリプトは root 権限で実行しないと、Raspberry Pi が固まります。

#!/usr/bin/env python3

import wiringpi
import time

PWM_PIN = 18

DUTY_MIN = 45
DUTY_MAX = 105

wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(PWM_PIN, wiringpi.GPIO.PWM_OUTPUT)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)
wiringpi.pwmSetClock(375)

while True:
    for duty in range(DUTY_MIN, DUTY_MAX):
        wiringpi.pwmWrite(PWM_PIN, duty)
        time.sleep(0.01)

    for duty in range(DUTY_MAX, DUTY_MIN, -1):
        wiringpi.pwmWrite(PWM_PIN, duty)
        time.sleep(0.01)