Skip to content

New controls for heating and water#1

Open
mikeSwe77 wants to merge 5 commits intochristian-ek:mainfrom
mikeSwe77:main
Open

New controls for heating and water#1
mikeSwe77 wants to merge 5 commits intochristian-ek:mainfrom
mikeSwe77:main

Conversation

@mikeSwe77
Copy link

@mikeSwe77 mikeSwe77 commented Jan 18, 2026

Added ability to change heating temperature, change water heater mode and boost hot water production.

Summary by CodeRabbit

  • New Features

    • Hot water mode control (eco/high/low)
    • Hot water boost button
    • Target temperature control (10–30°C, 0.5°C steps)
    • Room temperature monitoring
    • Enhanced temperature displays with color-coded zones
  • Improvements

    • More reliable device state synchronization and polling; better error handling for updates
  • Chores

    • Minimum app compatibility raised to version 12.0.0

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 18, 2026

📝 Walkthrough

Walkthrough

Updated manifests and driver definitions to require Homey compatibility >=12.0.0; added hotwater_boost and ivt_hotwater_mode capabilities; refactored heat-pump driver class and capability options; implemented new device lifecycle, XMPP PUT support, guarded polling, and room-temperature capability mapping; added .homeyignore and large device snapshot.

Changes

Cohort / File(s) Summary
Manifests (root & compose)
​.homeycompose/app.json, app.json, drivers/heat-pump/driver.compose.json
Bumped compatibility to >=12.0.0; changed driver class to "heatpump"; added statusIndicator: "measure_temperature"; added target_temperature, combined measure_temperature zones, and new capabilities ivt_hotwater_mode and hotwater_boost; updated capabilitiesOptions (titles, zones, min/max/step).
Capability Definitions
​.homeycompose/capabilities/hotwater_boost.json, ​.homeycompose/capabilities/ivt_hotwater_mode.json, ​.homeycompose/capabilities/alarm_status.json
Added hotwater_boost (boolean/button, get/set) and ivt_hotwater_mode (enum picker with eco/high/low); removed trailing newline marker in alarm_status.json (no semantic change).
Device Driver Implementation
drivers/heat-pump/device.js
Major refactor: added guarded polling (isWriting), delayed startup, async getDeviceData, new capability handlers onCapabilityTargetTemperature, onCapabilityHotWaterMode, onCapabilityHotWaterBoost performing encrypted PUT via XMPP client; updateValue made async with alarm handling; improved error handling, client reconnect on settings change, and cleanup on delete.
Capability Mapping Library
lib/capabilities.js
Added ROOM_TEMP mapping pointing measure_temperature to /heatingCircuits/hc1/roomtemperature.
Submodule & Ignore
lib/bosch-xmpp (submodule ref), .homeyignore
Updated bosch-xmpp submodule commit reference; added .homeyignore with common ignore patterns and a README exception.
Docs / Data Snapshot
docs/rawscan.txt
Added large YAML-style device/system snapshot containing nested thermostat entities, recordings, and state maps (data-only addition).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Homey as Homey Platform
    participant Device as HeatPump Device
    participant XMPP as XMPP Client
    participant HeatPump as Physical Heat Pump

    User->>Homey: change capability (target_temperature / ivt_hotwater_mode / hotwater_boost)
    Homey->>Device: trigger capability handler
    Device->>Device: set isWriting = true
    Device->>XMPP: PUT encrypted payload (capability change)
    XMPP->>HeatPump: send command
    HeatPump-->>XMPP: respond
    XMPP-->>Device: deliver response
    Device->>Device: set isWriting = false
    Device->>Homey: update capability state
    Homey->>User: confirm change

    rect rgba(100,200,100,0.5)
    Note over Device,HeatPump: Polling loop skips fetch while isWriting = true
    end

    Device->>XMPP: periodic GET (when not writing)
    XMPP->>HeatPump: request state endpoints
    HeatPump-->>XMPP: return values
    XMPP-->>Device: parse values
    Device->>Homey: update capabilities
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through manifests and nets with glee,
Added boosts and modes to make hot water free,
I guarded polling, put through XMPP rhyme,
Now room temps hum in tidy time,
Cheers from a rabbit for this cozy spree!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'New controls for heating and water' directly aligns with the PR's stated objective to add controls for changing heating temperature, water heater mode, and hot water boost.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@docs/rawscan.txt`:
- Around line 1121-1124: The raw scan contains sensitive internal data (an
internal IP and device path) in the recordedResource block; sanitize by
replacing the specific IP and any credential-related node references with
placeholders (e.g., replace "http://192.168.7.67" with
"http://<REDACTED_INTERNAL_IP>" and the id
"/system/sensors/temperatures/outdoor_t1" with
"/system/sensors/temperatures/<REDACTED_DEVICE>") or move the entire raw scan to
a private location before committing; update occurrences tied to the
recordedResource, uri, and interval fields accordingly and ensure no other
credential or device-identifying nodes remain in the file.

In `@drivers/heat-pump/device.js`:
- Around line 74-88: The onCapabilityHotWaterBoost handler currently ignores the
incoming value and always triggers a boost; update the onCapabilityHotWaterBoost
method to first check the incoming value and only proceed with setting
isWriting, calling this.client.put(endpoint, payload) and scheduling
setCapabilityValue('hotwater_boost', false) when value is truthy (true); if
value is false, short-circuit and return a resolved promise without sending the
PUT or scheduling the reset, and keep the existing try/catch/finally structure
so isWriting is only set while performing the write and errors are handled the
same way.
- Around line 166-168: The code is comparing a boolean capability to the string
'error', so the OK flow never fires; update the condition that calls
homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error)
to check the boolean value returned by this.getCapabilityValue('alarm_status')
(e.g., use if (!this.getCapabilityValue('alarm_status')) or === false) instead
of === 'error' so the trigger runs when the alarm_status capability is false.
- Around line 103-107: In the meter_power branch the code uses currentHour - 2
to index res.recording which can be negative or out-of-range and causes a
TypeError; update the branch (the block where value.name.includes('meter_power')
computes currentHourObject and result) to first validate that res.recording
exists and is an array, compute a safe index (e.g., wrap/shift hours or clamp to
0..res.recording.length-1 instead of currentHour-2), guard that
currentHourObject is defined and currentHourObject.c is not zero before
dividing, and provide a sensible fallback (e.g., result = 0 or skip updating)
when data is missing to avoid exceptions and silent failures.
- Around line 174-182: The code calls a non-existent method setUpdateInterval in
the settings handler; replace that call by creating a new interval and assigning
it to this.interval (clearInterval already done) using setInterval to invoke the
existing async getDeviceData only when this.isWriting is false, matching the
onInit behavior; update the block that references setUpdateInterval to set
this.interval = setInterval(async () => { if (!this.isWriting) await
this.getDeviceData(); }, newSettings.interval * 1000) so the device continues
polling with the new interval and avoids runtime errors.

In `@lib/bosch-xmpp`:
- Line 1: The submodule pointer for lib/bosch-xmpp references a missing upstream
commit (eb70803c0211f39d1887b8b12bf0420a7d35a2a2); update the repo so fresh
clones succeed by fixing the submodule entry: either ensure the commit exists
upstream, or update the pointer in the submodule configuration (the
lib/bosch-xmpp submodule entry in .gitmodules and the commit recorded in the
index) to a valid upstream commit (e.g., f066951) or correct the URL to the
proper upstream repository, then commit the submodule change so clones
initialize without "not our ref" errors.
🧹 Nitpick comments (1)
.homeycompose/capabilities/hotwater_boost.json (1)

1-11: LGTM! Consider adding an icon for UI consistency.

The capability definition is well-structured with proper localization. The button UI component and insights: false are appropriate for a temporary boost action.

For consistency with other capabilities (e.g., alarm_status.json which defines "icon": "/assets/icons/status.svg"), consider adding an icon property.

💡 Optional: Add icon for visual consistency
   "title": {
     "en": "Extra Hot Water",
     "sv": "Extra Varmvatten"
   },
+  "icon": "/assets/icons/hotwater.svg",
   "uiComponent": "button",

Comment on lines 166 to 168
} else if (this.getCapabilityValue('alarm_status') === 'error') {
this.log('Alarm status has changed to OK. Trigger OK card.');
this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this)
.catch(this.error);
this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

alarm_status_ok never triggers due to string comparison.
At Line 166, alarm_status is a boolean capability, but it’s compared to the string 'error', so the OK flow never fires.

✅ Proposed fix
-    } else if (this.getCapabilityValue('alarm_status') === 'error') {
+    } else if (this.getCapabilityValue('alarm_status') === true) {
       this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else if (this.getCapabilityValue('alarm_status') === 'error') {
this.log('Alarm status has changed to OK. Trigger OK card.');
this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this)
.catch(this.error);
this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error);
}
} else if (this.getCapabilityValue('alarm_status') === true) {
this.homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error);
}
🤖 Prompt for AI Agents
In `@drivers/heat-pump/device.js` around lines 166 - 168, The code is comparing a
boolean capability to the string 'error', so the OK flow never fires; update the
condition that calls
homey.flow.getDeviceTriggerCard('alarm_status_ok').trigger(this).catch(this.error)
to check the boolean value returned by this.getCapabilityValue('alarm_status')
(e.g., use if (!this.getCapabilityValue('alarm_status')) or === false) instead
of === 'error' so the trigger runs when the alarm_status capability is false.

@@ -1 +1 @@
Subproject commit 4b2217acf779cfe614cc29c2c204bca33b4edaeb
Subproject commit eb70803c0211f39d1887b8b12bf0420a7d35a2a2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check current submodule status and gather commit information
echo "=== Submodule Status ==="
git submodule status lib/bosch-xmpp

echo -e "\n=== Target Commit Details ==="
if git -C lib/bosch-xmpp rev-parse eb70803c0211f39d1887b8b12bf0420a7d35a2a2 &>/dev/null; then
  echo "Commit exists: YES"
  git -C lib/bosch-xmpp show --stat eb70803c0211f39d1887b8b12bf0420a7d35a2a2 | head -50
else
  echo "Commit exists: NO (cannot verify)"
fi

echo -e "\n=== Previous Commit (if available) ==="
git show HEAD:lib/bosch-xmpp 2>/dev/null || echo "Unable to retrieve previous pointer"

Repository: christian-ek/se.anywhere.ivt

Length of output: 468


🏁 Script executed:

#!/bin/bash
echo "=== Submodule Configuration ==="
git config --file=.gitmodules --list | grep bosch-xmpp

echo -e "\n=== Current HEAD State for lib/bosch-xmpp ==="
git ls-tree HEAD lib/bosch-xmpp

echo -e "\n=== Try to find the commit in local branches ==="
if git -C lib/bosch-xmpp rev-parse eb70803c0211f39d1887b8b12bf0420a7d35a2a2 &>/dev/null; then
  echo "Local commit found"
  git -C lib/bosch-xmpp branch --contains eb70803c0211f39d1887b8b12bf0420a7d35a2a2 2>&1 | head -10
else
  echo "Commit not in local git history"
fi

echo -e "\n=== Check recent commits in lib/bosch-xmpp ==="
git -C lib/bosch-xmpp log --oneline -5 2>&1 || echo "Cannot access log (submodule not cloned)"

Repository: christian-ek/se.anywhere.ivt

Length of output: 649


Submodule pointer references commit unavailable in upstream—blocking issue.

The commit eb70803c0211f39d1887b8b12bf0420a7d35a2a2 does not exist in the upstream repository at https://github.com/robertklep/bosch-xmpp.git. Fresh clones will fail to initialize this submodule with the error "not our ref." This must be resolved before merging:

  • Ensure the commit exists in the upstream repository, or
  • Update the pointer to an existing upstream commit (e.g., the latest available is f066951), or
  • Verify the submodule URL is correct.
🤖 Prompt for AI Agents
In `@lib/bosch-xmpp` at line 1, The submodule pointer for lib/bosch-xmpp
references a missing upstream commit (eb70803c0211f39d1887b8b12bf0420a7d35a2a2);
update the repo so fresh clones succeed by fixing the submodule entry: either
ensure the commit exists upstream, or update the pointer in the submodule
configuration (the lib/bosch-xmpp submodule entry in .gitmodules and the commit
recorded in the index) to a valid upstream commit (e.g., f066951) or correct the
URL to the proper upstream repository, then commit the submodule change so
clones initialize without "not our ref" errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant