LoginSignup
3
2

More than 1 year has passed since last update.

MixJuiceで現在の日時を取得する

Posted at

何をするか?

MixJuice経由でWeb APIを利用し、IchigoJamから現在の日時を取得します。

現在の日時を取得するWeb API

現在の日時を取得するWeb APIを探したところ、以下のものが見つかりました。

日本標準時プロジェクト

日本標準時プロジェクト https/http を介してアクセスされる場合

現在時刻を時分秒形式で返すAPIが定義されています。

https://ntp-a1.nict.go.jp/cgi-bin/time

以下のような形式で現在時刻が取得できる仕様です。

Sat Jun  5 03:53:33 2021 JST

月が数字ではなく英字列なのが気になりますが、余計なデータが無く扱いやすそうな仕様!

さらに、ヘッダはAccess-Control-Allow-Origin:*を含み、HTTPSにも対応する仕様となっています。
IchigoJam webのバーチャルMixJuice対応もバッチリな仕様!

…しかし、毎月6日~月末はサービス停止、
2022年3月31日をもって完全にサービス終了となっており、使い物になりません。
入出力の仕様が素晴らしいだけに、非常に残念!!

IchigoJam + MixJuice用 日付&時間データ

IchigoJam + MixJuice用 日付&時間データ

以下のURLで日本の現在時刻を取得できます。

http://www.openspc2.org/data/date/full.txt

以下のような形式の結果が返ります。

2021
12
14
2
0
23

秒の情報は取得できないようですが、「MixJuice用」と銘打っているだけあって形式のシンプルさは最高です。
しかし、ヘッダにAccess-Control-Allow-Originが含まれておらず、
HTTPSにも対応していない(接続できない)ので、IchigoJam webのバーチャルMixJuiceからのアクセスは難しそうです。

World Time API

World Time API: Simple JSON/plain-text API to obtain the current time in, and related data about, a timezone.

以下のURLで日本の現在時刻を取得できます。

https://worldtimeapi.org/api/timezone/Asia/Tokyo

また、アクセス元のIPアドレスに基づくタイムゾーンの自動選択もできます。

https://worldtimeapi.org/api/ip

以下のような形式の結果が返ります。

{"abbreviation":"JST","client_ip":"35.199.178.127","datetime":"2021-12-14T00:12:43.579568+09:00","day_of_week":2,"day_of_year":348,"dst":false,"dst_from":null,"dst_offset":0,"dst_until":null,"raw_offset":32400,"timezone":"Asia/Tokyo","unixtime":1639408363,"utc_datetime":"2021-12-13T15:12:43.579568+00:00","utc_offset":"+09:00","week_number":50}

見やすく整形すると、以下のようになります。

{
    "abbreviation": "JST",
    "client_ip": "35.199.178.127",
    "datetime": "2021-12-14T00:12:43.579568+09:00",
    "day_of_week": 2,
    "day_of_year": 348,
    "dst": false,
    "dst_from": null,
    "dst_offset": 0,
    "dst_until": null,
    "raw_offset": 32400,
    "timezone": "Asia/Tokyo",
    "unixtime": 1639408363,
    "utc_datetime": "2021-12-13T15:12:43.579568+00:00",
    "utc_offset": "+09:00",
    "week_number": 50
}

HTTPSでのアクセスに対応しており、ヘッダにaccess-control-allow-origin: *が含まれるため、
IchigoJam webのバーチャルMixJuiceからのアクセスもしやすいです。

ただし、単純に時刻を取得するためだけに使うには結果が長いです。
結果をJSONではなくプレーンテキストで返すモードもありますが、結果の長さはあまり変わりませんでした。

TimeAPI

Simple and Free Time API | TimeAPI

以下のURLで日本の現在時刻を取得できます。

https://www.timeapi.io/api/Time/current/zone?timeZone=Asia/Tokyo

以下のような形式の結果が返ります。

{"year":2021,"month":12,"day":13,"hour":23,"minute":51,"seconds":12,"milliSeconds":388,"dateTime":"2021-12-13T23:51:12.3888497","date":"12/13/2021","time":"23:51","timeZone":"Asia/Tokyo","dayOfWeek":"Monday","dstActive":false}

見やすく整形すると、以下のようになります。

{
    "year": 2021,
    "month": 12,
    "day": 13,
    "hour": 23,
    "minute": 51,
    "seconds": 12,
    "milliSeconds": 388,
    "dateTime": "2021-12-13T23:51:12.3888497",
    "date": "12/13/2021",
    "time": "23:51",
    "timeZone": "Asia/Tokyo",
    "dayOfWeek": "Monday",
    "dstActive": false
}

HTTPSには対応していますが、Access-Control-Allow-Originヘッダは入っておらず、
IchigoJam webのバーチャルMixJuiceでの利用は若干面倒かもしれません。
(CORS Everywhereなどの拡張機能を用いればアクセスは可能です)

World Clock API

Home Page

以下のURLでUTCの現在時刻(日本時間の9時間前)が取得できます。

http://worldclockapi.com/api/json/utc/now

以下のような形式の結果が返ります。

{"$id":"1","currentDateTime":"2021-12-13T15:30Z","utcOffset":"00:00:00","isDayLightSavingsTime":false,"dayOfTheWeek":"Monday","timeZoneName":"UTC","currentFileTime":132838830284824919,"ordinalDate":"2021-347","serviceResponse":null}

見やすく整形すると、以下のようになります。

{
    "$id": "1",
    "currentDateTime": "2021-12-13T15:30Z",
    "utcOffset": "00:00:00",
    "isDayLightSavingsTime": false,
    "dayOfTheWeek": "Monday",
    "timeZoneName": "UTC",
    "currentFileTime": 132838830284824910,
    "ordinalDate": "2021-347",
    "serviceResponse": null
}

ただし、日本時間の直接取得には対応していないようです。
(utcの代わりにjstすべてのタイムゾーンでの現在の時間に載っている他のUTC+9のタイムゾーンの名前を入れると、無効なタイムゾーン(not a valid Time Zone)としてエラーになりました)
また、秒単位の時刻の取得も簡単にはできないようです。
(CyberChefを用いるcurrentFileTimeから秒単位の時刻を取り出せるので、不可能ではないと思われます)

さらに、HTTPSへの対応が不完全(接続は出来るが証明書の名前が無効)であり、
ヘッダにAccess-Control-Allow-Originが含まれないため、
IchigoJam webのバーチャルMixJuiceからのアクセスは難しそうです。

まとめ

API HTTPS対応 CORS対応 結果のシンプルさ 日本時間対応 秒単位対応 時間の制約無くアクセス可能
日本標準時プロジェクト ×
IchigoJam + MixJuice用 日付&時間データ × × ×
World Time API ×
TimeAPI × ×
World Clock API × × × ×

(ヘッダがAccess-Control-Allow-Origin:*を含むことを「CORS対応」としています)

現在の日時を取得する

方針

今回は、IchigoJam webのバーチャルMixJuiceからのアクセスがしやすく、
利用時間の制限も無い World Time API を用いて現在の日時を取得することにしました。
取得する形式は、データの終わりが}で明示されるためわかりやすいJSONを用いることにしました。

返されるデータのうち、"datetime":"2021-12-14T00:12:43.579568+09:00",の部分に日時の情報が、
"day_of_week":2,の部分に曜日の情報が入っているので、これらから情報を抜き出します。

今回扱うJSONのデータでは、オブジェクトのネストが無く、
データの文字列にカンマやエスケープ、閉じカッコは含まれていないようです。
そこで、この性質を利用し、以下のようなロジックで情報を抜き出します。

  • ,があったら、名前モードにする。
  • :があったら、データモードにする。
  • "があったら、文字列モードかどうかを切り替える。(名前/データモードとは別に管理するモード)
  • }があったら、読み取りを終了する。
  • 名前モードの文字列モードでは、名前の識別のため、名前の文字の文字コードの和を計算する。
  • データモードでは、十進数値を読み取り、数字の後数字以外が来たら読み取った数値を記録する。
    • "datetime"の後では、日時を表す数値をそれぞれ配列に格納する。
    • "day_of_week"の後では、曜日を表す数値を変数に格納する。
    • それ以外では、無視する。

実装

コード全体

10 ' ジコク シュトク
20 ?"MJ GETS worldtimeapi.org/api/timezone/Asia/Tokyo"
30 W=0:LET[0],0,0,0,0,0,0:N=1:H=0:S=0:P=0:V=0:E=0
40 C=INKEY():IF C=0 GOTO 40 ELSE GOTO 70
50 CLT
60 C=INKEY():IF TICK()>=30 GOTO 160 ELSE IF C=0 GOTO 60
70 IF C=#22 S=!S:IF S AND N H=-#22
80 IF S AND N H=H+C
90 IF C=#3A:N=0
100 IF C=#2C:N=1
110 IF #30 <= C AND C <= #39 V=V*10+C-#30:E=1 ELSE IF E GOTO 130
120 IF C=#7D GOTO 160 ELSE GOTO 50
130 IF H=845 AND P<6 [P]=V:P=P+1
140 IF H=1149 W=V
150 V=0:E=0:GOTO 120
160 ?[0];"/";[1];"/";[2];" (";
170 IF W=0 ?"Sun";
180 IF W=1 ?"Mon";
190 IF W=2 ?"Tue";
200 IF W=3 ?"Wed";
210 IF W=4 ?"Thu";
220 IF W=5 ?"Fri";
230 IF W=6 ?"Sat";
240 ?") ";[3];":";[4];":";[5]

解説

タイトルを置きます。

10 ' ジコク シュトク

クエリを送ります。

20 ?"MJ GETS worldtimeapi.org/api/timezone/Asia/Tokyo"

以下の変数を初期化します。

  • W:曜日
  • 配列:日時
  • N:名前モードか
  • H:名前の文字の文字コードの和
  • S:文字列モードか
  • P:次に読み取った数値を格納する配列の要素
  • V:読み取り中の数値
  • E:数値を読み取り中か
30 W=0:LET[0],0,0,0,0,0,0:N=1:H=0:S=0:P=0:V=0:E=0

結果の最初の文字を時間無制限で待ち、読み取ります。

40 C=INKEY():IF C=0 GOTO 40 ELSE GOTO 70

結果の2文字目以降を読み取ります。0.5秒文字が来なかったら、読み取りを打ち切ります。

50 CLT
60 C=INKEY():IF TICK()>=30 GOTO 160 ELSE IF C=0 GOTO 60

読み取った文字が"なら、文字列モードかどうかを切り替えます。
名前モードで文字列モードに入るなら、名前の文字の文字コードの和Hを初期化します。
(この"の文字コードも足されるため、その分マイナスにしておきます)

70 IF C=#22 S=!S:IF S AND N H=-#22

名前モードの文字列モードなら、今の文字の文字コードを足します。

80 IF S AND N H=H+C

読み取った文字が:であれば、データモードに切り替えます。

90 IF C=#3A:N=0

読み取った文字が,であれば、名前モードに切り替えます。

100 IF C=#2C:N=1

読み取った文字が数字であれば、数値の読み取り状態を更新します。
数値を読み取った状態で数字以外の文字を読み取った時は、読み取った数値を記録する処理に行きます。

110 IF #30 <= C AND C <= #39 V=V*10+C-#30:E=1 ELSE IF E GOTO 130

読み取った文字が}であれば、読み取りを終了します。
そうでなければ、次の文字の読み取りに行きます。

120 IF C=#7D GOTO 160 ELSE GOTO 50

読み取った名前が"datetime"であれば、読み取った日時を表す数値を配列に格納します。

130 IF H=845 AND P<6 [P]=V:P=P+1

読み取った名前が"day_of_week"であれば、読み取った数値を曜日を表す変数に格納します。

140 IF H=1149 W=V

数値の読み取り状態を初期化し、次の文字の読み取りに行きます。

150 V=0:E=0:GOTO 120

読み取った日時と曜日を出力します。

160 ?[0];"/";[1];"/";[2];" (";
170 IF W=0 ?"Sun";
180 IF W=1 ?"Mon";
190 IF W=2 ?"Tue";
200 IF W=3 ?"Wed";
210 IF W=4 ?"Thu";
220 IF W=5 ?"Fri";
230 IF W=6 ?"Sat";
240 ?") ";[3];":";[4];":";[5]

実験結果

MixJuiceを接続した状態でプログラムを実行し、しばらく待つと、

2021/12/14 (Tue) 3:41:5

のような形式で現在の日時が出力されました。
(取得を開始したタイミングの日時なので、出力されるタイミングからは遅れています)

MixJuice実機では、MJ SPW (送信間隔[ms])コマンドでデータをIchigoJamに転送する速度を調整できるようです。
また、今回のプログラムでは、

75 ?CHR$(C);

という行を追加することで、受信したデータを出力して確認できるようになります。

IchigoJam webでは日時の取得に成功し、実行を開始してから約50秒後に日時が出力されました。
(現在の)バーチャルMixJuiceではMJ SPWコマンドは効かないようで、データは欠けていました。

IchigoJam実機 (1.0.0) では、送信間隔を40msに設定すると、データが欠けて曜日の取得に失敗しました。
送信間隔を45msに設定すると、データが欠けずに日時の取得に成功し、
実行を開始してから約16秒で日時が出力されました。

IchigoJam実機 (1.3.1) では、送信間隔を15msに設定してもデータは欠けず、
実行を開始してから約7秒で日時が出力されました。
また、送信間隔を0msに設定しても最初の128バイト程度は受信できるようで、
データは欠けたものの日時の取得には成功し、実行を開始してから約3秒で日時が出力されました。

おわりに

Web APIを利用してIchigoJamからMixJuice経由で現在の日時を取得し、出力することができました。

ちなみに、執筆時においてMixJuiceのページもHTTPSには対応していないようです。
(接続はできるが証明書の名前が無効で、無視して続行すると404 Not Foundになりました)

IchigoJamはjig.jpの登録商標です。

3
2
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
3
2