2025-01-12

iPhone で unix time をミリ秒で得る 〜 Termux 代替の iSH を使う【2025-01-14 書き直し】

 

 

Android の Termux 相当を iPhone で実現するには iSH や a-shell アプリというターミナルエミュレーターがあります。

 

残念なことに Termux: Widget や Termux: Tasker プラグインのような仕組みはありません。

 

なので、作成したシェルスクリプトをウィジェット化してワンタップで実行するとか、プラグインで Tasker や MacroDroid で自動化する、というようなことはできません。

 

 

しかし iSH はパッケージを自由に追加可能な Alpine Linux です。


ターミナルエミュレーター機能に限れば Termux 相当といえるでしょう。


iSH のディレクトリやファイルを iOS のファイルアプリで扱えるので GUI エディターが使え、シェルスクリプトを作成・編集できます。

 

 

iSH とエディター LiquidLogic をインストールします。

 

 

iOS のファイルアプリで iSH のディレクトリにアクセスできますから、いつでもスクリプトを編集できます。

 


 

 

iSH で下記のスクリプト(SwitchBot plug の状態を確認するスクリプト)を作成し、任意のディレクトリに SW_stat.sh という名前で格納し、実行権を与えておきます。

 

ーーーーーーーーーー ここから ーーーーーーーーーー
deviceid
="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)

curl -sS -X GET "https://api.switchbot.net/v1.1/devices/${deviceid}/status"
\
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}" \
 | cat > ./SW_stat.txt

cat ./SW_stat.txt
echo ""
ーーーーーーーーーー ここまで ーーーーーーーーーー

 

 

これを実行して、SwitchBot plug の状態を確認してみます。

 

そのため iSH で、必要なパッケージをインストールします(echo や cat, base64 は iSH に最初から入っています)。

 

   ~$ apk add uuidgen openssl curl


そして作成したシェルスクリプト SW_stat.sh を実行します。


   ~$ ./SW_stat.sh


結果はエラーでうまくできません。

コマンドラインを一つずつ検証したところ、

 

   t=$(date +%s%3N)

 

この部分でちゃんとミリ秒が得られていないためということがわかりました。

 

改めて date コマンドを検証してみます。

 

   ~$ date +%s%3N
   17366467533N

 

結果は 10桁(秒)に文字列 "3N" がくっついています。


Mac のターミナルで date を検証してみると、上記と同じで 10桁(秒)に文字列 "3N" がくっついてしまいます。

 

 

まずは Mac で brew を使って coreutils をインストールし、GNU 版 date コマンドの gdate でミリ秒が得られました。


   ~$ gdate +%s%3N
   1736647342397

 

Mac と同様に iSH 上で coreutils をインストールして、

 

   ~$ gdate +%s%3N

 

としますが、そんなコマンドはないよと叱られます。

 

ですが coreutils インストールによって、date コマンド自体がミリ秒に対応したことがわかりました。

 

   ~$ date +%s%3N
   1736649967217
 

 

と、13桁のミリ秒を得ました。

 

 

unix time のミリ秒を得るコマンドが Mac と iPhone の iSH で異なるのは、macOS が BSD なのに対して iPhone に入れた iSH が Alpine Linux のためでしょう。

 

 

 

ともあれ date コマンドで unix time ミリ秒が得られるようになりましたので、改めて前記のシェルスクリプトを実行してみます。


   ~$ ./SW_stat.sh

 

curl 実行結果を書き出した SW_stat.txt の内容は下記のように得られ、問題なく処理できました。

 

   ~$ cat SW_stat.txt
   {"statusCode":100,"body":{"version":"V2.0-
   2.0","power":"on","voltage":99,"weight":5.9,
   "electricityOfDay":81,"electricCurrent":95,
   "deviceId":"<デバイス ID>","deviceType":"Plug Mini (JP)",
   "hubDeviceId":"
<デバイス ID>"},"message":"success"}

 

 

iSH が Termux の代替になることを確認できましたが、さてどのように活用しましょうか。

 

 

iSH で作成・保存したシェルスクリプトをショートカット化できると面白いのですが、いまのところできるのかどうかわかっていません(多分、できなさそう (;_;) )。

 

 

 

 

 

 

 

 

2025-01-10

Termux をファイルマネージャーでアクセス ⇨ Android のエディターが使えるようになる

 

Termux のストレージは Termux でしか見えません。


termux-setup-storage コマンドで Androd の内部ストレージを Termux でアクセスできるようになりますが、Android 側からは見えないのです。

 

Android 側からアクセスできるようにするにはいくつかの方法があります。

 

Android 側からアクセスできると Android のエディターアプリから Termux のシェル作成・編集が GUI でできるようになります。

 

Termux でシェル作成・編集は CUI で行うのが基本で、Emacs などは GUI っぽくしてはいますが CUI で、とても操作性がよくありません。

 

 

Android 側からアクセスできるファイルマネージャーをスマホのホーム画面に配置したものが次図です。

 

いくつものファイルマネージャーは必要ないのですが、事例的にインストールしました。

 

実際に使って便利なのは です(これを開くと Termux の home ディレクトリの中身が一発で表示されます)。

 


      ⑥:Acode エディター(コード自動整形機能あり)

      ⑦:Simple Text Editor(コード自動整形機能なし)

 

 

1.Android の Files のアクティビティをショートカット化(

https://bike8615.blogspot.com/2024/11/termux_20.html

Files は Android に標準装備されていますが隠されていて通常は使えませんが、アクティビティをショートカット化すれば使えるようになり、Termux のストレージをアクセスできるようになります

 

 

2.Files by Google を使う(

https://bike8615.blogspot.com/2025/01/termux-android.html

 

 

3.Termux WiKi で紹介のファイルマネージャーを使う 

https://wiki.termux.com/wiki/internal_and_external_storage

この記事内の「Access Termux from a file manager」箇所に2つほど推奨ファイルマネージャーが紹介されています

 

 

調べた限りでは以上が Android 側から Termux のストレージをアクセスできるファイルマネージャーです。

 

 

Android 側からファイルマネージャーで Termux のストレージをアクセスできると、Google Play Store からインストールしたエディターで Termux のシェルを作成・編集できます。

 

 

冒頭の画面コピーにはエディターを2つインストールしていますが、Termux で使うのは Acode で、Simple Text Editor の方はほとんど使いません。

 

 

さらに Acode や Simple Text Editor から Termux のディレクトリやファイルが直接アクセス可能になります。


エディターから新規にシェルを作成してファイルマネージャーを経由せずに任意の Termux のディレクトリへ格納でき、作成したシェルの編集時にファイルマネージャーを経由せずに開くことも可能になるのです。


 

次の画面コピーは Acode から直接に "SW_stat.sh" という作成済みのシェルを開いた画面です。

 


 

 

同様に Simple Text Editor から直接 Termux のファイル(シェル)を開き、編集することもできます。

 

 

 

 

 

 

 

 

2025-01-08

Termux のディレクトリとファイル操作を Android アプリで可能にする

 

下記記事で特別なファイラーをショートカット化すれば扱えるようになる、と紹介しました。

 

Termux のディレクトリやファイルを Android 側でも操作できるようにする

 

記事では、Android のドロワーにも現れず、ホーム画面に配置できない隠されている特別な標準の「ファイル」のアクティビティをショートカット化して Android のホーム画面に配置すれば操作可能になるとしました。

 

 

今回 Files by Google でも扱えることを発見しました。

このアプリを開くと次画面のようになります。

 



 

一番下に「内部ストレージ」と「その他のストレージを参照」が表示されますが「その他のストレージを参照」 をタップすると次画面になります。

 

 


 

「バグレポート」という箇所をタップします。

「システムトレース」が表示される機種(?)もあります。


その場合はどちらをタップしても構いません。

 


 

 

現れた画面で左上の 部分をタップすると次画面になります。

 


 

一番下にある「>_ Termux 空き容量: 92.62GB」という箇所をタップします。

 

Termux の home ディレクトリ一覧が現れますので、操作したいディレクトリをタップすればアクセスできます。

 


 

 

「ファイル」をショートカット化した場合に比べて少し手順がかかりますが、Termux のディレクトリやファイルを操作できるようになります。

 

 

Termux は Android を root 化しなくても Linux 環境を扱えますし、各種のパッケージのインストール、コマンド利用やシェル作成・編集が可能になります。

 

一方、Termux 側からコマンドラインで Androiud の内部ストレージ: "sdカード" は操作できますが(termux-setup-storage 実行が必要です)、Android 側からは Termux のディレクトリやファイルは見れません。

 

見れるようにする方法が本記事や、冒頭の記事に記載した方法があるのですが、これらの方法はほとんど紹介されていません。

 

本記事で紹介の Files by Google による方法は多分ほかでは紹介されていないと思います。

 

 

Termux に詳しい方でも Android 側からは操作できない、としている方々が多いようです。

 

 

「ファイル」ショートカットによって Termux のファイルが Android 側からも操作できるようになると、Termux のシェル作成・編集にエディターアプリが使えるようになります。

 

私は Simple Text Editor(無料) と Acode(F-Droid 版は無料)を使っています。

 

前者は コード自動整形機能はありませんが、後者には備わっています。

 

 

 

Termux の CUI によって vim や nano などで編集することに比べて、Android のエディターアプリにより GUI で格段に操作性が向上します。

 

また Gboard 入力で日本語も入力できます。

 

 

 

 

 

 




2024-12-30

Tasker の使い方 〜 Termux のシェルを使ったり、その結果を Tasker で判定したり、また Pushbullet とも連携してスマホ間での通知も処理できる 〜

 

下記記事で Termux、Termux: Tasker プラグイン、Termux シェルなどを駆使して「やさしい充電」を実現しました。

 

SwitchBot API v1.0 に代えて v1.1 を使う 〜 80%/90% 充電で自動停止する方法 〜

 

今回は、上記記事で使用したシェルの内容を少し変更します。

 

シェルで実行した curl コマンドの実行結果を Tasker で判定します。

 

やりたいことは次図です。

対象となるスマホは UMIDIGI s5 Pro で、サブスマホです。

 


 

充電完了で SwitchBot plug が電源オフ後、1時間以降に再度電源をオンにする Tasker の設定です。

 

再電源オンは、再充電に備えるためですが、なんで1時間経過後かというと、1時間経ってれば充電ケーブルを抜いているだろう、ということからです。

 

現在「やさしい充電」の対象は UMIDIGI s5 Pro と iPhone SE3 ですので、一方が充電完了しても他方は充電する可能性もありますので。。。

 

OPPO Reno11 A は「やさしい充電」機能がこの機種自体に備わっていますので、SwitchBot plug での制御対象ではありません。

 

 

まずは次のタスクをご覧ください。

 


 

 

タスク番号 1〜5 は前準備です。

 

  WiFi の接続状態を得ます

         ウチには WiFi-AP が4個所あり、SwitchBot Plug mini が
         接続されている WiFi-AP を判定するためです

         %ni_active_wifi_ssid に接続中の WiFi の SSID が得られます

 

   %ni_active_wifi_ssid を変数 %R1wifi に入れておきます

 

   SwitchBot Plug mini がオンかオフかを得るためシェルを実行

         シェル(curl GET)を実行し json をパースして電源の状態 ".body.power" を得ます

         シェルの内容は次のようになっています

 

ーーーーー ここから ーーーーー
#!/data/data/com.termux/files/usr/bin/bash

deviceid="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)

ret=($(curl -sS -X GET   "https://api.switchbot.net/v1.1/devices/${deviceid}/status" \
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}" \
| jq ".body.power, .body.voltage, .body.version"))

out=`echo ${ret[0]} | sed 's/"//g'`

echo $out
ーーーーー ここまで ーーーーー

            ${ret[0]} の内容(["on"] または ["off"] から ' " ' を除いて [on] または [off] を抽出)

            これを $out に入れて echo コマンドで標準出力します 

 

 

curl の実行結果はファイルへ吐き出すこともでき、この場合は複数の情報を Tasker に戻すことができます。

 

次のようなシェルにすると SW_stat.txt ファイルには curl 実行結果が入ります。


ーーーーー ここから ーーーーー
#!/data/data/com.termux/files/usr/bin/bash

deviceid="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)


curl -sS -X GET "https://api.switchbot.net/v1.1/devices/${deviceid}/status" \
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}" \
 | cat > ./SW_stat.txt

cat ./SW_stat.txt
echo ""
ーーーーー ここまで ーーーーー
 

SW_stat.txt ファイルの内容は次のような結果になります。

 

{"statusCode":100,"body":{"version":"V2.0-2.0","power":"on","voltage":100.1,"weight":0,"electricityOfDay":808,"electricCurrent":0,"deviceId":"<デバイスID>","deviceType":"Plug Mini (JP)","hubDeviceId":"<デバイスID>"},"message":"success"}

 

 

   結果 %stdout(システム変数)を変数 %SWbot に入れておきます

         シェルの最後に echo コマンド で標準出力したもの([on] または [off])
         が $stdout に入っています

 

   変数 %Times は充電完了時に unix time(秒)を得て +3600(秒)
         を足してあります

         これはあとで1時間経過後を判定するときに使います。



 6〜20 が実際の処理です。

 

スマホの WiFi 接続が SwitchBot Plug と同じ WiFi-AP か?

      no  : stop

▶   yes : %SWbot は on か?

              yes : stop

              no  : 充電完了時から1時間以上経過したか?

                      yes : SW_on.sh 実行 ⇨ stop(SwitchBot plug の電源をオン)

                      no  : 10 分待って ▶ へ戻る



プロファイルは「5:00 〜 19:00 の 30 分ごと」としています。

 

すでにリタイヤしていますので夜間充電はしません。

 

また、寝室は別の WiFi-AP で、そこにスマホがある場合も充電はしません。




さらにメインスマホ(OPPO Reno11 A)を持って外出中は SwitchBot plug の電源はオフにし、帰宅したら再び前記の処理に戻します。



そのため、メインスマホから Pushbullet でサブスマホと連携します。



メインスマホのプロファイルは自宅の WiFi-AP に接続しているか切断状態かの2つをトリガーにしています。



外出時のタスクは次のようになっています。




帰宅時のタスクは次のようになっています。




最初に5秒の待機を行っているのは、WiFi-AP 間をハンドオーバーしたときにメッセージが送信されてしまうのを防止するためです。



サブスマホへは Pushbullet から、次のメッセージを送信します。


   ・宛先:UMIDIGI s5Pro

   ・タイトル:通知

   ・内容:not-home(外出時)

               at-home(帰宅時)



 

サブスマホ側ではプロファイルに Pushbullet のメッセージを受け取ったとき、として

 

   ・外出時のメッセージの場合:SW_off.sh を実行

                                             冒頭のプロファイルをオフ

 

   ・帰宅時のメッセージの場合:冒頭のプロファイルをオン


とします。

 

冒頭のプロファイルは「5:00 〜 19:00 の 30 分ごと」のことです。

 

 


Pushbullet をインストールして2台のスマホで同じアカウントで設定すると、両者の間でメッセージを交換できます。

 

 

また Pushbullet インストールによって Tasker のプラグインになっていますので、プラグインアクションで内容を検査できますし、メッセージ受信時にプロファイルにすることもできます。

 

 

 

おわりに ・・・


・Termux: Tasker プラグインを Tasker から操作できる

   これにより、Termux の様々なコマンドやシェルを連携できる

・Termux を使えることで Tasker 処理に柔軟性が生まれる

・Termux のシェルの中で実行結果を得ることができる

・Termux のシェルの実行結果を Tasker に渡して判定することができる

   シェルの実行結果をシステム変数で受け取ることができ、Tasker のアクション
   で使用できる

   また、ファイルに吐き出すことやそのファイルを読み込むことで Tasker のアクシ
   ョンで使用できる

・WiFi の状態を判定できる

・Unix time(1970年1月1日を起点としてそこからの経過秒数(10桁)や
   ミリ秒(13桁)を得て計算することや判定することができる

・Pushbullet 連携を行って複数デバイス間でメッセージ交換ができる

   デバイスはスマホのほか、PC や Mac ともメッセージ交換できる

   sms を送信し、他方で受信するというやり方に比べて大変便利で通信料無料で利用できる


 

 

MacroDroid でも Pushbullet 連携を含めて Tasker と同様のことができます。 



 

 

 

 

 

2024-12-24

SwitchBot API v1.1 で Plug mini の状態を得る

 

 

curl コマンドで得ます。

 

次のシェルスクリプトを SW_stat.sh とでもして、Termux の ~/.termux/tasker ディレクトリに実行権を与えて格納します。

 

ーーーーーーーーーー ここから ーーーーーーーーーー
#!/data/data/com.termux/files/usr/bin/bash

deviceid="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)

curl -sS -X GET   "https://api.switchbot.net/v1.1/devices/${deviceid}/status" \
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}"

ーーーーーーーーーー ここまで ーーーーーーーーーー

 

これを ./SW_stat.sh で実行すると下記の結果が得られます。


~/.termux/tasker $ ./SW_stat.sh
{"statusCode":100,"body":{"version":"V2.0-2.0","power":"on","voltage":101.3,"weight":0.1,"electricityOfDay":169,"electricCurrent":3,"deviceId":"<デバイスID>","deviceType":"Plug Mini (JP)","hubDeviceId":"<デバイスID>"},"message":"success"}

~/.termux/tasker $

 

それぞれ次の意味です。

 

"statusCode":100    # ステータスコード:100(正常終了)
"version":"V2.0-2.0"
# バージョン:v2.0
"power":"on"            # 電源状態:オン          
"voltage":101.3 # 電圧:101.3V          
"weight":0.1                # 1日の消費電力(0.1 W)
"electricityOfDay":169 # 1日の使用時間(169 分)
"electricCurrent":3   # 現在の電流(3 A)⇨ 大きすぎる
"deviceId":"
<デバイスID>" # デバイスID
"deviceType":"Plug Mini (JP)"
# デバイスタイプ(Plug Mini (JP))
"hubDeviceId":"<デバイスID>" # Hub デバイスID
"message":"success" # メッセージ:成功

 

SwitchBot アプリのステータスとはなぜかズレがありますので、ちょっといい加減ですねぇ。

アプリの方が実際値なのでしょうか(?)

 


 

 

中身を次のようにし、シェル名を SW_stat2.sh として実行してみます。

 

ーーーーーーーーーー ここから ーーーーーーーーーー
#!/data/data/com.termux/files/usr/bin/bash

deviceid="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)

ret=($(curl -sS -X GET   "https://api.switchbot.net/v1.1/devices/${deviceid}/status" \
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}" \
| jq ".body.power, .body.voltage, .body.version"))

echo ""
out=`echo ${ret[0]} | sed 's/"//g'`
# get {"off"} or {"on"} & convert to {off} or {on}

echo power:   $out
echo ""
ーーーーーーーーーー ここまで ーーーーーーーーーー

 

~/.termux/tasker $ ./SW_stat2.sh

power:  on

~/.termux/tasker $

 

 

【解  説】

 

curl コマンドは -sS オプションで「進捗状況メーター」と呼ばれる出力を非表示(-s)にしてエラーのみ表示(-S)します

 

curl の実行結果を ret という変数に入れます

jq コマンドでパースして結果の "power" 値を ${ret[0]} として得ます(例では「"on"」)

[0] は jq でパースした 0 番目を指します

例では [1] は voltage (電圧) を示し、[2] が version (バージョン) を示します


sed で整形して「"on"」から「""」を取り除き「on」を抽出し、echo で表示しています(さほど意味はないのですが・・・) 

 

 

 

この仕組みを使えば、power 値を MacroDroid や Tasker で判定することが可能になると考え、応用してみました。

 

一つ新しい次の記事がその応用例です。

 

Tasker の使い方 〜 Termux のシェルを使ったり、その結果を Tasker で判定したり、また Pushbullet とも連携してスマホ間での通知も処理できる 〜