senec 0.4.0 → 0.6.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 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