Skip to content

Releases: Interstellar0verdrive/MyHOME-stability

0.5.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 17:12

MyHOME Integration Release v0.5.0

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

A basic shutter can now be calibrated from a dialog instead of from a stopwatch, a tape measure and two action calls. Settings → Devices & services → MyHOME → Configure → "Calibrate a cover" drives the shutter, times its runs from the actuator's own status frames, asks for three tape readings and stores the result where the shutter reads it. Nothing changes for a cover that is not calibrated this way, and nothing is ever written to myhome.yaml.

Added

  • Guided calibration of a basic cover, under Configure → "Calibrate a cover". Three ways in: (A) the first shutter of a kind — three button presses and three tape readings, about four minutes, ending on a named profile every similar shutter can inherit; (B) a shutter similar to one already measured — pick the profile, measure the curtain travel, with an optional check at half of it; (C) a shutter that has a profile and stops in the wrong place — its own run times, its own roll coefficients if it needs them, or the thorough calibration on its own: no timed run at all, four tape readings and a check, on the times the shutter already moves on, of which it stores the two roll coefficients and nothing else. A correction measures some of the model and leaves the shutter following its profile for the rest, which is what profile <name>, adjusted says. There is no stopwatch anywhere: the integration knows when the motor started (the actuator says so itself), so a press marks only the end of a run, which halves the human error and leaves the tape as the only tool. The ascent is measured by two runs of one press each: the first ends on the press that marks the bottom edge leaving its base — the dialog stops the shutter there, so the press can be checked by looking at it and, where it went in late, corrected with the tape — and the second runs the whole travel for the press at the top. Path A and a correction can both be followed by the thorough calibration: four more readings at a quarter and three quarters of the travel in each direction, which fit a scale factor on the times as well as the rolls — the tape corrects the finger — and a fifth at 40 %, a position nothing was fitted to, whose gap is what the summary reports as the accuracy. Expect 1–2 cm at the end stops and 2–4 cm at intermediate positions afterwards. The readings taken with a tape are a phase of their own: one screen warns that the shutter is about to move by itself, and from there the runs chain without a button between them, each naming itself on the progress bar. They are taken in the order that spares a run — the timed descent leaves the shutter at the bottom, so the ascent is read first and the shutter is opened completely once instead of twice. Nothing moves before a screen announces it and nothing is written before the last one; every measurement can be repeated on its own, and closing the dialog leaves the configuration untouched. The full page is docs/guided-calibration.md.
  • Screens that manage what was measured, in the same dialog. Profiles and covers: one selector per basic cover to assign a profile (and a follow-up form for the curtain travels nobody knows yet), plus view, hand-edit and delete for each profile — the delete names the shutters that lose it. Calibrations: per shutter, view the stored values, correct them by hand, measure again, or delete them and go back to the configuration file. A profile written in cover_profiles: is shown and never rewritten.
  • Calibration source and Calibrating attributes on basic covers: where the travel model that is loaded came from, and whether a calibration step owns the shutter right now (cover.set_cover_position is refused while it does).
  • Spanish, German and Portuguese translations of the whole integration, beside the existing English, French, Italian and Dutch.
  • Diagrams in the calibration screens — what "the bottom edge leaves the base" and "measure from the base" mean, drawn rather than described. They are served by the integration itself, from custom_components/myhome/images.

Changed

  • Configure opens a menu. The connection settings are behind its last item, "Gateway and connection", with exactly the same fields: address, port, password, configuration file path, command sessions, the event option and the session tunables. The other items are the calibration and what it stored. Saving that form still reloads the integration; the calibration screens rebuild the entry once, when the dialog is closed, and only if something was really stored.
  • Calibration source tells a measurement from an inheritance, and both from the mixture of the two. It says guided for a shutter running on nothing but its own measured (or hand-edited) values, profile <name> for one that follows a profile and was never measured itself, profile <name>, adjusted when some keys were measured on it and the profile still answers for the rest — which is what a correction of the run times alone leaves behind — and yaml when nothing is stored for it and the numbers come from the configuration file or the defaults. The distinction matters because a profile assigned from the dialog ranks above the keys the cover's own configuration-file entry writes — it is a statement about that cover made after the file — while a profile: the file names itself does not, and a measurement of the cover always wins over either.
  • Where a cover's values come from, on the screens and not only in an attribute. The Calibrations list, the action menu and View the values under it, Give each cover a profile, the three screens that close a calibration and a profile's list of followers all say it in words: Measured, Inherited from profile "name", Adjusted from profile "name", From the file, Defaults. They are decided in the same place as the Calibration source token, so a screen and the attribute can never disagree about one shutter; the fifth exists because yaml covers both "the file writes these times" and "nobody ever said", which is one word for two pieces of news.
  • One name per thing, on every screen and in the documentation. The second level is the thorough calibration everywhere (it had been "the precise level", "refine" and "improve the accuracy" in different places), path C is the correction, a movement the user times is a timed run, and the distance the bottom edge runs between the end stops is the curtain travel — never "height", which had survived on thirteen screens that were not the ones measuring it, the path menu's "(height only)" among them. The height: key and the Height attribute keep their spelling, and the height of the bottom edge above its rest keeps its name, because it is a position and not the travel. In French the feature is la calibration throughout: the correction screen used to offer le calibrage approfondi two lines under corriger la calibration.
  • myhome.cover_calibration_run marks the cover Calibrating while it runs, so cover.set_cover_position is refused for the half minute it takes. It is built out of the same primitives as the guided steps, and two things timing one motor would each measure a run the other one stopped. The action already refused to start on a cover that was moving.
  • The wording of the dialog, read through in all seven languages. An outside review of every string produced 414 proposals; those that still describe the screens are in, in the impersonal Italian the rest of the flow uses, with the glossary each language settled on — bottom edge, curtain, slat opening time, takes precedence over, and their equivalents. Buttons keep Home Assistant's own imperative. The counts and the claims were then checked against the code rather than against the review: the correction asks for three tape readings and not two, the thorough calibration for five and not four, Calibration source is named as holding the origin and not the numbers, what is saved is applied when the dialog closes rather than at once, and the accuracy on the thorough summary is the verification's own answer — the gap at the one position nothing was fitted to — with the percentage the screen quotes taken from the run that produced it instead of a constant.
  • The deletion of a profile counts every shutter that follows it. The count and the list on "Eliminare questo profilo?" came from the assignments this dialog makes, so a profile several shutters follow through the profile: key of myhome.yaml announced "0 covers" on the very screen that was about to remove it. Both sources are counted now, and named apart, because the deletion reaches them differently: the assignment is stripped from the stored record, while the profile: line stays in the file and goes back to naming the cover_profiles: entry it had been shadowing.

0.4.5

Choose a tag to compare

@github-actions github-actions released this 12 Sep 08:49

MyHOME Integration Release v0.4.5

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

Fixed

  • A command written into a session the gateway had quietly closed is sent again. A MyHOMEServer1 drops a command session that has had nothing to send for about half a minute, without telling anyone; the next write into that socket succeeds locally while the frame never reaches the bus, and only the acknowledgement that never comes says so. Since 0.4.3 such a frame was neither sent again nor treated as lost — it was reported to the caller as delivered — so a light stayed off while Home Assistant showed it switching, and a shutter that never moved ran a phantom estimate to 35 %. Every transport failure is retried on a fresh session again, whatever the write itself returned, and a command counts as delivered only once the gateway has answered it (a refusal included), timed from the write that was answered. A command no attempt was answered for is dropped, so a cover cancels its estimate instead of timing a run that never started. The retry can put a second copy of a command on the bus, which for these commands changes nothing — on twice is on, up twice is up — and is the cheaper mistake by a wide margin.
  • An idle command session is given back before the gateway takes it. Home Assistant held it for 60 seconds against the gateway's ~30, so in a quiet house the connection was usually already dead when the next command was written into it. It is now closed after 20 seconds of silence and re-opened on demand.

0.4.4

Choose a tag to compare

@github-actions github-actions released this 08 Sep 17:24

MyHOME Integration Release v0.4.4

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

Shutters that start half way no longer stop short. Twelve real shutters on one MyHOMEServer1, replayed at their real bus timings: every run that started or ended at an end stop landed within 1-2 cm, and every run that started from an intermediate position stopped about 0.45 s of motor time short — 3-4 cm too high on a descent, 5-9 cm too low on an ascent of a 195 cm window. Cause: the actuator only starts turning a fixed while after its direction frame, and keeps turning a little after its stop frame, and the timed model had nowhere to put either cost. It now does.

Added

  • stop_latency (default 0.1 s) and start_delay (default 0.5 s), per cover and per cover profile: the two fixed costs of driving a shutter over this bus, in seconds. They resolve like every other timing key — the cover's own value, then the profile's, then the default — and a profile carries them unscaled: a shorter window has less curtain to wind, not a faster gateway. start_delay is only used until (or instead of) the actuator's own "moving" status; a gateway that relays no status frames uses it for every run. Setting both to 0 reproduces the 0.4.3 timing exactly. Both are published as Start delay / Stop latency attributes when they differ from the defaults, and both are named by the existing warning when they are written on an advanced: cover, where they do nothing.

Fixed

  • Shutters that start half way no longer stop short. A movement was timed from the moment its frame reached the bus, but the motor only starts about half a second later — the actuator says so itself, with a "moving" status — and it keeps turning about a tenth of a second past the stop frame. Every run that did not end at an end stop was therefore about 0.45 s of motor short: 3-4 cm too high on a descent, 5-9 cm too low on an ascent of a 195 cm window, with the errors cancelling on the way back. The run is now timed from the actuator's own "moving" status, and the stop frame is written early enough for the motor to coast onto the target.
  • myhome.cover_calibration_run measures the motor, not the frames. It waits for the actuator to say it has started before counting its half run, writes the stop the same tenth of a second early a set position does, and reports motor_seconds between the two status frames when the actuator gives them. On an actuator that takes a second and a half to start, the old measurement was nearly a second long — and that number goes straight into cover_calibration_compute, which inverts the roll against it.
  • A shutter no longer stops the instant it starts when the command queue is very busy. If the end of a run fell due at the same moment the movement's own frame reached the bus — a scene of nine or twelve covers on a slow gateway, a run barely longer than the queue in front of it — the stop could go out a tenth of a second behind the frame that started the motor: the shutter stayed where it was and the entity froze on the position it had been asked for. A run now ends only when its own clock says it does, and a timer that fires while the run is being re-based onto the bus (or onto the actuator's own "moving" status) re-arms itself at the real end instead of stopping anything.

Changed

  • opening_time, closing_time and slat_time are motor times — a stopwatch from the moment the curtain moves to the moment it stops. They always were, but until 0.4.4 the bus latency had nowhere else to go, so a user who padded them with half a second of bus should take it back off.
  • motor_seconds (myhome.cover_calibration_run) is no longer floored at the run that was asked for; it is the measurement, and only a caller whose waits do not move the clock at all still gets the planned figure.

0.4.3

Choose a tag to compare

@github-actions github-actions released this 08 Sep 14:25

MyHOME Integration Release v0.4.3

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

Covers driven together stop where they are told again. A basic actuator timed its run from the moment the command was queued rather than from the moment the gateway actually wrote it on the bus, and a scene moving a dozen shutters at once left the last ones running short. Nothing to configure: no new key, no changed default, no change to the roll model, the profiles or the calibration maths.

Fixed

  • Covers commanded together stopped too high. One command worker writes about ten frames a second, so with twelve covers given set_cover_position at once the k-th direction frame left the socket roughly 0.1 × k seconds after that cover had already started counting, while its stop — scheduled for the end of the run, and finding an empty queue by then — went out immediately. Every motor ran shorter than modelled: measured on a 195 cm shutter, the twelve stopped between 5 and 14 cm too high, the last ones worst, while the same covers driven one at a time landed within a centimetre or two. The run is now timed from the instant the frame is written to the bus, and the timed stop that ends it moves with that instant.
  • The stop that ends a set position or a tilt run is timed the same way. The motor keeps turning while the stop frame waits its turn, so the estimate is frozen where the shutter really got to when the stop left, not on the target it had already passed. That stop is armed from the instant the direction frame reached the bus, and is not queued before it, so a run whose start waited its turn still runs its full length instead of being cut short by its own stop.
  • A movement command that never reaches the bus no longer moves the estimate. When the command path gives up on a direction frame — the queue TTL expired, the gateway never answered — the cover goes back to the position it started from, instead of running a phantom estimate to an end stop nothing is heading for. A stop that is dropped after being queued keeps the behaviour a refused stop already had: the shutter runs on to its end stop, and the estimate runs with it.
  • The window in which a gateway echo is recognised opens when the frame is written, not when it is queued. A command that spent a second in the queue is still recognised by its own repeat, instead of that repeat being read as somebody at the keypad.
  • A cover no longer runs to its end stop when its command waited in the queue. A scene that moves several shutters at once can leave a frame waiting more than a second and a half before the gateway writes it; the gateway's own repeat of that command then arrived after the window in which it is recognised as a repeat, and was read as somebody pressing the keypad — the shutter ran to the end of its travel and the stop that should have ended the run was cancelled with it. The window now covers the wait as well, and a command is timed from the moment its frame reaches the socket rather than from the gateway's acknowledgement.
  • A command the gateway never acknowledged is not written a second time. The frame had already left the socket, so the actuator has it: the retry only ever repeats a frame that never reached the socket at all. Such a command is still reported and counted as dropped, exactly as before.

Changed

  • Stop frames overtake the command queue. A stop (*2*0*<where>##) is handed to a sending worker before any movement or status frame already waiting for another device; ordering among stops, and among everything else, stays FIFO. Behind a frame of its own device it is inserted right after that frame, not appended behind every other cover's too, so a scene moving a dozen other shutters can no longer make the stop wait for all of them; what one device is told still reaches the bus in the order it was told, so a stop can never end a run that has not started. A status request for the same device does not hold the stop back either — only another movement frame does — and "same device" is (WHO, WHERE, bus interface), so a light and a cover sharing a WHERE are told apart. A late stop lengthens a run exactly as a late start shortens it, and twelve stops can collide just as twelve starts can. The queue bound, the TTL, the published queue length and the diagnostics counters are unchanged and still count the total. This ordering is a guarantee of the queue, not of the bus: with command_worker_count set above its default of 1, two adjacent frames for the same device can still be written out of order.
  • myhome.cover_calibration_run reports the interval the motor really ran. It starts timing the half run when the direction frame reaches the bus, and motor_seconds is now the interval between that delivery and the delivery of the stop — never less than the run that was asked for — rather than the number of seconds the run was planned for. On an idle queue the two are the same figure. The action fails with a message naming the entity when either frame never reaches the bus, instead of reporting seconds for a shutter that did not move, or did not stop.

0.4.2

Choose a tag to compare

@github-actions github-actions released this 08 Sep 10:50

MyHOME Integration Release v0.4.2

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

Covers: the position estimate of a basic actuator now follows the shutter's real mechanics instead of a straight line, it can be measured in centimetres with two new actions, and one measured shutter can describe every other shutter of the same kind. Read Changed before upgrading: the estimate of ordinary shutters moves by default, and the tilt controls are now opt-in.

Added

  • A roll model for basic covers (roll, a number between 1.0 and 5.0). A rolling shutter winds onto a tube: the motor turns at a constant speed, the curtain does not, because the roll is fat when the shutter is up and the tube is bare when it is down. roll is the ratio between the two radii, and therefore between the fastest and the slowest curtain speed. 1.0 is the linear model of every release so far; ordinary domestic shutters measure between 1.4 and 2.0. Only the curtain phase goes through it — the slat phase stays linear and the end stops are still reached by running into them — and it applies to basic actuators only, an advanced: one reporting its own position. See Configuration → Why the position is not linear.
  • A roll per direction (opening_roll, closing_roll, on a cover and in a profile; same range, both defaulting to roll). They mirror opening_time and closing_time exactly: write one when the shutter does not behave the same way up and down. Geometry says it should — the roll has the same radius at the same height whichever way the curtain moves — but a real shutter going up is lifting the whole hanging curtain and peeling the slats off the floor, and the measured difference is not small: the shutter these numbers were taken on wants about 1.7 coming down and 2.1 going up. Descents use closing_roll, ascents opening_roll, curtain phase only.
  • Cover profiles (cover_profiles:, at gateway level beside the platform sections). A profile holds a reference_height in centimetres and the model measured at that height (opening_time, closing_time, slat_time, roll, or opening_roll / closing_roll); a cover then names it with profile: and gives its own height:, and the times and the rolls are scaled to it — each directional roll by the same formula, and the curtain times by the growth of the closing roll. Measure one shutter, describe the other twelve by their height. A key written on the cover still wins, key by key, so a single slower motor is one line, not a second profile. See Configuration → Cover profiles.
  • Two calibration actions, both returning response data: myhome.cover_calibration_run drives a targeted basic cover to one end stop and back for the seconds a linear set position 50 % would use, so that you can measure where it stopped; myhome.cover_calibration_compute turns those centimetres, with the cover's height, into the roll of that direction — the descent measurement gives closing_roll, the optional ascent measurement opening_roll — and a ready-to-paste cover_profiles: snippet, which carries a single roll: when the two agree within 0.1 and both directional keys when they do not. The two equations are independent: neither checks the other, and neither solves the slat_time, which is always the configured value or the one passed in the call. A measurement no coefficient in the accepted range can produce is refused, with the band of centimetres that direction can actually reach. The step-by-step procedure, with the accuracy to expect, is Recipes → Calibrating a shutter in centimetres; the fields, the response keys and the refusals are in Services and events.
  • Cover keys height: (centimetres of curtain travel, what scales a profile) and profile: (the name of a cover_profiles: entry; an unknown name is a validation error listing the ones that are defined), and tilt: (see Changed).
  • Basic covers gained the Roll state attribute — replaced by Opening roll and Closing roll when the two directions differ — and Height / Profile when those keys are written.

Changed

  • The estimated position of basic covers of class: shutter — the default class — changes. roll defaults to 1.6 there (and to 1.0 on every other class, which has no roll to model), so a shutter coming down from fully open now reads 44 % when half the curtain run has elapsed instead of 50 %, which is where it actually is. Nothing moves differently by itself, but cover.set_cover_position runs the motor for a different number of seconds, and an automation comparing current_position against a threshold may fire at a different moment. The two end stops are unaffected. Write roll: 1.0 on a cover to keep exactly the 0.4.1 estimate, or measure the real values with the calibration actions above. The same 1.6 is used in both directions until opening_roll or closing_roll says otherwise.
  • The tilt controls are now opt-in: tilt: true. Until 0.4.1, slat_time greater than 0 on a basic cover both split the run in two phases and published the tilt features. It now only does the first: the timing model is unchanged — a run up from fully closed still spends slat_time on the slats, a current_position of 0 still means the curtain rests on the floor, set_cover_position still costs both phases — but current_tilt_position and the four cover.*_tilt services are only offered with tilt: true alongside slat_time. Add tilt: true to every cover you tilt from Home Assistant, otherwise those service calls have no target and a dashboard card loses its tilt buttons. The default changed because a slat_time written only to make the position honest was giving every such shutter a tilt control its user had not asked for.
  • opening_time is the official name of the full upward run; shutter_run is a legacy alias of it. The alias is kept for good and needs no migration: files written for 0.1 through 0.4.1 load unchanged, and closing_time still falls back to the same value. The two may be written together only with the same number — different values are refused with a message naming both keys, since they are one setting. The documentation now uses opening_time throughout.
  • The Shutter run state attribute of basic covers is gone, replaced by Opening time, Closing time and Roll — or Opening roll and Closing roll when the two directions differ — plus Slat time, Height and Profile when in use. Shutter run was Opening time under another name and would have been actively misleading next to a Closing time that no longer derives from it. A template or dashboard reading state_attr(..., 'Shutter run') has to be pointed at Opening time.
  • The validator's advanced: warning covers the new keys: roll, opening_roll, closing_roll, height, profile and tilt do nothing on an actuator that reports its own position, and are named one by one in the log line, as the timing keys already were. The configuration still loads.

Deprecated

  • shutter_run on a cover, and inside a cover_profiles: entry. It keeps working, it is still accepted everywhere opening_time is, and there is no plan to remove it — a fork whose point is that configurations keep loading does not break one to rename a key. New configurations should use opening_time.

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 07 Sep 22:07

MyHOME Integration Release v0.4.1

Installation

HACS (recommended)

  1. Add this repository as a custom repository in HACS
  2. Install the MyHOME integration
  3. Restart Home Assistant

Manual installation

  1. Download myhome.zip from the assets below
  2. Extract it into custom_components/myhome/ in your Home Assistant
    configuration directory (the archive holds the integration's files
    themselves, with no top-level folder)
  3. Restart Home Assistant

Changelog

A stabilisation release: no new feature and no new configuration key. Six rounds of independent code review (each round re-reviewing the fixes of the previous one, with every fix pinned by a test that fails without it) went over the gateway session, the cover model, the platforms, the validator, discovery, the flows and the docs. The suite runs in CI on every push. Read Changed before upgrading: a few configurations that could never work are now refused at load, and one entity-identity effect is listed there.

Fixed

  • Covers, found by the 2026-09-07 code review (all reproduced with tests):
    • an advanced actuator's real position could be overwritten by the time-based estimate after a plain "opening"/"closing" frame; advanced covers now only track the direction from those frames, and they finally report opening / closing from their own status frames (states 11-14);
    • set_cover_position to the value a moving cover was passing through did nothing and the cover ran on; it now stops there;
    • a full open_cover / close_cover did not re-calibrate: the actuator's end-stop frame froze the stale estimate instead of snapping it to 0 / 100. It snaps now, once three quarters of the expected run have elapsed; earlier stops are still honoured as real stops;
    • the last position is restored before the first status request instead of racing it;
    • inverted now also mirrors the level of an advanced actuator, so direction flags and position agree;
    • a slat_time on an advanced cover could make the whole myhome.yaml fail to load. The key does nothing on an advanced actuator (it has no tilt phase), but it was still cross-checked against the run times, and that check ran before the warning that explains the key is inert there;
    • an actuator that reports its own position but was left at the default advanced: false broke its own entity on the first such frame: the timed estimate was stopped, the direction was set again without restarting it, and the cover read Opening at a percentage that never moved for the best part of two minutes, with nothing in the log to explain it — and no later frame could repair it. Position frames are now ignored on a cover declared basic, the estimate keeps running, and the debug log names advanced: true as the missing key.
  • Covers, the frames we cannot tell apart from our own commands:
    • after a timed run short enough to finish before the gateway's late copy of our movement command arrives (a small tilt target on a short slat_time), that copy could start a phantom run to the end stop. Only a frame that can actually be the gateway echoing our own command is ignored now: a stopped frame after a movement we commanded, or a copy of the movement our own stop interrupted. A movement in any other direction is honoured immediately, a press in the same direction is recovered by a status re-read about two seconds later, and a stop Home Assistant could not even send — its command queue was full, or the connection was closing — now changes nothing at all, neither the repeat window nor the estimated position, on both of the two paths that send a stop. Without this a shutter driven from the wall could run fully open while Home Assistant reported it closed, until the next command from Home Assistant;
    • a cover.stop_cover the gateway could not take — its command queue was full, or the connection was closing — used to freeze the position half way and keep reporting it for good, because the actuator's own stop frame at the end of the physical run re-froze the same stale value. The shutter goes on running in that case, so the estimate now goes on running with it. The stop that ends a cover.set_cover_position or a tilt run follows the same rule, and had one failure of its own: it used to leave the position sitting on the target the shutter never reached, while the shutter itself ran on to the end stop. That run is now carried on to the end stop in the model too, so the actuator's own frame at the end of it puts the position back in step instead of confirming a wrong one. That now holds for short runs as well: a run that finished before the gateway repeated the command which started it used to be ended by that repeat, so a small tilt or a nudge of the position slider still froze on a value the shutter had already left behind. Keeping that repeat window has a cost of its own, and it is now paid: a real stop arriving in the same second and a half — a keypad press, an obstacle — cannot be told apart from the repeat either, so it is still ignored, but the actuator is then asked what it is doing and its answer ends the run about two seconds late. Before, such a stop was swallowed with no follow-up at all and the shutter was published as fully open while it stood still half way.
  • Covers, an advanced actuator whose stopped frame is lost: it no longer stays Opening / Closing for ever. After the longest configured travel time plus 30 s the actuator's status is re-read, and the direction is dropped only if nothing answers within the time a single command may really take. That is not the Command timeout option alone: the request may have to re-open a connection to the gateway first — there is one command connection per gateway, shared by everything Home Assistant sends to it, and it is closed after a minute in which nothing at all was sent — and the whole attempt is retried once, so the wait is twice the connection timeout plus twice the command timeout plus a two-second margin — about 42 seconds with the defaults — and it grows with the Command timeout option. An actuator whose real run is longer than that timer is therefore not reported as closed (or open) in the middle of it, waking every automation watching for it. An ordinary scene — a dozen commands acknowledged in well under a second — is comfortably inside that. What is not covered is a queue whose backlog outlasts the wait: queued commands are dropped only after the Command queue TTL option, sixty seconds by default, and holding Opening for a whole minute after a genuinely lost frame would be worse than the problem. The reported position is never estimated.
  • Sensors, binary sensors and climate, found by the same review:
    • a platform section written as a YAML list or a scalar (light: [...]) is reported as a normal validation error with its key path instead of crashing the setup with a traceback;
    • icon was documented as a common key but ignored by sensors, binary sensors, climate zones and the scenario-control event entity, and icon_on by binary sensors; they now work, icon_on given without icon included (the entity's default icon is used while off, the Lock/Unlock buttons keep their fixed icons, and the validator knows icon_on on a binary sensor, so it no longer reports it as an unknown key). On a power or energy meter icon applies to every entity of the meter, not only to the main one;
    • entity_name on a class: power meter now renames the Power entity;
    • in a plant with a central unit, every nameless zone was called "Central unit"; only the bare #0 is, #0#5 is "Zone 5" again;
    • a thermo zone written with a leading zero (zone: '01', or where: '01') is normalised to the form the bus uses, so its frames reach the entity. It used to be keyed 4-01 while every frame for that zone arrives as 4-1: the climate entity was created, was available and stayed unknown for ever, with nothing in the log but a debug line. The same mismatch hid a duplicate zone from the duplicate check and stopped a zone from sharing its device with the WHO 4 temperature probe on the same zone. A WHO 4 temperature sensor written the same way (where: '01') had the identical defect and is normalised with it: it is keyed 4-1 like its frames, is detected as a duplicate of the unpadded spelling and shares the zone's device like an unpadded probe;
    • a sensor of class temperature whose address resolves to zone 0 — where: '0', '00', '100', '200'…'900', '1000' — is now refused with the key path of the device instead of loading. The bus reports every one of those frames under the central unit's key (4-#0), so the entity was created, was named, was available and stayed unknown for ever while its readings were delivered to the central unit's climate entity — the same silent dead entity the zero-padding fix above removes. The central unit is a climate: device (zone: "#0") and never a probe, so there is nothing to normalise these to;
    • a climate zone paired with a temperature sensor on the same zone lost the zone's name to the probe: the shared device keeps the climate name and the probe name becomes the sensor's entity_name;
    • hvac_action on a heat: true, cool: true zone could freeze as soon as the central unit reported actuator status (dimension 20) instead of valve status (dimension 19): at unknown when such a frame arrived first, and at idle from the first actuator off/on pair onwards — the ordinary duty cycle of a thermostat. Only a frame that actually carries a direction, or one on a heat-only / cool-only zone, or one reporting "not active", now settles the attribute; otherwise it is still derived from the temperature. On a plant that reports the valve status too, an actuator frame that only says "on" no longer overrules the direction the valve frame had just reported, which used to publish idle while the valve was open — precisely when the valv...
Read more

v0.4.0 – two-phase covers, CEN/CEN+ devices, wall pushbutton events

Choose a tag to compare

@Interstellar0verdrive Interstellar0verdrive released this 06 Sep 23:10

Three additions: a two-phase travel model for covers, CEN/CEN+ scenario controls as Home Assistant devices with UI-selectable triggers, and a bus event for wall pushbuttons in dimmer mode. Nothing is renamed and no entity_id or unique_id changes; the event-contract changes are additive (a new mac key on the CEN/CEN+ bus events, one new event). A myhome.yaml written for 0.3.x keeps behaving exactly as it did: the cover model and the scenario controls are opt-in through new keys.

Fixed

  • Timed cover targets (set_cover_position, tilt) were cancelled by the gateway: MyHOMEServer1 answers a movement command with a "stopped" frame immediately followed by the "opening"/"closing" one, and that stop was taken as the end of the run, so the shutter ran to the end stop. The stop echo arriving within 1.5 s of our own command is now ignored; real stops (keypad) are still honoured. Found live on the first calibrated shutter.
  • myhome.send_message crashed with an internal error on frames that OWNd's typed parser does not model, such as a CEN+ virtual press (*25*21#1*#2##, WHERE starting with #). Well-formed frames are now sent as generic commands; malformed ones raise a proper validation error. Found while testing the scenario controls.

Added

  • Wall pushbutton events. The gateway echoes what a physical light pushbutton sent (*1*1000#WHAT*WHERE##) right before the actuator answers; those frames were dropped. They are now republished as myhome_light_pushbutton_event (mac, where, what, event, message). The point is dimmer-mode pushbuttons wired to relays: a hold sends dim_up/dim_down about twice a second and nothing else on the bus reflects it, so this is the only way to turn such a button into a dimming remote for, say, a Zigbee bulb. Short presses give on/off next to the status the entity already follows. Found on a bedside pushbutton.

  • CEN / CEN+ scenario controls as devices, with device triggers and an event entity. A wall keypad has no state, so until now its presses existed only as myhome_cenplus_event / myhome_cen_event bus events, usable from YAML and invisible everywhere else. Declaring the control under the new scenario_control: block in myhome.yaml now creates a device on the gateway carrying one event entity (event.<name>_scenario_control, state = timestamp of the last press, attributes event_type, pushbutton, protocol, object/where) and a set of device triggers, so "Button 2 held down on Living Room Keypad" can be picked in the automation editor instead of hand-written event triggers. Both CEN+ (object, buttons 1-32, including the long-press repeat and the four rotary events) and CEN (where, buttons 0-31) are supported; buttons decides which combinations the picker offers, never what reaches the bus. Controls that are not declared keep firing the bus events and create nothing, exactly as in 0.3.x.

    The device-trigger module is ported from fedem95/MyHOME by fedem95 (AGPL-3.0): the base-schema extension, the type/subtype split and the delegation to Home Assistant's own event trigger are theirs; the concept was also explored by mantovanellimatteo/MyHOME. The event-entity model is ported from adrael/MyHOME by raphael (AGPL-3.0), whose event.py implements the same shape for a doorbell.

    See Configuration → Scenario control and Recipes → Device triggers and blueprints.

  • mac in the myhome_cenplus_event / myhome_cen_event payloads. Additive: the existing object, pushbutton and event keys are untouched, so automations written before 0.4.0 keep matching. It carries the normalised MAC of the gateway that saw the frame, so a multi-gateway plant can tell two controls with the same object number apart — which is what the device triggers filter on. Suggested by fedem95, whose fork adds the same key.

  • Two automation blueprints, in blueprints/automation/myhome/: cenplus_button_light.yaml (short press toggles a light, long press turns it off) and cenplus_button_cover.yaml (hold up/down to open/close a cover, short press to stop). HACS does not install blueprints, so they are imported by URL — see Recipes → Importing the blueprints.

  • Two-phase travel model for basic covers (slat_time). On most roller shutters the motor run is not all lift: from fully closed the first seconds only tilt the slats ("lamelle") open while the curtain stays on the floor, and when closing the motor keeps running for the same few seconds after the curtain has touched the floor, to close them again. The linear 0-100 estimate therefore reported "5 %" with the curtain still on the floor, and set position 50 % from closed ended around 55-60 %. Declaring slat_time (seconds, default 0 = previous behaviour) splits every run into a slat phase and a curtain phase:

    • current_position now describes the curtain only — 0 = curtain on the floor whatever the slats do, 100 = fully open;
    • current_tilt_position describes the slats — 0 = closed, 100 = open — and the cover is closed only when both are 0;
    • the tilt services (cover.open_cover_tilt, cover.close_cover_tilt, cover.set_cover_tilt_position, cover.stop_cover_tilt) appear on covers with a slat_time, which makes "closed with the slats open" a single service call; above the floor the slats are always open, so tilt commands are ignored there;
    • cover.set_cover_position computes the run through both phases (from closed, 5 % costs slat_time + 0.05 × (opening_time - slat_time) seconds), and movements started from a physical keypad are tracked through the same model.

    See Configuration → The two-phase travel model and Recipes → Covers.

  • Separate opening_time and closing_time for basic covers. Both default to shutter_run, which stays the one value most installations need; set them when the motor is measurably slower in one direction. The idea of separate up/down travel times comes from andrea-parisi/MyHOME.

  • Basic covers expose Slat time, Opening time and Closing time as extra state attributes when those keys are in use, next to the existing Shutter run.

Changed

  • cover.set_cover_position with a target of 0 or 100 now runs the cover into its end stop instead of stopping it with a timer at the computed moment. The end stop is what re-calibrates a time-based estimate, and the stop command was redundant there.
  • The estimated tilt is persisted next to the position, so "closed with the slats open" survives a restart or a reload.

v0.3.1 – bus interfaces, central heating unit, OWNd 0.7.49

Choose a tag to compare

@Interstellar0verdrive Interstellar0verdrive released this 05 Sep 11:27

Hotfix release. Four bugs, no new features, no configuration change required. No entity_id, unique_id or event contract is touched — entities behind an F422 bus interface keep the exact ids they had in 0.3.0.

Fixed

  • Devices behind an F422 local bus interface never received state updates. The OWNd version we shipped (0.7.48) compared an integer WHO against a list of strings in OWNMessage.interface, so the property always returned None and the #4#<interface> part never reached the entity address: a frame such as *1*1*11#4#3## was reported as plain 1-11 and applied to the main-bus device with the same WHERE, if one existed. The dependency is now pinned to OWNd==0.7.49, which fixes this upstream (it also stops a TypeError on thermostat local-offset values 6/7/8 and makes session shutdown robust against a connection that was never opened). Upstream OWNd fix; independently found by GreenGrassBlueOcean and pinned by Dav41K9 and rdr-66.
  • Bus interface numbers were zero padded on the wire. Every command the integration sent carried 11#4#03 while the bus writes 11#4#3, so the address in our commands did not match the address in the gateway's replies — a mismatch that became visible the moment the OWNd fix above started reporting interfaces at all. interface is now accepted as an integer or as a 1- or 2-digit string (3, "3", "03") and always normalised to the unpadded bus form. Entity ids are preserved: the internal device key, and with it every unique_id, keeps the padded spelling (1-11#4#03), and incoming frames are matched against both spellings. See Configuration → Local bus interfaces. Problem identified by carferrer.
  • The central heating unit de-synchronised zone 1. OWNd rewrites a heating zone 0 frame to the zone in the first WHERE parameter, so *#4*0#1*20*1## — the central unit's actuator — was reported as entity 4-1 and drove zone 1's climate entity with the central unit's state. Such frames are now routed to the central-unit entity (4-#0). Fix contributed by Jacopo Jannone, via michnovka's fork.
  • myhome.sync_time blocked the event loop. Building the command calls pytz.timezone(), which reads the timezone database from disk; it now runs in an executor, so Home Assistant no longer logs a blocking-call warning when the service is called. Found by sxpert.

v0.3.0 – diagnostics, repairs and tunable sessions

Choose a tag to compare

@Interstellar0verdrive Interstellar0verdrive released this 05 Sep 11:11

Robustness and observability. Everything in this release is additive: with the default options nothing changes in how the integration talks to your gateway, and no entity_id, unique_id or event contract is touched.

Added

  • Diagnostics download. Settings → Devices & services → MyHOME → ⋮ → Download diagnostics (also available per device) produces a JSON file for bug reports: the config entry with the password removed and the MAC/host/UDN partially masked, the tunables in effect, a summary of the validated myhome.yaml (per platform: device count and who-where keys, never your device names), the gateway statistics and the last 50 bus frames. Session-negotiation frames are replaced by a marker so a password hash can never end up in a public issue. See Troubleshooting.
  • Gateway diagnostic entities on the gateway device: a connectivity binary sensor and a "last frame" timestamp sensor (both enabled by default), plus reconnect, dropped-command and queue-length counters (disabled by default — enable them from the entity settings when you are chasing a problem).
  • Repairs. The integration now raises a Home Assistant repair issue, in all four languages, when myhome.yaml cannot be loaded (with the file path and the exact validation message), when it contains keys the integration does not know (listed, with a "did you mean" hint, dismissable), and when the gateway's MAC address has no section in the file. Each issue disappears on its own as soon as a later load no longer hits it.
  • Tunable session options in Configure, pre-filled with the values 0.2.x used internally, so leaving them alone changes nothing: idle watchdog (300 s), probe window (30 s), command timeout (10 s), command queue TTL (60 s) and the default instant-power keep-alive (125 min, used when a sensor does not set keepalive_minutes in myhome.yaml). See Configuration → Options.

Changed

  • Identical status requests that are already waiting in the command queue are coalesced instead of being sent twice, so a reconnect no longer floods the gateway with duplicate *#…## frames.
  • Motion binary sensors keep their state across a reload or restart (the off-delay is restored with them), like covers already did in 0.2.1.
  • Temperature and illuminance sensors ask for a fresh value when the gateway reconnects, instead of waiting for the next spontaneous frame.

v0.2.1 – keep the cover position across reloads

Choose a tag to compare

@Interstellar0verdrive Interstellar0verdrive released this 05 Sep 11:11

Fixed

  • Time-based cover position was lost on every config-entry reload (and on a restart while the gateway was down): the entity is already unavailable when Home Assistant snapshots it for restoration, so the position is now persisted through extra_restore_state_data instead of the state attributes.