reolink-http 0.1.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 +7 -0
- data/lib/reolink/http/version.rb +7 -0
- data/lib/reolink/http.rb +101 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0df4961d3dddac35c27d48dc2a9d859d9e863c7bef207458642083fce41334d0
|
4
|
+
data.tar.gz: 56002d3e9acb54e5d6c305f3cf49552f01c173b894dcdd252b5ec73139974e0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a993b24bf83f29ba5f6e92cf75528276c793a2f07406a95a18b8c500dec593140f4eb76c03e73c082c75e9736a018fa16cb0612d0083fe99000ea1ab81fbf8d
|
7
|
+
data.tar.gz: 1700ad1ce09feb1a8105bc8c3678a547fad5f10a38bb5e11dde13fa7d91ba2ac227600690125368a653dae257b94d4c1170392a98ef916510334943f4953ecdf
|
data/lib/reolink/http.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
require_relative "http/version"
|
7
|
+
|
8
|
+
module Reolink
|
9
|
+
# Provides an abstraction of the Reolink device API.
|
10
|
+
# See the Reolink API documentation for commands, parameters, and response fields.
|
11
|
+
class HTTP
|
12
|
+
attr_reader :host, :token, :token_expires_at
|
13
|
+
|
14
|
+
def initialize(host, username: nil, password: nil)
|
15
|
+
@host = host
|
16
|
+
@username = username
|
17
|
+
@password = password
|
18
|
+
@token = nil
|
19
|
+
@token_expires_at = Time.new(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(method_name, params = {}, **kwargs)
|
23
|
+
# Assume any missing method is a valid Reolink command. We have no good way to validate this: the API changes and
|
24
|
+
# will be a maintenance burden, and GetAbility does not return all commands. An invalid command will still cause
|
25
|
+
# a proper error response, so this functionality is correct, if not ideal.
|
26
|
+
command(command: method_name.to_s.split("_").map(&:capitalize).join,
|
27
|
+
params:,
|
28
|
+
**kwargs)
|
29
|
+
end
|
30
|
+
|
31
|
+
def respond_to_missing?(*_args)
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def command(method: :post, **kwargs)
|
36
|
+
Net::HTTP.start(host, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
37
|
+
refresh_token(http:) if token_expires_at <= Time.now
|
38
|
+
case method
|
39
|
+
when :post then post(http:, **kwargs)
|
40
|
+
when :get then get(http:, **kwargs)
|
41
|
+
else
|
42
|
+
raise "Unknown method #{method}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def refresh_token(http:)
|
48
|
+
login_response = post(http:, command: "Login", params: { "User" => { "Version" => "0",
|
49
|
+
"userName" => @username,
|
50
|
+
"password" => @password } })
|
51
|
+
.first.value["Token"]
|
52
|
+
@token = login_response["name"]
|
53
|
+
@token_expires_at = Time.now + login_response["leaseTime"]
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def get(http:, command:, params: {})
|
59
|
+
http.get("/api.cgi?#{URI.encode_www_form({ cmd: command, token:, **params })}")
|
60
|
+
end
|
61
|
+
|
62
|
+
# `verbose` is passed as the `action` parameter. Ignored for non-Get* endpoints.
|
63
|
+
# 0 -- get current value only
|
64
|
+
# 1 -- get initial, range, and current value
|
65
|
+
def post(http:, command:, params: {}, verbose: true)
|
66
|
+
params = { command.delete_prefix("Set") => params } if command.start_with?("Set")
|
67
|
+
|
68
|
+
http.post("/api.cgi?cmd=#{command}" + ("&token=#{token}" if token).to_s,
|
69
|
+
JSON.generate([{ cmd: command, action: verbose ? 1 : 0, param: params }]))
|
70
|
+
.then { |http_response| Response.from_json(http_response.body) }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Represents a response from the device.
|
74
|
+
# cmd -- name of command
|
75
|
+
# code -- status code. 0 means no errors.
|
76
|
+
# initial -- initial value of attribute, for Get* requests when `verbose` is true
|
77
|
+
# range -- range of possible values for attribute, for Get* requests when `verbose` is true
|
78
|
+
# current -- current value of attribute, for Get* requests
|
79
|
+
# error -- error code and details. nil if no error.
|
80
|
+
class Response
|
81
|
+
# Parse a JSON string from the device and return *an array* of Response objects.
|
82
|
+
def self.from_json(str)
|
83
|
+
JSON.parse(str)
|
84
|
+
.map do |response|
|
85
|
+
new(**response.transform_keys(&:to_sym))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_reader :cmd, :code, :initial, :range, :value, :error
|
90
|
+
|
91
|
+
def initialize(cmd:, code:, initial: nil, range: nil, value: nil, error: nil)
|
92
|
+
@cmd = cmd
|
93
|
+
@code = code
|
94
|
+
@initial = initial&.[](cmd.delete_prefix("Get")) || initial
|
95
|
+
@range = range&.[](cmd.delete_prefix("Get")) || range
|
96
|
+
@value = value&.[](cmd.delete_prefix("Get")) || value
|
97
|
+
@error = error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reolink-http
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eddie Lebow
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- elebow@users.noreply.github.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/reolink/http.rb
|
21
|
+
- lib/reolink/http/version.rb
|
22
|
+
homepage: https://codeberg.org/elebow/reolink-http-ruby
|
23
|
+
licenses:
|
24
|
+
- AGPL-3.0-or-later
|
25
|
+
metadata:
|
26
|
+
homepage_uri: https://codeberg.org/elebow/reolink-http-ruby
|
27
|
+
source_code_uri: https://codeberg.org/elebow/reolink-http-ruby
|
28
|
+
changelog_uri: https://codeberg.org/elebow/reolink-http-ruby/src/CHANGELOG.md
|
29
|
+
rubygems_mfa_required: 'true'
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 3.1.0
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubygems_version: 3.4.1
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: Interface for Reolink's HTTP device API.
|
49
|
+
test_files: []
|