Skip to content

Fix plan web UI using browser timezone instead of Predbat's configured timezone#3626

Merged
springfall2008 merged 2 commits intomainfrom
copilot/fix-time-zone-for-adding-plan
Mar 22, 2026
Merged

Fix plan web UI using browser timezone instead of Predbat's configured timezone#3626
springfall2008 merged 2 commits intomainfrom
copilot/fix-time-zone-for-adding-plan

Conversation

Copy link
Contributor

Copilot AI commented Mar 22, 2026

When accessing the Predbat plan web UI from a device in a different timezone (e.g., iPhone in the US via Nabu Casa), clicking a time slot to set an override sent a time string formatted in the browser's local timezone to the server, which interpreted it in Predbat's configured timezone — causing overrides to land in the wrong slot.

Root cause

formatTimeDisplay() in web_helper.py used browser-local Date methods (getDay(), getHours(), getMinutes()) to format the ISO timestamps from the plan JSON. The resulting string (e.g., "Mon 00:30" instead of "Mon 05:30") was POSTed to the server and interpreted as Predbat local time.

The plan JSON timestamps already carry the correct Predbat timezone offset (e.g., 2024-11-25T05:30:00+0000), so the fix can be self-contained in the client.

Changes

  • New helper getTimezoneOffsetMinutes(isoTimestamp) — extracts the UTC offset in minutes from the ISO string, handling both +HHMM (strftime) and +HH:MM (isoformat()) variants
  • formatTimeDisplay() — now applies the extracted offset to UTC time and reads via getUTC*() methods, producing the correct Predbat-timezone display regardless of browser locale
  • formatTimestamp() — same fix for the "Updated: …" header timestamp (display consistency)
  • getMinutesFromTimeString() fallback — replaced the browser-local getHours()/getMinutes() fallback with the offset-aware equivalent
// Before — uses browser local timezone
const dayName = days[date.getDay()];
const hours = date.getHours().toString().padStart(2, '0');

// After — uses offset embedded in the ISO string
const offsetMinutes = getTimezoneOffsetMinutes(isoTimestamp);
const adjDate = new Date(date.getTime() + offsetMinutes * 60000);
const dayName = days[adjDate.getUTCDay()];
const hours = adjDate.getUTCHours().toString().padStart(2, '0');

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.octopus.energy
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick (dns block)
  • gitlab.com
    • Triggering command: /usr/lib/git-core/git-remote-https /usr/lib/git-core/git-remote-https origin REDACTED (dns block)
  • https://api.github.com/repos/springfall2008/batpred/contents/apps/predbat
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick (http block)
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick --test web_if (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Wrong Time Zone used for Updating Plan via Add on Web Page</issue_title>
<issue_description>Describe the bug
When an iPhone was used to update the plan via the Add-on Web Page in Home Assistant (Accessed via Nabu Casa), the plan updated using the iPhone local timezone, not the Predbat Time Zone, i.e. Touched the 5.30-6.00 slot and selected "Force Charge" the Force Charge was updated in the 6.30-7.00 plan time slot).

Its worth saying that if I use the selectors and select the time it works correctly.

Expected behaviour
The changes via the Plan work using the Prebat Time Zone not the Device TimeZone

Predbat version

1.5.5 / 8.34.4

Environment details

  • Home Assistant Green,
  • Standard HAOS, Predbat running as an App
  • iPhone used to access HA via Nabu Casa

Screenshots
If applicable, add screenshots to help explain your problem. The most useful ones can be your battery chart, the Predbat HTML plan and your current settings in HA.

Log file
Can you capture a log file from the time of the issue, debug mode is not normally required.

You can download the logfile from the WebUI on the Dash tab select predbat_debug.log

Predbat debug yaml file
This is important for any plan related issues.

Once you have captured the issue go to the Web UI, in the Dash tab click on predbat_debug.yaml and wait 30 seconds for it to download. Select 'keep' if your Web Browser thinks the file is dangerous.

Rename the download file to predbat_debug.yaml.txt and upload it to GitHub. This will allow your plan to be reproduced and also stores all your settings for review.
</issue_description>

<agent_instructions>The Web interface should show the time in the timezone predbat is configured to and not the web browsers time zone</agent_instructions>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

…tead of browser's

Co-authored-by: springfall2008 <48591903+springfall2008@users.noreply.github.com>
Agent-Logs-Url: https://github.com/springfall2008/batpred/sessions/08b1f3bd-45c3-4ec8-a9db-845272807ec4
Copilot AI changed the title [WIP] Fix wrong time zone used for updating plan via Add-on web page Fix plan web UI using browser timezone instead of Predbat's configured timezone Mar 22, 2026
Copilot AI requested a review from springfall2008 March 22, 2026 19:19
@springfall2008 springfall2008 marked this pull request as ready for review March 22, 2026 20:11
Copilot AI review requested due to automatic review settings March 22, 2026 20:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a timezone mismatch in the Plan Web UI where clicking a plan slot could send a browser-local time string to the backend, causing overrides to be applied to the wrong Predbat slot when the viewer is in a different timezone. The update makes the client render/derive times using the UTC offset embedded in the plan’s ISO timestamps (i.e., Predbat’s configured timezone), independent of the browser locale.

Changes:

  • Added a client-side helper to extract ±HHMM / ±HH:MM offsets from ISO timestamps.
  • Updated plan time rendering (formatTimeDisplay) to use the embedded offset + UTC accessors.
  • Updated “Updated: …” timestamp formatting and the getMinutesFromTimeString() fallback to be offset-aware.

Comment on lines +6768 to +6771
const match = isoTimestamp.match(/([+-])(\d{2}):?(\d{2})$/);
if (!match) return 0;
const sign = match[1] === '+' ? 1 : -1;
return sign * (parseInt(match[2]) * 60 + parseInt(match[3]));
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

In getTimezoneOffsetMinutes, consider handling falsy / non-string inputs (e.g., null/undefined) before calling .match() to avoid a runtime error if the function is ever called with missing data. Also, pass a radix (10) to parseInt to make the intent explicit and avoid any edge-case parsing differences.

Suggested change
const match = isoTimestamp.match(/([+-])(\d{2}):?(\d{2})$/);
if (!match) return 0;
const sign = match[1] === '+' ? 1 : -1;
return sign * (parseInt(match[2]) * 60 + parseInt(match[3]));
if (!isoTimestamp || typeof isoTimestamp !== 'string') {
return 0;
}
const match = isoTimestamp.match(/([+-])(\d{2}):?(\d{2})$/);
if (!match) return 0;
const sign = match[1] === '+' ? 1 : -1;
const hours = parseInt(match[2], 10);
const minutes = parseInt(match[3], 10);
if (Number.isNaN(hours) || Number.isNaN(minutes)) {
return 0;
}
return sign * (hours * 60 + minutes);

Copilot uses AI. Check for mistakes.
@springfall2008 springfall2008 merged commit e4150ad into main Mar 22, 2026
5 checks passed
@springfall2008 springfall2008 deleted the copilot/fix-time-zone-for-adding-plan branch March 22, 2026 20:17
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.

Wrong Time Zone used for Updating Plan via Add on Web Page

3 participants