Kindle Fire HD8 (2017) をandroidタブレット化

Kindle Fire HD8 (2017)を購入しました。

めちゃくちゃ安いですよこれ!

普段でもPrime会員なら4000円OFFですが、セールの時は更に安くなるので、急がない方はセールを待った方が更にお得に手に入ります。

Fire HD 8 タブレット (Newモデル) 16GB、ブラック

Fire HD 8 タブレット (Newモデル) 16GB、ブラック

 

 フィルムは家だけで使うので不要と思いましたが、カバーを買うことにしました。

 買ったカバーはこちらです。

Amazon Fire HD 8 (Newモデル) 用カバー ブラック

Amazon Fire HD 8 (Newモデル) 用カバー ブラック

 

カバーにしては値が張るのですが、結果的にはこの組み合わせで正解でした。

このカバーはスタンドになります。これが動画を見るのに最適です。半面この仕組みの為に磁石が入っているので重くなり、持ち運びには不向きというわけです。

 

さて、最初はPrimeビデオを見られればいいなーくらいに考えていたのですが、使ってみると色々な不満が出てきます。

結局のところKindle Fireが採用しているFireOSというものは、ベースはAndroidですが、Amazonのコンテンツを利用する、あるいはAmazonに注文するという機能に特化しているんですよね。

 

まず、Amazon公式からアプリをダウンロードできるのですが、置いてあるアプリの数が少なく、内容的にも欲しいものがありません。

一番不満だったのは、とにかく日本語入力が使いにくいとうことです。日本語どころかソフトウェアキーボードが何か変です。アンダーバー"_"を探すのに一苦労。

これではストレスが溜まりまくるので、まずこれをなんとかしようと、Google Play ストアからGoogle日本語入力をインストールしようとしました。しかし、Google Play ストアからはアプリをインストールできないようになっているじゃないですか!

 

ということでなんとかする方法は無いかとググってみると、まあ訳の分からないやり方ばかりヒットします。海外サイトの真似でしょうか?やってる本人も何やってるかわかってないんじゃないかと思うような手順ばかり。

 

いくつかのサイトをよく読んでみて、僕自身が信用できると思ったこちらのサイトを参考にさせていただくことにしました。

Kindle Fire HD8(第6世代)にPlayストアをインストール!オススメの導入方法 | 毎日検討中

現在は第7世代(2017年版)の追記がありますが、僕が作業をしたときには第6世代までの内容でした。

第6世代用のパッケージを導入して、その後アップデートをかけ、問題なく使えています。

 

GPSが付いていないので、ナビアプリなどは使えませんが、家の中で使うタブレットとしては十分です。

絶対に入れたいのは

です。

Googleのアカウントはこの端末専用のものにしています。

それで特に不便なことはありません。

そして、安い端末なので、子供用にしても惜しくありません。

を入れると閲覧制限が掛けやすく、操作感も子供向けにわかりやすいものになります。

我が家でもインストールして子供が触っています。

 

ということで、我が家のKindle Fire HD8は、格安androidタブレットとして活躍しています。

ラズパイのC#でbitFlyerの板を取得(Json.NETでデシリアライズ)~ビットコイン自動売買の準備~

「ラズパイのC#でbitFlyerの板を取得」の続きです。
今回はJson.NETを使ってbitFlyerの板データをC#のオブジェクトに変換してみます。
標準ライブラリでもJSON形式のデータを扱えますが、どうやら性能的にはJson.NETが優れているようなので、これを使うことにします。

Json.NETはこちらからダウンロードします。
www.newtonsoft.com


とりあえずDownloadボタンをクリックするとこちらのポップアップが開きます。
ダイレクトダウンロードを選択します。
f:id:zhihong:20170910222124p:plain
解凍して得られる"Bin/net45/Newtonsoft.Json.dll"が必要なdllです。
適当なディレクトリに置いておきます。


板のユーザモデルはこんな感じです。
仲値,買い気配配列,売り気配配列がメンバ変数になっています。
気配は価格とサイズをメンバ変数に持ったクラスです。

[JsonObject]
public class Board
{
    [JsonProperty("mid_price")]
    public string MidPrice { get; set; }

    [JsonProperty("bids")]
    public Quote[] Bids { get; set; }

    [JsonProperty("asks")]
    public Quote[] Asks { get; set; }

    [JsonObject]
    public class Quote
    {
        [JsonProperty("price")]
        public string Price { get; set; }

        [JsonProperty("size")]
        public string Size { get; set; }
    }
}


シリアライズ部分です。
responseがJSON形式の文字列です。

Board board = JsonConvert.DeserializeObject<Board>(response);


ソースコード全体はこんな感じになります。
最良気配から5本だけ表示するようにしてみます。

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;

[JsonObject]
public class Board
{
    [JsonProperty("mid_price")]
    public string MidPrice { get; set; }

    [JsonProperty("bids")]
    public Quote[] Bids { get; set; }

    [JsonProperty("asks")]
    public Quote[] Asks { get; set; }

    [JsonObject]
    public class Quote
    {
        [JsonProperty("price")]
        public string Price { get; set; }

        [JsonProperty("size")]
        public string Size { get; set; }
    }
}

class Sample
{
    static readonly Uri endpointUri = new Uri("https://api.bitflyer.jp");

    public static async Task GetBoard()
    {
        var method = "GET";
        var path = "/v1/getboard";
        var query = "";

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
        {
            client.BaseAddress = endpointUri;
            var message = await client.SendAsync(request);
            var response = await message.Content.ReadAsStringAsync();

            Board board = JsonConvert.DeserializeObject<Board>(response);

            Console.WriteLine("mid_price: {0}", board.MidPrice);
            Console.WriteLine("asks");
            for(int i=0; i < board.Asks.Length; ++i)
            {
                Board.Quote quote = board.Asks[i];
                Console.WriteLine("    price: {0}, size: {1}", quote.Price, quote.Size);
                if (5 == i) break;
            }
            Console.WriteLine("bids");
            for(int i=0; i < board.Asks.Length; ++i)
            {
                Board.Quote quote = board.Bids[i];
                Console.WriteLine("    price: {0}, size: {1}", quote.Price, quote.Size);
                if (5 == i) break;
            }
        }
    }

    static void Main(string[] args)
    {
        GetBoard().Wait();
    }
}


コンパイル
リソースにNewtonsoft.Json.dllを追加指定します。

$ mcs getboard_json.cs -r:/usr/lib/mono/4.6.2-api/System.Net.Http.dll,/usr/lib/mono/4.6.2-api/Facades/System.Threading.Tasks.dll,./Newtonsoft.Json.dll


実行

$ ./getboard_json.exe
mid_price: 443180.0
asks
    price: 443299.0, size: 0.14522859
    price: 443399.0, size: 0.41834898
    price: 443400.0, size: 0.5607
    price: 443445.0, size: 0.00319999
    price: 443460.0, size: 0.083
    price: 443505.0, size: 0.8059
bids
    price: 443061.0, size: 0.1562
    price: 443002.0, size: 12.0
    price: 443001.0, size: 0.33477141
    price: 443000.0, size: 0.50839729
    price: 442603.0, size: 1.96
    price: 442510.0, size: 27.4
$

よさそうですね。

ラズパイのC#でbitFlyerの板を取得~ビットコイン自動売買の準備~

前回はラズパイで最新のC#(Mono)を実行できるよ整え、bitFlyerからmaket一覧を取得しました。 
zhihong.hatenablog.com

今回は板を取得してみたいと思います。

前回のコードを少し修正するだけです。


エディタを開いて

$ vi getboard.cs


こんな感じに書きます。

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

class Sample
{
    static readonly Uri endpointUri = new Uri("https://api.bitflyer.jp");

    public static async Task GetBoard()
    {
        var method = "GET";
        var path = "/v1/getboard";
        var query = "";

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
        {
            client.BaseAddress = endpointUri;
            var message = await client.SendAsync(request);
            var response = await message.Content.ReadAsStringAsync();

            Console.WriteLine(response);
        }
    }

    static void Main(string[] args)
    {
        GetBoard().Wait();
    }
}


コンパイルします。

$ mcs getboard.cs -r:/usr/lib/mono/4.6.1-api/System.Net.Http.dll,/usr/lib/mono/4.6.1-api/Facades/System.Threading.Tasks.dll


実行です。

$ ./getmakets.exe


API PlaygroundでSubmitした時とは異なり、実際はダーッと出ますね。
BIDの先頭
f:id:zhihong:20170906232752p:plain

ASKの先頭
f:id:zhihong:20170906232833p:plain

末端
f:id:zhihong:20170906232904p:plain

正直ここまでは要らないですね。
最良気配から10本くらいで十分です。

ラズパイでC#からbitFlyerのAPIを呼び出す~ビットコイン自動売買の準備~

ラズパイでビットコインの自動トレードができたら楽しそうなので、ちょっと試してみました。

記事の概要:ラズパイ3に最新のC#(Mono)をインストールしてbitFlyerのAPIサンプルを実行
ビットコイン取引所:bitFlyer
OS:Raspbian GNU/Linux 8.0 (jessie)
言語:C#

取引所は僕が今口座を持っているbitFlyerです。
最近はほとんどの取引所がAPIを公開していますね。
プログラマには楽しい時代になりました。

※自分の備忘録を兼ねて実施した順番通りに書いていますが、1~4は失敗手順です。時間の無い方は5以降を参考にしてください。

1.Monoのインストール

まずは一般的な手順通りに最新のMonoをインストールします。

$ sudo apt-get update
$ sudo apt-get install mono-complete

2.バージョン確認

3.2.8になりました。

$ mono -V
Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-10)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: normal
Notifications: epoll
Architecture: armel,vfp+hard
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen

3.HelloWorld

とりあえずHelloWorld.csを書いて実行してみます。

$ cat HelloWorld.cs
using System;
public class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello World!");
    }
}
$ gmcs HelloWorld.cs
$ mono HelloWorld.exe
Hello World!

とりあえず動きました。

4.APIのサンプルを実行

ビットコイン取引所【bitFlyer Lightning】
から、一番上にあるgetmarketsのサンプルを実行してみます。

オリジナルのサンプルコード

こちらはサンプルそのままです。

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

class Sample
{
    static readonly Uri endpointUri = new Uri("https://api.bitflyer.jp");

    public static async Task Main()
    {
        var method = "GET";
        var path = "/v1/getmarkets";
        var query = "";

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
        {
            client.BaseAddress = endpointUri;
            var message = await client.SendAsync(request);
            var response = await message.Content.ReadAsStringAsync();

            Console.WriteLine(response);
        }
    }
}

修正したサンプルコード

"public static async Task Main()"の"Main"を"GetMarkets"に変更し、
"static void Main(string[] args)"から呼び出すように変更しています。

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

class Sample
{
    static readonly Uri endpointUri = new Uri("https://api.bitflyer.jp");

    public static async Task GetMarkets()
    {
        var method = "GET";
        var path = "/v1/getmarkets";
        var query = "";

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
        {
            client.BaseAddress = endpointUri;
            var message = await client.SendAsync(request);
            var response = await message.Content.ReadAsStringAsync();

            Console.WriteLine(response);
        }
    }

    static void Main(string[] args)
    {
        GetMarkets().Wait();
    }
}

これをgetmarkets.csに保存してコンパイルしてみると……。

$ gmcs getmakets.cs -r:/usr/lib/mono/4.5/System.Net.Http.dll,/usr/lib/mono/4.5/Facades/System.Threading.Tasks.dll
getmakets.cs(10,25): error CS0731: The type forwarder for type `System.Threading.Tasks.Task' in assembly `mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' has circular dependency
getmakets.cs(10,30): error CS1983: The return type of an async method must be void, Task, or Task<T>
getmakets.cs(10,30): warning CS0028: `Sample.Main()' has the wrong signature to be an entry point
Compilation failed: 2 error(s), 1 warnings
pi@raspberrypi:~/bf $

ということで、全然動かないですね。
サンプルで使っているSystem.Threading.Tasksのasync/awaitはC#5.0系から使えるとのことで、先ほど最新化したMonoではバージョンが低いんですね。

5.Monoを公式よりアップデート

ということで、Mono Project公式からラズパイ用の最新版Monoを取得することにします。

まずは公式ページを参照してください。
http://www.mono-project.com/download/#download-lin-raspbian
5.2.0の安定板をダウンロードできますね。(2017/09/02現在)

ダウンロードページにあるこちらのコマンドを順番に実行します。

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
$ echo "deb http://download.mono-project.com/repo/debian raspbianjessie main" | sudo tee /etc/apt/sources.list.d/mono-official.list
$ sudo apt-get update

6.インストールされるバージョンの確認

こんどはインストール前にちゃんと確認します。

$ apt-cache policy mono-complete
mono-complete:
インストールされているバージョン: 3.2.8+dfsg-10
候補: 5.2.0.215-0xamarin10+raspbian8b1
バージョンテーブル:
5.2.0.215-0xamarin10+raspbian8b1 0
500 http://download.mono-project.com/repo/debian/ raspbianjessie/main armhf Packages
*** 3.2.8+dfsg-10 0
500 http://mirrordirector.raspbian.org/raspbian/ jessie/main armhf Packages
100 /var/lib/dpkg/status

5.2.0が入りそうですね。

7.Mono5.2のインストール

そして再びapt-getです。

$ sudo apt-get install mono-complete

僕の場合は先に3系をインストールしていたので、途中で警告が出てインストールが止まってしまいましたが、そのときにメッセージに出たコマンドを実行したところ、問題なくインストールできました。
3系を入れなかった人はすんなりインストールできると思います。

8.改めてバージョン確認

5.2.0が入りました!

$ mono -V
Mono JIT compiler version 5.2.0.215 (tarball Mon Aug 14 16:59:51 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: normal
Notifications: epoll
Architecture: armel,vfp+hard
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen (concurrent by default)

9.コンパイル

コンパイラが変わっています。
gmcsでもdmcsでもなくmcsなんですね。
再度サンプルコードをコンパイルしてみます。

$ mcs getmakets.cs -r:/usr/lib/mono/4.6.1-api/System.Net.Http.dll,/usr/lib/mono/4.6.1-api/Facades/System.Threading.Tasks.dll

エラーが出なくなりました!

10.実行

いよいよ実行です!

$ ./getmakets.exe
[{"product_code":"BTC_JPY"},{"product_code":"FX_BTC_JPY"},{"product_code":"ETH_BTC"},{"product_code":"BCH_BTC"},{"product_code":"BTCJPY08SEP2017","alias":"BTCJPY_MAT1WK"},{"product_code":"BTCJPY15SEP2017","alias":"BTCJPY_MAT2WK"}]

取れました!
ただの市場マスタなのでちょっと面白くはないですが、とりあえずAPIを叩いて結果を取得できました!

これで遊ぶための準備が整ったので、これからいろいろ試してみようと思います。

Aspire One Cloudbook 11のWindows10をCreators Updateに更新

Acer Aspire One Cloudbook 11 AO1-131-F12N/KK のWindows10をCreators Updateに更新できました。

 

Cドライブの空き容量が8GB必要とのメッセージが出るので、最初はギリギリ8GBを空けて更新をかけましたが、インストールの途中で失敗しました。

10GB空けて再トライしたところ、うまくいきました。

それなら最初から10GBが必要と言ってくれればいいのに……。時間を無駄にしました。

 

10GB空けるのはなかなか苦しかったのですが、後から入れなおせるものは全て消し、使っていないプリインストールのアプリも全て消す勢いで進めればなんとかなります。

僕はこんな感じに消しました。

acer製プリインストールアプリ全て

・Kinsoft Office

Chromeのキャッシュ

 ※Chrome自体の再インストールが億劫でなければまるごと消してもよいでしょう

iTunes

 ※データフォルダは元々シンボリックリンクで別ドライブに配置している

 iTunesのバックアップデータ保存先をCドライブ以外に指定する方法 | SimpleStock3.1

iCloud

・ユーザフォルダの隠しフォルダ"AppData"のうち、フォルダ名にAppleと付くもの全て

マカフィー(WindowsDefenderで十分)

 

もちろんゴミ箱やディスクのクリーンアップは実行します。

 

C:\OEMフォルダは外付けHDDに移動しました。

 

アップデート後、約10GBのwindows.oldフォルダができましたが、これはクリーンアップで消せるフォルダです。

つまり、アップデート前に空けた容量そのまま、アップデート後も空き容量として維持できています。

 

Creators Updateで何をするというわけでもないのですが、なんとなく全体的な動作がキビキビしているように感じます。

このマシンは元々もっさり感が強いので、違いを体感できます。

今後のメジャーアップデートでは容量の問題でアップデートできる保証はありません。

今回は無理してでもアップデートしておいた方がよいと思います。

ETC2.0って典型的お役所仕事

 

車にETCを付けるときに、2.0にするか1.0にするか悩んだのですが、結局1.0にしました

どうも説明を聞いていると、自分には全く不要なものに思えたのです

だって、

「1,000km先の渋滞情報がわかります!」

って飛行機かよ!

 

時速100kmで走り続けて10時間かかる場所の渋滞情報でしょう!?

要る!?欲しい人いる?

 

「SAの特定の駐車場に停めるとご当地情報のホームページが自動で開きます」

あのさぁ……。

その情報もらって高速降りると思う?

 

もうこういうのいいから

今の機能で十分ですから

 

お役所仕事って言われてもしょうがないと思いません?

 

 高い……。

こっちでいいです。