Reputation: 563
I have 2 Milesight PTZ cameras and 5 Hikvision PTZ cameras. I use OnVif commands to move the camera (left, right, up, down). I wrote a code in the Elixir to send these OnVif commands to the cameras.
My Code
def request(%{"auth" => auth, "url" => base_url}, service, operation, parameters) do
url = "http://{camera-domain}:87362/onvif/ptz_service
namespace = shorten_service(service)
[username, password] = auth |> String.split(":")
onvif_request = gen_onvif_request(namespace, operation, parameters) |> IO.inspect
headers = [
{"Content-Type", "application/soap+xml; charset=utf-8"},
{"SOAPAction", "http://www.w3.org/2003/05/soap-envelope"}
]
case Evercam.HTTP.post(url, headers, onvif_request, digest_auth: {username, password}) do
{:ok, %Finch.Response{status: 404, body: body}} ->
{:error, 404, %{body: body}}
{:ok, response} ->
{xml, _rest} = response.body |> to_charlist |> :xmerl_scan.string()
soap_ns =
case elem(xml, 3) do
{ns, _} -> ns
_ -> "env"
end
case response.status == 200 do
true ->
case "/#{soap_ns}:Envelope/#{soap_ns}:Body/#{namespace}:#{operation}Response"
|> to_charlist
|> :xmerl_xpath.string(xml) do
[] ->
{:error, 405,
"/#{soap_ns}:Envelope/#{soap_ns}:Body"
|> to_charlist
|> :xmerl_xpath.string(xml)
|> parse_elements}
xpath_string ->
{:ok, parse_elements(xpath_string)}
end
false ->
"/html"
|> to_charlist
|> :xmerl_xpath.string(xml)
|> parse_content(response, soap_ns, XML)
end
{:error, error} ->
{:error, 500, Exception.message(error)}
end
end
OnVif Request Body
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis=200401-wss-wssecurity-utility-1.0.xsd">
<SOAP-ENV:Body>
<tptz:ContinuousMove xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl">
<tptz:ProfileToken>Profile_1</tptz:ProfileToken>
<tptz:Velocity>
<!-- Move Left -->
<!-- <PanTilt x="-0.4" y="0.0" xmlns="http://www.onvif.org/ver10/schema"/> -->
<!-- Move Right -->
<PanTilt x="0.4" y="0.0" xmlns="http://www.onvif.org/ver10/schema"/>
</tptz:Velocity>
</tptz:ContinuousMove>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This code works for Hikvision cameras but for Milesight cameras it gives following error.
{:ok,
%Finch.Response{
status: 401,
body: "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n<BODY><H1>401 Unauthorized</H1>\nYour client does not have permission to get URL from this server.\n</BODY></HTML>\n",
headers: [
{"date", "Tue, 19 Mar 2024 10:04:03 GMT"},
{"server", "WebServer"},
{"connection", "close"},
{"www-authenticate",
"Digest qop=\"auth\", realm=\"IPNC\", nonce=\"a807934f7c0d0d3f689hf689nbfe21ba\", stale=\"FALSE\""},
{"content-length", "164"},
{"content-type", "text/html; charset=UTF-8"}
],
trailers: []
}}
When I use Postman to send OnVif requests with the same parameters and request body it works.
Upvotes: 0
Views: 111