在使用 Elixir 进行 IPdome 控制时,可以使用 ExOnvif 库。
ExOnvif官方文档中未给停止移动调用命令,自己按照onvif协议 Onvif协议 扩展的此项功能;
停止移动 Stop
在Onvif协议中,用于停止云台移动的操作为Stop。当需要终止云台正在进行的平移(Pan)、倾斜(Tilt)或变焦(Zoom)动作时,向设备发送一个Stop命令,这个命令会使得云台立即停止所有指定类型的运动。
在上面的Onvif协议中,可以看出,Stop命令需要三个参数;
- ProfileToken字段用于指定要停止运动的PTZ的标识符文件。
- PanTilt和Zoom元素是布尔值,用来指示是否停止平移/倾斜运动和变焦运动。如果设置为true,则相应类型的运动会被停止。如果为false,则不采取任何操作。
完整的文件:
defmodule MvOnvif.Action do
use GenServer
@moduledoc """
自定义的Onvif的部分协议
获取当前状态(exonvif)
absolute move调用摄像头到指定位置,
continuous move摄像头连续移动
调用指定预置位
停止运动
"""
import ExOnvif.Utils.XmlBuilder
import SweetXml
alias ExOnvif.Device
alias ExOnvif.Media2
import ExOnvif.Utils.ApiClient, only: [ptz_request: 4]
# 初始化设备
defp get_device(uri) when not is_nil(uri) do
%{host: host, userinfo: userinfo} = URI.parse(uri)
[user, pw] = String.split(userinfo, ":")
Device.new("http://" <> host, user, pw);
end
defp get_device(uri) do
:error
end
# 获取ProfileToken标识符
defp get_main_stream_profile_token(device) do
profiles = Media2.get_profiles(device)
case profiles do
{:ok, list} -> {:ok, hd(list).reference_token}
_ -> "something went wrong"
end
end
# 生产Stop xml 命令,停止pt运动,停止zoom变焦
defp mv_stop(device, profile_token) do
body = element("tptz:Stop", [element("tptz:ProfileToken", profile_token),
element("tptz:PanTilt", true),
element("tptz:Zoom", true)
])
ptz_request(device, "Stop", body, fn resp -> :ok end )
end
# 摄像头停止移动 外部调用
def stop_(uri) do
with {:ok, device} <- get_device(uri),
{:ok, profile_token} <- get_main_stream_profile_token(device)
do
mv_stop(device, profile_token)
end
end
end
标准的Stop命令的xml文件
<SOAP-ENV:Body>
<wsdl:Stop>
<wsdl:ProfileToken>Profile_1</wsdl:ProfileToken>
<!-- 可选:停止所有运动或指定运动 -->
<wsdl:PanTilt>true</wsdl:PanTilt>
<wsdl:Zoom>true</wsdl:Zoom>
</wsdl:Stop>
</SOAP-ENV:Body>