NightFront NINA Plugin 3.19.1.0 - release notes Aligns with NightFront app v3.19.1. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did. Configs - The Targets page's Save, Move, Enable/Disable, Create and Update keep settings a newer NightFront wrote into the config, instead of dropping them. - A config that uses features from a newer NightFront is never changed: each of those edits is refused with the reason (update NightFront), and planning still runs. ==================== Earlier releases ==================== NightFront NINA Plugin 3.19.0.0 Installs alongside NightFront app v3.19.0. Frame - After a whole-mosaic Frame, NINA's Panel overlap box shows the overlap Frame set, in its unit; it used to keep its previous value while the panels were drawn at the new one. - Pressing + or − on that box after a Frame now steps from the overlap Frame set, not from the old one. - Frame pushes a center rounded to remove floating-point noise (at most 0.000005″), so a center a hair under a whole degree or hour is pushed as that whole value. - NINA's own Framing tab may still show a center on a whole degree as 29 d 60 m 0.0 s, even for coordinates typed into NINA; that is NINA's display, not the push. Updated with NightFront app 3.19.0 (the nightfront-cli.exe installed with this plugin) - Update (re-pointing an existing target) also restarts the small-turn allowance: accepted counts are kept only while a target stays within 5″, and turned less than 0.1° in all, of where it was when its counts were last reset. - An older mosaic on a very wide field (more than about 23°) at an odd multiple of 45° can no longer be framed whole; frame its panels one at a time. NightFront NINA Plugin 3.18.0.0 Installs alongside NightFront app v3.18.0. Example sequence and templates - New NightFront NINA Templates folder on your Desktop: an annotated example night and five templates (Start of Night, Imaging, Safety Recovery, Sky Flats, End of Night). - Built only from NINA's own items and NightFront's; notes say what each part does and what not to move. - Placeholders mark where your own startup, weather-stop, recovery and shutdown steps go. - A weather stop parks the mount before it waits for safe weather, and unparks it once the sky is safe, so imaging resumes. - Each night's first focus step unparks the mount, which the previous night's End of Night parked. - Dawn sky flats stop 30 minutes after sunrise, so a flat that fails in daylight is not retried all day. - Each night ends 5 minutes after sunrise, so the next night's startup waits for sunset. - The folder is replaced on every upgrade and removed on uninstall: copy a file before you edit it. - New guide page, *Example sequence and templates*; the guide's recommended sequence now matches the example night. NightFront Sky Flats and Trained Flats - A sequence saved in NINA no longer reopens with their steps doubled (each save added two more). NightFront NINA Plugin 3.17.0.0 Installs alongside NightFront app v3.17.0. Setup: config and data folder kept together - The NightFront Data Folder can now be left clear: it then uses the NightFront config's own folder. A new Clear button beside it does that; a data folder you already set is kept as it is. - Choosing a NightFront config in another folder asks whether to make that folder the data folder too; choosing a data folder that holds one NightFront config offers to plan from it, and closing that question without answering counts as No when a config is already set; a folder holding several names them all. - Only a real NightFront config is offered: a sync client's conflict copy of a seasonal plan no longer is. - Any change that would leave calibration.metadata.json (the collected-frames ledger and queued flats) behind asks first; closing the question without answering keeps it. - An amber line on the Setup page and a note on Nightly Update say when the config and a set data folder are in different folders, or when the config setting names a file that no longer exists; the night still plans. - A mapped drive and its network path, or a junction and its target, count as the same folder. Fill the rest of the night when the plan finishes early - When the NightFront Container's plan runs out with usable darkness left (at least 30 minutes, or the longest minimum imaging time among your enabled Active targets plus one slew, whichever is more), it replans the rest of the night and keeps imaging, with no extra template step. - If every enabled Active target is already complete, the best-placed one gets extra subs; Requested is exceeded on purpose and your config is not changed. - A line under the container's target count says what happened, for example *Plan finished at 03:12 with 2 h 10 m of darkness left — replanning to fill it*, or why it did not refill. - At most 3 refills a night; a refill that fails ends the container normally with one notification, and it never refills when your sequence stopped the plan or the safety monitor reports unsafe. - A hand-built or generated night is refilled only when a Replan instruction in the sequence has Replan hand-built plans ticked. - On by default; turn it off with Fill the rest of the night when the plan finishes early on the Options tab's Setup page. Needs the NightFront CLI from this release. Filter offsets: measured and written for you - The new NightFront Filter Offsets instruction autofocuses reference filter, filter, reference filter (a bracket, so focuser drift cancels out) over the filters your targets use, least-measured first, within a budget that defaults to the evening twilight (Sun −12° to −18°). - When a filter has at least three agreeing brackets, its offset is written into NINA's filter offset table automatically, only while the wheel is on the reference filter or right after an autofocus; nothing waits for a click and the night never stops. - Every limit scales with NINA's Autofocus step size (Options → Autofocus): a bracket's two reference runs must agree within half a step, the scatter and an unconfirmed change stay within a quarter step, and an offset larger than one step is flagged; the focuser's Max increment (Equipment → Focuser) is a hard ceiling. - If the autofocus step size is not set, nothing is written and the Filter offsets page says why. - A filter whose measurements disagree or look implausible is flagged instead of changed, and every write is a line in a history with a Restore button and one NINA notification. - NightFront writes only the focus offset: it never turns *Use filter offsets* on, never flags an autofocus filter and never edits your template. - The instruction will not start in daylight (Sun above −6°), and a filter change that does not reach the filter asked for ends that step without an autofocus. - A new Filter offsets page on the Options tab holds Manage filter offsets (off by default), the reference filter, a per-filter table (with Last bracket, when the filter was last measured between two reference runs), the limits in force and the history. - Its setup note says to keep *Autofocus after filter change* until every filter has an offset, then turn *Use filter offsets* on and remove that trigger together, with no filter flagged as the autofocus filter. It does not ask for *Disable guiding on filter change*: guiding can keep running through an offset move. - Measurements are saved beside your NightFront config in .filter-offsets.json, which the desktop app's Analysis page reads; each autofocus run also records Hocus Focus's star counts, fit errors, final HFR and duration, and its fitted focus curve (from Hocus Focus or NINA's own autofocus). - The plugin guide has a new *Filter offsets* page. - That page now also covers adopting NightFront's offsets when NINA's offsets are already filled and in use. Filter offsets: outlier rejection - With 4 or more brackets for a filter, a bracket far from the others is set aside before the offset is worked out, so one bad autofocus no longer widens the scatter or holds the filter back. - Nothing is deleted: the Filter offsets page lists each set-aside bracket under its filter, with its value and its distance from the median. Filter offsets: parfocal groups - Each row of the Filter offsets page has a Parfocal group choice (none, 1, 2 or 3) for filters you believe focus together. - A group is confirmed only once its measurements show every member within half of the filters' focus tolerance of the others (a quarter of an autofocus step until they have enough well-fitted autofocus runs); until then each filter keeps its own offset, and the page names the pair that does not yet agree. - A confirmed group gets one shared offset, or 0 when it includes the reference filter, and is recorded as committed even when NINA's table already holds that value. - A group confirmed on fewer than 3 brackets in all says it is waiting for more. - The NightFront Filter Offsets instruction measures one member of a confirmed group per run instead of all of them. - With no group chosen, nothing changes. Filter offsets: focus tolerance - Each filter's focus tolerance, how far from best focus its stars grow 5 %, is read from its own recent autofocus curves. - A parfocal group is confirmed within half of that tolerance, instead of a quarter of the autofocus step size. - An offset provably within half of it of the reference is written as 0, so NINA does not move the focuser for it. - A committed offset is rewritten only when a new estimate differs from it by more than half of it. - An offset already committed more than half the tolerance from the reference is kept, not pulled back to 0, by an estimate within half the tolerance of it. - Until a filter has 5 well-fitted autofocus runs, its rules are unchanged; the Filter offsets page names the tolerance when it decided what was written. NightFront Save Night's Log - A new instruction: put it last in your End area, after sky flats, and it saves this observing night's part of NINA's log into a nina-logs folder beside the NightFront config, where the desktop app's Analysis page reads it, so the desktop app can analyze the whole night while NINA stays open. - Run after noon but before that evening's dusk, it still saves the night that just ended, and its status line names the night it saved. - It waits up to 10 seconds for NINA's log to catch up (it needs NINA's log level at Info or more detailed); if the log does not catch up in time, the copy is still saved and the status line says the last lines may be missing. - NINA's own log folder is only read, and the instruction never fails the sequence. Replan - When a Seeing or Wind Speed trigger's Replan keeps the running target first, at the same position and rotation, imaging continues without slewing, plate-solving and rotating again. - A target that had not finished centering, or a night resuming after a safety interrupt, is centered as before. - Plans from Nightly Update and Replan dither less when filters dither at different rates: with L every 2 frames and R, G, B every frame, each round is L, L, R, G, B and then one dither (needs the NightFront CLI from this release). - When a plan returns to the target it is already on, the sequence keeps imaging it in the same target block, with one dither where the two parts meet, instead of centering again. Flats - A briefly locked calibration.metadata.json is retried for up to a minute instead of failing the flats run at once. - If it stays locked, the flats instruction fails once, NightFront While Flats Remain and While Same Rotation stop for the rest of that night's run, and a set already shot stays done and is recorded once the file can be written; NINA's log gives the reason Windows refused the write. - A flats set you skip while it is running is no longer recorded as complete. - A flats set that a closed or crashed NINA left "Claimed" is taken back and shot again from the next observing night (after local noon); NINA's log says when this happens. Targets page - Planned rows are no longer dimmed or captioned "disabled"; a Planned row's only action is → Active, which re-enables the target. Release notes - NightFront-Plugin-Release-Notes.txt in the install folder now lists every release, newest first; the installer's license page still shows only what this version changes. NightFront NINA Plugin 3.15.0.0 Installs alongside NightFront app v3.15.0. No C# changed, but the nightfront-cli.exe bundled with this plugin was rebuilt on a newer toolchain. Replan plans exactly as before — the same inputs give the same plan — but its search runs faster, and it no longer writes thousands of debug lines per solve, so there is far less output for NINA to read back during a Replan. NightFront NINA Plugin 3.14.0.0 Installs alongside NightFront app v3.14.0. The nightfront-cli.exe bundled with this plugin plans exactly as before — the app's new remote processing is desktop-only — and this release carries one plugin fix. A Replan in After Target no longer re-solves the night seconds after another Replan. When a Seeing or Wind Speed trigger's Replan ended the running target, that target's After Target fired straight away, and a Replan dropped there solved the night a second time from the same progress — which could change the plan again, for example dropping a mosaic panel the first solve had kept. That Replan now leaves the new plan in place and says so. After Target for a target that ends on its own still replans as before. NightFront NINA Plugin 3.13.1.0 Installs alongside NightFront app v3.13.0, which is unchanged. This release carries two plugin fixes. Frames you have reviewed no longer count as Collected on the Targets page before the next plan. After a review, the page used to count the reviewed batch twice — once as Accepted and again as Collected — until the next Nightly Update or Replan, so Remaining read too low (for example 1 sub where 31 were still needed). It now shows what the next plan will use. The same fix means While Work Remains no longer risks ending the night early because of those frames, and Check tonight judges feasibility against the same numbers. Looking at the page still never changes your collected-frames record. A Replan run from a Seeing or Wind Speed trigger no longer leaves the running target cut off from your meridian flip, autofocus and other triggers until it ends. The target used to keep imaging for the rest of its window with none of them running, so a flip could be missed. It now ends at its next step and the new plan takes over straight away, still under all of your triggers and your safety condition. NightFront NINA Plugin 3.13.0.0 Aligns with NightFront app v3.13.0; install the two together. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did: when the plugin edits your config (Requested counts, Move, Enable/Disable, adding targets from the Framing Assistant), it now keeps each filter's AstroBin filter id, which the older CLI would have dropped. NightFront NINA Plugin 3.12.0.0 Aligns with NightFront app v3.12.0; install the two together. The Targets page now has a Planned column beside Active, and you can move a target between them. A mosaic moves as a whole, and a split mosaic (one you moved before) shows once, captioned with how it's split. A Planned row is read-only here — move it to Active first, then edit its Requested counts. You can now enable or disable an Active target, or a whole mosaic at once, from the Targets page. A disabled target stays visible with its disabled caption so you can find it again to re-enable it. Per-panel disable is still a desktop-app-only control. Both take effect at the next plan, not the sequence already running — a target moved or disabled at dusk stays in tonight's already-imported plan. While Work Remains sees the change immediately, though, so disabling the last Active target with work left can end an unattended night at its next check. New: a Frame button sends a target — a single pointing, one mosaic panel, or a whole mosaic — straight to NINA's Framing Assistant, so you can see exactly what it will look like before shooting it. Whole-mosaic Frame reproduces the stored grid's center, rows and columns, rotation and overlap; it refuses rather than draw an approximate grid, and says why (the grid doesn't fit your rig's field of view, the panels don't agree on rotation — check Preserve Alignment — or your rig's description in NINA doesn't match this config's). Framing may switch NINA's Framing tab onto an online sky survey if it was set to a cached or offline one; nothing else about the target changes. ⚠️ A mosaic laid out by an older NightFront, or brought in by an AstroPM import, is refused for whole-mosaic Frame unless its rotation is a multiple of 90°. Those mosaics were laid out as the mirror image of the grid NINA draws at the same rotation, so NINA's panels would land away from yours. The desktop app can correct such a mosaic; until then, Frame its panels one at a time. When Frame could only tell it was mirrored from NINA's camera, because the NightFront config states no sensor size, the message asks you to enter the sensor size on the desktop app's Imaging System page first, since the app cannot offer the correction until then. Two more refusals say exactly what to do. A mosaic at 45°, 135°, 225° or 315° can be laid out either way round with the same panels, and only the camera's shape tells which (for a single row or column, the camera's field of view). Frame sends NINA's camera size and pixel scale to NightFront to decide it; the NightFront config's own optics win when it states them. If neither knows them, Frame asks you to enter them on the desktop app's Imaging System page rather than guessing. And an older mosaic within 0.1° of a right angle, which the desktop app deliberately does not flag, is never sent there for a correction: if it is too wide for NINA to draw whole, the message says so and points you to framing its panels one at a time. Frame also never pushes a grid whose panels could land just past the 5″ check: it refuses beforehand and says why. A mosaic with a single panel frames as one pointing at any rotation, and a mosaic laid out in NINA with its overlap in pixels rather than percent is recognized as NINA's and frames whole. Mosaics created in NINA, and ones the new desktop app lays out, frame whole — including wide grids, because the desktop app now places panels the same way NINA itself does. A very wide grid can still occasionally be refused, because NINA works out a camera's field of view slightly differently from NightFront and fits one overlap to both. ⚠️ After a Frame whose sky image failed to load, "Or update an existing target" is refused for that target until you frame it again successfully. NINA reports success even when the image never arrived, and this plugin could not otherwise tell the framing it is about to re-point apart from a stale one left over from before — Update is the one thing on this page that discards accepted frames, so it stays off rather than trust an unconfirmed picture. ⚠️ Update is also refused after NINA changes a framed target on its own — its Load Image button (or an automatic refresh) puts back the rotation you last used in NINA instead of the target's, or a camera change re-spaces a mosaic's panels. Press Frame again, not Load Image, to get the target's framing back. Turning the frame yourself is still fine. And after you frame one mosaic panel, no target is pre-selected for Update any more (before, a different target nearby could be); a mosaic is re-pointed only as a whole. After you Frame a whole mosaic, Preview pre-selects that mosaic even when its name is also some other mosaic's panel name, and a name that fits more than one target or mosaic pre-selects nothing and says which ones it could be. ⚠️ The Targets page now writes only to the config it is showing. If you change the config or data folder on the Setup tab (or press Clear) after loading the page, Move, Enable/Disable, Save, Create and Update refuse until you Reload or Preview again. None of them write to the session-config.json export snapshot any more — the desktop app never opens it, so a change there looked saved and was silently undone by the next export. New: a Name box beside Create. Create used to take its name from NINA's Framing Assistant at the moment you pressed it, and after a Frame that is still the framed target's name — so a new mosaic could come out named after an existing panel ("SNR G070 Panel 2 Panel 1"). Preview now fills the box from the Framing Assistant, you can change it, and Create writes exactly what's there. Create is unavailable while the box is blank or names a target or mosaic already in your config. Fixed: a mosaic whose panels carry an id but no mosaic name now shows as one mosaic, not as separate targets each with its own Move and Disable. Fixed: a mosaic's Preview line always read "0% overlap" regardless of what was actually framed. It now shows the real figure. Both need this plugin's own paired nightfront-cli.exe. An older CLI beside a newer plugin reports the usual version-mismatch message for Move and Enable/Disable; Frame needs no CLI at all for a single target, so it keeps working even then. NightFront NINA Plugin 3.11.0.0 Replan now plans differently, because the planner bundled with this plugin changed. No C# in this area changed, but nightfront-cli.exe — which every Replan shells out to — did, in two ways you will see in the plans it produces. A slew is now charged for how far the mount actually moves rather than at a flat worst-case rate, so a replanned night fits more imaging into the same darkness (measured: 90.3% → 93.7% of darkness on sensor, about 23 extra minutes a night). And a mosaic's panels can now be balanced against each other, with the hand-off margin defaulting to 1 hour — if you already had balancing switched on, that default is a change. See the NightFront 3.11.0 app notes for both. A target a Replan interrupted now gets its "After Target" notification. A mid-night Replan replaces the whole plan, so the target that was running vanished from the sequence without NINA ever reaching the end of it — and your end-of-target message for that target was simply never sent. The one target the night went wrong on was the one you heard nothing about. It is now reported as soon as the new plan lands, once. A result file NightFront cannot read now says so in NINA's log. The night is already left alone rather than wiped (see below in these same notes) — but silently, which reads exactly like a night on which no plan was needed. The same goes for a result path that cannot be derived or probed. A planner process that cannot be stopped is no longer stopped silently. When a sequence is stopped or a plan times out, NightFront kills the planner; a kill that failed, or a planner that outlived it, left nightfront-cli.exe running with nothing saying so — and it would go on to write its output into your data folder afterwards. NightFront now waits a moment for it to go and reports it if it doesn't. A weather trigger can now be told to wait for a crossing to hold. A new *Must hold for* box beside the threshold on the Wind Speed trigger: a reading has to stay on the new side of the threshold for that many minutes before the instructions run. NINA checks triggers between sequence items, so a wind sitting on 20 km/h can cross back and forth several times an hour, and each crossing fired a container whose intended contents are a Replan — a fresh solve and a rebuilt plan, over and over. A brief gust and back now fires nothing in either direction, rather than acting on the gust and then again on the recovery. It defaults to 0, which is off and behaves exactly as before, so nothing changes unless you set it. A Replan with no planner installed no longer fails the sequence. It threw, which marks the instruction failed and fires whatever failure notification you have wired up — at two in the morning, for a condition that cannot be fixed until dawn and that leaves tonight's already-imported plan perfectly good. It now reports the missing CLI and returns, leaving the plan running. A Replan that could not produce a plan now says so in nightfront-status.json. Only the success and decline paths wrote to it, so a replan that emptied the container or failed outright left the file describing the *previous* replan — anything reading that file was told the night was fine. A target with no Center and Rotate is no longer skipped in silence. It cannot have its rotator position measured, so no calibration requirement is recorded for it and its flats are never shot — which surfaces days later with nothing in the night's log to explain it. That skip now writes a warning naming the target, and the drift re-centering it also disables is noted alongside. The Seeing Trigger stopped working after the first night of a multi-night run. Its background sampler was shut down every time the container it sits on finished — which is once a night, at the end of *Loop while safe* — and only ever restarted when you started the sequence. So from night two onward it never fired, and it never said so: the sequencer kept displaying the last good FWHM it had read, and replans went on using that reading for another two hours before live seeing quietly dropped out of them altogether. A safety interruption brought the same failure forward to the middle of night one. It now restarts whenever that container is re-entered. A file NightFront could not write at dusk could cost you the whole night. Nightly Update saves the live weather reading beside your config before it asks the planner for a plan, and if that one write failed — a sync client or a virus scanner holding the file for a moment is enough — the instruction failed before the planner ever ran. No plan, an empty container, and the mount sat there until dawn. A write that cannot succeed now plans against the forecast alone and says so in NINA's log, which is what already happened every night at a site with no weather station. Nightly Update now records what it did in NINA's log. It reported only through a toast and the status dot, both gone by morning — so a successful plan, an emptied container, a lost forecast, an unreadable result and a missing config were one undifferentiated silence. Worst of all, a night the planner emptied because it believed everything was finished looked exactly like a good one, green dot included. Every outcome now writes a line, the emptied-container case as a warning, and a successful plan records how many targets it holds and whether the forecast behind it was assumed. Replan has done this for a release; this is the same pass applied to the other path. Messages from the planner no longer arrive with mangled punctuation. Degree, arcminute and arcsecond signs, and the dashes in its refusals, came through as ° and â€" inside NINA — the plugin was reading the planner's output in the wrong character set, which only showed up when NINA ran it, never from a terminal. It matters most on *Update an existing target*, whose summary is the only report you get that a re-point discarded accepted frames. A result file NightFront cannot read no longer empties the rest of your night. When the CLI wrote its result but the plugin could not open it — a sync client holding the file for a moment is enough — that was indistinguishable from the CLI having written nothing at all, which the plugin reads as *the night is finished*. The container was cleared and the status went green. "We could not tell what happened" is now its own outcome: the plan in the container is left exactly as it is and the failure is reported. A calibration metadata file NightFront cannot read is no longer overwritten with an empty one. Any read or parse failure produced a blank record, and the next write saved that blank over the real file — taking the cross-night collected-frames ledger, the accepted baselines and every calibration requirement with it, in one atomic replacement, with nothing said. An unreadable file now blocks the write instead, and a copy is set aside as calibration.metadata.json.unreadable so the contents can be recovered by hand. Re-pointing a target from the Framing Assistant now pre-selects the safer of two at the same spot. When two of your targets share a pointing — which is what Duplicate makes — the *Update an existing target* picker listed them in config order and started on the first, reliably the original: the one holding all the accepted frames a re-point discards. It now starts on whichever has the least accepted integration. You can still pick either. The confirmation after creating or updating a target no longer gets replaced by a footnote. When your config carried something worth remarking on (retired preference rules, say), that remark took the place of the result — so after a re-point you were told about the footnote instead of being told how many hours of accepted subframes had just been discarded. The remark now goes to the log and the result is shown. "Rebuild the plugin" is no longer shown for refusals that are not a version mismatch. The check matched the subcommand's name anywhere in the CLI's error, so genuine refusals — including the guards that stop a re-point destroying data — were hidden behind an instruction you could not act on. The Targets page throws away a framing preview when you press Reload. Previewing, pointing the plugin at a different config and reloading left the picker, the selection and the "Update would re-point ..." caption all describing the previous config, with Update still armed over the new one. A night that sets a readout mode no longer reports one target too many. The trailing restore-to-default step was being counted as a target in toasts and log lines. Replan's log line now says whether the replan actually changed anything. A target count alone could not distinguish "replanned, and it came back with the same targets" — the ordinary outcome — from "the replan did nothing". It now names the targets in order and says whether they differ from before, says when the collected-frames ledger could not be included (which can cause frames to be re-shot), and logs emptying the container as a warning rather than burying it among successes. Sidecar files are written so two writers cannot blend two documents into one. The calibration metadata, the collected-frames ledger and the readout-mode capture shared one temp filename, so two overlapping writes — a retried replan, or two NINA instances over one data folder — could leave a file holding half of each, which then fails to parse. Relatedly, when a readout-mode capture cannot be written, the camera's own default is no longer mistaken for the mode NightFront had already set — which previously left the camera on that mode at the end of the night instead of restoring it. Replan now says what it did, in NINA's log. It used to report only through a toast and the status line on the instruction — both gone by morning — so a night's replans left no trace at all. On one real log, eleven replan runs produced zero lines, which made a replan that had worked perfectly indistinguishable from one that never ran. Every outcome is now logged: which config and plan file it read, that it declined a hand-built plan, that it could not take the CLI lock, that the CLI failed and what it said, that it emptied the container because everything is complete, and — the one that was missing and mattered most — that it succeeded, with the target count and the live seeing and cloud it solved against. Renaming a target no longer makes its frames get shot again. The plugin counts what it captures each night and feeds that back to the planner, so several unattended nights can run against one backlog. Those counts were tracked by the target's name — so renaming a target in the desktop app orphaned them, the frames stopped being subtracted, and the next plan re-shot data already on disk. Each target now carries a hidden identity of its own, and the ledger follows that instead. ⚠️ It only protects frames counted from this version onward. Counts already in your calibration.metadata.json carry no identity, so a rename still orphans those — the log line about a ledger entry matching no target remains the warning for them. The same is true of any night a plugin older than this one records. ⚠️ The pairing matters, and only in one direction. This needs NightFront the desktop app to be recent enough to stamp its targets. An older app simply means no protection — nothing breaks, and nothing is lost. Likewise an older plugin beside a newer app: it ignores the identity and behaves exactly as it always did. Reviewing a renamed target now clears its counts as it should, and the Targets page's Collected column credits them to the target under its new name — so the page and the planner cannot disagree about what has been shot. The metadata file no longer loses information it does not understand. If a newer plugin writes something an older one has never heard of, the older one used to drop it the next time it saved, which happens every few minutes while a sequence runs. It now keeps it. This cannot be fixed retroactively in versions already installed — it protects everything from here on. Re-point a target you already have, from NINA's Framing Assistant. The Options tab's Targets page has always been able to *create* a target from what you framed; it can now update one. Frame the field, press Preview, and beside Create you will find a list of this config's targets nearest first to what you framed, with the best match picked for you. Press Update and that target — or every panel of that mosaic — is re-pointed at your rectangles. Use it when a mosaic was laid out slightly off, or when you want to recentre a field you have already been shooting, without leaving the mount. ⚠️ Every panel that genuinely moves loses its accepted subframe counts and is stamped reviewed. Frames collected at one pointing do not belong to a different composition — the same rule the desktop app applies when you move a target by hand. The line above the buttons says so before you press anything, and the result line says how many hours were discarded. A panel that did not really move — under 5 arcseconds, rotation within 0.1° — is left alone, counts and all. Planned is never touched, so the remaining time goes back to the full plan. Your rectangles are matched to the target's existing panels by nearest coordinate, not by the order they were drawn, so a mosaic re-framed panel-by-panel in a different order still lands correctly. It refuses anything it is not sure about, and changes nothing at all when it does: a panel count that does not match your framing, a completed target, a framing more than 5° from where the target is, a target with no coordinates, a name shared by two targets, a single panel of a mosaic on its own, or unsaved Requested edits in the table. The refusal is shown as the CLI wrote it. Version-skew messages are now the same wherever they appear. An older nightfront-cli.exe deployed beside a newer plugin used to answer *"Config file not found: add-targets"* — which reads as a missing config and is not. All four subcommands now say it needs a newer nightfront-cli.exe, including on the new target list, where the symptom would otherwise be a permanently empty picker with nothing said anywhere. NightFront NINA Plugin 3.10.2.0 NightFront has a Discord server. The plugin guide now carries the invite, under Questions and problems, along with what to bring when reporting something the plugin did — NINA's own log from the night, and both version numbers, since the plugin and the desktop app ship separately. NightFront NINA Plugin 3.10.1.1 Nightly Update no longer mistakes an unrelated JSON file for tonight's plan. It used to treat any .json file in the NightFront data folder whose name contained today's date as the plan; it now looks for the plan file by name — TargetsForTonight_.json, or the undated NightFrontPlan.json it writes when it generates one. This showed up on an observing night: a cloud-sync client wrote a conflict copy of an unrelated file into the data folder with its own date stamped into the name, Nightly Update imported that instead and failed with *"Encountered a JSON node without a $type discriminator"* — and, because it believed it had found a plan, never fell back to generating one. Anything a sync client, a backup tool or the desktop app happens to leave in that folder is now ignored. ⚠️ If you rename your plan files, Nightly Update will no longer find them. Nothing NightFront writes is affected — both the desktop app's Export and Replan use the standard name. The log now records which plan file was chosen, before it is read, so a bad import says what it was importing. When no plan file matches, it says that too. Plugin-side only: the bundled nightfront-cli.exe is the one from app 3.10.1, unchanged, and the fourth digit of the version says so. NightFront NINA Plugin 3.10.1.0 The installer now shows what changed. The license page opens with a What's new section for the version being installed, below the reminder to close N.I.N.A., and the same notes are installed beside the plugin as NightFront-Plugin-Release-Notes.txt. No plugin behavior changed. The bundled nightfront-cli.exe is built from app 3.10.1, whose changes are desktop-only (release notes behind a new What's new button, and a Targets page layout fix for macOS); plan, replan, feasibility, set-planned and add-targets behave exactly as in 3.10.0. NightFront NINA Plugin 3.10.0.0 The plugin now ships its own guide, and a button that opens it. A PDF covering every sequence item, trigger and setting, the Options tab and calibration flats is installed beside the plugin. The Options tab's Setup page has a new Plugin Guide button that opens it, so nobody has to find %LOCALAPPDATA%\NINA\Plugins\… by hand; if the file is missing, the button says where it should be. The page's introduction is rewritten to say what the plugin is: the part of NightFront's season-long workflow where the imaging actually happens. On-screen text that contradicted the plugin's behavior is corrected: - The Setup page no longer says NightFront uses "the latest Astrospheric forecast"; 7Timer! is the free default, Astrospheric is used with an API key. - Check tonight's tooltip gives the forecast cache per source (3 hours from 7Timer!, which is free; 6 hours from Astrospheric, which costs credits) instead of "6 hours, 65 credits" for all. - The Greedy/Proportional caption names Nightly Update's real field, If generating, plan for up to. - Replan's Exposure variant tooltip says the list comes from the config Replan actually reads (the Options-tab config first), and Replan hand-built plans lists every non-optimizer plan it declines: Editor, Greedy, Proportional and Dispatch plans, and the plugin's own Greedy and Proportional modes. - The Sky Flats and Trained Flats descriptions no longer say a completed requirement "moves into the archive" (it stays in the metadata file, stamped complete, until Flat Refresh Days pass), and While Same Rotation says it treats angles within about a degree as the same, respecting the rotator's range. No planning behavior changed. The bundled nightfront-cli.exe is built from app 3.10.0, whose changes are desktop-only (the app's own User Guide, and fixes to its Site, Stellarium, Editor and Processing screens); plan, replan, feasibility, set-planned and add-targets behave exactly as in 3.9.x. NightFront NINA Plugin 3.9.2.1 Completed targets no longer appear in the plugin. Reported from the field: projects already marked complete in the desktop app were still listed on the Options tab's Targets page, beside the ones actually in tonight's rotation. NightFront marks a project finished by recording *when* it was completed, and deliberately leaves its Active/Planned category alone — a new category value would make the config unopenable by an older CLI. The planner has always dropped a completed target on that stamp; the plugin checked only the category, so every completed project still read as Active here. The same test was behind a worse fault in While Work Remains. A project closed with frames still nominally owed kept that loop running — opening the roof for work the CLI will never plan — and a completed target driven by an exposure template could stop it from ever ending at all. It now stops once every enabled, incomplete Active target is done. Plugin-side only: the bundled nightfront-cli.exe is the one from app 3.9.2, unchanged, and the fourth digit of the version says so. NightFront NINA Plugin 3.9.2.0 A stale NightFront config no longer fails Nightly Update. Reported from a live night: *"Failure running Nightly Update. Reasons: The NightFront config … was last saved N days ago."* The instruction refused to load a plan that was sitting on disk, over the age of a file — nothing was wrong with the night. NINA's own SequenceItem.Run calls Validate() and fails the item outright when it returns false, so putting config age in Issues made it a *sequence failure* rather than the hint it was meant to be. Staleness is not a state that can stop a night: remaining work is planned − accepted − collected, and the collected-frames ledger already carries demand across the nights between config saves, so an out-of-date config is at worst an over-estimate of what is still owed. The age now shows as an amber advisory line on the instruction in the sequencer, saying in as many words that it does not stop tonight's plan. Issues keeps only the states where no plan can be produced at all — no data folder, no reachable NightFront Container, or no plan file with no CLI and config either. The version number jumps to align with the app. The plugin was last released as 3.3.0.0 against app 3.3.0; nothing needed a plugin release for 3.4 through 3.9.2, so the numbers drifted. This build bundles the nightfront-cli.exe from app 3.9.2, and is numbered to say so. The app itself is unchanged by this release — 3.9.2's own installer and tag are untouched. NightFront NINA Plugin 3.3.0.0 Aligns with NightFront app v3.3.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did: an install with no Astrospheric API key now plans against a real forecast instead of a fabricated one, so Replan behaves differently on exactly those installs. 7Timer! ASTRO is the new default forecast source. Before this, omitting astrosphericApiKey fell back to a stub that *invented* cloud, seeing and transparency — fine for offline development, and misleading as the only option for anyone without a paid, North-America-only Astrospheric account. 7Timer is free, keyless, global, and the only free source carrying all three variables NightFront models. Astrospheric is unchanged and is still what an API key selects; a config with a key plans byte-identically to 3.2.0. What this changes for the plugin, with no plugin code involved. The status this plugin publishes carries the CLI's forecastSource string, and IsAssumedForecast compares it against "stub", "stale-cache" and "astrospheric" to decide whether to tell the operator their night rests on assumption. A keyless install used to report "stub" and be flagged as assumed; it now reports "7timer" and is not — correctly, because the forecast is now real. Nothing to change here: the check is a denylist and a new source id falls outside it by construction. It is listed because the operator sees the difference at 2 a.m. and nothing else would explain it. Two consequences worth knowing on a keyless install. First launch now makes an unprompted network call. And 7Timer's horizon is 72 hours against Astrospheric's ~82, so a keyless Replan may plan across *fewer* nights than before, not more — the CLI reports the shortfall by name. A forecast that will not load is still reported, never fabricated. The ladder is live → cached within TTL → stale cache (up to 48 h, reported as "stale-cache") → report the failure. The stub is deliberately not the last rung: NO_FORECAST leaves the existing plan in place, and the storm that trips the safety monitor is the storm that takes the internet down. Also in the app, and not visible to this plugin at all: master-light stacking — registration, local normalization, integration, drizzle and autocrop, on either PixInsight or Siril — all of it on the processing machine, none of it in the observing loop. NightFront NINA Plugin 3.0.0.0 Aligns with NightFront app v3.0.0. C# changed here, and the nightfront-cli.exe deployed alongside this plugin changed too — every plan it writes now marks each target container "run once". Fixes NINA re-running Center and Rotate at the end of a target, for a tail too short to hold a frame. NightFront's exporter gates a target's container on a time condition, and NINA stops a container as soon as the *next* item would not fit — leaving up to one exposure still on the clock, which the container then spent on a fresh slew, plate solve and rotator sync it could never use. Measured on the night of 2026-08-22/23: two such passes on the night's last target, about two minutes, and the second was cut off mid-plate-solve by the time limit — surfacing as an ArgumentNullException out of NINA's own ASTAP solver, a failed instruction, and a failure notification at 05:50. Target containers now carry a LoopCondition of one iteration, which says "run this block once" as a count rather than as an instant; the time and altitude gates are unchanged and still decide whether the block is entered at all. Nothing about the imaging inside a target changes — the inner loop still re-images it until the next target is due. A plan from NightFront app ≥ 3.0.0 needs this plugin version. Two places that count frames adopt the nearest enclosing loop, and both would otherwise have read the new "run once" condition as an exposure count: the collected-frames ledger would have credited a frame for a pass that shot nothing (subtracting demand for frames never taken, so a target quietly goes short), and every row of the NightFront Container's target summary would have read one planned and one shot too many. Both now ignore a target container's own loop condition while still counting a segment's. Plans from older NightFront versions are unaffected either way. NightFront NINA Plugin 2.7.0.0 Aligns with NightFront app v2.7.0. The nightfront-cli.exe deployed alongside this plugin changed too: its exporter now emits SetReadoutMode (once per target container, then only on change within it, plus a trailing restore) whenever a config states a readout mode, so a Replan or an online-generated plan carries the same instructions a desktop export does. Imports NightFront's SetReadoutMode instructions; a NightFront config that states a readout mode needs plugin ≥ 2.7.0.0 (older plugins refuse the plan with "Unsupported instruction type"); configs without readout modes are unaffected. Calibration flats now match the lights' readout mode, not just their gain and offset. The calibration-metadata key gained a fifth field, read live off the connected camera the moment each light's exposure finishes (the same reasoning already used for the measured rotator angle vs. the plan's input Sky PA: the camera knows what was actually shot, not what a container the exposure never ran through might have stated). NightFront Sky/Trained Flats now sets the camera to the claimed mode before shooting. A requirement recorded before this change (or while the camera was disconnected) carries no readout mode; such an entry matches any mode on read, is upgraded in place the next time the same filter/angle/gain/offset is imaged again, and its flats are shot at whatever mode the camera already happens to be in - existing calibration.metadata.json files need no migration. NightFront NINA Plugin 2.6.0.0 Aligns with NightFront app v2.6.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan plans a short night differently. Replan no longer chops the tail of a night into three targets. If the roof opens late — or a weather hold clears at two in the morning — Replan is planning against whatever darkness is left, and until now it sized its visits as a fraction of *that remainder* rather than of the night. The effect was worst exactly when it hurt most: with under three hours to go, the rule that keeps the optimizer on one target for a decent stretch was arithmetically unable to ask for more than the 60-minute minimum, so it fell back to re-deciding every hour. Measured on a real night: a 03:00 Replan with 2 h 55 m of darkness left produced three targets at about 58 minutes each — three slews, three plate solves and a 247° rotator move, all inside three hours. Against the same night's true length the same decision now asks for roughly 2.6 hours, which is one target and one slew. ⚠️ This changes what Replan produces on a short night, and only on a short night. A full night — the ordinary case, where Replan runs at dusk or is not run at all — decodes bit-identically to v2.5.0. Nothing about a normal evening changes. Everything else in v2.6.0 is desktop-only and not reachable from NINA: a target discovery browser that ranks ~18,000 catalogued objects for your rig, site and time of year, and a Stellarium link for framing candidates. Neither is compiled into the CLI this plugin bundles. NightFront NINA Plugin 2.5.0.0 Aligns with NightFront app v2.5.0. A new "Proportional" planning mode, selectable from the Options tab. Where Greedy fills the night with the highest-priority target that can use it and then the next, Proportional splits each night's darkness *evenly* between the targets that can use it — so a list of long-running projects all advance together instead of the top of the list absorbing every clear night. The stated priority order still matters: it decides who goes first among the targets that are behind their share. Time nobody can use — a target that sets at midnight, or one with almost nothing left to shoot — goes back into the pool for the others rather than being left idle. Like Greedy, it is an auto-pilot mode: Replan will not overwrite a night it planned. That needed no new code — the CLI stamps any planner-produced night as generated, and Replan already declines anything not explicitly authored by the optimizer. Pick it under Options → NightFront → Planning Mode. --time-budget and Plan Selection are not used under it, for the same reason they are not used under Greedy: it is a single deterministic pass, so there is no search to budget and one plan rather than a front to choose a point on. One internal rule worth naming, because it decides which nights this mode is good for. A target's share is only enforceable to the granularity of its own minimum imaging time — the planner is not consulted again until that has elapsed. With a 60-minute minimum an eight-hour night therefore supports about eight targets before every share is shorter than a single visit, at which point Proportional degrades to taking turns in priority order. That is a reasonable night, not a broken one, but it is Greedy-shaped rather than proportional. Shorter minimums split more finely. Also in this release: the internal "is the optimizer selected" test that both non-GA modes hang off was generalized, so the Options-tab captions and the omitted flags now describe whichever deterministic planner is chosen rather than naming Greedy. NightFront NINA Plugin 2.4.0.0 Aligns with NightFront app v2.4.0. No C# changed — and, unusually for a release in this series, nothing this plugin does changes either. The nightfront-cli.exe deployed alongside it gained a fourth way to plan a night, but that mode is deliberately not reachable from NINA, and the plans Generate Plan and Replan produce are what v2.3.0 produced. The bump exists because the bundled binary changed, not because its behaviour did. A new "Dispatch" planning mode — desktop and command line only. It emulates NINA's own Target Scheduler: at every decision point it scores each target that can image right now against a set of weighted rules (percent complete, priority order, how soon the target sets, a penalty for switching targets) and goes to the winner. It optimizes nothing, which is the point — it exists to put an honest comparison marker on the desktop's plan-comparison chart, so you can see what a dispatch-style planner would have done with tonight's targets beside what the optimizer did, scored on the same two axes. It is reachable as --strategy=dispatch on the command line and as a ▶ Dispatch button in the desktop app. The plugin's Planning Mode dropdown does not offer it, on purpose: the comparison is worth making with your own eyes on a chart, and there is no reason to hand an unattended night to a planner that is not trying to produce the best plan. Target Scheduler's own default weights also give one target the whole night in most configurations, which is faithful emulation and rarely what you want at 2 a.m. Two things worth knowing if you do drive it from the command line: Dispatch produces a single plan rather than a range to choose from, so --plan-selection has nothing to act on; and --strategy is refused on replan, because re-deriving a deterministic ordering mid-night would just reproduce the ordering already in the plan file. Filter selection was reorganised internally with no change to what it picks. The scoring that chooses which filter each exposure is shot through moved into its own module; the arithmetic is unchanged down to floating-point rounding, and the scheduler's recorded reference plans reproduce bit for bit. Called out only so that "the filter code was rewritten in this release" does not read as a behaviour change later — it was not one. NightFront NINA Plugin 2.3.0.0 Aligns with NightFront app v2.3.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, and it changes which filter each exposure is shot through. Nothing about Replan's interface changed. Filters now rotate on how much of each filter's own job is left, not on absolute remaining time. The scheduler picked between a target's filters partly on remaining *seconds*, which reads "always L" on an ordinary LRGB set: L is deliberately planned for about twice R, G or B, so it holds the largest absolute remainder for most of a project's life even when every filter is equally far along. That is now measured as a percentage of each filter's own planned integration, so time lands in proportion to what you planned rather than converging on equal leftovers. Three defects fed the same symptom — reported as "no broadband blocks for anything but L, never R, G or B" — and all three are fixed: - An autofocus charged against a filter change was priced against the single exposure that paid for it, not the run of exposures the change actually buys. With Autofocus on filter change on and a minimum-exposures-before-change of 12, that came out at roughly eight times its true cost — more than the scheduler's other terms could ever answer, so the first filter to win kept the camera for the whole night. ⚠️ Note this correction does nothing at a minimum of 1, where the full charge is honest: a change there really does buy one exposure for a whole autofocus, and long single-filter runs are the intended outcome. - Filter-preference rules ignored their own Low/Medium/High setting whenever a rule named a single filter, which is the ordinary case. Every rule behaved as High and won every contest for as long as its condition held. The three strengths now genuinely differ. ⚠️ If you set a rule to Low or Medium, it has been acting as High until now — expect that rule to bite less hard, and the weaker the setting the larger the change. - A filter left with less than one exposure of demand — a routine outcome of the collected-frames ledger — could have its remaining work read as zero and effectively stop competing. ⚠️ Plans produced before v2.3.0 are not comparable to plans produced after it on any config that carries more than one filter per target. Recorded objective scores are likewise not comparable. NightFront NINA Plugin 2.2.0.0 Aligns with NightFront app v2.2.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, and it changes both what a plan contains and how its containers are gated. Plans now hold each target for longer. The scheduling GA's genome encoded target *selection* only, so continuing an in-progress visit required the gene at the current time bin to independently re-select the target already locked — measured at roughly a one-in-five chance per bin. Visits therefore ended at the minimum imaging time almost every time, not because a longer visit scored worse but because the encoding could barely express one. A second gene per bin now carries a dwell floor, and it is on by default. Expect noticeably fewer, longer visits per night, concentrated on fewer distinct targets — measured at roughly 25–35% fewer targets in a night on a real config, with both scheduling objectives improving. Nothing about Replan's interface changed; the plan it produces simply looks different. ⚠️ Plans produced before v2.2.0 are not comparable to plans produced after it, and neither are any recorded objective scores. Two container-gate faults are fixed, both found by reading a N.I.N.A. log after a Ground Station failure alert on the night of 2026-08-19. - The outer Deep Sky Object Container and its inner imaging loop were gated on the *same* instant. N.I.N.A. stops a container when the *next* item won't fit, so the inner loop quit with up to a whole exposure of time left, and Center and Rotate's near-zero estimated duration meant the outer gate never blocked *it* — so the container re-ran centering, repeatedly, over the tail. Measured on that night: 13 Center and Rotate runs for 5 blocks, about 13 minutes of sky, ending in an ArgumentNullException from the ASTAP solver. The outer container is now gated on its own end instant, and only the inner loop carries the handoff. - The last run of the night was gated at the twilight boundary, but the scheduler deliberately lets an exposure begun before dawn run to completion — so the final container could be gated part-way into its own last frame. Observed the same night as a 21-second final container that could only slew, center, and die. The last run now gates at whichever is later, twilight or its own end. NightFront NINA Plugin 2.1.1.0 Aligns with NightFront app v2.1.1. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so every plan and Replan this plugin produces now writes a Switch Filter instruction before every single exposure, instead of once per run of same-filter exposures. The bug this fixes. N.I.N.A.'s Take Exposure instruction carries no filter of its own — it images through whatever is physically in the filter wheel. The exporter used to rely on that, emitting one Switch Filter at the head of a run and bare Take Exposures after it. That holds only while nothing outside the plan touches the wheel. On the night of 2026-08-17 a meridian flip fired mid-run and the operator's own flip instruction set switched to L to plate-solve without switching back (N.I.N.A.'s centering restores the filter that was current when centering *began*, which by then was already L). The three remaining 600 s narrowband exposures of that target were shot through L. Nothing errored, and the frames landed under the target's own name. With dithering set to every frame — the common case — each exposure is its own segment, so a run of N exposures on one filter exported as one Switch Filter followed by N-1 unguarded ones. Those are exactly the exposures at risk. What Replan now does differently. The remainder it re-solves is exported with the filter re-asserted per exposure, so a meridian flip, a manual intervention, or any other plugin's instruction can no longer silently redirect the rest of a segment onto the wrong filter. A Switch Filter onto the filter already selected is a sub-second no-op in N.I.N.A. and does not re-trigger autofocus-on-filter-change, so the only visible difference is more Switch Filter lines in the sequence view and in the log. Also worth knowing: this plugin's collected-frames ledger attributes each exposure to the most recent Switch Filter in the plan tree — it has no other source. So frames shot through the wrong filter were also *credited* to the intended one, suppressing real demand until the next review cleared those rows. Nothing in the ledger needs changing; the fix removes the condition that produced the mis-attribution. NightFront NINA Plugin 2.1.0.0 Aligns with NightFront app v2.1.0, whose headline change is custom horizons — a per-azimuth altitude floor read from a .hrz file, replacing the single flat minimum altitude. Both the C# and the bundled nightfront-cli.exe changed. Passes NINA's own custom horizon (Options → Astrometry → Custom Horizon) to the CLI as --horizon= on every plan, replan and feasibility invocation. Read live off NINA's active profile — there is nothing to configure on this plugin's Options tab beyond a new read-only line under Plan Selection showing what NINA currently has set (or that nothing is). A NightFront config exported with its own embedded horizon still takes precedence; this only supplies one for a night this plugin plans itself, with no export ever having happened. Omitted entirely when NINA has no custom horizon configured, so an installation that has never touched that NINA setting sends the identical argument list it always has. What Replan now does differently. With a horizon in force, the remainder it re-solves is gated azimuth by azimuth rather than against one number, so a target low in an obstructed direction is dropped from the replan where it would previously have been scheduled. Measured on a real 7-target site with a 25°–35° .hrz, that removed 40 minutes of feasible time from one target and excluded two mosaic panels outright. The exported sequence's per-target altitude guard is unchanged in kind. It remains an AltitudeCondition, now floored at the horizon's *lowest* point. NINA's own AboveHorizonCondition was considered and rejected: this plugin's importer refuses any condition type it does not recognise, so emitting one would fail the whole night's import on any plugin older than this release. Note the consequence — a .hrz with near-0° rows over its open directions makes that guard looser than the flat minimum it replaces. It is a defence-in-depth net against a stale plan, not what makes the plan correct; the horizon is fully honoured by the plan's time windows. NightFront NINA Plugin 2.0.2.1 Repackages 2.0.2.0 to clear a Windows Defender false positive. Nothing in the plugin, the scheduler or the planning behaviour changed — if 2.0.2.0 installed for you and works, this release gains you nothing. Downloading 2.0.2.0 failed in Chrome and Edge with "virus detected". Defender flagged the nightfront-cli.exe inside it as Trojan:Win32/Wacatac.B!ml — an !ml verdict, meaning a machine-learning heuristic rather than a match against a known threat. The CLI is a 52 MB GraalVM native-image binary, which is a shape those classifiers habitually misread, and it ships unsigned. Nothing else in the package was flagged. It was a false positive, and the evidence is that the verdict is not stable: the CLI in plugin 2.0.0.1, scanned with the same Defender definitions on the same machine, came back clean. That binary and the flagged one are the same size and built from the same source — native-image output just isn't byte-reproducible, so the classifier was reacting to incidental bytes. Rebuilding the CLI produced a binary Defender accepts, and this release packages that one. The flagged build is being reported to Microsoft so their definitions stop flagging it for anyone who already has it. The real fix is code signing, which would stop this recurring and also clear SmartScreen's "unrecognized app" prompt. That is being looked at separately. NightFront NINA Plugin 2.0.2.0 Aligns with NightFront app v2.0.2. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so every plan this plugin produces sequences its filters differently — both Nightly Update's generate branch and Replan. Numbered 2.0.2.0 rather than 2.0.1.x because the version this plugin last shipped against was 2.0.0. Filters now rotate through the whole wheel instead of two of them. The scheduler's anti-streak rule tracked only whichever filter was currently on a winning run, so as soon as a rival won, the previous winner's penalty was wiped and it won straight back. With three or six filters loaded that could only ever alternate the top two — a six-filter SHO+RGB target ran OIII, SII, OIII, R, OIII, G, OIII, SII, …, and an LRGB target ran L, B, L, L, B, L. Since a dither resets *every* filter's counter, a two-filter cycle at the usual dither-every-frame setting meant a dither before every other exposure. On a real two-target night that was 32 dithers across 64 exposures; it is now 23 across 68 — fewer settling pauses and more time on the sensor, from the same config. If you focus on every filter change, plans now stay on one filter instead. With "autofocus on filter change" enabled, each change buys a focus run's worth of dead sky, so rotating for its own sake spends real dark time to save a twelve-second dither. The planner now recognises that and produces long single-filter runs, moving on only when remaining work, moon separation or one of your filter-preference rules actually shifts. On the scheduler's own regression fixtures this cut a night from 44 autofocus runs to 4, and raised imaged time from 12,900 to 17,400 seconds across an unchanged night. If you focus on a timer or after slews only — the default — nothing here applies to you and you get the rotation above. Nothing to configure either way: the planner reads your existing autofocus-on-filter-change setting and picks the right behaviour. No sequence or plugin setting changed. NightFront NINA Plugin 2.0.0.1 The NightFront icon is back in NINA's plugin list. 2.0.0.0 showed the generic puzzle-piece placeholder beside the plugin's name and nothing at all in the header of its Options page. Nothing was missing from the installer — the icon ships compiled into the plugin's own assembly, and every sequencer block that draws it was unaffected the whole time. The cause was the same change that made the repository private. The plugin's featured image used to be fetched from raw.githubusercontent.com, which now returns 404 for everyone, so 2.0.0.0 blanked the setting rather than ship a broken image request — and a blank one is what NINA renders as the placeholder. It now points at the copy inside the plugin assembly instead, so the icon needs no server to be reachable and there is nothing left to go stale. NightFront NINA Plugin 2.0.0.0 There is now an installer, and the license has changed. Please read the second part. Numbered 2.0.0.0 to match NightFront 2.0.0, which is a major release for manual and greedy scheduling. ⚠️ This is also the first release published as a downloadable artifact, so installing it brings you everything from 1.25.0.0 and 1.26.0.0 as well — the Planning Mode dropdown and Greedy support, Replan declining to overwrite a hand-built or generated plan, the While Work Remains loop condition, and the Seeing Trigger becoming ASCOM-StarFWHM-only. Read those two entries below as part of this upgrade. A proper MSI installer. NightFront's plugin is now distributed as NightFront-NINA-Plugin-2.0.0.0.msi on this repository's releases page, instead of a folder you copy by hand. It installs per-user to %LOCALAPPDATA%\NINA\Plugins\3.0.0\JeffRidder.NINA.Nightfront — the same place as before, so nothing about your setup changes — and needs no administrator rights. - ⚠️ Close N.I.N.A. before installing. The installer cannot overwrite files a running NINA holds open. It will tell you if NINA is running, but it is quicker to close it first. - ⚠️ The installer REPLACES the entire plugin folder, rather than copying over the top of it. This is deliberate and it fixes something: because the old hand-copy install never deleted anything, every existing installation is still carrying Tesseract.dll, tessdata\, x64\ and x86\ — about 16 MB — left behind when 1.26.0.0 removed the OCR seeing source. A stale DLL beside a live one is exactly the sort of thing an assembly loader can bind to by mistake. Upgrading with this installer clears them out. If you have put your own files in that folder, move them first. - nightfront-cli.exe is installed alongside the plugin as always, so Replan, online planning, the Targets page and Check Tonight keep working with no configuration. License change: this plugin is now proprietary. Versions up to and including 1.26.0.0 were published under the Mozilla Public License 2.0. From 2.0.0.0 the plugin is covered by the NightFront End User License Agreement — the same agreement that already covered the NightFront desktop application and nightfront-cli.exe — and its source repository is private. - Nothing is retracted. 1.26.0.0 and every earlier release remain under the MPL-2.0 they were published under, permanently. This change applies only going forward. - The MPL was never a considered choice — it came from the NINA plugin template's boilerplate. It stopped being honest once the source repository went private, and a declared open-source license whose source nobody can obtain is worse than a plain proprietary one. - What you can do with the plugin is unchanged in practice: install it and use it on your own equipment, for your own astrophotography. The agreement is installed as LICENSE.txt beside the plugin and is shown in full by the installer. - Third-party components are unaffected and are listed in THIRD-PARTY-NOTICES.txt, installed in the same folder. N.I.N.A. itself remains MPL-2.0 and is not redistributed by this plugin — the plugin only builds against its API, and NINA's own assemblies come from your NINA installation. No functional or behavioral changes to planning, sequencing or the ledger in this release. NightFront NINA Plugin 1.26.0.0 A new loop condition: While Work Remains. Wrap the outermost container of an unattended sequence in it and the observatory stops opening for nights it has nothing to shoot. It loops while any enabled, Active target in your NightFront config still owes integration time — planned minus accepted minus the plugin's own collected-frames ledger, the same arithmetic the Options tab's Targets page shows — and stops once they are all complete, or there are none. - ⚠️ Anything it cannot determine keeps the loop running. A missing, unreadable or wrong config, or a target whose exposures come from an exposure template the plugin cannot expand, all answer "continue". The two ways of being wrong are not symmetric: continuing wrongly costs one pass that Nightly Update reports as nothing to plan, while stopping wrongly ends the night at dusk with every instruction below it skipped and nobody awake to notice. - The condition says which case it hit on its own line in the sequencer — *"2 active targets still to shoot (31.4 h remaining)"*, *"All 3 active targets are complete"*, *"The NightFront config could not be read - continuing"*. A loop that keeps running and a loop that keeps running because it could not tell would otherwise look identical. - It warns you in the sequence editor when it will never be able to stop — no config found, a file that isn't a NightFront config, or a target whose exposures come from a template. That is the case you cannot see at runtime, since failing open looks exactly like a night still in progress. ⚠️ It never reports "everything is complete" as a problem: an exhausted target list is the ordinary end of a successful run, not a fault, and it never fails the sequence — the warning is advice. - Planned and disabled targets do not count, matching the two places NightFront itself filters. A target that cannot be scheduled tonight must not keep the roof opening. - It answers as of the start of the observing night, not the current instant: frames shot tonight reach the planner through the progress snapshot instead, and subtracting them here as well would both double-count them and risk breaking the loop out from under a plan still executing. The Seeing Trigger is now ASCOM-only — the OCR path is gone. The trigger reads star FWHM from your connected weather device and nothing else. Removed with it: the Seeing Image URL option, the trigger's own per-instance URL override, the Tesseract OCR engine, and the committed 4 MB tessdata language file — the plugin's download is meaningfully smaller for it. - Why. The device reading was already preferred on every poll and beat OCR on every axis: no web server to be up, no image to parse, no digit to misread, and no staleness question — an OCR sample's age came from a timestamp printed *into* an image a CDN could be serving from cache. What OCR bought was one site shape (a seeing monitor publishing only a picture) at the price of a silent-misread failure mode on a number that reaches the plan through live-conditions override. - ⚠️ If your weather device does not publish a star-FWHM sensor, this trigger can no longer fire. Validate() says so in the sequence editor, which is the one place you are present to be told; unattended it would simply do nothing. Live *seeing* then stops reaching Replan and Nightly Update, which fall back to the Astrospheric forecast — live cloud cover is unaffected. The issue is raised only when the device is connected and reports no FWHM — the genuinely actionable case. A disconnected device says nothing, because that is the normal daytime state and daytime is when sequences get edited. - A seeing reading a Replan inherits from the trigger is now bounded to two hours, the same live-data horizon the triggers re-arm on. The trigger keeps its last good reading across a failed poll so the readout does not blank, and the conditions file is stamped with the current time — so without a bound, a hub that stopped publishing at 21:00 could have a 3 a.m. Replan plan the rest of the night against six-hour-old seeing, with NightFront's own ±2h window structurally unable to screen it. The trigger also drops its reading on sequence teardown, so restarting a sequence hours later cannot act on the previous session's number. - ⚠️ A reading of 0 is treated as no reading, not as perfect seeing. This was already true and is now the only gate there is: NINA's weather DTO defaults an unset double to 0 and several ASCOM drivers report a flat 0 for a sensor they do not have, and 0.00″ is the best seeing physically possible — so taking it at face value would fire the trigger permanently on every site with no seeing sensor at all. A device that drops out mid-night likewise stops the trigger firing, without blanking the last good reading from the sequencer readout. - An OCR URL left behind in user.config by an upgrade is simply never read. Nothing needs changing in a saved sequence; the trigger keeps its threshold, comparator and polling interval. NightFront NINA Plugin 1.25.0.0 Nightly Update can plan with the Greedy planner instead of the optimizer. A new Planning Mode dropdown on the Options tab. *Optimizer (GA)* is the default and is exactly what every previous release did. *Greedy* fills the night with the highest-priority target that is feasible and still needs time, then the next — using the target order you dragged into place in the NightFront app. - It is instant and deterministic. There is no search, so Nightly Update's Time Budget field has no effect under Greedy, and Plan Selection does not apply either — Greedy produces one plan rather than a range to pick a point from. The Options tab says so when Greedy is selected. - ⚠️ Greedy is only as good as your priority order. With an order set it reaches a higher time on sensor than the optimizer typically finds; with no order set it has nothing to go on and the optimizer is the better choice. Set the order on the Targets page in the NightFront app. - Greedy is an auto-pilot mode: Replan stays out of its way. A greedy-planned night is marked as such, and Replan leaves it alone — re-solving it would just re-derive the same priority ordering. Replan no longer overwrites a plan you built yourself. NightFront 1.25.0 adds two ways to produce a night's plan without the optimizer: building one by hand in the new Editor, and generating one from your target priority order with the Greedy planner. Replan re-solves with the optimizer, so a wind or cloud trigger firing at 2 a.m. would have replaced either of those with an optimizer plan — mid-night, unattended, with nothing in the sequence reporting that it had happened. - A night whose plan you built or generated is now left alone by Replan. The status line reads *"Left the hand-built plan 'Guest night' in place"* and a notification says the same. This is reported as a normal, successful outcome, not a failure — it is the instruction doing its job. - Tick "Replan hand-built plans" on the Replan instruction to re-solve it anyway. Off by default. Worth turning on if you want the remainder of a hand-built night re-solved after a long weather interruption; leave it off if the plan is the point. - Nothing changes for an optimizer plan, which is every plan any previous NightFront version could export. The desktop app writes a small .authorship.json marker beside each exported plan file saying who produced it; a plan exported by an older app has no marker, and replans exactly as it always did. Also in this release, on the desktop side: hand-built and generated plans now survive closing the app, and can be deleted from the Plan tab. NightFront NINA Plugin 1.24.0.0 Aligns with NightFront app v1.24.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan and Nightly Update's generate branch can now choose a different plan than 1.23.0.0 would have for the same config and the same forecast. - The optimizer's time-on-sensor axis is measured against the night, not against the plan. It used to divide imaged time by the plan's *own* scheduled time — but idle time produces no slots at all, so a plan that left part of the night empty scored *higher* than one that filled it and paid a slew and an autofocus to do so. The denominator is now the night's total dark time. Plans that fill the horizon move by a fraction of a percent, either direction; a night where the targets run out of work part-way moves substantially. The knee the CLI picks off the Pareto front is chosen from the same front as before, so nothing about *how* it chooses changed — but a different point on it can now win. In practice this favours plans that actually use the night. - A horizon saved in the desktop app is now honoured by Replan. NightFront 1.24.0 adds a Horizon control (1 / 2 / 3 nights) to Nightly Planning. If you pick one and save, Replan solves across that many nights instead of one. If you never touch it — which includes every config written before 1.24.0 — Replan solves one night exactly as it always has. Nothing in this plugin passes a night count, so this is entirely driven by what the config states. - Check tonight is unchanged. It reports one night, as before, whatever the config's horizon says: the report flattens its per-night figures into one total, so a multi-night diagnosis would have made "imageable 6.0 h" read 18 h and a target blocked tonight but clear later read as schedulable. Internally the CLI's scheduler was split apart so a future manual-planning feature can reuse it, and the whole schedule is now pinned slot-for-slot by recorded goldens — the output is byte-identical across that change. No behavior rides on it. NightFront NINA Plugin 1.23.0.0 Aligns with NightFront app v1.23.0, which is a packaging release for the desktop app. Nothing in this plugin behaves differently — no C# changed, and unlike previous alignment releases the nightfront-cli.exe deployed alongside it did not change either. No Kotlin was touched at all, so Replan, Generate Plan, Check tonight and target creation all do exactly what they did in 1.22.0.0. The version bump exists so the plugin and the app it belongs to stay in step. For the record, what changed on the app side: its installer now ships obfuscated, presents a license agreement, and carries a copyright notice. The nightfront-cli.exe here is rebuilt from the same Kotlin as before and was verified to produce the same result on the same config. NightFront NINA Plugin 1.22.0.0 Aligns with NightFront app v1.22.0. Makes the Targets page readable at the mount, and lets you create a target — or a whole mosaic — from NINA's own Framing Assistant without going back to the desktop app. - Targets are collapsed by default, and each one says how it stands. A collapsed row shows the target's name, how complete it is, and how many hours it still owes; expanding shows the exposure plan as before. The completion percentage is derived from the Remaining column underneath it, so the two cannot disagree — including for a filter with a sub-exposure residue, where the obvious arithmetic shows zero for a row the optimizer is about to spend ten minutes on. - A mosaic is one line, named for the mosaic, with its panels nested underneath. Previously each panel sat at the top level as a peer of every other target, four of them in a row each repeating "mosaic: M 16" and burying the rest of the list. The mosaic row pools its panels' progress and remaining hours — in seconds, so a panel with twenty hours left is not averaged against one that is nearly done — and after a Check tonight it says how many of its panels are imageable. - A new Check tonight button says what the sky actually allows. For each target: how many hours are imageable tonight, or why none are — never high enough, too close to the moon, or the case that looks like neither, where it was high at some point and clear of the moon at some point but never both at once. It also flags a target whose feasible time never comes in one stretch long enough to start on, which is the one way a target can look perfectly healthy and still get nothing all night. Reads only; it changes nothing, and it will not clear your collected-frames tally. It uses the cached forecast when one is less than six hours old. - Only Active targets are listed now. Tonight's scheduler never touches a Planned target, so an edit to one here could not reach the planner. Manage the Planned queue in the desktop app. - New: create a target from the Framing Assistant. Frame an object — single or a mosaic grid — pick one of your exposure templates, and press Create. Each panel becomes a real target with the template's filters, gains and moon profiles written in, named the way NINA itself names panels (M 16 Panel 1). Preview first shows exactly what will be created. The write goes through the same nightfront-cli.exe that does the planning, so nothing in your config is disturbed. - Coordinates are converted to J2000 on the way through. NINA's framing surfaces commonly hold JNow, and the difference in 2026 is about the same size as one panel step — enough to frame a mosaic that looks right and is systematically off. - The template's filters are written in inline rather than as a template reference: a template-driven target carries no accepted counts anywhere, so this plugin's ledger can never reconcile against one. - If a name it would create already exists, nothing is created at all. Two targets sharing a name do not error anywhere downstream — they merge in the NINA export and pool their frame counts. - The plugin description no longer sits under both Options pages. NINA renders it below whichever page you are on, so ~4,700 characters of it were in the way of the Targets page. There is now a short introduction on Setup, where it belongs, and the full detail lives in the README. Two new nightfront-cli.exe subcommands ship with this release (feasibility and add-targets). Both are needed by the features above, so an older CLI deployed beside this DLL will report that it needs updating rather than failing obscurely. NightFront NINA Plugin 1.21.0.0 Aligns with NightFront app v1.21.0. Adds a Targets page to the Options tab, so you can see what tonight still owes — and adjust it — without leaving NINA. - A new Targets page beside Setup. For every target in your NightFront config it lists each filter with Requested, Accepted, Collected and Remaining (in both subframes and hours). Accepted is what you kept at your last review; Collected is what this plugin has counted since; Remaining is what the optimizer will actually try to shoot. - Requested is editable, and Save writes it back to your config. The write goes through the same nightfront-cli.exe that does the planning, so the file is updated exactly as a desktop Save would update it and nothing else in it is disturbed. Save waits if a Nightly Update or Replan is mid-solve rather than racing it, and re-reads from disk afterwards so what you see is what is stored. - Accepted stays read-only, deliberately. It records your judgement about frames you have looked at, and it is one of the two signals this plugin uses to decide when its own tally has been superseded. A second way to change it would quietly fight the first. - A filter shot at two sub lengths stays two rows. Those are two separate quantities of sky time with their own progress, and each keeps its own Requested and Remaining. - Remaining matches what the optimizer will actually plan, including mid-night. Frames shot earlier tonight are counted toward your plan by a different route, so the Targets page leaves them out of Collected exactly as the planner does. Counting them in both places would have shown you fewer frames outstanding than are really going to be taken — during the night, which is when you would be reading the page to decide whether to step in. - An empty Collected column now says why it is empty. "Nothing collected since your last review" and "your data folder isn't set, so nothing is being counted" used to look identical, and the second means the frame tally is quietly doing nothing. - Save no longer freezes NINA. If a Nightly Update or Replan was mid-solve, pressing Save could lock the whole window for up to a minute while it waited its turn. It now waits in the background and tells you it is waiting. - A failed Save reports the actual problem. On a config carrying settings retired back in 1.14, a real failure — a filter that no longer exists, an ambiguous row — was displaced by an unrelated advisory note about those retired settings, naming neither the problem nor the fix. - The Options tab is now split Setup / Targets. Every existing setting is unchanged and still on Setup. This release also carries everything from 1.20.1.0 below, which was never published separately. NightFront NINA Plugin 1.20.1.0 Aligns with NightFront app v1.20.1. Fixes three consequences of a change in 1.20.0.0 that went further than it looked: allowing a filter to appear twice at two different sub lengths meant a filter's name stopped being enough to identify a row, and three places were still treating it as though it were. Only targets whose filters are split across two sub lengths are affected — a target shot entirely at one exposure, which is most of them, behaves exactly as in 1.20.0.0. - Replan and Nightly Update no longer subtract collected frames twice. *(No C# changed for this, but the nightfront-cli.exe deployed alongside this plugin did.)* The collected-frames ledger records what was shot per target and filter, and the CLI applied that total to every row sharing the filter's name. A target with Ha at 600s and Ha at 300s therefore had the same collection deducted from both: 6000 seconds collected removed 12000 seconds of planned work. The lost demand was never re-scheduled and nothing reported it — the target simply appeared to finish early. Collection is now shared out across those rows so each second counts exactly once. - The ledger notices a review again when only one of a filter's two rows changes. This plugin reads each filter's accepted count to decide when your review has superseded its own tally, and it kept only the last row for a repeated filter name. Reviewing frames on the 60s Ha row while the 600s row stood still therefore looked like no review at all, and the tally went on suppressing demand. Counts for a repeated name are now added together. The reviewedAtUtc stamp NightFront writes on an AstroPM import was always the primary trigger and was never affected — this restores the secondary one, which matters if you adjust accepted by hand. - Mosaic panel names are readable in the container's target list. Panel names differ only at the end ("... Panel 1" vs "... Panel 2") and the column trimmed the end, so every panel of a mosaic displayed as the same truncated string. The column is wider and now shows the full name on hover. NightFront NINA Plugin 1.20.0.0 Aligns with NightFront app v1.20.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan and Nightly Update's generate branch now compute each filter's remaining demand from integration seconds rather than from a frame count. - Frames captured under an Exposure Variant now count for what they actually were. A filter's progress was stored as a subframe count at that filter's *default* exposure, so 40 frames shot at 300s under a High Wind variant and then accepted came back as 40 x 600s — twice the integration actually collected — and the demand Replan planned against was reduced by twice as much. The config now also carries plannedSeconds/acceptedSeconds, which the CLI reads in preference to the frame counts. The collected-frames ledger this plugin writes was already denominated in seconds for exactly this reason; the config side now matches it. - Replan will schedule differently for any target whose frames were not all shot at one sub length. That is the point of the change rather than a side effect: those targets previously had their remaining demand over- or under-stated. A target shot entirely at its default exposure — which is most of them — plans exactly as it did in 1.19.0.0. - An AstroPM project listing one filter at two sub lengths imports as two rows, not one. Previously the two were summed as bare frame counts and labelled with whichever exposure appeared first in the file: 20 x 60s plus 40 x 600s became 45 subs at 60s, i.e. 45 minutes standing in for 5h15m of real data. Each sub length now keeps its own row and its own exposure. - A config written by v1.20.0 is backward-compatible, and an older config loads unchanged. The two new fields are additive and nullable; absent, they are derived from the frame counts exactly as before. An older nightfront-cli.exe paired with a newer config ignores them and reads the frame counts, which are still written. This plugin's own tolerant readers are unaffected — the collected-frames ledger still keys on accepted, which is still emitted. NightFront NINA Plugin 1.19.0.0 Aligns with NightFront app v1.19.0, which adds imaging-system optics and mosaic creation, and rewrites this plugin's store-page description. - The plugin's description and long description now describe what it actually does. Both still claimed that importing a plan file exported by the desktop app was the only way to get a plan into NINA. That stopped being true several releases ago: Nightly Update generates plans online through the bundled nightfront-cli.exe, and Replan, the weather and seeing triggers, the target triggers, Plan Selection, the collected-frames ledger and the calibration-flats instructions all went unmentioned. No C# changed for this — it is assembly metadata the NINA plugin hub reads. - No plugin behaviour changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan and Nightly Update's generate branch run a newer optimizer build. They produce the same plans they did in 1.18.0.0: v1.19.0 is desktop-side only — optics fields on the Imaging System page, a mosaic-creation mode in the manual-entry dialog, and sexagesimal coordinate entry throughout the app. Nothing touches the scheduler, the objectives, the decoder or the exporter. (The only C# in this release is the assembly metadata above; no executable code changed.) - Fixed in the CLI's shared coordinate code: a declination of exactly zero could lose its sign. Sexagesimal conversion derived the sign from value < 0.0, which IEEE reports as false for negative zero. It reached the exported-plan path through NinaSequenceModel, though only for a target at exactly Dec 0°00'00" — so no plan this plugin has imported was affected in practice. - A config written by v1.19.0 is backward-compatible. The new optics block is additive and nullable, and neither this plugin nor the CLI's planning path reads it — it exists only so the desktop app can compute mosaic panel centres from the rig's field of view. An older plugin paired with a newer app sees exactly what it saw before. NightFront NINA Plugin 1.18.0.0 Aligns with NightFront app v1.18.0, which adds the mosaic editing UI. - Nothing in this plugin changed, and Replan produces exactly the plans it did in 1.17.0.0. v1.18.0 is desktop-side only: a mosaic's panels now appear as one card in the app's Targets page instead of N separate ones, with a panel tab strip, group-wide settings, per-panel enable and removal, and a rename that rewrites every panel at once. None of it touches the scheduler, the objectives, the decoder, the exporter or the config format. This bump exists so the plugin version keeps matching the app version — not because a replan will decide anything differently. - A config written by v1.18.0 is byte-compatible with 1.17.0.0. The three mosaic grouping fields are unchanged, so an older plugin paired with a newer app sees exactly what it saw before. - ⚠️ Still true, and now enforced in more places: a mosaic panel's name is derived and must not be hand-edited. The app refuses a mosaic rename that would collide with an existing target, because two panels sharing a name do not error anywhere — this plugin's collected-frames ledger pools their rows under one key, and Ground Station's $$TARGET_NAME$$ resolves to whichever one it finds. If you rename targets outside NightFront, that is the failure to avoid. - Removing one panel of a mosaic in the app no longer renumbers the others. Panel 1, 2, 4 is correct and deliberate: closing the gap would rename Panel 4, and this plugin's ledger records frames against that name, so the panel's collected counts would be orphaned and already-shot frames re-shot. NightFront NINA Plugin 1.17.0.0 Aligns with NightFront app v1.17.0, which adds mosaic targets. - Mosaics: no plugin change was needed, and that is the design. A mosaic panel is an ordinary target with its own coordinates, rotation and filter plan — it just carries three extra grouping fields the app uses to show the panels together. Everything here treats it exactly as it always treated a target: the collected-frames ledger counts each panel separately under its own name, the Before/After Target triggers fire per panel, and calibration flats still collapse to one requirement per filter because all the panels share a rotation angle. - nightfront-cli.exe was rebuilt for this release, but Replan produces the same plans it did in 1.16.0.0. The only CLI-side changes are three optional passthrough fields on a target; nothing the scheduler, the objectives or the decoder read. This bump exists because the executable deployed beside the DLL differs, which is the rule regardless of whether behavior moved — not because a replan will now decide anything differently. - ⚠️ A mosaic panel's name is derived and must not be hand-edited (M 16 Panel 1, matching NINA's own convention). The collected-frames ledger, this plugin's target rows and Ground Station's $$TARGET_NAME$$ all key on that name, so renaming a panel outside NightFront orphans its collected counts and those frames get re-shot. The app renders panel names read-only for this reason. - Fixed: the Wind Speed Trigger's lower container only ever ran once a night. The first time wind dropped back below your threshold the instructions you dropped under "When it drops back below" ran normally; every later time, the trigger fired and ran nothing at all — no instructions, no error, and nothing in the NINA log to say it had been asked. NINA resets the upper container for us and knows nothing about the lower one, so once the lower one had finished it refused to run again. Both halves are now reset before they run. - Fixed: a night whose wind never crossed the threshold still ran the below-threshold Replan every two hours. A condition that persists past the two-hour live-data horizon is meant to earn a fresh plan — but that only makes sense for the *adverse* side, where the plan was built to cope with something. "Still calm since dusk" asks for the plan the night already has. On 2026-08-08 that produced three "wind is back below threshold" replans, at 22:58, 00:59 and 03:05, on a reading that never once crossed 20 km/h. Only the upper half re-arms now; the lower half fires on a genuine downward crossing and nothing else. - The weather triggers now log what they acted on. One line per firing, with the reading, the threshold, which container ran, and whether it was a fresh crossing or a re-arm. Previously the reading appeared only in the sequencer UI and the Replan it fires logged nothing, so an unattended night's weather-driven replans could only be reconstructed by inferring the readings from the arithmetic of when the trigger fired. - No other C# changed — the wind fixes above only change *when* the Wind Speed Trigger asks for a replan, not what a replan produces. NightFront NINA Plugin 1.16.0.0 - Fixed: a target the schedule visited more than once only ever got imaged the first time, and the last target of the night ran long to make up for it. NightFront's optimizer routinely comes back to a target later in the night, but the exported sequence gave each target a single block whose end time was the *next* target's start — so the return visit's frames sat behind an expired gate and were silently never shot, while the final target absorbed all the leftover time. On a four-way round-robin planned an hour per target per pass, an eight-hour night ran 1/1/1/5. Each visit is now its own block with its own window, so the sequence executes the night that was actually planned. - Coming back to a target now re-centres and restarts guiding, which is more than the dither that used to mark that point. - The Before/After Target triggers fire once per visit, so a target visited twice sends two sets of notifications a night. - Fixed: frames from a revisited target were under-counted in the collected-frames ledger. With one block per visit, each visit was recorded separately and the later one overwrote the earlier — so remaining demand looked higher than it was, and frames already on disk would eventually be re-shot. Counts from every visit of a target are now added together before being written. - Fixed: the filter-wheel slot number written into an exported plan came from the target's own filter list rather than from your filter wheel — a target listing Ha and OIII claimed slots 0 and 1 whatever the wheel actually holds. It now comes from the Filter Definitions list on NightFront's Imaging System page, in the order you have them listed there, and a filter missing from that list stops the export rather than silently selecting slot 0. This never affected plans imported through this plugin, which looks each filter up by name against your NINA profile and ignores the slot number entirely; it mattered only if you loaded an exported plan file straight into NINA. - Beyond the ledger fix above no other C# changed, but the nightfront-cli.exe deployed alongside this plugin did — so Replan and Nightly Update's online planning now produce the corrected per-visit sequence described above. NightFront NINA Plugin 1.15.1.0 - Replan's Exposure Variant is now a dropdown, and it tells you where you stand as you type. The field lists the variants your last NightFront export actually declared, plus a blank entry for "normal exposures", so the ordinary case is a pick rather than a spelling test. Beside it, a dot and one line say what the name you have right now means — *Matches "High Wind" in your config*, *Not in your config - normal exposures will be used*, or *No exported config to check against yet* — updated on every keystroke instead of whenever NINA next re-validates the sequence. - The dot for an unrecognised name is amber, not red, and the wording says normal exposures will be used. That is what actually happens: NightFront ignores a name it doesn't know and plans at your usual sub lengths rather than losing the night. The validation issue (added in 1.15.0.0) still appears too, and still says the replan will run. - You can still type a name. The list comes from the session-config.json your export writes, so a sequence built before your first export has nothing to choose from — and a name already saved in a sequence stays in the list even when the config no longer defines it, so opening an old sequence can't quietly drop it. - Fixed: Replan did nothing at all if you never exported a plan from NightFront. It looked only for the session-config.json that NightFront's *Export* writes, so on an installation that lets Nightly Update generate its plans instead, every Replan warned "no session-config.json found" and left the night alone — quietly, in the middle of a safety recovery, which is exactly when it was needed. Replan now finds its config the same way Nightly Update already did: the NightFront config you set on the Options tab first, falling back to the exported sidecar. Nothing changes for an installation that has only the sidecar. - This also settles a subtler disagreement: with both present, Nightly Update planned the night from your app config while Replan re-solved it from the exported sidecar — a frozen snapshot whose accepted-subframe counts stop updating the moment it is written. Both now read the same file, so a replan cannot re-schedule data the original plan already knew was in the bank. - Replan's validation now says so up front when no config can be found, rather than leaving you to discover it from a notification at 3am. - The Exposure Variant dropdown reads whichever config Replan resolved, so it always lists the variants a replan can actually honour. NightFront NINA Plugin 1.15.0.0 - The Seeing Trigger now reads your weather device first, and only falls back to OCR. If your ASCOM weather device (or hub) publishes a star-FWHM value — the standard ObservingConditions StarFWHM sensor, which observatories running a seeing monitor commonly expose — every poll takes the reading straight from it. The image URL is fetched and OCR'd only when the device reports nothing, so a site with a hub can leave the URL blank entirely; the trigger's validation no longer asks for one while the device is answering. The status line names which source it used, because the two substitute for one another silently and a plausible FWHM otherwise tells you nothing about where it came from. - The field is matched by name, not hardcoded: any property whose name contains "FWHM" qualifies, so a hub publishing seeing under its own sensor name still works. - A reading of 0 (or a negative one) counts as *no reading*, not as perfect seeing. Several drivers report a flat 0 for a sensor they don't have, and 0.00″ would be the best seeing physically possible — it would have pinned the trigger on and reached your plans. - This also removes a real limitation of "Generate Plan" for hub-equipped sites: seeing used to be unavailable at dusk because the trigger had not polled yet, so a from-scratch plan's live reading was always cloud-only. A device reading needs no prior poll and no trigger at all. - Replan now tells you when its Exposure Variant name doesn't exist. Typing a variant your NightFront config doesn't define has always been *harmless* at run time — NightFront warns to a log and plans at your normal exposures rather than losing the night — which is exactly what made a typo or a rename impossible to notice: the wind trigger fires, the replan succeeds, and the subs are simply never shortened. The instruction now flags an unrecognised name in the sequence editor and lists the variants your config does define. Matching is case-insensitive, and the message says plainly that the replan will still run. - Nothing is reported when the plugin can't read your session-config.json at all — before your first export from NightFront there is nothing to check against, and flagging a perfectly good name there would be a permanent false alarm. NightFront NINA Plugin 1.14.0.0 - Fixed: "Before Target" and "After Target" repeating over and over once the night's last target finished. On 2026-08-05 a single target ending at 05:26:30 produced 16 Before/After pairs — 32 notifications — in nine seconds. What was happening: once a target's handoff time passes, the loop your NightFront Container sits inside comes back round and enters that target again. NINA looks at it, sees its window has closed, skips every instruction inside it and moves on — but it still announces the target on the way in and on the way out. The triggers were faithfully reporting a target that did nothing, once per revolution of your loop, for as long as the loop kept turning. Nothing was racing; it was a loop, not a timing problem. - Each trigger now fires at most once per target, and "After Target" only for a target it saw genuinely start. A target the loop merely walks past — because its window has closed, or because it has not opened yet — announces nothing. A target that is *resumed* (say after a safety recovery) does not announce a second start, and still gets its "After Target" when it really ends. - This was there before, invisibly: until 1.12.0.0 the dropped instructions were silently discarded by a gate, so the storm ran into nothing. Fixing that made it audible. - Fixed: "NightFront Rotate to Next Angle" reporting a failure once every calibration requirement was satisfied. Running out of requirements is how a flats session *ends* — it means everything got shot — but the instruction treated it as a fault, marking itself FAILED and setting off any failure notification you have wired up. It now does nothing at all in that case and leaves the rotator exactly where it is; there is no "next" angle to move to. Same for a data folder that has no calibration metadata in it yet. - The Sky Flats and Trained Flats instructions still fail if asked to shoot flats with nothing outstanding. That is deliberate: skipping a rotation costs nothing, but silently skipping the flats would report a successful night with no calibration frames in it, and you'd find out days later. - Removed: the Humidity Trigger and the Dew-Point Margin Trigger, and the "Use the threshold from my NightFront config rule" switch that went with them. The matching Humidity and Dew-Point Margin filter-preference rules are gone from the desktop app in the same release. - Why: both were being used as stand-ins for how transparent the sky is, and they cannot be. Your hygrometer and dew-point sensor are at the mount, measuring the air around them. Transparency is a property of the whole column of atmosphere your light travelled through. A damp valley floor under a flawless sky, and dry air under high cirrus, are both ordinary nights — and neither reading tells them apart. Setting your own threshold doesn't fix that; it just means the rule fires exactly as configured, on a number that isn't about the thing you wanted. - The Wind Speed Trigger is unaffected and works exactly as before. It never went through a config rule — it picks one of your own exposure variants — so nothing about it was tied to the removed machinery. - Your existing config still opens. A saved Humidity or Dew-Point Margin rule is dropped quietly on load; everything else in the file is untouched. (Without that, one leftover rule would have stopped the whole config from loading.) A saved *sequence* containing one of the removed triggers will show it as an unknown instruction — delete it from the sequence. - Dew point, temperature and humidity are still read and recorded from your weather device, as they always were for wind, pressure and sky quality. They just no longer steer the plan. - No other C# changed for the removals above, but the nightfront-cli.exe deployed alongside this plugin did, so Replan and Nightly Update's own planning no longer act on humidity or dew-point rules even if an older config still lists them. NightFront NINA Plugin 1.13.0.0 - New: choose which plan you get — Options tab → "Plan Selection". NightFront doesn't solve for one schedule, it solves for a whole range of them trading time on sensor against image quality, and it has always picked the knee of that curve for you. Now you can ask for an end of it instead: - Balanced (the default, and what every previous release did) — the knee: the plan whose weaker side is as strong as it can be. - Max Quality — the best-quality end. Fewer hours, better placed. Worth it when you're collecting the frames you actually intend to keep. - Max Utilization — the most sky time used, accepting some of it at worse airmass. Worth it when a target is running out of season and any usable minute beats an idle one. - Applies to both Nightly Update's own planning and Replan, deliberately — a replan that chased a different tradeoff than the plan it replaced would change what your night is optimizing for, halfway through, with nothing telling you. - ⚠️ If you exported a plan from the desktop app and clicked a point on its Pareto chart, that saved choice still wins under Balanced — and is deliberately overridden by Max Quality or Max Utilization. Picking an end of the curve here is you saying what you want tonight; the saved one is a point you clicked on some earlier night's curve. If you want your exported choice back, set this to Balanced. - Aligns with NightFront app v1.13.0. Both this plugin and the nightfront-cli.exe deployed alongside it changed: the CLI gained a --plan-selection flag, and the plugin gained the setting that drives it. Nothing about how a plan is *executed* changed. - Existing sequences are unaffected. Leave the dropdown alone and the CLI receives exactly the arguments it always has, byte for byte — the flag is omitted entirely for Balanced. NightFront NINA Plugin 1.12.0.0 - New: Dew-Point Margin trigger. Watches the gap between temperature and dew point — how many degrees the air still has to cool before dew forms — and runs one instruction block when it closes to your threshold and another when it opens back up. It's the better damp-air reading of the two: 90% humidity at 20°C and 90% at 2°C are the same number and very different nights. - ⚠️ It runs the opposite way round from the Humidity trigger, and the blocks do not swap to match. A *small* margin is the bad case, so here the lower block is the one that responds to worsening conditions. Copy your humidity wiring across unchanged and you get a trigger that acts on the driest nights of the season and never on the wettest. The block labels tell you which is which — read them rather than assuming. - Needs a weather device reporting both temperature and dew point. If either is missing the trigger does nothing at all, rather than inventing a margin and acting on it all night. - Defaults to 3°C, matching the desktop app's own Dew-Point Margin rule default. - New: keep a trigger and its config rule in step. The Humidity and Dew-Point Margin triggers decide *when* to replan; a matching rule in your NightFront config decides *what changes*. When those two numbers disagree, a crossing replans the night and changes nothing — and nothing tells you. Two things now address that: - "Use the threshold from my NightFront config rule" — tick it and the trigger reads its threshold straight from the rule, so they cannot drift. The threshold box goes read-only while it's on, because a number you can edit but that is quietly ignored is the problem, not the fix. A line underneath states the rule in plain terms, including which block it activates — which is what saves you from wiring dew-point margin backwards. ⚠️ It is off by default, including on triggers you have already saved. Turning it on automatically would move your trigger off the number you typed without telling you, which is the same class of silent surprise this feature exists to remove. The warnings below point you at it. - Warnings while you edit the sequence, not at 2am: your trigger fires at 70% but the rule applies at 85%; you have no matching rule at all, so a Replan here can only re-plan and change nothing; or your rules disagree about direction and no single threshold fits them. - The missing-rule warning only appears if a Replan is actually in one of the blocks — a trigger wired to a Ground Station notification needs no rule and isn't nagged about one. And if the config simply can't be found, nothing is reported: "couldn't look" is not "there's no rule." - ⚠️ Available for Humidity and Dew-Point Margin only. Their rule thresholds are stored in the same units the triggers read (%RH, whole °C). Seeing rules use an internal scale that is not the arcsec figure the Seeing Trigger reads, so there is nothing to sync there. Wind never reaches the optimizer at all — it only picks one of your exposure variants — so it has no rule to pair with. - Because rule thresholds are whole numbers, a synced trigger always sits on a whole unit. - Icons. The two target triggers now use a crosshair, Humidity and Dew-Point Margin a water droplet, the Seeing Trigger an eye, and the Wind Speed Trigger three wavy gusts — instead of all of them sharing the NightFront comet, which made the palette hard to scan. - "NightFront While Calibration Remains" is now "NightFront While Flats Remain" — it loops over outstanding *flat* requirements specifically. Existing sequences are unaffected: only the displayed name changed, so nothing needs re-adding. - Aligns with NightFront app v1.12.0. No CLI change this time — nightfront-cli.exe is unchanged in behaviour from 1.11.0.0, so Replan, Nightly Update and the optimizer all plan exactly as before. Everything above is plugin-side. NightFront NINA Plugin 1.11.0.0 - New: Wind Speed and Humidity triggers. Each watches one reading from your weather device and holds two instruction blocks — one that runs when the reading rises to your threshold, and one that runs when it drops back below. Both halves matter: a wind trigger that only fires going up would leave the rest of the night in short subframes even after the air settled. - Wind, as intended: a Replan naming a "High Wind" exposure variant above your threshold, and a Replan with that field blank below it. Your total integration is unchanged either way — the same sky time is just divided into more, shorter frames. - Humidity, as intended: a plain Replan on each side, plus a Humidity rule in your NightFront config saying what should change (typically preferring narrowband when it's damp). Replan hands NINA's live humidity reading to the optimizer; the rule decides what to do with it. ⚠️ Keep the two thresholds consistent — a trigger set at 70% against a rule written for 85% replans and then changes nothing at all, with no error to tell you. - If the condition stays across the threshold, the trigger fires again roughly every two hours, matching how long a live reading is trusted to override the forecast. It won't loop. - A disconnected weather device, or one that doesn't report the value, fires nothing. Missing data is not a low reading, and it would be a poor time to act on one. - ⚠️ Neither is a safety cutoff. NINA's safety monitor remains the only thing deciding whether it is safe to image at all. These triggers only run instructions you wrote. - ⚠️ Triggers are evaluated between sequence items. With 600s subs a crossing can go unnoticed for up to ten minutes, and no trigger can interrupt an exposure already running. That's how NINA works; no plugin can change it. - Aligns with NightFront app v1.11.0. No C# changed for this part, but the nightfront-cli.exe deployed alongside this plugin did, so Replan and Nightly Update's generate branch now: - understand two new rule types in your config — Humidity and Dew-Point Margin — and apply them to the live reading NINA captured. These do nothing when you plan on the desktop, because no weather forecast sells humidity; they exist to let you say, in your own units and for your own site, what a damp night should change. NightFront deliberately holds no built-in opinion about what a given humidity means. - score a rule that only applies to part of the night more fairly. Previously such a rule quietly docked every candidate schedule's quality score by roughly the same amount, which measured nothing and just compressed the scale. Your plans don't change unless a rule was already narrow — but quality figures for those sessions aren't comparable with older ones. - ⚠️ A config using a Humidity or Dew-Point Margin rule needs this plugin version or newer. An older nightfront-cli.exe cannot read those rules and will reject the whole config, not just the rule. They ship together, so this only bites if you've hand-copied an old CLI somewhere. - Fixed, and worth reading if you use the frame tally: every target was being recorded one frame short, every run. Not an occasional race — a systematic off-by-one. Found on the night of 2026-08-03: four OIII subs of Wolf-Rayet 134 were shot and saved, and the tally recorded three. NINA raises two notifications as an exposure ends, and the first one arrives while the exposure still reads as "running". NightFront acted on that one, wrote the count as it stood a moment before, and then — because it had just written — skipped the second notification, the one that actually said the frame was done. For every frame but the last, the next frame's notification corrected it. For the last frame of each target there is no next notification, so the tally stayed one short permanently. NightFront now acts only on the notifications that can actually change a count, and a suppressed one is always written out shortly afterwards instead of being dropped. Counts also never move backwards within a run, which they could when NINA re-entered the container and reset each instruction's state. What this means for you: any backlog accumulated before this version under-counts by one frame per target per plan, so a handful of subs may be re-shot. Reviewing a target clears its tally and resets it to the truth. - Fixed: the frame tally is now also written when the night simply ends. It was written whenever a Replan swapped the plan, and periodically while imaging — but a night that just ran to dawn could lose the last couple of minutes of counts. Barely visible at 600s subs; more so since 1.9.0 made short exposure variants a normal thing to use. - Fixed: the "After Target" trigger reported that it fired but never ran the instructions under it. A Ground Station send (or anything else) dropped into that trigger did nothing, every time, while the trigger's own status line said it had fired for the target that just finished. NINA gates a container's instructions on the loop conditions of *every* container above it, and the trigger ran its instructions under the target that had just ended — whose handoff time gate had, by that point, gone false. That's what ended the target in the first place, so the gate was false every time the trigger fired. The instructions now run under a stand-in for the target instead, which keeps $$TARGET_NAME$$/$$TARGET_RA$$/$$TARGET_DEC$$ resolving while leaving the finished target's own gate out of it. Gates above the target ("Loop while safe") still apply. "Before Target" was never visibly affected, but shared the same defect and is fixed by the same change. NightFront NINA Plugin 1.10.0.0 - Fixed: reviewing your subs now clears the plugin's tally properly. The plugin counts frames it shoots so it can keep working a backlog across several unattended nights (remaining = planned − accepted − collected). When you reviewed those frames and updated Accepted, it used to subtract only however many you accepted — so any sub you *rejected* stayed on the tally and went on suppressing that much demand forever. Reviewing a target now clears its tally outright, which is what "I've looked at all of these" actually means. On the worked example (120 planned, 60 accepted, 15 collected, then accepting 10 and rejecting 5) the backlog now comes out 50 rather than 45. - Fixed, and the important one: a review where you reject everything is now seen. Rejecting every collected sub leaves Accepted unchanged, so nothing told the plugin those frames had been adjudicated. The tally kept growing every cycle until the target's remaining demand reached zero — at which point NightFront drops the target, reports "nothing to plan", and the plugin empties the NightFront Container. NightFront now stamps each target with when it was last reviewed, and the plugin clears that target's tally for every night before the stamp. The stamp is written automatically by Import From AstroPM for every project it matched, whether or not any count changed, and by a new per-target Mark reviewed button on NightFront's Targets page for anyone who reviews outside AstroPM. Like any other edit, it reaches the plugin once you save the config. - Clearing is per target, never all-or-nothing. An AstroPM import covers whichever project files it finds, so M63 can be reviewed while LDN 234 is not — LDN 234's frames stay on the tally until you get to them. - Frames shot at an exposure variant now reconcile correctly. The tally stores seconds, but the old subtraction worked in frames, so accepting 10 frames against a night shot at 180s removed the wrong amount of sky time. Nothing is partially subtracted any more, so the mismatch cannot arise. - Frames from the night currently in progress are never cleared, so a mid-night Replan can't discard what it already shot. - Requires the NightFront desktop app 1.10.0 or later to write the review stamp. Older configs still work — they fall back to the "Accepted changed" trigger, exactly as before. NightFront NINA Plugin 1.9.0.0 - New: shorter subs when the wind picks up. You can now define named *exposure variants* in NightFront — say a "High Wind" variant shooting narrowband at 300s instead of 600s — and name one on the Replan instruction. Replan then plans the rest of the night in those sub lengths. Your total integration time is unchanged: the same sky time is simply divided into more, shorter frames, so a gust ruins less. Leave the field blank (the default) and nothing changes. - The intended setup is a wind trigger holding two Replan instructions: one above your threshold naming the variant, one below it left blank. - A name NightFront doesn't recognise is ignored with a warning rather than failing the replan. If you rename a variant in the app, the worst that happens is you don't get the shorter subs — you never lose the night. - ⚠️ This is not a wind cutoff. NINA's safety monitor remains the only thing deciding whether it's safe to image at all. A variant only picks which of *your own* exposure lengths gets used. - ⚠️ Triggers are evaluated between sequence items. With 600s subs, a wind trigger can't fire for up to 10 minutes and can never interrupt an exposure already running. That's how NINA works; no plugin can change it. - Aligns with NightFront app v1.9.0. Beyond the variant support above, the nightfront-cli.exe deployed alongside this plugin also changed, so Replan and Nightly Update's generate branch now: - report which night they actually planned, rather than echoing the night named in the config. These only disagreed in a case you could reach by hand (an explicit past night date combined with a multi-night horizon), never through the plugin — but a plan file and its result file naming different nights is worth ruling out outright. - schedule one last sub for a filter the frame ledger has left just short of complete, instead of stranding those final few minutes. Previously a filter with less than one exposure's worth of time remaining could never be scheduled *and* never counted as finished, so it sat there. Only reachable if you've been running 1.8.0's frame tracking. - New (optional, for the curious): the CLI can plan across several nights and write out what it decided for each one. Neither is used by this plugin — both default to off — and the measurements behind that decision are in the app's own design notes. Planning three nights instead of one turned out to change *tonight* not at all, while taking 2.5x as long, because the scheduler fills each night in order and can't take time back from tonight to spend on tomorrow. NightFront NINA Plugin 1.8.0.0 _Supersedes 1.7.0.0, which was prepared but never published — everything below is what changes if you are coming from 1.6.1._ - Nightly Update can now build tonight's plan itself. It still imports today's plan file when the configured folder has one; when there isn't one, it reads your Active targets and exposure plans straight from a NightFront config, folds in whatever live conditions NINA can see, runs the same optimizer, and loads the result into the NightFront Container. No pre-generated plan file needed, and one instruction to place either way — you don't have to decide in advance whether a plan will exist, which is exactly what you can't know when a desktop export is a few days old. Replan is unchanged and happily picks up from a plan generated this way. - New option: NightFront config (Options tab, with a Browse button). Point it at the .json your NightFront app saves. Leave it blank and it falls back to the session-config.json written by the app's Export. Worth setting: that export sidecar only exists if you ran the optimizer and exported — the very thing online planning saves you — and its accepted-subframe counts are frozen at export time. Nightly Update warns if the config it found is more than a week old. A "Clear" button restores the fallback. - "If generating, plan for up to N seconds" on the Nightly Update instruction (default 180s), saved with your sequence, so different sequences can use different budgets. It's a *wall-clock* budget rather than a search-size knob, which is what makes it safe to expose: it means the same thing on any hardware — a slower machine just searches less far in the same time — so there's no benchmarking to do. It applies only when a plan has to be generated, and is ignored when today's plan file is found. Replan keeps its existing Fast preset, since it interrupts a night already underway where every second costs imaging time. - NightFront now tracks the frames it captures, per target and filter, across nights. Until now every plan computed remaining = planned − accepted, and accepted only moves when you review frames in AstroPM and save the config — so between imaging a night and reviewing it, the next plan would re-schedule data already on disk *and report success*. The plugin now keeps its own ledger of what it actually shot and hands it to the optimizer, which subtracts it. Review as often or as rarely as you like; the plan stays honest in between. - Counts are reconciled against your config whenever a plan runs: accept 30 of 50 reviewed frames and the other 20 stay counted, rather than the whole record being discarded. - Tracked in *seconds*, not frame counts, so a night shot at a different sub length still subtracts the right amount of sky time. - Only nights before tonight are counted this way. Tonight's progress is still handled by Replan's existing progress snapshot, so a mid-night replan can never subtract the same frames twice. - If the ledger is ever the sole reason a night looks finished, it is discarded and the night is planned anyway. Reporting "nothing to plan" empties the container, and that is not something a counting bug should be able to cause. - Pointing the NightFront config option at a different project ignores the ledger rather than applying one project's counts to another's targets. - Known limitation, older configs only: a target that references an *exposure template* rather than listing its filters has no accepted count to reconcile against, so its collected frames reduce demand but can never be given back if you later reject frames at review. Opening and re-saving the config in NightFront fixes it permanently — that converts the template into per-filter Planned/Accepted rows, which is what the app writes anyway. A log line names any affected target. - Calibration metadata is now schema 5. Existing files upgrade in place; frame counting simply starts from tonight. - Fixes a Replan failure on night 2 of a multi-night export. NightFront exports several nights but only one session-config.json, carrying night 1's date — so on any later night Replan computed a window entirely in the past and failed outright, exactly when it was needed most during safety recovery. Both plan and replan now take the night from the site clock, using the config's own date only as a fallback. - Refuses to plan a window containing no astronomical darkness instead of scheduling exposures in daylight. Nothing downstream checked the Sun's altitude, so certain longitudes and high-latitude summers could produce a confident, fully-populated, useless plan. - Survives a lost internet connection: if the forecast can't be fetched, a stale cached one is used and reported as stale rather than the run failing. - Ordinary "nothing to do" outcomes — every target complete, no dark time left, no forecast at all — are reported as informational status instead of surfacing as an error that aborts the sequence. - Plan-file discovery hardened: the CLI's temporary output files carry the current date in their names and are deliberately left behind on failure, so they were valid candidates for "today's plan". They are now excluded, and the CLI child process is killed on cancellation as well as on timeout, so a stopped sequence can no longer leave one running. - Stops littering the data folder with …plan-tmp.json.result.json files. Only a run that actually loaded a plan cleaned up after itself, so every other outcome — all targets complete, no dark time, no forecast, a failed run, a stopped sequence — left its temporary files behind. Every path now cleans up, and the housekeeping pass sweeps up any left over from earlier builds (or from a crash) once the night that produced them is over. - Writes nightfront-status.json after each run: a flat summary of the conditions read and what the optimizer did with them. This is for inspection and external tooling — NINA's sequencer expressions have no file-reading function, so it is deliberately not described as an expression variable source. - Live conditions captured from NINA now include wind, gusts, humidity, temperature, dew point, pressure, sky quality, sky temperature, rain rate and safety state. These are recorded and reported only — they do not influence scheduling. Wind is the safety monitor's job, and sky quality mostly measures moonlight and light pollution rather than transparency, so feeding either into the optimizer would do more harm than good. - Adds the missing sequencer UI templates for Replan, which previously had none and rendered with NINA's default item chrome. - Much of the above needed no C# change at all, but the nightfront-cli.exe deployed alongside this plugin did change — so Replan now derives the night from the clock, tolerates a stale forecast, reports structured outcomes rather than inferring them from whether a file appeared, and subtracts frames already collected on previous nights. NightFront NINA Plugin 1.7.0.0 (never published — superseded by 1.8.0.0) - New instruction: "Generate Plan" — builds tonight's imaging plan *on the spot*, with no pre-generated plan file. It reads your Active targets and exposure plans straight from a NightFront config, folds in whatever live conditions NINA can see, runs the same optimizer, and loads the result into the NightFront Container. "Nightly Update" and "Replan" are unchanged and still work exactly as before; this is a third option, not a replacement, and Replan happily picks up from an online-generated plan. - New option: NightFront config (Options tab, with a Browse button). Point it at the .json your NightFront app saves. Leave it blank and Generate Plan falls back to the session-config.json written by the app's Export. It's worth setting: that export sidecar only exists if you ran the optimizer and exported — the very thing online planning is meant to save you — and its accepted-subframe counts are frozen at export time, so a stale copy will re-shoot data you already have. Generate Plan warns if the config it found is more than a week old. A "Clear" button restores the fallback. - "Plan for up to N seconds" is editable on the Generate Plan instruction itself (default 180s), and saved with your sequence, so different sequences can use different budgets. It's a *wall-clock* budget rather than a search-size knob, which is what makes it safe to expose: it means the same thing on any hardware — a slower machine just searches less far in the same time — so there's no benchmarking to do. Replan is untouched and keeps its existing Fast preset, since it interrupts a night already underway where every second costs imaging time. - Fixes a Replan failure on night 2 of a multi-night export. NightFront exports several nights but only one session-config.json, carrying night 1's date — so on any later night Replan computed a window entirely in the past and failed outright, exactly when it was needed most during safety recovery. Both plan and replan now take the night from the site clock, using the config's own date only as a fallback. - Refuses to plan a window containing no astronomical darkness instead of scheduling exposures in daylight. Nothing downstream checked the Sun's altitude, so certain longitudes and high-latitude summers could produce a confident, fully-populated, useless plan. - Survives a lost internet connection: if the forecast can't be fetched, a stale cached one is used and reported as stale rather than the run failing. Previously survivable for Replan (the existing plan stayed loaded) but fatal for online planning, which would have ended with an empty container. - Ordinary "nothing to do" outcomes — every target complete, no dark time left, no forecast at all — are now reported as informational status instead of surfacing as an error that aborts the sequence. - Plan-file discovery hardened: the CLI's temporary output files carry the current date in their names and are deliberately left behind on failure, so they were valid candidates for "today's plan". They are now excluded, and the CLI child process is killed on cancellation as well as on timeout, so a stopped sequence can no longer leave one running. - Generate Plan also performs the plan-history and calibration-metadata housekeeping that only Nightly Update did before, so an installation using Generate Plan *instead of* Nightly Update doesn't accumulate old files indefinitely. - Stops littering the data folder with …plan-tmp.json.result.json files. Only a run that actually loaded a plan cleaned up after itself, so every other outcome — all targets complete, no dark time, no forecast, a failed run, a stopped sequence — left its temporary files behind. Generate Plan's are undated, so nothing would ever have collected them. Both instructions now clean up on every path, and the housekeeping pass sweeps up any left over from earlier builds (or from a crash) once the night that produced them is over. - Writes nightfront-status.json after each run: a flat summary of the conditions read and what the optimizer did with them. This is for inspection and external tooling — NINA's sequencer expressions have no file-reading function, so it is deliberately not described as an expression variable source. - Live conditions captured from NINA now include wind, gusts, humidity, temperature, dew point, pressure, sky quality, sky temperature, rain rate and safety state. These are recorded and reported only — they do not influence scheduling. Wind is the safety monitor's job, and sky quality mostly measures moonlight and light pollution rather than transparency, so feeding either into the optimizer would do more harm than good. - Adds the missing sequencer UI templates for Replan, which previously had none and rendered with NINA's default item chrome. - Much of the above needed no C# change at all, but the nightfront-cli.exe deployed alongside this plugin did change — so Replan now derives the night from the clock, tolerates a stale forecast, and reports structured outcomes rather than inferring them from whether a file appeared. NightFront NINA Plugin 1.6.1.0 - Fixes calibration flats being shot out of the configured "Flat filter order." With the order set to L, B, G, R, OIII, Ha, SII, the night of 2026-07-29/30 shot 20 Ha flats before the 10 L flats — the order came out inverted rather than merely wrong. - Cause: NINA normalizes both requested and reported rotator mechanical positions into the profile's configured Rotator Range (Options → Equipment → Rotator: Full 360° / Half 180° / Quarter 90°), but every angle comparison in the calibration path was plain, non-wrapping arithmetic. Under the common Half setting one physical rotator position is recorded as ~0.01° on one night and ~179.95° on another — 0.06° apart physically, 179.94° apart arithmetically. "NightFront Rotate to Next Angle" correctly picked L at 179.95° and sent the rotator to 180°, which NINA moved to its Half-range equivalent of 0°; the flats instruction then read the position as ~0° and, preferring what's outstanding at the *current* angle, only considered requirements near 0° — which meant Ha, not L. - Every angle comparison now takes the shorter arc modulo the profile's rotator range span, so both sides of that range's wrap are recognized as one physical position. This restores the filter order and, because the same arithmetic drove deduplication, stops the calibration metadata accumulating a duplicate ~0°/~180° pair per filter (each of which was collecting its own set of flats). - Existing duplicate pairs already in calibration.metadata.json are left alone — they each get flats once more and then age out via "Flat refresh days" as usual. No manual cleanup is needed. - Also replaces the scoped selection's whole-degree *bucket* comparison with a symmetric ±1° tolerance (the same standard deduplication already used), so two angles a fraction of a degree apart can no longer land either side of a bucket edge and count as different positions. - nightfront-cli.exe is unchanged this release — Replan produces exactly the same plans as in 1.6.0; only the plugin's own calibration-flat sequencing changed. NightFront NINA Plugin 1.6.0.0 - Version-only bump to align with NightFront app v1.6.0, which renames the app's "Long-Range Planning" feature to "Seasonal Planning" throughout (nav tab, screens, and internals) to match the "From season to subframe" tagline. - No C# changed, and nightfront-cli.exe is unchanged in behavior this release — the rename touched no file on the CLI's call graph (ConfigLoader, GeneticScheduler, the decoder, the objectives, ParetoSelection are all byte-identical), so Replan produces exactly the same plans as in 1.5.2. - Seasonal planning is an app-side feature only; it has never been part of the plan files this plugin imports, so nothing about the import path, the sequence JSON, or the calibration metadata changes. NightFront NINA Plugin 1.5.2.0 - Nightly Update now cleans up old plan files. Each run deletes plan files, their .progress.json sidecars, and archived replan-history/ snapshots once they fall outside a retention window — the same once-per-night housekeeping slot that already prunes stale calibration requirements, so there's nothing new to place in your sequence. - New "Plan Retention Days" option (default 2). Set it to 0 to keep everything forever. The default keeps tonight's plan plus the previous night; older ones are removed. - Cleanup is conservative by construction: the live calibration.metadata.json, selection.json, and session-config.json are never touched, a file whose name carries no yyyy-MM-dd date is never deleted, and retention is a window rather than "anything before today" — a plan file's date is the night it was generated for, which doesn't roll over at local midnight, so a Nightly Update or Replan running at 01:00 must not treat the plan it's currently executing as yesterday's. - nightfront-cli.exe is unchanged this release — Replan produces exactly the same plans as in 1.5.1; only the plugin's own housekeeping changed. NightFront NINA Plugin 1.5.1.0 - Fixes targets being slewed to after their observing window had already passed — the failure seen after a long safety/weather hold, where on recovery every target in the plan was visited in sequence with a real slew/center, including targets long since set (one was slewed to at ~3° altitude). - Two parts, both shipped together: - C# (this plugin): the importer now imports each target DeepSkyObjectContainer's own loop Conditions. Previously only inner (sequential) containers' conditions were imported, so the per-target time gate — and the new altitude guard below — were silently dropped and the outer slew/center block ran unconditionally. It also now parses the AltitudeCondition node. - nightfront-cli.exe / the exported plan: each target container now carries an AltitudeCondition guard floored at the site's minimum altitude. NINA's core TimeCondition is date-less and rolls a past handoff time forward to its next occurrence, so after a multi-hour hold the time gate alone no longer skips a stale target; the altitude guard is genuinely false-on-entry for a target already set below the site minimum, so its slew is skipped. The guard uses NINA's AltitudeOffset field, so the same plan loads correctly both on a direct NINA sequence load and via Nightly Update / Replan. - The recommended primary recovery mechanism is unchanged: place the Replan instruction in your template's Once Safe branch so a hold recomputes a fresh remainder plan. The altitude guard is defense-in-depth that limits damage when a stale plan is executed anyway. NightFront NINA Plugin 1.5.0.0 - Aligns with NightFront app v1.5.0. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan runs faster this release — its genetic-algorithm fitness evaluation is now parallelized across the CPU's cores (via kEvolve's MTSimpleProblem) instead of being evaluated one candidate schedule at a time. On a multi-core imaging PC this shortens the replan solve noticeably. - The plan Replan produces is unchanged. Only the per-candidate fitness evaluation is threaded; breeding, elitism, and Pareto ranking stay single-threaded, so the algorithm's dynamics — and thus the schedule it converges on for a given config — are identical to 1.4.1. This is a speed change, not a scheduling change, and scores remain comparable to the previous release. NightFront NINA Plugin 1.4.1.0 - Aligns with NightFront app v1.4.1. No C# changed, but the nightfront-cli.exe deployed alongside this plugin did, so Replan picks a different plan this release in one specific case: when no selection.json sidecar exists (you have never picked a point on the Pareto chart for this config), Replan's automatic choice used to land on an extreme of the front - typically the plan with the most imaging time and the worst average airmass, or the reverse, depending on nothing more than iteration order. It now picks the balanced compromise: the plan whose *worse* of the two objectives is as good as possible. - If you HAVE chosen a point in the app and exported it, nothing changes - Replan still reproduces your recorded utilization-vs-quality tradeoff, exactly as before. NightFront NINA Plugin 1.4.0.0 - Aligns with NightFront app v1.4.0. No C# changed in this plugin, but - like 1.3.4.0 and unlike the version-only bumps - the nightfront-cli.exe deployed alongside it (what Replan shells out to) did, so Replan produces different schedules this release. Both of the scheduler's fitness objectives were reworked: - A filter with nothing left to shoot (Accepted >= Planned) no longer counts toward its target's feasible imaging window. Such a filter usually carries no moon-avoidance profile, so it stayed "feasible" long after the target's real filters were moon-blocked, manufacturing a window nothing could fill and pinning that target's score at zero for every candidate schedule. - Targets that cannot be imaged at all tonight - fully moon-blocked, or never high enough - are now excluded from the utilization average rather than averaged in as zero. No schedule can change whether they are feasible, so they only compressed the score's usable range. - The quality axis is now a convex blend of airmass and filter-preference satisfaction, bounded to 0-1. It was previously airmass multiplied by a preference boost, which could exceed 1 and let a preference rule that matches every hour act as a constant scale factor rather than something a schedule is actually rewarded for satisfying. Airmass still dominates; preferences nudge and break ties. - Scores are not comparable to previous releases. A schedule that reported utilization 0.33 before will report roughly 0.43 for the same plan, and quality now reads below 1 rather than above it. The numbers moved, not the underlying quality. - The desktop app also gained a per-filter, per-night feasibility diagnosis (which targets and filters can actually be imaged, and why not, on each forecast night). That is app-only - it does not affect the plan JSON this plugin imports. NightFront NINA Plugin 1.3.6.0 - Added "Before Target" and "After Target," two new sequence triggers that fire around each NightFront-planned target and run whatever instructions you drop into them - e.g. a Ground Station send announcing the target starting/finishing. "Before Target" fires just before a target's own slew/centering; "After Target" fires once it's done (completed, skipped, or failed), including after the very last target of the night. Both re-parent their action container onto the firing target for the duration of the run, so Ground Station's own $$TARGET_NAME$$/$$TARGET_RA$$/$$TARGET_DEC$$ tokens resolve correctly - previously impossible from outside the NightFront Container, since Ground Station only looks upward for a target and everything NightFront imports lives below the container. Place either on the NightFront Container itself or one of its ancestors (e.g. the same branch as "Loop while safe"), not a sibling branch such as "Once Safe" - Validate() now warns if it can't see any targets from where it's placed. - Aligns with NightFront app v1.3.6. The app change this release is GUI-only (the GA convergence charts on the nightly and long-range plan pages moved into a collapsed "Diagnostics" disclosure at the bottom of each page), so the nightfront-cli.exe Replan shells out to unchanged behavior. NightFront NINA Plugin 1.3.5.0 - Version-only bump to align with NightFront app v1.3.5. The app change this release is GUI-only (a moon-brightness bar added to the nightly-plan forecast display, plus code-review fixes to it), so neither this plugin's C# nor the nightfront-cli.exe Replan shells out to changed behavior. NightFront NINA Plugin 1.3.4.0 - Aligns with NightFront app v1.3.4. Like 1.3.1.0 - and unlike the version-only bumps below - no C# changed, but the nightfront-cli.exe deployed alongside this plugin (what Replan shells out to) did, so Replan behaves differently this release. - Replan is now much faster on typical imaging hardware. The "Replan Effort Level" option (Fast/Balanced/Thorough) used to map to the desktop app's full GA effort presets - the same compute budget used to plan a whole multi-night roadmap. A replan only re-solves the remainder of one night, so those budgets were far larger than needed. The CLI now resolves these same three names against a dedicated, much smaller replan preset family: the default "Fast" drops from pop 100 / gen 200 to pop 60 / gen 50 (roughly a 2-second solve on a modest overnight PC), and even "Thorough" is now smaller than the old "Fast." If you'd picked Balanced or Thorough, you get the new replan-scaled tier with no plugin edit. - Fixed Replan being able to schedule Planned (roadmap) targets into tonight's plan. The session-config.json the app exports carries your whole roadmap, Planned targets included, and those default to enabled - so the CLI's replan path was considering them as candidates even though the desktop app's nightly plan correctly excludes anything not marked Active. Replan now filters to enabled Active targets only, matching the nightly plan. NightFront NINA Plugin 1.3.3.0 - Version-only bump to align with NightFront app v1.3.3 (a re-sweep of the desktop app's GA effort-preset values after the to-do #6/#7 changes, entirely on the app side). No plugin-side functional change this release - in particular, this did not touch the separate, smaller replan effort presets that Replan uses. NightFront NINA Plugin 1.3.2.0 - Version-only bump to align with NightFront app v1.3.2 (Planned/Accepted/Remaining sub-frame tracking, completion-% influence on scheduling, AstroPM import fixes, and assorted GUI changes, entirely on the app side). No plugin-side functional change this release. NightFront NINA Plugin 1.3.1.0 - Aligns with NightFront app v1.3.1. Unlike the version-only bumps below, this one does change plugin behavior, even though no C# changed: the nightfront-cli.exe deployed alongside this plugin is what Replan shells out to, and its Astrospheric usage was cut substantially. - Replan is much cheaper to run repeatedly. Every Replan used to buy its own full Astrospheric forecast (80 API credits), because each run is a separate process with nothing shared between them - so a night that flapped unsafe/safe repeatedly paid for the same forecast over and over, unattended. The CLI now costs 65 credits (it no longer requests wind data, which nothing used) and caches each site's forecast on disk for 6 hours, matching how often Astrospheric refreshes the underlying model. In practice the first fetch of the night is the only one that costs anything, and every later Replan reuses it. - This does not make Replan work off stale weather. The live cloud-cover reading this instruction already sends from your weather driver (and the seeing value from a Seeing Trigger, if you have one) still overrides the forecast for the hours around the replan - which is the window Replan actually schedules into. Only the further-out hours come from the cached forecast. - Worth knowing if you were watching your credit balance: the NightFront app had long documented a "100 credits/day" cap. That figure is from Astrospheric's v1 API and never applied - the app has only ever called v2, which allows ~29,900 per month and refreshes on the 1st of the month, not daily. A verified live call reads the true remaining balance into the CLI log. NightFront NINA Plugin 1.3.0.0 - Aligns with NightFront app v1.3.0, which puts pressure on completing Active targets in Long Range Planning (a new "Planned Target Weight" control, entirely on the app side). Unlike the recent version-only bumps below, this release also carries the two plugin-side fixes here. - Fixed CenterAfterDriftTrigger centering on RA 0/Dec 0 for the whole night when placed outside the NightFront Container (the production template's own layout, on "Loop while safe") - NINA's built-in coordinate inheritance only looks upward from the trigger's own position and never finds a target nested below the container. A new NightFrontCenterAfterDriftCoordinator now actively pushes each target's live coordinates into any such trigger the moment NINA starts running it, mirroring how tcpalmer/nina.plugin.targetscheduler solves the same problem for its own container. - Fixed Replan naming its output with the current calendar date instead of the date of the plan it's replacing, when run after local midnight. NightFrontApp routinely exports several nights' plan files at once, so a date-based folder lookup for "today's plan" doesn't just fail after midnight - it can wrongly match a *later* night's already-exported file, since that file's date now matches "today" just as validly. NightFrontContainer now remembers the exact file name (SourcePlanFileName) it was actually populated from at import/replan time, and Replan uses that directly instead of re-deriving it from the folder, so its output (and the progress-snapshot/replan-history names derived from it) always matches the plan it's actually replacing, keeping that same name across every replan of the same night. NightFront NINA Plugin 1.2.1.0 - Version-only bump to align with NightFront app v1.2.1 (Long Range Planning effort-preset values differentiated from a real sweep, entirely on the app side). No plugin-side functional change this release. NightFront NINA Plugin 1.2.0.0 - Version-only bump to align with NightFront app v1.2.0 (nav-rail consolidation, long-range plan Gantt visualization, and an Active-before-Planned water-filling fix, entirely on the app side). No plugin-side functional change this release. NightFront NINA Plugin 1.1.2.0 - Version-only bump to align with NightFront app v1.1.2 (which adds AstroPM target/exposure-plan import, entirely on the app side) so the plugin/app version numbers signal compatibility. No plugin-side functional change this release. NightFront NINA Plugin 1.1.1.0 - Added "Seeing Trigger," a new sequence trigger: periodically samples a real-time seeing-monitor data source (e.g. an Alcor "Current Condition" telemetry page, OCR'd via Tesseract) and, only on the transition to a user-configured FWHM threshold, runs whatever instructions you drop into its own action container - independent of NightFront's own plan-execution machinery, so dropping a Replan instruction inside gets seeing-triggered replanning for free. Re-arms after 2 hours (the same live-data horizon a replan trusts a reading for) if the condition stays continuously true, so a persistent good/bad spell produces a fresh replan periodically rather than firing only once. A new "Seeing Data Source URL" plugin option configures the default data source (overridable per-trigger). - Replan now blends a live seeing reading into the forecast the same way it already blends live cloud cover: if a Seeing Trigger elsewhere in the sequence has a fresh sample, its FWHM reading is included alongside cloud cover in the live-conditions override handed to the NightFront CLI. - Fixed NightFront While Same Rotation stopping early and skipping a still-outstanding, lower-filter-order-ranked calibration requirement genuinely at the current rotation angle, in favor of a higher-ranked filter sitting at a completely different angle. Confirmed against a real production metadata file (an "L" and "B" requirement within 0.05deg of each other; a second, unrelated "L" requirement ~45deg away jumped the queue ahead of "B" once the first "L" completed). NightFront Sky Flats/Trained Flats now also prefer whatever's outstanding at the rotator's current physical angle before falling back to the globally-next-best entry. NightFront NINA Plugin 1.1.0.0 - Added "Replan After Safety Recovery," a new sequence instruction for unattended recovery from a safety-monitor interruption: place it inside your sequence's own "Once Safe" recovery branch and it reads tonight's live progress and current weather, spawns the NightFront CLI to re-solve the remainder of the night, and repopulates the NightFront Container with the fresh plan before your sequence's native recovery logic restarts execution - so already-completed targets aren't silently re-shot after every interruption. Two new plugin options support it: "Replan Effort Level" (Fast/Balanced/Thorough GA compute budget, defaulting to Fast since most imaging PCs run overnight on modest hardware) and "NightFront CLI Path" (where to find/launch the NightFront CLI - note there's no packaged NightFront CLI executable yet, so this must point at a user-provided wrapper script for now). Requires an updated NightFront app that also exports the new session-config.json/selection.json sidecars this instruction depends on. - The previous plan file is now archived to a timestamped copy in a replan-history subfolder before each replan overwrites it, so it stays available for later comparison instead of being silently lost. - Fixed calibration metadata (measured rotation angle + filter/gain/offset) being recorded as soon as a target's CenterAndRotate finished, before any of its light exposures had actually completed. It's now recorded per filter, right after that filter's own exposure(s) finish - so a target whose sequence stops partway through its filter list still gets correct metadata for whichever filters actually completed, and never records a filter that hasn't been shot yet. - Replaced the separate archived.metadata.json file with completion tracking in the single live metadata file: every calibration requirement now carries a DateAdded and a FlatsCompletedDate (null until a Sky/Trained Flats instruction completes it). NightFront While Same Rotation/While Calibration Remains and the flats instructions all skip completed entries. A new "Flat Refresh Days" plugin option prunes completed entries older than that many days, so a stale one is naturally recreated (and reshot) the next time its target/filter/rotation combination is encountered. - Added a "Flat Filter Order" plugin option (comma-separated filter names, e.g. L, B, G, R, OIII, Ha, SII) that determines the order Sky Flats, Trained Flats, and their loop conditions claim outstanding calibration requirements in, regardless of the order they were recorded in - useful since twilight sky flats often need specific filters shot while the sky is a particular brightness. NightFront NINA Plugin 1.0.5.0 - Fixed NightFront While Same Rotation and While Calibration Remains showing up with no icon or name in the sequencer's Loop Conditions list - their templates were missing the SequenceBlockView wrapper that draws that chrome, unlike every other item/condition. Added their mini-sequencer templates too. - NightFront Sky Flats and NightFront Trained Flats now expose their actual editable fields (min/max exposure, histogram mean target/tolerance, dither, amount for Sky Flats; amount for Trained Flats) in the sequencer - previously only the metadata file name was shown, with no way to configure them. - Bumped the plugin's version numbering to align with the NightFront app's own version scheme. NightFront NINA Plugin 1.0.0.8 - Removed the example FITS-keyword/image-pattern demo left over from the plugin template. It was injecting placeholder STRKEYWD/INTKEYWD/DBLKEYWD header values and a $$EXAMPLEPATTERN$$ file pattern option into every saved image; none of it was NightFront behavior. - Removed dead Entity Framework/SQLite configuration from app.config carried over from the template; NightFront has no such dependency. - Fixed a stale MyPlugin.Properties namespace left in Properties/Settings.Settings (the generated Settings.Designer.cs was already JeffRidder.NINA.Nightfront.Properties) and cleaned up leftover template comments. NightFront NINA Plugin 1.0.0.7 - Removed the fake random-data weather device/provider left over from the plugin template. It was unrelated to NightFront's plan-import feature. NightFront NINA Plugin 1.0.0.6 - Removed the altitude-chart imaging-tab panel left over from the plugin template. It was unrelated to NightFront's plan-import feature. NightFront NINA Plugin 1.0.0.5 - Fixed NightFront Container turning into an "Unknown Instruction" placeholder after saving and reopening a sequence. It was only MEF-exported as an ISequenceItem, so NINA's own sequence-container deserializer (which resolves containers from a separate ISequenceContainer export list, e.g. DeepSkyObjectContainer) could never find it. Now exported as both. NightFront NINA Plugin 1.0.0.4 - Nightly Update no longer requires the NightFront Container to be its immediate sibling. It now scans forward through its later siblings and their descendant containers, so the Container can be nested several levels deep - e.g. inside a container that loops repeatedly until dawn, while Update itself runs once near the top of the night's sequence. NightFront NINA Plugin 1.0.0.3 - Removed the vestigial "Default Notification Message" and "Profile Specific Notification Message" options left over from the plugin template. - Removed the remaining misplaced color icon from the NightFront Container block; the sequencer's own chrome already shows the icon and name. - Set the plugin list's featured icon to the NightFront app icon. - The .metadata.json calibration file now records each target's *measured* rotator position (read from the rotator right after that target's slew/center/rotate finishes) instead of the plan's input Sky PA, and dedupes filter/rotation-angle pairs within 1 degree of each other. NightFront NINA Plugin 1.0.0.2 - Renamed "NightFront Update" to "Nightly Update" and changed it to run as a sibling immediately before the NightFront Container it populates, instead of as a child inside it. Existing sequences will need the instruction moved out of the container. - Nightly Update now shows a live status indicator (success/failure and message) in the sequencer. - Fixed the sequencer palette icon, which previously rendered as the literal text "Te" instead of the NightFront mark. - NightFront Container now shows a live per-target summary (name, coordinates, rotation, scheduled time window, and sub-frame progress) instead of just an instruction count. - Nightly Update now writes a .metadata.json file alongside the imported plan, recording the filters and rotation angles used, for future calibration-frame tooling. NightFront NINA Plugin 1.0.0.1 - Initial release