Getting battery status (and other system information)

G

Guest

I'm developing an app in C# that needs to display battery status. I'm using
the 2.0 .Net with the WindowsMobile assemblies. I've followed the various
suggestions in the help files and been able to successfully compile and run,
but the data being returned is garbage. I also get garbage when I try a
couple other system calls, such as battery state. The device is an HP iPAQ
2495. I'm assuming the managed code makes some assumptions about the hardware
map of the WindowsCE 5.0 system. Has anybody made this work on an HP? I
haven't gone down the path of using the HP SDK and unmanaged code, but that's
my next step.
 
P

Peter Foot [MVP]

The Microsoft.WindowsMobile.Status.SystemState.Power* properties should be
supported on all WM5.0 devices. Can you show a snippet of the code you are
using and what values you are seeing returned?

Peter
 
G

Guest

Peter,
sorry I have responded -- I've been finishing another project. I've pasted
in the relevant lines:
this line is part of the field declaration at the top of Form1:
SystemState BattState = new SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents call in the
constructor:
BattState.Changed += new ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests that it never
gets called. But I'm assuming that BattState.CurrentValue should return
whatever the current value is on initialization. In the emulator it returns
"1". When it's run on the iPAQ, it returns a five digit number that seems
random.
 
G

Guest

Peter,
now that I've had a chance to study this, it appears that when there is no
power (that is the battery is discharged), the system returns "2". if it's
charged close to 100%, it returns "53084".
 
R

Robert Levy [MS]

Correct. You can use the Microsoft.WindowsMobile.Status.BatteryLevel enum
to make sense of these values.

Something like this:
pcBattTB.Text = ((BatteryLevel)BattState.CurrentValue).ToString();
 
G

Guest

thanks for the reply. I tried the cast and I'm still getting the same result.
if I look in the debugger, the hex value being returned is 0x00510000, which
correctly converts to 5308416. Since the documentation seems to imply that
the method should return a percentage value, I wonder if the enum is working
right. On the other hand, even when the percentage of battery available
changes on the front screen (ie 100% to 95%), the method returns the same
0x00510000. I also tried the property for battery level (ie charging, etc),
and still get the 00510000 hex value.
 
G

Guest

The way these SystemState properties appear to work is they are just querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main" value. The
value in the registry is actually an aggregate of these two values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a bug
in the way SystemState.CurrentValue is computed. Using SystemState, we can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris
 
G

Guest

Chris,
thanks. I've tracked down most of this, mostly by trial and error. I think
the root cause is the documentation in the DotNet CF 2.0 for the batt state
property. What i was looking for was the actual percentage value, as the
documentation states. What i was getting back, after sorting through the hex
values, was the values that match the enum states ("low, medium, high, very
high"). Although this is useful, it's not what i wanted. I finally fixed it
all by wrapping a coredll.dll call for battery state. From this call i get an
int 32 value back (as part of the battery struct) that matches the battery
display on the unit.

So either there's a bug in the DotNet code or the documentation is wrong
(which is still a bug).

Jim


--
Jim Coburn


CLC said:
The way these SystemState properties appear to work is they are just querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main" value. The
value in the registry is actually an aggregate of these two values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a bug
in the way SystemState.CurrentValue is computed. Using SystemState, we can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

Jim said:
thanks for the reply. I tried the cast and I'm still getting the same result.
if I look in the debugger, the hex value being returned is 0x00510000, which
correctly converts to 5308416. Since the documentation seems to imply that
the method should return a percentage value, I wonder if the enum is working
right. On the other hand, even when the percentage of battery available
changes on the front screen (ie 100% to 95%), the method returns the same
0x00510000. I also tried the property for battery level (ie charging, etc),
and still get the 00510000 hex value.
 
R

Robert Levy [MS]

The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

Yup. SystemState is essentially a wrapper around the notification &
quick-queryting APIs in regext.h that makes it easy to use the registry keys
defined in snapi.h.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main" value.
The
value in the registry is actually an aggregate of these two values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState, we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved
from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

Jim said:
thanks for the reply. I tried the cast and I'm still getting the same
result.
if I look in the debugger, the hex value being returned is 0x00510000,
which
correctly converts to 5308416. Since the documentation seems to imply
that
the method should return a percentage value, I wonder if the enum is
working
right. On the other hand, even when the percentage of battery available
changes on the front screen (ie 100% to 95%), the method returns the same
0x00510000. I also tried the property for battery level (ie charging,
etc),
and still get the 00510000 hex value.
 
R

Robert Levy [MS]

Whenever using CurrentValue, you have to cast it from Object to whatever it
is really supposed to be (in this case, an enum). We use an enum rather
than raw percentage because raw percentage changes all the time and these
APIs are really not meant to be used in cases like that (like building a
battery meter type app). The intention is that the enum can be used to get
notified of particularly significant state changes and throttle app behavior
accordingly.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


Jim said:
Chris,
thanks. I've tracked down most of this, mostly by trial and error. I think
the root cause is the documentation in the DotNet CF 2.0 for the batt
state
property. What i was looking for was the actual percentage value, as the
documentation states. What i was getting back, after sorting through the
hex
values, was the values that match the enum states ("low, medium, high,
very
high"). Although this is useful, it's not what i wanted. I finally fixed
it
all by wrapping a coredll.dll call for battery state. From this call i get
an
int 32 value back (as part of the battery struct) that matches the battery
display on the unit.

So either there's a bug in the DotNet code or the documentation is wrong
(which is still a bug).

Jim


--
Jim Coburn


CLC said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main" value.
The
value in the registry is actually an aggregate of these two values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState, we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved
from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and
just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

Jim said:
thanks for the reply. I tried the cast and I'm still getting the same
result.
if I look in the debugger, the hex value being returned is 0x00510000,
which
correctly converts to 5308416. Since the documentation seems to imply
that
the method should return a percentage value, I wonder if the enum is
working
right. On the other hand, even when the percentage of battery available
changes on the front screen (ie 100% to 95%), the method returns the
same
0x00510000. I also tried the property for battery level (ie charging,
etc),
and still get the 00510000 hex value.
--
Jim Coburn


:

Correct. You can use the Microsoft.WindowsMobile.Status.BatteryLevel
enum
to make sense of these values.

Something like this:
pcBattTB.Text = ((BatteryLevel)BattState.CurrentValue).ToString();

--
-Robert Levy
Program Manager, Consumer Product Experiences Framework

Peter,
now that I've had a chance to study this, it appears that when
there is no
power (that is the battery is discharged), the system returns "2".
if it's
charged close to 100%, it returns "53084".
--
Jim Coburn


:

Peter,
sorry I have responded -- I've been finishing another project.
I've
pasted
in the relevant lines:
this line is part of the field declaration at the top of Form1:
SystemState BattState = new
SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents call
in the
constructor:
BattState.Changed += new ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests
that it
never
gets called. But I'm assuming that BattState.CurrentValue should
return
whatever the current value is on initialization. In the emulator
it
returns
"1". When it's run on the iPAQ, it returns a five digit number
that seems
random.
--
Jim Coburn


:

The Microsoft.WindowsMobile.Status.SystemState.Power* properties
should
be
supported on all WM5.0 devices. Can you show a snippet of the
code you
are
using and what values you are seeing returned?

Peter

--
Peter Foot
Windows Embedded MVP
www.peterfoot.net | www.inthehand.com

I'm developing an app in C# that needs to display battery
status. I'm
using
the 2.0 .Net with the WindowsMobile assemblies. I've followed
the
various
suggestions in the help files and been able to successfully
compile
and
run,
but the data being returned is garbage. I also get garbage
when I
try a
couple other system calls, such as battery state. The device
is an HP
iPAQ
2495. I'm assuming the managed code makes some assumptions
about the
hardware
map of the WindowsCE 5.0 system. Has anybody made this work on
an HP?
I
haven't gone down the path of using the HP SDK and unmanaged
code,
but
that's
my next step.
 
G

Guest

Hi Robert,

I think you are misunderstanding the point of my post. It isn't to
criticize or point out limitations, etc. It was to state that there appears
to be a bug in SystemState.CurrentValue. The invocation of this property is
_not_ applying the bitmask before it returns. It just returns the value
stored in the registry.

In this code:

using ( SystemState ss = new SystemState( SystemProperty.PowerBatteryState ) )
{
object obj = ss.CurrentValue;
}

obj is an Int32 with a value of 5308416. Casting this to the enum
BatteryState is useless because 5308416 is not one of the supported values
for this enum.

Thanks,
Chris



Robert Levy said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

Yup. SystemState is essentially a wrapper around the notification &
quick-queryting APIs in regext.h that makes it easy to use the registry keys
defined in snapi.h.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main" value.
The
value in the registry is actually an aggregate of these two values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState, we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved
from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

Jim said:
thanks for the reply. I tried the cast and I'm still getting the same
result.
if I look in the debugger, the hex value being returned is 0x00510000,
which
correctly converts to 5308416. Since the documentation seems to imply
that
the method should return a percentage value, I wonder if the enum is
working
right. On the other hand, even when the percentage of battery available
changes on the front screen (ie 100% to 95%), the method returns the same
0x00510000. I also tried the property for battery level (ie charging,
etc),
and still get the 00510000 hex value.
--
Jim Coburn


:

Correct. You can use the Microsoft.WindowsMobile.Status.BatteryLevel
enum
to make sense of these values.

Something like this:
pcBattTB.Text = ((BatteryLevel)BattState.CurrentValue).ToString();

--
-Robert Levy
Program Manager, Consumer Product Experiences Framework

Peter,
now that I've had a chance to study this, it appears that when there
is no
power (that is the battery is discharged), the system returns "2". if
it's
charged close to 100%, it returns "53084".
--
Jim Coburn


:

Peter,
sorry I have responded -- I've been finishing another project. I've
pasted
in the relevant lines:
this line is part of the field declaration at the top of Form1:
SystemState BattState = new
SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents call in
the
constructor:
BattState.Changed += new ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests that
it
never
gets called. But I'm assuming that BattState.CurrentValue should
return
whatever the current value is on initialization. In the emulator it
returns
"1". When it's run on the iPAQ, it returns a five digit number that
seems
random.
--
Jim Coburn


:

The Microsoft.WindowsMobile.Status.SystemState.Power* properties
should
be
supported on all WM5.0 devices. Can you show a snippet of the code
you
are
using and what values you are seeing returned?

Peter

--
Peter Foot
Windows Embedded MVP
www.peterfoot.net | www.inthehand.com

I'm developing an app in C# that needs to display battery
status. I'm
using
the 2.0 .Net with the WindowsMobile assemblies. I've followed
the
various
suggestions in the help files and been able to successfully
compile
and
run,
but the data being returned is garbage. I also get garbage when
I
try a
couple other system calls, such as battery state. The device is
an HP
iPAQ
2495. I'm assuming the managed code makes some assumptions about
the
hardware
map of the WindowsCE 5.0 system. Has anybody made this work on
an HP?
I
haven't gone down the path of using the HP SDK and unmanaged
code,
but
that's
my next step.
 
R

Robert Levy [MS]

Gotcha. I'll send this over to the appropriate dev to get looked at. In
the mean time, you could try manually applying the mask (which should be
called out in snapi.h) before casting.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
Hi Robert,

I think you are misunderstanding the point of my post. It isn't to
criticize or point out limitations, etc. It was to state that there
appears
to be a bug in SystemState.CurrentValue. The invocation of this property
is
_not_ applying the bitmask before it returns. It just returns the value
stored in the registry.

In this code:

using ( SystemState ss = new SystemState(
SystemProperty.PowerBatteryState ) )
{
object obj = ss.CurrentValue;
}

obj is an Int32 with a value of 5308416. Casting this to the enum
BatteryState is useless because 5308416 is not one of the supported values
for this enum.

Thanks,
Chris



Robert Levy said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

Yup. SystemState is essentially a wrapper around the notification &
quick-queryting APIs in regext.h that makes it easy to use the registry
keys
defined in snapi.h.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main"
value.
The
value in the registry is actually an aggregate of these two
values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their
corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState, we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved
from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and
just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

:

thanks for the reply. I tried the cast and I'm still getting the same
result.
if I look in the debugger, the hex value being returned is 0x00510000,
which
correctly converts to 5308416. Since the documentation seems to imply
that
the method should return a percentage value, I wonder if the enum is
working
right. On the other hand, even when the percentage of battery
available
changes on the front screen (ie 100% to 95%), the method returns the
same
0x00510000. I also tried the property for battery level (ie charging,
etc),
and still get the 00510000 hex value.
--
Jim Coburn


:

Correct. You can use the
Microsoft.WindowsMobile.Status.BatteryLevel
enum
to make sense of these values.

Something like this:
pcBattTB.Text = ((BatteryLevel)BattState.CurrentValue).ToString();

--
-Robert Levy
Program Manager, Consumer Product Experiences Framework

Peter,
now that I've had a chance to study this, it appears that when
there
is no
power (that is the battery is discharged), the system returns "2".
if
it's
charged close to 100%, it returns "53084".
--
Jim Coburn


:

Peter,
sorry I have responded -- I've been finishing another project.
I've
pasted
in the relevant lines:
this line is part of the field declaration at the top of Form1:
SystemState BattState = new
SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents call
in
the
constructor:
BattState.Changed += new ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests
that
it
never
gets called. But I'm assuming that BattState.CurrentValue should
return
whatever the current value is on initialization. In the emulator
it
returns
"1". When it's run on the iPAQ, it returns a five digit number
that
seems
random.
--
Jim Coburn


:

The Microsoft.WindowsMobile.Status.SystemState.Power*
properties
should
be
supported on all WM5.0 devices. Can you show a snippet of the
code
you
are
using and what values you are seeing returned?

Peter

--
Peter Foot
Windows Embedded MVP
www.peterfoot.net | www.inthehand.com

I'm developing an app in C# that needs to display battery
status. I'm
using
the 2.0 .Net with the WindowsMobile assemblies. I've followed
the
various
suggestions in the help files and been able to successfully
compile
and
run,
but the data being returned is garbage. I also get garbage
when
I
try a
couple other system calls, such as battery state. The device
is
an HP
iPAQ
2495. I'm assuming the managed code makes some assumptions
about
the
hardware
map of the WindowsCE 5.0 system. Has anybody made this work
on
an HP?
I
haven't gone down the path of using the HP SDK and unmanaged
code,
but
that's
my next step.
 
G

Guest

Robert,
I appreciate the time you guys spend on this, so thanks. My point, and what
got me started on all this, is the documentation is wrong. In the Managed
Code, SystemState, Properties documentation for PowerBatteryStrength Property
, it states "Gets the remaining battery power level, expressed as a
percentage of fully charged." Since I'm writing an app for a medical device,
I did want battery percentage. I also found the bug that Chris identified,
which set me back a bit.
--
Jim Coburn


Robert Levy said:
Gotcha. I'll send this over to the appropriate dev to get looked at. In
the mean time, you could try manually applying the mask (which should be
called out in snapi.h) before casting.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
Hi Robert,

I think you are misunderstanding the point of my post. It isn't to
criticize or point out limitations, etc. It was to state that there
appears
to be a bug in SystemState.CurrentValue. The invocation of this property
is
_not_ applying the bitmask before it returns. It just returns the value
stored in the registry.

In this code:

using ( SystemState ss = new SystemState(
SystemProperty.PowerBatteryState ) )
{
object obj = ss.CurrentValue;
}

obj is an Int32 with a value of 5308416. Casting this to the enum
BatteryState is useless because 5308416 is not one of the supported values
for this enum.

Thanks,
Chris



Robert Levy said:
The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

Yup. SystemState is essentially a wrapper around the notification &
quick-queryting APIs in regext.h that makes it easy to use the registry
keys
defined in snapi.h.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main"
value.
The
value in the registry is actually an aggregate of these two
values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute the
PowerBatteryStrength. If we convert these values to their
corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState, we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value retrieved
from
the registry to capture only the desired digits relevant to the desired
property, but mechanism (3) does not appear to apply this bitmask and
just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

:

thanks for the reply. I tried the cast and I'm still getting the same
result.
if I look in the debugger, the hex value being returned is 0x00510000,
which
correctly converts to 5308416. Since the documentation seems to imply
that
the method should return a percentage value, I wonder if the enum is
working
right. On the other hand, even when the percentage of battery
available
changes on the front screen (ie 100% to 95%), the method returns the
same
0x00510000. I also tried the property for battery level (ie charging,
etc),
and still get the 00510000 hex value.
--
Jim Coburn


:

Correct. You can use the
Microsoft.WindowsMobile.Status.BatteryLevel
enum
to make sense of these values.

Something like this:
pcBattTB.Text = ((BatteryLevel)BattState.CurrentValue).ToString();

--
-Robert Levy
Program Manager, Consumer Product Experiences Framework

Peter,
now that I've had a chance to study this, it appears that when
there
is no
power (that is the battery is discharged), the system returns "2".
if
it's
charged close to 100%, it returns "53084".
--
Jim Coburn


:

Peter,
sorry I have responded -- I've been finishing another project.
I've
pasted
in the relevant lines:
this line is part of the field declaration at the top of Form1:
SystemState BattState = new
SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents call
in
the
constructor:
BattState.Changed += new ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests
that
it
never
gets called. But I'm assuming that BattState.CurrentValue should
return
whatever the current value is on initialization. In the emulator
it
returns
"1". When it's run on the iPAQ, it returns a five digit number
that
seems
random.
--
Jim Coburn


:

The Microsoft.WindowsMobile.Status.SystemState.Power*
properties
should
be
supported on all WM5.0 devices. Can you show a snippet of the
code
you
are
using and what values you are seeing returned?

Peter

--
Peter Foot
Windows Embedded MVP
www.peterfoot.net | www.inthehand.com

I'm developing an app in C# that needs to display battery
status. I'm
using
the 2.0 .Net with the WindowsMobile assemblies. I've followed
the
various
suggestions in the help files and been able to successfully
compile
and
run,
but the data being returned is garbage. I also get garbage
when
I
try a
couple other system calls, such as battery state. The device
is
an HP
iPAQ
2495. I'm assuming the managed code makes some assumptions
about
the
hardware
map of the WindowsCE 5.0 system. Has anybody made this work
on
an HP?
I
haven't gone down the path of using the HP SDK and unmanaged
code,
but
that's
my next step.
 
P

Paul G. Tobey [eMVP]

Documentation errors should be reported by clicking the Send Feedback link
which should be on every page in the help. The alias to which this is sent
goes to the guys actually writing the docs, so it *will* get fixed! Please
send it.

Paul T.

Jim said:
Robert,
I appreciate the time you guys spend on this, so thanks. My point, and
what
got me started on all this, is the documentation is wrong. In the Managed
Code, SystemState, Properties documentation for PowerBatteryStrength
Property
, it states "Gets the remaining battery power level, expressed as a
percentage of fully charged." Since I'm writing an app for a medical
device,
I did want battery percentage. I also found the bug that Chris identified,
which set me back a bit.
--
Jim Coburn


Robert Levy said:
Gotcha. I'll send this over to the appropriate dev to get looked at. In
the mean time, you could try manually applying the mask (which should be
called out in snapi.h) before casting.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


CLC said:
Hi Robert,

I think you are misunderstanding the point of my post. It isn't to
criticize or point out limitations, etc. It was to state that there
appears
to be a bug in SystemState.CurrentValue. The invocation of this
property
is
_not_ applying the bitmask before it returns. It just returns the
value
stored in the registry.

In this code:

using ( SystemState ss = new SystemState(
SystemProperty.PowerBatteryState ) )
{
object obj = ss.CurrentValue;
}

obj is an Int32 with a value of 5308416. Casting this to the enum
BatteryState is useless because 5308416 is not one of the supported
values
for this enum.

Thanks,
Chris



:

The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

Yup. SystemState is essentially a wrapper around the notification &
quick-queryting APIs in regext.h that makes it easy to use the
registry
keys
defined in snapi.h.

--
-Robert Levy
Program Manager, Consumer Productivity Experiences


The way these SystemState properties appear to work is they are just
querying
and monitoring the registry values on the device at
[HKEY_LOCAL_MACHINE\System\State].

For example, SystemState.PowerBatteryState and PowerBatteryStrength
are
stored at [HKEY_LOCAL_MACHINE\System\State\Battery] in the "Main"
value.
The
value in the registry is actually an aggregate of these two
values...from
right-to-left, the first four digits (i.e. 0x0000) constitute the
PowerBatteryState and the remaining digits (i.e. 0x0051) constitute
the
PowerBatteryStrength. If we convert these values to their
corresponding
enumeration values:

0x0000 = BatteryState.Normal
0x0051 = BatteryLevel.VeryHigh

The problem you are running into (as far as I can tell) appears to
be a
bug
in the way SystemState.CurrentValue is computed. Using SystemState,
we
can
get these battery values via three different mechanisms:

1. static accessor such as SystemState.PowerBatteryState
2. change notification through ChangeEventArgs.NewValue
3. instance accessor SystemState.CurrentValue

Mechanisms (1) and (2) correctly apply a bitmask to the value
retrieved
from
the registry to capture only the desired digits relevant to the
desired
property, but mechanism (3) does not appear to apply this bitmask
and
just
returns the value straight from the registry (in your case 5308416).

FYI,
Chris

:

thanks for the reply. I tried the cast and I'm still getting the
same
result.
if I look in the debugger, the hex value being returned is
0x00510000,
which
correctly converts to 5308416. Since the documentation seems to
imply
that
the method should return a percentage value, I wonder if the enum
is
working
right. On the other hand, even when the percentage of battery
available
changes on the front screen (ie 100% to 95%), the method returns
the
same
0x00510000. I also tried the property for battery level (ie
charging,
etc),
and still get the 00510000 hex value.
--
Jim Coburn


:

Correct. You can use the
Microsoft.WindowsMobile.Status.BatteryLevel
enum
to make sense of these values.

Something like this:
pcBattTB.Text =
((BatteryLevel)BattState.CurrentValue).ToString();

--
-Robert Levy
Program Manager, Consumer Product Experiences Framework

Peter,
now that I've had a chance to study this, it appears that when
there
is no
power (that is the battery is discharged), the system returns
"2".
if
it's
charged close to 100%, it returns "53084".
--
Jim Coburn


:

Peter,
sorry I have responded -- I've been finishing another project.
I've
pasted
in the relevant lines:
this line is part of the field declaration at the top of
Form1:
SystemState BattState = new
SystemState(SystemProperty.PowerBatteryStrength);

the following lines are added after the InitializeComponents
call
in
the
constructor:
BattState.Changed += new
ChangeEventHandler(BattState_Changed);
pcBattTB.Text = BattState.CurrentValue.ToString();

I define the BattState_Changed later on. The debugger suggests
that
it
never
gets called. But I'm assuming that BattState.CurrentValue
should
return
whatever the current value is on initialization. In the
emulator
it
returns
"1". When it's run on the iPAQ, it returns a five digit number
that
seems
random.
--
Jim Coburn


:

The Microsoft.WindowsMobile.Status.SystemState.Power*
properties
should
be
supported on all WM5.0 devices. Can you show a snippet of
the
code
you
are
using and what values you are seeing returned?

Peter

--
Peter Foot
Windows Embedded MVP
www.peterfoot.net | www.inthehand.com

I'm developing an app in C# that needs to display battery
status. I'm
using
the 2.0 .Net with the WindowsMobile assemblies. I've
followed
the
various
suggestions in the help files and been able to
successfully
compile
and
run,
but the data being returned is garbage. I also get
garbage
when
I
try a
couple other system calls, such as battery state. The
device
is
an HP
iPAQ
2495. I'm assuming the managed code makes some assumptions
about
the
hardware
map of the WindowsCE 5.0 system. Has anybody made this
work
on
an HP?
I
haven't gone down the path of using the HP SDK and
unmanaged
code,
but
that's
my next step.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top