senec 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cc66f87a694b567a5d255e80aeca2ce5bd6bc31bbdce717f991c0f4a4bb6cae
4
- data.tar.gz: 6c2def742896e62ee42d475983b4285ecb3e7a0a0315d6fc5317f959831d4401
3
+ metadata.gz: 37a0113a0636d99436244e2e69122dba3d8e978c74c63858f2cc35774a3eb6b5
4
+ data.tar.gz: bffc7d07e16369e04b518034ab87feedc07ecdc97091e8694caf7b113ff8e95e
5
5
  SHA512:
6
- metadata.gz: c1006a948b5e0932fd9c1e675dbaec90f11e5c6a54b5899c239db0854f7e8623c03030dff72f4162acd716e60ae256526ceea2e883bf7b8f3ac8220ad93fb049
7
- data.tar.gz: 3004661d438142e41e30c758d41e9f0b7ecf3e2f74f5533387689c215aa92e11346806651f413c7b76cb686a575a8f0188f9e03829c38ae1ca36496f074f20f0
6
+ metadata.gz: 2a10a927e07bf216f44e0fc7bd6770d61d851c6523b72fb040800667b65d5e0d4421352929091df67129b7dd1fa16111cc408be93da0398e94ffde0cf99c81f5
7
+ data.tar.gz: c0fa250c00fecf7f6a4a8ac2efc0e04740a3de1d6dfef469cf84e8ff63851e32a85835854edc47858f98109515f8c411d82c4a548a7886f7384a3915307bead5
@@ -8,13 +8,13 @@ jobs:
8
8
 
9
9
  steps:
10
10
  - name: Checkout the code
11
- uses: actions/checkout@v2
11
+ uses: actions/checkout@v3
12
12
 
13
13
  - name: Set up Ruby
14
14
  uses: ruby/setup-ruby@v1
15
15
  with:
16
16
  bundler-cache: true
17
- ruby-version: '3.0'
17
+ ruby-version: '3.1'
18
18
 
19
19
  - name: Lint with RuboCop
20
20
  run: bundle exec rubocop
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ require:
4
4
  - rubocop-rake
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.6
7
+ TargetRubyVersion: 2.7
8
8
  NewCops: enable
9
9
 
10
10
  Style/Documentation:
@@ -15,3 +15,6 @@ Style/FrozenStringLiteralComment:
15
15
 
16
16
  Metrics/MethodLength:
17
17
  Max: 15
18
+
19
+ Layout/LineLength:
20
+ AllowedPatterns: ['\A#'] # Allow long comments
@@ -0,0 +1,18 @@
1
+ {
2
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
3
+ "editor.formatOnSave": true,
4
+ "editor.tabSize": 2,
5
+
6
+ "files.trimTrailingWhitespace": true,
7
+
8
+ "ruby.lint": {
9
+ "rubocop": {
10
+ "forceExclusion": true
11
+ }
12
+ },
13
+
14
+ "[ruby]": {
15
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
16
+ "editor.formatOnSave": true
17
+ }
18
+ }
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gemspec
6
6
  # Rake is a Make-like program implemented in Ruby (https://github.com/ruby/rake)
7
7
  gem 'rake'
8
8
 
9
- # rspec-3.10.0 (http://github.com/rspec)
9
+ # rspec-3.12.0 (http://github.com/rspec)
10
10
  gem 'rspec'
11
11
 
12
12
  # Automatic Ruby code style checking tool. (https://github.com/rubocop/rubocop)
@@ -20,3 +20,12 @@ gem 'rubocop-rspec'
20
20
 
21
21
  # A RuboCop plugin for Rake (https://github.com/rubocop/rubocop-rake)
22
22
  gem 'rubocop-rake'
23
+
24
+ # HTTP should be easy (https://github.com/httprb/http)
25
+ gem 'http'
26
+
27
+ # Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests. (https://relishapp.com/vcr/vcr/docs)
28
+ gem 'vcr'
29
+
30
+ # Library for stubbing HTTP requests in Ruby. (https://github.com/bblimke/webmock)
31
+ gem 'webmock'
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Georg Ledermann
3
+ Copyright (c) 2020,2022 Georg Ledermann
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -2,13 +2,12 @@
2
2
 
3
3
  Access your local SENEC Solar Battery Storage System
4
4
 
5
- **WARNING:** This project was coded in a few hours just for fun after the photovoltaic stuff was installed in my house. I'm not affiliated in any way with the SENEC company.
5
+ **WARNING:** I'm not affiliated in any way with the SENEC company.
6
6
 
7
7
  Inspired by:
8
8
 
9
- * https://github.com/mchwalisz/pysenec
10
- * https://gist.github.com/smashnet/82ad0b9d7f0ba2e5098e6649ba08f88a
11
-
9
+ - https://github.com/mchwalisz/pysenec
10
+ - https://gist.github.com/smashnet/82ad0b9d7f0ba2e5098e6649ba08f88a
12
11
 
13
12
  ## Installation
14
13
 
@@ -31,6 +30,8 @@ puts "Battery fuel charge: #{request.bat_fuel_charge} %"
31
30
  puts "Battery charge current: #{request.bat_charge_current} A"
32
31
  puts "Battery voltage: #{request.bat_voltage} V"
33
32
  puts "\n"
33
+ puts "Case temperature: #{request.case_temp} °C"
34
+ puts "\n"
34
35
  puts "Wallbox charge power: [ #{request.wallbox_charge_power.join(',')} ] W"
35
36
  puts "\n"
36
37
  puts "Grid power: #{request.grid_power} W"
@@ -47,6 +48,8 @@ puts "Measure time: #{Time.at request.measure_time}"
47
48
  # Battery charge current: 19.8 A
48
49
  # Battery voltage: 49.2 V
49
50
  #
51
+ # Case temperature: 31.3 °C
52
+ #
50
53
  # Wallbox charge power: [ 8680, 0, 0, 0 ] W
51
54
  #
52
55
  # Grid power: 315 W
@@ -64,7 +67,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
64
67
 
65
68
  Bug reports and pull requests are welcome on GitHub at https://github.com/solectrus/senec. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/solectrus/senec/blob/master/CODE_OF_CONDUCT.md).
66
69
 
67
-
68
70
  ## License
69
71
 
70
72
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -95,16 +95,11 @@ module Senec # rubocop:disable Metrics/ModuleLength
95
95
  91 => 'EARTH FAULT'
96
96
  }.freeze
97
97
 
98
- # Taken from https://gist.github.com/smashnet/82ad0b9d7f0ba2e5098e6649ba08f88a
98
+ # For a full list of available vars, see http://[IP-of-your-SENEC]/vars.html
99
+ # Comments taken from https://gist.github.com/smashnet/82ad0b9d7f0ba2e5098e6649ba08f88a
99
100
  BASIC_REQUEST = {
100
101
  STATISTIC: {
101
102
  CURRENT_STATE: '', # Current state of the system (int, see SYSTEM_STATE_NAME)
102
- LIVE_BAT_CHARGE_MASTER: '', # Battery charge amount since installation (kWh)
103
- LIVE_BAT_DISCHARGE_MASTER: '', # Battery discharge amount since installation (kWh)
104
- LIVE_GRID_EXPORT: '', # Grid export amount since installation (kWh)
105
- LIVE_GRID_IMPORT: '', # Grid import amount since installation (kWh)
106
- LIVE_HOUSE_CONS: '', # House consumption since installation (kWh)
107
- LIVE_PV_GEN: '', # PV generated power since installation (kWh)
108
103
  MEASURE_TIME: '' # Unix timestamp for above values (ms)
109
104
  },
110
105
  ENERGY: {
@@ -117,14 +112,8 @@ module Senec # rubocop:disable Metrics/ModuleLength
117
112
  GUI_INVERTER_POWER: '', # PV production (W)
118
113
  STAT_HOURS_OF_OPERATION: '' # Appliance hours of operation
119
114
  },
120
- BMS: {
121
- CHARGED_ENERGY: '', # List: Charged energy per battery
122
- DISCHARGED_ENERGY: '', # List: Discharged energy per battery
123
- CYCLES: '' # List: Cycles per battery
124
- },
125
- PV1: {
126
- POWER_RATIO: '', # Grid export limit (percent)
127
- P_TOTAL: '' # ?
115
+ TEMPMEASURE: {
116
+ CASE_TEMP: ''
128
117
  },
129
118
  WALLBOX: {
130
119
  APPARENT_CHARGING_POWER: ''
data/lib/senec/request.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'net/http'
1
+ require 'http'
2
2
  require 'json'
3
3
  require 'senec/value'
4
4
  require 'senec/constants'
@@ -10,66 +10,70 @@ module Senec
10
10
  end
11
11
 
12
12
  def house_power
13
- value = response.dig('ENERGY', 'GUI_HOUSE_POW')
14
- Senec::Value.new(value).to_i
13
+ get('ENERGY', 'GUI_HOUSE_POW')
15
14
  end
16
15
 
17
16
  def inverter_power
18
- value = response.dig('ENERGY', 'GUI_INVERTER_POWER')
19
- Senec::Value.new(value).to_i
17
+ get('ENERGY', 'GUI_INVERTER_POWER')
20
18
  end
21
19
 
22
20
  def bat_power
23
- value = response.dig('ENERGY', 'GUI_BAT_DATA_POWER')
24
- Senec::Value.new(value).to_i
21
+ get('ENERGY', 'GUI_BAT_DATA_POWER')
25
22
  end
26
23
 
27
24
  def bat_fuel_charge
28
- value = response.dig('ENERGY', 'GUI_BAT_DATA_FUEL_CHARGE')
29
- Senec::Value.new(value).to_f
25
+ get('ENERGY', 'GUI_BAT_DATA_FUEL_CHARGE')
30
26
  end
31
27
 
32
28
  def bat_charge_current
33
- value = response.dig('ENERGY', 'GUI_BAT_DATA_CURRENT')
34
- Senec::Value.new(value).to_f
29
+ get('ENERGY', 'GUI_BAT_DATA_CURRENT')
35
30
  end
36
31
 
37
32
  def bat_voltage
38
- value = response.dig('ENERGY', 'GUI_BAT_DATA_VOLTAGE')
39
- Senec::Value.new(value).to_f
33
+ get('ENERGY', 'GUI_BAT_DATA_VOLTAGE')
40
34
  end
41
35
 
42
36
  def grid_power
43
- value = response.dig('ENERGY', 'GUI_GRID_POW')
44
- Senec::Value.new(value).to_i
37
+ get('ENERGY', 'GUI_GRID_POW')
45
38
  end
46
39
 
47
40
  def wallbox_charge_power
48
- response.dig('WALLBOX', 'APPARENT_CHARGING_POWER').map do |value|
49
- Senec::Value.new(value).to_i
50
- end
41
+ get('WALLBOX', 'APPARENT_CHARGING_POWER')
42
+ end
43
+
44
+ def case_temp
45
+ get('TEMPMEASURE', 'CASE_TEMP')
51
46
  end
52
47
 
53
48
  def current_state
54
- value = response.dig('STATISTIC', 'CURRENT_STATE')
55
- state = Senec::Value.new(value).to_i
49
+ state = get('STATISTIC', 'CURRENT_STATE')
56
50
 
57
51
  STATE_NAMES[state]
58
52
  end
59
53
 
60
54
  def measure_time
61
- value = response.dig('STATISTIC', 'MEASURE_TIME')
62
- Senec::Value.new(value).to_i
55
+ get('STATISTIC', 'MEASURE_TIME')
63
56
  end
64
57
 
65
58
  private
66
59
 
60
+ def get(*keys)
61
+ value = response.dig(*keys)
62
+
63
+ if value.is_a?(Array)
64
+ value.map do |v|
65
+ Senec::Value.new(v).decoded
66
+ end
67
+ else
68
+ Senec::Value.new(value).decoded
69
+ end
70
+ end
71
+
67
72
  def response
68
73
  @response ||= begin
69
- res = Net::HTTP.post uri, Senec::BASIC_REQUEST.to_json
74
+ res = HTTP.post uri, json: Senec::BASIC_REQUEST
70
75
 
71
- case res
72
- when Net::HTTPOK
76
+ if res.status.success?
73
77
  JSON.parse(res.body)
74
78
  else
75
79
  throw "Failure: #{res.value}"
data/lib/senec/value.rb CHANGED
@@ -4,37 +4,35 @@ module Senec
4
4
  @data = data
5
5
  end
6
6
 
7
- def to_f
8
- decoded_value
9
- end
10
-
11
- def to_i
12
- decoded_value.round
13
- end
14
-
15
- private
16
-
17
- def decoded_value
7
+ def decoded
18
8
  parts = @data.split('_')
19
9
  prefix = parts[0]
20
10
  value = parts[1]
21
11
 
22
12
  case prefix
23
13
  when 'fl'
24
- hex2float(value)
25
- when 'i3', 'u1', 'u3'
26
- hex2int(value)
14
+ decoded_float(value)
15
+ when 'i3', 'u1', 'u3', 'u6', 'u8'
16
+ decoded_int(value)
17
+ when 'st'
18
+ value
27
19
  # TODO: There are some more prefixes to handle
28
20
  else
29
- raise ArgumentError, "#{@data} cannot be decoded!"
21
+ raise ArgumentError, "#{@data} has unknown prefix!"
30
22
  end
31
23
  end
32
24
 
33
- def hex2float(hex)
25
+ alias to_i decoded
26
+ alias to_f decoded
27
+ alias to_s decoded
28
+
29
+ private
30
+
31
+ def decoded_float(hex)
34
32
  ["0x#{hex}".to_i(16)].pack('L').unpack1('F').round(1)
35
33
  end
36
34
 
37
- def hex2int(hex)
35
+ def decoded_int(hex)
38
36
  "0x#{hex}".to_i(16)
39
37
  end
40
38
  end
data/lib/senec/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Senec
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.6.0'.freeze
3
3
  end
data/senec.gemspec CHANGED
@@ -10,11 +10,12 @@ Gem::Specification.new do |spec|
10
10
  spec.description = 'Access your local SENEC Solar Battery Storage System'
11
11
  spec.homepage = 'https://github.com/solectrus/senec'
12
12
  spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
14
14
 
15
15
  spec.metadata['homepage_uri'] = spec.homepage
16
16
  spec.metadata['source_code_uri'] = 'https://github.com/solectrus/senec'
17
17
  spec.metadata['changelog_uri'] = 'https://github.com/solectrus/senec/releases'
18
+ spec.metadata['rubygems_mfa_required'] = 'true'
18
19
 
19
20
  # Specify which files should be added to the gem when it is released.
20
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: senec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Georg Ledermann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-06 00:00:00.000000000 Z
11
+ date: 2022-11-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Access your local SENEC Solar Battery Storage System
14
14
  email:
@@ -21,6 +21,7 @@ files:
21
21
  - ".gitignore"
22
22
  - ".rspec"
23
23
  - ".rubocop.yml"
24
+ - ".vscode/settings.json"
24
25
  - CODE_OF_CONDUCT.md
25
26
  - Gemfile
26
27
  - LICENSE.txt
@@ -41,6 +42,7 @@ metadata:
41
42
  homepage_uri: https://github.com/solectrus/senec
42
43
  source_code_uri: https://github.com/solectrus/senec
43
44
  changelog_uri: https://github.com/solectrus/senec/releases
45
+ rubygems_mfa_required: 'true'
44
46
  post_install_message:
45
47
  rdoc_options: []
46
48
  require_paths:
@@ -49,14 +51,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
49
51
  requirements:
50
52
  - - ">="
51
53
  - !ruby/object:Gem::Version
52
- version: 2.6.0
54
+ version: 2.7.0
53
55
  required_rubygems_version: !ruby/object:Gem::Requirement
54
56
  requirements:
55
57
  - - ">="
56
58
  - !ruby/object:Gem::Version
57
59
  version: '0'
58
60
  requirements: []
59
- rubygems_version: 3.2.28
61
+ rubygems_version: 3.3.25
60
62
  signing_key:
61
63
  specification_version: 4
62
64
  summary: Unofficial Ruby Client for SENEC Home