NTPSource.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from TimeSource import TimeSource
  2. from TimeSyncer import TimeSyncer
  3. from Debug import Debug
  4. import utime as time
  5. import network
  6. import ntptime
  7. from machine import Timer
  8. from machine import Pin
  9. from micropython import schedule
  10. # Wi-Fi接続
  11. def wifi_connect(ssid, passkey, timeout=20):
  12. conn = network.WLAN(network.STA_IF)
  13. if conn.isconnected():
  14. return conn
  15. conn.active(True)
  16. conn.connect(ssid, passkey)
  17. while not conn.isconnected() and timeout > 0:
  18. time.sleep(1)
  19. timeout -= 1
  20. if conn.isconnected():
  21. return conn
  22. else:
  23. return None
  24. class NTPSource(Debug, TimeSyncer, TimeSource):
  25. """NTP時刻ソース"""
  26. def __init__(self, ssid, passwd, sync_indicator_pin=18, sync_interval=120):
  27. """
  28. Args:
  29. ssid: Wi-Fiアクセスポイント名
  30. passwd: Wi-Fi接続パスフレーズ
  31. sync_indicator_pin: 同期インジケーターのGPIO
  32. sync_interval: 同時間隔(分)
  33. """
  34. # Wi-Fi関連
  35. self.ssid = ssid # SSID
  36. self.passwd = passwd # パスフレーズ
  37. # 同期インジケーター
  38. self.sync_led = Pin(sync_indicator_pin, Pin.OUT)
  39. self.sync_led.value(0) # 消灯
  40. # 同時間隔(デフォルト2時間)
  41. self.interval = sync_interval
  42. # タイマー1分
  43. self.tm = Timer()
  44. self.tm.init(mode=Timer.PERIODIC, period=60*1000, callback=self._timer_handler)
  45. # タイマーカウンタ
  46. self.tick_counter = self.interval + 1
  47. # コールバック関数
  48. self._callbacks = []
  49. def _timer_handler(self, t):
  50. self.tick_counter += 1
  51. if self.tick_counter > self.interval: # 同時間隔
  52. self.tick_counter = 0 # カウンタリセット
  53. schedule(self.sync_start, 0)
  54. def sync_start(self, arg=0):
  55. """同期スタート(引数はダミー)"""
  56. # まずWi-Fi接続
  57. conn = wifi_connect(self.ssid, self.passwd)
  58. if conn is not None:
  59. conn.ifconfig() # IP設定
  60. time.sleep(1) # 安定するまで待つ
  61. ntptime.host = "ntp.nict.jp"
  62. now = ntptime.time() + 9 * 60 * 60 # 日本時間
  63. data = (now, time.ticks_ms()) # (UNIXエポックタイム, 受信ticks_ms)
  64. conn.active(False) # Wi-Fiの電源を切る
  65. self.sync_led.value(1) # 同期LED点灯
  66. try:
  67. for callback in self._callbacks:
  68. if callback is not None:
  69. schedule(callback, data)
  70. except RuntimeError:
  71. self.dprint("--- schedule() queue full ---")
  72. else:
  73. self.dprint("--- Cant connect to %s", self.ssid)
  74. self.sync_led.value(0) # 同期インジケータ消灯
  75. def sync_stop(self):
  76. """特にすることはなにもない"""
  77. return
  78. def add_callback(self, callback):
  79. """
  80. 時刻を通知するコールバック関数
  81. """
  82. if callback is not None:
  83. self._callbacks.append(callback)