SSDに換装したWindows7 AHCI モードでクラッシュ

一世代前のノートブックパソコン、まだまだ使えるのだが、動作がやや緩慢、そこで最近ぐっと購入しやすい値段になってきたSSDに換装してみた。 使ったのは250GBのSamsung840EVo。
Windows用のマイグレーションソフトウエアが付属してくるのでUSBを通してSATAに接続できるケースさえ手元にあればディスクイメージのコピーは問題なくできる。 あとはパソコンの裏ケースをはずし、HDDを取り出して、SSDを組み付けるだけ。ただし、Dual Bootで入れておいたMint Linuxはきれいに無視されるので、バックアップとリストアをしっかりおこなっておいて、再導入する必要があった。またWindowsのリカバリーパティションも複製されないようなので、リカバリーディスクを作成しておく必要がありそうだ。
Windows7の起動とアプリケーションの起動が圧倒的に早くなった。 めでたしめでたし、と思ったが、付属のSamsung Magicianという管理ツールを使ってみると、AHCIモードが無効になっているので、最適状態ではない、というようなメッセージが出ている。
AHCIというのはディスクの管理モードのようで、BIOS画面を見るとHDDのアクセス方法の選択肢の一つになっていた。 このパソコンの規定値はIDEアクセスモードになっており、これをAHCIに変えてやればよいと思ったのだが、設定を切り替えて作動させてみるとWindowsが起動途中でクラッシュする。いわゆるBSOD(Blue Screen of Death=青いエラー画面)が出てその内容を読む暇もなくリセットがかかる。

しょうがないので、Bios設定を元にもどし、再起動。 Google検索で”BSOD Windows 7 AHCI SSD”のキーワードで検索したら、 以下の記事を発見。なんと4ねんん以上も前に書かれている。こういうEarly Adapterがいてくれるおかげで後からついていく我々はネット検索するだけで問題解決ができてしまう。

HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlset / Services /msahci
このレジストリの値を0に変更(自分の場合は3になっていた)してWindowsを終了し起動の途中でF2キー(Deleteキーの場合もある)を押してBios画面を呼び出して AHCIに設定しWindows7を起動すると今度はクラッシュすることなく必要なドライバーを導入した後、再起動を促されるのでもう一度リブートして解決。

Python、comprehension を使った一括処理

Pythonには” … for … in”という構文を使った、一括でメンバー要素を処理する機能がある。Comprehensionと呼ばれ、リスト、セット、辞書に使える。
リストの使用例

>>> a_list =list(range(10))
>>> a_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a_list = [x**2 for x in a_list]  --List comprehension
>>> a_list
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

If を使い、要素のFilteringをしてから処理することもできる。下はリスト中、偶数だけを処理して新しいリストを作成した例。 

>>> a_list = list(range(10))
>>> a_list = [x**2 for x in a_list if (x%2 ==0)]
>>> a_list
[0, 4, 16, 36, 64]

Python Dictionary の キーと値をスワップして新しい辞書を作る。

>>> week_dict={'Mon':'月','Tue':'火','Wed':'水','Thu':'木','Fri':'金','Sat':'土','Sun':'日'}
>>> youbi_dict={value:key for key,value in week_dict.items()}
>>> youbi_dict
{'木': 'Thu', '土': 'Sat', '月': 'Mon', '火': 'Tue', '水': 'Wed', '日': 'Sun', '金': 'Fri'}
>>> week_dict
{'Mon': '月', 'Fri': '金', 'Tue': '火', 'Sat': '土', 'Sun': '日', 'Wed': '水', 'Thu': '木'}
>>> week_dict['Fri']
'金'
>>> youbi_dict['日']
'Sun'

辞書は順番はキープしないのだ。

Raspberry Pi でパソコン電源をInternet上から操作

家の外部からタブレットなりノートパソコンなりを使って自宅のパソコンにリモートアクセスするためのアプリというのは色々ある。Internet経由でアクセスする、というもので、Linuxでは当たり前のように実装されているし、 WindowsでもRemote Desktopというアプリケーションが同梱されているし、ファイアウオールでRemote Desktopが使えない環境でもWebベースのTeamViewer とかlogmeinというサードパーティの製品を使えばセキュアな接続がいとも簡単にできてしまう。 Chromeをブラウザとして使用しているのならChrome remote desktopというアプリが今の旬である。

 なぜそんなことが必要か、という疑問が湧くかもしれないが自分の場合、外部からお気に入りの開発環境にログインし、コード開発を一つのマシン上で行う、という使い方がメインになっている。 もちろん将来的にすべての作業がブラウザ上でできる、という環境が構築されればそんな必要はなくなるわけだが、

問題はパソコンにアクセスするには当然のことながら当該パソコンの電源が入っていなくてはならない、という事。
 エコの観点からみると年がら年中つけっぱなしになっているパソコン、というのはエネルギーの浪費に見える。 WEBサーバーを自宅のパソコンを使って構成していた時には電源をつけっぱなしにするしかなかったのだが、アイドル状態でも常に80Wくらいの消費電力が発生していた。
 現在はCubieboardという、手のひらに収まるサイズのArmcortexの開発ボードをサーバーとして使って賄っており、消費電力は3W以下だ。

で、パソコンの電源を使うときだけ遠隔操作でオンする方法がないか調べてみた。

 InstructableにElectric Impというモジュールを使って電源のオンオフをする方法が紹介されている
このモジュール、SDカードと同じform factorだが、内部にWifiモジュールとArm Coretex M3を内臓したれっきとした開発ボードであって、クラウドサービスに接続してパソコンやタブレット上から専用のコントロールパネルアプリを使って接続されたデバイスのリモートコントロールができるようになっている。

InstructableではこのElectric Impに簡単なトランジスタを追加して、PCのPower switch lineを瞬間的にショート状態にする。(つまりパソコンのスイッチを押したのと同じ状態にする)ことによってPCを起動する方法が述べられている。 Electric Impの値段は25ドル程度だが、サポート用の部品(Imp用のブレークアウトなど)を買い足すと40ドルくらいの出費になりそうだ。
自宅でcubieboardのWEBサーバーを随時動かしているのであえてアカウントを作ってクラウドを使ってコントロールする必要はないわけで、 そうすると似たようなことはArduinoでもできるはずと思うわけだが、これまたArduino本体にWifi、あるいはEthernetシールドを追加すると40ドルくらいの出費になる。 CubieBoardのGPIOをパソコンのスイッチに接続して操作することも可能だろうが、部屋が2階と地下室に分かれているし、メインサーバーになっているカードのGPIOで他のデバイスをハードウエアコントロールというのは安全性の面から心理的抵抗がある。

そこで遊び終わって引出しに眠っていたRaspberry Piを使うことにした。Desktop用のLinuxが走るほどのグラフィック性能を持つボードをただの電源スイッチとして使う、というといかにももったいない感じがするのではあるが Piの値段も含めて40ドルくらいで済んでしまうのでコストパーフォマンスの面から考えると他の方法に比べても高くはない、というか他の手間を考えるとこちらのほうが安上がりの感じ。

調べてみるとデバイス制御をPythonベースのhttp サーバーから実行できるWEBIOPIというPi用のライブラリーを発見した。 これをインストールするとGETとかPOSTのHTTP用のプロトコルを使ったRESTという手法でハードウエアのコントロールができるようになる。 つまりWEBサーバー上にページを作り、そのページ上にボタンを描画して、WEBIOPIで提供されているRESTコールを紐つけるという方法でPiのGPIOピンの遠隔操作ができるようになる。 このRESTという手法、非常に単純で、urlのパスに模してパラメーターをサーバーに送ってあげるというもの。GETはアドレスをブラウザで指定するだけで実行できるのでたとえば APIですべてのGPIOの状況を取得するAPIを使うには webiopiをバックグラウンドで走らせている状態で、

https://example.com/GPIO/*

とアドレスをブラウザに打ち込むだけで、Jason書式でGPIOの各ピンの状況が返ってくる。 ただし、これではページの表示自体がJasonのレスポンスになるので実用的ではなく、実際にはJavaScriptでコードを書くことになるが、webiopiにはうwebiopi.jsというヘルパーファイルが同梱されているので、使う難易度は低くなっている。

GPIOの使い方だが、
出力用に設定したGPIOピンをトランジスタを介してパソコンの電源スイッチとパラレルに接続し、パルス上の信号を出力してやるとパワースイッチを押したのと同様のことになり電源が立ち上がる。(電源が入っているときには逆に電源が落ちる)。電源スイッチへ接続されるピンはパソコンのマザーボード上のフロントパネルコネクター部分(パソコンケースのケーブル類を接続するコネクタ部分)に接続ピンがあるのでワイヤーをスプライスしてつなげてやればよい。。
また信号を出す前にパソコンの電源が入っているかどうかをわかっている必要があるのだが、フロントパネルコネクターには電源表示用のLEDへ接続されるピンも存在している。 そこでこのピンをGPIOでモニターすることによってパソコンに電源が入っているかどうかの判定をすることにした。

実際に組んだ回路。使ったGPIOピンは25をパワースイッチ用の出力に、24をLED電圧モニター用の入力にそれぞれ使用。 IntelのPC Interface 仕様(下に抜粋を載せます)を読む限り、パワースイッチ端子はトランジスタに直接接続(PWR+をコレクタ側に、PWR-をEmitter側に)しても大丈夫と思うが、5Vの小型リレーがたまたま手元にあったので使ってみた。NPNトランジスタのかわりに2N7000のようなFETを使えば、R1は必要ない。入力ピンのほうはLEDのVfでクランプされる電圧になるので規定の3.3V以下。万が一LEDがオープンとなっ場合5Vかかってしまうが、GPIOには保護用のクランプダイオードくらいはいっているのだろうと勝手に思い込んでいるので,保険は電流制限のR2のみ。

Table 5. Switch/LED Front Panel Electrical Connection

Pin Signal Description
2 FP PWR/SLP MSG LED pull-up (330 ohm) to +5 V
6 PWR_SW_P Power Switch high reference pull-up (10000 ohm) to +5 V
8 PWR_SW_N Power Switch Low reference pull-down (100 ohm) to GND

贅沢の極み?

贅沢の極み?


html pageの記述


<!DOCTYPE html>
<html lang="en">
<head>
<base href="https://example.com/" />
<title>PC power </title>
<!--[if IE]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>

<body>
    <h2>Turn On Basement PC</h2>
    
パソコンの電源操作ボタンでやんす。!
<form class="buttonBar"></form>

<script type="text/javascript" src="//code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="poweronbutton.js"></script>
</body>
</html>

参照されているJavascriptの記述

/**
 * Created on 5/4/14.
 * poweronbutton.js となっているが、実際にはGPIOのモニターも行う総括的なコード
 * powerbutton element id='pb'
 * html form tag class = buttonBar.
 * GPIO #25 connected to 1n2222 which drives spdp relay to momentariry close power switch.
 * PC power switch is momentary switch.  if PC is off, it will turn on PC.  if PC is on, it will turn off pc
 * relay connected to power connections of PC system panel terminals.
 * GPIO24 connected to Power LED terminal.
 * webiopi (python httms and coap server) installed on target raspberry pi
 *
 */
function setupGPIO(){   // set GPIO25 to out for pc power switch connection.
                        // and  GPIO24 to in  for monitoring PC power LED terminal status
    $.post( 'https://example.com/GPIO/24/function/in',
        function(data) {
            if (data==='IN')setTimeout(monitorPower(),1000);
                  });
    $.post( 'https://example.com/GPIO/25/function/out',
        function(data) {
            data =(data=='OUT')?'PC Power':'setup failed';
            $('#pb').attr("value",data);

        });
}

// }
function turnon(){ // RET command to output pulse
    $.post(
        'https://example.com/GPIO/25/sequence/1000,010',
        function(data) {
            data=(data==0)?'Power switch pushed':'NG';
            $('#pb').attr("value",data); }

    );
}
function monitorPower(){//monitor GPIO 24 status every one second
    $.get('https://example.com/GPIO/24/value',
        function(data){
            data= (data==='0')?'PC is OFF':'PC is ON';
            $('#powerstatus').html(data);
    setTimeout(monitorPower(),1000); //call myself every 1second

})

}
$(function(){
    $('<input type="button" class="power" id="pb" />')
        .appendTo('.buttonBar')
        .attr("value", "Initializing")
        .attr("title", "Turn on Somethin'")
        .click(function () {
            turnon();
        });
    $('<div></div>')
        .appendTo('.buttonBar')
        .attr('id','powerstatus');
      setupGPIO();
    }
);

ターゲットのRaspberry Piにwebiopiが導入され起動されていることが前提になる。 また、上の方法では同梱されてくるwebiopi.jsは使わずに自前のJavaScriptでREST APIを直接アクセスしている。

ページの仕組み:
ブラウザーがページを読み込み終わった時点で、上のjavascriptが以下の作業を実行する。
ボタンを描画し、ボタンのラベルを”Initializing” と表示する。
GPIO25を出力ピンに設定。 ボタンのラベルを”PC Power”と書き換え、ボタンのクリック動作にパルスを送信するRESTコマンドを紐つける。
GPIO24を入力ピンに設定。同時に入力ピンの1秒ごとのモニターをスタート。WEBIOPIからRESTで返された状況に応じてページ上に”Power is ON” または ”Power is OFF”を一秒ごとに更新表示

JavaScriptの部分はRefactoringやnamespacing をやっていないので改善の余地あり。またPower LEDのモニターだけではパソコンがオンしていることはわかっても、実際にWindowsが立ち上がっているかどうかはわからないので、何らかのインターネットサービスをPi側からモニターする手法を併用するほうがよさそうだし、CSSの記述も追加してページの見栄えもよくしたいと思うが、一応初期の目的はこれにて達成。

なお、WEBIOPI自体にログイン形式のセキュリティ機能が実装されており、ページの最初のロード時にログインネームとパスワードを聞いてくる仕組みになっている。ログインとパスワードの初期値がそれぞれ”webiopi” と”raspberry” となっているので、マニュアルの手順に従って変更しておく必要がある。

また、Raspberry Piへの電源だが、パソコンの電源に5V standbyが存在しているため、ここから引き込んでいる。24p/20pコネクタの紫の線だが、マザーボードの電源側への要求スペックが500mAで電源側の仕様が2Aなので余裕のようだ。Raspberry PiもPCの筐体に入れてしまったので見た目もすっきりである。

<後記> 電力消費計を入手したので、実際のところ、どれだけエコになっているのか測定してみた。 パソコンを普通に電源投入すると80Wくらの消費になっていた。 パソコンをオフにすると7Wだ。パソコン用の電源が動いていて5Vのスタンバイ電源からPiとその他に供給しているということだ。 その差73Wだが、電気代で考えるとまったくパソコンをオンしなかった場合、年間約50ドルちょっとの節約になる。パソコンの稼働率が10パーセントくらいと仮定すると45ドルの節約なので1年でもとが取れる計算になる。