garden_messenger 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +16 -4
- data/README.md +4 -4
- data/exe/garden_messenger +1 -50
- data/garden_messenger.gemspec +1 -1
- data/lib/garden_messenger/atlas_scientific/ec.rb +21 -0
- data/lib/garden_messenger/atlas_scientific/i2c_device.rb +100 -0
- data/lib/garden_messenger/atlas_scientific/ph.rb +17 -0
- data/lib/garden_messenger/atlas_scientific/temperature.rb +13 -0
- data/lib/garden_messenger/cli.rb +57 -0
- data/lib/garden_messenger/reporter.rb +1 -1
- data/lib/garden_messenger/version.rb +1 -1
- data/lib/garden_messenger.rb +5 -0
- metadata +16 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7b25c790bf561282f4fb0e150d2a6d5e75cbae1f7e2a7176af43a25caef39d9
|
4
|
+
data.tar.gz: 9e7109e232c79bea95bba4a1a7b885809bcddbd909af94f9ed5bb7ba26f72700
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d90a0176635a0c122c70f169c9233bcfe7cad1851b8abf2ba3f855ea8e5f27093a10ea1a28614b00608cc7a8b3832f725a1e5740b41fac4ab671f9de293122c
|
7
|
+
data.tar.gz: 99a55d17590b04f90e76a2c4ec6680f46e7c40179629681bac3b7c5da15a1fdbd2b3e0b66ad771982479bda83f81db9fb728b7bcf9389b0c6b847d97d2a85754
|
data/.rubocop.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
inherit_from:
|
2
|
-
- https://raw.githubusercontent.com/siegy22/dotfiles/
|
2
|
+
- https://raw.githubusercontent.com/siegy22/dotfiles/c4b42f0bba4e4eb0a573d538ecc99266be90a8f8/rubocop.yml
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
garden_messenger (0.
|
4
|
+
garden_messenger (0.2.0)
|
5
5
|
action_cable_client (~> 3.0)
|
6
6
|
http (~> 4.1)
|
7
|
-
i2c-devices (~> 0.0.6)
|
8
7
|
thor (~> 0.20)
|
9
8
|
|
10
9
|
GEM
|
@@ -12,9 +11,16 @@ GEM
|
|
12
11
|
specs:
|
13
12
|
action_cable_client (3.0.1)
|
14
13
|
websocket-eventmachine-client (>= 1.2.0)
|
14
|
+
activesupport (6.0.0.rc1)
|
15
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
16
|
+
i18n (>= 0.7, < 2)
|
17
|
+
minitest (~> 5.1)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
zeitwerk (~> 2.1, >= 2.1.4)
|
15
20
|
addressable (2.6.0)
|
16
21
|
public_suffix (>= 2.0.2, < 4.0)
|
17
22
|
ast (2.4.0)
|
23
|
+
concurrent-ruby (1.1.5)
|
18
24
|
domain_name (0.5.20180417)
|
19
25
|
unf (>= 0.0.5, < 1.0.0)
|
20
26
|
eventmachine (1.2.7)
|
@@ -27,7 +33,8 @@ GEM
|
|
27
33
|
domain_name (~> 0.5)
|
28
34
|
http-form_data (2.1.1)
|
29
35
|
http_parser.rb (0.6.0)
|
30
|
-
|
36
|
+
i18n (1.6.0)
|
37
|
+
concurrent-ruby (~> 1.0)
|
31
38
|
jaro_winkler (1.5.2)
|
32
39
|
minitest (5.11.3)
|
33
40
|
parallel (1.17.0)
|
@@ -47,9 +54,12 @@ GEM
|
|
47
54
|
unicode-display_width (>= 1.4.0, < 1.6)
|
48
55
|
ruby-progressbar (1.10.0)
|
49
56
|
thor (0.20.3)
|
57
|
+
thread_safe (0.3.6)
|
58
|
+
tzinfo (1.2.5)
|
59
|
+
thread_safe (~> 0.1)
|
50
60
|
unf (0.1.4)
|
51
61
|
unf_ext
|
52
|
-
unf_ext (0.0.7.
|
62
|
+
unf_ext (0.0.7.6)
|
53
63
|
unicode-display_width (1.5.0)
|
54
64
|
websocket (1.2.8)
|
55
65
|
websocket-eventmachine-base (1.2.0)
|
@@ -59,11 +69,13 @@ GEM
|
|
59
69
|
websocket-eventmachine-client (1.2.0)
|
60
70
|
websocket-eventmachine-base (~> 1.0)
|
61
71
|
websocket-native (1.0.0)
|
72
|
+
zeitwerk (2.1.5)
|
62
73
|
|
63
74
|
PLATFORMS
|
64
75
|
ruby
|
65
76
|
|
66
77
|
DEPENDENCIES
|
78
|
+
activesupport (= 6.0.0.rc1)
|
67
79
|
bundler (~> 2.0)
|
68
80
|
garden_messenger!
|
69
81
|
minitest (~> 5.0)
|
data/README.md
CHANGED
@@ -6,10 +6,10 @@ Collects data of [AtlasScientific](https://www.atlas-scientific.com/) and [myStr
|
|
6
6
|
|
7
7
|
Currently supported:
|
8
8
|
|
9
|
-
[
|
10
|
-
[
|
11
|
-
[
|
12
|
-
[x] [myStrom Switch (CH)](https://mystrom.ch/wifi-switch-ch/)
|
9
|
+
- [x] [pH Kit](https://www.atlas-scientific.com/product_pages/kits/ph-kit.html)
|
10
|
+
- [x] [Conductivity Kit](https://www.atlas-scientific.com/product_pages/kits/ec_k1_0_kit.html)
|
11
|
+
- [x] [Temperature Kit](https://www.atlas-scientific.com/product_pages/kits/temp_kit.html)
|
12
|
+
- [x] [myStrom Switch (CH)](https://mystrom.ch/wifi-switch-ch/)
|
13
13
|
|
14
14
|
|
15
15
|
## Installation
|
data/exe/garden_messenger
CHANGED
@@ -1,54 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'garden_messenger'
|
4
|
-
require 'thor'
|
5
4
|
|
6
|
-
|
7
|
-
desc 'report MONITOR_URL TOKEN [options]', 'Report to a monitor which is located on MONITOR_URL'
|
8
|
-
option 'wattage-switch-host'
|
9
|
-
option 'update-rate'
|
10
|
-
option 'verbose', type: :boolean
|
11
|
-
def report(monitor_url, token)
|
12
|
-
reporter = GardenMessenger::Reporter.new(
|
13
|
-
monitor_url,
|
14
|
-
token,
|
15
|
-
options.fetch('update-rate') { 30 },
|
16
|
-
options.fetch('verbose') { false }
|
17
|
-
)
|
18
|
-
|
19
|
-
reporter.report! do
|
20
|
-
data = {}
|
21
|
-
|
22
|
-
if options.key?('wattage-switch-host')
|
23
|
-
wattage = GardenMessenger::Wattage.new(options['wattage-switch-host'])
|
24
|
-
data[:wattage] = wattage.get
|
25
|
-
end
|
26
|
-
|
27
|
-
data[:temp] = rand(18.0...26.0)
|
28
|
-
data[:ph] = rand(4.0...8.0)
|
29
|
-
data[:ec] = rand(0.8...1.6)
|
30
|
-
|
31
|
-
data
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
desc 'dev', 'Report random values to local monitor'
|
36
|
-
def dev
|
37
|
-
reporter = GardenMessenger::Reporter.new(
|
38
|
-
'ws://localhost:3000/cable',
|
39
|
-
'dev-token',
|
40
|
-
1,
|
41
|
-
true
|
42
|
-
)
|
43
|
-
|
44
|
-
reporter.report! do
|
45
|
-
temp = rand(18.0...26.0)
|
46
|
-
ph = rand(4.0...8.0)
|
47
|
-
ec = rand(0.8...1.6)
|
48
|
-
wattage = rand(700.0...800.0)
|
49
|
-
{ temp: temp, ph: ph, ec: ec, wattage: wattage }
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
MessengerCLI.start(ARGV)
|
5
|
+
GardenMessenger::CLI.start(ARGV)
|
data/garden_messenger.gemspec
CHANGED
@@ -24,9 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_dependency 'action_cable_client', '~> 3.0'
|
26
26
|
spec.add_dependency 'http', '~> 4.1'
|
27
|
-
spec.add_dependency 'i2c-devices', '~> 0.0.6'
|
28
27
|
spec.add_dependency 'thor', '~> 0.20'
|
29
28
|
|
29
|
+
spec.add_development_dependency 'activesupport', '6.0.0.rc1'
|
30
30
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
31
31
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
32
32
|
spec.add_development_dependency 'rake', '~> 10.0'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'garden_messenger/atlas_scientific/i2c_device'
|
2
|
+
|
3
|
+
module GardenMessenger
|
4
|
+
module AtlasScientific
|
5
|
+
# Abstraction layer to EZO Conductivity Circuit
|
6
|
+
# https://www.atlas-scientific.com/product_pages/circuits/ezo_ec.html
|
7
|
+
class EC < I2CDevice
|
8
|
+
def initialize(address = 0x64)
|
9
|
+
super(address)
|
10
|
+
end
|
11
|
+
|
12
|
+
def probe_type=(type)
|
13
|
+
k(type)
|
14
|
+
end
|
15
|
+
|
16
|
+
def k(*args)
|
17
|
+
execute('k', *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module GardenMessenger
|
2
|
+
module AtlasScientific
|
3
|
+
class I2CDevice
|
4
|
+
class NoDataToSendError < StandardError; end
|
5
|
+
class StillProcessingError < StandardError; end
|
6
|
+
class CommandSyntaxError < StandardError; end
|
7
|
+
class UnknownStatusCodeError < StandardError; end
|
8
|
+
|
9
|
+
STILL_PROCESSING = 254
|
10
|
+
I2C_SLAVE = 0x0703
|
11
|
+
|
12
|
+
def initialize(address, path = Dir.glob('/dev/i2c-*').first)
|
13
|
+
@address = address
|
14
|
+
@path = path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Takes a reading using the r ezo command
|
18
|
+
# and casts it to a float
|
19
|
+
def reading
|
20
|
+
r.to_f
|
21
|
+
end
|
22
|
+
alias take_reading reading
|
23
|
+
alias read reading
|
24
|
+
|
25
|
+
def take_reading_with_temperature_compensation(temperature)
|
26
|
+
rt(temperature.to_s).to_f
|
27
|
+
end
|
28
|
+
|
29
|
+
def calibrated?
|
30
|
+
!execute('cal', '?').casecmp?('?cal,0')
|
31
|
+
end
|
32
|
+
|
33
|
+
[
|
34
|
+
'baud',
|
35
|
+
'cal',
|
36
|
+
'factory',
|
37
|
+
'find',
|
38
|
+
'i',
|
39
|
+
'i2c',
|
40
|
+
'l',
|
41
|
+
'o',
|
42
|
+
'plock',
|
43
|
+
'r',
|
44
|
+
'rt',
|
45
|
+
'sleep',
|
46
|
+
'status',
|
47
|
+
't'
|
48
|
+
].each do |cmd|
|
49
|
+
define_method(cmd) do |*args|
|
50
|
+
execute(cmd, *args)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
alias information i
|
55
|
+
|
56
|
+
alias temperature_compensation t
|
57
|
+
|
58
|
+
alias protocol_lock plock
|
59
|
+
|
60
|
+
def execute(command, *args)
|
61
|
+
io = File.open(@path, 'r+')
|
62
|
+
# Set i2c address and mode
|
63
|
+
io.ioctl(I2C_SLAVE, @address)
|
64
|
+
|
65
|
+
# Prepare EZO command like
|
66
|
+
ezo_command = [command, *args].join(',')
|
67
|
+
|
68
|
+
io.syswrite(ezo_command)
|
69
|
+
return if command == 'sleep'
|
70
|
+
|
71
|
+
# Wait for the command to finish
|
72
|
+
result, status = loop do
|
73
|
+
result = io.read(31)
|
74
|
+
status = result[0].unpack1('C')
|
75
|
+
break [result, status] unless status == STILL_PROCESSING
|
76
|
+
end
|
77
|
+
|
78
|
+
check_for_status_code(status, ezo_command)
|
79
|
+
result[1..-1].strip
|
80
|
+
ensure
|
81
|
+
io&.close
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_for_status_code(code, ezo_command)
|
85
|
+
return if code == 1
|
86
|
+
|
87
|
+
case code
|
88
|
+
when 255
|
89
|
+
raise NoDataToSendError
|
90
|
+
when 2
|
91
|
+
raise CommandSyntaxError, "There was an error executing the following command: #{ezo_command}\n" \
|
92
|
+
'Please check the documentation of your circuit.'
|
93
|
+
else
|
94
|
+
raise UnknownStatusCodeError, "Unkown Response code: #{code} received from device.\n" \
|
95
|
+
'Check the latest datasheet of atlas scientific.'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'garden_messenger/atlas_scientific/i2c_device'
|
2
|
+
|
3
|
+
module GardenMessenger
|
4
|
+
module AtlasScientific
|
5
|
+
# Abstraction layer to EZO pH Circuit
|
6
|
+
# https://www.atlas-scientific.com/product_pages/circuits/ezo_ph.html
|
7
|
+
class PH < I2CDevice
|
8
|
+
def initialize(address = 0x63)
|
9
|
+
super(address)
|
10
|
+
end
|
11
|
+
|
12
|
+
def slope
|
13
|
+
execute('slope', '?')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'garden_messenger/atlas_scientific/i2c_device'
|
2
|
+
|
3
|
+
module GardenMessenger
|
4
|
+
module AtlasScientific
|
5
|
+
# Abstraction layer to EZO RTD Temperature Circuit
|
6
|
+
# https://www.atlas-scientific.com/product_pages/circuits/ezo_rtd.html
|
7
|
+
class Temperature < I2CDevice
|
8
|
+
def initialize(address = 0x66)
|
9
|
+
super(address)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module GardenMessenger
|
4
|
+
class CLI < Thor
|
5
|
+
desc 'report MONITOR_URL TOKEN [options]', 'Report to a monitor which is located on MONITOR_URL'
|
6
|
+
option 'wattage-switch-host'
|
7
|
+
option 'update-rate'
|
8
|
+
option 'verbose', type: :boolean
|
9
|
+
def report(monitor_url, token)
|
10
|
+
reporter = GardenMessenger::Reporter.new(
|
11
|
+
monitor_url,
|
12
|
+
token,
|
13
|
+
options.fetch('update-rate') { 30 },
|
14
|
+
options.fetch('verbose') { false }
|
15
|
+
)
|
16
|
+
|
17
|
+
water_temperature = GardenMessenger::AtlasScientific::Temperature.new
|
18
|
+
ph = GardenMessenger::AtlasScientific::PH.new
|
19
|
+
ec = GardenMessenger::AtlasScientific::EC.new
|
20
|
+
wattage = GardenMessenger::Wattage.new(options['wattage-switch-host'])
|
21
|
+
|
22
|
+
reporter.report! do
|
23
|
+
data = { air_temp: 0.0, humidity: 0.0 }
|
24
|
+
|
25
|
+
data[:wattage] = wattage.get if options.key?('wattage-switch-host')
|
26
|
+
data[:water_temp] = water_temperature.take_reading
|
27
|
+
ph_thread = Thread.new { ph.take_reading_with_temperature_compensation(data[:water_temp]) }
|
28
|
+
ec_thread = Thread.new { ec.take_reading_with_temperature_compensation(data[:water_temp]) }
|
29
|
+
data[:ph] = ph_thread.value
|
30
|
+
data[:ec] = ec_thread.value
|
31
|
+
|
32
|
+
data
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'dev', 'Report random values to local monitor'
|
37
|
+
def dev
|
38
|
+
reporter = GardenMessenger::Reporter.new(
|
39
|
+
'ws://localhost:3000/cable',
|
40
|
+
'dev-token',
|
41
|
+
1,
|
42
|
+
true
|
43
|
+
)
|
44
|
+
|
45
|
+
reporter.report! do
|
46
|
+
{
|
47
|
+
air_temp: rand(18.0...30.0),
|
48
|
+
humidity: rand(50.0...60.0),
|
49
|
+
water_temp: rand(18.0...26.0),
|
50
|
+
ph: rand(4.0...8.0),
|
51
|
+
ec: rand(0.8...1.6),
|
52
|
+
wattage: rand(700.0...800.0)
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/garden_messenger.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'garden_messenger/cli'
|
1
2
|
require 'garden_messenger/reporter'
|
2
3
|
require 'garden_messenger/version'
|
3
4
|
require 'garden_messenger/wattage'
|
5
|
+
require 'garden_messenger/atlas_scientific/i2c_device'
|
6
|
+
require 'garden_messenger/atlas_scientific/ph'
|
7
|
+
require 'garden_messenger/atlas_scientific/ec'
|
8
|
+
require 'garden_messenger/atlas_scientific/temperature'
|
4
9
|
|
5
10
|
module GardenMessenger
|
6
11
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: garden_messenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yves Siegrist
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: action_cable_client
|
@@ -39,33 +39,33 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '4.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: thor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: '0.20'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: '0.20'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: activesupport
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: 6.0.0.rc1
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 6.0.0.rc1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -148,6 +148,11 @@ files:
|
|
148
148
|
- garden_messenger.gemspec
|
149
149
|
- garden_messenger.service
|
150
150
|
- lib/garden_messenger.rb
|
151
|
+
- lib/garden_messenger/atlas_scientific/ec.rb
|
152
|
+
- lib/garden_messenger/atlas_scientific/i2c_device.rb
|
153
|
+
- lib/garden_messenger/atlas_scientific/ph.rb
|
154
|
+
- lib/garden_messenger/atlas_scientific/temperature.rb
|
155
|
+
- lib/garden_messenger/cli.rb
|
151
156
|
- lib/garden_messenger/reporter.rb
|
152
157
|
- lib/garden_messenger/version.rb
|
153
158
|
- lib/garden_messenger/wattage.rb
|