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.
@@ -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'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dredger
4
+ module IoT
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -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: []