TTGO T-Watch用開発環境の作り方2020年3月版

最初に入手したときと作成手法が変わっていたのでメモ書き

(1) Arduino IDEをインストール

Windowsの場合、Microsoft StoreからArduino IDEをインストールする。

(2)githubのTTGO_TWatch_LibraryをArduino IDEに組み込む

githubの https://github.com/Xinyuan-LilyGO/TTGO_TWatch_Library にて「Download ZIP」を行い、T-Wach用ライブラリzipをダウンロード。

次にArduino IDEを起動して、「スケッチ」-「ライブラリをインクルード」-[.ZIP形式のライブラリをインストール」を選択し、ダウンロードしたT-Watch用ライブラリzipを読み込む。

この結果、「スケッチ」-「ライブラリをインクルード」を開くと下の方にある「提供されたライブラリ」の下に「TTGO T-Watch」が追加される。

(3)Ardbuino IDEのボードマネージャにESP32を追加

Installation instructions using Arduino IDE Boards Manager」に書いてあるとおりだけど、「ファイル」-「環境設定」を開き、「追加のボードマネージャのURL」に「 https://dl.espressif.com/dl/package_esp32_index.json 」を追加します。

なお、既にURLが書かれている場合は「,」で区切ることで複数のURLを記述できます。

追加した後は「ツール」-「ボード」-「ボードマネージャ」を選択し、検索欄に「esp32」と入力すると、「esp32 by Espressif SYstems」というのが登場しますので、それをインストールします。

(4) ボードでTTGO T-Watchを選択する

「ツール」-「ボード」から「TTGO T-Watch」を選択する。

Windowsのシリアルポートの番号確認バッチファイル

WindowsでUSBシリアルを繋いだ場合、そのCOM番号が何になったのかを確認するにはデバイスマネージャーの表示で確認する必要がある。

まぁ、いちいち面倒なので、ポートが認識されるとポップアップ表示をしてくれる「PortPop」とか、GUIで一覧を表示する「ViewComPorts」があったりする。

で、ViewComPortsを試してみようと思ったら、こちらはコンパイル済みバイナリが無い・・・ソースを見てみるとWMIから情報を引っ張っているっぽい。

ということはPowerShellで実装できるのでは?

と試してみたところ成功

バッチファイルの内容は下記3行。

@echo off
powershell -sta -ExecutionPolicy Unrestricted -Command "Get-WmiObject -Class Win32_PnPEntity -Filter \"PNPClass='Ports'\" | select Name,Manufacturer,DeviceID"
pause

なお、最初オンボードのIntel Active Managamentが「Service:Serial」だったので、それでfilterしようとしたら、FDTIのは「Service:FTSER2K」だったので、両方に共通の「PNPClass:Ports」を選択しています。

FDTIのWMI出力サンプル

__GENUS                     : 2
__CLASS                     : Win32_PnPEntity
__SUPERCLASS                : CIM_LogicalDevice
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_PnPEntity.DeviceID="FTDIBUS\\VID_0403+PID_6001+FTHG96ISA\\0000"
__PROPERTY_COUNT            : 26
__DERIVATION                : {CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                    : WIN10PC
__NAMESPACE                 : root\cimv2
__PATH                      : \\WIN10PC\root\cimv2:Win32_PnPEntity.DeviceID="FTDIBUS\\VID_0403+PID_6001+FTHG96ISA\\0000"
Availability                : 
Caption                     : USB Serial Port (COM4)
ClassGuid                   : {4d36e978-e325-11ce-bfc1-08002be10318}
CompatibleID                : 
ConfigManagerErrorCode      : 0
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
Description                 : USB Serial Port
DeviceID                    : FTDIBUS\VID_0403+PID_6001+FTHG96ISA\0000
ErrorCleared                : 
ErrorDescription            : 
HardwareID                  : {FTDIBUS\COMPORT&VID_0403&PID_6001}
InstallDate                 : 
LastErrorCode               : 
Manufacturer                : FTDI
Name                        : USB Serial Port (COM4)
PNPClass                    : Ports
PNPDeviceID                 : FTDIBUS\VID_0403+PID_6001+FTHG96ISA\0000
PowerManagementCapabilities : 
PowerManagementSupported    : 
Present                     : True
Service                     : FTSER2K
Status                      : OK
StatusInfo                  : 
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : WIN10PC
PSComputerName              : WIN10PC

Intel Active ManagementのWMI出力サンプル

__GENUS                     : 2
__CLASS                     : Win32_PnPEntity
__SUPERCLASS                : CIM_LogicalDevice
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_PnPEntity.DeviceID="PCI\\VEN_8086&DEV_A2BD&SUBSYS_82B4103C&REV_00\\3&11583659&1&B3"
__PROPERTY_COUNT            : 26
__DERIVATION                : {CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                    : WIN10PC
__NAMESPACE                 : root\cimv2
__PATH                      : \\WIN10PC\root\cimv2:Win32_PnPEntity.DeviceID="PCI\\VEN_8086&DEV_A2BD&SUBSYS_82B4103C&REV_00\\3&11583659&1&B3"
Availability                : 
Caption                     : Intel(R) Active Management Technology - SOL (COM3)
ClassGuid                   : {4d36e978-e325-11ce-bfc1-08002be10318}
CompatibleID                : {PCI\VEN_8086&DEV_A2BD&REV_00, PCI\VEN_8086&DEV_A2BD, PCI\VEN_8086&CC_070002, PCI\VEN_8086&CC_0700...}
ConfigManagerErrorCode      : 0
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
Description                 : Intel(R) Active Management Technology - SOL
DeviceID                    : PCI\VEN_8086&DEV_A2BD&SUBSYS_82B4103C&REV_00\3&11583659&1&B3
ErrorCleared                : 
ErrorDescription            : 
HardwareID                  : {PCI\VEN_8086&DEV_A2BD&SUBSYS_82B4103C&REV_00, PCI\VEN_8086&DEV_A2BD&SUBSYS_82B4103C, PCI\VEN_8086&DEV_A2BD&CC_070002, PCI\VEN_8086&DEV_A2BD&CC_0700}
InstallDate                 : 
LastErrorCode               : 
Manufacturer                : Intel
Name                        : Intel(R) Active Management Technology - SOL (COM3)
PNPClass                    : Ports
PNPDeviceID                 : PCI\VEN_8086&DEV_A2BD&SUBSYS_82B4103C&REV_00\3&11583659&1&B3
PowerManagementCapabilities : 
PowerManagementSupported    : 
Present                     : True
Service                     : Serial
Status                      : OK
StatusInfo                  : 
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : WIN10PC
PSComputerName              : WIN10PC

rsyncによるディレクトリ同期を行う際、並列実行により高速化する手法

rsyncを高速化するために、分散して実行することにした。

全部を1つのスクリプトとしてもいいのだが、デバグがしやすいように分割して作業を行えるようにしている。

また、下記の記述はLinuxの/usrをコピーすることを想定している。環境に応じて書き換えること。

まず、/usr/xxx以下にあるファイルまでをコピーするために以下を実行する。

# rsync --archive -v --exclude="*/*/" /usr/ /mnt/vol/voltest

このexcludeオプションをつけている場合、「/usr/xxx/yyy」のファイルとシンボリックリンクはコピーされる。しかし「/usr/xxx/zzz/」のディレクトリはコピーされない。

次に、「/usr/xxx/zzz/」のディレクトリ一覧を取得する。

# find /usr -mindepth 2 -maxdepth 2 -type d -print

このディレクトリ一覧を下記のperlスクリプトに食わせる。(下記スクリプトは” find /usr -mindepth 2 -maxdepth 2 -type d -print > list.txt”で取得したlist.txtを使う想定)

#!/usr/bin/perl

use threads;
use Thread::Queue;

my $LOGDIR="/root/test";
my $MAXSESSION=5;

my $sourcepathbase="/usr";
my $destpathbase="/mnt/vol/voltest";

my $stream = Thread::Queue->new;

open(FILE,"list.txt");
while(my $tmp=<FILE>){
        $stream->enqueue("$tmp");

}
close(FILE);

sub SyncExecute{
        while(my $str = $stream->dequeue){
                # 改行削除
                $str =~ s/\n//ig;
                $str =~ s/\r//ig;
                # ログ出力用ファイル名
                my $filename=$str;
                $filename =~ s/\//-/ig;
                $filename =~ s/\.//ig;
                $filename =~ s/-$//ig;
                $filename =~ s/#//ig;
                $filename =~ s/^-//ig;
                $filename =~ s/ //ig;
                my $logfile="$LOGDIR/test-$filename.log";
                # rsync元と先の処理
                my $tmp,$st,$ed;
                my $sourcepath,$destpath;
                $tmp=substr($str,0,1);
                if($tmp eq "/"){
                        $sourcepath=$sourcepathbase.$str."/";
                        $destpath=$destpathbase.$str;
                }else{
                        $sourcepath=$sourcepathbase."/".$str."/";
                        $destpath=$destpathbase."/".$str;
                }
                `date >> $logfile`;
                print "rsync -v --archive $sourcepath $destpath >> $logfile 2>&1 \n";
                `rsync -v --archive $sourcepath $destpath >> $logfile 2>&1 `;
                `date >> $logfile`;
                #`sleep 5`;
        }
}


my @kids;
foreach(1..$MAXSESSION){
        my $kid = threads->new(\&SyncExecute,$stream);
        push(@kids,$kid);
        $stream->enqueue(undef);
}


print "wait\n";

foreach(@kids){
        my ($return) =$_ -> join;
}

このスクリプトは、rsyncの同時実行数5で、並列にrsyncを実行していくものになっている。

実行したサーバの負荷状況に応じて「my $MAXSESSION=5;」で設定している 同時実行数 を調整する。あまり大きくしすぎるとサーバからの応答が遅くなりすぎるのでほどほどに・・・


2020/03/10追記

上記で実行するrsyncコマンドはハードリンクの処理を行わないものとなっている。

このため、ハードリンクされているファイルがある場合、コピー先のファイルが1つではなく複数別個のものとしてコピーされる。

ハードリンクをそのままコピーしたい場合は「–hard-links」オプションを追加する必要があるのだが、ハードリンク処理の効力範囲は同一プロセス内で処理すること、という条件があるため、今回のような分割処理して高速化する、という場合には不適切となっている。

このため、ハードリンクファイルがある場合は、初回同期は分割処理で行い、2回目はディレクトリ全体を–hard-linksオプションをつけて1プロセスで処理してハードリンク処理を行わせる、という手法をとる必要がある。

なお、ハードリンク処理が完了したあと、分割処理の対象となった場合、すでにファイルが存在しているので再コピーされる、ということは発生しない。

NetAppのperfstatデータ収集ツールで取得したファイルを分解する

現用のNetAppの状況確認をするために「perfstatデータ収集ツール」というのが配布されている。
注:ONTAP 9.5以降はperfstatは非対応とのこと

rsh/sshで対象のNetAppにログインして、いろんなコマンドを実行して、1つのテキストファイルとして出力をする。

この「1つのテキストファイル」というのがくせ者で、200MBぐらいのファイルができたりする。

これだとエディタで取り扱いづらいので細かく分割することにした。

中をみてみると「=-=-=-=-=-= CONFIG IPアドレス PRESTATS =-=-=-=-=-= aggr status -v」という感じで「 =-=-=-=-=-= 」区切りでファイルが出力されている。

それを元にファイルを分割したのが下記スクリプト。

$inputfile="x:\tmp\source\perfstat7_20191122_1400.txt"
$outdir="x:\tmp\output"

$filename=""

Get-Content $inputfile -Encoding UTF8 | ForEach-Object {
    $line=$_
    if( $line.Contains("=-=-=-=-=-=") ){
        $filename=$line
        $filename=$filename.Replace("=-=-=-=-=-= ","")
        $filename=$filename.Replace("/","-")
        $filename=$filename.Replace(":","")
        $filename=$outdir+"\"+$filename+".txt"
        New-Item $filename
    }
    if($filename -ne ""){
        $line | Add-Content $filename
    }
}

今回は1回しか実行しないので速度を気にする必要がないので簡単さを優先している。

もし、出力速度を気にするのであれば1行毎にAdd-Contentするのは非常に効率が悪いので工夫が必要となる。

参考例:「PowerShellで巨大なファイルをGet-Contentし、Export-Csvするのを省メモリで行う


2019/11/25 追記

上記のスクリプトだと遅すぎで、約200MBのファイル処理に5時間かかりました。

やはり改行のみ行が数万行ある、というのが悪かったようです。

また、同じヘッダ行が何回か登場するようで単純に「New-Item」としているとファイル名が重複しているというエラーがでてしまっていました。

さすがに5時間はないなーということで、高速化処理をしたのが下記となります。

実行にかかる時間は2分と大幅短縮となりました。

$inputfile="x:\tmp\source\perfstat7_20191122_1400.txt"
$outdir="x:\tmp\output2"

$filename=""

$results=@()
$linecount=0

Get-Content $inputfile -Encoding UTF8 | ForEach-Object {
    $line=$_
    if( $line.Contains("=-=-=-=-=-=") ){
        if($filename -ne ""){
            $results | Add-Content $filename
            $results=@()
            $linecount=0
        }
        $filename=$line
        $filename=$filename.Replace("=-=-=-=-=-= ","")
        $filename=$filename.Replace("/","-")
        $filename=$filename.Replace(":","")
        $filename=$outdir+"\"+$filename+".txt"
        if ( !(Test-Path $filename) ){
            New-Item $filename
        }
    }

    if($filename -ne ""){
        $results += $line
        $linecount++
        if(($linecount % 1000) -eq 0 ){
            $results | Add-Content $filename
            $results=@()
        }
    }
}

ユーザバックエンドがSQLのiredmailのSOGoでユーザがログインできない

2020/09/10追記

iRedMail内のパスワード文字列取り扱いについて「Password hashes」というドキュメントが公開された。

それによればmd5-cryptを使いたい場合は「{CRYPT}$1$5ulpxxxx$VS0xHxxKxMPBSIPQlXDXC/」という風に「{CRYPT}」という前置詞を追加すれば良いらしい。


qmail+vpopmailからパスワード暗号化文字列ごと移植したpostfix+dovecotベースの統合環境iredmail環境がある。

iredmailにはExchange互換サーバのSOGoもあるので、そちらでログインしようとしたらエラーになる。

roundcubeからだとログインができるし、dovecotを使うPOP3/IMAPアクセスでも問題無い。

/var/log/sogo/sogo.log へのエラーは下記の様になっていた。

Jul 04 13:15:04 sogod [9257]: SOGoRootPage Login from 'クライアントIPアドレス' for user 'ユーザ名@ドメイン名' might not have worked - password policy: 65535  grace: -1  expire: -1  bound: 0

iredmailのフォーラムに「Can’t configure password policy when using SOGo」といのがあり、sogo.confに「passwordPolicy = YES;」を追加すればいいじゃん?とあったのでやってみたが、変化はなし。

SOGo側のbug tracking system「 0003899: SQL authentication 」にてヒントを発見。

暗号化文字列の指定の問題のようだ。

今回、sogo.confは下記の様に「userPasswordAlgorithm = ssha512」となっており、パスワード暗号化文字列がssha512フォーマットである、ということになっている。

    SOGoUserSources = (
        {
            type = sql;
            id = users;
            viewURL = "mysql://sogo:~@127.0.0.1:3306/sogo/users";
            canAuthenticate = YES;

            // The algorithm used for password encryption when changing
            // passwords without Password Policies enabled.
            // Possible values are: plain, crypt, md5-crypt, ssha, ssha512.
            userPasswordAlgorithm = ssha512;
            prependPasswordScheme = YES;

            // Use `vmail.mailbox` as per-domain address book.
            isAddressBook = YES;
            displayName = "Domain Address Book";
            SOGoEnableDomainBasedUID = YES;
            DomainFieldName = "domain";
        },

しかし、今回、vpopmail時代の文字列「$1$5ulpxxxx$VS0xHxxKxMPBSIPQlXDXC/」という書式、つまりはmd5-cryptフォーマットを流用しているので認証できなかった、ということになる。

メインとなるiredmail側は新しくパスワードを設定した場合はssha512、移植したものはmd5-cryptという運用にしている。

ただ、postfix,dovecot,roundcubeの運用に関しては、ssha512でもmd5-cryptでも問題無くログインできている。

それに対してSOGo側は「SOGO Installation and Configuration Guide」を見ると userPasswordAlgorithm には1つの値しか指定はできないようだ。

セキュリティを考えると全体をmd5-cryptに下げる、という選択肢はとれないので、SOGoを使いたい場合は、パスワードを再設定する、ということになる。

パスワードを再設定すると以下のログとなる。

Jul 04 13:50:43 sogod [1094]: SOGoRootPage successful login from 'クライアントIPアドレス' for user 'ユーザ名@ドメイン名' - expire = -1  grace = -1