diff --git a/src/driver/nbiot.be b/src/driver/nbiot.be index 97377dcb088ef81b646d91a83e41d1cc339a5b20..1857b2ea16f144eec9fb2e4eb6215bb376aeb1bc 100644 --- a/src/driver/nbiot.be +++ b/src/driver/nbiot.be @@ -3,6 +3,7 @@ import string class NBIoTRequestType static var MQTT = 1 static var COAP = 2 + static var NTP = 3 end class NBIoTRequest @@ -31,6 +32,12 @@ class NBIoTMQTTRequest : NBIoTRequest end end +class NBIoTNTPRequest : NBIoTRequest + def init() + self.type = NBIoTRequestType.NTP + end +end + class NBIoTCOAPRequest : NBIoTRequest var host var port @@ -79,16 +86,17 @@ end class NBIoTDriverState static var RESET = 1 static var READY = 2 - static var COAP_OPEN = 3 - static var COAP_SET_OPTIONS = 4 - static var COAP_SEND = 5 - static var COAP_RECEIVE = 6 - static var COAP_CLOSE = 7 - static var MQTT_OPEN = 8 - static var MQTT_CONNECT = 9 - static var MQTT_PUBLISH = 10 - static var MQTT_CHECK_CONN = 11 - static var MQTT_CLOSE = 12 + static var NTP_SYNC = 3 + static var MQTT_OPEN = 4 + static var MQTT_CONNECT = 5 + static var MQTT_PUBLISH = 6 + static var MQTT_CHECK_CONN = 7 + static var MQTT_CLOSE = 8 + static var COAP_OPEN = 9 + static var COAP_SET_OPTIONS = 10 + static var COAP_SEND = 11 + static var COAP_RECEIVE = 12 + static var COAP_CLOSE = 13 end class NBIoTDriver @@ -106,7 +114,6 @@ class NBIoTDriver def init(rx, tx) self.state = NBIoTDriverState.RESET self.rsp_awaiting = false - self.payload_awaiting = false self.retries = self.MAX_RETRIES self.request_queue = [] self.request = nil @@ -132,6 +139,21 @@ class NBIoTDriver self.request = nil end + def set_system_time(rsp) + var rsp_args = string.split(rsp, '\"') + var timestamp = nil + + for rsp_arg : rsp_args + timestamp = tasmota.strptime(rsp_arg, "%y/%m/%d,%H:%M:%S") + + if timestamp != nil + break + end + end + + tasmota.cmd('time ' + str(timestamp['epoch'] + 3600)) # UTC + 1 + end + def build_mqtt_open_cmd() var cmd = 'AT+QMTOPEN=0,\"%s\",%s\r\n' @@ -151,37 +173,58 @@ class NBIoTDriver return string.format(cmd, self.request.topic, self.request.payload) end - def rsp_contains_msg(msg) + def send_cmd(cmd) + self.ser.write(bytes().fromstring(cmd)) + self.rsp_awaiting = true + + tasmota.log(string.format('NBT: Sending command \'%s\'', string.replace(cmd, '\r\n', '')), 2) + end + + def rsp_contains_msg(msg, return_rsp) if self.rsp_awaiting var rsp = self.ser.read().asstring() if string.find(rsp, msg) >= 0 self.rsp_awaiting = false + + tasmota.log(string.format('NBT: Received \'%s\'', msg), 2) + if return_rsp + return rsp + end + return true else if self.retries > 0 self.retries -= 1 - tasmota.log(string.format('NBT: state %s retries %s', str(self.state), str(self.retries)), 2) end - - return false end + end + + if return_rsp + return nil else return false end end - def rsp_contains_msg_or_send(msg, cmd) - if self.rsp_contains_msg(msg) - tasmota.log(string.format('NBT: Received \'%s\'', msg), 2) + def fetch_rsp_if_contains_msg_or_send(msg, cmd) + var rsp = self.rsp_contains_msg(msg, true) - return true + if rsp != nil + return rsp else - self.ser.write(bytes().fromstring(cmd)) - self.rsp_awaiting = true + self.send_cmd(cmd) + + return nil + end + end - tasmota.log(string.format('NBT: Sending command \'%s\'', string.replace(cmd, '\r\n', '')), 2) + def rsp_contains_msg_or_send(msg, cmd) + if self.rsp_contains_msg(msg, false) + return true + else + self.send_cmd(cmd) return false end @@ -205,7 +248,9 @@ class NBIoTDriver self.request = self.request_queue[0] self.request_queue.remove(0) - if self.request.type == NBIoTRequestType.MQTT + if self.request.type == NBIoTRequestType.NTP + self.next_state(NBIoTDriverState.NTP_SYNC) + elif self.request.type == NBIoTRequestType.MQTT var mqtt_connection = NBIoTMQTTConnection(self.request.host, self.request.port, self.request.username, @@ -224,18 +269,14 @@ class NBIoTDriver self.finish_request() end end - # ---- send coap request ---- # - elif self.state == NBIoTDriverState.COAP_SET_OPTIONS - if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPOPTION=1,11,\"test\"\r\n') - self.next_state(NBIoTDriverState.COAP_SEND) - end - elif self.state == NBIoTDriverState.COAP_SEND - if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPSEND=1,0,\"37.120.174.40\",5683,0\r\n') - self.next_state(NBIoTDriverState.COAP_RECEIVE) + # ---- fetch time from ntp server ---- # + elif self.state == NBIoTDriverState.NTP_SYNC + var rsp = self.fetch_rsp_if_contains_msg_or_send('+QNTP: 0', 'AT+QNTP=1,\"0.at.pool.ntp.org\"\r\n') + + if rsp != nil + self.set_system_time(rsp) + self.next_state(NBIoTDriverState.READY) end - elif self.state == NBIoTDriverState.COAP_RECEIVE - var msg = self.ser.read().asstring() - print(msg) # ---- punlish mqtt message ---- # elif self.state == NBIoTDriverState.MQTT_CHECK_CONN if self.retries == 1 @@ -267,6 +308,18 @@ class NBIoTDriver self.next_state(NBIoTDriverState.READY) end end + # ---- send coap request ---- # + elif self.state == NBIoTDriverState.COAP_SET_OPTIONS + if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPOPTION=1,11,\"test\"\r\n') + self.next_state(NBIoTDriverState.COAP_SEND) + end + elif self.state == NBIoTDriverState.COAP_SEND + if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPSEND=1,0,\"37.120.174.40\",5683,0\r\n') + self.next_state(NBIoTDriverState.COAP_RECEIVE) + end + elif self.state == NBIoTDriverState.COAP_RECEIVE + var msg = self.ser.read().asstring() + print(msg) else tasmota.log('NBT: Invalid driver state, stopping driver', 2) tasmota.remove_driver(self) @@ -286,6 +339,12 @@ nbiot.init = def (m) tasmota.add_driver(self._driver) end + def sync_time() + var request = NBIoTNTPRequest() + + self._driver.queue_request(request) + end + def mqtt_publish(host, port, username, password, topic, payload, callback) if type(payload) == type('') var request = NBIoTMQTTRequest(host, port, username, password, topic, payload, callback)