diff --git a/src/couchdb/.allowed_datafiles b/src/couchdb/.allowed_datafiles index 0b0d865c..1654f837 100644 --- a/src/couchdb/.allowed_datafiles +++ b/src/couchdb/.allowed_datafiles @@ -3,7 +3,11 @@ src/couchdb/collections.json src/couchdb/scenarios_data/default/manifest.json src/couchdb/scenarios_data/scenario_1/manifest.json src/couchdb/scenarios_data/scenario_2/manifest.json +src/couchdb/scenarios_data/shared/catalog/assets.csv +src/couchdb/scenarios_data/shared/catalog/failure_modes.csv +src/couchdb/scenarios_data/shared/catalog/sensors.csv src/couchdb/scenarios_data/shared/failure_code/failure_code_sample.csv +src/couchdb/scenarios_data/shared/fmea/failure_modes_sample.json src/couchdb/scenarios_data/shared/iot/chiller_6.json src/couchdb/scenarios_data/shared/iot/hydraulic_pump_1.json src/couchdb/scenarios_data/shared/iot/metro_pump_1.json diff --git a/src/couchdb/collections.json b/src/couchdb/collections.json index e99f367d..db67d67f 100644 --- a/src/couchdb/collections.json +++ b/src/couchdb/collections.json @@ -24,6 +24,39 @@ ] ] }, + "catalog": { + "format": "csv", + "indexes": [ + [ + "category" + ], + [ + "asset" + ], + [ + "failure_mode" + ], + [ + "sensor" + ] + ] + }, + "failure_mode": { + "format": "json", + "primary_key": [ + "asset_class" + ], + "id_prefix": "fm", + "indexes": [ + [ + "doctype", + "asset_class" + ], + [ + "asset_class" + ] + ] + }, "iot": { "format": "json", "primary_key": [ @@ -111,4 +144,4 @@ "id_prefix": "fc", "indexes": [] } -} \ No newline at end of file +} diff --git a/src/couchdb/scenarios_data/default/manifest.json b/src/couchdb/scenarios_data/default/manifest.json index 3f227ba8..89d7f5ca 100644 --- a/src/couchdb/scenarios_data/default/manifest.json +++ b/src/couchdb/scenarios_data/default/manifest.json @@ -7,5 +7,11 @@ ], "asset": "shared/iot/asset_profile_sample.json", "vibration": "shared/iot/motor_01.json", - "failurecode": "shared/failure_code/failure_code_sample.csv" + "catalog": [ + "shared/catalog/assets.csv", + "shared/catalog/failure_modes.csv", + "shared/catalog/sensors.csv" + ], + "failure_mode": "shared/fmea/failure_modes_sample.json", + "failure_code": "shared/failure_code/failure_code_sample.csv" } diff --git a/src/couchdb/scenarios_data/shared/catalog/assets.csv b/src/couchdb/scenarios_data/shared/catalog/assets.csv new file mode 100644 index 00000000..d8817b40 --- /dev/null +++ b/src/couchdb/scenarios_data/shared/catalog/assets.csv @@ -0,0 +1,2 @@ +category,category_description,asset,description +static equipment,Equipment with no primary moving parts used to contain or separate process media.,Pressure vessel,Stores liquids or gases under controlled pressure for batch or continuous operations. diff --git a/src/couchdb/scenarios_data/shared/catalog/failure_modes.csv b/src/couchdb/scenarios_data/shared/catalog/failure_modes.csv new file mode 100644 index 00000000..d9585a31 --- /dev/null +++ b/src/couchdb/scenarios_data/shared/catalog/failure_modes.csv @@ -0,0 +1,2 @@ +category,failure_mode,description +static equipment,Internal coating degradation,"Protective lining loses adhesion or coverage, exposing the base material to corrosion or product contamination." diff --git a/src/couchdb/scenarios_data/shared/catalog/sensors.csv b/src/couchdb/scenarios_data/shared/catalog/sensors.csv new file mode 100644 index 00000000..f81539a1 --- /dev/null +++ b/src/couchdb/scenarios_data/shared/catalog/sensors.csv @@ -0,0 +1,2 @@ +sensor,description +differential pressure,"Sensor used to measure pressure difference across filters, exchangers, valves, or flow restrictions." diff --git a/src/couchdb/scenarios_data/shared/fmea/failure_modes_sample.json b/src/couchdb/scenarios_data/shared/fmea/failure_modes_sample.json new file mode 100644 index 00000000..1bae9df9 --- /dev/null +++ b/src/couchdb/scenarios_data/shared/fmea/failure_modes_sample.json @@ -0,0 +1,13 @@ +[ + { + "_id": "fm:sample-pump", + "doctype": "failure_mode", + "asset_class": "sample pump", + "failure_modes": [ + "seal leakage", + "impeller wear" + ], + "source": "synthetic sample", + "exhaustive": false + } +] diff --git a/src/couchdb/tests/test_loader.py b/src/couchdb/tests/test_loader.py new file mode 100644 index 00000000..9b3780d9 --- /dev/null +++ b/src/couchdb/tests/test_loader.py @@ -0,0 +1,57 @@ +import json +from pathlib import Path + +from couchdb import loader + + +def test_failure_code_collection_parses_shared_csv() -> None: + cfg = loader.collection_config("failure_code") + base_dir = Path(loader.__file__).parent / "scenarios_data" / "default" + + docs = loader._collect_docs( + "failure_code", + "shared/failure_code/failure_code_sample.csv", + cfg, + base_dir=str(base_dir), + ) + + assert cfg["format"] == "csv" + assert len(docs) == 10 + assert docs[0]["code"] == "FC001" + assert docs[4]["description"] == "excessive vibration, shaking, or instability" + + +def test_default_manifest_uses_failure_code_collection_key() -> None: + manifest_path = ( + Path(loader.__file__).parent / "scenarios_data" / "default" / "manifest.json" + ) + + with manifest_path.open() as f: + manifest = json.load(f) + + assert "failure_code" in manifest + assert "failurecode" not in manifest + assert manifest["catalog"] == [ + "shared/catalog/assets.csv", + "shared/catalog/failure_modes.csv", + "shared/catalog/sensors.csv", + ] + assert manifest["failure_mode"] == "shared/fmea/failure_modes_sample.json" + + +def test_failure_mode_collection_parses_shared_json() -> None: + cfg = loader.collection_config("failure_mode") + base_dir = Path(loader.__file__).parent / "scenarios_data" / "default" + + docs = loader._collect_docs( + "failure_mode", + "shared/fmea/failure_modes_sample.json", + cfg, + base_dir=str(base_dir), + ) + + assert cfg["format"] == "json" + assert cfg["primary_key"] == ["asset_class"] + assert len(docs) == 1 + assert docs[0]["asset_class"] == "sample pump" + assert docs[0]["failure_modes"] == ["seal leakage", "impeller wear"]