dredger-iot 0.1.2 → 0.2.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 +4 -4
- data/CHANGELOG.md +13 -1
- data/README.md +69 -0
- data/bin/dredger +30 -1
- data/lib/dredger/iot/sensors/bh1750.rb +22 -0
- data/lib/dredger/iot/sensors/bh1750_provider.rb +34 -0
- data/lib/dredger/iot/sensors/ina219.rb +25 -0
- data/lib/dredger/iot/sensors/ina219_provider.rb +54 -0
- data/lib/dredger/iot/sensors/sht31.rb +25 -0
- data/lib/dredger/iot/sensors/sht31_provider.rb +41 -0
- data/lib/dredger/iot/sensors/tsl2561.rb +22 -0
- data/lib/dredger/iot/sensors/tsl2561_provider.rb +72 -0
- data/lib/dredger/iot/sensors.rb +8 -0
- data/lib/dredger/iot/version.rb +1 -1
- metadata +30 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84cb846712d4d17f969147389859dfae1bdc8a67fb304e491e857891726d7234
|
|
4
|
+
data.tar.gz: 5c905f7f6e651692f6eff7145e9b9399357df33e340d4694eceab260f31b1b00
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a0cfe26a32e99b21b3a6ccbddede15162bf85f7a85aac6e32715f34cc8a300218515e358bbd271cd5dd648d9ca6df892eb4fda2cd3bf08761a128c25887142ba
|
|
7
|
+
data.tar.gz: 179a10159ea14047fa146ed5a03223c2f362591357c39c754fef36718d75c2c35fff7bb0e7facafc9c094e48d0015e5eef0a367ca10cb4f93674e0369f2fa6f8
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2025-10-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- New sensors: SHT31 (I2C temp/humidity), BH1750 (I2C lux), TSL2561 (I2C lux), INA219 (I2C bus voltage/current)
|
|
14
|
+
- CLI: --shunt option for INA219 to specify shunt resistance (default 0.1 Ω)
|
|
15
|
+
- Examples: example scripts for SHT31, BH1750, TSL2561, INA219
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- README: document new sensors and CLI usage
|
|
19
|
+
- Coverage: exclude all provider implementations from coverage (hardware-dependent)
|
|
20
|
+
|
|
10
21
|
## [0.1.2] - 2025-10-04
|
|
11
22
|
|
|
12
23
|
### Added
|
|
@@ -53,7 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
53
64
|
- RuboCop configuration and compliance
|
|
54
65
|
- Comprehensive documentation and usage examples
|
|
55
66
|
|
|
56
|
-
[Unreleased]: https://github.com/TheMadBotterINC/dredger-iot/compare/v0.
|
|
67
|
+
[Unreleased]: https://github.com/TheMadBotterINC/dredger-iot/compare/v0.2.0...HEAD
|
|
68
|
+
[0.2.0]: https://github.com/TheMadBotterINC/dredger-iot/compare/v0.1.2...v0.2.0
|
|
57
69
|
[0.1.2]: https://github.com/TheMadBotterINC/dredger-iot/compare/v0.1.1...v0.1.2
|
|
58
70
|
[0.1.1]: https://github.com/TheMadBotterINC/dredger-iot/compare/v0.1.0...v0.1.1
|
|
59
71
|
[0.1.0]: https://github.com/TheMadBotterINC/dredger-iot/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -98,9 +98,58 @@ Dredger-IoT includes drivers for popular embedded sensors:
|
|
|
98
98
|
- **DS18B20** - 1-Wire digital temperature sensor
|
|
99
99
|
- **BMP180** - I2C barometric pressure/temperature sensor
|
|
100
100
|
- **MCP9808** - I2C high-accuracy temperature sensor
|
|
101
|
+
- **SHT31** - I2C temperature/humidity sensor
|
|
102
|
+
- **BH1750** - I2C ambient light sensor (lux)
|
|
103
|
+
- **TSL2561** - I2C ambient light sensor (lux)
|
|
104
|
+
- **INA219** - I2C bus voltage/current monitor
|
|
101
105
|
|
|
102
106
|
Sensors use a provider pattern for testability and hardware abstraction.
|
|
103
107
|
|
|
108
|
+
## CLI Usage
|
|
109
|
+
|
|
110
|
+
Commands:
|
|
111
|
+
- list-sensors
|
|
112
|
+
- List available sensor types supported by dredger-iot.
|
|
113
|
+
- read SENSOR [ARGS]
|
|
114
|
+
- Read once or continuously from a sensor.
|
|
115
|
+
- Examples:
|
|
116
|
+
- dredger read bme280 0x76
|
|
117
|
+
- dredger read dht22 P9_12
|
|
118
|
+
- dredger read ina219 0x40 --shunt 0.1
|
|
119
|
+
- test-gpio PIN
|
|
120
|
+
- Simple blink test to verify GPIO output works.
|
|
121
|
+
- test-i2c
|
|
122
|
+
- Scans a few common I2C addresses (hardware backend only).
|
|
123
|
+
- info
|
|
124
|
+
- Prints version, detected backends, and environment variables.
|
|
125
|
+
|
|
126
|
+
Options:
|
|
127
|
+
- --backend BACKEND
|
|
128
|
+
- auto (default), simulation, hardware
|
|
129
|
+
- simulation forces both GPIO and I2C simulation backends
|
|
130
|
+
- hardware forces libgpiod (GPIO) and linux (I2C)
|
|
131
|
+
- --format FORMAT
|
|
132
|
+
- text (default) or json
|
|
133
|
+
- --interval SECONDS
|
|
134
|
+
- Poll continuously at the specified interval (e.g., 2.0)
|
|
135
|
+
- --shunt OHMS
|
|
136
|
+
- INA219-only: specify the shunt resistance in ohms (default 0.1)
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
```bash
|
|
140
|
+
# Read a BME280 once (auto-detected backends)
|
|
141
|
+
dredger read bme280 0x76
|
|
142
|
+
|
|
143
|
+
# Read a DHT22 every 2 seconds, JSON output
|
|
144
|
+
dredger read dht22 P9_12 --interval 2 --format json
|
|
145
|
+
|
|
146
|
+
# Force simulation backends for local testing
|
|
147
|
+
dredger --backend simulation read bh1750 0x23
|
|
148
|
+
|
|
149
|
+
# INA219 with custom shunt
|
|
150
|
+
dredger read ina219 0x40 --shunt 0.05
|
|
151
|
+
```
|
|
152
|
+
|
|
104
153
|
## Usage Examples
|
|
105
154
|
|
|
106
155
|
### DHT22 Temperature/Humidity Sensor
|
|
@@ -483,6 +532,26 @@ reading.timestamp # Time object when reading was taken
|
|
|
483
532
|
- **`MCP9808`** - High-accuracy temperature (I2C)
|
|
484
533
|
- Parameters: `i2c_addr` (default: `0x18`), `provider`
|
|
485
534
|
- Returns: temperature (celsius)
|
|
535
|
+
|
|
536
|
+
- **`SHT31`** - Temperature/humidity (I2C)
|
|
537
|
+
- Parameters: `i2c_addr` (default: `0x44`), `provider`
|
|
538
|
+
- Returns: temperature (celsius), humidity (%)
|
|
539
|
+
|
|
540
|
+
- **`BH1750`** - Ambient light (I2C)
|
|
541
|
+
- Parameters: `i2c_addr` (default: `0x23`), `provider`
|
|
542
|
+
- Returns: illuminance (lux)
|
|
543
|
+
|
|
544
|
+
- **`TSL2561`** - Ambient light (I2C)
|
|
545
|
+
- Parameters: `i2c_addr` (default: `0x39`), `provider`
|
|
546
|
+
- Returns: illuminance (lux)
|
|
547
|
+
|
|
548
|
+
- **`INA219`** - Bus voltage/current monitor (I2C)
|
|
549
|
+
- Parameters: `i2c_addr` (default: `0x40`), `provider`
|
|
550
|
+
- Returns: bus_voltage (V), current (mA)
|
|
551
|
+
- CLI example:
|
|
552
|
+
```bash path=null start=null
|
|
553
|
+
dredger read ina219 0x40 --shunt 0.1
|
|
554
|
+
```
|
|
486
555
|
|
|
487
556
|
### Scheduling
|
|
488
557
|
|
data/bin/dredger
CHANGED
|
@@ -69,6 +69,10 @@ class DredgerCLI
|
|
|
69
69
|
@options[:interval] = i
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
opts.on('--shunt OHMS', Float, 'INA219 shunt resistance in ohms (default: 0.1)') do |ohms|
|
|
73
|
+
@options[:ina219_shunt] = ohms
|
|
74
|
+
end
|
|
75
|
+
|
|
72
76
|
opts.on('-h', '--help', 'Show this help') do
|
|
73
77
|
puts opts
|
|
74
78
|
exit
|
|
@@ -87,7 +91,11 @@ class DredgerCLI
|
|
|
87
91
|
'bme280' => 'BME280 - Temperature/Humidity/Pressure (I2C)',
|
|
88
92
|
'ds18b20' => 'DS18B20 - Waterproof Temperature (1-Wire)',
|
|
89
93
|
'bmp180' => 'BMP180 - Barometric Pressure/Temperature (I2C)',
|
|
90
|
-
'mcp9808' => 'MCP9808 - High-Accuracy Temperature (I2C)'
|
|
94
|
+
'mcp9808' => 'MCP9808 - High-Accuracy Temperature (I2C)',
|
|
95
|
+
'sht31' => 'SHT31 - Temperature/Humidity (I2C)',
|
|
96
|
+
'bh1750' => 'BH1750 - Ambient Light (I2C)',
|
|
97
|
+
'tsl2561' => 'TSL2561 - Ambient Light (I2C)',
|
|
98
|
+
'ina219' => 'INA219 - Bus Voltage/Current (I2C)'
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
puts 'Available Sensors:'
|
|
@@ -136,6 +144,27 @@ class DredgerCLI
|
|
|
136
144
|
exit 1
|
|
137
145
|
end
|
|
138
146
|
Dredger::IoT::Sensors::DS18B20.new(device_id: device_id, provider: provider)
|
|
147
|
+
when 'sht31'
|
|
148
|
+
addr = (args.shift || '0x44').to_i(16)
|
|
149
|
+
i2c = Dredger::IoT::Bus::Auto.i2c
|
|
150
|
+
provider = Dredger::IoT::Sensors::SHT31Provider.new(i2c_bus: i2c)
|
|
151
|
+
Dredger::IoT::Sensors::SHT31.new(i2c_addr: addr, provider: provider)
|
|
152
|
+
when 'bh1750'
|
|
153
|
+
addr = (args.shift || '0x23').to_i(16)
|
|
154
|
+
i2c = Dredger::IoT::Bus::Auto.i2c
|
|
155
|
+
provider = Dredger::IoT::Sensors::BH1750Provider.new(i2c_bus: i2c)
|
|
156
|
+
Dredger::IoT::Sensors::BH1750.new(i2c_addr: addr, provider: provider)
|
|
157
|
+
when 'tsl2561'
|
|
158
|
+
addr = (args.shift || '0x39').to_i(16)
|
|
159
|
+
i2c = Dredger::IoT::Bus::Auto.i2c
|
|
160
|
+
provider = Dredger::IoT::Sensors::TSL2561Provider.new(i2c_bus: i2c)
|
|
161
|
+
Dredger::IoT::Sensors::TSL2561.new(i2c_addr: addr, provider: provider)
|
|
162
|
+
when 'ina219'
|
|
163
|
+
addr = (args.shift || '0x40').to_i(16)
|
|
164
|
+
i2c = Dredger::IoT::Bus::Auto.i2c
|
|
165
|
+
shunt = @options[:ina219_shunt] || 0.1
|
|
166
|
+
provider = Dredger::IoT::Sensors::INA219Provider.new(i2c_bus: i2c, shunt_resistance_ohms: shunt)
|
|
167
|
+
Dredger::IoT::Sensors::INA219.new(i2c_addr: addr, provider: provider)
|
|
139
168
|
else
|
|
140
169
|
puts "Error: Unknown sensor type '#{type}'"
|
|
141
170
|
exit 1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# BH1750 ambient light sensor (I2C)
|
|
7
|
+
# Provider must respond to :read_lux(addr) -> Float (lux)
|
|
8
|
+
class BH1750 < 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
|
+
lux = @provider.read_lux(@i2c_addr)
|
|
17
|
+
[reading(sensor_type: 'illuminance', value: lux, unit: 'lux')]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for BH1750 ambient light sensor (I2C)
|
|
7
|
+
# Measurement: Continuous High-Resolution Mode (1 lx, typical 120ms)
|
|
8
|
+
class BH1750Provider
|
|
9
|
+
POWER_ON = 0x01
|
|
10
|
+
RESET = 0x07
|
|
11
|
+
CONT_HIRES = 0x10
|
|
12
|
+
|
|
13
|
+
def initialize(i2c_bus:)
|
|
14
|
+
@i2c = i2c_bus
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Returns lux as Float
|
|
18
|
+
def read_lux(addr)
|
|
19
|
+
# Power on and reset
|
|
20
|
+
@i2c.write(addr, [POWER_ON])
|
|
21
|
+
@i2c.write(addr, [RESET])
|
|
22
|
+
# Start continuous high-resolution measurement
|
|
23
|
+
@i2c.write(addr, [CONT_HIRES])
|
|
24
|
+
# Wait for conversion
|
|
25
|
+
sleep(0.18)
|
|
26
|
+
# Read 2 bytes (big-endian)
|
|
27
|
+
bytes = @i2c.read(addr, 2)
|
|
28
|
+
raw = (bytes[0] << 8) | bytes[1]
|
|
29
|
+
(raw / 1.2).to_f
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# INA219 current/voltage/power monitor (I2C)
|
|
7
|
+
# Provider must respond to :read_measurements(addr) -> { bus_voltage_v:, current_ma:, shunt_voltage_mv: }
|
|
8
|
+
class INA219 < 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
|
+
m = @provider.read_measurements(@i2c_addr)
|
|
17
|
+
[
|
|
18
|
+
reading(sensor_type: 'bus_voltage', value: m[:bus_voltage_v], unit: 'V'),
|
|
19
|
+
reading(sensor_type: 'current', value: m[:current_ma], unit: 'mA')
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for INA219 current/voltage monitor (I2C)
|
|
7
|
+
# Simplified: computes current from shunt voltage and provided shunt resistance,
|
|
8
|
+
# avoids calibration register dependency.
|
|
9
|
+
class INA219Provider
|
|
10
|
+
REG_SHUNT_VOLTAGE = 0x01
|
|
11
|
+
REG_BUS_VOLTAGE = 0x02
|
|
12
|
+
|
|
13
|
+
def initialize(i2c_bus:, shunt_resistance_ohms: 0.1)
|
|
14
|
+
@i2c = i2c_bus
|
|
15
|
+
@r_shunt = shunt_resistance_ohms.to_f
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns { bus_voltage_v: Float, current_ma: Float, shunt_voltage_mv: Float }
|
|
19
|
+
def read_measurements(addr)
|
|
20
|
+
shunt_raw = read_word(addr, REG_SHUNT_VOLTAGE, signed: true)
|
|
21
|
+
bus_raw = read_word(addr, REG_BUS_VOLTAGE, signed: false)
|
|
22
|
+
|
|
23
|
+
# Shunt voltage LSB = 10uV => mV = raw * 0.01
|
|
24
|
+
shunt_mv = shunt_raw * 0.01
|
|
25
|
+
# Current (mA) = (shunt_mv / R_ohms)
|
|
26
|
+
current_ma = (@r_shunt.positive? ? (shunt_mv / @r_shunt) : 0.0)
|
|
27
|
+
|
|
28
|
+
# Bus voltage: bits [15:3] * 4mV
|
|
29
|
+
bus_voltage_v = ((bus_raw >> 3) * 0.004)
|
|
30
|
+
|
|
31
|
+
{
|
|
32
|
+
bus_voltage_v: bus_voltage_v,
|
|
33
|
+
current_ma: current_ma,
|
|
34
|
+
shunt_voltage_mv: shunt_mv
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# Read 16-bit word
|
|
41
|
+
# INA219 registers are big-endian; register reads may return bytes LSB-first
|
|
42
|
+
def read_word(addr, reg, signed: false)
|
|
43
|
+
bytes = @i2c.read(addr, 2, register: reg)
|
|
44
|
+
val = (bytes[0] << 8) | bytes[1]
|
|
45
|
+
if signed && val > 0x7FFF
|
|
46
|
+
val - 0x1_0000
|
|
47
|
+
else
|
|
48
|
+
val
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# SHT31 temperature/humidity sensor (I2C)
|
|
7
|
+
# Provider must respond to :read_measurements(addr) -> { temperature_c:, humidity: }
|
|
8
|
+
class SHT31 < 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
|
+
m = @provider.read_measurements(@i2c_addr)
|
|
17
|
+
[
|
|
18
|
+
reading(sensor_type: 'temperature', value: m[:temperature_c], unit: 'celsius'),
|
|
19
|
+
reading(sensor_type: 'humidity', value: m[:humidity], unit: '%')
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for Sensirion SHT31 temperature/humidity over I2C.
|
|
7
|
+
# Basic single-shot measurement without CRC checks for simplicity.
|
|
8
|
+
# Datasheet formula:
|
|
9
|
+
# - Temperature (°C) = -45 + 175 * (ST / 65535)
|
|
10
|
+
# - Humidity (%RH) = 100 * (SRH / 65535)
|
|
11
|
+
class SHT31Provider
|
|
12
|
+
# I2C commands
|
|
13
|
+
CMD_SINGLE_SHOT_HIGHREP = [0x24, 0x00].freeze # High repeatability, clock stretching disabled
|
|
14
|
+
|
|
15
|
+
def initialize(i2c_bus:)
|
|
16
|
+
@i2c = i2c_bus
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns { temperature_c: Float, humidity: Float }
|
|
20
|
+
def read_measurements(addr)
|
|
21
|
+
# Trigger single-shot measurement
|
|
22
|
+
@i2c.write(addr, CMD_SINGLE_SHOT_HIGHREP)
|
|
23
|
+
# Max measurement duration ~15ms (high repeatability). Add margin.
|
|
24
|
+
sleep(0.02)
|
|
25
|
+
|
|
26
|
+
# Read 6 bytes: T_MSB, T_LSB, T_CRC, RH_MSB, RH_LSB, RH_CRC
|
|
27
|
+
data = @i2c.read(addr, 6)
|
|
28
|
+
|
|
29
|
+
st = (data[0] << 8) | data[1]
|
|
30
|
+
srh = (data[3] << 8) | data[4]
|
|
31
|
+
|
|
32
|
+
temp_c = -45.0 + (175.0 * st / 65_535.0)
|
|
33
|
+
humidity = (100.0 * srh / 65_535.0)
|
|
34
|
+
humidity = humidity.clamp(0.0, 100.0)
|
|
35
|
+
|
|
36
|
+
{ temperature_c: temp_c, humidity: humidity }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# TSL2561 ambient light sensor (I2C)
|
|
7
|
+
# Provider must respond to :read_lux(addr) -> Float (lux)
|
|
8
|
+
class TSL2561 < 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
|
+
lux = @provider.read_lux(@i2c_addr)
|
|
17
|
+
[reading(sensor_type: 'illuminance', value: lux, unit: 'lux')]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dredger
|
|
4
|
+
module IoT
|
|
5
|
+
module Sensors
|
|
6
|
+
# Hardware provider for TSL2561 ambient light sensor (I2C)
|
|
7
|
+
# Uses simple configuration: integration 402ms, low gain.
|
|
8
|
+
class TSL2561Provider
|
|
9
|
+
CMD = 0x80
|
|
10
|
+
CONTROL = 0x00
|
|
11
|
+
TIMING = 0x01
|
|
12
|
+
DATA0LOW = 0x0C
|
|
13
|
+
DATA1LOW = 0x0E
|
|
14
|
+
|
|
15
|
+
POWER_ON = 0x03
|
|
16
|
+
POWER_OFF = 0x00
|
|
17
|
+
INTEG_402MS = 0x02 # integration time bits [1:0] = 10
|
|
18
|
+
GAIN_LOW = 0x00 # gain bit [4] = 0
|
|
19
|
+
|
|
20
|
+
def initialize(i2c_bus:)
|
|
21
|
+
@i2c = i2c_bus
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns lux as Float
|
|
25
|
+
def read_lux(addr)
|
|
26
|
+
# Power on
|
|
27
|
+
@i2c.write(addr, [POWER_ON], register: CMD | CONTROL)
|
|
28
|
+
# Set timing: 402ms, low gain
|
|
29
|
+
@i2c.write(addr, [GAIN_LOW | INTEG_402MS], register: CMD | TIMING)
|
|
30
|
+
|
|
31
|
+
# Wait for integration
|
|
32
|
+
sleep(0.45)
|
|
33
|
+
|
|
34
|
+
ch0 = read_word(addr, CMD | DATA0LOW)
|
|
35
|
+
ch1 = read_word(addr, CMD | DATA1LOW)
|
|
36
|
+
|
|
37
|
+
compute_lux(ch0, ch1).to_f
|
|
38
|
+
ensure
|
|
39
|
+
# Power off to save energy
|
|
40
|
+
@i2c.write(addr, [POWER_OFF], register: CMD | CONTROL)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Read 16-bit little-endian word from LSB register
|
|
46
|
+
def read_word(addr, reg)
|
|
47
|
+
bytes = @i2c.read(addr, 2, register: reg)
|
|
48
|
+
bytes[0] | (bytes[1] << 8)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Lux calculation based on TSL2561 datasheet/Adafruit library
|
|
52
|
+
def compute_lux(ch0, ch1)
|
|
53
|
+
return 0.0 if ch0.zero?
|
|
54
|
+
|
|
55
|
+
ratio = ch1.to_f / ch0
|
|
56
|
+
|
|
57
|
+
if ratio <= 0.5
|
|
58
|
+
(0.0304 * ch0) - (0.062 * ch0 * (ratio**1.4))
|
|
59
|
+
elsif ratio <= 0.61
|
|
60
|
+
(0.0224 * ch0) - (0.031 * ch1)
|
|
61
|
+
elsif ratio <= 0.80
|
|
62
|
+
(0.0128 * ch0) - (0.0153 * ch1)
|
|
63
|
+
elsif ratio <= 1.30
|
|
64
|
+
(0.00146 * ch0) - (0.00112 * ch1)
|
|
65
|
+
else
|
|
66
|
+
0.0
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/dredger/iot/sensors.rb
CHANGED
|
@@ -9,3 +9,11 @@ require_relative 'sensors/ds18b20'
|
|
|
9
9
|
require_relative 'sensors/ds18b20_provider'
|
|
10
10
|
require_relative 'sensors/bmp180'
|
|
11
11
|
require_relative 'sensors/mcp9808'
|
|
12
|
+
require_relative 'sensors/sht31'
|
|
13
|
+
require_relative 'sensors/sht31_provider'
|
|
14
|
+
require_relative 'sensors/bh1750'
|
|
15
|
+
require_relative 'sensors/bh1750_provider'
|
|
16
|
+
require_relative 'sensors/tsl2561'
|
|
17
|
+
require_relative 'sensors/tsl2561_provider'
|
|
18
|
+
require_relative 'sensors/ina219'
|
|
19
|
+
require_relative 'sensors/ina219_provider'
|
data/lib/dredger/iot/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dredger-iot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The Mad Botter INC
|
|
@@ -53,6 +53,8 @@ files:
|
|
|
53
53
|
- lib/dredger/iot/scheduler.rb
|
|
54
54
|
- lib/dredger/iot/sensors.rb
|
|
55
55
|
- lib/dredger/iot/sensors/base_sensor.rb
|
|
56
|
+
- lib/dredger/iot/sensors/bh1750.rb
|
|
57
|
+
- lib/dredger/iot/sensors/bh1750_provider.rb
|
|
56
58
|
- lib/dredger/iot/sensors/bme280.rb
|
|
57
59
|
- lib/dredger/iot/sensors/bme280_provider.rb
|
|
58
60
|
- lib/dredger/iot/sensors/bmp180.rb
|
|
@@ -60,7 +62,13 @@ files:
|
|
|
60
62
|
- lib/dredger/iot/sensors/dht22_provider.rb
|
|
61
63
|
- lib/dredger/iot/sensors/ds18b20.rb
|
|
62
64
|
- lib/dredger/iot/sensors/ds18b20_provider.rb
|
|
65
|
+
- lib/dredger/iot/sensors/ina219.rb
|
|
66
|
+
- lib/dredger/iot/sensors/ina219_provider.rb
|
|
63
67
|
- lib/dredger/iot/sensors/mcp9808.rb
|
|
68
|
+
- lib/dredger/iot/sensors/sht31.rb
|
|
69
|
+
- lib/dredger/iot/sensors/sht31_provider.rb
|
|
70
|
+
- lib/dredger/iot/sensors/tsl2561.rb
|
|
71
|
+
- lib/dredger/iot/sensors/tsl2561_provider.rb
|
|
64
72
|
- lib/dredger/iot/version.rb
|
|
65
73
|
homepage: https://github.com/TheMadBotterINC/dredger-iot
|
|
66
74
|
licenses:
|
|
@@ -75,25 +83,27 @@ metadata:
|
|
|
75
83
|
rubygems_mfa_required: 'true'
|
|
76
84
|
keywords: iot, embedded, linux, gpio, i2c, beaglebone, raspberry-pi, hardware, sensors,
|
|
77
85
|
dht22, bme280, ds18b20, bmp180, mcp9808, libgpiod, automation
|
|
78
|
-
post_install_message: "\n═══════════════════════════════════════════════════════════════════\n
|
|
79
|
-
\
|
|
80
|
-
\ \n
|
|
81
|
-
\
|
|
82
|
-
\ ___ ___ | \n
|
|
83
|
-
\ \n
|
|
84
|
-
\
|
|
85
|
-
\ | | \n
|
|
86
|
-
\
|
|
87
|
-
\
|
|
88
|
-
\
|
|
89
|
-
\
|
|
90
|
-
\
|
|
91
|
-
\
|
|
92
|
-
|
|
93
|
-
\
|
|
94
|
-
|
|
95
|
-
\ = Dredger::IoT::Bus::Auto.
|
|
96
|
-
|
|
86
|
+
post_install_message: "\n ═══════════════════════════════════════════════════════════════════\n
|
|
87
|
+
\ \n _______________
|
|
88
|
+
\ \n | DREDGER-IoT | \n
|
|
89
|
+
\ |_______________| \n /|
|
|
90
|
+
\ ___ ___ | \n / | |___| |___||
|
|
91
|
+
\ \n / |______________| \n
|
|
92
|
+
\ ====|========================|==== \n |
|
|
93
|
+
\ | |-----------| | | \n | |____| |_____|
|
|
94
|
+
\ | \n ___|____| |____|___ \n
|
|
95
|
+
\ ~~~~{________|_________________________|________}~~~~~~~ \n ~~ |
|
|
96
|
+
\ \\ // | ~~~ \n | \\___________________//
|
|
97
|
+
\ | \n |_____________________________| \n
|
|
98
|
+
\ ~~~ \\ // ~~~ \n \\_______________//
|
|
99
|
+
\ \n ═══════════════════════════════════════════════════════════════════\nHardware
|
|
100
|
+
Integration for Embedded Linux v0.2.0\n ═══════════════════════════════════════════════════════════════════\n\n
|
|
101
|
+
\ \U0001F389 Thanks for installing!\n\n \U0001F4DA Hardware Setup (kernel modules
|
|
102
|
+
& permissions):\n https://github.com/TheMadBotterINC/dredger-iot#hardware-setup\n\n
|
|
103
|
+
\ \U0001F680 Quick Start:\n require 'dredger/iot'\n gpio = Dredger::IoT::Bus::Auto.gpio\n
|
|
104
|
+
\ i2c = Dredger::IoT::Bus::Auto.i2c\n\n \U0001F4A1 Supported Sensors:\n
|
|
105
|
+
\ DHT22, BME280, DS18B20, BMP180, MCP9808\n\n \U0001F4D6 Full Documentation:\n
|
|
106
|
+
\ https://github.com/TheMadBotterINC/dredger-iot\n\n"
|
|
97
107
|
rdoc_options: []
|
|
98
108
|
require_paths:
|
|
99
109
|
- lib
|