[APP][Pro] Homewizard 🧙‍♂️

Control your HomeWizard products (not the Link or Smart Switch.)

Stable: v3.15.3
Test/beta: v3.15.55


Nederlands forum topic hier, maar meeste info zal in dit engelse gedeelte te vinden zijn omdat dit al langer loopt.
[APP][Pro][NL] Homewizard 🧙‍♂️


HOMEWIZARD ENERGY PRODUCTS NOTES

Wifi P1 dongle support is only working when dongle has firmware 2.09! Please check firmware before you try to add it. This firmware support mDNS (auto discovery) hence easier to add. It is the same technique used as ChromeCast (Google). So if you face issues with your wifi network and struggle with the devices not found you can check you wifi vendor support pages on ChromeCast issues as it the same discovery method. Wait for the dongle to get this firmware from the cloud before you try to add it.

kwh1 & kwh3 (SDM230 & SDM630), energy sockets and the watermeter (~August 2022) before you try to add them you MUST enable Local API in your Homewizard Energy app. This is disabled by default and will not allow a discovery to work (mDNS method).

Make sure your wifi devices are getting a reserved ip address in your DHCP scope of your Wifi / Router dhcp.

PLUGIN BATTERY
If you want to control your Plugin Battery via Homey you have to add the P1 as a APIv2 device.
You can have it next to your existing P1api1 and disable the Homey Energy include to avoid double energy tracking. Or you remove the old one but do note that historical data for this P1 will be lost.

Steps:

  1. Add P1 as APIv2 (during the pairing process you have to press the P1 button on the device so be sure you near your P1 within 30 sec.

  2. Then you can add/pair your Plugin Battery (it is not really an order if battery is first or last, it is just key that the P1 is added as APIv2).

  3. After this you can add a flow and control the mode of the Plugin Battery via the P1apiv2.

TROUBLESHOOT TIPS FOR P1, KWH (SDM230/SDM630), WATERMETER, ENERGY-SOCKETS AND PLUGIN-BATTERY

  • Check de logs in the app settings (version v3.10.x)

  • Make sure Homey is in the same (wifi network)
  • Make sure devices are not on a Guest wifi SSID or AP client isolation is turned on (must be off!)
  • Make sure multicast is enabled on all your access points and routers
  • (unifi?) Disable Multicast enhancement
  • Reboot homey (mDNS discovery might be stuck)
  • Reboot your wifi accesspoints/routers (unifi / ubiquiti common issues)
  • Power cycle your device P1, KWH, watermeter or socket(s)
  • Verify “LOCAL API” is on in Homewizard Energy app for the device(s)
  • Watermeter does not work when on battery only (must be usb powered to enable LOCAL API mode)
  • Install mDNS discovery app on your iphone/android and check for _hwenergy._tcp and see you can see your devices there.
  • Toggle the LOCAL API in the official HomeWizard Energy app and restart the HW app on Homey to discover again

Or

Pihole and Adguard users:
For those users that have Homewizard device issues (! Icon) or devices that wont move to available is a tip related to Pihole and/or Adguard.
Multicast DNS isnt handled properly via these DNS sinkholes. You should install AVAHI service on your Pihole and/or Adguard linux server that picks up these queries and resolves these queries locally.

TIPS

  • For Homewizard Energy devices my suggestion is reserve static ip’s in the dhcp server scope of your router (when possible). Some routers and dhcpserver keep cycle their dhcp scope.

  • More advanced tip(and those who are knowledgeable enough to implement): separate your IoT devices from your local LAN. Most of these IoT devices are cheap China tech and not known to proper firmware updates. When you separate these you need mdns repeater/proxy/relay on your router. But only if you know how to do it as its very complex to implement and requires a high level of network understanding (vlans & firewall rules).


HOMEWIZARD (legacy, yeah the old appliance)

small

Upon first deployment you need add the HomeWizard unit first,
then you can add the related/connected components
from HomeWizard to your Homey (ie. Heatlink, Energylink etc.

Get your local Homewizard IP address and local password (not the Homewizard Online account!)

If trying to add this in the Homey GUI and get a quick flash of this screen and blank after, please use the webinterface of Homey GUI https://my.homey.app.

Homey does not support Heatlink and Energylink directly without the Homewizard unit.
Homewizard have protected their 868mhz communication with Energylink and Heatlink so you still need the Homewizard unit to make this work.

Supports: Energylink, Heatlink, Windmeter, Rainmeter, Temperature sensors, Smoke & Motion sensors
Does not support: Light bulbs & Power sockets (use KlikAanKlikUit or Smartwares app to control these).
Note on Motion sensor: There is a 10 seconds delay (use KlikAanKlikUit or Smartwares app if you need direct response).

Relevant sources and links
Project master source: GitHub - jtebbens/com.homewizard: Homewizard app for Homey · GitHub
Beta channel: https://github.com/jtebbens/com.homewizard/tree/beta
Test install from app store: HomeWizard | Homey

ONLY SENT DIAGNOSTIC REPORTS WHEN I ASK FOR IT

Developers: Jeroen Tebbens, Jeroen Bos, Nick Bockmeulen, Freddie Welvering, Emile

:memo: Latest Updates (v3.15.49–v3.15.55)

Battery Policy — DP Optimizer Fixes

  • getSlot biased toward active slot (v3.15.55) — At the exact midpoint between two hourly slots (e.g. 12:30), getSlot() previously picked the next slot due to a millisecond timing offset, causing that slot’s action to be applied up to 30 minutes too early. It now always returns the most recently started slot (the one currently being executed), falling back to nearest-future only when no past slot exists yet (e.g. on first startup)

  • Partial-slot charge modelling (v3.15.55) — When the optimizer recomputes mid-slot, it previously modelled the current slot as a full 1-hour charging opportunity (0.8 kWh). This caused it to overestimate how much charge could be obtained in the remaining time and incorrectly skip the next slot. The DP now scales chargeSocDeltaG and chargeKwhFull for slot 0 based on the fraction of the slot still remaining (slot0RemainingFrac), so it correctly plans additional charge slots when needed (e.g. charge=2 instead of charge=1)

  • vPreserve opportunity cost (v3.15.53) — The DP previously treated PV charging during preserve slots as free: storing surplus PV had zero cost in the value function. It now subtracts the foregone export revenue (storedKwh × price × exportRatio) from vPreserve. This corrects the bias toward preserve when PV could profitably be exported instead, making standby more competitive at low positive prices

Battery Policy — Planning & Consumption

  • Consumption slot timezone fix (v3.15.49) — Price records now carry explicit Amsterdam hour/minute fields. When present, consumption lookups use getPredictedConsumptionForSlot() instead of deriving the hour from the UTC timestamp. Previously, UTC timestamps without a timezone indicator were shifted by +2h (CEST), causing all consumption forecasts to land on the wrong slot and return the baseload floor (~314 W) everywhere

  • Null consumption when nothing is learned (v3.15.49) — If the learning engine has not yet accumulated any non-zero consumption data, consumptionWPerSlot is passed as null to the optimizer instead of an all-zero array. An all-zero array caused the baseload floor to over-constrain discharge planning as if the house never consumed power; null correctly instructs the optimizer to use unconstrained max discharge power (800 W)

  • pvStoreWins simulation in planning forward pass (v3.15.49) — The optimizer’s forward pass now simulates the _pvStoreWins override that the runtime policy engine applies. When a standby slot would have pvStoreWins active (PV surplus worth more than current export price), the planning chart shows zero_charge_only and updates the projected SoC accordingly — matching what actually happens at runtime

  • Planning slot reasons (v3.15.49)_mapActionToHwModeForPlanning now returns a reason string alongside hwMode (e.g. dp:charge negative_price, preserve:pv_strong(3200W)). Stored in the schedule and visible in the settings UI for easier diagnostics

Battery Policy — PV Estimation

  • PV estimation fallback to weather forecast (v3.15.54)_estimatePvProduction() is now used everywhere house consumption is calculated. When no flow card is supplying live PV data (or the data is stale), it falls back to a weather-based estimate using sun score and configured PV capacity. Previously this._pvProductionW ?? 0 was used directly, causing 0 W PV during stale periods and overcounting house consumption by the full battery charge power in the learning engine

  • P1 firmware batteryPower = 0 correction (v3.15.55) — The P1/DSMR firmware incorrectly reports battery power as 0 W when the battery is in to_full mode. The battery-policy device now detects this case (mode = to_full, reported power = 0) and substitutes the configured max charge power from device state. Without this correction the learning engine recorded house consumption ~800 W too high during every grid-charging session


Previous Updates (v3.15.40)

Battery Policy — Negative Price Optimizer

  • RTE correction for physical SoCchargeSocDeltaG was previously computed including the RTE factor, causing the DP to think the battery needed 5 hours to fill instead of the physical 4 hours (at 800 W / 2.688 kWh). RTE losses are now applied only on the discharge side (dischargeValue × RTE), matching how the firmware reports physical SoC

  • Skip marginal negative slots — The DP now skips marginally negative slots (e.g. −€0.021) when better slots (e.g. −€0.367) provide sufficient capacity to fill the battery. Previously all negative slots were charged, including the least valuable ones

  • Preserve at negative price → standby — When spot price is negative and PV is strong, the battery is now held in standby instead of zero_charge_only. Charging from PV surplus via zero_charge_only would consume capacity before cheaper grid-charge slots, partially missing the best −€0.367 windows

  • PV accuracy protected at negative pricesrecordPvAccuracy() is no longer called when spot price is negative. Users often disable their inverter to avoid export costs; recording actual=0 against a positive forecast would incorrectly degrade PV learning data


Previous Updates (v3.15.38)

Battery Cycle Tracking

  • Cycle accumulators survive restarts_cycleKwhDischarged, _cycleRevenue and _cycleCost are now persisted to device store (alongside _costEnergy/_costAvg). Previously a restart during an active discharge silently reset all accumulators to zero, causing the evening discharge to be missing from cycle history and ROI tracking

  • RTE learning cycle fix — Balance guard lowered from 1.45 → 1.40. The old threshold (1.45) meant the minimum measurable RTE at guard-passage was 1/1.45 = 68.9%, just below the 70% floor — so every measurement that barely passed the guard was immediately discarded. With 1.40 the minimum is 71.4%, ensuring a valid measurement every time the guard passes

Battery Policy

  • Negative price → always charge to full — When spot price is negative, the mapper now returns to_full regardless of PV state. Charging at negative prices earns money, so PV-mode guards (zero_charge_only, pvStoreWins) are bypassed

UI

  • Learning status always currentlearning_status is now written on every _updateWeather call (hourly), not only when the optimizer runs. Previously, with policy disabled or in predictive mode, the Leerdagen/coverage/PV-accuracy pills in the settings UI would show stale values

Previous Updates (v3.15.37)

Battery Policy — PV Forecast & Learning

  • Yield-factor normalisation (v1 + v2) — Yield factors learned while radiation_bias_factor > 1.5 was active were systematically under-calibrated (biased radiation as baseline). One-time reset so they re-learn against unbiased radiation. v2 also resets the bias factor itself, which had been artificially inflated to the cap by the miscalibrated yield factors

  • Solcast moved to _updateWeather — Solcast forecast is now fetched on every weather update (including when policy is disabled), keeping the PV chart current at all times

  • Intraday PV scaling tuned — Lower learning weights for intraday correction; prevents overreaction to temporary deviations early in the day

  • Cycle recorded on discharge→charge transition — Battery cycles are now also recorded when SoC never reaches 0% (typical on PV-heavy days): trigger is the transition from discharging to charging once ≥ 0.3 kWh has been discharged

Battery Policy — Battery Mode Camera

  • Predictive modes visible in camera — In predictive mode (HW Slim Laden active) modes were not recorded because the policy does not run. The slot interval now also records mode + SoC when policy is disabled, so switches between predictive_charge, predictive_discharge, predictive_zero and predictive_standby become visible in the Battery Modes webcam

Memory & Stability

  • Startup crash fix (v3.15.35)homey.settings.set allocates ~30 MB V8 heap per call regardless of payload size. With multiple devices initialising concurrently, heap peaked at 70+ MB → Memory Warning. All drivers now use a serialised write queue (8 s between writes). Rebuildable UI state (planning, explainability, weather) lives in _liveState in memory and is served via api.js — never written to homey.settings

  • Settings page live-stateHomey.get on the settings page now automatically merges in-memory live-state via a GET /getLiveState API call. Existing render code requires no changes

  • SDM230_v2 / SDM630_v2 polling spread (v3.15.36) — When multiple SDM devices are present, the first poll is spread across the polling interval to avoid simultaneous HTTP requests

  • Initial weather and policy deferred — Weather fetch deferred to T+30 s, first policy check to T+45 s after startup. Prevents a cumulative heap peak of 70+ MB during the onInit cascade on setups with many devices

  • Device-type counter in memory log[MEM] log line now shows instance counts per driver type (energy_v2=2 plugin_battery=1 …) to speed up triage of crashes from users with different device configurations


:memo: Previous Updates (v3.15.10)

Battery Policy — Optimizer & PV Modelling

  • pvCoverage uses net PV surplus — PV coverage fraction in the DP now subtracts house consumption before dividing by max charge power: max(0, pvW − consW) / maxChargeW. Previously raw pvW was used, causing the DP to overstate free SoC gain during zero_charge_only slots, underestimate effective charge cost, and overcount cumulative pvKwhFromT. All downstream calculations (pvStrongCoverage threshold, dp.fill guard, terminal value discount) now reflect what the battery can actually absorb

  • pvKwhTomorrow is net-absorbable — Tomorrow’s PV estimate passed to the optimizer changed from raw forecast watts to net surplus after learned house consumption, further capped by battery group max charge rate. Fixes over-optimistic terminal value discounting and headroom floor decisions on days where house load consumes most of the PV output

  • dp.fill guard restricted to non-PV slots — The dp-flattening step (when PV tomorrow can fully refill the battery) is now skipped during slots with strong PV coverage. Previously flattening during PV hours caused the DP to lose sight of the evening peak value; the DP then relied on the discharge floor as a crutch and could miss profitable peaks

Battery Policy — Planning

  • Three-tier per-slot discharge floor — Each price slot now gets its own floor based on expected PV output: strong PV (surplus ≥ 50% of max charge power) → min_discharge_price (default €0.22, prevents round-trip loss during solar peak); weak PV (50–400W surplus) → break-even + €0.02; night → €0 or break-even depending on PV day. Previously a single flat floor was applied to all slots

  • Linear interpolation for policy-engine PV lookup_getPvWForTimestamp now uses linear interpolation between forecast points (consistent with the optimizer’s _getPvForSlot). The old nearest-neighbour (35-min threshold) produced different pvStrong decisions for :15/:30/:45-offset slots, causing planning and optimizer to disagree on zero_charge_only transitions

Battery Policy — PV Forecast & Planning

  • Solcast integration - Satellite-based PV forecast (30-min resolution) blended with Open-Meteo weather model. Optional, requires Solcast API key and resource ID in settings. Lazy-loaded; cached across restarts

  • Blend log split by day - [PV blend] log now shows today and tomorrow separately, making it easy to verify forecast accuracy per day

  • Self-sufficiency tracking - Daily grid import vs. house consumption accumulated in real time (15 s poll). Persisted to settings across restarts; visible in battery expansion analysis

  • SoC plan snapshot - Planned SoC per slot stored on first computation, never overwritten. Enables frontend to show “planned vs. actual” SoC for past slots

  • currentPrice fix - Widget/settings were showing the first slot (which could be in the past); now correctly uses the first future slot

  • Consumption margin - Optimizer assumes 20% higher consumption than learned average while evening patterns are still building up

  • _recomputeOptimizer made async - Required for Solcast API calls inside the optimizer path

Battery Policy — PV Camera Image & Planning UI

  • PV Opwek camera image - New third camera image (planning_pv / “PV Opwek”) on the battery-policy device shows PV actual vs forecast as a webcam-style chart. Visible in the Homey app without needing the settings page — ideal for quick access from phone or tablet. Uses quickchart.io with Chart.js 4, 900×900 resolution, dark theme

  • SoC forward simulation - Fixed stale SoC projection on the planning chart. Previously the optimizer’s socProjected was computed hours ago with a different starting SoC, causing the dashed SoC line to jump unrealistically. Now simulates forward from the real current SoC using mode + pvW per slot, producing a realistic trajectory

  • PV surplus text repositioned - “Zonne-energie vandaag” forecast text (e.g. “Batterij wordt volledig vol van zonne-energie”) moved from a separate block below the daily profit table to an inline caption between today’s PV chart and the planning hour cards

Polling & Connectivity

  • Plugin battery polling floor - Polling interval now enforced to minimum 5 seconds (Math.max(..., 5)) in all three code paths (startup, settings change, interval restart); settings UI also enforces min: 5

  • SDM230 backoff on failure - After 3 consecutive poll failures the SDM230 slows to a 60 s backoff interval. Automatically restores normal interval on next successful poll

  • Cloud WebSocket race condition fix - mainWs was assigned before the socket was ready; a concurrent reconnect could replace it mid-handshake, leaving stale event listeners firing on the wrong socket. Fixed by using a local ws variable for all event listeners, with a guard (if (this.mainWs !== ws) return) that silently drops events from superseded sockets. Also removed the redundant double-open guard that was papering over the root cause


Battery Policy — Previous (v3.15.3)

Battery Policy — Multi-Battery Discharge Fix

  • Discharge power capped at 800 W - HW firmware limits discharge (max_production_w) to 800 W regardless of battery count (charge scales linearly, discharge does not). The fallback calculation incorrectly assumed unitCount × 800 W, causing 3-battery setups to report “capaciteit: 2400W” in explainability text while actual discharge was locked at 800 W. Fixed in policy-engine, explainability-engine, and device _getBatteryState() fallback. If the max_production_w and max_consumption_w are properly set (eg. 1600w) that value will be used.

  • WebSocket capability guard - max_consumption_w and max_production_w are now only updated when actually present in the WS payload (typeof === 'number'). Previously, missing fields were written as 0, which caused the ?? fallback to pass through 0 instead of triggering the corrected 800 W fallback

  • Confidence rounding - Learning-adjusted confidence now uses Math.round() after adjustment, preventing 14-decimal-place values (e.g. 99.33326922747905) in timeline entries and flow tokens

Battery Policy — Learning Engine

  • 15-minute consumption resolution - Consumption patterns upgraded from hourly (7 × 24 = 168 slots) to 15-minute (7 × 24 × 4 = 672 slots). Includes automatic migration from old hourly format, spreading existing averages evenly across quarter slots

  • Amsterdam timezone fix - All consumption recording now uses _getAmsterdamTime() (via toLocaleString with Europe/Amsterdam timezone) instead of getHours() which returns UTC on Homey. One-time reset migration clears old UTC-indexed data; re-learning takes ~24–48h

  • Daily profile export - New getDailyProfile(dayOfWeek) method returns 96 slots with predicted wattage, enabling per-day consumption charts in the settings UI

Battery Policy — Expansion Analysis (new)

  • What-if battery comparison - New computeExpectedProfit() method on OptimizationEngine runs the DP for 1–4 battery scenarios without modifying the live schedule. Shows marginal daily/yearly profit per additional battery, power bottleneck slots where house consumption exceeds discharge capacity, and payback period based on configurable investment cost

  • Settings tab “Uitbreiding” - New tab visualises expansion scenarios with per-unit profit cards, shortfall indicators, and user-adjustable battery price input

Battery Policy — Consumption Profile Chart (new)

  • Learned consumption chart - New chart in the planning tab renders the learned 15-min consumption profile per day-of-week. Features day selector (Ma–Zo), peak detection with top-3 labels, colour-coded bars (green → yellow → red), and current-slot highlight. Updates hourly via policy_consumption_profile setting

Optimizer Engine — Refactoring

  • Pure DP kernel - Backward induction extracted into _runBackwardDP() — a fully side-effect-free method returning {dp, policy, ...}. Forward pass remains in compute(). Enables computeExpectedProfit() to reuse the same DP logic without touching _schedule

  • Projected profit tracking - _schedule now includes projectedProfit (€) from the DP value function at current SoC, used by expansion analysis


:open_book: Full Changelog

Click to expand complete version history

The power sensor from homewizard adds up to the total usage in homey energy. But the watcher should be the overall power usage. And all the other devices a slice of that. Now I have more usage then the watcher says.

For example

650 should be the bottom value. (Total usage)

I don’t even see Energie (HomeWizard)

Hi all, Homewizard app is not compatible yet with Homey 3.0. It was just released (final) and I have it installed today myself so I can start development/update on the Homewizard app to make it work properly with Homey 3.0.

Thanks for the quick reply! If you need any info let me know. I will wait until the next release

Thanks!

Beta release (pending) Energylink is now detected as overall measure (Smart Meter/Slimme Meter).
To use this you have to pair your Energylink again.

:+1:

Ok beta version is approved so you guys can play with it.

Thanks! The p1 energy is added to the energy measured in the zones so the total energy is not correct.

Please explain. Don’t understand.

After I log out and in (app) everything looks fine.

Ok

After a wile the Engerylink values won’t update anymore. Resetting the app does not resolve the problem.

That problem is related to your Homewizard wifi connectivity. I have no problems with the beta app myself (still running and getting Energylink data). Another one could be Homewizard and Energylink distance. Not sure how your units are placed and configured but it sounds like you have to check it first.

Mmm strange, never noticed that problem before…

I noticed the same thing (before the beta version), but like Jeroen said it’s a Homewizard issue.
What i did , i connect Homewizard to a KAKU switch and connect the switch to Homey.
At 00:05 Homey checks with Energylink if the values are not greater then 1kwh.
If they are greater Homey switch the KAKU off and after 30 sec on , to reset Homewizard.
And the problem is fixed :grinning:

Yes correct. Another problem what could cause this is if you have other integrations (domoticz or HASS etc) talking to your Homewizard unit. The Homewizard unit gets overloaded (high cpu or open connections) which eventually make the Homewizard unresponsive for a while. Not sure if you have other http gets getting data from Homewizard?

No I only use HomeWizard with Energylink at the moment. Maybe I’am switching tot Youless in the near future so I can switch off Homewizard. But for now I’am happy with your app and investigate the connection with Homey as you mention.