Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## [Unreleased]

### easee_cloud 1.3.8

Two fixes to the 7 A start from 1.3.7, from its review. A reloaded driver
no longer offers 7 A before its first poll: the car may already charge at
6 A, so the driver now waits until a poll has seen the charger not charging.
A pause or the stand-down that clears a boost now also drops the boost's 7 A
from the current the driver re-writes after a phase change: a pause keeps
the 6 A order and the stand-down 0 A. Before, the next poll could write 7 A
again without the cap or the 90 s window. A pause keeps 6 A rather than
0 A because Core's contactor cycle sends a resume after a pause with no new
order between. Tested in the Lua harness; not yet on hardware.

### easee_cloud 1.3.7

Start a 6 A order at 7 A. On an Easee Home with an Audi e-tron (three
Expand Down
4 changes: 2 additions & 2 deletions SUPPORT_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ Catalog source is not proof that a target can install or run a driver.
| deye | 2.1.1 | blixt-l1 | not_assessed | — | not_recorded | not_assessed |
| easee | 1.0.4 | ftw-core | not_assessed | — | not_recorded | not_assessed |
| easee | 1.0.4 | blixt-l1 | not_assessed | — | not_recorded | not_assessed |
| easee_cloud | 1.3.7 | ftw-core | not_assessed | — | not_recorded | not_assessed |
| easee_cloud | 1.3.7 | blixt-l1 | not_assessed | — | not_recorded | not_assessed |
| easee_cloud | 1.3.8 | ftw-core | not_assessed | — | not_recorded | not_assessed |
| easee_cloud | 1.3.8 | blixt-l1 | not_assessed | — | not_recorded | not_assessed |
| esphome_dsmr | 1.0.7 | ftw-core | not_assessed | — | not_recorded | not_assessed |
| esphome_dsmr | 1.0.7 | blixt-l1 | not_assessed | — | not_recorded | not_assessed |
| etrel | 1.0.3 | ftw-core | not_assessed | — | not_recorded | not_assessed |
Expand Down
2 changes: 1 addition & 1 deletion devices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ manufacturers:
protocols:
- protocol: http
driver: "easee_cloud"
version: "1.3.7"
version: "1.3.8"
ders: [ev]
control: true
firmware_versions: ""
Expand Down
31 changes: 22 additions & 9 deletions drivers/lua/easee_cloud.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ DRIVER = {
id = "easee_cloud",
name = "Easee Cloud",
manufacturer = "Easee",
version = "1.3.7",
version = "1.3.8",
protocols = { "http" },
capabilities = { "ev" },
description = "Easee Home/Charge via Cloud REST API. No local protocol needed.",
Expand Down Expand Up @@ -96,14 +96,14 @@ local EASEE_MAX_A = 32
-- delay and clamps the dynamic current to 7 A before its start command.
-- Here the boost is one amp per phase, held only until the charger reports
-- charging (op_mode 3) or START_BOOST_MAX_MS passes, then 6 A. It is only
-- used when 7 A fits (start_boost_fits), and at most once per start.
-- `start_boost: false` disables it.
-- used when 7 A fits (start_boost_fits), after a poll has seen the charger
-- not charging, and at most once per start. `start_boost: false` disables it.
local START_BOOST_A = EASEE_MIN_A + 1
local START_BOOST_MAX_MS = 90000
local start_boost_enabled = true
local boost_until_ms = nil -- non-nil while 7 A is offered for a 6 A order
local boost_spent = false -- one boost per start; reset by a 0 A order or a stop
local last_op_mode = nil -- op_mode from the latest successful poll
local last_op_mode = nil -- op_mode from the latest successful poll; nil before the first

-- pick_phases is the driver-level phase decision: given the requested
-- charging power, the per-phase fuse ceiling, the operator's mode
Expand Down Expand Up @@ -536,6 +536,16 @@ local function end_start_boost(why)
return true
end

-- clear_start_boost drops the boost without a write and re-arms it. A running
-- boost left 7 A in last_amps_set; it becomes hold_a, what the charger should
-- hold, so a pending phaseMode re-assert cannot write 7 A outside the window
-- and the cap check.
local function clear_start_boost(hold_a)
if boost_until_ms ~= nil then last_amps_set = hold_a end
boost_until_ms = nil
boost_spent = false
end

function driver_init(config)
host.set_make("Easee")

Expand Down Expand Up @@ -860,8 +870,9 @@ function driver_command(action, power_w, cmd)
local ok = post_command("/commands/pause_charging")
if ok then
paused_state = true
boost_until_ms = nil
boost_spent = false
-- Keep the 6 A order, not 0 A: Core's contactor cycle sends
-- ev_resume after ev_pause with no new order in between.
clear_start_boost(EASEE_MIN_A)
end
return ok
elseif action == "ev_resume" then
Expand Down Expand Up @@ -941,7 +952,10 @@ function driver_command(action, power_w, cmd)
else
write_a, boosting = START_BOOST_A, true
end
elseif start_boost_enabled and not boost_spent and last_op_mode ~= 3 and start_boost_fits(cmd, max_a) then
elseif start_boost_enabled and not boost_spent and start_boost_fits(cmd, max_a) and
last_op_mode ~= nil and last_op_mode ~= 3 then
-- An unknown op_mode may be charging: after a driver reload
-- the car can already charge at 6 A before the first poll.
write_a, boosting = START_BOOST_A, true
end
end
Expand Down Expand Up @@ -1009,8 +1023,7 @@ function driver_default_mode()
if post_command("/commands/pause_charging") then
paused_state = true
end
boost_until_ms = nil
boost_spent = false
clear_start_boost(0)
local err = write_setting(charger_serial, {dynamicChargerCurrent = 0})
if err == nil then
last_amps_set = 0
Expand Down
43 changes: 43 additions & 0 deletions drivers/tests/lua_harness/test_easee_cloud_start_boost.lua
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,47 @@ assert(order(4140)); assert(last_amps() == 7)
later(91000)
assert(order(4140)); assert(last_amps() == 6, "order past the window wrote 7 A")

-- 15. No boost before a poll has seen the charger not charging. After a
-- driver reload the car may already charge at 6 A.
boot()
assert(order(4140)); assert(last_amps() == 6, "boost before the first poll")
poll_fails()
assert(order(4140)); assert(last_amps() == 6, "boost after only a failed poll")
poll(3, 4.1)
assert(order(4140)); assert(last_amps() == 6, "reloaded driver boosted a running session")
poll(2)
assert(order(4140)); assert(last_amps() == 7, "no boost once a poll saw the charger stop")
-- A first poll that sees the charger waiting allows the boost.
boot()
assert(order(4140)); assert(last_amps() == 6)
poll(2)
assert(order(4140)); assert(last_amps() == 7, "no boost after a poll saw the charger waiting")

-- 16. A pause clears the boost. The phaseMode re-assert that the first order
-- scheduled then writes the 6 A order, not the boost's 7 A.
boot()
poll(2)
assert(order(4140)); assert(last_amps() == 7)
assert(driver_command("ev_pause", 0, {}))
later(5000)
poll(2)
assert(last_amps() == 6, "re-assert after a pause wrote the cleared boost's 7 A")

-- 17. Default mode clears the boost even when its 0 A write fails; the
-- re-assert then retries 0 A instead of writing 7 A.
boot()
poll(2)
assert(order(4140)); assert(last_amps() == 7)
local http_post = host.http_post
host.http_post = function(url, ...)
if url:find("/settings", 1, true) then return nil, "HTTP 503" end
return http_post(url, ...)
end
driver_default_mode()
host.http_post = http_post
assert(last_amps() == 7)
later(5000)
poll(2)
assert(last_amps() == 0, "re-assert after default mode wrote the cleared boost's 7 A")

print("easee_cloud start boost: ok")
6 changes: 3 additions & 3 deletions index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,15 @@ drivers:
size_bytes: 4054
sha256: "4a2cd1efb4a5583468ce897ebd88a000e348917295c40210e86ecf834c0ba543"
- name: "easee_cloud"
version: "1.3.7"
version: "1.3.8"
tier: core
protocol: http
connectivity: cloud
setup: [vendor_portal]
ders: [ev]
control: true
size_bytes: 46180
sha256: "26e4b146262a1416fc64f81e27cda6b7aebe0a8e1f7fb924912675c00f7f86f7"
size_bytes: 46954
sha256: "652708cfe0d97027b97a3be407df49e20b74f1f30f429df20a24df46e9afc806"
- name: "esphome_dsmr"
version: "1.0.7"
tier: core
Expand Down
6 changes: 3 additions & 3 deletions manifests/easee_cloud.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "easee_cloud"
version: "1.3.7"
version: "1.3.8"
tier: core
author: "Sourceful Labs AB"
protocol: http
Expand All @@ -16,9 +16,9 @@ tested_devices:
notes: "Easee Home/Charge via Cloud REST API. No local protocol needed."
min_driver_version: "1.0.1"
min_host_version: "2.0.0"
size_bytes: 46180
size_bytes: 46954
dkb_id: "easee_cloud"
sha256: "26e4b146262a1416fc64f81e27cda6b7aebe0a8e1f7fb924912675c00f7f86f7"
sha256: "652708cfe0d97027b97a3be407df49e20b74f1f30f429df20a24df46e9afc806"
signature: ""

bytecode_sha256: ""
Expand Down
2 changes: 1 addition & 1 deletion support-status.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@
},
{
"catalog_source": true,
"catalog_version": "1.3.7",
"catalog_version": "1.3.8",
"driver_id": "easee_cloud",
"targets": {
"blixt-l1": {
Expand Down
Loading