diff --git a/src/driver/nbiot.be b/src/driver/nbiot.be
index 085598f1a9492339fe1ac085752dcc7e31369f37..17ba6b928d00e325a4f8b3a5a3039e716f2eac7a 100644
--- a/src/driver/nbiot.be
+++ b/src/driver/nbiot.be
@@ -1,41 +1,156 @@
import string
+class NBIoTRequestType
+ static var MQTT = 1
+ static var COAP = 2
+end
+
+class NBIoTRequest
+ var type
+end
+
+class NBIoTMQTTRequest : NBIoTRequest
+ var type
+ var host
+ var port
+ var username
+ var password
+ var topic
+ var payload
+ var callback
+
+ def init(host, port, username, password, topic, payload, callback)
+ self.type = NBIoTRequestType.MQTT
+ self.host = host
+ self.port = port
+ self.username = username
+ self.password = password
+ self.topic = topic
+ self.payload = payload
+ self.callback = callback
+ end
+end
+
+class NBIoTCOAPRequest : NBIoTRequest
+ var host
+ var port
+ var path
+ var query
+ var topic
+ var payload
+ var callback
+
+ def init(host, port, path, method, query, payload, callback)
+ self.type = NBIoTRequestType.COAP
+ self.host = host
+ self.port = port
+ self.path = path
+ self.method = method
+ self.query = query
+ self.payload = payload
+ self.callback = callback
+ end
+end
+
+class NBIoTMQTTConnection
+ var host
+ var port
+ var username
+ var password
+
+ def init(host, port, username, password)
+ self.host = host
+ self.port = port
+ self.username = username
+ self.password = password
+ end
+
+ def equals(other)
+ var equal = true
+ equal = equal && self.host == other.host
+ equal = equal && self.port == other.port
+ equal = equal && self.username == other.username
+ equal = equal && self.password == other.password
+
+ return equal
+ end
+end
+
class NBIoTDriverState
static var RESET = 1
- static var INIT_COAP = 2
- static var INIT_MQTT = 3
- static var READY = 4
- static var COAP_SET_OPTIONS = 5
- static var COAP_SEND = 6
- static var COAP_RECEIVE = 7
+ 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
end
class NBIoTDriver
var ser
var state
- var send_queue
- var send_request
- var ok_awaiting
+ var rsp_awaiting
var payload_awaiting
var retries
+ var request_queue
+ var request
+ var mqtt_connection
def init(rx, tx)
self.state = NBIoTDriverState.RESET
- self.send_queue = []
- self.send_request = nil
- self.ok_awaiting = false
+ self.rsp_awaiting = false
+ self.payload_awaiting = false
self.retries = 0
+ self.request_queue = []
+ self.request = nil
+ self.mqtt_connection = nil
self.ser = serial(rx, tx, 115200, serial.SERIAL_8N1)
end
- def check_ok()
- if self.ok_awaiting
- var msg = self.ser.read().asstring()
- print(msg)
+ def queue_request(request)
+ self.request_queue.push(request)
+ end
+
+ def finish_request(payload)
+ if self.request.callback != nil
+ self.request.callback(payload)
+ end
+
+ self.request = nil
+ end
+
+ def build_mqtt_open_cmd()
+ var cmd = 'AT+QMTOPEN=0,\"%s\",%s\r\n'
+
+ return string.format(cmd, self.request.host, str(self.request.port))
+ end
- if string.find(msg,'OK') >= 0
- self.ok_awaiting = false
+ def build_mqtt_conn_cmd()
+ var client_id = 'nb-iot' # todo: change
+ var cmd = 'AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n'
+
+ return string.format(cmd, client_id, self.request.username, self.request.password)
+ end
+
+ def build_mqtt_pub_cmd()
+ var cmd = 'AT+QMTPUB=0,0,0,0,\"%s\",\"%s\"\r\n'
+
+ return string.format(cmd, self.request.topic, self.request.payload)
+ end
+
+ def rsp_contains_msg(msg)
+ if self.rsp_awaiting
+ var rsp = self.ser.read().asstring()
+ print(rsp)
+
+ if string.find(rsp, msg) >= 0
+ self.rsp_awaiting = false
return true
else
@@ -50,54 +165,90 @@ class NBIoTDriver
end
end
- def check_ok_or_send(cmd)
- if self.check_ok()
+ def rsp_contains_msg_or_send(msg, cmd)
+ if self.rsp_contains_msg(msg)
return true
else
print('send ' + cmd)
self.ser.write(bytes().fromstring(cmd))
- self.ok_awaiting = true
+ self.rsp_awaiting = true
return false
end
end
- def check_ready()
- var msg = self.ser.read().asstring()
- print(msg)
-
- return string.find(msg,'RDY') >= 0
- end
-
- def reset()
- self.ser.write(bytes().fromstring('AT+QRST=1\r\n'))
- print('write AT+QRST')
- end
-
def every_second()
+ # ---- RESET ---- #
if self.state == NBIoTDriverState.RESET
- if !self.check_ready()
- self.reset()
- else
- self.state = NBIoTDriverState.INIT_COAP
+ if self.rsp_contains_msg_or_send('RDY', 'AT+QRST=1\r\n')
+ self.state = NBIoTDriverState.READY
end
- elif self.state == NBIoTDriverState.INIT_COAP
- if self.check_ok_or_send('AT+QCOAPCREATE=1,0\r\n')
- self.state = NBIoTDriverState.COAP_SET_OPTIONS
+ # ---- READY ---- #
+ elif self.state == NBIoTDriverState.READY
+ if self.request_queue.size() > 0
+ self.request = self.request_queue[0]
+ self.request_queue.remove(0)
+
+ if self.request.type == NBIoTRequestType.MQTT
+ var mqtt_connection = NBIoTMQTTConnection(self.request.host,
+ self.request.port,
+ self.request.username,
+ self.request.password)
+
+ if self.mqtt_connection != nil && self.mqtt_connection.equals(mqtt_connection)
+ self.state = NBIoTDriverState.MQTT_CHECK_CONN
+ elif self.mqtt_connection != nil
+ self.mqtt_connection = mqtt_connection
+ self.state = NBIoTDriverState.MQTT_CLOSE
+ else
+ self.mqtt_connection = mqtt_connection
+ self.state = NBIoTDriverState.MQTT_OPEN
+ end
+ else
+ self.finish_request()
+ end
end
+ # ---- COAP ---- #
elif self.state == NBIoTDriverState.COAP_SET_OPTIONS
- if self.check_ok_or_send('AT+QCOAPOPTION=1,11,\"test\"\r\n')
+ if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPOPTION=1,11,\"test\"\r\n')
self.state = NBIoTDriverState.COAP_SEND
end
elif self.state == NBIoTDriverState.COAP_SEND
- if self.check_ok_or_send('AT+QCOAPSEND=1,0,\"37.120.174.40\",5683,0\r\n')
+ if self.rsp_contains_msg_or_send('OK', 'AT+QCOAPSEND=1,0,\"37.120.174.40\",5683,0\r\n')
self.state = NBIoTDriverState.COAP_RECEIVE
end
elif self.state == NBIoTDriverState.COAP_RECEIVE
var msg = self.ser.read().asstring()
print(msg)
+ # ---- MQTT ---- #
+ elif self.state == NBIoTDriverState.MQTT_CHECK_CONN
+ if self.rsp_contains_msg_or_send('+QMTCONN: 0,3', 'AT+QMTCONN?\r\n')
+ self.state = NBIoTDriverState.MQTT_PUBLISH
+ end
+ elif self.state == NBIoTDriverState.MQTT_OPEN
+ if self.rsp_contains_msg_or_send('+QMTOPEN: 0,0', self.build_mqtt_open_cmd())
+ self.state = NBIoTDriverState.MQTT_CONNECT
+ end
+ elif self.state == NBIoTDriverState.MQTT_CONNECT
+ if self.rsp_contains_msg_or_send('+QMTCONN: 0,0,0', self.build_mqtt_conn_cmd())
+ self.state = NBIoTDriverState.MQTT_PUBLISH
+ end
+ elif self.state == NBIoTDriverState.MQTT_PUBLISH
+ if self.rsp_contains_msg_or_send('+QMTPUB: 0,0,0', self.build_mqtt_pub_cmd())
+ self.finish_request()
+
+ self.state = NBIoTDriverState.READY
+ end
+ elif self.state == NBIoTDriverState.MQTT_CLOSE
+ if self.rsp_contains_msg_or_send('+QMTDISC: 0,0', 'AT+QMTDISC=0\r\n')
+ if self.request != nil
+ self.state = NBIoTDriverState.MQTT_OPEN
+ else
+ self.state = NBIoTDriverState.READY
+ end
+ end
else
- print('duuude')
+ tasmota.remove_driver(self)
end
end
end
@@ -114,6 +265,42 @@ nbiot.init = def (m)
tasmota.add_driver(self._driver)
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)
+
+ self._driver.queue_request(request)
+
+ return true
+ else
+ return false
+ end
+ end
+
+ def coap_get(host, port, path, query, callback)
+ if type(path) != type([]) || type(query) != type([])
+ return false
+ else
+ var request = NBIoTCOAPRequest(host, port, path, 'GET', query, nil, callback)
+
+ self._driver.queue_request(request)
+
+ return true
+ end
+ end
+
+ def coap_post(host, port, path, payload, callback)
+ if type(path) != type([])
+ return false
+ else
+ var request = NBIoTCOAPRequest(host, port, path, 'POST', [], payload, callback)
+
+ self._driver.queue_request(request)
+
+ return true
+ end
+ end
end
return nbiot()