diff --git a/PiJuiceSharp/AbsentPiJuiceStatus.cs b/PiJuiceSharp/AbsentPiJuiceStatus.cs
new file mode 100644
index 0000000..abbc227
--- /dev/null
+++ b/PiJuiceSharp/AbsentPiJuiceStatus.cs
@@ -0,0 +1,72 @@
+
+namespace PiJuiceSharp
+{
+ ///
+ /// A placeholder implementation of that returns default values for when no PiJuice
+ /// interface is present at all.
+ ///
+ public sealed class AbsentPiJuiceStatus : IPiJuiceStatus
+ {
+ public void Dispose()
+ {
+ }
+
+ public float GetBatteryCurrent()
+ {
+ return 0F;
+ }
+
+ public int GetBatteryTemperature()
+ {
+ return 0;
+ }
+
+ public float GetBatteryVoltage()
+ {
+ return 0F;
+ }
+
+ public int GetChargeLevel()
+ {
+ return 0;
+ }
+
+ public Dictionary GetFaultStatus()
+ {
+ return new();
+ }
+
+ public float GetGpioCurrent()
+ {
+ return 0F;
+ }
+
+ public float GetGpioVoltage()
+ {
+ return 0F;
+ }
+
+ public LedBlinkState GetLedBlinkState(Led led)
+ {
+ return new();
+ }
+
+ public Color GetLedState(Led led)
+ {
+ return new();
+ }
+
+ public StatusInfo GetStatus()
+ {
+ return new StatusInfo(false, false, BatteryStatus.NoPiJuice, PowerInputStatus.NotPresent, PowerInputStatus.NotPresent);
+ }
+
+ public void SetLedBlinkState(Led led, LedBlinkState state)
+ {
+ }
+
+ public void SetLedState(Led led, Color color)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/PiJuiceSharp/IPiJuiceStatus.cs b/PiJuiceSharp/IPiJuiceStatus.cs
new file mode 100644
index 0000000..908d689
--- /dev/null
+++ b/PiJuiceSharp/IPiJuiceStatus.cs
@@ -0,0 +1,19 @@
+
+namespace PiJuiceSharp
+{
+ public interface IPiJuiceStatus : IDisposable
+ {
+ float GetBatteryCurrent();
+ int GetBatteryTemperature();
+ float GetBatteryVoltage();
+ int GetChargeLevel();
+ Dictionary GetFaultStatus();
+ float GetGpioCurrent();
+ float GetGpioVoltage();
+ LedBlinkState GetLedBlinkState(Led led);
+ Color GetLedState(Led led);
+ StatusInfo GetStatus();
+ void SetLedBlinkState(Led led, LedBlinkState state);
+ void SetLedState(Led led, Color color);
+ }
+}
\ No newline at end of file
diff --git a/PiJuiceSharp/PiJuiceInterface.cs b/PiJuiceSharp/PiJuiceInterface.cs
index e4b9dfd..1eb5e7c 100644
--- a/PiJuiceSharp/PiJuiceInterface.cs
+++ b/PiJuiceSharp/PiJuiceInterface.cs
@@ -1,4 +1,5 @@
using System.Device.I2c;
+using System.Diagnostics.CodeAnalysis;
namespace PiJuiceSharp
{
@@ -8,14 +9,27 @@ public sealed class PiJuiceInterface : IDisposable
private readonly I2cDevice i2cDevice;
private readonly int address;
-
- public PiJuiceInterface(int busId = 1, int deviceAddress = 0x14)
+ private PiJuiceInterface(int busId = 1, int deviceAddress = 0x14)
{
var settings = new I2cConnectionSettings(busId, deviceAddress);
this.i2cDevice = I2cDevice.Create(settings);
this.address = deviceAddress;
}
+ public static bool TryConnect([NotNullWhen(true)] out PiJuiceInterface? piJuiceInterface)
+ {
+ try
+ {
+ piJuiceInterface = new PiJuiceInterface();
+ return true;
+ }
+ catch (IOException)
+ {
+ piJuiceInterface = null;
+ return false;
+ }
+ }
+
public void Dispose()
{
this.i2cDevice?.Dispose();
diff --git a/PiJuiceSharp/PiJuiceSharp.csproj b/PiJuiceSharp/PiJuiceSharp.csproj
index dc3fe02..a224475 100644
--- a/PiJuiceSharp/PiJuiceSharp.csproj
+++ b/PiJuiceSharp/PiJuiceSharp.csproj
@@ -24,7 +24,7 @@
True
latest-all
True
- 0.2.0
+ 0.3.0
True
diff --git a/PiJuiceSharp/PiJuiceStatus.cs b/PiJuiceSharp/PiJuiceStatus.cs
index 14eee33..d793b18 100644
--- a/PiJuiceSharp/PiJuiceStatus.cs
+++ b/PiJuiceSharp/PiJuiceStatus.cs
@@ -1,7 +1,7 @@
namespace PiJuiceSharp
{
- public sealed class PiJuiceStatus : IDisposable
+ public sealed class PiJuiceStatus : IPiJuiceStatus
{
private const byte STATUS_CMD = 0x40;
private const byte CHARGE_LEVEL_CMD = 0x41;
@@ -15,11 +15,23 @@ public sealed class PiJuiceStatus : IDisposable
private const byte LED_BLINK_CMD = 0x68;
private readonly PiJuiceInterface piJuiceInterface;
- public PiJuiceStatus(PiJuiceInterface piJuiceInterface)
+ private PiJuiceStatus(PiJuiceInterface piJuiceInterface)
{
this.piJuiceInterface = piJuiceInterface;
}
+ public static IPiJuiceStatus Create()
+ {
+#pragma warning disable CA2000 // Dispose objects before losing scope - the PiJuiceInterface is disposed by the returned object
+ if (PiJuiceInterface.TryConnect(out PiJuiceInterface? piJuiceInterface))
+ {
+ return new PiJuiceStatus(piJuiceInterface);
+ }
+#pragma warning restore CA2000 // Dispose objects before losing scope
+
+ return new AbsentPiJuiceStatus();
+ }
+
public StatusInfo GetStatus()
{
byte d = this.piJuiceInterface.Read(STATUS_CMD);
diff --git a/PiJuiceSharp/StatusInfo.cs b/PiJuiceSharp/StatusInfo.cs
index 380e5ee..6b391b6 100644
--- a/PiJuiceSharp/StatusInfo.cs
+++ b/PiJuiceSharp/StatusInfo.cs
@@ -2,10 +2,31 @@
{
public enum BatteryStatus
{
+ ///
+ /// Battery is present, but not charging
+ ///
Normal = 0,
+
+ ///
+ /// Battery is charging from the its power input
+ ///
ChargingFromIn = 1,
+
+ ///
+ /// Battery is charging from the 5V IO pin
+ ///
ChargingFrom5vIo = 2,
- NotPresent = 3
+
+ ///
+ /// The PiJuice board is present, but no battery is connected
+ ///
+ NotPresent = 3,
+
+ ///
+ /// No PiJuice board is present - no readings will be available. This is an extension to the
+ /// original PiJuice Python library.
+ ///
+ NoPiJuice = 8000,
}
public enum PowerInputStatus
diff --git a/PiJuiceTest/Program.cs b/PiJuiceTest/Program.cs
index cdc2b96..96543e0 100644
--- a/PiJuiceTest/Program.cs
+++ b/PiJuiceTest/Program.cs
@@ -2,9 +2,7 @@
using static System.Console;
-var piJuiceInterface = new PiJuiceInterface();
-
-var piJuiceStatus = new PiJuiceStatus(piJuiceInterface);
+IPiJuiceStatus piJuiceStatus = PiJuiceStatus.Create();
#region Console writing function
static void WriteHeader(string header)
diff --git a/README.md b/README.md
index 01cdcd2..000a095 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,15 @@
![PiJuiceSharp logo](/docs/favicon-256.png)
-An implementation of the PiJuice client library based on the original [PiJuice Python library](https://github.com/PiSupply/PiJuice/blob/master/Software/Source/pijuice.py) in pure .NET. Currently packaged as a .NET 6 library with only a dependency on `System.Device.Gpio`.
+An implementation of the PiJuice client library based on the original [PiJuice Python library](https://github.com/PiSupply/PiJuice/blob/master/Software/Source/pijuice.py)
+in pure .NET. Currently packaged as a .NET 6 library with only a dependency on `System.Device.Gpio`.
-This library currently only supports a subset of the Status APIs, and other APIs such as the RTC and Power Management are not yet implemented. Implementing others should be fairly straightforward, but I just don't have a need for them at the moment - contributions are welcome if you need to extend it!
+Only a subset of the Status APIs are currently supported, and other APIs such as the RTC and Power Management are not yet implemented.
+Implementing others should be fairly straightforward, but I just don't have a need for them at the moment - contributions are welcome if you
+need to extend it!
+
+This library is safe to use even if you don't know that the device will have a PiJuice attached. When a PiJuice isn't present,
+default values will be returned for all APIs, and a value of `NoPiJuice` for `GetStatus().BatteryStatus`.
## Installation
@@ -14,18 +20,25 @@ You can install the library from [NuGet](https://www.nuget.org/packages/PiJuiceS
dotnet add package PiJuiceSharp
```
-## PiJuice Status APIs
+## PiJuiceStatus
You can use the `PiJuiceStatus` class to get various point-in-time status values of the PiJuice board.
-To construct a `PiJuiceStatus`, you need to pass in an instance of `PiJuiceInterface`.
+To construct a `PiJuiceStatus`, call `PiJuiceStatus.Create()`. This returns an implementation of `IPiJuiceStatus` which will be either a
+fully connected `PiJuiceStatus` instance or an `AbsentPiJuiceStatus` instance which handles the case when no PiJuice was present.
``` csharp
-var piJuiceInterface = new PiJuiceInterface();
+var piJuiceStatus = PiJuiceStatus.Create();
+```
+
+If you're using dependency injection, you can configure the `IPiJuiceStatus` interface as a singleton:
-var piJuiceStatus = new PiJuiceStatus(piJuiceInterface);
+``` csharp
+services.AddSingleton(PiJuiceStatus.Create());
```
+## PiJuice Status APIs
+
`GetStatus()` returns an object containing basic status information, defined as:
``` csharp
@@ -34,7 +47,8 @@ public enum BatteryStatus
Normal = 0,
ChargingFromIn = 1,
ChargingFrom5vIo = 2,
- NotPresent = 3
+ NotPresent = 3,
+ NoPiJuice = 8000
}
public enum PowerInputStatus