スクリプト類とメニューボタン

トップ ソフト 雑記 日記 リンク

2015/06/18

サチコと神ねこ様のリンク

Pouchというサイトで、わこ(@wako3999)さんが連載されている「サチコと神ねこ様」という漫画があるのですが、新しい話から古い話へのリンクは有るのに、古い話から新しい話へのリンクが無いので、第1回から順に読むのが困難2020年ぐらいから次の話へのリンクが付いたようです。
タグ一覧でも新しいもの順ですし、レコメンドで出てくる話もランダムで、番号順に読むのは無理そうです。

なので各話へのリンクを作りました。順に追記します。

最近の更新分(表示されるまで少し時間が掛かります)

最初から







































































































































































































































































































2015/04/10

Bluetoothイヤフォン MDR-EX31BN のNFC簡単接続をWindowsでも

Bluetoothイヤフォン MDR-EX31BN を買いました。
わたしが買ったのは赤色です。
この製品には、「NFC簡単接続」という機能があり、NFC対応Android端末とタッチするだけでBluetoothのペアリング設定ができるという代物です。
通常、ボタンを押してのペアリング設定だと7秒間もボタンを押し続けないといけないのですが、このNFC簡単接続だと、お互いの機器を近づけて2秒ほどで認識されます。

しかし用意されているのは、Androidアプリだけ。
Windows7マシンにPasoriを繋いで簡単ログインなどに使っているのですが、これでペアリング設定ができないのかなと疑問に思いチャレンジしてみました。

わたしが使っているのはRC-S330ですが、上位機種でも問題ないでしょう。
Pasoriには、Felicaランチャーというアプリがあり、Pasoriに読ませたチップによってプログラムを起動することが可能です。



一方、Bluetoothのペアリングは、Bluetoothアプリの各機種毎のコントロールパネルで行います。
タスクバーのBluetoothアイコンから、機器一覧を出して、そこからイヤフォンのコントロールパネルを出して、この接続ボタンを押します。



要はプログラムで、この接続ボタンを押せば良いわけです。

以前はWindowsプログラムならSDKでゴリゴリ書いていたのですが、最近はもっと簡単にできるはず。
手近なところで、標準で入っているPowerShellで操作できるかなと調べてみたところ、ありました。

UI Automation PowerShell Extension

ダウンロードしないといけないので、完全に標準の機能だけでは済みませんでしたが、かなり手軽にできるようです。
インストールは
\マイ ドキュメント\WindowsPowerShell\Modules\UIAutomation
に展開して、PowerShellのプロンプトから
Import-Module .\UIAutomation.dll
を実行します。

モジュールのロードは、PowerShellのプロンプトを閉じると無効になってしまいます。
Linuxなどのように、自動で読み込んでくれるような仕組みは無いものかと調べてみると、これも有りました。そのままずばりプロファイル機能。
\マイ ドキュメント\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 (*1)
に書いておくと、プロンプトを開いたときに実行してくれます。
これで先ほどのImport-Moduleコマンドを書いてPowerShellプロンプトを開くと・・・

スクリプトの実行がシステムで無効になっているため、ファイル ~\マイ ドキュメント\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 を読み込めません。詳細については、「get-help about_signing」と入力してヘルプを参照してください。
発生場所 行:1 文字:2
+ . <<<< '~\マイ ドキュメント\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'
+ CategoryInfo : NotSpecified: (:) []、PSSecurityException
+ FullyQualifiedErrorId : RuntimeException


なにやら真っ赤な字でエラーが出てきました。
プロンプトから手動で実行するには、人間が操作しているので問題ありませんが、自動で実行されるのはセキュリティ的に問題があるということで、制限が掛けられているのです。
これはPowerShellのプロンプトを管理者権限で起動して
Set-ExecutionPolicy RemoteSigned
を実行することで、 設定が変更できます。 (*2)
ここで嵌まったのが、上記の方法で設定を変更したのに、Felicaランチャーから起動したときにはエラーが出てきてしまうというものでした。
どうにも分からず、TLに投げてみたところ




と、PowerShellの偉い人からズバリな回答をいただきました。
スタートメニューにあるPowerShell(x86)のリンクから設定すると、無事に起動しました。
Felicaランチャーが32bitコードで書かれているのが原因だったようです。

さて、これでかなり近づいてきました。
あとはPowerShellでボタンを押すだけです。

$process = Start-Process  -FilePath "C:\Program Files\WIDCOMM\Bluetooth Software\BTWUIExt.exe" -ArgumentList "/deviceAddr=fcf152a9a66a" -PassThru
$window = Get-UiaWindow -ProcessId $process.Id
$window | Get-UiaButton -AutomationId 'btnConnectDisconnect' -Class 'Button' | Invoke-UiaButtonClick | Out-Null
Stop-Process $process.Id

deviceAddrに設定する値は、機械によって異なると思います。わたしは、
Process Explorer
を使って、Bluetoothイヤフォンのコントロールパネルが表示されているときに、プロセスがどんなコマンドラインで呼ばれているのかを調べました。

これをエクスプローラーから実行すると、接続ボタンが表示されているときは接続ボタンが、切断ボタンが表示されているときは切断ボタンが押されます。
NFC簡単接続でも、接続中にもう一度タッチすると切断されるので、完全に同じ動作です。

あとは、FelicaランチャーにこのPowerShellをセットするだけ。イヤフォンをPasoriに近づけてみると、メモ帳が開く・・・。
そう、ps1ファイルは普通に開くとメモ帳が開いてしまうのです。
PowerShellでは、"powershell.exe file.ps1"とすることで、指定のファイルを実行できるのですが、Felicaランチャーのアプリ指定画面では、ファイルを一つ指定できるだけです。
そこで最初の画面写真にあったように、VBスクリプトでPowerShellを起動するようにしました。
VBSファイルなら、そのまま開くだけで実行されます。
CreateObject("WScript.Shell").Run "powershell.exe (ディレクトリ名)\headset_setting.ps1",0
これで完成。

(*1) 実際のファイル位置は、PowerShellプロンプトで、 $profile を実行すると表示されます。
何も設定していなければ、実際にその場所には何もファイルが無いと思いますので、新規作成する必要があります。

(*2) 指定方法は
Tech TIPS:WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する @IT
を参考に。

2015/03/30

電話番

そろそろ新しい季節ですね。
新入生・新社会人の方、頑張ってください。
わたしも、そんな頃があったなぁと想い出に浸っていたら、ふと思い出したことがあったので、ブログにカビが生えないように書き留めてみます。



新社会人として、大手製鉄会社の孫会社にあたるソフトウェア開発会社に入った私。
3週間の新入社員研修を済ませ、配属になったのは大阪の事業所でした。
事業所と言っても、細い雑居ビルのワンフロア。親会社と協力会社が入り交じった机が並び、縦長の島二つに40人ほどがぎゅうぎゅう詰めになっているような部屋でした。

新人ですし、いきなりバリバリ仕事ができるわけでもなく、まずはOJTとして指導を受けつつ、「電話が掛かってきたら出て」と言われました。
事業所には事務や総務の人はおらず、みんな何かしら開発に近い作業をしていました。開発者の人なら分かると思いますが、作業中の割り込みは効率が悪くなる要素です。新人への業務としてはもってこいの仕事かと思います。

プルルルル
「はい、○○(親会社名)です。」
『株式会社$#%※=(←よく聞き取れない)の山本(仮名)と申します。佐藤(仮名)さんはおられますでしょうか。』
「申し訳ありません、もう一度お名前をお願いできますでしょうか。」
『$#%※=(←やっぱり聞き取れない)の山本です。」
新人研修で電話の取り方は習いました。いわゆる正常系は習いましたが、異常系を習っていません。
ここで頭がフル回転します。

(いきなり名指しで掛けてきたということは、普段から取引のある会社だという事は分かる。)
(ここで、失礼ですがもう一度お願いしますというのは、本当に失礼すぎる。)
(相手も急いでいるだろう。電話代だって向こう持ちだ。)
(普段から掛けてきているところなら、佐藤さんだって分かるはずだ。)

ここで、佐藤さんの机まで行って声を掛けます。
「佐藤さん、会社名が聞き取れなかったのですが、山本さんからお電話です」
『どこの山本さん?』
(ああー、やっぱりちゃんと聞き直すのが正解だったのかー)



というやり取りです。

今にして思えば、「分からないまま次に進むな、ちゃんと理解するまで繰り返せ」という事なんでしょうけど、自社内で完結しているならまだしも、相手先があることだと難しいですね。
しかし、別の立場から見ると、あんたとこの社員の経験を積ませるために、うちが電話代を払うの?って思われちゃったりしないか。何度も聞き返されて、ちょっとイラッと来るとか。(分かりやすい社名にするか、二回目以降はゆっくりしゃべれば良いだけだが)

いきなり聞いたことのない単語を言われると、頭が言葉として認識できない事がありませんか?最近聞いた中だと「ラッスンゴレライ」みたいな。
そこの業務に携わって経験を積んでいれば、騒音で相手会社名の一部分しか聞こえなくても推測で分かるかもしれません。

あるとき気がついたのは、「よく電話が掛かってくる会社名一覧」が有れば済んだ話ではないかと思いました。
なので、新入社員が入ってきて電話番を引き渡す人は「よく電話が掛かってくる会社名一覧」を作っておいてあげると嬉しいかなーと思いました。


開発メインの会社だと、電話は事務や総務の人が取ってくれると、一番簡単な解決だとは思います。
その後、その事業所は別のビルに移転しフロアが広くなり、事務の人が本社から配属されてきたので、電話を取ることはほとんどありませんでした。

2014/12/12

libpqxxを使ってみた。

PostgreSQL Advent Calendar 2014 の 12日目です。枠が空いていたので、2回目の飛び込みをしてみました。
昨日はnuko_yokohamaさんのjsqueryを使ってみたでした。

 普段わたしはウェブアプリをPHPで作っていて、そこからPostgreSQLへアクセスするのですが、バッチ処理やループ処理などはCやC++で書くことがあります。
 少し前までは、C言語でバッチ処理を書いていて、ecpgを使った埋め込みSQLを使っていました。
 AIXでDB2を使っていた経験があり、その延長で埋め込みSQLは便利だなと思っていたのです。

 しかし、複雑なことをするに従って、また他のライブラリの都合などもあり、徐々にC++に移行してきました。

 7日目の nuko_yokohama さんのスライドにもあったように、C++でecpgを使うのは、ちょっと微妙です。完全対応では無いので、何か問題が発生したときに切り分けで嵌まりそうです。
 そこで、libpqxxという、C++ライブラリを使ってみました。

http://pqxx.org/development/libpqxx/
 現在、最新バージョンとしては4.0.1が公開されています。
 が、開発版のスナップショットも公開されています。
 4.0.1はリリースが古く、それからちょこっと修正も入っているので、こちらの方がいいかなと思います。
http://pqxx.org/~jtv/tmp/pqxx/snapshot/

 configure して make して make install 簡単ですね。

 コードは、とてもシンプルです。
 コネクションやトランザクション、結果などそれぞれがオブジェクトになるので、簡単にアクセスできます。
// パスワードは .pgpass にでも書いておきましょう
unique_ptr<pqxx::connection> db_conn(new pqxx::connection("host=pgsql.example.jp port=5432 dbname=testdb user=testuser application_name=testprog"));
try {
     pqxx::read_transaction tran(*db_conn);
     ostringstream query;
     query << "SELECT val" << endl;
     query << "FROM tbl" << endl;
     query << "WHERE cond='cond'" << endl;
     pqxx::result res(tran.exec( query.str() ));
     if (res.begin() == res.end()) cerr << "nodata" << endl;
     for (pqxx::result::const_iterator row = res.begin(); row != res.end(); row++) {
          cout << row["val"] << endl;
     }
     tran.commit();
}
catch (const pqxx::sql_error& e) {
     cerr << e.what() << " : SQL->" << e.query() << endl;
}
catch (const pqxx::usage_error& e) {
     cerr << e.what() << endl;
}

 更新でも同じ流れです。
pqxx::work tran(*db_conn);
std::ostringstream query;
query << "INSERT INTO tbl (" << endl;
query << "val, cond" << endl;
query << ") VALUES (" << endl;
query << "  " << std::dec << val << endl;
query << ", " << tran.quote( cond ) << endl;
query << ")" << endl;
pqxx::result res(tran.exec( query.str() ));
tran.commit();

 quoteだけではなく、ちゃんとプリペアドステートメントも使えます。
pqxx::connection_base &con_base(*db_conn);
con_base.prepare("sel", "SELECT name FROM tbl WHERE code=$1");
pqxx::read_transaction tran(*db_conn);
pqxx::result res( tran.prepared("sel")("hoge").exec() );
for (pqxx::result::const_iterator row = res.begin(); row != res.end(); row++) {
    cout << row["name"] << endl;
}
tran.commit();

 プリペアドステートメントはデータベースコネクションへ登録、実際のステートメントはトランザクションから
tran.prepared(ステートメント名)($1)($2)・・・.exec()
という形式で呼び出します。

 嵌まりどころがなくて、拍子抜けするぐらいです。
 以前のバージョンでは、PostgreSQLのbigint型を扱うときにCのlong long int型を使おうとするには、includeファイルの定義を変更したりする必要があったのですが、今のバージョンでは不要です。

これでC++からも簡単PostgreSQL!!

2014/12/04

RDS for PostgreSQLを使い始めてみたレポート

PostgreSQL Advent Calendar 2014 の 4日目です。
昨日はNagayasuさんのPostgreSQLカンファレンス2014開催のお知らせと見どころのご紹介 #pgcon14jでした。


 拙作「ふぁぼるっく」 のデータベースをRDS for PostgreSQLへ移行しました。
 一昨日ぐらいに全データを移し終わったところです。
 RDS内部のソフトウェア的なところは、これまでも他の方の記事にあったので、スペック部分に的を当てて書いてみたいと思います。

 それまでは、自宅サーバでよく使うデータやインデックスだけをSSD上のテーブルスペースに置き、あまり参照されないデータなどをHDD上のテーブルスペースで運用していました。今年の5月からVPSのSSDプランを借り、よく使うデータやインデックスだけをVPSのSSDに置いて、残りのデータを自宅サーバに置き、postgresql_fdwで自宅サーバに繋いで利用していましたが、いろいろ問題点が溜まってきました。
  • 自宅サーバのSSDがすぐ劣化する(一年ちょっと)
  • SSDを買い続けるのと、交換作業の度にバッチを止めたり、回復作業が面倒
    (当時はSSDでRAID 1を組むほどの思い切りがなかった)
  • ときどきレプリケーションが失敗してスレーブが止まる
  • VPSに移行したが、負荷が高すぎて処理制限を掛けられ、PostgreSQLがOSごと転けた
  • 自宅サーバに戻って2TB HDD*5(RAID5)マスターサーバと4TB HDD*2(RAID0)スレーブサーバで組んでみたが、やっぱり速度が出ない

自宅サーバの惨状 ふぁぼ収集サービスのつらみより
気がついたら、コードを書くよりインフラのメンテナンス作業の方に時間を多く取られていることに気がつきました。障害を克服する楽しさが無いとは言いませんが、ソフトウェアでやりたいことが溜まっていくのに、なかなか手がつけられません。ストレスが溜まります。
 ここは、インフラ担当を一人雇うつもりで、全データをRDS for PostgreSQLに移行しました。

db.r3.large インスタンス
General Purpose (SSD) 2000GB

 最終的に、上記の構成になりました。
 当初は、r3.xlargeインスタンスでプロビジョンドIOPSの1000 IOPSにして利用しようと考えていました。100GBの構成でテストしてみたり、料金計算ツールでなんとか払える範囲であることを確認したり・・・。

 最小構成で動くことを確認し、あとは本番用サーバを建てようとしたところ、なにやらエラーが。
2000GB で作るなら、6000 IOPS からだよ。
慌てて料金計算ツールで試算してみたところ、月額10万円以上もの金額! とても趣味に使える金額ではありません。100GBの時は1000 IOPSからだったのに・・・。

 ふと考えてみると、EC2のEBSはサイズが1TBまででしたので(2014年11月に16TBまでの拡張が発表されました)、3TBまで使えるRDSは内部でEBSを束ねているのだろうと考えられます。
 そうすると、通常のディスクやGeneral Purpose (SSD)でも、ボリュームサイズが大きければ、単体ディスクの時よりスピードが出るのではないか?
動かしてみた。

 移行中に溜まっていた処理を一気に流しているので、かなりギリギリの処理になっていますが、性能が落ちているなー、というときでも400 IOPS程度出ています。
調子の良いときで2000 IOPS、とても良いときで3000 IOPSでました。

db.r3.large インスタンスは、
 vCPU 2
 メモリ 15GB
 ネットワークパフォーマンス 中
 プロビジョンド IOPS用の最適化なし
という条件で、コア数的には自宅サーバやVPS時代と比べて劣っているのですが、ディスクが高速なおかげで、全く遜色を感じません。
こんなことなら、もっと早く移行しておくべきでした。

ということで、速度も巨大ストレージも欲しているデータベースは、RDSでも幸せに運用できるのではないかと思います。
2014年12月現在、3TBまでですが、これもEBSの拡大に合わせて大きくできるのではないかと期待しています。



 ここまで書いておいて、これ単純にAWSの話で、PostgreSQL関係なくね?と気がついたので、やっぱりソフトウェア的な話も。



 RDSへの移行は、しばらく前から考えてはいたのですが、日常的にテーブル間でデータコピーが発生する構成なため、どのように RDS for PostgreSQL を絡めるか、また自宅サーバで1.7TBほどディスクを使っているデータベースをどうやって移行するかが悩みどころでした。

 AWSから出ていくデータには大きなデータ転送量が掛かってしまうため、AWSのサービスを使い始めたら最後、日常的に参照以外でデータをまとめて取り出すことは考えない方がいいでしょう。こうして、それまで組んでいた「よく使うデータはインターネット側、あまり使わない古いデータは自宅サーバ」という構成は諦めることにしました。
 全てのデータを1台のサーバで運用するのは、それまで自宅サーバだけの時代に経験しているので、あとは移行方法です。なるべく動かしたまま移行したいと考えていたところ、タイミング良く11月の更新で移行ツールのサポートが発表されました。

Amazon RDS for PostgreSQLのアップデート- リードレプリカ、9.3.5のサポート、データ移行、3つの新しい拡張モジュール

 Londisteというツールでレプリケーションを組むことで、マスターサーバからデータを送りつける感じ?でコピーを作成するようです。
 そして検証環境を組んでLondisteを使ってみようとしたのですが、上手く行かない。最新バージョンは3.xなのですが、PostgreSQL wikiには2.xの説明しかありません。3.xではコマンド体系が変わっているようで、なんとか付属のドキュメントを読みつつ試してみたのですが、全く動きそうなところにも持って行けませんでした。
 この時点でVPSでの運用ができなくなり、自宅サーバに戻って速度の出ないディスクを前に未処理のデータが溜まり続けるという前にも後ろにも進めないような状況に陥ってしまいました。
 「早く標準のストリーミングで移行できるようにしてくれ」と願っている時間もなく、RDSの仕組みを見る限り、ターミナルにログインしてpg_basebackupコマンドを叩けるような構成では無さそうです。
 仕方なく、オーソドックスなpg_dump、psqlの組み合わせで移行しました。


 データベース作成には、LC_COLLATE、LC_CTYPEの設定が必要だったため、既存のデータベースの削除と、テーブルスペース作成・データベースの作成までは先に済ませます。

CREATE DATABASE favlook
  WITH OWNER = favlook
       ENCODING = 'UTF8'
       TABLESPACE = hoge
       LC_COLLATE = 'C'
       LC_CTYPE = 'C'
       TEMPLATE = template0
       CONNECTION LIMIT = -1;
続いて元のサーバからデータのエクスポート
 RDSでは、rdsadminユーザーがSUPERUSER権限を持ち、サーバを建てた時点で作られているユーザーにはrds_superuserという権限が与えられています。
 こんな感じ
-- Role: rdsadmin
CREATE ROLE rdsadmin LOGIN
  SUPERUSER INHERIT CREATEDB CREATEROLE REPLICATION;

ALTER ROLE rdsadmin
  SET log_statement = 'none';
ALTER ROLE rdsadmin
  SET log_min_error_statement = 'panic';
ALTER ROLE rdsadmin
  SET log_min_messages = 'panic';
ALTER ROLE rdsadmin
  SET exit_on_error = '0';
ALTER ROLE rdsadmin
  SET TimeZone = 'utc';

-- Role: postgres
CREATE ROLE postgres LOGIN
  NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION;
GRANT rds_superuser TO postgres;
単純にpg_dumpでデータを出力すると、テーブルの権限を設定する部分で警告が出まくります。
 ですので、--no-ownerオプションをつけて、ログインユーザーで作成します。
pg_dump -U [user] -f table.sql --no-owner --no-tablespaces -s [database]
これでテーブルを作成し、あとは必要なデータからコピーしていくという流れで移行しました。

 本格的な運用はまだこれからですが、とりあえずtextsearch_jaを使っていた処理をどうしようかなぁ、というところです。サーバ側でカスタマイズは難しそうなので、postgresql_fdwみたいな感じで、postgresql_RPCとかできると良さそうですね。


明日はsoneさんの今、データベースは中国地方が一番アツい!! です。

広告