etlup 0.0.1__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.
- etlup-0.0.1/.gitignore +12 -0
- etlup-0.0.1/LICENSE.txt +9 -0
- etlup-0.0.1/PKG-INFO +44 -0
- etlup-0.0.1/README.md +21 -0
- etlup-0.0.1/__init__.py +3 -0
- etlup-0.0.1/pyproject.toml +64 -0
- etlup-0.0.1/src/etlup/__about__.py +4 -0
- etlup-0.0.1/src/etlup/__init__.py +3 -0
- etlup-0.0.1/src/etlup/data_models.py +286 -0
- etlup-0.0.1/tests/__init__.py +3 -0
etlup-0.0.1/.gitignore
ADDED
etlup-0.0.1/LICENSE.txt
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Hayden Swanson <hayden_swanson22@yahoo.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
etlup-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: etlup
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Project-URL: Documentation, https://github.com/Hayden Swanson/etlup#readme
|
|
5
|
+
Project-URL: Issues, https://github.com/Hayden Swanson/etlup/issues
|
|
6
|
+
Project-URL: Source, https://github.com/Hayden Swanson/etlup
|
|
7
|
+
Author-email: Hayden Swanson <hayden_swanson22@yahoo.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE.txt
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
18
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Requires-Dist: matplotlib==3.7.2
|
|
21
|
+
Requires-Dist: pydantic==2.5.3
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# etlup
|
|
25
|
+
|
|
26
|
+
[](https://pypi.org/project/etlup)
|
|
27
|
+
[](https://pypi.org/project/etlup)
|
|
28
|
+
|
|
29
|
+
-----
|
|
30
|
+
|
|
31
|
+
## Table of Contents
|
|
32
|
+
|
|
33
|
+
- [Installation](#installation)
|
|
34
|
+
- [License](#license)
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```console
|
|
39
|
+
pip install etlup
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
`etlup` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
|
etlup-0.0.1/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# etlup
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/etlup)
|
|
4
|
+
[](https://pypi.org/project/etlup)
|
|
5
|
+
|
|
6
|
+
-----
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [License](#license)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```console
|
|
16
|
+
pip install etlup
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
`etlup` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
|
etlup-0.0.1/__init__.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "etlup"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = ''
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
keywords = []
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Hayden Swanson", email = "hayden_swanson22@yahoo.com" },
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Programming Language :: Python",
|
|
19
|
+
"Programming Language :: Python :: 3.8",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
25
|
+
"Programming Language :: Python :: Implementation :: PyPy",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"pydantic==2.5.3",
|
|
29
|
+
"matplotlib==3.7.2"
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Documentation = "https://github.com/Hayden Swanson/etlup#readme"
|
|
34
|
+
Issues = "https://github.com/Hayden Swanson/etlup/issues"
|
|
35
|
+
Source = "https://github.com/Hayden Swanson/etlup"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.version]
|
|
38
|
+
path = "src/etlup/__about__.py"
|
|
39
|
+
|
|
40
|
+
[tool.hatch.envs.types]
|
|
41
|
+
extra-dependencies = [
|
|
42
|
+
"mypy>=1.0.0",
|
|
43
|
+
]
|
|
44
|
+
[tool.hatch.envs.types.scripts]
|
|
45
|
+
check = "mypy --install-types --non-interactive {args:src/etlup tests}"
|
|
46
|
+
|
|
47
|
+
[tool.coverage.run]
|
|
48
|
+
source_pkgs = ["etlup", "tests"]
|
|
49
|
+
branch = true
|
|
50
|
+
parallel = true
|
|
51
|
+
omit = [
|
|
52
|
+
"src/etlup/__about__.py",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.coverage.paths]
|
|
56
|
+
etlup = ["src/etlup", "*/etlup/src/etlup"]
|
|
57
|
+
tests = ["tests", "*/etlup/tests"]
|
|
58
|
+
|
|
59
|
+
[tool.coverage.report]
|
|
60
|
+
exclude_lines = [
|
|
61
|
+
"no cov",
|
|
62
|
+
"if __name__ == .__main__.:",
|
|
63
|
+
"if TYPE_CHECKING:",
|
|
64
|
+
]
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains the code for ensuring data follows a predifined format and uses Pydantic
|
|
3
|
+
|
|
4
|
+
--------------------CONSTRUCTION DATA---------------------
|
|
5
|
+
- ConstructionBase
|
|
6
|
+
- all assembly and test types inherit from this base class, contains the needed and shared fields and validation for every assembly/test (user, measurement date, etc...)
|
|
7
|
+
|
|
8
|
+
- Subclasses of ConstructionBase (assembly and test types!)
|
|
9
|
+
- type field overwritten to ensure it is the correct assembly or test type
|
|
10
|
+
- data field so the data can be of a defined format as well
|
|
11
|
+
* data_cache method takes the data field and trims any fat to put in the database for fast lookup (code to visualize the data will use this)
|
|
12
|
+
|
|
13
|
+
----------------OTHER DATA NOT IMPLMEMENTED----------------
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from typing import Union, List
|
|
17
|
+
from typing_extensions import Literal
|
|
18
|
+
from pydantic import BaseModel, field_validator, model_validator, Field, AwareDatetime, AliasChoices, RootModel, ConfigDict
|
|
19
|
+
import numpy as np
|
|
20
|
+
import json
|
|
21
|
+
from _ctypes import PyObj_FromPtr
|
|
22
|
+
import re
|
|
23
|
+
import json
|
|
24
|
+
from datetime import datetime
|
|
25
|
+
import pytz
|
|
26
|
+
from typing import get_args
|
|
27
|
+
|
|
28
|
+
#-----------------------------------------------------------#
|
|
29
|
+
def get_constr_model(constr_type: str):
|
|
30
|
+
"""
|
|
31
|
+
Returns a single construction model class based on type
|
|
32
|
+
"""
|
|
33
|
+
#loop through all subclasses of ConstructionBase
|
|
34
|
+
for ConstrSubclass in ConstructionBase.get_subclasses():
|
|
35
|
+
#get all the types the construction class is defined for
|
|
36
|
+
model_constr_types = get_args(ConstrSubclass.model_fields['type'].annotation)
|
|
37
|
+
#check if the supplied type is part of it
|
|
38
|
+
if constr_type in model_constr_types:
|
|
39
|
+
return ConstrSubclass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def validate_datetime(meas_date: datetime) -> datetime:
|
|
44
|
+
#if measurement date has tz information, convert from that TZ to UTC time!
|
|
45
|
+
if not isinstance(meas_date, datetime):
|
|
46
|
+
raise ValueError(f"Inputted date is not a datetime object it is {type(meas_date)}")
|
|
47
|
+
#is a datetime object...
|
|
48
|
+
if meas_date.tzinfo is None:
|
|
49
|
+
#need to do this otherwise it has a default for no timezone given!
|
|
50
|
+
raise ValueError("Measurement data has no time zone information, see https://en.wikipedia.org/wiki/ISO_8601")
|
|
51
|
+
|
|
52
|
+
#converts time to UTC time
|
|
53
|
+
return meas_date.astimezone(pytz.utc)
|
|
54
|
+
|
|
55
|
+
class NoIndent(object):
|
|
56
|
+
""" Value wrapper. """
|
|
57
|
+
def __init__(self, value, max_length=None):
|
|
58
|
+
self.value = value
|
|
59
|
+
self.max_length = max_length
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class DocumentationEncoder(json.JSONEncoder):
|
|
63
|
+
FORMAT_SPEC = '@@{}@@'
|
|
64
|
+
regex = re.compile(FORMAT_SPEC.format(r'(\d+)'))
|
|
65
|
+
|
|
66
|
+
def __init__(self, **kwargs):
|
|
67
|
+
# Save copy of any keyword argument values needed for use here.
|
|
68
|
+
self.__sort_keys = kwargs.get('sort_keys', None)
|
|
69
|
+
super(DocumentationEncoder, self).__init__(**kwargs)
|
|
70
|
+
|
|
71
|
+
def default(self, obj):
|
|
72
|
+
return (self.FORMAT_SPEC.format(id(obj)) if isinstance(obj, NoIndent)
|
|
73
|
+
else super(DocumentationEncoder, self).default(obj))
|
|
74
|
+
|
|
75
|
+
def encode(self, obj):
|
|
76
|
+
format_spec = self.FORMAT_SPEC # Local var to expedite access.
|
|
77
|
+
json_repr = super(DocumentationEncoder, self).encode(obj) # Default JSON.
|
|
78
|
+
|
|
79
|
+
# Replace any marked-up object ids in the JSON repr with the
|
|
80
|
+
# value returned from the json.dumps() of the corresponding
|
|
81
|
+
# wrapped Python object.
|
|
82
|
+
for match in self.regex.finditer(json_repr):
|
|
83
|
+
# see https://stackoverflow.com/a/15012814/355230
|
|
84
|
+
_id = int(match.group(1))
|
|
85
|
+
no_indent = PyObj_FromPtr(_id)
|
|
86
|
+
if no_indent.max_length is not None and isinstance(no_indent.value, list) and len(str(no_indent.value)) > no_indent.max_length:
|
|
87
|
+
truncated_value = str(no_indent.value)[0:no_indent.max_length]
|
|
88
|
+
json_obj_repr = truncated_value + '...'
|
|
89
|
+
else:
|
|
90
|
+
json_obj_repr = json.dumps(no_indent.value, sort_keys=self.__sort_keys)
|
|
91
|
+
|
|
92
|
+
# Replace the matched id string with json formatted representation
|
|
93
|
+
# of the corresponding Python object.
|
|
94
|
+
json_repr = json_repr.replace(
|
|
95
|
+
'"{}"'.format(format_spec.format(_id)), json_obj_repr)
|
|
96
|
+
|
|
97
|
+
return '\n'+json_repr #\n to get rid of weird indent in html :)
|
|
98
|
+
|
|
99
|
+
#----------------------SUBMODELS------------------------#
|
|
100
|
+
class SensorVendorTestData(BaseModel):
|
|
101
|
+
vendor_leakage_current_uA: Union[None,float] = Field(validation_alias=AliasChoices('vendor_leakage_current_uA','Vendor Leakage Current [uA]'))
|
|
102
|
+
vendor_breakdown_voltage_V: Union[None,float] = Field(validation_alias=AliasChoices('vendor_breakdown_voltage_V','Vendor Breakdown Voltage [V]'))
|
|
103
|
+
vendor_category: Union[None,Literal["BAD", "GOOD", "MEDIUM"]] = Field(validation_alias=AliasChoices('vendor_category','Vendor Category'))
|
|
104
|
+
current: Union[None,List] = Field(validation_alias=AliasChoices('current','Current'))
|
|
105
|
+
voltage: Union[None,List] = Field(validation_alias=AliasChoices('voltage','Voltage'))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class GantryPickAndPlaceData(BaseModel):
|
|
109
|
+
target: List[float]
|
|
110
|
+
actual: List[float]
|
|
111
|
+
delta: List[float]
|
|
112
|
+
|
|
113
|
+
@field_validator('*')
|
|
114
|
+
@classmethod
|
|
115
|
+
def length_check(cls, v):
|
|
116
|
+
if len(v) != 4:
|
|
117
|
+
raise ValueError("The required length is 4 for target, actual and delta. It is [x, y, z, rot]")
|
|
118
|
+
return v
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
#---------------------------------------- BASE CONSTRUCTION MODELS ---------------------------------------#
|
|
122
|
+
class ConstrHelperMixin:
|
|
123
|
+
@classmethod
|
|
124
|
+
def get_examples(cls):
|
|
125
|
+
json_schema = cls.model_config.get("json_schema_extra")
|
|
126
|
+
return [json.dumps(examp, cls=DocumentationEncoder, indent=2) for examp in json_schema.get("examples", []) if json_schema]
|
|
127
|
+
|
|
128
|
+
class ConstructionBase(BaseModel, ConstrHelperMixin):
|
|
129
|
+
measurement_date: AwareDatetime #force times to have timezone
|
|
130
|
+
location: str
|
|
131
|
+
user_created: str
|
|
132
|
+
|
|
133
|
+
@field_validator('*')
|
|
134
|
+
@classmethod
|
|
135
|
+
def empty_str_to_none(cls, v):
|
|
136
|
+
if isinstance(v, str) and v.strip() == '':
|
|
137
|
+
return None
|
|
138
|
+
return v
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def get_subclasses(cls):
|
|
142
|
+
return tuple(cls.__subclasses__())
|
|
143
|
+
|
|
144
|
+
@field_validator("measurement_date")
|
|
145
|
+
@classmethod
|
|
146
|
+
def validate_measurement_date(cls, v):
|
|
147
|
+
return validate_datetime(v)
|
|
148
|
+
|
|
149
|
+
#------------------------------------------------------#
|
|
150
|
+
|
|
151
|
+
class SensorVendorTest(ConstructionBase):
|
|
152
|
+
model_config = ConfigDict(json_schema_extra={
|
|
153
|
+
'examples': [
|
|
154
|
+
{
|
|
155
|
+
"component": "TYL4U001",
|
|
156
|
+
"type": "Sensor Vendor Test",
|
|
157
|
+
"measurement_date": "2023-01-01T12:00:00+01:00",
|
|
158
|
+
"location": "FBK",
|
|
159
|
+
"user_created": "fsiviero",
|
|
160
|
+
"data": {
|
|
161
|
+
"vendor_leakage_current_uA": 158.176,
|
|
162
|
+
"vendor_breakdown_voltage_V": 282.0,
|
|
163
|
+
"vendor_category": "BAD",
|
|
164
|
+
"current": NoIndent([1.7981099942332435e-9, 2.1325199384136795e-9,2.3892399170222234e-9,2.6674600306364482e-9,2.9917699428949618e-9,3.3739500082674567e-9,3.8820999748168106e-9,4.47047021623348e-9,5.163700134147575e-9,5.982729867071157e-9,6.888820180961375e-9,7.861340023396224e-9,8.972140363994185e-9,9.177109738800482e-9,1.1357499829500739e-8,1.3345699656497345e-8,1.591829956737456e-8,1.9567799824926624e-8,2.4187400526898273e-8,2.9501000753384687e-8,4.2371500086346714e-8,5.5717400755384006e-6,0.000025144199753412977,0.000034218599466839805,0.000040536098822485656,0.00004414160139276646,0.000045468401367543265,0.00005196220081415959,0.00006523320189444348,0.00007574760093120858,0.00008891220204532146,0.00011379199713701382,0.00013335900439415127,0.00015114799316506833,0.0001657230022829026,0.00018318099319003522,0.00020124799630139023,0.00021330300660338253,0.00022421199537348002,0.00023484700068365782,0.00024567899527028203,0.00025691199698485434,0.0002710630069486797,0.00028676798683591187,0.0003011419903486967,0.00031354298698715866,0.0003255319898016751,0.00033718798658810556,0.00034998898627236485,0.00037184200482442975,0.0003914310073014349,0.0004061759973410517,0.00042100698919966817,0.0004358369915280491,0.0004506719997152686,0.00046582298818975687,0.0004808040102943778,0.0004961600061506033,0.0005116279935464263,0.0005280390032567084,0.000550133001524955,0.000574567005969584], max_length=40),
|
|
165
|
+
"voltage": NoIndent([0.0,2.0,4.0,6.0,8.0,10.0,12.0,14.0,16.0,18.0,20.0,22.0,23.0,25.0,26.0,28.0,30.0,32.0,34.0,36.0,38.0,40.0,41.0,43.0,45.0,47.0,49.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,85.0,90.0,95.0,100.0,105.0,110.0,115.0,120.0,125.0,130.0,135.0,140.0,145.0,150.0,155.0,160.0,165.0,170.0,175.0,180.0,185.0,190.0,195.0,200.0,205.0,210.0,215.0,220.0,225.0,230.0,235.0,240.0,245.0,250.0,255.0,260.0,265.0,270.0,275.0,280.0], max_length=40)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
type: Literal['Sensor Vendor Test']
|
|
172
|
+
component: str
|
|
173
|
+
data: SensorVendorTestData
|
|
174
|
+
|
|
175
|
+
def calc_data_cache(self):
|
|
176
|
+
return self.data
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class ModuleETROCStatus(ConstructionBase):
|
|
180
|
+
model_config = ConfigDict(json_schema_extra={
|
|
181
|
+
'examples': [
|
|
182
|
+
{
|
|
183
|
+
"component": "PE0001",
|
|
184
|
+
"type": "etroc_status",
|
|
185
|
+
"measurement_date": "2023-01-01T12:00:00+01:00",
|
|
186
|
+
"location": "BU",
|
|
187
|
+
"user_created": "hayden",
|
|
188
|
+
"data": NoIndent(np.ones((16,16), dtype=int).tolist(), max_length=60)
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
})
|
|
192
|
+
type: Literal['etroc_status']
|
|
193
|
+
component: str
|
|
194
|
+
data: List[List[int]]
|
|
195
|
+
|
|
196
|
+
@field_validator('data')
|
|
197
|
+
@classmethod
|
|
198
|
+
def length_check(cls, v):
|
|
199
|
+
v_arr = np.array(v)
|
|
200
|
+
if v_arr.shape != (16,16):
|
|
201
|
+
raise ValueError(f"Your array is not the correct shape, it should be 16x16, you gave: {v_arr.shape}")
|
|
202
|
+
|
|
203
|
+
def calc_data_cache(self):
|
|
204
|
+
return self.data
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
#---------------------ASSEMBLY----------------------#
|
|
208
|
+
|
|
209
|
+
class SubassemblyAlignment(ConstructionBase):
|
|
210
|
+
model_config = ConfigDict(json_schema_extra={
|
|
211
|
+
'examples': [
|
|
212
|
+
{
|
|
213
|
+
"compoenent": "PS0001",
|
|
214
|
+
"type": "subassembly alignment",
|
|
215
|
+
"measurement_date": "2023-01-01T12:00:00+01:00",
|
|
216
|
+
"location": "BU",
|
|
217
|
+
"user_created": "hayden",
|
|
218
|
+
"data": {
|
|
219
|
+
"target": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
220
|
+
"actual": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
221
|
+
"delta": NoIndent([639.141118, 287.244992, 64.009534,-0.048954])
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
})
|
|
226
|
+
type: Literal['subassembly alignment']
|
|
227
|
+
component: str
|
|
228
|
+
data: GantryPickAndPlaceData
|
|
229
|
+
|
|
230
|
+
def calc_data_cache(self):
|
|
231
|
+
return self.data
|
|
232
|
+
|
|
233
|
+
class GantryPickPlace(ConstructionBase):
|
|
234
|
+
model_config = ConfigDict(json_schema_extra={
|
|
235
|
+
'examples': [
|
|
236
|
+
{
|
|
237
|
+
"module": "PBU0001",
|
|
238
|
+
"compoenent": "PE0001",
|
|
239
|
+
"component_pos": 1,
|
|
240
|
+
"type": "pick and place survey precure",
|
|
241
|
+
"measurement_date": "2023-01-01T12:00:00+01:00",
|
|
242
|
+
"location": "BU",
|
|
243
|
+
"user_created": "hayden",
|
|
244
|
+
"data": {
|
|
245
|
+
"target": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
246
|
+
"actual": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
247
|
+
"delta": NoIndent([639.141118, 287.244992, 64.009534,-0.048954])
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"module": "PBU0001",
|
|
252
|
+
"compoenent": "PE0001",
|
|
253
|
+
"component_pos": 1,
|
|
254
|
+
"type": "pick and place survey postcure",
|
|
255
|
+
"measurement_date": "2023-01-01T12:00:00+01:00",
|
|
256
|
+
"location": "BU",
|
|
257
|
+
"user_created": "hayden",
|
|
258
|
+
"data": {
|
|
259
|
+
"target": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
260
|
+
"actual": NoIndent([639.141118, 287.244992, 64.009534,-0.048954]),
|
|
261
|
+
"delta": NoIndent([639.141118, 287.244992, 64.009534,-0.048954])
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
],
|
|
265
|
+
})
|
|
266
|
+
type: Literal['pick and place survey precure', 'pick and place survey postcure']
|
|
267
|
+
module: str
|
|
268
|
+
component: str
|
|
269
|
+
component_pos: int
|
|
270
|
+
data: GantryPickAndPlaceData
|
|
271
|
+
|
|
272
|
+
def calc_data_cache(self):
|
|
273
|
+
print("whoops")
|
|
274
|
+
return self.data
|
|
275
|
+
|
|
276
|
+
def display_data(self):
|
|
277
|
+
#take the data and make a plot or calculation
|
|
278
|
+
pass
|
|
279
|
+
|
|
280
|
+
def as_html_card(self):
|
|
281
|
+
pass
|
|
282
|
+
|
|
283
|
+
#-------------------------Model for list of construction objects-------------------------------#
|
|
284
|
+
class ConstructionCong(RootModel): #cong for conglomerate
|
|
285
|
+
#https://github.com/pydantic/pydantic/issues/3947
|
|
286
|
+
root: List[Union[ConstructionBase.get_subclasses()]] = Field(..., discriminator='type') #could try Union[Type[ConstructionBase]] later
|