mirror of https://github.com/arendst/Tasmota.git
Update debug_panel (#20449)
This commit is contained in:
parent
69d4e323d6
commit
151e201048
|
@ -21,8 +21,6 @@ class debug_panel
|
||||||
var port
|
var port
|
||||||
var web
|
var web
|
||||||
var sampling_interval
|
var sampling_interval
|
||||||
#
|
|
||||||
var payload1, payload2 # temporary object bytes() to avoid reallocation
|
|
||||||
|
|
||||||
static var SAMPLING = 100
|
static var SAMPLING = 100
|
||||||
static var HTML_HEAD1 =
|
static var HTML_HEAD1 =
|
||||||
|
@ -73,8 +71,6 @@ class debug_panel
|
||||||
self.port = port
|
self.port = port
|
||||||
self.web = webserver_async(port)
|
self.web = webserver_async(port)
|
||||||
self.sampling_interval = self.SAMPLING
|
self.sampling_interval = self.SAMPLING
|
||||||
self.payload1 = bytes(100) # reserve 100 bytes by default
|
|
||||||
self.payload2 = bytes(100) # reserve 100 bytes by default
|
|
||||||
|
|
||||||
self.web.set_chunked(true)
|
self.web.set_chunked(true)
|
||||||
self.web.set_cors(true)
|
self.web.set_cors(true)
|
||||||
|
@ -110,30 +106,74 @@ class debug_panel
|
||||||
cnx.content_stop()
|
cnx.content_stop()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
static class feeder
|
||||||
|
var cnx # connection object
|
||||||
|
|
||||||
|
def init(cnx)
|
||||||
|
self.cnx = cnx
|
||||||
|
tasmota.add_driver(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def close()
|
||||||
|
tasmota.remove_driver(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def every_100ms()
|
||||||
|
self.send_feed()
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_feed()
|
||||||
|
var cnx = self.cnx
|
||||||
|
if !cnx.connected()
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
var payload1 = self.cnx.server.payload1
|
||||||
|
var payload2 = self.cnx.server.payload2
|
||||||
|
var server = self.cnx.server
|
||||||
|
if cnx.buf_out_empty()
|
||||||
|
# if out buffer is not empty, do not send any new information
|
||||||
|
# var payload
|
||||||
|
# send free heap
|
||||||
|
payload1.clear()
|
||||||
|
payload1 .. "id:"
|
||||||
|
server.bytes_format_int(payload2, tasmota.millis())
|
||||||
|
payload1 .. payload2
|
||||||
|
payload1 .. "\r\nevent:free_heap\r\ndata:"
|
||||||
|
server.bytes_format_int(payload2, tasmota.memory('heap_free'), '---')
|
||||||
|
payload1 .. payload2
|
||||||
|
payload1 .. " KB\r\n\r\n"
|
||||||
|
# payload = f"id:{tasmota.millis()}\r\n"
|
||||||
|
# "event:free_heap\r\n"
|
||||||
|
# "data:{tasmota.memory().find('heap_free', 0)} KB\r\n\r\n"
|
||||||
|
cnx.write(payload1)
|
||||||
|
|
||||||
|
# send wifi rssi
|
||||||
|
payload1.clear()
|
||||||
|
payload1 .. "id:"
|
||||||
|
server.bytes_format_int(payload2, tasmota.millis())
|
||||||
|
payload1 .. payload2
|
||||||
|
payload1 .. "\r\nevent:wifi_rssi\r\ndata:"
|
||||||
|
server.bytes_format_int(payload2, tasmota.wifi('quality'), '--')
|
||||||
|
payload1 .. payload2
|
||||||
|
payload1 .. "%\r\n\r\n"
|
||||||
|
|
||||||
|
# payload = f"id:{tasmota.millis()}\r\n"
|
||||||
|
# "event:wifi_rssi\r\n"
|
||||||
|
# "data:{tasmota.wifi().find('quality', '--')}%\r\n\r\n"
|
||||||
|
cnx.write(payload1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def send_info_feed(cnx, uri, verb)
|
def send_info_feed(cnx, uri, verb)
|
||||||
cnx.set_chunked(false) # no chunking since we use EventSource
|
cnx.set_chunked(false) # no chunking since we use EventSource
|
||||||
cnx.send(200, "text/event-stream")
|
cnx.send(200, "text/event-stream")
|
||||||
self.send_info_tick(cnx)
|
#
|
||||||
end
|
var feed = feeder(cnx)
|
||||||
|
feed.send_feed() # send first values immediately
|
||||||
def send_info_tick(cnx)
|
|
||||||
if cnx.buf_out_empty()
|
|
||||||
# if out buffer is not empty, do not send any new information
|
|
||||||
var payload
|
|
||||||
# send free heap
|
|
||||||
payload = f"id:{tasmota.millis()}\r\n"
|
|
||||||
"event:free_heap\r\n"
|
|
||||||
"data:{tasmota.memory().find('heap_free', 0)} KB\r\n\r\n"
|
|
||||||
cnx.write(payload)
|
|
||||||
|
|
||||||
# send wifi rssi
|
|
||||||
payload = f"id:{tasmota.millis()}\r\n"
|
|
||||||
"event:wifi_rssi\r\n"
|
|
||||||
"data:{tasmota.wifi().find('quality', '--')}%\r\n\r\n"
|
|
||||||
cnx.write(payload)
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.set_timer(self.sampling_interval, def () self.send_info_tick(cnx) end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add button 'GPIO Viewer' redirects to '/part_wiz?'
|
# Add button 'GPIO Viewer' redirects to '/part_wiz?'
|
||||||
|
|
Binary file not shown.
|
@ -125,6 +125,7 @@ class GPIO_viewer
|
||||||
|
|
||||||
def send_events_page(cnx, uri, verb)
|
def send_events_page(cnx, uri, verb)
|
||||||
cnx.set_chunked(false) # no chunking since we use EventSource
|
cnx.set_chunked(false) # no chunking since we use EventSource
|
||||||
|
cnx.set_cors(true)
|
||||||
cnx.send(200, "text/event-stream")
|
cnx.send(200, "text/event-stream")
|
||||||
|
|
||||||
self.send_events_tick(cnx)
|
self.send_events_tick(cnx)
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#@ solidify:webserver_async
|
#@ solidify:webserver_async
|
||||||
#@ solidify:Webserver_async_cnx
|
#@ solidify:Webserver_async_cnx
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# class Webserver_async_cnx
|
||||||
|
#############################################################
|
||||||
class Webserver_async_cnx
|
class Webserver_async_cnx
|
||||||
var server # link to server object
|
var server # link to server object
|
||||||
var cnx # holds the tcpclientasync instance
|
var cnx # holds the tcpclientasync instance
|
||||||
|
@ -46,7 +49,7 @@ class Webserver_async_cnx
|
||||||
var resp_headers
|
var resp_headers
|
||||||
var resp_version
|
var resp_version
|
||||||
var chunked # if true enable chunked encoding (default true)
|
var chunked # if true enable chunked encoding (default true)
|
||||||
var cors # if true send CORS headers (default true)
|
var cors # if true send CORS headers (default false)
|
||||||
# bytes objects to be reused
|
# bytes objects to be reused
|
||||||
var payload1
|
var payload1
|
||||||
# conversion
|
# conversion
|
||||||
|
@ -79,7 +82,7 @@ class Webserver_async_cnx
|
||||||
self.resp_headers = ''
|
self.resp_headers = ''
|
||||||
self.resp_version = 1 # HTTP 1.1 # TODO
|
self.resp_version = 1 # HTTP 1.1 # TODO
|
||||||
self.chunked = true
|
self.chunked = true
|
||||||
self.cors = true
|
self.cors = false
|
||||||
# register cb
|
# register cb
|
||||||
self.fastloop_cb = def () self.loop() end
|
self.fastloop_cb = def () self.loop() end
|
||||||
tasmota.add_fast_loop(self.fastloop_cb)
|
tasmota.add_fast_loop(self.fastloop_cb)
|
||||||
|
@ -384,6 +387,9 @@ class Webserver_async_cnx
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# class Webserver_dispatcher
|
||||||
|
#############################################################
|
||||||
class Webserver_dispatcher
|
class Webserver_dispatcher
|
||||||
var uri_prefix # prefix string, must start with '/'
|
var uri_prefix # prefix string, must start with '/'
|
||||||
var verb # verb to match, or nil for ANY
|
var verb # verb to match, or nil for ANY
|
||||||
|
@ -412,6 +418,11 @@ class Webserver_dispatcher
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# class webserver_async
|
||||||
|
#
|
||||||
|
# This is the main class to call
|
||||||
|
#############################################################
|
||||||
class webserver_async
|
class webserver_async
|
||||||
var local_port # listening port, 80 is already used by Tasmota
|
var local_port # listening port, 80 is already used by Tasmota
|
||||||
var server # instance of `tcpserver`
|
var server # instance of `tcpserver`
|
||||||
|
@ -424,7 +435,9 @@ class webserver_async
|
||||||
var dispatchers
|
var dispatchers
|
||||||
# copied in each connection
|
# copied in each connection
|
||||||
var chunked # if true enable chunked encoding (default true)
|
var chunked # if true enable chunked encoding (default true)
|
||||||
var cors # if true send CORS headers (default true)
|
var cors # if true send CORS headers (default false)
|
||||||
|
#
|
||||||
|
var payload1, payload2 # temporary object bytes() to avoid reallocation
|
||||||
|
|
||||||
static var TIMEOUT = 1000 # default timeout: 1000ms
|
static var TIMEOUT = 1000 # default timeout: 1000ms
|
||||||
static var HTTP_REQ = "^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n"
|
static var HTTP_REQ = "^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n"
|
||||||
|
@ -438,6 +451,10 @@ class webserver_async
|
||||||
self.connections = []
|
self.connections = []
|
||||||
self.dispatchers = []
|
self.dispatchers = []
|
||||||
self.server = tcpserver(port) # throws an exception if port is not available
|
self.server = tcpserver(port) # throws an exception if port is not available
|
||||||
|
self.chunked = true
|
||||||
|
self.cors = false
|
||||||
|
self.payload1 = bytes(100) # reserve 100 bytes by default
|
||||||
|
self.payload2 = bytes(100) # reserve 100 bytes by default
|
||||||
# TODO what about max_clients ?
|
# TODO what about max_clients ?
|
||||||
self.compile_re()
|
self.compile_re()
|
||||||
# register cb
|
# register cb
|
||||||
|
@ -457,14 +474,73 @@ class webserver_async
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# enable or disable chunked mode (enabled by default)
|
||||||
def set_chunked(chunked)
|
def set_chunked(chunked)
|
||||||
self.chunked = bool(chunked)
|
self.chunked = bool(chunked)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# enable or disable CORS mode (enabled by default)
|
||||||
def set_cors(cors)
|
def set_cors(cors)
|
||||||
self.cors = bool(cors)
|
self.cors = bool(cors)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# Helper function to encode integer as hex (uppercase)
|
||||||
|
static def bytes_format_hex(b, i, default)
|
||||||
|
b.clear()
|
||||||
|
if (i == nil) b .. default return end
|
||||||
|
# sanity check
|
||||||
|
if (i < 0) i = -i end
|
||||||
|
if (i < 0) return end # special case for MININT
|
||||||
|
if (i == 0) b.resize(1) b[0] = 0x30 return end # return bytes("30")
|
||||||
|
|
||||||
|
b.resize(8)
|
||||||
|
var len = 0
|
||||||
|
while i > 0
|
||||||
|
var digit = i & 0x0F
|
||||||
|
if (digit < 10)
|
||||||
|
b[len] = 0x30 + digit
|
||||||
|
else
|
||||||
|
b[len] = 0x37 + digit # 0x37 = 0x41 ('A') - 10
|
||||||
|
end
|
||||||
|
len += 1
|
||||||
|
i = (i >> 4)
|
||||||
|
end
|
||||||
|
# reverse order
|
||||||
|
b.resize(len)
|
||||||
|
b.reverse()
|
||||||
|
end
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# Helper function to encode integer as int
|
||||||
|
static def bytes_format_int(b, i, default)
|
||||||
|
b.clear()
|
||||||
|
if (i == nil) b .. default return end
|
||||||
|
var negative = false
|
||||||
|
# sanity check
|
||||||
|
if (i < 0) i = -i negative = true end
|
||||||
|
if (i < 0) return end # special case for MININT
|
||||||
|
if (i == 0) b.resize(1) b[0] = 0x30 return end # return bytes("30")
|
||||||
|
|
||||||
|
b.resize(11) # max size for 32 bits ints '-2147483647'
|
||||||
|
var len = 0
|
||||||
|
while i > 0
|
||||||
|
var digit = i % 10
|
||||||
|
b[len] = 0x30 + digit
|
||||||
|
len += 1
|
||||||
|
i = (i / 10)
|
||||||
|
end
|
||||||
|
if negative
|
||||||
|
b[len] = 0x2D
|
||||||
|
len += 1
|
||||||
|
end
|
||||||
|
# reverse order
|
||||||
|
b.resize(len)
|
||||||
|
b.reverse()
|
||||||
|
end
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
# closing web server
|
# closing web server
|
||||||
def close()
|
def close()
|
||||||
|
|
Loading…
Reference in New Issue