senec 0.6.2 → 0.7.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: 877e39b91e6ff1f4709131aaf96394db590396faad43d8648c88ab90cce1ca3a
4
- data.tar.gz: bffeb00945d5a22ab11936299ec8d716283aa5c8283250c2ec337534f10af690
3
+ metadata.gz: f3914b7ea67325757972bb42f497370f9195ba55222d5e5fc87c03af9ff7c825
4
+ data.tar.gz: dca80a11290b1ea0f2b791090b83ba4a169ade0ec528f36ec92463ccb945f5dc
5
5
  SHA512:
6
- metadata.gz: 966c843b9dfe626d753cf7ceafa1c030479a59c8bd076009e8406252147d09f11f239225b86c628a537eb87b538d5893503c6206579cf0c769d235e442035100
7
- data.tar.gz: ca2fc0dfe72ce5934bc0ebeae1b2ac453f188031dbd0a2c515f135c892bc1d971fec9d81f9b7ccde604affdd0a6d312ee9dabfa349f00bd9df2ec97039e22734
6
+ metadata.gz: d19c80369fad7f4f066e0916e26c4280eb8d2a708e149cf9fb11071f29cee49be6fdebd7b225bb1368796771d3cc73682132e22056410db03ec98bea4dbd07e8
7
+ data.tar.gz: 9ca1fa435012bbe331924b1fd2173358fd700fbe3cb5fa2cbd75a9e2a59f9017c6ff575aee089df918bdfe9318dcd34c2b543ae3bd43207617af5bc96a2d79f0
@@ -6,6 +6,11 @@ jobs:
6
6
  test:
7
7
  runs-on: ubuntu-latest
8
8
 
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: ['3.0', '3.1', '3.2']
13
+
9
14
  steps:
10
15
  - name: Checkout the code
11
16
  uses: actions/checkout@v3
@@ -14,7 +19,7 @@ jobs:
14
19
  uses: ruby/setup-ruby@v1
15
20
  with:
16
21
  bundler-cache: true
17
- ruby-version: '3.1'
22
+ ruby-version: ${{ matrix.ruby }}
18
23
 
19
24
  - name: Lint with RuboCop
20
25
  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.7
7
+ TargetRubyVersion: 3.0
8
8
  NewCops: enable
9
9
 
10
10
  Style/Documentation:
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020,2022 Georg Ledermann
3
+ Copyright (c) 2020,2023 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
@@ -1,3 +1,6 @@
1
+ [![Continuous integration](https://github.com/solectrus/senec/actions/workflows/push.yml/badge.svg)](https://github.com/solectrus/senec/actions/workflows/push.yml)
2
+ [![wakatime](https://wakatime.com/badge/user/697af4f5-617a-446d-ba58-407e7f3e0243/project/84ac7dc2-9288-497c-bb20-9c6123d3de66.svg)](https://wakatime.com/badge/user/697af4f5-617a-446d-ba58-407e7f3e0243/project/84ac7dc2-9288-497c-bb20-9c6123d3de66)
3
+
1
4
  # Unofficial Ruby Client for SENEC Home
2
5
 
3
6
  Access your local SENEC Solar Battery Storage System
@@ -20,7 +23,8 @@ $ gem install senec
20
23
  ```ruby
21
24
  require 'senec'
22
25
 
23
- request = Senec::Request.new host: '10.0.1.99'
26
+ senec_ip = '10.0.1.99'
27
+ request = Senec::Request.new host: senec_ip
24
28
 
25
29
  puts "PV production: #{request.inverter_power} W"
26
30
  puts "House power consumption: #{request.house_power} W"
@@ -53,10 +57,22 @@ puts "Measure time: #{Time.at request.measure_time}"
53
57
  # Wallbox charge power: [ 8680, 0, 0, 0 ] W
54
58
  #
55
59
  # Grid power: 315 W
56
- # Current state of the system: CHARGE
60
+ # Current state of the system: 14
57
61
  # Measure time: 2021-10-06 17:50:22 +0200
58
62
  ```
59
63
 
64
+ To get the state name (in German) instead of just the number:
65
+
66
+ ```ruby
67
+ state_names = Senec::State.new(host: senec_ip).names
68
+ request = Senec::Request.new host: senec_ip, state_names: state_names
69
+
70
+ puts request.current_state_name
71
+ # => "LADEN"
72
+ ```
73
+
74
+ The state names are extracted on-the-fly from the JavaScript source code returned by the SENEC web interface.
75
+
60
76
  ## Development
61
77
 
62
78
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -71,6 +87,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/solect
71
87
 
72
88
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
73
89
 
90
+ Copyright (c) 2020,2023 Georg Ledermann
91
+
74
92
  ## Code of Conduct
75
93
 
76
94
  Everyone interacting in this project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/solectrus/senec/blob/master/CODE_OF_CONDUCT.md).
@@ -1,100 +1,4 @@
1
- module Senec # rubocop:disable Metrics/ModuleLength
2
- # Taken from https://github.com/mchwalisz/pysenec
3
- STATE_NAMES = {
4
- 0 => 'INITIAL STATE',
5
- 1 => 'ERROR INVERTER COMMUNICATION',
6
- 2 => 'ERROR ELECTRICY METER',
7
- 3 => 'RIPPLE CONTROL RECEIVER',
8
- 4 => 'INITIAL CHARGE',
9
- 5 => 'MAINTENANCE CHARGE',
10
- 6 => 'MAINTENANCE READY',
11
- 7 => 'MAINTENANCE REQUIRED',
12
- 8 => 'MAN. SAFETY CHARGE',
13
- 9 => 'SAFETY CHARGE READY',
14
- 10 => 'FULL CHARGE',
15
- 11 => 'EQUALIZATION: CHARGE',
16
- 12 => 'DESULFATATION: CHARGE',
17
- 13 => 'BATTERY FULL',
18
- 14 => 'CHARGE',
19
- 15 => 'BATTERY EMPTY',
20
- 16 => 'DISCHARGE',
21
- 17 => 'PV + DISCHARGE',
22
- 18 => 'GRID + DISCHARGE',
23
- 19 => 'PASSIVE',
24
- 20 => 'OFF',
25
- 21 => 'OWN CONSUMPTION',
26
- 22 => 'RESTART',
27
- 23 => 'MAN. EQUALIZATION: CHARGE',
28
- 24 => 'MAN. DESULFATATION: CHARGE',
29
- 25 => 'SAFETY CHARGE',
30
- 26 => 'BATTERY PROTECTION MODE',
31
- 27 => 'EG ERROR',
32
- 28 => 'EG CHARGE',
33
- 29 => 'EG DISCHARGE',
34
- 30 => 'EG PASSIVE',
35
- 31 => 'EG PROHIBIT CHARGE',
36
- 32 => 'EG PROHIBIT DISCHARGE',
37
- 33 => 'EMERGANCY CHARGE',
38
- 34 => 'SOFTWARE UPDATE',
39
- 35 => 'NSP ERROR',
40
- 36 => 'NSP ERROR: GRID',
41
- 37 => 'NSP ERROR: HARDWRE',
42
- 38 => 'NO SERVER CONNECTION',
43
- 39 => 'BMS ERROR',
44
- 40 => 'MAINTENANCE: FILTER',
45
- 41 => 'SLEEPING MODE',
46
- 42 => 'WAITING EXCESS',
47
- 43 => 'CAPACITY TEST: CHARGE',
48
- 44 => 'CAPACITY TEST: DISCHARGE',
49
- 45 => 'MAN. DESULFATATION: WAIT',
50
- 46 => 'MAN. DESULFATATION: READY',
51
- 47 => 'MAN. DESULFATATION: ERROR',
52
- 48 => 'EQUALIZATION: WAIT',
53
- 49 => 'EMERGANCY CHARGE: ERROR',
54
- 50 => 'MAN. EQUALIZATION: WAIT',
55
- 51 => 'MAN. EQUALIZATION: ERROR',
56
- 52 => 'MAN: EQUALIZATION: READY',
57
- 53 => 'AUTO. DESULFATATION: WAIT',
58
- 54 => 'ABSORPTION PHASE',
59
- 55 => 'DC-SWITCH OFF',
60
- 56 => 'PEAK-SHAVING: WAIT',
61
- 57 => 'ERROR BATTERY INVERTER',
62
- 58 => 'NPU-ERROR',
63
- 59 => 'BMS OFFLINE',
64
- 60 => 'MAINTENANCE CHARGE ERROR',
65
- 61 => 'MAN. SAFETY CHARGE ERROR',
66
- 62 => 'SAFETY CHARGE ERROR',
67
- 63 => 'NO CONNECTION TO MASTER',
68
- 64 => 'LITHIUM SAFE MODE ACTIVE',
69
- 65 => 'LITHIUM SAFE MODE DONE',
70
- 66 => 'BATTERY VOLTAGE ERROR',
71
- 67 => 'BMS DC SWITCHED OFF',
72
- 68 => 'GRID INITIALIZATION',
73
- 69 => 'GRID STABILIZATION',
74
- 70 => 'REMOTE SHUTDOWN',
75
- 71 => 'OFFPEAK-CHARGE',
76
- 72 => 'ERROR HALFBRIDGE',
77
- 73 => 'BMS: ERROR OPERATING TEMPERATURE',
78
- 74 => 'FACOTRY SETTINGS NOT FOUND',
79
- 75 => 'BACKUP POWER MODE - ACTIVE',
80
- 76 => 'BACKUP POWER MODE - BATTERY EMPTY',
81
- 77 => 'BACKUP POWER MODE ERROR',
82
- 78 => 'INITIALISING',
83
- 79 => 'INSTALLATION MODE',
84
- 80 => 'GRID OFFLINE',
85
- 81 => 'BMS UPDATE NEEDED',
86
- 82 => 'BMS CONFIGURATION NEEDED',
87
- 83 => 'INSULATION TEST',
88
- 84 => 'SELFTEST',
89
- 85 => 'EXTERNAL CONTROL',
90
- 86 => 'ERROR: TEMPERATURESENSOR',
91
- 87 => 'GRID OPERATOR: CHARGE PROHIBITED',
92
- 88 => 'GRID OPERATOR: DISCHARGE PROHIBITED',
93
- 89 => 'SPARE CAPACITY',
94
- 90 => 'SELFTEST ERROR',
95
- 91 => 'EARTH FAULT'
96
- }.freeze
97
-
1
+ module Senec
98
2
  # For a full list of available vars, see http://[IP-of-your-SENEC]/vars.html
99
3
  # Comments taken from https://gist.github.com/smashnet/82ad0b9d7f0ba2e5098e6649ba08f88a
100
4
  BASIC_REQUEST = {
data/lib/senec/request.rb CHANGED
@@ -5,8 +5,9 @@ require 'senec/constants'
5
5
 
6
6
  module Senec
7
7
  class Request
8
- def initialize(host:)
8
+ def initialize(host:, state_names: nil)
9
9
  @host = host
10
+ @state_names = state_names
10
11
  end
11
12
 
12
13
  def house_power
@@ -46,9 +47,13 @@ module Senec
46
47
  end
47
48
 
48
49
  def current_state
49
- state = get('STATISTIC', 'CURRENT_STATE')
50
+ get('STATISTIC', 'CURRENT_STATE')
51
+ end
52
+
53
+ def current_state_name
54
+ throw RuntimeError, 'No state names provided!' unless @state_names
50
55
 
51
- STATE_NAMES[state]
56
+ @state_names[current_state]
52
57
  end
53
58
 
54
59
  def measure_time
@@ -0,0 +1,46 @@
1
+ require 'http'
2
+
3
+ module Senec
4
+ class State
5
+ def initialize(host:)
6
+ @host = host
7
+ end
8
+
9
+ attr_reader :host
10
+
11
+ # Extract state names from JavaScript file, which is formatted like this:
12
+ #
13
+ # var system_state_name = {
14
+ # 0: "FIRST STATE",
15
+ # 1: "SECOND STATE",
16
+ # ...
17
+ # };
18
+ def names
19
+ response.match(FILE_REGEX)[0].split("\n").each_with_object({}) do |line, hash|
20
+ key, value = line.match(LINE_REGEX)&.captures
21
+ next unless key && value
22
+
23
+ hash[key.to_i] = value
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ FILE_REGEX = /var system_state_name = \{(.*?)\};/m
30
+ LINE_REGEX = /(\d+)\s*:\s*"(.*)"/
31
+
32
+ def response
33
+ @response ||= begin
34
+ res = HTTP.get uri
35
+ raise Senec::Error, res.status.to_s unless res.status.success?
36
+
37
+ res.body.to_s
38
+ end
39
+ end
40
+
41
+ # Use the JavaScript file with German names from the SENEC web interface
42
+ def uri
43
+ URI.parse("http://#{host}/js/DE-de.js")
44
+ end
45
+ end
46
+ end
data/lib/senec/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Senec
2
- VERSION = '0.6.2'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
data/lib/senec.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'senec/version'
2
+ require 'senec/state'
2
3
  require 'senec/request'
3
4
 
4
5
  module Senec
data/senec.gemspec CHANGED
@@ -10,7 +10,7 @@ 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.7.0')
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
14
14
  spec.add_runtime_dependency 'http', '~> 5'
15
15
 
16
16
  spec.metadata['homepage_uri'] = spec.homepage
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.6.2
4
+ version: 0.7.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: 2022-11-13 00:00:00.000000000 Z
11
+ date: 2023-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -46,6 +46,7 @@ files:
46
46
  - lib/senec.rb
47
47
  - lib/senec/constants.rb
48
48
  - lib/senec/request.rb
49
+ - lib/senec/state.rb
49
50
  - lib/senec/value.rb
50
51
  - lib/senec/version.rb
51
52
  - senec.gemspec
@@ -65,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
66
  requirements:
66
67
  - - ">="
67
68
  - !ruby/object:Gem::Version
68
- version: 2.7.0
69
+ version: 3.0.0
69
70
  required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  requirements:
71
72
  - - ">="
72
73
  - !ruby/object:Gem::Version
73
74
  version: '0'
74
75
  requirements: []
75
- rubygems_version: 3.3.25
76
+ rubygems_version: 3.4.6
76
77
  signing_key:
77
78
  specification_version: 4
78
79
  summary: Unofficial Ruby Client for SENEC Home