Esempio n. 1
0
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
Esempio n. 2
0
    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
Esempio n. 3
0
    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]
Esempio n. 4
0
    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")
Esempio n. 5
0
    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)