apmtools 0.2.15__tar.gz → 0.2.17__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {apmtools-0.2.15 → apmtools-0.2.17}/PKG-INFO +1 -1
- {apmtools-0.2.15 → apmtools-0.2.17}/pyproject.toml +1 -1
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/shiny/summary.py +175 -169
- apmtools-0.2.17/src/apmtools/units.py +386 -0
- apmtools-0.2.15/src/apmtools/units.py +0 -155
- {apmtools-0.2.15 → apmtools-0.2.17}/.gitignore +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/LICENSE +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/README.md +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/__init__.py +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/classes.py +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/data_processing.py +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/functions.py +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/legacy.py +0 -0
- {apmtools-0.2.15 → apmtools-0.2.17}/src/apmtools/shiny/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: apmtools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.017
|
|
4
4
|
Summary: A collection of tools for processing air pollution monitoring data
|
|
5
5
|
Project-URL: Homepage, https://github.com/federlorenz/apmtools
|
|
6
6
|
Author-email: Federico Lorenzetti <lorenzetti.federico@gmail.com>
|
|
@@ -9,12 +9,14 @@ import pandas as pd
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
PLOT_TYPES = {
|
|
12
|
-
"line": "Line",
|
|
13
12
|
"bar": "Bar",
|
|
14
|
-
"histogram": "Histogram",
|
|
15
13
|
"box": "Boxplot",
|
|
14
|
+
"histogram": "Histogram",
|
|
15
|
+
"line": "Line",
|
|
16
|
+
"scatter": "Scatter",
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
|
|
18
20
|
# ``None`` means row-level plotting. The other values are passed directly to
|
|
19
21
|
# Summary.group_stat(frequency=...).
|
|
20
22
|
FREQUENCIES = {
|
|
@@ -28,13 +30,13 @@ FREQUENCIES = {
|
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
AGGREGATES = {
|
|
33
|
+
"Count": "count",
|
|
34
|
+
"Maximum": "max",
|
|
31
35
|
"Mean": "mean",
|
|
32
36
|
"Median": "median",
|
|
33
|
-
"Sum": "sum",
|
|
34
37
|
"Minimum": "min",
|
|
35
|
-
"Maximum": "max",
|
|
36
|
-
"Count": "count",
|
|
37
38
|
"Standard deviation": "std",
|
|
39
|
+
"Sum": "sum",
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
def _default_x(data: pd.DataFrame) -> str:
|
|
@@ -55,26 +57,15 @@ def _default_group(data: pd.DataFrame) -> str | None:
|
|
|
55
57
|
|
|
56
58
|
def _numeric_columns(data: pd.DataFrame) -> list[str]:
|
|
57
59
|
"""Return numeric column names as strings."""
|
|
58
|
-
return [
|
|
60
|
+
return sorted([
|
|
59
61
|
str(column)
|
|
60
62
|
for column in data.columns
|
|
61
63
|
if pd.api.types.is_numeric_dtype(data[column])
|
|
62
|
-
]
|
|
63
|
-
|
|
64
|
-
def _normalise_y(data: pd.DataFrame, x: str, y: str | Sequence[str] | None) -> list[str]:
|
|
65
|
-
"""Validate and normalise an initial Y selection."""
|
|
66
|
-
numeric = _numeric_columns(data)
|
|
67
|
-
if y is None:
|
|
68
|
-
return [column for column in numeric if column != x][:1]
|
|
69
|
-
values = [y] if isinstance(y, str) else list(y)
|
|
70
|
-
missing = [column for column in values if column not in data.columns]
|
|
71
|
-
if missing:
|
|
72
|
-
raise ValueError(f"Unknown y column(s): {missing}")
|
|
73
|
-
return [str(column) for column in values]
|
|
64
|
+
])
|
|
74
65
|
|
|
75
66
|
|
|
76
67
|
def _categorical_columns(data: pd.DataFrame) -> list[str]:
|
|
77
|
-
"""Return
|
|
68
|
+
"""Return categorical column names as strings."""
|
|
78
69
|
return sorted(
|
|
79
70
|
[
|
|
80
71
|
str(column)
|
|
@@ -86,6 +77,41 @@ def _categorical_columns(data: pd.DataFrame) -> list[str]:
|
|
|
86
77
|
)
|
|
87
78
|
|
|
88
79
|
|
|
80
|
+
def _datetime_columns(data: pd.DataFrame) -> list[str]:
|
|
81
|
+
"""Return datetime column names as strings."""
|
|
82
|
+
return sorted(
|
|
83
|
+
[
|
|
84
|
+
str(column)
|
|
85
|
+
for column in data.columns
|
|
86
|
+
if pd.api.types.is_datetime64_any_dtype(data[column])
|
|
87
|
+
],
|
|
88
|
+
key=str.casefold,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _timedelta_columns(data: pd.DataFrame) -> list[str]:
|
|
93
|
+
"""Return timedelta column names as strings."""
|
|
94
|
+
return sorted(
|
|
95
|
+
[
|
|
96
|
+
str(column)
|
|
97
|
+
for column in data.columns
|
|
98
|
+
if pd.api.types.is_timedelta64_dtype(data[column])
|
|
99
|
+
],
|
|
100
|
+
key=str.casefold,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def _default_y(data: pd.DataFrame, x: str, y: str | Sequence[str] | None) -> list[str]:
|
|
104
|
+
"""Validate and normalise an initial Y selection."""
|
|
105
|
+
numeric = _numeric_columns(data)
|
|
106
|
+
if y is None:
|
|
107
|
+
return [column for column in numeric if column != x][:1]
|
|
108
|
+
values = [y] if isinstance(y, str) else list(y)
|
|
109
|
+
missing = [column for column in values if column not in data.columns]
|
|
110
|
+
if missing:
|
|
111
|
+
raise ValueError(f"Unknown y column(s): {missing}")
|
|
112
|
+
return [str(column) for column in values]
|
|
113
|
+
|
|
114
|
+
|
|
89
115
|
def _alphabetical(values) -> list[str]:
|
|
90
116
|
"""Return string values sorted alphabetically, case-insensitively."""
|
|
91
117
|
return sorted((str(value) for value in values), key=str.casefold)
|
|
@@ -274,13 +300,16 @@ def create_summary_app(
|
|
|
274
300
|
columns = _alphabetical(summary.columns)
|
|
275
301
|
column_map = {str(c): c for c in summary.columns}
|
|
276
302
|
numeric_columns = _alphabetical(_numeric_columns(summary))
|
|
277
|
-
categorical_columns = _categorical_columns(summary)
|
|
303
|
+
categorical_columns = _alphabetical(_categorical_columns(summary))
|
|
304
|
+
datetime_columns = _alphabetical(_datetime_columns(summary))
|
|
305
|
+
timedelta_columns = _alphabetical(_timedelta_columns(summary))
|
|
306
|
+
|
|
278
307
|
|
|
279
308
|
x = _default_x(summary) if x is None else str(x)
|
|
280
309
|
if x not in column_map:
|
|
281
310
|
raise ValueError(f"Unknown x column: {x!r}")
|
|
282
311
|
|
|
283
|
-
initial_y =
|
|
312
|
+
initial_y = _default_y(summary, x, y)
|
|
284
313
|
if group_by is None:
|
|
285
314
|
initial_groups = [_default_group(summary)] if _default_group(
|
|
286
315
|
summary) is not None else []
|
|
@@ -340,8 +369,11 @@ def create_summary_app(
|
|
|
340
369
|
"datetime_end", "End datetime",
|
|
341
370
|
value="", placeholder="YYYY-MM-DD or YYYY-MM-DD HH:MM:SS",
|
|
342
371
|
),
|
|
343
|
-
ui.
|
|
344
|
-
|
|
372
|
+
ui.panel_conditional(
|
|
373
|
+
"input.plot_type === 'histogram'",
|
|
374
|
+
ui.input_numeric("bins", "Histogram bins",
|
|
375
|
+
value=30, min=1, max=200, step=1),
|
|
376
|
+
),
|
|
345
377
|
ui.input_text("title", "Plot title", value=title),
|
|
346
378
|
ui.help_text(
|
|
347
379
|
"Subset and datetime filters are applied before aggregation. "
|
|
@@ -358,39 +390,53 @@ def create_summary_app(
|
|
|
358
390
|
def server(input, output, session):
|
|
359
391
|
@render.ui
|
|
360
392
|
def x_control():
|
|
361
|
-
|
|
362
|
-
if
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
393
|
+
kind = input.plot_type()
|
|
394
|
+
if kind in ("box", "bar"):
|
|
395
|
+
choices = categorical_columns
|
|
396
|
+
multiple = True
|
|
397
|
+
elif kind == "line":
|
|
398
|
+
choices = datetime_columns
|
|
399
|
+
multiple = False
|
|
400
|
+
else:
|
|
401
|
+
choices = numeric_columns
|
|
402
|
+
multiple = False
|
|
403
|
+
|
|
404
|
+
if not choices:
|
|
405
|
+
return ui.help_text(f"No compatible X variables for {kind}.")
|
|
406
|
+
selected = [x] if x in choices else [choices[0]]
|
|
407
|
+
if multiple:
|
|
408
|
+
return ui.input_selectize(
|
|
409
|
+
"x", "X-axis / categories",
|
|
410
|
+
choices={c: c for c in choices},
|
|
411
|
+
selected=selected, multiple=True,
|
|
372
412
|
)
|
|
373
413
|
return ui.input_select(
|
|
374
|
-
"x", "X-axis /
|
|
375
|
-
choices={c: c for c in
|
|
376
|
-
selected=
|
|
414
|
+
"x", "X-axis / variable",
|
|
415
|
+
choices={c: c for c in choices},
|
|
416
|
+
selected=selected[0],
|
|
377
417
|
)
|
|
378
418
|
|
|
379
419
|
@render.ui
|
|
380
420
|
def y_control():
|
|
381
|
-
|
|
382
|
-
if
|
|
383
|
-
|
|
384
|
-
|
|
421
|
+
kind = input.plot_type()
|
|
422
|
+
if kind == "histogram":
|
|
423
|
+
return ui.div()
|
|
424
|
+
if not numeric_columns:
|
|
425
|
+
return ui.help_text("No numeric Y variables available.")
|
|
426
|
+
selected = next(
|
|
427
|
+
(v for v in initial_y if v in numeric_columns), numeric_columns[0])
|
|
428
|
+
if kind in ("box", "bar", "scatter"):
|
|
385
429
|
return ui.input_select(
|
|
386
430
|
"y", "Y-axis / variable",
|
|
387
431
|
choices={c: c for c in numeric_columns},
|
|
388
432
|
selected=selected,
|
|
389
433
|
)
|
|
390
434
|
return ui.input_selectize(
|
|
391
|
-
"y", "Y-axis /
|
|
435
|
+
"y", "Y-axis / variables",
|
|
392
436
|
choices={c: c for c in numeric_columns},
|
|
393
|
-
selected=initial_y
|
|
437
|
+
selected=[v for v in initial_y if v in numeric_columns] or [
|
|
438
|
+
selected],
|
|
439
|
+
multiple=True,
|
|
394
440
|
)
|
|
395
441
|
|
|
396
442
|
@render.ui
|
|
@@ -450,89 +496,92 @@ def create_summary_app(
|
|
|
450
496
|
@reactive.calc
|
|
451
497
|
def selected_data():
|
|
452
498
|
current = filtered_summary()
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
499
|
+
kind = input.plot_type()
|
|
500
|
+
x_input = input.x()
|
|
501
|
+
selected_x = ([x_input] if isinstance(
|
|
502
|
+
x_input, str) else list(x_input or []))
|
|
503
|
+
if not selected_x:
|
|
504
|
+
return pd.DataFrame()
|
|
505
|
+
|
|
506
|
+
if kind == "histogram":
|
|
507
|
+
value_names = selected_x
|
|
508
|
+
else:
|
|
509
|
+
y_input = input.y()
|
|
510
|
+
value_names = ([y_input] if isinstance(
|
|
511
|
+
y_input, str) else list(y_input or []))
|
|
512
|
+
if not value_names:
|
|
457
513
|
return pd.DataFrame()
|
|
458
514
|
|
|
459
|
-
y_columns = [column_map[c] for c in selected_y]
|
|
460
515
|
selected_groups = list(input.group_by())
|
|
461
516
|
grouping_by = [column_map[c] for c in selected_groups]
|
|
462
517
|
frequency = FREQUENCIES[input.frequency()]
|
|
463
518
|
aggregate = AGGREGATES[input.aggregate()]
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
# All selected grouping columns are passed directly to
|
|
476
|
-
# Summary.group_stat() when a frequency is selected.
|
|
519
|
+
value_columns = [column_map[c] for c in value_names]
|
|
520
|
+
|
|
521
|
+
if kind in ("box", "bar"):
|
|
522
|
+
for c in selected_x:
|
|
523
|
+
if column_map[c] not in grouping_by:
|
|
524
|
+
grouping_by.append(column_map[c])
|
|
525
|
+
if kind == "scatter" and frequency is not None:
|
|
526
|
+
# Both numerical axes must be aggregated on the same rows.
|
|
527
|
+
value_columns = list(dict.fromkeys(
|
|
528
|
+
[column_map[selected_x[0]], *value_columns]
|
|
529
|
+
))
|
|
477
530
|
if frequency is not None:
|
|
478
|
-
current = _aggregate(
|
|
479
|
-
|
|
480
|
-
|
|
531
|
+
current = _aggregate(
|
|
532
|
+
current, value_columns, frequency, grouping_by, aggregate
|
|
533
|
+
)
|
|
481
534
|
return current
|
|
482
535
|
|
|
483
536
|
@render_plotly
|
|
484
537
|
def plot():
|
|
485
538
|
plot_df = selected_data()
|
|
486
539
|
selected_plot = input.plot_type()
|
|
487
|
-
|
|
488
|
-
|
|
540
|
+
x_input = input.x()
|
|
541
|
+
selected_x = ([x_input] if isinstance(
|
|
542
|
+
x_input, str) else list(x_input or []))
|
|
543
|
+
y_input = None if selected_plot == "histogram" else input.y()
|
|
489
544
|
selected_y = ([y_input] if isinstance(
|
|
490
545
|
y_input, str) else list(y_input or []))
|
|
491
546
|
selected_groups = list(input.group_by())
|
|
492
547
|
frequency = FREQUENCIES[input.frequency()]
|
|
493
548
|
|
|
494
|
-
if plot_df.empty or not
|
|
549
|
+
if plot_df.empty or not selected_x or (
|
|
550
|
+
selected_plot != "histogram" and not selected_y
|
|
551
|
+
):
|
|
495
552
|
return px.scatter(title="No data for the selected filters")
|
|
496
553
|
|
|
497
|
-
|
|
498
|
-
# produced by group_stat(). For example, selecting ``pm25`` and
|
|
499
|
-
# hourly means produces ``pm25_mean`` in the aggregated result.
|
|
500
|
-
selected_y_columns = [column_map[c] for c in selected_y]
|
|
554
|
+
aggregate = AGGREGATES[input.aggregate()]
|
|
501
555
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
# Therefore the aggregated frequency column replaces the
|
|
506
|
-
# originally selected X-axis column.
|
|
507
|
-
if frequency is not None:
|
|
508
|
-
aggregate = AGGREGATES[input.aggregate()]
|
|
509
|
-
y_columns = _aggregated_value_columns(
|
|
510
|
-
plot_df, selected_y_columns, aggregate
|
|
511
|
-
)
|
|
512
|
-
if selected_plot == "box":
|
|
513
|
-
if selected_x not in column_map:
|
|
514
|
-
return px.scatter(title="Select a categorical X variable for the boxplot")
|
|
515
|
-
x_column = column_map[selected_x]
|
|
516
|
-
else:
|
|
517
|
-
x_column = frequency
|
|
556
|
+
def mapped(column):
|
|
557
|
+
original = column_map[column]
|
|
558
|
+
return f"{original}_{aggregate}" if frequency is not None else original
|
|
518
559
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
560
|
+
if selected_plot == "histogram":
|
|
561
|
+
x_column = mapped(selected_x[0])
|
|
562
|
+
y_columns = []
|
|
563
|
+
elif selected_plot in ("box", "bar"):
|
|
564
|
+
x_columns = [column_map[c] for c in selected_x]
|
|
565
|
+
x_column = x_columns[0]
|
|
566
|
+
y_columns = [mapped(selected_y[0])]
|
|
567
|
+
elif selected_plot == "scatter":
|
|
568
|
+
x_column = mapped(selected_x[0])
|
|
569
|
+
y_columns = [mapped(selected_y[0])]
|
|
526
570
|
else:
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
571
|
+
x_column = frequency if frequency is not None else column_map[selected_x[0]]
|
|
572
|
+
y_columns = [mapped(c) for c in selected_y]
|
|
573
|
+
|
|
574
|
+
required = [x_column, *y_columns]
|
|
575
|
+
if selected_plot in ("box", "bar"):
|
|
576
|
+
required.extend(x_columns)
|
|
577
|
+
if any(c not in plot_df.columns for c in required):
|
|
578
|
+
return px.scatter(title="Selected variables are unavailable after aggregation")
|
|
579
|
+
|
|
580
|
+
if selected_plot in ("box", "bar"):
|
|
581
|
+
plot_df = plot_df.copy()
|
|
582
|
+
plot_df["__plot_category"] = plot_df[x_columns].astype(
|
|
583
|
+
str).agg(" | ".join, axis=1)
|
|
584
|
+
x_column = "__plot_category"
|
|
536
585
|
|
|
537
586
|
# Multiple grouping columns are supported by group_stat(). For
|
|
538
587
|
# plotting, Plotly needs one color/category column, so combine the
|
|
@@ -546,74 +595,31 @@ def create_summary_app(
|
|
|
546
595
|
)
|
|
547
596
|
|
|
548
597
|
if selected_plot == "histogram":
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
id_vars=[group_column],
|
|
558
|
-
var_name="variable",
|
|
559
|
-
value_name="value",
|
|
560
|
-
)
|
|
561
|
-
fig = px.histogram(
|
|
562
|
-
long_df,
|
|
563
|
-
x="value",
|
|
564
|
-
color=group_column,
|
|
565
|
-
nbins=int(input.bins()),
|
|
566
|
-
barmode="overlay",
|
|
567
|
-
opacity=0.45,
|
|
568
|
-
facet_row=("variable" if len(y_columns) > 1 else None),
|
|
569
|
-
)
|
|
570
|
-
# Keep the groups as the legend entries rather than the
|
|
571
|
-
# selected Y variables.
|
|
572
|
-
fig.update_traces(marker_line_width=0)
|
|
573
|
-
else:
|
|
574
|
-
long_df = plot_df[y_columns].melt(
|
|
575
|
-
var_name="variable", value_name="value"
|
|
576
|
-
)
|
|
577
|
-
fig = px.histogram(
|
|
578
|
-
long_df,
|
|
579
|
-
x="value",
|
|
580
|
-
color="variable",
|
|
581
|
-
nbins=int(input.bins()),
|
|
582
|
-
barmode="overlay" if len(
|
|
583
|
-
y_columns) > 1 else "relative",
|
|
584
|
-
opacity=0.65 if len(y_columns) > 1 else 1.0,
|
|
585
|
-
)
|
|
598
|
+
fig = px.histogram(
|
|
599
|
+
plot_df,
|
|
600
|
+
x=x_column,
|
|
601
|
+
color="__plot_group" if group_columns else None,
|
|
602
|
+
nbins=int(input.bins()),
|
|
603
|
+
barmode="overlay",
|
|
604
|
+
opacity=0.45 if group_columns else 1.0,
|
|
605
|
+
)
|
|
586
606
|
elif selected_plot == "box":
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
title="Boxplots require a categorical variable on the X axis"
|
|
593
|
-
)
|
|
594
|
-
y_column = y_columns[0]
|
|
595
|
-
if group_columns:
|
|
596
|
-
fig = px.box(
|
|
597
|
-
plot_df, x=x_column, y=y_column,
|
|
598
|
-
color="__plot_group", points="outliers",
|
|
599
|
-
)
|
|
600
|
-
else:
|
|
601
|
-
fig = px.box(
|
|
602
|
-
plot_df, x=x_column, y=y_column, points="outliers"
|
|
603
|
-
)
|
|
607
|
+
fig = px.box(
|
|
608
|
+
plot_df, x=x_column, y=y_columns[0],
|
|
609
|
+
color="__plot_group" if group_columns else None,
|
|
610
|
+
points="outliers",
|
|
611
|
+
)
|
|
604
612
|
elif selected_plot == "bar":
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
facet_row="variable" if len(y_columns) > 1 else None, barmode="group",
|
|
616
|
-
)
|
|
613
|
+
fig = px.bar(
|
|
614
|
+
plot_df, x=x_column, y=y_columns[0],
|
|
615
|
+
color="__plot_group" if group_columns else None,
|
|
616
|
+
barmode="group",
|
|
617
|
+
)
|
|
618
|
+
elif selected_plot == "scatter":
|
|
619
|
+
fig = px.scatter(
|
|
620
|
+
plot_df, x=x_column, y=y_columns[0],
|
|
621
|
+
color="__plot_group" if group_columns else None,
|
|
622
|
+
)
|
|
617
623
|
else:
|
|
618
624
|
# ``identifier`` identifies an individual input monitor. It
|
|
619
625
|
# must therefore be used as Plotly's line-group key even when
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
upas_units = {'AccelComplianceCnt': '#',
|
|
2
|
+
'AccelComplianceHrs': 'hrs',
|
|
3
|
+
'AccelT': '°C',
|
|
4
|
+
'AccelX': 'mg',
|
|
5
|
+
'AccelXMax': 'mg',
|
|
6
|
+
'AccelXMin': 'mg',
|
|
7
|
+
'AccelXVar': 'mg',
|
|
8
|
+
'AccelY': 'mg',
|
|
9
|
+
'AccelYMax': 'mg',
|
|
10
|
+
'AccelYMin': 'mg',
|
|
11
|
+
'AccelYVar': 'mg',
|
|
12
|
+
'AccelZ': 'mg',
|
|
13
|
+
'AccelZMax': 'mg',
|
|
14
|
+
'AccelZMin': 'mg',
|
|
15
|
+
'AccelZVar': 'mg',
|
|
16
|
+
'AtmoAlt': 'm',
|
|
17
|
+
'AtmoDensity': 'g L-1',
|
|
18
|
+
'AtmoP': 'hPa',
|
|
19
|
+
'AtmoRH': '%',
|
|
20
|
+
'AtmoT': '°C',
|
|
21
|
+
'BCS1': 'bool',
|
|
22
|
+
'BCS2': 'bool',
|
|
23
|
+
'BC_NPG': 'bool',
|
|
24
|
+
'BFGenergy': 'integer',
|
|
25
|
+
'BattVolt': 'V',
|
|
26
|
+
'BatteryCharge': '%',
|
|
27
|
+
'CO2': 'ppm',
|
|
28
|
+
'Charging': 'bool',
|
|
29
|
+
'DateTimeUTC': 'HH:MM:SS',
|
|
30
|
+
'Dead': 'bool',
|
|
31
|
+
'ExtPow': '-',
|
|
32
|
+
'FLOWCTL': 's',
|
|
33
|
+
'FdpT': '°C',
|
|
34
|
+
'FilterDP': 'Pa',
|
|
35
|
+
'GPSQual': '-',
|
|
36
|
+
'GPSRT': 's',
|
|
37
|
+
'GPSalt': 'm',
|
|
38
|
+
'GPShDOP': '-',
|
|
39
|
+
'GPSlat': 'decimalDegree',
|
|
40
|
+
'GPSlon': 'decimalDegree',
|
|
41
|
+
'GPSsat': '#',
|
|
42
|
+
'GPSspeed': 'm s-1',
|
|
43
|
+
'HighVisRaw': '-',
|
|
44
|
+
'IRRaw': '-',
|
|
45
|
+
'LUX': 'lux',
|
|
46
|
+
'LowVisRaw': '-',
|
|
47
|
+
'MFSVout': 'V',
|
|
48
|
+
'MassFlow': 'g min-1',
|
|
49
|
+
'MassFlowFactory': 'g min-1',
|
|
50
|
+
'NOXRaw': '-',
|
|
51
|
+
'OverallFlowFactory': 'L min-1',
|
|
52
|
+
'OverallFlowOffset': 'L min-1',
|
|
53
|
+
'OverallFlowRate': 'L min-1)',
|
|
54
|
+
'PCB1T': '°C',
|
|
55
|
+
'PCB2P': 'hPa',
|
|
56
|
+
'PCB2T': '°C',
|
|
57
|
+
'PM0_5NC': '# cm-3',
|
|
58
|
+
'PM0_5NCVar': '# cm-3',
|
|
59
|
+
'PM10MC': 'µg m-3',
|
|
60
|
+
'PM10MCVar': 'µg m-3',
|
|
61
|
+
'PM10NC': '# cm-3',
|
|
62
|
+
'PM10NCVar': '# cm-3',
|
|
63
|
+
'PM1MC': 'µg m-3',
|
|
64
|
+
'PM1MCVar': 'µg m-3',
|
|
65
|
+
'PM1NC': '# cm-3',
|
|
66
|
+
'PM1NCVar': '# cm-3',
|
|
67
|
+
'PM2_5MC': 'μg/m3',
|
|
68
|
+
'PM2_5MCVar': 'µg m-3',
|
|
69
|
+
'PM2_5NC': '# cm-3',
|
|
70
|
+
'PM2_5NCVar': '# cm-3',
|
|
71
|
+
'PM2_5SampledMass': 'µg',
|
|
72
|
+
'PM2_5SampledMassFactory': 'μg',
|
|
73
|
+
'PM2_5SampledMassOffset': 'μg',
|
|
74
|
+
'PM4MC': 'µg m-3',
|
|
75
|
+
'PM4MCVar': 'µg m-3',
|
|
76
|
+
'PM4NC': '# cm-3',
|
|
77
|
+
'PM4NCVar': '# cm-3',
|
|
78
|
+
'PMFanErrorCnt': '#',
|
|
79
|
+
'PMFanSpeedWarn': '#',
|
|
80
|
+
'PMLaserErrorCnt': '#',
|
|
81
|
+
'PMMeasCnt': '#',
|
|
82
|
+
'PMReadingErrorCnt': '#',
|
|
83
|
+
'PMtypicalParticleSize': 'µm',
|
|
84
|
+
'PMtypicalParticleSizeVar': 'µm',
|
|
85
|
+
'PT100R': 'Ω',
|
|
86
|
+
'PumpPow1': 'integer',
|
|
87
|
+
'PumpPow2': 'integer',
|
|
88
|
+
'PumpV': 'V',
|
|
89
|
+
'PumpingFlowFactory': 'L min-1',
|
|
90
|
+
'PumpingFlowOffset': 'L min-1',
|
|
91
|
+
'PumpingFlowRate': 'L min-1)',
|
|
92
|
+
'PumpsON': 'bool',
|
|
93
|
+
'RotX': 'mdeg s-1',
|
|
94
|
+
'RotXMax': 'mdeg s-1',
|
|
95
|
+
'RotXMin': 'mdeg s-1',
|
|
96
|
+
'RotXVar': 'mdeg s-1',
|
|
97
|
+
'RotY': 'mdeg s-1',
|
|
98
|
+
'RotYMax': 'mdeg s-1',
|
|
99
|
+
'RotYMin': 'mdeg s-1',
|
|
100
|
+
'RotYVar': 'mdeg s-1',
|
|
101
|
+
'RotZ': 'mdeg s-1',
|
|
102
|
+
'RotZMax': 'mdeg s-1',
|
|
103
|
+
'RotZMin': 'mdeg s-1',
|
|
104
|
+
'RotZVar': 'mdeg s-1',
|
|
105
|
+
'SCDRH': '%',
|
|
106
|
+
'SCDT': '°C',
|
|
107
|
+
'SD_DATAW': 's',
|
|
108
|
+
'SD_HEADW': 's',
|
|
109
|
+
'SampleTime': '',
|
|
110
|
+
'SampledVolume': 'L',
|
|
111
|
+
'SampledVolumeFactory': 'L',
|
|
112
|
+
'SampledVolumeOffset': 'L',
|
|
113
|
+
'StepCount': '#',
|
|
114
|
+
'TPumpsOFF': 's',
|
|
115
|
+
'TPumpsON': 's',
|
|
116
|
+
'U12T': '°C',
|
|
117
|
+
'U29P': '°C',
|
|
118
|
+
'U29T': '°C',
|
|
119
|
+
'UVRaw': '-',
|
|
120
|
+
'UVindex': '-',
|
|
121
|
+
'UnixTime': 's',
|
|
122
|
+
'VOCRaw': '-',
|
|
123
|
+
'XDown': '%',
|
|
124
|
+
'Xup': '%',
|
|
125
|
+
'Ydown': '%',
|
|
126
|
+
'Yup': '%',
|
|
127
|
+
'Zdown': '%',
|
|
128
|
+
'Zup': '%',
|
|
129
|
+
'cartridgeid': '-',
|
|
130
|
+
'end': 'YYYY-MM-DDTHH:MM:SS',
|
|
131
|
+
'index': '-',
|
|
132
|
+
'length': 'days HH:MM:SS',
|
|
133
|
+
'pm25': 'µg m-3',
|
|
134
|
+
'pm25correctedrh': 'µg m-3',
|
|
135
|
+
'start': 'YYYY-MM-DDTHH:MM:SS',
|
|
136
|
+
'time': 'YYYY-MM-DDTHH:MM:SS',
|
|
137
|
+
'upasid': '-',
|
|
138
|
+
'v3_3': 'V',
|
|
139
|
+
'v5': 'V'}
|
|
140
|
+
|
|
141
|
+
upas_datatype = {'AccelComplianceCnt': 'integer',
|
|
142
|
+
'AccelComplianceHrs': 'timedelta',
|
|
143
|
+
'AccelT': 'numeric',
|
|
144
|
+
'AccelX': 'numeric',
|
|
145
|
+
'AccelXMax': 'numeric',
|
|
146
|
+
'AccelXMin': 'numeric',
|
|
147
|
+
'AccelXVar': 'numeric',
|
|
148
|
+
'AccelY': 'numeric',
|
|
149
|
+
'AccelYMax': 'numeric',
|
|
150
|
+
'AccelYMin': 'numeric',
|
|
151
|
+
'AccelYVar': 'numeric',
|
|
152
|
+
'AccelZ': 'numeric',
|
|
153
|
+
'AccelZMax': 'numeric',
|
|
154
|
+
'AccelZMin': 'numeric',
|
|
155
|
+
'AccelZVar': 'numeric',
|
|
156
|
+
'AtmoAlt': 'numeric',
|
|
157
|
+
'AtmoDensity': 'numeric',
|
|
158
|
+
'AtmoP': 'numeric',
|
|
159
|
+
'AtmoRH': 'numeric',
|
|
160
|
+
'AtmoT': 'numeric',
|
|
161
|
+
'BCS1': 'bool',
|
|
162
|
+
'BCS2': 'bool',
|
|
163
|
+
'BC_NPG': 'bool',
|
|
164
|
+
'BFGenergy': 'integer',
|
|
165
|
+
'BattVolt': 'numeric',
|
|
166
|
+
'BatteryCharge': '%',
|
|
167
|
+
'CO2': 'numeric',
|
|
168
|
+
'Charging': 'bool',
|
|
169
|
+
'DateTimeUTC': 'datetime',
|
|
170
|
+
'Dead': 'bool',
|
|
171
|
+
'ExtPow': 'bool',
|
|
172
|
+
'FLOWCTL': 'timedelta',
|
|
173
|
+
'FdpT': 'numeric',
|
|
174
|
+
'FilterDP': 'numeric',
|
|
175
|
+
'GPSQual': 'text',
|
|
176
|
+
'GPSRT': 'timedelta',
|
|
177
|
+
'GPSalt': 'numeric',
|
|
178
|
+
'GPShDOP': '',
|
|
179
|
+
'GPSlat': 'numeric',
|
|
180
|
+
'GPSlon': 'numeric',
|
|
181
|
+
'GPSsat': 'integer',
|
|
182
|
+
'GPSspeed': 'numeric',
|
|
183
|
+
'HighVisRaw': '',
|
|
184
|
+
'IRRaw': '',
|
|
185
|
+
'LUX': 'numeric',
|
|
186
|
+
'LowVisRaw': '',
|
|
187
|
+
'MFSVout': 'numeric',
|
|
188
|
+
'MassFlow': 'numeric',
|
|
189
|
+
'MassFlowFactory': 'numeric',
|
|
190
|
+
'NOXRaw': 'numeric',
|
|
191
|
+
'OverallFlowFactory': 'numeric',
|
|
192
|
+
'OverallFlowOffset': 'numeric',
|
|
193
|
+
'OverallFlowRate': 'numeric',
|
|
194
|
+
'PCB1T': 'numeric',
|
|
195
|
+
'PCB2P': 'numeric',
|
|
196
|
+
'PCB2T': 'numeric',
|
|
197
|
+
'PM0_5NC': 'integer',
|
|
198
|
+
'PM0_5NCVar': 'numeric',
|
|
199
|
+
'PM10MC': 'numeric',
|
|
200
|
+
'PM10MCVar': 'numeric',
|
|
201
|
+
'PM10NC': 'numeric',
|
|
202
|
+
'PM10NCVar': 'numeric',
|
|
203
|
+
'PM1MC': 'numeric',
|
|
204
|
+
'PM1MCVar': 'numeric',
|
|
205
|
+
'PM1NC': 'numeric',
|
|
206
|
+
'PM1NCVar': 'numeric',
|
|
207
|
+
'PM2_5MC': 'numeric',
|
|
208
|
+
'PM2_5MCVar': 'numeric',
|
|
209
|
+
'PM2_5NC': 'numeric',
|
|
210
|
+
'PM2_5NCVar': 'numeric',
|
|
211
|
+
'PM2_5SampledMass': 'numeric',
|
|
212
|
+
'PM2_5SampledMassFactory': 'numeric',
|
|
213
|
+
'PM2_5SampledMassOffset': 'numeric',
|
|
214
|
+
'PM4MC': 'numeric',
|
|
215
|
+
'PM4MCVar': 'numeric',
|
|
216
|
+
'PM4NC': 'numeric',
|
|
217
|
+
'PM4NCVar': 'numeric',
|
|
218
|
+
'PMFanErrorCnt': 'numeric',
|
|
219
|
+
'PMFanSpeedWarn': 'bool',
|
|
220
|
+
'PMLaserErrorCnt': 'numeric',
|
|
221
|
+
'PMMeasCnt': 'numeric',
|
|
222
|
+
'PMReadingErrorCnt': 'numeric',
|
|
223
|
+
'PMtypicalParticleSize': 'numeric',
|
|
224
|
+
'PMtypicalParticleSizeVar': 'numeric',
|
|
225
|
+
'PT100R': 'numeric',
|
|
226
|
+
'PumpPow1': 'numeric',
|
|
227
|
+
'PumpPow2': 'numeric',
|
|
228
|
+
'PumpV': 'numeric',
|
|
229
|
+
'PumpingFlowFactory': 'numeric',
|
|
230
|
+
'PumpingFlowOffset': 'numeric',
|
|
231
|
+
'PumpingFlowRate': 'numeric',
|
|
232
|
+
'PumpsON': 'bool',
|
|
233
|
+
'RotX': 'numeric',
|
|
234
|
+
'RotXMax': 'numeric',
|
|
235
|
+
'RotXMin': 'numeric',
|
|
236
|
+
'RotXVar': 'numeric',
|
|
237
|
+
'RotY': 'numeric',
|
|
238
|
+
'RotYMax': 'numeric',
|
|
239
|
+
'RotYMin': 'numeric',
|
|
240
|
+
'RotYVar': 'numeric',
|
|
241
|
+
'RotZ': 'numeric',
|
|
242
|
+
'RotZMax': 'numeric',
|
|
243
|
+
'RotZMin': 'numeric',
|
|
244
|
+
'RotZVar': 'numeric',
|
|
245
|
+
'SCDRH': 'numeric',
|
|
246
|
+
'SCDT': 'numeric',
|
|
247
|
+
'SD_DATAW': 'timedelta',
|
|
248
|
+
'SD_HEADW': 'timedelta',
|
|
249
|
+
'SampleTime': 'datetime',
|
|
250
|
+
'SampledVolume': 'numeric',
|
|
251
|
+
'SampledVolumeFactory': 'numeric',
|
|
252
|
+
'SampledVolumeOffset': 'numeric',
|
|
253
|
+
'StepCount': 'numeric',
|
|
254
|
+
'TPumpsOFF': 'bool',
|
|
255
|
+
'TPumpsON': 'bool',
|
|
256
|
+
'U12T': 'numeric',
|
|
257
|
+
'U29P': 'numeric',
|
|
258
|
+
'U29T': 'numeric',
|
|
259
|
+
'UVRaw': 'numeric',
|
|
260
|
+
'UVindex': 'numeric',
|
|
261
|
+
'UnixTime': 'datetime',
|
|
262
|
+
'VOCRaw': 'numeric',
|
|
263
|
+
'XDown': 'numeric',
|
|
264
|
+
'Xup': 'numeric',
|
|
265
|
+
'Ydown': 'numeric',
|
|
266
|
+
'Yup': 'numeric',
|
|
267
|
+
'Zdown': 'numeric',
|
|
268
|
+
'Zup': 'numeric',
|
|
269
|
+
'end': 'datetime',
|
|
270
|
+
'length': 'timedelta',
|
|
271
|
+
'pm25': 'numeric',
|
|
272
|
+
'pm25correctedrh': 'numeric',
|
|
273
|
+
'start': 'datetime',
|
|
274
|
+
'time': 'datetime',
|
|
275
|
+
'v3_3': 'numeric',
|
|
276
|
+
'v5': 'numeric'}
|
|
277
|
+
|
|
278
|
+
lascar_units = {"CO(ppm)":"ppm"}
|
|
279
|
+
|
|
280
|
+
lascar_datatype = {"CO(ppm)": "numeric",
|
|
281
|
+
'start': "datetime",
|
|
282
|
+
'end': "datetime",
|
|
283
|
+
'length': "timedelta",
|
|
284
|
+
'time': "datetime"}
|
|
285
|
+
|
|
286
|
+
purple_units = {'mac_address':"-",
|
|
287
|
+
'firmware_ver':"-",
|
|
288
|
+
'hardware':"-",
|
|
289
|
+
'current_temp_f':"F",
|
|
290
|
+
'current_humidity':"%",
|
|
291
|
+
'current_dewpoint_f':"F",
|
|
292
|
+
'pressure':"mBar",
|
|
293
|
+
'adc':"",
|
|
294
|
+
'mem':"",
|
|
295
|
+
'rssi':"",
|
|
296
|
+
'uptime':"",
|
|
297
|
+
'pm1_0_cf_1': "μg m-3",
|
|
298
|
+
'pm2_5_cf_1': "μg m-3",
|
|
299
|
+
'pm10_0_cf_1': "μg m-3",
|
|
300
|
+
'pm1_0_atm': "μg m-3",
|
|
301
|
+
'pm2_5_atm': "μg m-3",
|
|
302
|
+
'pm10_0_atm': "μg m-3",
|
|
303
|
+
'pm2.5_aqi_cf_1': "μg m-3",
|
|
304
|
+
'pm2.5_aqi_atm': "μg m-3",
|
|
305
|
+
'p_0_3_um':"#",
|
|
306
|
+
'p_0_5_um':"#",
|
|
307
|
+
'p_1_0_um':"#",
|
|
308
|
+
'p_2_5_um':"#",
|
|
309
|
+
'p_5_0_um':"#",
|
|
310
|
+
'p_10_0_um':"#",
|
|
311
|
+
'pm1_0_cf_1_b': "μg m-3",
|
|
312
|
+
'pm2_5_cf_1_b': "μg m-3",
|
|
313
|
+
'pm10_0_cf_1_b': "μg m-3",
|
|
314
|
+
'pm1_0_atm_b': "μg m-3",
|
|
315
|
+
'pm2_5_atm_b': "μg m-3",
|
|
316
|
+
'pm10_0_atm_b': "μg m-3",
|
|
317
|
+
'pm2.5_aqi_cf_1_b': "μg m-3",
|
|
318
|
+
'pm2.5_aqi_atm_b': "μg m-3",
|
|
319
|
+
'p_0_3_um_b':"#",
|
|
320
|
+
'p_0_5_um_b':"#",
|
|
321
|
+
'p_1_0_um_b':"#",
|
|
322
|
+
'p_2_5_um_b':"#",
|
|
323
|
+
'p_5_0_um_b':"#",
|
|
324
|
+
'p_10_0_um_b':"#",
|
|
325
|
+
'gas':"",
|
|
326
|
+
'pm_adj': "μg m-3"}
|
|
327
|
+
|
|
328
|
+
purple_datatype = {'mac_address': "text",
|
|
329
|
+
'firmware_ver': "text",
|
|
330
|
+
'hardware': "text",
|
|
331
|
+
'current_temp_f': "numeric",
|
|
332
|
+
'current_humidity': "numeric",
|
|
333
|
+
'current_dewpoint_f': "numeric",
|
|
334
|
+
'pressure': "numeric",
|
|
335
|
+
'adc': "text",
|
|
336
|
+
'mem': "text",
|
|
337
|
+
'rssi': "text",
|
|
338
|
+
'uptime': "text",
|
|
339
|
+
'pm1_0_c': "numeric",
|
|
340
|
+
'PumpingFlowFactory': 'numeric',
|
|
341
|
+
'PumpingFlowOffset': 'numeric',
|
|
342
|
+
'PumpingFlowRate': 'numeric',
|
|
343
|
+
'PumpsON': 'bool',
|
|
344
|
+
'RotX': 'numeric',
|
|
345
|
+
'RotXMax': 'numeric',
|
|
346
|
+
'RotXMin': 'numeric',
|
|
347
|
+
'RotXVar': 'numeric',
|
|
348
|
+
'RotY': 'numeric',
|
|
349
|
+
'RotYMax': 'numeric',
|
|
350
|
+
'RotYMin': 'numeric',
|
|
351
|
+
'RotYVar': 'numeric',
|
|
352
|
+
'RotZ': 'numeric',
|
|
353
|
+
'pm1_0_cf_1': "numeric",
|
|
354
|
+
'pm2_5_cf_1': "numeric",
|
|
355
|
+
'pm10_0_cf_1': "numeric",
|
|
356
|
+
'pm1_0_atm': "numeric",
|
|
357
|
+
'pm2_5_atm': "numeric",
|
|
358
|
+
'pm10_0_atm': "numeric",
|
|
359
|
+
'pm2.5_aqi_cf_1': "numeric",
|
|
360
|
+
'pm2.5_aqi_atm': "numeric",
|
|
361
|
+
'p_0_3_um': "numeric",
|
|
362
|
+
'p_0_5_um': "numeric",
|
|
363
|
+
'p_1_0_um': "numeric",
|
|
364
|
+
'p_2_5_um': "numeric",
|
|
365
|
+
'p_5_0_um': "numeric",
|
|
366
|
+
'p_10_0_um': "numeric",
|
|
367
|
+
'pm1_0_cf_1_b': "numeric",
|
|
368
|
+
'pm2_5_cf_1_b': "numeric",
|
|
369
|
+
'pm10_0_cf_1_b': "numeric",
|
|
370
|
+
'pm1_0_atm_b': "numeric",
|
|
371
|
+
'pm2_5_atm_b': "numeric",
|
|
372
|
+
'pm10_0_atm_b': "numeric",
|
|
373
|
+
'pm2.5_aqi_cf_1_b': "numeric",
|
|
374
|
+
'pm2.5_aqi_atm_b': "numeric",
|
|
375
|
+
'p_0_3_um_b': "numeric",
|
|
376
|
+
'p_0_5_um_b': "numeric",
|
|
377
|
+
'p_1_0_um_b': "numeric",
|
|
378
|
+
'p_2_5_um_b': "numeric",
|
|
379
|
+
'p_5_0_um_b': "numeric",
|
|
380
|
+
'p_10_0_um_b': "numeric",
|
|
381
|
+
'gas': "text",
|
|
382
|
+
'pm_adj': "numeric",
|
|
383
|
+
'start':"datetime",
|
|
384
|
+
'end':"datetime",
|
|
385
|
+
'length':"timedelta",
|
|
386
|
+
'time':"datetime"}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
upas_units= {'PumpingFlowRate':"",
|
|
2
|
-
'OverallFlowRate':"",
|
|
3
|
-
'SampledVolume':"",
|
|
4
|
-
'FilterDP':"",
|
|
5
|
-
'BatteryCharge':"",
|
|
6
|
-
'AtmoT':"",
|
|
7
|
-
'AtmoP':"",
|
|
8
|
-
'AtmoRH':"",
|
|
9
|
-
'AtmoDensity':"",
|
|
10
|
-
'AtmoAlt':"",
|
|
11
|
-
'GPSQual':"",
|
|
12
|
-
'GPSlat':"",
|
|
13
|
-
'GPSlon':"",
|
|
14
|
-
'GPSalt':"",
|
|
15
|
-
'GPSsat':"",
|
|
16
|
-
'GPSspeed':"",
|
|
17
|
-
'GPShDOP':"",
|
|
18
|
-
'AccelX':"",
|
|
19
|
-
'AccelXVar':"",
|
|
20
|
-
'AccelXMin':"",
|
|
21
|
-
'AccelXMax':"",
|
|
22
|
-
'AccelY':"",
|
|
23
|
-
'AccelYVar':"",
|
|
24
|
-
'AccelYMin':"",
|
|
25
|
-
'AccelYMax':"",
|
|
26
|
-
'AccelZ':"",
|
|
27
|
-
'AccelZVar':"",
|
|
28
|
-
'AccelZMin':"",
|
|
29
|
-
'AccelZMax':"",
|
|
30
|
-
'RotX':"",
|
|
31
|
-
'RotXVar':"",
|
|
32
|
-
'RotXMin':"",
|
|
33
|
-
'RotXMax':"",
|
|
34
|
-
'RotY':"",
|
|
35
|
-
'RotYVar':"",
|
|
36
|
-
'RotYMin':"",
|
|
37
|
-
'RotYMax':"",
|
|
38
|
-
'RotZ':"",
|
|
39
|
-
'RotZVar':"",
|
|
40
|
-
'RotZMin':"",
|
|
41
|
-
'RotZMax':"",
|
|
42
|
-
'Xup':"",
|
|
43
|
-
'XDown':"",
|
|
44
|
-
'Yup':"",
|
|
45
|
-
'Ydown':"",
|
|
46
|
-
'Zup':"",
|
|
47
|
-
'Zdown':"",
|
|
48
|
-
'StepCount':"",
|
|
49
|
-
'LUX':"",
|
|
50
|
-
'UVindex':"",
|
|
51
|
-
'HighVisRaw':"",
|
|
52
|
-
'LowVisRaw':"",
|
|
53
|
-
'IRRaw':"",
|
|
54
|
-
'UVRaw':"",
|
|
55
|
-
'PMMeasCnt':"",
|
|
56
|
-
'PM1MC':"",
|
|
57
|
-
'PM1MCVar':"",
|
|
58
|
-
'PM2_5MC': "μg/m3",
|
|
59
|
-
'PM2_5MCVar':"",
|
|
60
|
-
'PM4MC':"",
|
|
61
|
-
'PM4MCVar':"",
|
|
62
|
-
'PM10MC':"",
|
|
63
|
-
'PM10MCVar':"",
|
|
64
|
-
'PM0_5NC':"",
|
|
65
|
-
'PM0_5NCVar':"",
|
|
66
|
-
'PM1NC':"",
|
|
67
|
-
'PM1NCVar':"",
|
|
68
|
-
'PM2_5NC':"",
|
|
69
|
-
'PM2_5NCVar':"",
|
|
70
|
-
'PM4NC':"",
|
|
71
|
-
'PM4NCVar':"",
|
|
72
|
-
'PM10NC':"",
|
|
73
|
-
'PM10NCVar':"",
|
|
74
|
-
'PMtypicalParticleSize':"",
|
|
75
|
-
'PMtypicalParticleSizeVar':"",
|
|
76
|
-
'PM2_5SampledMass':"",
|
|
77
|
-
'PMReadingErrorCnt':"",
|
|
78
|
-
'PMFanErrorCnt':"",
|
|
79
|
-
'PMLaserErrorCnt':"",
|
|
80
|
-
'PMFanSpeedWarn':"",
|
|
81
|
-
'PCB1T':"",
|
|
82
|
-
'PCB2T':"",
|
|
83
|
-
'FdpT':"",
|
|
84
|
-
'AccelT':"",
|
|
85
|
-
'PT100R':"",
|
|
86
|
-
'PCB2P':"",
|
|
87
|
-
'PumpPow1':"",
|
|
88
|
-
'PumpPow2':"",
|
|
89
|
-
'PumpV':"",
|
|
90
|
-
'MassFlow':"",
|
|
91
|
-
'MFSVout':"",
|
|
92
|
-
'BFGenergy':"",
|
|
93
|
-
'BattVolt':"",
|
|
94
|
-
'v3_3':"",
|
|
95
|
-
'v5':"",
|
|
96
|
-
'PumpsON':"",
|
|
97
|
-
'Dead':"",
|
|
98
|
-
'BCS1':"",
|
|
99
|
-
'BCS2':"",
|
|
100
|
-
'BC_NPG':"",
|
|
101
|
-
'FLOWCTL':"",
|
|
102
|
-
'GPSRT':"",
|
|
103
|
-
'SD_DATAW':"",
|
|
104
|
-
'SD_HEADW':"",
|
|
105
|
-
'TPumpsOFF':"",
|
|
106
|
-
'TPumpsON':"",
|
|
107
|
-
'CO2':"",
|
|
108
|
-
'SCDT':"",
|
|
109
|
-
'SCDRH':"",
|
|
110
|
-
'VOCRaw':"",
|
|
111
|
-
'NOXRaw':""}
|
|
112
|
-
|
|
113
|
-
lascar_units = {"CO(ppm)":"ppm"}
|
|
114
|
-
|
|
115
|
-
purple_units = {'mac_address':"",
|
|
116
|
-
'firmware_ver':"",
|
|
117
|
-
'hardware':"",
|
|
118
|
-
'current_temp_f':"",
|
|
119
|
-
'current_humidity':"",
|
|
120
|
-
'current_dewpoint_f':"",
|
|
121
|
-
'pressure':"",
|
|
122
|
-
'adc':"",
|
|
123
|
-
'mem':"",
|
|
124
|
-
'rssi':"",
|
|
125
|
-
'uptime':"",
|
|
126
|
-
'pm1_0_cf_1':"",
|
|
127
|
-
'pm2_5_cf_1':"",
|
|
128
|
-
'pm10_0_cf_1':"",
|
|
129
|
-
'pm1_0_atm':"",
|
|
130
|
-
'pm2_5_atm':"",
|
|
131
|
-
'pm10_0_atm':"",
|
|
132
|
-
'pm2.5_aqi_cf_1':"",
|
|
133
|
-
'pm2.5_aqi_atm':"",
|
|
134
|
-
'p_0_3_um':"",
|
|
135
|
-
'p_0_5_um':"",
|
|
136
|
-
'p_1_0_um':"",
|
|
137
|
-
'p_2_5_um':"",
|
|
138
|
-
'p_5_0_um':"",
|
|
139
|
-
'p_10_0_um':"",
|
|
140
|
-
'pm1_0_cf_1_b':"",
|
|
141
|
-
'pm2_5_cf_1_b':"",
|
|
142
|
-
'pm10_0_cf_1_b':"",
|
|
143
|
-
'pm1_0_atm_b':"",
|
|
144
|
-
'pm2_5_atm_b':"",
|
|
145
|
-
'pm10_0_atm_b':"",
|
|
146
|
-
'pm2.5_aqi_cf_1_b':"",
|
|
147
|
-
'pm2.5_aqi_atm_b':"",
|
|
148
|
-
'p_0_3_um_b':"",
|
|
149
|
-
'p_0_5_um_b':"",
|
|
150
|
-
'p_1_0_um_b':"",
|
|
151
|
-
'p_2_5_um_b':"",
|
|
152
|
-
'p_5_0_um_b':"",
|
|
153
|
-
'p_10_0_um_b':"",
|
|
154
|
-
'gas':"",
|
|
155
|
-
'pm_adj': "μg/m3"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|