
Ahp board
dglcinc/pivac
Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)

Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)
Ah board is an open-source printed circuit board by dglcinc, from the dglcinc/pivac repository on GitHub. It is a 2-layer board of 86.4 × 53.3 mm with 53 parts on 28 nets, routed with 404 tracks and 24 vias.
It is built around the DS2482S-100+, LTV-814S and 1812L020/60DR, with the 1N4148W, S1M and SMAJ43CA among its other parts. Its parts include 18 resistors, 9 capacitors, 7 diodes, 5 connectors and 4 ICs.
Python package to pull data from Raspberry-Pi (RPi)-based inputs, and output JSON data. Supports the assembly and delivery of RPi-based monitoring and control solutions, like HVAC and home automation. Could also be used for other monitoring projects like home brewing and sous vide. These inputs include both RPi hardware inputs (like GPIO pins and GPIO-supported protocols like 1-Wire), as well as external sources useful for assembling a complete solution, such as HTTP-based data feeds and web sites (a.k.a. screen scraping.) This package is "input-only" - no provision is (currently) made to process updates.
Currently supported inputs include:
module: keyThe package is extensible, so if the supported inputs don't meet your needs, you can add your own.
The package provides each input individually, so you can pick and choose which ones you want. Customization is possible via a configuration file.
This package has the modest aspiration of simplifying a certain class of monitoring (and eventually control) use cases for Raspberry Pi based projects, by providing pre-built recipes for acquiring data, and emitting the data in JSON format. It has no aspirations to replace more general RPi packages like GPIO and w1Therm (in fact it is built on top of them). Examples cases using JSON data:
The core concept of this package is simple - go get some data from somewhere related to your use case (a piece of HVAC equipment or a home automation product website) and return it as a JSON-formatted data collection. You can then reformat it and deliver it in a number of different ways. A standard call interface and configuration file format makes it easy to add new modules for new input types.
What can I say, I like Python. It's easy and fun to write some pretty fancy stuff. And supposedly it's where the Pi in Raspberry Pi comes from (Pi-thon, get it?).
I actually started this project on Arduino, using a packaged Arduino-based PLC from Digital Loggers. There are some advantages to using the Arduino in terms of analog inputs, PWM handling, performance, etc. and the DL PLC is pretty cool, with optical input isolators, open collector outputs, LCD screen, etc. I didn't really need these features, and the programming model was not fun (e.g. coding Lua on NodeMCU to do your Wi-Fi comms., serial-loading sketches constantly, etc.) Great if you need it, a pain if you don't. I abandoned this because the RPi is way simpler - I can SSH in headless, use a standard UNIX programming model and tools (which I know very well) code in fun languages like Python -- what's not to like? The code for the (archived) Arduino version is at HVAC-plc.
Ambitious contributors/forkers who like the RPi model and also have more need for Arduino features could follow the suggestion in this excellent Maker article to piggy-back an Arduino to your RPi's serial port, and add a module that reads the Arduino and supplies JSON as output.
I suppose you could do some work to optimize by only generating output when state changes, but that gets a lot more complicated and I don't really see the benefit for my use case, so I didn't do it.
Eventually. For the HVAC use case specifically, I have shied away from making the correct operation of the HVAC system dependent on the RPi:
I'm pondering a design that allows some control or automation by the RPi, but fallback to full mechanical behavior if the RPi is down. When I have a good plan for that I'll reconsider having the RPi control the system.
My original project delivered the JSON from my data sources into a python script that dynamically generated a simple web page on the RPi as an Apache-based Python CGI. I then internet-enabled my project (to avoid doing port forwarding to my RPi, and to learn AWS IOT...) by setting up the RPi as a thing on Amazon's IOT service, and using a Lambda to generate an S3-based static page whenever the thing shadow is updated by my RPi, once every few seconds. I know kinda sloppy but it works... You could optimize your updating to minimize charges for Lambda, etc., but at the volume I consume (low and cheap) it's not a priority. The github repository for the archived version is at HVAC-pi, including the python cgi in the /local subdirectory, and the AWS thing code in /hvac-pi-aws.
I serendipitously stumbled on a project targeted at the boating community, Signal K. Some features of that project are strikingly similar to mine (gather data from a variety of disparate sources and protocols and rationalize them into a JSON-based data stream). They have more and better developers, and a pretty highly evolved ecosystem. So I've converted to outputting my JSON to a Signal K server, and then using the tools in that ecosystem (such as the excellent iOS app WilhelmSK) to store and render my data. It's very cool. Check it out. Here are screenshots from the WilhelmSK iPhone and iPad app. The first screen is the real-time gauges to monitor all my vital statistics, and the second screen is a Grafana dashboard visualizing time series data for all the inputs, stored in an InfluxDB database.
The features of the architecture are:
The data flow and component view of the architecture is as follows:
%%{init: {'flowchart': {'htmlLabels': true, 'curve': 'linear', 'subgraphTitleMargin': {'top': 30, 'bottom': 30}}, 'theme': 'base'}}%%
graph TD
subgraph Devices["Physical Devices"]
A1["Arduino<br/>10.0.0.114<br/>Hydronic PSI<br/>(Fusch 100 PSI)"]
A2["Arduino<br/>10.0.0.219<br/>DHW PSI<br/>(Fusch 200 PSI)"]
CAM["Tapo C120<br/>10.0.0.19<br/>RTSP 2560×1440"]
OW["1-Wire Sensors<br/>GPIO (temp)"]
GPIO["GPIO Pins<br/>Switches / Relays"]
RL["Honeywell<br/>mytotalconnectcomfort.com<br/>(HTTPS)"]
TED["TED5000<br/>10.0.0.49<br/>⚠ disabled"]
FLIR["FLIR FX Camera<br/>⚠ disabled"]
end
subgraph Pivac["pivac"]
NOTE["📝 Python | ~/github/pivac<br/>systemd services"]
P1["pivac.ArduinoPSI<br/>pivac-arduino-psi.service"]
P2["pivac.ArduinoThermPSI<br/>pivac-arduino-therm-psi.service"]
P3["pivac.Sentry<br/>pivac-sentry.service<br/>(OpenCV perspective warp<br/>+ 7-seg digit recognition)"]
P4["pivac.OneWireTherm<br/>pivac-1wire.service"]
P5["pivac.GPIO<br/>pivac-gpio.service"]
P6["pivac.RedLink<br/>pivac-redlink.service<br/>(screen scraping)"]
PROV["pivac-provider.py<br/>(WebSocket delta push<br/>+ JWT auth)"]
end
Clone the repository and install into a Python virtual environment:
git clone https://github.com/dglcinc/pivac
cd pivac
python3 -m venv ~/pivac-venv
source ~/pivac-venv/bin/activate
pip install -e .If you need the RPi-specific hardware dependencies (GPIO, 1-wire), also run:
pip install RPi.GPIO w1thermsensor --break-system-packagesIf you prefer not to install at all, the scripts and config will work properly using the local repository directory as the launch point — just run python scripts/pivac-provider.py directly from the clone.
Copy the sample config and edit it for your setup:
sudo mkdir -p /etc/pivac
sudo cp config/config.yml.sample /etc/pivac/config.yml
sudo nano /etc/pivac/config.ymlEach top-level key in the config file (starting with pivac.) is a provider instance name. By default, it is also the Python module that gets loaded. If you want multiple instances of the same module (e.g. two sensors of the same type with different IPs), add a module: key to point to the shared implementation:
pivac.Sensor1:
module: pivac.ArduinoSensor
ipaddr: 10.0.0.10
...
pivac.Sensor2:
module: pivac.ArduinoSensor
ipaddr: 10.0.0.11
...Enable or disable modules by setting enabled: true/false. A complete, commented sample is provided as config/config.yml.sample.
Signal K integration requires a pivac_config: section in your config file containing the SignalK host, port, and credentials:
pivac_config:
signalk:
host: localhost
port: 3000
username: admin
password: yourpasswordNote: pivac_config is a reserved key for framework settings — it is not treated as a provider module.
pivac-provider.py — the main script. It dynamically loads modules from your config file and either pushes data to Signal K via WebSocket (daemon mode) or outputs JSON to stdout (useful for testing). The --help option provides full documentation; arguments and choices are dynamically configured from the contents of the config file.pivac-provider.sh — a wrapper for the .py script that restarts it if it fails (e.g. when running with --daemon). This script execs to provider.sh and inherits its behavior.provider.sh — a generic wrapper script that restarts a script if it fails and catches the SIGHUP signal (kill -1) to restart the script. A standard kill (SIGINT) will stop both the wrapper and the script.# Test a module - outputs JSON to stdout
python scripts/pivac-provider.py pivac.GPIO
# Pretty-print output for debugging
python scripts/pivac-provider.py pivac.OneWireTherm --format pretty
# Run continuously (daemon mode) - connects to Signal K via WebSocket
python scripts/pivac-provider.py pivac.RedLink --daemon
# Options
# --loglevel DEBUG|INFO|WARNING|ERROR|CRITICAL
# --format compact|pretty
# --daemon [N] (run forever, or N iterations)In production, each module runs as a dedicated systemd service. Service files are provided in scripts/systemd/. To install:
sudo cp scripts/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable pivac-1wire pivac-redlink pivac-gpio pivac-arduino-psi pivac-arduino-therm-psi pivac-emporia pivac-sentry
sudo systemctl start pivac-1wire pivac-redlink pivac-gpio pivac-arduino-psi pivac-arduino-therm-psi pivac-emporia pivac-sentryEach service connects independently to Signal K via WebSocket and restarts automatically on failure.
The pivac package currently contains the following modules:
Pivac is designed so that new data providers can be added without modifying any framework code. The steps are:
1. Write the module
Create pivac/MyModule.py. The module must implement a status() function with this signature:
def status(config={}, output="default"):
...output="default": return a plain Python dict of sensor readings (used for command-line testing)output="signalk": return a Signal K delta dict built using the pivac helper functions:from pivac import sk_init_deltas, sk_add_source, sk_add_value
deltas = sk_init_deltas()
source = sk_add_source(deltas)
sk_add_value(source, "environment.inside.myreading", value)
return deltaspivac. (e.g. pivac.MyModule)You can use the propagate_defaults() helper to copy top-level config values down to each entry in inputs: — see GPIO.py or OneWireTherm.py for examples.
2. Add a config section
Add a section to /etc/pivac/config.yml using the module's full Python name as the key:
pivac.MyModule:
description: My new sensor module
enabled: true
daemon_sleep: 5
# ... module-specific config keys ...If you need multiple independent instances of the same module (e.g. two sensors with different IPs), give each a unique key and use the module: key to point them both at the same implementation:
pivac.MySensor1:
module: pivac.MyModule
ipaddr: 10.0.0.10
pivac.MySensor2:
module: pivac.MyModule
ipaddr: 10.0.0.113. Test standalone
Verify the module works before connecting it to Signal K:
source ~/pivac-venv/bin/activate
python scripts/pivac-provider.py pivac.MyModule --format prettyThis outputs the raw JSON to stdout without needing Signal K running.
4. Create a systemd service file
Copy an existing service file and adapt it:
cp scripts/systemd/pivac-gpio.service scripts/systemd/pivac-mymodule.serviceEdit the new file — change the Description and the module name in ExecStart:
[Unit]
Description=Pivac MyModule provider
After=network.target signalk.service
Requires=signalk.service
[Service]
Type=simple
User=pi
Environment=PIVAC_CFG=/etc/pivac/config.yml
ExecStart=/home/pi/pivac-venv/bin/python3 /home/pi/github/pivac/scripts/pivac-provider.py pivac.MyModule --loglevel ERROR --daemon
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target5. Install and start the service
sudo cp scripts/systemd/pivac-mymodule.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable pivac-mymodule
sudo systemctl start pivac-mymodule6. Verify
journalctl -u pivac-mymodule -n 50 --no-pagerpivac.set_config(configfile=""): This method must be called before using any of the modules. It locates and reads the config file, first in /etc/pivac/config.yml then in config/config.yml relative to the parent directory of the scripts, if you do not specify it. Returns the config dictionary. This currently can only be set once, because the data read from the config file is used to load modules by the pivac-provider.py script. If you attempt to set again it will return the current config dict.
pivac.get_config(): Returns the config dictionary read from the config file.
[module].status(config={}, output="default"): Each module implements (at least) this method, and can be used individually in your project. Each module supports one interface method, status(). Status takes two arguments - a dictionary containing the configuration for the module read from the configuration file, and a string indicating the output type ("default" for plain JSON dict, "signalk" for a Signal K delta structure).
In order to use the OneWireTherm module, you need to enable the OneWire RPi driver. You can do this in either the GUI system configuration (if you're using the desktop) or on the command line:
sudo raspi-config
[select "Interfacing Options"]
[select "1-Wire"]
[select "<Yes>"]
exitGPIO.status(config={}, output="default"): each pin included in the configuration file will be reported as "true" if on and "false" if off.
Example output using the sample yml file with python pivac-provider.py pivac.GPIO --format pretty:
{
"ZV": true,
"DHW": false,
"BLR": true,
"BOS2": false,
"BOS1": false,
"DEHUM": false,
"HPCALL": false
}OneWireTherm.status(config={}, output="default"): the module will return the current temperature reported by every sensor on the 1-wire bus. Options in the config file allow you to assign names, and specify a temperature scale and rounding. Example output using the sample yml file with python pivac-provider.py pivac.OneWireTherm --format pretty:{
"UBT": 45,
"OUT": 47,
"LBT": 73,
"IN": 40
}TED5000.status(): Returns JSON for the current PowerNow values of MTUs 1-4 from the URL <my_ted_gateway_ip_or_hostname>/LiveData.xml. All TED data is available; The configuration file allows you to specify any path from the LiveData.xml url using an XPath-style path, and the "friendly" name it should be mapped to. Example output using the sample yml file with python pivac-provider.py pivac.TED5000 --format pretty:{
"MainPanel": 1161,
"SubPanel": 398,
"HVAC": 30
}ArduinoSensor.status(config={}, output="default"): Polls an Arduino over HTTP and returns the pressure reading in PSI. The Arduino serves a simple JSON response containing a psi key. Designed for use with ratiometric pressure sensors (e.g. Fusch 100PSI, Fusch 200PSI, 0.5–4.5V output). Multiple config sections can share this implementation using the module: key — for example, pivac.ArduinoPSI and pivac.ArduinoThermPSI both point to pivac.ArduinoSensor with different ipaddr values. Example output:{
"psi": 18.4
}Redlink.status(verbose=False): Returns the current temperature, humidity, status, and name (as set on the thermostat) for every thermostat associated with the location defined on mytotalconnectcomfort.com. Temperature will be defined as on the thermostat. Humidity will be a whole number. Status will be one of "cool", "heat", "fanOn", or "off". Outdoor humidity is returned as "outhum". The key for each object is the thermostat identifier used in the RedLink registry. verbose = True causes the scraper to navigate to the sub-page for each thermostat, collect all available detailed data like setpoints, and return it as a nested JSON object for each thermostat; this option is slower, so don't use it unless you need it. Example output using the sample yml file with python pivac-provider.py pivac.RedLink --format pretty:{
"2834229": {
"status": "fan",
"hum": 51,
"name": "KIDS ROOM",
"temp": 74
},
"outhum": 100.0,
"2528432": {
"status": "off",
"hum": 47,
"name": "KITCHEN",
"temp": 75
}
}Emporia.status(config={}, output="default"): Polls an Emporia Vue Gen 2 energy monitor via the PyEmVue cloud API and returns per-circuit power readings in Watts. Each circuit in the Emporia app becomes a separate value in the output, keyed by <panel_name>.<circuit_name>. Circuit names are taken from the Emporia app labels and sanitized to lowercase with underscores.The module authenticates with the Emporia cloud using your account credentials and caches the auth token locally. On first run it discovers all devices on the account; the device list is cached in memory for the lifetime of the process.
Config keys:
| Key | Required | Default | Description |
|---|---|---|---|
username | Yes | — | Emporia account email |
password | Yes | — | Emporia account password |
token_file | No | /etc/pivac/emporia-tokens.json | Path for cached auth token |
sk_path | No | electrical.emporia | Signal K base path for all readings |
panels | No | all panels, auto-named | Dict mapping device GID strings to friendly panel names |
daemon_sleep | No | 0 | Seconds between polls — recommended 60 to match the 1-minute API window |
Run scripts/emporia-discover.py to find your device GIDs and generate a suggested config block.
Example output with two panels configured:
{
"house.main": 3020.4,
"house.utility_sub_panel": 331.4,
"house.wall_oven": 0.0,
"house.bosch_bova": 6.5,
"apartment.main": 268.7,
"apartment.furnace": 10.4,
"apartment.clothes_washer": 0.0
}Sentry.status(config={}, output="default"): Reads the Sentry 2100 controller display on an NTI Trinity Ti-200 boiler using a Tapo C120 IP camera over RTSP. On each poll cycle the module captures frames for up to cycle_timeout seconds, reads each display mode as the indicator lights cycle, and emits the results as Signal K deltas.The display cycles through three modes: water temp, outdoor air temp, and gas input value. Indicator lights below the display identify the active mode. The dhw_temp indicator is a boiler status light (DHW priority active), not a display mode — it is emitted as a boolean regardless of what the display is showing.
Digit recognition uses 7-segment pattern matching (not OCR). LED and indicator state is detected via brightness ratio in each region of interest. Coordinates for all regions must be calibrated once using scripts/sentry-calibrate.py.
Config keys:
| Key | Required | Default | Description |
|---|---|---|---|
rtsp_url | Yes | — | RTSP stream URL including camera credentials |
display_warp | Yes | — | Perspective-warp corners and output size (from calibration) |
digit_positions | Yes | — | List of 3 digit bounding boxes relative to warped display |
leds | Yes | — | Centre-pixel coords for burner/circ/circ_aux/thermostat_demand |
indicators | Yes | — | Centre-pixel coords for water_temp/air/gas_input/dhw_temp |
cycle_timeout | No | 30 | Seconds to wait for all three display modes |
mode_stable_frames | No | 3 | Consecutive stable frames before accepting a reading |
led_ratio | No | 1.15 | Spot/background brightness ratio for LED detection |
digit_threshold_factor | No | 0.50 | Threshold = mean + factor×(max−mean) per digit |
daemon_sleep | No | 0 | Seconds between polls — recommended 60 |
Signal K paths emitted:
| Path | Type | Description |
|---|---|---|
hvac.boiler.sentry.waterTemp | number | °F as shown on display — boiler supply water temperature |
hvac.boiler.sentry.outdoorTemp | number | °F as shown on display — outdoor air temperature |
hvac.boiler.sentry.gasInputValue | number | Raw 40–240 scale (see boiler manual for BTU/hr conversion) |
hvac.boiler.sentry.dhwPriority | boolean | True when boiler is in DHW priority mode |
hvac.boiler.sentry.errorCode | string | Error/status code e.g. ER3 (only when displayed) |
hvac.boiler.sentry.burnerOn | boolean | Burner firing |
hvac.boiler.sentry.circOn | boolean | Circulator pump on |
hvac.boiler.sentry.circAuxOn | boolean | Auxiliary circulator on |
hvac.boiler.sentry.thermostatDemand | boolean | Thermostat demand active |
Run scripts/sentry-calibrate.py to capture a reference frame and identify pixel coordinates for the display ROI, digit positions, LEDs, and indicators.
The FlirFX module lets you collect temperature and humidity data from a FLIR camera. The config file format allows you to specify multiple cameras (inputs) and your login credentials. Example output using the sample yml file with python pivac-provider.py pivac.FlirFX --format pretty:
{
"192.168.2.79": {
"temperature": 67.98,
"humidity": 49
}
}The goal of my RPi project was to create a simple app (single responsive HTML dashboard) that allows me to monitor my HVAC system. It pulls data from four sources:
Here's a photo of the finished install. The pipes on the left are the hydronic supply and return for one of the zones, with the zone valve bottom middle. The right side is a vertically mounted DIN rail. At the top of the rail are feed-throughs for all of the zones and power (kind of like a customizable punch-down block), using Phoenix Contact DIN rail mounted modular terminal blocks. In the middle are the Magnecraft relays (with timer and alternating relays at bottom to trim chiller runs), and at the bottom is the RPi in a commercially available DIN box (Phoenix Contact). On the left of the RPI is the header where the relay and 1-wire inputs go in. The RPi is powered by a 24VAC to 5VDC transformer (just visible under the header) that allows me to run the RPi off the standard HVAC power supply.

These are pretty commonly used sensors, because they are cheap and easy to use. There are plenty of tutorials on how to wire these (e.g. this one), so I'm not going to cover here. The best Python library I found for these is w1thermsensor, so that's the one I use. Note that without some hacking the data line for the 1-wire bus must be GPIO pin 4. I prefer to power the sensors rather than use "parasitic" mode (which has some limitations), but that's just me.
The RPi supports several protocols out of the box, such as I2C and SPI. 1-Wire suited my needs, so that's the only one pivac currently supports. The module framework can be easily extended for these by following the 1-Wire Therm example.
The GPIO pins on the RPi are a good way to collect data. A good way to know which pins you can/should use for inputs is to use a pin mapping chart, like this one. Make sure to use the one appropriate for your Pi.
When reading from a digital pin, in order to get a consistent reading you need to pull it up to a known voltage (e.g. VCC, 3.3V on the board), or pull it down to ground. If you pull up, then you can signal a change by grounding the pin to board ground. If you pull it to ground, then you need to send it a voltage. The ground and the voltage need to be from the same source, so best to reference board ground and board 3.3v for these pins.
The RPi provides both pull-up and pull-down resistors for the pins (if you don't know what these are, see here). I use pull-ups, so my circuits are normally connected only to board ground unless my relays close. You may have your own purposes. My library lets you configure a pin as either pull-up or pull-down. Technically you can set them all individually but it's easier to remember if you do one or the other.
The TED5000 is a power panel monitor that allows you to monitor energy consumption in your home by placing CTs (current transformers) on your main feed or subcircuits in your home's power panel. A small gateway attached to the CTs runs a web server that publishes a website accessible on your local network, that allows you to view a dashboard for current and historical data, charting, and also publishes XML-based data via HTTP GET.
The gateway can be a little flaky and also it's a closed ecosystem. You can't easily integrate it with anything else, except by using a couple of APIs it provides. One is a built in capability to publish historical data in one-minute intervals. Another is the "real time" HTTP URL that allows you to collect the current values of all the system parameters in a structured HTML document.
I opted for using the "real time" interface, since that would allow me to control how often and where the data are reported. So my python script calls the real time interface URL, parses the response using the Python lxml parser, and prints the "PowerNow" values for the four possible MTUs (I have 3) to stdout as a JSON-formatted object.
Others may be interested in more or different values from the real-time XML document. The script can easily be extended as desired. Note: TED5000 has been discontinued and is difficult to source; the module remains in pivac for existing users.
This is a website targeted specifically at owners of Honeywell WiFi thermostats, or RedLink thermostats connected to a RedLink gateway. Honeywell does not make the data APIs for this site publicly available. There are APIs called by the site, but more header spoofing would be required to get the server to generate a valid request. The same information can be retrieved by screen-scraping the site, so I didn't bother to decode the API headers.
This code makes a number of assumptions, so if your personal use is different, you'll have to tweak the scraping code, which uses Mechanize.
Some points to keep in mind:
There is a site that provides an undocumented way to access Honeywell's REST API interface, here.
The ArduinoSensor module polls a small Arduino web server over HTTP. The Arduino reads a ratiometric pressure sensor (0.5–4.5V output), converts the voltage to PSI, and returns it as a simple JSON response. This approach is useful when you need analog inputs that the RPi doesn't natively support well.
A single module implementation can serve multiple sensor instances by using the module: key in each config section. For example, the hydronic loop and DHW pressure sensors each have their own config section (pivac.ArduinoPSI and pivac.ArduinoThermPSI) with different IP addresses, both pointing to module: pivac.ArduinoSensor.
The Arduinos are configured with static IP addresses in your config file. If an Arduino is unreachable (timeout), a warning is logged and the module returns an empty delta — the service continues running and retries on the next poll interval.
pivac is free for personal and other noncommercial use. Commercial use, including installing it for a customer, building it into a product, or selling boards made from these designs, needs a separate licence from the copyright holder; ask through github.com/dglcinc.
| Content | Licence |
|---|---|
| Code, scripts, firmware, configuration | PolyForm Noncommercial 1.0.0 (LICENSE) |
| Documents, drawings, images, board designs | CC BY-NC 4.0 (LICENSE-DOCS) |
hardware/vendor/ | Each maker's own terms |
pivac/, scripts/, tests/, config/, grafana/, the generator scripts in hardware/, and the package files. Source files carry an SPDX-License-Identifier line.docs/, this README, the KiCad projects, gerbers and fabrication outputs in hardware/, and the architecture slides.hardware/vendor/ holds Phoenix Contact's 3D models, which stay under Phoenix Contact's terms.| Qty | Value | Footprint | References |
|---|---|---|---|
| 5 | 1k | R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R3, R4, R9, R10, R16 |
| 4 | 2k2 | R_1206_3216Metric_Pad1.30x1.75mm_HandSolder | R5, R6, R7, R8 |
| 3 | 100n | C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C4, C5, C6 |
| 3 | 10k | R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R11, R12, R17 |
| 3 | 4k7 | R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R13, R14, R15 |
| 2 | 10k0 0.1% | R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R1, R2 |
| 2 | 1812L020/60DR | Fuse_1812_4532Metric_Pad1.30x3.40mm_HandSolder | F1, F2 |
| 2 | 1N4148W | D_SOD-123 | D3, D4 |
| 2 | 1u | C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C7, C8 |
| 2 | Arduino header | pivac:ArduinoHeader_1x8 | J11, J12 |
| 2 | LTV-814S | SMDIP-4_W9.53mm | U3, U4 |
| 1 | 100R | R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R18 |
| 1 | 100u 63V | CP_Elec_10x10.5 | C1 |
| 1 | 10u | C_1206_3216Metric_Pad1.33x1.80mm_HandSolder | C2 |
| 1 | 1n C0G | C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C9 |
| 1 | 22u | C_1206_3216Metric_Pad1.33x1.80mm_HandSolder | C3 |
| 1 | Arduino header | pivac:ArduinoHeader_1x10 | J10 |
| 1 | Arduino header | pivac:ArduinoHeader_1x6 | J13 |
| 1 | C | pivac:TestLoop | TP2 |
| 1 | DATA->D2 | SolderJumper-2_P1.3mm_Open_RoundedPad1.0x1.5mm | JP1 |
| 1 | DS2482S-100+ | SOIC-8_3.9x4.9mm_P1.27mm | U2 |
| 1 | MC 1,5/4-G-3,81 24VAC | PhoenixContact_MC_1,5_4-G-3.81_1x04_P3.81mm_Horizontal | TB1 |
| 1 | PTSM 0,5/3-HH-2,5-SMD 1-wire | pivac:PTSM_0.5_3-HH-2.5-SMD | TB3 |
| 1 | PTSM 0,5/3-HH-2,5-SMD flow | pivac:PTSM_0.5_3-HH-2.5-SMD | TB4 |
| 1 | PTSM 0,5/4-HH-2,5-SMD air | pivac:PTSM_0.5_4-HH-2.5-SMD | TB2 |
| 1 | RF | pivac:TestLoop | TP3 |
| 1 | S1M | D_SMA | D1 |
| 1 | SMAJ43CA | D_SMA | D2 |
| 1 | TMR 3-4811WI | pivac:TMR3WI_TMR12WI_SIP-8 | U1 |
| 1 | VS | pivac:TestLoop | TP1 |
| 1 | blue | LED_0805_2012Metric_Pad1.15x1.40mm_HandSolder | LED2 |
| 1 | green PWR | LED_0805_2012Metric_Pad1.15x1.40mm_HandSolder | LED1 |
| 1 | red | LED_0805_2012Metric_Pad1.15x1.40mm_HandSolder | LED3 |
| 1 | test row | pivac:TestRow_1x12 | J1 |

dglcinc/pivac
Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)

dglcinc/pivac
Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)

dglcinc/pivac
Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)

dglcinc/pivac
Python library to vacuum data from Raspberry-Pi-based monitoring and control solutions (like HVAC)
siliconvalleyar-oss/kicad_preview
KiCad Preview - Flutter viewer for KiCad schematics and PCBs

JohnNeville/SunSprout
An esp32-c5 powered board that adds dual source battery charging, fuel management, and differential i2c bus. This was largely developed to be a complement with my other soil sensor project.

alexthomazo/remora
Contrôleur fil pilote permettant de contrôler 7 zones et un relai.



wa1hco/rotator_controller
Clean slate rebuild of full featured rotator controller.

MadsRudolph/vinyl-adc
Discrete 3rd-order delta-sigma stereo audio ADC, built from op-amps and logic gates: a four-layer Raspberry Pi HAT made by PCBWay, with KiCad files, SPICE simulations and measurements

howie-j/opensolder
Fully open source JBC T245-compatible soldering station
It measures 86.4 × 53.3 mm and has 2 copper layers, 1.6 mm thick.
53 parts, built around the DS2482S-100+, LTV-814S, 1812L020/60DR and 1N4148W. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
From the dglcinc/pivac repository on GitHub, at the commit this page was made from: the board is hardware/ah-board/ah-board.kicad_pcb and its schematic hardware/ah-board/ah-board.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask dglcinc before reusing the design.