Repository navigation
Releases
v0.11.0
☕ Like this project? GitHub Sponsors · Ko-fi · Buy Me a Coffee
Added
- HmIP-BDT-I. The wall dimmer with an extra input on channel 3
(MULTI_MODE_INPUT_TRANSMITTER) has 8 channels instead of the
HmIP-BDT's 7, so its dimmer channels sit one higher (transmitter 4,
virtual receivers 5-7, week profile 8). Data from a device export.
Security
- Built with Go 1.27.3, which fixes GO-2026-6809 (crypto/x509).
go.modtargets Go 1.27.3, so a consumer module has to be on Go
1.27.3 or newer.
v0.10.1
Fixed
- An HmIP ENUM written by its label is stored as that label's slot.
A parameter whose MIN is a string (the HmIP-BSL'sCOLOR:BLACK…
WHITE) is string-based, and clients write the VALUE_LIST entry
itself — aiohomematic's_enum_value_is_indexrule, openccu-loom's
EnumWireValue. The simulator converted every label numerically and
silently stored 0, the first slot, so aCOLOR=GREENwrite became
BLACKand a test reading the CCU side could not tell a landed write
from a dropped one. The label now becomes its index in the stored
paramset (the value the CCU reports back) and a label outside the
VALUE_LIST is refused as an invalid value. Index writes are unchanged.
v0.10.0
Added
- 2-channel HB-LC-Bl1-Velux. The AskSin firmware of this homebrew
Velux actuator builds as a 1- or a 2-channel device under the same
TYPE. The 2-channel variant (twoBLINDchannels) is added as
HB-LC-Bl1-Velux-2ch.jsonnext to the existing 1-channel file; the
device keeps reportingHB-LC-Bl1-Velux. The filename is only the
catalogue key, so passHB-LC-Bl1-Velux-2chto restrict a run to
this variant. Data from a device export
(SukramJ/aiohomematic#3447).
Security
- Built with Go 1.27.2, which fixes Go standard-library vulnerabilities
(net/http and HTTP/2, crypto/tls, net/textproto, html/template).
golangci-lint v2.14.0 (reads Go 1.27.2's export data).
v0.9.0
Changed
-
BREAKING (
pkg/litefake): heating groups answer members the way
an openccu-lite box does.members,former_membersand
devices_to_configureare objects ({id, serial, type}) instead of
bare ids; a create and an update answer the group's detail plus the
members asdevices_to_configure; the detail carries
device_nameas<name> <device>, every offered type as
{id, label}and notype_label; the type labels are the box's
(Heating_Control,HmIP-Heizungssteuerung). The candidates of a
group type are seeded with the newOptions.GroupCandidates; a
member that is no candidate is dropped without an error, as on a
box, and a channel that belongs to a group is listed asleftover.
A test that created a group with an arbitrary member id now has to
seed that id as a candidate. Read and written on a box on
2026-10-03;CONTRACT.mdrecords the observations. -
Requires Go 1.27.1.
go.modtargets Go 1.27.1 and CI and release
builds use it, the same patch release openccu-loom builds with.
v0.8.0
godevccu is now the reference implementation and maintains its own
device data. pydevccu is archived; no behaviour or data is taken from
it any more.
Changed
- BREAKING: Homegear-mode
getVersionreportsgodevccu-<version>
instead ofpydevccu-0.2.0, andhmconst.PydevccuVersionis removed.
Clients that detect the simulator by thepydevccusubstring must
look forgodevccu. - Documentation describes godevccu as the reference implementation;
pydevccu is only named as the origin of existing behaviour.
Removed
make dataandscript/copy_data.sh: the device and paramset
descriptions ininternal/embed/data/are maintained in this
repository. Add a device in the format of Homematic(IP) Local's
export_device_definitionZIP.
v0.7.0
Changed
- Requires Go 1.27.
go.modtargets Go 1.27 and CI builds with it;
a consumer module has to be on Go 1.27 or newer. golangci-lint is now
installed from source in CI, because the prebuilt binary is built with
an older Go and refuses a module that targets a newer one.
Fixed
- litefake: a refused login answers like the box.
POST /api/auth/v1/login
with an unknown user or a wrong password now answers
401 {"error":"invalid-credentials","message":"invalid credentials"}— the
answer observed on a real openccu-lite box (1.0.0-dev.32), identical for both
cases. litefake answered the generic route errorunauthenticated, so a client
could not be tested against telling a refused login apart from a missing
session. The contract records it (CONTRACT §A.2).
v0.6.0
Added
- CLI:
-devicesrestricts the loaded device types outside lite mode
(the library already hadConfig.Devices).
v0.5.0
Scenario API and interface-process behaviours modelled on
hm-simulator by Sebastian
Raff (MIT) — thanks for documenting what rfd and hmipserver actually
answer. Every behaviour below that concerns the CCU comes from that
documentation and was not measured for godevccu; DOCUMENTATION.md
lists the source of each.
Added
- Fault injection:
VirtualCCU.InjectFault(iface, FaultRule)makes
the next calls of a method answer a fault, answer late, never answer,
or close the connection — on XML-RPC, its TLS twin and BIN-RPC alike;
ClearFaultsdrops the rules and releases held calls. - Interface restarts:
DropConnection,StopInterface,
StartInterface(iface, forgetClients)andRestartInterfacestop an
interface process (its port refuses connections) and bring it back on
the same port, forgetting its clients or calling them back
(system.listMethodson BidCos, thenlistDevices). - Introspection:
WriteLog(every clientsetValue/putParamset
over XML-RPC, BIN-RPC and JSON-RPC, with rejected parameters and the
fault) andCallbackLog(every call to a client with sent/answered
time),ConfigPending,PoisonedChannels,Ports. - Control port:
VirtualCCU.ControlHandler()serves the scenario
API asPOST /scenario/<call>; the CLI exposes it with
-control-port.-ports-json <file|->writes the bound ports once
every server listens; port0now lets the system pick;-realism
and-interfaces Name=port,…reach the realism preset and the
separate interface listeners from the command line. - Realism fields:
InitSemantics(init keyed by exact url,
deleteDevicesbeforenewDevices, VERSION diff, HmIP resend),
MasterModel(rfd's and hmipserver's MASTER write models with sticky
and queuedCONFIG_PENDINGand poisoned channels),InterfaceQuirks
(no PONG from hmipserver, derivedgetServiceMessageswith rfd's
"",SENDER_BROKENon rfd's unfilteredgetLinks, rfd's metadata
faults) — all three part ofRealismCCU()— and
ServiceMessagesFault, which stays out of the preset.
Fixed
- Re-registering or removing a client now stops its batched-event
dispatcher; before, a client re-registered under the same interface id
with a new url kept receiving batched events at the old url.
Changed
- Persisted init registrations (
PersistInit) are written as a list of
{interface_id, url}; the earlier map format is still read. - The
Realism.FaultCodesdoc comment listed codes that did not match
internal/ccu/faults.go; it now names −2/−3/−5 as implemented.
v0.4.0
Added
pkg/litefakemodels the box's auth mode off (CONTRACT.md §A.2,
expanded from the openccu-lite security documentation):
Options.AuthOffand the knobFake.SetAuthOffmake
GET /api/auth/v1/stateanswer every caller — any credential or
none — with the fixed anonymous administrator session object
carryingauth_off: true. Its identifier strings come from
Options.AuthOffAccount/Options.AuthOffSID(defaults
DefaultAuthOffAccount,DefaultAuthOffSID): litefake placeholders,
since the contract does not fix the real box's values. Only the state
answer is modelled; route authorization is unchanged, and the
normal-mode answers carry noauth_offmember.
Fixed
pkg/litefakemints session ids in the box's shape — 26 characters
of uppercaseA-Z2-7(CONTRACT.md §A.2, per the openccu-lite
documentation). They were lowercased before, so a downstream
shape check refused every litefake-minted id; caught by
OpenCCU-Loom's box-shell SSO conformance test on its first run.
Changed
- README and DOCUMENTATION list
LITEas the fourth backend mode: the
fake openccu-lite boxpkg/litefakeserves, with its topology, its
API surfaces, the CLI/library entry points and the CONTRACT.md
provenance spelled out.
v0.3.0
Added
pkg/litefake— a fake openccu-lite box. occulited's HTTP API
(token auth with method tiers, the XML-RPC proxy with its verbatim
init refusal, the SSE event stream with resume/filters/resync and
stream limits,/state, metadata, system, pairing, UPnP), composed
on top of per-interface simulator listeners the way occulited sits on
a real box's interface processes. Moved here from OpenCCU-Loom's test
harness (tests/harness/litefake) so any client can use it; written
from the condensed wire contract inpkg/litefake/CONTRACT.md. That
contract is pre-1.0, so the package may change in minor releases.-mode liteon the CLI: serve the fake box standalone on a fixed
address (-lite-listen, default:2121), loading every embedded
device type by default;-lite-devicesrestricts the fleet,
-lite-tokens,-lite-interfacesand-lite-tlssteer auth,
topology and transport.litefake.Options.ListenAddr: bind the box API to a fixed
address; empty keeps the loopback-ephemeral in-process test default.