VS CodeでPowerShellファイルを作成・実行したら文字化けした

今までPowerShellPowerShell ISEを使って書いていたのですが、以下の記事を読んで、Visual Studio Codeで書いてみました。
VS Code での PowerShell サポートが強化されました - tech.guitarrapc.cóm

 
Hello world的な

"Hello world!"
"ハローワールド!"

というexample.ps1スクリプトを作成し、実行してみたところ、

Hello world!
繝上Ο繝シ繝ッ繝シ繝ォ繝・

と、日本語部分が文字化けしたため、対応をメモしておきます。

 

環境

 

原因と対応

VS Codeでファイルを新規作成するときのデフォルトの文字コードUTF-8 (BOMなし)のためです。

 
試しに、日本語が含まれるps1ファイルの文字コード

などにして実行した場合、

Hello world!
ハローワールド!

と正しく表示されました。

 
どの文字コードで保存しておくのが良いのか調べてみたところ、

より、UTF-8 with BOMが良さそうでした。

 
VS Codeでファイルの文字コードGUIで変更する場合は以下の通りです。
特集:Visual Studio Code早分かりガイド:Visual Studio Codeの使い方、基本の「キ」 (3/5) - @IT

今回はコマンドパレットを使ってみます。

  • Ctrl + Shift + Pでコマンドパレットを開く
  • chfと入力しChange File Encodingのみに絞られたところで、Enter
  • sと入力し、Save with Encodingのみに絞られたところで、Enter
  • UTF-8 with BOMを選択

 
再度実行すると、

Hello world!
ハローワールド!

となりました。

 

PowerShell ISEで作成したps1ファイルの文字コードについて

手元のPowerShell ISEでps1ファイルを作成して文字コードを確認するとUTF-8 with BOMでした。

一方、公式資料で確認すると、

By default, Windows PowerShell ISE saves new script files (.ps1), script data files (.psd1), and script module files (.psm1) as Unicode (BigEndianUnicode) by default.

How to Write and Run Scripts in the Windows PowerShell ISE

UTF-16 BEと書かれていました。

 
この違いはどこから来るのかを調べてみましたが、公式資料は見当たらないものの、v3.0から変更になったようでした。

 

文字コードまわりの資料

PowerShell

 

一般

#stapy #glnagano 第7回 Python勉強会 in GEEKLAB.NAGANOに参加しました

7/6にギークラボ長野で開かれた、第7回 Python勉強会 in GEEKLAB.NAGANOに参加しました。
Python勉強会 in GEEKLAB.NAGANO #7 - GEEKLAB.NAGANO | Doorkeeper

 
「みんなのPython勉強会 #14」の東京会場を中継する形での勉強会でした。資料などは以下のページにまとまっています。
みんなのPython勉強会#14 - connpass

 
今回のテーマは「Python x Web」ということで、HTTP通信の基本からスクレイピングまでの盛りだくさんでした。

 

いま、ふたたびのWeb入門 (辻 真吾さん)

Webの基礎から詳しく解説していただきました。

最近PythonでWebサーバを書いてみた直後だったこともあり、自分の理解度の確認と復習ができてよかったです。

 

bottleではじめるWEBアプリの最初の一歩 (山田 聡さん)

Webアプリの最初の一歩ということで、Bottleを使ったWebアプリの説明がありました。

1ファイルで書かれているWebフレームワークであり、レンタルサーバでも動かせる場合もあるので、Bottleは扱いやすく感じています。

 

Reactiveなウェブサイトへの誘い (山下 陽介さん)

DjangoといくつかのJavaScriptフレームワークの紹介が参考になりました。

DjangoとTornadoを併用とあったことから、Tornadoはどんなものか気になったため、今度さわってみようと思いました。

もし資料が公開されたら後で読み返そうと思います。

 
勉強会中にDjango + WebSocket調べてみたところ、HerokuのblogにDjango Channelsの記事がありました。DjangoだけでWebSocketを扱える未来が来るのか、気になりました。
Finally, Real-Time Django Is Here: Get Started with Django Channels | Heroku

 

Webスクレイピング - 小手先の技術 (嶋田 健志さん)

Webスクレイピング用のPythonライブラリの紹介・使い方でした。

自分がさわったことがあったのはlxmlだけだったため、それ以外のライブラリはどんな感じで動かすのか気になっていたので、ためになりました。

Scrapyは気になっていましたが、結構大がかりと感じました。

また、紹介のあった「PythonによるWebスクレイピング」も良さそうでした。

 

その他

今回は平日の定時後ということもあり、

を使って移動しました。

回数券の有効期間は1ヶ月以内であるものの、特急の乗り継ぎもできるようで、なかなか良いものです。

 
最後になりましたが、開催・運営をされたみなさま、ありがとうございました。

特に、勉強会中に東京-長野間中継の調整で手を尽くしてくださったみなさま、ありがとうございました。

Visual Studio CodeでPython + Djangoを書いて、py.testを実行してみた

それなりの規模のDjangoアプリを書く場合、PyCharmなどのIDEを使っています。

ただ、諸般の事情によりIDEが使えないことも考えて、Visual Studio Code(以下VS Code)のPython拡張を試してみました。
Python with Visual Studio Code - Visual Studio Code

 
なお、今回は上記の公式ドキュメント例にもある通り、DonJayamanneさんのPython support for Visual Studio Codeを使います。
DonJayamanne/pythonVSCode: Python support for Visual Studio Code

 
目次

 

環境

 

環境準備

Python support for Visual Studio Codeのインストール

コマンドプロンプトからDjango用のディレクトリを用意し、そのディレクトリでVS Codeを起動します。

# ディレクトリ作成と移動
D:\Sandbox>mkdir vscode_django
D:\Sandbox>cd vscode_django

# カレントディレクトリとして VS Codeを起動 (末尾のドットを忘れずに)
D:\Sandbox\vscode_django>code .

 
VS Codeが起動したら、

  • Ctrl + Alt + P(もしくはF1)でコマンドパレットを起動
  • ei(Extensions: Install Extension) と入力して、拡張機能:拡張機能のインストールを選択
  • Python (DonJayamanne)を選択し、インストール
  • インストール後、VS Codeを再起動

と、Pythonを設定します。

 

Djangoのインストールと確認

今回はVS Code上のターミナルで実行します。ただ、現時点のバージョンではコピー&ペーストができません(↑・↓で入力履歴の再表示は可能)。
ターミナルを統合した「Visual Studio Code」インサイダー版、6月から日毎リリースに - 窓の杜

  • 表示 > Toggle Integrated Terminal (もしくはCtrl + @) を選択
  • 画面の下にターミナルが開く
  • ターミナルに以下を入力
# virtualenv環境を作成
D:\Sandbox\vscode_django>virtualenv -p c:\python35-32\python.exe env
D:\Sandbox\vscode_django>env\Scripts\activate

# pipでインストール
(env) D:\Sandbox\vscode_django>pip install django
...
Successfully installed django-1.9.7

 
続いて、Djangoのインストール先を確認するため、以下のPythonスクリプトを作成します。
Python Tips:ライブラリ・モジュールの場所を調べたい - Life with Python

django_checker.py

import django
print(django.__file__)

 
Debug Viewに切り替えます(Ctrl + Shift + D)。

  • 実行ボタンを押す(F5)
  • 環境の選択を求められるので、Pythonを選択
  • 情報バーにPlease set up the launch configuration file for your applicationが、エディタにlaunch.jsonが表示
  • launch.jsonはデフォルトのまま、django_checker.pyファイルを選択
  • 実行環境でPythonが選択されていることを確認の上、実行ボタンを押す(F5)
  • ファイアウォールのブロック表示がでたら、必要な内容をチェックしてアクセスを許可
  • デバッグコンソールに以下が表示
Traceback (most recent call last):
  File "d:\Sandbox\vscode_django\django_checker.py", line 1, in <module>
    import django
ImportError: No module named 'django'

Djangoが認識されていないことから、virtualenvのPythonインタプリタは使われていないようです。

 
公式ドキュメントによると、対応方法としては

  • settings.jsonpython.pythonPathを指定する
  • virtualenv環境をactivateしてから、VS Codeを起動する
  • launch.jsonpythonPathを指定する
    • 今回の場合、"pythonPath": "${workspaceRoot}/env/Scripts/python.exe",
    • ただし、この場合はデバッグ時だけ有効で、エディタのインテリセンスなどが効かない

の3つが挙げられていました。
Python Path and Version · DonJayamanne/pythonVSCode Wiki

エディタのインテリセンスは効かせたいこと、グローバルな設定は避けたいことから、今回はvirtualenv環境をactivateしてから、VS Codeを起動する方法をとります。

 
そのため、いったん VS Codeを閉じてから、以下のようにVS Codeを起動します。

# virtualenvをon
D:\Sandbox\vscode_django>env\Scripts\activate

# VS Codeの起動
(env) D:\Sandbox\vscode_django>code .

 
再度、django_checker.pyファイルを選択し、デバッグ実行(F5)します。デバッグコンソールには

D:\Sandbox\vscode_django\env\lib\site-packages\django\__init__.py

と表示され、virtualenvのPythonインタプリタで実行されるようになりました。

 

Djangoアプリの作成

It worked!の確認

VS Code ターミナルを起動し(Ctrl + @)、Djangoアプリを作成します。

(env) D:\Sandbox\vscode_django>django-admin startproject myproject .
(env) D:\Sandbox\vscode_django>python manage.py startapp myapp

また、myproject/settings.pyINSTALLED_APPSに、上記作成のアプリmyappを追加します。

 
Djangoアプリができたため、

  • Debug viewに切り替える(Ctrl + Shift + D)
  • Djangoを選んでから、実行ボタンを押す(F5)
  • manage.pyの一行目のところで停止するが、そのまま続行(F5)
  • Debug Consoleに開発サーバの起動が表示
  • ブラウザでhttp://localhost:8000/へとアクセスすると、It worked!が表示されます。

を行い、動作を確認します。

 
なお、該当するlaunch.jsonの内容は

{
    "name": "Django",
    "type": "python",
    "request": "launch",
    "stopOnEntry": true,
    "program": "${workspaceRoot}/manage.py",
    "args": [
        "runserver",
        "--noreload"
    ],
    "debugOptions": [
        "WaitOnAbnormalExit",
        "WaitOnNormalExit",
        "RedirectOutput",
        "DjangoDebugging"
    ]
},

でした。

--noreloadがあることから、オートリロードされないのがデフォルトのようです。もし、オートリロードしたい場合はその部分を削除します。

 

Djangoアプリへ機能を追加

Hello worldを表示するよう、機能を追加します。

myproject/urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^myapp/', include('myapp.urls', 'my')),  # 追加
]

 
myapp/urls.py

from django.conf.urls import url
from django.views.generic.base import TemplateView

urlpatterns = [
    url(r'^$', 
        TemplateView.as_view(template_name='hello.html'),
        name='hello'),
]

 
myapp/templates/hello.html

<h1>Hello world!</h1>

 
完成したため、

  • Djangoを選択して実行ボタンを押す(F5)
  • http://localhost:8000/myapp/へアクセスすると、Hello world!が表示

にて動作を確認します。

 

py.testの設定と実行

以前、Djangoアプリをpytest-djangoでテストしたことがあったため、同じように作業します。
Djangoアプリについて、pytest-djangoを使ってテストしてみた - メモ的な思考的な

 
ターミナルにてインストールします。

(env) D:\Sandbox\vscode_django>pip install pytest pytest-django

 
pytest.iniを書きます。

pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE=myproject.settings
norecursedirs=env

 
URL解決のテストを書きます。

py.testのデフォルトでは、test_*.pyというファイル名であればテストファイルとみなされます。そのため、Djangoが自動生成したmyapp/tests.pyはテストの対象とはなりません。
My tests are not being found. Why not? | FAQ — pytest-django documentation

そこで、myapp/tests/ ディレクトリを作成し、その中にテストファイルtest_urls.pyを作成することにします。

 
まずはエラーとなるよう、テストコードを書きます。

myapp/tests/test_urls.py

# myapp.urls.py
# urlpatterns = [
#    url(r'^$', TemplateView.as_view(template_name='hello.html'), name='hello'),]

# テストコード
class URL解決テスト(TestCase):
    def test_helloのパスが404とならないこと(self):
        try:
            resolve('/mysite/hello')
        except Resolver404:
            pytest.fail('raise error')

 
ターミナルから実行します。

(env) D:\Sandbox\vscode_django>py.test

...
myapp\tests\test_urls.py:11: Failed

エラーになりました。また、一部が文字化けしています。

 
テストが通るように修正します。

myapp.urls.py

urlpatterns = [
    url(r'^hello$', 
        TemplateView.as_view(template_name='hello.html'),
        name='hello'),
]

 
もう一度テストします。

(env) D:\Sandbox\vscode_django>py.test
...
========================== 1 passed =...

テストが通りました。

 
以上より、VS Codeを使ってPython + Djangoを書いて、py.testを実行することができました。

 

IDE機能

IDE機能もありました。

 

インテリセンス

f:id:thinkAmi:20160705220750p:plain

 

メソッドの引数の表示

f:id:thinkAmi:20160705220802p:plain

 

コードナビゲーション
  • Go To Definition(定義へ移動)
  • Peek Definition(定義をここに表示)
  • Find All References(すべての参照の検索)

f:id:thinkAmi:20160705220812p:plain

 

linter設定

Linting · DonJayamanne/pythonVSCode Wiki

 
他にもいろいろとありました。

なお、現時点では、タブはまだprerelease Insiders buildのため、今後に期待します。
Tabbed editor support in Visual Studio Code

2016/7/9 追記

先日リリースされた1.3.0にてタブ機能が追加されました。

2016/7/9 追記おわり

 

ソースコード

GitHubにあげておきました。
thinkAmi-sandbox/vscode_django-sample

なお、デバッグ時のみvirtualenv環境が使われるのを確認するために、pythonPathを追加した.vscode/launch.jsonも入れてあります。

 

その他参考

 
なお、公式ドキュメントではlaunch.jsonに関する説明が見当たりませんでした。そのため、以下を参考にしました。
特集:VS Code早分かりガイド:Visual Studio CodeでNode.jsアプリをデバッグする (2/4) - @IT

「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」が良かったのでPythonで書いてみた

Pythonでhttp.serverを使っているうちに、せっかくならもう少し下のレイヤについても知りたくなりました。

何か良い資料がないかを探したところ、本当の基礎からのWebアプリケーション入門――Webサーバを作ってみようというページを見つけ、さらに書籍「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」発売されます - プログラミング言語を作る日記にて、書籍として発売されたのを知りました。

 
自分はEPUB/PDFセットをGihyo Digital Publishingで買って読みました。

gihyo.jp

 
感想としては、

  • Webサーバを作るのに必要な用語が、1つずつ丁寧に詳しく解説されている
  • どうしてこう書くのかという理由が書かれており、出典としてRFCを示している
  • チュートリアル的にWebサーバを作っていくので、理解しやすい
    • 知りたかったソケットプログラミングから始まっていたのも良かった
  • Apacheの設定にも一部ふれられていた

など、まさに自分が知りたいポイントについて書かれていたため、とてもためになりました。ありがとうございました。

 
書籍のソースコードJavaだったのですが、別の言語で実装すればさらに理解が深まるだろうと考え、第1章・第2章のWebサーバ作成をPythonで書いてみました。なお、仕様の一部は簡略化しました。

Python版のソースコードGitHubに置いておきます*1
thinkAmi-sandbox/syakyo_create_web_server

 
第3章以降はTomcatのようなものを作っていたため、現時点では読むだけにしました。もし、第3章以降もPythonで書くとしたら、WSGIで実装する形になるのでしょうか。
java - What is the Python equivalent of Tomcat? - Stack Overflow

 
以下、Pythonで書いた時に悩んだことをメモしておきます。

 
目次

 

環境

  • Windows10 x64
  • Python 3.5.2 32bit

 

1.3.2 TCPサーバ/クライアントのプログラム

ソケットを使ったプログラムの流れとしては、書籍中の他、以下のページが参考になりました。
サーバプログラム

Pythonでソケットを使うには、標準ライブラリのsocketを使います。
18.1. socket — 低水準ネットワークインターフェース — Python 3.5.1 ドキュメント

Pythonでのソケット通信については、以下が参考になりました。
プログラミングと慶應通信 : Pythonによるsocket programming入門

なお、Python版では終了マークとして"0"を送信するは実装しませんでした。

 

ソケットを使った送受信

Pythonでソケットを使ってデータを送受信する際、そのデータはバイト列とする必要があります。

 
そのため、

# 送信
socket.send(data.encode("utf-8"))

# 受信
data = socket.recv(1024)
data.decode("utf-8")

のように、送信前にエンコード・受信後にデコードしました。

ただ、今回エンコード・デコード用文字コードとしてutf-8を使いましたが、本来どの文字コードを使うべきかは分かりませんでした。

 

ファイルの入出力

以下が参考になりました。
ファイル - Dive Into Python 3 日本語版

 

1.5.3 1つのHTMLファイルを返す

HTTPレスポンスヘッダのDateを出力する

Pythonではどのようにやるのがいいのかを探したところ、stackoverflowに回答がありました。
http - RFC 1123 Date Representation in Python? - Stack Overflow

いくつか方法がありましたが、email.utilsライブラリは今でも機能追加されていることから、email.utils.formatdate(usegmt=True)を使うことにしました。

 

1.5.4 普通にWebページを表示できるようにする

Pythonのマルチスレッドについて

今回は標準ライブラリのthreadingを使います。
17.1. threading — スレッドベースの並列処理 — Python 3.5.1 ドキュメント

PythonのThreadやProcessについては、以下が参考になりました。
python - Should I use fork or threads? - Stack Overflow

 

accept()中の停止について

Ctrl+Cでは停止できなかったため、Breakキーで強制停止します。
Python socket accept in the main thread prevents quitting - Stack Overflow

 

レスポンスボディの送信について

Java版とは異なり、テキストデータと画像データを同じ方法で返すやり方が分からなかったため、

if "text" in content_type:
    with open(DOCUMENT_ROOT + path, encoding="utf-8") as f:
        r = f.read()
        write_line(sock, r)
elif "image" in content_type:
    with open(DOCUMENT_ROOT + path, mode="rb") as f: 
        r = f.read()
        # 画像の場合、読み込んだバイナリに改行コードを加えてはいけないので、そのまま送る
        sock.send(r)

のように、Content-Typeを見て処理分岐する形にしました。

 

2.6 Modoki/0.2のソースコード

エンコードされた日本語URLのデコード

Python3のため、urllib.parse.unquote()を使ってデコードしました。

 

Windowsでのos.path.join()

Windowsの場合、os.path.join()を使うと

DOCUMENT_ROOT = "D:/Sandbox/syakyo_create_web_server/src/static"
path = "/index.html"
print(os.path.join(DOCUMENT_ROOT, path))
# => D:/index.html

のように、相対パスが返ってきます。
os.path.join() | 11.2. os.path — 共通のパス名操作 — Python 3.5.1 ドキュメント

 
今回は絶対パスが欲しかったため、stackoverflowを参考にして、

docroot_drive = DOCUMENT_ROOT[0:2]
docroot_path = DOCUMENT_ROOT[2:]
full_path = os.path.join(docroot_drive, os.sep, docroot_path + path)
print("fullpath: {}".format(full_path))
#=> D:/Sandbox/syakyo_create_web_server/src/static/index.html

としました。
Python os.path.join on Windows - Stack Overflow

 

301リダイレクト時のChromeの挙動について

書籍とは異なりChromeで動作確認をしていたのですが、301リダイレクト時にキャッシュされているような挙動がありました。

調べてみると、やはりキャッシュされているようでした。
chromeは、301リダイレクトをキャッシュしている - too_youngの日記  
 

htmlの文字コード設定について

書籍のままだとChromeで文字化けしたため、<meta charset="UTF-8">タグを追加しました。

 

ソースコード

再掲となりますが、以下となります。
thinkAmi-sandbox/syakyo_create_web_server

*1:理解のためのコメントをたくさん書いてありますが、あまり気にしないでください...

pure Pythonのライブラリapcaccessを使って、apcupsdのデータを取得する

apcupsdで取得できるUPS情報をPythonのオブジェクトとして扱う方法を探したところ、apcaccessライブラリを見つけました。

 
試してみた時のメモを残します。

 

環境

  • Windows10 x64
  • Python 3.5.1 32bit
  • apcaccess 0.0.4

 

実装

PyPIGitHubにはドキュメントがないため、テストコードやソースコードを見たところ、

  • apcaccess.status.get()で、UPSの情報を取得
    • 引数hostIPアドレスなどを与えれば、リモートのapcupsdの情報も取得可能
  • apcaccess.status.parse()で、PythonのOrderedDictへ変換
  • apcaccess.status.print_status()で、読みやすい形でprintする

ということが分かりました。

 
usage_apcaccess.py

from apcaccess.status import get, print_status, parse

def main(host="localhost"):
    # apcupsdよりデータ取得
    raw = get(host=host)
    # rawデータだと文字化け
    print(raw)
    print("-"*10)

    # OrderedDictへparse
    parsed = parse(raw)
    print(parsed)

    # 読みやすい形でprint
    print_status(raw)
    print("-"*10)

if __name__ == "__main__":
    # ローカルホスト
    # main()
    
    # リモートホスト
    main(host="192.168.0.10")

 
結果

>python usage_apcaccess.py

# print(raw)
 APC      : xxx,xxx,xxxx
 'DATE     : 2016-06-29 
 HOSTNAME : your host
 )VERSION  : 3.14.12 (29 March 2014) Win32
 UPSNAME  : UPS_IDEN
 CABLE    : Custom Cable Smart
 DRIVER   : APC Smart UPS (any)
 UPSMODE  : Stand Alone
...

# print(parse(raw))
OrderedDict([('APC', 'xxx,xxx,xxxx'), ('DATE', '2016-06-29'), ('HOSTNAME', 'your host'), ('VERSION', '3.14.12 (29 March 2014) Win32'), ('UPSNAME', 'UPS_IDEN'), ('CABLE', 'Custom Cable Smart'), ('DRIVER', 'APC Smart UPS (any)'), ('UPSMODE', 'Stand Alone'), ...])

# print_status(raw)
APC      : xxx,xxx,xxxx
DATE     : 2016-06-29
HOSTNAME : your host
VERSION  : 3.14.12 (29 March 2014) Win32
UPSNAME  : UPS_IDEN
CABLE    : Custom Cable Smart
DRIVER   : APC Smart UPS (any)
UPSMODE  : Stand Alone

 
なかなか良さそうです。

 

ソースコード

GitHubに上げました。usage_apcaccess.pyが今回のスクリプトファイルです。
thinkAmi-sandbox/apcupsd_python-sample

Windows10 + Python3 + apcupsdで、UPSの状態をブラウザから確認する

以前、あるWindows端末に接続されているAPCUPSの状態を、別の端末のブラウザから確認できるよう、Rubyを使って実装しました。
Windows7 + WEBrick + apcupsdで、UPSの状態をブラウザから確認する - メモ的な思考的な

 
今回は、Pythonを使って同じことを試してみました。

なお、apcupsdのセットアップ方法については上記のエントリと同じため、省略します。

 

環境

  • Windows10 x64
  • Python 3.5.1 32bit
  • apcupsd 3.14.12
    • 現時点で最新版の3.14.14では、multimon.cgiを実行した時にError: Cannot open hosts fileというエラーが出て正しく動作しないため、バージョンを下げています。

 

PythonCGIを動かす

Rubyの時はWEBrickを使いましたが、Pythonで同じようなものがないかを探したところ、標準ライブラリhttp.server.CGIHTTPRequestHandlerを使えば良さそうでした。

CGIHTTPRequestHandlerでは、カレントディレクトリ + cgi_directoriesCGIディレクトリとして認識されます。そのため、スクリプト実行時にos.chdir()でカレントディレクトリを変更しておく必要があります。
How to set the DocumentRoot while using python's HTTPServer? - Stack Overflow

 
実際のコードは以下の通りです。

execute_apcupsd_cgi.py

from http.server import CGIHTTPRequestHandler, test
import os

def main():
    os.chdir("C:/apcupsd")
    CGIHTTPRequestHandler.cgi_directories = ["/cgi"]
    test(HandlerClass=CGIHTTPRequestHandler, port=8080)

if __name__ == "__main__":
    main()

 
なお、今回はhttp.server.test()を使いましたが、test()関数のソースコードやドキュメントを参考にして、自作しても良さそうです。

 
あとは、python execute_apcupsd_cgi.pyで起動し、

  • http://localhost:8080/cgi/multimon.cgi
  • http://localhost:8080/cgi/upsstats.cgi

などにアクセスして、ブラウザに表示されればOKです。

 

ソースコード

GitHubに上げました。execute_apcupsd_cgi.pyが今回のスクリプトファイルです。
thinkAmi-sandbox/apcupsd_python-sample

apcupsdで、APC製UPSのアラーム音を消す

apcupsdを使って、APCUPSのアラーム音を消したときのメモです。

 

環境

  • Windows10 x64
  • Smart-UPS 750
  • シリアルケーブル(940-0024C)を使用
  • apcupsd 3.14.12

 
なお、どのケーブルを使っているか分からない場合は以下が参考になりました。
apcupsd で APC製 UPS を電源管理する方法 - maruko2 Note.

 

準備

アラーム音を消すには、apcupsdに含まれるapctestを使います。

そのための準備として、

  • apcupsdのtrayを終了
  • サービスApcupsd UPS Monitorを終了

を行います。

 

実行

 
コマンドプロンプトからapctestを実行します。

まずは、1) Query the UPS for all known valuesで現在の状態を確認します。

>C:\apcupsd\bin\apctest.exe

apctest 3.14.12 (29 March 2014) Win32
Checking configuration ...
sharenet.type = Network & ShareUPS Disabled
cable.type = Custom Cable Smart
mode.type = APC Smart UPS (any)
Setting up the port ...
Doing prep_device() ...

You are using a SMART cable type, so I'm entering SMART test mode
Hello, this is the apcupsd Cable Test program.
This part of apctest is for testing Smart UPSes.
Please select the function you want to perform.

1) Query the UPS for all known values
2) Perform a Battery Runtime Calibration
3) Abort Battery Calibration
4) Monitor Battery Calibration progress
5) Program EEPROM
6) Enter TTY mode communicating with UPS
Q) Quit

Select function number: 1    # 入力

...
Alarm status: 0
...

Alarm statusに値が設定されています。

ユーザマニュアルConfiguration Directives Used to Set the UPS EEPROM | APCUPSD User ManualBEEPSTATEによると、現時点ではアラーム音が鳴る設定のようです。

 
続いて、Alarm statusはどのような値が取れるのかを、5) Program EEPROM > 1) Print EEPROM valuesにて確認します。

That is all for now.

1) Query the UPS for all known values
...
5) Program EEPROM
...
Q) Quit

Select function number: 5    # 入力

This is the EEPROM programming section of apctest.
Please select the function you want to perform.

 1) Print EEPROM values
...
 Q) Quit

Select function number: 1    # 入力

Doing prep_device() ...

Valid EEPROM values for the APC Smart UPS (any)

                         Config        Current  Permitted
Description              Directive     Value    Values
===================================================================
...
Alarm delay              BEEPSTATE     0        0 T N
...
===================================================================
...

現在の0の他、TNを設定できそうです。

 
Nがアラーム音を消す設定のため、5) Change alarm delay にて作業を行います。

 1) Print EEPROM values
...
 5) Change alarm delay
...
 Q) Quit

Select function number: 5    # 入力

Enter new alarm delay: N    # 入力

# 結果
The old UPS alarm status is: 0
The new UPS alarm status is: N

 
1) Print EEPROM valuesにて、設定結果を確認します。

 1) Print EEPROM values
...
 5) Change alarm delay
...
 Q) Quit

Select function number: 1    # 入力

Doing prep_device() ...
...
                         Config        Current  Permitted
Description              Directive     Value    Values
===================================================================
Alarm delay              BEEPSTATE     N        0 T N

変更が反映されていました。

 
以上で作業は終わりのため、apctestを終了します。

 1) Print EEPROM values
...
 Q) Quit

Select function number: Q    # 入力

End EEPROM programming.

1) Query the UPS for all known values
...
Q) Quit

Select function number: Q    # 入力

End apctest.

 
最後にステータスを確認します。

サービスApcupsd UPS Monitorを開始後、コマンドプロンプトより実行します。

>C:\apcupsd\bin\apcaccess.exe status
...
ALARMDEL : No alarm  # 更新されている
BATTV    : 27.5 Volts
...

No alarmであり、アラーム音を消す設定になっていることが確認できました。