atrea_control 1.1.0 → 1.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/.rubocop_todo.yml +13 -7
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +43 -9
- data/atrea_control.gemspec +2 -0
- data/lib/atrea_control/duplex.rb +79 -31
- data/lib/atrea_control/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ff5e62d3cbb95e39a1b342fa6662636255b8d78b6d76ab54f1e4c3cc12841afc
|
|
4
|
+
data.tar.gz: b1aa30c99ff332e261cb3c9e9752bba0eedd16e730bec244c67e91b51b2ab661
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 881da41972aea45c4e3ea36b2a14ec44d87c9a8d42e6249048780bcfb9066c8c42b35d27770be7f23663a13cc3f0b663b621030adb58f52714851d7d3a833354
|
|
7
|
+
data.tar.gz: ee2aaa4913ab06f77ff3fab98661b53085519dffdb1b49786d39e32db80d365618d274e3aef17d12e6041bba9d8d7f030afe5616e5c106c16ccd84062bb88b83
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config --auto-gen-only-exclude`
|
|
3
|
-
# on 2021-
|
|
3
|
+
# on 2021-10-26 20:31:23 UTC using RuboCop version 1.22.2.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
9
|
+
# Offense count: 2
|
|
10
10
|
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
|
|
11
11
|
# IgnoredMethods: refine
|
|
12
12
|
Metrics/BlockLength:
|
|
@@ -14,13 +14,19 @@ Metrics/BlockLength:
|
|
|
14
14
|
- '**/*.gemspec'
|
|
15
15
|
- 'spec/atrea_control/duplex_spec.rb'
|
|
16
16
|
|
|
17
|
-
# Offense count:
|
|
17
|
+
# Offense count: 1
|
|
18
|
+
# Configuration parameters: CountComments, Max, CountAsOne.
|
|
19
|
+
Metrics/ClassLength:
|
|
20
|
+
Exclude:
|
|
21
|
+
- 'lib/atrea_control/duplex.rb'
|
|
22
|
+
|
|
23
|
+
# Offense count: 5
|
|
18
24
|
# Configuration parameters: .
|
|
19
25
|
# SupportedStyles: have_received, receive
|
|
20
26
|
RSpec/MessageSpies:
|
|
21
27
|
EnforcedStyle: receive
|
|
22
28
|
|
|
23
|
-
# Offense count:
|
|
29
|
+
# Offense count: 2
|
|
24
30
|
# Configuration parameters: Max.
|
|
25
31
|
RSpec/MultipleExpectations:
|
|
26
32
|
Exclude:
|
|
@@ -31,7 +37,7 @@ RSpec/StubbedMock:
|
|
|
31
37
|
Exclude:
|
|
32
38
|
- 'spec/atrea_control/duplex_spec.rb'
|
|
33
39
|
|
|
34
|
-
# Offense count:
|
|
40
|
+
# Offense count: 5
|
|
35
41
|
RSpec/SubjectStub:
|
|
36
42
|
Exclude:
|
|
37
43
|
- 'spec/atrea_control/duplex_spec.rb'
|
|
@@ -60,9 +66,9 @@ Style/MutableConstant:
|
|
|
60
66
|
Exclude:
|
|
61
67
|
- 'spec/atrea_control/duplex_spec.rb'
|
|
62
68
|
|
|
63
|
-
# Offense count:
|
|
69
|
+
# Offense count: 2
|
|
64
70
|
# Cop supports --auto-correct.
|
|
65
|
-
# Configuration parameters:
|
|
71
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
|
66
72
|
# URISchemes: http, https
|
|
67
73
|
Layout/LineLength:
|
|
68
74
|
Exclude:
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -9,4 +9,7 @@ gem "rake", "~> 13.0"
|
|
|
9
9
|
gem "rspec", "~> 3.10"
|
|
10
10
|
gem "rubocop", "~> 1.7", require: false
|
|
11
11
|
gem "rubocop-rspec", "~> 2.4", require: false
|
|
12
|
-
|
|
12
|
+
group :test do
|
|
13
|
+
gem "simplecov", require: false
|
|
14
|
+
gem "webmock", "~> 3.14"
|
|
15
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,22 +1,49 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
atrea_control (1.
|
|
4
|
+
atrea_control (1.2.0)
|
|
5
|
+
nokogiri (~> 1.12)
|
|
6
|
+
rest-client (~> 2.1)
|
|
5
7
|
selenium-webdriver (~> 3.142)
|
|
6
8
|
|
|
7
9
|
GEM
|
|
8
10
|
remote: https://rubygems.org/
|
|
9
11
|
specs:
|
|
12
|
+
addressable (2.8.0)
|
|
13
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
10
14
|
ast (2.4.2)
|
|
11
15
|
childprocess (3.0.0)
|
|
16
|
+
crack (0.4.5)
|
|
17
|
+
rexml
|
|
12
18
|
diff-lcs (1.4.4)
|
|
13
19
|
docile (1.4.0)
|
|
14
|
-
|
|
20
|
+
domain_name (0.5.20190701)
|
|
21
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
22
|
+
hashdiff (1.0.1)
|
|
23
|
+
http-accept (1.7.0)
|
|
24
|
+
http-cookie (1.0.4)
|
|
25
|
+
domain_name (~> 0.5)
|
|
26
|
+
mime-types (3.3.1)
|
|
27
|
+
mime-types-data (~> 3.2015)
|
|
28
|
+
mime-types-data (3.2021.0901)
|
|
29
|
+
netrc (0.11.0)
|
|
30
|
+
nokogiri (1.12.5-x86_64-darwin)
|
|
31
|
+
racc (~> 1.4)
|
|
32
|
+
nokogiri (1.12.5-x86_64-linux)
|
|
33
|
+
racc (~> 1.4)
|
|
34
|
+
parallel (1.21.0)
|
|
15
35
|
parser (3.0.2.0)
|
|
16
36
|
ast (~> 2.4.1)
|
|
37
|
+
public_suffix (4.0.6)
|
|
38
|
+
racc (1.6.0)
|
|
17
39
|
rainbow (3.0.0)
|
|
18
40
|
rake (13.0.6)
|
|
19
41
|
regexp_parser (2.1.1)
|
|
42
|
+
rest-client (2.1.0)
|
|
43
|
+
http-accept (>= 1.7.0, < 2.0)
|
|
44
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
45
|
+
mime-types (>= 1.16, < 4.0)
|
|
46
|
+
netrc (~> 0.8)
|
|
20
47
|
rexml (3.2.5)
|
|
21
48
|
rspec (3.10.0)
|
|
22
49
|
rspec-core (~> 3.10.0)
|
|
@@ -31,20 +58,19 @@ GEM
|
|
|
31
58
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
32
59
|
rspec-support (~> 3.10.0)
|
|
33
60
|
rspec-support (3.10.2)
|
|
34
|
-
rubocop (1.
|
|
61
|
+
rubocop (1.22.2)
|
|
35
62
|
parallel (~> 1.10)
|
|
36
63
|
parser (>= 3.0.0.0)
|
|
37
64
|
rainbow (>= 2.2.2, < 4.0)
|
|
38
65
|
regexp_parser (>= 1.8, < 3.0)
|
|
39
66
|
rexml
|
|
40
|
-
rubocop-ast (>= 1.
|
|
67
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
|
41
68
|
ruby-progressbar (~> 1.7)
|
|
42
69
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
43
|
-
rubocop-ast (1.
|
|
70
|
+
rubocop-ast (1.12.0)
|
|
44
71
|
parser (>= 3.0.1.1)
|
|
45
|
-
rubocop-rspec (2.
|
|
46
|
-
rubocop (~> 1.
|
|
47
|
-
rubocop-ast (>= 1.1.0)
|
|
72
|
+
rubocop-rspec (2.5.0)
|
|
73
|
+
rubocop (~> 1.19)
|
|
48
74
|
ruby-progressbar (1.11.0)
|
|
49
75
|
rubyzip (2.3.2)
|
|
50
76
|
selenium-webdriver (3.142.7)
|
|
@@ -56,7 +82,14 @@ GEM
|
|
|
56
82
|
simplecov_json_formatter (~> 0.1)
|
|
57
83
|
simplecov-html (0.12.3)
|
|
58
84
|
simplecov_json_formatter (0.1.3)
|
|
59
|
-
|
|
85
|
+
unf (0.1.4)
|
|
86
|
+
unf_ext
|
|
87
|
+
unf_ext (0.0.8)
|
|
88
|
+
unicode-display_width (2.1.0)
|
|
89
|
+
webmock (3.14.0)
|
|
90
|
+
addressable (>= 2.8.0)
|
|
91
|
+
crack (>= 0.3.2)
|
|
92
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
60
93
|
|
|
61
94
|
PLATFORMS
|
|
62
95
|
x86_64-darwin-19
|
|
@@ -69,6 +102,7 @@ DEPENDENCIES
|
|
|
69
102
|
rubocop (~> 1.7)
|
|
70
103
|
rubocop-rspec (~> 2.4)
|
|
71
104
|
simplecov
|
|
105
|
+
webmock (~> 3.14)
|
|
72
106
|
|
|
73
107
|
BUNDLED WITH
|
|
74
108
|
2.2.17
|
data/atrea_control.gemspec
CHANGED
|
@@ -34,5 +34,7 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
# For more information and examples about making a new gem, checkout our
|
|
35
35
|
# guide at: https://bundler.io/guides/creating_gem.html
|
|
36
36
|
|
|
37
|
+
spec.add_dependency "nokogiri", "~> 1.12"
|
|
38
|
+
spec.add_dependency "rest-client", "~> 2.1"
|
|
37
39
|
spec.add_dependency "selenium-webdriver", "~> 3.142"
|
|
38
40
|
end
|
data/lib/atrea_control/duplex.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "logger"
|
|
4
|
+
require "nokogiri"
|
|
5
|
+
require "rest-client"
|
|
4
6
|
require "selenium-webdriver"
|
|
5
7
|
|
|
6
8
|
module AtreaControl
|
|
@@ -8,6 +10,10 @@ module AtreaControl
|
|
|
8
10
|
class Duplex
|
|
9
11
|
CONTROL_URI = "https://control.atrea.eu/"
|
|
10
12
|
|
|
13
|
+
attr_reader :current_mode, :current_power, :outdoor_temperature
|
|
14
|
+
# @return [DateTime] store time of last update
|
|
15
|
+
attr_reader :valid_for
|
|
16
|
+
|
|
11
17
|
# @param [String] login
|
|
12
18
|
# @param [String] password
|
|
13
19
|
# @param [Hash] sensors_map which box is related to sensor ID
|
|
@@ -21,6 +27,7 @@ module AtreaControl
|
|
|
21
27
|
@sensors = sensors_map
|
|
22
28
|
end
|
|
23
29
|
|
|
30
|
+
# @return [Selenium::WebDriver::Firefox::Driver]
|
|
24
31
|
def driver
|
|
25
32
|
return @driver if defined?(@driver)
|
|
26
33
|
|
|
@@ -44,8 +51,7 @@ module AtreaControl
|
|
|
44
51
|
|
|
45
52
|
submit = form.find_element(css: "input[type=submit]")
|
|
46
53
|
submit.click
|
|
47
|
-
finish_login
|
|
48
|
-
inspect
|
|
54
|
+
finish_login && inspect
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
# Retrieve dashboard URI from object tag and open it again
|
|
@@ -64,82 +70,124 @@ module AtreaControl
|
|
|
64
70
|
container.text
|
|
65
71
|
end
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
element = driver.find_element css: "div#pageTitle > a"
|
|
71
|
-
element.attribute(:href) =~ /unit=(\d+)/
|
|
72
|
-
Regexp.last_match(1)
|
|
73
|
+
# @return [String] ID of logged user
|
|
74
|
+
def user_id
|
|
75
|
+
@user_id ||= driver.execute_script("return window._user")
|
|
73
76
|
end
|
|
74
77
|
|
|
75
|
-
# @return [
|
|
76
|
-
def
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
element = sensor_element(@sensors[__method__])
|
|
80
|
-
element.find_element(css: "div").text.to_f
|
|
78
|
+
# @return [String] ID of recuperation unit
|
|
79
|
+
def unit_id
|
|
80
|
+
@unit_id ||= driver.execute_script("return window._unit")
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
# @return [
|
|
84
|
-
def
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
# element = driver.find_element id: "contentBox#{@sensors[__method__]}"
|
|
88
|
-
element = sensor_element(@sensors[__method__])
|
|
89
|
-
element.find_element(css: "div:first-child").text.to_f
|
|
83
|
+
# @return [String]
|
|
84
|
+
def user_auth
|
|
85
|
+
@user_auth ||= driver.execute_script("return window.user")&.[] "auth"
|
|
90
86
|
end
|
|
91
87
|
|
|
92
88
|
# @return [String]
|
|
93
|
-
def
|
|
94
|
-
return unless logged?
|
|
89
|
+
def current_mode_name
|
|
90
|
+
return current_mode unless logged?
|
|
95
91
|
|
|
96
|
-
element = sensor_element(@sensors[
|
|
92
|
+
element = sensor_element(@sensors[:current_mode])
|
|
97
93
|
element.find_element(css: "div:first-child").text
|
|
98
94
|
end
|
|
99
95
|
|
|
100
96
|
# quit selenium browser
|
|
101
97
|
def close
|
|
102
98
|
@logged = false
|
|
99
|
+
@user_auth = nil
|
|
103
100
|
driver.quit
|
|
101
|
+
remove_instance_variable :@driver
|
|
104
102
|
end
|
|
105
103
|
|
|
104
|
+
alias logout! close
|
|
105
|
+
|
|
106
106
|
def as_json(_options = nil)
|
|
107
107
|
{
|
|
108
108
|
logged: logged?,
|
|
109
|
-
current_mode:
|
|
109
|
+
current_mode: current_mode_name,
|
|
110
110
|
current_power: current_power,
|
|
111
111
|
outdoor_temperature: outdoor_temperature,
|
|
112
|
+
valid_for: valid_for,
|
|
112
113
|
}
|
|
113
114
|
end
|
|
114
115
|
|
|
116
|
+
alias values as_json
|
|
117
|
+
|
|
115
118
|
def to_json(*args)
|
|
116
119
|
as_json.to_json(*args)
|
|
117
120
|
end
|
|
118
121
|
|
|
119
122
|
def inspect
|
|
120
|
-
"<AtreaControl name: '#{name}' outdoor_temperature: #{outdoor_temperature}°C current_power: #{current_power}% current_mode: '#{
|
|
123
|
+
"<AtreaControl name: '#{name}' outdoor_temperature: '#{outdoor_temperature}°C' current_power: '#{current_power}%' current_mode: '#{current_mode_name}' valid_for: '#{valid_for}'>"
|
|
121
124
|
end
|
|
122
125
|
|
|
126
|
+
def call_unit!
|
|
127
|
+
return false unless user_auth
|
|
128
|
+
|
|
129
|
+
parse_response(response_comm_unit)
|
|
130
|
+
@valid_for = Time.now
|
|
131
|
+
as_json
|
|
132
|
+
rescue RestClient::Forbidden
|
|
133
|
+
close if @logged
|
|
134
|
+
login && call_unit!
|
|
135
|
+
end
|
|
123
136
|
|
|
124
137
|
private
|
|
125
138
|
|
|
126
|
-
def
|
|
127
|
-
|
|
139
|
+
def parse_response(response)
|
|
140
|
+
xml = Nokogiri::XML response.body
|
|
141
|
+
sensors_values = @sensors.transform_values do |id|
|
|
142
|
+
xml.xpath("//O[@I=\"#{id}\"]/@V").last&.value
|
|
143
|
+
end
|
|
144
|
+
refresh_data(sensors_values)
|
|
128
145
|
end
|
|
129
146
|
|
|
130
|
-
|
|
131
|
-
|
|
147
|
+
# @param [Hash] values
|
|
148
|
+
# @return [Hash]
|
|
149
|
+
def refresh_data(values)
|
|
150
|
+
@outdoor_temperature = values[:outdoor_temperature].to_f / 10
|
|
151
|
+
@current_power = values[:current_power].to_f
|
|
152
|
+
@current_mode = mode_map[values[:current_mode]]
|
|
153
|
+
|
|
154
|
+
as_json
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# ? I10204 ?
|
|
158
|
+
def mode_map
|
|
159
|
+
{ "0" => "Vypnuto", "1" => "Automat", "2" => "Větrání", "6" => "Rozvážení" }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def logger
|
|
163
|
+
@logger ||= ::Logger.new($stdout)
|
|
132
164
|
end
|
|
133
165
|
|
|
134
166
|
def finish_login
|
|
135
167
|
13.times do |i|
|
|
136
168
|
return true if open_dashboard
|
|
137
169
|
rescue Selenium::WebDriver::Error::NoSuchElementError => _e
|
|
138
|
-
t = [
|
|
170
|
+
t = [3 * (1 + i), 25].min
|
|
139
171
|
logger.debug "waiting #{t}s for login..."
|
|
140
172
|
sleep t
|
|
141
173
|
end
|
|
142
174
|
raise Error, "unable to login"
|
|
143
175
|
end
|
|
176
|
+
|
|
177
|
+
def sensor_element(sensor_id)
|
|
178
|
+
driver.find_element id: "contentBox#{sensor_id}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# @return [RestClient::Response]
|
|
182
|
+
def response_comm_unit
|
|
183
|
+
params = {
|
|
184
|
+
_user: user_id,
|
|
185
|
+
_unit: unit_id,
|
|
186
|
+
auth: user_auth,
|
|
187
|
+
_t: "config/xml.xml",
|
|
188
|
+
}
|
|
189
|
+
autologin_token = CGI.escape([@login, @password].join("\b"))
|
|
190
|
+
RestClient.get "https://control.atrea.eu/comm/sw/unit.php", { Cookie: "autoLogin=#{autologin_token}", params: params }
|
|
191
|
+
end
|
|
144
192
|
end
|
|
145
193
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atrea_control
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lukáš Pokorný
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-10-
|
|
11
|
+
date: 2021-10-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: nokogiri
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.12'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.12'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rest-client
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.1'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.1'
|
|
13
41
|
- !ruby/object:Gem::Dependency
|
|
14
42
|
name: selenium-webdriver
|
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|