diff --git a/requirements.txt b/requirements.txt index 8b330d4..712b95a 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ click click_config_file PyYAML +pyxplora-api +requests diff --git a/xplora_ha/xplora_ha.py b/xplora_ha/xplora_ha.py index 5ae9d03..4df177d 100755 --- a/xplora_ha/xplora_ha.py +++ b/xplora_ha/xplora_ha.py @@ -14,6 +14,8 @@ from logging.handlers import SysLogHandler import click import click_config_file import yaml +from pyxplora_api.pyxplora_api import PyXploraApi +import requests HOME_FOLDER = os.environ.get('HOME', os.environ.get('USERPROFILE', '/')) @@ -24,7 +26,55 @@ else: CACHE_FOLDER = f"{HOME_FOLDER}/.local/" LOG_FOLDER = f"{HOME_FOLDER}/log/" - +WATCH_STATES = [ + { + "function": "getWatchBattery", + "entity_name": "battery_level" + }, + { + "function": "getWatchIsCharging", + "entity_name": "battery_charging" + }, + { + "function": "getWatchIsInSafeZone", + "entity_name": "in_safe_zone" + }, + { + "function": "getWatchLastLocation", + "entity_name": "last_location" + }, + { + "function": "getWatchOnlineStatus", + "entity_name": "online_status" + }, + { + "function": "getWatchSafeZoneLabel", + "entity_name": "safe_zone_label" + }, + # { + # "function": "getWatchState", + # "entity_name": "state" + # }, + { + "function": "getWatchUnReadChatMsgCount", + "entity_name": "unread_chat_count" + }, + { + "function": "getWatchUserCurrentStep", + "entity_name": "current_step" + }, + { + "function": "getWatchUserSteps", + "params": { + "date": time.time() + }, + "entity_name": "user_steps" + }, + { + "function": "getWatchUserTotalStep", + "entity_name": "user_total_step" + } +] class XploraHa: """Integrate Xplora watches into Home Assistant""" @@ -48,6 +98,50 @@ class XploraHa: } self.data = self._read_cached_data() + headers = { + "Authorization": f"Bearer {self.config['home_assistant_token']}", + "content-type": "application/json", + } + self.ha_session = requests.Session() + self.ha_session.headers.update(headers) + + self.xplora = PyXploraApi( + self.config['xplora_country_code'], + self.config['xplora_phone_number'], + self.config['xplora_password'] + ) + self.xplora.init(forceLogin=False, signup=True) + while True: + self._process_watches() + time.sleep(self.config['interval']) + + def _process_watches(self): + for watch in self.xplora.watchs: + self._debug(watch['ward']) + base_sensor_entity = f"sensor.xplora_watch_{watch['ward']['name']}_" + for watch_state in WATCH_STATES: + function = getattr(self.xplora, watch_state['function']) + if 'params' in watch_state: + state = function(watch['ward']['id'], **watch_state['params']) + else: + state = function(watch['ward']['id']) + self._publish_ha_state( + f"{base_sensor_entity}{watch_state['entity_name']}", + { + "state": state, + } + ) + + def _publish_ha_state(self, entity_id, state): + self._debug( + { "posting": { "entity": entity_id, "state": state } } + ) + result = self.ha_session.post( + f"{self.config['home_assistant_url']}/api/states/{entity_id}", + json=state + ) + self._debug( { "result": result.json() }) + def close(self): '''Close class and save data''' self._save_cached_data(self.data) @@ -181,6 +275,42 @@ class XploraHa: default=60*60*24*7, help='Max age in seconds for the cache' ) +@click.option( + '--home-assistant-url', + '-u', + required=True, + help='Home Assistant URL, like http://example.org:8123' +) +@click.option( + '--home-assistant-token', + '-t', + required=True, + help='Home Assistant token' +) +@click.option( + '--xplora-country-code', + '-c', + required=True, + help='Xplora phone country code' +) +@click.option( + '--xplora-phone-number', + '-p', + required=True, + help='Xplora phone number of your account' +) +@click.option( + '--xplora-password', + '-P', + required=True, + help='Xplora account password' +) +@click.option( + '--interval', + '-i', + default=30, + help='Interval in seconds between checks on the Xplora API' +) # @click.option("--dummy","-n", is_flag=True, # help="Don't do anything, just show what would be done.") @click_config_file.configuration_option()