Skip to main content

Example: pool

This is an example of how you can model a pool using Connhex Resources.

Connhex Resources: pool as a resource.

Resources

This example shows a base resource (pool) and its related resources (pump, cleaner, heater, location, technician). You can either specify attributes (e.g. pool has a location) or relationships (e.g. pool includes many pumps).

Relationships

  • pool
    • has one location
    • has one technician
    • has many pumps
    • has many cleaners
    • has many heaters
  • pump
    • has one maintenance schedule
    • has one motor
    • has one filter
    • has one pressure gauge
    • has one ECU (Connhex connectable)
  • cleaner
    • has one maintenance schedule
    • has one hose
    • has one type
    • has one SKU
  • heater
    • has one maintenance schedule
    • has one BTU output rating
    • has one motor
    • has one tank
    • has one ECU (Connhex connectable)

One could go and relate as many resources as needed: for example, a motor could be a resource characterized by:

  • manufacturer
  • model
  • serial number
  • power
  • voltage
  • current
  • rpm
  • etc.

Attributes

Here are the attributes of the pool resource:

  • location
    • has one location (Connhex specific object: lat, lon, address)
  • technician
    • has one name
    • has one contact (email, phone, ...)
Alternative

You could also create a technician resource and relate it to the pool resource. For example, this would be useful if you wanted to create a pool management app.

JSON Schemas

Let's see an example of modeling the pool resource using JSON-Schema.

{
"schema": {
"$id": "https://connhex.com/example/pool.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"location": {
"type": "object",
"title": "location",
"properties": {
"text": {
"type": "string",
"title": "Formatted text address"
},
"lat": {
"type": "number",
"title": "Latitude"
},
"lng": {
"type": "number",
"title": "Longitude"
}
},
"connhex": {
"type": "location",
"autocomplete": true
}
},
"technician": {
"type": "object",
"title": "technician",
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"contact": {
"type": "object",
"title": "Contact",
"properties": {
"email": {
"type": "email",
"title": "Email"
},
"phone": {
"type": "string",
"title": "Phone"
}
}
}
}
},
"pumps": {
"type": "array",
"title": "pumps",
"items": {
"type": "string",
"connhex": {
"id": "pump"
}
}
},
"cleaners": {
"type": "array",
"title": "cleaners",
"items": {
"type": "string",
"connhex": {
"id": "cleaner"
}
}
},
"heaters": {
"type": "array",
"title": "heaters",
"items": {
"type": "string",
"connhex": {
"id": "heater"
}
}
}
}
}
}

A couple of things to note:

  • pumps, cleaners and heaters are arrays of strings because they contain the ids of the respective related resources. A GET request to /resources/pools would simply return the ids, but specifying {include:'pumps,cleaners,heaters'} would return an array containing complete objects.
  • location is a predefined Connhex object. The client-side Connhex Resources module will automatically integrate with the Google Maps API to provide an autocomplete feature for the address field. This is identified trough the connhex property:
"connhex": {
"type": "location",
"autocomplete": true
}
Location naming

You can name the location field whatever you like: for example, you could also call it address. The only requirement is that the connhex property is present exactly as shown above, with the type set to location.

  • you can easily identify between references and attributes by looking at the connhex property. All references have it set to:
"connhex": {
"id": ":referenceId"
}

Historicization

Let's now see how historicization can be useful in this case.

Suppose your app manages public swimming pools. It needs to track water filtration over time and the pumps provide all the measurements you need.

Without using Connhex Resources

The typical approach would be to associate filtration measurements directly to the pool. This is perfectly fine, but it has a couple of drawbacks:

  • what if the pump breaks down? You would need to associate another one and hope the measurements carried an identifier of the pump they were taken from: otherwise, you wouldn't be able to tell which measurements belong to which pump.
  • what if the pump is moved to a new location? You would need to implement a deassociate-reassociate logic.
  • what if there are measurements that are not related to the pool and need to persist? Take for example the total amount of water filtered, or the total hours of operation. These metrics shouldn't be associated to a pool, since the should persist for maintenance reasons even if the pump is moved to a new location.

Using Connhex Resources

A pump is related to a pool. As soon as this relationship is updated, the previous measurements are automatically historicized. This means it will be possible to identify what measurements belong to which pump irrespectively of the pump's message payload.

Everything related to maintenance is still associated to the pump resource, so that can be handled separately. You could also relate the pump back to the pool: this way, you would automatically track how many hours the pump has been used in a given pool.