Device functions

Devices are composed of functions (each of which is a Python plug-in located in the synth/devices directory. All devices inherit the Basic device function. You can specify as many functions for a device as you like. Functions are composable (a device is constructed by inheriting from all specified functions) so functions can interact with each other if necessary.

Each function optionally takes some parameters (typically specified in a scenario .json file) and optionally creates and manages some device properties.

basic

This function is inherited by all devices automatically. It does not need to be explicitly declared, unless you want to change its behaviour

Configurable parameters:

{
    "label_root" : (optional) the root name of the label property
    "use_label_as_$id" : (optional) - if true then instead of creating a "label" property, the $id property is given the label name  (i.e. human-named $id)
}

Device properties created:

{
    "$id" : a unique random property which looks like a MAC address
    "is_demo_device" : to identify that this is a Synth-created device
    "label" : A human-readable label "Device 0", "Device 1" etc.
}

Aggregate

Aggregates properties within the model

Configurable parameters:

{
        "numbers" : ["name","name", ...]  # Names of numeric properties to be averaged
        "booleans" : ["name", "name", ...]  # Ditto for boolean properties
}

Device properties created:

{
        (whatever properties it finds)
}

battery

A battery which runs-out and can be replaced. When the battery has run out, communications are inhibited.

Configurable parameters:

{
    "life_mu" : the average length of battery life, e.g. "PT5M"
    "life_sigma" : the random deviation on this number - defaults to none
    "autoreplace" : set to true to auto-replace the battery when exhausted
    "autoreplace_delay" : how long until exhausted battery gets replaced
}

Device properties created:

{
    "battery" : current battery level as an integer percentage
}

bulb

Simulates a light switch, given a device which has a longitude and latitude (therefore a time of day and therefore an external light level) Reacts appropriately to location on Earth, time-of-day and season-of-year.

Configurable parameters:

{
    "power" : (optional)    number (or list to pick from) for Watts consumed by light when on
                            if this is provided, then emits a "power" property
}

Device properties created:

{
    "switched_on" : switches on and off 
}

button

Presses a button on the device, according to some timefunction.

Configurable parameters:

{
    "timefunction" : A time function specification.
}

Device properties created:

{
    "button_press" : Sent as a 1 on every button press
}

co2

Simulates co2 levels (driven by local occupancy)

Configurable parameters:

{
}

Device properties created:

{
    "co2_ppm"
}


Good summary of limits for CO2 here: https://www.engineeringtoolbox.com/co2-comfort-level-d_1024.html

comms

Simulates unreliable communications between device and service. If a property “rssi” exists, this is used to further modify the reliability.

Configurable parameters:

{
    "reliability" : 1.0     A fraction 0.0..1.0 or the word "rssi" to generate reliability from RSSI
    "period" :      P1D     Mean period with which device goes up and down [or RSSI varies, if being created] (has exponential tail with max 100x). Defaults to once a day
    "has_buffer" :  false   If this boolean is true then the device buffers data while comms is down (else it throws it away)
    "unbuffered_properties" : ["propname",...] (optional) these properties will be lost (not buffered) when comms goes offline - means that e.g. heartbeat messages don't get magically restored after an outage
    "suppress_messages" : false If true then wont emit log messages
}

Device properties created:

{
}

commswave

Takes device communications up and down according to a timefunction. Comms will be working whenever the timefunction returns non-zero.

Configurable parameters:

{
    "timefunction" : A timefunction definition
    "threshold" : (optional) Comms will only work when the timefunction is returning >= threshold. If missing then any non-zero value will make comms work.
}

Device properties created:

{
}

disruptive

Simulates sensors from Disruptive Technologies. By default they pair-up in “sites”

Configurable parameters:

{
    "sensor_type" : (optional) one of [ccon, temperature, proximity, touch] - if not set then automatically chooses (temperature, proximity) alternately
    "site_prefix" : (optional)      "Fridge "#
    "send_network_status" : False   Disruptive sensors send a lot of these messages
    "nominal_temp" : (optional) for temperature sensors, what the nominal temp is supposed to be, e.g. -18 for a freezer. If it's an array, then chosen randomly. Created as a property too, so DP can do filters relative to it
    "nominal_temp_deviation" : (optional) the normal deviation of the temperature (choice matches above)
    "cooling_MTBF" : (optional) mean time between failure of cooling, for temperature devices, specified as ISO8601 period (e.g. "P100D" means that on average every fridge will fail every 100 days)
    "cooling_TTF" : (optional) mean time to fix a cooling failure
    "site_type" : (optional) a string or list which matches choice above
}

Device properties created:

{
    "sensorType" : one of      [ccon, temperature, proximity, touch]
    "signalStrengthCellular" :   y                                    0..100
    "signalStrengthSensor" :               y           y        y
    "state" :                                          y              PRESENT | NOT_PRESENT
    "temperature" :                        y                          degrees C (0.00,0.05) every 15m
    "transmissionMode" :                   y           y        y     HIGH_POWER_BOOST_MODE | LOW_POWER_STANDARD_MODE
    "eventType" :                1         2           2        2     1="cellularStatus" every 5m  2="networkStatus" every 15m
    "connection" :               y                                    CELLULAR | OFFLINE

    "site"  # A site is something like a room, or a fridge, around which multiple devices can exist, whose behaviour is correlated (this only gets created if this device is not part of a model)
}


sensorType                     eventType              other properties
----------                     ---------              ----------------
ccon
    every 5m                   "cellularStatus"       "signalStrengthCellular": 10
    when goes offline/online   "connectionStatus"     "connection" : CELLULAR|OFFLINE

temperature/proximity/touch
    once a day                  batteryStatus         "batteryPercentage" : 100      
    every 15m                   networkStatus         "signalStrengthSensor": 0..100, "

+temperature
    every 15m                   temperature           "temperature" : 22.5

+proximity
    when changed                objectPresent         "state" : "PRESENT|NOT_PRESENT"     

+touch
                                touch 

(interestingly, DT's temperature and proximity sensors both also report touch events, but we ignore that here)

energy

Simulates energy meter

Configurable parameters:

{
    "opening_times" : (optional) "name of an opening-times pattern"
    "max_power" : (optional) maximum power level
    "baseload_power" : (optional) baseload power level (e.g. night-time)
    "power_variation" : (optional) how much "noise" on the reading
}

Device properties created:

{
    "kWh" : odometer
    "kW" : instantaneous
}

enumerated

Creates a property whose value changes between specific enumerated values, with a given probability. Useful for simulating device events such as lifecycle events and error conditions.

Configurable parameters:

{
    "name" : property name
    "values" :      [a,set,          of, possible,values]
    "periods" :     [a,corresponding,set,of,      periods] (each is an ISO8601 duration e.g. "P1D" means the event will happen once a day)
    "sigmas" :      [a,corresponding,set,of,      standard-deviations] (optional, e.g. "PT1H" means the period will vary randomly with 1 standard deviation of 1 hour)
    "always_send" : true (optional)  If true then values will be sent even if they haven't changed
}

If sigmas are not specified, they default to 50% of the periods to create a good amount of random spread. If you want to remove all randomness, specify sigmas of “PT0S”.

Device properties created:

{
    "<name>" : the output property
}

firmware

Provides a device firmware revision, which can be change by incoming “upgradeFirmware” events, and rolled-back to factory firmware by incoming “factoryReset” events.

Configurable parameters:

{
}

Device properties created:

{
    "firmware" : The current firmware of the device
}

heartbeat

Forces the device to communicate at regular intervals so that communications timeouts can be detected by the service. Doesn’t set any properties.

Configurable parameters:

{
    "interval" : as an ISO8601 duration e.g. "PT10M"
}

Device properties created:

{
}

hvac

Simulates HVAC system in a building, with heating and cooling and inputs like local weather etc.

Configurable parameters:

{
        opening_times : (optional) "nine_to_five"
        target_temp_ideal : (optional) 21 
        occupied_target_temp_min : (optional) 20
        occupied_target_temp_max : (optional) 22
        unoccupied_target_temp_min : (optional) 16
        unoccupied_target_temp_max : (optional) 28
        kwh_per_degree_day : (optional) 1000
        degrees_change_per_hour : (optional) 5  # How fast heating or cooling can work
}

Device properties created:

{
        insolation  # Amount of sunshine 
        temperature # Internal building temperature
        kW          # Power being used for heating or cooling
        pump_run    # When heating or cooling pumps are running
}

latlong

Scatters devices on the surface of the Earth in a realistic way according to population. If no arguments are provided, devices are scattered across the whole Earth. Uses a Google Maps API.

Configurable parameters:

{
    "generate_addresses" : true/false       If true then creates address_* properties (street, town, country etc.)

    "area_centre" : e.g. "London, UK"       } optional, but both must be specified if either are
    "area_radius" : e.g. "Manchester, UK"   } 
    -or-
    "addresses" : e.g. ["London, UK", "Manchester, UK"] } a set of locations which are picked device-by-device

    "map_file" : e.g. "devicepilot_logo" - optional
    "google_maps_key" : "xyz" } Google Maps now requires this. Often defined in ../synth_accounts/default.json
}

Device properties created:

{
    "latitude" : latitude in degrees as a floating-point number
    "longitude" : longitude in degrees as a floating-point number
}

light

Simulates a light sensor, given a device which has a longitude and latitude. Reacts appropriately to location on Earth, time-of-day and season-of-year.

Configurable parameters:

{
}

Device properties created:

{
    "light" : updates once an hour with the local light level
    "clouds" : true (optional)
    "generate" : true (optional) - create "power" and "energy" properties for solar PV (-ve because generating)
}

lora_device

Simulates a LoraWAN device (e.g. from The Things Network)

Configurable parameters:

{
}

Device properties created:

{
}

lora_gateway

Simulates a LoraWAN gateway (e.g. from The Things Network)

Configurable parameters:

{
}

Device properties created:

{
}

mobile

Devices which (are supposed to) move in a predictable way

Configurable parameters:

{
    "area_centre" : e.g. "London, UK"       } optional, but both must be specified if either are. Points-to-visit will be within this set.
    "area_radius" : e.g. "Manchester, UK"   } 
    "num_locations" : 10                            The total number of defined locations 
    "points_to_visit" : 4                           Number of these locations that any individual device can visit (MUST be <= num_locations!). Optional, but if specified then must be at least 2
    "update_period" : "PT1H" (optional)             How often to update position
    "generate_fleet_management_metrics" : False     If true then output several properties to do with fleet management (fuel, miles etc.)
    "route_plan" : null (optional)                  If set then use realistic route-planning, with given mode (e.g. "walking", "driving")
    "google_maps_key" : "xyz"                       Google Maps now requires this. Often defined in ../synth_accounts/default.json
}

Device properties created:

{
    "latitude" : latitude in degrees as a floating-point number
    "longitude" : longitude in degrees as a floating-point number
}

names

Provides first name and last name of device owner, chosen randomly hashed by $id.

Configurable parameters:

{
}

Device properties created:

{
    "first_name" : the owner's first name
    "last_name" : the owner's last name
}

occupancy

Simulates occupancy sensor

Configurable parameters:

{
    opening_times : "nine_to_five" (optional)
    peak_occupancy : 1.0 (optional)
    variability_by_device : 0.2 (optional)
}

Device properties created:

{
    "occupied" : true / false
}

sump

Simulates a sump, managed by a water pump (e.g. pumping accumulated surface water out of storm drains, or similar) Requires that device has property “precipitation_intensity” in mm/hr, as created by “weather”

Configurable parameters:

{
}

Device properties created:

{
    sump_level_mm : mm of water
    sump_limit_mm :
    sump_pump_energy_consumption_kW
}

variable

Creates device properties which can be static (if “value” is defined) or driven by some timefunction (if “timefunction” is defined)

Configurable parameters:

{
    "name" : the name of the variable
    "value" : a static number or string - or an array to pick one randomly OR
    "timefunction" : a timefunction definition OR
    "random_lower", "random_upper" : a range of values to pick randomly within (with optional "precision" parameter) OR
    "randstruct" : "["A definition like this where",[" lists "," are "," concatenated"], " and tuples are ("chosen from","selected betwixt"), "randomly]" OR
    "series" : a list: first device gets first value, second device second value etc.
}

-or-

[an array of the above to create multiple properties]

Device properties created:

{
    <name> : (properties are created according to the "name" argument)
}

vending_machine

Simulates a vending machine.

Configurable parameters:

{
        "product_catalogue" : (optional) [ "name" : "Mars Bar", "price" : 0.80, "category" : "snack", "lifetime" : "P1000D", ... ]
        "send_available_positions" : (optional) False
        "cashless_to_cash_ratio" : (optional) 0..1      # The ratio of cashless transactions to cash-based ones
}

Device properties created:

{
    <TODO>
}