diff --git a/src/driver/nbiot.be b/src/driver/nbiot.be
index 000e6a9df474dd66f129d1f47b8eeb0bbad17864..a7b350299f015cb6ac2fb3bdb537209b8e746f00 100644
--- a/src/driver/nbiot.be
+++ b/src/driver/nbiot.be
@@ -10,8 +10,9 @@ class NBIoTRequestType
   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 HTTP = 5
+  static var NTP = 6
+  static var PSM_ENABLE = 7
 end
 
 class NBIoTRequest
@@ -68,18 +69,32 @@ end
 class NBIoTCOAPRequest : NBIoTRequest
   var host
   var port
-  var path
-  var query
+  var paths
+  var method
+  var queries
   var topic
   var payload
 
-  def init(host, port, path, method, query, payload, callback)
+  def init(host, port, paths, method, queries, payload, callback)
     super(self).init(NBIoTRequestType.COAP, callback)
     self.host = host
     self.port = port
-    self.path = path
+    self.paths = paths
+    self.method = method
+    self.queries = queries
+    self.payload = payload
+  end
+end
+
+class NBIoTHTTPRequest : NBIoTRequest
+  var url
+  var method
+  var payload
+
+  def init(url, method, payload, callback)
+    super(self).init(NBIoTRequestType.HTTP, callback)
+    self.url = url
     self.method = method
-    self.query = query
     self.payload = payload
   end
 end
@@ -104,8 +119,56 @@ class NBIoTCommand
   end
 end
 
+class NBIoTReadDriver
+  var ser
+  var buf
+  var flush
+  var printed
+
+  def fetch_and_flush()
+    self.flush = true
+    self.printed = false
+    return self.buf
+  end
+
+  def fast_loop()
+    if self.flush
+      self.buf = ''
+      self.flush = false
+    end
+
+    var bytes_available = self.ser.available()
+
+    if (size(self.buf) + bytes_available) >= 2048
+      self.buf = self.buf[(size(self.buf) + bytes_available) - 2048 ..]
+    end
+
+    if bytes_available != 0
+      self.buf += self.ser.read().asstring()
+    end
+    
+    # todo remove
+    if string.find(self.buf, 'xcx') >= 0 && !self.printed
+      tasmota.log('------time stop------', 2) # todo remove
+      # tasmota.log('buf size: ' + str(size(self.buf)), 2)
+      # tasmota.log(self.buf, 2)
+      self.printed = true
+    end
+  end
+  
+  def init(ser)
+    self.ser = ser
+    self.buf = ''
+    self.flush = false
+    self.printed = false
+
+    tasmota.add_fast_loop(/-> self.fast_loop()) # todo deactivate when psm enabled
+  end
+end
+
 class NBIoTProcedure
   var ser
+  var read_drv
   var request
   var response
   var debug
@@ -114,8 +177,9 @@ class NBIoTProcedure
   var rsp_awaiting
   var cmd_in_process
 
-  def init(ser, request)
+  def init(ser, read_drv, request)
     self.ser = ser
+    self.read_drv = read_drv
     self.request = request
     self.response = nil
     self.debug = false
@@ -134,20 +198,27 @@ class NBIoTProcedure
   end
 
   def send_cmd()
-    self.ser.write(bytes().fromstring(self.cmd_in_process.cmd))
-    self.rsp_awaiting = true
+    if self.cmd_in_process.cmd != nil
+      self.ser.write(bytes().fromstring(self.cmd_in_process.cmd))
 
-    tasmota.log(string.format('NBT: Sending command \'%s\'', string.replace(self.cmd_in_process.cmd, '\r\n', '')), 2)
+      tasmota.log(string.format('NBT: Sending command \'%s\'', string.replace(self.cmd_in_process.cmd, '\r\n', '')), 2)
+    end
+
+    self.rsp_awaiting = true
   end
 
   def read_rsp_contains_expected_rsp(return_rsp)
     if self.rsp_awaiting
-      var rsp = self.ser.read().asstring()
+      var rsp = self.read_drv.fetch_and_flush()
 
       if self.debug
         print(rsp)
       end
 
+      if string.find(rsp, 'OK') >= 0
+        tasmota.log('------time start------', 2) # todo remove
+      end
+
       if string.find(rsp, self.cmd_in_process.rsp) >= 0
         self.rsp_awaiting = false
 
@@ -204,8 +275,8 @@ end
 class NBIoTDebugProcedure : NBIoTProcedure
   var cmd_debug
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
 
     self.debug = true
     self.cmd_debug = NBIoTCommand(request.cmd + '\r\n', request.rsp, request.retries)
@@ -225,8 +296,8 @@ class NBIoTResetProcedure : NBIoTProcedure
   var cmd_reset
   var cmd_at
 
-  def init(ser)
-    super(self).init(ser)
+  def init(ser, read_drv)
+    super(self).init(ser, read_drv)
 
     self.cmd_reset = NBIoTCommand('AT+QRST=1\r\n', 'RDY', 10)
     self.cmd_at = NBIoTCommand('AT\r\n', 'OK')
@@ -252,8 +323,8 @@ class NBIoTEnablePSMProcedure : NBIoTProcedure
   var cmd_enable_psm
   var cmd_enable_sleep
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
 
     self.cmd_register = NBIoTCommand('AT+CEREG=5\r\n', 'OK', 10)
     self.cmd_enable_psm = NBIoTCommand('AT+CPSMS=1,,,\"01011111\",\"00000001\"\r\n', 'OK', 10)
@@ -282,8 +353,8 @@ class NBIoTDisablePSMProcedure : NBIoTProcedure
   var cmd_disable_psm
   var cmd_disable_sleep
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv)
+    super(self).init(ser, read_drv)
 
     self.cmd_register = NBIoTCommand('AT+CEREG=1\r\n', 'OK')
     self.cmd_disable_psm = NBIoTCommand('AT+CPSMS=0\r\n', 'OK')
@@ -309,16 +380,14 @@ class NBIoTMQTTConnectProcedure : NBIoTProcedure
   var cmd_open
   var cmd_conn
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, 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', 15)
+    self.cmd_open = NBIoTCommand(string.format(cmd, request.host, str(request.port)), '+QMTOPEN: 0,0', 15)
 
     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', 
-                                 15)
+    self.cmd_conn = NBIoTCommand(string.format(cmd, request.client, request.username, request.password), '+QMTCONN: 0,0,0', 15)
   end
 
   def execute()
@@ -340,13 +409,13 @@ class NBIoTMQTTPublishProcedure : NBIoTProcedure
   var cmd_conn
   var cmd_pub
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, 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)
+    self.cmd_pub = NBIoTCommand(string.format(cmd, request.topic, request.payload), '+QMTPUB: 0,0,0', 10)
   end
 
   def execute()
@@ -367,8 +436,8 @@ end
 class NBIoTMQTTDisconnectProcedure : NBIoTProcedure
   var cmd_close
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
 
     self.cmd_close = NBIoTCommand('AT+QMTCLOSE=0\r\n', '+QMTCLOSE: 0,0', 10)
   end
@@ -386,8 +455,8 @@ end
 class NBIoTNTPProcedure : NBIoTProcedure
   var cmd_ntp
 
-  def init(ser, request)
-    super(self).init(ser, request)
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
 
     self.cmd_ntp = NBIoTCommand('AT+QNTP=1,\"0.at.pool.ntp.org\"\r\n', '+QNTP: 0', 10)
   end
@@ -412,7 +481,7 @@ class NBIoTNTPProcedure : NBIoTProcedure
       self.cmd_in_process = self.cmd_ntp
     end
 
-    var rsp = self.fetch_read_rsp_if_contains_expected_rsp_or_send('+QNTP: 0', 'AT+QNTP=1,\"0.at.pool.ntp.org\"\r\n')
+    var rsp = self.fetch_read_rsp_if_contains_expected_rsp_or_send()
 
     if rsp != nil
       self.response = self.extract_timestamp(rsp)
@@ -423,6 +492,124 @@ class NBIoTNTPProcedure : NBIoTProcedure
   end
 end
 
+class NBIoTCOAPGetProcedure : NBIoTProcedure
+  var cmd_create
+  var cmd_url
+  var cmd_send
+  var cmd_del
+
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
+
+    self.cmd_create = NBIoTCommand('AT+QCOAPCREATE=1,0\r\n', 'OK', 10)
+    
+    var cmd = string.format('AT+QCOAPOPTION=%i', request.paths.size() + request.queries.size())
+  
+    for path : request.paths
+      cmd += string.format(',11,\"%s\"', path)
+    end
+
+    for query : request.queries
+      cmd += string.format(',11,\"%s\"', query)
+    end
+ 
+    cmd += '\r\n'
+
+    self.cmd_url = NBIoTCommand(cmd, 'OK', 10)
+    
+    cmd = 'AT+QCOAPSEND=0,1,\"%s\",%s,0\r\n'
+    self.cmd_send = NBIoTCommand(string.format(cmd, request.host, str(request.port)), '+QCOAPSEND: 0', 1)
+    self.cmd_del = NBIoTCommand('AT+QCOAPDEL\r\n', 'OK', 10)
+  end
+
+  def execute()
+    if self.cmd_in_process == nil
+      self.cmd_in_process = self.cmd_create
+    end
+    
+    if self.cmd_in_process == self.cmd_create && self.read_rsp_contains_expected_rsp_or_send()
+      self.cmd_in_process = self.cmd_url
+    elif self.cmd_in_process == self.cmd_url && self.read_rsp_contains_expected_rsp_or_send()
+      self.cmd_in_process = self.cmd_send
+
+      if !self.done
+        self.read_rsp_contains_expected_rsp_or_send()
+        self.ser.flush()
+      end
+
+      self.done = true
+    end
+    
+    self.aborted = self.retries_exceeded()
+  end
+end
+
+class NBIoTHTTPGetProcedure : NBIoTProcedure
+  var cmd_url
+  var cmd_input
+  var cmd_get
+  var cmd_wait
+  var cmd_read
+  var payload_size
+
+  def init(ser, read_drv, request)
+    super(self).init(ser, read_drv, request)
+
+    var url = request.url
+
+    if size(url) > 0 && url[size(url)-1] != '/'
+      url += '/'
+    end
+
+    self.cmd_url = NBIoTCommand(string.format('AT+QHTTPURL=%i,15\r\n', size(url)), '>', 30)
+    self.cmd_input = NBIoTCommand(string.format('%s\r\n', url), 'OK', 30)
+    self.cmd_get = NBIoTCommand('AT+QHTTPGET=15\r\n', 'OK', 50)
+    self.cmd_wait = NBIoTCommand(nil, '+QHTTPGET: 0,', 100)
+    self.cmd_read = NBIoTCommand('AT+QHTTPREAD=256\r\n', '+QHTTPREAD:', 100)
+
+    self.payload_size = 0
+    self.response = ''
+  end
+  
+  def execute()
+    if self.cmd_in_process == nil
+      self.cmd_in_process = self.cmd_url
+    end
+    
+    if self.cmd_in_process == self.cmd_url && self.read_rsp_contains_expected_rsp_or_send()
+      self.cmd_in_process = self.cmd_input
+    elif self.cmd_in_process == self.cmd_input && self.read_rsp_contains_expected_rsp_or_send()
+      self.cmd_in_process = self.cmd_get
+    elif self.cmd_in_process == self.cmd_get && self.read_rsp_contains_expected_rsp_or_send()
+      self.cmd_in_process = self.cmd_wait
+    elif self.cmd_in_process == self.cmd_wait
+      var rsp = self.fetch_read_rsp_if_contains_expected_rsp_or_send()
+
+      if rsp != nil
+        var params = string.split(rsp, ',')
+        var payload_size = params[params.size()-1]
+
+        self.payload_size = int(string.replace(payload_size, '\r\n', '')) + 256
+        self.cmd_in_process = self.cmd_read
+      end
+    elif self.cmd_in_process == self.cmd_read
+      var rsp = self.fetch_read_rsp_if_contains_expected_rsp_or_send()
+
+      if rsp != nil
+        self.response += rsp # todo filter
+        # print('rsp ' + rsp)
+        self.done = size(self.response) > self.payload_size
+
+        if self.done
+          # print(self.response)
+        end
+      end
+    end
+    
+    self.aborted = self.retries_exceeded()
+  end
+end
+
 # ------------------------------------------------------- #
 #                       Driver State                      #
 # ------------------------------------------------------- #
@@ -434,6 +621,22 @@ class NBIoTDriverState
   static var DISABLE_PSM = 3
   static var READY = 4
   static var BUSY = 5
+
+  static def tostring(state)
+    if state == NBIoTDriverState.INIT
+      return 'INIT'
+    elif state == NBIoTDriverState.PSM
+      return 'PSM'
+    elif state == NBIoTDriverState.RESET
+      return 'RESET'
+    elif state == NBIoTDriverState.DISABLE_PSM
+      return 'DISABLE_PSM'
+    elif state == NBIoTDriverState.READY
+      return 'READY'
+    elif state == NBIoTDriverState.BUSY
+      return 'BUSY'
+    end
+  end
 end
 
 # ------------------------------------------------------- #
@@ -443,6 +646,7 @@ end
 class NBIoTDriver
   var ser
   var psm_eint
+  var read_drv
   var state
   var request_queue
   var procedure
@@ -452,6 +656,8 @@ class NBIoTDriver
     self.ser = serial(rx, tx, 115200, serial.SERIAL_8N1)
     self.psm_eint = psm_eint
 
+    self.read_drv = NBIoTReadDriver(self.ser)
+
     self.state = NBIoTDriverState.INIT
     self.request_queue = []
     self.procedure = nil
@@ -497,7 +703,10 @@ class NBIoTDriver
   end
 
   def next_state(state)
-    tasmota.log(string.format('NBT: Transitioning from state %i to %i', self.state, state), 2)
+    var current_state = NBIoTDriverState.tostring(self.state)
+    var next_state = NBIoTDriverState.tostring(state)
+
+    tasmota.log(string.format('NBT: Transitioning from state %s to %s', current_state, next_state), 2)
 
     self.state = state
   end
@@ -520,7 +729,7 @@ class NBIoTDriver
     tasmota.set_timer(150, /-> self.set_psm_pin_high())
   end
 
-  def every_second()
+  def every_250ms()
     if self.state == NBIoTDriverState.PSM
       if self.psm_disabled
         self.next_state(NBIoTDriverState.INIT)
@@ -532,7 +741,7 @@ class NBIoTDriver
       tasmota.set_timer(150, /-> self.wake_up())
     elif self.state == NBIoTDriverState.RESET
       if self.procedure == nil
-        self.start_procedure(NBIoTResetProcedure(self.ser))
+        self.start_procedure(NBIoTResetProcedure(self.ser, self.read_drv))
       end
 
       self.procedure.execute()
@@ -550,7 +759,7 @@ class NBIoTDriver
       end
     elif self.state == NBIoTDriverState.DISABLE_PSM
       if self.procedure == nil
-        self.start_procedure(NBIoTDisablePSMProcedure(self.ser))
+        self.start_procedure(NBIoTDisablePSMProcedure(self.ser, self.read_drv))
       end
 
       self.procedure.execute()
@@ -568,17 +777,21 @@ class NBIoTDriver
         var procedure = nil
 
         if request.request_type == NBIoTRequestType.DEBUG
-          procedure = NBIoTDebugProcedure(self.ser, request)
+          procedure = NBIoTDebugProcedure(self.ser, self.read_drv, request)
         elif request.request_type == NBIoTRequestType.MQTT_CONN
-          procedure = NBIoTMQTTConnectProcedure(self.ser, request)
+          procedure = NBIoTMQTTConnectProcedure(self.ser, self.read_drv, request)
         elif request.request_type == NBIoTRequestType.MQTT_PUB
-          procedure = NBIoTMQTTPublishProcedure(self.ser, request)
+          procedure = NBIoTMQTTPublishProcedure(self.ser, self.read_drv, request)
         elif request.request_type == NBIoTRequestType.MQTT_DISC
-          procedure = NBIoTMQTTDisconnectProcedure(self.ser, request)
+          procedure = NBIoTMQTTDisconnectProcedure(self.ser, self.read_drv, request)
         elif request.request_type == NBIoTRequestType.NTP
-          procedure = NBIoTNTPProcedure(self.ser, request)
+          procedure = NBIoTNTPProcedure(self.ser, self.read_drv, request)
+        elif request.request_type == NBIoTRequestType.COAP && request.method == 'GET'
+          procedure = NBIoTCOAPGetProcedure(self.ser, self.read_drv, request)
+        elif request.request_type == NBIoTRequestType.HTTP && request.method == 'GET'
+          procedure = NBIoTHTTPGetProcedure(self.ser, self.read_drv, request)
         elif request.request_type == NBIoTRequestType.PSM_ENABLE
-          procedure = NBIoTEnablePSMProcedure(self.ser, request)
+          procedure = NBIoTEnablePSMProcedure(self.ser, self.read_drv, request)
         else
           tasmota.log(string.format('NBT: Request with type %i not supported, discarding request', request.request_type), 2)
         end
@@ -675,21 +888,27 @@ nbiot.init = def (m)
       return self._driver.queue_request(request)
     end
 
-    def coap_get(host, port, path, query, callback)
-      if type(path) != type([]) || type(query) != type([])
+    def http_get(url, callback)
+      var request = NBIoTHTTPRequest(url, 'GET', nil, callback)
+
+      return self._driver.queue_request(request)
+    end
+
+    def coap_get(host, port, paths, queries, callback)
+      if type(paths) != type([]) || type(queries) != type([])
         return false
       else
-        var request = NBIoTCOAPRequest(host, port, path, 'GET', query, nil, callback)
+        var request = NBIoTCOAPRequest(host, port, paths, 'GET', queries, nil, callback)
 
         return self._driver.queue_request(request)
       end
     end
 
-    def coap_post(host, port, path, payload, callback)
-      if type(path) != type([])
+    def coap_post(host, port, paths, payload, callback)
+      if type(paths) != type([])
         return false
       else
-        var request = NBIoTCOAPRequest(host, port, path, 'POST', [], payload, callback)
+        var request = NBIoTCOAPRequest(host, port, paths, 'POST', [], payload, callback)
 
         return self._driver.queue_request(request)
       end