tilt_hydrometer 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/tilt_hydrometer +22 -0
- data/lib/tilt_hydrometer.rb +20 -0
- data/lib/tilt_hydrometer/beacon_decorator.rb +44 -0
- data/lib/tilt_hydrometer/brewfather.rb +30 -0
- data/lib/tilt_hydrometer/core.rb +52 -0
- data/lib/tilt_hydrometer/devices.rb +14 -0
- data/lib/tilt_hydrometer/logger.rb +5 -0
- data/lib/tilt_hydrometer/mqtt.rb +31 -0
- data/lib/tilt_hydrometer/throttled_execution.rb +32 -0
- data/lib/tilt_hydrometer/version.rb +5 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be01ff292822b0e7e14d96b7ea82f28aef55c2e48a58336782c57ceb26cc66dd
|
4
|
+
data.tar.gz: ea44e0c738b3184fdefff1bceb60b95365442db0c3d40217cd30543916fc25be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2da1750ca050fc1c1a42b23c2a331886d2568572ad047e5da966128224c9ab719b5f10117ceb6d9578237ffa1c26e6989c3582a4e05b73d8ac3b92409214b87
|
7
|
+
data.tar.gz: 5018e571839af1c99ed3a59757da2153f5c34353bc8d575ee7b50bf15f7872002bb08e9c54d353bd16ae3e4a28bd8fb431bbe670f313bae5babdee3a4ba0661a
|
data/bin/tilt_hydrometer
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
require 'optparse/uri'
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
require 'tilt_hydrometer'
|
9
|
+
|
10
|
+
options = {
|
11
|
+
interval: 15 * 60,
|
12
|
+
mqtt_prefix: ''
|
13
|
+
}
|
14
|
+
|
15
|
+
OptionParser.new do |parser|
|
16
|
+
parser.on('-b', '--brewfather URL', URI, 'Brewfather Custom Stream URL')
|
17
|
+
parser.on('-i', '--interval SECONDS', Integer, 'Logging interval')
|
18
|
+
parser.on('-m', '--mqtt URI', URI, 'URI to MQTT broker')
|
19
|
+
parser.on('-p', '--mqtt_prefix STRING', String, ' MQTT topic prefix')
|
20
|
+
end.parse!(into: options)
|
21
|
+
|
22
|
+
TiltHydrometer::Core.new(options).run
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require 'scan_beacon'
|
7
|
+
require 'faraday'
|
8
|
+
require 'mqtt'
|
9
|
+
|
10
|
+
require 'tilt_hydrometer/version'
|
11
|
+
require 'tilt_hydrometer/logger'
|
12
|
+
require 'tilt_hydrometer/devices'
|
13
|
+
require 'tilt_hydrometer/beacon_decorator'
|
14
|
+
require 'tilt_hydrometer/throttled_execution'
|
15
|
+
require 'tilt_hydrometer/brewfather'
|
16
|
+
require 'tilt_hydrometer/mqtt'
|
17
|
+
require 'tilt_hydrometer/core'
|
18
|
+
|
19
|
+
module TiltHydrometer
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
module BeaconDecorator
|
5
|
+
def color
|
6
|
+
TiltHydrometer::DEVICES[uuid]
|
7
|
+
end
|
8
|
+
|
9
|
+
def temp
|
10
|
+
data[0].to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def gravity
|
14
|
+
gravity_string = data[1].to_s
|
15
|
+
|
16
|
+
"#{gravity_string[-4] || 0}.#{gravity_string[-3..-1]}".to_f
|
17
|
+
end
|
18
|
+
|
19
|
+
def plato
|
20
|
+
(
|
21
|
+
(-1 * 616.868) +
|
22
|
+
(1111.14 * gravity) -
|
23
|
+
(630.272 * (gravity**2)) +
|
24
|
+
(135.997 * (gravity**3))
|
25
|
+
).round(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
def celsius
|
29
|
+
(
|
30
|
+
(temp - 32.0) * (5.0 / 9.0)
|
31
|
+
).round(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
def values_out_of_range?
|
35
|
+
temp > 212
|
36
|
+
end
|
37
|
+
|
38
|
+
def log
|
39
|
+
LOGGER.debug("Beacon: #{inspect}")
|
40
|
+
LOGGER.debug("Data: #{data.inspect}")
|
41
|
+
LOGGER.debug("UUID: #{uuid.inspect}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
class Brewfather
|
5
|
+
include TiltHydrometer::ThrotteledExecution
|
6
|
+
|
7
|
+
def initialize(url, interval)
|
8
|
+
@url = url
|
9
|
+
@interval = interval
|
10
|
+
end
|
11
|
+
|
12
|
+
def post(beacon)
|
13
|
+
throtteled_execution(beacon.uuid) do
|
14
|
+
Faraday.post(@url, beacon_json(beacon), 'Content-Type' => 'application/json')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def beacon_json(beacon)
|
21
|
+
{
|
22
|
+
name: "Tilt-#{beacon.color}",
|
23
|
+
temp: beacon.temp.to_s,
|
24
|
+
temp_unit: 'F',
|
25
|
+
gravity: beacon.gravity.to_s,
|
26
|
+
gravity_unit: 'G'
|
27
|
+
}.to_json
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
class Core
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
scanner.scan do |beacons|
|
11
|
+
beacons.each do |beacon|
|
12
|
+
beacon.extend(TiltHydrometer::BeaconDecorator)
|
13
|
+
beacon.log
|
14
|
+
|
15
|
+
if beacon.values_out_of_range?
|
16
|
+
LOGGER.debug('values out of range') && next
|
17
|
+
end
|
18
|
+
|
19
|
+
brewfather&.post(beacon)
|
20
|
+
mqtt&.publish(beacon)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def scanner
|
28
|
+
@scanner ||=
|
29
|
+
ScanBeacon::DefaultScanner.new.tap do |s|
|
30
|
+
s.add_parser(
|
31
|
+
ScanBeacon::BeaconParser.new(
|
32
|
+
:tilt, 'm:0-5=4c000215a495,i:4-19,d:20-21,d:22-23,p:24-25'
|
33
|
+
)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def brewfather
|
39
|
+
return unless @options[:brewfather] && @options[:interval]
|
40
|
+
|
41
|
+
@brewfather ||=
|
42
|
+
TiltHydrometer::Brewfather.new(@options[:brewfather], @options[:interval])
|
43
|
+
end
|
44
|
+
|
45
|
+
def mqtt
|
46
|
+
return unless @options[:mqtt] && @options[:mqtt_prefix]
|
47
|
+
|
48
|
+
@mqtt ||=
|
49
|
+
TiltHydrometer::MQTT.new(@options[:mqtt], @options[:mqtt_prefix])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
DEVICES = {
|
5
|
+
'A495BB10-C5B1-4B44-B512-1370F02D74DE' => 'Red',
|
6
|
+
'A495BB20-C5B1-4B44-B512-1370F02D74DE' => 'Green',
|
7
|
+
'A495BB30-C5B1-4B44-B512-1370F02D74DE' => 'Black',
|
8
|
+
'A495BB40-C5B1-4B44-B512-1370F02D74DE' => 'Purple',
|
9
|
+
'A495BB50-C5B1-4B44-B512-1370F02D74DE' => 'Orange',
|
10
|
+
'A495BB60-C5B1-4B44-B512-1370F02D74DE' => 'Blue',
|
11
|
+
'A495BB70-C5B1-4B44-B512-1370F02D74DE' => 'Yellow',
|
12
|
+
'A495BB80-C5B1-4B44-B512-1370F02D74DE' => 'Pink'
|
13
|
+
}.freeze
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
class MQTT
|
5
|
+
def initialize(mqtt_uri, prefix)
|
6
|
+
@mqtt_uri = mqtt_uri
|
7
|
+
@prefix = prefix
|
8
|
+
end
|
9
|
+
|
10
|
+
def publish(beacon)
|
11
|
+
::MQTT::Client.connect(@mqtt_uri) do |c|
|
12
|
+
c.publish(topic(beacon), beacon_json(beacon), true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def topic(beacon)
|
19
|
+
@prefix + beacon.color
|
20
|
+
end
|
21
|
+
|
22
|
+
def beacon_json(beacon)
|
23
|
+
JSON.generate(
|
24
|
+
temp_f: beacon.temp,
|
25
|
+
temp_c: beacon.celsius,
|
26
|
+
gravity_sg: beacon.gravity,
|
27
|
+
gravity_p: beacon.plato
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TiltHydrometer
|
4
|
+
module ThrotteledExecution
|
5
|
+
def throtteled_execution(uuid)
|
6
|
+
unless execution_allowed?(uuid)
|
7
|
+
LOGGER.debug('Execution got throtteled')
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
reset_timer(uuid)
|
12
|
+
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
|
16
|
+
def execution_allowed?(uuid)
|
17
|
+
return true if timers[uuid].nil?
|
18
|
+
|
19
|
+
# puts @interval.inspect
|
20
|
+
|
21
|
+
timers[uuid] + @interval < Time.now.utc
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset_timer(uuid)
|
25
|
+
timers[uuid] = Time.now.utc
|
26
|
+
end
|
27
|
+
|
28
|
+
def timers
|
29
|
+
@timers ||= {}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tilt_hydrometer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steffen Schröder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-11-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mqtt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: scan_beacon
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.7.11
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.7.11
|
69
|
+
description: Read Tilt Hydrometer beacons and post to Brewfather
|
70
|
+
email: steffen@schroeder-blog.de
|
71
|
+
executables:
|
72
|
+
- tilt_hydrometer
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- bin/tilt_hydrometer
|
77
|
+
- lib/tilt_hydrometer.rb
|
78
|
+
- lib/tilt_hydrometer/beacon_decorator.rb
|
79
|
+
- lib/tilt_hydrometer/brewfather.rb
|
80
|
+
- lib/tilt_hydrometer/core.rb
|
81
|
+
- lib/tilt_hydrometer/devices.rb
|
82
|
+
- lib/tilt_hydrometer/logger.rb
|
83
|
+
- lib/tilt_hydrometer/mqtt.rb
|
84
|
+
- lib/tilt_hydrometer/throttled_execution.rb
|
85
|
+
- lib/tilt_hydrometer/version.rb
|
86
|
+
homepage: https://github.com/ChaosSteffen/tilt_hydrometer
|
87
|
+
licenses:
|
88
|
+
- BSD-2-Clause
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 2.5.5
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubygems_version: 3.1.4
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Tilt Hydrometer
|
109
|
+
test_files: []
|