NTPSource.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. sync_indicator_pin: 同期インジケーターのGPIO
  30. sync_interval: 同時間隔(分)
  31. """
  32. # Wi-Fi関連
  33. self.ssid = ssid # SSID
  34. self.passwd = passwd # パスフレーズ
  35. # 同期インジケーター
  36. self.sync_led = Pin(sync_indicator_pin, Pin.OUT)
  37. self.sync_led.value(0) # 消灯
  38. # 同時間隔(デフォルト2時間)
  39. self.interval = sync_interval
  40. # タイマー1分
  41. self.tm = Timer()
  42. self.tm.init(mode=Timer.PERIODIC, period=60*1000, callback=self._timer_handler)
  43. # タイマーカウンタ
  44. self.tick_counter = self.interval + 1
  45. # コールバック関数
  46. self._callbacks = []
  47. def _timer_handler(self, t):
  48. self.tick_counter += 1
  49. if self.tick_counter > self.interval: # 同時間隔
  50. self.tick_counter = 0 # カウンタリセット
  51. schedule(self.sync_start, 0)
  52. def sync_start(self, arg=0):
  53. # まずWi-Fi接続
  54. conn = wifi_connect(self.ssid, self.passwd)
  55. if conn is not None:
  56. conn.ifconfig() # IP設定
  57. time.sleep(1) # 安定するまで待つ
  58. ntptime.host = "ntp.nict.jp"
  59. now = ntptime.time() + 9 * 60 * 60 # 日本時間
  60. data = (now, time.ticks_ms()) # (UNIXエポックタイム, 受信ticks_ms)
  61. conn.active(False) # 電源を切る
  62. self.sync_led.value(1) # 同期LED点灯
  63. try:
  64. for callback in self._callbacks:
  65. if callback is not None:
  66. schedule(callback, data)
  67. except RuntimeError:
  68. self.dprint("--- schedule() queue full ---")
  69. else:
  70. self.dprint("--- Cant connect to %s", self.ssid)
  71. def sync_stop(self):
  72. """特にすることはなにもない"""
  73. return
  74. def add_callback(self, callback):
  75. """
  76. 時刻を通知するコールバック関数
  77. """
  78. if callback is not None:
  79. self._callbacks.append(callback)