Note, however, that is one of the purposes of the deviceStartComm() and deviceStopComm() hooks. They get called when: the database first loads, devices are enabled or disabled, devices are added, devices are deleted, and device properties change. The latter occurs when OKing out of the main Device dialog. So those are really the hooks that should be used for opening hardware or network communication.
This is a very clean story. I like it a lot. However, in reality...
Take a GC-100 for which the user asked to use device 2:2 as an IR emitter. I've got to find it, connect to it, and read its configuration to see if there is such a device and whether it's configured right. If I want to present pop-up menus for choices, I need to completely enumerate the device. At that point, we've done all of the heavy lifting and got a perfectly good new network/device configuration running. I just need to hand that over to the device object...
if the user actually clicked that Ok button all the way through.
(Note that I can't just do this ConfigUI gig without looking at the existing device. Connecting to a GC-100
again resets its previous connection, so I
must look for an existing device connection and use that for the ConfigUI work.)
So endDeviceConfigUi can take the new access object and stash it somewhere out of sight until the comm callback tells me that the change actually went through, at which point I can apply it to the device. But ConfigUI and device don't (always) share identifiers, so I need that hidden-field trick of yours to generate one.
And I need to come up with some way to clean up that stashed access object if the user changed their mind and clicked the outer Cancel button, because there's no comms-didn't-change-after-all notification.
The cleanest solution, for now, is to spin up the device in ConfigUI, validate with it, then spin it down completely at endDeviceConfigUi no matter the outcome. And then spin it back up from scratch in the comms layer. (After making sure we've given it enough time to settle. GC-IRx seems to have undocumented "you're too fast for me" behavior, as does much cheap-ish hardware.)
The message I'm trying to get through to you is this: keeping the ConfigUI layer is separate and distinct from the device-lifecycle layer is neat and clean and good, but it's a bit impractical. ConfigUI needs to deal with device state (often creating tentatively-changed configuration data and device state), and needs the ability to "leave" Python data to be picked up by comm layer mutations, and some way to throw that left-over state out when the user hits the outer Cancel.
This isn't a show-stopper issue. We can get by. But it's
painful and brittle, so I'm letting you know.
Cheers
-- perry