snovaのブログ

主にプログラミングやデジタルコンテンツについて書きます。最近はPython, Flutter, VRに興味があります。

スマートスピーカー、ロック、コンセント、照明を使って賃貸住宅をスマートホーム化する

イントロダクション

スマートホームが巷で流行っていますが、実際そんなにいいものなのか調べるため、簡単なものを賃貸住宅に導入してみました。 夏休みはもう終わりましたが、資格の勉強と漫画、ゲームしかしなさそうだったので、自由研究として挑戦しました。

目次

自由研究の流れ

以下のような流れで進めました。

  1. 製品の選定、購入
  2. 機器取付
  3. IFTTT等で設定
  4. 評価

選定と購入

ベースとなるスマートスピーカーは以前の記事で紹介しています。

snova301.hatenablog.com

スマートホーム化するとしても、多くのガジェットが存在します。 実際、wikipediaにも

スマートホームとは、IoT(もののインターネット)やAIなどの技術を駆使して、住む人にとってより安全・安心で快適な暮らしを実現する住宅のこと。

という文言から始まり、いくつか商品やサービスが紹介されています。

そこで、何の目的で、何を買うか、からまず考えてみました。 選定結果は以下の通り。

製品群 目的
スマートフォン Android搭載。iOS端末もあるが今回は使用しない。
スマートスピーカ スマートフォンの代わり。持ってる
スマートロック 家の鍵をかけたか忘れることがあるため。
スマートコンセント 電気機器の電気量を個別で知りたいため。
スマート照明 白熱球を使っていたので、新しいものに交換したいため。

(実は監視カメラも買ったのですが、別の機会に紹介します。)

以上を踏まえ、購入したものはこちら。

製品群 製品 理由
スマートスピーカ Google Home Mini すでに持ってる。
スマートロック sesame mini qurioと悩んだがsesameのほうがAmazonレビューが良かったので。
スマートコンセント JULES.V Amazonで安かったので。
スマート照明 TP-Link KL110 Amazonで安かったので。

スマートロック

SESAMEはもともとクラウドファンディングで発表されたものです。 特徴は以下の通り。

  • 多くのタイプの鍵に対応
  • 取り付けが簡単
  • アプリで解錠
  • IFTTT、Google Assistant、Amazon Alexa等に対応
  • 鍵のシェアが可能
  • 従来の鍵も使用可能
  • APIが提供されている

スマートロックって工事がいるようなイメージだったのですが、調べてみると簡易的で安いものがあると知って驚きました。

早速Amazonで購入したので、開封してみます。

設定はわかりやすい説明書があるので、手順通り進めば問題ありません。

取り付け前

取り付け後

電池は上から交換です。

鍵の形状の問題でアタッチメントを取り付けたのですが、その時間を含めても数分で終了しました。

SESAME本体だけだとBluetooth通信で解錠指令を送るのですが、オンラインで解錠したかったら別途アクセスポイントを購入しないといけません。 アクセスポイントはUSBに挿して電源供給するのですが、知らなかったので少し困りました。 みなさま、お気をつけて。

アプリでセッティングして、実際に動かしてみました。 駆動音が気になりますが、便利です。

スマートコンセント

各コンセントから消費される電気量を調べるために購入しました。 設定は説明書通りすれば、問題ありません。

スイッチ機能もありますが、電気機器が物理スイッチで起動するものしか意味ないような気がします。 赤外リモコンを制御できるスマート機器を購入して併用したいです。

スマート照明

照明の消し忘れが多いので、購入しました。

アプリ上で照明の状態を確認したり、使用電気量が確認できるのがいいですね。

明かりは白熱球と特に変わりません。 アプリ立ち上げたり、"OK, Google"と言って照明をつけるのが面倒なので、現在点灯手段を模索中です。

Google Assistantとの連携

SESAMEの場合

Google Homeで"OK Google, 鍵は開いてる?"みたいなことがしたかったので、設定しました。

こちらのサイトの通りに実践しました。

それ以外の場合

Googleの公式に方法が載っていました。

照明のスイッチが地味に便利でした。

Google Assinstantにはルーティンという設定が用意されています。 "ただいま"と言えば、複数のコマンドを実行します。

まとめ

スマートホーム化しなくても生きていけます。 しかし、あったほうが便利ですし、技術を勉強する機会にもなります。 最終的には、家事をほぼ無くすことを目標に、赤外線リモコンやら物理スイッチやらをネットに繋がるようにしていきます。

FlutterでシンプルなTo Do Listアプリを作った

イントロダクション

Flutterの練習です。 今回はTo Do Listアプリを開発しました。

目次

初期化

こちらの記事に記載しています。

snova301.hatenablog.com

vscodeを使う場合は、command + shift + pFlutter: New Projectをします。

ToDoListの本体

Stateless Widgetを定義します。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'to do list with Flutter',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: ToDoWidget(title: 'to do list with Flutter'),
    );
  }
}

class ToDoWidget extends StatefulWidget {
  ToDoWidget({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _ToDoWidgetState createState() => _ToDoWidgetState();
}

To Do Listの本体部分を作成します。 buildウィジェットで枠を作ります。 このとき、実際にリスト作成する部分は_buildTodoListに書くようにします。

To Doの追加は_pushAddTodoScreenで行います。 追加アイコンはマテリアルアイコンを使用しました。

class _ToDoWidgetState extends State<ToDoWidget> {

  List<String> _todoItems = [];

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('To do list')
      ),
      
      body: _buildTodoList(),
      floatingActionButton: new FloatingActionButton(
        onPressed: _pushAddTodoScreen,
        tooltip: 'Add task',
        child: new Icon(Icons.add)
      ),
    );
  }

To DoタスクはListViewで表示します。

各To Doタスクを追加するため、_addTodoItem_buildTodoItemでタスクを追加するウィジェットを作成します。 追加されたタスクは_todoItemsリストに追加していきます。

このとき、スワイプして削除するため、Dismissibleを使います。 また、スワイプ削除の際は文字がグレーになるよう背景色を設定します。

  Widget _buildTodoList() {
    return new ListView.builder(
      itemBuilder: (context, index) {
        if(index < _todoItems.length) {
          return _buildTodoItem(_todoItems, index);
        }
      },
    );
  }


  void _addTodoItem(String task) {
    if(task.length > 0) {
      setState(() => _todoItems.add(task));
    }
  }


  Widget _buildTodoItem(_todoItems, index) {
    String todoText = _todoItems[index];

    return Dismissible(
      key: Key(todoText),

      onDismissed: (direction) {
        setState(() {
          _todoItems.removeAt(index);
        });
      },
      background: Container(color: Colors.grey),

      child: Card(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            new ListTile(
              leading: Icon(Icons.check_circle_outline),
              title: new Text(todoText),
              onTap: (){},
            ),
          ]
        ),
      ),
    );
  }

タスク追加テキストについてです。 タスク追加ボタンを押すとテキストエリアが表示され、タスクを書き込めるようにしています。

  void _pushAddTodoScreen() {
    Navigator.of(context).push(
      new MaterialPageRoute(
        builder: (context) {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text('Add a new task')
            ),

            body: new TextField(
              autofocus: true,
              onSubmitted: (val) {
                _addTodoItem(val);
                Navigator.pop(context);
              },
              decoration: new InputDecoration(
                hintText: 'What is next task?',
                contentPadding: const EdgeInsets.all(16.0)
              ),
            )
          );
        }
      )
    );
  }
}

コード全体

gistで共有します。

ToDoList app

githubでも共有します。

github.com

結果

タスク画面

追加画面

削除後画面

まとめ

FlutterでTo Do Listを作成しました。 設定もできず、保存もできない酷いアプリですが、かんたんに作ることができました。 (さすがに、もう少しまともに動かせるように改良します。)

次回もFlutterで簡単なアプリを作りたいと思います。

参考サイト

JuliaのJuMPで線形計画法

イントロダクション

線形計画法で使う場面に遭遇したので、Pythonで解いていました。 しかし、どうせなら勉強のために、とJuliaで解くことにしました。

目次

線形計画法とは

複数の1次関数をすべて満たす数値のうち、目的関数の解を最大または最小とする最適化法です。 このとき、いずれの関数も線形(1次式)とならなければなりません。

線形の問題ですので、組合せ最適化などに比べると容易に解が出ます。 簡単な線形計画問題は高校数学の領域の問題で出題されます。

導入

実行環境は以下の通りです。

PC: macbook Air
OS: MacOS Mojave
Julia: 1.1

JuliaにはJuMPという最適化用のパッケージがあります。 今回はJuMPで線形計画法を解きます。

インストールはaddモードでJuMPをaddするだけです。 ソルバーにはGLPKを採用しました。

(v1.1) pkg> add JuMP
(v1.1) pkg> add GLPK

問題を解いてみる

適当に作った問題を解かせます。

たくみ君はお母さんからおつかいを頼まれました。内容は1000円で、1個8円のチョコを20個、1個17円のスナック菓子を10個買うというものでした。残ったお金でたくみ君のチョコとスナック菓子を買って良いと言われました。ただし、お店にはチョコが150個、スナック菓子が60個しかなく、お釣りはもらえません。チョコとスナック菓子を何個ずつ買えばよいでしょう?

チョコの個数をx、スナック菓子の個数をy、代金をzとすると、制限条件は以下のようになります。

 20 \leqq x \leqq 150

 10 \leqq y \leqq 60

 z \leqq 1000

目的条件は以下のようになり、このときzが最大となるxとyの組み合わせを考えます。

 z = 8x + 17y

JuMPのexampleを参考にコードを組みました。

まず、計算モデル定義します。 今回はGLPKを使用しています。

model = Model(with_optimizer(GLPK.Optimizer))

次に制限の記述です。 個数や金額は整数型なので、Intも引数に入れます。

@variable(model, 20 <= x <= 150, Int)
@variable(model, 10 <= y <= 60, Int)

目的関数の定義です。 最大化問題なので、Maxと記述します。

@objective(model, Max, 8x + 17y)

最大化したい値の制限条件も記述します。

@constraint(model, 8x + 18y <= 1000)

そして、実行。

JuMP.optimize!(model)

結果の取り出しはvalueを使います。

obj_value = JuMP.objective_value(model)
x_value = JuMP.value(x)
y_value = JuMP.value(y)

全体のコードは以下。

using JuMP, GLPK

function takumi_LP(; verbose = true)
    model = Model(with_optimizer(GLPK.Optimizer))

    @variable(model, 20 <= x <= 150, Int)
    @variable(model, 10 <= y <= 60, Int)

    @objective(model, Max, 8x + 17y)
    @constraint(model, 8x + 18y <= 1000)

    if verbose
        print(model)
    end

    JuMP.optimize!(model)

    obj_value = JuMP.objective_value(model)
    x_value = JuMP.value(x)
    y_value = JuMP.value(y)

    if verbose
        println("Objective value: ", obj_value)
        println("x: ", x_value)
        println("y: ", y_value)
    end

end

takumi_LP(verbose = true)

解は以下の通り。

Max 8 x + 17 y
Subject to
 x integer
 y integer
 x ≥ 20.0
 y ≥ 10.0
 x ≤ 150.0
 y ≤ 60.0
 8 x + 18 y ≤ 1000.0
Objective value: 988.0
x: 98.0
y: 12.0

つまり、たくみ君はチョコを98個、スナック菓子を12個買うと、最大代金(988円)でお菓子を買えます。

上記のコードをGithubに載せます。

github.com

まとめ

JuMPを使うことでjuliaで線形計画問題を解くことができます。 JuMPには線形計画問題だけではなく、他の最適化計算ができるみたいなので、次回チャレンジします。

参考サイト

Google Play and the Google Play logo are trademarks of Google LLC.