No.39, No.38, No.37, No.36, No.35, No.34, No.33[7件]
Tweet ⌚ 2024年3月31日(日) 06:53:43 情報 <2493文字>
SNS 避難場所
![202308260401053-admin.png](images/202308260401053-admin.png)
Twitter(X) の動向が不安定な感じになり…不意に不遇の凍結とかの憂き目に遭った時に備えていくつかの SNS にアカウントを用意したっていうかまぁそんな際の緊急連絡先メモみたいな?
:
![20230826040105-admin.png](images/20230826040105-admin.png)
Twitter(X): @nekonyanma
:
![202308260401051-admin.png](images/202308260401051-admin.png)
Pawoo: @nekonyanma@pawoo.net
:
![202308260401052-admin.png](images/202308260401052-admin.png)
Misskey.io: @nekonyanma@misskey.io
※ ドライブの容量(?)の都合で画像を超絶圧縮してアップロードしてるんで超低画質です(-_-;)
:
![(キャプション自動取得対象外)](images/202308260401054-admin.png)
Bluesky: nekonyanma.bsky.social
:
他にタイッツー: @nekonyanma もあるけど…ちょっと様子見なかんじかな汗
:
長く使ってきた Twitter が手に馴染んでて一番使いやすいかなって思いつつ…不安定すぎるシステムがどうにも耐え難い感じですかね よくもまぁあんなので金取ろうと思ったなってのが最近の使用感ですかね(-_-;)
Pawoo は Mastodon が騒がれ始めた頃に ID を取ったまま最近まで放置してました Mastodon 系にも bot 投稿できるようになったんで…その頃から投稿頻度が高まってきたかな?って感じです 実写系画像テロする輩がちょくちょく発生するのがちょっと困った感じですかね
Misskey.io は Twitter の退避先として話題になってたんで ID を取ってみました イイネ!系のリアクションが頻繁に来る賑やかしさがあるけど…アニメ画像に埋め尽くされる雰囲気はちょっと落ち着かなくて閲覧頻度は低めです ドライブの容量(?)なんてのがあるらしく…普段どおりの画質でアップロードし続けてたら 2 年以内に容量いっぱいになりそうな感じだったんで Misskey.io のみ画像をありえないレベルの超低画質でアップロードするようにしています 予めご了笑ください
Bluesky は…これまた Twitter の退避先として急速に話題になってたんで ID を取ってみました リンクの張り方とかハッシュタグの作法が他の SNS と少し違う感じなんでちょっと扱いづらい感じですかね あと客層が心もち意識が高い系っぽいイメージなんで少し落ち着かないですね汗 まぁそれ故に新たな発見を得られやすくて刺激になっていいのかなって思ったりしますが
:
安住の地は何処にあるのだろう…なんかそんなかんじで
Tweet ⌚ 2023年8月26日(土) 02:44:42 メモ <1072文字>
(M5) ATOM Lite でまぁまぁスマートなリモコンを作ろう
![202307171653523-admin.png](images/202307171653523-admin.png)
今年の初めに…かれこれ 18 年くらい住んでたボロアパートをぶっ壊すってんで追い出されて今度は高級マンションの最上階に引っ越してきました!(>_<)w そんな高級マンションには…ご入居前リフォームで 2022 年製のエアコンに交換されていたのはいいんだけどちょっと使いづらいんですよね
何が使いづらいかっていうと…リモコンでのタイマーセットが不便なんですよ 以前のボロアパートで使ってたエアコンはリモコンに RTC(時計) が実装されていたのでタイマーセットも絶対時間で行うことができていたんですよ それがご新居のエアコンのリモコンには RTC(時計) が付いてないもんだでタイマーセットしようとすると「7時間後」って感じの相対時間での設定になるんですよ 不便ですよね(-_-;)
そんな訳なんでもちっとタイマーセットしやすいリモコンをどうにかするっていうか…せっかくなんでスマホちゃん等と連動させて絶対時間でエアコンの On/Off を制御できるリモコンを作ってみることにしました
昨年に「安いじゃん!」って思って買っておいた (M5) ATOM Lite が手元にあるんでそれを使うことにしました 今買うなら (M5) ATOMS3 Lite のほうがいいのかも知れないけど未確認です汗
それと CGI っていうか Perl が使える Web サーバが必要です 今回は Raspberry Pi OS にセットアップした Apache を使ってるけど…プロバイダなどで供されている CGI の使える Web サーバでも大丈夫だと思います
そうそう今回使う (M5) ATOM Lite には RTC が載っていません それ即ち時計が使えないって事なんでその辺をどうにかしなければなりません
そこで一定時間(今回は約30秒)ごとに Web サーバにアクセスして…アクセスされた Web サーバが現在時刻(とエアコン設定内容)を返しそれにより時刻の判定を行うようにしました
:
それでは最初に (M5) ATOM Lite の方から初めていきましょう 開発環境は Linux っていうか Snap 版の Arduino IDE を使いました まぁ Arduino IDE であれば Windows 版とかでも同じく使えるとは思いますが未確認です汗 そんな Arduino IDE の設定は M5StickC Plus の開発環境を構築する が参考になると思います ボードを追加した後に「M5Stack-ATOM」を設定すれば ok です
お次は (M5) ATOM Lite 向けのライブラリのインストールですかね これは「ツール」メニューから「ライブラリを管理…」を選んで検索窓に必要なキーワードを入れて出てきたものをインストールってする感じですかね
![20230717165352-admin.png](images/20230717165352-admin.png)
「m5atom」と入れて出てきた「M5Atom」をインストールする
![202307171653522-admin.png](images/202307171653522-admin.png)
「irremoteesp8266」と入れて出てきた「IRremoteEsp8266」をインストールする
![202307171653521-admin.png](images/202307171653521-admin.png)
「heatpumpir」と入れて出てきた「HeatpumpIR」をインストールする
これでライブラリ類の準備も完了ですかね それではコードを見ていきましょう…っていうか手探りの「どうにか動く」テスト的なものだったのが意外と問題なく動いてしまって「あーなんか書き直すのもめんどくさいなー」って気分が昂ぶってきたんでそんなテスト的なものをそのまま載せています 動作未保証なのはもちろんとして…諸々をきちっと書き直して使ってください それだけが私の望みです汗
:
----- Start of remcon.ino -----
#include <M5Atom.h> // Atom のヘッダファイルを準備
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <MitsubishiHeatpumpIR.h>
const char* url = "http://user:pass@hoge.orz/remocon/read.cgi"; // 現在時刻&設定内容の場所
const char* ssid = "WiFi_ssid"; // SSID
const char* password = "WiFi_pass"; // パスワード
const uint16_t kIrLed = 12; // 赤外線 LED 送信用のポート番号
IRSenderBitBang irSender(kIrLed); // 赤外線LEDが接続されているピン番号
HeatpumpIR *airCon = new MitsubishiFDHeatpumpIR(); // 三菱エアコンのインスタンス
// FastLED ライブラリの設定(CRGB構造体)
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
return (CRGB)((r << 16) | (g << 8) | b);
}
WiFiMulti WiFiMulti; // Wi-Fi を使いたい
void setup() {
Serial.begin(115200);
Serial.println("");
M5.begin(true, false, true); // 本体初期化(UART有効, I2C無効, LED有効)
M5.dis.drawpix(0, dispColor(0, 0, 0)); // LED全消灯(赤, 緑, 青)
WiFiMulti.addAP(ssid, password); // 「SSID」と「パスワード」を設定しておく
Serial.print("Fi-Fi Connecting.");
}
void loop() {
while (WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
M5.dis.drawpix(0, dispColor(255, 0, 0)); //LED(赤)
delay(500);
}
Serial.print("ADDR: ");
Serial.println(WiFi.localIP());
M5.dis.drawpix(0, dispColor(20, 20, 20)); // LED(白)
HTTPClient http;
http.begin(url);
Serial.print("GET: ");
int httpCode = http.GET(); // GET メソッドでファイルを取得
Serial.println(httpCode);
// Serial.println(http.errorToString(httpCode));
if (httpCode > 0) {
String htdoc = http.getString(); // 取得したファイルの内容
Serial.println(htdoc);
// YYYY/MM/DD HH:YY:MM(WDAY)\ts?,HH:MM e?,HH:MM m?
// 現在年/月/日 時:分:秒(曜日)\t開始フラグ,時:分 終了フラグ,時:分 モード
String now_hour = htdoc.substring(11, 13); // 現在時を取得
String now_min = htdoc.substring(14, 16); // 現在分を取得
String st = htdoc.substring(25, 27); // 開始フラグを取得
String ed = htdoc.substring(34, 36); // 終了フラグを取得
String st_hour = htdoc.substring(28, 30); // 開始時
String st_min = htdoc.substring(31, 33); // 開始分
String ed_hour = htdoc.substring(37, 39); // 終了時
String ed_min = htdoc.substring(40, 42); // 終了分
String md = htdoc.substring(43, 45); // モードを取得
if (st == "s1" && now_hour == st_hour && now_min == st_min) {
if (md == "m1") {
Serial.println("Cool");
M5.dis.drawpix(0, dispColor(0, 0, 255)); //LED(青)
airCon->send(irSender, POWER_ON, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 冷房
} else if (md == "m2") {
Serial.println("Hot");
M5.dis.drawpix(0, dispColor(255, 255, 0)); //LED(黄)
airCon->send(irSender, POWER_ON, MODE_HEAT, FAN_1, 16, VDIR_DOWN, HDIR_AUTO); // 暖房
} else {
Serial.println("Dry");
M5.dis.drawpix(0, dispColor(0, 255, 0)); //LED(緑)
airCon->send(irSender, POWER_ON, MODE_DRY, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 除湿
}
}
if (ed == "e1" && now_hour == ed_hour && now_min == ed_min) {
Serial.println("--- Stop ---");
M5.dis.drawpix(0, dispColor(255, 0, 255)); //LED(紫)
airCon->send(irSender, POWER_OFF, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 電源 Off
}
} else { // ファイルの取得に失敗している
Serial.println("Error");
}
delay(30000);
}
----- End of remcon.ino -----
※デバッグ用のシリアル通信のアレが残っているんで実稼働時には消したほうがいいかも知れないです
冒頭の #include <MitsubishiHeatpumpIR.h> は…まぁ見ての通り三菱社製のエアコン制御をする時に使うものです これが他社製であれば
#include <DaikinHeatpumpIR.h> // ダイキン社製
#include <FujitsuHeatpumpIR.h> // 富士通社製
#include <HitachiHeatpumpIR.h> // 日立社製
#include <PanasonicHeatpumpIR.h> // パナソニック社製
#include <ToshibaHeatpumpIR.h> // 東芝社製
こんな感じになるんじゃないかと思います(未確認) 詳しくは Aruduino IDE の関連フォルダ Arduino/libraries/HeatpumpIR/ を眺めてみるといいかと思います
:
データ(と時間)を取ってくる Web サーバの設定と… Wi-Fi 接続に関する設定を行います
const char* url = "http://user:pass@hoge.orz/remcon/read.cgi"; // 現在時刻&設定内容の場所
const char* ssid = "WiFi-ssid"; // SSID
const char* password = "WiFi-pass"; // パスワード
保安上っていうか恐らくベーシック認証なりをかけて運用すると思うのですが…その際に ID とパスワードの入力を自動化しておかねばなりません そんなときは http://user:pass@hoge.orz/remcon/read.cgi って感じで URL の前に「user:pass@」を付ければ自動で認証してくれます この書き方は一般的なブラウザでも(警告が出るかもだけど)使えます
その次に Wi-Fi の SSID とパスワードの設定を行います 上記のベーシック認証と併せて平文のパスワードを記すことになるので取り扱いには十分注意してください
:
HTTPClient http;
http.begin(url);
int httpCode = http.GET(); // GET メソッドでファイルを取得
Wi-Fi 接続が確立したら目的のサーバからデータを取ってきます 後でも説明しますが…ここで得られるデータは次のようになっています
YYYY/MM/DD HH:YY:MM(WDAY)[タブ(\t)]s?,HH:MM e?,HH:MM m?
[タブ(\t)] の前半がアクセスした時点での日時
[タブ(\t)] の後半がエアコンの開始/終了の時刻とモードを指しています
例えば 12 時 34 分に作動させたい場合は s1,12:34 となります その次が e1,23:45 だったら 23 時 45 分に電源を切る動作となります これが s0 もしくは e0 だった場合は何も動作しないようにしています
行末の m? は動作モードを指しています m1 が冷房 m2 が暖房 m3 が除湿です
http.GET(); した際のバッファサイズが不明だったんで…できるだけ切り詰めて必要最小限の内容にしました バッファに余裕があればもっと見やすい内容にするのもアリかもしれませんね
:
そして実際に赤外線で信号を送信する部分です
airCon->send(irSender, POWER_ON, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 冷房
各パラメータの意味は以下のようになっています
// airCon->send( irSender, POWER_**, MODE_**, FAN1, 温度設定, VDIR_** , HDIR_** ); // 設定項目 ※温度設定は「整数値」で
// Arduino/libraries/HeatpumpIR/HeatpumpIR.h
//
// ・POWER (電源)
// POWER_ON (on)
// POWER_OFF (off)
// ・MODE (モード)
// MODE_AUTO (自動)
// MODE_COOL (冷房)
// MODE_HEAT (暖房)
// MODE_DRY (除湿)
// MODE_ON (不明)
// MODE_OFF (不明)
// ・FAN (風量)
// FAN_AUTO
// FAN_1 (弱)
// FAN_2
// FAN_3
// FAN_4
// FAN_5 (強)
// ・VDIR (風向高さ)
// VDIR_AUTO
// VDIR_UP
// VDIR_MUP
// VDIR_MIDDLE
// VDIR_MDOWN
// VDIR_DOWN
// ・HDIR (風向左右)
// HDIR_AUTO
// HDIR_LEFT
// HDIR_MLEFT
// HDIR_MIDDLE
// HDIR_MRIGHT
// HDIR_RIGHT
エアコンの設定温度は整数値で指定する必要があるようです 最近は 0.5℃ 間隔で設定できるエアコンが増えてる感じですが…そこまで細かい制御には対応できないっぽいです また今回のプログラムでは設定温度を即値の決め打ちしています 使い勝手を高めるのであればこの辺も外部から変更できるようにすべきですね
だいたいこんな感じですかね これを delay(30000); して約 30 秒間隔のループで回しています なにかの都合…例えば http.GET(); した際にサーバの返答が遅れたりするとループ間隔が長くなり指定された時間を通り越してしまうかも?って思ってこのくらいの間隔にしました まぁこの辺は各環境によりけりで程よい設定にしてもらえればなぁって思います
:
さて…お次は UI っていうか Web サーバ側の云々ですかね 用意するのは 4 つのファイル(index.html, index.css, index.cgi, read.cgi)とスクリプトが生成する 1 つのファイル(data.txt)です
----- Start of index.html -----
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<!-- ビューポートの設定 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- スタイルシートの読み込み -->
<link href="./index.css" rel="stylesheet">
<title>M5 Atom Lite タイマー予約</title>
</head>
<body>
<center><div class="red"></div></center>
<center><form action="./index.cgi" method="get">
<div>
<label for="name"><a href="./index.cgi">M5 Atom Lite タイマー予約</a></label>
</div>
<div><hr class="double" width=80% noshade></div>
<div>
<label><input class="st" type="checkbox" name="st" value="1">「入り」を使う</label>
</div>
<div>
<select name="st_hour">
<option class="st_hour" value="00">00</option>
<option class="st_hour" value="01">01</option>
<option class="st_hour" value="02">02</option>
<option class="st_hour" value="03">03</option>
<option class="st_hour" value="04">04</option>
<option class="st_hour" value="05">05</option>
<option class="st_hour" value="06">06</option>
<option class="st_hour" value="07">07</option>
<option class="st_hour" value="08">08</option>
<option class="st_hour" value="09">09</option>
<option class="st_hour" value="10">10</option>
<option class="st_hour" value="11">11</option>
<option class="st_hour" value="12">12</option>
<option class="st_hour" value="13">13</option>
<option class="st_hour" value="14">14</option>
<option class="st_hour" value="15">15</option>
<option class="st_hour" value="16">16</option>
<option class="st_hour" value="17">17</option>
<option class="st_hour" value="18">18</option>
<option class="st_hour" value="19">19</option>
<option class="st_hour" value="20">20</option>
<option class="st_hour" value="21">21</option>
<option class="st_hour" value="22">22</option>
<option class="st_hour" value="23">23</option>
</select>時
<select name="st_min">
<option class="st_min" value="00">00</option>
<option class="st_min" value="10">10</option>
<option class="st_min" value="20">20</option>
<option class="st_min" value="30">30</option>
<option class="st_min" value="40">40</option>
<option class="st_min" value="50">50</option>
</select> 分
</div>
<div><hr class="double" width=80% noshade></div>
<div>
<label><input class="ed" type="checkbox" name="ed" value="1">「切り」を使う</label>
</div>
<div>
<select name="ed_hour">
<option class="ed_hour" value="00">00</option>
<option class="ed_hour" value="01">01</option>
<option class="ed_hour" value="02">02</option>
<option class="ed_hour" value="03">03</option>
<option class="ed_hour" value="04">04</option>
<option class="ed_hour" value="05">05</option>
<option class="ed_hour" value="06">06</option>
<option class="ed_hour" value="07">07</option>
<option class="ed_hour" value="08">08</option>
<option class="ed_hour" value="09">09</option>
<option class="ed_hour" value="10">10</option>
<option class="ed_hour" value="11">11</option>
<option class="ed_hour" value="12">12</option>
<option class="ed_hour" value="13">13</option>
<option class="ed_hour" value="14">14</option>
<option class="ed_hour" value="15">15</option>
<option class="ed_hour" value="16">16</option>
<option class="ed_hour" value="17">17</option>
<option class="ed_hour" value="18">18</option>
<option class="ed_hour" value="19">19</option>
<option class="ed_hour" value="20">20</option>
<option class="ed_hour" value="21">21</option>
<option class="ed_hour" value="22">22</option>
<option class="ed_hour" value="23">23</option>
</select>時
<select name="ed_min">
<option class="ed_min" value="00">00</option>
<option class="ed_min" value="10">10</option>
<option class="ed_min" value="20">20</option>
<option class="ed_min" value="30">30</option>
<option class="ed_min" value="40">40</option>
<option class="ed_min" value="50">50</option>
</select>分
</div>
<div><hr class="double" width=80% noshade></div>
<div>
<input class="md" type="radio" name="md" value="1">冷房
<input class="md" type="radio" name="md" value="2">暖房
<input class="md" type="radio" name="md" value="3">除湿
</div>
<div><hr class="hrline" width=80% noshade></div>
<div>
<input class="submit" type="submit" value="予約">
</div>
</form></center>
</body>
</html>
----- End of index.html -----
index.html ってファイル名なんで…デフォルトで表示されるファイルっぽいですが実際にはそのような用途には使っていません デザインしやすいようにファイルを分割してあるだけで実際に表示は index.cgi が行います
----- Start of index.css -----
/* ボディ */
body { /* 一般的な表示部 */
margin: 0 ;
padding: 0 ;
font-size: 20px ;
line-height: 3 ;
}
input { /* チェックボックス */
width: 25px;
height: 25px;
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
transform: scale(1.4);
}
select { /* プルダウンメニュー */
font-size: 30px ;
}
.hrline { /* 罫線(?) */
border: none;
background-color: #fff;
border-width: 1px 0 0 0;
border-top: double;
border-color: black;
}
.submit { /* 送信ボタン */
width: 100px;
height: 40px;
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
transform: scale(1.4);
}
.red { /* 設定変更した */
font-size: 40px ;
color: #ff0000;
}
/* スマホだけに適用するCSS */
@media screen and ( max-width:479px ) {
body { /* 一般的な表示部 */
font-size: 20px ;
}
input { /* チェックボックス */
width: 25px;
height: 25px;
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
transform: scale(1.4);
}
select { /* プルダウンメニュー */
font-size: 25px ;
}
.hrline { /* 罫線(?) */
border: none;
background-color: #fff;
border-width: 1px 0 0 0;
border-top: double;
border-color: black;
}
.submit { /* 送信ボタン */
width: 100px;
height: 40px;
-moz-transform: scale(1.4);
-webkit-transform: scale(1.4);
transform: scale(1.4);
}
.red { /* 設定変更した */
font-size: 40px ;
color: #ff0000;
}
}
----- End of index.css -----
でっか文字な表示にしたくて見様見真似で用意しました 見様見真似の即興ってことで CSS について何一つ理解していません汗 おかしな所しかないと思うけど…まぁその辺は生温かい目で見守って頂けると幸いに思います(瀧汗
----- Start of index.cgi -----
#!/usr/bin/perl
$datafile = "./data.txt"; # ATOM Lite が読みにくるファイル
$htmlfile = "./index.html"; # ベースとなる HTML ファイル
if ($ENV{'REQUEST_METHOD'} eq 'POST') { # POST メソッドで送られてきた場合
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else { # GET メソッドで送られてきた場合
$query = $ENV{'QUERY_STRING'};
}
#### ATOM Lite が読みにくるデータファイルを作成する ####
open (DATA, $datafile);
$data = <DATA>; # 既存のデータファイルを読み内容を取り出しておく
if ($data =~ /s(\d),(\d\d):(\d\d) e(\d),(\d\d):(\d\d) m(\d)/) {
$in{'st'} = $1;
$in{'st_hour'} = $2;
$in{'st_min'} = $3;
$in{'ed'} = $4;
$in{'ed_hour'} = $5;
$in{'ed_min'} = $6;
$in{'md'} = $7;
}
close (DATA);
if ($query) { # データを受信していた場合の処理
open (DATA, ">", $datafile);
foreach $data (split(/&/, $query)) { # 「&」で分割して全て処理する
($key, $value) = split(/=/, $data); # 「name=value」のそれぞれに分割して連想配列を作っていく
$value =~ s/\+/ /g; # 以下ざっくりとした URL デコードする
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
$value =~ s/\t//g;
$in{"$key"} = $value; # value = $in{"$name"} の連想配列が出来上がる
}
# 送られてきた内容を適用してデータファイルを更新
if (!($query =~ /st=/)) { $in{'st'} = '0'; } # チェックボックスの挙動がアレなんで個別対応(汗
if (!($query =~ /ed=/)) { $in{'ed'} = '0'; } # チェックボックスの挙動がアレなんで個別対応(汗
if ($in{'st'}) { print DATA "s1,"; } else { print DATA "s0,"; }
if ($in{'st_hour'}) { printf DATA "%02d:", $in{'st_hour'}; } else { print DATA "00:"; }
if ($in{'st_min'}) { printf DATA "%02d ", $in{'st_min'}; } else { print DATA "00 "; }
if ($in{'ed'}) { print DATA "e1,"; } else { print DATA "e0,"; }
if ($in{'ed_hour'}) { printf DATA "%02d:", $in{'ed_hour'}; } else { print DATA "00:"; }
if ($in{'ed_min'}) { printf DATA "%02d ", $in{'ed_min'}; } else { print DATA "00 "; }
if ($in{'md'} eq "1") { print DATA "m1\n"; } elsif ($in{'md'} eq "2") { print DATA "m2\n"; } else { print DATA "m3\n"; }
close (DATA);
}
open (IN, $htmlfile); # 以下ベースとなる HTML ファイルを読み込み設定時間などを反映させる
print "Content-type: text/html; charset=UTF-8\n\n";
@lines = <IN>;
foreach (@lines) {
if ($query) { s/(<div class="red">)(<\/div>)/$1設定しました$2/; }
if ($in{'st'} eq "1") { s/(class="st")/$1 checked/; }
if ($in{'st_hour'}) { s/(class="st_hour" value=")($in{'st_hour'}")/$1$2 selected/; }
if ($in{'st_min'}) { s/(class="st_min" value=")($in{'st_min'}")/$1$2 selected/; }
if ($in{'ed'} eq "1") { s/(class="ed")/$1 checked/; }
if ($in{'ed_hour'}) { s/(class="ed_hour" value=")($in{'ed_hour'}")/$1$2 selected/; }
if ($in{'ed_min'}) { s/(class="ed_min" value=")($in{'ed_min'}")/$1$2 selected/; }
if ($in{'md'}) { s/(name="md" value=")($in{'md'}")/$1$2 checked="checked"/; }
print $_;
}
close (IN);
----- End of index.cgi -----
実際に表示を受け持つ index.cgi です 表示を受け持ちつつ…フォームで入力された値を解釈して data.txt を生成します そしてそのフォームで入力された値 index.html の内容を書き換えて表示するようになっています こうしておけば以前の設定内容を次回の設定に引き継げるようになるので便利かなーって思いまして
そんな訳なんで .htaccess で Web サーバの設定変更が可能な場合は DirectoryIndex index.cgi としてデフォルトで読み出されるファイルに設定しておくといいでしょう
あとこの index.cgi は GET メソッドでデータを受けれられるので…極端な話パラメータ付きの URL を直打ちすることでも設定が可能です 例えば 08 時 20 分 に 冷房 で作動させ 19 時 30 分 に電源を切る場合だと
http://user:pass@hoge.orz/remocon/index.cgi?st=1&st_hour=08&st_min=20&ed=1&ed_hour=19&ed_min=30&md=1
こんな感じの URL になります それ即ち wget や curl などのコマンドでアクセスすることが可能となり…さらに cron などを使えば毎日の動作や毎週の動作といった感じで自動化することも可能になります いや実際に試してはないですけどたぶん大丈夫だと思います汗
----- Start of read.cgi -----
#!/usr/bin/perl
print "Content-type: text/plain; charset=UTF-8\n\n";
# 現在日時の表示
@wdays = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time());
printf "%04d/%02d/%02d %02d:%02d:%02d(%s)\t", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $wdays[$wday];
$datafile = "./data.txt"; # ブラウザで設定した内容のファイル
open (DATA, $datafile);
print <DATA>; # ファイルの 1 行目を読み取り表示する
close (DATA);
----- End of read.cgi -----
(M5) ATOM Lite がアクセスしてくるファイル(CGI)です 現在日時を整形して表示して…あとは index.cgi が生成した data.txt の内容をくっつけて送信してくれます
:
ごちゃごちゃ長くなったんで以下にまとめときます 「名前を付けてリンク先を保存」とかすれば手間がなくていいと思いますたぶん
remcon.ino (M5) ATOM Lite 用 Arduino Sketch ファイル
index.html 表示のベースとなる HTML ファイル
index.css でっか文字にするためのアレ
index.cgi ページ表示しつつデータファイルを作成する
read.cgi (M5) ATOM Lite が読みに来る先のやつ
data.txt index.cgi が作成するデータファイル
![20230717165352-admin.jpg](images/20230717165352-admin.jpg)
そして後はいい感じに設置して完了ですかね (M5) ATOM Lite の赤外線はかなり飛距離が短いんで…エアコンにへばりつけるような設置になっちゃうのかな
あーあと余談っていうか注意事項ですが (M5) ATOM Lite が読みに来る read.cgi は数十秒に 1 回のペースで 24 時間 365 日延々とアクセスがあります そのままの Web サーバだと…そのアクセス毎にログファイルが蓄積されることになります もし可能なら Web サーバの設定を変更して…このアクセスに対してのみログの書き込みを抑制するなどしたほうがいいと思います ざっくり SetEnvIf nolog なんて感じのキーワードでぐぐれば必要な情報に辿り着けるとイイナ!
:
そんな感じで最後までご覧いただきありがとございました汗 ざっくりテスト用に作ったのをイジくりまわした代物なのでいろいろおかしな部分はありますが…手っ取り早く動作を体感してみたい!って時には役立つかもです それにしても 1,000円 ちょっとで買える (M5) ATOM Lite はホントすごいですよね きちんと筐体に収められていつつ… Wi-fi で接続を確立して HTTP でデータを取ってくることができる 赤外線 LED でリモコンのような動作もさせられる 欲を云えば RTC(時計) が欲しかったかなって感じではあるけど…それもどっかのサーバに接続して時刻を取得すればそれほど問題にはならないんでまぁいいかな♪ なんかそんなかんじで #Arduino #M5StickC
Tweet ⌚ 2023年7月17日(月) 08:43:28 情報 <19935文字>
IPv6 での接続について
![2023032509192510-admin.png](images/2023032509192510-admin.png)
2023年2月18日(土)に行った屋内電源及びネットワーク回線の工事の際に Firewall の設定を間違えてて WAN 側から IPv6 でのアクセスができない状態になってました
LAN 内では問題なくアクセスできたので設定ミスに気付くまで時間がかかってしまいました(汗 まぁ環境にもよるんだろうけど…意外と WAN 側からの諸々のテストは疎かになりがちなんで自戒メモ
![20230325091925-admin.png](images/20230325091925-admin.png)
![202303250919251-admin.png](images/202303250919251-admin.png)
そんな IPv6 での接続をざっくり判定して表示しています まぁ時既に世の多くが IPv6 での接続をサポートしてるっぽいんであ んまり意味ないかもだけど(滝汗
:
ちなみにスマホちゃんの SIM でのデータ通信だと IPv4 と IPv6 を選択できるようです
---- Android の場合の設定例 ----
![202303250919259-admin.png](images/202303250919259-admin.png)
「設定」画面から「ネットワークとインターネット」を選ぶ
![202303250919258-admin.png](images/202303250919258-admin.png)
「ネットワークとインターネット」画面から「SIM」を選ぶ
![202303250919257-admin.png](images/202303250919257-admin.png)
「SIM」画面から「対象のSIM」を選ぶ ※ここでは NTT DOCOMO を選択
![202303250919256-admin.png](images/202303250919256-admin.png)
先ほど選択した「NTT DOCOMO」画面から「アクセスポイント名」を選ぶ
![202303250919255-admin.png](images/202303250919255-admin.png)
「APN」画面から「現在使用中のAPN」を選ぶ ※ここでは DMM mobile を選択
![202303250919254-admin.png](images/202303250919254-admin.png)
「アクセスポイントの編集」画面で「APNプロトコル」を選ぶ
![202303250919253-admin.png](images/202303250919253-admin.png)
「APNプロトコル」ダイアログが出るので IPv4 か IPv6 を選択する
![202303250919252-admin.png](images/202303250919252-admin.png)
右上の「︙」メニュー内の「保存」を選ぶ
--------
ご使用の OS のバージョンや SIM によって設定できたりできなかったりするらしいので…設定できたらラッキー☆って感じですかね つーかそもそも IPv6 の判定のやりかた自体が間違ってる可能性もアレですが(-_-;) #Android
Tweet ⌚ 2023年3月25日(土) 08:14:13 メモ <784文字>
でんげき☆Network Service お部屋サーバの一時休止のお知らせ
2023年2月18日(土)に屋内電源及びネットワーク回線の工事を行うため午前8時頃から午後6時頃までサーバが停止してアクセスできなくなります日程・時間などに変更が生じた場合には追ってご連絡いたします
ご不便をおかけしますがよろしくお願い致します
----- 追記 -----
無事に工事が終了しました ご協力ありがとございました
Tweet ⌚ 2022年12月31日(土) 18:29:36 メモ <204文字>
かつや・牛バラ焼きとささみタレカツの合い盛り
![20221120084016-admin.jpg](images/20221120084016-admin.jpg)
かつや の期間限定!「牛バラ焼きとささみタレカツの合い盛り」丼を食べてきました!
毎度ながらの丼からあふれんばかりの具だくさんすぎて思わずほっこりしちゃう盛り付けですね
どちらの具から頂こうか心もち悩みつつ…それじゃ鶏ささみタレカツからいってみましょう
しょーみ鶏ささみカツって「なんかパサパサしてそうだな」ってイメージだったんだけど…サックリ揚がったカツをタレにくぐらせることによりジューシーな仕上がりになってて先入観ぶっちぎりの美味しさでこれはイケます!
そして相方の牛バラ焼は…にんにくの香りを活かしたタレで焼かれているのでしょうか? 濃いめの味付けが脂ぎっしゅな牛バラ肉と相まってこれも美味い! 一緒に焼かれた玉ねぎと…付け合せの千切りキャベツによるアクセントが効いて飽きること無く楽しめます!
いやむしろ濃厚な具だくさんすぎて毎度ながらのご飯とのペース配分が乱されっぱなしな肉いメニューです 期間限定にしとくのは実に惜しい美味しさなんでまた早めにもっぺん楽しんでこなくっちゃですね!(>_<)w #外食記録
Tweet ⌚ 2022年11月20日(日) 08:40:16 日記 <488文字>
吉野家・牛すき鍋膳
![20221031163105-admin.jpg](images/20221031163105-admin.jpg)
寒くなってきたらコレに限るね!ってことで 吉野家 の 牛すき鍋膳 を食べてきました
なんか「一食で半日分の野菜が摂れる」って辺りを推してる感じだけど…いやいや思ってたより脂ぎっしゅなお肉がたっぷりで食べ応えがありますぞ!
しかもお肉と野菜がたっぷりなだけでなく〆のうどんまで入ってるので満足感が大きいです
これが濃い目のタレでぐつぐつ煮込まれているってんだからご飯がどんだけあっても足りません!
定番通り小鉢の溶き卵にくぐらせながら食べるもよし…溶き卵を煮立った鍋に入れ玉子とじにしてご飯に載せて食べるのもイイネ!
圧倒的に価格以上の満足感を得られます これはまた近いうちに食べに行きたいです #外食記録
Tweet ⌚ 2022年10月31日(月) 16:31:05 日記 <317文字>
TeraStation™ 5000N Series って NAS のディスク交換した際のリカバリ方法メモ
時既に死語となりつつある SOHO っていうか小規模企業用のファイルサーバとして多く使われているファイルサーバ(NAS)がリプレースされて大漁にジャンク屋さん等に流れてきて安く叩き売りされているってイメージの TeraStation™ 5000N Series があるんだけど…こいつは動作用のシステム(Linux)を搭載 Disk 上に構築してるって都合上なのかその Disk を抜いちゃうとピクリともしない置物になっちゃうんでその辺をリカバリする方法を今後の忘れ物防止メモ的に記した概ね私的なドキュメントです汗
そんなこなんで今回は前々から使ってた BUFFALO TeraStation TS5200D って NAS のディスクを HDD から…消音化を期待して SSD へと置換した際の作業履歴です ちなみに HDD として運用してた際のデータは約 4TB ほどあり…それを 2TB の SSD にまるっと複製するのは物理的に不可能だってことなんで HDD のデータは事前にファイルを抜いた後に SSD に換装して真っ更な状態に再構築したって条件になります
それでは→ TeraStation™ 5000N Series | Buffalo Americas から USB メモリに書き込むブート可能なイメージファイルをダウンロードしてきます
「DOWNLOAD CONTENTS」タブを選んだ後に…
「Bootable USB recovery image for TS5000 series.」って感じの説明があるものをダウンロードします ※ 2024/03/31 時点で「TS5k_recovery_260.zip」ってファイルでした これを適当な場所に解凍しておきます
これを別途用意しておいた USB メモリ(※概ね 2GB くらいの容量を必要とするらしく…まぁ余裕を考えて 2.1GB 以上の USB メモリが必須だと思われる)にブートイメージを書き込みます この際 Windows 利用の場合だと添付の専用ツールでどうにかなるらしいのですが…まぁ Linux とかなら普通に dd を使って TS5000V2.6bootUSB.ddi を書き込めばいいようです ※画像は既に TS5000V2.6bootUSB.ddi を書き込んだ後のものなのでアレですけど汗
$ sudo dd if=TS5000V2.6bootUSB.ddi of=/dev/sd○ status=progress
of=/dev/sd○ の「○」の部分は各人の環境により異なります! 必ず「コントロールセンター」→「ハードウェア:ディスク」を参照するなりして適切に指定してください!! ※画像は既に TS5000V2.6bootUSB.ddi を書き込んだ後のものなのでアレですけど再び汗
:
これでブータブル USB メモリの準備ができたんで TeraStation のリカバリをしていきます もちろんこの段階で TeraStation に HDD なり SSD を正しく装着した状態にしておきます
先程の USB メモリを TeraStation 背面の USB ポートに挿し…ブートのセレクタスイッチを「USB」側にセットして電源を接続して本体前面にある電源ボタンを ON にします
しばらくすると本体前面の液晶表示部に「Recovery I41 PushFuncToStart」と表示されるんで…同じく本体前面にある「FUNCTION」ボタンを押す
本体前面の液晶表示部が「Recovery I37 SystemRecovering」となりリカバリ処理が実行されます
リカバリが完了しました
電源を切り…本体背面のブートのセレクタスイッチを「HDD」側にセットしてリカバリ USB メモリを抜いて LAN ケーブルなんかを挿して諸々の準備が整ったら再度電源を入れます
:
これで後は BUFFALO TeraStation TS5200D の IP アドレスにブラウザでアクセスすれば設定画面が表示される…らしいんですがなんかバグったような表示になり先に進めない? 困りましたね(-_-;)
どうやらこの辺はファームのアップデートを行えば対処できるらしいんでそのようにしてみます
TeraStation 5000シリーズ ファームウェア アップデーター (Windows) ってのがあるようなのでダウンロードしてきます
ダウンロードした ts5000-v422.exe は…そのまま ZIP ツールで解凍できるんで適当なフォルダに解凍します そして解凍したフォルダに移動して TS5000-v422 フォルダに移動した後に Windows のアプリケーションを Linux 上で動作させる Wine ってのを使って TSUpdater.exe を実行します
$ wine TSUpdater.exe
TeraStation のファームがいろいろと更新されていきます
これらの作業が全て完了すれば…今度こそ BUFFALO TeraStation TS5200D の IP アドレスにブラウザでアクセスできるようになり諸々の設定が可能になります
ちなみに初回起動時の管理者ユーザ名とパスワードは
ユーザー名:admin
パスワード:password
で入れます 入ったら直ちにパスワードを別のものに変更しておきましょう
そんなこなんないろいろとややこしそうな作業の連続ですが…まぁ間違えたりしても最初のリカバリ USB メモリでのブートの辺りまで戻れば何度でもやり直し可能なんで気楽に作業すればいいかなって感じです それでは良いジャンク NAS 生活を!(>_<)w #NAS #Ubuntu