P1On Privacy Policy
⚠️ DRAFT — requires counsel review before publication. Placeholders in
[BRACKETS]must be completed by the controller. This draft is written to satisfy GDPR Art. 13/14 and to serve as the privacy-policy URL required by the Apple App Store and Google Play.Every statement about data below is checked against the code (tables in backend/template.yaml, entity definitions in DATA_MODEL.md). Questions only counsel or the owner can answer are marked
> **For counsel:**. The controller identity, DPO and lawful bases are owner task O15 and are not decided here.
Effective date: [DATE]
Version: [SEMVER — bump on every material change; the app stores the version the user accepted]
Last updated: 2026-10-05
1. Who we are (data controller)
[CONTROLLER LEGAL NAME], [REGISTERED ADDRESS], [COMPANY NUMBER] ("P1On", "we", "us")
is the controller of your personal data.
- Contact / Data Protection Officer:
[DPO NAME, EMAIL] - Supervisory authority: you may lodge a complaint with the Belgian Data Protection Authority (Gegevensbeschermingsautoriteit / Autorité de protection des données, www.dataprotectionauthority.be) or, if you are in the Netherlands, the Autoriteit Persoonsgegevens (www.autoriteitpersoonsgegevens.nl).
For counsel: name the controller legal entity and decide whether a DPO must be appointed (Art. 37) — owner task O15. Nothing in this draft names either.
2. What P1On does
P1On is a mobile app that reads your home smart-meter data via a P1 WiFi reader you own, shows you real-time and historical energy usage and cost, and produces AI-generated weekly insights, usage alerts and a progress ("skyline") view.
Households. In P1On a home is the unit that owns readers and data. You can invite other people into your home with a link. Every member of a home sees that home's devices, readings, insights, alerts, alert history and progress, and the list of its members. See §3 ("Shared with the other members of your home").
Important: smart-meter consumption data is personal data. It can reveal when you are home, your sleep and holiday patterns, and which appliances you use. P1On additionally infers appliance-level behaviour using non-intrusive load monitoring (NILM). We treat this data accordingly.
3. What data we process
Each row names the database table or service that holds the data, so the retention in §6 can be read against it.
| Category | Examples | Source | Stored in |
|---|---|---|---|
| Account data | email address (your sign-in name), password (held by Cognito, never by us in readable form), email-verification state | You, at registration | Amazon Cognito user pool |
| Profile | email, display name, language | You, at registration and in settings | p1on-users |
| Home | home name, time zone, who created it, how many owners and members it has | You | p1on-homes |
| Household membership | which homes you belong to, your role (owner or member), who invited you, when you joined | You and the home's owners | p1on-home-members |
| Invite links | a SHA-256 hash of each link (the link itself is never stored), who created it, expiry, revocation, use count | The home's owners | p1on-invites |
| Invite codes | for each short invite code, a keyed hash of it (HMAC, with a secret held outside the database; the code itself is never stored) and the home it opens, with no user identifier; and, for each user who types a code, counters of attempts per hour and per day | The home's owners (codes); you (attempts) | p1on-invite-codes, p1on-invite-attempts |
| Device and contract data | reader serial number, firmware version, friendly name, status, last-seen time, energy plan and price zone (set per device, by a home owner), who paired it | You, your P1 reader | p1on-devices |
| Home profile | appliance survey answers (solar, EV, heat pump, electric boiler, dishwasher, washer, dryer, with size buckets), optional | You | p1on-devices (on the device row) |
| Energy readings | power, per-phase voltage and current, grid import/export per tariff register, the active tariff register, your meter's quarter-hour and monthly peak demand (capacity tariff, Belgium), frequency, power factor (every 1–10 s); gas usage (cumulative m³ and the time your gas meter recorded it), if gas is enabled (O11). Your meter's equipment number and protocol version are received with each reading but not stored | Your P1 reader | p1on-readings (raw items) |
| Hourly and daily summaries | averages, peaks and totals per hour and per day, including the NILM estimates below | Computed by us from readings | p1on-readings (rollup items) |
| Inferred behaviour | NILM appliance-category estimates (always-on, heating, EV charging, cooking, major appliance, other), stored on every reading and summary | Computed by us from readings | p1on-readings |
| Alert rules | the rules you set up, thresholds, schedules, who created each one | You | p1on-alerts |
| Alert history | each time an alert fired: what was measured, the rule's settings at that moment, the time | Computed by us | p1on-alert-events |
| Weekly insights | the AI-written headline, summary and tips, the week's figures and findings, the language, and the time you first opened it (openedAt) |
Computed by us, worded by an AI model | p1on-insights |
| Progress and gamification | daily scored rows (actual and target kWh, outdoor temperature used, off-peak share, standby watts), streaks, badges, points, quests | Computed by us | p1on-progress, p1on-progress-days |
| Live connection data | connection id, home, your user id, connect time, while the app shows live data | The app | p1on-ws-connections |
| Notification data | Expo push token, device platform (iOS/Android), registration and last-used time | Your device, if you enable push | p1on-push-tokens |
| Notification content | the text of each push, which can contain energy figures (for example "peaked at 3 120 W"), your home id and the id of the alert or insight | Computed by us | Not stored by us; sent to Expo (§8) |
| Usage metric | when you first open an insight: an event holding your user id, home id, insight id and week | The app | AWS CloudWatch logs and metrics |
| Usage data (last active day) | the calendar date (Europe/Brussels) you last opened the app, overwritten at most once a day. Only the latest date is kept, no history. It is used to count how many people use the app each day and how many stopped, so we can tell whether the product works | The app, when it loads your profile | p1on-users (your profile row) |
| Usage metric (pairing and daily activity) | anonymous counters: a reader pairing was started, succeeded or was refused (with a fixed reason code such as "expired challenge"), "one more person was active today", and which step of the pairing screen was reached (reader found, WiFi details sent, connected, or failed, with a fixed error code and whether Bluetooth or the test link was used). The app sends these pairing steps in the background; the request carries no identifier and we do not record who sent it. The counters hold no user, home or device id and no WiFi name | Our servers | AWS CloudWatch metrics and logs |
| Technical/diagnostic | crash and error reports, including home and device identifiers on server-side errors | The app and our servers (via Sentry) | Sentry |
Shared with the other members of your home. Every member of a home can see all the rows above that are keyed to the home: devices (including the contract data), readings and summaries, insights, alerts, alert history, progress, and the member list (user id, role, join date and the display name each member chose to set; never email addresses). Only home owners can change the energy plan and price zone, and only owners can invite or remove members. When someone leaves or is removed, they lose access at once.
For counsel: (a) the lawful basis for disclosing one person's household data to the other members the owner invites; (b) whether the household exemption (Art. 2(2)(c)) or joint controllership applies between members; (c) whether a member must be told that an owner can see their usage.
We do not collect data from your grid operator or supplier portal: all energy data comes
from hardware you own. We do not collect your location, address or phone number. Two shared
caches hold no personal data at all: day-ahead wholesale electricity prices (p1on-prices) and
daily mean outdoor temperature per price zone (p1on-weather).
4. Why we process it, and our legal basis
| Purpose | Legal basis (GDPR Art. 6) |
|---|---|
| Real-time monitoring, history, cost, and alerts (the core service) | Performance of a contract — Art. 6(1)(b) |
| AI weekly insights and NILM appliance disaggregation | [Legitimate interest — Art. 6(1)(f), with a documented LIA] or [Consent — Art. 6(1)(a)] — counsel to confirm |
| Improving and training our ML models | [Legitimate interest with LIA] / [Consent] — counsel to confirm; see §7 |
| Progress and gamification (daily score, streaks, badges, quests) | [Contract — Art. 6(1)(b), or legitimate interest — Art. 6(1)(f) — counsel to confirm] |
| Sharing a home's data with its other members | [counsel to confirm — see the note in §3] |
| Sending push notifications | Consent — Art. 6(1)(a); you may withdraw in OS settings |
| Security, fraud prevention, diagnostics and measuring whether insights are opened | Legitimate interest — Art. 6(1)(f) |
| Complying with legal obligations | Legal obligation — Art. 6(1)(c) |
For counsel: confirm the lawful basis for each bracketed row (owner task O15). Whether NILM disaggregation, which infers appliance behaviour, can rest on the contract or needs consent is the central question.
Where a purpose relies on consent, we ask for it explicitly and you may withdraw it at any time without affecting the lawfulness of earlier processing.
5. AI-generated content
Your weekly insights are generated by Amazon Nova large language models (Nova Micro, with Nova 2 Lite as a fallback if the primary is unavailable), hosted on AWS Bedrock in the EU. The model receives only the week's figures (total kWh, kWh per day, kWh per appliance category, the pre-computed findings and tip candidates, and your appliance survey answers) and last week's tip texts. It does not receive your name, email address, home name or any identifier. They are advisory only — they do not make automated decisions with legal or similarly significant effects about you (GDPR Art. 22 does not apply). AI-generated text is labelled as such in the app.
6. How long we keep data
Retention is enforced by DynamoDB time-to-live (TTL) where a TTL is shown. DynamoDB deletes an expired item within about 48 hours of its expiry, so a TTL is a clean-up, not a precise clock.
| Table / store | What it holds | Retention |
|---|---|---|
p1on-users |
Profile, including the last active day | Until you delete your account; then replaced by a tombstone (user id and deletion time only) that expires after 48 hours |
| Cognito user pool | Email and credentials | Until you delete your account |
p1on-homes, p1on-home-members |
Home and membership | Until the home is deleted, or until you leave or are removed (your membership row) |
p1on-invites |
Invite-link hashes | 7 days (TTL); expiry is also enforced in code |
p1on-invite-codes |
Invite-code hashes | 7 days (TTL); expiry is also enforced in code; deleted when the invite is revoked, the home is deleted or its creator is erased |
p1on-invite-attempts |
Per-user counters of invite-code attempts (brute-force protection) | About 25 hours (TTL); deleted when you delete your account |
p1on-devices |
Readers, contract data, appliance survey | Until the device or its home is deleted |
p1on-alerts |
Alert rules | Until you delete the rule or the home is deleted |
p1on-alert-events |
Alert history | 90 days (TTL) |
p1on-readings, raw readings |
High-frequency readings and their NILM estimates | 9 days (TTL) |
p1on-readings, hourly and daily summaries |
Aggregates and NILM category averages | 2 years (731 days from the start of the period, TTL) |
p1on-insights |
Weekly insights | 2 years (TTL, from generation) |
p1on-progress-days |
Daily progress rows | 2 years (731 days from the day, TTL) |
p1on-progress |
Streaks, badges, points, quest | Until the home is deleted |
p1on-ws-connections |
Live connections | 24 hours (TTL), or until you disconnect |
p1on-push-tokens |
Push tokens | No TTL: until you delete your account, or until Expo reports the token invalid |
| CloudWatch logs and metrics | Insight-open events, anonymous pairing-step and daily-activity counters, operational logs | Lambda logs are deleted automatically after 30 days (14 days for the reading-ingest function); IoT rule error logs after 30 days |
| Sentry | Crash and error reports | [Not configured in code — Sentry's default for our plan applies; owner/counsel to confirm and state the actual period] |
| Backups (DynamoDB point-in-time recovery) | A rolling copy of every table above | 35 days — see "Backups" below |
There is no separate analytics or training store today: the long-term history is the 2-year summaries above. (A cold-storage bucket exists but nothing writes to it; see §7.) Two shared caches hold no personal data and are not listed above: day-ahead electricity prices (40 days) and daily mean temperatures (400 days).
Backups. Every DynamoDB table has point-in-time recovery switched on, which keeps a rolling 35-day backup that we can restore from if data is lost or corrupted. When you delete your account (or something expires), your data is erased from the live tables at once, but copies of it can remain in these backups until the 35-day window has passed; backups are not edited, they simply roll off. We do not restore a backup in a way that would bring back an erased account. This is standard practice, and the 35 days is the longest your data can persist after erasure (plus the up-to-48-hour TTL delay above).
For counsel: confirm the 2-year period for summaries, insights and progress rows and its justification (seasonality of household consumption), and the Sentry retention period.
When you delete your account we erase your data as described in §9.
7. Machine-learning training
[NOT YET LIVE — the ML training/export pipeline this section describes (readings → S3 → training store) is not implemented yet; do not publish this section, or reword it to the present tense, until it ships. Kept here as the intended design:]
We use your readings to train models that power insights and anomaly detection. Before data
enters our training store we [pseudonymise it by replacing device and user identifiers with salted tokens held separately]. The optional appliance-label feedback loop is strictly
opt-in. Deleting your account also removes your data from the training store.
8. Who we share data with (sub-processors)
We use vetted service providers under Art. 28 data-processing agreements. Our current sub-processor list is at sub-processors.md. What each receives:
| Recipient | What it receives | Where |
|---|---|---|
| AWS (hosting, DynamoDB, Cognito, IoT Core, SNS, CloudWatch) | All data in §3 | eu-central-1 (Frankfurt) |
| AWS Bedrock (Amazon Nova models) | The week's figures and your appliance survey answers, as described in §5; no identifiers | EU inference only; the code refuses to run if the region is not in the EU |
| Expo push service (Expo, a US company) | Your push token and the notification: title, body (may contain energy figures), and a data block with only your home id and the id of the alert or insight (so the app opens the right screen) | United States [counsel to confirm] |
| Apple (APNs) and Google (FCM) | The notification, forwarded by Expo to your phone | United States and other regions [counsel to confirm] |
| Expo Updates | Your app's request for app updates (your IP address, platform, app version) | [counsel to confirm] |
| Sentry | Crash and error reports. The app is configured not to attach request bodies, headers or cookies; server-side reports carry home and device identifiers | [Region not yet confirmed — owner to confirm] |
Transfers outside the EEA. Notification delivery goes through Expo, which is a US company, and on to Apple and Google; your push token and the notification content leave the EEA on that path. Sentry's region is not yet confirmed. Everything else stays in the EU.
For counsel: the transfer mechanism for Expo, Apple/Google and (if US) Sentry — Standard Contractual Clauses, the EU–US Data Privacy Framework, or another — and whether the push payload should be reduced so that it carries no figures or identifiers (owner decision; design change).
Public data sources receive no personal data. To price dynamic tariffs and compute progress targets we fetch day-ahead electricity prices (api.energy-charts.info) and daily mean temperature (KMI/IRM in Belgium, KNMI in the Netherlands). Each request names only a price zone (BE, NL or LU), a weather station and a date. No user, device or home information is sent.
9. Your rights
You have the right to access, rectify, erase, restrict, and object to processing of your data, and to data portability. In the app you can:
Delete your account (Profile → Delete account) — erases your data across all our stores; access is revoked within 30 seconds, and the stored data is physically deleted in the background, normally within 15 minutes and in every case within 24 hours.
Shared homes. What is erased depends on who else is in your home:
- If you are the only member, the whole home is deleted: its devices, readings, summaries, insights, alerts, alert history, progress rows and invite links.
- If other people are still members, the home and its data stay in place for them. Only your own membership, push tokens, live connections, profile and sign-in account are removed. If you were the only owner, the longest-standing remaining member becomes the owner. Rows that record who created something (a device's pairer, an alert's creator, an invite's creator, who invited a member) keep your user id, which no longer maps to any account.
For counsel: whether keeping a departed member's opaque user id on shared-home rows, and keeping the readings of a shared home, is acceptable under Art. 17, or whether the user id must be scrubbed (owner decision; a code change).
Download your data (Profile → Download my data) — a machine-readable JSON copy (GDPR Art. 15 and 20). It contains your profile (including your display name), the homes you belong to (name, time zone, your role), their devices, alert rules, alert history, insights, progress rows, the invite links you created (never the link itself or its hash), your push tokens with their registration time, and the daily summaries of every device for the whole two-year retention. The hourly summaries and the raw readings still inside their nine-day window are delivered in pages by the web app's download; the phone apps' download carries everything else, and we send the hourly and raw detail on request within the one-month period below. Each export request is logged with your user id and the time (never the data) so we can show we answered within the deadline.
You may also contact [DPO EMAIL]. We respond within one month (GDPR Art. 12(3)).
10. Security
Data is encrypted in transit (TLS) and at rest (AWS KMS on our databases and storage). Every request is authenticated, and access to a home's data is checked on every request against your current membership of that home (a consistent read, so a removed member is refused immediately). Readers authenticate to our broker with their own factory-installed certificate. Error reports are configured not to attach request bodies, headers or cookies.
11. Children
P1On is not directed at children. You must be at least 16 years old to use it.
12. Changes
We may update this policy; we will notify you of material changes in the app and record the version you accept.
13. Contact
[CONTROLLER LEGAL NAME] — [DPO / PRIVACY EMAIL] — [POSTAL ADDRESS].