Thanks so much for all the pointers @jnecr . It appears they’re both dead ends, which is at least conclusive.
-
setCarsOffSet()is just a field setter (this.carsOffSet = val), no DM write. The field is a carousel slot-index offset: it’s added to the requested slot to compute shovelslot, which is then written as WR DM0 . It only remaps slot numbering for the dual-carousel (10/20-slot) geometry and gets reset to 0 at the top of every load/unload, so it’s a slot count, not a travel reference. No transfer/carriage variant of it exists. -
CassetteConfTable turned out to be an immutable holder with exactly four fields, Id, Levels, Z-Pitch, BCZ-Pitch, loaded from an XML device config ( blocks), not JSON as I’d guessed. WriteZPitch just pushes Z-Pitch → WR DM23 and BCZ-Pitch → WR DM27, i.e. the carousel’s vertical geometry. No transfer-station or slide-stroke entry anywhere in it. And DM25 (shelf count) is read-only from the host (RD DM25), nothing writes it, same for DM29 (max slot) and DM46 (carousel position), so the firmware owns all of those.
So both leads close off the same way: the carousel exposes its geometry over serial, but the slide stroke isn’t stored anywhere the serial interface or the config files can reach — it’s baked into the .cod. That puts us back on the firmware-reconfig path. We will probably do the same as how @ben solved it with a Raspberry Pi with full control.