RoyAalekh commited on
Commit
2d7280b
·
verified ·
1 Parent(s): aeee7e2

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +203 -147
  2. consts.py +23 -0
  3. plotting.py +427 -0
  4. requirements.txt +3 -6
app.py CHANGED
@@ -1,147 +1,203 @@
1
- import io
2
- import random
3
- from typing import List, Tuple
4
-
5
- import aiohttp
6
- import panel as pn
7
- from PIL import Image
8
- from transformers import CLIPModel, CLIPProcessor
9
-
10
- pn.extension(design="bootstrap", sizing_mode="stretch_width")
11
-
12
- ICON_URLS = {
13
- "brand-github": "https://github.com/holoviz/panel",
14
- "brand-twitter": "https://twitter.com/Panel_Org",
15
- "brand-linkedin": "https://www.linkedin.com/company/panel-org",
16
- "message-circle": "https://discourse.holoviz.org/",
17
- "brand-discord": "https://discord.gg/AXRHnJU6sP",
18
- }
19
-
20
-
21
- async def random_url(_):
22
- pet = random.choice(["cat", "dog"])
23
- api_url = f"https://api.the{pet}api.com/v1/images/search"
24
- async with aiohttp.ClientSession() as session:
25
- async with session.get(api_url) as resp:
26
- return (await resp.json())[0]["url"]
27
-
28
-
29
- @pn.cache
30
- def load_processor_model(
31
- processor_name: str, model_name: str
32
- ) -> Tuple[CLIPProcessor, CLIPModel]:
33
- processor = CLIPProcessor.from_pretrained(processor_name)
34
- model = CLIPModel.from_pretrained(model_name)
35
- return processor, model
36
-
37
-
38
- async def open_image_url(image_url: str) -> Image:
39
- async with aiohttp.ClientSession() as session:
40
- async with session.get(image_url) as resp:
41
- return Image.open(io.BytesIO(await resp.read()))
42
-
43
-
44
- def get_similarity_scores(class_items: List[str], image: Image) -> List[float]:
45
- processor, model = load_processor_model(
46
- "openai/clip-vit-base-patch32", "openai/clip-vit-base-patch32"
47
- )
48
- inputs = processor(
49
- text=class_items,
50
- images=[image],
51
- return_tensors="pt", # pytorch tensors
52
- )
53
- outputs = model(**inputs)
54
- logits_per_image = outputs.logits_per_image
55
- class_likelihoods = logits_per_image.softmax(dim=1).detach().numpy()
56
- return class_likelihoods[0]
57
-
58
-
59
- async def process_inputs(class_names: List[str], image_url: str):
60
- """
61
- High level function that takes in the user inputs and returns the
62
- classification results as panel objects.
63
- """
64
- try:
65
- main.disabled = True
66
- if not image_url:
67
- yield "##### ⚠️ Provide an image URL"
68
- return
69
-
70
- yield "##### ⚙ Fetching image and running model..."
71
- try:
72
- pil_img = await open_image_url(image_url)
73
- img = pn.pane.Image(pil_img, height=400, align="center")
74
- except Exception as e:
75
- yield f"##### 😔 Something went wrong, please try a different URL!"
76
- return
77
-
78
- class_items = class_names.split(",")
79
- class_likelihoods = get_similarity_scores(class_items, pil_img)
80
-
81
- # build the results column
82
- results = pn.Column("##### 🎉 Here are the results!", img)
83
-
84
- for class_item, class_likelihood in zip(class_items, class_likelihoods):
85
- row_label = pn.widgets.StaticText(
86
- name=class_item.strip(), value=f"{class_likelihood:.2%}", align="center"
87
- )
88
- row_bar = pn.indicators.Progress(
89
- value=int(class_likelihood * 100),
90
- sizing_mode="stretch_width",
91
- bar_color="secondary",
92
- margin=(0, 10),
93
- design=pn.theme.Material,
94
- )
95
- results.append(pn.Column(row_label, row_bar))
96
- yield results
97
- finally:
98
- main.disabled = False
99
-
100
-
101
- # create widgets
102
- randomize_url = pn.widgets.Button(name="Randomize URL", align="end")
103
-
104
- image_url = pn.widgets.TextInput(
105
- name="Image URL to classify",
106
- value=pn.bind(random_url, randomize_url),
107
- )
108
- class_names = pn.widgets.TextInput(
109
- name="Comma separated class names",
110
- placeholder="Enter possible class names, e.g. cat, dog",
111
- value="cat, dog, parrot",
112
- )
113
-
114
- input_widgets = pn.Column(
115
- "##### 😊 Click randomize or paste a URL to start classifying!",
116
- pn.Row(image_url, randomize_url),
117
- class_names,
118
- )
119
-
120
- # add interactivity
121
- interactive_result = pn.panel(
122
- pn.bind(process_inputs, image_url=image_url, class_names=class_names),
123
- height=600,
124
- )
125
-
126
- # add footer
127
- footer_row = pn.Row(pn.Spacer(), align="center")
128
- for icon, url in ICON_URLS.items():
129
- href_button = pn.widgets.Button(icon=icon, width=35, height=35)
130
- href_button.js_on_click(code=f"window.open('{url}')")
131
- footer_row.append(href_button)
132
- footer_row.append(pn.Spacer())
133
-
134
- # create dashboard
135
- main = pn.WidgetBox(
136
- input_widgets,
137
- interactive_result,
138
- footer_row,
139
- )
140
-
141
- title = "Panel Demo - Image Classification"
142
- pn.template.BootstrapTemplate(
143
- title=title,
144
- main=main,
145
- main_max_width="min(50%, 698px)",
146
- header_background="#F08080",
147
- ).servable(title=title)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import panel as pn
2
+ import pandas as pd
3
+
4
+ from consts import INVERTER_ID_MAPPING, TEMPERATURE_COLUMNS_TO_USE
5
+ from plotting import (
6
+ create_heatmap,
7
+ create_iv_plot_with_power_curves,
8
+ create_iv_plot,
9
+ create_iv_plot_with_power_and_temperature_curves,
10
+ create_iv_plot_with_temperature_curves,
11
+ )
12
+
13
+ # Read metadata to get the date range
14
+ timeseries_data = pd.read_csv(
15
+ r"data/multi_index_timeseries_data.csv",
16
+ index_col=0,
17
+ header=[0, 2],
18
+ parse_dates=True,
19
+ )
20
+ other_features_data = pd.read_csv(
21
+ r"data/other_features_data.csv", index_col=0, header=0, parse_dates=True
22
+ )
23
+ other_features_data = other_features_data[TEMPERATURE_COLUMNS_TO_USE]
24
+ kpi_data = pd.read_csv(
25
+ r"data/kpi_data.csv", index_col=0, header=0, parse_dates=True
26
+ )
27
+ daily_timeseries_data = pd.read_csv(
28
+ r"data/daily_aggregated_timeseries_data.csv",
29
+ index_col=0,
30
+ header=0,
31
+ parse_dates=True,
32
+ )
33
+
34
+ # Initialize Panel extension
35
+ pn.extension("plotly")
36
+
37
+ # Widgets for selecting columns
38
+ inverter_ids = pn.widgets.MultiSelect(
39
+ name="Inverter IDs",
40
+ value=[list(INVERTER_ID_MAPPING.keys())[0]],
41
+ options=list(INVERTER_ID_MAPPING.keys()),
42
+ size=8,
43
+ )
44
+ # Line Plots
45
+ plot_power_curves = pn.widgets.Checkbox(name="Plot P-dc and P-ac", value=False)
46
+ plot_temperature_curves = pn.widgets.Checkbox(name="Plot Temperatures", value=False)
47
+
48
+ # Heatmaps
49
+ heatmap_pr = pn.widgets.Checkbox(name="Heat Map PR", value=False)
50
+ heatmap_sy = pn.widgets.Checkbox(name="Heat Map SY", value=False)
51
+ heatmap_current = pn.widgets.Checkbox(name="Heat Map - Current", value=False)
52
+ heatmap_voltage = pn.widgets.Checkbox(name="Heat Map - Voltage", value=False)
53
+ heatmap_power = pn.widgets.Checkbox(name="Heat Map - Power", value=False)
54
+ heatmap_irradiance = pn.widgets.Checkbox(name="Heat Map - Irradiance", value=False)
55
+ heatmap_temperature = pn.widgets.Checkbox(
56
+ name="Heat Map - Temperature " "Heatsink", value=False
57
+ )
58
+
59
+ # Create a loading spinner
60
+ loading_spinner = pn.indicators.LoadingSpinner(width=50, height=50)
61
+
62
+
63
+ # Panel interactive functions
64
+ @pn.depends(
65
+ inverter_ids.param.value,
66
+ plot_power_curves.param.value,
67
+ plot_temperature_curves.param.value,
68
+ )
69
+ def update_iv_plot(inverter_ids, plot_power_curves, plot_temperature_curves):
70
+ if not inverter_ids:
71
+ return pn.pane.Markdown("No Inverters selected for Plotting.")
72
+ else:
73
+ # Plot IV + Power + Temperature Curves
74
+ if plot_power_curves and plot_temperature_curves:
75
+ print("Plotting IV + Power + Temperature Curves")
76
+ return create_iv_plot_with_power_and_temperature_curves(
77
+ timeseries_data, other_features_data, inverter_ids
78
+ )
79
+ # Plot IV + Temperature Curves
80
+ elif (not plot_power_curves) and plot_temperature_curves:
81
+ print("Plot IV + Temperature Curves")
82
+ return create_iv_plot_with_temperature_curves(
83
+ timeseries_data, other_features_data, inverter_ids
84
+ )
85
+ # Plot IV + Power Curves
86
+ elif plot_power_curves and (not plot_temperature_curves):
87
+ print("Plot IV + Power Curves")
88
+ return create_iv_plot_with_power_curves(timeseries_data, inverter_ids)
89
+ # Plot only IV Curves
90
+ else:
91
+ print("Plot only IV Curves")
92
+ return create_iv_plot(timeseries_data, inverter_ids)
93
+
94
+
95
+ @pn.depends(heatmap_pr.param.value)
96
+ def update_heatmap_pr(heatmap_pr):
97
+ if heatmap_pr:
98
+ pr_df = kpi_data.filter(like="pr")
99
+ pr_df.columns = [i.split("-")[1] for i in pr_df.columns]
100
+ pr_heatmap = create_heatmap(pr_df, "PR Heatmap")
101
+ return pn.Row(pr_heatmap)
102
+ return pn.pane.Markdown("")
103
+
104
+
105
+ @pn.depends(heatmap_sy.param.value)
106
+ def update_heatmap_sy(heatmap_sy):
107
+ if heatmap_sy:
108
+ sy_df = kpi_data.filter(like="daily_specific_yield")
109
+ sy_df.columns = [i.split("-")[1] for i in sy_df.columns]
110
+ sy_heatmap = create_heatmap(sy_df, "SY Heatmap")
111
+ return pn.Row(sy_heatmap)
112
+ return pn.pane.Markdown("")
113
+
114
+
115
+ @pn.depends(heatmap_current.param.value)
116
+ def update_heatmap_current(heatmap_current):
117
+ if heatmap_current:
118
+ current_df = daily_timeseries_data.filter(like="I")
119
+ current_df.columns = [i.split("-")[1] for i in current_df.columns]
120
+ current_heatmap = create_heatmap(current_df, "Current Heatmap")
121
+ return pn.Row(current_heatmap)
122
+ return pn.pane.Markdown("")
123
+
124
+
125
+ @pn.depends(heatmap_voltage.param.value)
126
+ def update_heatmap_voltage(heatmap_voltage):
127
+ if heatmap_voltage:
128
+ voltage_df = daily_timeseries_data.filter(like="V")
129
+ voltage_df.columns = [i.split("-")[1] for i in voltage_df.columns]
130
+ voltage_heatmap = create_heatmap(voltage_df, "Voltage Heatmap")
131
+ return pn.Row(voltage_heatmap)
132
+ return pn.pane.Markdown("")
133
+
134
+
135
+ @pn.depends(heatmap_power.param.value)
136
+ def update_heatmap_power(heatmap_power):
137
+ if heatmap_power:
138
+ power_df = daily_timeseries_data.filter(like="P")
139
+ power_df.columns = [i.split("-")[1] for i in power_df.columns]
140
+ power_heatmap = create_heatmap(power_df, "Power Heatmap")
141
+ return pn.Row(power_heatmap)
142
+ return pn.pane.Markdown("")
143
+
144
+
145
+ @pn.depends(heatmap_irradiance.param.value)
146
+ def update_heatmap_irradiance(heatmap_irradiance):
147
+ if heatmap_irradiance:
148
+ irradiance_df = daily_timeseries_data.filter(like="G")
149
+ irradiance_df.columns = [i.split("-")[1] for i in irradiance_df.columns]
150
+ irradiance_heatmap = create_heatmap(irradiance_df, "Irradiance " "Heatmap")
151
+ return pn.Row(irradiance_heatmap)
152
+ return pn.pane.Markdown("")
153
+
154
+
155
+ @pn.depends(heatmap_temperature.param.value)
156
+ def update_heatmap_temperature(heatmap_temperature):
157
+ if heatmap_temperature:
158
+ temp_df = daily_timeseries_data.filter(like="THeatSink")
159
+ temp_df.columns = [i.split("-")[1] for i in temp_df.columns]
160
+ temp_heatmap = create_heatmap(temp_df, "T-Heatsink Heatmap")
161
+ return pn.Row(temp_heatmap)
162
+ return pn.pane.Markdown("")
163
+
164
+
165
+ # Create dashboard layout
166
+ dashboard = pn.Column(
167
+ "# ENEL Dashboard",
168
+ # IV Plots
169
+ pn.Row(
170
+ pn.Column(inverter_ids, plot_power_curves, plot_temperature_curves),
171
+ pn.panel(update_iv_plot, sizing_mode="stretch_width"),
172
+ ),
173
+ # Heatmaps
174
+ pn.Row(
175
+ pn.Column(heatmap_pr), pn.panel(update_heatmap_pr, sizing_mode="stretch_width")
176
+ ),
177
+ pn.Row(
178
+ pn.Column(heatmap_sy), pn.panel(update_heatmap_sy, sizing_mode="stretch_width")
179
+ ),
180
+ pn.Row(
181
+ pn.Column(heatmap_current),
182
+ pn.panel(update_heatmap_current, sizing_mode="stretch_width"),
183
+ ),
184
+ pn.Row(
185
+ pn.Column(heatmap_voltage),
186
+ pn.panel(update_heatmap_voltage, sizing_mode="stretch_width"),
187
+ ),
188
+ pn.Row(
189
+ pn.Column(heatmap_power),
190
+ pn.panel(update_heatmap_power, sizing_mode="stretch_width"),
191
+ ),
192
+ pn.Row(
193
+ pn.Column(heatmap_irradiance),
194
+ pn.panel(update_heatmap_irradiance, sizing_mode="stretch_width"),
195
+ ),
196
+ pn.Row(
197
+ pn.Column(heatmap_temperature),
198
+ pn.panel(update_heatmap_temperature, sizing_mode="stretch_width"),
199
+ ),
200
+ )
201
+
202
+ # Serve the dashboard
203
+ dashboard.servable()
consts.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ INVERTER_ID_MAPPING = {
2
+ "01.01.1A.2 (699)": 699,
3
+ "02.08.1A.2 (700)": 700,
4
+ "02.09.1A.2 (701)": 701,
5
+ "03.08.1A.2 (702)": 702,
6
+ "05.02.1A.2 (703)": 703,
7
+ "05.06.1A.2 (704)": 704,
8
+ }
9
+
10
+ CURRENT = "I"
11
+ VOLTAGE = "V"
12
+ IRRADIANCE = "G"
13
+ POWER_AC = "P-AC"
14
+ POWER_DC = "P"
15
+ T_AMBIENT = "T_Air"
16
+ T_MODULE = "Tmod"
17
+ T_HEATSINK = "T_HEAT_SINK"
18
+ T_CPU = "T_CPU"
19
+ T_BOARD = "T_BOARD"
20
+
21
+ TEMPERATURE_COLUMNS_TO_USE = ["T_CPU", "T_BOARD", "T_Air", "Inv", "T_HEAT_SINK"]
22
+
23
+ HEATMAP_OPTIONS = ["PR", "SY", "IVPGT"]
plotting.py ADDED
@@ -0,0 +1,427 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import panel as pn
2
+ import plotly.graph_objs as go
3
+ import plotly.express as px
4
+ from plotly.subplots import make_subplots
5
+
6
+ from consts import (
7
+ INVERTER_ID_MAPPING,
8
+ CURRENT,
9
+ IRRADIANCE,
10
+ VOLTAGE,
11
+ POWER_DC,
12
+ POWER_AC,
13
+ T_AMBIENT,
14
+ T_MODULE,
15
+ T_HEATSINK,
16
+ T_CPU,
17
+ T_BOARD,
18
+ )
19
+
20
+
21
+ def create_iv_plot(df, inverter_ids):
22
+ """# Helper function to create a line plot with secondary y-axis"""
23
+
24
+ print("Selected Inverter Ids: {}".format(inverter_ids))
25
+ fig = make_subplots(
26
+ rows=2,
27
+ cols=1,
28
+ shared_xaxes=True,
29
+ vertical_spacing=0.01,
30
+ specs=[[{"secondary_y": True}], [{}]],
31
+ )
32
+
33
+ for inverter in inverter_ids:
34
+ inv_id = INVERTER_ID_MAPPING[inverter]
35
+ print("Creating plot for inv_id: {}".format(inv_id))
36
+ inv_data = df[str(inv_id)]
37
+
38
+ # Graph 1: DC current and G-POA (Twin Y-Axis)
39
+ fig.add_trace(
40
+ go.Scatter(
41
+ x=inv_data.index,
42
+ y=inv_data[CURRENT],
43
+ mode="lines",
44
+ name=f"{CURRENT}-{inv_id}",
45
+ ),
46
+ row=1,
47
+ col=1,
48
+ secondary_y=False,
49
+ )
50
+
51
+ fig.add_trace(
52
+ go.Scatter(
53
+ x=inv_data.index,
54
+ y=inv_data[IRRADIANCE],
55
+ mode="lines",
56
+ name=f"{IRRADIANCE}-{inv_id}",
57
+ ),
58
+ row=1,
59
+ col=1,
60
+ secondary_y=True,
61
+ )
62
+
63
+ # Graph 2: Voltage
64
+ fig.add_trace(
65
+ go.Scatter(
66
+ x=inv_data.index,
67
+ y=inv_data[VOLTAGE],
68
+ mode="lines",
69
+ name=f"{VOLTAGE}-{inv_id}",
70
+ ),
71
+ row=2,
72
+ col=1,
73
+ )
74
+ # Update axis labels
75
+ fig.update_yaxes(title_text="Current (A)", row=1, col=1)
76
+ fig.update_yaxes(title_text="Irradiance (W/m2)", row=1, col=1, secondary_y=True)
77
+ fig.update_yaxes(title_text="Voltage (V)", row=2, col=1)
78
+ fig.update_xaxes(title_text="Datetime", row=2, col=1)
79
+
80
+ # Update layout to add titles and adjust axis labels
81
+ fig.update_layout(title_text="IV Plots", height=800, width=1000)
82
+
83
+ return fig
84
+
85
+
86
+ def create_iv_plot_with_power_curves(df, inverter_ids):
87
+ """# Helper function to create a line plot with secondary y-axis"""
88
+
89
+ print("Selected Inverter Ids: {}".format(inverter_ids))
90
+ fig = make_subplots(
91
+ rows=3,
92
+ cols=1,
93
+ shared_xaxes=True,
94
+ vertical_spacing=0.01,
95
+ specs=[[{"secondary_y": True}], [{}], [{}]],
96
+ )
97
+
98
+ for inverter in inverter_ids:
99
+ inv_id = INVERTER_ID_MAPPING[inverter]
100
+ print("Creating plot for inv_id: {}".format(inv_id))
101
+ inv_data = df[str(inv_id)]
102
+
103
+ # Graph 1: DC current and G-POA (Twin Y-Axis)
104
+ fig.add_trace(
105
+ go.Scatter(
106
+ x=inv_data.index,
107
+ y=inv_data[CURRENT],
108
+ mode="lines",
109
+ name=f"{CURRENT}-{inv_id}",
110
+ ),
111
+ row=1,
112
+ col=1,
113
+ secondary_y=False,
114
+ )
115
+
116
+ fig.add_trace(
117
+ go.Scatter(
118
+ x=inv_data.index,
119
+ y=inv_data[IRRADIANCE],
120
+ mode="lines",
121
+ name=f"{IRRADIANCE}-{inv_id}",
122
+ ),
123
+ row=1,
124
+ col=1,
125
+ secondary_y=True,
126
+ )
127
+
128
+ # Graph 2: Voltage
129
+ fig.add_trace(
130
+ go.Scatter(
131
+ x=inv_data.index,
132
+ y=inv_data[VOLTAGE],
133
+ mode="lines",
134
+ name=f"{VOLTAGE}-{inv_id}",
135
+ ),
136
+ row=2,
137
+ col=1,
138
+ )
139
+
140
+ # Graph 3: P-dc and P-ac
141
+ fig.add_trace(
142
+ go.Scatter(
143
+ x=inv_data.index,
144
+ y=inv_data[POWER_DC],
145
+ mode="lines",
146
+ name=f"{POWER_DC}-{inv_id}",
147
+ ),
148
+ row=3,
149
+ col=1,
150
+ )
151
+ fig.add_trace(
152
+ go.Scatter(
153
+ x=inv_data.index,
154
+ y=inv_data[POWER_AC],
155
+ mode="lines",
156
+ name=f"{POWER_AC}-{inv_id}",
157
+ ),
158
+ row=3,
159
+ col=1,
160
+ )
161
+
162
+ # Update axis labels
163
+ fig.update_yaxes(title_text="Current (A)", row=1, col=1)
164
+ fig.update_yaxes(title_text="Irradiance (W/m2)", row=1, col=1, secondary_y=True)
165
+ fig.update_yaxes(title_text="Voltage (V)", row=2, col=1)
166
+ fig.update_yaxes(title_text="P-dc & P-ac (W)", row=3, col=1)
167
+ fig.update_xaxes(title_text="Datetime", row=3, col=1)
168
+
169
+ # Update layout to add titles
170
+ fig.update_layout(title_text="IV Plot with Power Curves", height=800, width=1000)
171
+
172
+ return fig
173
+
174
+
175
+ def create_iv_plot_with_power_and_temperature_curves(df, df2, inverter_ids):
176
+ # Create the specs for subplots
177
+ print("Selected Inverter Ids: {}".format(inverter_ids))
178
+ fig = make_subplots(
179
+ rows=4,
180
+ cols=1,
181
+ shared_xaxes=True,
182
+ vertical_spacing=0.01,
183
+ specs=[[{"secondary_y": True}], [{}], [{}], [{}]],
184
+ )
185
+
186
+ for inverter in inverter_ids:
187
+ inv_id = INVERTER_ID_MAPPING[inverter]
188
+ print("Creating plot for inv_id: {}".format(inv_id))
189
+ inv_data = df[str(inv_id)]
190
+ temperature_data = df2[df2["Inv"] == inv_id]
191
+
192
+ # Graph 1: DC current and G-POA (Twin Y-Axis)
193
+ fig.add_trace(
194
+ go.Scatter(
195
+ x=inv_data.index,
196
+ y=inv_data[CURRENT],
197
+ mode="lines",
198
+ name=f"{CURRENT}-{inv_id}",
199
+ ),
200
+ row=1,
201
+ col=1,
202
+ secondary_y=False,
203
+ )
204
+
205
+ fig.add_trace(
206
+ go.Scatter(
207
+ x=inv_data.index,
208
+ y=inv_data[IRRADIANCE],
209
+ mode="lines",
210
+ name=f"{IRRADIANCE}-{inv_id}",
211
+ ),
212
+ row=1,
213
+ col=1,
214
+ secondary_y=True,
215
+ )
216
+
217
+ # Graph 2: Voltage
218
+ fig.add_trace(
219
+ go.Scatter(
220
+ x=inv_data.index,
221
+ y=inv_data[VOLTAGE],
222
+ mode="lines",
223
+ name=f"{VOLTAGE}-{inv_id}",
224
+ ),
225
+ row=2,
226
+ col=1,
227
+ )
228
+
229
+ # Graph 3: P-dc and P-ac
230
+ fig.add_trace(
231
+ go.Scatter(
232
+ x=inv_data.index,
233
+ y=inv_data[POWER_DC],
234
+ mode="lines",
235
+ name=f"{POWER_DC}-{inv_id}",
236
+ ),
237
+ row=3,
238
+ col=1,
239
+ )
240
+ fig.add_trace(
241
+ go.Scatter(
242
+ x=inv_data.index,
243
+ y=inv_data[POWER_AC],
244
+ mode="lines",
245
+ name=f"{POWER_AC}-{inv_id}",
246
+ ),
247
+ row=3,
248
+ col=1,
249
+ )
250
+
251
+ # Graph 4: T-amb, T-mod, T-heatsink, T-CPU and T-board
252
+ fig.add_trace(
253
+ go.Scatter(
254
+ x=temperature_data.index,
255
+ y=temperature_data[T_AMBIENT],
256
+ name=f"{T_AMBIENT}-{inv_id}",
257
+ ),
258
+ row=4,
259
+ col=1,
260
+ )
261
+ fig.add_trace(
262
+ go.Scatter(
263
+ x=inv_data.index, y=inv_data[T_MODULE], name=f"{T_MODULE}-{inv_id}"
264
+ ),
265
+ row=4,
266
+ col=1,
267
+ )
268
+ fig.add_trace(
269
+ go.Scatter(
270
+ x=temperature_data.index,
271
+ y=temperature_data[T_HEATSINK],
272
+ name=f"{T_HEATSINK}-{inv_id}",
273
+ ),
274
+ row=4,
275
+ col=1,
276
+ )
277
+ fig.add_trace(
278
+ go.Scatter(
279
+ x=temperature_data.index,
280
+ y=temperature_data[T_CPU],
281
+ name=f"{T_CPU}-{inv_id}",
282
+ ),
283
+ row=4,
284
+ col=1,
285
+ )
286
+ fig.add_trace(
287
+ go.Scatter(
288
+ x=temperature_data.index,
289
+ y=temperature_data[T_BOARD],
290
+ name=f"{T_BOARD}-{inv_id}",
291
+ ),
292
+ row=4,
293
+ col=1,
294
+ )
295
+
296
+ # Update axis labels
297
+ fig.update_yaxes(title_text="Current (A)", row=1, col=1)
298
+ fig.update_yaxes(title_text="Irradiance (W/m2)", row=1, col=1, secondary_y=True)
299
+ fig.update_yaxes(title_text="Voltage (V)", row=2, col=1)
300
+ fig.update_yaxes(title_text="P-dc & P-ac (W)", row=3, col=1)
301
+ fig.update_xaxes(title_text="Datetime", row=4, col=1)
302
+ fig.update_yaxes(title_text="Temperature (°C)", row=4, col=1)
303
+
304
+ # Update layout to add titles
305
+ fig.update_layout(
306
+ title_text="IV Plots with Power and Temperature", height=800, width=1000
307
+ )
308
+
309
+ return pn.pane.Plotly(fig)
310
+
311
+
312
+ def create_iv_plot_with_temperature_curves(df, df2, inverter_ids):
313
+ # Create the specs for subplots
314
+ print("Selected Inverter Ids: {}".format(inverter_ids))
315
+ fig = make_subplots(
316
+ rows=3,
317
+ cols=1,
318
+ shared_xaxes=True,
319
+ vertical_spacing=0.01,
320
+ specs=[[{"secondary_y": True}], [{}], [{}]],
321
+ )
322
+
323
+ for inverter in inverter_ids:
324
+ inv_id = INVERTER_ID_MAPPING[inverter]
325
+ print("Creating plot for inv_id: {}".format(inv_id))
326
+ inv_data = df[str(inv_id)]
327
+ temperature_data = df2[df2["Inv"] == inv_id]
328
+
329
+ # Graph 1: DC current and G-POA (Twin Y-Axis)
330
+ fig.add_trace(
331
+ go.Scatter(
332
+ x=inv_data.index,
333
+ y=inv_data[CURRENT],
334
+ mode="lines",
335
+ name=f"{CURRENT}-{inv_id}",
336
+ ),
337
+ row=1,
338
+ col=1,
339
+ secondary_y=False,
340
+ )
341
+
342
+ fig.add_trace(
343
+ go.Scatter(
344
+ x=inv_data.index,
345
+ y=inv_data[IRRADIANCE],
346
+ mode="lines",
347
+ name=f"{IRRADIANCE}-{inv_id}",
348
+ ),
349
+ row=1,
350
+ col=1,
351
+ secondary_y=True,
352
+ )
353
+
354
+ # Graph 2: Voltage
355
+ fig.add_trace(
356
+ go.Scatter(
357
+ x=inv_data.index,
358
+ y=inv_data[VOLTAGE],
359
+ mode="lines",
360
+ name=f"{VOLTAGE}-{inv_id}",
361
+ ),
362
+ row=2,
363
+ col=1,
364
+ )
365
+
366
+ # Graph 4: T-amb, T-mod, T-heatsink, T-CPU and T-board
367
+ fig.add_trace(
368
+ go.Scatter(
369
+ x=temperature_data.index,
370
+ y=temperature_data[T_AMBIENT],
371
+ name=f"{T_AMBIENT}-{inv_id}",
372
+ ),
373
+ row=3,
374
+ col=1,
375
+ )
376
+ fig.add_trace(
377
+ go.Scatter(
378
+ x=inv_data.index, y=inv_data[T_MODULE], name=f"{T_MODULE}-{inv_id}"
379
+ ),
380
+ row=3,
381
+ col=1,
382
+ )
383
+ fig.add_trace(
384
+ go.Scatter(
385
+ x=temperature_data.index,
386
+ y=temperature_data[T_HEATSINK],
387
+ name=f"{T_HEATSINK}-{inv_id}",
388
+ ),
389
+ row=3,
390
+ col=1,
391
+ )
392
+ fig.add_trace(
393
+ go.Scatter(
394
+ x=temperature_data.index,
395
+ y=temperature_data[T_CPU],
396
+ name=f"{T_CPU}-{inv_id}",
397
+ ),
398
+ row=3,
399
+ col=1,
400
+ )
401
+ fig.add_trace(
402
+ go.Scatter(
403
+ x=temperature_data.index,
404
+ y=temperature_data[T_BOARD],
405
+ name=f"{T_BOARD}-{inv_id}",
406
+ ),
407
+ row=3,
408
+ col=1,
409
+ )
410
+
411
+ # Update axis labels
412
+ fig.update_yaxes(title_text="Current (A)", row=1, col=1)
413
+ fig.update_yaxes(title_text="Irradiance (W/m2)", row=1, col=1, secondary_y=True)
414
+ fig.update_yaxes(title_text="Voltage (V)", row=2, col=1)
415
+ fig.update_xaxes(title_text="Datetime", row=3, col=1)
416
+ fig.update_yaxes(title_text="Temperature (°C)", row=3, col=1)
417
+
418
+ # Update layout to add titles
419
+ fig.update_layout(title_text="IV Plots with Temperature", height=800, width=1000)
420
+
421
+ return pn.pane.Plotly(fig)
422
+
423
+
424
+ def create_heatmap(df, title):
425
+ fig = px.imshow(df.transpose(), aspect="auto", title=title)
426
+ fig.update_layout(height=400, width=1200)
427
+ return pn.pane.Plotly(fig)
requirements.txt CHANGED
@@ -1,6 +1,3 @@
1
- panel
2
- jupyter
3
- transformers
4
- numpy
5
- torch
6
- aiohttp
 
1
+ pandas
2
+ plotly
3
+ panel