IFTTTとNature Remoの連携が出来ない(解決)

Nature Remoを買ったので、意気揚々とIFTTTと連携してあんなことしてみよう、、って思って下記の通りに連携してみました。

が、うまく連携できていないようで、Control home appliances で何も出てきません。No options found となります。

f:id:onozaty:20190708233325p:plain

何度か連携のしなおしをしてみましたが、解決せず、、といった状況です。

なんか他の人と違うことしているかな、、と思って考えてみましたが、やったことといえば、Nature Remoのメールアドレスを早々に変えたところでしょうか。

あと気になったのは、Nature Remo側でIFTTTに対して許可するときに何が許可されるのか出てこなかったところです。

f:id:onozaty:20190708233259p:plain

解決したら、追記したいと思います。


追記@2019-07-11

Nature Remoのサポートに問い合わせたところ、Control home appliancesで出てくるのはエアコン、テレビ、照明以外で学習機能で登録したもので、エアコン、テレビ、照明はTurn on air conditionerやControl TVなどといったところから選択可能とのことでした。

f:id:onozaty:20190711234221p:plain

下記を見て、Control home appliancesにテレビがあったので、てっきりすべての機器がControl home appliancesで出てくるものと勘違いしてしまっていました。

ということで、無事IFTTTで操作できました。ありがとうございました。

Redmine: View customize plugin の v2.3.0 をリリースしました

View customize plugin の v2.3.0 をリリースしました。

ViewCustomize.contextへプロジェクトのカスタムフィールドを追加しています。

ViewCustomize.contextへの追加基準ですが、いまのところ下記のように考えています。(何でも入れてしまうとメンテナンスが面倒になっていくのと、きりがなくなりそうなので)

  • 他の方法で取得できない、または取得出るがかなり煩雑
  • 利用するシチュエーションが多数想定できる

今回のプロジェクトのカスタムフィールドは、、

  • REST APIを使えば取得できなくないがREST APIを使うこと自体が煩雑
  • 他の人からのPull requestがあったのと、ユーザのカスタムフィールドのように、プロジェクト毎に有効/無効を切り替えたり、表示したいものを変えたりといったような使い方ができそう

ということで追加しました。

ShortcutKey2URL for Chrome のバージョン1.1.0をリリースしました

ShortcutKey2URL for Chrome のバージョン1.1.0をリリースしました。

ShortcutKey2URL は、ショートカットキーを使用してURLを開いたり、移動したり、JavaScriptを実行できる拡張機能です。

スタートアップキーであらかじめ設定しておいた動作の一覧を表示し、次のキーでその動作を実行します。

f:id:onozaty:20171018003430p:plain

バージョン1.1.0での変更内容

コンテキストメニューからページを追加可能になりました。

f:id:onozaty:20190624000929p:plain

ポップアップからクリックでも実行できるようにしました。(マウスで操作したい人もいるかもしれないということで...)

f:id:onozaty:20190624001536p:plain

複数ウインドウが存在する場合、アクティブではないウインドウに対して処理してしまうことがあるバグを修正しました。

CSVファイルをPostgreSQLにロードするツール(csv2postgresql)を作りました

CSVファイルをPostgreSQLにロードするツールを作りました。

事前にテーブルを作っておく必要は無いので、とりあえずCSVファイルをPostgreSQLにロードしていじりたいって時に便利かと思います。

テーブルはCSVのヘッダに記載のフィールド名を元に作成されます。なお、既にテーブルがある場合は作りません。

内部的にはCOPYコマンドを使っているので、とても早いと思います。(もともとバッチINSERTを使った実装をしていましたが、COPYコマンド使うように変えたら50倍早くなりました)

利用方法

実行にはJava(JDK8以上)が必要となります。

下記から最新の実行ファイル(csv2postgresql-x.x.x-all.jar)を入手します。

入手したjarファイルを指定してアプリケーションを実行します。

java -jar csv2postgresql-1.0.0-all.jar config.properties table1 data.csv

引数は下記の通りです。

  1. 設定ファイルパス
  2. テーブル名
  3. CSVファイルパス

実行すると、下記のように処理したレコード件数、かかった時間が出力されます。

Loading...
Loading is completed. (Number of records: 100,000 / Elapsed millsecods: 322)

設定ファイル

設定ファイルには、PostgreSQLの接続先情報と、CSVファイルのエンコーディングを記載します。

  • database.url JDBC接続URL
  • database.user DBユーザ名
  • database.password DBパスワード
  • csv.encoding CSVファイルのエンコーディング

以下は例です。

database.url=jdbc:postgresql://192.168.33.10:5432/testdb
database.user=user1
database.password=pass1
csv.encoding=UTF-8

テーブル名

ロード先のテーブル名を指定します。

テーブルが存在しなかった場合、新規にテーブルを作成します。この際、各カラムはtext型として作成されます。

CSVファイル

CSVファイルのヘッダは必須です。ヘッダに記載のフィールド名を使って、ロード先のテーブルのカラムとマッピングします。 なお、英数字以外の文字が指定されていた場合、アンダースコア(_)に置換されます。

たとえばUser Nameというフィールドがあった場合、データベースのカラムとしてはuser_nameにマッピングされます。

サンプル

PostgreSQLを起動するためのVagrant環境と、設定ファイルとCSVファイルのサンプルが用意してあります。 これらを使うことによって、簡単に本ツールを試せます。

vagrantフォルダにてvagrant upを実行すると、PostgreSQL11をインストールした仮想環境(192.168.33.10)が立ち上がります。

sampleフォルダ配下の設定ファイルとCSVファイルを利用してロードを行います。

java -jar csv2postgresql-1.0.0-all.jar sample/config.properties test_table sample/sample-100000.csv

ビルド方法

ソースコードからビルドして利用する場合、Java(JDK8以上)がインストールされた環境で、下記コマンドでアプリケーションをビルドします。

gradlew shadowJar

build/libs/csv2postgresql-x.x.x-all.jarという実行ファイルが出来上がります。(x.x.xはバージョン番号)

Ed Sheeran - DIVIDE WORLD TOUR 2019 (2019年4月10日@東京ドーム)

Ed Sheeran(エド・シーラン)のライブに嫁さんと一緒に参戦してきました。

15時過ぎに東京ドームについて、まずは物販からということで、Tシャツとタオルをを購入。物販は10分程度並んだだけで、そんな待たずに買えました。

席は1階スタンドです。ステージから真正面ですが遠いです。S席の範囲がとても広く、どこになるかは運任せなのでしょうがないですね。

17時45分からオープニングアクトでONE OK ROCKです。チケット購入した後に発表されたオープニングアクトですが、ワンオクも聞けるなんて、、すごい得した気分です。エド・シーランと交流があるのは有名な話だったので、もしかしたらなーって思っていたけど、まさか本当にそうなるなんて!!

狭いステージを動き回るTakaかっこいい。

オープニングアクトは45分くらいで終わり、19時からエド・シーランのライブ開始です。

ギターとループステーションだけでライブやりきってしまうというのは知っていましたが、いや、ほんと凄すぎました。ループステーションを使ってどんどん音を重ねていって、歌いながらプラスしてさらにギター、、エド・シーラン一人によってすごい複雑な音楽が作り出されます。

特に最後のYou Need Me, I Don’t Need Youは圧巻で、鳥肌が立ちました。ほんと最高のライブでした。

セットリスト (ONE OK ROCK)

  1. Push Back
  2. Deeper Deeper
  3. Clock Strikes
  4. Head High
  5. Stand Out Fit In
  6. The Beginning
  7. Mighty Long Fall
  8. Wasted Nights

セットリスト (Ed Sheeran)

  1. Castle on the Hill
  2. Eraser
  3. The A Team
  4. Don’t / New Man
  5. Dive
  6. Bloodstream
  7. Love Yourself (Justin Bieber)
  8. Tenerife Sea
  9. Lego House / Kiss Me / Give Me Love
  10. Galway Girl
  11. Feeling Good / I See Fire
  12. Thinking Out Loud
  13. One / Photograph
  14. Perfect
  15. Nancy Mulligan
  16. Sing
  17. Shape of You (アンコール)
  18. You Need Me, I Don’t Need You (アンコール)

REST APIを利用して複数の関連チケットをまとめて作成する(Redmine View Customize Plugin)

チケットを作成して、関連付けを行いたいという問い合わせがあったので書いてみました。

チケットの関連付けには下記のAPIを使います。

設定内容

  • Path pattern: .*
  • Insertion position: Bottom of issue detail
$(function() {

  var projectId = $('#issue_project_id').val();
  var trackerId = $('#issue_tracker_id').val();
  var subject = $('#issue_subject').val();
  var priorityId = $('#issue_priority_id').val();
  var currentIssueId =  ViewCustomize.context.issue.id;

  // 関連チケットとして作成する情報
  var issueChildren = [
    {
      'issue': {
        'project_id': projectId,
        'tracker_id': trackerId,
        'subject': subject + ' - 関連チケット1',
        'priority_id': priorityId
      }
    },
    {
      'issue': {
        'project_id': projectId,
        'tracker_id': trackerId,
        'subject': subject + ' - 関連チケット2',
        'priority_id': priorityId
      }
    },
    {
      'issue': {
        'project_id': projectId,
        'tracker_id': trackerId,
        'subject': subject + ' - 関連チケット3',
        'priority_id': priorityId
      }
    }
  ];

  var link = $('<a title="関連チケットの一括作成" class="icon icon-add" href="#">関連チケットの一括作成</a>');
  $('#issue_tree').before($('<p>').append(link));

  link.on('click', function() {

    if (!confirm('関連チケットをまとめて作成します。よろしいですか。')) {
      return;
    }

    // チケット作成処理(非同期)を順次実行し、最後にリロード
    var defer = $.Deferred();
    var promise = defer.promise();

    for (var i = 0; i < issueChildren.length; i++) {
      promise = promise.then(createIssue(issueChildren[i]));
    }

    promise
      .done(function() {
        // 成功したらリロード
        location.reload();
      })
      .fail(function() {
        alert('失敗しました');
      });

    defer.resolve();
  });

  function createIssue(issue) {

    return function() {

      return $.ajax({
        type: 'POST',
        url: '/issues.json',
        headers: {
          'X-Redmine-API-Key': ViewCustomize.context.user.apiKey
        },
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(issue)
      })
      .then(function(response) {
        var createdIssueId = response.issue.id;
        return $.ajax({
          type: 'POST',
          url: '/issues/' + currentIssueId + '/relations.json',
          headers: {
            'X-Redmine-API-Key': ViewCustomize.context.user.apiKey
          },
          dataType: 'json',
          contentType: 'application/json',
          data: JSON.stringify({
            'relation' : {
              'issue_to_id' : createdIssueId,
              'relation_type' : 'relates'
            }
          })
        })
      })
    };
  }
})

画面イメージ

f:id:onozaty:20190324003243g:plain