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")
## ## 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)
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)