Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web download debug feature #1777

Merged
merged 4 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/predbat/predbat.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import asyncio
import json

THIS_VERSION = "v8.8.11"
THIS_VERSION = "v8.8.12"

# fmt: off
PREDBAT_FILES = ["predbat.py", "config.py", "prediction.py", "gecloud.py","utils.py", "inverter.py", "ha.py", "download.py", "unit_test.py", "web.py", "predheat.py", "futurerate.py", "octopus.py", "solcast.py","execute.py", "plan.py", "fetch.py", "output.py", "userinterface.py"]
Expand Down Expand Up @@ -264,6 +264,7 @@ def reset(self):
"""
reset_prediction_globals()
self.predheat = None
self.predbat_mode = "Monitor"
self.soc_kwh_history = {}
self.html_plan = "<body><h1>Please wait calculating...</h1></body>"
self.unmatched_args = {}
Expand Down
13 changes: 9 additions & 4 deletions apps/predbat/userinterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ def read_debug_yaml(self, filename):
current["value"] = item["value"]
self.log("Restored debug settings - minutes now {}".format(self.minutes_now))

def create_debug_yaml(self):
def create_debug_yaml(self, write_file=True):
"""
Write out a debug info yaml
"""
Expand Down Expand Up @@ -634,9 +634,14 @@ def create_debug_yaml(self):
debug["inverters"] = inverters_debug

debug["CONFIG_ITEMS"] = CONFIG_ITEMS
with open(filename, "w") as file:
yaml.dump(debug, file)
self.log("Wrote debug yaml to {}".format(filename_p))

if write_file:
with open(filename, "w") as file:
yaml.dump(debug, file)
self.log("Wrote debug yaml to {}".format(filename_p))
else:
# Return the debug yaml as a string
return yaml.dump(debug)

def create_entity_list(self):
"""
Expand Down
54 changes: 51 additions & 3 deletions apps/predbat/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ async def start(self):
app.router.add_get("/config", self.html_config)
app.router.add_post("/config", self.html_config_post)
app.router.add_get("/dash", self.html_dash)
app.router.add_get("/debug_yaml", self.html_debug_yaml)
app.router.add_get("/debug_log", self.html_debug_log)
app.router.add_get("/debug_apps", self.html_debug_apps)
app.router.add_get("/debug_plan", self.html_debug_plan)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, "0.0.0.0", 5052)
Expand Down Expand Up @@ -122,7 +126,7 @@ def icon2html(self, icon):
icon = '<span class="mdi mdi-{}"></span>'.format(icon.replace("mdi:", ""))
return icon

def get_status_html(self, level, status):
def get_status_html(self, level, status, debug_enable, read_only, mode):
text = ""
if not self.base.dashboard_index:
text += "<h2>Loading please wait...</h2>"
Expand All @@ -131,7 +135,14 @@ def get_status_html(self, level, status):
text += "<h2>Status</h2>\n"
text += "<table>\n"
text += "<tr><td>Status</td><td>{}</td></tr>\n".format(status)
text += "<tr><td>Mode</td><td>{}</td></tr>\n".format(mode)
text += "<tr><td>SOC</td><td>{}%</td></tr>\n".format(level)
text += "<tr><td>Debug Enable</td><td>{}</td></tr>\n".format(debug_enable)
text += "<tr><td>Set Read Only</td><td>{}</td></tr>\n".format(read_only)
text += "<tr><td>Download</td><td><a href='./debug_apps'>apps.yaml</a></td></tr>\n"
text += "<tr><td></td><td><a href='./debug_yaml'>predbat_debug.yaml</a></td></tr>\n"
text += "<tr><td></td><td><a href='./debug_log'>predbat.log</a></td></tr>\n"
text += "<tr><td></td><td><a href='./debug_plan'>predbat_plan.html</a></td></tr>\n"
text += "</table>\n"
text += "<br>\n"

Expand Down Expand Up @@ -428,7 +439,8 @@ async def html_log(self, request):

text += '- <a href="./log">All</a> '
text += '<a href="./log?warnings">Warnings</a> '
text += '<a href="./log?errors">Errors</a><br>\n'
text += '<a href="./log?errors">Errors</a> '
text += '<a href="./debug_log">Download</a><br>\n'

text += "<table width=100%>\n"

Expand Down Expand Up @@ -546,6 +558,41 @@ def render_type(self, arg, value):
text = str(value)
return text

async def html_file(self, filename, data):
if data is None:
return web.Response(content_type="text/html", text="{} not found".format(filename), status=404)
else:
return web.Response(content_type="application/octet-stream", body=data.encode("utf-8"), headers={"Content-Disposition": "attachment; filename={}".format(filename)}) # Convert text to binary if needed

async def html_debug_yaml(self, request):
"""
Return the Predbat debug yaml data
"""
yaml_debug = self.base.create_debug_yaml(write_file=False)
return await self.html_file("predbat_debug.yaml", yaml_debug)

async def html_file_load(self, filename):
"""
Load a file and serve it up
"""
data = None
if os.path.exists(filename):
with open(filename, "r") as f:
data = f.read()
return await self.html_file(filename, data)

async def html_debug_log(self, request):
return await self.html_file_load("predbat.log")

async def html_debug_apps(self, request):
return await self.html_file_load("apps.yaml")

async def html_debug_plan(self, request):
html_plan = self.base.html_plan
if not html_plan:
html_plan = None
return await self.html_file("predbat_plan.html", html_plan)

async def html_dash(self, request):
"""
Render apps.yaml as an HTML page
Expand All @@ -554,7 +601,7 @@ async def html_dash(self, request):
text = self.get_header("Predbat Dashboard")
text += "<body>\n"
soc_perc = calc_percent_limit(self.base.soc_kw, self.base.soc_max)
text += self.get_status_html(soc_perc, self.base.current_status)
text += self.get_status_html(soc_perc, self.base.current_status, self.base.debug_enable, self.base.set_read_only, self.base.predbat_mode)
text += "</body></html>\n"
return web.Response(content_type="text/html", text=text)

Expand Down Expand Up @@ -732,6 +779,7 @@ async def html_apps(self, request):
self.default_page = "./apps"
text = self.get_header("Predbat Config")
text += "<body>\n"
text += "<a href='./debug_apps'>apps.yaml</a><br>\n"
text += "<table>\n"
text += "<tr><th>Name</th><th>Value</th><td>\n"

Expand Down
Loading