As I Please

MTのいんすとーるの練習と、その他びぼうろく・・・

ビエラ panasonic のIPコントロール(DT5)とめざましじゃんけん

古いパナソニックビエラ(うちのはDT5)でリモコン操作(赤外線)を、IP経由で行う。 nature remo で赤外線飛ばすのは時に安定しないしプログラマブルにはほど遠い感じがするので、 IPでやれないかと。 手法は、
  1. upnp でIPアドレス、送信先を取得
  2. soapで投げつける。
という方向で。 参照、利用したのは、pyvieraというライブラリ。 古いので認証なしで使える。ただし、python2 用のようで、viera.py を改修。urlilb2を使っていたり、海外のリモコンエミューレトなのでいくつかのボタンが無い(NRC_DATA-ONOFF:dボタン、NRC_PROG-ONOFF:番組表、NRC_SPLIT-ONOFF:2画面?)ので、これらにちょっとだけ対処。ドイツのPanasonic TV mit IPS Steuernというものを参考に。dボタンのコードがなかなか見つからなかった。改修した viera.pyはこちら
import urllib.request,urllib.error, urllib.parse
class Viera(object):
    def __init__(self, hostname, control_url, service_type):
        self.hostname = hostname
        self.control_url = control_url
        self.service_type = service_type
        self.sendkey_action = Action('X_SendKey', ('X_KeyEvent',))
    def _sendkey(self, slug):
        req = self.sendkey_action.to_soap_request(
            self.control_url,
            self.hostname,
            self.service_type,
            (slug,),
        )
        urllib.request.urlopen(req).read()
    def __unicode__(self):
        return '' % (
            self.hostname,
            self.control_url,
            self.service_type,
        )
    def vol_up(self):
        self._sendkey('NRC_VOLUP-ONOFF')
    def vol_down(self):
        self._sendkey('NRC_VOLDOWN-ONOFF')
    def mute(self):
        self._sendkey('NRC_MUTE-ONOFF')
    def num(self, number):
        for digit in str(number):
            self._sendkey('NRC_D%s-ONOFF' % digit)
    def power(self):
        self._sendkey('NRC_TV-ONOFF')
    def toggle_3D(self):
        self._sendkey('NRC_3D-ONOFF')
    def toggle_SDCard(self):
        self._sendkey('NRC_SD_CARD-ONOFF')
    def red(self):
        self._sendkey('NRC_RED-ONOFF')
    def green(self):
        self._sendkey('NRC_GREEN-ONOFF')
    def yellow(self):
        self._sendkey('NRC_YELLOW-ONOFF')
    def blue(self):
        self._sendkey('NRC_BLUE-ONOFF')
    def vtools(self):
        self._sendkey('NRC_VTOOLS-ONOFF')
    def cancel(self):
        self._sendkey('NRC_CANCEL-ONOFF')
    def option(self):
        self._sendkey('NRC_SUBMENU-ONOFF')
    def Return(self):
        self.sendkey('NRC_RETURN-ONOFF')
    def enter(self):
        self._sendkey('NRC_ENTER-ONOFF')
    def right(self):
        self._sendkey('NRC_RIGHT-ONOFF')
    def left(self):
        self._sendkey('NRC_LEFT-ONOFF')
    def up(self):
        self._sendkey('NRC_UP-ONOFF')
    def down(self):
        self._sendkey('NRC_DOWN-ONOFF')
    def display(self):
        self._sendkey('NRC_DISP_MODE-ONOFF')
    def menu(self):
        self._sendkey('NRC_MENU-ONOFF')
    def connect(self):
        self._sendkey('NRC_INTERNET-ONOFF')
    def link(self):
        self._sendkey('NRC_VIERA_LINK-ONOFF')
    def guide(self):
        self._sendkey('NRC_EPG-ONOFF')
    def text(self):
        self._sendkey('NRC_TEXT-ONOFF')
    def subtitles(self):
        self._sendkey('NRC_STTL-ONOFF')
    def info(self):
        self._sendkey('NRC_INFO-ONOFF')
    def index(self):
        self._sendkey('NRC_INDEX-ONOFF')
    def hold(self):
        self._sendkey('NRC_HOLD-ONOFF')
    def d(self):
        self._sendkey('NRC_DATA-ONOFF')
    def prog(self):
        self._sendkey('NRC_PROG-ONOFF')
    def split(self):
        self._sendkey('NRC_SPLIT-ONOFF')
class Action(object):
    def __init__(self, name, arguments):
        self.name = name
        self.arguments = arguments
    def to_soap_request(self, url, hostname, service_type, values):
        assert len(values) == len(self.arguments)
        params = ''.join(['<%s>%s' % (arg, value, arg) for arg, value in zip(self.arguments, values)])
        soap_body = (
            ''
            ''
            ''
            ''
            '%(params)s'
            ''
            ''
        ''
        ) % {
            'method_name': self.name,
            'service_type': service_type,
            'params': params,
        }
        headers = {
            'Host': hostname,
            'Content-Length': len(soap_body),
            'Content-Type': 'text/xml',
            'SOAPAction': '"%s#%s"' % (service_type, self.name),
        }
        soap_body = soap_body.encode()
#        headers = urllib.parse.urlencode(headers).encode()
        req = urllib.request.Request(url, soap_body, headers)
        return req
テスト稼働で、フジテレビめざましじゃんけんを自動で毎日やらせてみた。
import socket
import urllib.request,urllib.error,urllib.parse
from urllib.request import urlopen
from viera import Viera
from pyviera import VieraFinder
import time
import random
tv = Viera('(IP_address)','http://(IP_address):55000/nrc/control_0','urn:panasonic-com:service:p00NetworkControl:1')
if __name__ == '__main__':
    tv.num(8)
    time.sleep(5)
    tv.info()
    for i in range(20):
        button = random.choice(('tv.blue()','tv.red()','tv.green()'))
        eval(button)
        time.sleep(3)
これを、月~金は 05:57,06:57,07:34,07:57に、土は 07:37,08:21 にcronで起動。 テレビがついていれば、IP経由でch8 に変更して、ランダムに青赤緑を投げつける。 半年以上動かしていて、一週間で最大300点オーバーの週もあった。 ちなみに、最近のvieraはアプリ最初のアクセス時に認証を求めるようで、そうするとこちらのライブラリが良さそう。 https://github.com/florianholzapfel/panasonic-viera/issues/9
https://github.com/florianholzapfel/panasonic-viera/blob/master/panasonic_viera/__init__.py PINコードを入力して、credential情報を取得し使い回す必要があるようだ。

theme の変更(2020/09) @Style Bootstrap Theme for Movable Type

google の検索結果などで、「ページがモバイル フレンドリーではありません。」と表示されている。MT5?時代の themeを使い続けていたためなので、ここらへんで、おそまきながら新しいものに変更。
といっても、MovableType 7のblog用でモバイル対応していて良さそうなものも一発では見つからなかったので、MT6用ということではあるけど、@Style Bootstrap Theme for Movable Typeを入れてみる。すでにサポートはされていないようだけど、まずは慣れということで。。。
一度テストブログを作成して、特に MT7でも問題ないようなのを確認して、themaの変更、google analyticsの移設、google adsense の再設定くらいでスタート。

cacti 1.2.x  インストール時の php モジュールの誤認識について

cacti1.2.14を新規にインストールし、$cacti/install/index.php で各種ライブラリ他がちゃんとインストールされているかを事前チェックしたが、どうしても phpのモジュールが 'cli-no' として認識されない現象が発生。 'cacti install cli no' あたりのキーワードで探してみると、いろんな人が引っかかっているようだ。 代表的なのはこれ?https://github.com/Cacti/cacti/issues/2348 cliなので、要は phpのpathが間違っているか、テスト時に起動している phpが正しくない(/usr/bin/php ? /usr/local/bin/php? etc...) ということが原因のようだが、いくら見直しても??? include/config.php に
$php_path = '/usr/local/bin/php';
を設定しているし、mysqlのDBの table:settings の 'path_php_binary' の内容を見てもおかしくない。 でもって、解決策は、嘘のようだが、mysqlの中のデータを(同じ値でもいいので)一度上書きすることだった。
mysql> update settings set value = '/usr/local/bin/php' where name = 'path_php_binary';
嘘のようなホントのような、このコマンド1つ流したあとで installチェックがちゃんと通った。 今となっては path_php_binary に何かゴミ文字が入っていたのかとも思うけど。。。 これ、今年で2回目。。。なんで、ちょっと備忘録的に書いておく。

Hue Bridge2 and Google Home

Hue bridge(丸形)にライトをぶらさげていたけど、Google Homeから音声コントロールしようとしたら、このブリッジではだめで bridge2(角形)アップデートしないいけないということで購入。
bridge2の配下にランプをもっていって、アプリからのコントロールはうまく行ったが、Google HomeアプリがこのHueをうまく認識してくれない。
Philips のサポートに連絡したら、いろいろと解決策を提案してくれ、レスポンスは非常に良かった。
ただ、確認依頼内容については

  1. LEDは3つとも点灯している?
    もちろん
  2. アプリで自宅外リモート接続を有効にして。Hueのアカウント名とパスワードでログインして
    特に問題無くできる
  3. GoogleHomeで一度Hueとの接続を解除してから接続しなおしてみて

    https://support.google.com/chromecast/answer/7073578?hl=ja
    デバイスと Google Home の接続を解除する
    Google Home アプリ Google Home アプリを開きます。
    ホーム画面の左上にある(+) をタップします。
    [デバイスのセットアップ]をタップして、[セットアップ済みデバイスのリンク]をタップします。
    [Philips Hue]が表示される場合はタップしてアカウントのリンクを解除してください。

    セットアップ済みとしては出てこない。
  4. もう一度デバイスのセットアップよりHueを追加してみてください。
    新規に登録してみるが、一度リンクした後にエラーとなる。
と。エラー画面を送付したら、次の指示は、
  1. 以前お使いのV1ブリッジがHueアカウントにリンクされていないか以下をご確認ください。
  2. 以下のリンクへHueアカウントでログインしてください。https://account.meethue.com/
    見たけれど、新しいv2が出てくる。
  3. [ブリッジ]タブにすでにリンク済みのブリッジがある場合は[リンクの解除]でリンク解除します。
  4. 自宅外リモート接続を一度、無効にしてから有効にします。
  5. もう一度、グーグルホームアプリよりHueとの連携をお試しください。
    やっぱり同じ、リンクはするけれどエラーと表示されて連携しない。
次の指示はちょっと意味不明な、、、
  1. Hueブリッジのリンクは新しいブリッジとできておりますが、
    IPアドレスが192.168.x.yになっている必要があります。
    試しにルータ設定でDHCPでの割り当てIPアドレスを
    192.168.から始まるものにしてみるとどうなりますでしょうか。
えっ?それ?という返答。
うちはプライベートアドレスには、10.xのA-Classを複数使っているので、それを変えるのは難しいが、スモール環境を作って試してみた。が、こんな理由で急に動くはずも無く。。。

次の指示は、
    Hueの自宅外リモート接続は問題ないようですので、
    Google側の問題の可能性があります。
    既にお問合せ済みの場合は申し訳ございませんが、
    Googleサポートに一度お尋ねいただけますでしょうか。
    Google側には問題がないと回答が来ましたら、
    以下をお試しください。
  1. GoogleHomeアプリおよびHueアプリが最新であることをご確認ください。再インストールしてあれば最新です。
  2. テスト用にもう一つGoogleアカウントとHueアカウントを作成してそちらでテストしてみてください。
  3. 改善しない場合はHueブリッジの初期化をお試しください。
    ブリッジの電源を入れたまま、背面にある「Restore Factory Setting」のリセット・ホールを、
    ピン状のものでブリッジ正面のLEDが点滅するまで長押しします。
     ※本操作を行うと、ブリッジ及びhue純正アプリに設定・記録されている全ての項目が消去されます。
    お手数ですが、再度設定を行ってください。
  4. Googleホームの初期化をお試しください。詳細はGoogleのサポートにお尋ねください。
  5. 上記にても改善しない場合は問題の切り分けのために引取点検を実施することが可能です。
    弊社のサポートセンターにHueブリッジを送付いただき、検査を行います。
    ご希望の場合はその旨をお申しつけください。
ということでハードウェア故障の可能性も含めた対応の示唆だった。
アプリの再インストールは Google Home,Hue アプリともに行い、初期化もどちらも行ってみたけどうまくいかなかった。
アカウント別にしてテストというのもなかなか面倒だし、ということで探したらアプリ内ではどうしてもコントロールできない、Google側の設定で Hueの接続を切らないと行けないようだ。
具体的には、Googleアカウントに webでログイン(PC、スマホどちらでもOK)して、セキュリティ>リンクされたアカウント に、連携したアプリ一覧で出てくる。またはこのリンク。ここに出てきた Hueを一度削除し、Google Homeアプリから再度デバイスの登録を行うとOKになった。Google Home,Google アシスタントアプリの中ではダメで、一度ブラウザで別起動に飛ばないと設定出来ないよう。。。1週間くらいはまった。。。

nginx on FreeBSD12

普通に ports (/usr/ports/www/nginx/ )でインストールしようとしたら エラーが。
https://github.com/slact/nchan/issues/506にあるのほぼ一緒。 redis関連のところで sockaddr のエラーが。

ほぼ指示にあるように

cd /usr/ports/www/nginx
make patch
cd work
git clone https://github.com/slact/nchan.git
cd ..
ここで Makefileに
CONFIGURE_ARGS+= add-dynamic-module=/usr/ports/www/nginx/work/nchan
を追加。すでに CONFIGURE_ARGS+= の項目はあるので最後に
--add-dynamic-module=/usr/ports/www/nginx/work/nchan
を追加。
あとは make でとりあえずエラーは出ずにコンパイルできた。

cmake on FreeBSD9

やっぱり いまどき gccだけじゃなく、clang, llvm あたりを入れておきたいということで、sourceをもってきてみたら、ほぼほぼ cmakeを要求される。
昔に入れたcmakeは ver3.5.2 で古すぎる。
最新のもの(3.18.0)を持ってきて bootstrapをかけると dup3,accept4,pipe2 あたりが必要で、これは FreeBSD10以降じゃないと入っていない。
ということで FreeBSD9で使えるcmakeを探してみると、、、1つ前の 3.17.3で FreeBSDのバージョンを見て、dup3,pipe2とかを利用したりしなかったり。3.18.0だと問答無用に使っている。ということで、まずは
dup3とかが入っていない /usr/lib/libc.so (/lib/libc.so7へのシンボリックリンク)を利用してcmake(3.17.3)を作成する。
sourceを持ってきて、
CC=/usr/local/bin/gcc ./bootstrap
でコンパイルしてみると、
/usr/lib/libstdc++.so.6: version GLIBCXX_3.4.14 required by /usr/local/src/cmake-3.17.3/Bootstrap.cmk/cmake not found

次は

CC=/usr/local/bin/gcc CPP="-std=c++17" LD_LIBRARY_PATH=/usr/local/lib CXX="/usr/local/bin/g++"
で行ったが、
/usr/local/src/cmake-3.17.3/Source/cmFileCommand.cxx: メンバ関数 ‘bool \xe7\x84\xa1\xe5\x90\x8d}::cURLProgressHelper::UpdatePercentage(double, double, std::__cxx11::string&)’ 内:
/usr/local/src/cmake-3.17.3/Source/cmFileCommand.cxx:1445:38: エラー: ‘lround’ is not a member of ‘std’
       this->CurrentPercentage = std::lround(value / total * 100.0);
で失敗する。 std::lround が無いバージョンを探すと、https://gitlab.kitware.com/cmake/cmake/-/blob/v3.13.4/Source/cmFileCommand.cxx
のようで、3.13.4 を持ってきてやり直してみる。
CC="/usr/local/bin/gcc" CXX="/usr/local/bin/g++" ./bootstrap
CC="/usr/local/bin/gcc" CXX="/usr/local/bin/g++" gmake
CC="/usr/local/bin/gcc" CXX="/usr/local/bin/g++" gmake test
CC="/usr/local/bin/gcc" CXX="/usr/local/bin/g++" gmake install
test でいくらか失敗するけど、まぁそのくらいなら、、、で入れてしまう。
/usr/lib/libstdc++.so.6 が、、、と言われるので、バックアップとって/usr/local/lib/にsymlink をはってしまう。

clamav-0.102 までの道のり onf FreeBSD9

まず、/usr/local/bin/gcc(gcc48) を使って、gcc-5.5.0 をインストール。 次に、coreutil-8.32 をインストール。 isl (http://isl.gforge.inria.fr/isl-0.22.tar.gz) をインストールしようとしたが、
to_string’ is not a member of ‘std’ 
のエラーが出るのであきらめる。/usr/ports/を見ると、0.19を使っているようなので、0.19を入れるとこれはちゃんとエラーなしに入った。 次に gcc-6.5.0 、これはエラーなしに 入った。configure & make & make install bintuil を installしようとしたら、これもエラー。
dwarf2/index-write.c:779:32: エラー: ‘log2’ is not a member of ‘std’
       (std::pow (2, std::ceil (std::log2 (name_count * 4 / 3))));
gcc-7.5.0 のインストール。これは問題ない。 ./configure & gmake & gmake install gcc-8.4.0 のインストール。これはエラー。
In file included from /usr/include/machine/pcb.h:44,
                 from /usr/include/sys/user.h:38,
                 from ./md-unwind-support.h:34,
                 from ../../.././libgcc/unwind-dw2.c:411:
/usr/include/machine/segments.h:184:16: エラー: ‘rd_base’ の幅がそのサイズを超えています
  unsigned long rd_base:64 __packed; /* base address  */
std 関連のエラーはちょっと後で考えるとして、それ以外でバージョンを上げられるものをあげていく。 libxml-2.9.9 をインストール。これも configure & gmake & gmake install でいけた。 ここで clamav-0.102.4 をインストール。これも configure --enable-milter & gmake & gmake install でOK。既存の設定ファイルもそういじることなく起動できた。(clamav-clamd,clamav-milter,clamav-freshclam)

certbot on FreeBSD9

なかなかやめられない古いOSで、次は証明書(let's encrypt) を使い続けたくて。。。 運用には certbot を使うのがデフォルトのようで、ports が使えないことを前提にすれば、git clone で持ってくるのがベスト。 ということで、

git clone https://github.com/certbot/certbot

を行ったら、

SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

ということで、gitが tls1.2をしゃべらない!のが問題(古い git clientすぎた)ので、まずはこれをバージョンアップしてみた。ところが、、、直らない。。。見ると gitは裏では curl を使っているようなので、これが tls1.2を使うようにしないといけなかった。ということで、curlも最新版を持ってきて openssl も tls1.2 を使えるバージョンを参照してinstall. でも、今度は git-remote-https.core を吐いて何もすすまない。shared ライブラリ参照が違うとかそこらへんだろうから、ということで、libzも入れ直してみたがやはりおかしい。。。 コンパイラ環境の問題かもと疑ってみると、そこらへんだったみたい。 curl -> /usr/bin/gcc 利用 git -> /usr/bin/gcc 利用は coreを吐く。 ということで環境変数 CC=/usr/local/bin/gcc を設定しコンパイルしなした gitだとちゃんと cloneできた。 libz,libiconv,libintl,libchasetあたりも/usr/local/lib 側をちゃんとリンクしてくれた。 いまどきllvm,clangなんでしょうが、、、、、もうちょい生きながらえさせて。 git cloneでファイルをダウンロードできたが、次にhttps://certbot.eff.org/docs/contributing.htmlを参照して、

python3 tools/venv3.py

なのだが、ここでどうも yaml(pyyaml)のところでエラー。これも gccを利用しているが/usr/bin/gcc を見ているケースと/usr/local/bin/gcc を見るケースがあるのが問題のよう。 .cshrc で /usr/local/bin を優先させることで /usr/local/bin/gcc を先に見るようにしたところ、まずはここはクリア。 bash で
source venv3/bin/activate
run_acme_server &
certbot_test certonly --standalone -d test.example.com
と実行してまずはローカルで動くかどうかを試すのだが、run_acme_server のところで落ちる。うまく webserver が起き上がってくれない。
[venv3] root@host:/usr/local/src/certbot # run_acme_server
=> Starting pebble instance deployment...
ELF binary type "0" not known.
=> Tear down the test infrastructure...
=> Test infrastructure stopped and cleaned up.
Traceback (most recent call last):
  File "/usr/local/src/certbot/venv3/bin/run_acme_server", line 11, in 
    load_entry_point('certbot-ci', 'console_scripts', 'run_acme_server')()
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 221, in main
    with acme_server as acme_xdist:
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 96, in __enter__
    self.start()
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 62, in start
    raise e
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 57, in start
    self._prepare_pebble_server()
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 135, in _prepare_pebble_server
    self._launch_process(
  File "/usr/local/src/certbot/certbot-ci/certbot_integration_tests/utils/acme_server.py", line 205, in _launch_process
    process = subprocess.Popen(command, stdout=stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env)
  File "/usr/local/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: '/usr/local/src/certbot/certbot-ci/certbot_integration_tests/assets/pebble_v2.3.0_linux-amd64'
なんか、certbot が linuxの実行ファイル(linux binary for amd64)を抱えていてこれが freebsdでは動かない、ということのようだ。linux-compat とか入れればいいのかもしれないがそこまでやるかな。。。ということでこの線はあきらめて、、、 certbot は普通に python(2or3)のコードだったことを思い出して、$src/certbot/の中を見ると、setup.pyがあるので、
python3 setup.py build
python3 setup.py install
で、/usr/local/bin/certbot にインストールされた。
certbot certonly --standalone -d test.example.com
でちゃんと証明書が降りてきた。