示例#1
0
 def setUp(self):
     self.mock_api = True
     if self.mock_api:
         self.creds = NokiaCredentials()
     else:
         config = configparser.ConfigParser()
         config.read('nokia.conf')
         self.creds = NokiaCredentials(
             consumer_key=config.get('nokia', 'consumer_key'),
             consumer_secret=config.get('nokia', 'consumer_secret'),
             access_token=config.get('nokia', 'access_token'),
             access_token_secret=config.get('nokia', 'access_token_secret'),
             user_id=config.get('nokia', 'user_id'))
     self.api = NokiaApi(self.creds)
 def test_attributes(self):
     """
     Make sure the NokiaCredentials objects have the right attributes
     """
     creds = NokiaCredentials(access_token=1,
                              token_expiry=2,
                              token_type=3,
                              refresh_token=4,
                              user_id=5,
                              client_id=6,
                              consumer_secret=7)
     assert hasattr(creds, 'access_token')
     self.assertEqual(creds.access_token, 1)
     assert hasattr(creds, 'token_expiry')
     self.assertEqual(creds.token_expiry, 2)
     assert hasattr(creds, 'token_type')
     self.assertEqual(creds.token_type, 3)
     assert hasattr(creds, 'refresh_token')
     self.assertEqual(creds.refresh_token, 4)
     assert hasattr(creds, 'user_id')
     self.assertEqual(creds.user_id, 5)
     assert hasattr(creds, 'client_id')
     self.assertEqual(creds.client_id, 6)
     assert hasattr(creds, 'consumer_secret')
     self.assertEqual(creds.consumer_secret, 7)
示例#3
0
 def test_attributes(self):
     """ Make sure the NokiaApi objects have the right attributes """
     assert hasattr(NokiaApi, 'URL')
     creds = NokiaCredentials(user_id='FAKEID')
     api = NokiaApi(creds)
     assert hasattr(api, 'credentials')
     assert hasattr(api, 'oauth')
     assert hasattr(api, 'client')
示例#4
0
 def test_attributes(self):
     """ Make sure the NokiaApi objects have the right attributes """
     assert hasattr(NokiaApi, 'URL')
     creds = NokiaCredentials(user_id='FAKEID', token_expiry='123412341234')
     api = NokiaApi(creds)
     assert hasattr(api, 'credentials')
     assert hasattr(api, 'token')
     assert hasattr(api, 'client')
     assert hasattr(api, 'refresh_cb')
示例#5
0
 def test_attribute_defaults(self):
     """
     Make sure NokiaApi object attributes have the correct defaults
     """
     self.assertEqual(NokiaApi.URL, 'https://api.health.nokia.com')
     creds = NokiaCredentials(user_id='FAKEID')
     api = NokiaApi(creds)
     self.assertEqual(api.credentials, creds)
     self.assertEqual(api.client.auth, api.oauth)
     self.assertEqual(api.client.params, {'userid': creds.user_id})
示例#6
0
 def test_attribute_defaults(self):
     """
     Make sure NokiaCredentials attributes have the proper defaults
     """
     creds = NokiaCredentials()
     self.assertEqual(creds.access_token, None)
     self.assertEqual(creds.access_token_secret, None)
     self.assertEqual(creds.consumer_key, None)
     self.assertEqual(creds.consumer_secret, None)
     self.assertEqual(creds.user_id, None)
示例#7
0
 def test_attribute_defaults(self):
     """
     Make sure NokiaApi object attributes have the correct defaults
     """
     self.assertEqual(NokiaApi.URL, 'https://api.health.nokia.com')
     creds = NokiaCredentials(user_id='FAKEID', token_expiry='123412341234')
     api = NokiaApi(creds)
     self.assertEqual(api.credentials, creds)
     self.assertEqual(api.client.params, {})
     self.assertEqual(api.client.token, api.token)
     self.assertEqual(api.refresh_cb, None)
示例#8
0
 def __init__(self, config):
     """Initialize the data object."""
     from nokia import NokiaApi, NokiaCredentials
     credentials = NokiaCredentials(config.get("access_token"),
                                    config.get("access_token_secret"),
                                    config.get("consumer_key"),
                                    config.get("consumer_secret"),
                                    config.get("user_id"))
     self._api = NokiaApi(credentials)
     self.data = None
     self._update()
示例#9
0
def nokia_creds(token_dict):
    '''
    :param token_dict:
    :return: Nokia Credentials Object
    '''
    return NokiaCredentials(client_id=client_id,
                            consumer_secret=client_secret,
                            access_token=token_dict['access_token'],
                            token_expiry=token_dict['token_expiry'],
                            token_type=token_dict['token_type'],
                            user_id=token_dict['user_id'],
                            refresh_token=token_dict['refresh_token'])
示例#10
0
 def setUp(self):
     self.mock_api = True
     creds_attrs = [
         'access_token',
         'token_expiry',
         'token_type',
         'refresh_token',
         'user_id',
         'client_id',
         'consumer_secret',
     ]
     if self.mock_api:
         creds_args = {a: 'fake' + a for a in creds_attrs}
         creds_args.update({
             'token_expiry': '123412341234',
             'token_type': 'Bearer',
         })
         self.creds = NokiaCredentials(**creds_args)
     else:
         config = configparser.ConfigParser()
         config.read('nokia.conf')
         creds_args = {a: config.get('nokia', a) for a in creds_attrs}
         self.creds = NokiaCredentials(**creds_args)
     self.api = NokiaApi(self.creds)
示例#11
0
    def __init__(self, smarthome, consumer_key, consumer_secret, access_token, access_token_secret, user_id, cycle=300):
        self.logger = logging.getLogger(__name__)
        self._sh = smarthome
        self._consumer_key = consumer_key
        self._consumer_secret = consumer_secret
        self._access_token = access_token
        self._access_token_secret = access_token_secret
        self._auth = NokiaAuth(self._consumer_key, self._consumer_secret)
        self._user_id = user_id
        self._creds = NokiaCredentials(self._access_token, self._access_token_secret, self._consumer_key,
                                       self._consumer_secret, self._user_id)
        self._client = NokiaApi(self._creds)

        self._cycle = cycle
        self._items = {}

        if not self.init_webinterface():
            self._init_complete = False
示例#12
0
def refresh_weight(cfg_file, engine, db_df):
    print("REFRESHING WEIGHT...")
    parser = configparser.ConfigParser()
    parser.read(cfg_file)
    client_id = parser.get('nokia', 'client_id')
    client_secret = parser.get('nokia', 'client_secret')
    access_token = parser.get('nokia', 'access_token')
    token_expiry = parser.get('nokia', 'token_expiry')
    token_type = parser.get('nokia', 'token_type')
    refresh_token = parser.get('nokia', 'refresh_token')
    user_id = parser.get('nokia', 'user_id')

    creds = NokiaCredentials(access_token=access_token,
                             token_expiry=token_expiry,
                             token_type=token_type,
                             refresh_token=refresh_token,
                             user_id=user_id,
                             client_id=client_id,
                             consumer_secret=client_secret)
    client = NokiaApi(
        creds, refresh_cb=(lambda x: persist_nokia_refresh_token(x, cfg_file)))

    [date_start, date_end] = get_target_date_endpoints('weight', db_df)
    date_query = date_start
    date_diff = date_end - date_query
    days = date_diff.days + 2

    measures = client.get_measures(meastype=1, limit=days)
    weight_json = [{
        'weight': (float("{:.1f}".format(x.weight * 2.20462))),
        'date': x.date.strftime('%Y-%m-%d')
    } for x in measures]
    date_values = [[pd.to_datetime(x['date']), x['weight']]
                   for x in weight_json]
    date_values_imp = [[pd.to_datetime(x['date']), np.nan]
                       for x in weight_json]
    updated_df = insert_values(date_values, 'weight', db_df)
    updated_df = insert_values(date_values_imp, 'weight_imputed', updated_df)

    with engine.connect() as conn, conn.begin():
        updated_df.to_sql('fitness', conn, if_exists='replace')

    return updated_df
示例#13
0
    def test_set_token_refresh_cb(self):
        """
        Make sure set_token calls refresh_cb when specified
        """
        timestamp = int((datetime.datetime.utcnow() -
                         datetime.datetime(1970, 1, 1)).total_seconds())
        creds = NokiaCredentials(token_expiry=timestamp)
        refresh_cb = MagicMock()
        api = NokiaApi(creds, refresh_cb=refresh_cb)
        token = {
            'access_token': 'fakeat',
            'refresh_token': 'fakert',
            'expires_in': 100,
        }

        api.set_token(token)

        self.assertEqual(api.token, token)
        refresh_cb.assert_called_once_with(token)
示例#14
0
 def test_attributes(self):
     """
     Make sure the NokiaCredentials objects have the right attributes
     """
     creds = NokiaCredentials(access_token=1,
                              access_token_secret=1,
                              consumer_key=1,
                              consumer_secret=1,
                              user_id=1)
     assert hasattr(creds, 'access_token')
     self.assertEqual(creds.access_token, 1)
     assert hasattr(creds, 'access_token_secret')
     self.assertEqual(creds.access_token_secret, 1)
     assert hasattr(creds, 'consumer_key')
     self.assertEqual(creds.consumer_key, 1)
     assert hasattr(creds, 'consumer_secret')
     self.assertEqual(creds.consumer_secret, 1)
     assert hasattr(creds, 'user_id')
     self.assertEqual(creds.user_id, 1)
示例#15
0
def main():
    try:
        # Let's try to load up the config file...
        with open(CFN) as cf:
            c = json.load(cf)
        creds = NokiaCredentials(
            access_token=c['access_token'],
            token_expiry=c['token_expiry'],
            token_type=c['token_type'],
            refresh_token=c['refresh_token'],
            user_id=c['user_id'],
            client_id=c['client_id'],
            consumer_secret=c['consumer_secret'],
        )
    except:
        # Can't get credentials, let's go through the process...
        creds = nokia_auth()

    # And now we're ready to get our weights...
    get_weight(creds)
示例#16
0
    def test_set_token(self):
        """
        Make sure NokiaApi.set_token makes the expected changes
        """
        timestamp = int((datetime.datetime.utcnow() -
                         datetime.datetime(1970, 1, 1)).total_seconds())
        creds = NokiaCredentials(token_expiry=timestamp)
        api = NokiaApi(creds)
        token = {
            'access_token': 'fakeat',
            'refresh_token': 'fakert',
            'expires_in': 100,
        }

        api.set_token(token)

        self.assertEqual(api.token, token)
        self.assertEqual(api.get_credentials().access_token, 'fakeat')
        self.assertEqual(api.get_credentials().refresh_token, 'fakert')
        # Need to check 100 or 101 in case a second ticked over during testing
        self.assertTrue(
            int(api.credentials.token_expiry) == (timestamp + 100)
            or int(api.credentials.token_expiry) == (timestamp + 101))
示例#17
0
def nokia_sync(force=False):
    config = get_config()

    n = config['nokia']
    creds = NokiaCredentials(n['access_token'], n['token_expiry'],
                             n['token_type'], n['refresh_token'], n['user_id'],
                             n['client_id'], n['consumer_secret'])

    nokia_client = NokiaApi(creds, refresh_cb=nokia_refresh_cb)

    measures = nokia_client.get_measures()
    measure = measures[0]

    logger.info('Recieved {} measurements'.format(len(measures)))

    # Now check if we need to update
    last_update = max([m.date.timestamp for m in measures])

    logger.info('Last measurement at {}'.format(last_update))
    logger.info('Last update at {}'.format(config['nokia']['last_update']))

    if (config['nokia']['last_update'] >= last_update) and not force:
        logger.info('No new weight updates')
        return measures

    msg = ''

    fit = FitEncoder_Weight()
    fit.write_file_info()
    fit.write_file_creator()
    fit.write_device_info(datetime.timestamp(datetime.now()))

    for measure in measures:
        if (config['nokia']['last_update'] < measure.date.timestamp) or force:

            if measure.weight is not None:
                bmi = measure.weight / config['nokia']['height']**2

                msg += 'New measurement at {} ({})\n'.format(
                    str(measure.date.datetime), measure.date.humanize())

                msg += 'New weight = {} kg\n'.format(measure.weight)
                msg += 'New fat ratio= {} %\n'.format(measure.fat_ratio)
                msg += 'New hydration = {} %\n'.format(measure.hydration)
                msg += 'New bone mass = {} kg\n'.format(measure.bone_mass)
                msg += 'New muscle mass = {} kg\n'.format(measure.muscle_mass)
                msg += 'Calculated BMI = {} kg.m^-2\n'.format(bmi)

                for m in msg.splitlines():
                    logger.info(m)

                # Sync Garmin

                logger.info('Syncing weight of {} with GARMIN.'.format(
                    measure.weight))

                fit.write_weight_scale(timestamp=measure.date.timestamp,
                                       weight=measure.weight,
                                       percent_fat=measure.fat_ratio,
                                       percent_hydration=measure.hydration,
                                       bone_mass=measure.bone_mass,
                                       muscle_mass=measure.muscle_mass,
                                       bmi=bmi)

    fit.finish()

    with GarminClient(config['garmin']['username'],
                      config['garmin']['password']) as client:
        client.upload_activity(io.BytesIO(fit.getvalue()), 'fit')

    # Sync Strava

    measure = measures[0]
    ts = datetime.timestamp(datetime.now())
    ts -= (config['nokia']['weight_int'] * 86400)
    weight = [m.weight for m in measures if m.date.timestamp >= ts]

    logger.info("Averaging {} weight measurements".format(len(weight)))

    weight = mean(weight)

    if (config['nokia']['last_update'] != measure.date.timestamp) or force:
        logger.info('Syncing weight of {} with STRAVA.'.format(measure.weight))
        strava = Strava(config['strava'])
        strava_token = strava.connect()
        config['strava'] = strava_token
        strava.client.update_athlete(weight=weight)

        msg += 'Synced weight of {} with Strava\n'.format(measure.weight)

    config = get_config()
    config['nokia']['last_update'] = max([m.date.timestamp for m in measures])
    write_config(config)

    send_email('New Weight Sync', msg)

    return measures
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Authenticate to the Withings API."""
    from nokia import NokiaApi, NokiaAuth, NokiaCredentials

    hass.http.register_view(WithingsAuthCallbackView())

    client_id = config.get(CONF_CLIENT_ID)
    consumer_secret = config.get(CONF_CONSUMER_SECRET)

    config_path = hass.config.path(WITHINGS_CONFIG_PATH)

    @asyncio.coroutine
    def _read_config():
        if not os.path.isfile(config_path):
            return None
        with open(config_path, 'r') as auth_file:
            config = json.load(auth_file)
            if config.get('client_id') == client_id:
                return config

    @asyncio.coroutine
    def _write_config(creds):
        with open(config_path, 'w') as auth_file:
            json.dump(
                {
                    'client_id': client_id,
                    'access_token': creds.access_token,
                    'refresh_token': creds.refresh_token,
                    'token_type': creds.token_type,
                    'token_expiry': creds.token_expiry,
                    'user_id': creds.user_id,
                }, auth_file)

    @asyncio.coroutine
    def _add_device(creds):
        client = NokiaApi(creds)
        withings = WithingsSensor(hass, client)
        yield from withings.async_update()
        return async_add_devices([withings])

    config = yield from _read_config()
    if config is not None:
        creds = NokiaCredentials(client_id=client_id,
                                 consumer_secret=consumer_secret,
                                 access_token=config['access_token'],
                                 token_expiry=config['token_expiry'],
                                 token_type=config['token_type'],
                                 refresh_token=['refresh_token'],
                                 user_id=config['user_id'])
        yield from _add_device(creds)
    else:
        callback_uri = '{}{}'.format(hass.config.api.base_url,
                                     WithingsAuthCallbackView.url)
        auth = NokiaAuth(client_id,
                         consumer_secret,
                         callback_uri=callback_uri,
                         scope='user.info,user.metrics,user.activity')
        authorize_url = auth.get_authorize_url()

        configurator = hass.components.configurator
        request_id = configurator.async_request_config(
            "Withings",
            description="Authorization required for Withings account.",
            link_name="Authorize Home Assistant",
            link_url=authorize_url,
            entity_picture='/local/images/logo_nokia_health_mate.png')

    @asyncio.coroutine
    def initialize_callback(code):
        """Handle OAuth callback from Withings authorization flow."""
        creds = auth.get_credentials(code)
        yield from _write_config(creds)
        yield from _add_device(creds)
        configurator.async_request_done(request_id)

    hass.data[DATA_CALLBACK] = initialize_callback
    return True
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Authenticate to the Nokia Health API."""
    from nokia import NokiaApi, NokiaAuth, NokiaCredentials

    hass.http.register_view(NokiaAuthCallbackView())

    consumer_key = config.get(CONF_CONSUMER_KEY)
    consumer_secret = config.get(CONF_CONSUMER_SECRET)

    config_path = hass.config.path(NOKIA_CONFIG_PATH)

    @asyncio.coroutine
    def _read_config():
        if not os.path.isfile(config_path):
            return None
        with open(config_path, 'r') as auth_file:
            config = json.load(auth_file)
            if config['consumer_key'] == consumer_key:
                return config

    @asyncio.coroutine
    def _write_config(creds):
        with open(config_path, 'w') as auth_file:
            json.dump(
                {
                    'consumer_key': consumer_key,
                    'access_token': creds.access_token,
                    'access_token_secret': creds.access_token_secret,
                    'user_id': creds.user_id,
                }, auth_file)

    @asyncio.coroutine
    def _add_device(creds):
        client = NokiaApi(creds)
        nokia = NokiaSensor(hass, client)
        yield from nokia.async_update()
        return async_add_devices([nokia])

    config = yield from _read_config()
    if config is not None:
        creds = NokiaCredentials(config['access_token'],
                                 config['access_token_secret'], consumer_key,
                                 consumer_secret, config['user_id'])
        yield from _add_device(creds)
    else:
        auth = NokiaAuth(consumer_key, consumer_secret)
        callback_uri = '{}{}'.format(hass.config.api.base_url,
                                     NokiaAuthCallbackView.url)
        authorize_url = auth.get_authorize_url(callback_uri=callback_uri)

        configurator = hass.components.configurator
        request_id = configurator.async_request_config(
            "Nokia Health",
            description="Authorization required for Nokia Health account.",
            link_name="Authorize Home Assistant",
            link_url=authorize_url,
            entity_picture='/local/images/logo_nokia_health_mate.png')

    @asyncio.coroutine
    def initialize_callback(oauth_verifier):
        """Handle OAuth callback from Nokia authorization flow."""
        creds = auth.get_credentials(oauth_verifier)
        yield from _write_config(creds)
        yield from _add_device(creds)
        configurator.async_request_done(request_id)

    hass.data[DATA_CALLBACK] = initialize_callback
    return True
示例#20
0
 def test_get_credentials(self):
     """
     Make sure NokiaApi returns the credentials as expected
     """
     creds = NokiaCredentials(token_expiry=0)
     api = NokiaApi(creds)
示例#21
0
    def _update(self):
        """
        Updates information on diverse items
        Mappings:
        ('weight', 1),
        ('height', 4),
        ('fat_free_mass', 5),
        ('fat_ratio', 6),
        ('fat_mass_weight', 8),
        ('diastolic_blood_pressure', 9),
        ('systolic_blood_pressure', 10),
        ('heart_pulse', 11),
        ('temperature', 12),
        ('spo2', 54),
        ('body_temperature', 71),
        ('skin_temperature', 72),
        ('muscle_mass', 76),
        ('hydration', 77),
        ('bone_mass', 88),
        ('pulse_wave_velocity', 91)
        """

        if 'access_token' not in self.get_items(
        ) or 'token_expiry' not in self.get_items(
        ) or 'token_type' not in self.get_items(
        ) or 'refresh_token' not in self.get_items():
            self.logger.error(
                "Plugin '{}': Mandatory Items for OAuth2 Data do not exist. Verify that you have items with withings_type: token_expiry, token_type, refresh_token and access_token in your item tree."
                .format(self.get_fullname()))
            return

        if self._client is None:
            if self.get_item('access_token')(
            ) and self.get_item('token_expiry')() > 0 and self.get_item(
                    'token_type')() and self.get_item('refresh_token')():

                if (self.shtime.now() < datetime.datetime.fromtimestamp(
                        self.get_item('token_expiry')(),
                        tz=self.shtime.tzinfo())):
                    self.logger.debug(
                        "Plugin '{}': Token is valid, will expire on {}.".
                        format(
                            self.get_fullname(),
                            datetime.datetime.fromtimestamp(
                                self.get_item('token_expiry')(),
                                tz=self.shtime.tzinfo()).strftime(
                                    '%d.%m.%Y %H:%M:%S')))
                    self.logger.debug(
                        "Plugin '{}': Initializing NokiaCredentials: access_token - {} token_expiry - {} token_type - {} refresh_token - {} user_id - {} client_id - {} consumer_secret - {}"
                        .format(self.get_fullname(),
                                self.get_item('access_token')(),
                                self.get_item('token_expiry')(),
                                self.get_item('token_type')(),
                                self.get_item('refresh_token')(),
                                self._user_id, self._client_id,
                                self._consumer_secret))
                    self._creds = NokiaCredentials(
                        self.get_item('access_token')(),
                        self.get_item('token_expiry')(),
                        self.get_item('token_type')(),
                        self.get_item('refresh_token')(), self._user_id,
                        self._client_id, self._consumer_secret)
                    self._client = NokiaApi(self._creds,
                                            refresh_cb=self._store_tokens)
                else:
                    self.logger.error(
                        "Plugin '{}': Token is expired, run OAuth2 again from Web Interface (Expiry Date: {})."
                        .format(
                            self.get_fullname(),
                            datetime.datetime.fromtimestamp(
                                self.get_item('token_expiry')(),
                                tz=self.shtime.tzinfo()).strftime(
                                    '%d.%m.%Y %H:%M:%S')))
                    return
            else:
                self.logger.error(
                    "Plugin '{}': Items for OAuth2 Data are not set with required values. Please run process via WebGUI of the plugin."
                    .format(self.get_fullname()))
                return
        measures = self._client.get_measures()
        last_measure = measures[0]

        if last_measure.get_measure(
                11) is not None and 'heart_pulse' in self._items:
            self._items['heart_pulse'](last_measure.get_measure(11))
            self.logger.debug("Plugin '{}': heart_pulse - {}".format(
                self.get_fullname(), last_measure.get_measure(11)))

        # Bugfix for strange behavior of returning heart_pulse as seperate dataset..
        if last_measure.get_measure(1) is None:
            last_measure = measures[1]

        if last_measure.get_measure(1) is not None and 'weight' in self._items:
            self._items['weight'](last_measure.get_measure(1))
            self.logger.debug("Plugin '{}': weight - {}".format(
                self.get_fullname(), last_measure.get_measure(1)))

        if last_measure.get_measure(4) is not None and 'height' in self._items:
            self._items['height'](last_measure.get_measure(4))
            self.logger.debug("Plugin '{}': height - {}".format(
                self.get_fullname(), last_measure.get_measure(4)))

        if last_measure.get_measure(
                5) is not None and 'fat_free_mass' in self._items:
            self._items['fat_free_mass'](last_measure.get_measure(5))
            self.logger.debug("Plugin '{}': fat_free_mass - {}".format(
                self.get_fullname(), last_measure.get_measure(5)))

        if last_measure.get_measure(
                6) is not None and 'fat_ratio' in self._items:
            self._items['fat_ratio'](last_measure.get_measure(6))
            self.logger.debug("Plugin '{}': fat_ratio - {}".format(
                self.get_fullname(), last_measure.get_measure(6)))

        if last_measure.get_measure(
                8) is not None and 'fat_mass_weight' in self._items:
            self._items['fat_mass_weight'](last_measure.get_measure(8))
            self.logger.debug("Plugin '{}': fat_mass_weight - {}".format(
                self.get_fullname(), last_measure.get_measure(8)))

        if last_measure.get_measure(
                9) is not None and 'diastolic_blood_pressure' in self._items:
            self._items['diastolic_blood_pressure'](
                last_measure.get_measure(9))
            self.logger.debug(
                "Plugin '{}': diastolic_blood_pressure - {}".format(
                    self.get_fullname(), last_measure.get_measure(9)))

        if last_measure.get_measure(
                10) is not None and 'systolic_blood_pressure' in self._items:
            self._items['systolic_blood_pressure'](
                last_measure.get_measure(10))
            self.logger.debug(
                "Plugin '{}': systolic_blood_pressure - {}".format(
                    self.get_fullname(), last_measure.get_measure(10)))

        if last_measure.get_measure(
                11) is not None and 'heart_pulse' in self._items:
            self._items['heart_pulse'](last_measure.get_measure(11))
            self.logger.debug("Plugin '{}': heart_pulse - {}".format(
                self.get_fullname(), last_measure.get_measure(11)))

        if last_measure.get_measure(
                12) is not None and 'temperature' in self._items:
            self._items['temperature'](last_measure.get_measure(12))
            self.logger.debug("Plugin '{}': temperature - {}".format(
                self.get_fullname(), last_measure.get_measure(12)))

        if last_measure.get_measure(54) is not None and 'spo2' in self._items:
            self._items['spo2'](last_measure.get_measure(54))
            self.logger.debug("Plugin '{}': spo2 - {}".format(
                self.get_fullname(), last_measure.get_measure(54)))

        if last_measure.get_measure(
                71) is not None and 'body_temperature' in self._items:
            self._items['body_temperature'](last_measure.get_measure(71))
            self.logger.debug("Plugin '{}': body_temperature - {}".format(
                self.get_fullname(), last_measure.get_measure(71)))

        if last_measure.get_measure(
                72) is not None and 'skin_temperature' in self._items:
            self._items['skin_temperature'](last_measure.get_measure(72))
            self.logger.debug("Plugin '{}': skin_temperature - {}".format(
                self.get_fullname(), last_measure.get_measure(72)))

        if last_measure.get_measure(
                76) is not None and 'muscle_mass' in self._items:
            self._items['muscle_mass'](last_measure.get_measure(76))
            self.logger.debug("Plugin '{}': muscle_mass - {}".format(
                self.get_fullname(), last_measure.get_measure(76)))

        if last_measure.get_measure(
                77) is not None and 'hydration' in self._items:
            self._items['hydration'](last_measure.get_measure(77))
            self.logger.debug("Plugin '{}': hydration - {}".format(
                self.get_fullname(), last_measure.get_measure(77)))

        if last_measure.get_measure(
                88) is not None and 'bone_mass' in self._items:
            self._items['bone_mass'](last_measure.get_measure(88))
            self.logger.debug("Plugin '{}': bone_mass - {}".format(
                self.get_fullname(), last_measure.get_measure(88)))

        if last_measure.get_measure(
                91) is not None and 'pulse_wave_velocity' in self._items:
            self._items['pulse_wave_velocity'](last_measure.get_measure(91))
            self.logger.debug("Plugin '{}': pulse_wave_velocity - {}".format(
                self.get_fullname(), last_measure.get_measure(91)))

        if 'height' in self._items and (
                'bmi' in self._items or 'bmi_text'
                in self._items) and last_measure.get_measure(1) is not None:
            if self._items['height']() > 0:
                bmi = round(
                    last_measure.get_measure(1) /
                    ((self._items['height']()) * (self._items['height']())), 2)
                if 'bmi' in self._items:
                    self._items['bmi'](bmi)
                if 'bmi_text' in self._items:
                    if bmi < 16:
                        self._items['bmi_text']('starkes Untergewicht')
                    elif 16 <= bmi < 17:
                        self._items['bmi_text']('mäßiges Untergewicht ')
                    elif 17 <= bmi < 18.5:
                        self._items['bmi_text']('leichtes Untergewicht ')
                    elif 18.5 <= bmi < 25:
                        self._items['bmi_text']('Normalgewicht')
                    elif 25 <= bmi < 30:
                        self._items['bmi_text']('Präadipositas (Übergewicht)')
                    elif 30 <= bmi < 35:
                        self._items['bmi_text']('Adipositas Grad I')
                    elif 35 <= bmi < 40:
                        self._items['bmi_text']('Adipositas Grad II')
                    elif 40 <= bmi:
                        self._items['bmi_text']('Adipositas Grad III')
            else:
                self.logger.error(
                    "Plugin '{}': Cannot calculate BMI: height is 0, please set height (in m) for height item manually."
                    .format(self.get_fullname()))
        else:
            self.logger.error(
                "Plugin '{}': Cannot calculate BMI: height and / or bmi item missing."
                .format(self.get_fullname()))