Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type attributes (and recursive sub-attributes) all CamelCase; Add PollPeriodMs as an int attribute for HubitatTankSettingsGt #256

Open
jessicamillar opened this issue Feb 5, 2024 · 3 comments

Comments

@jessicamillar
Copy link
Collaborator

jessicamillar commented Feb 5, 2024

Part 1: Enforcing uniformity of CamelCase for attributes and sub-attributes of GridWorks Types.
(Also, enforcing that all GridWorks Types have a Version, which is a 3 digit numeric string. I've already added the Version for the new TankModule types so no change needed)

Note that this is only for the message in transmission as bytes. If you can find a way to have the python class objects have camel case attributes and tuple_to_type does the snake to camel translation, that would be great.

Relevant for:

  • in types/hubitat_tank_gt:

  • HubitatTankSettingsGt (in hubitat_tank_gt)

  • FibaroTempSensorSettingsGt

  • all classes in types/rest_poller_gt:

  • all classes in types/hubitat_poller_gt

Note that sub-attributes do NOT have to be types although they can be. So for example as it stands, FibaroTempSensorSettingsGt is NOT a GridWorks type as it does not have a TypeName or Version.

Part 2) Add poll period (PollPeriodMs or PollPeriodSeconds at your discretion) as an attribute of the FibaroTempSensorSettingsGt. This will make our lives easier in the field as we work on calibrating the 3 tank modules George will be installing Weds/Thurs.

Here is a before/after example (except with a single device instead of all 4). This is for a simulated tank module on my home computer with a fictitious hubitat.

{
  "ComponentAttributeClassId": "60ac199d-679a-49f7-9142-8ca3e6428a5f",
  "ComponentId": "8e92bcce-eceb-4d6c-b640-fe610b03b639",
  "DisplayName": "Tank Module <1>  SN i007",
  "Tank": {
    "devices": [
      {
        "analog_input_id": 1,
        "device_id": 1,
        "enabled": true,
        "exponent": 1,
        "fibaro_component_id": "7dd3921a-cd8a-4e54-aa6a-0659517a5810",
        "rest": 
          {"poll_period_seconds": 1, "session": {"base_url": null, "timeout": null}, "request": {"url": {"url": null, "url_args": {"scheme": "http", "user": null, "password": null, "host": "hubitat-rose.local", "port": null, "path": "", "query": [["access_token", "cfe301e9-84ce-4c95-a833-0177374e63f9"]], "fragment": "", "encoded": true}, "url_path_format": "/apps/api/{app_id}/devices/{device_id}/refresh", "url_path_args": {"app_id": 4, "device_id": 1}}, "method": "GET", "params": null, "data": null, "headers": null, "timeout": null, "ssl": null},  "errors": {"request": {"error_for_http_status": true, "raise_exception": false, "report": true}, "convert": {"error_for_http_status": true, "raise_exception": false, "report": true}}, "url": "http://hubitat-rose.local/apps/api/4/devices/1/refresh?access_token=cfe301e9-84ce-4c95-a833-0177374e63f9"},
        "stack_depth": 1,
        "tank_label": "i007 A1 (Thermistor #1 TANK TOP)",
        "telemetry_name_gt_enum_symbol": "c89d0ba1",
        "temp_unit_gt_enum_symbol": "ec14bd47"
      },

],
"hubitat_component_id": "67b46892-3ea7-4869-90d5-0ff39b84e603",
"sensor_supply_voltage": 23.7
},
"TypeName": "hubitat.tank.component.gt",
"Version": "000"

AFTER:
{
"ComponentAttributeClassId": "60ac199d-679a-49f7-9142-8ca3e6428a5f",
"ComponentId": "8e92bcce-eceb-4d6c-b640-fe610b03b639",
"DisplayName": "Tank Module <1> SN i007",
"Tank": {
"Devices": [
{
"PollPeriodMs": 1000,
"AnalogInputId": 1,
"DeviceId": 1,
"Enabled": true,
"Exponent": 1,
"FibaroComponentId": "7dd3921a-cd8a-4e54-aa6a-0659517a5810",
"Rest": null,
"StackDepth": 1,
"TankLabel": "i007 A1 (Thermistor #1 TANK TOP)",
"TelemetryNameGtEnumSymbol": "c89d0ba1",
"TempUnitGtEnumSymbol": "ec14bd47"
}
],
"HubitatComponentId": "67b46892-3ea7-4869-90d5-0ff39b84e603",
"SensorSupplyVoltage": 23.7
},
"TypeName": "hubitat.tank.component.gt",
"Version": "001"
}

@anschweitzer
Copy link
Collaborator

anschweitzer commented Feb 6, 2024

IIRC, Part 1 is already done.

The magic is:

    class Config:
        alias_generator = snake_to_camel
        allow_population_by_field_name = True

for example, see this. alias_generator produces field names for serialization. allow_population_by_field_name allows you to use the snake case to set the value in python.

I was very excited to discover all this.

@anschweitzer
Copy link
Collaborator

anschweitzer commented Feb 6, 2024

We should not need makers anymore. Instead:

  1. The types just implement from_data_class and to_data_class.

    @classmethod
    def from_data_class(cls, component: RESTPollerComponent) -> "RESTPollerComponentGt":
    def to_data_class(self) -> RESTPollerComponent:

  2. The TypeNames for the new types are added to default_decoders.py.

I was excited to discover that we can locate the functionality of the makers inside the type class.

@anschweitzer
Copy link
Collaborator

Just for reference, I thought the outcome of previous discussions (a year ago?) was TypeName is the version. If the type changes in a non backwards compatible way, you create a new type with a new type name. Most changes should be backwards / forwards compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants