ruby_onvif_client 0.0.7 → 0.0.8

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
  SHA1:
3
- metadata.gz: ab23cbb25cad70f098518423df54826d7a75c1ae
4
- data.tar.gz: cc1e662e1b7e25b1c88535c7e2551e7ed0906a81
3
+ metadata.gz: ff6213cb0545f46781a35cdeb0b2a23410dc6fe1
4
+ data.tar.gz: 552415292467d299f720d748568b559ac460f480
5
5
  SHA512:
6
- metadata.gz: 8c8b233a208a8e2570650ceba6be1bb42a1886cbb944b06c1d240c5ff6f192115ed05edb2405b6fed47d4fc07536e3b3fe001d5e4e2e897c68ca9e1c89788913
7
- data.tar.gz: d273e1e94f21a0c000ec045fc87310ba1786eb6dcfe6e8413a0b5709f6e2b90683d7ddcd60f495f21bdfd56ea47c745f23ad2da07366570b80d8a25564dbe21d
6
+ metadata.gz: 00a9acf05dd4d4e9d5a2ae0093eec0a435d6cf4061aa19b6e181b462b1069d6b77e3924c293a231a205595226cf7cb87237049a8719d9659c5a6f5233dc48d0c
7
+ data.tar.gz: 35bbd68f291dd691f019fe26552d0295051fe5644eb5607b88eac9856bbc1d5f67791ce8defeead8dabe7d89d6201b1af3cecfd7f10f4cafaa74a4a9e63400cd
@@ -0,0 +1,124 @@
1
+ module ONVIF
2
+ module PtzCommon
3
+ def get_configuration_optional_value xml_doc, configuration
4
+ configuration = {} if configuration.nil?
5
+ unless xml_doc.at_xpath("tt:DefaultAbsolutePantTiltPositionSpace").nil?
6
+ configuration[:daptps] = value(xml_doc, "tt:DefaultAbsolutePantTiltPositionSpace")
7
+ end
8
+ unless xml_doc.at_xpath("tt:DefaultAbsoluteZoomPositionSpace").nil?
9
+ configuration[:dazps] = value(xml_doc, "tt:DefaultAbsoluteZoomPositionSpace")
10
+ end
11
+ unless xml_doc.at_xpath("tt:DefaultRelativePanTiltTranslationSpace").nil?
12
+ configuration[:drptts] = value(xml_doc, "tt:DefaultRelativePanTiltTranslationSpace")
13
+ end
14
+ unless xml_doc.at_xpath("tt:DefaultRelativeZoomTranslationSpace").nil?
15
+ configuration[:drzts] = value(xml_doc, "tt:DefaultRelativeZoomTranslationSpace")
16
+ end
17
+ unless xml_doc.at_xpath("tt:DefaultContinuousPanTiltVelocitySpace").nil?
18
+ configuration[:dcptvs] = value(xml_doc, "tt:DefaultContinuousPanTiltVelocitySpace")
19
+ end
20
+ unless xml_doc.at_xpath("tt:DefaultContinuousZoomVelocitySpace").nil?
21
+ configuration[:dczvs] = value(xml_doc, "tt:DefaultContinuousZoomVelocitySpace")
22
+ end
23
+ unless xml_doc.at_xpath("tt:DefaultPTZTimeout").nil?
24
+ configuration[:d_ptz_timeout] = value(xml_doc, "tt:DefaultPTZTimeout")
25
+ end
26
+ return configuration
27
+ end
28
+
29
+ def get_space_muster root_doc, parent_node_name, configuration
30
+ configuration = {} if configuration.nil?
31
+ configuration[parent_node_name.underscore] = {}
32
+ spaces = root_doc.xpath("tt:" + parent_node_name)
33
+ unless spaces.at_xpath("tt:AbsolutePanTiltPositionSpace").nil?
34
+ configuration[parent_node_name.underscore][:aptps] = get_spaces spaces, "AbsolutePanTiltPositionSpace"
35
+ end
36
+ unless spaces.at_xpath("tt:AbsoluteZoomPositionSpace").nil?
37
+ configuration[parent_node_name.underscore][:azps] = get_spaces spaces, "AbsoluteZoomPositionSpace"
38
+ end
39
+ unless spaces.at_xpath("tt:RelativePanTiltTranslationSpace").nil?
40
+ configuration[parent_node_name.underscore][:rptts] = get_spaces spaces, "RelativePanTiltTranslationSpace"
41
+ end
42
+ unless spaces.at_xpath("tt:RelativeZoomTranslationSpace").nil?
43
+ configuration[parent_node_name.underscore][:rzts] = get_spaces spaces, "RelativeZoomTranslationSpace"
44
+ end
45
+ unless spaces.at_xpath("tt:ContinuousPanTiltVelocitySpace").nil?
46
+ configuration[parent_node_name.underscore][:cptvs] = get_spaces spaces, "ContinuousPanTiltVelocitySpace"
47
+ end
48
+ unless spaces.at_xpath("tt:ContinuousZoomVelocitySpace").nil?
49
+ configuration[parent_node_name.underscore][:czvs] = get_spaces spaces, "ContinuousZoomVelocitySpace"
50
+ end
51
+ unless spaces.at_xpath("tt:PanTiltSpeedSpace").nil?
52
+ configuration[parent_node_name.underscore][:ptss] = get_spaces spaces, "PanTiltSpeedSpace"
53
+ end
54
+ unless spaces.at_xpath("tt:ZoomSpeedSpace").nil?
55
+ configuration[parent_node_name.underscore][:zss] = get_spaces spaces, "ZoomSpeedSpace"
56
+ end
57
+ configuration[parent_node_name.underscore][:extension] = ""
58
+ return configuration
59
+ end
60
+
61
+ def get_spaces xml_doc, node_name
62
+ results = []
63
+ unless xml_doc.at_xpath("tt:" + node_name).nil?
64
+ xml_doc.xpath("tt:" + node_name).each do |space|
65
+ if space.at_xpath("tt:YRange").nil?
66
+ results << get_zoom_limits(space)
67
+ else
68
+ results << get_pan_tilt_limits(space)
69
+ end
70
+ end
71
+ end
72
+ return results
73
+ end
74
+
75
+ def get_speed xml_doc, speed_name, configuration
76
+ configuration = {} if configuration.nil?
77
+ speed_doc = xml_doc.at_xpath("tt:" + speed_name)
78
+ unless speed_doc.nil?
79
+ pan_tilt = speed_doc.at_xpath("tt:PanTilt")
80
+ zoom = speed_doc.at_xpath("tt:Zoom")
81
+ configuration[speed_name.underscore] = {}
82
+ unless pan_tilt.nil?
83
+ configuration[speed_name.underscore][:pan_tilt] = {
84
+ x: attribute(pan_tilt, "x"),
85
+ y: attribute(pan_tilt, "y"),
86
+ space: attribute(pan_tilt, "space")
87
+ }
88
+ end
89
+ unless zoom.nil?
90
+ configuration[speed_name.underscore][:pan_tilt] = {
91
+ x: attribute(zoom, "x"),
92
+ space: attribute(zoom, "space")
93
+ }
94
+ end
95
+ end
96
+ return configuration
97
+ end
98
+
99
+ def get_pan_tilt_limits xml_doc
100
+ configuration = {}
101
+ configuration = get_zoom_limits xml_doc
102
+ configuration[:y_range] = get_min_max(xml_doc, "tt:YRange")
103
+ return configuration
104
+ end
105
+
106
+ def get_zoom_limits xml_doc
107
+ return {
108
+ uri: value(xml_doc, "tt:URI"),
109
+ x_range: get_min_max(xml_doc, "tt:XRange")
110
+ }
111
+ end
112
+
113
+ def get_min_max xml_doc, parent_name
114
+ this_node = xml_doc
115
+ unless parent_name.nil?
116
+ this_node = xml_doc.at_xpath(parent_name)
117
+ end
118
+ return {
119
+ min: value(this_node, "tt:Min"),
120
+ max: value(this_node, "tt:Max")
121
+ }
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,85 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class AbsoluteMove < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx",//[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # position: {
10
+ # pan_tilt: { //optional
11
+ # x: 1, //[float]
12
+ # y: 2, //[float]
13
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
14
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
15
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
16
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
17
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
18
+ # },
19
+ # zoom: { //optional
20
+ # x: 1,//[float]
21
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
22
+ # }
23
+ # }
24
+ # speed: { //optional
25
+ # pan_tilt: { //optional
26
+ # x: 1, //[float]
27
+ # y: 2, //[float]
28
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
29
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
30
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
31
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
32
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
33
+ # },
34
+ # zoom: { //optional
35
+ # x: 1,//[float]
36
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
37
+ # }
38
+ # }
39
+ # }
40
+ def run options, cb
41
+ message = create_ptz_onvif_message
42
+ message.body = ->(xml) do
43
+ xml.wsdl(:AbsoluteMove) do
44
+ xml.wsdl :ProfileToken, options[:profile_token]
45
+ xml.wsdl(:Position) do
46
+ unless options[:position][:pan_tilt].nil?
47
+ xml.wsdl :PanTilt, {
48
+ "x" => options[:position][:pan_tilt][:x],
49
+ "y" => options[:position][:pan_tilt][:y],
50
+ "space" => options[:position][:pan_tilt][:space]
51
+ }
52
+ end
53
+ unless options[:position][:zoom].nil?
54
+ xml.wsdl :Zoom, {
55
+ "x" => options[:position][:zoom][:x],
56
+ "space" => options[:position][:zoom][:space]
57
+ }
58
+ end
59
+ end
60
+ unless options[:speed].nil?
61
+ xml.wsdl(:Speed) do
62
+ unless options[:speed][:pan_tilt].nil?
63
+ xml.wsdl :PanTilt, {
64
+ "x" => options[:speed][:pan_tilt][:x],
65
+ "y" => options[:speed][:pan_tilt][:y],
66
+ "space" => options[:speed][:pan_tilt][:space]
67
+ }
68
+ end
69
+ unless options[:speed][:zoom].nil?
70
+ xml.wsdl :Zoom, {
71
+ "x" => options[:speed][:zoom][:x],
72
+ "space" => options[:speed][:zoom][:space]
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ send_message message do |success, result|
80
+ callback cb, success, result
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class ContinuousMove < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx",//[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # velocity: { //optional
10
+ # pan_tilt: { //optional
11
+ # x: 1, //[float]
12
+ # y: 2, //[float]
13
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
14
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
15
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
16
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
17
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
18
+ # },
19
+ # zoom: { //optional
20
+ # x: 1,//[float]
21
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
22
+ # }
23
+ # },
24
+ # timeout: '' //optional [duration]
25
+ # }
26
+ def run options, cb
27
+ message = create_ptz_onvif_message
28
+ message.body = ->(xml) do
29
+ xml.wsdl(:ContinuousMove) do
30
+ xml.wsdl :ProfileToken, options[:profile_token]
31
+ unless options[:velocity].nil?
32
+ xml.wsdl(:Velocity) do
33
+ unless options[:velocity][:pan_tilt].nil?
34
+ xml.wsdl :PanTilt, {
35
+ "x" => options[:velocity][:pan_tilt][:x],
36
+ "y" => options[:velocity][:pan_tilt][:y],
37
+ "space" => options[:velocity][:pan_tilt][:space]
38
+ }
39
+ end
40
+ unless options[:velocity][:zoom].nil?
41
+ xml.wsdl :Zoom, {
42
+ "x" => options[:velocity][:zoom][:x],
43
+ "space" => options[:velocity][:zoom][:space]
44
+ }
45
+ end
46
+ end
47
+ end
48
+ xml.wsdl :Timeout, options[:timeout] unless options[:timeout].nil?
49
+ end
50
+ end
51
+ send_message message do |success, result|
52
+ callback cb, success, result
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ require_relative '../action'
2
+ require_relative '../helper/ptz_common'
3
+
4
+ module ONVIF
5
+ module PtzAction
6
+ class GetConfiguration < Action
7
+ include PtzCommon #get_configuration_optional_value , get_speed, get_pan_tilt_limits, get_zoom_limits
8
+ # p_c_token 的结构
9
+ # p_c_token = "xxxxx" //[ReferenceToken] Token of the requested PTZConfiguration.
10
+ def run p_c_token, cb
11
+ message = create_ptz_onvif_message
12
+ message.body = ->(xml) do
13
+ xml.wsdl(:GetConfiguration) do
14
+ xml.wsdl :PTZConfigurationToken, p_c_token
15
+ end
16
+ end
17
+ send_message message do |success, result|
18
+ if success
19
+ xml_doc = Nokogiri::XML(result[:content])
20
+ root_doc = xml_doc.at_xpath("//tptz:PTZConfiguration")
21
+ pan_tilt_limits_range = root_doc.at_xpath("tt:PanTiltLimits/tt:Range")
22
+ zoom_limits_range = root_doc.at_xpath("tt:ZoomLimits/tt:Range")
23
+ configuration = {
24
+ name: value(root_doc, 'tt:Name'),
25
+ use_count: value(root_doc, 'tt:UseCount'),
26
+ token: attribute(root_doc, 'token'),
27
+ node_token: value(root_doc, 'tt:NodeToken')
28
+ }
29
+ configuration = get_configuration_optional_value root_doc, configuration
30
+ configuration = get_speed root_doc, "DefaultPTZSpeed", configuration
31
+ configuration[:default_ptz_timeout] = value(root_doc, "tt:DefaultPTZTimeout")
32
+ configuration[:pan_tilt_limits] = {
33
+ range: get_pan_tilt_limits(pan_tilt_limits_range)
34
+ }
35
+ configuration[:zoom_limits] = {
36
+ range: get_zoom_limits(zoom_limits_range)
37
+ }
38
+ configuration[:extension] = ""
39
+ callback cb, success, configuration
40
+ else
41
+ callback cb, success, result
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,53 @@
1
+ require_relative '../action'
2
+ require_relative '../helper/ptz_common'
3
+
4
+ module ONVIF
5
+ module PtzAction
6
+ class GetConfigurationOptions < Action
7
+ include PtzCommon #get_speed, get_pan_tilt_limits, get_zoom_limits, get_space_muster
8
+ # c_token 的结构
9
+ # c_token = "xxxxx" //[ReferenceToken] Token of an existing configuration that the options are intended for.
10
+ def run c_token, cb
11
+ message = create_ptz_onvif_message
12
+ message.body = ->(xml) do
13
+ xml.wsdl(:GetConfigurationOptions) do
14
+ xml.wsdl :ConfigurationToken, c_token
15
+ end
16
+ end
17
+ send_message message do |success, result|
18
+ if success
19
+ xml_doc = Nokogiri::XML(result[:content])
20
+ root_doc = xml_doc.xpath("//tptz:PTZConfigurationOptions")
21
+ pt_control_direction = root_doc.at_xpath("tptz:PTControlDirection")
22
+ configuration = {}
23
+ configuration = get_space_muster(root_doc, "Spaces", nil)
24
+ unless pt_control_direction.nil?
25
+ eflip_mode = []; reverse_mode = []
26
+ pt_control_direction.xpath("tt:EFlip/tt:Mode").each do |mode|
27
+ eflip_mode << mode.content
28
+ end
29
+ pt_control_direction.xpath("tt:Reverse/tt:Mode").each do |mode|
30
+ reverse_mode << mode.content
31
+ end
32
+ configuration[:PTControlDirection] = {
33
+ eflip: {
34
+ mode: eflip_mode,
35
+ extension: ""
36
+ },
37
+ reverse: {
38
+ mode: reverse_mode,
39
+ extension: ""
40
+ }
41
+ }
42
+ end
43
+ configuration[:ptz_timeout] = get_min_max(root_doc, "tt:PTZTimeout")
44
+ configuration[:extension] = ""
45
+ callback cb, success, configuration
46
+ else
47
+ callback cb, success, result
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../action'
2
+ require_relative '../helper/ptz_common'
3
+
4
+ module ONVIF
5
+ module PtzAction
6
+ class GetConfigurations < Action
7
+ include PtzCommon #get_configuration_optional_value , get_speed, get_pan_tilt_limits, get_zoom_limits
8
+ def run cb
9
+ message = create_ptz_onvif_message
10
+ message.body = ->(xml) do
11
+ xml.wsdl(:GetConfigurations)
12
+ end
13
+ send_message message do |success, result|
14
+ if success
15
+ xml_doc = Nokogiri::XML(result[:content])
16
+ configurations = []
17
+ xml_doc.xpath("//tptz:PTZConfiguration").each do |root_node|
18
+ pan_tilt_limits_range = root_node.at_xpath("tt:PanTiltLimits/tt:Range")
19
+ zoom_limits_range = root_node.at_xpath("tt:ZoomLimits/tt:Range")
20
+ configuration = {
21
+ name: value(root_node, 'tt:Name'),
22
+ use_count: value(root_node, 'tt:UseCount'),
23
+ token: attribute(root_node, 'token'),
24
+ node_token: value(root_node, 'tt:NodeToken')
25
+ }
26
+ configuration = get_configuration_optional_value root_node, configuration
27
+ configuration = get_speed root_node, "DefaultPTZSpeed", configuration
28
+ configuration[:default_ptz_timeout] = value(root_node, "tt:DefaultPTZTimeout")
29
+ configuration[:pan_tilt_limits] = {
30
+ range: get_pan_tilt_limits(pan_tilt_limits_range)
31
+ }
32
+ configuration[:zoom_limits] = {
33
+ range: get_zoom_limits(zoom_limits_range)
34
+ }
35
+ configuration[:extension] = ""
36
+ configurations << configuration
37
+ end
38
+ callback cb, success, configurations
39
+ else
40
+ callback cb, success, result
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,8 +1,10 @@
1
1
  require_relative '../action'
2
+ require_relative '../helper/ptz_common'
2
3
 
3
4
  module ONVIF
4
5
  module PtzAction
5
6
  class GetNode < Action
7
+ include PtzCommon
6
8
  # node_token 的结构 //[ReferenceToken] Token of the requested PTZNode.
7
9
  def run node_token ,cb
8
10
  message = create_ptz_onvif_message
@@ -14,8 +16,22 @@ module ONVIF
14
16
  send_message message do |success, result|
15
17
  if success
16
18
  xml_doc = Nokogiri::XML(result[:content])
17
- preset_token = value(xml_doc, '//tptz:PTZNode')
18
- callback cb, success, preset_token
19
+ preset_token = xml_doc.at_xpath('//tptz:PTZNode')
20
+ ptz_node = {
21
+ name: value(preset_token, "tt:Name"),
22
+ token: attribute(preset_token, "token")
23
+ }
24
+ ptz_node = get_space_muster(preset_token, "SupportedPTZSpaces", ptz_node)
25
+ ptz_node[:maximum_number_of_presets] = value(preset_token, "tt:MaximumNumberOfPresets")
26
+ ptz_node[:home_supported] = value(preset_token, "tt:HomeSupported")
27
+ ptz_node[:auxiliary_commands] = []
28
+ unless preset_token.at_xpath("tt:AuxiliaryCommands").nil?
29
+ ptz_node[:auxiliary_commands] = []
30
+ preset_token.xpath("tt:AuxiliaryCommands").each do |command|
31
+ ptz_node[:auxiliary_commands] << command.content
32
+ end
33
+ end
34
+ callback cb, success, ptz_node
19
35
  else
20
36
  callback cb, success, result
21
37
  end
@@ -1,10 +1,11 @@
1
1
  require_relative '../action'
2
+ require_relative '../helper/ptz_common'
2
3
 
3
4
  module ONVIF
4
5
  module PtzAction
5
6
  class GetNodes < Action
6
- # node_token 的结构 //[ReferenceToken] Token of the requested PTZNode.
7
- def run node_token ,cb
7
+ include PtzCommon
8
+ def run cb
8
9
  message = create_ptz_onvif_message
9
10
  message.body = ->(xml) do
10
11
  xml.wsdl(:GetNodes)
@@ -12,8 +13,24 @@ module ONVIF
12
13
  send_message message do |success, result|
13
14
  if success
14
15
  xml_doc = Nokogiri::XML(result[:content])
15
- # ???
16
- callback cb, success, preset_token
16
+ ptz_nodes = []
17
+ xml_doc.xpath('//tptz:PTZNode').each do |preset_token|
18
+ ptz_node = {
19
+ name: value(preset_token, "tt:Name"),
20
+ token: attribute(preset_token, "token")
21
+ }
22
+ ptz_node = get_space_muster(preset_token, "SupportedPTZSpaces", ptz_node)
23
+ ptz_node[:maximum_number_of_presets] = value(preset_token, "tt:MaximumNumberOfPresets")
24
+ ptz_node[:home_supported] = value(preset_token, "tt:HomeSupported")
25
+ unless preset_token.at_xpath("tt:AuxiliaryCommands").nil?
26
+ ptz_node[:auxiliary_commands] = []
27
+ preset_token.xpath("tt:AuxiliaryCommands").each do |command|
28
+ ptz_node[:auxiliary_commands] << command.content
29
+ end
30
+ end
31
+ ptz_nodes << ptz_node
32
+ end
33
+ callback cb, success, ptz_nodes
17
34
  else
18
35
  callback cb, success, result
19
36
  end
@@ -0,0 +1,37 @@
1
+ require_relative '../action'
2
+ require_relative '../helper/ptz_common'
3
+
4
+ module ONVIF
5
+ module PtzAction
6
+ class GetPresets < Action
7
+ include PtzCommon #get_speed()
8
+ # p_token 的结构
9
+ # p_token = "xxxxx" //[ReferenceToken] A reference to the MediaProfile where the operation should take place.
10
+ def run p_token, cb
11
+ message = create_ptz_onvif_message
12
+ message.body = ->(xml) do
13
+ xml.wsdl(:GetPresets) do
14
+ xml.wsdl :ProfileToken, p_token
15
+ end
16
+ end
17
+ send_message message do |success, result|
18
+ if success
19
+ xml_doc = Nokogiri::XML(result[:content])
20
+ presets = []
21
+ xml_doc.xpath('//tptz:Preset').each do |node|
22
+ preset = {
23
+ name: value(node, 'tt:Name'),
24
+ token: attribute(node, "token")
25
+ }
26
+ preset = get_speed node, "PTZPosition", preset
27
+ presets << preset
28
+ end
29
+ callback cb, success, presets
30
+ else
31
+ callback cb, success, result
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class GotoHomePosition < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx",//[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # speed: { //optional
10
+ # pan_tilt: { //optional
11
+ # x: 1, //[float]
12
+ # y: 2, //[float]
13
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
14
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
15
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
16
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
17
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
18
+ # },
19
+ # zoom: { //optional
20
+ # x: 1,//[float]
21
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
22
+ # }
23
+ # }
24
+ # }
25
+ def run options, cb
26
+ message = create_ptz_onvif_message
27
+ message.body = ->(xml) do
28
+ xml.wsdl(:GotoHomePosition) do
29
+ xml.wsdl :ProfileToken, options[:profile_token]
30
+ unless options[:speed].nil?
31
+ xml.wsdl(:Speed) do
32
+ unless options[:speed][:pan_tilt].nil?
33
+ xml.wsdl :PanTilt, {
34
+ "x" => options[:speed][:pan_tilt][:x],
35
+ "y" => options[:speed][:pan_tilt][:y],
36
+ "space" => options[:speed][:pan_tilt][:space]
37
+ }
38
+ end
39
+ unless options[:speed][:zoom].nil?
40
+ xml.wsdl :Zoom, {
41
+ "x" => options[:speed][:zoom][:x],
42
+ "space" => options[:speed][:zoom][:space]
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ send_message message do |success, result|
50
+ callback cb, success, result
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class GotoPreset < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx",//[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # preset_token: "xxxxxx", //[ReferenceToken] A requested preset token.
10
+ # speed: { //optional
11
+ # pan_tilt: { //optional
12
+ # x: 1, //[float]
13
+ # y: 2, //[float]
14
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
15
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
16
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
17
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
18
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
19
+ # },
20
+ # zoom: { //optional
21
+ # x: 1,//[float]
22
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
23
+ # }
24
+ # }
25
+ # }
26
+ def run options, cb
27
+ message = create_ptz_onvif_message
28
+ message.body = ->(xml) do
29
+ xml.wsdl(:GotoPreset) do
30
+ xml.wsdl :ProfileToken, options[:profile_token]
31
+ xml.wsdl :PresetToken, options[:preset_token]
32
+ unless options[:speed].nil?
33
+ xml.wsdl(:Speed) do
34
+ unless options[:speed][:pan_tilt].nil?
35
+ xml.wsdl :PanTilt, {
36
+ "x" => options[:speed][:pan_tilt][:x],
37
+ "y" => options[:speed][:pan_tilt][:y],
38
+ "space" => options[:speed][:pan_tilt][:space]
39
+ }
40
+ end
41
+ unless options[:speed][:zoom].nil?
42
+ xml.wsdl :Zoom, {
43
+ "x" => options[:speed][:zoom][:x],
44
+ "space" => options[:speed][:zoom][:space]
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ send_message message do |success, result|
52
+ callback cb, success, result
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,85 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class GotoHomePosition < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx",//[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # translation: {
10
+ # pan_tilt: { //optional
11
+ # x: 1, //[float]
12
+ # y: 2, //[float]
13
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
14
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
15
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
16
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
17
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
18
+ # },
19
+ # zoom: { //optional
20
+ # x: 1,//[float]
21
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
22
+ # }
23
+ # }
24
+ # speed: { //optional
25
+ # pan_tilt: { //optional
26
+ # x: 1, //[float]
27
+ # y: 2, //[float]
28
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace", //[anyURI]
29
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
30
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
31
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
32
+ # // http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
33
+ # },
34
+ # zoom: { //optional
35
+ # x: 1,//[float]
36
+ # space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace",//[anyURI]
37
+ # }
38
+ # }
39
+ # }
40
+ def run options, cb
41
+ message = create_ptz_onvif_message
42
+ message.body = ->(xml) do
43
+ xml.wsdl(:GotoHomePosition) do
44
+ xml.wsdl :ProfileToken, options[:profile_token]
45
+ xml.wsdl(:Translation) do
46
+ unless options[:translation][:pan_tilt].nil?
47
+ xml.wsdl :PanTilt, {
48
+ "x" => options[:translation][:pan_tilt][:x],
49
+ "y" => options[:translation][:pan_tilt][:y],
50
+ "space" => options[:translation][:pan_tilt][:space]
51
+ }
52
+ end
53
+ unless options[:translation][:zoom].nil?
54
+ xml.wsdl :Zoom, {
55
+ "x" => options[:translation][:zoom][:x],
56
+ "space" => options[:translation][:zoom][:space]
57
+ }
58
+ end
59
+ end
60
+ unless options[:speed].nil?
61
+ xml.wsdl(:Speed) do
62
+ unless options[:speed][:pan_tilt].nil?
63
+ xml.wsdl :PanTilt, {
64
+ "x" => options[:speed][:pan_tilt][:x],
65
+ "y" => options[:speed][:pan_tilt][:y],
66
+ "space" => options[:speed][:pan_tilt][:space]
67
+ }
68
+ end
69
+ unless options[:speed][:zoom].nil?
70
+ xml.wsdl :Zoom, {
71
+ "x" => options[:speed][:zoom][:x],
72
+ "space" => options[:speed][:zoom][:space]
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ send_message message do |success, result|
80
+ callback cb, success, result
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class RemovePreset < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx", //[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # preset_token: "xxxxxxx" //[ReferenceToken] A requested preset token.
10
+ # }
11
+ def run options ,cb
12
+ message = create_ptz_onvif_message
13
+ message.body = ->(xml) do
14
+ xml.wsdl(:RemovePreset) do
15
+ xml.wsdl :ProfileToken, options[:profile_token]
16
+ xml.wsdl :PresetToken, options[:preset_token]
17
+ end
18
+ end
19
+ send_message message do |success, result|
20
+ callback cb, success, result
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../action'
2
+
3
+ module ONVIF
4
+ module PtzAction
5
+ class SetPreset < Action
6
+ # options 的结构
7
+ # {
8
+ # profile_token: "xxxxxxx", //[ReferenceToken] A reference to the MediaProfile where the operation should take place.
9
+ # preset_name: "xxxxx", // optional; [string] A requested preset name.
10
+ # preset_token: "xxxxxxx" //optional; [ReferenceToken] A requested preset token.
11
+ # }
12
+ def run options ,cb
13
+ message = create_ptz_onvif_message
14
+ message.body = ->(xml) do
15
+ xml.wsdl(:SetPreset) do
16
+ xml.wsdl :ProfileToken, options[:profile_token]
17
+ xml.wsdl :PresetName, options[:preset_name] unless options[:preset_name].nil?
18
+ xml.wsdl :PresetToken, options[:preset_token] unless options[:preset_token].nil?
19
+ end
20
+ end
21
+ send_message message do |success, result|
22
+ if success
23
+ xml_doc = Nokogiri::XML(result[:content])
24
+ preset_token = value(xml_doc, '//tptz:PresetToken')
25
+ callback cb, success, preset_token
26
+ else
27
+ callback cb, success, result
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ruby_onvif_client'
3
- s.version = '0.0.7'
4
- s.date = '2013-07-08'
3
+ s.version = '0.0.8'
4
+ s.date = '2013-07-15'
5
5
  s.summary = "Ruby实现的onvif客户端"
6
6
  s.description = "使用ruby实现的简单的onvif客户端"
7
7
  s.authors = ["jimxl"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_onvif_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - jimxl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-08 00:00:00.000000000 Z
11
+ date: 2013-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em_ws_discovery
@@ -86,9 +86,20 @@ files:
86
86
  - lib/ruby_onvif_client/client.rb
87
87
  - lib/ruby_onvif_client/message.rb
88
88
  - lib/ruby_onvif_client/path.rb
89
+ - lib/ruby_onvif_client/ptz/goto_home_position.rb
90
+ - lib/ruby_onvif_client/ptz/remove_preset.rb
91
+ - lib/ruby_onvif_client/ptz/set_preset.rb
89
92
  - lib/ruby_onvif_client/ptz/get_nodes.rb
93
+ - lib/ruby_onvif_client/ptz/goto_preset.rb
94
+ - lib/ruby_onvif_client/ptz/get_configuration.rb
90
95
  - lib/ruby_onvif_client/ptz/stop.rb
96
+ - lib/ruby_onvif_client/ptz/continuous_move.rb
97
+ - lib/ruby_onvif_client/ptz/relative_move.rb
98
+ - lib/ruby_onvif_client/ptz/get_configurations.rb
99
+ - lib/ruby_onvif_client/ptz/get_presets.rb
100
+ - lib/ruby_onvif_client/ptz/get_configuration_options.rb
91
101
  - lib/ruby_onvif_client/ptz/get_node.rb
102
+ - lib/ruby_onvif_client/ptz/absolute_move.rb
92
103
  - lib/ruby_onvif_client/device_management.rb
93
104
  - lib/ruby_onvif_client/media.rb
94
105
  - lib/ruby_onvif_client/media/get_video_encoder_configuration.rb
@@ -104,6 +115,7 @@ files:
104
115
  - lib/ruby_onvif_client/media/set_video_encoder_configuration.rb
105
116
  - lib/ruby_onvif_client/media/get_video_encoder_configurations.rb
106
117
  - lib/ruby_onvif_client/media/get_stream_uri.rb
118
+ - lib/ruby_onvif_client/helper/ptz_common.rb
107
119
  - lib/ruby_onvif_client/action.rb
108
120
  - lib/ruby_onvif_client/ptz.rb
109
121
  - lib/ruby_onvif_client/device_discovery.rb