2021年9月15日水曜日

「栽培データ検索システム」を作りました。


栽培データを、オープンデータとして登録・検索するための「栽培データ検索システム」を作りました。


ひとまず、テスト運用中です。


ざっくり概要を説明しますと、栽培データを持っている人がオープンデータとして公開していいよーという場合に登録してもらいます。そうすると、みんなが検索して使えるよ、という(素朴な)ものです。

ライセンスは、商用・非商用にかかわらず、自由に再利用が可能となる Open Data Commons Public Domain Dedication and License(PDDL) での公開を想定しています。

やはり、スマート農業の普及においては、ハード部分だけでなく、ソフト部分の整備もセットで必要なんじゃないかと思うのです。

何か自分で便利な機器を作ろうと思ったときに、ネット等でたいていの部品は簡単に手に入ります。作り方も、調べれば何とかなります。あとは、例えば、指標になるような栽培データがあれば、自作した機器を、より一層、幅広く活用することができます。

まぁ、まだ登録データは、私の1件だけ(しかも原木椎茸)なので、お声がけもして、少しずつ増やしていけたらなと。

もちろん、栽培データは秘中の秘なり、というのが普通は当然な気もします(特に品目によっては)。一方で、みんながお互いにデータをうまく使って栽培技術を高めたり、はたまた経営改善につなげれば、全体としては底上げになるんじゃないかと思います。実験ですね。


今回のシステムは、静的なページはGoogle サイト、登録部分はGoogle フォーム、データの検索と削除部分はGAS(Google Apps Script)で作りました。いやはや、GASほんと便利。

当初は、どこかにサーバーを準備して、PHP + MySQLとかで作ろうかと考えていたのですが、GASで作れたので維持費はゼロ(ドメイン代のみ)。ありがたや。しかし、収益性もゼロなので、低燃費でやっていきます。


さてさて、いろいろ、楽しくなるといいなぁ。


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

2021年8月29日日曜日

GASで簡単な検索システムを作る。


栽培データを登録・検索するためのシステム(のテスト版)をGAS(Google Apps Script)で作ってみました。

備忘録として、以下作り方です。


① ベータベースの作成

データベースへのデータの登録は、Google フォームを使います。


登録するデータは、①作成者、②作成者URL(任意)、③作成者メールアドレス(任意)、④栽培地、⑤品目、⑥データ種別、⑦栽培データへのリンク、⑧備考(任意)です。

(テスト版なので、登録できる栽培地、品目、データ種別のリストは一部のみ。)


フォームから登録したデータが入ったスプレッドシート。これが、検索するデータベース(代わり)になります。


①~⑧のデータが、それぞれB~I列に入っています。今回、とりあえず動かすためのサンプルとして、7データほど入れました。

シート名は「cdb」としています(スクリプト内でこの名前で使います)。


② スクリプトファイルの作成

GASのスクリプトファイルを作成します。トップページを表示するためのdoGet関数と、検索結果を返すdoPost関数があります。

function doGet() {
  let htmlIndex = HtmlService.createTemplateFromFile("index");
  let result = "";
  htmlIndex.result = result;
  return htmlIndex.evaluate().setTitle("栽培データ検索システム");
}

function doPost(e) {
  let item = e.parameter.item;
  let typ = e.parameters.typ;
  let pref = e.parameter.pref;
  let kywd = e.parameter.kywd;
  let htmlResult = HtmlService.createTemplateFromFile("index");

  let cdbSt =  SpreadsheetApp.openById("スプレッドシートID").getSheetByName("cdb");
  let rowNum = [];
  
  if(item != "未選択") {
    let itemFinder = cdbSt.getRange("F2:F").createTextFinder(item).findAll();
    for(let i in itemFinder) {
      rowNum.push(itemFinder[i].getRow());
    }
  } else {
    htmlResult.result = "品目を選択してください。";

    return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
  }

  if(typ == null) {
    htmlResult.result = "データ種別を選択してください。";

    return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
  } else if(typ[0] != "全部") {
    let num = 0;
    const itemRowNum = rowNum.length;
    for(let x = 0; x < itemRowNum; x++) {
      let check = false;
      for(let y = 0; y < typ.length; y++){
        let typCheck = cdbSt.getRange(rowNum[x - num], 7).getValue().split(", ");
        for(let i = 0; i < typCheck.length; i++) {
          if(typ[y] == typCheck[i]) {
            check = true;
          }
        }
      }
      if(check == false) {
        let dlt = rowNum.indexOf(rowNum[x - num]);
        rowNum.splice(dlt,1);
        num++;
      }
    }
  }

  if(pref != "全国") {
    let prefFinder = cdbSt.getRange("E2:E").createTextFinder(pref).findAll();
    for(let i in prefFinder) {
      rowNum.push(prefFinder[i].getRow());
    }
    rowNum = rowNum.filter(function (x, i, self) {
      return self.indexOf(x) === i && i !== self.lastIndexOf(x);
    });
  }

  if(kywd != "") {
    let kywdFinder = cdbSt.getRange("B2:I").createTextFinder(kywd).findAll();
    for(let i in kywdFinder) {
      rowNum.push(kywdFinder[i].getRow());
    }
    rowNum = rowNum.filter(function (x, i, self) {
      return self.indexOf(x) === i && i !== self.lastIndexOf(x);
    });
  }

  rowNum.sort((a, b) => {return a - b;});
  
  let num = rowNum.length;
  let result = ["<table><tr><th>作成者</th><th>作成者URL</th><th>作成者メールアドレス</th><th>栽培地</th><th>品目</th><th>データ種別</th><th>栽培データへのリンク</th><th>備考</th></tr>"];
  for (let i = 0; i < num; i++) {
    result.push("<tr><td>");
    result.push(Array.prototype.concat.apply([], cdbSt.getRange(rowNum[i], 2, 1, 8).getValues()).join("</td><td>"));
    result.push("</td></tr>");
  }
  result.push("</table>");

  htmlResult.result = result.join("");

  return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
}
※ コードを一部修正しました。(2021-8-31)

15行目の「スプレッドシートID」は、書き換えてください。当該スプレッドシートURLの下記部分です。

https://docs.google.com/spreadsheets/d/ここの値をコピペ/edit#gid=0


③ HTMLファイルの作成

GASのHTMLファイルを作成します。ファイル名は「index.html」としています(スクリプト内でこの名前で使っています)。検索フォームと検索結果を表示します。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <center><h1><a href="ウェブアプリURL">栽培データ検索システム</a>(β版)</h1></center>
    <form method="post" action="ウェブアプリURL">
      <p><b><品目>*</b><br>
        <select name="item">
          <option value="未選択">選択してください…</option>
          <option value="シイタケ">シイタケ</option>
          <option value="キクラゲ">キクラゲ</option>
          <option value="エノキ">エノキ</option>
        </select>
      <p><b><データ種別></b><br>
       <input type="checkbox" name="typ" value="全部" checked="checked">全部
        <input type="checkbox" name="typ" value="温度">温度
        <input type="checkbox" name="typ" value="湿度">湿度
        <input type="checkbox" name="typ" value="照度">照度
      </p>
      <p><b><栽培地></b><br>
       <input type="radio" name="pref" value="全国" checked="checked">全国
        <input type="radio" name="pref" value="福島県">福島県
        <input type="radio" name="pref" value="茨城県">茨城県
        <input type="radio" name="pref" value="栃木県">栃木県
      </p>
      <p><b><キーワード></b><br>
        <input type="text" name="kywd" size="30">
      <p>
        <input type="submit" value="検索">
      </p>
    </form>
    <p>
      * 必須
    </p>
    <br>
    <p>
      <?!=result?>
    </p>
  </body>
</html>

7、8行目の「ウェブアプリURL」は、ウェブアプリケーションの公開後に取得できるウェブアプリのURLを記述します。


④ ウェブアプリケーションの公開と共有

作成したスクリプとHTMLトファイルを、ウェブアプリケーションとして公開、共有します。

「デプロイ」→「新しいデプロイ」から、

「説明」→「簡単検索システム」(適当に)
「次のユーザーとして実行」→「自分」
「アクセスできるユーザー」→「全員」

として、デプロイを実行。

「アクセスを承認」がまだの場合は、承認します。

ウェブアプリのURLが発行されますので、HTMLファイルにウェブアプリURLを記述し、「デプロイを管理」から「新バージョン」のデプロイを実行します。

プロジェクトの「共有」設定を、「リンクを知っている全員」に変更。

これで、ウェブアプリURLから検索トップページにアクセスして、検索ができるようになります。


⑤ 動かしてみる

動かしてみます。


品目は、選択必須。

データ種別は、チェックボックスで複数選択が可能となっているので、選択された品目のうちチェックされたデータ種別を1つでも含むものが検索されます。

栽培地は、ラジオボタンで1つ選択。キーワードは、入力されたキーワードを含むものを検索します。

また、品目が未選択、もしくはデータ種別が1つも選択されていないと検索されません。


上の写真の条件での検索結果。


こんな感じになります。


こちら↓から動かせます。


***

ということで、GASで作る簡易的な検索システムでした。

スプレッドシートの1シートに収まる程度の小規模なデータの運用であれば、けっこう十分なのではなかろうかと(厳密にはどの程度まで耐えられるのか分かりませんけども)。何よりGASの場合、サーバーの準備を考える必要がなく、維持ゼロというのが素晴らしいですね。

先日、BloggerでTwitterカードを表示するために投稿ULRから画像のURLをリダイレクトするウェブアプリケーションを作ろうとして失敗しましたが、この検索システムはそこから転生したので、何でもやってみるものですね。

表示する情報を整理したり、URLはリンクにしたり等々、もう少し手を加えて、栽培データのオープンデータ化に活用していきたいと思います。




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

2021年8月26日木曜日

里芋の花

里芋の花が咲きました。

里芋の花

里芋の花

里芋の花

里芋の花

里芋の花

里芋の花

里芋の花

あれ、里芋って花咲の?と思ったら、品種にもよるそうですが、もともと熱帯の植物なので高温・多湿・多雨といった条件で咲くことがあるそうです。

ここのところ、まさに熱帯みたいな気候ですからねぇ。


里芋畑

今年の里芋はこの成長。原木椎茸の廃ホダとナメコの廃菌床を積み続けた新しい畑は、やっぱりいいですね。


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

2021年8月22日日曜日

Bloggerで簡単にTwitterカードを設定する方法

BloggerでTwitterカードを設定する方法です。

いつの間にか、以前の方法が使えなくなってしまったので新たな方法を調べたところ、簡単にできるようになっていました。最近のテーマは、HTMLの編集で1行追加すれば普通に表示される仕様になっているみたいです。

しかし、このブログのように過去のテーマのままカスタマイズされていたりすると1行追加だけでは使えない場合もあります。かと言って、せっかくカスタマイズしたのに新しいテーマへ更新してしまうのも躊躇されます。

そんなわけで、Bloggerでだいたい一から簡単にTwitterカードを表示させる方法です。

以下を<head>タグ内に記述します。

<meta content="summary_large_image" name="twitter:card"></meta>
<meta content="@アカウント名" name="twitter:site"></meta>
<meta content="@アカウント名" name="twitter:creator"></meta>
<b:if cond="data:blog.pageType == &quot;index&quot;">
  <meta expr:content="data:blog.title" name="twitter:title"></meta>
<b:else>
  <meta expr:content="data:blog.pageName + &quot; - &quot; + data:blog.title" name="twitter:title"></meta>
</b:else></b:if>
<b:if cond="data:blog.pageType == &quot;index&quot;">
  <meta content="トップページ場合に表示するの画像のURL" name="twitter:image"></meta>
<b:else>
  <meta expr:content="data:blog.postImageUrl" name="twitter:image"></meta>
</b:else></b:if>

1行目のcontentは「summary_large_image」(大きい画像)もしくは「summary」(小さい画像)、2、3行目のアカウント名はTwitterアカウント、10行目のcontentはブログのトップページ(index)で表示する画像のURLを記述します。

URLとDescriptionについては、新しいテーマでなくともOGP設定がなされているようなので省略。

Titleも設定されていましたが、今回は好みの表示形式でなかったため改めて設定しました。

トップページの場合は「ブログ名」、各投稿ページの場合は「投稿タイトル - ブログ名」という表示形式になります。(デフォルトだと、各投稿のページが「投稿タイトル」になってました。テーマによる?)

Imageは、トップページの場合は固定の画像、各投稿ページの場合は"data:blog.postImageUrl"で投稿内の画像を表示します。

この"data:blog.postImageUrl"タグがなかったために、昔はBloggerで
のTwitterカードの設定が一苦労だったのですよね。(まぁ、知らなかっただけで、2015年頃にはすでに追加されていたみたいです。)

今回も、始めImageをOpen Graphタグ(property="og:image")で設定したら、なぜか"data:blog.postImageUrl"が使えず、仕方がないのでGAS(Google Apps Script)で投稿ULRから画像のURLをリダイレクトするウェブアプリケーションを作って代用を試みるもこちらもだめ…四苦八苦(丸一日)していたところで、ふとTwitterのカードタグ(name="twitter:image")で設定してみたら、すんなり"data:blog.postImageUrl"が使えました。

ふぅ…いろいろなぜなのかはよく分からないのですが(笑)。


手のかからないBloggerですが、やはりたまにはメンテナンスが必要ですね。

あと、結局、今回は使いませんでしたが、GASのウェブアプリケーションはかなり便利ですね(今更)。簡単な検索システムを、PHPとMySQLで作ろうと思っていたのですが、GASでいいかもしれません。





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

2021年8月21日土曜日

【定期】家計の見直し(2021年8月)

定期的な家計の見直しです。

仕事と生活がリンクする家族農業において、家計の最少化は、心強い生存基盤となります。

また、定期的な見直しを行うことで、自身や家族にとって本当に必要なもの、価値があるものが何なのか、改めて確認することができるのではないかと思います。


・スマホの月額料金

UQ mobileの「くりこしプランS」に「でんきセット割」を適用させまして、7月利用分の請求から月額基本料金が990円(税込)になりました。

いやはや、さすがに1000円切りはインパクトありますね。ありがたや、ありがたや。(子回線分は申し込みをミスりまして9月利用分から適用見込みです。いつもミスる…笑)

通話は、基本的に楽天モバイルのSIMでRakuten Linkを利用しています。こちら0円運用。いつまでこの状態が続くのか分かりませんが、まぁ、せっかくなので使えるうちは感謝の心で使わせていただきます。


・電気料金

UQ mobileで「でんきセット割」を適用させるため、自宅の電気をUQでんきにしました。

こちらは変更以前よりも基本料金および電力量料金が若干の値上がってしまったのですが、電気代に応じたPontaポイントの還元がありますし、スマホとトータルで考えればだいぶお得になります。

還元されるPontaポイントは、UQ mobileとUQでんきの契約者名義が別ですと低くなってしまうため、電気の契約者名義の変更手続きをしました(父→私)。変更が反映され次第、au IDを統合する予定です。

ただ、電気の申し込み時に契約者の名義が揃っていないと、あとから変更してau IDを統合しても還元率のアップはできない?という話もあり(最寄りのUQスポット)…やってみないと分かりませんね。無理そうな場合は、次の手を打ちます。


・ポイント投資

お買い物やらクレジットカードやら何やらで、生活の中でまぁまぁポイントが貯まっていきます。

宵越しの銭、もとい宵越しのポイントは持たない精神でパーッと使ってしまってもいいのですが、とくに必要のないものを買っても仕方がないので、一昨年くらいからポイント投資を始めてみました。

昨年は、一時期悲しいことになりましたが、何やかんや盛り返し、いい感じに育ってきました。まぁ、もともと数百、数千円分くらいのポイントなので、たかが知れておりますが、ちょっと愛着が湧いてくるので面白いものです。

これからはPontaポイントも投資に使っていこうと思います。


***

新型コロナウイルス感染症(COVID-19)は、またまたけっこう大変な状況になってきましたね。

個人的な理解ではありますが、感染症への立ち向かい方は、できる限りウイルスの伝播を緩やかにすることなのかなと思います。そのために各々何ができるのか。

そんなわけで、しばらくの間、いわきと佐野の行き来は控えることにしました。普段は楽しい二拠点生活ですが、感染症に対しては脆弱かもしれませんね。ともあれ、妻は佐野、私はいわきでそれぞれ頑張ります。

人間万事塞翁が馬、困難な日々ですが、今だからこそできる事や見える事もきっとありますね。この時代を生き抜いていきましょう。



半年前くらいに食べたアボカドが良い感じで育ってきました。

(そういえばアボカドって品種登録されているのかなと思って検索してみたのですが、されていないみたいですね。)


・関連投稿



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

2021年8月17日火曜日

【読書】感染症と文明――共生への道 (岩波新書)

こんなタイミングですので、お盆に読んでみました。2011年の著書です。


・感染症と文明――共生への道 (岩波新書)


今回の新型コロナウイルス感染症(COVID-19)の流行は、まさに青天の霹靂といった感覚でいたのですが、本書で感染症の歴史をみてみると、ただの平和ぼけだったのかもしれないと考え直させられます。

文明の発祥とともに始まった人類と感染症との闘いは、今尚続いているのですね。

そして、テーマでもある「感染症との共生」とはどういったものなのか。示唆に富み、非常に良かったです。

未だ終わりの見えない難しい日々ですが、今を歴史の中に置いて考えてみると、少し視野が広がるように思います。


また、あとがきにて東日本大震災時の支援活動に触れた部分があります。

"空はあくまで青く、海はあくまで蒼い。穏やかな水面には、渡り鳥が羽を休めている。風が吹き渡る。波音に驚いたのか、渡り鳥が一斉に飛び立つ。水面が波打つ。どこまでも平和な光景が広がっていた。これが、地震や津波を引き起こした同じ惑星の営みであることに眩暈を覚えた。"

私も当時、似たような心境を抱いたのを覚えています。

感染症に限らず、各地で災害も頻発しています。

こうした時代にあって、自然や人、社会と自らがどう向き合っていくのか、改めて考えてみたいと思いました。




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

2021年8月1日日曜日

【農業】職業講座の準備

今度、中学校の職業講座でお話しする機会があります。

予め質問をいただいたのですが、中学生くらいの世代の方々が、いま農業に対してどういったイメージや疑問を持っているのか、垣間見ることができて貴重ですね。

やはり、環境や最近よく目にするSDGs、はたまた地域おこし等、農業の持つ公共性的な側面への関心が大きいように感じます。

私自身、もともと産業としての農業よりも、土地利用の形態としての農業に興味がありますので、こうした質問は楽しいです。


またもう一方で、職業として考えたときに農業ってどうなの?という部分ですね。

農業のおもしろさは、選択肢の幅広さにあるように思います。

農業という産業を支える担い手として経営発展を目指すもよし。職人的に技術を磨き、ひたすら品質を求めるもよし。6次化等の形で他産業と組み合わせるもよし。

大事なのは、自分は農業を通して何がしたいのか(もしくは、したくないのか)という軸をしっかり持つことなのかなと思います。

もちろん、何れの形にせよ、最終的に収支をプラスにする頑張りは必要になりますけどね。


一生懸命、回答を考えていこうと思います。将来を考えるちょっとした材料になってくれたらいいですね。




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