Add initial code

This commit is contained in:
Antonio J. Delgado 2025-07-26 12:17:28 +03:00
parent 0ec5cb8ff8
commit 7c058e03df
2 changed files with 133 additions and 1 deletions

View file

@ -1,3 +1,5 @@
click
click_config_file
PyYAML
pyxplora-api
requests

View file

@ -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()