---
# System prepended metadata

title: Hazards notes

---

# Hazards notes


## Sifis 

- Actors:
    - Devices
    - Users
    - Supervisors

- Interactions
    - The user wants to interact with a device
    - The interactions go through supervisors
    - The supervisors may allow or disallow the interaction

## Hazards and risks

- The interaction with a device may have certain hazards bound to it.
- The hazard is purely possible
- The amount of risk is modeled through a level/score

## Web of Things devices

The thing description can be enriched with a specific ontology.

We have multiple levels of precision/refinement
- We can simply bind the hazard to an interaction affordance: if you interact your behaviour brings a risk to be accounted, no matter other specifics. (e.g. any change to the configuration of the window may hurt somebody in the way)

- We can restrict the hazard to a specific subset of the values the interaction brings (e.g. setting a brightness property over 80 might overheat the lamp), we express it using jsonpath

- We may want to express that the hazard is even more context-dependent (e.g. setting the brightness is a fire hazard only if another property is set).

### Evaluation

The supervisor consumes the Thing Description and is able to use the interaction information in two ways:
- Use the jsonpath expression and apply it to the input information to apply policy to the request
- Use the Form to actually interact with the Thing and forward the user request if it is deemed acceptable

```mermaid
sequenceDiagram
    Supervisor-wot->>Thing: GET .well-known/wot
    Thing-->>Supervisor-wot: ThingDescription.json
    Supervisor-wot->>Supervisor-sifis: Lamp(id1, ...)
    User->>Supervisor-sifis: Find Lamps
    Supervisor-sifis-->>User: "lamps": [id1, id2, ..]
    User->>Supervisor-sifis: turnOnLamp(id1)
    Supervisor-sifis->>Supervisor-ingest: id1.property.on = true;
    Supervisor-ingest->>Supervisor-policy: jsonpath($[@ == true], "true") -> HazardEnergyConsumption;
    Supervisor-policy->>Supervisor-wot: isOk(id1.property.on = true, HazardEnergyConsumption)
    Supervisor-wot->>Thing: PUT properties/on, true
```



### Open questions

- jsonpath expressions do not work with scalar values
  Solutions:
  - wrap the scalar value in an array on evaluation and imply that the jsonpath is always `$[condition]` if the expression doesn't start with `$`.
  - we could consider an alternative to JSON Path. This is not the best tool to detect if an expression matches or not inside a JSON, because it is made to return a group of matching elements instead of a boolean value. This is not ideal, especially considering the _truthyness_ and _falsyness_ nature of Javascript values:
    - An empty array is _truthy_
    - An empty string is _falsy_
    - An empty object is _truthy_
    - A `0` number is _falsy_
    - The double equality operator (`0 == false` is true, `0 === false` is false)
    There is not an easy answer, because I (Edoardo Morandi) am not aware of a good alternative to JSON Path. Surely, we can use JSON Path, but we need to keep in mind that we are creating an evaluation layer above this query language and we would need to carefully write a specification for the transformation from the result of the JSON Path query to a boolean value.
- ~~The interaction information comes from two sources in TD-1.1: inbound (e.g. a json in the PUT http body) and as part of the `uriVariables`~~
  ~~Solutions:~~
  - ~~Require that `uriVariables` never change the hazard of the interaction~~
  - ~~Add more rules so the uriVariables extracted are added to the data to evaluate as a `.uriVariables` array and require the jsonpath expression to use `.body` to access the body of the message~~
- The interaction information can potentially depend on many factors:
  - The state of the current properties -- all of them, not only a property that is being changed
  - The state of the actions
    A running action could impact the hazards of changing properties, and it is also necessary to evaluate the hazards after each running action ends and each pending action runs, in a loop until all the actions are handled.
    - This thought highlights the model for action execution is unspecified, leading to the fact that it is not possible for an external supervisor to really predict the levels of hazard the thing is going to traverse before all the action have finished.
  - The properties passed in the body
  - The `uriVariables`
    Unlike what has been written beforehand, `uriVariables` cannot be just assumed to never change the hazard unless they are not used at all. If an `uriVariable` is used in order to change the behavior of a property-set or an action, which is a potential change in the hazard model of the taken behavior. Assuming that "an `uriVariable` cannot change the hazard level" would only lead to edge cases in which the hazard level is changing in the real world but it is not representable by our model, completely disrupting the safety of the system.
    
  All the elements taken into account MUST be accessible through the JSON Path in order to correctly express the level of hazard.
  
  The completeness of the information provided would automatically make the _state transition_ model useless for the evaluation of the hazard. In fact, the hazard of the transition if intrinsecally defined by the property/action change of the Thing, which is able to correctly express the hazard types and level without any state machine model built by the supervisor (which still needs to evaluate if the operation is allowed or not). Therefore, the ability of expressing **all** the information required to evaluate the hazards through the JSON Path (or an alternative query language) would also remove the need to extend the query language itself in order to express a _transition_.
  
  Moreover, we should consider if exposing a `self` element could be useful for the model. In details:
  - setting a property should expose the property itself under `self`;
  - modifying an action (invoking, cancelling) should expose the pending and running actions of the same kind.
  I (Edoardo Morandi) am not sure about the usefulness of this feature, I would like this to being discussed thoughtfully in order to find real case in which it would be very useful or, on the contrary, a large set of real examples in which this kind of feature is never needed.
  
- context-dependent hazard evaluation would require to access more information e.g. expressing that `.properties.on == true && .properties.brightness > 80` is a fire hazard
  - Note from Edoardo Morandi: the issue expressed in the previous point already includes this.

- We *really* need a validator for the _hazard transitions_ that can be implemented outside the supervisor.

  Let's say we have a thing with two properties, `A` and `B`. `A` is integral value between 1 and 10, `B` is a boolean. Let's define the following abstract hazards for the setting of the properties:
  - `A`
    - Hazard H1 if new `A > 5` and current `B` is true
    - Hazard H2 if new `A < 5` and current `B` is true
  - `B`
    - Hazard H1 if new `B` is true and current `A > 5`
    - Hazard H2 if new `B` is true and current `A < 5`
    
  This schema hides a design issue: what's the hazard level when the new `A` is 5?
  
  In this example the issue can be considered "simple to spot", but it is not in general. In details, with just a few properties (even without taking into account the state of possible actions) there is a combinatorial explosion of possible states, and it is extremely plausible to forget some of them. In the best case there is a state of the thing that consists of an hazard and it cannot be evaluated by the supervisor (which consider the transition valid even if it should not), in the worst case the Thing could be stuck in a state from which it cannot escape because all the possible transitions would consist of an unallowed hazard (i.e.: the state led to an overheating, the evaluation of the current temperature would still evaluate to a fire hazard even if the thing is turned off). Let's make a plausible example:
  - We have a lamp with 3 additional switches
  - Switch `A` activates an _extra brightness_ mode
  - Switch `B` activates the usage of higher frequency photons
  - Switch `C` activates a "color fade" mode, for which the color of the lamp is continuously changed in a loop
  - If none of these modes are activated, the lamp can reach 20C° at max
  - If one of these modes is activated, the lamp can reach 40C°
  - If two of these modes are activated at the same time, the lamp can reach 90C°
  - If all three of the these modes are activated, the lamp can reach 180C°
  
Keeping in mind that, using single properties, it is possible to change only the state of one of the properties at a time, we have the following schema:
```mermaid
stateDiagram-v2
  state 20C° {
    !A,!B,!C
  }
  
  state 40C° {
    A,!B,!C
    !A,B,!C
    !A,!B,C
  }
  
  state 90C° {
    A,B,!C
    A,!B,C
    !A,B,C
  }
  
  state 180C° {
    A,B,C
  }
  
  !A,!B,!C --> A,!B,!C 
  !A,!B,!C --> !A,B,!C 
  !A,!B,!C --> !A,!B,C 
  
  A,!B,!C --> !A,!B,!C 
  !A,B,!C --> !A,!B,!C 
  !A,!B,C --> !A,!B,!C 
  
  A,!B,!C --> A,B,!C 
  A,!B,!C --> A,!B,C 
  !A,B,!C --> A,B,!C 
  !A,B,!C --> !A,B,C 
  !A,!B,C --> A,!B,C 
  !A,!B,C --> !A,B,C 
  
  A,B,!C --> A,!B,!C
  A,!B,C --> A,!B,!C
  A,B,!C --> !A,B,!C
  !A,B,C --> !A,B,!C
  A,!B,C --> !A,!B,C
  !A,B,C --> !A,!B,C
  
  A,B,!C --> A,B,C
  A,!B,C --> A,B,C
  !A,B,C --> A,B,C
  
  A,B,C --> A,B,!C
  A,B,C --> A,!B,C
  A,B,C --> !A,B,C
```

Even if there are just 4 possible "hazard statuses" in this model, and even if there are only three switches (which, just by being switches are one of the simplest model possible), there are a non trivial amount of possibile transitions. And it is necessary to keep in mind that the current model to represent the level of hazard is relative to the affordance of each property, specifically depending on the the new value[^1] and the values of the other properties.

[^1]: in theory it could also depend on the current value, but it is almost useless with boolean value, and it would just complicate the schema with self loops.

Even considering a single property `A`, in terms of hazards it is necessary to consider 4 hazards depending on the condition of the new value and the possible combinations of the other properties. In practice we would need something like this (only the parts related to the hazards are shown):
```jsonld
{
    "properties": {
        "A": {
            "hazards": [
                {
                    "jsonPath": "[?(@.value == false && @.properties.B == false && @.properties.C == false)]",
                    "riskLevel": 1,
                    "@id": "sho:FireHazard",
                    "description": "The execution may cause fire",
                    "name": "Fire hazard",
                    "category": "sho:Safety",
                },
                {
                    "jsonPath": "[?((@.value == true && @.properties.B == false && @.properties.C == false) || (@.value == false && @.properties.B == true && @.properties.C == false) || (@.value == false && @.properties.B == false && @.properties.C == true))]",
                    "riskLevel": 3,
                    "@id": "sho:FireHazard",
                    "description": "The execution may cause fire",
                    "name": "Fire hazard",
                    "category": "sho:Safety",
                },
                {
                    "jsonPath": "[?((@.value == true && @.properties.B == true && @.properties.C == false) || (@.value == true && @.properties.B == false && @.properties.C == true) || (@.value == false && @.properties.B == true && @.properties.C == true))]",
                    "riskLevel": 5,
                    "@id": "sho:FireHazard",
                    "description": "The execution may cause fire",
                    "name": "Fire hazard",
                    "category": "sho:Safety",
                },
                {
                    "jsonPath": "[?(@.value == true && @.properties.B == true && @.properties.C == true)]",
                    "riskLevel": 8,
                    "@id": "sho:FireHazard",
                    "description": "The execution may cause fire",
                    "name": "Fire hazard",
                    "category": "sho:Safety",
                }
            }
        }
    }
}
```
This situation has a lot of downsides:
- it is extremely verbose and redundant, because it is necessary to correctly express the type of hazard multiple times for each property and for all of them;
- the `jsonPath` expressions are very verbose and error prone (keep in mind that this example represents a simple situation);
- the same pattern must be repeated for all the other properties, leading to copy-pasting the implementation and the possibilities of more errors;
- there is no guarantee that the expressed conditions are exaustive.

The last issue does not have an easy solution, but it is possible that fixing the other three with a more expressful model would also bring to creating an exaustiveness checker. Anyway, there are two possibile situations when the checks are not exaustive:
- the supervisor does not allow to switch into that underspecified state; this would limit the usability of the thing, making it partially useless;
- the supervisor allows to switch into the underspecified state, evaluating it as not risky at all; this could potentially break the safety of the system, cause severe harm and/or damage and, last but not least, lead the thing into a state from which it _cannot escape_ because of the hazard level of all the possible transitions.

### Alternative proposal

I (Edoardo Morandi) have a proposal for an alternative implementation for the definitions of the hazards. The main idea is to correlate a hazard (question: always one? Possibly more than one?) to a set of states. If any transition leads to one of these states, then the hazard is applied.

Here a brief representation of the idea using an extended Thing Description:
```jsonld
{
  "properties": {
    "A": { /* ... */ },
    "B": { /* ... */ },
    "C": { /* ... */ }
  },
  "hazards": [
    {
      "risk": {
        "riskLevel": 1,
        "@id": "sho:FireHazard",
        "description": "The execution may cause fire",
        "name": "Fire hazard",
        "category": "sho:Safety",
      },
      "conditions": [
        [
          {
            "jsonPath": "$.properties.A",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": false,
          },
        ] 
      ],
    },
    {
      "risk": {
        "riskLevel": 3,
        "@id": "sho:FireHazard",
        "description": "The execution may cause fire",
        "name": "Fire hazard",
        "category": "sho:Safety",
      },
      "conditions": [
        [
          {
            "jsonPath": "$.properties.A",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": false,
          },
        ], 
        [
          {
            "jsonPath": "$.properties.A",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": false,
          },
        ], 
        [
          {
            "jsonPath": "$.properties.A",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": true,
          },
        ] 
      ],
    },
    {
      "risk": {
        "riskLevel": 5,
        "@id": "sho:FireHazard",
        "description": "The execution may cause fire",
        "name": "Fire hazard",
        "category": "sho:Safety",
      },
      "conditions": [
        [
          {
            "jsonPath": "$.properties.A",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": false,
          },
        ], 
        [
          {
            "jsonPath": "$.properties.A",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": true,
          },
        ], 
        [
          {
            "jsonPath": "$.properties.A",
            "condition": false,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": true,
          },
        ] 
      ],
    },
    {
      "risk": {
        "riskLevel": 8,
        "@id": "sho:FireHazard",
        "description": "The execution may cause fire",
        "name": "Fire hazard",
        "category": "sho:Safety",
      },
      "conditions": [
        [
          {
            "jsonPath": "$.properties.A",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.B",
            "condition": true,
          },
          {
            "jsonPath": "$.properties.C",
            "condition": true,
          },
        ]
      ]
    }
  ]
}
```

This kind of approach changes the evaluation process quite a lot, hopefully making it simpler. But let's dig deeper into some details.

#### The condition object

A single condition object is made of the fields `jsonPath` and `condition`. The former represents the _field_ in the _virtual json_ of the Thing, the latter represents the _condition_ that must match in order to contribute to the final boolean expression.

`jsonPath` is now used as expected, only to retrieve the field instead of being used to evaluate the condition. This approach eliminates some limitations we encountered with the previous model and should also avoid some edge cases.

The `condition` field can be used in two different ways. The first way (the _short_ version) it is the one showed in the example, for which the value of the field is checked against the value of the variable referenced by `jsonPath` using strict equality. The other way of using `condition` (the _long_ version) is like in the following example:
```jsonld
{
  "jsonPath": /* ... */,
  "condition": {
    "value": 50,
    "op": "lt"
  }
}
```
More formally, `condition` can be also an object containing the fields `value` and `op`. The first is the value that is being compared, the second is the _comparison operation_. Notice that, to avoid ambiguities, the _short_ version can only be used with integral types. Therefore it is possible to use the following for more complex situations:
```jsonld
{
  "jsonPath": /* ... */,
  "condition": {
    "value": {
      "field1": "hello",
      "field2": 42
    },
    "op": "eq"
  }
}
```

#### The conditions field

The `conditions` field inside each object of `hazards` is an array of arrays of _condition objects_. In logic terms, the outer array expresses an `OR` correlations between the inner arrays, which in turn express an `AND` correlation between different _condition objects_. For instance, take the following example:
```jsonld
{
  "risk": /* ... */,
  "conditions": [
    [
      {
        /* Condition A */
      },
      {
        /* Condition B */
      },
    ],
    [
      {
        /* Condition C */
      }
    ],
    [
      {
        /* Condition D */
      },
      {
        /* Condition E */
      },
      {
        /* Condition F */
      }
    ]
  ]
}
```
This hazard is evaluated as _active_ iif `(A ∧ B) ∨ C ∨ (D ∧ E ∧ F)`

#### Alternative risk representation

One of the possibile criticisms of this entire representation consists of the overhead of the risk, that needs to be specified multiple times in order to specify different level of the same risk for different conditions.

A possible solution is to split the constant part of the risk from the mutable part and using the `@id` as unique identifier. Here a JSON-LD showing the idea:
```jsonld
{
  "properties": {
    "A": { /* ... */ },
    "B": { /* ... */ },
    "C": { /* ... */ }
  },
  "risks": [
    {
      "@id": "sho:FireHazard",
      "description": "The execution may cause fire",
      "name": "Fire hazard",
      "category": "sho:Safety",
    } 
  ],
  "hazards": [
    {
      "risk": {
        "level": 1,
        "@id": "sho:FireHazard",
      },
      "conditions": [ /* ... */ ],
    },
    {
      "risk": {
        "level": 3,
        "@id": "sho:FireHazard",
      },
      "conditions": [ /* ... */ ],
    },
    {
      "risk": {
        "level": 5,
        "@id": "sho:FireHazard",
      },
      "conditions": [ /* ... */ ],
    },
    {
      "risk": {
        "level": 8,
        "@id": "sho:FireHazard"
      },
      "conditions": [ /* ... */]
    }
  ]
}
```

This alternative has the advantage of avoiding unwanted inconsistencies between the different occurrences of the same risk, but on the other hand it does not allow _per-condition_ customizations.

#### Labels instead of JSON Path

Another possible variant is to use custom labels instead of JSON Path in order to refer to parts of the JSON data. Something like this:
```jsonld
{
  "properties": {
    "A": {
      "label": "propA",
      /* ... */
    },
    "B": { 
      "label": "propB",
      /* ... */
    },
    "C": {
      "label": "propC",
      /* ... */
    }
  },
  "hazards": [
    {
      "risk": {
        "riskLevel": 1,
        "@id": "sho:FireHazard",
        "description": "The execution may cause fire",
        "name": "Fire hazard",
        "category": "sho:Safety",
      },
      "conditions": [
        [
          {
            "jsonPath": "propA",
            "condition": false,
          },
          {
            "jsonPath": "propB",
            "condition": false,
          },
          {
            "jsonPath": "propC",
            "condition": false,
          },
        ] 
      ],
    },
    /* ... */ 
  ]
}
```

This could have the advantage of completely avoiding the use of JSON Path, but on the other hand makes the implementation responsible for the validity and uniqueness of the labels. Probably this change is not worth, but it is was important to mention this idea.

#### Actions, indirect effects and transitory hazards

Modelling hazards in relation to properties can be intuitive, but unfortunately things start to fall apart when start introducing actions-related hazards. Keep in mind that we are aware the higher Sifis layer can just make these situations impossible to represent, but our aim is to make the hazards of any potential _smart thing_ representable. It is not necessary to propose an initial design that is also complete, but it should be easily extendable in the future in order to comprehend a larger set of cases.

The first issue is simply related to the missing correspondency between the consequences of an action and the hazards described by other properties. For instance, a lamp could exposes the `brightness` and `color` properties, and express some fire hazards based on these two properties. However, what is really happening is that these two properties influences a _hidden_ `temperature` property of the lamp. If the lamp want to expose an action that performs a color animation and this behavior increases the temperature of the lamp, it is necessary to expose this change of state to correctly evaluate the hazards of eventual subsequent actions (this point will be more clear in the next paragraphs). This kind of thing can be already represented without issues, using the `readOnly` field of a property in order to make it not directly modificable.

The second issue consists of the _simple_ case (the reason why this is "simple" will be more clear later) of queueing many actions. Let's say our lamp supports a `fade` action that supports a _brightness offset_, i.e. we can ask to increase the brightness by 20 using a fade effect of 3 seconds. Given that a higher brightness increases the temperature of the lamp, it is fundamental that the supervisor has all the information needed to _predict_ the state of the lamp at the end of the action in order to eventually deny the possibility of queueing other actions or setting properties. In order to support this behavior one possible solution is to allow an additional field for the actions in order to specify the _consequences_ of the action. For instance:
```jsonld
{
  "actions": {
    "fade": {
      consequences: [
        {
          "jsonPath": "@.properties.temperature",
          "value": "???"
        },
        {
          "jsonPath": "@.properties.brightness",
          "value": "???"
        },
      ],
      /* ... */
    }
  }
}
```
The fact that `value` is not correctly specified is to highlight the fact that this is not a trivial problem. Indeed, if fade supports both an absolute and a relative brightness (i.e. both `70` and `+20`), it is necessary to use conditional expressions inside the field, and because the main idea is that we should avoid these kind of things (because brings to a huge amount of issues and edge cases) I (Edoardo Morandi) still don't have a valid solution to the problem.

The third issue is related to the concept of _transitory hazard_ and _transitory states_: an action could bring the thing to an intermediate state that has a different set of hazards and/or risk levels that could be different from the one reached at the end of an action. This cannot be simply solved by setting the hazard of the action to the worst _transitory hazard_ because we still need to be able to predict the _worst consequences_ in case the action is cancelled during its _critical_ phase. Keep in mind that this behavior could be triggered by a malicious agent though a simple timing attack, therefore at least one level of the whole model should prevent the situation just described. One possible way to handle the problem at the level of Thing Description is to describe the _consequences_ field from the previous issues using the worst case scenario instead of the _final state_. This could deny _a priori_ some situations that could be _preceived_ as completely safe by the user, but the _real_ safety comes first.

There is a fourth issue that is particularly related to some part of the specification that is not detailed enough. What happens if a property is set while an action is running and it is changing its value? If the set is totally ignored, the risks are exactly as described by the action, but it is not necessarly what the user expected. But on the other hand, if the change of the property creates a worst case scenario for the action it is totally not trivial to enforce a re-evaluation of the running and pending actions. My opinion (Edoardo Morandi) is that trying to set the property must lead to an error or to be ignored, but this behavior should be better described in the specification, and then we could adapt the best solution for the hazards model.

#### Events

Events are the elephant in the room, because they express _passive_ behaviors, not _active_ like properties and actions. To be more clear, a supervisor can decide if changing a property or invoking an action is possibile depending on the involved risks and their level. But this is not possible with an event, which _just happens_, which means that associating risks to events is useless or it is necessary to use different paradigms. It is simple to find an example to demonstrate the usefulness of hazards on events: a smart gas sensor can send events whenever some gas is detected, which is obviously hazardous. At this point it should be clear that associating hazards and events can be very important, and that it is necessary to find a suitable way to integrate them into the model.

First of all, a thing is interested to its own events? I don't think it's the case, simply because it does not need a _way of communicating_ some statuses to itself, it already has all the information. Therefore the _real_ target for the hazards information can only be the supervisor, the user clients or other things. Probably the supervisor it is out of scope, because it should operate inbetween things and _thing controllers_, and it is also necessary to _actively subscribe_ to events. In the end, even if making the supervisor listen to all the events (and their hazards) could be doable, it would behave just like any other client or servient.

The user clients are a possible target for hazardous events, because they can trigger alarms for the user and can also express some mechanism to automatically interact with smart things in order to compensate for the risk raised event. However, even if this approach can be useful, it is not enough to guarantee a real safety: what happens if the client, installed for instance on the smartphone of the user, does not have internet access when the events are triggered? It cannot trigger the automatic behavior, breaking the safety of the entire system.

The only remaining possible target are the other smart things. In theory it makes sense, because a lamp should be able to express the maximum level of risk of explosion in case of "gas detection" events on the _on-off_ property. Good, but at the moment we cannot express, inside the conditions of a property/action risk, something like "a gas leak from another arbitrary thing". Especially because it would require the lamp to be designed with all the possible risks depending on external events, which is totally not doable.

We propose a specific solution for this problem, which involves _virtual_ smart things. The idea is it should be possible to create, for instance, a _virtual smart room_ that can be specifically configured in order to work with the things inside the room. In this way we follow the same automation approach that could be set on a user client, but without the problem of _not being available_ because the _virtual thing_ is part of the mesh of the real things. Moreover, the _virtual room_ can be behind the supervisor like all other things in order to avoid eventual issues, because it should be able to _actively_ interact with other things and a misconfiguration could trigger a safety risk that must be rejected by the supervisor.

In order to support this kind of behavior it should be sufficient a way to create custom virtual things because, once it is possible to express hazards and risks associated with events analogously to properties and actions, the Thing Description already has all the information needed. There are a lot of open questions, for instance which physical device or devices are responsible for hosting the _virtual thing_, but they are out of scope for this document.

#### JSON Pointer?

To be discussed: is JSON Path overkill for our purposes? Could JSON Pointer be enough? Is it worth to choose one respect to the other?






---
---
---

> [name=marco-rasori] [time=Mon, Jan 23, 2023]

### Notes. Starting from Edoardo's "Alternative Proposal"
A static app label is created at the time of application packaging. For each API within the application code, the app label includes the maximum risk for that API. For example, if the API `turnOnLamp()` is called within the code, we know what is the actual property that is set; in this case, `property.On=true`.
According to the method described [here](#Alternative-proposal), in the Thing Description, we have one or more conditions referring to one or more risks.
To create the app label, we first look in the Thing Description for the conditions in which `property.On=true`. Then, we extract the related risks, we *merge* them, and take the highest risk level for a hazard, if there are two risks with the same hazards.
In the example [above](#Alternative-proposal), if we have `property.A=true`, we select the conditions with
```jsonld
{
  "jsonPath": "$.properties.A",
  "condition": true,
}
```
and we extract the risk:
```jsonld
"risk": {
  "riskLevel": XXX,
  "@id": "sho:FireHazard",
  "description": "The execution may cause fire",
  "name": "Fire hazard",
  "category": "sho:Safety",
}
```
In this case, the matching conditions are three, and they all have the same hazard, i.e., Fire Hazard.
However, one hazard has `riskLevel=3`, one has `riskLevel=5`, and one has `riskLevel=8`.
In this case, we select the one with `riskLevel=8`, because it is the worst case, and we include it in the app label.

It is true that `property.A=true` does not guarantee that the `riskLevel` experimented by the user will be 8, since it could be that `property.B` and `property.C` always remain equal to false. The developer could even set them to false at the beginning of the code, but this does not guarantee that the device will not enter the state with `riskLevel=8`, where `property.A`, `property.B`, and `property.C` are all equal to true. Indeed, the user could physically interact with the thing, e.g., by pressing a button on it, or it could use another app that sets `property.B` and `property.C` to true, thus entering the state with `riskLevel=8`.

An additional note for the 'merge' operation:
if we have `property.A=true` in two conditions and one is associated with the risk `{FireHazard:riskLevel=8}` and the other with `{FireHazard:riskLevel=5, EnergyConsumption:riskLevel=3}`, the merge operation will result in the set `{FireHazard:riskLevel=8, EnergyConsumption:riskLevel=3}`

#### Non-Boolean Properties
APIs that do not set a Boolean value but take a parameter, such as the API `setBrightness(val)`, will set a property by calling, for example, `property.D=val`. The value of the parameter `val` could be not directly determined by analysing the app code. For example, if we have `val=mod(time.now, 100)`, we are not able to determine the value `val` will take. For this reason, if `val` is not a numerical value, but a variable is given as parameter, we should take all the conditions in which `property.D` is in, and act as in the previous case, i.e., extract the related risks, merge them, and take the highest risk level for a hazard, if there are two risks with the same hazards.

Edoardo already defined how a property with values in a given range can be defined within the risks in the thing description:
```jsonld
{
  "jsonPath": "$.properties.D",
  "condition": {
    "value": 50,
    "op": "lt"
  }
}
```

#### Risks for Developers
The developer using the IDE with the provided plugin will be prompted with the risks as defined above. A possible improvement could be adding a feature that allows the developer to see how the API, or the resulting static app label, would be in the average smart home, with the average things.
The reasoning behind this is that we show the developer the worst case scenario, e.g., a scenario in which the lamps deployed in the smart home are halogen. However, it might be that, in most of the cases, the used lamps are LED.
Another improvement could be to simulate the home in which the application will be installed, by having the developer selecting the things deployed in the home, and show him the risks for the set of things selected.

On the contrary, the app label shown to the user is created dynamically when the user wishes to install an app, and it depends on the things deployed in the user's smart home.

#### How can the plugin show that information to the developer?
Can the API label be statically associated with an API?
Well, in theory it could. For example, for the API `turnOnLamp()`, which internally calls `property.On=true`, we can take the most risky lamp description, extract the highest risk, e.g., `{FireHazard:riskLevel=8, EnergyConsumption:riskLevel=3}`, and associate it with the API.
In this solution, the API label will possibly be different at each release of the the SIFIS-Home APIs, and it would depend on the set of thing descriptions we, as SIFIS-Home, have available.

Another solution might be associating the label dynamically, having a database of thing description which may change over time (independently of the SIFIS-Home APIs release). In that case, the risk shown to the developer while programming is computed on the fly according to the thing descriptions found in the database.
