Raspberry piでNTPとRTCモジュールの時刻設定をうまいことやりたい

## 目的
Raspberry piにRTCモジュールをつけるけど、NTPサーバーにつながる場合はNTPで時刻同期するようにしたい

## 経緯
Raspberry piでRTCモジュールをつけてみたが、NTPサーバーに繋がる場合は、そちらを参照するように設定したいと思いスクリプトを作ってRTCモジュールの時刻書き換えを行っていました。

ntpdateを使ってごにょごにょしてましたが、Raspberry piでは使わなくてもいいということを知ったので、その方法を記載します。

## 結論

```timedatectl```を使う！


## 設定の手順
RTCモジュールの接続手順とNTPサーバーの設定手順を残します。

### RTCモジュールの接続
RTCモジュールを接続する手順です。

#### i2cの有効化
RTCモジュールは、I2C接続のためI2Cを有効化します。

##### コマンド実行
```bash
$ sudo raspi-config
```

##### 「Interface Options」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711722/8c141174-2d77-570e-b167-1edd63b0fcdd.png)

##### 「I2C」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711722/b8e03a44-3980-90d0-bb9d-48b7dadbdafa.png)

##### I2C の有効か確認メッセージが表示されるのを確認し「Yes」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711722/4e2e1707-52aa-936b-d5a7-ea0eed9c0eed.png)

##### メッセージが出てきたら「OK」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711722/bdbe6eb6-e2db-1b85-b779-4bb7e49d32ef.png)
##### これも入れておきます。
```bash
$ sudo apt-get install -y i2c-tools
```
#### RTCモジュールをラズパイにセット
<img width="200" alt="InkedFPBOazsaUAI7Dyd_LI.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/711722/a6cc37fc-8c8f-949d-93a6-5c938356c22f.jpeg">

##### 使用するRTCモジュールを設定
```txt:/boot/config.txt
dtoverlay=i2c-rtc,ds1307
```
##### 接続確認
I2Cアドレス0x68になっている。
```bash
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```
##### ```timedatactl```で現状を確認
`RTC time: n/a`になっている。  
```bash
$ timedatectl
               Local time: Tue 2022-03-29 22:16:55 JST
           Universal time: Tue 2022-03-29 13:16:55 UTC
                 RTC time: n/a
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
##### 再起動
```bash
$ sudo reboot
```
##### もう一度、接続確認
0x68が`UU`にっていることを確認
```bash
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```
##### ```timedatectl```で確認
`RTC time:`に時刻が表示されるようになっている。  
```bash
$ timedatectl
               Local time: Tue 2022-03-29 22:30:02 JST
           Universal time: Tue 2022-03-29 13:30:02 UTC
                 RTC time: Tue 2022-03-29 13:30:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
##### RTCモジュールの時刻も確認
```bash
$ sudo hwclock -r
2022-03-29 22:32:16.728296+09:00
````
:::note info
※システム時刻と同じになってるのはNTPが有効になっており、再起動時にRTCモジュールに書き込まれているためです。
:::

### NTPサーバーの設定
NTPサーバーを指定する。
#### systemd-timesyncdサービスのステータスを確認
warningが出ています。
`2.debian.pool.ntp.org`のNTPサーバーと時刻同期しているようです。

```bash
$ sudo systemctl status systemd-timesyncd
Warning: The unit file, source configuration file or drop-ins of systemd-timesyncd.service changed on disk. Run 'systemctl daemon-reload' to reload units.
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
  Drop-In: /usr/lib/systemd/system/systemd-timesyncd.service.d
           └─disable-with-time-daemon.conf
   Active: active (running) since Tue 2022-03-29 22:29:18 JST; 5min ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 334 (systemd-timesyn)
   Status: "Synchronized to time server for the first time 194.0.5.123:123 (2.debian.pool.ntp.org)."
    Tasks: 2 (limit: 2059)
   CGroup: /system.slice/systemd-timesyncd.service
           └─334 /lib/systemd/systemd-timesyncd

Mar 29 22:29:17 raspberrypi systemd[1]: Starting Network Time Synchronization...
Mar 29 22:29:18 raspberrypi systemd[1]: Started Network Time Synchronization.
Mar 29 22:29:58 raspberrypi systemd-timesyncd[334]: Synchronized to time server for the first time 194.0.5.123:123 (2.debian.pool.ntp.org).
```
#### confファイルを作成
1. ```/etc/systemd/timesyncd.conf.d``` フォルダを作成
1. ```/etc/systemd/timesyncd.conf.d/*.conf``` ファイルを作成
ファイル名は自分で決めていいみたい。
```/etc/systemd/timesyncd.conf.d/*.conf
[Time]
NTP=ntp.jst.mfeed.ad.jp ntp.nict.jp
FallbackNTP=time.google.com
```
#### timedatectlでNTPを有効にする
```bash
$ sudo timedatectl set-ntp true
```
#### systemd-timesyncdサービスを再起動する
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart systemd-timesyncd
```
#### systemd-timesyncdサービスのステータスを確認
`ntp.jst.mfeed.ad.jp`に同期している。
```bash
$ sudo systemctl status systemd-timesyncd
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
  Drop-In: /usr/lib/systemd/system/systemd-timesyncd.service.d
           └─disable-with-time-daemon.conf
   Active: active (running) since Tue 2022-03-29 22:47:49 JST; 6s ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 835 (systemd-timesyn)
   Status: "Synchronized to time server for the first time 210.173.160.57:123 (ntp.jst.mfeed.ad.jp)."
    Tasks: 2 (limit: 2059)
   CGroup: /system.slice/systemd-timesyncd.service
           └─835 /lib/systemd/systemd-timesyncd

Mar 29 22:47:49 raspberrypi systemd[1]: Starting Network Time Synchronization...
Mar 29 22:47:49 raspberrypi systemd[1]: Started Network Time Synchronization.
Mar 29 22:47:49 raspberrypi systemd-timesyncd[835]: Synchronized to time server for the first time 210.173.160.57:123
```
## 動作を確認してみた

RTCの時刻をずらし以下のパターンで、システム時刻やRTCモジュールの時刻がどのようになっているのかを確認してみる。

| No.   | NTP   | ネットワーク |
| :---: | :---: | :--------- |
|1|無効|-|
|2|有効|ネットワークなし|
|3|有効|ネットワークあり<br>NTPサーバーに繋がらない|
|4|有効|ネットワークあり<br>NTPサーバーに繋がる|



### No.1 NTPが無効の場合
#### NTPを無効化
```bash
$ sudo timedatectl set-ntp false
```
#### RTCの時刻をずらす
```bash
$ sudo hwclock --set --date '2022-03-30 00:00:00.000000+09:00'
```
#### 時刻確認
`RTC time: Tue 2022-03-29 15:00:03`でRTCの時刻が手動更新されたことを確認。
```bash
$ timedatectl
               Local time: Tue 2022-03-29 22:55:51 JST
           Universal time: Tue 2022-03-29 13:55:51 UTC
                 RTC time: Tue 2022-03-29 15:00:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no
```
#### 再起動
```bash
$ sudo reboot
```
#### 時刻確認
- ```System clock synchronized: no```となっておりNTPサーバーに同期はされていない。
- ```Local time: Wed 2022-03-30 00:01:50 JST```Local timeがRTCモジュールに設定した時刻で更新されていることを確認。
```bash
$ timedatectl
               Local time: Wed 2022-03-30 00:01:50 JST
           Universal time: Tue 2022-03-29 15:01:50 UTC
                 RTC time: Tue 2022-03-29 15:01:50
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no
```






### No.2 NTPが有効、ネットワークなし
#### NTPを有効化
```bash
$ sudo timedatectl set-ntp true
```
#### systemd-timesyncdサービスを再起動してNTPサーバの時刻に同期させる
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart systemd-timesyncd
```
#### 時刻確認
(NTPサーバーと同期されている）
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:23:41 JST
           Universal time: Tue 2022-03-29 14:23:41 UTC
                 RTC time: Tue 2022-03-29 14:23:42
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### RTCの時刻をずらす
```bash
$ sudo hwclock --set --date '2022-03-30 00:00:00.000000+09:00'
```
#### 時刻確認
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:24:08 JST
           Universal time: Tue 2022-03-29 14:24:08 UTC
                 RTC time: Tue 2022-03-29 15:00:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### ネットワーク接続を切っておく
#### 再起動
```bash
$ sudo reboot
```
#### 時刻確認
RTCモジュールの時刻で、Local timeが更新されていることを確認。
```bash
$ timedatectl
               Local time: Tue 2022-03-30 00:06:41 JST
           Universal time: Tue 2022-03-29 15:06:41 UTC
                 RTC time: Tue 2022-03-29 15:06:41 
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no
```






### No.3 NTPが有効、ネットワークあり、NTPサーバーに繋がらない
#### NTPを有効化
```bash
$ sudo timedatectl set-ntp true
```
#### systemd-timesyncdサービスを再起動してNTPサーバの時刻に同期させる
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart systemd-timesyncd
```
#### 時刻確認
(NTPサーバーと同期されている）
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:13:41 JST
           Universal time: Tue 2022-03-29 14:13:41 UTC
                 RTC time: Tue 2022-03-29 14:13:42
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### RTCの時刻をずらす
```bash
$ sudo hwclock --set --date '2022-03-30 00:00:00.000000+09:00'
```
#### 時刻確認
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:16:20 JST
           Universal time: Tue 2022-03-29 14:16:20 UTC
                 RTC time: Tue 2022-03-29 15:00:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### NTPサーバーを存在しないものに変更
```/etc/systemd/timesyncd.conf.d/*.conf
[Time]
NTP=timetest.co.jp
#NTP=ntp.jst.mfeed.ad.jp ntp.nict.jp
#FallbackNTP=time.google.com
```
#### 再起動
```bash
$ sudo reboot
```
#### 時刻確認
`System clock synchronized: no`なので、NTPサーバーと同期できていない。
RTCモジュールの時刻で、Local timeが更新されていることを確認。
```bash
$ timedatectl
               Local time: Wed 2022-03-30 00:02:23 JST
           Universal time: Tue 2022-03-29 15:02:23 UTC
                 RTC time: Tue 2022-03-29 15:02:23
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no
```






### No.4 NTPが有効、ネットワークあり、NTPサーバーに繋がる
#### NTPを有効化
```bash
$ sudo timedatectl set-ntp true
```
#### systemd-timesyncdサービスを再起動してNTPサーバの時刻に同期させる
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart systemd-timesyncd
```
#### 時刻確認
(NTPサーバーと同期されている）
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:03:47 JST
           Universal time: Tue 2022-03-29 14:03:47 UTC
                 RTC time: Tue 2022-03-29 14:03:47
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### RTCの時刻をずらす
```bash
$ sudo hwclock --set --date '2022-03-30 00:00:00.000000+09:00'
```
#### 時刻確認
RTCが１時間ずれてる
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:07:15 JST
           Universal time: Tue 2022-03-29 14:07:15 UTC
                 RTC time: Tue 2022-03-29 15:00:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```
#### 再起動
```bash
$ sudo reboot
```
#### 時刻確認
`RTC time`がシステム時刻で更新されていることを確認。
NTPサーバーと同期が入るとRTCモジュールの時刻を更新している。
```bash
$ timedatectl
               Local time: Tue 2022-03-29 23:09:03 JST
           Universal time: Tue 2022-03-29 14:09:03 UTC
                 RTC time: Tue 2022-03-29 14:09:03
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```

NTPサーバーから時刻同期できる場合は、RTCモジュールの時刻も書き換えてくれていることがわかりました。
これで、Raspberry pi起動時に独自にRTCモジュールの時刻を更新するとかやらなくてよくなっています。