2022年8月17日水曜日

徒然じゃない日々(17)

農業(とその周辺分野)に役立つICT活用と開発にちょこちょこと取り組んでいるのですが、基本的に自分が使うものが多いので(費用を掛けないことに全振りして)収支は気にしていませんでした。

なんですが、最近、Web API のサービスなんかも始めてしまったので継続性の担保のためにも多少収益化を考えた方がいいのかもという気がしてきました。

それならそれで、せっかくなら「より便利」と「収益化」を両立したいな、とかとか考えた結果……とりあえず、栄養成分表示(推定値)の計算用スプレッドシートに商品へのリンクを追加してみました。

探り探りやっていきたいと思います。


田んぼ


Twitter (@nkkmd) 日々更新中です。

2022年8月14日日曜日

青果物卸売市場調査(日別調査)を JSON 形式で取得する Web API を作りました。

先日作った青果物市況情報の Web API をちょっといじって、青果物卸売市場調査(日別調査)も Web API 化してみました。

この Web API を通せば国外にサーバーのある GAS (Google Apps Script) 等のサービスを使ったデータの取得が可能になります。


以下、今回作成した青果物卸売市場調査(日別調査) Web API の説明です。

https://api.cultivationdata.net/wmr?cc=値1&cat=値2

パラメーターやキーの説明はこちら → 青果物卸売市場調査(日別調査)API説明書

都市ごとの野菜 or 果実のデータを JSON 形式で取得できます。例えば、「仙台市」の「野菜」であれば、パラメーター1の都市 (cc) が「0401」、パラメーター2の種別 (cat) が「v」となります。



現状、最新データの取得のみ対応しています。更新は15時頃です。

エラー回避のため、本来は値が数値になる部分を含め全て文字列として扱っています。

今後、日付を遡れるようにしたり、JSON の構造を見直したりしていこうと思っています。その辺は随時 cultivationdata.net 上でやっていきます。


***

今回は、青果物市況情報の Web API のコードがほぼ使えたので、台風穏便に過ぎ去ってくれるといいなぁと思いながら数時間程度で作ることができました。




・関連投稿


Twitter (@nkkmd) 日々更新中です。

2022年8月10日水曜日

WebARENA Indigo (Ubuntu) で Flask + uWSGI + Nginx を使って Web アプリを作る。【後編】

前編では WebARENA Indigo の設定を行いました。続きです。

Flask + uWSGI + Nginx を使って Web アプリを作っていきます。


▼ Web アプリ作成の下準備


必要なパッケージをインストール。
$ sudo apt update
$ sudo apt install python-is-python3
$ sudo apt install python-pip python3-pip
$ sudo pip install flask
$ sudo pip install uwsgi
$ sudo apt install nginx

ホームディレクトリに app ディレクトリを作成。
$ mkdir app


▼ 常時 SSL 化(HTTPS 化)の下準備


私がドメインを取得している Xserver Domain と Xserver SSL での設定例になります。

Xserver Domain の DNSレコード設定で Web アプリに使うドメインに A レコードを追加(インスタンスの IP アドレス)。

SSL 証明書を Xserver SSL で申し込み。利用環境は他社サーバー。「取得申請」から「DNS認証」(TXT レコードを DNSレコード設定に追加)。

「SSL証明書」と「秘密鍵」をダウンロード。

「SSL証明書」と「秘密鍵」を app ディレクトリに設置。
> scp -P 2222 -i ~/.ssh/private_key.txt ~/Downloads/letsencrypt12345678.crt ユーザー名@IPアドレス:/home/ユーザー名/app/ (SSL証明書)
> scp -P 2222 -i ~/.ssh/private_key.txt ~/Downloads/letsencrypt12345678.key ユーザー名@IPアドレス:/home/ユーザー名/app/ (秘密鍵)


▼ Web アプリの作成


アプリの本体 main.py を app ディレクトリに作成。
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>WebARENA Indigo (Ubuntu) で Flask + uWSGI + Nginx を使って Web アプリを作る。</h1>'

if __name__ == "__main__":
    import ssl
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    ssl_context.load_cert_chain(
        '/home/ユーザー名/app/letsencrypt12345678.crt', '/home/ユーザー名/app/letsencrypt12345678.key'
    )
    app.run(host='0.0.0.0', port=443, ssl_context=ssl_context)
※ ローカルでアプリのテストを行う場合は、10~15行目を「app.run()」に置き換えてください。インスタンス上での確認には curl や wget を使います。


▼ uWSGI の設定


アプリを呼び出す WSGI のエントリポイント wsgi.py を app ディレクトリに作成。
from main import app

if __name__ == '__main__':
    app.run()

uWSGI の設定ファイル app.ini を app ディレクトリに作成。
[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = /tmp/myapp.sock
chmod-socket = 666
vacuum = true

die-on-term = true

wsgi-file = /home/ユーザー名/app/wsgi.py
logto = /home/ユーザー名/app/uwsgi.log
※ sock や log ファイルは自動で作成されます。


▼ Nginx の設定


サーバーブロック構成ファイル myapp.conf を /etc/nginx/sites-available ディレクトリに作成。
server {
    listen 80;
    server_name サーバー名(Web アプリのドメイン);
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    ssl on;
    server_name サーバー名(Web アプリのドメイン);
    ssl_certificate /home/ユーザー名/app/letsencrypt12345678.crt;
    ssl_certificate_key /home/ユーザー名/app/letsencrypt12345678.key;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/myapp.sock;
    }
}
※ HTTP (80番ポート) へのアクセスは HTTPS (443番ポート) にリダイレクトされます。

myapp.conf を /etc/nginx/sites-enabled ディレクトリにリンク。デフォルトの構成ファイルのリンクを削除。
sudo ln -s /etc/nginx/sites-available/myapp.conf /etc/nginx/sites-enabled
sudo unlink /etc/nginx/sites-enabled/default
※ nginx.conf から読み込まれるのは sites-enabled ディレクトリ内のファイルになります。

セキュリティ上好ましくないので Nginx のバージョンを表示させなくする。
$ sudo nano /etc/nginx/nginx.conf

http {
    ~
    server_tokens off; (コメントアウトを外す)
    ~
}

Nginx を起動。
$ sudo systemctl start nginx


▼ サービス化(デーモン化)

myapp.service を /etc/systemd/system ディレクトリに作成。
[Unit]
Description=uWSGI instance for myapp
After=syslog.target

[Service]
ExecStart=/usr/local/bin/uwsgi --ini /home/ユーザー名/app/app.ini
WorkingDirectory=/home/ユーザー名/app/

User=ユーザー名
Group=www-data
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

myapp を起動。自動起動を有効化。
$ sudo systemctl start myapp
$ sudo systemctl enable myapp




ということで完成です。

uWSGI、Nginx あたりの理解がまだいまいちなのですが、とりあえず動かしながら学習していければと思います。




・関連投稿


Twitter (@nkkmd) 日々更新中です。

2022年8月9日火曜日

WebARENA Indigo (Ubuntu) で Flask + uWSGI + Nginx を使って Web アプリを作る。【前編】

WebARENA Indigo という VPS 上に、Flask + uWSGI + Nginx を使って 青果物市況情報 Web API を作りました。

それほど難しくないような気もしつつ、雰囲気で作ったらやはりところどころ突っかかったので、備忘録がてらざっくり設定手順を書いておこうと思います。WebARENA Indigo の OS は Ubuntu 22.04、クライアントは Windows 10 です。

同じような感じで突っかかっている方の参考になれば幸いです。


▼ WebARENA Indigo の設定


① 「SSH 鍵の作成」→「インスタンスの作成・起動」→「秘密鍵を使って SSH でログイン」

WebARENA Indigo のダッシュボードで SSH 鍵を作成・保存。インスタンスの作成・起動。秘密鍵をクライアントの「.ssh」に設置。

PowerShell にて SSH ログイン。初期ユーザー名は「ubuntu」。
> ssh ubuntu@インスタンスのIPアドレス -i ~/.ssh/private_key.txt


② タイムゾーンの変更と日本語化

タイムゾーンを Asia/Tokyo に変更。
$ sudo timedatectl set-timezone Asia/Tokyo

日本語パッケージをインストールして設定。
$ sudo apt install language-pack-ja-base language-pack-ja ibus-mozc
$ sudo localectl set-locale LANG=ja_JP.UTF-8


③ WebARENA Indigo でファイアーウォールを設定をする

WebARENA Indigo のダッシュボードからファイアーウォールを作成(「ネットワーク管理」内)。

SSH 及び Web アプリで使うポートを開けます(HTTP「80」、HTTPS「443」)。SSH はセキュリティ向上のため22番ポートから変更したいため、22番ポートと任意のポートを開けておきます。後ほど22番は閉じます。IP アドレスは「0.0.0.0」。

インスタンスに適用。


④ SSH のポートを変更

sshd_config のポートを変更して再起動。
$ sudo nano /etc/ssh/sshd_config

#Port 22
Port 2222 (任意のポート番号)

$ sudo systemctl restart sshd

PowerShell の別ウィンドウを開き、変更後のポートからアクセス。
> ssh -p 2222 ubuntu@IPアドレス -i ~/.ssh/private_key.txt

無事にログインできたら WebARENA Indigo のファイアーウォール設定で22番ポートを閉じます。


⑤ ufw でファイアーウォールを設定する

ufw をインストール。
$ sudo apt install ufw

incoming ポリシーを deny (破棄) に設定。
$ sudo ufw default deny

IPv6を無効化。
$ sudo nano /etc/default/ufw

IPV6=no

必要なポートを開放。
$ sudo ufw allow 2222
$ sudo ufw allow 80
$ sudo ufw allow 443


⑥ 「ユーザーを作成」→「SSH ユーザー化」→「初期ユーザーの削除」

初期ユーザーのままだとセキュリティ上よろしくないので、新たにユーザーを作成します。パスワードを2回入力(その他は空欄でも問題なし)。sudo 権限を付与。
$ sudo adduser 新ユーザー名
$ sudo gpasswd -a 新ユーザー名 sudo

ubuntu (ユーザー名) の SSH 公開鍵を新しいユーザーにコピー。所有者を変更。
$ sudo cp -r .ssh/ /home/新ユーザー名/
$ sudo chown -R 新ユーザー名:新ユーザー名 /home/新ユーザー名/.ssh/

新ユーザーで SSH ログインが可能になります。
> ssh -p 2222 新ユーザー名@IPアドレス -i ~/.ssh/private_key.txt

scp はこうなります。(後編で使います)
> scp -P 2222 -i ~/.ssh/private_key.txt ./Desktop/test.txt 新ユーザー名@IPアドレス:/home/新ユーザー名/ (インスタンスへファイルをコピー)
> scp -P 2222 -i ~/.ssh/private_key.txt 新ユーザー名@IPアドレス:/home/新ユーザー名/test.txt ./Desktop/ (クライアントへファイルをコピー)

初期ユーザーの削除。他のプロセスで使用中とのメッセージが出た場合は sudo kill してから再度削除。
$ sudo userdel -r ubuntu




ということで、WebARENA Indigo の設定でした。

後編は、突っかかった Flask + uWSGI + Nginx の部分を作っていきます。




・関連投稿


Twitter (@nkkmd) 日々更新中です。

2022年8月6日土曜日

青果物市況情報を JSON 形式で取得する Web API を作りました。

青果物市況情報は農林水産省が公開しています。しかしながら、URL や HTML の構造等により若干扱いづらいのですよね(機械にとって)。そのため、スプレッドシートで直接読み込むというようなことはできません。

また、国外のサーバーからのアクセスはブロックされるようで、GAS (Google Apps Script) での利用もできません。

今回はそうした扱いづらさをなんとか突破し、公開データの中にある救いの CSV を利用して、より使いやすいように JSON 形式でデータを取得できる Web API を作ってみました。

同様に JSON 形式で青果物市況情報を取得できるサービスには WAGRI があります。ただし、データ利用には40,000円/月の利用料金がかかります(青果物市況情報以外にもデータはたくさんあります)。また、説明を読むに基本的には農家が個人で使うという想定はされていないようです。


以下、今回作成した青果物市況情報 Web API の説明です。

https://api.cultivationdata.net/mcdata?mc=値1&cat=値2

パラメーターやキーの説明はこちら → 青果物市況情報API説明書

-----
・追記(2022-8-13)

一部休市日のデータ取得の不具合を修正しました。パラメーターの仕様が変更になりました。
-----

市場ごとの野菜 or 果実のデータを JSON 形式で取得できます。例えば、「盛岡市中央卸売市場」の「野菜」であれば、パラメーター1の市場 (mc) が「03300」、パラメーター2の種別 (cat) が「v」となります。


取得できる JSON はこのような感じになります。



国外サーバーからのアクセスもできますので、GAS 等での利用も可能です。

現状、最新データの取得のみ対応しています。更新は15時頃です。

エラー回避のため、本来は値が数値になる部分を含め全て文字列として扱っています。

今後、日付を遡れるようにしたり、JSON の構造を見直したりしていこうと思っています。その辺は随時 cultivationdata.net 上でやっていきます。


***

ここからは作ってみての感想等々。

農林水産省の青果物市況情報が公開されているページの URL は「.do」という拡張子になっており、これは Java による Web アプリケーションとのこと。裏でいろいろと処理をしているということですね。なのでスプレッドシートの IMPORTXML 関数で素直に値を取得するといったことが(たぶん)できません。

そこで GAS(Google Apps Script) を使ってページの遷移を追いかけデータを取得しようと試みたところ、

"The Amazon CloudFront distribution is configured to block access from your country."(Amazon CloudFront ディストリビューションは、あなたの国からのアクセスをブロックするように設定されています)

というメッセージが出て弾かれました。おそらく、国内からしかアクセスできないようになっているのですね。GAS は Google のサービスですので、確認していませんがサーバーは米国ですかね。

ならばと Google Cloud Functions(GCP) でリージョンを東京に設定。Python でスクリプトを作り再度アクセスするも……またもやだめ。

なぜ……?と思って調べみると、


こういうことらしいです。根本的選択ミス。

かくなる上は、Raspberry Pi で自宅サーバーをたてるか、Amazon Lambda(AWS) か、さくらの VPS か……と、コストや学習にかかる時間を勘案しつつあれこれ検討していたところ、WebARENA Indigo という安価で使い方も簡単そうな VPS を発見。

インスタンスの料金(Linux)は、メモリ 1GB、1vCPU、SSD 20GB で1時間あたり0.55円(税込)、月で349円(税込)です。

このサービスの存在を一切知らなかったのですが、運営会社は NTTPCコミュニケーションズ という会社で、NTTコミュニケーションズの子会社でした。サーバーの設置場所は東京。大丈夫そう。早速契約。

Web API は、ネット上に参考になる情報がけっこうあった Flask + uWSGI + Nginx で作成。ここの設定で2日くらいエラーにはまったのですが、分かってしまえば本当に何てことのない原因で……動けばいいやと雰囲気で作っているとこういうことになるのですよねぇ。

何はともあれ、そんなこんなで無事に動かすことができたのでよかったです。この Web API を通すことで国外のサーバーからでもデータの取得が可能です。

しばらく様子を見て、調子が良さそうなら Heroku で動かしている気象データの Web API も移そうかと思っています。


今後も農家がデータを活用しやすいような環境をコツコツ作っていきます。


・関連投稿




Twitter (@nkkmd) 日々更新中です。

2022年7月16日土曜日

家族農業の持続性を高めるための基礎基本

農業は、ある意味で社会の土台の一端を担う職業です。

であればこそ、混迷を増す世の中においてもブレずにいたいと思っています。

そうした中で、家族農業の持続性を高める基礎基本を自分なりにまとめてみました。


1. ミニマムな生活費の把握


経営と家計が厳密に分離していない家族農業では、ミニマムな生活費の把握が大きな安心感につながります。

常時ミニマムに維持し続けるかはさておき、把握しておくだけでもいざという時の選択肢を増やすことができると思います。

また、農家もとい自営業は不安定な部分もありますから、お金に関する使える制度やサービスは大いに活用していきたいところです。

私は農家の老後ってどうすればいいの……?というのが就農前にけっこう不安だったので、めちゃくちゃ調べて計算しました。ざっくりライフプランの設計なんかもやっておくと、さらに安心ですね。



2. バックオフィス業務の効率化


後回しにされがちかも(?)しれませんが、最初から意識しておくと効果てきめんです。

実感として、同じ1時間の短縮をするのであれば農作業よりも事務作業の方が圧倒的に簡単です。

雨の日に事務作業を……というのはよく聞きますが、日々の5分程度のスキマ時を活用して溜め込まずに処理できるようになると負担感はぐっと小さくなります。そうすると、雨の日は休むなり、勉強するなり、他の仕事をするなり、より有意義に過ごすことができます。

今は確定申告も Google フォームとスプレッドシートを駆使して半日かけずに終わらせることができるようになりました。領収書の打ち込みは都度 Google フォームから行い、そこから帳簿類がスプレッドシートで自動で作成されるようにしてあります。いろいろ試しましたが、無料ですし、これが一番楽な気がします。

あとは経営に関する数字や状況、今後の方針や計画等を常に頭の中に入れておくと、ちょっと文章書かなきゃいけないような書類にも怯まなくなる気がします。



3. 適正規模の見極め


個人的には、適正規模の見極めこそ農業経営の肝なんじゃないかと思っています。

仕事ですから、結局はどのくらいの労働力を投入し、どのくらいのお金の出る入るを目指すかが重要です。

その実現に向けた仕組みを作るために最適な規模はどの程度なのか。ここをピタッと決められると安定感がでますね。

ひるがえって、不用意な規模拡大は経営の難易度を上げてしまう気がします。


4. 6次化と多角化


農業は収量と販売価格がともに不確定なため、リスク・リターンのバランスが悪いですね。

ここをいかにコントロールするかということの1つの解決策が6次化かと思います。価格の決定権を持つ、利益配分割合を高める、その他諸々。

もちろん、6次化には6次化の難しさがあります。しかし、挑戦するだけの価値はあると思います。

また、生産を起点とした6次化のみならず、農業関連分野、もしくは自身の持っているもの、得意等を活かした多角化も視野に入れておきたいですね。

私の観測範囲においては、きのこ農家は6次化や多角化が好きです(笑)。


5. 主体的撤退


進むも地獄退くも地獄、八方塞がり、にっちもさっちもいきません……という事態を避けるために、事前に撤退ラインを決めておくといいかもしれません。

また、基本的に労働力が限られる家族農業においては、何でもかんでもやろうと思っても時間が全然足りません。選択と集中が必要となります。

良い商品があっても、より良い商品ができれば撤退する判断は必要ですね。撤退しても経験は残ります。



6. 効果的な再投資


家族農業の課題として感じるのが、効果的な再投資です。残した利益をどう使っていくかということですね。

もちろん資機材や設備の更新等は見据えつつ、さらなる一手をどう打つのか。規模の設定であったり6次化、多角化とも関わってくるところです。

明確な正解はないかもしれませんが、常にアンテナは張っておきたいですね。


7. 健康第一


最後に、一番大事なことです。何はともあれ健康第一。特に、腰と精神は死守です。

あとは健康診断、30代くらいになったら人間ドックは必須でやっておきたいですね。


***

さて、7つほど書いてみましたが、あくまで一個人の考えですので、どうぞ話半分で……(笑)。

変化する時代の中で、たくましく生き抜いていきましょう。


紫陽花


Twitter (@nkkmd) 日々更新中です。

2022年7月10日日曜日

【無料】栄養成分表示(推定値)の計算用スプレッドシート(日本食品標準成分表2020年版対応)

栄養成分表示の推定値計算用スプレッドシートを日本食品標準成分表2020年版(八訂)に対応したものに更新しました。


PC で Google アカウントにログインした状態で、リンク先にて「ファイル」から「コピーを作成」で編集可能なスプレッドシートのファイルが作成されます。

時々いただくのですが、アクセス権(編集者)のリクエストはしないでください(重要!)。編集しますと元ファイルが変更されてしまいますので権限付与はしていません。コピーしてお使いください

-----
追記(2022-8-17)

「原材料・分量の入力」シートの「食品名」の項目に Amazon へのリンクを追加しました。食品名で検索した商品へのリンクが表示されます。
-----



計算用スプレッドシートの前バージョンからの変更点ですが、エネルギーについて KJ 単位を追加しました。

それからファイルを少しでも軽くするために成分表の計算に使わない部分を削除したりと多少手を加えました。


<計算手順>


1) 「成分表」シートから該当する食品名を探す

Ctrl + F で検索すると便利です。見つからない時は表記が異なっている可能性があるので、ひらがな、カタカナ、漢字、いろいろ試してみましょう。

2) 当該食品の索引番号を「原材料・分量の入力」シートの A 列に入力する(半角数字)

3) 分量を「原材料・分量の入力」シートの B 列にグラム(g)で入力する(半角数字)

4. 全ての原材料について 1 〜 3 を繰り返す

5. 「栄養成分の計算結果」シートに結果が出ます

初期設定では100gあたりで結果が計算されるようになっていますが、A2 セルの値で変更できます。


※ 入力が必要なセル部分は薄黄色になっています。

※ 計算する項目を増やすなどの改変はご自由にどうぞ。

※ 原材料の入力欄は50行分作ってありますが、必要であれば行を追加して数式をコピーしてください。

※ 調味料等の重量換算が必要なものは「『栄養摂取状況調査のための 標準的図版ツール(2009 年版)』に基づく重量目安表(2009 年版)」( 国立健康・栄養研究所)(PDF)が参考になります。


<計算結果の保存>


GAS (Google Apps Script) を利用して計算結果及び原材料・分量の保存ができます。

計算結果は「保存された計算結果」シートに、原材料・分量は新たにスプレッドシートを作成して保存します。

スクリプトはコピーして作成した計算用スプレッドシートに含まれているので、「拡張機能」 → 「Apps Script」よりアクセスして、2行目の「スプレッドシート ID」及び12行目の「フォルダー ID」を書き換えてください。

フォルダー ID は、原材料・分量を記録したスプレッドシートを保存しておくフォルダのものになります。

書き換えた後、save 関数を実行することで計算結果及び原材料・分量の保存がされます。(GAS の初回実行時は承認が必要となります)


・関連投稿



Twitter (@nkkmd) 日々更新中です。