Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions allsky_ina3221/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Changelog — allsky_ina3221

---

## v2.0.0 — 2026-03-07

### Breaking Changes
- Replaced `barbudor_ina3221` library with `adafruit-circuitpython-ina3221`.
- Channel reading API updated internally to use 0-based index property access (`ina[n].bus_voltage`) instead of method calls (`ina3221.bus_voltage(channel)`)

### New Features
- **Low voltage shutdown** — monitors a configurable channel and triggers a kernel-managed `sudo shutdown -h` when voltage drops below a set threshold
- **Shutdown delay** — configurable dropdown (1, 5, 15, 30, or 60 minutes) to allow AllSky logs and housekeeping to complete before power off
- **Shunt resistance** — configurable via the UI; defaults to 0.05 ohms to match the Adafruit INA3221 breakout board
- **Custom I2C address** — `i2caddress` param is now wired up and functional; uses `busio.I2C` with the specified hex address when set
- **Shutdown channel validation** — logs a warning at startup if low voltage shutdown is enabled but the selected monitor channel is disabled
- **Shutdown channel dropdown** — `shutdownchannel` is now a select field (Channel 1/2/3) instead of a free-text field, preventing invalid input
- **UI tabs** — settings are now organised across three tabs: main settings, Extra Data, and Shutdown

### Bug Fixes
- Fixed critical shutdown logic flaw — the shutdown countdown was being rescheduled on every module run (every ~1 minute), resetting the timer indefinitely and preventing the system from ever shutting down. Log showed 65+ consecutive WARNING entries over nearly 2 hours with the voltage dropping from 11.98V to 10.97V while the system stayed running
- Added `is_shutdown_pending()` helper that calls `shutdown --show` to check whether a shutdown is already scheduled before issuing a new one. If a shutdown is already pending, the module logs a quieter level 1 info message and skips the command entirely
- Fixed low voltage shutdown silently failing when the AllSky user lacked passwordless sudo rights for `/sbin/shutdown`. `subprocess.run` with `check=False` was swallowing the failure with no log output
- Replaced `check=False` with full output capture — shutdown command result (success or failure) is now always logged at level 0
- Added `timeout=10` to the subprocess call to prevent hanging if sudo prompts for a password
- All failure paths now log a clear actionable error message including the exact `visudo` entry required:
```
allsky ALL=(ALL) NOPASSWD: /sbin/shutdown
```
- Fixed `cleanup` using a Python `set` (`{}`) instead of a `list` (`[]`) for the files array — this would have caused `ina3221_cleanup()` to fail silently
- Fixed `shunt_voltage` unit handling — the Adafruit library returns millivolts; value is now correctly divided by 1000 before being added to `bus_voltage`
- Fixed sensor returning 0.0 on first read — added `time.sleep(0.5)` after init to allow the first conversion cycle to complete
- Fixed `params` key access using direct `[]` indexing — all params now use `.get()` with safe defaults, preventing `KeyError` crashes when the module config is missing newly added keys (e.g. after an upgrade)
- Fixed `to_bool()` helper to handle AllSky passing channel enable params as either `bool` or `str` depending on context
- Removed never-called `debugOutput()` function that referenced wrong sensor variables (temperature, humidity etc.) — was copied from another module
- Removed `barbudor`-specific `IS_FULL_API` configuration block

### Installation
- Added `requirements.txt` for automatic dependency installation by the AllSky module installer
- Dependencies: `adafruit-circuitpython-ina3221`, `adafruit-blinka`, `adafruit-circuitpython-busdevice`
- No pinned versions to avoid conflicts with other AllSky modules that share the same Adafruit dependencies

### Cleanup
- Renamed all functions and variables to PEP 8 snake_case (`readChannel` → `read_channel` etc.)
- Replaced three repeated `if c1/c2/c3` channel read blocks with a single loop over a `channels` list
- Replaced wildcard import (`from barbudor_ina3221.full import *`) with explicit import
- Added `to_bool()`, `read_channel()`, and `check_shutdown()` as named, documented helper functions
- Added docstrings to all functions
- Added `subprocess` and `busio` imports required for shutdown and custom I2C address support
- Version bumped from v1.1.1 to v2.0.0 reflecting library replacement and new features

---

## v1.1.1 — original release
- Initial implementation using `barbudor_ina3221` library
- Basic voltage, current, and power monitoring across three channels
- AllSky overlay variable output via `saveExtraData`
111 changes: 109 additions & 2 deletions allsky_ina3221/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,113 @@
| **Level** | Experienced |
| **Runs In** | Periodic |

A simple module to read 1 to 3 channels from an INA3221 voltage and current sensor.
A module to read voltage, current, and power from 1 to 3 channels of an INA3221 triple-channel power monitor. Each channel is independently configurable with a custom name that maps directly to an AllSky overlay variable.

These modules can be useful for monitoring the current being fed to a dew heater to determine if its actually working or not
## Use Cases

- **Solar power systems** — monitor solar panel output voltage and current alongside battery state and load consumption simultaneously across all three channels
- **Battery monitoring** — track battery voltage over time and use the low voltage shutdown feature to safely power down the Pi before the battery is fully depleted, protecting both the battery and the filesystem
- **Dew heater monitoring** — confirm a dew heater is drawing the expected current and flag if it has failed or disconnected
- **USB power monitoring** — monitor the voltage and current being delivered to the camera or other USB peripherals
- **Bi-directional current monitoring** — current readings are not abs()-filtered, so the module can detect both charge and discharge current on a battery channel

## Hardware

This module supports the [Adafruit INA3221 Triple-Channel DC Voltage and Current Sensor Breakout](https://www.adafruit.com/product/6062). The board monitors up to three independent channels at 0–26V and ±3.2A via I2C.

Default I2C address: `0x40`

Shunt resistor value: `0.05 ohms` (Adafruit breakout default)

## Installation

Install the required Python libraries on your Raspberry Pi:

```bash
pip3 install -r requirements.txt --break-system-packages
```

Or let the AllSky module installer handle this automatically via `requirements.txt`.

### Sudoers Configuration (required for low voltage shutdown)

If you intend to use the low voltage shutdown feature, the AllSky user must have passwordless sudo rights for the shutdown command. Run:

```bash
sudo visudo -f /etc/sudoers.d/allsky-shutdown
```

Add the following line (replace `allsky` with your AllSky user if different):

```
allsky ALL=(ALL) NOPASSWD: /sbin/shutdown
```

## Configuration

Settings are organised across three tabs in the AllSky WebUI.

### Main Tab

| Parameter | Description | Default |
| --- | --- | --- |
| I2C Address | Override the default I2C address. Leave blank for `0x40`. Must be hex e.g. `0x41` | _(blank)_ |
| Enable Channel 1 | Enable reading from channel 1 | `true` |
| Channel 1 Name | AllSky overlay variable name prefix for channel 1 | `solar` |
| Enable Channel 2 | Enable reading from channel 2 | `true` |
| Channel 2 Name | AllSky overlay variable name prefix for channel 2 | `battery` |
| Enable Channel 3 | Enable reading from channel 3 | `true` |
| Channel 3 Name | AllSky overlay variable name prefix for channel 3 | `usb` |
| Shunt Resistance | Shunt resistor value in ohms. Change only if using a non-Adafruit board | `0.05` |

### Extra Data Tab

| Parameter | Description | Default |
| --- | --- | --- |
| Extra Data Filename | JSON file written with voltage/current data for the overlay manager | `allskyina3221.json` |

### Shutdown Tab

| Parameter | Description | Default |
| --- | --- | --- |
| Enable Low Voltage Shutdown | Monitor a channel and shut down when voltage drops below the threshold | `false` |
| Shutdown Monitor Channel | Channel to monitor (1, 2, or 3) | `2` |
| Shutdown Voltage Threshold | Voltage in volts below which shutdown is triggered | `11.5` |
| Shutdown Delay | How long after the trigger before the system shuts down | `1 Minute` |

## Overlay Variables

For each enabled channel, the following variables are written to the extra data JSON file and are available in the AllSky overlay manager. Variable names are based on the channel name configured in settings (uppercased).

Using the default channel names `solar`, `battery`, and `usb`:

| Variable | Description | Units |
| --- | --- | --- |
| `AS_SOLARVOLTAGE` | Channel 1 voltage | V |
| `AS_SOLARCURRENT` | Channel 1 current | A |
| `AS_SOLARPOWER` | Channel 1 power | W |
| `AS_BATTERYVOLTAGE` | Channel 2 voltage | V |
| `AS_BATTERYCURRENT` | Channel 2 current | A |
| `AS_BATTERYPOWER` | Channel 2 power | W |
| `AS_USBVOLTAGE` | Channel 3 voltage | V |
| `AS_USBCURRENT` | Channel 3 current | A |
| `AS_USBPOWER` | Channel 3 power | W |
| `AS_INA3221TIME` | Timestamp of last successful read | MM/DD/YYYY HH:MM:SS |

Disabled channels will show `N/A` in the overlay.

## Low Voltage Shutdown

When enabled, the module monitors the configured channel on every periodic run. If the voltage drops below the threshold, a warning is logged and a kernel-managed shutdown is scheduled via `sudo shutdown -h`. The shutdown is handled by the OS independently of AllSky, allowing logs and housekeeping to complete before power off.

The module checks whether a shutdown is already pending before scheduling a new one, preventing the countdown from being reset on every module run.

## Notes

- The module requires a short initialisation delay (`0.5s`) after connecting to the sensor to allow the first conversion cycle to complete. Without this, the first read returns `0.0`.
- Current readings are not abs()-filtered, allowing detection of bi-directional current flow (e.g. battery charging vs discharging).
- If using a non-Adafruit INA3221 board, check the shunt resistor value printed on the PCB and update the **Shunt Resistance** setting accordingly. An incorrect value will result in inaccurate current and power readings.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for full version history.
Loading