egauge-rb 0.2.0 → 1.0.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: 62c4a2fc2d4b598158af977fef23b0358f8b3aef93c8ff67c244fc4496a5273f
4
- data.tar.gz: 64de5a4c83da20b04103b9b1dd6c81892d34947b7f43740fd6b7b2e6760aaaa4
3
+ metadata.gz: 870ff3fbd68b41a31cbe2f5569747a9bad1548f6155916eb7e8b6fae6e14c908
4
+ data.tar.gz: 83f121d4b91772be8f06b6df1a7ae86636bef65d86ccc1eebecf0b6220f1ea12
5
5
  SHA512:
6
- metadata.gz: 849514cd5fd5d144d472f961b5467cd7abfa62f483f2d702e6b7366afaf4bc492e423d007f2b2f9c54b9acafc7dc929ff314c40fe090c8eb8381432571dcc919
7
- data.tar.gz: 9180bb1e396cc44b844d3703ad3e79bdfb9dcebd80cd38ed67915615858d3059ae287903f43a0ef509b10704d28361393f54520d67426f5e3980e707396f2071
6
+ metadata.gz: a24cfeee85d4adf9c3e77a9d5afff9d99cdb3f187e914a5d1e1ce3f55ae96a9a99c8f6f069230e43ec0dd0dd8ce352b129c2bac2c654256e42b844837f9b8076
7
+ data.tar.gz: 0063d5d9e63410339c912630930d07fed8bb154ae67e84dadfdc03f4e4242473cb16b33b009321d6561f6253cfe6eb1bd8e372046c2490a6f942863513c7f8db
@@ -1,15 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- egauge-rb (0.1.0)
5
- activesupport
4
+ egauge-rb (1.0.0)
5
+ activesupport (= 5.2.1)
6
6
  httpclient
7
- nokogiri
7
+ nokogiri (= 1.8.5)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (5.1.6)
12
+ activesupport (5.2.1)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 0.7, < 2)
15
15
  minitest (~> 5.1)
@@ -18,12 +18,12 @@ GEM
18
18
  concurrent-ruby (1.0.5)
19
19
  diff-lcs (1.3)
20
20
  httpclient (2.8.3)
21
- i18n (1.0.0)
21
+ i18n (1.1.1)
22
22
  concurrent-ruby (~> 1.0)
23
23
  method_source (0.9.0)
24
24
  mini_portile2 (2.3.0)
25
25
  minitest (5.11.3)
26
- nokogiri (1.8.2)
26
+ nokogiri (1.8.5)
27
27
  mini_portile2 (~> 2.3.0)
28
28
  pry (0.11.3)
29
29
  coderay (~> 1.1.0)
@@ -57,4 +57,4 @@ DEPENDENCIES
57
57
  rspec (~> 3.0)
58
58
 
59
59
  BUNDLED WITH
60
- 1.16.0
60
+ 1.16.2
data/README.md CHANGED
@@ -21,46 +21,50 @@ Or install it yourself as:
21
21
  ## Usage
22
22
  Using this gem requires some understanding of the [Egauge API](https://www.egauge.net/docs/egauge-xml-api.pdf).
23
23
 
24
- ### Basic Query
25
- Queries return response objects that can be interacted with. More details on the response object are found below.
26
24
  ```ruby
27
25
  require 'egauge'
28
- client = Egauge::Client.new('http://egaugeurl.egaug.es/12345')
29
- # This nil is necessary because the query structure is 'h&n=24'
30
- client.query(:h => nil, :n => 24, :f => 1522800000)
26
+ client = Egauge::Client.new('http://<device_name>.egaug.es')
31
27
  ```
32
- ### Helper query
33
- There are helpers to query data for you without having to craft queries. These also return response objects.
28
+ The Client object implements a `fetch` method which takes hash that needs these keys set:
29
+ - `:timestamp` [Timestamp] - This is the point in time
30
+ from which to fetch past readings. The "latest" reading
31
+ will be the beginning of the current period breakdown.
32
+ For instance, if the timestamp is `2018-10-20 13:06` and
33
+ the breakdown is hourly, the latest reading will be
34
+ from `2018-10-20 13:00`.
35
+ - `:breakdown` [Symbol] - This defines the time period
36
+ between the readings. This can be `:hour`, `:day` or `:month`.
37
+ - `:count` [Integer] - Number of past readings to fetch.
38
+
34
39
  ```ruby
35
- require 'egauge'
36
- client = Egauge::Client.new('http://egaugeurl.egaug.es/12345')
37
- client.full_day_kwh
40
+ options = {
41
+ :timestamp => 2018-10-26 21:47:23 -0400,
42
+ :breakdown => :hour,
43
+ :count => 3
44
+ }
45
+ client.fetch(options)
46
+ [
47
+ {"Date & Time"=>"1540602000", "Usage [kWh]"=>"0.000000000", "Generation [kWh]"=>"155625.220777500", "Solar [kWh]"=>"155625.220777500", "Solar+ [kWh]"=>"155707.304512778"},
48
+ {"Date & Time"=>"1540598400", "Usage [kWh]"=>"0.000000000", "Generation [kWh]"=>"155625.240751111", "Solar [kWh]"=>"155625.240751111", "Solar+ [kWh]"=>"155707.304512778"},
49
+ {"Date & Time"=>"1540594800", "Usage [kWh]"=>"0.000000000", "Generation [kWh]"=>"155625.262013333", "Solar [kWh]"=>"155625.262013333", "Solar+ [kWh]"=>"155707.304512778"}
50
+ ]
38
51
  ```
39
52
 
40
- ### Egauge response object
41
- Queries will return a response object. That object will have reader methods for each header that will return the rows of that header.
42
-
43
- If you're unsure what your headers are, there is a method you can use to find out!
53
+ ## Development
44
54
 
45
- ```ruby
46
- require 'egauge'
47
- client = Egauge::Client.new('http://egaugeurl.egaug.es/12345')
48
- response = client.query('cgi-bin/egauge-show', :h => nil, :n => 24, :f => 1522800000)
55
+ After checking out the repo, run `bin/setup` to install dependencies.
56
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
49
57
 
50
- respones.headers
51
- => ["solar", "solar2"]
58
+ To install this gem onto your local machine, run `bundle exec rake install`.
59
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
52
60
 
53
- response.solar
54
- => [123412341234, 123412341234, 123412341234]
61
+ ## Testing
55
62
 
63
+ `Rspec` is used as the testing framework. To test the whole suite, just run the following command.
64
+ ```ruby
65
+ rake spec
56
66
  ```
57
67
 
58
- ## Development
59
-
60
- 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.
61
-
62
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
-
64
68
  ## Contributing
65
69
 
66
70
  Bug reports and pull requests are welcome on GitHub at https://github.com/ArcadiaPower/egauge-rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_dependency "httpclient"
24
- spec.add_dependency "nokogiri"
25
- spec.add_dependency "activesupport"
24
+ spec.add_dependency "nokogiri", "1.8.5"
25
+ spec.add_dependency "activesupport", "5.2.1"
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 1.16"
28
28
  spec.add_development_dependency "rake", "~> 10.0"
@@ -1,5 +1,3 @@
1
1
  require "egauge/version"
2
- require "egauge/power_helpers"
3
2
  require "egauge/client"
4
- require "egauge/response"
5
3
  require "active_support/all"
@@ -1,24 +1,65 @@
1
1
  require 'httpclient'
2
+ require 'csv'
2
3
 
3
4
  module Egauge
4
5
  class Client
5
- include Egauge::PowerHelpers
6
-
7
6
  EGAUGE_PATH = '/cgi-bin/egauge-show?'.freeze
8
7
 
8
+ # The base_url should look something like
9
+ # this: 'http://egauge12345.egaug.es'
9
10
  def initialize(base_url)
10
11
  @client = HTTPClient.new(base_url: base_url)
11
12
  end
12
13
 
13
- def query(options = {})
14
- Egauge::Response.new(client.get(EGAUGE_PATH + query_string(options)).body)
14
+ # The options hash should have 3 keys defined:
15
+ # 1. :timestamp [Timestamp] - This is the point in time
16
+ # from which to fetch past readings. The "latest" reading
17
+ # will be the beginning of the current period breakdown.
18
+ # For instance if the timestamp is 2018-10-20 13:06 and
19
+ # the breakdown is hourly, the latest reading will be
20
+ # from 2018-10-20 13:00
21
+ # 2. :breakdown [Symbol] - This defines the time period
22
+ # between the readings. This can be :hour, :day or :month
23
+ # 3. :count [Integer] - Number of past readings to fetch
24
+ #
25
+ # This method returns an array of hashes with these values
26
+ # - "Date & Time" (An integer representing time since epoch)
27
+ # - "Usage [kWh]"
28
+ # - "Generation [kWh]"
29
+ # - "Solar [kWh]"
30
+ # - "Solar+ [kWh]"
31
+ def fetch(options)
32
+ timestamps = build_timestamps(options)
33
+ params = { T: timestamps.join(","), c: nil }
34
+ query(params)
15
35
  end
16
36
 
17
37
  private
18
38
  attr_reader :client
19
39
 
20
- def query_string(options)
21
- options.stringify_keys.map do |key, value|
40
+ def build_timestamps(options)
41
+ timestamp = options[:timestamp]
42
+ breakdown = options[:breakdown]
43
+ count = options[:count]
44
+
45
+ end_time = timestamp.send("beginning_of_#{breakdown}".to_sym)
46
+ time_method = "#{breakdown}s"
47
+ timestamps = []
48
+ count.times do |i|
49
+ timestamps << (end_time - i.send(time_method)).to_i
50
+ end
51
+ timestamps
52
+ end
53
+
54
+ def query(params)
55
+ csv_str = client.get(EGAUGE_PATH + query_string(params)).body
56
+ records = []
57
+ CSV.parse(csv_str, headers: true){|l| records << l.to_h }
58
+ records
59
+ end
60
+
61
+ def query_string(params)
62
+ params.stringify_keys.map do |key, value|
22
63
  query_parameter = key.dup
23
64
  query_parameter << "=#{value.to_s}" unless value.nil?
24
65
  query_parameter
@@ -1,3 +1,3 @@
1
1
  module Egauge
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: egauge-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joey Ferguson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-30 00:00:00.000000000 Z
11
+ date: 2018-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 1.8.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 1.8.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 5.2.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 5.2.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -129,8 +129,6 @@ files:
129
129
  - egauge-rb.gemspec
130
130
  - lib/egauge.rb
131
131
  - lib/egauge/client.rb
132
- - lib/egauge/power_helpers.rb
133
- - lib/egauge/response.rb
134
132
  - lib/egauge/version.rb
135
133
  homepage: https://github.com/ArcadiaPower/egauge-rb
136
134
  licenses:
@@ -1,21 +0,0 @@
1
- module Egauge
2
- module PowerHelpers
3
- KWH_DIVIDER = 3600000
4
-
5
- def full_day_kwh(day = Time.zone.now.end_of_day.to_i)
6
- query(:C => nil, :h => nil, :n => 24, :f => day)
7
- end
8
-
9
- def monthly_kwh(number_of_months = 12)
10
- query(:C => nil, :T => months(number_of_months))
11
- end
12
-
13
- private
14
-
15
- def months(number_of_months)
16
- number_of_months.times.map do |number|
17
- number.months.ago.beginning_of_month.to_i
18
- end.unshift(Time.current.to_i).join(',')
19
- end
20
- end
21
- end
@@ -1,34 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module Egauge
4
- class Response
5
- KWH_DIVIDER = 3600000
6
-
7
- def initialize(body)
8
- @body = Nokogiri.parse(body)
9
- load_power_output
10
- end
11
-
12
- def headers
13
- @_headers ||= body.css("cname").map { |header| header.text.downcase.gsub(/\W/,"_") }
14
- end
15
-
16
- private
17
-
18
- attr_reader :body
19
-
20
- def column_content(header_index)
21
- rows.map { |row| (row.css("c").children[header_index].text.to_i / KWH_DIVIDER).abs }
22
- end
23
-
24
- def rows
25
- @_rows ||= body.css("r")
26
- end
27
-
28
- def load_power_output
29
- headers.each_with_index do |header, index|
30
- self.class.send(:define_method, header) { column_content(index) }
31
- end
32
- end
33
- end
34
- end