From 4958cbf8e95387a5bbfd7d68bc60d28407d5a8ea Mon Sep 17 00:00:00 2001 From: yellowcooln <12516003+yellowcooln@users.noreply.github.com> Date: Sat, 19 Sep 2026 19:30:57 -0400 Subject: [PATCH] fix(repeater): delegate sensor endpoints from StatsApp to APIEndpoints CherryPy mounts StatsApp at / but sensor endpoints are on APIEndpoints. Add @cherrypy.expose delegation methods so /sensors_types, /sensors_config, /sensors_config_update, and /sensors_read resolve correctly instead of falling through to the SPA catch-all. --- repeater/web/http_server.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/repeater/web/http_server.py b/repeater/web/http_server.py index dec7172..f4b9b56 100644 --- a/repeater/web/http_server.py +++ b/repeater/web/http_server.py @@ -491,6 +491,35 @@ class StatsApp: logger.error(f"Error serving index.html: {e}") raise cherrypy.HTTPError(500, "Internal server error") + # ============================================================================ + # Sensor Manager endpoint delegation (APIEndpoints methods → StatsApp) + # ============================================================================ + + @cherrypy.expose + @cherrypy.tools.json_out() + def sensors_types(self): + """Delegate to APIEndpoints.sensors_types().""" + return self.api.sensors_types() + + @cherrypy.expose + @cherrypy.tools.json_out() + def sensors_config(self): + """Delegate to APIEndpoints.sensors_config().""" + return self.api.sensors_config() + + @cherrypy.expose + @cherrypy.tools.json_out() + @cherrypy.tools.json_in() + def sensors_config_update(self): + """Delegate to APIEndpoints.sensors_config_update().""" + return self.api.sensors_config_update() + + @cherrypy.expose + @cherrypy.tools.json_out() + def sensors_read(self): + """Delegate to APIEndpoints.sensors_read().""" + return self.api.sensors_read() + @cherrypy.expose def default(self, *args, **kwargs): """Handle client-side routing - serve index.html for all non-API routes.""" @@ -499,6 +528,7 @@ class StatsApp: if cherrypy.request.method == "OPTIONS": return "" + # Application UI plugins: /plugins/{id}/... if args and args[0] == "plugins": if len(args) < 2: