def __init__(self, api_key, entity, timestamp, payload): ''' Constructor @param api_key: FIWARe API Key @param entity: Entity name @param timestamp: timestamp of data creation @param payload: UltraLight payload to be transmitted to FIWARE IoT agent ''' # Create service group the first time an object is created if Efiware.CREATE_SERVICE_GROUP: Efiware.CREATE_SERVICE_GROUP = False try: self.create_service_group(EfConfig.FIWARE_APIKEY, EfConfig.FIWARE_ENTITY, EfConfig.FIWARE_DATAMODEL) except EfException as ex: ex.show() # Send UL packet try: url = EfConfig.FIWARE_UL_URL params = { "k": api_key, "i": entity, "t": timestamp.strftime("%Y-%m-%dT%H:%M:%SZ"), "getCmd": 1 } headers = {"Content-Type": "text/plain"} client = EfHttpClient(headers, url, params, payload) print(client) client.post() except: raise EfException("Unable to post UL packet to FIWARE IoT agent")
def create_service_group(self, api_key, entity_type, data_model): """ Create service group on FIWARE CB @param api_key: FIWARE API Key @param entity_type: Entity type (FIWARE_ENTITY_OBSERVATION or FIWARE_ENTITY_POLLUTION) @param data_model: List of correspondances between UL and NGSI nomenclatures """ ## Post request try: url = EfConfig.FIWARE_SERVGROUP_URL params = {} headers = { "Content-Type": "application/json", "fiware-service": EfConfig.FIWARE_SERVICE, "fiware-servicepath": "/" + entity_type } # Declare datamodels attributes = [] for key, value in data_model.items(): if key in EfConfig.FIWARE_DATAMODEL_STRINGS: attr = {"object_id": key, "name": value, "type": "String"} else: attr = {"object_id": key, "name": value, "type": "Number"} attributes.append(attr) # Add location geo:point attribute location = { "expression": "${@longitude}, ${@latitude}", "name": "location", "type": "geo:point" } attributes.append(location) payload = { "services": [{ "apikey": api_key, "protocol": ["IoTA-UL"], "cbroker": "http://orion:1026", "entity_type": entity_type, "resource": "/iot/d", "attributes": attributes }] } client = EfHttpClient(headers, url, params, json.dumps(payload)) client.post() except: raise EfException( "Unable to create service group. Probably because it already exists" )
def get(self): """ Run HTTP get request """ try: result = requests.get(self.url, headers=self.header, params=self.parameters, data=self.payload) if result.status_code == 200: reader = csv.DictReader(io.StringIO(result.text), delimiter=',') return reader else: raise EfException("Unable to reach server via HTTP. Status: " + result.status_code + " . Reason: " + result.reason) except Exception as ex: raise EfException(str(ex))
def post(self): """ Run HTTP post request """ try: result = requests.post(self.url, headers=self.header, params=self.parameters, data=self.payload) if result.status_code in [200, 201]: try: return result.json() except: return result.text else: raise EfException("Unable to reach server via HTTP. Status: " + result.status_code + " . Reason: " + result.reason) except Exception as ex: raise EfException(str(ex))
def query(self, country, polluant): ''' Query observation data @param country: country code @param polluant: polluant to be queried @return ordered dictionary contained the requested information ''' url = "" try: url = EfConfig.EEA_URL + "/" + country + "_" + polluant + ".csv" headers = {"Content-type": "text/csv"} client = EfHttpClient(headers, url) print("Downloading from " + url + "...") res = client.get() stations = {} for row in res: station_code = row["station_code"] ref_time = row["value_datetime_end"] timestamp = datetime.strptime(ref_time, "%Y-%m-%d %H:%M:%S%z") conc = row["value_numeric"] # Retain only the latest reading from each station update = True if conc != '': if station_code in stations: ts = stations[station_code]["timestamp"] if ts > timestamp: update = False if update: lat = row["samplingpoint_y"] lon = row["samplingpoint_x"] measurement = { "timestamp": timestamp, "lat": lat, "lon": lon, EfConfig.POLLUTION_PARAMETERS[polluant]: conc } stations[station_code] = measurement return stations except: raise EfException("Unable to get data URL from " + url)