読者です 読者をやめる 読者になる 読者になる

echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

Masto.netを使った簡単なMastodonのテスト

GWは9連休!…とか思っていたら、気づいたらもう半分過してしまい、若干凹んでいます。
働きたくないでござる

…さて、最近ネットやらTwitterで、やたら「Mastodon」という言葉を目にするようになりました。
ちなみに「Mastodon」の特徴を簡単に説明すると

てな感じです。

で、APIも公開されていて、いろんな人が各環境でのライブラリをすでに作っているわけで、あすかさんのブログにも、こんなものが紹介されていました。
kmycode.hatenablog.jp

「Mastonet」という、Guillaume Lacasa氏というフランス人の方が作成したC#用のMastodonライブラリです。
github.com

というわけで、どうせ寝てるだけだしMastodonの理解もかねて、僕も作ってみようと思いました。


Mastonetのインストール
Visual Studio使ってるなら、NuGet経由でインストールできます。
ただしGithubのREADME.md内にも「A preview version is available on Nuget : https://www.nuget.org/packages/Mastonet
とある通り、「プレリリースを含める」チェックボックスにチェックを入れないと検索されないので、それだけは注意です。

とりあえずビューとソース本文
f:id:Makky12:20170503192330p:plain

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mastonet;
using System.Diagnostics;

namespace MastodonApp
{
    public partial class Form1 : Form
    {
        private String timeLine = String.Empty;
        private TimelineStreaming stream = null;

        private enum StreamStetus
        {
            Not_Login = 0,
            Not_Start = 1,
            Now_Starting = 2,
        }

        private StreamStetus stream_status = StreamStetus.Not_Login;

        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            var id = textBox1.Text;
            var pass = textBox2.Text;

            if (String.IsNullOrEmpty(id) || String.IsNullOrEmpty(pass))
            {
                MessageBox.Show("IDまはたパスワードが未入力です。");
                return;
            }

            try
            {
                var ret = await this.MastoNet_Run(id, pass);

                timer1.Interval = 5000;
                timer1.Enabled = true;
                timer1.Tick += new System.EventHandler(timer1_Tick);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private Task<int> MastoNet_Run(String id, String pass)
        {

            return Task.Run(async () =>
            {
                if (stream_status != StreamStetus.Now_Starting)
                {
                    if (stream_status == StreamStetus.Not_Login)
                    {
                        var authClient = new AuthenticationClient("friends.nico");
                        var appRegistration = await authClient.CreateApp("MastodonApp", Scope.Read | Scope.Write | Scope.Follow); 
                        var auth = await authClient.ConnectWithPassword(id, pass);

                        var client = new MastodonClient(appRegistration, auth);
                        stream_status = StreamStetus.Not_Start;

                        stream = client.GetPublicStreaming();

                        var dispString = String.Empty;

                        stream.OnUpdate += (sender, e) =>
                        {
                            var dispName = e.Status.Account.DisplayName;
                            var content = e.Status.Content;

                            dispString = dispName + "\r\n" + content + "\r\n" + "\r\n";
                            this.timeLine += dispString;
                        };
                    }

                    stream.Start();
                    this.stream_status = StreamStetus.Now_Starting;
                }
                return 0;
            });
        }

        private void timer1_Tick(object sender, System.EventArgs e)
        {
            this.textBox3.Text = this.timeLine;
        }

        protected void button2_Click(object sender, EventArgs e)
        {
            if (stream != null && this.stream_status == StreamStetus.Now_Starting)
            {
                stream.Stop();
                this.stream_status = StreamStetus.Not_Start;
            }
        }
    }
}

と、ビューとソースを記載しましたが、重要なのはソースの「MastoNet_Run()」の内部です。

  • アプリ登録
var authClient = new AuthenticationClient("friends.nico");
var appRegistration = await authClient.CreateApp("MastodonApp", Scope.Read | Scope.Write | Scope.Follow); 

クライアント作成には「ClientID」「ClientSecret」という2つの値が必要で、これを取得するためにアプリ登録を行います。
アプリ登録は上記の通り、MastodonインスタンスのAuthenticationClientクラスを作成した上で、そのCreateApp()メソッドを実行すればOKです。

  • 認証とクライアント作成
var auth = await authClient.ConnectWithPassword(id, pass);
var client = new MastodonClient(appRegistration, auth);

認証は、OAuthを使用する方法と、メアドとパスワードで行う方法があり、後者は上記の通りauthClient.ConnectWithPassword()メソッドを実行すればOK。
※ただし後者は作者曰く「非推奨」とのことなので、問題なければOAuthを使ったほうがよいみたいです。

前者の場合、作者のREADME.mdによれば

  1. AuthenticationClientクラスのOAuthUrl()メソッドを実行して、urlを取得
  2. 1で取得したurlにアクセスして、APICodeを取得
  3. 2で取得したAPICodeを引数にして、AuthenticationClientクラスのConnectWithCode()メソッドを実行

を実行すればOK…のはずなんですが、なぜか僕の環境ではうまくいかなかったので、今後の宿題にします。*1

で、クライアント作成ですが、ここまでで実行したCreateApp()メソッドの戻り値とConnectWith***()メソッドの戻り値を引数にして、MastodonClientクラスのインスタンスを作成するだけです。

  • タイムラインのストリーミングと更新通知
stream = client.GetPublicStreaming();
var dispString = String.Empty;

stream.OnUpdate += (sender, e) =>
{
    var dispName = e.Status.Account.DisplayName;
    var content = e.Status.Content;
};

タイムラインのストリームは、先程作成したクライアントに各タイムラインストリーム取得用のメソッドが用意されているので、それを使用します。
(今回はGetPublicStreaming()メソッドで、連合タイムラインのストリームを取得しています。)
で、更新された場合、ストリームのOnUpdate()イベントハンドラーが呼ばれるので、その中に追加でやりたい処理を記載します。

なお、上記の通り、引数e(StreamUpdateEventArgs)の

  • Status.Account.DisplayNameに「ユーザー名」
  • Status.Contentに「本文」

が取得できます。

最後に、ストリームのstart()メソッドで、実際にストリーミングを開始します。(なおご想像の通り、stop()メソッドでストリーミングの停止ができます。)
※この時「この呼び出しを待たないため、現在のメソッドの実行は…」という警告が出るかもしれませんが、無視してOKです。

なお、上記ソースの実行結果はこちら。*2
f:id:Makky12:20170503200012p:plain
まあ、いろんな方がブログなどで書いていたので知っていましたが、本文がHTMLタグ付きなんですよね…
本来はその対処も追加しないといけないですが、今回はまあいいでしょう。

というわけで、Masto.netを使用した、簡単なMastodonアプリの作成でした。
せっかくのGW、いろんな方がMastodonライブラリを作成されているので、機会があればMastodonアプリやライブラリの作成に挑戦するのもいいかもしれません。

さて明日からは、そろそろ本腰入れてXamarinプロジェクトを再開しないと。

…なんか普段より、むしろGWのほうがコーディング時間が長いような???

*1:これに限らず、インスタンス環境に依存する?事項がなんか多かった気がします。
初めに使用したインスタンスでは、url&API Codeの取得は問題なく出来たんですが…

あと、初めに使用したインスタンスではCreateApp()メソッド実行時に、強制的に接続が切断されていたのですが、friends.nicoインスタンスにしたら、ソースは1行も変えてないのに、全く問題なくなった…とか。これらは今後、要調査です。

*2:他の方がコンソールアプリでやっていたため、僕はフォームアプリで作成しましたが、手っ取り早く試すだけならコンソールアプリがおすすめです。
フォームアプリだどスレッドセーフとか非同期処理時のフォームコントロールプロパティ設定とかの関係で、コンソールアプリより少々厄介です。

knockout.jsでMVVMを実装 その1

4月から新しいプロジェクトにアサインしたのですが、早くも「C#やれるって話だったのに全然やれないじゃん!話が違う!」みたいな事になってます…

でも「Xamarinやりたい!XAMLみたいにMVVMやりたい!」とか思ってたら、(C#ではないですが)「knockout.js」というJavaScriptフレームワークでMVVMを使用することになったので、復習がてらメモ。

knockout.jsとは?

  • JavaScriptのクライアントサイド MVVMフレームワーク
  • AngularJSに比べて、簡潔でとっつきやすく、敷居が低い…かも。(ただし簡潔だから良いというわけでもないので、「AngularJSより優秀だ!」なんて言うつもりはない。)
  • jQueryとは違い、HTML内の各コントロールはDOMで操作する。

 ※5/12訂正:DOMを操作するのではなく、バインドした変数を使って操作します。すいません。

公式サイト
日本語版ドキュメント(非公式)


インストールと実行
…とは書いたものの、別に「インストール」って程でもなく、jQueryなどと同様、knockout.js本体にscriptタグでリンクするだけ。
リンクもCDN形式でも良いし、公式サイトからダウンロードしたファイルへのパスを通してももちろんOK。

では、百聞は一見にしかずって事で、ソースをば。
なお面倒くさいソースが短かったので、*.htmlファイル内に直接スクリプトも書いてますが、本当はファイルを分けたほうが良いと思います。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./knockout-3.4.2.js"></script>
<script>
window.onload = function() {

    var self = this;

    var myViewModel = function() {
        self.myText = "Hello kockout.js!";
        
        onClick = function() {
            alert('Button is clicked.');
        };
    };

    var vm = new myViewModel();
    ko.applyBindings(vm);
};
</script>
</head>
<body>
<input type="text" data-bind="value: myText"><button data-bind="click: onClick">button</button><br>
<span data-bind="text: myText"></span><br>
</body>
</html>

とりあえず、HTMLタグ内に「data-bind」とかいう、明らかに見慣れない属性が目につきますが、これがknockout.jsのデータバインドの仕組みです。
この「data-bind」内で指定したプロパティ(value,text等)に、data-bind内で指定した変数(ここではmyText)に値を入れて、データバインドを実装しています。

で、JavaScriptの方を見ると、まず

var myViewModel = function()

という文がありますが、この「myViewModel」がいわばMVVMのViewModelの本体で、この中でHTML内の変数など、色々な定義をします。

そしてその中に

self.myText = "Hello kockout.js!";

とありますが、ここで「HTML内のmyTextに'Hello kockout.js!'を代入しなさい」という処理を実行しているわけです。

そしてmyViewModelの定義が終わったあとで、最後に

var vm = new myViewModel();
ko.applyBindings(vm);

として、myViewModelをapplyBindingsメソッドの引数に指定してますが、こうすることで実際にバインディングが実行されます。
f:id:Makky12:20170428204825p:plain

なお、HTMLの部品をDOMで操作するので、スクリプトは「window.onload()」や「document.ready()」など「すべての部品が読み込まれた」段階で実行するようにして下さい。
あと、applyBindingsメソッドの前の「ko」ですが、これはknockout.jsのグローバルオブジェクトで、knockout.js固有の処理は、この「ko」を介して実行します。


もちろん双方向バインディングも可能
ただ、鋭い方は気づいたかもしれませんが、これだとVM→Viewの一方通行です。
実際、このあとテキストボックスの値を変えても…
f:id:Makky12:20170428204832p:plain

はい。
テキストボックスは'Hello Xamarin!'に変わったのに、ラベルは'Hello knockout.js'のままです。
つまりView→VMバインディングが行われていません。

といっても、別にchangeイベントとかは全く必要なく、スクリプトを1行変えるだけで解決します。

window.onload = function() {

    var self = this;

    var myViewModel = function() {
        // self.myText = "Hello kockout.js!";
        self.myText = ko.observable("Hello kockout.js!");
        
        onClick = function() {
            alert('Button is clicked.');
        };
    };

    var vm = new myViewModel();[f:id:Makky12:20170428210141p:plain]
    ko.applyBindings(vm);

    alert("loaded.");
};

上記の通り、「self.myText =」の右辺を「ko.observable("Hello kockout.js!");」に変えるだけで、双方向バインディングの完成です。
ko.observable()メソッドの戻り値を変数に入れる事で、その変数はどこで変更されても、その変更がリアルタイムにViewやVMなどに反映されます。
※ちなみに、引数は初期値になりますので「デフォルトは未入力」という場合は、引数に何も指定しなければOKです。

実際、今度はちゃんとテキストボックスの値とラベルの値が連動します。
f:id:Makky12:20170428210141p:plain

ちなみに、ko.observable()を実行した変数の値の取得と設定(=getter,setter)ですが

var getter = vm.myText();  // getter
vm.myText('Hello C#!');    // setter

て感じで、[ViewModelの変数名].[変数名(引数なし)]だとgetter、[ViewModelの変数名].[変数名(引数あり)]だとsetterです。
(setterの場合、引数に指定した値が代入される。)

イベントについて
最後にイベントですが、まあ'button'コントロールにこれ見よがしに「data-bind="click: onClick"」なんて書いてるので、おおよそ見当はついたと思います。
まあそんな感じで「data-bind」に「イベント('click'など):関数 or 変数名」として、スクリプト内でそれに対応した関数を作成するだけです。

ちなみに(もうお分かりとは思いますが)、実行結果はこんな感じ。
f:id:Makky12:20170428211550p:plain

ただし、公式サイトを見る限り、こんな感じで直接イベント名を記載できるのは、'click'だけのようです…残念。(というか、それなら「イベント」じゃなくて「クリックイベント」としたほうが良かったような…)

※ただしchangeなど、その他のイベントも、実装する方法はもちろんありますので、ご安心を。(それについては、後日記載予定です。)

とまあ、かなり駆け足でknockout.jsの概要を記載しましたが、いかがですか?
せっかくのGW、ちょっと気になった方がいたら、試してみるのも良いかもしれません。(割と導入は簡単ですから。)


…でもやっぱり、C#は…いいぞ。(結局それ)

Visual Studio 2017でXamarinを動かしてみた。

ていうか、前回の記事から50日…
いくら仕事で体調が優れないからって、ちゃんと定期的に何か書かないと…

だれか、終業後も元気でいられる方法、教えてください…

Visual Studio2017正式リリース
先日、マイクロソフト本社で開催された、Infragistics Day 2017 Springに参加して、改めて「Xamarinは、いいぞ」って再認識したのですが、同時期にVisual Studio 2017が公開されました。

そして昨日、エクセルソフトの田淵さんが、こんな記事を公開されました。
ytabuchi.hatenablog.com

そこで、この記事を参考に、Visual Studio 2017でXamarinを動かしてみました。


ダウンロードとインストール
まずは公式サイトからインストーラーをインストールします。(今回は無料のCommunity版を選びましたが、もう少しビジネスが軌道に乗ったら、Pro版買いたいなあ。)

で、インストーラーを起動すると、下記画面になります。
f:id:Makky12:20170318212441p:plain

この中の「.netによるモバイル開発」にチェックを入れ、右の「概要」では下記項目にチェックを入れました。(個々の詳細については、先程の田淵さんの記事に詳しく説明がありますので、そちらを参考にされるとよいと思います。)

  • Xamarin Workbooks
  • Android SDK セットアップ (レベル23)
  • Java SE Development Kit (8.0.xxx.xx)
  • F# 言語サポート
  • Xamarin用ユニバーサルWindowsプラットフォーム

※F# 言語サポートは、必要ないなら不要かも。(僕は一応入れました)
※「Xamarinインストール&実行が重い!」と言われる根源である「Google Android エミュレーター」ですが、Android実機があり、Visual Studioで実機デバッグできる環境がある(作る)なら不要です。(実機デバッグ環境についてはこちらの「2.実機デバッグ環境構築」を参照)
またこれを入れないなら「Intel Hardware Accelerated Execution Manager (HAXM)」も必須ではないです。


実際に動かしてみる
インストールが完了したら、早速Visual Studio 2017を起動。(結構スタートページのデザインは変わっています。)
「新しいプロジェクト」から、[Visual C#]-[Cross-Platform>-[クロスプラットフォームアプリ (Xamarin.Forms またはネイティブ)]を選択します。

で、とりあえず何もせずにビルド&デバッグ
f:id:Makky12:20170318212502j:plain

動いた!

あれ?でも以前と違って、ContentPageをNavigationPageに(引数で)渡してないぞ?
というか、MainPageクラスのコンストラクタに、引数自体がない…

…という理由で焦ったので、少しソースコードを追ってみた所、違いが判明。
(上が前のソース、下が今回のソース)
f:id:Makky12:20170318212520p:plainf:id:Makky12:20170318212528p:plain

なるほど、今はContentPageを直書きではなく、MainPageクラス側でXAMLなどでガッツリContentPageを作り込んで、それをMainPageに渡すのか。
確かに、XAMLで作り込める分、この方が良いかも。
Infragisticsさんから4月に便利なツールも発売されるみたいですし。

※もちろん以前のように、ContentPageの直書きでもOKです。下の画像でコメントアウトしたソースのように、MainPage変数にContentPageのインスタンスを渡してあげるだけです。(↓その結果)
f:id:Makky12:20170318212512j:plain


Visual Studio 2015のプロジェクトを動かす
最後に、Visual Studio 2015のXamarinプロジェクトを直接開くと、こんなメッセージが表示されました。
f:id:Makky12:20170318212537p:plain

気にせずそのまま[OK]をクリックしたら、こんなレポートが表示されました。
f:id:Makky12:20170318212549p:plain

どうやら、Windows Phoneプロジェクトの移行に失敗したようですね。でも肝心のAndroidiOSプロジェクトは成功したようなので、問題ないでしょう。

このプロジェクトをビルド&デバッグすると、何も問題なく実機で動作しました。
(結果はさっきの画像と同じなので省略。)

あ、ちなみに実機デバッグ環境ですが、Visual Studio 2015で設定済ならば、特に何もしなくても、Visual Studio 2017で何の問題も無く動作しました。
(実機デバッグ環境についてはこちらの「2.実機デバッグ環境構築」を参照。←2度め)


それではみなさん、素敵なXamarinライフを!

最後に一言。


「Xamarinは、いいぞ。」

【2017/3/19追記】
このあとIoT(ラズパイ3)のプロジェクトをVisual Studio 2017で動かしたのですが、これについては変換のメッセージすら表示されることなく、Visual Studio 2015で作成したプロジェクトが全く問題なく動きました。
(「ユニバーサルWindowsプラットフォーム開発」や「Windows Core開発」あたりにチェックを入れればいいのかな?ちなみに「概要」はデフォルトのまま変えてません。)

今までのVisual Studioは、大抵リリース直後は何かあったのでインストールを見送っていたのですが、今回は今のところいい感じです。

ちなみに、合計40GB強のインストールに、下記スペックのPCで2時間ほどかかりました。参考までに。(Xamarinだけなら、こんなに容量ありません。)

■インストール先のスペック

  • OS:Windows10 Pro(64bit)
  • CPU:Intel Core i7-7500U
  • メモリ:8GB
  • HDD:1TB(約850GB空き)

一区切りしたので、色々考えてみる。

前の記事が昨年12月4日投稿…ちょっと期間が空きすぎですね。
定期的に書かないと、読んで貰えないってのに。

…まあ、別にサボってて書かなかったわけではないんですが。(精一杯の言い訳)

プロジェクト終了
はい。現在参画中のプロジェクトですが、今月末で終了となりました。
といっても、お世辞にも"Misssion completed"って訳ではなく、まあ半分「打ち切り」みたいなもんですが。

で、エージェント経由で理由を聞いたんですが、まあ色々ありました。
でも「協調性がない」とか、個人的には「どこが?」って感じです。
(結構言われるけど。でも「作業中に独り言が多い」というのは、反省しなければなりませんが。)

でも、コミュニケーションが全然噛み合わなかったり、そもそもベースの考え方が違ったりしていたので、その点が他メンバにはマイナスに写ったのかもしれません。(僕もかなり悩んでいて、メンタルが弱っていましたし…)

悩みに悩んだ末、記憶喪失に
さっき「今月末で終了」って言ったよね。アレは嘘だ。
正確に言えば、もう終わってます。

メンタルがかなり弱っていた事や、新しく処方された薬が合わなかった(?)などの不運もあったんですが、仕事中、急に「気持ち悪い…ていうか、猛烈な嘔吐感が」って思ったんです。
で、急いでトイレにダッシュしたんですが、間に合わず…って所までは覚えているんです。

…でも、そっから先の記憶がない(というか、全く思い出せない)んです。
ていうかマジで、あの日の記憶だけが頭からポッカリ抜けているんです。それくらいヤバイ状況でした。
(後で医師に聞いた所、一時は「命の危険もあった」らしいです。まあ個人的には「その日病院に行っていた」ことすら記憶に無いんですが…)*1

で、医師から診断書が出てしまったので、そりゃ「継続不可能」って判断しますわな、クライアントも。

初プロジェクト終了の感想
正直な話ですが、やっぱり人間関係にしろ、プロジェクトの空気にしろ「合う・合わない」は絶対あるんだ、と感じました。
そして「どうやっても無理」なプロジェクトだったら、その時点でバイバイしてしまったほうがいいです。

身勝手な言い方ですが、それが「フリー」の特権ですから。
合わないプロジェクトで無理して頑張るより、自分に合うプロジェクトで心の底から頑張ったほうが、絶対プラスになります。

あと「もう無理」と思った時点で、できるだけ早く対応してくれるエージェントだと、こちらとしても安心です。

反省点とか
でもやっぱり、反省点もあるのは事実で。

事前の情報で「フリーエンジニアは自分から積極的に意見を提案しないといけない」とか「言われたことやってるだけだったら、フリーの存在価値がない」っていうことを多く見かけたので、結構頑張って、自分から積極的なところを見せたのですが…

無理にそこまでする必要はないですね。

正直、フリーだからと言って、変に気張らずに「まずは相手の要求に、誠実に、謙虚に、全力で応える」事のほうが大事だと感じました。
(もちろん、+αで先述のことが出来れば最高ですけど)
そして「自分の求める事が出来ないと」感じたならば、そのプロジェクトを降りればいいだけですし。

で、現在は
ちょっと時間もあるので、今後の事とか、次に現場に入った時の事とか、色々と考えています。
やっぱり「お金」とか「体調」とか、あとやっぱり「自分らしい働き方」をするためには、自分のオフィスで働くのが一番!…という事を考え、現在は異業種交流会とか、人脈&業務拡大に精を出している今日このごろです。

仕事の依頼とか、増えないかなあ。

*1:もっと言うと、そんな状況にも関わらず、自分で車を運転して帰ったらしいです。奇跡的に無事故だったから良かったものの、今考えると恐ろしい…

おいパイ食わねえか?

いや、食うわけでもおみまいする訳でもないですが。

前から使ってた業務用オンボロPCの後継機としてDELLの通販で買ったPCが、先週ようやく届きました。
そして、それを契機に買ったRaspberry Piの開発が(やっと)Visual Studioで出来るようになったので、セットアップについて備忘録を書いておこうと思います。

作業1.Windows 10 IoT Core Dashboardの入手
1.「Windows Insider Program」のサイトで、アカウント登録します。(MSアカウントが必要)
https://insider.windows.com/

2.次の画面の「IoT Coreの入手」ボタンをクリック。

3.Windows Developer Centerの「Windows IoT」ページに移動するので「すぐに作業を開始」ボタンをクリック。

4.「Get Started」画面で、自分の環境に合わせて、以下を選択して、「Next」ボタンをクリック。
 ・Select your hardware:インストールするデバイス(Raspberry Pi3等)
 ・Select your installation media:Raspberry Piなら「microSD card」の方
 ・Select your OS version:「Windows10 IoT Core」(Insider Previewじゃない方)
  
5.「Step 1 of 4: Get the tools」ページの「Download Dashborad」ボタンをクリックして、Windows 10 IoT Core Dashboardをダウンロード&インストールする。


作業2.Windows 10 IoTのインストール
1.先程インストールした「Windows 10 IoT Core Dashboard」(以下、「ダッシュボード」)で「Set up a new device」をクリック。

2.右側のフレームで、以下を設定する
 ・デバイスの種類:「Raspberry Pi2 & 3」
 ・OSビルド:「Windows IoT Core」
 ・ドライブ:Raspberry Pi3用のmicroSDを挿しているドライブ名
 ・デバイス名:デフォルトで「minwinpc」となっていますが、変えるならデバイス名を入力。(そのままで良い場合は変更不要。)
 ・パスワード:(自分で決めた)Raspberry Pi3ログイン用のパスワードを入力。

3.micro SDにWindows IoT Core書き込みが始まるので、完了まで待機。(microSDの内容は全て消去されるので、ご注意を。)

4.書き込みが完了したら、microSDをRaspberry Pi3に差し込み、HDMIケーブルをディスプレイに接続し、ACアダプタをコンセントに挿す(Raspberry Piの出力はHDMIだけなので、HDMI対応ディスプレイがない場合、DVI変換ケーブルなどが必要になります。)

5.Raspberry Piの起動が完了し、ディスプレイに画面が表示されるまで、暫く待つ。(ちょっと時間がかかります。)

6.Raspberry Piの「設定」画面から、以下の3つを設定します。(最低限、これを設定すればOKのはずです。)
 ・「使用言語」&「キーボード言語」:どちらも「日本語」
 ・ネットワークとWifi:自分の環境に合わせて設定して下さい。
 ・Bluetooth:僕の環境では「ON」だと無線LANが上手く繋がらない現象があったので「OFF」にしました。(無線LANが上手くつながらない場合「OFF」にしたほうが良いかもしれません。)

Visual Studioデバッグ
1.Visual Studioを開き「新しいプロジェクト」から[Visual C#]-[Windows]-ユニバーサル-[空白のアプリ(Visual C#)]を選択。

2.ソリューションが開いたら、ツールメニューの「ターゲットCPU」(「ANY CPU」等が選択されている箇所)を「ARM」にする

3.ターゲットデバイス(「ローカルコンピュータ」などが選択されている場所)を「リモートPC」にして「手動で構成」欄で、以下を設定。
 ・アドレス:ディスプレイに表示されているRaspberry Piの「IPアドレス
 ・認証モード:ユニバーサル認証

デバッグ実行すれば、問題なければディスプレイに実行画面が表示されるはずです。(ソースは1行もいじらなくてOKです。)

※なお、上手くデバッグ出来ない場合、以下の事をチェックしてみて下さい。
 ・Raspberry Piのインターネット接続(無線の場合、これが結構切れます。)
 ・「認証モード」が「ユニバーサル認証」になっていない(Raspberry Pi3では「なし」ではダメみたいです)
 ・「参照の設定」の[ユニバーサルアプリ]-[拡張]-[Windows IoT Core]でチェックされているものが最新バージョンではない。(そもそもチェックされていないなら不要)

おまけ.Device Portalに接続
Raspberry Piの詳細設定は、ダッシュボード画面の「自分のデバイス」を右クリック-[Device Portalを開く]で起動できる「Device Portal」画面で行なえます。
(ちなみにログイン認証ですが、初期IDは「administrator」、初期パスワードは「作業2の手順1で設定したパスワード」です。)

「ここで何か作業をしないとデバッグできない」わけではないですが、とりあえず「タイムゾーン」は「Tokyo,Osaka,Sapporo」に変えておいたほうが良いかもしれません。

と、急ぎ足なうえ、画像もなくて申し訳ないですが、とりあえず実機デバッグが出来る環境を構築できました。
Xamarin.Formsも環境を再度構築したので、その話はまた後日書こうと思います。

本当の「フリー」について考える

何か、気づいたら前回の記事から1ヶ月近く経ってたんですね。
てっきり2週間位かと思ってました…反省です。

さて、気がつけば昨日、2回目の請求も完了していました。
しかし支払サイトは45日…早く入金されないと、マジで金が底をつく…(切実)

で、そんな訳でフリーになって約2ヶ月が経過したわけですが、この間に切実に感じたことがあります。
それは「早く自分のスペースで仕事が出来る環境を見つけないとマズイ…」という事です。

これまで2ヶ月契約先で働いた訳ですが、正直「何か結局、サラリーマンと変わらないなあ」という感じです。結局、週5日通勤して…という生活ですし。

まあそれだけならまだ良いんですが、僕は性格上、仕事に関しては非常に厳しいというか、ハッキリと物を言う性格なんですが、まあそれのせいで意見が衝突する…というか、相手によっては一触即発、なんてことも場合によってはあるわけです。(というか、今回も実際にあった)

個人的には「仕事での事なら、多少衝突しても意見を言い合ったほうが良い」という性格なので、臆する事はないのですが、それでも正直、あまり気分がいいもんではないです。
そうなると、仕事のモチベーションというか、どれだけ「なるべくなら楽しく仕事をしよう」と頑張っても、やっぱり仕事が嫌になっています。

でも、かといって「自分が我慢さえすれば」なんて考えは全く持ってないので、そういう場合でもハッキリと言ってしまうわけです。(まあ自分が我慢して自分だけストレスが溜まるのなんて勘弁ですし、そもそも自分の意見も言えないような人物なら、お客からしたら高い金を払って来てもらう価値も無いわけだし。)

となると「協調性が無い…というか、やっぱ個人(というか一人)で働くほうが性に合ってるんだ」と実感するわけです。
だって個人なら全てにおいて自分の好きなように(自分が責任を持って)やれますし、そもそもそういう働き方に憧れてフリーになったんだし。
だから早いところ、本当の「フリー」な状態で仕事をしなければ!と、最近強く思うのです。

ただ、そういう状態を確立しようとなると、まだまだ色々調べたり、勉強しなければならないです。
リモート案件も無いことはないけど、まだまだ数は少ないですから。(というか、僕が住んでいる地方では絶望的)

本当は営業とかして、クライアントを増やさないといけないんですが、そういうノウハウもなければ、人脈もまだまだ不足している。
そういう事も考えて、12月…そして来年以降、積極的に活動して、早めにそういう働き方を確立しなければいけないです。

それにリモートワークなら、地域に限定されることもないですし、週1回出向くくらいなら全く問題ないですから、仕事の幅も広がりますし。
(まあ、個人的には長野とか北海道みたいな、個人的に好きな場所なら、むしろ喜んで、って感じですし。単に「温泉が好き」なだけかもしれませんが…)

それに、そういう人脈などを通してビジネススキルを磨かないといけないですし、いろんなノウハウも学ばないといけない。
それに12月になればお金も入金されますし、新しいPCが届きますから、トレンドの技術や興味のある技術をもっと勉強して、同じ趣向の技術者の方とも交流を持ちたい、なんて思ってます。

そのためにも…というか来年、再来年につらい思いをしないためにも、今もっと頑張らなくては。

※ちなみに、個人的にはXamarin.FormsやIoTに大変興味を持っており、ネットで情報収集しまくってます。
…ていうか、何だかんだで結局C#大好きだなあ、自分。

フリーになって1ヶ月経った感想

手塚規雄さんが、Twitterでこんなつぶやきをしていた。

面白そうだったので、僕もやってみました。
https://shindanmaker.com/568560

その結果がこちら。
これを見てくれ。こいつをどう思う?

おそらく、以前(というか、闘病中で文字通り「一寸先が闇」だった頃)だったら、何が何でも飛びついたと思います。
ただ、病気から回復して、こうしてフリーとして生きている今の自分なら、間違いなく断ります。

なぜかって?

だって、基本給46万ってことは、大雑把に考えて、手取り40万弱ですよ?
って事は残業代含め、まあ良くて45~50万ってとこですよね?
しかも月50時間の残業は確定です。(まあ「男性が多い」ってのは、「一生この業界で食べていく」と決心した時点で諦めてます。)

そんなの、どう考えても割に合わないですもん。
フリーなら残業ゼロでも、基本給+10~15万くらいは堅いですし。(東京ならもっと多いと思います)

そりゃ退職金とか老後の生活とか福利厚生とかありますが、よく考えたら

  • 退職金:今はない企業も多い。というか退職まで生きている保証なんて無いから、それなら生きてるうちに多く貰って、自分で蓄えたい。
  • 老後の生活:これも退職金と同じで、死んだらもそうだけど、そもそも会社に何かあったら終わりだし。
  • 福利厚生:よく考えたら、福利厚生って、言うほど世話になったことがないや。

まあ簡単に言えば「自分の事は全部自分で責任持つから、その分時間やお金や自由がたくさんある働き方をすべきだ」ってのが、僕がフリーになった理由でもあるわけです。

実際、フリーになって1ヶ月経ちましたが、別にそういった面での大変さはそれほど感じていません。(むしろ「何から何まで、全部自分の責任でやっているんだ」という満足感のほうが大きいです。)

(僕みたいな)そういう「自分の事は、全部自分が責任を持たないと」というような考えの人には、フリーという働き方はお勧めだと思います。

逆に「そんなの面倒くさい」とか「そんなの誰かがやってくれるよ」って人は、フリーになるのはやめたほうが良いです。多分身が持ちません。
(あと「業務時間外では自分の業務関連の事に1ミリも関わらない」という人も、フリーには不向きだと思います。やっぱりどんな形でも、スキルアップは必要です。僕もフリーになってから、何かしら勉強する時間が大幅に増えました。)

まあ、僕のように人生波乱万丈で「フリーしか生きていく道がなかった」場合は別としても、そういう「自分の事は、全部自分が責任を持たないと」みたいな人は、一度フリーを検討するのも、決して悪くないと思いますよ。
(逆に言えば、そんな僕でもやっていけるのですから、決して選択肢としては悪くないと思います。)

…少なくとも、会社(特にブラック企業)に飼い殺しにされて、最悪な事態になる前に。