0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで始めるテストツール製作(7)ez Shareからのファイル取得

0
Posted at

1. はじめに

ez Shareは1.無線LAN親機、2.Webサーバ、3.ストレージ(マイクロSDメモリ)の3つの機能を備えるSDメモリカードアダプタです。マイクロSDメモリを入れたez Shareをデジタルカメラに挿し、撮影した写真を無線LANでスマホやPCに転送するのが主な用途ですが、例えばSDカードリーダー経由でオシロスコープのUSB端子に接続するとキャプチャしたスクリーンショットの画像ファイルを無線LAN経由で取得できます。

ez Shareおよび使用例
fig.1 ez Shareおよび使用例

組込み機器のファームウェアが外部ストレージ(USBメモリやSDメモリカード)に書き込んだデータを確認用PCに取り込んで確認する工程は手作業での外部ストレージの抜き差しがともなうため自動化が難しいのをez ShareとPythonのスクリプトで克服し、組込み系の自動テストを進化させます。

別の手段としてUSB切替器で外部ストレージの接続先を組込み機器と確認用PCで切り替えられるようにしUSB切替器を治具で操作して自動化する方法もありますが、USB切替器の操作治具が不要で構成がシンプルなところがez Shareのメリットです。

2. ez Shareの使い方

  1. マイクロSDメモリを入れたez Shareを組込み機器へ挿します
  2. 確認用PCのWi-Fiを「ez Share」に接続します
    • 初期パスワードは製品パッケージに記載されています
  3. Webブラウザでhttp://ezまたはhttp://ezshare.cardを開きます
    • 起動画面が開いて進捗バーが100%まで進むと初期画面へ遷移します
  4. 設定は「Change Configuration」を開き入力画面に「admin」を入れてConfirmを押下します。設定は次の項目があります
    • Adminパスワード
    • Wi-Fi SSID
    • Wi-Fiパスワード
    • Wi-Fiチャンネル
  5. SDカード内のファイル閲覧は「disk_list」を開きます
  6. ファイル一覧からファイルを選んでダウンロードします

ez Shareは1.SDカードアダプタ型、2.SDメモリ内蔵型、の2種類あり、本稿で使用するのは前者のSDカードアダプタ型です。「テザー撮影できないカメラでテザー撮影する」によると後者はdisk_list機能がないとのことです。

起動画面
fig.2 起動画面

初期画面
fig.3 初期画面

設定画面 1
fig.4 設定画面 1

設定画面 2
fig.5 設定画面 2

ディスクリスト 1
fig.6 ディスクリスト

3. 実装

3.1 要件

  1. ディレクトリを指定してファイル一覧のWebページ(HTMLファイル)を取得できること
  2. ファイルを指定してダウンロードできること

3.2 実装

1.ファイル一覧を取得するget_dir()、2.ファイルをダウンロードするget_download()、3.メニュー、の3つの関数を実装します。

mytools_ezShare.py
# mytools_ezShare.py by ka's@pbjpkas 2026
# MIT License
#
# 動作確認
# - Python 3.13.0 / Microsoft Windows 11 Pro 25H2
# - requests 2.32.3
#   インストール方法:py -m pip install requests
import ntpath
import requests

def get_dir(path):
    if len(path) == 0:
        print('root dir')
    else:
        print(path)
    
    url = 'http://ezshare.card/dir?dir=A:' + path
    print(url)
    
    response = requests.get(url)
    print(response.status_code)
    print(response.text)
    return True

def get_download(path):
    if len(path) == 0:
        print('ERROR, no path specified.')
        return False
    else:
        print(path)
    
    url = 'http://ezshare.card/download?file=' + path
    print(url)
    
    response = requests.get(url)
    print(response.status_code)
    
    if response.status_code == requests.codes.ok:
        with open(ntpath.basename(path), 'wb') as fp:
            fp.write(response.content)
        fp.close()
        return True
    else:
        print('ERROR, not success')
        return False

def main():
    while True:
        print('= myTools ez Share =')
        print('a: dir')
        print('b: download file')
        print('x: exit')
        
        s = input('>')
        
        if s == 'a':
            path = input('Enter path>')
            get_dir(path)
        
        if s == 'b':
            path = input('Enter path>')
            get_download(path)
        
        if s == 'x':
            if __name__ == '__main__':
                print('Bye.')
            return

if __name__ == '__main__':
    main()

4. 実行例

次のように実行します。

py mytools_ezShare.py

以下のようにメニューとプロンプト(>)が表示されればOKです。

= myTools ez Share =
a: dir
b: download file
x: exit
>

実行例のSDカードのファイル配置を以下に示します。

実行例のSDカードのファイル配置
├DS1Z_QuickPrint1.png (オシロスコープのスクリーンショットファイル)
├ezshare.cfg                      (ez Shareが自動で配置するファイル、0バイト)
├sample0.png
├sample0.txt
├sample1/
 ├sample1.bmp
 ├sample2/
  ├sample2.jpg

4.1 SDカードのファイル一覧取得

"a"を選択し一覧を取得したいパスを指定します。最上位の階層は何も入力せずEnterすればOKです。

>a
Enter path>
root dir
http://ezshare.card/dir?dir=A:
200
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="format-detection" content="telephone=no">
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link rel="shortcut icon" href="i-share/img/favicon.ico" type="image/x-icon">
<link rel="icon" href="i-share/img/favicon.ico" type="image/x-icon">
<title>Index of A:</title>
</head>
<body>
<h1><a href="photo">back to photo</a></h1>
<h1>Directory Index of A:</h1>
<pre>
   2026- 4-15   21:38:22         &lt;DIR&gt;   <a href="dir?dir=A:%5CSYSTEM~1"> System Volume Information</a>
   2016-11-12   21:36:36           0KB  <a href="http://192.168.4.1/download?file=EZSHARE.CFG"> ezshare.cfg</a>
   2014-11- 1   12: 0: 0          31KB  <a href="http://192.168.4.1/download?file=DS1Z_Q~1.PNG"> DS1Z_QuickPrint1.png</a>
   2026- 4-15   23:37:18           1KB  <a href="http://192.168.4.1/download?file=SAMPLE0.TXT"> SAMPLE0.TXT</a>
   2026- 4-15   23:38:10           2KB  <a href="http://192.168.4.1/download?file=SAMPLE0.PNG"> SAMPLE0.PNG</a>
   2026- 4-15   23: 9:18         &lt;DIR&gt;   <a href="dir?dir=A:%5CSAMPLE1"> SAMPLE1</a>

Total Entries: 6
Total Size: 34KB
</pre>
</body>
</html>

sample1\sample2ディレクトリを指定する例を以下に示します。1.パスの区切り文字は"\"、2.パスの末尾に"\"を付けない、です。

>a
Enter path>sample1\sample2
sample1\sample2
http://ezshare.card/dir?dir=A:sample1\sample2
200
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="format-detection" content="telephone=no">
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link rel="shortcut icon" href="i-share/img/favicon.ico" type="image/x-icon">
<link rel="icon" href="i-share/img/favicon.ico" type="image/x-icon">
<title>Index of A:sample1\sample2</title>
</head>
<body>
<h1><a href="photo">back to photo</a></h1>
<h1>Directory Index of A:sample1\sample2</h1>
<pre>
   2026- 4-15   23:39:16         &lt;DIR&gt;   <a href="dir?dir=A:sample1%5Csample2"> .</a>
   2026- 4-15   23:39:16         &lt;DIR&gt;   <a href="dir?dir=A:sample1"> ..</a>
   2026- 4-15   23:40:18           4KB  <a href="http://192.168.4.1/download?file=ample1%5Csample2%5CSAMPLE2.JPG"> SAMPLE2.JPG</a>

Total Entries: 3
Total Size: 4KB
</pre>
</body>
</html>

sample2.jpgのリンクのパスが「ample1%5Csample2%5CSAMPLE2.JPG」と先頭の一文字欠けていますが、ひとまず後回しにします。

4.2 ファイルのダウンロード

"b"を選択しダウンロードしたいファイルのパスを指定します。sample1\sample2\sample2.jpgを指定する例を以下に示します。

>b
Enter path>sample1\sample2\sample2.jpg
sample1\sample2\sample2.jpg
http://ezshare.card/download?file=sample1\sample2\sample2.jpg
200

存在しないファイルを指定すると404が返ってきます。

>b
Enter path>hoge.txt
hoge.txt
http://ezshare.card/download?file=hoge.txt
404
ERROR, not success

4.3 exit

"x"を選択すると"Bye."を表示して終了します。

>x
Bye.

5. おわりに

ez ShareとマイクロSDメモリ、SDカードリーダーを数千円で用意しコメント込みで70行のPythonのスクリプトを書くことで、手作業での外部ストレージの抜き差しなしに組込み機器が外部ストレージへ書き込んだデータを確認用PCへ取り込むことができました。確認用PCで期待値との比較を自動化できるようになります。

システムテスト自動化標準ガイド」で自動化すべきでないテストの一つに「物理的なやりとりがあるテスト。例えば、カードリーダーにカードを通す、何かの装置の接続を外す、電源をオフかオンにするなど」(強調筆者)が挙げられていますが、とはいえ組込み系だって自動化したいニーズはあります。そこで今回は何かの装置の付け外しを頑張って自動化するのではなく、付け外しせずに済む方向で自動化を実現し「自動化すべきでない」という呪縛を克服しました。

コーディングがともなうテスト自動化は属人化の懸念があるようですがコメント含めて70行のPythonのスクリプトに属人化は心配のしすぎと思います。むしろPythonは汎用技術でありソフト屋さんにとってのポータブルスキルでしょう。

手動での操作が付いて回る組込み系のシステムテストで自動テストができると、夜間や休日に試作機——とても高価で貴重——を有効活用できます。費用面でいえばez Shareなど数千円の機材コストは稼働日に手動でリグレッションテストを実施してデグレを見つけることを考えると十分ペイするものと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?