dredger-iot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +33 -0
- data/LICENSE.txt +21 -0
- data/README.md +521 -0
- data/lib/dredger/iot/bus/auto.rb +87 -0
- data/lib/dredger/iot/bus/gpio.rb +59 -0
- data/lib/dredger/iot/bus/gpio_label_adapter.rb +41 -0
- data/lib/dredger/iot/bus/gpio_libgpiod.rb +63 -0
- data/lib/dredger/iot/bus/i2c.rb +55 -0
- data/lib/dredger/iot/bus/i2c_linux.rb +52 -0
- data/lib/dredger/iot/bus.rb +5 -0
- data/lib/dredger/iot/pins/beaglebone.rb +56 -0
- data/lib/dredger/iot/pins.rb +3 -0
- data/lib/dredger/iot/reading.rb +28 -0
- data/lib/dredger/iot/scheduler.rb +43 -0
- data/lib/dredger/iot/sensors/base_sensor.rb +31 -0
- data/lib/dredger/iot/sensors/bme280.rb +26 -0
- data/lib/dredger/iot/sensors/bme280_provider.rb +157 -0
- data/lib/dredger/iot/sensors/bmp180.rb +26 -0
- data/lib/dredger/iot/sensors/dht22.rb +26 -0
- data/lib/dredger/iot/sensors/dht22_provider.rb +79 -0
- data/lib/dredger/iot/sensors/ds18b20.rb +24 -0
- data/lib/dredger/iot/sensors/ds18b20_provider.rb +55 -0
- data/lib/dredger/iot/sensors/mcp9808.rb +23 -0
- data/lib/dredger/iot/sensors.rb +11 -0
- data/lib/dredger/iot/version.rb +7 -0
- data/lib/dredger/iot.rb +14 -0
- metadata +112 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for DHT22/DHT11 sensors via GPIO bit-banging.
|
|
7
|
+
# Implements the DHT22 1-wire-like protocol:
|
|
8
|
+
# 1. Pull pin low for 1-10ms (start signal)
|
|
9
|
+
# 2. Pull high and wait for sensor response (80us low, 80us high)
|
|
10
|
+
# 3. Read 40 bits (5 bytes): humidity_hi, humidity_lo, temp_hi, temp_lo, checksum
|
|
11
|
+
# 4. Bit timing: ~50us low start + 26-28us high=0 or 70us high=1
|
|
12
|
+
class DHT22Provider
|
|
13
|
+
# gpio_bus: a GPIO bus interface (e.g., Dredger::IoT::Bus::Auto.gpio)
|
|
14
|
+
def initialize(gpio_bus:)
|
|
15
|
+
@gpio = gpio_bus
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Sample the DHT22 sensor on the given pin.
|
|
19
|
+
# Returns { humidity: Float, temperature_c: Float } or raises on error.
|
|
20
|
+
# Note: This is a simplified bit-bang implementation. Real production code would need:
|
|
21
|
+
# - Precise microsecond timing (Ruby is not ideal; consider C extension or kernel driver)
|
|
22
|
+
# - Retry logic and timeout handling
|
|
23
|
+
# - Support for both DHT11 and DHT22 data formats
|
|
24
|
+
def sample(pin_label)
|
|
25
|
+
# Send start signal: pull low for ~1ms, then high
|
|
26
|
+
@gpio.set_direction(pin_label, :out)
|
|
27
|
+
@gpio.write(pin_label, 0)
|
|
28
|
+
sleep(0.001) # 1ms low
|
|
29
|
+
@gpio.write(pin_label, 1)
|
|
30
|
+
sleep(0.00004) # 40us high
|
|
31
|
+
|
|
32
|
+
# Switch to input and read response
|
|
33
|
+
@gpio.set_direction(pin_label, :in)
|
|
34
|
+
|
|
35
|
+
# Wait for sensor to pull low (80us), then high (80us)
|
|
36
|
+
# In a real implementation, we'd wait with timeout and verify timing
|
|
37
|
+
sleep(0.00016) # ~160us for response
|
|
38
|
+
|
|
39
|
+
# Read 40 bits of data (5 bytes)
|
|
40
|
+
# This is highly simplified - real bit-banging requires microsecond precision
|
|
41
|
+
# For production, use a kernel module or C extension with RT priority
|
|
42
|
+
bytes = read_40_bits(pin_label)
|
|
43
|
+
|
|
44
|
+
# Verify checksum
|
|
45
|
+
checksum = (bytes[0] + bytes[1] + bytes[2] + bytes[3]) & 0xFF
|
|
46
|
+
raise IOError, 'DHT22 checksum mismatch' unless checksum == bytes[4]
|
|
47
|
+
|
|
48
|
+
# Parse DHT22 format (16-bit values, 0.1 resolution)
|
|
49
|
+
humidity_raw = (bytes[0] << 8) | bytes[1]
|
|
50
|
+
temp_raw = (bytes[2] << 8) | bytes[3]
|
|
51
|
+
|
|
52
|
+
# Handle negative temperature (MSB of temp_raw)
|
|
53
|
+
temp_raw = -(temp_raw & 0x7FFF) if temp_raw.anybits?(0x8000)
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
humidity: humidity_raw / 10.0,
|
|
57
|
+
temperature_c: temp_raw / 10.0
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Read 40 bits from the sensor.
|
|
64
|
+
# This is a stub - real implementation requires precise timing.
|
|
65
|
+
# In production, consider using a kernel driver or hardware peripheral.
|
|
66
|
+
def read_40_bits(_pin_label)
|
|
67
|
+
# Placeholder: return simulated data for now
|
|
68
|
+
# Real implementation would read GPIO with microsecond timing
|
|
69
|
+
# For each bit: wait for low->high transition, measure high duration
|
|
70
|
+
# If high > 40us, bit=1; else bit=0
|
|
71
|
+
warn 'DHT22Provider: bit-banging not fully implemented, returning stub data'
|
|
72
|
+
# humidity=65.2% => 0x028C, temp=31.4°C => 0x013A
|
|
73
|
+
# checksum = (0x02 + 0x8C + 0x01 + 0x3A) & 0xFF = 0xC9
|
|
74
|
+
[0x02, 0x8C, 0x01, 0x3A, 0xC9]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# DS18B20 digital temperature sensor (1-Wire protocol)
|
|
7
|
+
# Uses a provider interface to allow simulation in tests and hardware backends in production.
|
|
8
|
+
class DS18B20 < BaseSensor
|
|
9
|
+
# provider must respond to :read_temperature(device_id) -> Float (celsius)
|
|
10
|
+
def initialize(device_id:, provider:, metadata: {})
|
|
11
|
+
super(metadata: metadata)
|
|
12
|
+
@device_id = device_id
|
|
13
|
+
@provider = provider
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def readings
|
|
17
|
+
temp_c = @provider.read_temperature(@device_id)
|
|
18
|
+
[reading(sensor_type: 'temperature', value: temp_c, unit: 'celsius')]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
# EOF
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for DS18B20 1-Wire temperature sensor.
|
|
7
|
+
# Uses the Linux kernel w1-gpio module (w1_therm driver).
|
|
8
|
+
#
|
|
9
|
+
# Setup:
|
|
10
|
+
# 1. Enable w1-gpio in device tree or config.txt (Raspberry Pi)
|
|
11
|
+
# 2. Load modules: modprobe w1-gpio && modprobe w1-therm
|
|
12
|
+
# 3. Devices appear in /sys/bus/w1/devices/28-*/w1_slave
|
|
13
|
+
#
|
|
14
|
+
# Device IDs are 64-bit unique addresses, typically formatted as:
|
|
15
|
+
# "28-0000056789ab" (family code 28 = DS18B20)
|
|
16
|
+
class DS18B20Provider
|
|
17
|
+
W1_BASE_PATH = '/sys/bus/w1/devices'
|
|
18
|
+
|
|
19
|
+
def initialize(base_path: W1_BASE_PATH)
|
|
20
|
+
@base_path = base_path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Read temperature from DS18B20 sensor.
|
|
24
|
+
# device_id: device address (e.g., "28-0000056789ab")
|
|
25
|
+
# Returns temperature in Celsius as Float
|
|
26
|
+
def read_temperature(device_id)
|
|
27
|
+
device_path = File.join(@base_path, device_id, 'w1_slave')
|
|
28
|
+
raise IOError, "DS18B20 device not found: #{device_id}" unless File.exist?(device_path)
|
|
29
|
+
|
|
30
|
+
# Read device file (contains CRC check and temperature)
|
|
31
|
+
content = File.read(device_path)
|
|
32
|
+
lines = content.split("\n")
|
|
33
|
+
|
|
34
|
+
# First line contains CRC status: "xx xx xx xx xx xx xx xx xx : crc=xx YES"
|
|
35
|
+
raise IOError, 'DS18B20 CRC check failed' unless lines[0]&.end_with?('YES')
|
|
36
|
+
|
|
37
|
+
# Second line contains temperature: "xx xx xx xx xx xx xx xx xx t=23437"
|
|
38
|
+
temp_match = lines[1]&.match(/t=(-?\d+)/)
|
|
39
|
+
raise IOError, 'DS18B20 temperature parse failed' unless temp_match
|
|
40
|
+
|
|
41
|
+
# Temperature is in millidegrees Celsius
|
|
42
|
+
temp_match[1].to_i / 1000.0
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# List all connected DS18B20 devices
|
|
46
|
+
def list_devices
|
|
47
|
+
return [] unless Dir.exist?(@base_path)
|
|
48
|
+
|
|
49
|
+
Dir.glob(File.join(@base_path, '28-*')).map { |path| File.basename(path) }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
# EOF
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# MCP9808 high-accuracy I2C temperature sensor
|
|
7
|
+
# Provider must respond to :read_temperature(addr) -> Float (celsius)
|
|
8
|
+
class MCP9808 < BaseSensor
|
|
9
|
+
def initialize(i2c_addr:, provider:, metadata: {})
|
|
10
|
+
super(metadata: metadata)
|
|
11
|
+
@i2c_addr = i2c_addr
|
|
12
|
+
@provider = provider
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def readings
|
|
16
|
+
temp_c = @provider.read_temperature(@i2c_addr)
|
|
17
|
+
[reading(sensor_type: 'temperature', value: temp_c, unit: 'celsius')]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
# EOF
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'sensors/base_sensor'
|
|
4
|
+
require_relative 'sensors/dht22'
|
|
5
|
+
require_relative 'sensors/dht22_provider'
|
|
6
|
+
require_relative 'sensors/bme280'
|
|
7
|
+
require_relative 'sensors/bme280_provider'
|
|
8
|
+
require_relative 'sensors/ds18b20'
|
|
9
|
+
require_relative 'sensors/ds18b20_provider'
|
|
10
|
+
require_relative 'sensors/bmp180'
|
|
11
|
+
require_relative 'sensors/mcp9808'
|
data/lib/dredger/iot.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'iot/version'
|
|
4
|
+
require_relative 'iot/reading'
|
|
5
|
+
require_relative 'iot/scheduler'
|
|
6
|
+
require_relative 'iot/bus'
|
|
7
|
+
require_relative 'iot/pins'
|
|
8
|
+
require_relative 'iot/sensors'
|
|
9
|
+
|
|
10
|
+
module Dredger
|
|
11
|
+
module IoT
|
|
12
|
+
class Error < StandardError; end
|
|
13
|
+
end
|
|
14
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dredger-iot
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- The Mad Botter INC
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ffi
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.15'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.15'
|
|
26
|
+
description: |
|
|
27
|
+
Dredger-IoT provides FFI-based GPIO and I2C access for embedded Linux systems like Beaglebone Black.
|
|
28
|
+
Features include: libgpiod GPIO backend, Linux i2c-dev I2C backend, simulation backends for testing,
|
|
29
|
+
sensor drivers (DHT22, BME280, DS18B20, BMP180, MCP9808), Beaglebone pin label mapping, and
|
|
30
|
+
scheduling utilities for periodic polling and exponential backoff.
|
|
31
|
+
email:
|
|
32
|
+
- opensource@themadbotter.com
|
|
33
|
+
executables: []
|
|
34
|
+
extensions: []
|
|
35
|
+
extra_rdoc_files: []
|
|
36
|
+
files:
|
|
37
|
+
- CHANGELOG.md
|
|
38
|
+
- LICENSE.txt
|
|
39
|
+
- README.md
|
|
40
|
+
- lib/dredger/iot.rb
|
|
41
|
+
- lib/dredger/iot/bus.rb
|
|
42
|
+
- lib/dredger/iot/bus/auto.rb
|
|
43
|
+
- lib/dredger/iot/bus/gpio.rb
|
|
44
|
+
- lib/dredger/iot/bus/gpio_label_adapter.rb
|
|
45
|
+
- lib/dredger/iot/bus/gpio_libgpiod.rb
|
|
46
|
+
- lib/dredger/iot/bus/i2c.rb
|
|
47
|
+
- lib/dredger/iot/bus/i2c_linux.rb
|
|
48
|
+
- lib/dredger/iot/pins.rb
|
|
49
|
+
- lib/dredger/iot/pins/beaglebone.rb
|
|
50
|
+
- lib/dredger/iot/reading.rb
|
|
51
|
+
- lib/dredger/iot/scheduler.rb
|
|
52
|
+
- lib/dredger/iot/sensors.rb
|
|
53
|
+
- lib/dredger/iot/sensors/base_sensor.rb
|
|
54
|
+
- lib/dredger/iot/sensors/bme280.rb
|
|
55
|
+
- lib/dredger/iot/sensors/bme280_provider.rb
|
|
56
|
+
- lib/dredger/iot/sensors/bmp180.rb
|
|
57
|
+
- lib/dredger/iot/sensors/dht22.rb
|
|
58
|
+
- lib/dredger/iot/sensors/dht22_provider.rb
|
|
59
|
+
- lib/dredger/iot/sensors/ds18b20.rb
|
|
60
|
+
- lib/dredger/iot/sensors/ds18b20_provider.rb
|
|
61
|
+
- lib/dredger/iot/sensors/mcp9808.rb
|
|
62
|
+
- lib/dredger/iot/version.rb
|
|
63
|
+
homepage: https://github.com/TheMadBotterINC/dredger-iot
|
|
64
|
+
licenses:
|
|
65
|
+
- MIT
|
|
66
|
+
metadata:
|
|
67
|
+
platforms: Hardware backends require Linux. Simulation works everywhere.
|
|
68
|
+
homepage_uri: https://github.com/TheMadBotterINC/dredger-iot
|
|
69
|
+
source_code_uri: https://github.com/TheMadBotterINC/dredger-iot
|
|
70
|
+
changelog_uri: https://github.com/TheMadBotterINC/dredger-iot/blob/master/CHANGELOG.md
|
|
71
|
+
bug_tracker_uri: https://github.com/TheMadBotterINC/dredger-iot/issues
|
|
72
|
+
documentation_uri: https://github.com/TheMadBotterINC/dredger-iot/blob/master/README.md
|
|
73
|
+
rubygems_mfa_required: 'true'
|
|
74
|
+
keywords: iot, embedded, linux, gpio, i2c, beaglebone, raspberry-pi, hardware, sensors,
|
|
75
|
+
dht22, bme280, ds18b20, bmp180, mcp9808, libgpiod, automation
|
|
76
|
+
post_install_message: "\n═══════════════════════════════════════════════════════════════════\n
|
|
77
|
+
\ \n _______________
|
|
78
|
+
\ \n | DREDGER-IoT | \n
|
|
79
|
+
\ |_______________| \n /|
|
|
80
|
+
\ ___ ___ | \n / | |___| |___||
|
|
81
|
+
\ \n / |______________| \n
|
|
82
|
+
\ ====|========================|==== \n | | |-----------|
|
|
83
|
+
\ | | \n | |____| |_____| | \n
|
|
84
|
+
\ ___|____| |____|___ \n~~~~{________|_________________________|________}~~~~~~~
|
|
85
|
+
\ \n ~~ | \\ // | ~~~ \n |
|
|
86
|
+
\ \\___________________// | \n |_____________________________|
|
|
87
|
+
\ \n ~~~ \\ // ~~~ \n
|
|
88
|
+
\ \\_______________// \n═══════════════════════════════════════════════════════════════════\n
|
|
89
|
+
\ Hardware Integration for Embedded Linux v0.1.0\n═══════════════════════════════════════════════════════════════════\n\n\U0001F389
|
|
90
|
+
Thanks for installing!\n\n\U0001F4DA Hardware Setup (kernel modules & permissions):\n
|
|
91
|
+
\ https://github.com/TheMadBotterINC/dredger-iot#hardware-setup\n\n\U0001F680 Quick
|
|
92
|
+
Start:\n require 'dredger/iot'\n gpio = Dredger::IoT::Bus::Auto.gpio\n i2c
|
|
93
|
+
\ = Dredger::IoT::Bus::Auto.i2c\n\n\U0001F4A1 Supported Sensors:\n DHT22, BME280,
|
|
94
|
+
DS18B20, BMP180, MCP9808\n\n\U0001F4D6 Full Documentation:\n https://github.com/TheMadBotterINC/dredger-iot\n\n"
|
|
95
|
+
rdoc_options: []
|
|
96
|
+
require_paths:
|
|
97
|
+
- lib
|
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.1'
|
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - ">="
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '0'
|
|
108
|
+
requirements: []
|
|
109
|
+
rubygems_version: 3.6.9
|
|
110
|
+
specification_version: 4
|
|
111
|
+
summary: Generic hardware integration for embedded Linux (GPIO, I2C) with sensor drivers.
|
|
112
|
+
test_files: []
|