[Nut-upsdev] Re: Serial Ports (Was Re: Common Power Management : NUT and HAL (stage 1))

David Zeuthen david at fubar.dk
Thu Sep 7 16:26:38 UTC 2006


Hi,

Sorry for the lag, I was on vacation,

On Thu, 2006-08-31 at 13:47 +0200, Arnaud Quette wrote:
> >     This is easy to provide for e.g. NUT, it simply includes a HAL FDI
> >     file that looks somewhat like this
> >
> >                 <deviceinfo version="0.2">
> >                   <device>
> >                     <match key="legacy_port.type" string="serial">
> >                       <append key="legacy_port.probers.type"         type="strlist">nut-serial-ups</append>
> >                       <append key="legacy_port.probers.capabilities" type="strlist">battery.ups</append>
> >                       <append key="legacy_port.probers.programs"     type="strlist">nut-hal-serial-prober</append>
> >                     </match>
> >                   </device>
> >                 </deviceinfo>
> 
> there is a big problem here:
> NUT can't provide a generic serial prober since there are far too many
> protocols, and issuing some wrong protocol commands might have bad
> effect on wrong UPS.

Good point. It might not even be a UPS; it might be a modem or something
else that one of the probers touch. Something I forgot, need to be very
careful here. It's fixable though.


> so the only thing we (NUT) can do is to provide a list in which the
> user will pick his mfr/model, and then launch the right driver in
> probe mode to see if the device is there.

Right, ok, so we introduce a new infrastructure to have each prober
return a list of device id's, e.g. the NUT serial prober would return

   "Ablerex MS-RT",
   "AEC MiniGuard UPS 700 Megatec M2501 cable",
   "APC Back-UPS RS 500 custom non-USB cable",
   ...

which are strings that can be presented to the user (pretty sure we just
want to ditch i18n here). It's important to note that these device id's
are completely opaque to HAL itself though they will appear in end-user
UI.


> Note that this probe mode is not yet implemented, though it can be
> easily done. It's simply a "-p" flag that cause the driver to exit
> after the driver discovery function (upsdrv_initinfo()), printing out
> mfr/model info or some magic if nothing was detected...
> 
> >  3. With the legacy_port.* properties we can now provide a sane UI
> >     (both API and UI-wise) to provide probing for serial devices. Said
> >     configuration programs would look at legacy_port.probers.
> >     capabilities which contains well-defined HAL capabilities that can
> >     be translated into the users language. So in addition to the
> >     legacy_port capability we'd export an interface with methods called
> >
> >      org.freedesktop.Hal.Device.LegacyPort
> >
> >     with methods
> >
> >      UnconfigurePort()
> >
> >    to simply unconfigure a port and,

We'd want a new method here

 GetSupportedDevices (IN int proberNumber, OUT string[] deviceIds)

that returns the list of device id's. Note that we could use HAL device
properties to carry this information but it would be a lot of
information and it's not something one needs in .fdi files to match on
so retrieving through a method call is fine I suppose.

Implementation-wise this just call the prober program with the option
--get-list-of-supported-device-id or something and the prober program
prints these to stdout, one line at a time.

> >
> >      ConfigurePort (IN int proberNumber)
> >        throws AlreadConfiguredException,
> >               NoSuchProberException,
> >               ProberDidNotFindDeviceException
> >

Now, this method would be

       ConfigurePort (IN int proberNumber, IN string deviceId)

where deviceId is an item from GetSupportedDevices().

> >     where the latter method, ConfigurePort, will try to run the
> >     requested prober. If that fails (e.g. return code is != 0) then
> >     this exception is thrown. If it succeeds, then the properties
> >     legacy_port.is_configured and legacy_port.configured_type
> >     is set accordingly.

<snip>

> >  4. To preserve the value of the properties
> >
> >      legacy_port.is_configured,
> >      legacy_port.configured_type
> >
> >     across HAL restarts, the ConfigurePort() method simply saves
> >     the values somewhere in /var/run/hald/blah and we have a callout
> >     on the device object pick them up. The file name chosen to save
> >     it under will include system.product and system.product from the
> >     /o/fd/Hal/d/computer object to satisfy requirement f) above.

We also want legacy_port.configured_device_id so we remember this.

> you will have an MGE unit soon, with both USB and serial connection ;-)

Sounds good, saw that, thanks!

> one more important thought:
> nut drivers generally need some more config param. Ie some generic
> drivers (like genericups, a generic dry contact UPS driver) need a
> mandatory upstype to know which serial pin match which UPS signal (ie
> DCD = low battery).

Can't this be solved by just have a lot of generic entries in the device
id list, e.g.

 "Generic UPS (DCD = low battery)"
 "Generic UPS (DST = low battery)"
 ...

and so on? That way, we'll only have to poke the user for one option,
namely the device id.

> we have 2 choices here:
> 
> 1) rely upon the nut config files to define detailed options.
> 
> - the below things are based on the new NUT config format and tools,
> not yet available in the trunk, but from the JD-NewConf branch and
> scheduled for nut 2.2
> - the config is in the form:
> mode = "pm"
> ups.myups (
>         driver.name = genericups
>         driver.parameter.port = /dev/ttyS0
>         driver.parameter.upstype = 1
> )
> 
> - it only requires the ups section name ("myups" here) on the HAL
> side, then the nut driver will take care of finding its info to run.
> Ie
> - the HAL config is in the form:
>        <deviceinfo version="0.2">
>          <device>
>            <match key="legacy_port.configured_type" contains="nut-serial-ups">
>              <append key="info.addons"
> type="strlist">hald-addon-genericups</append>
>              <append key="info.addons.ups-name" type="int">myups</append>
>            </match>
>          </device>
>        </deviceinfo>
> 
> - the addon has to be called using "addon-name -a ups-name"

With this proposal it would simply just read

 legacy_port.configured_device_id

which is exported in the environment too.

> - the NUT compat list (drivers.list) include the mandatory parameters
> for the exact model, if any or none otherwise.
> ie the right upstype for genericups:
> "mfr"	"model"		""	"genericups upstype=1"
> 
> - NUT provides libupsconfig to configure things easilly (ie
> configuring in pm-Power Management mode for a serial unit is few lines
> of code):
> > new_config();
> > set_mode("pm");
> > add_ups("myups", "genericups", "/dev/ttyS0");
> > set_driver_parameter("upstype", "1", string_type);
> > save_config(destination, comments_template, 1, error_handler);
> 
> -everything has been prepared by Jonathan Dion, during his internship
> at MGE (ending today), to deal with such a case,
> - this leaves all the UPS specifics outside of HAL, and is IMO the
> best approach, though it has to be generic (ie gpsd must also have the
> same approach?). This is also the simplest approach for the nut
> driver, since the same config code is used.
> 
> 
> 2) Store things in the HAL file, ie:
> 
> - the hal config is in the form:
>        <deviceinfo version="0.2">
>          <device>
>            <match key="legacy_port.configured_type" contains="nut-serial-ups">
>              <append key="info.addons"
> type="strlist">hald-addon-genericups</append>
>              <append key="info.addons.upstype" type="int">1</append>
>            </match>
>          </device>
>        </deviceinfo>
> 
> - that implies g-p-m (or other apps) will manages that format
> - it has the advantage to centralise config things, but the
> disadvantage to need some specific code in the nut drivers to read
> this, though is simply some hal_get queries.

I'd like the interface between serial probers and HAL to be as simple as
possible so doing 1) would be preferable. So, to recap, from the HAL
point of view, the serial prober needs to perform two functions.

 1) give a list of supported device id's

 2) given a device id, look if a device is on the port

For 2), we can assume that the user have been instructed that he should
only push the "probe for device" button in the UI if he is certain the
device is supported. Ie. that it's a dangerous operation.

How does this sound?

Cheers,
David





More information about the Nut-upsdev mailing list