wattsense-api-client 0.1.3 → 0.3.2

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: 7e5cc59939bd0952db2322c7edb70d025890d9a4f609d1721ce7ced2c60ad259
4
- data.tar.gz: c38e19e274bf617810a7d5f917dc88e46eeaeedef1a09c7217b9307fc73f62ff
3
+ metadata.gz: fdbe56bc224c52dabf5ec031b0c2cacf722500deb3dc11e7eccf886475b0a2a8
4
+ data.tar.gz: 77dfcb5d92512aec9f5db55410e1d3dca5c756e7a35fc34a4875eca828f945f2
5
5
  SHA512:
6
- metadata.gz: 96fec947210d528404ade2a792dcf591e2ef37b98139329f878a15183ecde4849dc406267925d4e97f03c87e4e9584a769a698693fd75491b38902d42eeca82e
7
- data.tar.gz: eb062bf4ab929d98f0a9d39c6b0c4e7fed3011e68270422b463dbce6f747cb2ce23d6ef1e7f0f6943519153cfa195d5312a9fba8632fe52f67b83d8806f9de7d
6
+ metadata.gz: e7cc5f941d05d3630ec4ff0562eb1d5a1f2cf4bb69f76d22b60c9dcf4df2eb3f623966ae92440810e024fcea6fde8536ac8d76e871f7a44e84f6e0ab0e1260f6
7
+ data.tar.gz: 910ec81176e4600489a3f4704aa7cc480161b7191dcb6d3631cc4662d487f6357f1a11b6321e8d90ba2f27a4e41c58f0f15c2f1ae0713e7f42c5cec874dcea10
@@ -21,8 +21,27 @@ class HttpRequester
21
21
  # HTTP GET method
22
22
  #
23
23
  # TODO: document
24
- def get(path, &before_req_callback)
25
- do_request(::Net::HTTP::Get.new(uri_from_path(path)), before_req_callback)
24
+ def get(path, query_parameters = nil, &before_req_callback)
25
+ uri = uri_from_path_and_query_parameters(path, query_parameters)
26
+ do_request(::Net::HTTP::Get.new(uri), before_req_callback)
27
+ end
28
+
29
+ # HTTP POST method
30
+ #
31
+ # TODO: document
32
+ def post(path, payload, &before_req_callback)
33
+ req = ::Net::HTTP::Post.new(uri_from_path_and_query_parameters(path))
34
+ req.body = payload
35
+ do_request(req, before_req_callback)
36
+ end
37
+
38
+ # HTTP POST method
39
+ #
40
+ # TODO: document
41
+ def put(path, payload, &before_req_callback)
42
+ req = ::Net::HTTP::Put.new(uri_from_path_and_query_parameters(path))
43
+ req.body = payload
44
+ do_request(req, before_req_callback)
26
45
  end
27
46
 
28
47
  private
@@ -37,7 +56,9 @@ class HttpRequester
37
56
  end
38
57
  end
39
58
 
40
- def uri_from_path(path)
41
- URI("#{@base_url}/#{path}")
59
+ def uri_from_path_and_query_parameters(path, query_parameters = nil)
60
+ uri = URI("#{@base_url}/#{path}")
61
+ uri.query = ::URI.encode_www_form(query_parameters) if query_parameters
62
+ uri
42
63
  end
43
64
  end
@@ -5,6 +5,9 @@
5
5
  #++
6
6
  # frozen_string_literal: true
7
7
 
8
+ require 'openssl'
9
+ require 'base64'
10
+
8
11
  module WattSenseApi
9
12
  module V1
10
13
  # This module gather all the necessary elements for ClientV1 ability to authenticate to the
@@ -19,8 +22,15 @@ module WattSenseApi
19
22
  #
20
23
  # @param api_key [String] The api's credential key
21
24
  # @param api_secret [String] The api's credential secret
22
- def api_key_authentication(_api_key, _api_secret)
23
- raise(::WattSenseApi::NotImplementedError, 'Please use (username, password) couple for now.')
25
+ def api_key_authentication(api_key, api_secret)
26
+ @auth_block =
27
+ lambda do |request|
28
+ time = now_in_ms
29
+ to_sign = to_sign_from_request(request, time)
30
+ signed = ::OpenSSL::HMAC.digest('SHA512', api_secret, to_sign.join("\n"))
31
+ request['X-API-Auth'] = "#{api_key}:#{::Base64.strict_encode64(signed)}"
32
+ request['X-API-Timestamp'] = time.to_s
33
+ end
24
34
  end
25
35
 
26
36
  # This method allows to use username/password credentials with HTTP Basic user authentication
@@ -31,6 +41,21 @@ module WattSenseApi
31
41
  def basic_user_authentication(username, password)
32
42
  @auth_block = ->(request) { request.basic_auth(username, password) }
33
43
  end
44
+
45
+ # @return [Integer] Time now in ms since Epoch
46
+ def now_in_ms
47
+ now = ::Time.now
48
+ now.tv_sec * 1000 + now.tv_usec / 1_000
49
+ end
50
+
51
+ # @return [String] Message to sign
52
+ def to_sign_from_request(request, time)
53
+ to_sign = [request.method, request.uri.path]
54
+ to_sign.push(request.uri.query) if request.uri.query
55
+ to_sign.push(request.body) if request.body
56
+ to_sign << time.to_s
57
+ to_sign
58
+ end
34
59
  end
35
60
  end
36
61
  end
@@ -11,6 +11,8 @@ require 'http_requester'
11
11
  require 'watt_sense_api/v1/authentication'
12
12
  require 'watt_sense_api/v1/organization'
13
13
  require 'watt_sense_api/v1/user_management'
14
+ require 'watt_sense_api/v1/device_information'
15
+ require 'watt_sense_api/v1/properties_measurements'
14
16
 
15
17
  module WattSenseApi
16
18
  module V1
@@ -20,6 +22,8 @@ module WattSenseApi
20
22
  include ::WattSenseApi::V1::Authentication
21
23
  include ::WattSenseApi::V1::Organization
22
24
  include ::WattSenseApi::V1::UserManagement
25
+ include ::WattSenseApi::V1::DeviceInformation
26
+ include ::WattSenseApi::V1::PropertiesMeasurements
23
27
 
24
28
  # You can create a client V1 with both user's credentials or api creddentials.
25
29
  #
@@ -44,7 +48,16 @@ module WattSenseApi
44
48
  'Please give one of either couples: (api_key, api_secret) or (username, password)'
45
49
  )
46
50
  end
47
- super(::WattSenseApi::V1::BASE_URL, auth_callback: @auth_block)
51
+ super(::WattSenseApi::V1::BASE_URL, auth_callback: @auth_block, headers_callback: headers_callback)
52
+ end
53
+
54
+ private
55
+
56
+ def headers_callback
57
+ lambda do |req|
58
+ req['Accept'] = 'application/json'
59
+ req['Content-Type'] = 'application/json'
60
+ end
48
61
  end
49
62
  end
50
63
  end
@@ -0,0 +1,61 @@
1
+ #--
2
+ # Copyright (C) 2021 - Octopus Lab SAS
3
+ # All rights are described by the GPLv3 license present in the file /LICENSE available in the
4
+ # original repository of this file or [here](https://www.gnu.org/licenses/gpl-3.0.fr.html).
5
+ #++
6
+ # frozen_string_literal: true
7
+
8
+ require 'net/http'
9
+ require 'json'
10
+
11
+ module WattSenseApi
12
+ module V1
13
+ # This module gather all the methods to deal with [Device Information](https://api.wattsense.com/#tag/Device-Information).
14
+ #
15
+ # In WattSense Api, the Wattsense Box is designated as device in all this API.
16
+ module DeviceInformation
17
+ # List all your devices
18
+ #
19
+ # @note: filters not implemented yet.
20
+ #
21
+ # @return [Array<Hash>] The devices information as a Hash in an Array.
22
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPSuccess with a body)
23
+ def devices
24
+ response = get('devices')
25
+ raise(::WattSenseApi::HTTPError, response) unless response.is_a?(::Net::HTTPSuccess)
26
+
27
+ return [] if response.is_a?(::Net::HTTPNoContent)
28
+
29
+ ::JSON.parse(response.body)
30
+ end
31
+
32
+ # Get the information of the specified one
33
+ #
34
+ # @param deviceId [String] The ID of the device which you seek the informations
35
+ #
36
+ # @return [Hash] The device information as a Hash when id is not nil.
37
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPSuccess with a body)
38
+ def device(id)
39
+ response = get("devices/#{id}")
40
+ raise(::WattSenseApi::HTTPError, response) unless response.is_a?(::Net::HTTPSuccess) && !response.body&.empty?
41
+
42
+ ::JSON.parse(response.body)
43
+ end
44
+
45
+ # Activate a device
46
+ #
47
+ # @note No check implemented nor tests.
48
+ #
49
+ # @param params [Hash] Parameters as expected by WattSense documentation.
50
+ #
51
+ # @return [Hash] The device information as a Hash
52
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPSuccess with a body)
53
+ def device_activate(params)
54
+ response = post('devices', params)
55
+ raise(::WattSenseApi::HTTPError, response) unless response.is_a?(::Net::HTTPSuccess) && !response.body&.empty?
56
+
57
+ ::JSON.parse(response.body)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,69 @@
1
+ #--
2
+ # Copyright (C) 2021 - Octopus Lab SAS
3
+ # All rights are described by the GPLv3 license present in the file /LICENSE available in the
4
+ # original repository of this file or [here](https://www.gnu.org/licenses/gpl-3.0.fr.html).
5
+ #++
6
+ # frozen_string_literal: true
7
+
8
+ require 'net/http'
9
+ require 'json'
10
+
11
+ module WattSenseApi
12
+ module V1
13
+ # This module gather all the methods to deal with [Properties Measurements](https://api.wattsense.com/#tag/Properties-Measurements)
14
+ module PropertiesMeasurements
15
+ # Get the specified device's properties list with values.
16
+ #
17
+ # @see https://api.wattsense.com/#operation/listDevicePropertiesValues API documentation
18
+ #
19
+ # @param device_id [String] The device id
20
+ #
21
+ # @return [Array<Hash>|NilClass] Array of the properties' values or nil if your device is not configured
22
+ # and/or has no properties.
23
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPSuccess with a body)
24
+ def device_properties(device_id)
25
+ response = get("devices/#{device_id}/properties")
26
+ return ::JSON.parse(response.body) if response.is_a?(::Net::HTTPOK)
27
+
28
+ return if response.is_a?(::Net::HTTPNoContent)
29
+
30
+ raise(::WattSenseApi::HTTPError, response)
31
+ end
32
+
33
+ # Get a specified device's property to a given value.
34
+ #
35
+ # @see https://api.wattsense.com/#operation/getPropertyMeasurement API documentation
36
+ #
37
+ # @param device_id [String] The device id
38
+ # @param property_id [String] The property id or slug for which we ask the latest value
39
+ #
40
+ # @return [Hash|NilClass] Hash of the property's latest value (nil if property is unreachable)
41
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPAccepted with a body)
42
+ def device_property(device_id, property_id)
43
+ response = get("devices/#{device_id}/properties/#{property_id}")
44
+ return ::JSON.parse(response.body) if response.is_a?(::Net::HTTPOK)
45
+
46
+ return if response.is_a?(::Net::HTTPNoContent)
47
+
48
+ raise(::WattSenseApi::HTTPError, response)
49
+ end
50
+
51
+ # Set a specified device's property to a given value.
52
+ #
53
+ # @see https://api.wattsense.com/#operation/setPropertyValue API documentation
54
+ #
55
+ # @param device_id [String] The device id
56
+ # @param property_id [String] The property id or slug for which we ask to set the value
57
+ # @param body [Hash] The body of the request. Hash that will be transformed to json.
58
+ #
59
+ # @return [Hash] Hash of the resulted action.
60
+ # @raise [::WattSenseApi::HTTPError] when server response is not as expected (HTTPAccepted with a body)
61
+ def device_property_set(device_id, property_id, body)
62
+ response = put("devices/#{device_id}/properties/#{property_id}", body.to_json)
63
+ return ::JSON.parse(response.body) if response.is_a?(::Net::HTTPAccepted)
64
+
65
+ raise(::WattSenseApi::HTTPError, response)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -6,6 +6,6 @@
6
6
  # frozen_string_literal: true
7
7
 
8
8
  module WattSenseApi
9
- VERSION = '0.1.3'
9
+ VERSION = '0.3.2'
10
10
  public_constant :VERSION
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wattsense-api-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roland Laurès
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-17 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -17,7 +17,7 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.14'
20
- type: :runtime
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
@@ -31,7 +31,7 @@ dependencies:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.10'
34
- type: :runtime
34
+ type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
@@ -45,7 +45,7 @@ dependencies:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.20.0
48
- type: :runtime
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
@@ -59,7 +59,7 @@ dependencies:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '2.4'
62
- type: :runtime
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
@@ -73,7 +73,7 @@ dependencies:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.21.2
76
- type: :runtime
76
+ type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -87,7 +87,7 @@ dependencies:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.9'
90
- type: :runtime
90
+ type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
@@ -107,7 +107,9 @@ files:
107
107
  - lib/watt_sense_api/v1.rb
108
108
  - lib/watt_sense_api/v1/authentication.rb
109
109
  - lib/watt_sense_api/v1/client.rb
110
+ - lib/watt_sense_api/v1/device_information.rb
110
111
  - lib/watt_sense_api/v1/organization.rb
112
+ - lib/watt_sense_api/v1/properties_measurements.rb
111
113
  - lib/watt_sense_api/v1/user_management.rb
112
114
  - lib/watt_sense_api/version.rb
113
115
  - lib/wattsense-api-client.rb
@@ -115,10 +117,10 @@ homepage: https://rubygems.org/gems/wattsense-api-client
115
117
  licenses:
116
118
  - GPL v3
117
119
  metadata:
118
- bug_tracker_uri: https://gitlab.com/octopuslab-public/wattsense-api-client/-/issues
119
- changelog_uri: https://gitlab.com/octopuslab-public/wattsense-api-client/-/blob/main/CHANGELOG.md
120
- documentation_uri: https://octopuslab-public.gitlab.io/wattsense-api-client/0.1.3
121
- homepage_uri: https://gitlab.com/octopuslab-public/wattsense-api-client
120
+ bug_tracker_uri: https://gitlab.com/fr-octopuslab/wattsense-api-client/-/issues
121
+ changelog_uri: https://gitlab.com/octopuslab/wattsense-api-client/-/blob/main/CHANGELOG.md
122
+ documentation_uri: https://fr-octopuslab.gitlab.io/wattsense-api-client/0.3.2
123
+ homepage_uri: https://gitlab.com/octopuslab/wattsense-api-client
122
124
  post_install_message:
123
125
  rdoc_options: []
124
126
  require_paths: