Skip to content

Commit

Permalink
Merge pull request neilzilla#26 from antoinebou12/master
Browse files Browse the repository at this point in the history
Update and Bug Fixes to Renpho Weight Home Assistant Component
  • Loading branch information
antoinebou12 committed Apr 19, 2024
2 parents f89c181 + e53faf1 commit 391c037
Show file tree
Hide file tree
Showing 16 changed files with 669 additions and 146 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Renpho Weight Home Assistant Component
# IN DEVELOPPEMENT
# IN DEVELOPPEMENT (Not Working)

![Version](https://img.shields.io/badge/version-v3.0.1-blue)
![License](https://img.shields.io/badge/license-MIT-green)
Expand All @@ -24,6 +24,9 @@ https://github.com/antoinebou12/hass_renpho/assets/13888068/0bf0e48f-0582-462a-b

Use http proxy for the app here a list https://hidemy.io/en/proxy-list/?type=s#list

## Install config
![image](https://github.com/antoinebou12/hass_renpho/assets/13888068/b1a90a12-9f57-42ad-adf8-008a6de92880)

### Weight

![Weight Sensor](docs/images/weight.png)
Expand Down
366 changes: 246 additions & 120 deletions api/app.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ pyjwt
python-dotenv
pycryptodome
starlette
aiohttp_socks
32 changes: 24 additions & 8 deletions custom_components/renpho/api_renpho.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ def __init__(self, email, password, user_id=None, refresh=60, proxy=None):
self.is_polling_active = False
self.proxy = proxy

_LOGGER.info(f"Initializing RenphoWeight instance. Proxy is {'enabled: ' + proxy if proxy else 'disabled.'}")

@staticmethod
def get_timestamp() -> int:
start_date = datetime.date(1998, 1, 1)
Expand Down Expand Up @@ -112,18 +114,30 @@ async def open_session(self):

async def check_proxy(self):
"""
Checks if the proxy is working by making a request to httpbin.org.
Checks if the proxy is working by making a request to a Renpho API endpoint.
"""
test_url = 'https://renpho.qnclouds.com/api/v3/girths/list_girth.json?app_id=Renpho&terminal_user_session_key='
test_url = 'http://httpbin.org/get'

if not self.proxy:
_LOGGER.info("No proxy configured. Proceeding without proxy.")
else:
_LOGGER.info(f"Checking proxy connectivity using proxy: {self.proxy}")

try:
connector = ProxyConnector.from_url(self.proxy) if self.proxy else None
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get(test_url) as response:
session = aiohttp.ClientSession(connector=connector)
async with session.get(test_url) as response:
if response.status == 200:
_LOGGER.info("Proxy check successful." if self.proxy else "Direct connection successful.")
return True
else:
_LOGGER.error(f"Failed to connect using {'proxy' if self.proxy else 'direct connection'}. HTTP Status: {response.status}")
return False
except Exception as e:
_LOGGER.error(f"Proxy connection failed: {e}")
return False

finally:
await session.close()

async def _request(self, method: str, url: str, retries: int = 3, skip_auth=False, **kwargs):
"""
Expand Down Expand Up @@ -198,11 +212,13 @@ async def validate_credentials(self):
Validate the current credentials by attempting to authenticate.
Returns True if authentication succeeds, False otherwise.
"""
_LOGGER.debug("Validating credentials for user: %s", self.email)
try:
return await self.auth()
except Exception as e:
_LOGGER.error(f"Validation failed: {e}")
return False
_LOGGER.error("Failed to validate credentials for user: %s. Error: %s", self.email, e)
raise AuthenticationError(f"Invalid credentials for user {self.email}. Error details: {e}") from e


async def auth(self):
"""Authenticate with the Renpho API."""
Expand Down Expand Up @@ -665,4 +681,4 @@ class APIError(Exception):


class ClientSSLError(Exception):
pass
pass
41 changes: 31 additions & 10 deletions custom_components/renpho/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,55 @@

async def async_validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]:
"""Validate the user input allows us to connect."""
_LOGGER.debug("Starting to validate input: %s", data)
_LOGGER.debug("Starting to validate input for Renpho integration: %s", data)

# Initialize RenphoWeight instance
renpho = RenphoWeight(
email=data[CONF_EMAIL],
password=data[CONF_PASSWORD],
refresh=data.get(CONF_REFRESH, 60),
proxy=data.get("proxy", None)
)

# Check if a proxy is set and validate it
if renpho.proxy:
_LOGGER.info(f"Proxy is configured, checking proxy: {renpho.proxy}")
proxy_is_valid = await renpho.check_proxy()
if not proxy_is_valid:
_LOGGER.error(f"Proxy check failed for proxy: {renpho.proxy}")
raise CannotConnect(reason="Proxy check failed", details={"proxy": renpho.proxy})
else:
_LOGGER.info("Proxy check passed successfully.")
else:
_LOGGER.info("No proxy configured, skipping proxy check.")

_LOGGER.info(f"Attempting to validate credentials for {data[CONF_EMAIL]}")

# Validate credentials
is_valid = await renpho.validate_credentials()
if not is_valid:
_LOGGER.error(f"Failed to validate credentials for user: {data[CONF_EMAIL]}. Invalid credentials.")
raise CannotConnect(
reason="Invalid credentials",
details={
"email": data[CONF_EMAIL],
},
details={"email": data[CONF_EMAIL]},
)
else:
_LOGGER.info(f"Credentials validated successfully for {data[CONF_EMAIL]}")

# Fetch and validate scale users
_LOGGER.info("Fetching scale users associated with the account.")
await renpho.get_scale_users()

user_ids = [
user.get("user_id", None)
for user in renpho.users
]
user_ids = [user.user_id for user in renpho.users if user.user_id is not None]

if not user_ids:
_LOGGER.error(f"No users found associated with the account {data[CONF_EMAIL]}")
raise CannotConnect(reason="No users found", details={"email": data[CONF_EMAIL]})
else:
_LOGGER.info(f"Found users with IDs: {user_ids} for the account {data[CONF_EMAIL]}")

return {"title": data[CONF_EMAIL], "user_ids": user_ids, "renpho_instance": renpho}


class RenphoConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
Expand Down Expand Up @@ -122,4 +143,4 @@ def __str__(self):
return f"CannotConnect: {self.reason} - {self.details}"

def get_details(self):
return self.details
return self.details
2 changes: 1 addition & 1 deletion custom_components/renpho/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
)
CONF_UNIT_OF_MEASUREMENT = "unit_of_measurement"

KG_TO_LBS: Final = 2.20462
KG_TO_LBS: Final = 2.2046226218
CM_TO_INCH: Final = 0.393701

# General Information Metrics
Expand Down
10 changes: 5 additions & 5 deletions custom_components/renpho/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"dependencies": [],
"codeowners": ["@neilzilla", "@antoinebou12"],
"requirements": [
"pycryptodome>=3.3.1",
"requests>=2.25.0",
"aiohttp>=3.6.1",
"voluptuous>=0.11.7",
"pycryptodome",
"requests",
"aiohttp",
"voluptuous",
"pydantic",
"aiohttp_socks"
],
"iot_class": "cloud_polling",
"version": "3.0.1",
"version": "3.0.2",
"config_flow": true
}
Binary file removed custom_components/renpho/renpho.png
Binary file not shown.
67 changes: 66 additions & 1 deletion custom_components/renpho/string.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,70 @@
"abort": {
"already_configured": "Device is already configured"
}
},
"sensor": {
"weight": "Weight",
"bmi": "BMI",
"muscle": "Muscle Mass",
"bone": "Bone Mass",
"waistline": "Waistline",
"hip": "Hip",
"stature": "Stature",
"bodyfat": "Body Fat",
"water": "Water Content",
"subfat": "Subcutaneous Fat",
"visfat": "Visceral Fat",
"bmr": "Basal Metabolic Rate",
"protein": "Protein Content",
"bodyage": "Body Age",
"neck": "Neck",
"shoulder": "Shoulder",
"left_arm": "Left Arm",
"right_arm": "Right Arm",
"chest": "Chest",
"waist": "Waist",
"hip": "Hip",
"left_thigh": "Left Thigh",
"right_thigh": "Right Thigh",
"left_calf": "Left Calf",
"right_calf": "Right Calf",
"whr": "Waist-Hip Ratio",
"abdomen": "Abdomen",
"unit": {
"kg": "kg",
"percent": "%",
"cm": "cm",
"bpm": "bpm"
},
"category": {
"measurements": "Measurements",
"body_composition": "Body Composition",
"metabolic_metrics": "Metabolic Metrics",
"age_metrics": "Age Metrics",
"device_information": "Device Information",
"miscellaneous": "Miscellaneous",
"meta_information": "Meta Information",
"user_profile": "User Profile",
"electrical_measurements": "Electrical Measurements",
"cardiovascular_metrics": "Cardiovascular Metrics",
"other_metrics": "Other Metrics",
"girth_measurements": "Girth Measurements",
"girth_goals": "Girth Goals"
},
"label": {
"physical_metrics": "Physical Metrics",
"body_composition": "Body Composition",
"metabolic_metrics": "Metabolic Metrics",
"age_metrics": "Age Metrics",
"device_information": "Device Information",
"miscellaneous": "Miscellaneous",
"meta_information": "Meta Information",
"user_profile": "User Profile",
"electrical_measurements": "Electrical Measurements",
"cardiovascular_metrics": "Cardiovascular Metrics",
"other_metrics": "Other Metrics",
"girth_measurements": "Girth Measurements",
"girth_goals": "Girth Goals"
}
}
}
}
23 changes: 23 additions & 0 deletions custom_components/renpho/translations/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"config": {
"step": {
"user": {
"data": {
"email": "Geben Sie Ihre E-Mail-Adresse für Ihr veraltetes Renpho-Konto ein.",
"password": "Geben Sie Ihr Renpho-Kontopasswort ein.",
"refresh": "Stellen Sie die Datenaktualisierungsrate in Sekunden ein. Standard ist 60 Sekunden.",
"unit_of_measurement": "Wählen Sie die Maßeinheit für das Gewicht. Die Optionen sind Kilogramm (kg) oder Pfund (lbs).",
"proxy": "Optional: Geben Sie einen Proxy-Server an (z.B. 'http://127.0.0.1:8080')."
}
}
},
"error": {
"cannot_connect": "Verbindung zum Dienst kann nicht hergestellt werden",
"invalid_auth": "Ungültige Authentifizierung",
"unknown": "Ein unbekannter Fehler ist aufgetreten"
},
"abort": {
"already_configured": "Gerät ist bereits konfiguriert"
}
}
}
88 changes: 88 additions & 0 deletions custom_components/renpho/translations/es.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"config": {
"step": {
"user": {
"data": {
"email": "Ingrese su dirección de correo electrónico de la cuenta Renpho Obsoleta.",
"password": "Ingrese la contraseña de su cuenta Renpho.",
"refresh": "Establezca la frecuencia de actualización de los datos en segundos. El valor predeterminado es de 60 segundos.",
"unit_of_measurement": "Seleccione la unidad de medida para el peso. Las opciones son kilogramos (kg) o libras (lbs).",
"proxy": "Opcional: Especifique un servidor proxy para usar (por ejemplo, 'http://127.0.0.1:8080')."
}
}
},
"error": {
"cannot_connect": "No se puede conectar al servicio",
"invalid_auth": "Autenticación inválida",
"unknown": "Se produjo un error desconocido"
},
"abort": {
"already_configured": "El dispositivo ya está configurado"
}
},
"sensor": {
"weight": "Peso",
"bmi": "IMC",
"muscle": "Masa Muscular",
"bone": "Masa Ósea",
"waistline": "Circunferencia de la Cintura",
"hip": "Cadera",
"stature": "Estatura",
"bodyfat": "Grasa Corporal",
"water": "Contenido de Agua",
"subfat": "Grasa Subcutánea",
"visfat": "Grasa Visceral",
"bmr": "Tasa Metabólica Basal",
"protein": "Contenido de Proteína",
"bodyage": "Edad Corporal",
"neck": "Cuello",
"shoulder": "Hombro",
"left_arm": "Brazo Izquierdo",
"right_arm": "Brazo Derecho",
"chest": "Pecho",
"waist": "Cintura",
"hip": "Cadera",
"left_thigh": "Muslo Izquierdo",
"right_thigh": "Muslo Derecho",
"left_calf": "Pantorrilla Izquierda",
"right_calf": "Pantorrilla Derecha",
"whr": "Ratio Cintura-Cadera",
"abdomen": "Abdomen",
"unit": {
"kg": "kg",
"percent": "%",
"cm": "cm",
"bpm": "bpm"
},
"category": {
"measurements": "Mediciones",
"body_composition": "Composición Corporal",
"metabolic_metrics": "Métricas Metabólicas",
"age_metrics": "Métricas de Edad",
"device_information": "Información del Dispositivo",
"miscellaneous": "Misceláneo",
"meta_information": "Meta Información",
"user_profile": "Perfil de Usuario",
"electrical_measurements": "Mediciones Eléctricas",
"cardiovascular_metrics": "Métricas Cardiovasculares",
"other_metrics": "Otras Métricas",
"girth_measurements": "Mediciones de Circunferencia",
"girth_goals": "Objetivos de Circunferencia"
},
"label": {
"physical_metrics": "Métricas Físicas",
"body_composition": "Composición Corporal",
"metabolic_metrics": "Métricas Metabólicas",
"age_metrics": "Métricas de Edad",
"device_information": "Información del Dispositivo",
"miscellaneous": "Misceláneo",
"meta_information": "Meta Información",
"user_profile": "Perfil de Usuario",
"electrical_measurements": "Mediciones Eléctricas",
"cardiovascular_metrics": "Métricas Cardiovasculares",
"other_metrics": "Otras Métricas",
"girth_measurements": "Mediciones de Circunferencia",
"girth_goals": "Objetivos de Circunferencia"
}
}
}
Loading

0 comments on commit 391c037

Please sign in to comment.