如何使用 Onvif 协议切换继电器输出的状态

How to switch the state of a relay-output using the Onvif protocol

我目前正在尝试切换多个测试相机(均符合 Onvif 标准)的继电器输出状态。当试图检索海康威视 PTZ 摄像机的继电器输出列表时,混乱就开始了。我可以成功获得继电器输出(它只有 1 个)并要求它的 'RelayLogicalState' 可以打开或关闭。

我使用 'SetRelayOutputState' 来切换继电器输出,它的参数是要切换的继电器输出的标记和 'RelayLogicalState'。由于只有 1 个继电器输出,我只能发送该令牌,因此 'RelayLogicalState' 是 2 个项目(活动或非活动)的枚举,这里没有太多错误。我可以切换继电器输出的状态,但是当再次调用 'GetrelayOutputs' 以检查其状态时,此函数将始终将输入设置为 'inactive'.

对于 BOSCH,我可以再次检索继电器输出,只有 1 个存在,但调用 'SetRelayOutputState' 对调用时的 2 个 'RelayLogicalState' 中的任何一个都没有任何作用。

供参考:http://www.onvif.org/ver10/deviceio.wsdl

两台相机都安装了最新的固件,根据 Onvif 设备管理器,它们都使用 Onvif 2.0 版。

    private void OutputLowButton_Click(object sender, EventArgs e)
    {
        if (relayOutputs != null)
        {
            //only 1 present so we take the first for this example
            var output = relayOutputs.First();
            execute(() => IOClient.SetRelayOutputState(output.token, RelayLogicalState.inactive));
        }
    }
    private void OutputHighButton_Click(object sender, EventArgs e)
    {
        if (relayOutputs != null)
        {
            //only 1 present so we take the first for this example
            var output = relayOutputs.First();
            execute(() => IOClient.SetRelayOutputState(output.token, RelayLogicalState.active)); 
        }
    }
    private void OutputStateButton_Click(object sender, EventArgs e)
    {
        //only 1 present so we take the first for this example
        var relayOutputs = execute(() => IOClient.GetRelayOutputs());
        if(relayOutputs != null)
            MessageBox.Show(relayOutputs.First().Properties.IdleState.ToString());
    }

编辑

最终我按照以下方式让它工作:

 relayOutput.Properties.Mode = Onv_Device_Management.RelayMode.Bistable;
            relayOutput.Properties.IdleState = Onv_Device_Management.RelayIdleState.open;
            TryCatch(() => deviceClient.SetRelayOutputSettingsAsync(relayOutput.token, relayOutput.Properties));
            TryCatch(() => deviceClient.SetRelayOutputState(relayOutput.token, Onv_Device_Management.RelayLogicalState.active));

我也遇到了一些问题。还有一个 onvif 函数叫做 SetRelayOutputSettings。你有几个设置:

空闲状态
打开/关闭
延迟时间
当模式为 "monostable" 时,它将返回空闲状态
模式
双稳态 - 你必须自己处理状态变化
单稳态 - 设置状态后,它将在 "delayTime"

后返回空闲状态

当然你也要把Token送到那里。仍然要解决问题,我必须按此顺序调用函数(伪代码我不是 c#):

void SetState(string token, bool bOpen) // true if high, false if low
{
   SetRelayOutputSettings(token, bOpen, "bistable", 20);
   SetRelayOutputState(token, "active");
   SetRelayOutputState(token, "inactive");
}

希望对你有所帮助。