2020年11月25日水曜日

RaspberryPiOSあーやっちまったー起動しないんですけど

fstabの設定を間違えて起動しなくなる

ちょっと記述を間違えただけで起動しなくなります。USBメモリのマウント位置固定するときに綴りがちょっと違っただけなんです。システムのファイルシステムじゃないから起動しなくなることはなかろうと、たかをくくってよく確認しなかったのが悪いんだけど…
起動してくれったっていいじゃないかよー

これを治すにはシングルユーザモードに切り替えてから編集するのが定石ですが、これが結構面倒くさい。

通常の手順は、

WindowsでSDカードを読み込む

cmdline.txtの行末に"init=/bin/sh"を追記

シングルーユーザーモードで起動

ルートフォルダーを再マウントする 

 #umount /
 #mount -o remount,rw /dev/mmcblk0p2 /

問題箇所を修正

シャットダウンする 

再びWindowsでSDカードを読み込む

cmdline.txtの行末に"init=/bin/sh"をコメントアウト

RaspberryPiにSDカードを戻す

RaspberryPiを起動


nasを使うと簡単

NASにUSBカードリーダー経由でSDカードを接続

PCから認識されたNASの『USBディスク』を開く

問題箇所を修正

アンマウントする

RaspberryPiを起動する

 

Windowsを使った場合のSDカードの動きを見ると

RaspberryPi→WindowsPC cmdline.txtを編集

WindowsPC→RaspberryPi 問題箇所を編集

RaspberryPi→WindowsPC cmdline.txtを編集

しかもこの手順が問題が解決されるまで繰り返されるわけで、問題箇所がすぐにわかっていれば1回で終わるものの、何度も繰り返すと嫌になること間違いなしです。しかも、ルートフォルダのアンマウント、マウントも面倒だし、RaspberryPiの起動を待つのもまた面倒。

でも、NASならSDカードを差し込んでPCで編集。外してRaspberryPiに差し込んで起動するか確認するだけ。あーーらくちん♪

そういえば。。。

ハードディスクが連続して壊れた…昔の事件の話

ちなみにいま使っているNASはSynology DS418です。

ドライブベイが4個あります。ハードディスク1ドライブから運用でき2ドライブでミラーリングが始まり、ハードディスク追加で容量が増やせるのでいいですね。

4T+4T+8T+16T+32T+64Tの順で増やすと効率が良さそうです。毎年1個づつ追加入れ替えとか。でも、そんなペースでHDDの容量も増えないかw

ここで、NASに使用するハードディスクは同じものに揃えたほうがパフォーマンスがいい。という話もあるけど、パフォーマンスよりもデータの永続性の方が大事だと思います。同時期に同じハードディスクを購入すると同じロットになり特性は揃えられますが、もし設計上のミスがあり時間が経って故障が出るようだと、同時期にハードディスクが故障します。かつて富士通やSeagateのハードディスクで使用されていたLSIの封止材に問題があり、同時期にハードディスクが壊れていくということがありました。それを経験すると同一ロットで揃えるのは非常に怖いですね。なので性能は二の次、メーカー・ブランドを変えて構成していっています。

詳しくはこちら→ 失敗事例 2000年 LSI封止材事件 

当時、超大問題になりました…。

概要は

ICパッケージのモールド材のエポキシ樹脂を難燃化するために添加したリンが吸湿により燐酸になり,パッケージのリードのメッキの銀がマイグレーションを起こしてリード間でショートを起こすというもの

 もともと難燃剤としては臭素が使われていたが,塩素,臭素といったハロゲン系の元素を燃やすとダイオキシン系の有毒ガスが出ると言うことでハロゲンを使わないという動きが広がっており,これに応じて材料をリンに変更

磁気ディスク装置の不具合に関する訴訟の和解についてより

ただ、この問題は更に広がり

問題となったパッケージ封止材は,合計で1000トンも出荷されており、LSIの数に換算するとおよそ10億個と推定される。HDD用LSIはその一部に過ぎず,ケーブル・テレビのセットトップ・ボックス用LSIやパソコンのメインボードに実装されたLSI,LSIテスタ用ICなどでもトラブル例が報告されており、今後他の電子製品にも波及する危険性がある。

失敗事例 2000年 LSI封止材事件より

あちこちで電子機器の故障が頻発していたという。あな恐ろしや。


ということで、同じカゴに卵を全部入れないのが得策です。


あああーー大事なデータ NASの箱に全部入れてるーーー(笑)



RasberryPiをGNSS/GPSで時刻を合わせる RTC無いの?

この記事は次の環境を想定して書かれています

RaspberryPi WH
RaspberryPi4 
RaspberryPiOS
python3
GNSS/GPSアンテナモジュール シリアルポート接続
GU-902MGG-USB USB-UARTブリッジ(Prolific PL2303SA /秋月電子通商)ZED-F9P USB接続 

液晶LCD1602モジュールと組み合わせた電波時計の作例はこちら 

GPSとGNSS

GPS(グローバルポジショニングシステム)は、日本国内では衛星を使った測位システムとして認識されていますが、本来GPSはアメリカの測位システムの名前です。現在、GPSアンテナと総称されているものは他の測位衛星GLONASS(ロシア)やみちびき(日本)Galileo(欧州)やBeiDou(中国)も利用して測位しています。そのため、利用する測位システムの名称としては、GNSS(Global Navigation Satellite System / 全球測位衛星システム)が正確にあらわしていますので、以下GNSSに統一します。

RaspberryPiにはRTCが無い!

 さてさて、GNSSロガーを作って、実際に山登りしながらロギングしていると、ログファイルのタイムスタンプがずれているではないですか。いつも時刻があっていて、てっきりRaspberryPiには時計が内蔵されているものだと思っていたので、当日のタイムスタンプのファイルが無くGNSSログが取れていないかのかと頭が真っ白になりました。でも前日のタイムスタンプのファイルがログファイルだった(汗)

確かにパソコンに入っているCR2032みたいなボタン電池は入っていないし、当然RTC(リアルタイムクロック:内蔵時計)は無い。

自宅で使っている分にはネットワーク環境があるのでNTPで時間がピッタリあっている。でも、出先で携帯の電波も入らないようなところだと、当然テザリングでの時刻合わせもできない。かといって、携帯電波の入るところでRaspberryPiを起動して自動的に時刻合わせをした上で現地向かうとして、到着後登山リュックにGPSアンテナ配線したりRaspberryPiを仕込んでバッテリー配線したりしているときに、電源の配線抜けでリセットかかってしまうと完全にお手上げ状態になる。

となると、内蔵時計を合わせる方法は…

(a)RTCを搭載する

(b)GNSS信号から時刻を取得する

『登山』が大前提にあり、現在RaspberryPi/WHをメインに使用しているので、回路は簡単にしたい。揺れるし、雑に扱うし。ということで方式(b)GNSSで時刻を合わせることとしました。


GNSSで時刻合わせをするには date -sできないけど 

方法としては、gpspipeなどを使用するのが定石のようですが。。。


GPSDATE="`/usr/bin/gpspipe -w | /usr/bin/head -10 | /bin/grep TPV | /bin/sed -r 's/.*"time":"([^"]*)".*/\1/' | /usr/bin/head -1`"
echo $GPSDATE
/bin/date -s "$GPSDATE"
このgpspipeはgpsdと通信をして標準出力へ出力するというもの。
gpspipe is a tool to connect to gpsd and output the received sentences to stdout. 

GNSSロガーはもうできているので、今の所gpsdは入れたくないし。

GNSSロガーなのでGNSSのデータはもうすでに取得できている状況で、メッセージの解析もpythonを使用すればそれほど難しくはありません。
実際ログを見てみると

$GPGSV,4,2,14,20,52,198,18,21,00,321,,23,59,195,16,24,39,050,30*78
$GPGSV,4,3,14,25,47,170,,31,09,246,20,32,34,308,46,193,72,151,19*4C
$GPGSV,4,4,14,194,69,159,,195,05,171,*7D
$GLGSV,2,1,07,67,29,129,,68,75,069,,69,38,331,45,77,12,033,13*67
$GLGSV,2,2,07,78,65,025,28,79,56,222,21,80,02,217,*51
$GNGLL,3528.05140,N,13358.44323,E,055944.00,A,A*7B
$GNRMC,055945.00,A,3528.05143,N,13358.44320,E,0.202,,241120,,,A*67
$GNVTG,,T,,M,0.202,N,0.374,K,A*3D
$GNGGA,055945.00,3528.05143,N,13358.44320,E,1,10,1.08,72.7,M,30.4,M,,*72
$GNGSA,A,3,15,20,10,24,23,32,,,,,,,2.22,1.08,1.95*1B
$GNGSA,A,3,69,77,79,78,,,,,,,,,2.22,1.08,1.95*14
$GPGSV,4,1,14,10,64,272,21,12,57,100,,15,22,108,15,18,01,200,07*7A
$GPGSV,4,2,14,20,52,198,19,21,00,321,,23,59,195,15,24,39,050,30*7A
$GPGSV,4,3,14,25,47,170,,31,09,246,20,32,34,308,46,193,72,151,19*4C
$GPGSV,4,4,14,194,69,159,,195,05,171,*7D
$GLGSV,2,1,07,67,29,129,,68,75,069,,69,38,331,44,77,12,033,13*66
$GLGSV,2,2,07,78,65,025,27,79,56,222,22,80,02,217,*5D
$GNGLL,3528.05143,N,13358.44320,E,055945.00,A,A*7A
$GNRMC,055946.00,A,3528.05125,N,13358.44322,E,0.412,,241120,,,A*61
$GNVTG,,T,,M,0.412,N,0.763,K,A*38
$GNGGA,055946.00,3528.05125,N,13358.44322,E,1,10,1.08,72.7,M,30.4,M,,*73
$GNGSA,A,3,15,20,10,24,23,32,,,,,,,2.22,1.08,1.95*1B
$GNGSA,A,3,69,77,79,78,,,,,,,,,2.22,1.08,1.95*14
$GPGSV,4,1,14,10,64,272,20,12,57,100,,15,22,108,13,18,01,200,09*73
$GPGSV,4,2,14,20,52,198,19,21,00,321,,23,59,195,15,24,39,050,29*72
$GPGSV,4,3,14,25,47,170,,31,09,246,20,32,34,308,46,193,72,151,19*4C
$GPGSV,4,4,14,194,69,159,,195,05,171,*7D
$GLGSV,2,1,07,67,29,129,,68,75,069,,69,38,331,44,77,12,033,12*67
$GLGSV,2,2,07,78,65,025,26,79,56,222,22,80,02,217,*5C
$GNGLL,3528.05125,N,13358.44322,E,055946.00,A,A*7B
$GNRMC,055947.00,A,3528.05120,N,13358.44324,E,0.238,,241120,,,A*6D

ログを眺めると$RMCメッセージから時間が取得できそうです。

次に/bin/date -sで時刻合わせをする。まずは実験。
 

pi@pi126:~ $ date
2020年 11月 21日 土曜日 11:13:01 JST
pi@pi126:~ $ sudo date -s "2020/11/21 11:00"
2020年 11月 21日 土曜日 11:00:00 JST
よしよし

pi@pi126:~ $ date
2020年 11月 21日 土曜日 11:15:48 JST

あれ??
date -sで設定したはずの時刻がもとに戻っています。というか、設定し直されています。まぁ、いつも時刻があっているのでNTPで合わされているんだろうな。と、NTPを止めてみます。

root@pi126:~# systemctl stop ntp.service
Failed to stop ntp.service: Unit ntp.service not loaded.

えーーー!?ntpサービスで同期していないの?

もうちょっと調べたら、RaspberryPiOSというかLinuxではtimedatectl を使うとのこと。

root@pi126:~# timedatectl set-time '2020-11-21 12:07'
Failed to set time: Automatic time synchronization is enabled
NTPでの時刻を合わせの制御もtimedatectlでするらしい。ntp.serviceじゃないんだ。
NTPサービス止まってるし。ん?ま。。。後で調べるとして...。

timedatectl statusで状況を確認します。

root@pi126:~# timedatectl status
              Local time: 土 2020-11-21 12:11:48 JST
          Universal time: 土 2020-11-21 03:11:48 UTC
                RTC time: n/a
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
NTPサービスここで有効になっているようです。
無効にします。

root@pi126:~# timedatectl set-ntp no
root@pi126:~# timedatectl status
              Local time: 土 2020-11-21 12:13:18 JST
          Universal time: 土 2020-11-21 03:13:18 UTC
                RTC time: n/a
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no
NTP service: inactiveで無効になりました。

root@pi126:~# timedatectl set-time '2020-11-21 12:07'
root@pi126:~# date
2020年 11月 21日 土曜日 12:07:10 JST

これでやっと(笑)時刻のセットができるようになりました。

ちなみに書式は

# timedatectl set-time "YYYY-MM-DD HH:MM:SS"
先の日付ならば

# timedatectl set-time "2020-11-21 12:07:10"
 となります。

参考:CentOSの時刻を手動で変更 @suzu6


GNSSのメッセージから時刻を取り出す ~python3を使って

以下、GNSSアンテナからシリアルで送信されたメッセージから時間を取り出して時刻設定するプログラムです。

使用環境:

RaspberryPi WH
RaspberryPiOS
python3
GU-902MGG-USB GNSSアンテナモジュール(秋月電子)
ZED-F9P USB接続 

 今回作成したプログラムです

[gnssdate.py] 

#!/usr/bin/python3
import os
import platform
import sys
import subprocess
import re
import time
from datetime import datetime, timedelta, timezone

import serial
import serial.serialutil as srlutil

def hms2deg(hhmm_mmmm):
    (hh,mm,pmmm) = re.split("(.*)(..)\.(.*)", hhmm_mmmm)[1:4]
    mm_mmmm = mm + "." + pmmm
    deg = float(hh) + float(mm_mmmm) / 60
    return deg

def checksum(line):
    # ex:
    # $GNGGA,004135.00,3634.2352,N,13825.76522,E,2,10,1.91,30.7,M,30.4,M,,0000*7C
    line = line.strip()
    code = 0
    if line[0] != "$":
        return False

    csrange = line[1:-3]
    csraw = line[-3:]       #*7C
    if csraw[0] != "*":
        return False

    csxor = int(csraw[1:], 16)
    for ch in csrange:
        code ^= ord(ch)

    if csxor != code:
        return False

    return True

def rmc_time(line_,tz_):
    if not checksum(line_):
        return None
    line_ = line_.strip()

    chunks = line_.split(",")
    if not re.search("\$..RMC",chunks[0]):
        return None
    print(line_)

    #if "A" not in chunks[2]:    # "A" is active data
    #    return None

    if len(chunks[9]) < 6:
        return None
    if len(chunks[1]) < 6:
        return None

    #print(chunks[9],end=" ")   #191120
    #print(chunks[1])           #090850.40
    (dymmy,day,month,year,dummy)= re.split("(..)(..)(..)",chunks[9])
    (dymmy,hour,minute,sec,msec10,dummy) = re.split("(..)(..)(..)\.(.*)",chunks[1])
    #(hour,min,sec) = re.split("(..)(..)(.*)",chunks[1])

    print("20%s/%s/%s %s:%s:%s.%s"%(year,month,day,hour,minute,sec,msec10))
    dt = datetime(2000 + int(year),int(month),int(day),
               int(hour),int(minute),int(sec),int(msec10)*10000) + \
            timedelta(hours=tz_)

    return dt

if __name__ == '__main__':
    _comport = "COM7"
    _baudrate = 115200
    _timezone = 9

    dtnow = datetime.now()
    print("gnssdate.py at ", end="")
    print(dtnow)

    comport = _comport
    baudrate = _baudrate
    timzn = _timezone
    args = sys.argv
    print(args)
    if len(args) < 3:
        print("gnssdate.py [SerialPort] [BaudRate] [timezone by numeric]")
        #exit(-1)
    else:
        comport = args[1]
        baudrate = int(args[2])
        if len(args) > 3:
            timzn = int(args[3])

    print("waiting boot up of GNSS/GPS unit....")

    if "Linux" in platform.system():
        subprocess.call(["/usr/bin/timedatectl", "set-ntp", "no"])

    time.sleep(10)

    while True:
        dtnow = datetime.now()
        print(dtnow)
        dtstart = dtnow
        portname = comport.split("/")[-1]
        #strdt = dtnow.strftime("_%Y%m%d%H%M.log")

        ser = serial.Serial(comport, baudrate=baudrate, timeout=2)
        line = ""
        while True:
            try:
                bline = ser.readline()
                if bline[0] != ord("$"):    # Charactor of top of line is not "$"
                    ser.reset_input_buffer()
                    continue

            except srlutil.SerialException as sx:
                print("GNSS/GPS Unit is unplugged from SerialPort...")
                print(sx)
                ser.close()
                sys.exit(1)
            else:
                try:
                    line = bline.decode('ascii')
                except UnicodeError as ux:
                    print(ux)
                    ser.close()
                    break

                print(line)
                dtrmc = rmc_time(line, timzn)
                dtnow = datetime.now()
                if dtrmc:
                    delay = dtrmc - dtnow
                    print("GNSS :", end="")
                    print(dtrmc)
                    print("Clock:", end="")
                    print(dtnow)
                    print(" Delay:", end="")
                    print(delay)
                    gnsstime = dtrmc.strftime("%Y-%m-%d %H:%M:%S")

                    if "Linux" in platform.system():
                        #subprocess.call(["/usr/bin/timedatectl", "set-ntp", "no"])
                        subprocess.call(["/usr/bin/timedatectl", "set-time", gnsstime])
                        # subprocess.call(["/usr/bin/timedatectl","set-ntp","yes"])
                        sys.exit(0)

                ser.reset_input_buffer()

 

呼び出し方の例

Linux:
#python3 gnssdate.py /dev/ttyUSB0 115200

Windows:
>python gnssdate.py COM7 115200

 
デフォルトの動作は日本時間ですが、タイムゾーンのオフセットも指定できます。

#python3 gnssdate.py <Serial Port> <baudrate> [TimeZone Offset in Hour]
 

GNSSからの時刻と日付を受信した時点で日時を確定しています。
Windowsで動作させた場合時刻を表示し続けます。
Linuxの場合は時刻をシステム時刻を変更します。
当然電波の入らないところでは確定しませんのでいつまでたっても動作が止まりません。

GNSSアンテナモジュールのボーレートは適宜設定してください。デフォルトでは9600bpsが多いのですが、ここでは、Python3 pyserialですべてのプラットフォームで対応している最高レート115200bpsを例として記載しております。

Windowsで動作させたときは、日時が確定してもそのまま動作し続けます。
Linux環境で動作させたときは、日時が確定するとシステムクロックの修正を行い終了します。
subprocess.call(["/usr/bin/timedatectl", "set-ntp", "no"])

プログラム中でNTPによる自動調整は止めています。通信環境がある通常運用に戻すときはNTPを有効化してください。

/usr/bin/timedatectl set-time で設定できる最小単位が秒なので精度は秒単位となります。

RaspberryPIOSで自動実行するにはrc.localの最終行に以下のように追加します。
[/etc/rc.local]

/usr/bin/python3 /var/samba/gnssdate.py /dev/ttyUSB0 115200

 
SSHでRaspberryPiに接続して動作確認すると0.3秒ぐらい遅れますが、実際にOS起動時にrc.local等で起動させて時刻合わせを試みると、他のタスクが忙しいためか3秒前後の遅れが発生します。

とりあえず日時がざっくり合えばいいと言う方はどうぞ。


GNSSロガーについてもまた後ほど。
NMEA0183対応のテキストバージョンはできたんだけど、UBloxのRAW出力には対応していないもので。


2020年11月3日火曜日

RaspberryPiOS/ラズビアンにll la lが無い!? ls-l ls -A ls -CF って簡単に呼び出せます

 ubuntuやcentos他のLinux系で最初から使用できるll,la,lって非常に便利です。RaspberryPiOSでは最初使える様になっておらず、つい

$ll

-bash: ll: コマンドが見つかりません

としてしまいがちですが、実はすでにll,la,lといったコマンドはエイリアスで登録されており、コメントアウトされているところを修正するだけで呼び出すことができるようになります。

ユーザーディレクトリで

$ls -al
-rw------- 1 pi pi   56 11月  3 08:43 .Xauthority
-rw------- 1 pi pi 1815 11月  3 08:43 .bash_history
-rw-r--r-- 1 pi pi  220  8月 20 19:31 .bash_logout
-rw-r--r-- 1 pi pi 3520 11月  3 18:31 .bashrc
  :

の中の.bashrcにすでに設定されています。

$nano .bashrc
[.bashrc]
:
# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'
:

#alias となっているところの#を削除します
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'

設定を反映させるには
$ source ~/.bashrc

もしくは、一度ログアウトして再度ログインしなおします。

以上で ll,la,l が利用できるようになりました。

pi@raspberrypi:~ $ ll
合計 48
drwxr-xr-x 2 pi   pi   4096  8月 20 19:40 Bookshelf
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Desktop
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Documents
drwxr-xr-x 3 pi   pi   4096 10月 26 11:12 Downloads
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Music
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Pictures
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Public
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Templates
drwxr-xr-x 2 pi   pi   4096  8月 20 19:55 Videos
-rw-r--r-- 1 root root   39 10月 30 02:47 hello-add.log
-rw-r--r-- 1 root root   42 10月 30 02:47 hello-remove.log
-rw-r--r-- 1 root root 2172 11月  3 20:24 udevpl2303.log

pi@raspberrypi:~ $ la
.Xauthority    .config   .python_history       Downloads  hello-add.log
.bash_history  .emacs.d  .xsession-errors      Music      hello-remove.log
.bash_logout   .gnupg    .xsession-errors.old  Pictures   udevpl2303.log
.bashrc        .local    Bookshelf             Public
.bashrc~       .pki      Desktop               Templates
.cache         .profile  Documents             Videos

pi@raspberrypi:~ $ l
Bookshelf/  Documents/  Music/     Public/     Videos/        hello-remove.log
Desktop/    Downloads/  Pictures/  Templates/  hello-add.log  udevpl2303.log




2020年11月2日月曜日

RaspberryPi 機種別性能比較表 2020年版

 RaspberryPi 機種別性能比較表 2020年版

自分用に作成したものですがご参考になれば。


ご自分の用途に合わせて選んでください。
現行はRaspberryPi4とRaspberryPi Zeroです。RaspberryPi3はPi4と値段も消費電力もあまり変わらないのでPi4がおすすめです。

デスクトップPC用途なら RaspberryPi 4 Model B メインメモリ8GB
バッテリー運用やモバイル用途なら Raspberry Pi Zero WH 150mA すばらしい!!

ええ。どちらも購入しちゃったものなのでイチオシなんです(笑)

もっと省電力ならArduinoか。でもPython使いたいし。
RaspberryPi やっぱりOSあって楽チンですもん。





RaspberryPiOSにPython3をインストールし使えるようにする

RaspberryPiOSにPython3をインストールする

以上。終わり。

いやいや。RaspberryPiOSをダウンロードから初めて、SDカードに書き込めばすでにPython3がインストールされています。また、すでによく使われるライブラリもインストールされています。

では、現時点でインストールされているPython3を確認していましょう。

$ python3

Python 3.7.3 (default, Jul 25 2020, 13:03:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>

Ctrl+D で終了

続いてインストールされているライブラリを確認してみます。

$ pip3 list
Package Version
----------------- -----------
asn1crypto 0.24.0
astroid 2.1.0
asttokens 1.1.13
automationhat 0.2.0
beautifulsoup4 4.7.1
blinker 1.4
blinkt 0.1.2
buttonshim 0.0.2
Cap1xxx 0.1.3
certifi 2018.8.24
chardet 3.0.4
Click 7.0
colorama 0.3.7
colorzero 1.1
cookies 2.2.1
cryptography 2.6.1
docutils 0.14
drumhat 0.1.0
entrypoints 0.3
envirophat 1.0.0
ExplorerHAT 0.4.2
Flask 1.0.2
fourletterphat 0.1.0
gpiozero 1.5.1
html5lib 1.0.1
idna 2.6
isort 4.3.4
itsdangerous 0.24
jedi 0.13.2
Jinja2 2.10
keyring 17.1.1
keyrings.alt 3.1.1
lazy-object-proxy 1.3.1
logilab-common 1.4.2
lxml 4.3.2
MarkupSafe 1.1.0
mccabe 0.6.1
microdotphat 0.2.1
mote 0.0.4
motephat 0.0.3
mypy 0.670
mypy-extensions 0.4.1
numpy 1.16.2
oauthlib 2.1.0
olefile 0.46
pantilthat 0.0.7
parso 0.3.1
pgzero 1.2
phatbeat 0.1.1
pianohat 0.1.0
picamera 1.13
piglow 1.2.5
pigpio 1.44
Pillow 5.4.1
pip 18.1
psutil 5.5.1
pycrypto 2.6.1
pygame 1.9.4.post1
Pygments 2.3.1
PyGObject 3.30.4
pyinotify 0.9.6
PyJWT 1.7.0
pylint 2.2.2
pyOpenSSL 19.0.0
pyserial 3.4
python-apt 1.8.4.1
pyxdg 0.25
rainbowhat 0.1.0
requests 2.21.0
requests-oauthlib 1.0.0
responses 0.9.0
roman 2.0.0
RPi.GPIO 0.7.0
RTIMULib 7.2.1
scrollphat 0.0.7
scrollphathd 1.2.1
SecretStorage 2.3.1
Send2Trash 1.5.0
sense-hat 2.2.0
setuptools 40.8.0
simplejson 3.16.0
six 1.12.0
skywriter 0.0.7
sn3218 1.2.7
soupsieve 1.8
spidev 3.4
ssh-import-id 5.7
thonny 3.2.6
touchphat 0.0.1
twython 3.7.0
typed-ast 1.3.1
unicornhathd 0.0.4
urllib3 1.24.1
webencodings 0.5.1
Werkzeug 0.14.1
wheel 0.32.3
wrapt 1.10.11

ちなみにPython2はどうでしょうか。
$ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15)
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Ctrl+D で終了

ついでにPython2のライブラリを見てみます
$pip list
Package           Version
----------------- -----------
arandr            0.1.9
asn1crypto        0.24.0
automationhat     0.2.0
blinker           1.4
blinkt            0.1.2
buttonshim        0.0.2
Cap1xxx           0.1.3
certifi           2018.8.24
chardet           3.0.4
Click             7.0
colorama          0.3.7
colorzero         1.1
configparser      3.5.0b2
cookies           2.2.1
cryptography      2.6.1
dnspython         1.16.0
drumhat           0.1.0
entrypoints       0.3
enum34            1.1.6
envirophat        1.0.0
ExplorerHAT       0.4.2
Flask             1.0.2
fourletterphat    0.1.0
funcsigs          1.0.2
gpg               1.12.0
gpiozero          1.5.1
idna              2.6
ipaddress         1.0.17
itsdangerous      0.24
Jinja2            2.10
keyring           17.1.1
keyrings.alt      3.1.1
MarkupSafe        1.1.0
microdotphat      0.2.1
mock              2.0.0
mote              0.0.4
motephat          0.0.3
numpy             1.16.2
oauthlib          2.1.0
olefile           0.46
pantilthat        0.0.7
pbr               4.2.0
phatbeat          0.1.1
pianohat          0.1.0
picamera          1.13
piglow            1.2.5
pigpio            1.44
Pillow            5.4.1
pip               18.1
pycairo           1.16.2
pycrypto          2.6.1
pygame            1.9.4.post1
PyGObject         3.30.4
pyinotify         0.9.6
PyJWT             1.7.0
pyOpenSSL         19.0.0
pyserial          3.4
pyxdg             0.25
rainbowhat        0.1.0
requests          2.21.0
requests-oauthlib 1.0.0
responses         0.9.0
RPi.GPIO          0.7.0
RTIMULib          7.2.1
scrollphat        0.0.7
scrollphathd      1.2.1
SecretStorage     2.3.1
sense-hat         2.2.0
setuptools        40.8.0
simplejson        3.16.0
six               1.12.0
skywriter         0.0.7
sn3218            1.2.7
spidev            3.4
touchphat         0.0.1
twython           3.7.0
unicornhathd      0.0.4
urllib3           1.24.1
Werkzeug          0.14.1
wheel             0.32.3

さて、ここまで見て
お気づきいただけましたでしょうか…。

$python
として実行するとPython2が実行されています。

Python3を実行するには
$python3
として実行します。

自分が使っているPython3のライブラリを追加しようとしてpip install ほにゃららとすると、そのpipはpip2を呼び出しているため、Python2へ追加されてしまいます。Python3のライブラリとして使用できません。し、当然インポート時にもエラーになります。

Python2サポート終了

さて、このpython2。サポートが2020年1月1日に終了しています。
Python2最終版が
Python 2.7.18 April 20, 2020

Python Foundationはもう使用しないでくださいと案内しています

とはいえ、Python2アンインストールするのはちょっと怖い。
どうなるのだろうか。