Repository navigation
Expand file tree
/
Copy pathProjectConfig.py
More file actions
132 lines (110 loc) · 4.16 KB
/
Copy pathProjectConfig.py
File metadata and controls
132 lines (110 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#################################################
#
# PROJECT CONFIGURATION TYPES
#
# Defines the shared data structures used by ConfigInfo.py and the individual
# site configuration files.
#
import os
from collections import namedtuple
from dataclasses import dataclass
AGILENT_DESCRIPTOR_FIELDS = [ 'Port','Channel list','Thermocouple channels','GHI channels','DNI channels','DNI gain','Front panel channel' ]
CollectorMapping = namedtuple('CollectorMapping', ['Name', 'Port', 'BoardSerial'])
PICOTOOL_PATH = os.path.expanduser(r"~\.pico-sdk\picotool\2.0.0\picotool\picotool.exe")
@dataclass
class tProjectConfig:
Name: str
DisplayName: str
WindowTitle: str
MenuTitle: str
LogFolder: str
LogFilePrefix: str
ArchiveFolder: str
HeaderIdentity: str
Latitude: float
Longitude: float
Elevation: float
Timezone: str
Agilents: list
CollectorPorts: list
CollectorGridRows: int
CollectorGridCols: int
MarqueePort: str | None
MarqueeDisplayOrder : list | None
OutsideTempSensorPort: str | None
DomeTempSensorPort: str | None
ElectronicsTempSensorPort: str | None
PowerRelayAgilentIndex: int | None
MotorPowerChannels: str | None
UsbHubPowerChannel: str | None
NipPowerChannels: str | None
NipOnOffButtonChannel: str | None
PyranometerPowerChannel: str | None
bUseDniToStartDay: bool
CollectorStartAfterSunriseMinutes: int
CollectorStopBeforeSunsetMinutes: int
PicotoolPath: str
ThingerUserName: str | None
ThingerDeviceId: str | None
ThingerBucketId: str | None
ThingerBearerToken: str | None
#################################################
#
# Derived capability properties
#
# Python properties are methods that callers read like normal attributes.
# For example, call sites use PROJECT_CONFIG.bHasAgilents, but the value is
# computed from PROJECT_CONFIG.Agilents each time it is read. That preserves
# the readable bHas... style without making anyone maintain a second copy of
# the same fact.
#
# The maintenance rule is simple: edit the lists, ports, channel groups, and
# credentials above. Do not add manually-entered capability booleans. Add a
# property only when multiple call sites need the same capability question
# answered from real config data.
#
@property
def bHasAgilents(self):
return len(self.Agilents) > 0
@property
def bHasThermocouples(self):
return any(agilent[AGILENT_DESCRIPTOR_FIELDS.index('Thermocouple channels')] is not None for agilent in self.Agilents)
@property
def bHasOutsideTempSensor(self):
return self.OutsideTempSensorPort is not None
@property
def bHasDomeTempSensor(self):
return self.DomeTempSensorPort is not None
@property
def bHasElectronicsTempSensor(self):
return self.ElectronicsTempSensorPort is not None
@property
def bHasTempHumiditySensors(self):
return self.bHasOutsideTempSensor or self.bHasDomeTempSensor or self.bHasElectronicsTempSensor
@property
def bHasMarquee(self):
return self.MarqueePort is not None
@property
def bHasThinger(self):
return self.ThingerUserName is not None and self.ThingerDeviceId is not None and self.ThingerBucketId is not None and self.ThingerBearerToken is not None
@property
def bHasNip(self):
return self.PowerRelayAgilentIndex is not None and self.NipPowerChannels is not None and self.NipOnOffButtonChannel is not None
@property
def bHasPyranometer(self):
return self.PowerRelayAgilentIndex is not None and self.PyranometerPowerChannel is not None
@property
def bHasMotorPowerRelay(self):
return self.PowerRelayAgilentIndex is not None and self.MotorPowerChannels is not None
@property
def bHasUsbPowerRelay(self):
return self.PowerRelayAgilentIndex is not None and self.UsbHubPowerChannel is not None
@property
def bHasPowerRelays(self):
return self.bHasMotorPowerRelay or self.bHasUsbPowerRelay or self.bHasNip or self.bHasPyranometer
@property
def bHasDniSensor(self):
return any(agilent[AGILENT_DESCRIPTOR_FIELDS.index('DNI channels')] is not None for agilent in self.Agilents)
@property
def bHasGhiSensor(self):
return any(agilent[AGILENT_DESCRIPTOR_FIELDS.index('GHI channels')] is not None for agilent in self.Agilents)