【ミニPC】CHUWIのLarkBox Proを購入

手のひらPC、CHUWIのLarkBox Proを買いました。
https://www.amazon.co.jp/gp/product/B08M655CFF?ie=UTF8&psc=1&linkCode=ll1&tag=engetu-22&linkId=459746322f6c5a22d26b0c70629dae52&language=ja_JP&ref_=as_li_ss_tlwww.amazon.co.jp
 
もはや手持ちのsoundcore mini 3(Bluetoothスピーカー)より小さいけど、性能としては十分。
16000円なので使い潰してもあまり痛くはない。
最近は低電力の日常用と高電力の高速処理(ゲーム等)用でPCを分ける運用をしているけど、
高速処理については、以下で紹介してる自作PCを使ってる。
engetu21.hatenablog.com
 
日常用に関しては、OneMix2をこれまで使ってた。
pc.watch.impress.co.jp
が、バッテリーがパンパンに膨れてやばそうなので取り外したり、勝手にzキーが押され続けたり(これはディスプレイを裏返してタブレットモードにすることで解決(解決してない))、YouTube等の動画再生を走らせるとたまに熱暴走?でフリーズして戻ってこない等、とても日常用として使用できないので引退してもらうことにした。
 
LarkBox ProのスペックはAmazonで書いてある通りなので、特筆すべきことはないけど、この記事を書くにも支障はでてないし、同時に裏で動画を流すのも何ら問題ない。メモリ容量は厳しめだけど、まぁゲームとかしない限りは全く普通に使える。Officeは持っていないのでそちらでの使い勝手は不明。
ちなみに当たりはずれがあるのか、Windows11にできないといった書き込みを見るが、私が買ったものに関しては普通にWindowsUpdateにてWindows11のアップグレード案内がでた。枯れてなさそうなのでする気はないけど。
 
HTML5 ベンチマークで計ってみた。
s3-ap-northeast-1.amazonaws.com

比較対象は特に設けてないけど、これを見て納得できる人であれば購入を考えてみてもよいのでは。

【Ubuntu22.04】激安USB無線LANドングル(RTL88x2bu)のドライバインストール

AKEIEというメーカの1200MbpsのUSB無線LANドングルをAmazonで買いました。お値段1500円。
www.amazon.co.jp

よくあるコピー品なので、まぁ似たような製品の中で一番安いのをチョイス。

Ubuntu22.04を入れたLIVA Zに挿してみたところ、GUI上では認識されていなさそう。
では、ということでip address showを打ってみても表示はされない。
 
USBデバイスとしてそもそも認識しているかを確認。

$ lsusb
Bus 001 Device 010: ID 0bda:b812 Realtek Semiconductor Corp. RTL88x2bu [AC1200 Techkey]

認識はしているようなので、その点で問題はなさそう。
おそらくドライバがないんだろうと踏んで、出力された「RTL88x2bu」で検索をかけてみる。
ドライバが提供されていたので、そちらを利用します(なお、RTL88x2buはチップセット名らしい)。
GitHub - RinCat/RTL88x2BU-Linux-Driver: Realtek RTL88x2BU WiFi USB Driver for Linux
今回はgitコマンドで取得。

$ git clone https://github.com/RinCat/RTL88x2BU-Linux-Driver.git
Cloning into 'RTL88x2BU-Linux-Driver'...
remote: Enumerating objects: 2712, done.
remote: Counting objects: 100% (242/242), done.
remote: Compressing objects: 100% (62/62), done.
remote: Total 2712 (delta 216), reused 187 (delta 180), pack-reused 2470
Receiving objects: 100% (2712/2712), 8.28 MiB | 1.09 MiB/s, done.
Resolving deltas: 100% (1939/1939), done.

 
ダウンロードしたディレクトリに移動し、makeを実行。

$ cd RTL88x2BU-Linux-Driver/
$ make

gccが入っていない場合はsudo apt install gccで入れるべし(1敗)

なにやらちょいちょいwarningがでているけど、とりあえず終わるまで放置。

完了したらインストール。そして再起動。

$ sudo make install
install -p -m 644 88x2bu.ko /lib/modules/5.15.0-47-generic/kernel/drivers/net/wireless/
/sbin/depmod -a 5.15.0-47-generic

$ sudo shutdown -r now

GUI上もip addressコマンドでも表示されたことを確認。本体のLEDも点灯してくれるようになります。
ちなみにWindowsなら挿すだけで認識します。ここらへんは流石というべきか。
 
追記。
Ubuntu22.04の仕様なのかLIVA Zに問題があるのか、内臓のWiFiと今回のドングルでインタフェースとしては2つ備えることになるが、どうもGUI上で片方をOFFにしようとすると、WiFiという機能そのものをOFFにするらしく、どちらかを稼働させておくことができないらしい。
この場合は、以下のコマンドでデバイスを直接指定してOFFにするといい。

$ ip l
でデバイス名を確認し、

$ ip link set デバイス名 down
でリンクダウン。

$ ip link set デバイス名 up
でリンクアップに戻せる。

なお、一時的にZorin OSを入れてみたところ、片方のみOFFにはできたので、おそらくUbuntu22.04の仕様かバグの模様。
 
さらに追記。
調べてるうちに「nmtui」というコマンドに辿り着いたけど、どうやらこれを叩くとGUIっぽくWiFiネットワークの選択やIPアドレスの設定をすることができるらしい。
UbuntuServerのようなCUIオンリーの場合は便利そう。
※コマンドが無いと言われる場合は、sudo apt install -y network-managerで導入可能。
ただし、ラズパイなどは、dhcpcdを使っているため、設定がバッティングして途中でネットワークが落ちる(のかはわからないが、SSHは切れてしまう)事象が発生したため、その場合はdhcpcdを落とす必要がある。その場合は以下のサイトが参考になる。
signal-flag-z.blogspot.com

Oracle→PostgreSQLマイグレーション時の「型」について/Ora2Pgについて

Oracleにあるテーブルと同様のものをPostgreSQLで作成する場合、
型については大体以下の様に変換すれば、CREATEを作るときに困ることがなく、
OracleデータをCSVで落とし、そのままPostgreSQLに登録した時もエラーにならない(基本的には)。

1.主な変換表

・NUMBER(4, 0):整数
→整数の場合は9桁までならinteger
→10桁以上はbigint
 
・NUMBER(4, 2):小数点あり
→numeric(4, 2)
 
・VARCHAR2(24):可変長文字列
→varchar(24)
→あるいはcharacter varying(24)
 
・DATE:日付
→timestamp
 
・条件分岐
DECODE(列名, 条件1, 結果1, 条件2, 結果2, 結果3)

CASE 列名
WHEN 条件1THEN 結果1
WHEN 条件2THEN 結果2
ELSE 結果3 END
 

2.Ora2Pgについて

・OracleDB用のDDLDMLファイルがあるなら「Ora2Pg」を使うのも手。
一応、インストール方法と実施方法を記載。(下記はWindows10でのインストール)
■ora2pgをDL
https://github.com/darold/ora2pg
[↓Code]からDownload ZIPを選択して落とす。
 
■Strawberry PerlのDL
https://strawberryperl.com/releases.html
Portableの64bitを落とす。
 
■Strawberry Perlを解凍
解凍後、コマンドプロンプトでportableshell.batを実行(管理者権限は不要)
 

>portableshell.bat
(略)
Perl executable: C:\Users\hondxuser01\Downloads\strawberry-perl-5.32.1.1-64bit-portable\perl\bin\perl.exe
Perl version : 5.32.1 / MSWin32-x64-multi-thread

 
環境変数にPATHを通す
C:\strawberry-perl-5.32.1.1-64bit-portable\perl\bin

※一旦再起動

■ora2pgを解凍
ora2pgのフォルダ配下で以下のコマンドを実行

>perl Makefile.PL
(略)
Now type: dmake && dmake install

 
■Makeの実行
上記の通り、dmake && dmake installを実行すると怒られる。

>dmake && dmake install
#############################################################
### ###
### DMAKE WARNING ###
### ###
### Do not use dmake.exe utility as it is no longer ###
### part of Strawberry Perl, use gmake.exe instead! ###
### ###
### If you have troubles with CPAN client delete: ###
### %USERPROFILE%\AppData\Local\.cpan\CPAN\MyConfig.pm ###
### ###
#############################################################

※dmake.exeユーティリティはStrawberryPerlの一部ではなくなったため、使用しないでください。代わりにgmake.exeを使用してください。
とのこと。
 
助言に従って、gmakeを使用する。

>gmake && gmake install

Cドライブ直下にora2pgフォルダが作成される。
 
■ora2pgコマンド実行
とりあえず、コマンドが動くことを確認。

>ora2pg
FATAL: can't find configuration file C:\ora2pg\ora2pg.conf

Usage: ora2pg [-dhpqv --estimate_cost --dump_as_html] [--option value]

-a | --allow str : Comma separated list of objects to allow from export.
Can be used with SHOW_COLUMN too.

 
※PCを再起動すると環境変数が読み込まれず、コマンドが打てない場合
その場合はしょうがないので、DLしたフォルダのora2pgを直接叩くことでも実行可能
C:\DataDirectory\04:soft\ora2pg-21.1\blib\script\ora2pg

■OracleSQL→ポスグレSQL変換コマンド

> ora2pg -c ora2pg_dist.conf -i aaaaaaaaaaa.sql -o aaaaaaaaaaa_pg.sql -t QUERY

 
「-c」でコンフィグファイルを指定する必要がある。
基本的にはora2pg配下にあるconfファイルを指定する。
 
_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 
あまり関係ないけど、ポスグレではCREATEするときはテーブル名もカラム名も全て小文字がよい。
例えば、社員テーブルをEmployeeという名前で登録した場合、
SELECTのFROMで「EMPLOYEE」や「Employee」で実行すると、すべて小文字にてSQLが発行されるため、
そんなテーブルはない、と判断されてエラーが返ってくる。
一応、""(ダブルクォーテーション)でテーブル名を囲うことで解決は可能だが、
いちいちSELECTで設定するのはきついので、基本的には小文字で全て管理していくほうが混乱が発生しない。
参考:https://ringtreelab.hateblo.jp/entry/2021/10/08/214007

【Tableau】式のメモ

業務でTableau(Desktop/Server)を弄るようになったのでメモ。
式はDesktopとServerの両方で使えるはずだけど、一部の関数は片方にしか用意されていないのとかあるので、その場合は代替を利用する必要があるかも。
 
■年月日(2022-01-01)を示すカラムから202201(年月で6文字)の形で文字列として別項目で定義する場合
LEFT(str([year_month_day]),4) + SPLIT(str([year_month_day]),"-",2)
・LEFTで対象の項目の先頭から4文字取る(2022(年)の部分)
・SPLITで、-(ハイフン)を区切り文字として、2句目の2文字を抽出
・それぞれの文字列として足す。
 
■202201等の6桁の文字列を日付として定義する場合
※カラム「Ym」に202201(仮)が入っている場合
DATE(DATEPARSE('yyyyMM',[Ym]))
 
■データとして値が入っていない(空、またはNULLだった)際に0埋めで表現したい場合
ZN(LOOKUP(SUM([kingaku]),0))
参考:https://note.com/rika_olga_f/n/n2e8e0454d4ec
 
■会計年度の算出方法
DATEADD('month', -12, [年月])
 
ただし、そもそもの会計年度の始めの月(大体4月)をディメンションで設定するのはTableauDesktopでしかできないようで、TableauServerでの実現に言及したサイトは皆無でした。
参考:https://community.tableau.com/s/question/0D54T00000G54goSAB/%E5%B9%B4%E5%BA%A6%E3%81%AE%E9%96%8B%E5%A7%8B%E6%9C%88

【Python3】psycopg2でtimestamp型のデータを登録する場合

psycopg2を利用して、アップデートを実行する際に、更新日時カラム(timestamp型)に現在日時を入れる場合は以下のようにする。

import psycopg2
import datetime

POS_DBNAME = "postgres"
POS_HOST = "localhost"
POS_USER = "postgres"
POS_PASS = "postgres"

# 現在の日付を取得
dt = datetime.datetime.now()

# UPDATE文定義
update_str = f"""
update table_a set
name = 'hoge'
, update_datettime = '{dt}'
where
id = 1
"""

# ポスグレ接続
pos_conn = psycopg2.connect(f"dbname={POS_DBNAME} host={POS_HOST} user={POS_USER} password={POS_PASS}")
pos_cursor = pos_conn.cursor()

# update文実行
pos_cursor.execute(update_str)
result = pos_cursor.statusmessage.split()

# 明示的なコミットと接断
pos_conn.commit()
pos_cursor.close()
pos_conn.close()


アップデートの結果は配列で取得できる。配列0がDML、配列1が件数を表す。printすると以下の通り。
print(result)

  • >['Update', '1']

なので、画面やログに残すには1の方を利用すればよし。
print(f"更新件数は{result[1]}だよ")

  • >更新件数は1件だよ

なお、変数dtを出力すると以下の通り。

print(dt)
datetime.datetime(2022, 6, 1, 17, 10, 13, 447320)

【Python3】文字列で管理されている年月(YYYYMM)から昨月を算出する例

import datetime
from dateutil.relativedelta import relativedelta

MONTH = "202206"
LAST_MONTH = (datetime.datetime.strptime(MONTH,'%Y%m') + relativedelta(months=-1)).strftime("%Y%m")

■ポイント
・datetime.datetime.strptime(MONTH,'%Y%m') で第一引数の変数を対象に文字列→日付に変換。
 第二引数はフォーマットを示す。
 %YはYYYYで西暦4桁を示す。西暦2桁にしたい場合は%yとする。
 %mはMMで月2桁を示す。
「datetime.datetime.strptime(MONTH,'%Y%m')」単体で実行すると、
datetime.datetime(2022, 6, 1, 0, 0)
 という形の日付データとなる。

・relativedelta(months=-1)で対象日付から-1ヶ月を引いた月を算出。
printをすれば、datetime.datetime(2022, 5, 1, 0, 0)の形で出力される

・strftime("%Y%m")で-1ヶ月した日付を文字列に変換する。
 この場合は、YYYYMMの形になるが、事前に1ヶ月引いた値を用いるため、結果としてLAST_MONTHの値は以下のようになる。

print(LAST_MONTH)
'202205'

なお、今月を算出する場合はrelativedelta(months=0)を設定(この例を用いる場合には意味がない)
来月を算出する場合はrelativedelta(months=1)を設定する。

【Alexa】Alexaのスキルを作って自宅照明を点ける

角度を変えるサーボモータにirMagician(赤外線モジュール)をつけ、それをラズパイに接続します。
で、Alexaから自宅のラズパイ上に用意したBottle(HTTPサーバ)にHTTPを飛ばし、それをトリガにirMagicianとサーボモータを動かすことで、自宅照明のON/OFFをAlexa経由でやっちゃおう、というのが今回の趣旨です。
 
なのでAlexaスキルを作ります。
過去に調べた感じでは、IFTTTのWebhookと連携させないと実現できないような記事ばっかりだったので、面倒だな…と思ってましたが、どうやらAlexaスキルはPython(lambda)で作れるらしいと知ったので、今回はそれでやっています。
今回は自作スキルをベータテスト扱いで使うことになるので、使用期限は3ヶ月です。
スキルは基本的に全ユーザに公開する形になるので、特定のユーザに提供したいといった場合は、ベータテストで提供するか、Alexa for Business?を利用しなければいけない模様。
3ヶ月後に何をすればまた有効化できるのか(スキルを作り直す必要があるのか)はまた確認します。
追記:スキルを作り直す必要はないようですが、ベータテスト設定を再度実施する必要があるようです。
 
irMagicianとサーボモータの操作については以下のとこらへんで書いているため、そちらを参考にどうぞ。
一応、一番最後にBottleで動くソースとサーボモータ+irMagicianのソースを書いときます。
engetu21.hatenablog.com
 
engetu21.hatenablog.com

自宅サーバへのHTTPの引き込みは、ルータでポートを開けるか、以下のSSHポートフォワーディングで実現する必要があります。
engetu21.hatenablog.com



1.スキル作成

Alexaの開発者ポータルサイトにアクセス。
developer.amazon.com


左上のAlexaを押下。
ログインは自分が持っているAmazonアカウントを使用します。


左上の「スキル開発」→「開発者コンソール」を押下。


開発者登録をしていないとここで入力が必要になるようです。
サクッと情報を入れて、スキル開発に進みます。
 

左側の「Alexa Skills Kit」を押下します。
 

「スキルの作成」を押下することでスキル作成が始まります。
 

スキル名を設定。「アレクサ、○○」の○○部分にもなるので、
呼びたい名称を設定します。
 

モデルはデフォルトのカスタム。
 

バッグエンドリソースのホスティングPythonを選択。
すべて選択したら右上の「スキルを作成」を押下。
 

テンプレートはデフォルトのスクラッチで作成のままで「テンプレートで続ける」を押下。
 

2.ソースの変更

コードエディタタブを押下し、「lambda_function.py」のソースを変更します。

import requests
url = 'http://XXXXXXXXXXXXXX'

class LaunchRequestHandler(AbstractRequestHandler):
    """Handler for Skill Launch."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool

        return ask_utils.is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        # speak_output = "Welcome, you can say Hello or Help. Which would you like to try?"

        response = requests.get(url)

        return (
            handler_input.response_builder
                #.speak(speak_output)
                .speak(response.text)
                #.ask(speak_output)
                .response
        )

・変更点
1.import requests を追加
2.url = ''でHTTPを飛ばしたいURLを変数に設定
3.speak_output変数の定義部分をコメントアウト
4.response = requests.get(url) を追加
5..speak(speak_output) をコメントアウト
6..speak(response.text) を追加
7..ask(speak_output) をコメントアウト
どうやら「.speak」に設定した文言をAlexaはしゃべってくれるようなので、
ここにHTTPレスポンスでもらったメッセージを指定することで、それをしゃべらせるようにします。
 
変更が完了したところで、右上の「デプロイ」を押下。
 

3.(ベータテストとして)開発スキルの公開

公開タブを押し、公開用の設定を行っていきます。

誰にも公開しない、自分だけのスキルになるため、正直内容は適当でもいいです。
以下項目をそれぞれ埋めます。
公開名、説明、詳細な説明、サンプルフレーズ、小さなスキルアイコン、大きなスキルアイコン、カテゴリー
 

上記を埋めると、プライバシーとコンプライアンスの設定画面に飛ぶため、これも※印の部分をすべて回答します。
基本的にすべて「いいえ」で問題なし。
 

これまでの設定に問題なければ、ベータテスト欄にて、Eメールの設定ができます。
ここで、管理者用メールアドレスとベータテスター向けのメールアドレスを設定します。
自分だけで使う場合は、一緒のメールアドレスでOK。
設定後に「ベータテスト有効化」のボタンを押下。
有効になると同時にテスターメールアドレスにメールが飛ぶため、そちらを確認します。
飛んできたメールの
JP customers: To get started, follow this link:
の文言の下にあるURLを押すことで、Alexa設定画面に飛びます。
※リンクは2つありますが、必ずJP customers: To get started, follow this link:の方を押下すること
 

上記のようなメッセージが出てくるはずなので、「スキルテスト」を押下。
 

「有効にする」を押下し、利用が可能となります。
 
なお、スキルが実際にAlexaで使えるようになるには、若干時間がかかる(数分~数十分?)ので、気長に待ちましょう。
 

4.Bottleで動くHTTPサーバのソースとirMagician+サーボモータのソース

書いておかないと自分が困りそうな気がしてきたので記載しておきます。
以下、Bottleで動作するHTTPサーバのソース。

from bottle import route, run, template
import subprocess

@route('/youshitu_on')
def youshitu_on():
    subprocess.call("/home/pi/kadensousa/shells/youshitu_light_on.sh", shell=True)
    response = f'洋室の照明をつけました'
    return response

@route('/youshitu_off')
def youshitu_off():
    subprocess.call("/home/pi/kadensousa/shells/youshitu_light_off.sh", shell=True)
    response = f'洋室の照明を消しました'
    return response

@route('/washitu_on')
def washitu_on():
    subprocess.call("/home/pi/kadensousa/shells/washitu_light_on.sh", shell=True)
    response = f'和室の照明をつけました'
    return response

@route('/washitu_off')
def washitu_off():
    subprocess.call("/home/pi/kadensousa/shells/washitu_light_off.sh", shell=True)
    response = f'和室の照明を消しました'
    return response

run(host='0.0.0.0', port=50001)

 
上記で作ったPython自動起動させるために、以下のようにShellファイルを作成します。

$ vi /home/pi/site/start_syomei.sh
#!/bin/bash

nohup python3 /home/pi/site/syomei.py &

exit 0


systemdで動かす設定ファイルを作成します。

$ sudo vi /lib/systemd/system/start_syomei.service

[Unit]
Description=python program
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/home/pi/site/start_syomei.sh
Restart=no
User=pi

[Install]
WantedBy=multi-user.target

 
以下のコマンドで自動化。
$ sudo systemctl enable start_syomei.service
スタートは以下。
$ sudo systemctl enable start_syomei.service
 

以下はPythonで作ったHTTPサーバから呼び出されるShellの中身。
このプログラムでサーボモータが動き、赤外線が発信されます。

#!/bin/bash

echo 0=50 > /dev/servoblaster

python /home/pi/kadensousa/irmcli/irmcli.py -p -f /home/pi/kadensousa/irmcli/light_on.json

sleep 1

echo 0=70 > /dev/servoblaster

何でPythonとShellでごっちゃになってんの?って話ですが、最初にそういう風に作った(作ってしまった)ため、
いまさら全部Pythonで統一も面倒だなぁ。とか、そういう理由というだけです。
基本的にPython内でsubprocessで書けばShellで用意する必要はないはずです。