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)