foscam-ruby 0.0.1
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 +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/foscam-ruby.gemspec +34 -0
- data/lib/foscam-ruby.rb +8 -0
- data/lib/foscam/client.rb +425 -0
- data/lib/foscam/version.rb +3 -0
- data/spec/fixtures/vcr/foscam_camera_control_brightness.yml +42 -0
- data/spec/fixtures/vcr/foscam_camera_control_contrast.yml +42 -0
- data/spec/fixtures/vcr/foscam_camera_control_mode.yml +42 -0
- data/spec/fixtures/vcr/foscam_camera_control_orientation.yml +42 -0
- data/spec/fixtures/vcr/foscam_camera_control_resolution.yml +42 -0
- data/spec/fixtures/vcr/foscam_comm_write.yml +42 -0
- data/spec/fixtures/vcr/foscam_decoder_control.yml +42 -0
- data/spec/fixtures/vcr/foscam_get_camera_params.yml +52 -0
- data/spec/fixtures/vcr/foscam_get_forbidden.yml +84 -0
- data/spec/fixtures/vcr/foscam_get_misc.yml +66 -0
- data/spec/fixtures/vcr/foscam_get_params.yml +428 -0
- data/spec/fixtures/vcr/foscam_get_status.yml +68 -0
- data/spec/fixtures/vcr/foscam_reboot.yml +42 -0
- data/spec/fixtures/vcr/foscam_restore_factory.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_alarm.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_alias.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_datetime.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_ddns.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_decoder.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_forbidden.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_ftp.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_mail.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_misc.yml +105 -0
- data/spec/fixtures/vcr/foscam_set_network.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_pppoe.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_upnp.yml +42 -0
- data/spec/fixtures/vcr/foscam_set_user2.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user3.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user4.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user5.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user6.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user7.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_user8.yml +40 -0
- data/spec/fixtures/vcr/foscam_set_wifi.yml +40 -0
- data/spec/fixtures/vcr/foscam_snapshot.yml +236 -0
- data/spec/fixtures/vcr/foscam_upgrade_firmware.yml +40 -0
- data/spec/fixtures/vcr/foscam_upgrade_htmls.yml +40 -0
- data/spec/foscam/client_spec.rb +1269 -0
- data/spec/spec_helper.rb +24 -0
- metadata +301 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OWNmYzk4ZTEyZGZkMDJmNzUzMTZiNTg0M2EzYzBhYmExMDIyMGRhOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2NlYzQ3N2JiYjNkNmYxMzc5OGViZGFjNjVkMDI1OGU0NzI4MWVlYQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGIyYmM5ZGVhZjAwMzk3ZTU0ZGQzOGQ5ZDJmZTBkNGVkNGIyY2RkYTM1Yjk4
|
10
|
+
ZTc5YzVjM2IyZTIzMzRhNzdlNzZjMWZlOGVkYjBiM2Y0NGE5YjE3OGEwYmYx
|
11
|
+
YTIzNjcxYWJmYjVjNTllMjMxMWE3ZDAyNzNkYzJiNjE2ZjE3NDU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NjFhMWNlZWI3YzE3OTdjNDU4OGY0NWYxMmVmOTE0YWVmZjI0NzA1YjE2Mjc0
|
14
|
+
Y2ZmMmFhNGRlNDAzZjU4OTA5ODEyMTBkNjhjZmM0NzJiYzYxN2U1NWFlMTY0
|
15
|
+
NmEyZWVmZGNjNzgxN2M4NTE5N2VjYTgwZjkwMmViMTNkN2M3YzA=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Chris Waddington
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Foscam::Ruby
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'foscam-ruby'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install foscam-ruby
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/foscam-ruby.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'foscam/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "foscam-ruby"
|
8
|
+
spec.version = Foscam::VERSION
|
9
|
+
spec.authors = ["Chris Waddington"]
|
10
|
+
spec.email = ["cwadding@gmail.com"]
|
11
|
+
spec.description = %q{A ruby client for the foscam SDK.}
|
12
|
+
spec.summary = %q{A ruby client for the foscam SDK.}
|
13
|
+
spec.homepage = "https://github.com/cwadding/foscam-ruby"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'faraday'
|
22
|
+
spec.add_dependency 'mini_magick'
|
23
|
+
spec.add_dependency 'active_support'
|
24
|
+
spec.add_dependency 'i18n'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency 'rspec'#, '~> 2.10.0'
|
29
|
+
spec.add_development_dependency 'guard'
|
30
|
+
spec.add_development_dependency 'guard-rspec'
|
31
|
+
spec.add_development_dependency 'rb-fsevent'
|
32
|
+
spec.add_development_dependency 'vcr'
|
33
|
+
spec.add_development_dependency 'webmock'
|
34
|
+
end
|
data/lib/foscam-ruby.rb
ADDED
@@ -0,0 +1,425 @@
|
|
1
|
+
module Foscam
|
2
|
+
|
3
|
+
DDNS_STATUS = {
|
4
|
+
0 => "No Action",
|
5
|
+
1 => "It's connecting...",
|
6
|
+
2 => "Can't connect to the Server",
|
7
|
+
3 => "Dyndns Succeed",
|
8
|
+
4 => "DynDns Failed: Dyndns.org Server Error",
|
9
|
+
5 => "DynDns Failed: Incorrect User or Password",
|
10
|
+
6 => "DynDns Failed: Need Credited User",
|
11
|
+
7 => "DynDns Failed: Illegal Host Format",
|
12
|
+
8 => "DynDns Failed: The Host Does not Exist",
|
13
|
+
9 => "DynDns Failed: The Host Does not Belong to You",
|
14
|
+
10 => "DynDns Failed: Too Many or Too Few Hosts",
|
15
|
+
11 => "DynDns Failed: The Host is Blocked for Abusing",
|
16
|
+
12 => "DynDns Failed: Bad Reply from Server",
|
17
|
+
13 => "DynDns Failed: Bad Reply from Server",
|
18
|
+
14 => "Oray Failed: Bad Reply from Server",
|
19
|
+
15 => "Oray Failed: Incorrect User or Password",
|
20
|
+
16 => "Oray Failed: Incorrect Hostname",
|
21
|
+
17 => "Oray Succeed"
|
22
|
+
}
|
23
|
+
|
24
|
+
UPNP_STATUS = {
|
25
|
+
0 => "No Action",
|
26
|
+
1 => "Succeed",
|
27
|
+
2 => "Device System Error",
|
28
|
+
3 => "Errors in Network Communication",
|
29
|
+
4 => "Errors in Chat with UPnP Device",
|
30
|
+
5 => "Rejected by UPnP Device, Maybe Port Conflict"
|
31
|
+
}
|
32
|
+
|
33
|
+
ALARM_STATUS = {
|
34
|
+
0 => "No alarm",
|
35
|
+
1 => "Motion alarm",
|
36
|
+
2 => "Input Alarm"
|
37
|
+
}
|
38
|
+
|
39
|
+
CAMERA_PARAMS_MODE = {
|
40
|
+
0 => "50hz",
|
41
|
+
1 => "60hz",
|
42
|
+
2 => "outdoor"
|
43
|
+
}
|
44
|
+
CAMERA_CONTROL_MODE = CAMERA_PARAMS_MODE.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
45
|
+
|
46
|
+
CAMERA_PARAMS_ORIENTATION = {
|
47
|
+
0 => "default",
|
48
|
+
1 => "flip",
|
49
|
+
2 => "mirror",
|
50
|
+
3 => "flip+mirror"
|
51
|
+
}
|
52
|
+
|
53
|
+
CAMERA_CONTROL_ORIENTATION = CAMERA_PARAMS_ORIENTATION.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
54
|
+
|
55
|
+
CAMERA_PARAMS_RESOLUTION = {
|
56
|
+
8 => "qvga",
|
57
|
+
32 => "vga"
|
58
|
+
}
|
59
|
+
|
60
|
+
CAMERA_CONTROL_RESOLUTION = CAMERA_PARAMS_RESOLUTION.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
61
|
+
|
62
|
+
CAMERA_CONTROLS = {
|
63
|
+
resolution: 0,
|
64
|
+
brightness: 1,
|
65
|
+
contrast: 2,
|
66
|
+
mode: 3,
|
67
|
+
flip: 5
|
68
|
+
}
|
69
|
+
|
70
|
+
DECODER_CONTROLS = {
|
71
|
+
up: 0,
|
72
|
+
stop_up: 1,
|
73
|
+
down: 2,
|
74
|
+
stop_down: 3,
|
75
|
+
left: 4,
|
76
|
+
stop_left: 5,
|
77
|
+
right: 6,
|
78
|
+
stop_right: 7,
|
79
|
+
center: 25,
|
80
|
+
vertical_patrol: 26,
|
81
|
+
stop_vertical_patrol: 27,
|
82
|
+
horizon_patrol: 28,
|
83
|
+
stop_horizon_patrol: 29,
|
84
|
+
io_output_high: 94,
|
85
|
+
io_output_low: 95,
|
86
|
+
}
|
87
|
+
|
88
|
+
USER_PERMISSIONS = {
|
89
|
+
0 => :visitor,
|
90
|
+
1 => :operator,
|
91
|
+
2 => :administrator
|
92
|
+
}
|
93
|
+
|
94
|
+
PTZ_AUTO_PATROL_TYPE = {
|
95
|
+
0 => :none,
|
96
|
+
1 => :horizontal,
|
97
|
+
2 => :vertical,
|
98
|
+
3 => :"horizontal+vertical"
|
99
|
+
}
|
100
|
+
PTZ_AUTO_PATROL_TYPE_ID = PTZ_AUTO_PATROL_TYPE.invert
|
101
|
+
|
102
|
+
LED_MODE = {
|
103
|
+
0 => :mode1,
|
104
|
+
1 => :mode2,
|
105
|
+
2 => :disabled
|
106
|
+
}
|
107
|
+
LED_MODE_ID = LED_MODE.invert
|
108
|
+
DECODER_BAUD = {
|
109
|
+
9 => :B1200,
|
110
|
+
11 => :B2400,
|
111
|
+
12 => :B4800,
|
112
|
+
13 => :B9600,
|
113
|
+
14 => :B19200,
|
114
|
+
15 => :B38400,
|
115
|
+
4097 => :B57600,
|
116
|
+
4098 => :B115200
|
117
|
+
}
|
118
|
+
|
119
|
+
DECODER_BAUD_ID = DECODER_BAUD.invert
|
120
|
+
|
121
|
+
|
122
|
+
class Client
|
123
|
+
|
124
|
+
attr_accessor :url, :username, :password, :connection
|
125
|
+
|
126
|
+
def initialize(args = {})
|
127
|
+
@url = args.delete(:url)
|
128
|
+
@username = args.delete(:username)
|
129
|
+
@password = args.delete(:password)
|
130
|
+
connect(@url, @username, @password)
|
131
|
+
end
|
132
|
+
|
133
|
+
def connect(url, username = nil, password = nil)
|
134
|
+
@url = url
|
135
|
+
@username = username
|
136
|
+
@password = password
|
137
|
+
@connection = Faraday.new( url: @url) unless @url.nil?
|
138
|
+
@connection.basic_auth(@username, @password) unless @username.nil? && @password.nil?
|
139
|
+
end
|
140
|
+
|
141
|
+
def snapshot
|
142
|
+
response = @connection.get('snapshot.cgi')
|
143
|
+
response.success? ? ::MiniMagick::Image.read(response.body) : nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_status
|
147
|
+
response = @connection.get('get_status.cgi')
|
148
|
+
response = response.success? ? parse_response(response) : {}
|
149
|
+
unless response.empty?
|
150
|
+
response[:ddns_status] = DDNS_STATUS[response[:ddns_status].to_i]
|
151
|
+
response[:upnp_status] = UPNP_STATUS[response[:upnp_status].to_i]
|
152
|
+
response[:alarm_status] = ALARM_STATUS[response[:alarm_status].to_i]
|
153
|
+
response[:now] = DateTime.strptime(response[:now],'%s')
|
154
|
+
end
|
155
|
+
response
|
156
|
+
end
|
157
|
+
|
158
|
+
def get_camera_params
|
159
|
+
response = @connection.get('get_camera_params.cgi')
|
160
|
+
response = response.success? ? parse_response(response) : {}
|
161
|
+
unless response.empty?
|
162
|
+
response[:flip] = CAMERA_PARAMS_ORIENTATION[response[:flip].to_i]
|
163
|
+
response[:mode] = CAMERA_PARAMS_MODE[response[:mode].to_i]
|
164
|
+
response[:resolution] = CAMERA_PARAMS_RESOLUTION[response[:resolution].to_i]
|
165
|
+
[:brightness, :contrast].each {|field| response[field] = response[field].to_i}
|
166
|
+
end
|
167
|
+
response
|
168
|
+
end
|
169
|
+
|
170
|
+
def decoder_control(action)
|
171
|
+
case action
|
172
|
+
when Symbol || String
|
173
|
+
action_id = DECODER_CONTROLS[action.to_sym]
|
174
|
+
else
|
175
|
+
action_id = action
|
176
|
+
end
|
177
|
+
response = @connection.get("decoder_control.cgi?command=#{action_id}")
|
178
|
+
response.success?
|
179
|
+
end
|
180
|
+
|
181
|
+
def camera_control(params)
|
182
|
+
params.all? do |key, value|
|
183
|
+
# validation
|
184
|
+
case key
|
185
|
+
when :resolution
|
186
|
+
case value
|
187
|
+
when Integer
|
188
|
+
throw "invalid parameter value" unless [8,32].include?(value)
|
189
|
+
when String || Symbol
|
190
|
+
throw "invalid parameter value" unless ["vga","qvga"].include?(value.to_s.downcase)
|
191
|
+
if value.to_s.downcase == "vga"
|
192
|
+
value = 32
|
193
|
+
elsif value.to_s.downcase == "qvga"
|
194
|
+
value = 8
|
195
|
+
end
|
196
|
+
else
|
197
|
+
throw "invalid parameter value type"
|
198
|
+
end
|
199
|
+
when :brightness
|
200
|
+
throw "invalid parameter value" if value.to_i < 0 || value.to_i > 255
|
201
|
+
when :contrast
|
202
|
+
throw "invalid parameter value" if value.to_i < 0 || value.to_i > 6
|
203
|
+
when :mode
|
204
|
+
case value
|
205
|
+
when Integer
|
206
|
+
throw "invalid parameter value" if value.to_i < 0 || value.to_i > 2
|
207
|
+
when Symbol || String
|
208
|
+
throw "invalid parameter value" unless CAMERA_CONTROL_MODE.keys.include?(value.to_s.downcase.to_sym)
|
209
|
+
value = CAMERA_CONTROL_MODE[value.to_s.downcase.to_sym]
|
210
|
+
else
|
211
|
+
throw "invalid parameter value type"
|
212
|
+
end
|
213
|
+
when :flip
|
214
|
+
case value
|
215
|
+
when Integer
|
216
|
+
throw "invalid parameter value" if value.to_i < 0 || value.to_i > 3
|
217
|
+
when String || Symbol
|
218
|
+
throw "invalid parameter value" unless CAMERA_CONTROL_ORIENTATION.keys.include?(value.to_s.downcase.to_sym)
|
219
|
+
value = CAMERA_CONTROL_ORIENTATION[value.to_s.downcase.to_sym]
|
220
|
+
else
|
221
|
+
throw "invalid parameter value type"
|
222
|
+
end
|
223
|
+
else
|
224
|
+
throw "invalid parameter"
|
225
|
+
end
|
226
|
+
|
227
|
+
response = @connection.get("camera_control.cgi?param=#{CAMERA_CONTROLS[key.to_sym]}&value=#{value}")
|
228
|
+
response.success?
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def reboot
|
233
|
+
response = @connection.get("reboot.cgi")
|
234
|
+
response.success?
|
235
|
+
end
|
236
|
+
|
237
|
+
def restore_factory
|
238
|
+
response = @connection.get("restore_factory.cgi")
|
239
|
+
response.success?
|
240
|
+
end
|
241
|
+
|
242
|
+
def get_params
|
243
|
+
response = @connection.get("get_params.cgi")
|
244
|
+
response = response.success? ? parse_response(response) : {}
|
245
|
+
unless response.empty?
|
246
|
+
response[:now] = DateTime.strptime(response[:now],'%s')
|
247
|
+
[:ntp_enable, :wifi_enable, :pppoe_enable, :upnp_enable, :alarm_schedule_enable, :ftp_schedule_enable].each do |field|
|
248
|
+
response[field] = response[field].to_i > 0
|
249
|
+
end
|
250
|
+
[:ftp_schedule_sun_0, :ftp_schedule_sun_1, :ftp_schedule_sun_2,
|
251
|
+
:ftp_schedule_mon_0, :ftp_schedule_mon_1, :ftp_schedule_mon_2,
|
252
|
+
:ftp_schedule_tue_0, :ftp_schedule_tue_1, :ftp_schedule_tue_2,
|
253
|
+
:ftp_schedule_wed_0, :ftp_schedule_wed_1, :ftp_schedule_wed_2,
|
254
|
+
:ftp_schedule_thu_0, :ftp_schedule_thu_1, :ftp_schedule_thu_2,
|
255
|
+
:ftp_schedule_fri_0, :ftp_schedule_fri_1, :ftp_schedule_fri_2,
|
256
|
+
:ftp_schedule_sat_0, :ftp_schedule_sat_1, :ftp_schedule_sat_2,
|
257
|
+
:alarm_schedule_sun_0, :alarm_schedule_sun_1, :alarm_schedule_sun_2,
|
258
|
+
:alarm_schedule_mon_0, :alarm_schedule_mon_1, :alarm_schedule_mon_2,
|
259
|
+
:alarm_schedule_tue_0, :alarm_schedule_tue_1, :alarm_schedule_tue_2,
|
260
|
+
:alarm_schedule_wed_0, :alarm_schedule_wed_1, :alarm_schedule_wed_2,
|
261
|
+
:alarm_schedule_thu_0, :alarm_schedule_thu_1, :alarm_schedule_thu_2,
|
262
|
+
:alarm_schedule_fri_0, :alarm_schedule_fri_1, :alarm_schedule_fri_2,
|
263
|
+
:alarm_schedule_sat_0, :alarm_schedule_sat_1, :alarm_schedule_sat_2,
|
264
|
+
:daylight_savings_time, :ddns_proxy_port, :ftp_port, :mail_port, :port, :dev2_port, :dev3_port, :dev4_port, :dev5_port, :dev6_port, :dev7_port, :dev8_port, :dev9_port].each do |field|
|
265
|
+
response[field] = response[field].to_i
|
266
|
+
end
|
267
|
+
[:user1_pri, :user2_pri, :user3_pri, :user4_pri, :user5_pri, :user6_pri, :user7_pri, :user8_pri].each do |key|
|
268
|
+
response[key] = USER_PERMISSIONS[response[key].to_i]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
response
|
272
|
+
end
|
273
|
+
|
274
|
+
def upgrade_firmware
|
275
|
+
response = @connection.post("upgrade_firmware.cgi")
|
276
|
+
end
|
277
|
+
|
278
|
+
def upgrade_htmls
|
279
|
+
response = @connection.post("upgrade_htmls.cgi")
|
280
|
+
end
|
281
|
+
|
282
|
+
def set_alias(name)
|
283
|
+
throw "invalid parameter value" if name.length > 20
|
284
|
+
response = @connection.get("set_alias.cgi?alias=#{name}")
|
285
|
+
response.success?
|
286
|
+
end
|
287
|
+
|
288
|
+
def set_datetime(params)
|
289
|
+
# Extract the time zone
|
290
|
+
throw "invalid parameter value" if params.has_key?(:ntp_svr) && params[:ntp_svr].length > 64
|
291
|
+
response = @connection.get("set_datetime.cgi?#{params.to_query}")
|
292
|
+
response.success?
|
293
|
+
end
|
294
|
+
|
295
|
+
def set_users(params)
|
296
|
+
[:user1, :pwd1, :user2, :pwd2, :user3, :pwd3, :user4, :pwd4, :user5, :pwd5, :user6, :pwd6, :user7, :pwd7, :user8, :pwd8].each do |key|
|
297
|
+
throw "invalid parameter value" if params.has_key?(key) && params[key].length > 12
|
298
|
+
end
|
299
|
+
response = @connection.get("set_users.cgi?#{params.to_query}")
|
300
|
+
response.success?
|
301
|
+
end
|
302
|
+
|
303
|
+
# def set_devices(params)
|
304
|
+
# response = @connection.get("set_devices.cgi?#{params.to_query}")
|
305
|
+
# end
|
306
|
+
|
307
|
+
def set_network(params)
|
308
|
+
response = @connection.get("set_network.cgi?#{params.to_query}")
|
309
|
+
response.success?
|
310
|
+
end
|
311
|
+
|
312
|
+
def set_wifi(params)
|
313
|
+
response = @connection.get("set_wifi.cgi?#{params.to_query}")
|
314
|
+
response.success?
|
315
|
+
end
|
316
|
+
|
317
|
+
def set_pppoe(params)
|
318
|
+
throw "invalid parameter value" if params.has_key?(:user) && params[:user].length > 20
|
319
|
+
throw "invalid parameter value" if params.has_key?(:pwd) && params[:pwd].length > 20
|
320
|
+
response = @connection.get("set_pppoe.cgi?#{params.to_query}")
|
321
|
+
response.success?
|
322
|
+
end
|
323
|
+
|
324
|
+
def set_upnp(flag)
|
325
|
+
response = @connection.get("set_upnp.cgi?enable=#{handle_boolean(flag)}")
|
326
|
+
response.success?
|
327
|
+
end
|
328
|
+
|
329
|
+
def set_ddns(params)
|
330
|
+
throw "invalid parameter value" if params.has_key?(:user) && params[:user].length > 20
|
331
|
+
throw "invalid parameter value" if params.has_key?(:pwd) && params[:pwd].length > 20
|
332
|
+
throw "invalid parameter value" if params.has_key?(:host) && params[:host].length > 40
|
333
|
+
response = @connection.get("set_ddns.cgi?#{params.to_query}")
|
334
|
+
response.success?
|
335
|
+
end
|
336
|
+
|
337
|
+
def set_ftp(params)
|
338
|
+
response = @connection.get("set_ftp.cgi?#{params.to_query}")
|
339
|
+
response.success?
|
340
|
+
end
|
341
|
+
|
342
|
+
def set_mail(params)
|
343
|
+
throw "invalid parameter value" if params.has_key?(:user) && params[:user].length > 20
|
344
|
+
throw "invalid parameter value" if params.has_key?(:pwd) && params[:pwd].length > 20
|
345
|
+
[:sender, :receiver1, :receiver2, :receiver3, :receiver4].each do |key|
|
346
|
+
throw "invalid parameter value" if params.has_key?(key) && params[key].length > 40
|
347
|
+
end
|
348
|
+
response = @connection.get("set_mail.cgi?#{params.to_query}")
|
349
|
+
response.success?
|
350
|
+
end
|
351
|
+
|
352
|
+
def set_alarm(params)
|
353
|
+
response = @connection.get("set_alarm.cgi?#{params.to_query}")
|
354
|
+
response.success?
|
355
|
+
end
|
356
|
+
|
357
|
+
def comm_write(params)
|
358
|
+
response = @connection.get("comm_write.cgi?#{params.to_query}")
|
359
|
+
response.success?
|
360
|
+
end
|
361
|
+
|
362
|
+
def set_forbidden(params)
|
363
|
+
response = @connection.get("set_forbidden.cgi?#{params.to_query}")
|
364
|
+
response.success?
|
365
|
+
end
|
366
|
+
|
367
|
+
def get_forbidden
|
368
|
+
response = @connection.get("get_forbidden.cgi")
|
369
|
+
response.success? ? parse_response(response) : {}
|
370
|
+
end
|
371
|
+
|
372
|
+
def set_misc(params)
|
373
|
+
url_params = params.clone
|
374
|
+
[:ptz_patrol_rate, :ptz_patrol_up_rate, :ptz_patrol_down_rate, :ptz_patrol_left_rate, :ptz_patrol_right_rate].each do |key|
|
375
|
+
throw "invalid parameter value" if (url_params.has_key?(key) && (url_params[key].to_i < 0 || url_params[key].to_i > 100))
|
376
|
+
end
|
377
|
+
[:ptz_auto_patrol_interval, :ptz_patrol_h_rounds, :ptz_patrol_v_rounds].each do |key|
|
378
|
+
throw "invalid parameter value" if url_params.has_key?(key) && url_params[key].to_i < 0
|
379
|
+
end
|
380
|
+
[:ptz_disable_preset, :ptz_preset_onstart, :ptz_center_onstart].each do |key|
|
381
|
+
url_params[key] = handle_boolean(url_params[key]) if url_params.has_key?(key)
|
382
|
+
end
|
383
|
+
url_params[:led_mode] = LED_MODE_ID[url_params[:led_mode]] if url_params[:led_mode].is_a?(String) || url_params[:led_mode].is_a?(Symbol)
|
384
|
+
url_params[:ptz_auto_patrol_type] = PTZ_AUTO_PATROL_TYPE_ID[url_params[:ptz_auto_patrol_type]] if url_params[:ptz_auto_patrol_type].is_a?(String) || url_params[:ptz_auto_patrol_type].is_a?(Symbol)
|
385
|
+
response = @connection.get("set_misc.cgi?#{url_params.to_query}")
|
386
|
+
response.success?
|
387
|
+
end
|
388
|
+
|
389
|
+
def get_misc
|
390
|
+
response = @connection.get("get_misc.cgi")
|
391
|
+
response = response.success? ? parse_response(response) : {}
|
392
|
+
unless response.empty?
|
393
|
+
[:ptz_disable_preset, :ptz_preset_onstart, :ptz_center_onstart].each do |field|
|
394
|
+
response[field] = response[field].to_i > 0
|
395
|
+
end
|
396
|
+
[:ptz_auto_patrol_interval, :ptz_patrol_h_rounds, :ptz_patrol_v_rounds, :ptz_patrol_rate, :ptz_patrol_up_rate, :ptz_patrol_down_rate, :ptz_patrol_left_rate, :ptz_patrol_right_rate].each do |field|
|
397
|
+
response[field] = response[field].to_i
|
398
|
+
end
|
399
|
+
response[:led_mode] = LED_MODE[response[:led_mode].to_i]
|
400
|
+
response[:ptz_auto_patrol_type] = PTZ_AUTO_PATROL_TYPE[response[:ptz_auto_patrol_type].to_i]
|
401
|
+
response
|
402
|
+
end
|
403
|
+
response
|
404
|
+
end
|
405
|
+
|
406
|
+
def set_decoder(baud)
|
407
|
+
baud = DECODER_BAUD_ID[baud.to_sym] if baud.is_a?(String) || baud.is_a?(Symbol)
|
408
|
+
response = @connection.get("set_decoder.cgi?baud=#{baud}")
|
409
|
+
response.success?
|
410
|
+
end
|
411
|
+
|
412
|
+
private
|
413
|
+
|
414
|
+
def parse_response(response)
|
415
|
+
response.body.scan(/var (\w+)=([^;]+);[\s+]?/).inject({}) do | params, pair |
|
416
|
+
params.merge(pair.first.to_sym => pair.last.gsub(/'/, ''))
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
def handle_boolean(flag)
|
421
|
+
flag ? 1 : 0
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|
425
|
+
end
|