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 web
|
||||
var sampling_interval
|
||||
#
|
||||
var payload1, payload2 # temporary object bytes() to avoid reallocation
|
||||
|
||||
static var SAMPLING = 100
|
||||
static var HTML_HEAD1 =
|
||||
|
@ -73,8 +71,6 @@ class debug_panel
|
|||
self.port = port
|
||||
self.web = webserver_async(port)
|
||||
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_cors(true)
|
||||
|
@ -110,30 +106,74 @@ class debug_panel
|
|||
cnx.content_stop()
|
||||
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)
|
||||
cnx.set_chunked(false) # no chunking since we use EventSource
|
||||
cnx.send(200, "text/event-stream")
|
||||
self.send_info_tick(cnx)
|
||||
end
|
||||
|
||||
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)
|
||||
#
|
||||
var feed = feeder(cnx)
|
||||
feed.send_feed() # send first values immediately
|
||||
end
|
||||
|
||||
# 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)
|
||||
cnx.set_chunked(false) # no chunking since we use EventSource
|
||||
cnx.set_cors(true)
|
||||
cnx.send(200, "text/event-stream")
|
||||
|
||||
self.send_events_tick(cnx)
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#@ solidify:webserver_async
|
||||
#@ solidify:Webserver_async_cnx
|
||||
|
||||
#############################################################
|
||||
# class Webserver_async_cnx
|
||||
#############################################################
|
||||
class Webserver_async_cnx
|
||||
var server # link to server object
|
||||
var cnx # holds the tcpclientasync instance
|
||||
|
@ -46,7 +49,7 @@ class Webserver_async_cnx
|
|||
var resp_headers
|
||||
var resp_version
|
||||
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
|
||||
var payload1
|
||||
# conversion
|
||||
|
@ -79,7 +82,7 @@ class Webserver_async_cnx
|
|||
self.resp_headers = ''
|
||||
self.resp_version = 1 # HTTP 1.1 # TODO
|
||||
self.chunked = true
|
||||
self.cors = true
|
||||
self.cors = false
|
||||
# register cb
|
||||
self.fastloop_cb = def () self.loop() end
|
||||
tasmota.add_fast_loop(self.fastloop_cb)
|
||||
|
@ -384,6 +387,9 @@ class Webserver_async_cnx
|
|||
end
|
||||
end
|
||||
|
||||
#############################################################
|
||||
# class Webserver_dispatcher
|
||||
#############################################################
|
||||
class Webserver_dispatcher
|
||||
var uri_prefix # prefix string, must start with '/'
|
||||
var verb # verb to match, or nil for ANY
|
||||
|
@ -412,6 +418,11 @@ class Webserver_dispatcher
|
|||
end
|
||||
end
|
||||
|
||||
#############################################################
|
||||
# class webserver_async
|
||||
#
|
||||
# This is the main class to call
|
||||
#############################################################
|
||||
class webserver_async
|
||||
var local_port # listening port, 80 is already used by Tasmota
|
||||
var server # instance of `tcpserver`
|
||||
|
@ -424,7 +435,9 @@ class webserver_async
|
|||
var dispatchers
|
||||
# copied in each connection
|
||||
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 HTTP_REQ = "^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n"
|
||||
|
@ -438,6 +451,10 @@ class webserver_async
|
|||
self.connections = []
|
||||
self.dispatchers = []
|
||||
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 ?
|
||||
self.compile_re()
|
||||
# register cb
|
||||
|
@ -457,14 +474,73 @@ class webserver_async
|
|||
end
|
||||
end
|
||||
|
||||
#############################################################
|
||||
# enable or disable chunked mode (enabled by default)
|
||||
def set_chunked(chunked)
|
||||
self.chunked = bool(chunked)
|
||||
end
|
||||
|
||||
#############################################################
|
||||
# enable or disable CORS mode (enabled by default)
|
||||
def set_cors(cors)
|
||||
self.cors = bool(cors)
|
||||
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
|
||||
def close()
|
||||
|
|
Loading…
Reference in New Issue