tilt_hydrometer 0.0.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/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: []
|