カテゴリー: Development

  • ひげおやじ物語

    Azure Static Web Apps

    ひげおやじ物語
    https://static-web.kozawa.tokyo/ ※削除済

    無料枠でAzure DevOpsのパイプラインからAzure Static Web Appsにデプロイしようとすると以下のエラーとなる。

    [error]No hosted parallelism has been purchased or granted. To request a free parallelism grant, please fill out the following form https://aka.ms/azpipelines-parallelism-request

    エラーメッセージのURLからリクエストを投げても音沙汰なし。

    「Please consider that it could take 2-3 business days to proceed the request. We are working on improving this process at the moment. Sorry for the inconvenience.」

    と書かれているけれど1週間経過しても権限付与してもらえない。

    Azure DevOpsは諦めてGitHubのリポジトリからデプロイした。SSHキーの生成や設定が必要になった。

    Azure Blob Storage

    ひげおやじ物語
    https://blob-storage.kozawa.tokyo/ ※削除済

    Azure Blob Storageの静的Webサイトでカスタムドメインを使用する場合は、「Front Door と CDN」でドメインを認証してプライベートエンドポイント接続してやらないとhttpsでアクセスができない。めんどくさい作業が発生した。

    カスタム ドメインを Azure Blob Storage エンドポイントにマップする
    https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-custom-domain-name

    ホスティング環境

    Static Web Apps、Blob Storage、どちらも画面ポチポチでサーバ証明書を生成してくれるのは便利だけど、初めてやってみると何かしら引っかかるやん。しかも、Front Door、Storage、Networkで課金が発生している。Front Door高いな。結局、無料枠だけでは難しい気がする。

    Raspberry Pi がいいね。

  • 「Emoji kitchen」→

    できた。しばらくこれでー

    備忘:
    絵文字の組み合わせとして存在しないパターンがあって読み込んでエラーになったらリトライみたいなところから試行錯誤して最終的には以下を利用させていただくことで落ち着いた。
    https://github.com/xsalazar/emoji-kitchen
    スクレイピング用のソースとともに事前にスクレイピングした結果が「emojiOutput.json」に吐かれていて最近の絵文字まで対応している。約6.3MB、約8万5000パターン。お天気アイコンとの組み合わせだけ切り出すと数百キロにできるけど、お天気以外のアイコンも他で使いたいのでフロントのソースにベタ書きせずにバックエンド側にREST APIを作成した。クリックイベントも実装済み。

    絵文字を機械的に生成できるとは思えないので1つ1つ手作業で作っているのではなかろうか。約8万5000個、おつおつです。

  • SVGファイルで「🌀」テキストを回転させたい

    備忘:

    SVGファイルでテキスト1文字を綺麗に回転させることはできない。Androidで描画が欠落することを確認した。Windowsは知らん。テキストだけで完結したいけど無理そう…

    <svg version="1.1"
    	xmlns="http://www.w3.org/2000/svg"
    	xmlns:xlink="http://www.w3.org/1999/xlink"
    	height="50px"
    	width="50px"
    	viewBox="0 0 50 50">
    	<style>
    		#typhoon {
    			dominant-baseline: text-before-edge;
    			font-size: xxx-large;
    		}
    	</style>
    	<animateTransform
    		xlink:href="#typhoon"
    		attributeName="transform"
    		type="rotate"
    		from="0 25 25"
    		to="360 25 25"
    		dur="5s"
    		repeatCount="indefinite"
    	/>
    	<text id="typhoon">🌀</text>
    </svg>
    ChatGPT

    「🌀」という1文字の回転中心座標を正確に指定することは、環境やフォントによって異なるため、困難です。JSを使用するとSVGファイルをimgタグで埋め込むことができなくなります。さらに、SVGファイル内ではCSS/@keyframesが正常に動作しないことがあります。

    この問題に対する直接的な解決策は限られているようですが、一般的なアプローチとしては、素直に画像を回転させる方法が考えられます。回転したいテキストやシンボルを画像として作成し、必要な角度で回転させることで、一貫した表示が可能です。

    また、回転が必要なテキストやシンボルを固定された角度で使用する場合、事前に回転済みの画像を用意しておくことも考えられます。

    状況によって最適な方法が異なるかもしれませんが、回転の正確さやクロスブラウザの互換性を考慮しながら、適切な方法を選択することが重要です。

    	<text
    		id="typhoon"
    		x="50%"
    		y="50%"
    		text-anchor="middle"
    		dominant-baseline="central"
    	>🌀</text>

    テキストの中心座標を求めるのではなく、テキストを上下左右中央に揃えても、結局固定値のハードコーディングが残存してしまい、フォントサイズが変わると描画が欠落する可能性が考えられます。

    むずかしいなあ…

  • 常識の範囲内で、自由につかってください(2回目)

    備忘:

    常識の範囲内で、自由につかってください①
    https://twitter.com/JP_GHIBLI/status/1685606160580198400
    常識の範囲内で、自由につかってください②
    https://twitter.com/JP_GHIBLI/status/1685606411752108033
    常識の範囲内で、自由につかってください③
    https://twitter.com/JP_GHIBLI/status/1685606915164749824

    C. SVGアニメーション

    Aは、「常識の範囲内で、自由につかってください③」ツイートに添付されていたオリジナルファイル。Bは、Aをファイル変換サイトで変換したファイル。Cは、「常識の範囲内で、自由につかってください①②」に添付されている画像ファイルから作成したファイル。背景透過済み。クリックイベントを実装済み。マウスポインターが矢印のままだ今気づいた。軽微な不備1。

    SVGファイルにはCSS/JSを内包できる。ページ内に同じSVGファイルを複数配置してもidの重複などは発生しない。JSのグローバル領域が汚染されることもない。画像として表示する場合は、普通に<img>タグが使えるが、JSを実行する場合は、<object>タグで埋め込む必要がある。

  • 今日の天気 →

    温度センサーを移動して日本地図を追加した。妥協の産物だけどしばらくこれでー

    備忘:

    Simple Custom CSS and JS
    https://ja.wordpress.org/plugins/custom-css-js/

    そろそろブラウザ上でコードを書くのがしんどくなってきたので今どきのフレームワークを使ってビルド&デプロイする方法を検討中… WordPress本体に手を入れずにサイドバーを修正しているからメンドクサイことなる。素直にWordPressのウィジェットとして作成するか、別のページにWebアプリ作るかになると思われる。

    残課題:
    SVGファイルをobjectタグで読み込むとクリックイベントが拾えない。

    <style>
    	object {
    		pointer-events: none;
    	}
    </style>
    https://developer.mozilla.org/ja/docs/Web/CSS/pointer-events
    
    ググってセレクタを変更したり、pointer-eventsの値を変更してみたけれど object > #document > svg > path のイベントが拾えない。イベントリスナーを追加する時点で外部ファイルの読み込みが完了しておらずイベントの発火に失敗していると思われる。

    ソースにSVGファイルをベタ書きした。別途継続調査案件。

  • 今日の天気(テスト)

    予報区等GISデータの一覧
    https://www.data.jma.go.jp/developer/gis.html

    QGISプロジェクトへようこそ!
    https://qgis.org/ja/site/

    日本の白地図
    https://www.kabipan.com/geography/whitemap/

    備忘:

    予報区等のデータが、シェープファイルで公開されています。
    -全国・地方予報区 [ zip形式:481 MB ]
    -府県予報区等 [ zip形式:97 MB ]
    ・・・
    府県予報区等のzipを展開すると.dbf、.shp、.shxの3ファイルが現れます。
    報区等.dbf:4KB
    報区等.shp:155.8MB
    報区等.shx:612B
    これらの拡張子のファイルは何かという情報を検索して調べました。これらのファイルは、地図データであるシェープファイルということで、シェープファイルを扱えるQGISをインストールしました。QGISは以前、国土地理院の地図を調べたときに使用していましたが、地図ブーム終わった後にアンインストールしてしまいました。
    QGISを使用して日本地図を確認しました。この地図を利用しようとして試行錯誤しましたが、うまくいきませんでした。

    これはQGISで.shpファイルを表示したときの画面のスクリーンショットです。少し歪んでいるように思います。また、岩手県、瀬戸内海、長崎県の地形が複雑であることが分かると思います。.shpファイルを.svgファイルにエクスポートすると、記憶では27MBほどのサイズでした。しかし、ウェブサイトに公開する際には致命的なサイズであるため、QGISのジオメトリツールを使用して試行錯誤しました。
    ・「ベクタ」メニュー – 「ジオメトリの簡素化」
    ・「レイアウト」の「SVGファイルオプション」で「ジオメトリを簡素化してファイルを縮小」
    しかし、ウェブコンテンツとして利用できるほどの効果はありませんでした。そのため、QGISで表示している日本地図を画面キャプチャ(上記のPNGファイル)をSVGファイルに変換して、ファイルサイズを圧縮する方法を試しました。
    ・GIMPの「選択」 – 「選択範囲をパスに」
    ・Inkspaceの「パス」 – 「ビットマップのトレース」
    パラメタを変更してみました。それでも約7MBのファイルサイズとなり、見た目も悪く、県境に空白が生じる結果となりました。
    結論としては、岩手県、瀬戸内海、長崎県の海岸周辺は手動で最適化しなければ、全体的なバランスが取れず、ソフトウェアの機能だけでは意図した結果が得られないことが分かりました。
    また、QGISで.shpファイルから.svgファイルをエクスポートする場合、属性データ(エリアコード)が.svgファイルに反映されず、.svgファイルを手作業で修正する必要があることも分かりました。これはQt SVGライブラリのバグなのか、QGISの仕様なのかは不明です。

    結局、妥協せざるを得ませんでした。

    グーグル検索で日本地図のSVGファイルを見つけ、クリエイティブ・コモンズ・ライセンスに基づいて使用することにしました。このSVGファイルは日本の県境が分割されていますが、気象庁の気象データや予報区等とは若干異なるものです。全体的には同様ですが、北海道の分割が明示されている点などが異なります。日本地図、エリアコード、気象データの対応を再確認して修正する必要がありました。

    本来、クリックイベントを使用してSVG画像から地域を選択し、気象データを取得して画面に反映するだけのはずが、なぜこんなに複雑になってしまったのか、理解できません。

    ChatGPT添削おつおつ

  • 今日の天気(テスト)

    デカすぎてサイドバーに入らん… 縦長ダメやん。

  • 今日の天気(東京) 

    時に関する用語
    https://www.jma.go.jp/jma/kishou/know/yougo_hp/toki.html

    「朝の最低気温」と用いるときは0時から9時。

    JSON
    https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json

    「朝の最低」バグってる。

    9時前に「朝の最低」に「日中の最高」の値が入ってくる。__φ(. . )メモメモ

    気象庁の公式API公開して欲しいなー 河野さんはよー

  • 温度センサー

    技術検証済。MVP!ゆーしょー 🍻

    連投禁止w 定期的なイベントならタイマー回してバケツリレーしたらいいからな、温度が変わったときだけ不定期に通信するように修正した。初期値が気になるけどしばらくこれでー

    Socket.IO
    https://socket.io/get-started/chat

    WebSocket proxying
    http://nginx.org/en/docs/http/websocket.html

    備忘:

    WebSocket周りはSocket.IOライブラリのサンプルをコピペ/流用している。マイコンとかリバースプロキシ周りで時間がかかったなー

    • MicroPythonの開発環境「Thonny」をインストール
      Arduino IDE/Thonny/VScodeの3択。Arduino IDEはArduino言語なので不採用。VScodeの拡張機能は使いづらかったので不採用。Thonnyはエディタとして宜しくないけど消去法で採用。It’s a thonny!
    • MicroPythonのスクリプトのOSErrorやHTTPErrorのハンドリング
      無限ループは落としてはいけない。
    • Raspi4とPicoのどちらかが停止/起動した場合の動作確認
      マイコンのPicoは無条件に毎秒通知してくる。
    • サービスの依存関係?(未解決事件)
      raspi4(サーバ側)だけをOS再起動した場合、初回のWebSocket通信からエラーが通知されて復旧できない。systemdのserviceファイルを書いてNginxとアプリに依存関係を設定してみたり起動順序を入れ替えても解消せず。
      “””
      websocket.js:122 WebSocket connection to ‘wss://kozawa.tokyo/api/socket.io/?EIO=4&transport=websocket&sid=wNbbtvtR6kbla2AIAAAA’ failed: WebSocket is closed before the connection is established.
      “””
      Nginx単独の再起動が必要となる。
      →serviceファイルを作成して暫定対処済。
    • アプリのサービス化
      バックエンドにNode.jsのAPIサーバを立てて、Nginx/リバースプロキシを設定して、Socket.IOで/api/のサブディレクトリを使用するようにあれこれ試行錯誤した。Nginxの公式ドキュメントにたどり着くまでが長かった。プロトコルのバージョン?アップグレード?https/ws周りググって勉強にはなった。
    • お天気API
      気象庁がJSONファイルを公開していた。
      https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json
      weatherCode
      https://www.jma.go.jp/bosai/forecast/ にアクセスしてデバックツールの Console にて「Forecast.Const.TELOPS」を実行すると最新のweatherCodeが取得できる。情報豊富、先人の方々に感謝ー
      →副産物的な「今日の天気」を作成&公開した。

    バックエンドにAPIサーバがあったら何ができるー?わくわく