Androidのメモとか

ポキオの日記です。今日も遅延してない。

ASUS TransBook T101HAにXubuntuを入れたときのメモ

サクサク!

ASUS TRANSBOOK T101HA Ubuntu Xubuntu

重たいWindowsにさようなら

Windows10は素晴らしいんですが、以前投げ売りしてた非力なこのラップトップにはちょっと荷が重すぎました。

そこで、Linuxを入れてサクサクにしてやろうとおもい、いろんなOSを試してみましたが、導入容易性・ハードウェア互換性・動作快適性のすべてのバランスが高次元で達成できていたのが、Xubuntuでした。Xubuntu導入時のメモを備忘録として残しておきます。

Xubuntu

スンドゥブではないです。ズブントゥです。

xubuntu.org

Xubuntu(ズブントゥ)とは、Ubuntu コミュニティーから公式に派生した Linuxディストリビューションである。 デスクトップ環境には Xfce を採用する。(Wikipedia

シンプルでクリーンなルックスのXfceですが、軽量で非力なPCでもサクサク動きます。

セットアップ

OSイメージをUSBに焼く

xubuntu.org

ダウンロードサイトから64bit版のISOファイルをダウンロードしてきてから、イメージをUSBに焼きます。焼き焼きには毎度おなじみのEtcherをつかいました。

etcher.io

USBから起動、インストール

ざっくりとした手順はこんな感じ。

  • 作ったUSBを電源を切った状態のラップトップに差し込む
  • 電源ON、すぐにESCキーを長押し
  • 起動ディスクを聞かれるので、USBっぽいものを選択して起動
  • あとは愚直にInstall

画面が横を向いている

ASUS TRANSBOOK T101HA Ubuntu Xubuntu

このラップトップは2in1で、タブレットとしても使えるせいか、デフォルトの画面の向きが横向きになっています。

ASUS TRANSBOOK T101HA Ubuntu Xubuntu

ログイン後に、画面設定より画面のオリエンテーションをRightにすれば治ります。ただ、設定は保持されるものの、この設定が反映されるのはログイン後なので、ログインするまでは横向きになってしまいます。気にしないことにします。

また、画面の回転はこの設定画面から変更できますが、タッチパネルのタッチ位置が回転してくれません。下記のコマンドでキャリブレーション可能です。

xinput set-prop 13 --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1

これを毎回打つのは厳しいので、~/.profileの最後の方に記載しておき、自動でこのコマンドがExecuteされるようにしておきます。

なぜか自動でNUMLOCKがONになる

これはファックですね。しかし、このラップトップにはNUMLOCK切り替えのハードキーがなさそうなので、コマンドからNUMLOCKをOFFにします。

numlockx off

これも、~/.profileの最後の方に記載しておき、自動でこのコマンドがExecuteされるようにしておきます。

これで一通り動くようになりました

あとは必要なものをapt installして終わりです。なぜか日本語入力環境も、日本語フォントもプリインされていたので(日本のミラーから落としたから?違うよね?)、割と簡単にXubuntu環境が整いました。もりもりBashしていきましょう。

Ubuntuスタートアップバイブル

Ubuntuスタートアップバイブル

残項目

  • スピーカーが鳴らない
  • ログイン前に画面が横向きになる

GooglePhotoMarkdownerはLinuxでも使えます

Xubuntu最高。

ポキオ GooglePhotoMarkdowner Electron

非力なPCにXubuntuを入れるところから

素晴らしい土曜日の朝です。

早く起きたし、 #xubuntu 入れるか…。

A post shared by pokio (@pokiiiiio) on

以前買ったAsusのラップトップなんですが、Win10が動くのがイッパイイッパイで、ちょっともっさりとしていたのと、やっぱり普通にBashが使いたいのでXubuntuを入れました。

これが結構快適で、素晴らしいものです。只今、絶賛apt install中です。

せっかくなのでGooglePhotoMarkdownerもLinux対応

Linux向けのビルドスクリプトを追加しました。

github.com

理論的には起動するだろうと思っていたものの、実際にElectronアプリをLinuxでビルドしたことはなく、ちょっと心配でしたが・・・

ポキオ GooglePhotoMarkdowner Electron

ちゃんと動いているみたい! さぁ、Markdownやっていき!

M5STACKでデジタル名刺を作る

クールに自己紹介。

ポキオ M5STACK

M5STACKで何しよう?

relativelayout.hatenablog.com

前回、ノリで買ってしまったM5STACK。ノリで買ったのはいいものの、いい感じのユースケースが思い浮かびませんでしたが、後輩の@ktansaiがいい感じのデジタル名刺を作っていたので、早速パクらせていただきました(笑)

準備するもの

  • M5STACK
  • 表示する画像
  • Micro SDカード
  • パクってもいいじゃないかという強い心

正直言うと、SDカードではなく、画像を内蔵ストレージに書き込んでもいいのですが、それでは本家と全くおなじになってしまうので、私はSDカードに書き込んで、プログラムからそれを参照してみます。

画像

320x240のJPG画像を数枚用意しました。macOSKeynoteでテキトーに作りました。

プログラム

MicroPythonで書きました。

github.com

  • ButtonAとCを押すと、画像が変わる仕組みになっています。
  • SDカードはわざわざマウントしてあげる必要があります。
  • 画像の表示は便利関数が用意されています。
from m5stack import lcd
from m5stack import buttonA
from m5stack import buttonC
import uos
import utime

imageList = ["/sd/image1.jpg", "/sd/image2.jpg",
             "/sd/image3.jpg", "/sd/image4.jpg"]
position = 0

uos.mountsd()

lcd.clear()
lcd.image(0, 0, file=imageList[0], scale=0, type=lcd.JPG)

while True:
    if buttonA.wasPressed():
        position = position + 1
        lcd.clear()
        lcd.image(0, 0, file=imageList[position %
                                       len(imageList)], scale=0, type=lcd.JPG)
    if buttonC.wasPressed():
        position = position - 1
        lcd.clear()
        lcd.image(0, 0, file=imageList[position %
                                       len(imageList)], scale=0, type=lcd.JPG)

    utime.sleep(0.1)

いざプログラム実行!

いい感じっすねー。

ポキオ M5STACK

これで、ドヤ顔して勉強会にいけますね!

M5Stack Basic

M5Stack Basic

M5STACKことはじめ

エムファァァァイブスタアアアアアック!!!

ポキオ M5STACK

買ってしまった

M5Stack Basic

M5Stack Basic

M5STACKだけは絶対に買わない、そう思ってました。でも、気づいたら買ってました。どうも、ポキオです。買ったのは一番に安いBasic。色黒の子です。

ポキオ M5STACK

コンパクトなパッケージングをキープしながら、拡張性も両立しているところがすごいですねぇ。

ポキオ M5STACK

中身もギュッと詰まっています。

ポキオ M5STACK

unboxingの儀はこのくらいにして、とりあえずHello Worldしてみましょう。

M5Cloudにつないでみる

Arduino IDEでも開発できますが、せっかくなのでM5Cloudで開発してみます。Web上のIDEで、コンパイルとバイナリの流し込みもオンラインで実行できてしまいます。わざわざUSBで接続する必要は一切ありません。

github.com

このページのとおりにやれば簡単にセットアップでき・・・ると思ってたんですが、相変わらずmacOSのrootless系の問題にぶち当たったので、Pixel OSが動いているマシンでセットアップしてみました。基本的に公式ガイドに書いてある手順と変わりません。

ファームウェアのダウンロード

github.com

binファイルをダウンロード

esptoolでファームを焼く

まずpipesptoolをインストール。

pi@pokiiio-pixel:~ $ sudo pip install esptool

そんでもって、M5STACKをラップトップにUSB接続してから、M5Cloud用のファームを焼きます。

pi@pokiiio-pixel:~ $ esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash
pi@pokiiio-pixel:~ $ esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash --flash_mode dio -z 0x1000 ./Downloads/m5cloud-20180516-v0.4.0.bin 

これでOK。

M5STACKとM5Cloudをリンクさせる

github.com

ここに書いてあることと同じなので詳細は割愛。

  • M5STACKがWi-Fi APとして動作するので、スマホでアクセスして家のAPなどを登録
  • M5STACK上にPIN CODEが表示されるので、M5Cloud上でそのPIN CODEを入力してリンクする
  • あとはM5Cloud上でプログラミングするだけ

Hello World

M5Cloud上で、MicroPythonでプログラミング。

ポキオ M5STACK

コード自体はシンプル。

from m5stack import lcd

lcd.clear()
lcd.setCursor(0, 0)
lcd.setColor(lcd.WHITE)
lcd.print("Hello, pokio!")

これで、Upload & Runすると・・・

ポキオ M5STACK

うぇーい!

京急遅延ガジェット「ダァ3号」が山手線に対応しました

まさかの国鉄対応。

ポキオ 京急 ダァ3号

ポキオ、異動する

いままでは京急一本で行けるオフィスだったのですが、今回異動をしましてオフィスも変わり、通勤経路に山手線に乗るというイベントが発生してしまいました。なので、ダァ3号を致し方なく山手線に対応させてみました。

安心と信頼のNode-RED

ポキオ 京急 ダァ3号

[{"id":"3ad520c3.545e78","type":"tab","label":"フロー 1","disabled":false,"info":""},{"id":"80cbf517.c17cc8","type":"twitter-credentials","z":"","screen_name":"@pokiiiwo"},{"id":"3eb4297b.7362fe","type":"twitter in","z":"3ad520c3.545e78","twitter":"80cbf517.c17cc8","tags":"@keikyu_official","user":"user","name":"京急公式Twitterに新しい投稿","topic":"tweets","inputs":0,"x":180,"y":100,"wires":[["60533152.38f37"]]},{"id":"22429d61.35d622","type":"inject","z":"3ad520c3.545e78","name":"京急 + 山手線","topic":"","payload":"","payloadType":"date","repeat":"600","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":140,"wires":[["60533152.38f37"]]},{"id":"60533152.38f37","type":"http request","z":"3ad520c3.545e78","name":"京急運行情報取得","method":"GET","ret":"txt","url":"http://unkou.keikyu.co.jp","tls":"","x":150,"y":180,"wires":[["77d3de0e.446b9"]]},{"id":"77d3de0e.446b9","type":"function","z":"3ad520c3.545e78","name":"京急運行情報パース","func":"msg.payload = msg.payload.split(\"<div class=unko-panel>\")[1];\nmsg.payload = msg.payload.split(\"</div>\")[0];\nmsg.payload = msg.payload.replace(/\\r?\\n/g,\"\");\nmsg.keikyu = msg.payload;\nmsg.payload = null;\nreturn msg;","outputs":1,"noerr":0,"x":160,"y":220,"wires":[["49eb60e7.4544c"]]},{"id":"49eb60e7.4544c","type":"http request","z":"3ad520c3.545e78","name":"JR運行情報取得","method":"GET","ret":"txt","url":"https://transit.yahoo.co.jp/traininfo/detail/21/0/","tls":"","x":140,"y":260,"wires":[["8119d93e.e43388"]]},{"id":"8119d93e.e43388","type":"function","z":"3ad520c3.545e78","name":"JR運行情報パース","func":"msg.payload = msg.payload.split(\"\\\"og:description\\\" content=\\\"\")[1];\nmsg.payload = msg.payload.split(\"(\")[0];\nmsg.payload = msg.payload.replace(/\\r?\\n/g,\"\");\nmsg.yamanote = msg.payload;\nmsg.payload = null;\nreturn msg;","outputs":1,"noerr":0,"x":150,"y":300,"wires":[["1fbe8bb5.87f034"]]},{"id":"6f00e56f.8150ec","type":"exec","z":"3ad520c3.545e78","command":"python /home/pi/GitHub/TextToEPaper/text_to_e_paper.py","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"電子ペーパーに表示","x":480,"y":280,"wires":[[],[],[]]},{"id":"1fbe8bb5.87f034","type":"function","z":"3ad520c3.545e78","name":"keikyu, yamanote -> payload","func":"msg.payload = \"京浜急行 \\\"\" + msg.keikyu + \"\\\" 山手線 \\\"\" + msg.yamanote + \"\\\"\";\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":140,"wires":[["71e04a63.eb8114"]]},{"id":"7dac4a68.ffcf04","type":"inject","z":"3ad520c3.545e78","name":"","topic":"起動時","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"5","x":150,"y":60,"wires":[["60533152.38f37"]]},{"id":"71e04a63.eb8114","type":"switch","z":"3ad520c3.545e78","name":"差分があった場合だけ更新","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"info","vt":"global"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":500,"y":180,"wires":[["b6900e34.b64bb"],[]]},{"id":"b6900e34.b64bb","type":"function","z":"3ad520c3.545e78","name":"globalにセット","func":"global.set(\"info\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":460,"y":220,"wires":[["6f00e56f.8150ec"]]}]
  • メインのシーケンスはNode-REDで組み立てています。
  • (シーケンシャルですが)京急と山手線の運行情報をWebから取得しています
  • 山手線の運行情報はYahoo!から拝借
  • Global変数に、直前に表示させていた文字列を覚えておき、不要な画面書き換えを抑制

ちなみに、表示ロジックも変更。

github.com

Pythonスクリプトの引数とその数から、よしなに情報表示してくれます。よしなに。

番外編

こういうこともできます。

#iotlt も第40回!

A post shared by pokio (@pokiiiiio) on

エサヒィ。

エセヒィ #iotlt

A post shared by pokio (@pokiiiiio) on

GooglePhotoMarkdownerを更新しました

ちょっとだけ改善。

pokiiio googlephotomarkdowner

前回はオレオレElectronアプリを作りました

relativelayout.hatenablog.com

Google Photosにアップした写真を秒で、Markdown記法などでブログに埋め込める形に変換する俺得アプリを作りました。今回の改善ポイントは大きく2点です。

  • macOSで何故か出来ていなかったコピーアンドペーストに対応
  • 前回使った画像サイズ・代替テキスト・タイトルを永続化するように変更

地味に使いやすくなりました。

github.com

macOSで何故か出来ていなかったコピーアンドペーストに対応

なぜか出来てなかった。

pracucci.com

上記のワークアラウンドを鵜呑みにして、コードに追加しています。appのreadyで、以下のようにメニューを追加して、コピペに対応しています。

app.on('ready', function () {
    mainWindow = new BrowserWindow({ width: 800, height: 600 });
    mainWindow.loadURL('file://' + __dirname + '/index.html');
    // mainWindow.toggleDevTools();
    mainWindow.on('closed', function () {
        mainWindow = null;
    });

    var template = [{
        label: "Application",
        submenu: [
            { label: "About Application", selector: "orderFrontStandardAboutPanel:" },
            { type: "separator" },
            { label: "Quit", accelerator: "Command+Q", click: function () { app.quit(); } }
        ]
    }, {
        label: "Edit",
        submenu: [
            { label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
            { label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
            { type: "separator" },
            { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
            { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
            { label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
            { label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
        ]
    }
    ];

    Menu.setApplicationMenu(Menu.buildFromTemplate(template));
});

前回使った画像サイズ・代替テキスト・タイトルを永続化するように変更

electron-json-storageJSONデータを永続化するようにしています。

npm install electron-json-storage --save

いつもどおり、こんな感じでインストールします。

var storage = require('electron-json-storage');
var data = {};
data.photoSize = "hogehoge";
data.photoAlt = "fugafuga";
data.photoTitle = "piyopiyo";
storage.set('config', data, function (error) {
    if (error) throw error;
    // 保存完了
});

保存はこんな感じで、JSONオブジェクトを作って保存します。

var storage = require('electron-json-storage');
storage.get('config', function (error, data) {
    if (error) throw error;
    if (Object.keys(data).length === 0) return;
    // dataを読み込む
});

読み込みはこんな感じで簡単に出来ます。

というわけで

オレオレElectron、最高ですね。

オレオレElectronアプリを作ってGooglePhotosの写真をブログに貼り付ける処理を効率化する

オレオレ。

GooglePhotoMarkdowner

Google Photosの写真をブログに

皆さんはブログに載せる写真をどこに保存してますでしょうか。私は面倒くさいので、よくGoogle Photosに写真をアップロードして、StackEditなどでその写真へのリンクを取得してMarkdownでブログに埋め込んでいます。

ただ、StackEditも最近UIをガラ変させてきたのが嫌なのと、StackEditに頼らずとも簡単にGoogle Photosの写真をブログに埋め込むべく、オレオレアプリをElectronで書いてみました。

コードの内容はこれと同じです。 relativelayout.hatenablog.com

GooglePhotoMarkdowner

github.com

文字通り、Google Photos上の写真へのリンクからMarkdown記法による画像埋め込みコードを生成します。

こんな感じです。

GooglePhotoMarkdowner

生成物は3つ。

まずは、Google PhotoへのリンクURLから、下記のような誰でもアクセスできるURLを生成します。

https://lh3.googleusercontent.com/xxxxx=s600

次に、同時にMarkdown記法の文字列も生成します。

![GooglePhotoMarkdowner](https://lh3.googleusercontent.com/xxxxx=s600 "GooglePhotoMarkdowner")

念のため、HTML記法の文字列も生成します。

<img src="https://lh3.googleusercontent.com/xxxxx=s600" alt="GooglePhotoMarkdowner" title="GooglePhotoMarkdowner">

はい、これで執筆が捗る。

「Androidのメモとか」は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。

このブログは個人的なメモ書きであったり、考えを書く場所であります。執筆者の所属する団体や企業のコメントや意向とは無関係であります。また、このブログは必ずしも正しいことが書かれているとは限らず、誤字脱字や意図せず誤った情報を載せる場合がありえます。それが原因で読者が不利益を被ったとしても、執筆者はいかなる責任も負いません。ありがとうございます。