def parse_service(service, service_key_name, service_name, request_type): out = {"hpp": [], "cpp": [], "structs": []} api_prefix = safe_extract("apiPrefix", service, "") compulsory = safe_extract("compulsoryParameters", service, []) query_string = safe_extract("microbitQueryString", service, "") for e in service["endpoint"].keys(): endpoint = service["endpoint"][e] returns = safe_extract("returns", endpoint, []) return_type = generate_return_type(returns, service_name, e) if len(return_type["struct"]) > 0: out["structs"] += [return_type["struct"]] parameters = compulsory[:] parameters += safe_extract("parameters", endpoint, []) multi_type = False parameter_combinations = [] base_params = [] for p in parameters: if isinstance(p['type'], (list, )): multi_type = True continue base_params += [p] if multi_type: for p in parameters: if isinstance(p['type'], (list, )): for typ in p['type']: add_params = base_params[:] add_params += [{"name": p["name"], "type": typ}] parameter_combinations += [add_params] for c in parameter_combinations: function_def = generate_function_definition( return_type, service_key_name, service_name, e, c, query_string, returns, request_type, api_prefix) out["hpp"] += [function_def["hpp"]] out["cpp"] += [function_def["cpp"]] else: function_def = generate_function_definition( return_type, service_key_name, service_name, e, parameters, query_string, returns, request_type, api_prefix) out["hpp"] += [function_def["hpp"]] out["cpp"] += [function_def["cpp"]] return out
def poll(self): if len(self.poll_urls) == 0: return print self.poll_urls[self.url_index] res = requests.get(self.poll_urls[self.url_index]) cached = safe_extract(self.poll_urls[self.url_index], self.cached_response, None) diff = [] response_json = res.json() if cached: print "cached" print cached for r in response_json.keys(): record = response_json[r] if r not in cached.keys(): diff += [record] elif record["timestamp"] > cached[r]["timestamp"]: diff += [record] else: for r in response_json.keys(): record = response_json[r] diff += [record] # TODO: package and return a radio packet.... self.cached_response[self.poll_urls[self.url_index]] = response_json self.url_index = (self.url_index + 1) % len(self.poll_urls) return diff
def generate_urls(self): self.poll_urls = [] for polling_eps in self.polling_endpoints: url = safe_extract("baseURL", polling_eps, "") endpoints = safe_extract("endpoint", polling_eps, []) if len(endpoints) == 0: self.poll_urls += [url] continue params = re.findall(hub_regexp, url) for ep_key in endpoints.keys(): ep = endpoints[ep_key] trans_param = safe_extract("parameters", ep, []) # copy ep_url = url[:] # match regexp for regexp in params: regex, name, default = regexp[0], regexp[1], regexp[2] # special case for endpoint if name == "endpoint": ep_url = ep_url.replace(regex, ep_key) else: # otherwise, check if this parameter is required by our endpoint params object match = False for p in trans_param: if p["name"] == name: match = True #if it is matched, replace if match: ep_url = ep_url.replace(regex, self.hub_variables[name]) else: ep_url = ep_url.replace(regex, "") self.poll_urls += [ep_url]
PASCAL = serviceCPPName mapping = { "SERVICE_NAME_UPPER": UPPER, "SERVICE_NAME_PASCAL": PASCAL, "SERVICE_NAMESPACE_START": "namespace " + service + " {\r\n", "SERVICE_NAMESPACE_USING": "using namespace " + service + ";\r\n", "SERVICE_NAMESPACE_END": "\r\n}\r\n", "SERVICE_STRUCTS": "", "SERVICE_MEMBER_FUNCTION_DEFINITIONS": "", "SERVICE_MEMBER_FUNCTION_IMPLEMENTATIONS": "" } for serviceEp in translations[service]: if safe_extract("hub_only", translations[service][serviceEp], False): continue parsed_service = parse_service(translations[service][serviceEp], service, serviceCPPName, serviceEp) mapping["SERVICE_STRUCTS"] += '\r\n'.join(parsed_service["structs"]) mapping["SERVICE_MEMBER_FUNCTION_DEFINITIONS"] += tab.join( parsed_service["hpp"]) + "\r\n" + tab mapping["SERVICE_MEMBER_FUNCTION_IMPLEMENTATIONS"] += ''.join( parsed_service["cpp"]) out_h_file = open(out_location + "/inc/" + serviceCPPName + ".h", "w") out_cpp_file = open( out_location + "/source/" + serviceCPPName + ".cpp", "w")
def processRESTRequest(self, url, request_type, translation, part): operation = translation[request_type] if "baseURL" in operation: baseURL = operation["baseURL"] urlFormat = [ x for x in operation["microbitQueryString"].split("/") if x ] #print "baseURL" #print baseURL # the following giant mess needs to be refactored at some point... but not now. if part == PKG_CARBON: res = 'OK' #print "Handle carbon package here" #print "method url" #print url if url[0] == "index": URLreq = baseURL + "intensity" try: r = requests.get(URLreq) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) response = json.loads(r.text) #print response['data'][0]['intensity'][url[0]] res = response['data'][0]['intensity'][url[0]] if url[0] == "value": URLreq = baseURL + "intensity" try: r = requests.get(URLreq) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) response = json.loads(r.text) if response['data'][0]['intensity']['actual'] is not None: res = str(response['data'][0]['intensity']['actual']) else: res = str(response['data'][0]['intensity']['forecast']) if url[0] == 'genmix': URLreq = baseURL + "generation" try: r = requests.get(URLreq) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) response = json.loads(r.text) genmix = response['data']['generationmix'] for gendata in genmix: if gendata['fuel'] == url[1]: res = str(gendata['perc']) break #print res self.returnPacket.append(res) return self.returnPacket.marshall(True) if part == PKG_ENERGY: res = "OK" #print "Handle energy package here" #print baseURL #print url if url[0] == "energyLevel": if url[1] == "0": URLreq = baseURL + "energy_type=ELECTRICITY" elif url[1] == "1": URLreq = baseURL + "energy_type=GAS" elif url[1] == "2": URLreq = baseURL + "energy_type=SOLAR" if url[2] == "local": URLreq = URLreq + "&location_uid=" + PI_HEADER['school-id'] else: URLreq = URLreq + "&location_uid=" + url[2] if len(url) > 3: if url[3] == "historical": today = datetime.datetime.today() if url[4] == "hour": n_hours = int(url[5]) FromDay = datetime.datetime.today() - timedelta( hours=n_hours) if url[4] == "day": n_days = int(url[5]) FromDay = datetime.datetime.today() - timedelta( days=n_days) if url[4] == "week": n_weeks = int(url[5]) FromDay = datetime.datetime.today() - timedelta( weeks=n_weeks) if url[4] == "month": n_months = int(url[5]) n_days = 30 * n_months FromDay = datetime.datetime.today() - timedelta( days=n_days) URLreq = URLreq + "&from=" + FromDay.strftime( '%Y-%m-%d %H:%M:%S.%f') + "&to=" + today.strftime( '%Y-%m-%d %H:%M:%S.%f') print URLreq try: resp = requests.get(URLreq, headers=PI_HEADER) print resp.status_code if resp.status_code == 200: resJson = json.loads(resp.text) if 'value' in resJson: res = str(resJson['value']) else: res = resJson else: res = 0 except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) self.returnPacket.append(res) return self.returnPacket.marshall(True) if part == PKG_ISS: res = "OK" #print url[0] try: resp = requests.get(baseURL) resJson = json.loads(resp.text) #print resJson if url[0] == "location": res = "Lat:" + \ str(round(resJson['latitude'], 4)) + \ ", Lon:" + str(round(resJson['longitude'], 4)) elif url[0] == "solarlocation": res = "Lat:" + \ str(round(resJson['solar_lat'], 4)) + \ ", Lon:" + str(round(resJson['solar_lon'], 4)) elif url[0] == "velocity": res = int(round(resJson[url[0]], 2)) elif url[0] == "altitude": res = int(round(resJson[url[0]], 2)) elif url[0] == "daynum": epoch = datetime.datetime.utcfromtimestamp(0) today = datetime.datetime.today() d = today - epoch res = d.days #res = int(round(resJson[url[0]],2)) elif url[0] in resJson: res = resJson[url[0]] except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) self.returnPacket.append(res) return self.returnPacket.marshall(True) if part == PKG_INIT: res = "OK" #print "Handle Init package here" #print "method url" #print url #print PI_ID id = self.rPacket.get(1) if id == "reset": if os.path.isfile(PERSIST_FILE): os.remove(PERSIST_FILE) #print "done" # else: #print "not done" elif url[0] == "piId" or url[0] == "schoolId": if self.PI_ID[url[0]] is None: self.PI_ID[url[0]] = id file = open(PERSIST_FILE, 'w') pickle.dump(self.PI_ID, file) file.close() print "OK" else: res = self.PI_ID[url[0]] print "Not OK" #print PI_ID[url[0]] self.returnPacket.append(res) return self.returnPacket.marshall(True) if part == PKG_SHARE: res = "OK" if PI_HEADER['school-id'] == None or PI_HEADER['pi-id'] == None: print "Check headers" print PI_HEADER #print "Handle share package here" #print "method url" #print url if url[0] == "fetchData": URLreq = baseURL + url[1] try: resp = requests.get(URLreq, headers=PI_HEADER) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) #print URLreq resJson = json.loads(resp.text) print resJson if 'value' in resJson: res = resJson['value'] else: res = "NOT FOUND" if url[0] == "shareData": jsonData = {'shared_with': 'SCHOOL', 'value': '0'} jsonData['value'] = self.rPacket.get(1) #jsonData['value'] = jsonData['description'] name = self.rPacket.get(2) URLreq = baseURL + name + "/" varType = self.rPacket.get(2) if varType == 0: jsonData['shared_with'] = 'ALL' else: jsonData['shared_with'] = 'SCHOOL' print jsonData try: resp = requests.post(URLreq, headers=PI_HEADER, data=jsonData) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) if url[0] == "historicalData": jsonData = { 'namespace': 'histery', 'name': ' ', 'type': 0, 'unit': ' ', 'time': ' ', 'value': ' ' } jsonData['value'] = self.rPacket.get(1) jsonData['name'] = self.rPacket.get(2) jsonData['namespace'] = self.rPacket.get(3) jsonData['unit'] = self.rPacket.get(4) jsonData['time'] = datetime.datetime.today().strftime( "%Y-%m-%d %H:%M:%S") URLreq = operation["extraURL"] #print jsonData try: resp = requests.post(URLreq, headers=PI_HEADER, data=jsonData) #print resp except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) #print resp self.returnPacket.append(res) return self.returnPacket.marshall(True) # map micro:bit query string to variables out = self.mapQueryString(url, urlFormat) #print "out maping" #print str(out) #print urlFormat # auth_token ='ddca3062-11ff-4116-87dc-36da9f01afe6' # hed = {'Authorization': 'Bearer ' + auth_token} # dataOn = {"commands":[{"component":"main","capability": "switch", "command":"on"}]} # dataOff = {"commands":[{"component":"main","capability": "switch", "command":"off"}]} # if part == PKG_IOT : # baseURL = "https://api.smartthings.com/v1/devices/1439773a-c144-41cd-9c5d-d1b03d3fe0a1/commands" # data1 = self.rPacket.get(1) # data2 = self.rPacket.get(2) # try: # if data2 == 1: # requests.post(baseURL, json=dataOn,headers=hed) # else: # requests.post(baseURL, json=dataOff,headers=hed) # except requests.exceptions.RequestException as e: # print "Connection error: {}".format(e) # self.returnPacket.append("API CONNECTION ERROR") # return self.returnPacket.marshall(True) # self.returnPacket.append("OK") # return self.returnPacket.marshall(True) if part == PKG_IOT: res = "OK" if PI_HEADER['school-id'] == None or PI_HEADER['pi-id'] == None: print "Check headers" print PI_HEADER if request_type == "GET": URLreq = baseURL + url[1] if url[0] == "bulbState" or url[0] == "switchState": URLreq = URLreq + "/switch/" elif url[0] == "bulbLevel": URLreq = URLreq + "/switch-level/" elif url[0] == "bulbTemp": URLreq = URLreq + "/color-temperature/" elif url[0] == "sensorState": URLreq = URLreq + "/motion/" elif url[0] == "sensorTemp": URLreq = URLreq + "/temperature/" elif url[0] == "bulbColour": URLreq = URLreq + "/color-control/" else: print "Unknown request!!!" self.returnPacket.append("Unknown request!!!") return self.returnPacket.marshall(True) try: #print "URLreq:", URLreq resp = requests.get(URLreq, headers=PI_HEADER) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) #print URLreq # response = {"device": "bulb", "status": {"level": "90","color": "unknown"}} response = json.loads(resp.text) #print response res = str(response['value']) # print res elif request_type == "POST": jsonData = {'value': 'off'} name = self.rPacket.get(1) URLreq = baseURL + name if url[0] == "bulbState" or url[0] == "switchState": URLreq = URLreq + "/switch/" switchState = self.rPacket.get(2) if switchState == 0: jsonData['value'] = 'off' else: jsonData['value'] = 'on' elif url[0] == "bulbLevel": URLreq = URLreq + "/switch-level/" level = self.rPacket.get(2) jsonData['value'] = level elif url[0] == "bulbTemp": URLreq = URLreq + "/color-temperature/" level = self.rPacket.get(2) jsonData['value'] = level elif url[0] == "bulbColour": URLreq = URLreq + "/color-control/" level = self.rPacket.get(2) jsonData['value'] = level else: print "Unknown request!!!" self.returnPacket.append("Unknown request!!!") return self.returnPacket.marshall(True) try: resp = requests.post(URLreq, headers=PI_HEADER, data=jsonData) except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) self.returnPacket.append("API CONNECTION ERROR") return self.returnPacket.marshall(True) #print resp self.returnPacket.append(res) return self.returnPacket.marshall(True) # any code above needs to be refactored. # if no endpoint is specified, set a default key value of none if out["endpoint"] is None: out["endpoint"] = "none" # if there is no matching endpoint return error packet if out["endpoint"] not in operation["endpoint"].keys(): raise self.rPacket.marshall(False) endpoint = operation["endpoint"][out["endpoint"]] # extract further objects from the packet against the keys specified in the parameters part of the translation, and join with `out` if "parameters" in endpoint.keys(): out = self.__join_dicts( out, self.extractFurtherObjects(1, endpoint["parameters"])) regexStrings = {} queryObject = safe_extract("queryObject", operation, {}) headers = safe_extract("headers", operation, {}) # for each query field in the queryobject extract the %variable_name% pattern. for param in queryObject: regexStrings[param] = re.findall(hub_regexp, queryObject[param]) # for each query field in the queryobject extract the %variable_name% pattern. for param in headers: regexStrings[param] = re.findall(hub_regexp, headers[param]) # attach any hub variables that may be required in the query string for param in self.hubVariables["query_string"]: # p is the value p = self.hubVariables["query_string"][param] # provide the regexp for each enter in the regex strings, and key, with no default for reg in regexStrings: regexStrings[reg] += [("%" + param + "%", param, '')] # set the corresponding value in the out obj out[param] = p # to simplify code, lets lump the base url (that may require regex'ing) into the queryobj regexStrings["baseURL"] = re.findall(hub_regexp, baseURL) queryObject["baseURL"] = baseURL self.replace_template_with_values(regexStrings, queryObject, out) self.replace_template_with_values(regexStrings, headers, out) # remove our now regexp'd baseURL from the query object baseURL = queryObject["baseURL"] del queryObject["baseURL"] try: if request_type == "GET": r = requests.get(baseURL, headers=headers, params=queryObject) elif request_type == "POST": r = requests.post(baseURL, headers=headers, data=queryObject) print "Request sent to: %s with headers: %s and data: %s" % ( baseURL, str(headers), str(queryObject)) print str(r) #TODO: handle bad status codes... except requests.exceptions.RequestException as e: print "Connection error: {}".format(e) return self.returnPacket.marshall(False) if "jsonPath" in endpoint.keys(): path = [x for x in endpoint["jsonPath"].split(".") if x] print path response = json.loads(r.text) jsonObj = self.__json_recursive_find__(path, response) returnVariables = endpoint["returns"] for ret in returnVariables: print jsonObj if ret["name"] in jsonObj: print jsonObj[ret["name"]] self.returnPacket.append(str(jsonObj[ret["name"]])) return self.returnPacket.marshall(True)