2019/06/05(水)【雨量観測】XRAINのスクリーンショットを会社Slackに投稿するPerlスクリプト

天気情報が流れるチャンネルが会社のSlackにあるのですが、XRAINのスクリーンショットも流れてきてほしくなったので作りました。

ちなみに大学生の頃は大学院の研究室訪問や大学院試験の費用を稼ぐために気象会社でアルバイトしていました。

SlackのtokenとチャンネルIDの取得情報はググってください。

$logo は会社のロゴと矢印が描かれた画像で、矢印の先にオフィスがあるという具合になっています。適当な画像を用意して置き換えてください。

CPANモジュール以外は何か特別にインストール必要なものはありませんでした。

#!/usr/bin/evn perl

use strict;
use warnings;
use utf8;
use Log::Log4perl qw(:easy);
use WWW::Mechanize::Chrome;
use File::Spec;
use File::Basename 'dirname';
use HTTP::Request::Common qw//;
use Encode;
use Furl qw//;
use JSON;
use Imager;
use DDP;

# TODO:
#  * 会社付近の色を取得して雨が降っているか判定

my $dirname = File::Spec->rel2abs(dirname($0));
my $rain_url = 'http://www.river.go.jp/x/krd0207010.php?lon=139.50406730175018&lat=35.674031853779084&opa=0.4&zoom=8&leg=0&intvl=5&ext=0';
my $fn= $dirname . "/xrain.png";
my $logo = $dirname . '/logo_and_arrow.png';

Log::Log4perl->easy_init($ERROR);
my $mech = WWW::Mechanize::Chrome->new(headless => 1);
$mech->viewport_size({ width => 760, height => 780 });
$mech->get($rain_url);
my $png = $mech->content_as_png;

open(my $fh, '>', $fn) or die $!;
binmode($fh);
print {$fh} $png;
close $fh;

my $img = Imager->new;
$img->read(file => $fn) or die $img->errstr;

$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 460,
  ty => 527,
);

$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 1203,
  ty => 527,
);

$img->rubthrough(
  src  => do {
  my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 460,
  ty => 1170,
);
$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 1203,
  ty => 1170,
);

$img->write(file => $fn) or die $img->errstr;

my $req = HTTP::Request::Common::POST('https://slack.com/api/files.upload',
  Content_Type => 'multipart/form-data',
  Content => [
    token    => 'xxxx',
    channels => 'xxxx',
    file     => [$fn],
    title    => Encode::encode_utf8('XRAIN自動投稿'),
    initial_comment => $rain_url,
  ]
);

my $res = Furl->new->request($req);
my $json = Encode::decode_json($res->content);

#p $json;

うまくいけば↓のように投稿されます。cronで定期実行させています。

スクリーンショット_2019-06-05_21_19_07.png

2019/04/29(月)人生2回目の硬式テニスのシングルス区民大会出場!

2017年9月11日にテニスを始めて1年7ヶ月と少しになりました。

テニススクールでテニスを始めて半年ほど通った後は、会社でテニスサークルを立ち上げ、テニススクールと会社テニスの週2の練習(たまに社外のテニスサークルにも参加しつつ)を確保し続けてきました。会社のテニスサークルは、主要メンバーは会社サークルで始めたメンバーで、まだまだ経験不足の私が適宜アドバイスしつつやっています。(たまにアドバイスをもらうこともありますが。)

テニス技術の向上だけを考えるのであれば、自分より強いメンバーしかいない社外のテニスサークルをメインにしてやるべきであることは分かっています。本心でも実はそうしたいと思っています。しかし、社員をテニスにハマらせた自分が今から抜けるのはさすがに無責任であろうし、会社の唯一の運動部として私の役割は小さくないと思っています。また、毎週テニスコートを確保して、社員に運動の機会・スポーツを通じて部署を越えた交流の機会を提供することも私が会社に対して発揮できる価値の一つなんだろうとも思えてきています。そのため、テニスの技術向上を最優先させずに会社のメンバーとテニスするのはトータルでみると悪くはない選択であると考えています。 (少なくとも現状においては。)

さて、本日は人生2回目の区民大会シングルス出場でした。初めての出場の記録は https://pawafuru.com/0410 をご覧ください。

午前9時10分集合で、午前8時53分に到着。会場は午前8時55分が開館時刻だったので、良いタイミングでの到着でした。集合時刻の午前9時10分までは適当にコートでアップさせてもらえました。練習相手はどうすればいいんだろうかと困惑しましたが、自分より年上の方に誘われて良い具合にアップできました。

前回は試合までの待ち時間が長かったのですが今回は第1試合なのですぐ試合でした。対戦相手は自分と同世代くらいの方でした。フィッチでは、なぜかパニクって「回答は何ていうんだっけ」という状態になりました。どうにか「アップ・ダウン」が頭に出てきたので、アップで通じました。(ラフ or スムースのほうが通じやすいかな。)相手がレシーブを選んだので自分からサーブになりました。(練習時間が短くて体が温まっていないとの判断でレシーブを選んだのだろうか。)

1ゲーム目は、序盤の緊張で一度難しくない球を空振ったりしつつ 40-40まで行って、「ゲーム取れるかな」という具合だったのですが、たしかダブルフォルトでブレイクされました。

あとは、ラブゲームはなかったはずですが、サーブと前に出て攻める力の差が大きくてゲームカウント 0-6 で負けました。

スマートウォッチでスコア計測していましたが、ポイント数では 9-24 でした。(スマートウォッチの詳細:https://inside.pixiv.blog/pawa/5744)

写真 2019-04-29 9 50 21.jpg

試合内容は以下のようなところ:

  • レシーブミス多め(が、文句なしなレシーブもあり)
  • ダブルフォルト4回以上した
  • 深めストロークでシコリ勝った
  • フォアハンドストロークがオーバーさせる恐怖で2球連続で浅くなって打ち込まれる場面があった
  • 前回の練習でバックハンドストロークが後ろから前の野球打ちに戻ってるのに気づいて下から上のトップスピン用スイングに修正できた

練習メニューももっと実戦を意識したものにしていきたいですね。(今、ロングラリーするとき相手がいるところに打っているのをオープンコートを狙うようにするとか)

課題は以下です:

  • 確実に入るセカンドサーブを身につける
  • 前後左右に多少振られても自分のスイングで打ち込めるようにする
  • 攻めの姿勢(こういう戦力差がある試合でもむしろ興奮しちゃう程度にマゾヒズム傾向にあるので攻めるのは得意ではないのですが)

初出場の去年に比べると試合内容は格段に良くなりました。ちゃんと成長しているのを感じたので「立ち止まりさえしなければいずれは勝てる」でしょう。

Baby Steps To Giant Strides.

2019/01/01(火)IPv6無効化環境でMuninをアップデートしたら逝っちゃった件

yum update で諸々アップデートしていたら

Cron Daemon さんからメールが来ました。

[FATAL] There is nothing to do here, since there are no nodes with any plugins. 
Please refer to http://munin-monitoring.org/wiki/FAQ_no_graphs at /usr/share/munin/munin-html line xx

サーバ監視ツールの「munin」が逝っちゃったようだ😣

/var/log/munin-node/munin-node.log を覗くと、

yyyy/mm/dd-HH:MM:SS Munin::Node::Server (type Net::Server::Fork) starting! pid(xxx)
Resolved [*]:4949 to [::]:4949, IPv6
Not including resolved host [0.0.0.0] IPv4 because it will be handled by [::] IPv6
Binding to TCP port 4949 on host :: with IPv6
yyyy/mm/dd-HH:MM:SS Server closing!

との怪しいログが...。

調べると、CPANモジュール「Net::Server」のドキュメントに情報がありました。

On my linux box which defaults to net.ipv6.bindv6only=0, the following is output.

perl -e 'use base qw(Net::Server); main->run(host => "*")'
 
Resolved [*]:8080 to [::]:8080, IPv6
Not including resolved host [0.0.0.0] IPv4 because it will be handled by [::] IPv6
Binding to TCP port 8080 on host :: with IPv6

IPv6無効化環境なのにMuninがIPv6を利用して動こうとしているようであることが推測されました。

WebサーバでIPv6に対応するメリットを現状はほとんど感じないので、なんとかIPv6無効のまま正常に動くように直したいと思いました。CPANモジュール「Net::Server」のドキュメントによると、以下のように書いてありました。

If you do not want or need IPv6, simply set ipv to 4, pass IPv4 along in the port specification, set $ENV{'IPV'}=4; before running the server, or uninstall IO::Socket::INET6.

IPv6を要しない場合、 $ENV{'IPV'}=4 (環境変数でIPv4を指定する)か IO::Socket::INET6 (というCPANモジュール)をアンインストール(cpanm -U IO::Socket::INET6)せよとのこと。

しかし、 /usr/share/munin/munin-html line xx の前に $ENV{'IPV'}=4 を挿入しても変わりありませんでした。

どうしようか悩みましたが、 vim /etc/munin/munin.conf で以下を追記してやると「Server closing!」を回避できたのでメモしておきます。

[localhost]
    address 127.0.0.1
    use_node_name yes

use_node_name yes はなくても動くんじゃないかと思っています(未検証)。

解決までmuninのグラフが途切れましたが、また止まった時が動き出しました。

fw_conntrack-day.png

2018/10/02(火)テニスサークルを半年運営して役立った、毎回の活動を楽しくするアイテム6選

テニススクールに半年通ってから会社でテニス部を立ち上げ、また半年と少しが経過しました。テニス部員が楽しくレベルアップできるようにいろいろ試行錯誤しながら活動しています。今回はその試行錯誤を経て得られた、毎回の活動を楽しくするのに役立ったアイテムを紹介したいと思います!

ブリジストン NP(役立ち度:★★★, 満足度:★★☆)

使い始めこそ飛びすぎないかと感じましたが数ヶ月も使っている間に良い具合に飛びが抑えられて、6ヶ月半ほど経った今では、ダンロップFORTやテニススクールで打っているボールとの違いを感じないレベルになりました。驚異の耐久性でまだしばらく買い替える必要を感じていません。

スコアボード(役立ち度:★★☆, 満足度:★★★)

IMG_2473.jpg

https://item.rakuten.co.jp/lafino/goods-sanei-004/

驚異の1万円で買うのに相当悩みましたが、かなりしっかりしてそうでレビューも良いので買ってみました。非常に頑丈にできていて、トスを上げたボールが風で流されてしまうような強風の日でもスコアがパラパラめくれることもないし、ボールがスコアボードに直撃してもまったく壊れる感じもしないのはさすがとしか言いようがありません。何より試合のときのテンションが上がるのが良いです。

マーカーコーン(役立ち度:★☆☆, 満足度:★★★)

サーブ練習するにしても打つ場所に目標があるほうが良いだろうと思って買いました。Amazonで買うにはサイズが問題ないか心配していのですが、欲していたのは「まさにコレ」という商品でした。部員のレベルがまだまだきっちり狙えるほど高くないのでそこまで役立っていませんが、サーブのワイド・センターなどの打ち分けができるくらいレベルが上がればもっと役立つと思います。

SLIK 三脚 GX 6400(役立ち度:★★★, 満足度:★★★)

我がテニス部では、自身がどうやって打っているか知らずに上達するのは難しいであろうという考えに基づいて毎回の活動を映像に収めています。最初はスマホスタンドで撮影していたのですが、高さが足りない問題とスマホスタンドにボールが当たったときの安定性に難があったので、そこそこの三脚を買おうという機運になって買いました。これ以上良い三脚の必要性を感じないレベルで満足しています。あえて懸念点を上げるとすれば、猛烈な風が吹いたら三脚が倒れるだろうというところです。(とは言え、三脚を買ってから10回近くテニスしてそこまでの風はまだ吹いたことがありません。追記:15回くらいしたら倒れるレベルの風が吹きました。そこだけ難ありですね。)

SLIK 三脚アクセサリー スマホホルダー(役立ち度:★★★, 満足度:★★★)

普通は三脚を買ったらその上にカメラを載せるのでしょうが、今やスマホにカメラが付いているのに本当にスマホとは別でカメラが必要だろうか(いや、必要ないだろう)と思って買いました。(テニスをしている最中はスマホ使わないし。)これがまた良い商品で、角度調整などもバッチリできてガッシリとスマホをホールドしてくれて何も文句の付けようがないとしか言いようがありませんでした。ありがとうSLICK! 今も毎回スマホで撮影していてカメラが別で必要とは感じません。(体に取り付けるタイプのアクションカメラは役割が違うので別として。)

GoPro ウェアラブルカメラ HERO5 Session CHDHS-502-AP(役立ち度:★☆☆, 満足度:★★☆)

↓こういう動画が作りたくて買いました。

頭に装着できるアクセサリを GoPro と一緒に買うとまさにこのような動画が出来上がります。テニスをやるときは2時間やることが多いのですがバッテリーが到底持たない(1920x1080 60FPSで1時間くらい)のが玉に瑕ですね。あとは、やたらと熱を持つので今年の夏のような異常な暑さのときは使えません。(実際は使えなくはないけど故障リスクが怖い。)

これがなくてもスマホで撮影しているので問題ないというところで役立ち度を「★☆☆」にしましたが、あったほうが楽しい動画を作れるというのは確実に真でしょう。欠点は撮影者自身がどうやって打っているかは映っていないので確認のしようがないということです。(こればかりは仕方ない。)

検索してたどり着いた方も、このようなアイテムを使ってテニス部・テニスサークルの活動を盛り上げてみてはいかがでしょうか!?

2018/05/03(木)人生初のテニス公式戦の軌跡

2017年9月11日。生まれて此の方、初めてまともにラケットを握りました。自身で落下させたボールでさえもホームランしたのは記憶に古くありません。

テニスにハマった後は、2018年3月29日まで週2でテニススクールに通いました。ある程度はラリーが続くようになったと思えた後は、テニススクールを週1に減らして社外のテニスサークルに加入させてもらい、合計週2の練習を確保して続けてきました。

大会に出るには時期尚早かと思われましたが、経験値を貯めるのも重要かと思われたため、本日、5月3日、人生初のテニスの公式戦である区民大会(男子シングルス2部)に出場しました。

集合は午前11時でした。午前8時頃まで雨が降っていたため、中止ではなかろうかと思いました。念のために電話をして、「実施してます」との回答をもらい、いざ出発。

集合後から試合まではかなり待たされ、スポーツドリンクの残量が不安になるほどでした。1日に複数試合やる方もいるようで、2L入る水筒と簡単な食べ物を持参しておけばと少々後悔しました。スポーツドリンクは自販機でも売り切れになっていました。

結局、1時間半ほど他人の試合を見たあとに、我々の試合のプレイボール(野球の癖が)。フゥィッチでは「アップ」を宣言して的中! 風はそこそこありましたが、サーブで圧倒的に有利・不利が分かれるというほどの風ではなかったし、太陽のまぶしさも控えめで、人生初公式戦でいきなりサーブを打つのも自信がなかったため、「レシーブ」をもらいました。

相手からのサーブは中々に威力があって、打てないほどではありませんでしたが、手元で曲がるスライスの軌道にほとんど合わせることもできず、サービスエースの嵐。この時、初めて、「サーブや、ラリーが続いていたときのことばかり考えていて、リターンを安全に返すことをほとんど考えていなかったし、リターン練習が著しく不足していた」ことに気付かされました。

体が強張ってサーブも中々入らず、圧倒的絶望! ゲームカウント 0-4 まで来て、この状況を打破する何かはないかと考えるも、何もなく、せめて練習でやってきたことをやろうと思って、サーブのときにボールを見続けるというのを忘れていることに気づいて修正して、少しずつサーブが入るようになってきました。ゲームは奪えませんでしたが、相手のミスも誘って 30 - 40 くらいまで押せるようになってきました。リターンは1球だけまぐれで完璧なリターンエースを取りましたが、その後は続かず。最後のマッチポイントを取られた状態でのサーブも体が強張ってダブルフォルト。ゲームカウント 0 - 6 でジ・エンド。

初級・中級が分かれていないため、今の自身の実力で勝つのは困難を極めるとは分かっていましたが、中々の酷さで笑いそうになりました。良かったのは終盤、「サーブ時にボールを見続けていないことに気づいて修正できたこと」と、わずか1球ながら「完璧なリターンエースが取れた」ということ。あとはもうダメダメです。課題が紛う方なく「リターン」であると分かったのが最大の収穫でした。

この敗北は、また私のあすの出発にも、光を与えることでしょう。