Table of contents
hass_renpho: Polling a cloud API into Home Assistant sensors
hass_renpho is a fork of a Home Assistant integration for Renpho measurements. A shared coordinator refreshes cloud data and sensor entities expose that state. The repository warns that its old-app API path is no longer reliably working.
- Languages
- 2Code breakdown
- Documented components
- 2Explore modules
- Source documents
- 3Read the instructions
Repository languagesPython 99.51%2
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| Python | 144,406 | |
| Dockerfile | 711 |
1. Overview
1.1. Why it exists
Custom Home Assistant integration decoding Renpho Bluetooth & Cloud API biometric telemetry.
1.2. Best fit
Self-hosted health metric tracking and smart home automation triggers.
2. Use cases
A Home Assistant integration that polls the legacy Renpho cloud API and exposes scale measurements as sensors.
- Sign in and pick a scale user
- Home Assistant userHome AssistantRenpho cloud API
config_flow.py validates the email and password against Renpho, then shows a select_user step when the account has several scale users.
- Poll measurements on a timer
- Home AssistantRenpho cloud API
RenphoWeightCoordinator calls get_measurements(), list_girth() and list_girth_goal() every refresh seconds through a DataUpdateCoordinator.
- Show body metrics as sensors
- Home Assistant userHome Assistant
sensor.py and sensor_configs.py create sensors for weight, BMI, body fat, water, BMR, girth values and goals, with kg or lb for weight.
- Route calls through a proxy
- Home Assistant userRenpho cloud API
An optional proxy setting (http:// or socks5://) is checked by check_proxy() before Renpho calls, for IPs that renpho.qnclouds.com blocks.
- Test an account in the API
- Home Assistant userRenpho cloud API
api/app.py is a FastAPI app with routes such as /auth, /users, /measurements and /girth_info; vercel.json deploys it and the README points to its /docs page.
2.1. Scenario: Getting the morning weigh-in into Home Assistant
- Copy custom_components/renpho into <config_dir>/custom_components/renpho/ (or install through HACS).
- Add renpho: with email, password and refresh: 600 to configuration.yaml, plus sensor: platform: renpho.
- Restart Home Assistant; the integration signs in to the legacy Renpho API and resolves the user id.
- Step on the scale with the outdated Renpho app so the measurement reaches the cloud.
- Within the next refresh cycle the weight and body-fat sensors update on the dashboard.
Files readREADME.mdhacs.jsoncustom_components/renpho/manifest.jsoncustom_components/renpho/config_flow.pycustom_components/renpho/coordinator.pycustom_components/renpho/sensor.pycustom_components/renpho/api_renpho.pyapi/app.pyvercel.json
3. Try it
Address published in the repository README. The page opens in a sandboxed frame, only when you ask.
https://hass-renpho.vercel.app/docs4. Getting started
These commands come from the repository documentation. They were not run during this review.
Stable
Use the latest release
Not stable
git clone https://github.com/antoinebou12/hass_renpho5. Repository references
Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.
Prerequisites and first run
5.1. Prerequisites
README.md
- You must have a Renpho scale. If you don’t have one, you can purchase one here.
- You must have the Renpho app installed on your mobile device. You can download it here for Android and here for iOS.
- You must have the Home Assistant Community Store (HACS) installed and running.
5.2. Installation
README.md
5.3. Prerequisites (README.md)
docs/README.md
- You must have a Renpho account. If you don’t have one, you can create one here.
- You must have Home Assistant installed and running.
- Visual Studio Code is recommended for editing the files.
5.4. Installation (README.md)
docs/README.md
- Copy this folder to /custom_components/hass_renpho/.
- Add the necessary configuration to your configuration.yaml file.
Configuration and usage
5.5. Configuration
README.md
Add the following entry in your configuration.yaml: And then add the sensor platform:
:warning: Note: Refresh is the time in seconds to check for updates. Keep in mind that logging in will log you out of the app. Restart home assistant and you should see the sensors:
5.6. Parameters
docs/README.md
5.7. Parameters (README.md)
docs/README.md
- metric (str): The specific metric to retrieve (e.g., ‘weight’, ‘bmi’).
5.8. Parameters (docs/README.md)
docs/README.md
- metric (str): The metric to fetch (e.g., ‘bodyfat’, ‘water’).
- user_id (str, optional): The user ID for whom the metric should be fetched. Defaults to the object’s user_id if not provided.
5.9. Parameters (docs/README.md)
docs/README.md
- polling_interval (int): Time in seconds between each polling call. Defaults to 60 seconds.
API and integration
5.10. API Documentation
docs/README.md
5.11. API endpoints
docs/README.md
This document describes the API endpoints and methods utilized by the RenphoWeight class in the Home Assistant custom component for Renpho weight scales. It outlines the endpoints, expected parameters, and returned data.
5.12. API Documentation (README.md)
docs/README.md
Endpoint: /api/v3/users/sign_in.json Method: POST Parameters:
- app_id: Application identifier.
- secure_flag: Indicates secure login.
- email: User’s email address.
- password: User’s password.
Operations and troubleshooting
5.13. Troubleshooting
README.md
- Legacy Renpho app vs Renpho Health This integration uses the legacy Renpho cloud API (renpho.qnclouds.com) and the same account type as the older Renpho mobile app (not Renpho Health). Credentials and APIs differ; Renpho Health is not supported here.
- “No users found” / empty scale_users Renpho sometimes returns an empty list_scale_user list while sign-in and measurements still work. The integration now falls back to the account user id from the sign-in response. The hosted API explorer behaves the same: if the list is empty but you are logged in, /users returns a single synthetic user built from that account id.
- Rate limiting and IP blocks
5.14. Step by Step debugging
.devcontainer/README.md
Development and contributions
5.15. List Latest Device Model
docs/README.md
Endpoint: /api/v3/devices/list_lastest_model.json Method: GET (attempted but failed due to parameter issues) and POST Parameters:
- user_id: The user’s identifier.
- last_updated_at: Timestamp for last update.
- locale: Locale setting.
- app_id: Application identifier.
- terminal_user_session_key: Session key obtained from signing in.
- internal_model_json: An array of model identifiers.
5.16. Developing with Visual Studio Code + devcontainer
.devcontainer/README.md
The easiest way to get started with custom integration development is to use Visual Studio Code with devcontainers. This approach will create a preconfigured development environment with all the tools you need. In the container you will have a dedicated Home Assistant core instance running with your custom component code. You can configure this instance by updating the ./devcontainer/configuration.yaml file. Prerequisites
- git
- Docker
- For Linux, macOS, or Windows 10 Pro/Enterprise/Education use the current release version of Docker
- Windows 10 Home requires WSL 2 and the current Edge version of Docker Desktop (see instructions here). This can also be used for Windows Pro/Enterprise/Education.
- Visual Studio code
- [Remote - Containers (VSC Extension)][extension-link] More info about requirements and devcontainer in general Getting started:
- Fork the repository.
Source documentation
3 documents read from 3 candidates.
6. Features and components 2
- Coordinated refresh
- RenphoWeightCoordinator extends DataUpdateCoordinator with a configurable refresh interval. One update calls get_measurements, list_girth and list_girth_goal, then records the last-update time.
- Errors and sensor state
- The coordinator converts timeouts and API failures into UpdateFailed. Cancellation is treated separately during shutdown. Sensor definitions and the API wrapper remain outside the polling class.
7. Architecture
Expand a component to follow its connections, or explore the full diagram.
Home Assistant coordinator
Renpho API wrapper
Cloud measurements
Shared refreshed state
Sensor entities
Mermaid Interactive diagram
System overview of the components and connections verified in the repository.

flowchart LR
n0["Home Assistant coordinator"]
n1["Renpho API wrapper"]
n2["Cloud measurements"]
n3["Shared refreshed state"]
n4["Sensor entities"]
n0 --> n1
n1 --> n2
n2 --> n3
n3 --> n4
Text version of the diagram
- Home Assistant coordinator → Renpho API wrapper
- Renpho API wrapper → Cloud measurements
- Cloud measurements → Shared refreshed state
- Shared refreshed state → Sensor entities
Follow one path through the code
Follow _async_update_data through its three API calls and exception handling. A sensor value may be the last successful reading; the update status and timestamp are needed to distinguish it from fresh data.
8. Technical dossier
Built from the source at commit b38c9df (26 files). Each item comes from a pattern match in the code, so open the linked file before relying on it.
8.1. Layers and modules
Folders are sorted into layers by name, from the user interface down to data access. Because the sorting uses names only, the diagram says nothing about calls between layers.
Mermaid Layered view
flowchart TB
subgraph L_interface["Entry points and API"]
direction TB
interface_0["api<br/>3 files"]
end
subgraph L_core["Core source"]
direction TB
core_0["custom_components/renpho<br/>9 files"]
end
subgraph L_hosting["Build, CI and hosting"]
direction TB
hosting_0[".github<br/>7 files"]
hosting_1[".devcontainer<br/>3 files"]
hosting_2["api<br/>2 files"]
hosting_3["(root)<br/>1 file"]
end
L_interface ~~~ L_core
L_core ~~~ L_hosting
| Module | Layer | Files | Types | Extensions |
|---|---|---|---|---|
custom_components/renpho | Core source | 9 | 18 | .py |
api | Entry points and API | 3 | 15 | .py |
8.2. C4 model
From system context to code declarations. Each level reflects the available source evidence.
UML 1 · System context
The widest C4 view: who uses the project and which outside systems and data stores it relies on. Rendered with uml-mcp.
PlantUML source
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
Person(P_http, "HTTP client")
System(SYS, "hass_renpho", "hass_renpho is a fork of a Home Assistant integration for Renpho meas…")
System_Ext(E0, "Renpho cloud API")
System_Ext(E1, "Home Assistant")
Rel(P_http, SYS, "Uses")
Rel(SYS, E0, "Calls")
Rel(SYS, E1, "Calls")
@enduml
UML 2 · Containers
One level closer: the parts that run separately inside the project, their main language and how calls flow between them. Rendered with uml-mcp.
PlantUML source
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
Person(P_http, "HTTP client")
System_Boundary(SYS, "hass_renpho") {
Container(APP, "hass_renpho", "Python")
}
System_Ext(E0, "Renpho cloud API")
System_Ext(E1, "Home Assistant")
Rel(P_http, APP, "Uses")
Rel(APP, E0, "Calls")
Rel(APP, E1, "Calls")
@enduml
UML 3 · Components and layers
Modules grouped by source-layer classification. Boundaries show organization, not runtime isolation or call relationships. Rendered with uml-mcp.
PlantUML source
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "hass_renpho") {
Boundary(L0, "Entry points and API", "layer") {
Component(M0_0, "api", "Python", "3 files")
}
Boundary(L1, "Core source", "layer") {
Component(M1_0, "custom_components/renpho", "Python", "9 files")
}
Boundary(L2, "Build, CI and hosting", "layer") {
Component(M2_0, ".github", ".yml, .md", "7 files")
Component(M2_1, ".devcontainer", ".md, .yaml, .json", "3 files")
Component(M2_2, "api", "Dockerfile, .yml", "2 files")
Component(M2_3, "(root)", ".json", "1 files")
}
}
@enduml
UML 4 · Code
Selected declarations, fields and methods grouped by source file. No inheritance or call edges are inferred. Rendered with uml-mcp.
PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "hass_renpho" {
package "api/app.py" as F0 {
class "RenphoWeight" as T0_0 {
_json_session_headers()
get_timestamp()
prepare_data()
open_session()
check_proxy()
_request()
}
class "DeviceBind" as T0_1 {
id
mac
scale_name
demo
hw_ble_version
device_type
hw_software_version
created_at
}
class "Girth" as T0_2 {
girth_id
user_id
time_stamp
time_zone
mac
internal_model
scale_name
neck_value
}
class "GirthGoal" as T0_3 {
girth_goal_id
user_id
girth_type
setup_goal_at
goal_value
goal_unit
initial_value
initial_unit
}
class "MeasurementDetail" as T0_4 {
id
b_user_id
time_stamp
created_at
created_stamp
scale_type
scale_name
mac
}
class "UserResponse" as T0_5 {
status_code
status_message
terminal_user_session_key
device_binds_ary
new_bodyage_logic_flag
cooling_period_flag
id
email
}
class "MeasurementResponse" as T0_6 {
status_code
status_message
last_at
previous_flag
previous_at
measurements
}
class "Users" as T0_7 {
scale_user_id
user_id
mac
index
key
method
}
class "GirthResponse" as T0_8 {
status_code
status_message
girths
deleted_girth_ids
last_updated_at
}
class "APIResponse" as T0_9 {
status
message
data
}
class "GirthGoalsResponse" as T0_10 {
status_code
status_message
girth_goals
}
}
package "custom_components/renpho/sensor.py" as F1 {
class "RenphoSensor" as T1_0 {
_apply_native_metadata()
_schedule_update()
_handle_coordinator_update()
unique_id()
extra_state_attributes()
category()
}
}
package "custom_components/renpho/config_flow.py" as F2 {
class "CannotConnect" as T2_0 {
__str__()
get_details()
}
class "RenphoConfigFlow" as T2_1 {
async_step_user()
async_step_select_user()
}
}
package "custom_components/renpho/coordinator.py" as F3 {
class "RenphoWeightCoordinator" as T3_0 {
_async_update_data()
last_updated()
}
}
package "api/http_fingerprint.py" as F4 {
class "ClientFingerprint" as T4_0 {
user_agent
accept_language
extra_headers
}
}
}
@enduml
8.3. Public interface
Outside code can use everything listed here. The project also declares 33 public types.
UML Use cases
Each actor is a kind of caller, linked to what it can ask the project to do. Rendered with uml-mcp.
PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
left to right direction
actor "HTTP client" as A_http
rectangle "hass_renpho" {
usecase "GET /" as U0
usecase "GET /auth" as U1
usecase "GET /generate_api_key" as U2
usecase "GET /info" as U3
usecase "GET /users" as U4
usecase "GET /measurements" as U5
}
A_http --> U0
A_http --> U1
A_http --> U2
A_http --> U3
A_http --> U4
A_http --> U5
@enduml
HTTP routes 16
Mermaid Route map by prefix
flowchart LR
api(["HTTP API"])
g0["/"]
api --> g0
g0r0["GET /"]
g0 --> g0r0
g1["/all_users_measurements_his…"]
api --> g1
g1r0["GET /all_users_measurements_history"]
g1 --> g1r0
g2["/auth"]
api --> g2
g2r0["GET /auth"]
g2 --> g2r0
g3["/device_info"]
api --> g3
g3r0["GET /device_info"]
g3 --> g3r0
g4["/generate_api_key"]
api --> g4
g4r0["GET /generate_api_key"]
g4 --> g4r0
g5["/girth_goal"]
api --> g5
g5r0["GET /girth_goal"]
g5 --> g5r0
g6["/girth_info"]
api --> g6
g6r0["GET /girth_info"]
g6 --> g6r0
g7["/growth_record"]
api --> g7
g7r0["GET /growth_record"]
g7 --> g7r0
g8["/info"]
api --> g8
g8r0["GET /info"]
g8 --> g8r0
g9["/latest_model"]
api --> g9
g9r0["GET /latest_model"]
g9 --> g9r0
more["+6 groups"]
api --> more
| Method | Path | Source |
|---|---|---|
| GET | / | api/app.py:1301 |
| GET | /auth | api/app.py:1305 |
| GET | /generate_api_key | api/app.py:1310 |
| GET | /info | api/app.py:1319 |
| GET | /users | api/app.py:1330 |
| GET | /measurements | api/app.py:1374 |
| GET | /measurements_history | api/app.py:1385 |
| GET | /all_users_measurements_history | api/app.py:1396 |
Show 8 more routes
| GET | /weight | api/app.py:1407 |
| GET | /specific_metric | api/app.py:1418 |
| GET | /device_info | api/app.py:1429 |
| GET | /latest_model | api/app.py:1440 |
| GET | /girth_info | api/app.py:1451 |
| GET | /girth_goal | api/app.py:1462 |
| GET | /growth_record | api/app.py:1473 |
| GET | /message_list | api/app.py:1484 |
Entry points
api/app.pyentry file
8.4. Private interface
These names are internal by the language’s conventions: a leading underscore, private, static or pub(crate).
- underscore helper
- 8
_json_session_headersapi/app.py:396_requestapi/app.py:458_json_session_headerscustom_components/renpho/api_renpho.py:95
8.5. Entities and data model 11
Mermaid Entity class diagram
classDiagram
direction LR
class E0["DeviceBind"] {
+int id
+str mac
+str scale_name
+str demo
+int hw_ble_version
+int device_type
}
class E1["Girth"] {
+int girth_id
+int user_id
+int time_stamp
+str time_zone
+str mac
+str internal_model
}
class E2["GirthGoal"] {
+int girth_goal_id
+int user_id
+str girth_type
+int setup_goal_at
+float goal_value
+int goal_unit
}
class E3["MeasurementDetail"] {
+int id
+int b_user_id
+int time_stamp
+str created_at
+int created_stamp
+int scale_type
}
class E4["UserResponse"] {
+str status_code
+str status_message
+str terminal_user_session_key
+List~DeviceBind~ device_binds_ary
+int new_bodyage_logic_flag
+int cooling_period_flag
}
class E5["MeasurementResponse"] {
+str status_code
+str status_message
+int last_at
+int previous_flag
+int previous_at
+List~MeasurementDetail~ measurements
}
class E6["Users"] {
+str scale_user_id
+str user_id
+str mac
+int index
+int key
+int method
}
class E7["GirthResponse"] {
+str status_code
+str status_message
+List~Girth~ girths
+List~int~ deleted_girth_ids
+int last_updated_at
}
class E8["APIResponse"] {
+str status
+str message
+Any data
}
class E9["GirthGoalsResponse"] {
+str status_code
+str status_message
+List~GirthGoal~ girth_goals
}
E4 --> E0 : device_binds_ary
E5 --> E3 : measurements
E7 --> E1 : girths
E9 --> E2 : girth_goals
An arrow links a field to the entity its type names.
| Entity | Kind | First fields |
|---|---|---|
DeviceBind | Validated schema | id, mac, scale_name, demo, hw_ble_version, device_type, hw_software_version, created_at |
Girth | Validated schema | girth_id, user_id, time_stamp, time_zone, mac, internal_model, scale_name, neck_value |
GirthGoal | Validated schema | girth_goal_id, user_id, girth_type, setup_goal_at, goal_value, goal_unit, initial_value, initial_unit |
MeasurementDetail | Validated schema | id, b_user_id, time_stamp, created_at, created_stamp, scale_type, scale_name, mac |
UserResponse | Validated schema | status_code, status_message, terminal_user_session_key, device_binds_ary, new_bodyage_logic_flag, cooling_period_flag, id, email |
MeasurementResponse | Validated schema | status_code, status_message, last_at, previous_flag, previous_at, measurements |
Users | Validated schema | scale_user_id, user_id, mac, index, key, method |
GirthResponse | Validated schema | status_code, status_message, girths, deleted_girth_ids, last_updated_at |
Show 3 more entities
APIResponse | Validated schema | status, message, data |
|---|---|---|
GirthGoalsResponse | Validated schema | status_code, status_message, girth_goals |
ClientFingerprint | Dataclass | user_agent, accept_language, extra_headers |
8.6. Business logic
Once UI code and the services and entities above are set aside, these classes have the most methods.
RenphoWeightEntry points and API, 31 methods_json_session_headers, get_timestamp, prepare_data, open_session, check_proxy, _requestRenphoSensorCore source, 8 methods_apply_native_metadata, _schedule_update, _handle_coordinator_update, unique_id, extra_state_attributes, categoryCannotConnectCore source, 2 methods__str__, get_detailsRenphoConfigFlowCore source, 2 methodsasync_step_user, async_step_select_userRenphoWeightCoordinatorCore source, 2 methods_async_update_data, last_updated
8.7. External integrations
HTTP clients
Hosts named in the code
httpbin.org2 filesapi/app.py:441renpho.qnclouds.com2 filesapi/app.py:44
8.8. Stack and dependencies
Python requirements.txt 3 runtime
Python api/requirements.txt 16 runtime
External dependencies
13 declared packages (13 runtime, 0 development) in requirements.txt, api/requirements.txt.
Package table 13
| Package | Version | Scope | Purpose | Registry |
|---|---|---|---|---|
pycryptodome | >=3.3.1 | runtime | Cryptographic library for Python | pypi.org |
requests | >=2.26.0 | runtime | HTTP client | pypi.org |
aiohttp | >=3.6.1 | runtime | HTTP client | pypi.org |
fastapi | — | runtime | Web framework | pypi.org |
uvicorn | — | runtime | Application server | pypi.org |
jinja2 | — | runtime | Templates | pypi.org |
pydantic | — | runtime | Data validation | pypi.org |
python-multipart | — | runtime | A streaming multipart parser for Python | pypi.org |
cryptography | — | runtime | Authentication and security | pypi.org |
pyjwt | — | runtime | Authentication and security | pypi.org |
python-dotenv | — | runtime | Configuration | pypi.org |
starlette | — | runtime | Web framework | pypi.org |
aiohttp_socks | — | runtime | HTTP client | pypi.org |
8.9. CI/CD pipeline
4 GitHub Actions workflows, 4 jobs. Each box is a job; double-bordered boxes publish or deploy, and arrows follow needs.
Mermaid Pipeline flow
flowchart LR
subgraph wf0["Validate HACS"]
direction LR
wf0_validate_hacs["validate-hacs<br/>ubuntu-latest"]
end
subgraph wf1["Create Release"]
direction LR
wf1_release[["release<br/>ubuntu-latest"]]
end
subgraph wf2["Build"]
direction LR
wf2_build["Build<br/>ubuntu-latest"]
end
subgraph wf3["Python Unittest Workflow Inside Home Assist…"]
direction LR
wf3_build["build<br/>ubuntu-latest"]
end
t0(["push · pull request · schedule · manual run"])
t1(["push"])
t2(["push · pull request"])
t0 --> wf0_validate_hacs
t1 --> wf1_release
t1 --> wf2_build
t2 --> wf3_build
| Workflow | Triggers | Jobs | Publishes to |
|---|---|---|---|
Validate HACS.github/workflows/hacs-workflow.yml | push, pull request, schedule, manual run |
| — |
Create Release.github/workflows/release.yml | push |
| — |
Build.github/workflows/sonar.yml | push |
| — |
Python Unittest Workflow Inside Home Assistant VM.github/workflows/tests.yml | push, pull request |
| — |
8.10. Deployment
Mermaid Deployment diagram
flowchart LR
repo[("GitHub repository")]
ci[["GitHub Actions<br/>4 workflows"]]
image["Docker image<br/>FROM python:3.12.2-slim"]
host_Vercel("Vercel<br/>vercel.json")
repo -->|"push or pull request"| ci
ci -->|"docker build"| image
ci -.->|"configured"| host_Vercel
UML Deployment
The outer node is where the code runs. Each base image points to what it builds, solid arrows lead to databases and dashed ones to outside services. Rendered with uml-mcp.
PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Docker image" as H {
artifact "hass_renpho" as APP
}
artifact "FROM python:3.12.2-slim" as IMG0
IMG0 ..> APP : builds
artifact "FROM python:3.12.2-slim" as IMG1
IMG1 ..> APP : builds
cloud "Vercel" as X0
X0 ..> APP
cloud "Renpho cloud API" as E0
APP ..> E0
cloud "Home Assistant" as E1
APP ..> E1
@enduml
Where it runs
Docker base images
8.11. Monitoring
What the code logs, measures and exposes to tell whether it is working.
8.12. Security
Controls
Supply chain
Environment variables 5
The page lists names without their values and underlines the ones that look like secrets.
Nothing found for: Services, Database, Testing.
9. Types and file structure
33 declared types, with 12 in the base-relationship overview.
Type diagram
classDiagram
direction TB
class t1c013f7e1614["RenphoWeight"] {
__init__()
_json_session_headers()
get_timestamp()
prepare_data()
}
class t018fc6091cac["AuthenticationError"] {
}
class tf6d6f400bcb6["APIError"] {
}
class t3f96fd588bea["ClientSSLError"] {
}
class teb0533bd5d5d["RenphoWeightCoordinator"] {
__init__()
_async_update_data()
last_updated()
}
class t16ebe0abcf92["RenphoSensor"] {
__init__()
_apply_native_metadata()
_schedule_update()
_handle_coordinator_update()
}
class t21aebcf929af["DeviceBind"] {
get()
}
class ta3053775281d["UserResponse"] {
get()
}
class t7807df8cb6f0["MeasurementDetail"] {
get()
}
class ta4f92b147e4f["MeasurementResponse"] {
get()
}
class td4123c774424["Users"] {
get()
}
class t9147ce26b037["GirthGoal"] {
get()
}
class bbff3815f3008["Exception"] {
<<unresolved_base>>
}
bbff3815f3008 <|-- t018fc6091cac
bbff3815f3008 <|-- tf6d6f400bcb6
bbff3815f3008 <|-- t3f96fd588bea
class b86550088d462["DataUpdateCoordinator"] {
<<unresolved_base>>
}
b86550088d462 <|-- teb0533bd5d5d
class b861c1788888f["SensorEntity"] {
<<unresolved_base>>
}
b861c1788888f <|-- t16ebe0abcf92
class bb33e03eb53a5["BaseModel"] {
<<unresolved_base>>
}
bb33e03eb53a5 <|-- t21aebcf929af
bb33e03eb53a5 <|-- ta3053775281d
bb33e03eb53a5 <|-- t7807df8cb6f0
bb33e03eb53a5 <|-- ta4f92b147e4f
bb33e03eb53a5 <|-- td4123c774424
bb33e03eb53a5 <|-- t9147ce26b037
Unresolved bases remain labelled; full signatures are not reconstructed.
10. Reference
17 / 17 eligible files read (59 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.
What the scan covers
Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.
Linguist statistics cover the whole repository and may include other languages.
12. Files to read 3
13. Glossary
Repository
The versioned source files, configuration, and history of a project.
README
The repository’s entry document, usually covering its purpose and initial setup.
Dependency
A library, tool, or service that another component needs to build or run.
API
An interface through which software components exchange requests and results. An API does not have to use HTTP.
Container
An isolated process environment created from an image. Persistent data needs storage outside the container’s disposable filesystem.
Published port
A host port mapped to a service’s container port. Publishing a port can expose that service beyond its container network.
Fork
A separate repository derived from another project. A change in a fork is not automatically a change in the upstream project.
14. References
- antoinebou12. (2026, November 5). hass_renpho. [Software repository] github.com.
- antoinebou12. (2026, November 5). hass_renpho: README. [Repository documentation] github.com.
- antoinebou12. (2026, November 5). custom_components/renpho/coordinator.py. [Source file] github.com.
- antoinebou12. (2026, November 5). custom_components/renpho/sensor.py. [Source file] github.com.
- antoinebou12. (2026, November 5). custom_components/renpho/api_renpho.py. [Source file] github.com.
- Boucher, A. (2021, October 10). Renpho scale, Home Assistant, and reverse-engineering the API. [Project article] antoineboucher.info.
- Boucher, A. (2026, October 23). hass_renpho: Polling a cloud API into Home Assistant sensors. [Project article] antoineboucher.info.
Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.