Skip to content

Commit

Permalink
Merge branch 'master' into abel-modify-workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
trav3711 authored Feb 14, 2024
2 parents f650d9d + 79e7a27 commit ef3c9b0
Show file tree
Hide file tree
Showing 18 changed files with 147 additions and 59 deletions.
4 changes: 2 additions & 2 deletions ontology/docs/building_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ ENTITY-CODE:
represents this entity.
* **Code:** The human readable identifier for the entity. This should
be unique in document scope.
* **cloud_device_id:** the cloud device id from the cloud iot registry.
This field is mandatory when a translation exists.
* **cloud_device_id:** the numeric device id from cloud iot registry.
This field is mandatory when a translation exists. Must be a numeric string.
* **Connections:** Used to specify connections from other entities (sources)
pointing to this entity, with connection types. Entities are keys and cannot
be repeated. Values are one or more connections, specified as a single
Expand Down
27 changes: 27 additions & 0 deletions ontology/yaml/resources/HVAC/entity_types/ABSTRACT.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2700,6 +2700,33 @@ HP2ZC:
implements:
- CONTROL

HP3ZC:
guid: "bffa568b-5f69-4b08-8d8c-1377cd74d36e"
description: "Zone temp heat pump control with three compressors."
is_abstract: true
opt_uses:
- compressor_speed_percentage_command
- cooling_thermal_power_capacity
- discharge_air_temperature_sensor
- heating_thermal_power_capacity
- failed_discharge_air_temperature_alarm
- failed_zone_air_temperature_alarm
- high_zone_air_temperature_alarm
- low_zone_air_temperature_alarm
uses:
- compressor_run_command_1
- compressor_run_command_2
- compressor_run_command_3
- compressor_run_status_1
- compressor_run_status_2
- compressor_run_status_3
- reversing_valve_command
- zone_air_cooling_temperature_setpoint
- zone_air_heating_temperature_setpoint
- zone_air_temperature_sensor
implements:
- CONTROL


HWDC:
guid: "353bd503-92eb-4f72-8a82-ec1a91413f89"
Expand Down
13 changes: 12 additions & 1 deletion ontology/yaml/resources/HVAC/entity_types/AHU.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,17 @@ AHU_DFSS_DSP_ECONMD_HP2ZC:
- ECONMD
- HP2ZC

AHU_DFSS_DSP_ECONMD_HP3ZC:
guid: "f80e10d8-7889-489c-a195-48ee2be843fd"
description: "Single zone heat pump AHU with economizer mode control."
is_canonical: true
implements:
- AHU
- DFSS
- DSP
- ECONMD
- HP3ZC

AHU_DFSS_DSP_DX2ZC_ECONZ_EFSS:
guid: "ceb87a73-0847-4203-bf37-d6f57619f4fd"
description: "Single zone AHU."
Expand Down Expand Up @@ -2004,7 +2015,7 @@ AHU_BSPC_DX3SC_ECONM_EFSS_EFVSC_SARC_SFSS_SFVSC_SSPC:
implements:
- AHU
- BSPC
- DX2SC
- DX3SC
- ECONM
- EFSS
- EFVSC
Expand Down
9 changes: 9 additions & 0 deletions ontology/yaml/resources/HVAC/entity_types/CHWS.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@
### Canonical Types ###
########################

CHWS_RWTC_WDT:
guid: "c6b1443d-86c3-4012-8db3-698d133432da"
description: "Chilled water system with temperature control and monitoring."
is_canonical: true
implements:
- CHWS
- RWTC
- WDT

CHWS_WDT:
guid: "b8073a03-10fd-410e-a4d9-c8002181775b"
description: "Chilled water system with only basic delta-T monitoring."
Expand Down
10 changes: 10 additions & 0 deletions ontology/yaml/resources/HVAC/entity_types/FAN.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ FAN_SS_VSC:
- SS
- VSC

FAN_SS_VSC_ZSPC:
guid: "b9f968cc-211b-4b25-915d-525216aebc4e"
description: "Fan with start/stop status, open-loop speed control & zone static pressure control."
is_canonical: true
implements:
- FAN
- SS
- VSC
- ZSPC

FAN_SS_WDPM:
guid: "d12cbe88-243a-40a5-b624-3a2f355e7cfc"
description: "Fan with start/stop and differential pressure monitoring."
Expand Down
11 changes: 10 additions & 1 deletion ontology/yaml/resources/METERS/entity_types/ABSTRACT.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ PVCM:
guid: "97b8b9c1-21dd-4201-9424-c776e28de758"
description: "Phase-level current and voltage monitoring."
is_abstract: true
opt_uses:
- neutral_line_current_sensor
uses:
- phase1_line_current_sensor
- phase2_line_current_sensor
Expand All @@ -83,11 +85,18 @@ PWMRDM:
- generator_run_time_accumulator
- electricalgrid_run_time_accumulator

TPWM:
guid: "141dc3bf-85dd-4fce-9342-9a5462b3c274"
description: "Thermal power and thermal energy monitoring."
is_abstract: true
uses:
- thermal_energy_accumulator
- thermal_power_sensor

VCM:
guid: "dc4d2839-c00d-4935-bc67-013f7721535f"
description: "Current and voltage monitoring"
is_abstract: true
uses:
- current_sensor
- voltage_sensor

10 changes: 10 additions & 0 deletions ontology/yaml/resources/METERS/entity_types/GM.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ GM_PULSE:
uses:
- gas_flowrate_sensor
- gas_volume_accumulator

GM_TPWM:
guid: "223b81fb-9fcf-475b-a2f5-ad5d1364454c"
description: "Gas meter with thermal power and thermal energy monitoring."
is_canonical: true
implements:
- GM
- TPWM
opt_uses:
- gas_temperature_sensor
30 changes: 21 additions & 9 deletions tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ $ ./tools/docker_run.sh abel
2. Follow setup instructions for the [GUID Generator](./guid_generator).
3. Run `sudo python setup.py` for this directory.

##### Authentication

To Authenticate against GCP PubSub for telemetry validation you must install
and initialize the [gcloud CLI](https://cloud.google.com/sdk/docs/install).
Then, use the
[gcloud auth application-default-login](https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login)
command to create credentials for default logins.

### Toolkit CLI Workflow

Run `python toolkit.py` and provide the following arguments:
Expand All @@ -87,17 +95,18 @@ Run `python toolkit.py` and provide the following arguments:

4. `--validate` or `-v`: Runs instance validator to validate the building configuration file.

5. [Optional] Telemetry Validation: After a building configuration's entity types are validated, validation must also be run on the telemetry payload using the following parameters. **NOTE:** The OAuth credential (`-c`) and subscription (`-s`) are provided by the Google team. Please reach out to your IoT TPM for guidance.
5. [Optional] Telemetry Validation: After a building configuration's entity
types are validated, validation must also be run on the telemetry payload
using the following parameters. **NOTE:** The subscription (`-s`) is
provided by the Google team. Please reach out to your IoT TPM for guidance.

* `--subscription` or `-s`: The fully-qualified path to a Google Cloud Pubsub subscription (e.g., `projects/google.com:your-project/subscriptions/your-subscription`).

* `--credential` or `-c`: An absolute or relative path to an OAuth client credential JSON file.

* `--timeout` or `-t` **[Optional]**: The timeout duration in seconds for the telemetry validation test. The default value is 600 seconds, or 10 minutes. If this time limit is exceeded before the validator receives a test pubsub message for each of the entities configured in the given instance config file, the test will fail with an error and report the entities that were not heard from.

7. `--report-directory` or `-d` **[Optional]**: Writes instance validation (instance_validation_report.txt) and telemetry validation (telemetry_validation_report.json) reports to the specified `report-directory`. By default, writes instance validation output to the console and telemetry validation output to the current working directory.
6`--report-directory` or `-d` **[Optional]**: Writes instance validation(instance_validation_report.txt) and telemetry validation (telemetry_validation_report.json) reports to the specified `report-directory`. By default, writes instance validation output to the console and telemetry validation output to the current working directory.

8. `--udmi` **[Optional]**: Validates entity metadata as [UDMI](https://github.com/faucetsdn/udmi/). Flag is set to `True` by default; change this parameter to `--udmi=False` when not validating against UDMI.
7`--udmi` **[Optional]**: Validates entity metadata as [UDMI](https://github.com/faucetsdn/udmi/). Flag is set to `True` by default; change this parameter to `--udmi=False` when not validating against UDMI.

For example, the following input

Expand All @@ -107,10 +116,13 @@ python toolkit.py -i //path/to/building/configuration/file.yaml -g -v -s subscri

results in these actions:
1. Ingests a building configuration file.
2. Generates guids for every entity instance in the buiding configuration file and re-writes building configuration file in the new format.
4. Validates the building configuration file with the instance validator.
5. Validates the telemetry payloads for each reporting entity in the building configuration file.
6. Writes instance and telemetry validation results to the report directory as `//path/to/report-directory/instance_validation_report.txt` and `//path/to/report-directory/telemetry_validation_report.json`.
2. Generates guids for every entity instance in the building configuration
file and re-writes building configuration file in the new format.
3. Validates the building configuration file with the instance validator.
4. Validates the telemetry payloads for each reporting entity in the building
configuration file.
5. Writes instance and telemetry validation results to the report directory as
`//path/to/report-directory/instance_validation_report.txt` and `//path/to/report-directory/telemetry_validation_report.json`.

**NOTE:** The new building configuration format requires that entities are keyed by Version 4 UUIDs (referred to as guids) instead of the code. To convert from old format to the new format, run your building configuration file(.yaml) through the [guid generator](https://github.com/google/digitalbuildings/tree/master/tools/guid_generator).

Expand Down
4 changes: 2 additions & 2 deletions tools/abel/model/entity_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def __init__(

def __eq__(self, other):
if not isinstance(other, MissingField):
raise TypeError(f'{str(other)} must be a MissingField instance')
return False
standard_field_name_eq = self.std_field_name == other.std_field_name
entity_guid_eq = self.entity_guid == other.entity_guid
reporting_field_eq = (
Expand Down Expand Up @@ -396,7 +396,7 @@ def __init__(

def __eq__(self, other: ...) -> bool:
if not isinstance(other, DimensionalValueField):
raise TypeError(f'{str(other)} must be an DimensionalValueField instance')
return False
standard_field_name_eq = self.std_field_name == other.std_field_name
raw_field_name_eq = self.raw_field_name == other.raw_field_name
entity_guid_eq = self.entity_guid == other.entity_guid
Expand Down
6 changes: 3 additions & 3 deletions tools/abel/model/from_spreadsheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ def LoadFieldsFromSpreadsheet(
entity_field_entries: List[Dict[str, str]],
guid_to_entity_map: GuidToEntityMap,
) -> List[FieldTranslation]:
"""Loads list of entity field maps into FieldTranslation instances.
"""Loads list of entity fields from a spreadsheet into FieldTranslation
instances.
Once the entity field mapping is loaded into an FieldTranslation instance,
it
is then added to the ABEL internal model.
it is then added to the ABEL internal model.
Args:
entity_field_entries: A list of python dictionaries mapping entity field
Expand Down
22 changes: 11 additions & 11 deletions tools/abel/model/model_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,17 @@ def Build(self) -> ...:
Returns:
built Model instance
"""
# First add states to fields
for field in self.fields:
# For each state in the model
if isinstance(field, MultistateValueField):
for state in self.states:
# Create edges between states and their corresponding Multi-state
# value field in stances.
if state.reporting_entity_guid == field.reporting_entity_guid:
if state.std_field_name in (field.reporting_entity_field_name,
field.std_field_name):
field.AddState(state)
self.site.entities = self.entities
# For each entity, Add connections where entity is the source
for guid in self.site.entities:
Expand All @@ -210,17 +221,6 @@ def Build(self) -> ...:
entity.AddConnection(connection)
# For each field in the model
for field in self.fields:
# For each state in the model
for state in self.states:
# Create edges between states and their corresponding Multi-state
# value field in stances.
if uuid.UUID(state.reporting_entity_guid) == guid:
if state.std_field_name in (
field.reporting_entity_field_name,
field.std_field_name,
):
if isinstance(field, MultistateValueField):
field.AddState(state)
# Link field to entity if entity is virtual
if isinstance(entity, VirtualEntity):
if field.entity_guid == guid:
Expand Down
3 changes: 1 addition & 2 deletions tools/abel/tests/entity_field_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ def testMissingFieldEqualityRaisesTypeError(self):
test_missing_field = MissingField.FromDict(TEST_MISSING_FIELD_DICT)

# pylint: disable=unnecessary-dunder-call
with self.assertRaises(TypeError):
test_missing_field.__eq__('not a field')
self.assertFalse(test_missing_field.__eq__('not a field'))

@mock.patch.object(GuidToEntityMap, 'GetEntityCodeByGuid')
def testMissingFieldGetSpreadsheetRowMapping(self, test_get_code):
Expand Down
8 changes: 4 additions & 4 deletions tools/abel/validators/spreadsheet_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,16 +376,16 @@ def _ValidateConnections(
validation_errors.append(
ConnectionDependencyError(
row=row_number,
missing_code=connection.get(TARGET_ENTITY_CODE),
present_code=connection.get(SOURCE_ENTITY_CODE),
missing_code=connection.get(SOURCE_ENTITY_CODE),
present_code=connection.get(TARGET_ENTITY_CODE),
)
)
if connection[TARGET_ENTITY_CODE] not in codes:
validation_errors.append(
ConnectionDependencyError(
row=row_number,
missing_code=connection[SOURCE_ENTITY_CODE],
present_code=connection[TARGET_ENTITY_CODE],
missing_code=connection.get(TARGET_ENTITY_CODE),
present_code=connection.get(SOURCE_ENTITY_CODE),
)
)
return validation_errors
Expand Down
17 changes: 14 additions & 3 deletions tools/validators/instance_validator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,22 @@ Navigate to `digitalbuildings/tools/validators/instance_validator` and run `pyth

### Telemetry Validation

The validator supports a telemetry validation mode. When this mode is enabled, the validator will listen on a provided pubsub subscription for telemetry messages, and validate the message contents against the instance configuration. **It is recommended that you first use the instance validator with telemetry validation mode disabled, and then enable it after that passes.**
#### Authentication

To Authenticate against GCP PubSub for telemetry validation you must install
and initialize the [gcloud CLI](https://cloud.google.com/sdk/docs/install).
Then, use the
[gcloud auth application-default-login](https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login)
command to create credentials for default logins.

If you would like to use the telemetry validation mode, you must provide the `--subscription` parameter and the `--credential` parameter. **NOTE:** The OAuth credential and subscription are provided by the Google team. Please reach out to your IoT TPM for guidance. If a GCP Oauth client credential is not provided, then application default credentials will be used to authenticate against Google APIs. Running telemetry validation will also output a machine-readable log of the validation performed on a set of devices. This log will be output as `telemetry_validation_log.json` in the current working directory, unless otherwise specefied using the `--report_directory` parameter.
#### Validation

The validator supports a telemetry validation mode. When this mode is enabled, the validator will listen on a provided pubsub subscription for telemetry messages, and validate the message contents against the instance configuration. **It is recommended that you first use the instance validator with telemetry validation mode disabled, and then enable it after that passes.**

1. `--credential` or `-c`: An absolute or relative path to an OAuth client credential JSON file.
If you would like to use the telemetry validation mode, you must provide the
`--subscription` parameter. **NOTE:** The subscription is provided by the
Google team. Please reach out to your IoT TPM for guidance. Running
telemetry validation will also output a machine-readable log of the validation performed on a set of devices. This log will be output as `telemetry_validation_log.json` in the current working directory, unless otherwise specefied using the `--report_directory` parameter.

2. `--subscription` or `-s`: The fully-qualified path to a Google Cloud Pubsub subscription (e.g., `projects/google.com:your-project/subscriptions/your-subscription`).

Expand Down
9 changes: 0 additions & 9 deletions tools/validators/instance_validator/instance_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,6 @@ def _ParseArgs() -> argparse.ArgumentParser:
help='Pubsub subscription for telemetry to validate',
metavar='subscription')

parser.add_argument(
'-c',
'--credential',
dest='gcp_credential',
required=False,
help='gcp credential used to authenticate against pubsub api',
metavar='gcp credential')

parser.add_argument(
'-t',
'--timeout',
Expand Down Expand Up @@ -114,7 +106,6 @@ def _ParseArgs() -> argparse.ArgumentParser:
filenames=args.filenames,
modified_types_filepath=args.modified_types_filepath,
subscription=args.subscription,
gcp_credential_path=args.gcp_credential,
report_directory=args.report_directory,
timeout=int(args.timeout),
is_udmi=is_udmi,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
DMP_EDM-17-GUID:
type: HVAC/DMP_EDM
code: DMP_EDM-17
cloud_device_id: "1234567890123456"
cloud_device_id: "123456"
translation:
exhaust_air_damper_command:
present_value: "points.exhaust_air_damper_command.present_value"
Expand Down
Loading

0 comments on commit ef3c9b0

Please sign in to comment.