def test_invalid_call_params(self, _make_api_call):
        client = crossbarhttp.Client(self.__class__.url + "/call-signature",
                                     key="key", secret="secret")

        _make_api_call.return_value = "{}"

        result = client.call("test.add", 2, 3, offset=10)
        self.assertIsNone(result)
 def test_publish_signature(self):
     client = crossbarhttp.Client(self.__class__.url + "/publish-signature",
                                  key="key", secret="secret")
     publish_id = client.publish("test.publish", 4, 7, event="new event")
     self.assertIsNotNone(publish_id)
    def test_publish_bad_signature(self):
        client = crossbarhttp.Client(self.__class__.url + "/publish-signature",
                                     key="key", secret="bad secret")

        with self.assertRaises(crossbarhttp.ClientSignatureError) as context:
            client.publish("test.publish", 4, 7, event="new event")
    def test_publish_missing_signature_params(self):
        client = crossbarhttp.Client(self.__class__.url + "/publish-signature")

        with self.assertRaises(crossbarhttp.ClientMissingParams) as context:
            client.publish("test.publish", 4, 7, event="new event")
    def test_call_bad_signature(self):
        client = crossbarhttp.Client(self.__class__.url + "/call-signature",
                                     key="key", secret="bad secret")

        with self.assertRaises(crossbarhttp.ClientSignatureError) as context:
            client.call("test.add", 2, 3, offset=10)
    def test_call_missing_signature_params(self):
        client = crossbarhttp.Client(self.__class__.url + "/call-signature")

        with self.assertRaises(crossbarhttp.ClientMissingParams) as context:
            client.call("test.add", 2, 3, offset=10)
    def test_publish_bad_host(self):
        client = crossbarhttp.Client("http://bad:8080/publish")

        with self.assertRaises(crossbarhttp.ClientBadHost) as context:
            client.publish("test.publish", 4, 7, event="new event")
예제 #8
0
##
##  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
##  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
##  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
##  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
##  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
##  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
##  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
##  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
##  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
##  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
##  POSSIBILITY OF SUCH DAMAGE.
##
###############################################################################


import crossbarhttp

if __name__ == '__main__':
    # Create a new Crossbar.io push client (once), providing key/secret
    #
    client = crossbarhttp.Client("http://127.0.0.1:8080/publish-signed",
                                    key="foobar", secret="secret")

    # Publish an event with (positional) payload and get publication ID
    # Since we provided key/secret before, the request will be signed.
    #
    event_id = client.publish("com.myapp.topic1", "Hello, world!", 23)

    print("event published with ID {0}".format(event_id))
    def test_publish_bad_url(self):
        client = crossbarhttp.Client(self.__class__.url + "/publish_bad_url")

        with self.assertRaises(crossbarhttp.ClientBadUrl) as context:
            client.publish("test.publish", 4, 7, event="new event")
    def test_call_bad_url(self):
        client = crossbarhttp.Client(self.__class__.url + "/call_bad_url")

        with self.assertRaises(crossbarhttp.ClientBadUrl) as context:
            client.call("test.add", 2, 3, offset=10)
    def test_call_no_callee(self):
        client = crossbarhttp.Client(self.__class__.url + "/call")

        with self.assertRaises(crossbarhttp.ClientNoCalleeRegistered) as context:
            client.call("test.does_not_exist", 2, 3, offset=10)
 def test_publish(self):
     client = crossbarhttp.Client(self.__class__.url + "/publish")
     publish_id = client.publish("test.publish", 4, 7, event="new event")
     self.assertIsNotNone(publish_id)
 def test_call(self):
     client = crossbarhttp.Client(self.__class__.url + "/call")
     result = client.call("test.add", 2, 3, offset=10)
     self.assertEqual(result, 15)
 def test_call_exception(self):
     client = crossbarhttp.Client(self.__class__.url + "/call")
     with self.assertRaises(crossbarhttp.ClientCallRuntimeError) as context:
         client.call("test.exception")
    def test_no_call_params(self):
        client = crossbarhttp.Client(self.__class__.url + "/call")

        with self.assertRaises(crossbarhttp.ClientMissingParams) as context:
            client._make_api_call("POST", client.url)
 def test_verbose(self):
     client = crossbarhttp.Client(self.__class__.url + "/call-signature",
                                  key="key", secret="secret", verbose=True)
     result = client.call("test.add", 2, 3, offset=10)
     self.assertEqual(result, 15)
    def test_call_bad_host(self):
        client = crossbarhttp.Client("http://bad:8080/call")

        with self.assertRaises(crossbarhttp.ClientBadHost) as context:
            client.call("test.add", 2, 3, offset=10)
예제 #18
0
    def onJoin(self, details):

        try:
            self.log.info(str(TAG) + "Connecting to HTTP bridge")
            http_client = crossbarhttp.Client(http_bridge_url)
            http_client_connected = True
        except crossbarhttp.ClientBadHost:
            self.log.error(str(TAG) + "HTTP bridge unavailable")
            http_client_connected = False
        else:
            self.log.info(str(TAG) + "HTTP bridge connected")

        #RPC implementations in withings_rpc_handlers
        yield self.register(withings_energy, 'com.testlab.withings_energy')
        self.log.info(str(TAG) + "procedure withings_energy() registered")
        yield self.register(withings_activity, 'com.testlab.withings_activity')
        self.log.info(str(TAG) + "procedure withings_activity() registered")
        yield self.register(withings_sleep, 'com.testlab.withings_sleep')
        self.log.info(str(TAG) + "procedure withings_sleep() registered")
        yield self.register(withings_bloodpressure, 'com.testlab.withings_bloodpressure')
        self.log.info(str(TAG) + "procedure withings_bloodpressure() registered")
        yield self.register(withings_bodytemperature, 'com.testlab.withings_bodytemperature')
        self.log.info(str(TAG) + "procedure withings_bodytemperature() registered")
        yield self.register(withings_average_heartrate, 'com.testlab.withings_average_heartrate')
        self.log.info(str(TAG) + "procedure withings_average_heartrate() registered")

        #fetch initial datasets for userids
        for i in range (0, len(user_ids)):
            user_id = str(user_ids[i])
            if user_id == '0': continue
            credentials = WithingsCredentials(user_access_tokens[i], user_access_secret[i], withings_api_token, withings_api_secret, user_ids[i])
            withings_client = WithingsApi(credentials)
            energy_data[user_id], activity_data[user_id] = get_energy_and_activity(user_ids[i], withings_client)
            sleep_data[user_id] = get_sleep(user_ids[i], withings_client)
            heartrate_data[user_id], bloodpressure_data[user_id], bodytemperature_data[user_id] = get_measurement_data(user_ids[i], withings_client)

        while True:
            for i in range (0, len(user_ids)):
                user_id = str(user_ids[i])
                if user_id == '0':
                    continue

                #get credentials for this user and authenticate
                credentials = WithingsCredentials(user_access_tokens[i], user_access_secret[i], withings_api_token, withings_api_secret, user_id)
                withings_client = WithingsApi(credentials)

                # get the dates beforehand for easy usage
                today = datetime.date.today()
                startdate = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
                enddate = datetime.datetime.today().replace(hour=23, minute=59, second=59, microsecond=999)
                startepoch = startdate.timestamp()
                endepoch = enddate.timestamp()

                measures = []
                temp_activity = {}
                temp_sleep = {}
                temp_bloodpressure = {}

                try:
                    #fetch updated data for this user:
                    temp_activity = withings_client.get_activity(startdateymd=today, enddateymd=today)
                    temp_sleep = withings_client.get_sleepsummary(startdateymd=today - datetime.timedelta(days=1), enddateymd=today)
                    for m in meastype: measures.append(withings_client.get_measures(lastupdate=startepoch, meastype=m))
                except ConnectionError:
                    self.log.error(str(TAG) + "Withings Connection Error. Check connectivity and / or connection parameters and try again!")
                    yield sleep(60)
                    continue
                except WithingsAPIError as w:
                    self.log.error(str(TAG) + "Withings API Error: {}".format(w.message))
                    yield sleep(60)
                    continue

                #parse for updates in activity and energy and publish data
                try:
                    for record in temp_activity['activities']:
                        date = parse(record['date']).strftime('%Y-%m-%d')
                        steps = record['steps']
                        calories = record['calories'] + record['totalcalories']
                        try:
                            position = get_list_index(activity_data[user_id], 0, date) #raises ValueError if date is not found
                            if activity_data[user_id][position][1] != steps:
                                self.log.info(str(TAG) + "publishing to 'Withings Activity Update' with {userid} {date} {old} -> {result}", userid=user_id, date=date, old=activity_data[user_id][position][1], result=steps)
                                activity_data[user_id] = update_list_entry(activity_data[user_id], date, steps)
                                yield self.publish('com.testlab.withings_activity_update', [user_id, date, steps])
                        except ValueError:
                            activity_data[user_id].append([date, steps])
                            yield self.publish('com.testlab.withings_activity_update', [user_id, date, steps])
                            self.log.info(str(TAG) + "publishing to 'Withings Activity Update' with {userid} {date} {result}", userid=user_id, date=date, result=steps)

                        try:
                            position = get_list_index(energy_data[user_id], 0, date) #raises ValueError if date is not found
                            if energy_data[user_id][position][1] != calories:
                                self.log.info(str(TAG) + "publishing to 'Withings Energy Update' with {userid} {date} {old} -> {result}", userid=user_id, date=date, old=energy_data[user_id][position][1], result=calories)
                                energy_data[user_id][get_list_index(activity_data[user_id], 0, date)][1] = calories
                                yield self.publish('com.testlab.withings_energy_update', [user_id, date, calories])
                        except ValueError:
                            energy_data[user_id].append([date, calories])
                            yield self.publish('com.testlab.withings_energy_update', [user_id, date, calories])
                            self.log.info(str(TAG) + "publishing to 'Withings Energy Update' with {userid} {date} {result}", userid=user_id, date=date, result=calories)
                except KeyError:
                    pass

                #parse for updates in sleep statistics and publish new data
                try:
                    for record in temp_sleep['series']:
                        date = parse(record['date']).strftime('%Y-%m-%d')
                        duration = float((record['data']['deepsleepduration'] + record['data']['lightsleepduration'])) / 60 / 60
                        try:
                            position = get_list_index(sleep_data[user_id], 0, date) #raises ValueError if date is not found
                            if sleep_data[user_id][position][1] != duration and sleep_data[user_id][position][1] < duration: #and the value is different than current
                                self.log.info(str(TAG) + "publishing to 'Withings Sleep Update' with {userid} {date} {old} -> {result}", userid=user_id, date=date, old=sleep_data[user_id][position][1], result=duration)
                                sleep_data[user_id][position][1] = duration #update the field and publish
                                yield self.publish('com.testlab.withings_sleep_update', [user_id, date, duration])
                        except ValueError:
                            sleep_data[user_id].append([date, duration])
                            yield self.publish('com.testlab.withings_sleep_update', [user_id, date, duration])
                            self.log.info(str(TAG) + "publishing to 'Withings Sleep Update' with {userid} {date} {result}", userid=user_id, date=date, result=duration)
                except KeyError:
                    pass

                #loop through measurements and publish new information if necessary
                for measure in measures:
                    for measuregroup in measure:
                        for result in measuregroup.measures:
                            date = measuregroup.date.strftime('%Y-%m-%d %H:%M:%S')
                            value = normalize_value(result['value'], result['unit'])

                            if(result["type"] == 11): #Average Heartrate
                                #check if results are identical. If not, update
                                if len([item for item in heartrate_data[user_id] if item[0] == date]) >= 1:
                                    if heartrate_data[user_id][get_list_index(heartrate_data[user_id], 0, date)][1] != value:
                                        self.log.info(str(TAG) + "publishing to 'Withings HR Update' with {userid} {date} {old} -> {result}", userid=user_id, date=date, old=heartrate_data[user_id][get_list_index(heartrate_data[user_id], 0, date)][1], result=value)
                                        heartrate_data[user_id][get_list_index(heartrate_data[user_id], 0, date)][1] = value
                                        yield self.publish('com.testlab.withings_heartrate_update', [user_id, date, value])
                                else:
                                    self.log.info(str(TAG) + "publishing to 'Withings HR Update' with {userid} {date} {result}", userid=user_id, date=date, result=value)
                                    heartrate_data[user_id].append([date, value])
                                    yield self.publish('com.testlab.withings_heartrate_update', [user_id, date, value])

                            elif(result["type"] == 71): #Body Temperature
                                #check if results are identical. If not, update
                                if len([item for item in bodytemperature_data[user_id] if item[0] == date]) >= 1:
                                    if bodytemperature_data[user_id][get_list_index(bodytemperature_data[user_id], 0, date)][1] != value:
                                        self.log.info(str(TAG) + "publishing to 'Withings BodyTemp Update' with {userid} {date} {old} -> {result}", userid=user_id, date=date, old=bodytemperature_data[user_id][get_list_index(bodytemperature_data[user_id], 0, date)][1], result=value)
                                        bodytemperature_data[user_id][get_list_index(bodytemperature_data[user_id], 0, date)][1] = value
                                        yield self.publish('com.testlab.withings_bodytemp_update', [user_id, date, value])
                                else:
                                    self.log.info(str(TAG) + "publishing to 'Withings BodyTemp Update' with {userid} {date} {result}", userid=user_id, date=date, result=value)
                                    bodytemperature_data[user_id].append([date, value])
                                    yield self.publish('com.testlab.withings_bodytemp_update', [user_id, date, value])

                            elif(result["type"] == 10): #Systolic BP
                                temp_bloodpressure[date] = []
                                temp_bloodpressure[date].append(value)

                            elif(result["type"] == 9): #Diastolic BP
                                try:
                                    temp_bloodpressure[date].append(value)
                                except KeyError:
                                    self.log.error("Invalid blood pressure reading. Skipping!")
                                    continue

                                #check if results are identical. If not, update
                                if len([item for item in bloodpressure_data[user_id] if item[0] == date]) >= 1:
                                    if len(set(bloodpressure_data[user_id][get_list_index(bloodpressure_data[user_id], 0, date)][1]).intersection(temp_bloodpressure[date])) < 2:
                                        self.log.info(str(TAG) + "publishing to 'Withings BP Update' with {date} {old} -> {result}", date=date, old=bloodpressure_data[user_id][get_list_index(bloodpressure_data[user_id], 0, date)][1], result=temp_bloodpressure[date])
                                        bloodpressure_data[user_id][get_list_index(heartrate_data[user_id], 0, date)][1] = temp_bloodpressure[date]
                                        yield self.publish('com.testlab.withings_bloodpressure_update', [user_id, date, temp_bloodpressure[date]])
                                else:
                                    self.log.info(str(TAG) + "publishing to 'Withings BP Update' with {userid} {date} {result}", userid=user_id, date=date, result=temp_bloodpressure[date])
                                    bloodpressure_data[user_id].append([date, temp_bloodpressure[date]])
                                    yield self.publish('com.testlab.withings_bloodpressure_update', [user_id, date, temp_bloodpressure[date]])
            yield sleep(30)