ruby_onvif_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/lib/ruby_onvif_client/action.rb +31 -0
- data/lib/ruby_onvif_client/client.rb +44 -0
- data/lib/ruby_onvif_client/device_discovery.rb +36 -0
- data/lib/ruby_onvif_client/device_management/get_capabilities.rb +118 -0
- data/lib/ruby_onvif_client/device_management/get_device_information.rb +30 -0
- data/lib/ruby_onvif_client/device_management/get_network_interfaces.rb +131 -0
- data/lib/ruby_onvif_client/device_management/get_network_protocols.rb +32 -0
- data/lib/ruby_onvif_client/device_management/get_system_date_and_time.rb +60 -0
- data/lib/ruby_onvif_client/device_management/get_users.rb +32 -0
- data/lib/ruby_onvif_client/device_management/set_network_interfaces.rb +83 -0
- data/lib/ruby_onvif_client/device_management/set_system_date_and_time.rb +48 -0
- data/lib/ruby_onvif_client/device_management/set_system_factory_default.rb +21 -0
- data/lib/ruby_onvif_client/device_management/system_reboot.rb +25 -0
- data/lib/ruby_onvif_client/device_management.rb +10 -0
- data/lib/ruby_onvif_client/media/get_audio_encoder_configuration.rb +48 -0
- data/lib/ruby_onvif_client/media/get_audio_encoder_configuration_options.rb +57 -0
- data/lib/ruby_onvif_client/media/get_audio_encoder_configurations.rb +49 -0
- data/lib/ruby_onvif_client/media/get_audio_source_configurations.rb +32 -0
- data/lib/ruby_onvif_client/media/get_stream_uri.rb +58 -0
- data/lib/ruby_onvif_client/media/get_video_encoder_configuration.rb +104 -0
- data/lib/ruby_onvif_client/media/get_video_encoder_configuration_options.rb +95 -0
- data/lib/ruby_onvif_client/media/get_video_source_configuration.rb +55 -0
- data/lib/ruby_onvif_client/media/get_video_source_configurations.rb +40 -0
- data/lib/ruby_onvif_client/media.rb +10 -0
- data/lib/ruby_onvif_client/message.rb +41 -0
- data/lib/ruby_onvif_client/path.rb +5 -0
- data/lib/ruby_onvif_client/service.rb +37 -0
- data/lib/ruby_onvif_client.rb +3 -0
- data/ruby-onvif-client.gemspec +20 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a4ea5d47b7c0f188430173401d43c90c576fcc48
|
4
|
+
data.tar.gz: 070b68e1ef2e54093147fc3b32a220003ac85c4c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49aa588d66590b7b98f28f0bd793619d89f144a5da078f7d132a27d7403c3b924f3ae74e5e49df71cc9e770cef943b66f8933e611f86c344c1010ff5a05cb0d1
|
7
|
+
data.tar.gz: 9ab55c46c26c1c379e607d42cc79cf48796e4475d4d71463c466dff3e5ad2e8de95864e1cf7f0b0a0f717d7ee1f457b5d50feb3d634ced117a35a583dadb43b5
|
data/Gemfile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'message'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
class Action
|
5
|
+
def initialize client
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_message message
|
10
|
+
@client.send message.to_s do |success, result|
|
11
|
+
yield success, result
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def callback cb, *args
|
16
|
+
return if cb.class != Proc
|
17
|
+
cb.call *args
|
18
|
+
end
|
19
|
+
|
20
|
+
def value xml_doc, xpath
|
21
|
+
node = xml_doc.at_xpath(xpath)
|
22
|
+
return node.content unless node.nil?
|
23
|
+
''
|
24
|
+
end
|
25
|
+
def attribute xml_doc, xpath
|
26
|
+
node = xml_doc[xpath]
|
27
|
+
return node unless node.nil?
|
28
|
+
''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "em-http"
|
2
|
+
require "nokogiri"
|
3
|
+
require "nori"
|
4
|
+
|
5
|
+
module ONVIF
|
6
|
+
class Client
|
7
|
+
def initialize options
|
8
|
+
@options = {
|
9
|
+
connect_timeout: 5,
|
10
|
+
}.merge(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def send data
|
14
|
+
puts "send data to #{@options} ", data
|
15
|
+
http_options = {
|
16
|
+
connect_timeout: @options[:connect_timeout]
|
17
|
+
}
|
18
|
+
request_options = {
|
19
|
+
body: data,
|
20
|
+
}
|
21
|
+
http = EventMachine::HttpRequest.new(
|
22
|
+
@options[:address],
|
23
|
+
http_options
|
24
|
+
).post(request_options)
|
25
|
+
http.errback { yield false, {} }
|
26
|
+
http.callback do
|
27
|
+
puts "========================="
|
28
|
+
puts "receive message =>", http.response
|
29
|
+
puts "========================="
|
30
|
+
if http.response_header.status != 200
|
31
|
+
yield false, {header: http.response_header}
|
32
|
+
else
|
33
|
+
#nori = Nori.new(:strip_namespaces => true)
|
34
|
+
yield true, {
|
35
|
+
header: http.response_header,
|
36
|
+
#content: nori.parse(http.response)
|
37
|
+
content: http.response
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'path.rb'
|
2
|
+
require "uri"
|
3
|
+
require "ws_discovery"
|
4
|
+
|
5
|
+
module ONVIF
|
6
|
+
class DeviceDiscovery
|
7
|
+
def self.start options = {}
|
8
|
+
DeviceDiscovery.new.start(options) do |devices|
|
9
|
+
yield devices
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def start options
|
14
|
+
@options = {
|
15
|
+
}.merge(options)
|
16
|
+
searcher = WSDiscovery.search(
|
17
|
+
env_namespaces: {
|
18
|
+
"xmlns:dn" => "http://www.onvif.org/ver10/network/wsdl"
|
19
|
+
},
|
20
|
+
types: "dn:NetworkVideoTransmitter"
|
21
|
+
)
|
22
|
+
searcher.discovery_responses.subscribe do |notification|
|
23
|
+
device = {
|
24
|
+
ep_address: notification[:probe_matches][:probe_match][:endpoint_reference][:address],
|
25
|
+
types: notification[:probe_matches][:probe_match][:types],
|
26
|
+
device_ip: URI(notification[:probe_matches][:probe_match][:x_addrs]).host,
|
27
|
+
device_service_address: notification[:probe_matches][:probe_match][:x_addrs],
|
28
|
+
scopes: notification[:probe_matches][:probe_match][:scopes].split(' '),
|
29
|
+
metadata_version: notification[:probe_matches][:probe_match][:metadata_version]
|
30
|
+
}
|
31
|
+
yield device
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetCapabilities < Action
|
6
|
+
# options 的结构 <!--0 or more-->
|
7
|
+
# [{
|
8
|
+
# Category: "All", //nil, 'All', 'Analytics', 'Device', 'Events', 'Imaging', 'Media', 'PTZ'
|
9
|
+
# <!--0 or more-->
|
10
|
+
# }]
|
11
|
+
def run options, cb
|
12
|
+
message = Message.new
|
13
|
+
message.body = ->(xml) do
|
14
|
+
xml.wsdl(:GetCapabilities) do
|
15
|
+
unless options.nil?
|
16
|
+
options.each do |option|
|
17
|
+
xml.wsdl :Category, option["Category"]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
send_message message do |success, result|
|
23
|
+
if success
|
24
|
+
xml_doc = Nokogiri::XML(result[:content])
|
25
|
+
xml_analytics = xml_doc.at_xpath('//tt:Analytics')
|
26
|
+
xml_device = xml_doc.at_xpath('//tt:Device')
|
27
|
+
xml_events = xml_doc.at_xpath('//tt:Events')
|
28
|
+
xml_imaging = xml_doc.at_xpath('//tt:Imaging')
|
29
|
+
xml_media = xml_doc.xpath('//tt:Media')
|
30
|
+
xml_ptz = xml_doc.xpath('//tt:PTZ')
|
31
|
+
success_result = {}
|
32
|
+
success_result["analytics"] = _get_analytics(xml_analytics) unless xml_analytics.nil?
|
33
|
+
success_result["device"] = _get_device(xml_device) unless xml_device.nil?
|
34
|
+
success_result["events"] = _get_events(xml_events) unless xml_events.nil?
|
35
|
+
success_result["imaging"] = _get_imaging(xml_imaging) unless xml_imaging.nil?
|
36
|
+
success_result["media"] = _get_media(xml_media) unless xml_media.nil?
|
37
|
+
success_result["ptz"] = _get_ptz(xml_ptz) unless xml_ptz.nil?
|
38
|
+
callback cb, success, success_result
|
39
|
+
else
|
40
|
+
callback cb, success, result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def _get_analytics xml_analytics
|
46
|
+
{
|
47
|
+
x_addr: value(xml_analytics, '//tt:XAddr'),
|
48
|
+
rule_support: value(xml_analytics, '//tt:RuleSupport'),
|
49
|
+
ams: value(xml_analytics, '//tt:AnalyticsModuleSupport')
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def _get_device xml_device
|
54
|
+
network_keys = ["IPFilter", "ZeroConfiguration", "IPVersion6", "DynDNS", "Dot11Configuration",
|
55
|
+
"Dot1XConfigurations", "HostnameFromDHCP", "NTP", "DHCPv6"]
|
56
|
+
system_keys = ["DiscoveryResolve", "DiscoveryBye", "RemoteDiscovery", "SystemBackup", "SystemLogging",
|
57
|
+
"FirmwareUpgrade", "HttpFirmwareUpgrade", "HttpSystemBackup", "HttpSystemLogging", "HttpSupportInformation"]
|
58
|
+
security_keys = ["TLS1.0", "TLS1.1", "TLS1.2", "OnboardKeyGeneration", "AccessPolicyConfig",
|
59
|
+
"DefaultAccessPolicy", "Dot1X", "RemoteUserHandling", "X.509Token", "SAMLToken", "KerberosToken",
|
60
|
+
"UsernameToken", "HttpDigest", "RELToken", "SupportedEAPMethods"]
|
61
|
+
network = {}; system = {}; security = {}
|
62
|
+
network_keys.each do |key|
|
63
|
+
network[key.underscore] = value(xml_device, '//tt:' + key) unless value(xml_device, '//tt:' + key) == ''
|
64
|
+
end
|
65
|
+
system_keys.each do |key|
|
66
|
+
system[key.underscore] = value(xml_device, '//tt:' + key) unless value(xml_device, '//tt:' + key) == ''
|
67
|
+
end
|
68
|
+
security_keys.each do |key|
|
69
|
+
security[key.underscore] = value(xml_device, '//tt:' + key) unless value(xml_device, '//tt:' + key) == ''
|
70
|
+
end
|
71
|
+
return {
|
72
|
+
x_addr: value(xml_device, '//tt:XAddr'),
|
73
|
+
network: network,
|
74
|
+
system: system,
|
75
|
+
io: {
|
76
|
+
input_connectors: value(xml_device, '//tt:InputConnectors'),
|
77
|
+
relay_outputs: value(xml_device, '//tt:RelayOutputs'),
|
78
|
+
extension: ""
|
79
|
+
},
|
80
|
+
security: security
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def _get_events xml_events
|
85
|
+
{
|
86
|
+
x_addr: value(xml_events, '//tt:XAddr'),
|
87
|
+
wssubscription_policy_support: value(xml_events, '//tt:WSSubscriptionPolicySupport'),
|
88
|
+
wspull_point_support: value(xml_events, '//tt:WSPullPointSupport'),
|
89
|
+
wspsmis: value(xml_events, '//tt:WSPausableSubscriptionManagerInterfaceSupport')
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def _get_imaging xml_imaging
|
94
|
+
{
|
95
|
+
x_addr: value(xml_imaging, '//tt:XAddr')
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def _get_media xml_media
|
100
|
+
{
|
101
|
+
x_addr: value(xml_media, '//tt:XAddr'),
|
102
|
+
streaming_capabilities: {
|
103
|
+
rtp_multicast: value(xml_media, '//tt:RTPMulticast'),
|
104
|
+
rtp_tcp: value(xml_media, '//tt:RTPMulticast'),
|
105
|
+
rtp_rtsp_tcp: value(xml_media, '//tt:RTP_RTSP_TCP'),
|
106
|
+
extension: ""
|
107
|
+
},
|
108
|
+
extension: ""
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
def _get_ptz xml_ptz
|
113
|
+
{x_addr: value(xml_ptz, '//tt:XAddr')}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetDeviceInformation < Action
|
6
|
+
def run cb
|
7
|
+
message = Message.new
|
8
|
+
message.body = ->(xml) do
|
9
|
+
xml.wsdl(:GetDeviceInformation)
|
10
|
+
end
|
11
|
+
send_message message do |success, result|
|
12
|
+
if success
|
13
|
+
xml_doc = Nokogiri::XML(result[:content])
|
14
|
+
info = {
|
15
|
+
mf: value(xml_doc, '//tds:Manufacturer'),
|
16
|
+
model: value(xml_doc, '//tds:Model'),
|
17
|
+
firmware_version: value(xml_doc, '//tds:FirmwareVersion'),
|
18
|
+
serial_number: value(xml_doc, '//tds:SerialNumber'),
|
19
|
+
hardware_id: value(xml_doc, '//tds:HardwareId')
|
20
|
+
}
|
21
|
+
callback cb, success, info
|
22
|
+
else
|
23
|
+
callback cb, success, result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetNetworkInterfaces < Action
|
6
|
+
def run cb
|
7
|
+
message = Message.new
|
8
|
+
message.body = ->(xml) do
|
9
|
+
xml.wsdl(:GetNetworkInterfaces)
|
10
|
+
end
|
11
|
+
send_message message do |success, result|
|
12
|
+
if success
|
13
|
+
xml_doc_main = Nokogiri::XML(result[:content])
|
14
|
+
interfaces = []
|
15
|
+
xml_doc_main.xpath('//tds:NetworkInterfaces').each do |xml_doc|
|
16
|
+
xml_info = xml_doc.at_xpath('tt:Info')
|
17
|
+
xml_link = xml_doc.at_xpath('tt:Link')
|
18
|
+
xml_ipv4 = xml_doc.at_xpath('tt:IPv4')
|
19
|
+
xml_ipv6 = xml_doc.at_xpath('tt:IPv6')
|
20
|
+
success_result = {
|
21
|
+
token: attribute(xml_doc, "token"),
|
22
|
+
enabled: value(xml_doc, "tt:Enabled")
|
23
|
+
}
|
24
|
+
success_result["info"] = _get_info(xml_info) unless xml_info.nil?
|
25
|
+
success_result["link"] = _get_link(xml_link) unless xml_link.nil?
|
26
|
+
success_result["ipv4"] = _get_ipv_four(xml_ipv4) unless xml_ipv4.nil?
|
27
|
+
success_result["ipv6"] = _get_ipv_six(xml_ipv6) unless xml_ipv6.nil?
|
28
|
+
interfaces << success_result
|
29
|
+
end
|
30
|
+
callback cb, success, interfaces
|
31
|
+
else
|
32
|
+
callback cb, success, result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def _get_info xml_info
|
38
|
+
{
|
39
|
+
name: value(xml_info, 'tt:Name'),
|
40
|
+
hw_address: value(xml_info, 'tt:HwAddress'),
|
41
|
+
mtu: value(xml_info, 'tt:MTU')
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def _get_link xml_link
|
46
|
+
admin_xml_doc = xml_link.at_xpath('tt:AdminSettings')
|
47
|
+
oper_xml_doc = xml_link.at_xpath('tt:OperSettings')
|
48
|
+
link = {}
|
49
|
+
unless xml_doc.nil?
|
50
|
+
link["admin_settings"] = {
|
51
|
+
auto_negotiation: value(admin_xml_doc, "tt:AutoNegotiation"),
|
52
|
+
speed: value(admin_xml_doc, "tt:Speed"),
|
53
|
+
duplex: value(admin_xml_doc, "tt:Duplex")
|
54
|
+
}
|
55
|
+
end
|
56
|
+
unless oper_xml_doc.nil?
|
57
|
+
link["oper_settings"] = {
|
58
|
+
auto_negotiation: value(oper_xml_doc, "tt:AutoNegotiation"),
|
59
|
+
speed: value(oper_xml_doc, "tt:Speed"),
|
60
|
+
duplex: value(oper_xml_doc, "tt:Duplex")
|
61
|
+
}
|
62
|
+
end
|
63
|
+
link["interface_type"] = value(xml_link, "tt:InterfaceType") unless xml_link.at_xpath('tt:InterfaceType')
|
64
|
+
return link
|
65
|
+
end
|
66
|
+
|
67
|
+
def _get_ipv_four xml_ipv_four
|
68
|
+
puts xml_ipv_four
|
69
|
+
ipv_four = {enabled: value(xml_ipv_four, 'tt:Enabled')}
|
70
|
+
manual = []; config = {}
|
71
|
+
link_local = xml_ipv_four.xpath('tt:Config/tt:LinkLocal')
|
72
|
+
form_dhcp = xml_ipv_four.xpath('tt:Config/tt:FromDHCP')
|
73
|
+
xml_ipv_four.xpath('tt:Config//tt:Manual').each do |node|
|
74
|
+
manual << {
|
75
|
+
address: value(node, "tt:Address"),
|
76
|
+
prefix_length: value(node, "tt:PrefixLength")
|
77
|
+
}
|
78
|
+
end
|
79
|
+
config["manual"] = manual
|
80
|
+
config["link_local"] = {
|
81
|
+
address: value(link_local, "tt:Address"),
|
82
|
+
prefix_length: value(link_local, "tt:PrefixLength")
|
83
|
+
}
|
84
|
+
config["form_dhcp"] = {
|
85
|
+
address: value(form_dhcp, "tt:Address"),
|
86
|
+
prefix_length: value(form_dhcp, "tt:PrefixLength")
|
87
|
+
}
|
88
|
+
config["dhcp"] = value(xml_ipv_four, "tt:Config//tt:DHCP")
|
89
|
+
ipv_four["config"] = config
|
90
|
+
return ipv_four
|
91
|
+
end
|
92
|
+
|
93
|
+
def _get_ipv_six xml_ipv_six
|
94
|
+
ipv_six = {enabled: value(xml_ipv_six, 'tt:Enabled')}
|
95
|
+
config = {}; manual = []; link_local = []; form_dhcp = []; form_ra = []
|
96
|
+
xml_ipv_six.xpath('tt:Config/tt:Manual').each do |node|
|
97
|
+
manual << {
|
98
|
+
address: value(node, "tt:Address"),
|
99
|
+
prefix_length: value(node, "tt:PrefixLength")
|
100
|
+
}
|
101
|
+
end
|
102
|
+
xml_ipv_six.xpath('tt:Config/tt:LinkLocal').each do |node|
|
103
|
+
link_local << {
|
104
|
+
address: value(node, "tt:Address"),
|
105
|
+
prefix_length: value(node, "tt:PrefixLength")
|
106
|
+
}
|
107
|
+
end
|
108
|
+
xml_ipv_six.xpath('tt:Config/tt:FromDHCP').each do |node|
|
109
|
+
form_dhcp << {
|
110
|
+
address: value(node, "tt:Address"),
|
111
|
+
prefix_length: value(node, "tt:PrefixLength")
|
112
|
+
}
|
113
|
+
end
|
114
|
+
xml_ipv_six.xpath('tt:Config/tt:FromRA').each do |node|
|
115
|
+
form_ra << {
|
116
|
+
address: value(node, "tt:Address"),
|
117
|
+
prefix_length: value(node, "tt:PrefixLength")
|
118
|
+
}
|
119
|
+
end
|
120
|
+
config["manual"] = manual
|
121
|
+
config["link_local"] = link_local
|
122
|
+
config["form_dhcp"] = form_dhcp
|
123
|
+
config["form_ra"] = form_ra
|
124
|
+
config["ara"] = value(xml_ipv_six, "tt:AcceptRouterAdvert")
|
125
|
+
config["dhcp"] = value(xml_ipv_six, "tt:DHCP")
|
126
|
+
ipv_six["config"] = config
|
127
|
+
return ipv_six
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetNetworkProtocols < Action
|
6
|
+
def run cb
|
7
|
+
message = Message.new
|
8
|
+
message.body = ->(xml) do
|
9
|
+
xml.wsdl(:GetNetworkProtocols)
|
10
|
+
end
|
11
|
+
send_message message do |success, result|
|
12
|
+
if success
|
13
|
+
xml_doc = Nokogiri::XML(result[:content])
|
14
|
+
network = []
|
15
|
+
xml_doc.xpath('//tds:NetworkProtocols').each do |node|
|
16
|
+
network << {
|
17
|
+
name: value(node, 'tt:Name'),
|
18
|
+
enabled: value(node, 'tt:Enabled'),
|
19
|
+
port: value(node, 'tt:Port'),
|
20
|
+
extension: value(node, 'tt:Extension')
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
callback cb, success, network
|
25
|
+
else
|
26
|
+
callback cb, success, result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetSystemDateAndTime < Action
|
6
|
+
def run cb
|
7
|
+
message = Message.new
|
8
|
+
message.body = ->(xml) do
|
9
|
+
xml.wsdl(:GetSystemDateAndTime)
|
10
|
+
end
|
11
|
+
send_message message do |success, result|
|
12
|
+
if success
|
13
|
+
xml_doc = Nokogiri::XML(result[:content])
|
14
|
+
xml_utc = xml_doc.xpath('//tt:UTCDateTime')
|
15
|
+
xml_local = xml_doc.xpath('//tt:LocalDateTime')
|
16
|
+
utc_data_time = {
|
17
|
+
time: {
|
18
|
+
hour: value(xml_utc, '//tt:Hour'),
|
19
|
+
minute: value(xml_utc, '//tt:Minute'),
|
20
|
+
second: value(xml_utc, '//tt:Second')
|
21
|
+
},
|
22
|
+
date: {
|
23
|
+
year: value(xml_utc, '//tt:Year'),
|
24
|
+
month: value(xml_utc, '//tt:Month'),
|
25
|
+
day: value(xml_utc, '//tt:Day')
|
26
|
+
}
|
27
|
+
}
|
28
|
+
local_date_time = {
|
29
|
+
time: {
|
30
|
+
hour: value(xml_local, '//tt:Hour'),
|
31
|
+
minute: value(xml_local, '//tt:Minute'),
|
32
|
+
second: value(xml_local, '//tt:Second')
|
33
|
+
},
|
34
|
+
date: {
|
35
|
+
year: value(xml_local, '//tt:Year'),
|
36
|
+
month: value(xml_local, '//tt:Month'),
|
37
|
+
day: value(xml_local, '//tt:Day')
|
38
|
+
}
|
39
|
+
}
|
40
|
+
date_time = {
|
41
|
+
date_time_type: value(xml_doc, '//tt:DateTimeType'),
|
42
|
+
daylight_savings: value(xml_doc, '//tt:DaylightSavings'),
|
43
|
+
time_zone: {
|
44
|
+
tz: value(xml_doc, '//tt:TZ'),
|
45
|
+
},
|
46
|
+
extension: value(xml_doc, '//tt:Extension')
|
47
|
+
}
|
48
|
+
xml_utc_time = xml_doc.at_xpath('//tt:UTCDateTime')
|
49
|
+
xml_local_time = xml_doc.at_xpath('//tt:LocalDateTime')
|
50
|
+
date_time["utc_date_time"] = utc_data_time unless xml_utc_time.nil?
|
51
|
+
date_time["local_date_time"] = local_date_time unl unless xml_local_time.nil?
|
52
|
+
callback cb, success, date_time
|
53
|
+
else
|
54
|
+
callback cb, success, result
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class GetUsers < Action
|
6
|
+
def run cb
|
7
|
+
message = Message.new
|
8
|
+
message.body = ->(xml) do
|
9
|
+
xml.wsdl(:GetUsers)
|
10
|
+
end
|
11
|
+
send_message message do |success, result|
|
12
|
+
if success
|
13
|
+
xml_doc = Nokogiri::XML(result[:content])
|
14
|
+
users = []
|
15
|
+
xml_doc.xpath('//tds:User').each do |node|
|
16
|
+
users << {
|
17
|
+
name: value(node, 'tt:Username'),
|
18
|
+
password: value(node, 'tt:Password'),
|
19
|
+
user_level: value(node, 'tt:UserLevel')
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
callback cb, success, users
|
24
|
+
else
|
25
|
+
callback cb, success, result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class SetNetworkInterfaces < Action
|
6
|
+
# network_interface 的结构
|
7
|
+
# {
|
8
|
+
# interface_token: 'xxxxxx', // name [string]
|
9
|
+
# nwif:{ // #NetworkInterface
|
10
|
+
# enabled: true, //true, false [boolean]
|
11
|
+
# link: {
|
12
|
+
# auto_negotiation: true, //true, false [boolean]
|
13
|
+
# speed: 3, // [int]
|
14
|
+
# duplex: 'Full' //'Full', 'Half'
|
15
|
+
# }
|
16
|
+
# mtu: 2, // [int]
|
17
|
+
# ipv4: {
|
18
|
+
# enabled: true, //true, false [boolean]
|
19
|
+
# manual: [{
|
20
|
+
# address: "xxx.xxx.xxx.xxx", // [IPv4Address]
|
21
|
+
# prefix_length: 22 // [int]
|
22
|
+
# }],
|
23
|
+
# dhcp: true //true, false [boolean]
|
24
|
+
# },
|
25
|
+
# ipv6: {
|
26
|
+
# enabled: true, //true, false [boolean]
|
27
|
+
# ara: false//true, false #AcceptRouterAdvert [boolean]
|
28
|
+
# manual: [{
|
29
|
+
# address: "xxx.xxx.xxx.xxx", // [IPv4Address]
|
30
|
+
# prefix_length: 22 // [int]
|
31
|
+
# }],
|
32
|
+
# dhcp: true //true, false [boolean]
|
33
|
+
# }
|
34
|
+
# }
|
35
|
+
# }
|
36
|
+
def run network_interface, cb
|
37
|
+
message = Message.new namespaces: {:'xmlns:sch' => 'http://www.onvif.org/ver10/schema'}
|
38
|
+
message.body = ->(xml) do
|
39
|
+
xml.wsdl(:SetNetworkInterfaces) do
|
40
|
+
xml.wsdl :InterfaceToken, network_interface["interface_token"]
|
41
|
+
xml.wsdl :NetworkInterface do
|
42
|
+
xml.sch :Enabled, network_interface["nwif"]["enabled"]
|
43
|
+
xml.sch :Link do
|
44
|
+
xml.sch :AutoNegotiation, network_interface["nwif"]["link"]["auto_negotiation"]
|
45
|
+
xml.sch :Speed, network_interface["nwif"]["link"]["speed"]
|
46
|
+
xml.sch :Duplex, network_interface["nwif"]["link"]["duplex"]
|
47
|
+
end
|
48
|
+
xml.sch :MTU, network_interface["nwif"]["mtu"]
|
49
|
+
xml.sch :IPv4 do
|
50
|
+
xml.sch :Enabled, network_interface["nwif"]["ipv4"]["enabled"]
|
51
|
+
network_interface["nwif"]["ipv4"]["manual"].each do |manual|
|
52
|
+
xml.sch :Manual do
|
53
|
+
xml.sch :Address, manual["address"]
|
54
|
+
xml.sch :PrefixLength, manual["prefix_length"]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
xml.sch :DHCP, network_interface["nwif"]["ipv4"]["dhcp"]
|
58
|
+
end
|
59
|
+
xml.sch :IPv6 do
|
60
|
+
xml.sch :Enabled, network_interface["nwif"]["ipv6"]["enabled"]
|
61
|
+
xml.sch :AcceptRouterAdvert, network_interface["nwif"]["ipv6"]["ara"]
|
62
|
+
network_interface["nwif"]["ipv6"]["manual"].each do |manual|
|
63
|
+
xml.sch :Manual do
|
64
|
+
xml.sch :Address, manual["address"]
|
65
|
+
xml.sch :PrefixLength, manual["prefix_length"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
xml.sch :DHCP, network_interface["nwif"]["ipv6"]["dhcp"]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
xml.wsdl :Extension do
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
send_message message do |success, result|
|
77
|
+
#????
|
78
|
+
callback cb, success, result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../action'
|
2
|
+
|
3
|
+
module ONVIF
|
4
|
+
module DeviceManagementAction
|
5
|
+
class SetSystemDateAndTime < Action
|
6
|
+
# system_date_time 的结构
|
7
|
+
# {
|
8
|
+
# type: 'Manual', // 'Manual', 'NTP'
|
9
|
+
# ds: false // DaylightSavings [booblean]
|
10
|
+
# time_zone_tz: 'xxxxx'// string TimeZone -> TZ [token]
|
11
|
+
# year: 2013 // int
|
12
|
+
# month: 6 // int 1 to 12
|
13
|
+
# day: 26 // int 1 to 31
|
14
|
+
# hour: 5 // int 0 to 23
|
15
|
+
# minute: 31 //int 0 to 59
|
16
|
+
# second: 44 //int 0 to 61 (typically 59)
|
17
|
+
# }
|
18
|
+
def run system_date_time, cb
|
19
|
+
message = Message.new namespaces: {:'xmlns:sch' => 'http://www.onvif.org/ver10/schema'}
|
20
|
+
message.body = ->(xml) do
|
21
|
+
xml.wsdl(:SetSystemDateAndTime) do
|
22
|
+
xml.wsdl :DateTimeType, system_date_time["type"]
|
23
|
+
xml.wsdl :DaylightSavings, system_date_time["ds"]
|
24
|
+
xml.wsdl(:TimeZone) do
|
25
|
+
xml.sch :TZ, system_date_time["time_zone_tz"]
|
26
|
+
end
|
27
|
+
xml.wsdl(:TimeZone) do
|
28
|
+
xml.sch :Time do
|
29
|
+
xml.sch :Hour, system_date_time["hour"]
|
30
|
+
xml.sch :Minute, system_date_time["minute"]
|
31
|
+
xml.sch :Second, system_date_time["second"]
|
32
|
+
end
|
33
|
+
xml.sch :Date do
|
34
|
+
xml.sch :Year, system_date_time["year"]
|
35
|
+
xml.sch :Month, system_date_time["month"]
|
36
|
+
xml.sch :Day, system_date_time["day"]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
send_message message do |success, result|
|
42
|
+
#????
|
43
|
+
callback cb, success, result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|