my_solaredge 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +16 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +39 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +63 -0
- data/LICENSE.txt +21 -0
- data/README.md +76 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/my_solaredge/client.rb +41 -0
- data/lib/my_solaredge/credential_getter.rb +45 -0
- data/lib/my_solaredge/request/abstract_request.rb +58 -0
- data/lib/my_solaredge/request/energy.rb +40 -0
- data/lib/my_solaredge/request/energy_details.rb +47 -0
- data/lib/my_solaredge/request/overview.rb +12 -0
- data/lib/my_solaredge/request/power.rb +29 -0
- data/lib/my_solaredge/request/sites.rb +12 -0
- data/lib/my_solaredge/request/time_frame_energy.rb +29 -0
- data/lib/my_solaredge/response/abstract_response.rb +73 -0
- data/lib/my_solaredge/response/energy.rb +10 -0
- data/lib/my_solaredge/response/energy_details.rb +10 -0
- data/lib/my_solaredge/response/overview.rb +10 -0
- data/lib/my_solaredge/response/power.rb +13 -0
- data/lib/my_solaredge/response/sites.rb +14 -0
- data/lib/my_solaredge/response/time_frame_energy.rb +13 -0
- data/lib/my_solaredge/version.rb +5 -0
- data/lib/my_solaredge.rb +28 -0
- data/my_solaredge.gemspec +35 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4e783a33b4be16a47de8c2e56dd34c4da1923e3c8175fb034436d3ec3b1e8d45
|
4
|
+
data.tar.gz: dde7c760d8e94a154b22c89954220f8f2a8835a9886d1442a9887db26e0a5437
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 59adee7c96179683cbbc41a45a84f1f98b0784323e65ff9fa9c70d8fb7dedc37abc3a04e9f49ada58eebeab53859145acef2aa8c5161a7e8be458acf528f1f6d
|
7
|
+
data.tar.gz: 6546cf57dc19acccfb039c6c6a052faccd7adc388278a627117bfe611a4f7c9323d5df65df13c73c3abd5697f937b45667b1c8b11074d1de9325f71e0324d9bf
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push,pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- name: Set up Ruby
|
11
|
+
uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 3.0.1
|
14
|
+
bundler-cache: true
|
15
|
+
- name: Run the default task
|
16
|
+
run: bundle exec rake
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
TargetRubyVersion: 3.0
|
4
|
+
|
5
|
+
Layout/EndOfLine:
|
6
|
+
Enabled: False
|
7
|
+
|
8
|
+
Layout/FirstHashElementIndentation:
|
9
|
+
EnforcedStyle: consistent
|
10
|
+
|
11
|
+
Layout/LineLength:
|
12
|
+
Max: 120
|
13
|
+
|
14
|
+
Lint/ScriptPermission:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Exclude:
|
19
|
+
- "spec/**/*"
|
20
|
+
|
21
|
+
Style/BlockDelimiters:
|
22
|
+
IgnoredMethods: ["subject"]
|
23
|
+
|
24
|
+
Style/Documentation:
|
25
|
+
Exclude:
|
26
|
+
- "lib/my_solaredge/response/**/*" # they are so straightforward...
|
27
|
+
|
28
|
+
Style/StringLiterals:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/StringLiteralsInInterpolation:
|
32
|
+
Enabled: true
|
33
|
+
EnforcedStyle: double_quotes
|
34
|
+
|
35
|
+
Style/TrailingCommaInArguments:
|
36
|
+
EnforcedStyleForMultiline: consistent_comma
|
37
|
+
|
38
|
+
Style/TrailingCommaInHashLiteral:
|
39
|
+
EnforcedStyleForMultiline: comma
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
my_solaredge (0.1.0)
|
5
|
+
httparty (~> 0.17.3)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.2)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
httparty (0.17.3)
|
13
|
+
mime-types (~> 3.0)
|
14
|
+
multi_xml (>= 0.5.2)
|
15
|
+
mime-types (3.4.1)
|
16
|
+
mime-types-data (~> 3.2015)
|
17
|
+
mime-types-data (3.2022.0105)
|
18
|
+
multi_xml (0.6.0)
|
19
|
+
parallel (1.21.0)
|
20
|
+
parser (3.0.2.0)
|
21
|
+
ast (~> 2.4.1)
|
22
|
+
rainbow (3.0.0)
|
23
|
+
rake (13.0.6)
|
24
|
+
regexp_parser (2.2.1)
|
25
|
+
rexml (3.2.5)
|
26
|
+
rspec (3.11.0)
|
27
|
+
rspec-core (~> 3.11.0)
|
28
|
+
rspec-expectations (~> 3.11.0)
|
29
|
+
rspec-mocks (~> 3.11.0)
|
30
|
+
rspec-core (3.11.0)
|
31
|
+
rspec-support (~> 3.11.0)
|
32
|
+
rspec-expectations (3.11.0)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.11.0)
|
35
|
+
rspec-mocks (3.11.0)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.11.0)
|
38
|
+
rspec-support (3.11.0)
|
39
|
+
rubocop (1.23.0)
|
40
|
+
parallel (~> 1.10)
|
41
|
+
parser (>= 3.0.0.0)
|
42
|
+
rainbow (>= 2.2.2, < 4.0)
|
43
|
+
regexp_parser (>= 1.8, < 3.0)
|
44
|
+
rexml
|
45
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
46
|
+
ruby-progressbar (~> 1.7)
|
47
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
48
|
+
rubocop-ast (1.13.0)
|
49
|
+
parser (>= 3.0.1.1)
|
50
|
+
ruby-progressbar (1.11.0)
|
51
|
+
unicode-display_width (2.1.0)
|
52
|
+
|
53
|
+
PLATFORMS
|
54
|
+
x64-mingw32
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
my_solaredge!
|
58
|
+
rake (~> 13.0)
|
59
|
+
rspec (~> 3.0)
|
60
|
+
rubocop (~> 1.7)
|
61
|
+
|
62
|
+
BUNDLED WITH
|
63
|
+
2.2.21
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 reedstonefood
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# MySolaredge
|
2
|
+
|
3
|
+
A ruby gem to connect to Solaredge's API. Use it to retrieve the latest or historical energy data for your solar panels.
|
4
|
+
|
5
|
+
It is aimed at individual consumers, who wish to monitor their own solar panels, rather than installers/vendors who may have access to multiple sites.
|
6
|
+
|
7
|
+
## Supported endpoints
|
8
|
+
|
9
|
+
The first 6 endpoints lists in the API documentation have been implemented.
|
10
|
+
|
11
|
+
- **sites** - Returns a list of sites related to the given token
|
12
|
+
- **energy** - Return the site energy measurements
|
13
|
+
- **time_frame_energy** - Return the site total energy produced for a given period
|
14
|
+
- **power** - Return the site power measurements in 15 minutes resolution (max 1 month at a time)
|
15
|
+
- **overview** - Display the site overview data. Handy if you want to replicate the summary data shown in the mobile app
|
16
|
+
- **energy_details** - Detailed site energy measurements from meters such as consumption, export (feed-in), import (purchase), etc.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem install 'my_solaredge'
|
22
|
+
```
|
23
|
+
|
24
|
+
## Required credentials
|
25
|
+
|
26
|
+
To run the service, you will need an API Key. This can be obtained whilst logged in to [Solaredge's web application](https://monitoring.solaredge.com/).
|
27
|
+
|
28
|
+
Note there is a daily usage limit of around 300 calls per API key.
|
29
|
+
|
30
|
+
For most endpoints, you will need to know your site ID. This can be found via the `sites` endpoint.
|
31
|
+
|
32
|
+
It can also be provided alongside your API key when initializing the client. If it is not provided at this point, then it is assumed to be the first site ID from the `sites` endpoint. It is recommended to supply the site ID to save time & reduce un-necessary usage of the daily API quota.
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# Initializing the client
|
38
|
+
credentials = { api_key: 'ABC123' } # add site_id: 456 to this when you have it
|
39
|
+
solaredge = MySolaredge.new(credentials)
|
40
|
+
|
41
|
+
# Retrieve hourly energy production
|
42
|
+
energy = solaredge.energy(time_unit: :daily, start_date: '2022-02-14', end_date: Date.today)
|
43
|
+
energy["values"].first # { "date" => <DateTime: 2022-7-24T00:00:00>, "value"=> nil }
|
44
|
+
|
45
|
+
# Energy produced in given timeframe. Max 1 year
|
46
|
+
solaredge.time_frame_energy(start_date: '01 Jan 2022', '31 Mar 2022').value # returns a decimal of the total Wh produced in that time period
|
47
|
+
```
|
48
|
+
|
49
|
+
## Features
|
50
|
+
|
51
|
+
- Credentials can be provided either as a hash or a link to a YAML file
|
52
|
+
- All parameters are in camel_case (Ruby standard)
|
53
|
+
- Input types are flexible: where date/datetimes are required you can use Strings, Dates or Datetimes, and where strings are required, either Strings or Symbols are accepted
|
54
|
+
- In the output, dates are automatically converted to Date/DateTime objects
|
55
|
+
- The API produces the somewhat unusual response of `{ "endpoint_name" => { useful_data} }`. This gem saves you time by only giving `useful_data` in the Response. If you want the raw HTTPary response object then use `.raw_response` on the Response object
|
56
|
+
- Some convenience methods on responses, like `value` on `time_frame_energy` in the above example
|
57
|
+
|
58
|
+
## Why create this gem?
|
59
|
+
|
60
|
+
Whilst there [already is a ruby gem](https://rubygems.org/gems/solaredge) to connect to Solaredge's API, it hasn't been updated since 2015, whereas the API has been updated several times since then. Additionally, that gem does not appear to state what license it is released under.
|
61
|
+
|
62
|
+
Plus I wanted to make a version that was easier to use.
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
There are more endpoints in the API that have not been implemented. Feel free to submit PR's for these, or you could raise an issue & I might implement it for you.
|
67
|
+
|
68
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/reedstonefood/my_solaredge.
|
69
|
+
|
70
|
+
## Useful links
|
71
|
+
|
72
|
+
- [Solaredge's monitoring service API documentation](https://solar.ece.ksu.edu/downloads/guides/SolarEdge.pdf)
|
73
|
+
|
74
|
+
## License
|
75
|
+
|
76
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "my_solaredge"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
module MySolaredge
|
6
|
+
# The main object from where everything else happens
|
7
|
+
class Client
|
8
|
+
IMPLEMENTED_ENDPOINTS = %i[energy energy_details power overview sites time_frame_energy].freeze
|
9
|
+
|
10
|
+
def initialize(credentials_source)
|
11
|
+
@credentials_source = credentials_source
|
12
|
+
end
|
13
|
+
|
14
|
+
def credentials
|
15
|
+
@credentials ||= CredentialGetter.new(@credentials_source)
|
16
|
+
end
|
17
|
+
|
18
|
+
def api_key
|
19
|
+
credentials.api_key
|
20
|
+
end
|
21
|
+
|
22
|
+
def site_id
|
23
|
+
credentials.site_id || sites.first_site_id
|
24
|
+
end
|
25
|
+
|
26
|
+
IMPLEMENTED_ENDPOINTS.each do |endpoint|
|
27
|
+
define_method endpoint.to_s do |options = {}|
|
28
|
+
klass = Object.const_get("MySolaredge::Request::#{camelize(endpoint)}")
|
29
|
+
request = klass.new(api_key, site_id, options)
|
30
|
+
response_klass = Object.const_get("MySolaredge::Response::#{camelize(endpoint)}")
|
31
|
+
response_klass.new(request.call)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def camelize(string)
|
38
|
+
string.to_s.split('_').collect(&:capitalize).join
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
# Gets credentials from a source, either YAML or a string
|
5
|
+
class CredentialGetter
|
6
|
+
class InvalidSourceError < StandardError; end
|
7
|
+
class SiteIdNotAnIntegerError < StandardError; end
|
8
|
+
require 'yaml'
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize(data_source)
|
12
|
+
case data_source.class.to_s
|
13
|
+
when 'Hash'
|
14
|
+
load_hash(data_source)
|
15
|
+
when 'String'
|
16
|
+
load_file(data_source)
|
17
|
+
else
|
18
|
+
raise InvalidSourceError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def site_id
|
23
|
+
data["site_id"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def api_key
|
27
|
+
data["api_key"]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def load_file(source_file)
|
33
|
+
@data = YAML.load_file(source_file)
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_hash(hash)
|
37
|
+
@data = hash.transform_keys(&:to_s)
|
38
|
+
begin
|
39
|
+
@data["site_id"] = Integer(@data["site_id"]) if @data["site_id"]
|
40
|
+
rescue ArgumentError
|
41
|
+
raise SiteIdNotAnIntegerError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
module MySolaredge
|
6
|
+
module Request
|
7
|
+
# Sends requests to solaredges's main API
|
8
|
+
class AbstractRequest
|
9
|
+
include HTTParty
|
10
|
+
base_uri "https://monitoringapi.solaredge.com"
|
11
|
+
|
12
|
+
def initialize(api_key, site_id, options)
|
13
|
+
@api_key = api_key
|
14
|
+
@site_id = site_id
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
puts "Calling #{endpoint} with #{base_params.merge(params)}" if @options[:debug]
|
20
|
+
self.class.public_send(
|
21
|
+
method, endpoint,
|
22
|
+
query: base_params.merge(params),
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def base_params
|
27
|
+
{
|
28
|
+
"api_key" => @api_key,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def params
|
33
|
+
{}
|
34
|
+
end
|
35
|
+
|
36
|
+
def method
|
37
|
+
:get
|
38
|
+
end
|
39
|
+
|
40
|
+
# is this needed?
|
41
|
+
def klass_name
|
42
|
+
self.class.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
43
|
+
end
|
44
|
+
|
45
|
+
def body
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def convert_date(date)
|
50
|
+
Date.parse(date.to_s).strftime('%Y-%m-%d')
|
51
|
+
end
|
52
|
+
|
53
|
+
def convert_datetime(date)
|
54
|
+
DateTime.parse(date.to_s).strftime('%Y-%m-%d %H:%M:%S')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
module Request
|
5
|
+
# Return the site energy measurements
|
6
|
+
class Energy < AbstractRequest
|
7
|
+
ALLOWED_UNITS = %w[QUARTER_OF_AN_HOUR HOUR DAY WEEK MONTH YEAR].freeze
|
8
|
+
|
9
|
+
def endpoint
|
10
|
+
unless ALLOWED_UNITS.include?(time_unit)
|
11
|
+
raise ArgumentError, "time_unit must be one of: #{ALLOWED_UNITS.join(", ")}"
|
12
|
+
end
|
13
|
+
|
14
|
+
"/site/#{@site_id}/energy"
|
15
|
+
end
|
16
|
+
|
17
|
+
def params
|
18
|
+
{
|
19
|
+
"timeUnit" => time_unit,
|
20
|
+
"startDate" => start_date,
|
21
|
+
"endDate" => end_date,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def time_unit
|
28
|
+
@options[:time_unit].to_s.upcase
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_date
|
32
|
+
convert_date(@options[:start_date])
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_date
|
36
|
+
convert_date(@options[:end_date])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
module Request
|
5
|
+
# Detailed site energy measurements from meters such as consumption, export (feed-in), import (purchase), etc.
|
6
|
+
class EnergyDetails < AbstractRequest
|
7
|
+
ALLOWED_UNITS = %w[QUARTER_OF_AN_HOUR HOUR DAY WEEK MONTH YEAR].freeze
|
8
|
+
|
9
|
+
def endpoint
|
10
|
+
unless time_unit.nil? || ALLOWED_UNITS.include?(time_unit)
|
11
|
+
raise ArgumentError, "time_unit must be one of: #{ALLOWED_UNITS.join(", ")}"
|
12
|
+
end
|
13
|
+
|
14
|
+
"/site/#{@site_id}/energyDetails"
|
15
|
+
end
|
16
|
+
|
17
|
+
def params
|
18
|
+
{
|
19
|
+
"startTime" => start_time,
|
20
|
+
"endTime" => end_time,
|
21
|
+
}.merge(
|
22
|
+
time_unit.nil? ? {} : { "timeUnit" => time_unit },
|
23
|
+
).merge(
|
24
|
+
meters.nil? ? {} : { "meters" => meters },
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def time_unit
|
31
|
+
@options[:time_unit]&.to_s&.upcase
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_time
|
35
|
+
convert_datetime(@options[:start_time])
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_time
|
39
|
+
convert_datetime(@options[:end_time])
|
40
|
+
end
|
41
|
+
|
42
|
+
def meters
|
43
|
+
@options[:meters] # Must be comma-separated String
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
module Request
|
5
|
+
# Display the site overview data, including last year, last month and current energy
|
6
|
+
class Overview < AbstractRequest
|
7
|
+
def endpoint
|
8
|
+
"/site/#{@site_id}/overview"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
module Request
|
5
|
+
# Return the site power measurements in 15 minutes resolution. Max 1 month period
|
6
|
+
class Power < AbstractRequest
|
7
|
+
def endpoint
|
8
|
+
"/site/#{@site_id}/power"
|
9
|
+
end
|
10
|
+
|
11
|
+
def params
|
12
|
+
{
|
13
|
+
"startTime" => start_time,
|
14
|
+
"endTime" => end_time,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def start_time
|
21
|
+
convert_datetime(@options[:start_time])
|
22
|
+
end
|
23
|
+
|
24
|
+
def end_time
|
25
|
+
convert_datetime(@options[:end_time])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MySolaredge
|
4
|
+
module Request
|
5
|
+
# Return the site total energy produced for a given period
|
6
|
+
class TimeFrameEnergy < AbstractRequest
|
7
|
+
def endpoint
|
8
|
+
"/site/#{@site_id}/timeFrameEnergy"
|
9
|
+
end
|
10
|
+
|
11
|
+
def params
|
12
|
+
{
|
13
|
+
"startDate" => start_date,
|
14
|
+
"endDate" => end_date,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def start_date
|
21
|
+
convert_date(@options[:start_date])
|
22
|
+
end
|
23
|
+
|
24
|
+
def end_date
|
25
|
+
convert_date(@options[:end_date])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module MySolaredge
|
6
|
+
module Response
|
7
|
+
# Make response a bit easier to deal with in Ruby
|
8
|
+
class AbstractResponse
|
9
|
+
attr_reader :raw_response
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators :@parsed_response, :[]
|
14
|
+
|
15
|
+
def initialize(raw_response)
|
16
|
+
@raw_response = raw_response # responses are of the format {endpoint_name: { actual_data }}
|
17
|
+
parse if ok?
|
18
|
+
end
|
19
|
+
|
20
|
+
def ok?
|
21
|
+
raw_response.ok?
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse
|
25
|
+
@parsed_response = recursive_parse(useful_body_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
def useful_body_data
|
29
|
+
JSON.parse(raw_response.body).values.first
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def recursive_parse(original)
|
35
|
+
case original
|
36
|
+
when Hash
|
37
|
+
original.transform_values do |value|
|
38
|
+
clever_parse(value)
|
39
|
+
end
|
40
|
+
when Array
|
41
|
+
original.map do |value|
|
42
|
+
clever_parse(value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def clever_parse(value)
|
48
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
49
|
+
recursive_parse(value)
|
50
|
+
elsif date_string?(value)
|
51
|
+
Date.parse(value)
|
52
|
+
elsif datetime_string?(value)
|
53
|
+
DateTime.parse(value)
|
54
|
+
else
|
55
|
+
value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Try to identify dates
|
60
|
+
def datetime_string?(value)
|
61
|
+
value.is_a?(String) &&
|
62
|
+
value.length == 19 &&
|
63
|
+
/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/.match(value)
|
64
|
+
end
|
65
|
+
|
66
|
+
def date_string?(value)
|
67
|
+
value.is_a?(String) &&
|
68
|
+
value.length == 10 &&
|
69
|
+
/[0-9]{4}-[0-9]{2}-[0-9]{2}/.match(value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module MySolaredge
|
6
|
+
module Response
|
7
|
+
# Calls the /sites endpoint
|
8
|
+
class Sites < AbstractResponse
|
9
|
+
def first_site_id
|
10
|
+
raw_response.dig("sites", "site").first["id"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/my_solaredge.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "my_solaredge/client"
|
4
|
+
require_relative "my_solaredge/credential_getter"
|
5
|
+
require_relative "my_solaredge/version"
|
6
|
+
require_relative "my_solaredge/request/abstract_request"
|
7
|
+
require_relative "my_solaredge/request/energy"
|
8
|
+
require_relative "my_solaredge/request/energy_details"
|
9
|
+
require_relative "my_solaredge/request/overview"
|
10
|
+
require_relative "my_solaredge/request/power"
|
11
|
+
require_relative "my_solaredge/request/sites"
|
12
|
+
require_relative "my_solaredge/request/time_frame_energy"
|
13
|
+
require_relative "my_solaredge/response/abstract_response"
|
14
|
+
require_relative "my_solaredge/response/energy"
|
15
|
+
require_relative "my_solaredge/response/energy_details"
|
16
|
+
require_relative "my_solaredge/response/overview"
|
17
|
+
require_relative "my_solaredge/response/power"
|
18
|
+
require_relative "my_solaredge/response/sites"
|
19
|
+
require_relative "my_solaredge/response/time_frame_energy"
|
20
|
+
|
21
|
+
# Caling `new` creates a Client
|
22
|
+
module MySolaredge
|
23
|
+
class Error < StandardError; end
|
24
|
+
|
25
|
+
def self.new(...)
|
26
|
+
Client.new(...)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/my_solaredge/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "my_solaredge"
|
7
|
+
spec.version = MySolaredge::VERSION
|
8
|
+
spec.authors = ["reedstonefood"]
|
9
|
+
spec.email = ["reedstonefood@users.noreply.github.com"]
|
10
|
+
|
11
|
+
spec.summary = "Wrapper for Solaredge's monitoring webservice API"
|
12
|
+
spec.description = "A tool to get data from Solaredge's monitoring website, commonly data from solar panels"
|
13
|
+
spec.homepage = "https://github.com/reedstonefood/my_solaredge"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.0.0"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/reedstonefood/my_solaredge"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/reedstonefood/my_solaredge/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_dependency "httparty", "~> 0.17.3"
|
31
|
+
|
32
|
+
spec.metadata = {
|
33
|
+
'rubygems_mfa_required' => 'true',
|
34
|
+
}
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my_solaredge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- reedstonefood
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-07-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.17.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.17.3
|
27
|
+
description: A tool to get data from Solaredge's monitoring website, commonly data
|
28
|
+
from solar panels
|
29
|
+
email:
|
30
|
+
- reedstonefood@users.noreply.github.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- ".github/workflows/main.yml"
|
36
|
+
- ".gitignore"
|
37
|
+
- ".rspec"
|
38
|
+
- ".rubocop.yml"
|
39
|
+
- CHANGELOG.md
|
40
|
+
- Gemfile
|
41
|
+
- Gemfile.lock
|
42
|
+
- LICENSE.txt
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- bin/console
|
46
|
+
- bin/setup
|
47
|
+
- lib/my_solaredge.rb
|
48
|
+
- lib/my_solaredge/client.rb
|
49
|
+
- lib/my_solaredge/credential_getter.rb
|
50
|
+
- lib/my_solaredge/request/abstract_request.rb
|
51
|
+
- lib/my_solaredge/request/energy.rb
|
52
|
+
- lib/my_solaredge/request/energy_details.rb
|
53
|
+
- lib/my_solaredge/request/overview.rb
|
54
|
+
- lib/my_solaredge/request/power.rb
|
55
|
+
- lib/my_solaredge/request/sites.rb
|
56
|
+
- lib/my_solaredge/request/time_frame_energy.rb
|
57
|
+
- lib/my_solaredge/response/abstract_response.rb
|
58
|
+
- lib/my_solaredge/response/energy.rb
|
59
|
+
- lib/my_solaredge/response/energy_details.rb
|
60
|
+
- lib/my_solaredge/response/overview.rb
|
61
|
+
- lib/my_solaredge/response/power.rb
|
62
|
+
- lib/my_solaredge/response/sites.rb
|
63
|
+
- lib/my_solaredge/response/time_frame_energy.rb
|
64
|
+
- lib/my_solaredge/version.rb
|
65
|
+
- my_solaredge.gemspec
|
66
|
+
homepage: https://github.com/reedstonefood/my_solaredge
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata:
|
70
|
+
rubygems_mfa_required: 'true'
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 3.0.0
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.2.15
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Wrapper for Solaredge's monitoring webservice API
|
90
|
+
test_files: []
|