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アンインストールするのはちょっと怖い。
どうなるのだろうか。



2020年10月31日土曜日

RaspberryPi にsshdとSambaサーバの設定をする


1.sshdとSambaを設定する

1.1 sshd/SSH ネットワーク経由でRasberryPiが操作できる

sshdを設定するとWindowsパソコンからターミナルで接続できるようになり、設定作業がWindowsパソコンからできます。さらに設定した内容が記録としても残せるので、後で操作を確認したりもできますし、なにより画面が広くアプリが揃ったWindowsパソコンで調べた結果をコピペして設定することができ作業効率が格段と高まります。接続にはSSHに対応したターミナルソフトを使用しますが、Windows10では標準でSSHクライアント機能をもつようになったので、コマンドプロンプトからSSH接続でき非常に便利になりました。

1.2 Sambaファイル共有とは

Sambaを設定するとWindowsパソコンとファイル共有ができるので、Raspberry Piへプログラムを送ったり、RasberryPiで収集した結果をパソコンに持ってきたりが簡単にできるようになります。

2. sshdの設定 WindowsパソコンからSSHで接続できるようにする

2.1 RasbberryPi OSのSSHDの有効化

RasbberryPi の画面上で設定する方法とターミナルからコマンドを入力して設定する方法とがあります。

2.1.1 RasbberryPi の画面上で設定する

左上のラズベリーマークから[設定][Raspberry Pi の設定]をクリック
[インターフェイス]タブからSSH(●)有効をクリックします。
[OK]をクリックでSSHDが起動し他のPCからSSHで接続できます。

2.1.2 ターミナルで設定する 

左上のラズベリーマークの隣にある黒い■マークをクリックします。
次のようにコマンドを入力し有効化します。
$sudo su -
#cd /etc/ssh
#cp sshd_config sshd_config_org
#nano sshd_config

sshd_configファイルが開きます。次の箇所の#を削除します。
[sshd_config]
 :
Port 22
 :
PasswordAuthentication yes

Port 22 を開きます #を削除します
PasswordAuthentication を有効にします #を削除します
キーボードのコントロールを押しながらO(オー)でファイル上書き
キーボードのコントロールを押しながらXで編集終了

最後にSSHDサーバーを有効化し再起動します
#/etc/init.d/ssh enable
#/etc/init.d/ssh restart

2.2 IPアドレスを固定する

各種ネットワークサーバーをRaspberry Piで動作させるのに、IPアドレスが毎回変わるようだと接続が面倒になります。そのためIPアドレスを固定します。いろいろ調べたところIPアドレスの固定はDHCPClientDを使って固定する方法を推奨しているようなので、ここではその方法に習って設定します。
左上のラズベリーマークの隣にある黒い■マークをクリックします。
次のようにコマンドを入力します。

$sudo su -
$ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (ローカルループバック)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.11 netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::2f42:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        inet6 2405:6587:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x0<global>
        ether b8:27:eb:12:41:0d  txqueuelen 1000  (イーサネット)
        RX packets 18772  bytes 4701790 (4.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1649  bytes 258988 (252.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


#cd /etc
#cp dhcpcd.conf dhcpcd.conf.org
#nano dhcpcd.conf

パソコンでも確認してみます。Windows10のコマンドプロンプトを開きます。
スタートボタン田の右の虫眼鏡マークよこに
cmd
と入力しキーボードEnterを押します。
ipconfigとarp -a として確認します。

C:\Users\Owner>ipconfig
Windows IP 構成
イーサネット アダプター 192.168.0.12:
   接続固有の DNS サフィックス . . . . .: flets.jp
   IPv6 アドレス . . . . . . . . . . . .: 2405:6587:xxxx:xxxx:xxxx:xxxx:xxxx
   一時 IPv6 アドレス. . . . . . . . . .: 2405:6587:xxxx:xxxx:xxxx
   一時 IPv6 アドレス. . . . . . . . . .: 2405:6587:xxxx:xxxx:xxxx:xxxx:xxxx
   一時 IPv6 アドレス. . . . . . . . . .: 2405:6587:xxxx:xxxx:xxxx:xxxx
   リンクローカル IPv6 アドレス. . . . .: fe80::4989:xxxx:xxxx
   IPv4 アドレス . . . . . . . . . . . .: 192.168.0.12
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: fe80::225:xxxx
                                          192.168.0.1

C:\Users\Owner>arp -a

インターフェイス: 192.168.0.52 --- 0xf
  インターネット アドレス 物理アドレス           種類
  192.168.0.1           00-XX-XX-XX-XX-XX-XX-da     動的
  192.168.0.3           34-XX-XX-XX-XX-XX-XX-be     動的
  192.168.0.5           84-XX-XX-XX-XX-XX-XX-50     動的
  192.168.0.8           00-XX-XX-XX-XX-XX-XX-f7     動的
  192.168.0.12          00-XX-XX-XX-XX-XX-XX-96     動的
  192.168.0.18          00-XX-XX-XX-XX-XX-XX-9f     動的
  192.168.0.65          38-XX-XX-XX-XX-XX-XX-d3     動的
  192.168.0.66          d4-XX-XX-XX-XX-XX-XX-9e     動的
  192.168.0.67          cc-XX-XX-XX-XX-XX-XX-c4     動的
  192.168.0.73          dc-XX-XX-XX-XX-XX-XX-cc     動的
  192.168.0.74          a8-XX-XX-XX-XX-XX-XX-9e     動的
  192.168.0.81          b8-XX-XX-XX-XX-XX-XX-0d     動的
  192.168.0.87          00-XX-XX-XX-XX-XX-XX-64     動的
  192.168.0.255         ff-XX-XX-XX-XX-XX-XX-ff     静的
  224.0.0.22            01-XX-XX-XX-XX-XX-XX-16     静的
  224.0.0.251           01-XX-XX-XX-XX-XX-XX-fb     静的
  224.0.0.252           01-XX-XX-XX-XX-XX-XX-fc     静的
  239.255.255.250       01-XX-XX-XX-XX-XX-XX-fa     静的
  239.255.255.253       01-XX-XX-XX-XX-XX-XX-fd     静的
  255.255.255.255       ff-XX-XX-XX-XX-XX-XX-ff     静的


このWindows10パソコンのIPアドレスは192.168.0.12です。
デフォルトゲートウェイ(ルーターのアドレス/インターネットへの出口)は
192.168.0.1です。

以上を踏まえ、次のような行を探し行頭の#を削除しIPアドレスを設定します。
このとき事前に調べたIPアドレスを参考に修正します。
[dhcpcd.conf]
interface wlan0
static ip_address=192.168.0.126/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
 
interface wlan0
このwlan0は、ifconfigで得られた名前です。RaspberryPiOSのWifiはこの名前です。
static ip_address=192.168.0.126/24
この192.168.0としているところはWindows10パソコンの値を参考にして同じにします。
static ip_address最後の3桁126としているところは、120~126とか220~250ぐらいならだいたい他の機器で使用されておらず問題が起こりにくいのですが、この番号をどの番号にするかはルーターの設定状況と接続機器によって変わります。
先の arp -a で、同じ番号が無いことを確認し、なければたいがい問題ありません。もしあれば別の番号に変更します。
この番号の選定について、さらに詳しくはIPアドレスとDHCPについて調べてみてください。
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
はデフォルトゲートウェイの値を使います。

以上で編集は終了です。
キーボードのコントロールを押しながらO(オー)でファイル上書きし、
キーボードのコントロールを押しながらXで編集終了します。
最後に設定を反映させるために再起動します。

#reboot

以下RaspberryPiのIPアドレスは192.168.0.126として説明いたしますが、適宜環境に合わせて読み替えてください。

2.3 Windows10からSSHで接続する

Windows10 April 2018 UpdateよりSSH接続が正式対応しました。今までだとSSH接続用にPuttyやTeraTermやRLoginといったソフトのインストールが必要だったところが、Windowsに標準搭載されたことで、すぐにSSH接続できるようになりました。
Windows10のコマンドプロンプトを開きます。
スタートボタン横の検索窓からcmdと入力します。

コマンドプロンプトが開きます



以下次のように入力します。
C:\Users\Owner>ssh pi@192.168.0.126

@以下の192.168.0.126は先のページのdhcpcd.confで設定したRasberryPiのIPアドレスです。

Are you sure you want to continue connecting (yes/no)? yes

yesと入力します。

pi@192.168.0.126's password:

RasberryPiOSの初期設定で設定したパスワードを入力します。

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Oct 31 06:43:07 2020
pi@raspberrypi:~ $

このような表示が出てくればSSHでの接続が成功しています。

3 Sambaの設定

以下のURLの記事を参考にいたしました。
リモートワークで使えるRaspberry Piで作るファイル共有サーバhttps://qiita.com/Brutus/items/d3b3caee982852587b77

3.1 Sambaのインストール

$sudo su -
#apt-get install -y samba samba-common-bin  

DHCP から WINS 設定を使うように smb.conf を変更しますか?
と表示が出たら<いいえ>を選んでEnter

3.1.1 共有フォルダの作成

# mkdir /var/samba
共有フォルダへアクセスするユーザの作成
# useradd smbuser

3.1.2 パスワードの設定

他のパソコンから接続するためのパスワードを設定します。
これも、後で使用するので必ず控えてください。
# passwd smbuser
新しいパスワード: ********
新しいパスワードを再入力してください: ********
passwd: パスワードは正しく更新されました

3.1.3 権限変更

# chown smbuser:smbuser /var/samba/
Sambaのアクセス設定
# pdbedit -a smbuser
new password: ********
retype new password: ********
Unix username:        smbuser
NT username:
 :

3.1.4 共有フォルダの公開設定

# cp -p /etc/samba/smb.conf /etc/samba/smb.conf.org
# nano /etc/samba/smb.conf

/etc/samba/smb.confファイルに以下を追記する。
pi126の箇所は、先の固定IPを割り当てたものを使用しています。

[pi126]
   comment = Share Folder
   browseable = yes
   path = /var/samba
   writable = yes
   valid users = smbuser
   force user = smbuser

3.1.5 Sambaの再起動

動作状態の確認
# service smbd status
smbd.service - Samba SMB Daemon
   Loaded: loaded (/lib/systemd/system/smbd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2020-10-31 10:40:12 JST; 26min ago
     Docs: man:smbd(8)
           man:samba(7)
           man:smb.conf(5)


Active: active (running) となっていれば動作中です。
再起動します。
# service smbd restart


pdbedit
pdbeditコマンドは、SAM データベース (Samba ユーザーのデータベース) を管理します。
SAM データベース内に保持されるユーザーアカウントを管理するために利用され、 root だけが実行できます。

pdbeditを使用することで、ユーザーアカウントの追加、ユーザーアカウントの削除 、ユーザーアカウントの変更、ユーザーアカウントの一覧表示、ユーザーアカウントのインポートの操作が行えます。

データベースのユーザーアカウントを一覧表示
$ sudo pdbedit -L
smbuser:1001:

データベースのユーザーアカウントを一覧表示(詳細)
$ sudo pdbedit -L -v
---------------
Unix username:        smbuser
NT username:          
Account Flags:        [U          ]
User SID:             S-1-5-21-1950213270-485466186-3954191822-1000
Primary Group SID:    S-1-5-21-1950213270-485466186-3954191822-513
Full Name:            
Home Directory:       \\raspberrypi01\smbuser
HomeDir Drive:        
Logon Script:         
Profile Path:         \\raspberrypi01\smbuser\profile
Domain:               RASPBERRYPI01
Account desc:         
Workstations:         
Munged dial:          
Logon time:           0
Logoff time:          never
Kickoff time:         never
Password last set:    水, 25  3月 2020 15:11:40 JST
Password can change:  水, 25  3月 2020 15:11:40 JST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
ファイル共有サーバのアクセス
Raspberry Pi側でファイアウォールを有効にしている場合は、Sambaで使用する通信が許可されていることを前提とし、WindowsとMacそれぞれのアクセス方法について記載しています。

3.1.6 共有フォルダーにユーザーpiを追加する

このままではユーザーsmbuserしかファイルの操作ができません。smbuserは外からアクセスしてきたユーザーとなるので、自動ログインするユーザーpiにも権限を与えなければ、この共有フォルダーを使用できません。
ユーザーpiをsmbuserグループに追加します。
#adduser pi smbuser
ユーザ `pi' をグループ `smbuser' に追加しています...
ユーザ pi をグループ smbuser に追加
完了。

所属グループを確認するには
#cat /etc/group
:
systemd-coredump:x:996:
sambashare:x:116:
smbuser:x:1001:pi

続いてこのままでは未だに/var/sambaフォルダーはユーザーsmbuserからしか読み書きできません。ユーザーpiは読み込みのみです。そのため、ユーザーpiもこのフォルダーへの読み書きできるようにするにはフォルダーのアクセス権限を変更します。
変更前のアクセス権限の確認。
#ls -l /var
drwxr-xr-x  2 smbuser smbuser      4096 10月 31 10:43 samba

グループに所属するユーザーにも書き込み権限を与える
#chmod 775 /var/samba

変更後のアクセス権限の確認
#ls -l /var
drwxrwxr-x  2 smbuser smbuser      4096 10月 31 10:43 samba
#exit
$cd /var/samba
$echo Hello > test.txt
-bash: test.txt: 許可がありません

いえいえ慌てなくても大丈夫です。RaspberryPiにログインし直します。
$exit
>ssh pi@192.168.0.126
$cd /var/samba
$echo Hello > test.txt
$ls -al
合計 12
drwxrwxr-x  2 smbuser smbuser 4096 10月 31 19:10 .
drwxr-xr-x 12 root    root    4096 10月 31 10:43 ..
-rw-r--r--  1 pi      pi         6 10月 31 19:10 test.txt
このようにtest.txtが作成できました。

3.2 Windowsで共有フォルダーを開く

Windows10でSambaにアクセスするためには、Samba(SMB)のクライアントが必要になります。
Windows 10の場合はSMB 1.0 が無効になっているため、以下の手順でSambaのクライアントを有効にします。以前にファイル共有の設定が終わっていれば以下の設定は必要ありません。が、一応確認されたほうが良いと思います。

コントロールパネルを開く


プログラムから、

[Windows の機能の有効化または無効化]を開く

SMB 1.0/CIFS ファイル共有のサポートを開き


[SMB 1.0/CIFS クライアント]にチェックを入れて、[OK]をクリックします。
以上でWindows10側のファイル共有の設定が終わりました。


Windows10でRaspberryPiの共有フォルダーを開いてみます。
エクスプローラーを開く。

一番下のネットワークからRASPBERRYPIがあればそれを開きます。
今回共有フォルダーにした[pi126]をダブルクリックします。

ユーザー名を先に登録したsmbuser
パスワード設定したものを入力し[OK]を押します。

もし、ネットワークに[RASPBERRYPI]が存在しなければIPアドレスを指定して開きます。
アドレスバーに\\192.168.0.126\
と入力します。

pi126を開きます。
ユーザー名は先に登録したsmbuser
設定したパスワードを入力し[OK]を押します。
test.txtを開いてみます。
うまく開けました。

3.3 Macで共有フォルダーを開くには

Macの場合はFinderからアクセスします。

Finderの[移動]から、[サーバへ接続]を選択する。
[サーバアドレス]にsmb://192.168.0.126 と入力し、[接続]をクリックする。
ユーザー名は先に登録したsmbuser
設定したパスワードを入力し[OK]を押します。



4 ホスト名を変更する

Windowsやその他デバイスからSambaのネットワークを開くとホスト名が
『raspberrypi』と表示されます。複数台数のRaspberryPiがネットワークに接続された状態で識別するには名前を変更します。

/etc/hostname

/etc/hosts

の両方のファイルの「raspberrypi」を任意のホスト名に置き換えます。
ここでは「pi126」とします。

変更後、rebootすると反映されます。

※/etc/hostnameのみの変更だとrebootした後に元に戻ってしまうため、必ず2つとも変更する



参考:

Raspberry Piのホスト名を変更するhttps://qiita.com/naoyukisugi/items/66fd21512da75b437465