From dd36445fd18fbf448d49cd14d64a679cbe6c6d2e Mon Sep 17 00:00:00 2001 From: Bobby Noelte Date: Wed, 22 Jan 2025 23:47:28 +0100 Subject: [PATCH] Improve EOSdash. Make EOSdash use UI components from MonsterUI to ease further development. - Add a first menu with some dummy pages and the configuration page. - Make the configuration scrollable. - Add markdown component that uses markdown-it-py (same as used by the myth-parser for documentation generation). - Add bokeh (https://docs.bokeh.org/) component for charts - Added several prediction charts to demo - Add a footer that displays connection status with EOS server - Add logo and favicon Update EOS server: - Move error message generation to extra module Signed-off-by: Bobby Noelte --- docs/_generated/openapi.md | 38 ++- openapi.json | 104 ++++++- requirements.txt | 4 + src/akkudoktoreos/core/dataabc.py | 82 ++++++ src/akkudoktoreos/core/pydantic.py | 4 + .../prediction/elecpriceimport.py | 3 + src/akkudoktoreos/prediction/loadimport.py | 3 + .../prediction/pvforecastimport.py | 3 + src/akkudoktoreos/prediction/weatherimport.py | 3 + src/akkudoktoreos/server/dash/__init__.py | 0 .../assets/favicon/android-chrome-192x192.png | Bin 0 -> 22724 bytes .../assets/favicon/android-chrome-512x512.png | Bin 0 -> 115111 bytes .../dash/assets/favicon/apple-touch-icon.png | Bin 0 -> 20319 bytes .../dash/assets/favicon/favicon-16x16.png | Bin 0 -> 724 bytes .../dash/assets/favicon/favicon-32x32.png | Bin 0 -> 1631 bytes .../server/dash/assets/favicon/favicon.ico | Bin 0 -> 15406 bytes .../dash/assets/favicon/site.webmanifest | 1 + src/akkudoktoreos/server/dash/assets/icon.png | Bin 0 -> 7675 bytes src/akkudoktoreos/server/dash/assets/logo.png | Bin 0 -> 12120 bytes src/akkudoktoreos/server/dash/bokeh.py | 38 +++ src/akkudoktoreos/server/dash/components.py | 170 ++++++++++++ .../server/dash/configuration.py | 242 +++++++++++++++++ .../server/dash/data/democonfig.json | 86 ++++++ src/akkudoktoreos/server/dash/demo.py | 217 +++++++++++++++ src/akkudoktoreos/server/dash/footer.py | 93 +++++++ src/akkudoktoreos/server/dash/hello.py | 24 ++ src/akkudoktoreos/server/dash/markdown.py | 136 ++++++++++ src/akkudoktoreos/server/eos.py | 177 +++++------- src/akkudoktoreos/server/eosdash.py | 254 ++++++++++-------- src/akkudoktoreos/server/rest/error.py | 91 +++++++ tests/test_eosdashserver.py | 61 +++-- 31 files changed, 1582 insertions(+), 252 deletions(-) create mode 100644 src/akkudoktoreos/server/dash/__init__.py create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/android-chrome-192x192.png create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/android-chrome-512x512.png create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/apple-touch-icon.png create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/favicon-16x16.png create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/favicon-32x32.png create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/favicon.ico create mode 100644 src/akkudoktoreos/server/dash/assets/favicon/site.webmanifest create mode 100644 src/akkudoktoreos/server/dash/assets/icon.png create mode 100644 src/akkudoktoreos/server/dash/assets/logo.png create mode 100644 src/akkudoktoreos/server/dash/bokeh.py create mode 100644 src/akkudoktoreos/server/dash/components.py create mode 100644 src/akkudoktoreos/server/dash/configuration.py create mode 100644 src/akkudoktoreos/server/dash/data/democonfig.json create mode 100644 src/akkudoktoreos/server/dash/demo.py create mode 100644 src/akkudoktoreos/server/dash/footer.py create mode 100644 src/akkudoktoreos/server/dash/hello.py create mode 100644 src/akkudoktoreos/server/dash/markdown.py create mode 100644 src/akkudoktoreos/server/rest/error.py diff --git a/docs/_generated/openapi.md b/docs/_generated/openapi.md index 4b8d1c96..47510bd0 100644 --- a/docs/_generated/openapi.md +++ b/docs/_generated/openapi.md @@ -332,7 +332,7 @@ Returns: Fastapi Config Reset Post ``` -Reset the configuration. +Reset the configuration to the EOS configuration file. Returns: configuration (ConfigEOS): The current configuration after update. @@ -640,6 +640,42 @@ Merge the measurement of given key and value into EOS measurements at given date --- +## GET /v1/prediction/dataframe + +**Links**: [local](http://localhost:8503/docs#/default/fastapi_prediction_dataframe_get_v1_prediction_dataframe_get), [eos](https://petstore3.swagger.io/?url=https://raw.githubusercontent.com/Akkudoktor-EOS/EOS/refs/heads/main/openapi.json#/default/fastapi_prediction_dataframe_get_v1_prediction_dataframe_get) + +Fastapi Prediction Dataframe Get + +``` +Get prediction for given key within given date range as series. + +Args: + key (str): Prediction key + start_datetime (Optional[str]): Starting datetime (inclusive). + Defaults to start datetime of latest prediction. + end_datetime (Optional[str]: Ending datetime (exclusive). + +Defaults to end datetime of latest prediction. +``` + +**Parameters**: + +- `keys` (query, required): Prediction keys. + +- `start_datetime` (query, optional): Starting datetime (inclusive). + +- `end_datetime` (query, optional): Ending datetime (exclusive). + +- `interval` (query, optional): Time duration for each interval. Defaults to 1 hour. + +**Responses**: + +- **200**: Successful Response + +- **422**: Validation Error + +--- + ## PUT /v1/prediction/import/{provider_id} **Links**: [local](http://localhost:8503/docs#/default/fastapi_prediction_import_provider_v1_prediction_import__provider_id__put), [eos](https://petstore3.swagger.io/?url=https://raw.githubusercontent.com/Akkudoktor-EOS/EOS/refs/heads/main/openapi.json#/default/fastapi_prediction_import_provider_v1_prediction_import__provider_id__put) diff --git a/openapi.json b/openapi.json index d426dadc..b88c4ea7 100644 --- a/openapi.json +++ b/openapi.json @@ -3279,7 +3279,7 @@ }, "/v1/config/reset": { "post": { - "description": "Reset the configuration.\n\nReturns:\n configuration (ConfigEOS): The current configuration after update.", + "description": "Reset the configuration to the EOS configuration file.\n\nReturns:\n configuration (ConfigEOS): The current configuration after update.", "operationId": "fastapi_config_reset_post_v1_config_reset_post", "responses": { "200": { @@ -3859,6 +3859,108 @@ ] } }, + "/v1/prediction/dataframe": { + "get": { + "description": "Get prediction for given key within given date range as series.\n\nArgs:\n key (str): Prediction key\n start_datetime (Optional[str]): Starting datetime (inclusive).\n Defaults to start datetime of latest prediction.\n end_datetime (Optional[str]: Ending datetime (exclusive).\n\nDefaults to end datetime of latest prediction.", + "operationId": "fastapi_prediction_dataframe_get_v1_prediction_dataframe_get", + "parameters": [ + { + "description": "Prediction keys.", + "in": "query", + "name": "keys", + "required": true, + "schema": { + "description": "Prediction keys.", + "items": { + "type": "string" + }, + "title": "Keys", + "type": "array" + } + }, + { + "description": "Starting datetime (inclusive).", + "in": "query", + "name": "start_datetime", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Starting datetime (inclusive).", + "title": "Start Datetime" + } + }, + { + "description": "Ending datetime (exclusive).", + "in": "query", + "name": "end_datetime", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Ending datetime (exclusive).", + "title": "End Datetime" + } + }, + { + "description": "Time duration for each interval. Defaults to 1 hour.", + "in": "query", + "name": "interval", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Time duration for each interval. Defaults to 1 hour.", + "title": "Interval" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PydanticDateTimeDataFrame" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "summary": "Fastapi Prediction Dataframe Get", + "tags": [ + "prediction" + ] + } + }, "/v1/prediction/import/{provider_id}": { "put": { "description": "Import prediction for given provider ID.\n\nArgs:\n provider_id: ID of provider to update.\n data: Prediction data.\n force_enable: Update data even if provider is disabled.\n Defaults to False.", diff --git a/requirements.txt b/requirements.txt index 98669307..13c8721e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,10 @@ numpydantic==1.6.7 matplotlib==3.10.0 fastapi[standard]==0.115.7 python-fasthtml==0.12.0 +MonsterUI==0.0.29 +markdown-it-py==3.0.0 +mdit-py-plugins==0.4.2 +bokeh==3.6.3 uvicorn==0.34.0 scikit-learn==1.6.1 timezonefinder==6.5.8 diff --git a/src/akkudoktoreos/core/dataabc.py b/src/akkudoktoreos/core/dataabc.py index 5d40abce..a8321e00 100644 --- a/src/akkudoktoreos/core/dataabc.py +++ b/src/akkudoktoreos/core/dataabc.py @@ -1845,6 +1845,88 @@ def key_to_array( return array + def keys_to_dataframe( + self, + keys: list[str], + start_datetime: Optional[DateTime] = None, + end_datetime: Optional[DateTime] = None, + interval: Optional[Any] = None, # Duration assumed + fill_method: Optional[str] = None, + ) -> pd.DataFrame: + """Retrieve a dataframe indexed by fixed time intervals for specified keys from the data in each DataProvider. + + Generates a pandas DataFrame using the NumPy arrays for each specified key, ensuring a common time index.. + + Args: + keys (list[str]): A list of field names to retrieve. + start_datetime (datetime, optional): Start date for filtering records (inclusive). + end_datetime (datetime, optional): End date for filtering records (exclusive). + interval (duration, optional): The fixed time interval. Defaults to 1 hour. + fill_method (str, optional): Method to handle missing values during resampling. + - 'linear': Linearly interpolate missing values (for numeric data only). + - 'ffill': Forward fill missing values. + - 'bfill': Backward fill missing values. + - 'none': Defaults to 'linear' for numeric values, otherwise 'ffill'. + + Returns: + pd.DataFrame: A DataFrame where each column represents a key's array with a common time index. + + Raises: + KeyError: If no valid data is found for any of the requested keys. + ValueError: If any retrieved array has a different time index than the first one. + """ + # Ensure datetime objects are normalized + start_datetime = to_datetime(start_datetime, to_maxtime=False) if start_datetime else None + end_datetime = to_datetime(end_datetime, to_maxtime=False) if end_datetime else None + if interval is None: + interval = to_duration("1 hour") + if start_datetime is None: + # Take earliest datetime of all providers that are enabled + for provider in self.enabled_providers: + if start_datetime is None: + start_datetime = provider.min_datetime + elif ( + provider.min_datetime + and compare_datetimes(provider.min_datetime, start_datetime).lt + ): + start_datetime = provider.min_datetime + if end_datetime is None: + # Take latest datetime of all providers that are enabled + for provider in self.enabled_providers: + if end_datetime is None: + end_datetime = provider.max_datetime + elif ( + provider.max_datetime + and compare_datetimes(provider.max_datetime, end_datetime).gt + ): + end_datetime = provider.min_datetime + if end_datetime: + end_datetime.add(seconds=1) + + # Create a DatetimeIndex based on start, end, and interval + reference_index = pd.date_range( + start=start_datetime, end=end_datetime, freq=interval, inclusive="left" + ) + + data = {} + for key in keys: + try: + array = self.key_to_array(key, start_datetime, end_datetime, interval, fill_method) + + if len(array) != len(reference_index): + raise ValueError( + f"Array length mismatch for key '{key}' (expected {len(reference_index)}, got {len(array)})" + ) + + data[key] = array + except KeyError as e: + raise KeyError(f"Failed to retrieve data for key '{key}': {e}") + + if not data: + raise KeyError(f"No valid data found for the requested keys {keys}.") + + return pd.DataFrame(data, index=reference_index) + def provider_by_id(self, provider_id: str) -> DataProvider: """Retrieves a data provider by its unique identifier. diff --git a/src/akkudoktoreos/core/pydantic.py b/src/akkudoktoreos/core/pydantic.py index adf884af..99de8981 100644 --- a/src/akkudoktoreos/core/pydantic.py +++ b/src/akkudoktoreos/core/pydantic.py @@ -437,6 +437,10 @@ def to_dataframe(self) -> pd.DataFrame: index = pd.Index([to_datetime(dt, in_timezone=self.tz) for dt in df.index]) df.index = index + # Check if 'date_time' column exists, if not, create it + if "date_time" not in df.columns: + df["date_time"] = df.index + dtype_mapping = { "int": int, "float": float, diff --git a/src/akkudoktoreos/prediction/elecpriceimport.py b/src/akkudoktoreos/prediction/elecpriceimport.py index 1ec66842..cf34d767 100644 --- a/src/akkudoktoreos/prediction/elecpriceimport.py +++ b/src/akkudoktoreos/prediction/elecpriceimport.py @@ -63,6 +63,9 @@ def provider_id(cls) -> str: return "ElecPriceImport" def _update_data(self, force_update: Optional[bool] = False) -> None: + if self.config.elecprice.provider_settings is None: + logger.debug(f"{self.provider_id()} data update without provider settings.") + return if self.config.elecprice.provider_settings.import_file_path: self.import_from_file( self.config.elecprice.provider_settings.import_file_path, diff --git a/src/akkudoktoreos/prediction/loadimport.py b/src/akkudoktoreos/prediction/loadimport.py index 456107c9..dd54519d 100644 --- a/src/akkudoktoreos/prediction/loadimport.py +++ b/src/akkudoktoreos/prediction/loadimport.py @@ -62,6 +62,9 @@ def provider_id(cls) -> str: return "LoadImport" def _update_data(self, force_update: Optional[bool] = False) -> None: + if self.config.load.provider_settings is None: + logger.debug(f"{self.provider_id()} data update without provider settings.") + return if self.config.load.provider_settings.import_file_path: self.import_from_file(self.config.provider_settings.import_file_path, key_prefix="load") if self.config.load.provider_settings.import_json: diff --git a/src/akkudoktoreos/prediction/pvforecastimport.py b/src/akkudoktoreos/prediction/pvforecastimport.py index d04fb5eb..a093369c 100644 --- a/src/akkudoktoreos/prediction/pvforecastimport.py +++ b/src/akkudoktoreos/prediction/pvforecastimport.py @@ -63,6 +63,9 @@ def provider_id(cls) -> str: return "PVForecastImport" def _update_data(self, force_update: Optional[bool] = False) -> None: + if self.config.pvforecast.provider_settings is None: + logger.debug(f"{self.provider_id()} data update without provider settings.") + return if self.config.pvforecast.provider_settings.import_file_path is not None: self.import_from_file( self.config.pvforecast.provider_settings.import_file_path, diff --git a/src/akkudoktoreos/prediction/weatherimport.py b/src/akkudoktoreos/prediction/weatherimport.py index fa70003e..a0a5890b 100644 --- a/src/akkudoktoreos/prediction/weatherimport.py +++ b/src/akkudoktoreos/prediction/weatherimport.py @@ -63,6 +63,9 @@ def provider_id(cls) -> str: return "WeatherImport" def _update_data(self, force_update: Optional[bool] = False) -> None: + if self.config.weather.provider_settings is None: + logger.debug(f"{self.provider_id()} data update without provider settings.") + return if self.config.weather.provider_settings.import_file_path: self.import_from_file( self.config.weather.provider_settings.import_file_path, key_prefix="weather" diff --git a/src/akkudoktoreos/server/dash/__init__.py b/src/akkudoktoreos/server/dash/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/akkudoktoreos/server/dash/assets/favicon/android-chrome-192x192.png b/src/akkudoktoreos/server/dash/assets/favicon/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..9cf73763e2018c7ea9e3ef311bbd4bf153ca6516 GIT binary patch literal 22724 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
  • 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 literal 0 HcmV?d00001 diff --git a/src/akkudoktoreos/server/dash/assets/favicon/apple-touch-icon.png b/src/akkudoktoreos/server/dash/assets/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb08ab0a4ae80b2f553d4ec2987c9366ff673a9 GIT binary patch literal 20319 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 Y(9551ANvICMs1Xyls3f?s3p6w|-A!-wTHRIm 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 literal 0 HcmV?d00001 diff --git a/src/akkudoktoreos/server/dash/assets/logo.png b/src/akkudoktoreos/server/dash/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd4eb5dd658ea057af890900547b29980213633 GIT binary patch literal 12120 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
    xttllo6 z8HV~u*X5>mGdP30nrLi);LgyX>L1&|K1kU;ZMmf!7ti^#jA!JmWE`-!<)0w|#2XzbW&jdxax9PD4VFFvNpC*5~X z+&sRAy{ZglUGMpEB+be4%Dg|YPBLe0>indMb#WKKmVSssW8a`h)~W}fK-TA_h&!!* zBYgE{=}sTLsjrb9UgGek0+i-i6VtlX%O|iX%X-eNqPSG|dn#$4z0OPXR=T%7FRX=} zcZ=m6>>*mm+;3cqe;g$AfZVMd#+}O|3NvY8zKI6Bsp>v*LIoP;G`=E-ga%tLBMEr_ zu9L3#h$W5tw5*Hq&r>s(DA1ljU2eNP-dIp-g<-lY(m&-P)uN-|b&AZ7oG~26J96-v z-(g%y)%Kms#f${oTWeW~9s(z{3i#ovljAOb`KZX%xPxx3zili{zn|2cv?hD%6<6YL zC(7F-!2_jg9jEHpnZr3%$u#{yvxwqoZaCuZ!yTsb@Ciu6!aM>z!8y2hrRClYE_O1| zI>c4u?R^Y&!9>Ig`P}I+k-sW63~lrxOI1~Ux82flab%CsdBHb*?0qqEt0T{D^r%lO zw3t`LejBgdm53ATn>J>p*?i3%ztd4`=%W-7P`FbYNICh^83CdG#X4TxC$({H0*Fb{ zs8F%Z7Em}ZV6mig=t+*>tQ3UtbMP+TN{0FzTO+|t^Jct}?|zM_#>HJO55^w|4tkcIL$YzMsoP+x6EWYCt7cfeTj=kr%VtSH2iBbwVHF~)1q#|9g~=5XjoP2DtWo5AI6N`pE5z>=Y%o-WF3z^Exo1a%)hpe zV!ukX27mx2GO1i<;6ersxZNw+H|lr zGG{flnP`&6SbMqZyJ++p1@H}*&g?7 ztF#g`Z$yPAhp#R9O#<%i;Liz|7VLk$fo^gKWb=;*(OJd4yR^YlY=y7 zKaJfhpJ>|0f>s>gX#RrLP(2O`JJBQ}9w^%@QAyJye7a&SX=P|5#Jr6Qn6ZRzcL>rr zpD6IE_&G%-|fRRUTmJF}~QaO+R-(G-u({Xbk+fPIf`VT`68uke|Nw zDQJ8=m5rSYe1%Sox}Bpx%c|+=)H%h1(#NSY^_u6JdkN+Innu9khxRkxM>E_SfX{q| z_tD1g2-h=6O++`6Tvjs--GevoxOIq}<;z*)b0z~7a!F_o*gZG@FGv8NoFJHhj07+D z!nEU}v*6fp=$QURI*awUapMq(pn1bs!@}wt_#N1kU{iEpAA|f4N%7)cTJYF>Y0Um- zoB{0`33+`z!%pi7D@n;O?kI^@j;AZE+E+>H2^J(R9{z4W$p@HU4r6U^;FHHmo1(S< z)I?3Nq_Q{rbVkxT_PhzJc=ZM6DW9|daSenxOP_Tt%({OA361=fDLXw$g5yPG}IT2vJTh|9S#hVPb;PezZp5yrx=dC7Eogsr_>znV7P4GkN3t2@j70lXHKY zpKn1)_uPl+1bS?by`PYrM8cyDQVf$CSB(;Z;1dnFr(bb|y4k^gwJD*nd5UI~kUw9B zg`h?Kje(CiLSx0?#_=WaqTy_Ed6ero(Q(0vxMW6)d+p>?qEo2I2X%noOk~|<;of*N zWpGuCiFBVNyXqY8SQN!CNbu0EkmkyaW}%SBkJU8g_a{*1Sc+kvmW!B%?e04TtEyUe zDx^S)3hO*)g@b^>ZjL~}e+NS&g`7#7<8yz*A$>Z7e`|8#SpF1XDBxH5#y{#rRneb} zH9q^pc=W>cBpI)@*4oHC+jc5(+9QK}Baa3@7d6uQIX?{hG! z_V*ZasK3tqAHDKDB^{TuAvg25iZYqtZ*w8E@8vC2#X2MOm zPNRK(97x#bFT@E$$Vjst!r*=S3AtT{lm7-Mdhk0GHRtHOJ0*#Q4B#W4icnckMrnLYuscT!l^{FXlItd>@%FA~r``I4WmJEE%~Y{pY>9 zN$t(gi(p@0Uy-oaK!u4E<^rz*D^jEieUvY_=LI+|Ww-yNQt|uC^cal?mJ899{7>!N z!*wh$szdB?k4B@mdW-6;$wZd}f|+fB2A)-&QKOGv0Y*S_ZnfWkUn{?nF;y)q>I zxRW=ZM^4&!@*uD`qIby#Vt+x; z{`+8xW;XKNxR+J4E*-DPP5+C3ME3npdq2@11g+Zi(?u8GA~f!J&*XX19=$vTa@Hh~ zFW;-M6)54VIk^9ThqS5&eR!4l&7+O#L%x{Vz=KZan7&h}bSL;%w*M>)?eKOIFfe$; ze0M4f(wBZ)Euj|~p36rO9H^{t>PZ1&mSYSb3$M#dCRlIclLa%Co)J=vGVf~g7hGxP zIjXS|SuTISx%YoipuvFxQNxXWPX?X3Tv&6q?d5I63>a`miPYqR;|OsonYO$?Kj z^U`eM9(Tl8c-p0XMS`+EXD|2qmUR{!#`7c)_-3P-WW;(KzF>>{vdRFTpHcrkQuBQnW{rBH}dlA=IEYWaV@z(-W4+-VGrriG~B2xo-CjETyN%#d% zf9}3}3Q$=%NE514poxYj&JPN+$IBIL7))#{0G%T;{xOF$Y~TUQ_g-(`uCP&d zXhG#A#ihhAE^&4`NhrZO!uCSlTQf?APvkFKp&^Ns;xLY?aZx9tY^QRZ)2N;^rXDjNUuejop zX9g!{J?mDNPT~4{9%fZh_pnO;PoVX`bSa}rMlb%&ooh0m56*_$p`bASUo1DolGwo( zL2eNs+W$nVcP^+UqN%;3nOZ-7Bl~ktT8X}T${L+<{jf$wnbU>PQ(%$g(u`#G{RI&E`KRWksj1A7Y{N{XSR1NS2(WUgkmus@fP&qr%L9a-)9n)U!+P|F6XX zc5>K>j~XPN2b!l&*ZAd1=`VvnRqM3oq%1eDNt=aPPu^Mkew~qf|AmAR?!dcGiF7#( z8Aa6Hx@0fXziNQnVr`R(nAa~`Dt7-3F)$%unZWgLr1J0eGj?mi+@UB12wF&oCCobM z^9}nL+qGcl95sZdk0c5##>--8c?h&pI=AlpN{W3$p1PRr}3Brb!$S zfx?e@;ITn_WRkB|l;z2~Rw)#ONYk|XjegKXo61oDEN1<%ow$d(?1@qcWR#JQc`K!K z2T8L&r3DzRDf>iBOl{p!c7OiGepQHKzUEIk;6dQvO0##!y5sUUV+T%6XSkYeJ#zJA z+UPloE6l*@ZR^QQL$cr$LN+hV7^SPYd2MU%LR~6OTWJFd5rk~ zc=`O9{6LSd+8-GGO1Ml`xAH*XZKSn)qp1!JX{M{>E<2^@V33*44x%8wtH(~iJrjZW zp7MjKtM91y)%>(Uxo>2VjD(*)@yd(~BB&QS=^*Kwh249j%#Jzll3#k}!0W!pe1;3pj?kS)oJm-GMfgX8(YW~)_#M_Zm33w9p2)xD`(J1Z?0vV@ zu^u+`44uggk)jq#)=%+CDX~Gm)WZr78Jst0_OgmXseZhe)^Ix5jf~P;lYVjP2_niW z^UBHQ8hDx7ZLa=|%YxL6H2&qDZ%ckJusFAZX6@%X4;v4lc*(v(R*|%HXc@8q&E1 ztNTv0qFR_(a1M%%roQwCeFQnqO|{mRTT=A??%J2DO&wD%EMjir$~gAq-6GXH#jxG* z69fE%^OUX@s|{5h893%Co~G}09R<#1p>HXZlCtuVJeNGgfLS`~AwI%>AcGDKQ#*e& zgd@kT>2iHOpY2^Zcc=@wD|4w=EgsW+7#qBni=oDzNYLjqKrfUAHQ@gI&k$r+n2uc| zU&A+`35><#={4SXM4@k~4$;MU=)?8p!SRhAYsM8P=fofjIck0|z?7|oxEIIb-DB17 zPu84eo3u}hWKxQw8+?~_BT9L0qOk|$>0m$>iGi^A$BRvEb^>7%aVR497%(~>|Wk2z!JO^mez@F`B=mfFxjFAN@46Ms{Y$a~H zQxRS!mlLBP7%cFYsEmbpte>H$sA9D2bA?~oowC7WaHiz3xKI0=A zBif28_mQZnQJYk4f02}`x4Jj9c@d^Y$>r`2=knmjskBrJ@454K{L;Jdgg8RJ3`KhsB0$MvzKY+TfudBk3{Y;`3x>Ikw%8ZZCIrJ|Tu$9Q&uCfIanO+|aqnZq@GHNg-L=W_ zSz(ArR0X_+PzxtP0|@m%L-&XsO=y9#o}4?g{xPg6M1buAbQD)EvmSM&2(?W{HkA*_l2h6YbDRi0%jt!)-!N(0;Yn zcuGVbNpIR|h&Nm-n!pGeUnh>f4J;DX9W7&L#~5@YC{#DZB_{`Ab|u#Nu~d+e)ZNp(;3d`Ea2=dPH&QrrO zRQ07)vMBh8m2qTB7$wI{nAmvWmhjm4MuidH%mqixYg}()h~`2uPtEh2GpM<&fy-c| zsoInE7A_?SgxKwUyI=-nwgThz*8YD)(@jL2?YF5_a#wb9OUv;d1GI(J#pg%rCNMP^ zy*yyZ8xf#OXw;n8`)0|P-|LD?cc2!Sge37ao>qeuN(*v%dAIrC)ab6M>4+bSXvnjW zW5wl5vn4-$=@8%pr(7^LBF>}XF<3+80vF9gO9Lu9S(N3Leu^MWUDr?E%`&4LkMSYO zW8d`sm)ATHHmzR$Q$EGw6I|~q>2Yf;l zB(Vov2d652%E+F?83$9StGm~Kz4oR=`~ zisGt=HuO?ZLner-X@n2}A5a|iK2N182Pw??SyTE1c_=a=N_MPtb(se`-(XugqWWfh z@Z4i68gEf4gGyign<3)pr;)GO3cv|rw&b}u2O}o3u9y`yGML+00aLFyveTZ?x2%;;m#`Ux&ko(i|@qC>iNxZPtXg7p9 zgEpD->gf*KkfDAkK4A`=atOPUsPC*70lDBxZRvMTN%UP8L`;pOX)l7 zI}ndOVxFVO-NEnt%H&fhrBSw!&*N;_)`1D$l4XBg`~Nze<_`LK?F&U<(N;y=N&CD_ zRE$|?&&c|^iv{`%9-9cOa(!lIQA#}B+qs|!S~rSUlv|2Cnpt-uFeXmc^CkhENO2(+ z!*DXiQ}4V}E;{?Zuqeo%W+wwtsgF#g&hLlrItaMDxSJ<)h^rUT3nl!iA8 z)W_0gOg^sb+RNWKa+PVvG~%q^zQ!aSs*{G6)*JGmo#@h7S)5g}y|CMhFg;f4jY`-D zbjO940WjQGa@2!fjA0Ow8MB6O-N8XEhH1Z0@+1Tu2`}3sZ9lH7)PbgQ8Rdm%{eR~u zo^;Nl9_KM0?XT(oOM)s&-~bAY`{rPn^hdE7V()A+ryu-FK3xZ#(`sfR&(9IQbfK3n z!wa)D)IOM#o7tMRno;+$OT(lvUp5w=t;&Bgz-n9>vVE)5!M^nv+PEZgxd0vTc+Vv& z`Gp+XZLg((xnT`2U8#ZsEyw!hA&(jyl>3EiDR^7g;QzV0m=`aD&k$hLgPW>%L@`$& zDJA%2|C`c3sR_lpYLP4LC&sT_diSkJpGg5(6StUf^O_HAHoROj`#c6`^Ph<|9NZWo zAJSyBk_|X|c@NP=dMYB_SI)lXERA+70267H6{&r#HXK>q$& zncY7zZl&6U~b%fb|( z0klS9uHWf3Zpe*r+m+pIu`_f<%5N%Bb=B)+8sgPzJ%($MoFxBXt<;CTPLxqVo4#z< zmfkJwcP%U_k*@j5a_?VUi^y^R@v Card: + """Converts an Bokeh plot to a FastHTML FT component.""" + script, div = components(plot) + if header: + header = H4(header, cls="mt-2") + return Card( + NotStr(div), + NotStr(script), + header=header, + ) diff --git a/src/akkudoktoreos/server/dash/components.py b/src/akkudoktoreos/server/dash/components.py new file mode 100644 index 00000000..ac4938d3 --- /dev/null +++ b/src/akkudoktoreos/server/dash/components.py @@ -0,0 +1,170 @@ +from typing import Any, Optional, Union + +from fasthtml.common import H1, Div, Li + +# from mdit_py_plugins import plugin1, plugin2 +from monsterui.foundations import stringify +from monsterui.franken import Button, ButtonT, Card, Container, ContainerT, TabContainer + +scrollbar_viewport_styles = ( + "scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch;" +) + +scrollbar_cls = "flex touch-none select-none transition-colors p-[1px]" + + +def ScrollArea( + *c: Any, cls: Optional[Union[str, tuple]] = None, orientation: str = "vertical", **kwargs: Any +) -> Div: + """Creates a styled scroll area. + + Args: + orientation (str): The orientation of the scroll area. Defaults to vertical. + """ + new_cls = "relative overflow-hidden" + if cls: + new_cls += f" {stringify(cls)}" + kwargs["cls"] = new_cls + + content = Div( + Div(*c, style="min-width:100%;display:table;"), + style=f"overflow: {'hidden scroll' if orientation == 'vertical' else 'scroll'}; {scrollbar_viewport_styles}", + cls="w-full h-full rounded-[inherit]", + data_ref="viewport", + ) + + scrollbar = Div( + Div(cls="bg-border rounded-full hidden relative flex-1", data_ref="thumb"), + cls=f"{scrollbar_cls} flex-col h-2.5 w-full border-t border-t-transparent" + if orientation == "horizontal" + else f"{scrollbar_cls} w-2.5 h-full border-l border-l-transparent", + data_ref="scrollbar", + style=f"position: absolute;{'right:0; top:0;' if orientation == 'vertical' else 'bottom:0; left:0;'}", + ) + + return Div( + content, + scrollbar, + role="region", + tabindex="0", + data_orientation=orientation, + data_ref_scrollarea=True, + aria_label="Scrollable content", + **kwargs, + ) + + +def DashboardHeader(title: Optional[str]) -> Div: + """Creates a styled header with a title. + + Args: + title (Optional[str]): The title text for the header. + + Returns: + Div: A styled `Div` element containing the header. + """ + if title is None: + return Div("", cls="header") + return Div(H1(title, cls="text-2xl font-bold mb-4"), cls="header") + + +def DashboardFooter(*c: Any, path: str) -> Card: + """Creates a styled footer with the provided information. + + The footer content is reloaded every 5 seconds from path. + + Args: + path (str): Path to reload footer content from + + Returns: + Card: A styled `Card` element containing the footer. + """ + return Card( + Container(*c, id="footer-content"), + hx_get=f"{path}", + hx_trigger="every 5s", + hx_target="#footer-content", + hx_swap="innerHTML", + ) + + +def DashboardTrigger(*c: Any, cls: Optional[Union[str, tuple]] = None, **kwargs: Any) -> Button: + """Creates a styled button for the dashboard trigger. + + Args: + *c: Positional arguments to pass to the button. + cls (Optional[str]): Additional CSS classes for styling. Defaults to None. + **kwargs: Additional keyword arguments for the button. + + Returns: + Button: A styled `Button` component. + """ + new_cls = f"{ButtonT.primary}" + if cls: + new_cls += f" {stringify(cls)}" + kwargs["cls"] = new_cls + return Button(*c, submit=False, **kwargs) + + +def DashboardTabs(dashboard_items: dict[str, str]) -> Card: + """Creates a dashboard tab with dynamic dashboard items. + + Args: + dashboard_items (dict[str, str]): A dictionary of dashboard items where keys are item names + and values are paths for navigation. + + Returns: + Card: A styled `Card` component containing the dashboard tabs. + """ + dash_items = [ + Li( + DashboardTrigger( + menu, + hx_get=f"{path}", + hx_target="#page-content", + hx_swap="innerHTML", + ), + ) + for menu, path in dashboard_items.items() + ] + return Card(TabContainer(*dash_items, cls="gap-4"), alt=True) + + +def DashboardContent(content: Any) -> Card: + """Creates a content section within a styled card. + + Args: + content (Any): The content to display. + + Returns: + Card: A styled `Card` element containing the content. + """ + return Card(ScrollArea(Container(content, id="page-content"), cls="h-[75vh] w-full rounded-md")) + + +def Page( + title: Optional[str], + dashboard_items: dict[str, str], + content: Any, + footer_content: Any, + footer_path: str, +) -> Div: + """Generates a full-page layout with a header, dashboard items, content, and footer. + + Args: + title (Optional[str]): The page title. + dashboard_items (dict[str, str]): A dictionary of dashboard items. + content (Any): The main content for the page. + footer_content (Any): Footer content. + footer_path (Any): Path to reload footer content from. + + Returns: + Div: A `Div` element representing the entire page layout. + """ + return Container( + DashboardHeader(title), + DashboardTabs(dashboard_items), + DashboardContent(content), + DashboardFooter(footer_content, path=footer_path), + cls=("bg-background text-foreground w-screen p-4 space-y-4", ContainerT.xl), + ) diff --git a/src/akkudoktoreos/server/dash/configuration.py b/src/akkudoktoreos/server/dash/configuration.py new file mode 100644 index 00000000..cc43249d --- /dev/null +++ b/src/akkudoktoreos/server/dash/configuration.py @@ -0,0 +1,242 @@ +from typing import Any, Dict, List, Optional, Sequence, TypeVar, Union + +import requests +from monsterui.franken import Table, Tbody, Td, Th, Thead, Tr +from pydantic.fields import ComputedFieldInfo, FieldInfo +from pydantic_core import PydanticUndefined + +from akkudoktoreos.config.config import get_config +from akkudoktoreos.core.logging import get_logger +from akkudoktoreos.core.pydantic import PydanticBaseModel + +logger = get_logger(__name__) +config_eos = get_config() + +T = TypeVar("T") + + +def get_nested_value( + dictionary: Union[Dict[str, Any], List[Any]], + keys: Sequence[Union[str, int]], + default: Optional[T] = None, +) -> Union[Any, T]: + """Retrieve a nested value from a dictionary or list using a sequence of keys. + + Args: + dictionary (Union[Dict[str, Any], List[Any]]): The nested dictionary or list to search. + keys (Sequence[Union[str, int]]): A sequence of keys or indices representing the path to the desired value. + default (Optional[T]): A value to return if the path is not found. + + Returns: + Union[Any, T]: The value at the specified nested path, or the default value if not found. + + Raises: + TypeError: If the input is not a dictionary or list, or if keys are not a sequence. + KeyError: If a key is not found in a dictionary. + IndexError: If an index is out of range in a list. + """ + if not isinstance(dictionary, (dict, list)): + raise TypeError("The first argument must be a dictionary or list") + if not isinstance(keys, Sequence): + raise TypeError("Keys must be provided as a sequence (e.g., list, tuple)") + + if not keys: + return dictionary + + try: + # Traverse the structure + current = dictionary + for key in keys: + if isinstance(current, dict) and isinstance(key, str): + current = current[key] + elif isinstance(current, list) and isinstance(key, int): + current = current[key] + else: + raise KeyError(f"Invalid key or index: {key}") + return current + except (KeyError, IndexError, TypeError): + return default + + +def get_default_value(field_info: Union[FieldInfo, ComputedFieldInfo], regular_field: bool) -> Any: + """Retrieve the default value of a field. + + Args: + field_info (Union[FieldInfo, ComputedFieldInfo]): The field metadata from Pydantic. + regular_field (bool): Indicates if the field is a regular field. + + Returns: + Any: The default value of the field or "N/A" if not a regular field. + """ + default_value = "" + if regular_field: + if (val := field_info.default) is not PydanticUndefined: + default_value = val + else: + default_value = "N/A" + return default_value + + +def resolve_nested_types(field_type: Any, parent_types: list[str]) -> list[tuple[Any, list[str]]]: + """Resolve nested types within a field and return their structure. + + Args: + field_type (Any): The type of the field to resolve. + parent_types (List[str]): A list of parent type names. + + Returns: + List[tuple[Any, List[str]]]: A list of tuples containing resolved types and their parent hierarchy. + """ + resolved_types: list[tuple[Any, list[str]]] = [] + + origin = getattr(field_type, "__origin__", field_type) + if origin is Union: + for arg in getattr(field_type, "__args__", []): + if arg is not type(None): + resolved_types.extend(resolve_nested_types(arg, parent_types)) + else: + resolved_types.append((field_type, parent_types)) + + return resolved_types + + +def configuration(values: dict) -> list[dict]: + """Generate configuration details based on provided values and model metadata. + + Args: + values (dict): A dictionary containing the current configuration values. + + Returns: + List[dict]: A sorted list of configuration details, each represented as a dictionary. + """ + configs = [] + inner_types: set[type[PydanticBaseModel]] = set() + + for field_name, field_info in list(config_eos.model_fields.items()) + list( + config_eos.model_computed_fields.items() + ): + + def extract_nested_models( + subfield_info: Union[ComputedFieldInfo, FieldInfo], parent_types: list[str] + ) -> None: + regular_field = isinstance(subfield_info, FieldInfo) + subtype = subfield_info.annotation if regular_field else subfield_info.return_type + + if subtype in inner_types: + return + + nested_types = resolve_nested_types(subtype, []) + found_basic = False + for nested_type, nested_parent_types in nested_types: + if not isinstance(nested_type, type) or not issubclass( + nested_type, PydanticBaseModel + ): + if found_basic: + continue + + config = {} + config["name"] = ".".join(parent_types) + config["value"] = str(get_nested_value(values, parent_types, "")) + config["default"] = str(get_default_value(subfield_info, regular_field)) + config["description"] = ( + subfield_info.description if subfield_info.description else "" + ) + if isinstance(subfield_info, ComputedFieldInfo): + config["read-only"] = "ro" + type_description = str(subfield_info.return_type) + else: + config["read-only"] = "rw" + type_description = str(subfield_info.annotation) + config["type"] = ( + type_description.replace("typing.", "") + .replace("pathlib.", "") + .replace("[", "[ ") + .replace("NoneType", "None") + ) + configs.append(config) + found_basic = True + else: + new_parent_types = parent_types + nested_parent_types + inner_types.add(nested_type) + for nested_field_name, nested_field_info in list( + nested_type.model_fields.items() + ) + list(nested_type.model_computed_fields.items()): + extract_nested_models( + nested_field_info, + new_parent_types + [nested_field_name], + ) + + extract_nested_models(field_info, [field_name]) + return sorted(configs, key=lambda x: x["name"]) + + +def get_configuration(eos_host: Optional[str], eos_port: Optional[Union[str, int]]) -> list[dict]: + """Fetch and process configuration data from the specified EOS server. + + Args: + eos_host (Optional[str]): The hostname of the server. + eos_port (Optional[Union[str, int]]): The port of the server. + + Returns: + List[dict]: A list of processed configuration entries. + """ + if eos_host is None: + eos_host = config_eos.server.host + if eos_port is None: + eos_port = config_eos.server.port + server = f"http://{eos_host}:{eos_port}" + + # Get current configuration from server + try: + result = requests.get(f"{server}/v1/config") + result.raise_for_status() + except requests.exceptions.HTTPError as e: + detail = result.json()["detail"] + warning_msg = f"Can not retrieve configuration from {server}: {e}, {detail}" + logger.warning(warning_msg) + return configuration({}) + config = result.json() + + return configuration(config) + + +def Configuration(eos_host: Optional[str], eos_port: Optional[Union[str, int]]) -> Table: + """Create a visual representation of the configuration. + + Args: + eos_host (Optional[str]): The hostname of the EOS server. + eos_port (Optional[Union[str, int]]): The port of the EOS server. + + Returns: + Table: A `monsterui.franken.Table` component displaying configuration details. + """ + flds = "Name", "Type", "RO/RW", "Value", "Default", "Description" + rows = [ + Tr( + Td( + config["name"], + cls="max-w-64 text-wrap break-all", + ), + Td( + config["type"], + cls="max-w-48 text-wrap break-all", + ), + Td( + config["read-only"], + cls="max-w-24 text-wrap break-all", + ), + Td( + config["value"], + cls="max-w-md text-wrap break-all", + ), + Td(config["default"], cls="max-w-48 text-wrap break-all"), + Td( + config["description"], + cls="max-w-prose text-wrap", + ), + cls="", + ) + for config in get_configuration(eos_host, eos_port) + ] + head = Thead(*map(Th, flds), cls="text-left") + return Table(head, Tbody(*rows), cls="w-full uk-table uk-table-divider uk-table-striped") diff --git a/src/akkudoktoreos/server/dash/data/democonfig.json b/src/akkudoktoreos/server/dash/data/democonfig.json new file mode 100644 index 00000000..d37bf756 --- /dev/null +++ b/src/akkudoktoreos/server/dash/data/democonfig.json @@ -0,0 +1,86 @@ +{ + "elecprice": { + "charges_kwh": 0.21, + "provider": "ElecPriceAkkudoktor" + }, + "general": { + "latitude": 52.5, + "longitude": 13.4 + }, + "prediction": { + "historic_hours": 48, + "hours": 48 + }, + "load": { + "provider": "LoadAkkudoktor", + "provider_settings": { + "loadakkudoktor_year_energy": 20000 + } + }, + "optimization": { + "hours": 48 + }, + "pvforecast": { + "planes": [ + { + "peakpower": 5.0, + "surface_azimuth": -10, + "surface_tilt": 7, + "userhorizon": [ + 20, + 27, + 22, + 20 + ], + "inverter_paco": 10000 + }, + { + "peakpower": 4.8, + "surface_azimuth": -90, + "surface_tilt": 7, + "userhorizon": [ + 30, + 30, + 30, + 50 + ], + "inverter_paco": 10000 + }, + { + "peakpower": 1.4, + "surface_azimuth": -40, + "surface_tilt": 60, + "userhorizon": [ + 60, + 30, + 0, + 30 + ], + "inverter_paco": 2000 + }, + { + "peakpower": 1.6, + "surface_azimuth": 5, + "surface_tilt": 45, + "userhorizon": [ + 45, + 25, + 30, + 60 + ], + "inverter_paco": 1400 + } + ], + "provider": "PVForecastAkkudoktor" + }, + "server": { + "startup_eosdash": true, + "host": "0.0.0.0", + "port": 8503, + "eosdash_host": "0.0.0.0", + "eosdash_port": 8504 + }, + "weather": { + "provider": "BrightSky" + } +} diff --git a/src/akkudoktoreos/server/dash/demo.py b/src/akkudoktoreos/server/dash/demo.py new file mode 100644 index 00000000..e967ea23 --- /dev/null +++ b/src/akkudoktoreos/server/dash/demo.py @@ -0,0 +1,217 @@ +import json +from pathlib import Path +from typing import Union + +import pandas as pd +import requests +from bokeh.models import ColumnDataSource, Range1d +from bokeh.plotting import figure +from monsterui.franken import FT, Grid, P + +from akkudoktoreos.core.logging import get_logger +from akkudoktoreos.core.pydantic import PydanticDateTimeDataFrame +from akkudoktoreos.server.dash.bokeh import Bokeh + +DIR_DEMODATA = Path(__file__).absolute().parent.joinpath("data") +FILE_DEMOCONFIG = DIR_DEMODATA.joinpath("democonfig.json") +if not FILE_DEMOCONFIG.exists(): + raise ValueError(f"File does not exist: {FILE_DEMOCONFIG}") + +logger = get_logger(__name__) + +# bar width for 1 hour bars (time given in millseconds) +BAR_WIDTH_1HOUR = 1000 * 60 * 60 + + +def DemoPVForecast(predictions: pd.DataFrame, config: dict) -> FT: + source = ColumnDataSource(predictions) + provider = config["pvforecast"]["provider"] + + plot = figure( + x_axis_type="datetime", + title=f"PV Power Prediction ({provider})", + x_axis_label="Datetime", + y_axis_label="Power [W]", + sizing_mode="stretch_width", + height=400, + ) + + plot.vbar( + x="date_time", + top="pvforecast_ac_power", + source=source, + width=BAR_WIDTH_1HOUR * 0.8, + legend_label="AC Power", + color="lightblue", + ) + + return Bokeh(plot) + + +def DemoElectricityPriceForecast(predictions: pd.DataFrame, config: dict) -> FT: + source = ColumnDataSource(predictions) + provider = config["elecprice"]["provider"] + + plot = figure( + x_axis_type="datetime", + y_range=Range1d( + predictions["elecprice_marketprice_kwh"].min() - 0.1, + predictions["elecprice_marketprice_kwh"].max() + 0.1, + ), + title=f"Electricity Price Prediction ({provider})", + x_axis_label="Datetime", + y_axis_label="Price [€/kWh]", + sizing_mode="stretch_width", + height=400, + ) + plot.vbar( + x="date_time", + top="elecprice_marketprice_kwh", + source=source, + width=BAR_WIDTH_1HOUR * 0.8, + legend_label="Market Price", + color="lightblue", + ) + + return Bokeh(plot) + + +def DemoWeatherTempAir(predictions: pd.DataFrame, config: dict) -> FT: + source = ColumnDataSource(predictions) + provider = config["weather"]["provider"] + + plot = figure( + x_axis_type="datetime", + y_range=Range1d( + predictions["weather_temp_air"].min() - 1.0, predictions["weather_temp_air"].max() + 1.0 + ), + title=f"Air Temperature Prediction ({provider})", + x_axis_label="Datetime", + y_axis_label="Temperature [°C]", + sizing_mode="stretch_width", + height=400, + ) + plot.line( + "date_time", "weather_temp_air", source=source, legend_label="Air Temperature", color="blue" + ) + + return Bokeh(plot) + + +def DemoWeatherIrradiance(predictions: pd.DataFrame, config: dict) -> FT: + source = ColumnDataSource(predictions) + provider = config["weather"]["provider"] + + plot = figure( + x_axis_type="datetime", + title=f"Irradiance Prediction ({provider})", + x_axis_label="Datetime", + y_axis_label="Irradiance [W/m2]", + sizing_mode="stretch_width", + height=400, + ) + plot.line( + "date_time", + "weather_ghi", + source=source, + legend_label="Global Horizontal Irradiance", + color="red", + ) + plot.line( + "date_time", + "weather_dni", + source=source, + legend_label="Direct Normal Irradiance", + color="green", + ) + plot.line( + "date_time", + "weather_dhi", + source=source, + legend_label="Diffuse Horizontal Irradiance", + color="blue", + ) + + return Bokeh(plot) + + +def Demo(eos_host: str, eos_port: Union[str, int]) -> str: + server = f"http://{eos_host}:{eos_port}" + + # Get current configuration from server + try: + result = requests.get(f"{server}/v1/config") + result.raise_for_status() + except requests.exceptions.HTTPError as err: + detail = result.json()["detail"] + return P( + f"Can not retrieve configuration from {server}: {err}, {detail}", + cls="text-center", + ) + config = result.json() + + # Set demo configuration + with FILE_DEMOCONFIG.open("r", encoding="utf-8") as fd: + democonfig = json.load(fd) + try: + result = requests.put(f"{server}/v1/config", json=democonfig) + result.raise_for_status() + except requests.exceptions.HTTPError as err: + detail = result.json()["detail"] + # Try to reset to original config + requests.put(f"{server}/v1/config", json=config) + return P( + f"Can not set demo configuration on {server}: {err}, {detail}", + cls="text-center", + ) + + # Update all predictions + try: + result = requests.post(f"{server}/v1/prediction/update") + result.raise_for_status() + except requests.exceptions.HTTPError as err: + detail = result.json()["detail"] + # Try to reset to original config + requests.put(f"{server}/v1/config", json=config) + return P( + f"Can not update predictions on {server}: {err}, {detail}", + cls="text-center", + ) + + # Get Forecasts + try: + params = { + "keys": [ + "pvforecast_ac_power", + "elecprice_marketprice_kwh", + "weather_temp_air", + "weather_ghi", + "weather_dni", + "weather_dhi", + ], + } + result = requests.get(f"{server}/v1/prediction/dataframe", params=params) + result.raise_for_status() + predictions = PydanticDateTimeDataFrame(**result.json()).to_dataframe() + except requests.exceptions.HTTPError as err: + detail = result.json()["detail"] + return P( + f"Can not retrieve predictions from {server}: {err}, {detail}", + cls="text-center", + ) + except Exception as err: + return P( + f"Can not retrieve predictions from {server}: {err}", + cls="text-center", + ) + + # Reset to original config + requests.put(f"{server}/v1/config", json=config) + + return Grid( + DemoPVForecast(predictions, democonfig), + DemoElectricityPriceForecast(predictions, democonfig), + DemoWeatherTempAir(predictions, democonfig), + DemoWeatherIrradiance(predictions, democonfig), + cols_max=2, + ) diff --git a/src/akkudoktoreos/server/dash/footer.py b/src/akkudoktoreos/server/dash/footer.py new file mode 100644 index 00000000..b20142d3 --- /dev/null +++ b/src/akkudoktoreos/server/dash/footer.py @@ -0,0 +1,93 @@ +from typing import Optional, Union + +import requests +from fasthtml.common import A, P +from monsterui.daisy import Loading, LoadingT +from monsterui.franken import ButtonT, DivFullySpaced +from requests.exceptions import RequestException + +from akkudoktoreos.config.config import get_config +from akkudoktoreos.core.logging import get_logger + +logger = get_logger(__name__) +config_eos = get_config() + + +def get_alive(eos_host: str, eos_port: Union[str, int]) -> str: + """Fetch alive information from the specified EOS server. + + Args: + eos_host (str): The hostname of the server. + eos_port (Union[str, int]): The port of the server. + + Returns: + str: Alive data. + """ + result = requests.Response() + try: + result = requests.get(f"http://{eos_host}:{eos_port}/v1/health") + if result.status_code == 200: + alive = result.json()["status"] + else: + alive = f"Server responded with status code: {result.status_code}" + except RequestException as e: + warning_msg = f"{e}" + logger.warning(warning_msg) + alive = warning_msg + + return alive + + +def Footer(eos_host: Optional[str], eos_port: Optional[Union[str, int]]) -> str: + if eos_host is None: + eos_host = config_eos.server.host + if eos_port is None: + eos_port = config_eos.server.port + alive_icon = None + if eos_host is None or eos_port is None: + alive = "EOS server not given: {eos_host}:{eos_port}" + else: + alive = get_alive(eos_host, eos_port) + if alive == "alive": + alive_icon = Loading( + cls=( + LoadingT.ring, + LoadingT.sm, + ), + ) + alive = f"EOS {eos_host}:{eos_port}" + if alive_icon: + alive_cls = f"{ButtonT.primary} uk-link rounded-md" + else: + alive_cls = f"{ButtonT.secondary} uk-link rounded-md" + return DivFullySpaced( + P( + alive_icon, + A(alive, href=f"http://{eos_host}:{eos_port}/docs", target="_blank", cls=alive_cls), + ), + P( + A( + "Documentation", + href="https://akkudoktor-eos.readthedocs.io/en/latest/", + target="_blank", + cls="uk-link", + ), + ), + P( + A( + "Issues", + href="https://github.com/Akkudoktor-EOS/EOS/issues", + target="_blank", + cls="uk-link", + ), + ), + P( + A( + "GitHub", + href="https://github.com/Akkudoktor-EOS/EOS/", + target="_blank", + cls="uk-link", + ), + ), + cls="uk-padding-remove-top uk-padding-remove-botton", + ) diff --git a/src/akkudoktoreos/server/dash/hello.py b/src/akkudoktoreos/server/dash/hello.py new file mode 100644 index 00000000..997a5457 --- /dev/null +++ b/src/akkudoktoreos/server/dash/hello.py @@ -0,0 +1,24 @@ +from typing import Any + +from fasthtml.common import Div + +from akkudoktoreos.server.dash.markdown import Markdown + +hello_md = """![Logo](/eosdash/assets/logo.png) + +# Akkudoktor EOSdash + +The dashboard for Akkudoktor EOS. + +EOS provides a comprehensive solution for simulating and optimizing an energy system based +on renewable energy sources. With a focus on photovoltaic (PV) systems, battery storage (batteries), +load management (consumer requirements), heat pumps, electric vehicles, and consideration of +electricity price data, this system enables forecasting and optimization of energy flow and costs +over a specified period. + +Documentation can be found at [Akkudoktor-EOS](https://akkudoktor-eos.readthedocs.io/en/latest/). +""" + + +def Hello(**kwargs: Any) -> Div: + return Markdown(hello_md, **kwargs) diff --git a/src/akkudoktoreos/server/dash/markdown.py b/src/akkudoktoreos/server/dash/markdown.py new file mode 100644 index 00000000..24b66b3d --- /dev/null +++ b/src/akkudoktoreos/server/dash/markdown.py @@ -0,0 +1,136 @@ +"""Markdown rendering with MonsterUI HTML classes.""" + +from typing import Any, List, Optional, Union + +from fasthtml.common import FT, Div, NotStr +from markdown_it import MarkdownIt +from markdown_it.renderer import RendererHTML +from markdown_it.token import Token +from monsterui.foundations import stringify + + +def render_heading( + self: RendererHTML, tokens: List[Token], idx: int, options: dict, env: dict +) -> str: + """Custom renderer for Markdown headings. + + Adds specific CSS classes based on the heading level. + + Parameters: + self: The renderer instance. + tokens: List of tokens to be rendered. + idx: Index of the current token. + options: Rendering options. + env: Environment sandbox for plugins. + + Returns: + The rendered token as a string. + """ + if tokens[idx].markup == "#": + tokens[idx].attrSet("class", "uk-heading-divider uk-h1 uk-margin") + elif tokens[idx].markup == "##": + tokens[idx].attrSet("class", "uk-heading-divider uk-h2 uk-margin") + elif tokens[idx].markup == "###": + tokens[idx].attrSet("class", "uk-heading-divider uk-h3 uk-margin") + elif tokens[idx].markup == "####": + tokens[idx].attrSet("class", "uk-heading-divider uk-h4 uk-margin") + + # pass token to default renderer. + return self.renderToken(tokens, idx, options, env) + + +def render_paragraph( + self: RendererHTML, tokens: List[Token], idx: int, options: dict, env: dict +) -> str: + """Custom renderer for Markdown paragraphs. + + Adds specific CSS classes. + + Parameters: + self: The renderer instance. + tokens: List of tokens to be rendered. + idx: Index of the current token. + options: Rendering options. + env: Environment sandbox for plugins. + + Returns: + The rendered token as a string. + """ + tokens[idx].attrSet("class", "uk-paragraph") + + # pass token to default renderer. + return self.renderToken(tokens, idx, options, env) + + +def render_blockquote( + self: RendererHTML, tokens: List[Token], idx: int, options: dict, env: dict +) -> str: + """Custom renderer for Markdown blockquotes. + + Adds specific CSS classes. + + Parameters: + self: The renderer instance. + tokens: List of tokens to be rendered. + idx: Index of the current token. + options: Rendering options. + env: Environment sandbox for plugins. + + Returns: + The rendered token as a string. + """ + tokens[idx].attrSet("class", "uk-blockquote") + + # pass token to default renderer. + return self.renderToken(tokens, idx, options, env) + + +def render_link(self: RendererHTML, tokens: List[Token], idx: int, options: dict, env: dict) -> str: + """Custom renderer for Markdown links. + + Adds the target attribute to open links in a new tab. + + Parameters: + self: The renderer instance. + tokens: List of tokens to be rendered. + idx: Index of the current token. + options: Rendering options. + env: Environment sandbox for plugins. + + Returns: + The rendered token as a string. + """ + tokens[idx].attrSet("class", "uk-link") + tokens[idx].attrSet("target", "_blank") + + # pass token to default renderer. + return self.renderToken(tokens, idx, options, env) + + +markdown = MarkdownIt("gfm-like") +markdown.add_render_rule("heading_open", render_heading) +markdown.add_render_rule("paragraph_open", render_paragraph) +markdown.add_render_rule("blockquote_open", render_blockquote) +markdown.add_render_rule("link_open", render_link) + + +markdown_cls = "bg-background text-lg ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50" + + +def Markdown(*c: Any, cls: Optional[Union[str, tuple]] = None, **kwargs: Any) -> FT: + """Component to render Markdown content with custom styling. + + Parameters: + c: Markdown content to be rendered. + cls: Optional additional CSS classes to be added. + kwargs: Additional keyword arguments for the Div component. + + Returns: + An FT object representing the rendered HTML content wrapped in a Div component. + """ + new_cls = markdown_cls + if cls: + new_cls += f" {stringify(cls)}" + kwargs["cls"] = new_cls + md_html = markdown.render(*c) + return Div(NotStr(md_html), **kwargs) diff --git a/src/akkudoktoreos/server/eos.py b/src/akkudoktoreos/server/eos.py index 489931e4..a91e62b1 100755 --- a/src/akkudoktoreos/server/eos.py +++ b/src/akkudoktoreos/server/eos.py @@ -45,6 +45,7 @@ from akkudoktoreos.prediction.loadakkudoktor import LoadAkkudoktorCommonSettings from akkudoktoreos.prediction.prediction import PredictionCommonSettings, get_prediction from akkudoktoreos.prediction.pvforecast import PVForecastCommonSettings +from akkudoktoreos.server.rest.error import create_error_page from akkudoktoreos.server.rest.tasks import repeat_every from akkudoktoreos.utils.datetimeutil import to_datetime, to_duration @@ -57,98 +58,6 @@ # Command line arguments args = None -ERROR_PAGE_TEMPLATE = """ - - - - - - Energy Optimization System (EOS) Error - - - -
    - - -""" - - -def create_error_page( - status_code: str, error_title: str, error_message: str, error_details: str -) -> str: - """Create an error page by replacing placeholders in the template.""" - return ( - ERROR_PAGE_TEMPLATE.replace("STATUS_CODE", status_code) - .replace("ERROR_TITLE", error_title) - .replace("ERROR_MESSAGE", error_message) - .replace("ERROR_DETAILS", error_details) - ) - # ---------------------- # EOSdash server startup @@ -186,14 +95,16 @@ def start_eosdash() -> subprocess.Popen: psutil.process_iter.cache_clear() for retries in range(2): for p in psutil.process_iter(["name", "cmdline"]): - for arg in p.info["cmdline"]: - if arg.endswith("akkudoktoreos/server/eosdash.py") or arg.endswith( - "akkudoktoreos.server.eosdash" - ): - pid = p.pid - cmdline = p.info["cmdline"] - logger.warning(f"EOS can not start EOSdash, `{pid}` already running: {cmdline}") - return p + cmdline = p.info["cmdline"] + if cmdline: + for arg in cmdline: + if arg.endswith("akkudoktoreos/server/eosdash.py") or arg.endswith( + "akkudoktoreos.server.eosdash" + ): + logger.warning( + f"EOS can not start EOSdash, `{p.pid}` already running: {cmdline}" + ) + return p cmd = [ sys.executable, @@ -298,9 +209,6 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: ) -server_dir = Path(__file__).parent.resolve() - - class PdfResponse(FileResponse): media_type = "application/pdf" @@ -375,7 +283,7 @@ def fastapi_health_get(): # type: ignore @app.post("/v1/config/reset", tags=["config"]) def fastapi_config_reset_post() -> ConfigEOS: - """Reset the configuration. + """Reset the configuration to the EOS configuration file. Returns: configuration (ConfigEOS): The current configuration after update. @@ -664,6 +572,49 @@ def fastapi_prediction_series_get( return PydanticDateTimeSeries.from_series(pdseries) +@app.get("/v1/prediction/dataframe", tags=["prediction"]) +def fastapi_prediction_dataframe_get( + keys: Annotated[list[str], Query(description="Prediction keys.")], + start_datetime: Annotated[ + Optional[str], + Query(description="Starting datetime (inclusive)."), + ] = None, + end_datetime: Annotated[ + Optional[str], + Query(description="Ending datetime (exclusive)."), + ] = None, + interval: Annotated[ + Optional[str], + Query(description="Time duration for each interval. Defaults to 1 hour."), + ] = None, +) -> PydanticDateTimeDataFrame: + """Get prediction for given key within given date range as series. + + Args: + key (str): Prediction key + start_datetime (Optional[str]): Starting datetime (inclusive). + Defaults to start datetime of latest prediction. + end_datetime (Optional[str]: Ending datetime (exclusive). + + Defaults to end datetime of latest prediction. + """ + for key in keys: + if key not in prediction_eos.record_keys: + raise HTTPException(status_code=404, detail=f"Key '{key}' is not available.") + if start_datetime is None: + start_datetime = prediction_eos.start_datetime + else: + start_datetime = to_datetime(start_datetime) + if end_datetime is None: + end_datetime = prediction_eos.end_datetime + else: + end_datetime = to_datetime(end_datetime) + df = prediction_eos.keys_to_dataframe( + keys=keys, start_datetime=start_datetime, end_datetime=end_datetime, interval=interval + ) + return PydanticDateTimeDataFrame.from_dataframe(df, tz=config_eos.general.timezone) + + @app.get("/v1/prediction/list", tags=["prediction"]) def fastapi_prediction_list_get( key: Annotated[str, Query(description="Prediction key.")], @@ -1172,14 +1123,16 @@ def run_eos(host: str, port: int, log_level: str, access_log: bool, reload: bool psutil.process_iter.cache_clear() for retries in range(10): for p in psutil.process_iter(["name", "cmdline"]): - for arg in p.info["cmdline"]: - if arg.endswith("akkudoktoreos/server/eos.py") or arg.endswith( - "akkudoktoreos.server.eos" - ): - if p.pid != psutil.Process().pid: - # This is not our pid - logger.warning(f"EOS `{p.pid}` already running: {p.info["cmdline"]}") - return + cmdline = p.info["cmdline"] + if cmdline: + for arg in cmdline: + if arg.endswith("akkudoktoreos/server/eos.py") or arg.endswith( + "akkudoktoreos.server.eos" + ): + if p.pid != psutil.Process().pid: + # This is not our pid + logger.warning(f"EOS `{p.pid}` already running: {cmdline}") + return try: uvicorn.run( diff --git a/src/akkudoktoreos/server/eosdash.py b/src/akkudoktoreos/server/eosdash.py index 72df32fd..51765e49 100644 --- a/src/akkudoktoreos/server/eosdash.py +++ b/src/akkudoktoreos/server/eosdash.py @@ -1,126 +1,144 @@ import argparse import os import sys -from functools import reduce -from typing import Any, Union +import traceback +from pathlib import Path +from typing import Optional import psutil import uvicorn -from fasthtml.common import H1, Table, Td, Th, Thead, Titled, Tr, fast_app -from fasthtml.starlette import JSONResponse -from pydantic.fields import ComputedFieldInfo, FieldInfo -from pydantic_core import PydanticUndefined +from fasthtml.common import FileResponse, JSONResponse +from monsterui.core import FastHTML, Theme from akkudoktoreos.config.config import get_config from akkudoktoreos.core.logging import get_logger -from akkudoktoreos.core.pydantic import PydanticBaseModel +from akkudoktoreos.server.dash.bokeh import BokehJS +from akkudoktoreos.server.dash.components import Page -logger = get_logger(__name__) +# Pages +from akkudoktoreos.server.dash.configuration import Configuration +from akkudoktoreos.server.dash.demo import Demo +from akkudoktoreos.server.dash.footer import Footer +from akkudoktoreos.server.dash.hello import Hello + +# from akkudoktoreos.server.dash.altair import AltairJS +logger = get_logger(__name__) config_eos = get_config() +# The favicon for EOSdash +favicon_filepath = Path(__file__).parent.joinpath("dash/assets/favicon/favicon.ico") +if not favicon_filepath.exists(): + raise ValueError(f"Does not exist {favicon_filepath}") + # Command line arguments -args = None +args: Optional[argparse.Namespace] = None -def get_default_value(field_info: Union[FieldInfo, ComputedFieldInfo], regular_field: bool) -> Any: - default_value = "" - if regular_field: - if (val := field_info.default) is not PydanticUndefined: - default_value = val - else: - default_value = "N/A" - return default_value +# Get frankenui and tailwind headers via CDN using Theme.green.headers() +# Add altair headers +# hdrs=(Theme.green.headers(highlightjs=True), AltairJS,) +hdrs = ( + Theme.green.headers(highlightjs=True), + BokehJS, +) + +# The EOSdash application +app: FastHTML = FastHTML( + title="EOSdash", + hdrs=hdrs, + secret_key=os.getenv("EOS_SERVER__EOSDASH_SESSKEY"), +) -def resolve_nested_types(field_type: Any, parent_types: list[str]) -> list[tuple[Any, list[str]]]: - resolved_types: list[tuple[Any, list[str]]] = [] +def eos_server() -> tuple[str, int]: + """Retrieves the EOS server host and port configuration. - origin = getattr(field_type, "__origin__", field_type) - if origin is Union: - for arg in getattr(field_type, "__args__", []): - if arg is not type(None): - resolved_types.extend(resolve_nested_types(arg, parent_types)) + If `args` is provided, it uses the `eos_host` and `eos_port` from `args`. + Otherwise, it falls back to the values from `config_eos.server`. + + Returns: + tuple[str, int]: A tuple containing: + - `eos_host` (str): The EOS server hostname or IP. + - `eos_port` (int): The EOS server port. + """ + if args is None: + eos_host = str(config_eos.server.host) + eos_port = config_eos.server.port else: - resolved_types.append((field_type, parent_types)) - - return resolved_types - - -configs = [] -inner_types: set[type[PydanticBaseModel]] = set() -for field_name, field_info in list(config_eos.model_fields.items()) + list( - config_eos.model_computed_fields.items() -): - - def extract_nested_models( - subfield_info: Union[ComputedFieldInfo, FieldInfo], parent_types: list[str] - ) -> None: - regular_field = isinstance(subfield_info, FieldInfo) - subtype = subfield_info.annotation if regular_field else subfield_info.return_type - - if subtype in inner_types: - return - - nested_types = resolve_nested_types(subtype, []) - found_basic = False - for nested_type, nested_parent_types in nested_types: - if not isinstance(nested_type, type) or not issubclass(nested_type, PydanticBaseModel): - if found_basic: - continue - - config = {} - config["name"] = ".".join(parent_types) - try: - config["value"] = reduce(getattr, [config_eos] + parent_types) - except AttributeError: - # Parent value(s) are not set in current config - config["value"] = "" - config["default"] = get_default_value(subfield_info, regular_field) - config["description"] = ( - subfield_info.description if subfield_info.description else "" - ) - configs.append(config) - found_basic = True - else: - new_parent_types = parent_types + nested_parent_types - inner_types.add(nested_type) - for nested_field_name, nested_field_info in list( - nested_type.model_fields.items() - ) + list(nested_type.model_computed_fields.items()): - extract_nested_models( - nested_field_info, - new_parent_types + [nested_field_name], - ) - - extract_nested_models(field_info, [field_name]) -configs = sorted(configs, key=lambda x: x["name"]) - - -app, rt = fast_app( - secret_key=os.getenv("EOS_SERVER__EOSDASH_SESSKEY"), -) + eos_host = args.eos_host + eos_port = args.eos_port + if eos_host is None: + eos_host = "0.0.0.0" + if eos_port is None: + eos_port = 8503 + return eos_host, eos_port -def config_table() -> Table: - rows = [ - Tr( - Td(config["name"]), - Td(config["value"]), - Td(config["default"]), - Td(config["description"]), - cls="even:bg-purple/5", - ) - for config in configs - ] - flds = "Name", "Value", "Default", "Description" - head = Thead(*map(Th, flds), cls="bg-purple/10") - return Table(head, *rows, cls="w-full") +@app.get("/favicon.ico") +def get_eosdash_favicon(): # type: ignore + """Get favicon.""" + return FileResponse(path=favicon_filepath) -@rt("/") -def get(): # type: ignore - return Titled("EOS Dashboard", H1("Configuration"), config_table()) +@app.get("/") +def get_eosdash(): # type: ignore + """Serves the main EOSdash page. + + Returns: + Page: The main dashboard page with navigation links and footer. + """ + return Page( + None, + { + "EOSdash": "/eosdash/hello", + "Config": "/eosdash/configuration", + "Demo": "/eosdash/demo", + }, + Hello(), + Footer(*eos_server()), + "/eosdash/footer", + ) + + +@app.get("/eosdash/footer") +def get_eosdash_footer(): # type: ignore + """Serves the EOSdash Foooter information. + + Returns: + Footer: The Footer component. + """ + return Footer(*eos_server()) + + +@app.get("/eosdash/hello") +def get_eosdash_hello(): # type: ignore + """Serves the EOSdash Hello page. + + Returns: + Hello: The Hello page component. + """ + return Hello() + + +@app.get("/eosdash/configuration") +def get_eosdash_configuration(): # type: ignore + """Serves the EOSdash Configuration page. + + Returns: + Configuration: The Configuration page component. + """ + return Configuration(*eos_server()) + + +@app.get("/eosdash/demo") +def get_eosdash_demo(): # type: ignore + """Serves the EOSdash Demo page. + + Returns: + Demo: The Demo page component. + """ + return Demo(*eos_server()) @app.get("/eosdash/health") @@ -129,6 +147,13 @@ def get_eosdash_health(): # type: ignore return JSONResponse({"status": "alive"}) +@app.get("/eosdash/assets/{fname:path}.{ext:static}") +def get_eosdash_assets(fname: str, ext: str): # type: ignore + """Get assets.""" + asset_filepath = Path(__file__).parent.joinpath(f"dash/assets/{fname}.{ext}") + return FileResponse(path=asset_filepath) + + def run_eosdash(host: str, port: int, log_level: str, access_log: bool, reload: bool) -> None: """Run the EOSdash server with the specified configurations. @@ -159,14 +184,16 @@ def run_eosdash(host: str, port: int, log_level: str, access_log: bool, reload: psutil.process_iter.cache_clear() for retries in range(2): for p in psutil.process_iter(["name", "cmdline"]): - for arg in p.info["cmdline"]: - if arg.endswith("akkudoktoreos/server/eosdash.py") or arg.endswith( - "akkudoktoreos.server.eosdash" - ): - if p.pid != psutil.Process().pid: - # This is not our pid - logger.warning(f"EOSdash `{p.pid}` already running: {p.info["cmdline"]}") - return + cmdline = p.info["cmdline"] + if cmdline: + for arg in cmdline: + if arg.endswith("akkudoktoreos/server/eosdash.py") or arg.endswith( + "akkudoktoreos.server.eosdash" + ): + if p.pid != psutil.Process().pid: + # This is not our pid + logger.warning(f"EOSdash `{p.pid}` already running: {cmdline}") + return # Setup config from args if args: @@ -184,7 +211,7 @@ def run_eosdash(host: str, port: int, log_level: str, access_log: bool, reload: "akkudoktoreos.server.eosdash:app", host=host, port=port, - log_level=log_level.lower(), # Convert log_level to lowercase + log_level=log_level.lower(), access_log=access_log, reload=reload, ) @@ -198,7 +225,7 @@ def main() -> None: This function sets up the argument parser to accept command-line arguments for host, port, log_level, access_log, and reload. It uses default values from the - config_eos module if arguments are not provided. After parsing the arguments, + config module if arguments are not provided. After parsing the arguments, it starts the EOSdash server with the specified configurations. Command-line Arguments: @@ -212,7 +239,6 @@ def main() -> None: """ parser = argparse.ArgumentParser(description="Start EOSdash server.") - # Host and port arguments with defaults from config_eos parser.add_argument( "--host", type=str, @@ -225,8 +251,6 @@ def main() -> None: default=config_eos.server.eosdash_port, help="Port for the EOSdash server (default: value from config)", ) - - # EOS Host and port arguments with defaults from config_eos parser.add_argument( "--eos-host", type=str, @@ -239,8 +263,6 @@ def main() -> None: default=config_eos.server.port, help="Port of the EOS server (default: value from config)", ) - - # Optional arguments for log_level, access_log, and reload parser.add_argument( "--log_level", type=str, @@ -251,7 +273,7 @@ def main() -> None: "--access_log", type=bool, default=False, - help="Enable or disable access log. Options: True or False (default: True)", + help="Enable or disable access log. Options: True or False (default: False)", ) parser.add_argument( "--reload", @@ -260,6 +282,7 @@ def main() -> None: help="Enable or disable auto-reload. Useful for development. Options: True or False (default: False)", ) + global args args = parser.parse_args() try: @@ -267,6 +290,7 @@ def main() -> None: except Exception as ex: error_msg = f"Failed to run EOSdash: {ex}" logger.error(error_msg) + traceback.print_exc() sys.exit(1) diff --git a/src/akkudoktoreos/server/rest/error.py b/src/akkudoktoreos/server/rest/error.py new file mode 100644 index 00000000..dd8d9ee7 --- /dev/null +++ b/src/akkudoktoreos/server/rest/error.py @@ -0,0 +1,91 @@ +ERROR_PAGE_TEMPLATE = """ + + + + + + Energy Optimization System (EOS) Error + + + +
    +

    STATUS_CODE

    +

    ERROR_TITLE

    +

    ERROR_MESSAGE

    +
    ERROR_DETAILS
    + Back to Home +
    + + +""" + + +def create_error_page( + status_code: str, error_title: str, error_message: str, error_details: str +) -> str: + """Create an error page by replacing placeholders in the template.""" + return ( + ERROR_PAGE_TEMPLATE.replace("STATUS_CODE", status_code) + .replace("ERROR_TITLE", error_title) + .replace("ERROR_MESSAGE", error_message) + .replace("ERROR_DETAILS", error_details) + ) diff --git a/tests/test_eosdashserver.py b/tests/test_eosdashserver.py index 9f10a9c0..07cc6784 100644 --- a/tests/test_eosdashserver.py +++ b/tests/test_eosdashserver.py @@ -4,6 +4,14 @@ import requests +from akkudoktoreos.server.dash.demo import Demo + +if os.name == "nt": + host = "localhost" +else: + host = "0.0.0.0" +eosdash_url = f"http://{host}:8504" + def test_eosdash(eosdash_server): """Test the EOSdash server.""" @@ -12,26 +20,33 @@ def test_eosdash(eosdash_server): assert result.json()["status"] == "alive" -def test_eosdash_proxied_by_eos(server): - """Test the EOSdash server proxied by EOS server.""" - if os.name == "nt": - host = "localhost" - else: - host = "0.0.0.0" - eosdash_server = f"http://{host}:8504" - - # Assure EOSdash is up - startup = False - error = "" - for retries in range(10): - try: - result = requests.get(f"{eosdash_server}/eosdash/health") - if result.status_code == HTTPStatus.OK: - startup = True - break - error = f"{result.status_code}, {str(result.content)}" - except Exception as ex: - error = str(ex) - time.sleep(3) - assert startup, f"Connection to {eosdash_server}/eosdash/health failed: {error}" - assert result.json()["status"] == "alive" +class TestEOSdashServer: + def test_eosdash_proxied_by_eos(self, server_setup_for_class): + """Test the EOSdash server proxied by EOS server.""" + # Assure EOSdash is up + startup = False + error = "" + for retries in range(10): + try: + result = requests.get(f"{eosdash_url}/eosdash/health") + if result.status_code == HTTPStatus.OK: + startup = True + break + error = f"{result.status_code}, {str(result.content)}" + except Exception as ex: + error = str(ex) + time.sleep(3) + assert startup, f"Connection to {eosdash_url}/eosdash/health failed: {error}" + assert result.json()["status"] == "alive" + + def test_eosdash_demo(self, server_setup_for_class): + """Test EOSdash demo page.""" + server = server_setup_for_class["server"] + eos_dir = server_setup_for_class["eos_dir"] + + html = Demo(host, 8503) + assert html is not None + # Convert to string for easy lookup + html = str(html) + assert html.startswith("div") + assert "function embed_document(root)" in html