Automatic push from FunctionsAPI
This commit is contained in:
parent
14b2c6a78e
commit
89247c99e3
3623
Cargo.lock
generated
Normal file
3623
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
edition = "2024"
|
||||||
|
name = "web"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
fathom-function = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "main" }
|
||||||
|
pipeline-application = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "main" }
|
||||||
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
|
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
uuid = { version = "1" }
|
||||||
67
README.md
67
README.md
@ -1,2 +1,67 @@
|
|||||||
# 8617e56f5532458c8613357f82affd96
|
# Creation of an ILI report
|
||||||
|
|
||||||
|
A function that will create a ILI report asset and sequence.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
- `org_id`: as string which should be a valid `uuid` for the organization
|
||||||
|
- `project_id`: the id of the data project where the pipeline data is found
|
||||||
|
- `pipeline_id`: a `array` each item of which should be a valid uuid for a pipeline.
|
||||||
|
- `date`: a `string` formatted as an ISO date representing the date of the
|
||||||
|
inspection.
|
||||||
|
- `vendor_name`: a `string` the company who conducted the ILI inspection
|
||||||
|
- `report_type`: a `string` the type of the report possible values:
|
||||||
|
- `final`
|
||||||
|
- `preliminary`
|
||||||
|
- `inspection_type`: a `string` the type of technology used possible values:
|
||||||
|
- `mfl`
|
||||||
|
- `tfi`
|
||||||
|
- `ut`
|
||||||
|
- `emat`
|
||||||
|
- `caliper`
|
||||||
|
- `combo_mfl_and_tfi`
|
||||||
|
- `combo_mfl_and_ut`
|
||||||
|
- `combo_mfl_and_ec`
|
||||||
|
- `file_details`: a `array` of file detail objects
|
||||||
|
- `wall_thickness_source`: optional `string` to configure the wall source in the ILI report calculations
|
||||||
|
- `pipebody_tolerances`: an `object` representing the tolerances for the pipebody
|
||||||
|
- `haz_tolerances`: an `object` representing the tolerances for the heat affected zone (HAZ)
|
||||||
|
|
||||||
|
## Creating the function on the platform
|
||||||
|
|
||||||
|
To create this function on the platform using the `cli` set up the port forwarding as shown in README.
|
||||||
|
|
||||||
|
Then run the following command to create the function.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run functions create \
|
||||||
|
-f functions/ili_creation \
|
||||||
|
-d "Processes an ILI file and create the sequences and assets associated with that report" \
|
||||||
|
-i org_id=string \
|
||||||
|
-i project_id=string \
|
||||||
|
-i pipeline_id=string \
|
||||||
|
-i date=string \
|
||||||
|
-i vendor_name=string \
|
||||||
|
-i report_type=string \
|
||||||
|
-i wall_thickness_source=string \
|
||||||
|
-i inspection_type=string \
|
||||||
|
-i file_details=object \
|
||||||
|
-i pipebody_tolerances=object \
|
||||||
|
-i haz_tolerances=object
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing the function locally
|
||||||
|
|
||||||
|
You can run and test the function locally by running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can check it work with `curl` as follows
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jq '. | tojson' functions/ili_creation/example_input.json | curl -d '@-' localhost:8080
|
||||||
|
```
|
||||||
|
|||||||
246
example_input.json
Normal file
246
example_input.json
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
{
|
||||||
|
"date": "2002-02-01",
|
||||||
|
"file_details": [
|
||||||
|
{
|
||||||
|
"fileId": "a2e8295f-3547-47b1-92ae-d5446b081eee",
|
||||||
|
"revisionId": "2c68f624-2e9b-4c4a-90e0-d0243bd5c541"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"wall_thickness_source": "as-built",
|
||||||
|
"haz_tolerances": {
|
||||||
|
"axial_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"axial_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinhole": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pitting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inspection_type": "mfl",
|
||||||
|
"pipebody_tolerances": {
|
||||||
|
"axial_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.2
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"axial_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.19
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinhole": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.2
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pitting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"org_id": "2cbfe270-d195-48ad-aed1-24145924635c",
|
||||||
|
"pipeline_id": [
|
||||||
|
"01966d47-1d4c-7751-a1f1-0617caa3a00d"
|
||||||
|
],
|
||||||
|
"project_id": "680b61b0aedd6f9e639d8699",
|
||||||
|
"report_type": "final",
|
||||||
|
"vendor_name": "ILI-Ros"
|
||||||
|
}
|
||||||
224
src/main.rs
Normal file
224
src/main.rs
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
use fathom_function::{
|
||||||
|
chrono::NaiveDate,
|
||||||
|
forms::{TableCellValue, deserialize_date},
|
||||||
|
tracing,
|
||||||
|
};
|
||||||
|
use pipeline_application::application::{
|
||||||
|
Application, DimensionClass, ILIConfiguration, InlineInspection, InspectionType, ReportType,
|
||||||
|
Tolerance as ApplicationTolerance, ToleranceAdjustment, ToolTolerances, WallThicknessSource,
|
||||||
|
uom::si::{f64::Length, length::millimeter},
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[fathom_function::function]
|
||||||
|
async fn ili_creation(input: Input) -> Result<Output, String> {
|
||||||
|
let reports_details = input.report_details;
|
||||||
|
let tolerances = input.tolerances;
|
||||||
|
let config = input.config;
|
||||||
|
let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap();
|
||||||
|
|
||||||
|
for (pipeline_id, file_details) in input.pipeline_id.into_iter().zip(input.file_details) {
|
||||||
|
app.process_ili_report(
|
||||||
|
pipeline_id,
|
||||||
|
file_details.file_id,
|
||||||
|
&tolerances,
|
||||||
|
&reports_details,
|
||||||
|
&config,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
tracing::error!(%pipeline_id, ?err, "Error running ili calculations");
|
||||||
|
format!("{err:?}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(Output {
|
||||||
|
status: "Success".to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Output {
|
||||||
|
status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Input {
|
||||||
|
org_id: Uuid,
|
||||||
|
project_id: String,
|
||||||
|
pipeline_id: Vec<Uuid>,
|
||||||
|
file_details: Vec<FileDetails>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
report_details: InspectionReportDetails,
|
||||||
|
#[serde(flatten)]
|
||||||
|
tolerances: CombineTolerances,
|
||||||
|
#[serde(flatten)]
|
||||||
|
config: Config,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct Config {
|
||||||
|
wall_thickness_source: WTSource,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Config> for ILIConfiguration {
|
||||||
|
fn from(value: &Config) -> Self {
|
||||||
|
Self::default().with_wall_thickness_source(value.wall_thickness_source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone, Copy, Default)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
enum WTSource {
|
||||||
|
#[default]
|
||||||
|
AsBuilt,
|
||||||
|
Report,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WTSource> for WallThicknessSource {
|
||||||
|
fn from(value: WTSource) -> Self {
|
||||||
|
match value {
|
||||||
|
WTSource::AsBuilt => Self::AsBuilt,
|
||||||
|
WTSource::Report => Self::Reported,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct CombineTolerances {
|
||||||
|
haz_tolerances: Tolerances<HazTolerance>,
|
||||||
|
pipebody_tolerances: Tolerances<Tolerance>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Tolerances<T> {
|
||||||
|
general: T,
|
||||||
|
pitting: T,
|
||||||
|
axial_grooving: T,
|
||||||
|
circumferential_grooving: T,
|
||||||
|
pinhole: T,
|
||||||
|
axial_slotting: T,
|
||||||
|
circumferential_slotting: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Tolerance {
|
||||||
|
depth: TableCellValue,
|
||||||
|
length: TableCellValue,
|
||||||
|
width: TableCellValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct HazTolerance {
|
||||||
|
sensitivity: TableCellValue,
|
||||||
|
#[serde(flatten)]
|
||||||
|
tolerance: Tolerance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tolerance {
|
||||||
|
fn to_tolerance(&self, haz_tolerances: &HazTolerance) -> Option<ApplicationTolerance> {
|
||||||
|
Some(ApplicationTolerance::new(
|
||||||
|
Option::<f64>::try_from(&haz_tolerances.sensitivity).ok()??,
|
||||||
|
Option::<ToleranceAdjustment>::from(&haz_tolerances.tolerance)?,
|
||||||
|
Option::<ToleranceAdjustment>::from(self)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct InspectionReportDetails {
|
||||||
|
#[serde(deserialize_with = "deserialize_date")]
|
||||||
|
date: NaiveDate,
|
||||||
|
vendor_name: String,
|
||||||
|
report_type: ReportType,
|
||||||
|
/// The inspection type and technology used.
|
||||||
|
inspection_type: InspectionType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&CombineTolerances> for ToolTolerances {
|
||||||
|
fn from(value: &CombineTolerances) -> Self {
|
||||||
|
[
|
||||||
|
(
|
||||||
|
DimensionClass::General,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.general
|
||||||
|
.to_tolerance(&value.haz_tolerances.general),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::Pitting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.pitting
|
||||||
|
.to_tolerance(&value.haz_tolerances.pitting),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::AxialGrooving,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.axial_grooving
|
||||||
|
.to_tolerance(&value.haz_tolerances.axial_grooving),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::CircumferentialGrooving,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.circumferential_grooving
|
||||||
|
.to_tolerance(&value.haz_tolerances.circumferential_grooving),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::Pinhole,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.pinhole
|
||||||
|
.to_tolerance(&value.haz_tolerances.pinhole),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::AxialSlotting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.axial_slotting
|
||||||
|
.to_tolerance(&value.haz_tolerances.axial_slotting),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::CircumferentialSlotting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.circumferential_slotting
|
||||||
|
.to_tolerance(&value.haz_tolerances.circumferential_slotting),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(dc, tol)| tol.map(|tol| (dc, tol)))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Tolerance> for Option<ToleranceAdjustment> {
|
||||||
|
fn from(value: &Tolerance) -> Self {
|
||||||
|
Some(ToleranceAdjustment {
|
||||||
|
depth: Option::<f64>::try_from(&value.depth).ok()??,
|
||||||
|
width: Length::new::<millimeter>(Option::<f64>::try_from(&value.width).ok()??),
|
||||||
|
length: Length::new::<millimeter>(Option::<f64>::try_from(&value.length).ok()??),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&InspectionReportDetails> for InlineInspection {
|
||||||
|
fn from(value: &InspectionReportDetails) -> Self {
|
||||||
|
Self {
|
||||||
|
date: value.date,
|
||||||
|
vendor_name: value.vendor_name.to_owned(),
|
||||||
|
report_type: value.report_type,
|
||||||
|
inspection_type: value.inspection_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FileDetails {
|
||||||
|
pub file_id: Uuid,
|
||||||
|
pub revision_id: Uuid,
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user