Example #1
0
def simulation(
    TEMPERATURE_MAX=10,  # maximal ambient temperature
    TEMPERATURE_MIN=-5,  # minimal ambient temperature
    TEMPERATURE_ZONE_START=10,  # start value of the zone temperature
    T_SIM_START=0,  # simulation start time in seconds
    T_SIM_END=24 * 60 * 60,  # simulation end time in seconds
    COM_STEP=60 * 15,  # 1 min communication step in seconds
    SLEEP_TIME=0.2  # sleep time between every simulation step
):
    # create a fiware header object
    fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)

    # instantiate simulation model
    sim_model = SimulationModel(t_start=T_SIM_START,
                                t_end=T_SIM_END,
                                temp_max=TEMPERATURE_MAX,
                                temp_min=TEMPERATURE_MIN,
                                temp_start=TEMPERATURE_ZONE_START)

    # Create clients and restore devices and groups from files
    groups = parse_file_as(List[ServiceGroup], READ_GROUPS_FILEPATH)
    devices = parse_file_as(List[Device], READ_DEVICES_FILEPATH)
    cbc = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header)
    iotac = IoTAClient(url=IOTA_URL, fiware_header=fiware_header)
    iotac.post_groups(service_groups=groups, update=True)
    iotac.post_devices(devices=devices, update=True)

    # Get the device configurations from the server
    weather_station = iotac.get_device(device_id="device:001")
    zone_temperature_sensor = iotac.get_device(device_id="device:002")
    heater = iotac.get_device(device_id="device:003")

    # Get the service group configurations from the server
    group = iotac.get_group(resource="/iot/json", apikey=APIKEY)

    #  Create a http subscriptions that get triggered by updates of your
    #  device attributes and send data to Quantum Leap.
    qlc = QuantumLeapClient(url=QL_URL, fiware_header=fiware_header)

    qlc.post_subscription(entity_id=weather_station.entity_name,
                          entity_type=weather_station.entity_type,
                          cb_url="http://orion:1026",
                          ql_url="http://quantumleap:8668",
                          throttling=0)

    qlc.post_subscription(entity_id=zone_temperature_sensor.entity_name,
                          entity_type=zone_temperature_sensor.entity_type,
                          cb_url="http://orion:1026",
                          ql_url="http://quantumleap:8668",
                          throttling=0)

    qlc.post_subscription(entity_id=heater.entity_name,
                          entity_type=heater.entity_type,
                          cb_url="http://orion:1026",
                          ql_url="http://quantumleap:8668",
                          throttling=0)

    # create a MQTTv5 client with paho-mqtt and the known groups and devices.
    mqttc = IoTAMQTTClient(
        protocol=mqtt.MQTTv5,
        devices=[weather_station, zone_temperature_sensor, heater],
        service_groups=[group])
    # set user data if required
    mqttc.username_pw_set(username=MQTT_USER, password=MQTT_PW)

    #  Implement a callback function that gets triggered when the
    #  command is sent to the device. The incoming command should update the
    #  heater power of the simulation model
    def on_command(client, obj, msg):
        """
        Callback for incoming commands
        """
        # Decode the message payload using the libraries builtin encoders
        apikey, device_id, payload = \
            client.get_encoder(PayloadProtocol.IOTA_JSON).decode_message(
                msg=msg)
        # Update the heating power of the simulation model
        sim_model.heater_power = payload["heater_power"]

        # Acknowledge the command.
        client.publish(device_id=device_id,
                       command_name=next(iter(payload)),
                       payload=payload)

    # Add the command callback to your MQTTClient. This will get
    #  triggered for the specified device_id
    mqttc.add_command_callback(device_id=heater.device_id, callback=on_command)

    # connect to the mqtt broker and subscribe to your topic
    mqtt_url = urlparse(MQTT_BROKER_URL_EXPOSED)
    mqttc.connect(host=mqtt_url.hostname,
                  port=mqtt_url.port,
                  keepalive=60,
                  bind_address="",
                  bind_port=0,
                  clean_start=mqtt.MQTT_CLEAN_START_FIRST_ONLY,
                  properties=None)
    # subscribe to all incoming command topics for the registered devices
    mqttc.subscribe()

    # create a non-blocking thread for mqtt communication
    mqttc.loop_start()

    # define lists to store historical data
    history_weather_station = []
    history_zone_temperature_sensor = []
    history_heater_power = []

    # simulation without heater
    # Create a loop that publishes regularly a message to the broker
    #  that holds the simulation time "simtime" and the corresponding
    #  temperature "temperature" the loop should. You may use the `object_id`
    #  or the attribute name as key in your payload.
    print("Simulation starts")
    for t_sim in range(sim_model.t_start, sim_model.t_end + int(COM_STEP),
                       int(COM_STEP)):
        # publish the simulated ambient temperature
        mqttc.publish(device_id=weather_station.device_id,
                      payload={
                          "temperature": sim_model.t_amb,
                          "simtime": sim_model.t_sim
                      })

        # publish the simulated zone temperature
        mqttc.publish(device_id=zone_temperature_sensor.device_id,
                      payload={
                          "temperature": sim_model.t_zone,
                          "simtime": sim_model.t_sim
                      })

        # publish the 'simtime' for the heater device
        mqttc.publish(device_id=heater.device_id,
                      payload={"simtime": sim_model.t_sim})

        # simulation step for next loop
        sim_model.do_step(int(t_sim + COM_STEP))
        # wait for one second before publishing the next values
        time.sleep(SLEEP_TIME)

        # Get corresponding entities and write values to history
        weather_station_entity = cbc.get_entity(
            entity_id=weather_station.entity_name,
            entity_type=weather_station.entity_type)
        # append the data to the local history
        history_weather_station.append({
            "simtime":
            weather_station_entity.simtime.value,
            "temperature":
            weather_station_entity.temperature.value
        })

        # Get ZoneTemperatureSensor and write values to history
        zone_temperature_sensor_entity = cbc.get_entity(
            entity_id=zone_temperature_sensor.entity_name,
            entity_type=zone_temperature_sensor.entity_type)
        history_zone_temperature_sensor.append({
            "simtime":
            zone_temperature_sensor_entity.simtime.value,
            "temperature":
            zone_temperature_sensor_entity.temperature.value
        })

        # Get ZoneTemperatureSensor and write values to history
        heater_entity = cbc.get_entity(entity_id=heater.entity_name,
                                       entity_type=heater.entity_type)
        history_heater_power.append({
            "simtime": heater_entity.simtime.value,
            "heater_power": sim_model.heater_power
        })

    # close the mqtt listening thread
    mqttc.loop_stop()
    # disconnect the mqtt device
    mqttc.disconnect()

    clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header)
    clear_context_broker(url=CB_URL, fiware_header=fiware_header)

    return history_weather_station, history_zone_temperature_sensor, history_heater_power
Example #2
0
APIKEY = SERVICE_PATH.strip('/')

# Path to read json-files from previous exercises
READ_GROUPS_FILEPATH = \
    Path("./e5_iot_thermal_zone_control_groups.json")
READ_DEVICES_FILEPATH = \
    Path("./e5_iot_thermal_zone_control_devices.json")
READ_ENTITIES_FILEPATH = \
    Path("./e3_context_entities_entities.json")

# ## Main script
if __name__ == '__main__':
    # create a fiware header object
    fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
    # clear the state of your service and scope
    clear_iot_agent(url=IOTA_URL, fiware_header=fiware_header)
    clear_context_broker(url=CB_URL, fiware_header=fiware_header)

    # Create clients and restore devices and groups from file
    groups = parse_file_as(List[ServiceGroup], READ_GROUPS_FILEPATH)
    devices = parse_file_as(List[Device], READ_DEVICES_FILEPATH)
    entities = parse_file_as(List[ContextEntity], READ_ENTITIES_FILEPATH)
    cbc = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header)
    for entity in entities:
        cbc.post_entity(entity=entity)

    iotac = IoTAClient(url=IOTA_URL, fiware_header=fiware_header)
    iotac.post_groups(service_groups=groups)
    iotac.post_devices(devices=devices)

    # ToDo: Retrieve all iot resources from the IoT-Agent