def setUp(self) -> None: """ Setup test data Returns: None """ self.fiware_header = FiwareHeader( service=settings.FIWARE_SERVICE, service_path=settings.FIWARE_SERVICEPATH) self.ql_client = QuantumLeapClient(url=settings.QL_URL, fiware_header=self.fiware_header) self.cb_client = ContextBrokerClient(url=settings.CB_URL, fiware_header=self.fiware_header)
def test_test_query_endpoints_with_args(self) -> None: """ Test arguments for queries Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: for entity in create_entities(): # test limit for limit in range(5000, 25000, 5000): records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', limit=limit) logger.debug(records.json(indent=2)) logger.debug(records.to_pandas()) self.assertEqual(len(records.index), limit) # test last_n for last_n in range(5000, 25000, 5000): limit = 15000 last_n_records = client.get_entity_by_id( entity_id=entity.id, attrs='temperature,co2', limit=limit, last_n=last_n) self.assertGreater(last_n_records.index[0], records.index[0]) self.assertEqual(len(last_n_records.index), min(last_n, limit)) # test offset old_records = None for offset in range(5000, 25000, 5000): # with limit records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', offset=offset) if old_records: self.assertLess(old_records.index[0], records.index[0]) old_records = records old_records = None for offset in range(5000, 25000, 5000): # test with last_n records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', offset=offset, last_n=5) if old_records: self.assertGreater(old_records.index[0], records.index[0]) old_records = records
def __init__(self, config: Union[str, Path, HttpClientConfig, Dict] = None, session: Session = None, fiware_header: FiwareHeader = None, **kwargs): """ Constructor for master client Args: config (Union[str, Path, Dict]): Configuration object session (request.Session): Session object fiware_header (FiwareHeader): Fiware header **kwargs: Optional arguments that ``request`` takes. """ if config: self.config = config else: self.config = HttpClientConfig() super().__init__(session=session, fiware_header=fiware_header, **kwargs) # initialize sub clients self.cb = ContextBrokerClient(url=self.config.cb_url, session=self.session, fiware_header=self.fiware_headers, **self.kwargs) self.iota = IoTAClient(url=self.config.iota_url, session=self.session, fiware_header=self.fiware_headers, **self.kwargs) self.timeseries = QuantumLeapClient(url=self.config.ql_url, session=self.session, fiware_header=self.fiware_headers, **self.kwargs) # from here on deprecated? auth_types = { 'basicauth': self.__http_basic_auth, 'digestauth': self.__http_digest_auth } # 'oauth2': self.__oauth2} if self.config.auth: assert self.config.auth['type'].lower() in auth_types.keys() self.__get_secrets_file(path=self.config.auth['secret']) auth_types[self.config.auth['type']]() self.__secrets = { "username": None, "password": None, "client_id": None, "client_secret": None }
def test_meta_endpoints(self) -> None: """ Test meta data endpoints Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: self.assertIsNotNone(client.get_version()) self.assertIsNotNone(client.get_health())
def clear_quantumleap(url: str, fiware_header: FiwareHeader): """ Function deletes all data for a given fiware header Args: url: Url of the quantumleap service fiware_header: header of the tenant Returns: None """ def handle_emtpy_db_exception(err: RequestException) -> None: """ When the database is empty for request quantumleap returns a 404 error with a error message. This will be handled here evaluating the empty database error as 'OK' Args: err: exception raised by delete function """ if err.response.status_code == 404 \ and err.response.json().get('error', None) == 'Not Found': pass else: raise # create client client = QuantumLeapClient(url=url, fiware_header=fiware_header) # clear data entities = [] try: entities = client.get_entities() except RequestException as err: handle_emtpy_db_exception(err) # will be executed for all found entities for entity in entities: client.delete_entity(entity_id=entity.entityId, entity_type=entity.entityType)
def test_query_endpoints_by_type(self) -> None: """ Test queries by type with default values Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: entities = create_entities() for entity in entities: # get by type attrs_type = client.get_entity_by_type(entity_type=entity.type) for entity_id in attrs_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([len(entity_id.index) for entity_id in attrs_type]), 10000) attrs_values_type = client.get_entity_values_by_type( entity_type=entity.type, ) for entity_id in attrs_values_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([ len(entity_id.index) for entity_id in attrs_values_type ]), 10000) attr_type = client.get_entity_attr_by_type( entity_type=entity.type, attr_name="temperature") for entity_id in attr_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([len(entity_id.index) for entity_id in attr_type]), 10000) attr_values_type = client.get_entity_attr_values_by_type( entity_type=entity.type, attr_name="temperature") for entity_id in attr_values_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([ len(entity_id.index) for entity_id in attr_values_type ]), 10000)
def create_time_series_data(num_records: int = 50000): """ creates large testing data sets that should remain on the server. This is mainly to reduce time for testings """ fiware_header = FiwareHeader(service=settings.FIWARE_SERVICE, service_path="/static") with QuantumLeapClient(url=settings.QL_URL, fiware_header=fiware_header) \ as client: for i in range(num_records): notification_message = Message(data=create_entities(), subscriptionId="test") client.post_notification(notification_message)
def test_entity_context(self) -> None: """ Test entities endpoint Returns: None """ entities = create_entities() with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: notification_message = Message(data=entities, subscriptionId="test") client.post_notification(notification_message) time.sleep(1) entities = client.get_entities(entity_type=entities[0].type) for entity in entities: logger.debug(entity.json(indent=2))
def test_query_endpoints_by_id(self) -> None: """ Test queries with default values Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: entities = create_entities() with self.assertRaises(requests.RequestException): client.get_entity_by_id(entity_id=entities[0].id, entity_type='MyType') for entity in entities: # get by id attrs_id = client.get_entity_by_id(entity_id=entity.id, aggr_period='minute', aggr_method='avg', attrs='temperature,co2') logger.debug(attrs_id.json(indent=2)) logger.debug(attrs_id.to_pandas()) attrs_values_id = client.get_entity_values_by_id( entity_id=entity.id) logger.debug(attrs_values_id.to_pandas()) self.assertEqual(len(attrs_values_id.index), 10000) attr_id = client.get_entity_attr_by_id(entity_id=entity.id, attr_name="temperature") logger.debug(attr_id.to_pandas()) self.assertEqual(len(attr_id.index), 10000) attr_values_id = client.get_entity_attr_values_by_id( entity_id=entity.id, attr_name="temperature") logger.debug(attr_values_id.to_pandas()) self.assertEqual(len(attrs_values_id.index), 10000)
def test_input_endpoints(self) -> None: """ Test input endpoint Returns: None """ entities = create_entities() for entity in entities: self.cb_client.post_entity(entity) with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: notification_message = Message(data=entities, subscriptionId="test") client.post_subscription(cb_url=settings.CB_URL, ql_url=settings.QL_URL, entity_id=entities[0].id) client.post_notification(notification_message) time.sleep(1)
# different clients. It is also useful in combination with OAuth2Session # objects that handle authentication mechanisms and third party libraries. # Please be aware that you need to do the session handling yourself. # Hence, always create the session by using python's context protocol or # manually close the connection. with requests.Session() as s: cb_client = ContextBrokerClient(session=s, fiware_header=fiware_header) print(f"OCB Version: {cb_client.get_version()}") # # 3 Version information # # Independent of the selected mode, the version of the client can always be # accessed as follows: iota_client = IoTAClient(fiware_header=fiware_header) print(f"Iot-Agent Version: {iota_client.get_version()}") ql_client = QuantumLeapClient(fiware_header=fiware_header) print(f"QuantumLeap Version: {ql_client.get_version()}") # # 4 URL # # Additional to the FiwareHeader each client needs an URL, that points # to the Fiware-server. # # ## 4.1 Environment variables # # As shown above the client does not need to be given explicitly. If no URL # is given to the client, it is extracted from the environment variables # # ## 4.2 Direct Provision # # Instead of using an .env.filip or environment variables you can also
class TestTimeSeries(unittest.TestCase): """ Test class for time series api client """ def setUp(self) -> None: """ Setup test data Returns: None """ self.fiware_header = FiwareHeader( service=settings.FIWARE_SERVICE, service_path=settings.FIWARE_SERVICEPATH) self.ql_client = QuantumLeapClient(url=settings.QL_URL, fiware_header=self.fiware_header) self.cb_client = ContextBrokerClient(url=settings.CB_URL, fiware_header=self.fiware_header) def test_meta_endpoints(self) -> None: """ Test meta data endpoints Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: self.assertIsNotNone(client.get_version()) self.assertIsNotNone(client.get_health()) @clean_test(fiware_service=settings.FIWARE_SERVICE, fiware_servicepath=settings.FIWARE_SERVICEPATH, cb_url=settings.CB_URL, ql_url=settings.QL_URL) def test_input_endpoints(self) -> None: """ Test input endpoint Returns: None """ entities = create_entities() for entity in entities: self.cb_client.post_entity(entity) with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: notification_message = Message(data=entities, subscriptionId="test") client.post_subscription(cb_url=settings.CB_URL, ql_url=settings.QL_URL, entity_id=entities[0].id) client.post_notification(notification_message) time.sleep(1) @clean_test(fiware_service=settings.FIWARE_SERVICE, fiware_servicepath=settings.FIWARE_SERVICEPATH, ql_url=settings.QL_URL) def test_entity_context(self) -> None: """ Test entities endpoint Returns: None """ entities = create_entities() with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header) \ as client: notification_message = Message(data=entities, subscriptionId="test") client.post_notification(notification_message) time.sleep(1) entities = client.get_entities(entity_type=entities[0].type) for entity in entities: logger.debug(entity.json(indent=2)) def test_query_endpoints_by_id(self) -> None: """ Test queries with default values Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: entities = create_entities() with self.assertRaises(requests.RequestException): client.get_entity_by_id(entity_id=entities[0].id, entity_type='MyType') for entity in entities: # get by id attrs_id = client.get_entity_by_id(entity_id=entity.id, aggr_period='minute', aggr_method='avg', attrs='temperature,co2') logger.debug(attrs_id.json(indent=2)) logger.debug(attrs_id.to_pandas()) attrs_values_id = client.get_entity_values_by_id( entity_id=entity.id) logger.debug(attrs_values_id.to_pandas()) self.assertEqual(len(attrs_values_id.index), 10000) attr_id = client.get_entity_attr_by_id(entity_id=entity.id, attr_name="temperature") logger.debug(attr_id.to_pandas()) self.assertEqual(len(attr_id.index), 10000) attr_values_id = client.get_entity_attr_values_by_id( entity_id=entity.id, attr_name="temperature") logger.debug(attr_values_id.to_pandas()) self.assertEqual(len(attrs_values_id.index), 10000) def test_query_endpoints_by_type(self) -> None: """ Test queries by type with default values Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: entities = create_entities() for entity in entities: # get by type attrs_type = client.get_entity_by_type(entity_type=entity.type) for entity_id in attrs_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([len(entity_id.index) for entity_id in attrs_type]), 10000) attrs_values_type = client.get_entity_values_by_type( entity_type=entity.type, ) for entity_id in attrs_values_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([ len(entity_id.index) for entity_id in attrs_values_type ]), 10000) attr_type = client.get_entity_attr_by_type( entity_type=entity.type, attr_name="temperature") for entity_id in attr_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([len(entity_id.index) for entity_id in attr_type]), 10000) attr_values_type = client.get_entity_attr_values_by_type( entity_type=entity.type, attr_name="temperature") for entity_id in attr_values_type: logger.debug(entity_id.to_pandas()) self.assertEqual( sum([ len(entity_id.index) for entity_id in attr_values_type ]), 10000) def test_test_query_endpoints_with_args(self) -> None: """ Test arguments for queries Returns: None """ with QuantumLeapClient( url=settings.QL_URL, fiware_header=self.fiware_header.copy( update={'service_path': '/static'})) \ as client: for entity in create_entities(): # test limit for limit in range(5000, 25000, 5000): records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', limit=limit) logger.debug(records.json(indent=2)) logger.debug(records.to_pandas()) self.assertEqual(len(records.index), limit) # test last_n for last_n in range(5000, 25000, 5000): limit = 15000 last_n_records = client.get_entity_by_id( entity_id=entity.id, attrs='temperature,co2', limit=limit, last_n=last_n) self.assertGreater(last_n_records.index[0], records.index[0]) self.assertEqual(len(last_n_records.index), min(last_n, limit)) # test offset old_records = None for offset in range(5000, 25000, 5000): # with limit records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', offset=offset) if old_records: self.assertLess(old_records.index[0], records.index[0]) old_records = records old_records = None for offset in range(5000, 25000, 5000): # test with last_n records = client.get_entity_by_id(entity_id=entity.id, attrs='temperature,co2', offset=offset, last_n=5) if old_records: self.assertGreater(old_records.index[0], records.index[0]) old_records = records def tearDown(self) -> None: """ Clean up server Returns: None """ clear_all(fiware_header=self.fiware_header, cb_url=settings.CB_URL, ql_url=settings.QL_URL) self.ql_client.close() self.cb_client.close()
state = 1 elif temperature >= 21: state = 0 else: update = False # send the command to the heater entity if update: command = NamedCommand(name=heater.commands[0].name, value=state) cbc.post_command(entity_id=heater.entity_name, entity_type=heater.entity_type, command=command) mqttc.message_callback_add(sub=TOPIC_CONTROLLER, callback=on_measurement) # ToDo: create a quantumleap client qlc = QuantumLeapClient(...) # ToDO: create a http subscriptions that get triggered by updates of your # device attributes. Note that you can also post the same subscription # by the context broker. 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(...) qlc.post_subscription(...) # connect to the mqtt broker and subscribe to your topic
logger = logging.getLogger(__name__) if __name__ == "__main__": # ## 1 Setup # # A QuantumLeapClient and a ContextBrokerClient are created to access # FIWARE in the space given by the FiwareHeader. For more information see: # e01_http_clients.py fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH) # clear all existing data clear_all(fiware_header=fiware_header, cb_url=CB_URL, ql_url=QL_URL) ql_client = QuantumLeapClient(url=QL_URL, fiware_header=fiware_header) print("Quantum Leap " + ql_client.get_version()["version"] + " at url " + ql_client.base_url) cb_client = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header) print("Context broker version " + cb_client.get_version()["orion"]["version"] + " at url " + cb_client.base_url) # ## 2 Interact with QL # # ### 2.1 Create a ContextEntity to work with # # for more details see: e01_ngsi_v2_context_basics.py hall = {
# ## Parameters # ToDo: Enter your context broker url and port, e.g. http://localhost:1026 CB_URL = "http://localhost:1026" # ToDo: Enter your IoT-Agent url and port, e.g. http://localhost:4041 IOTA_URL = "http://localhost:4041" # ToDo: Enter your QuantumLeap url and port, e.g. http://localhost:8668 QL_URL = "http://localhost:8668" # ## Main script if __name__ == "__main__": # ToDo: Create a single client for each service and check the service for # its version cbc = ContextBrokerClient(url=CB_URL) print(cbc.get_version()) iotac = IoTAClient(url=IOTA_URL) print(iotac.get_version()) qlc = QuantumLeapClient(url=QL_URL) print(qlc.get_version()) # ToDo: Create a configuration object for a multi client config = HttpClientConfig(cb_url=CB_URL, iota_url=IOTA_URL, ql_url=QL_URL) # ToDo: Create a multi client check again all services for their version multic = HttpClient(config=config) print(multic.cb.get_version()) print(multic.iota.get_version()) print(multic.timeseries.get_version())
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
state = 1 elif temperature >= 21: state = 0 else: update = False # send the command to the heater entity if update: command = NamedCommand(name=heater.commands[0].name, value=state) cbc.post_command(entity_id=heater.entity_name, entity_type=heater.entity_type, command=command) mqttc.message_callback_add(sub=TOPIC_CONTROLLER, callback=on_measurement) # ToDo: create a quantumleap client qlc = QuantumLeapClient(url=QL_URL, fiware_header=fiware_header) # ToDO: create a http subscriptions that get triggered by updates of your # device attributes. Note that you can also post the same subscription # by the context broker. 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)