diff --git a/src/driver/nbiot.be b/src/driver/nbiot.be index 1cfe03078ad2e653fb6cb9eca4902b39f27af956..a831a83ef9e79ba3c8976bbcba80e53f0bcf31f8 100644 --- a/src/driver/nbiot.be +++ b/src/driver/nbiot.be @@ -6,10 +6,13 @@ import gpio # ------------------------------------------------------- # class NBIoTRequestType static var DEBUG = 0 - static var MQTT = 1 - static var COAP = 2 - static var NTP = 3 - static var PSM = 4 + static var MQTT_CONN = 1 + static var MQTT_PUB = 2 + static var MQTT_DISC = 3 + static var COAP = 4 + static var NTP = 5 + static var PSM_ENABLE = 6 + static var PSM_DISABLE = 7 end class NBIoTRequest @@ -35,20 +38,29 @@ class NBIoTDebugRequest : NBIoTRequest end end -class NBIoTMQTTRequest : NBIoTRequest +class NBIoTMQTTConnectRequest : NBIoTRequest var host var port + var client var username var password - var topic - var payload - def init(host, port, username, password, topic, payload, callback) - super(self).init(NBIoTRequestType.MQTT, callback) + def init(host, port, client, username, password, callback) + super(self).init(NBIoTRequestType.MQTT_CONN, callback) self.host = host self.port = port + self.client = client self.username = username self.password = password + end +end + +class NBIoTMQTTPublishRequest : NBIoTRequest + var topic + var payload + + def init(topic, payload, callback) + super(self).init(NBIoTRequestType.MQTT_PUB, callback) self.topic = topic self.payload = payload end @@ -73,49 +85,6 @@ class NBIoTCOAPRequest : NBIoTRequest end end -class NBIoTNTPRequest : NBIoTRequest - def init(callback) - super(self).init(NBIoTRequestType.NTP, callback) - end -end - -class NBIoTPSMRequest : NBIoTRequest - var value - - def init(value, callback) - super(self).init(NBIoTRequestType.PSM, callback) - self.value = value - end -end - -# ------------------------------------------------------- # -# Connections # -# ------------------------------------------------------- # - -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 - # ------------------------------------------------------- # # Procedures # # ------------------------------------------------------- # @@ -265,10 +234,8 @@ class NBIoTResetProcedure : NBIoTProcedure def execute() if self.cmd_in_process == nil self.cmd_in_process = self.cmd_reset - elif self.cmd_in_process == self.cmd_reset - if self.read_rsp_contains_expected_rsp_or_send() - self.cmd_in_process = self.cmd_at - end + elif self.cmd_in_process == self.cmd_reset && self.read_rsp_contains_expected_rsp_or_send() + self.cmd_in_process = self.cmd_at elif self.cmd_in_process == self.cmd_at self.done = self.read_rsp_contains_expected_rsp_or_send() end @@ -291,20 +258,90 @@ class NBIoTDisablePSMProcedure : NBIoTProcedure def execute() if self.cmd_in_process == nil self.cmd_in_process = self.cmd_register - elif self.cmd_in_process == self.cmd_register - if self.read_rsp_contains_expected_rsp_or_send() - self.cmd_in_process = self.cmd_disable_psm - end - elif self.cmd_in_process == self.cmd_disable_psm - if self.read_rsp_contains_expected_rsp_or_send() - self.cmd_in_process = self.cmd_disable_sleep - end + elif self.cmd_in_process == self.cmd_register && self.read_rsp_contains_expected_rsp_or_send() + self.cmd_in_process = self.cmd_disable_psm + elif self.cmd_in_process == self.cmd_disable_psm && self.read_rsp_contains_expected_rsp_or_send() + self.cmd_in_process = self.cmd_disable_sleep elif self.cmd_in_process == self.cmd_disable_sleep self.done = self.read_rsp_contains_expected_rsp_or_send() end end end +class NBIoTMQTTConnectProcedure : NBIoTProcedure + var cmd_open + var cmd_conn + + def init(ser, request) + super(self).init(ser, request) + + var cmd = 'AT+QMTOPEN=0,\"%s\",%s\r\n' + self.cmd_open = NBIoTCommand(string.format(cmd, self.request.host, str(self.request.port)), '+QMTOPEN: 0,0', 10) + + cmd = 'AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n' + self.cmd_conn = NBIoTCommand(string.format(cmd, self.request.client, self.request.username, self.request.password), + '+QMTCONN: 0,0,0', + 10) + end + + def execute() + if self.cmd_in_process == nil + self.cmd_in_process = self.cmd_open + elif self.cmd_in_process == self.cmd_open && self.read_rsp_contains_expected_rsp_or_send() + self.cmd_in_process = self.cmd_conn + elif self.cmd_in_process == self.cmd_conn + self.done = self.read_rsp_contains_expected_rsp_or_send() + end + + self.aborted = self.retries_exceeded() + end +end + +class NBIoTMQTTPublishProcedure : NBIoTProcedure + var cmd_conn + var cmd_pub + + def init(ser, request) + super(self).init(ser, request) + + self.cmd_conn = NBIoTCommand('AT+QMTCONN?\r\n', '+QMTCONN: 0,3', 10) + + var cmd = 'AT+QMTPUB=0,0,0,0,\"%s\",\"%s\"\r\n' + self.cmd_pub = NBIoTCommand(string.format(cmd, self.request.topic, self.request.payload), '+QMTPUB: 0,0,0', 10) + end + + def execute() + if self.cmd_in_process == nil + self.cmd_in_process = self.cmd_conn + elif self.cmd_in_process == self.cmd_conn && self.read_rsp_contains_expected_rsp_or_send() + self.cmd_in_process = self.cmd_pub + elif self.cmd_in_process == self.cmd_pub + self.done = self.read_rsp_contains_expected_rsp_or_send() + end + + self.aborted = self.retries_exceeded() + end +end + +class NBIoTMQTTDisconnectProcedure : NBIoTProcedure + var cmd_close + + def init(ser, request) + super(self).init(ser, request) + + self.cmd_close = NBIoTCommand('AT+QMTCLOSE=0\r\n', '+QMTCLOSE: 0,0', 10) + end + + def execute() + if self.cmd_in_process == nil + self.cmd_in_process = self.cmd_close + end + + self.done = self.read_rsp_contains_expected_rsp_or_send() + self.aborted = self.retries_exceeded() + end +end + class NBIoTNTPProcedure : NBIoTProcedure var cmd_ntp @@ -368,6 +405,7 @@ class NBIoTDriver var state var request_queue var procedure + var psm_disabled def init(rx, tx, psm_eint) self.ser = serial(rx, tx, 115200, serial.SERIAL_8N1) @@ -376,6 +414,7 @@ class NBIoTDriver self.state = NBIoTDriverState.INIT self.request_queue = [] self.procedure = nil + self.psm_disabled = false end def queue_request(request) @@ -387,8 +426,8 @@ class NBIoTDriver end def finish_procedure(done) - if done && self.procedure.request != nil && self.procedure.request.callback != nil - self.procedure.request.callback() + if self.procedure.request != nil && self.procedure.request.callback != nil + self.procedure.request.callback(done, nil) end self.procedure = nil @@ -401,6 +440,8 @@ class NBIoTDriver end def set_psm_pin(value) + tasmota.log(string.format('NBT: Setting PSM_EINT pin to %i', value), 2) + gpio.digital_write(self.psm_eint, value) end @@ -419,7 +460,12 @@ class NBIoTDriver if self.procedure.is_done() self.finish_procedure() - self.next_state(NBIoTDriverState.DISABLE_PSM) + + if self.psm_disabled + self.next_state(NBIoTDriverState.READY) + else + self.next_state(NBIoTDriverState.DISABLE_PSM) + end end elif self.state == NBIoTDriverState.DISABLE_PSM if self.procedure == nil @@ -429,6 +475,7 @@ class NBIoTDriver self.procedure.execute() if self.procedure.is_done() + self.psm_disabled = true self.finish_procedure() self.next_state(NBIoTDriverState.READY) end @@ -441,6 +488,12 @@ class NBIoTDriver if request.request_type == NBIoTRequestType.DEBUG procedure = NBIoTDebugProcedure(self.ser, request) + elif request.request_type == NBIoTRequestType.MQTT_CONN + procedure = NBIoTMQTTConnectProcedure(self.ser, request) + elif request.request_type == NBIoTRequestType.MQTT_PUB + procedure = NBIoTMQTTPublishProcedure(self.ser, request) + elif request.request_type == NBIoTRequestType.MQTT_DISC + procedure = NBIoTMQTTDisconnectProcedure(self.ser, request) elif request.request_type == NBIoTRequestType.NTP procedure = NBIoTNTPProcedure(self.ser, request) elif @@ -488,28 +541,40 @@ nbiot.init = def (m) tasmota.add_driver(self._driver) end - def set_power_save_mode(value, callback) - var request = NBIoTPSMRequest(value, callback) + def enable_power_save_mode(callback) + var request = NBIoTRequest(NBIoTRequestType.PSM_ENABLE, callback) + + self._driver.queue_request(request) + end + + def disable_power_save_mode(callback) + var request = NBIoTRequest(NBIoTRequestType.PSM_DISABLE, callback) self._driver.queue_request(request) end def sync_time(callback) - var request = NBIoTNTPRequest(callback) + var request = NBIoTRequest(callback) 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) + def mqtt_connect(host, port, client, username, password, callback) + var request = NBIoTMQTTConnectRequest(host, port, client, username, password, callback) - self._driver.queue_request(request) - - return true - else - return false - end + self._driver.queue_request(request) + end + + def mqtt_disconnect(callback) + var request = NBIoTRequest(NBIoTRequestType.MQTT_DISC, callback) + + self._driver.queue_request(request) + end + + def mqtt_publish(topic, payload, callback) + var request = NBIoTMQTTPublishRequest(topic, payload, callback) + + self._driver.queue_request(request) end def coap_get(host, port, path, query, callback)