You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
8.5 KiB
337 lines
8.5 KiB
namespace JiLinApp.Docking.Ptz;
|
|
|
|
/// <summary>
|
|
/// dot.NET Implementation of Pelco P Protocol
|
|
/// </summary>
|
|
public class PelcoP
|
|
{
|
|
private const byte STX = 0xA0;
|
|
private const byte ETX = 0xAF;
|
|
|
|
#region Pan and Tilt Commands
|
|
|
|
#region Data1
|
|
|
|
private const byte FocusFar = 0x01;
|
|
private const byte FocusNear = 0x02;
|
|
private const byte IrisOpen = 0x04;
|
|
private const byte IrisClose = 0x08;
|
|
private const byte CameraOnOff = 0x10;
|
|
private const byte AutoscanOn = 0x20;
|
|
private const byte CameraOn = 0x40;
|
|
|
|
#endregion Data1
|
|
|
|
#region Data2
|
|
|
|
private const byte PanRight = 0x02;
|
|
private const byte PanLeft = 0x04;
|
|
private const byte TiltUp = 0x08;
|
|
private const byte TiltDown = 0x10;
|
|
private const byte ZoomTele = 0x20;
|
|
private const byte ZoomWide = 0x40;
|
|
|
|
#endregion Data2
|
|
|
|
#region Data3
|
|
|
|
public static byte PanSpeedMin = 0x00;
|
|
public static byte PanSpeedMax = 0x3F;
|
|
|
|
#endregion Data3
|
|
|
|
#region Data4
|
|
|
|
public static byte TiltSpeedMin = 0x00;
|
|
public static byte TiltSpeedMax = 0x3F;
|
|
|
|
#endregion Data4
|
|
|
|
#endregion Pan and Tilt Commands
|
|
|
|
#region Enums
|
|
|
|
public enum PatternAction
|
|
{
|
|
Start,
|
|
Stop,
|
|
Run
|
|
}
|
|
|
|
public enum Action
|
|
{
|
|
Start,
|
|
Stop
|
|
}
|
|
|
|
public enum LensSpeed
|
|
{
|
|
Low = 0x00,
|
|
Medium = 0x01,
|
|
High = 0x02,
|
|
Turbo = 0x03
|
|
}
|
|
|
|
public enum Pan
|
|
{
|
|
Left = PanLeft,
|
|
Right = PanRight
|
|
}
|
|
|
|
public enum Tilt
|
|
{
|
|
Up = TiltUp,
|
|
Down = TiltDown
|
|
}
|
|
|
|
public enum Iris
|
|
{
|
|
Open = IrisOpen,
|
|
Close = IrisClose
|
|
}
|
|
|
|
public enum Zoom
|
|
{
|
|
Wide = ZoomWide,
|
|
Tele = ZoomTele
|
|
}
|
|
|
|
public enum Switch
|
|
{
|
|
On,
|
|
Off
|
|
}
|
|
|
|
public enum Focus
|
|
{
|
|
Near = FocusNear,
|
|
Far = FocusFar
|
|
}
|
|
|
|
public enum PresetAction
|
|
{
|
|
Set = 0x03,
|
|
Clear = 0x05,
|
|
Goto = 0x07
|
|
}
|
|
|
|
#endregion Enums
|
|
|
|
#region Extended Command Set
|
|
|
|
public static byte[] Preset(uint deviceAddress, PresetAction action, byte presetId)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, presetId);
|
|
}
|
|
|
|
public static byte[] Flip(uint deviceAddress)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x07, 0x00, 0x21);
|
|
}
|
|
|
|
public static byte[] ZeroPanPosition(uint deviceAddress)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x07, 0x00, 0x22);
|
|
}
|
|
|
|
public static byte[] AutoScan(uint deviceAddress, Action action)
|
|
{
|
|
byte m_action;
|
|
if (action == Action.Start)
|
|
m_action = 0x09;
|
|
else
|
|
m_action = 0x0B;
|
|
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] RemoteReset(uint deviceAddress)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x0F, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] Zone(uint deviceAddress, byte zone, Action action)
|
|
{
|
|
if (zone < 0x01 & zone > 0x08)
|
|
throw new Exception("Zone value should be between 0x01 and 0x08 include");
|
|
byte m_action;
|
|
if (action == Action.Start)
|
|
m_action = 0x11;
|
|
else
|
|
m_action = 0x13;
|
|
|
|
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, zone);
|
|
}
|
|
|
|
public static byte[] WriteToScreen(uint deviceAddress, string text)
|
|
{
|
|
if (text.Length > 40)
|
|
text = text.Remove(40, text.Length - 40);
|
|
System.Text.Encoding encoding = System.Text.Encoding.ASCII;
|
|
byte[] m_bytes = new byte[encoding.GetByteCount(text) * 8];
|
|
int i = 0;
|
|
byte m_scrPosition;
|
|
byte m_ASCIIchr;
|
|
|
|
foreach (char ch in text)
|
|
{
|
|
m_scrPosition = Convert.ToByte(i / 8);
|
|
m_ASCIIchr = Convert.ToByte(ch);
|
|
Array.Copy(
|
|
Message.GetMessage(deviceAddress, 0x00, 0x15, m_scrPosition, m_ASCIIchr),
|
|
0,
|
|
m_bytes,
|
|
i,
|
|
8
|
|
);
|
|
i += 8;
|
|
}
|
|
|
|
return m_bytes;
|
|
}
|
|
|
|
public static byte[] ClearScreen(uint deviceAddress)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x17, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] AlarmAcknowledge(uint deviceAddress, uint alarmID)
|
|
{
|
|
if (alarmID < 1 & alarmID > 8)
|
|
throw new Exception("Only 8 alarms allowed for Pelco P implementation");
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x19, 0x00, Convert.ToByte(alarmID));
|
|
}
|
|
|
|
public static byte[] ZoneScan(uint deviceAddress, Action action)
|
|
{
|
|
byte m_action;
|
|
if (action == Action.Start)
|
|
m_action = 0x1B;
|
|
else
|
|
m_action = 0x1D;
|
|
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] Pattern(uint deviceAddress, PatternAction action)
|
|
{
|
|
byte m_action = action switch
|
|
{
|
|
PatternAction.Start => 0x1F,
|
|
PatternAction.Stop => 0x21,
|
|
PatternAction.Run => 0x23,
|
|
_ => 0x23,
|
|
};
|
|
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] SetZoomLensSpeed(uint deviceAddress, LensSpeed speed)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x25, 0x00, (byte)speed);
|
|
}
|
|
|
|
public static byte[] SetFocusLensSpeed(uint deviceAddress, LensSpeed speed)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x27, 0x00, (byte)speed);
|
|
}
|
|
|
|
#endregion Extended Command Set
|
|
|
|
#region Base Command Set
|
|
|
|
public static byte[] CameraSwitch(uint deviceAddress, Switch action)
|
|
{
|
|
byte m_action = CameraOnOff;
|
|
if (action == Switch.On)
|
|
m_action += CameraOnOff; //Maybe wrong !!!
|
|
return Message.GetMessage(deviceAddress, m_action, 0x00, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] CameraIrisSwitch(uint deviceAddress, Iris action)
|
|
{
|
|
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] CameraFocus(uint deviceAddress, Focus action)
|
|
{
|
|
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] CameraZoom(uint deviceAddress, Zoom action)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, 0x00);
|
|
}
|
|
|
|
public static byte[] CameraTilt(uint deviceAddress, Tilt action, uint speed)
|
|
{
|
|
if (speed < TiltSpeedMin)
|
|
speed = TiltSpeedMin;
|
|
if (speed > TiltSpeedMax)
|
|
speed = TiltSpeedMax;
|
|
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, (byte)speed);
|
|
}
|
|
|
|
public static byte[] CameraPan(uint deviceAddress, Pan action, uint speed)
|
|
{
|
|
if (speed < PanSpeedMin)
|
|
speed = PanSpeedMin;
|
|
if (speed > PanSpeedMax)
|
|
speed = PanSpeedMax;
|
|
return Message.GetMessage(deviceAddress, 0x00, (byte)action, (byte)speed, 0x00);
|
|
}
|
|
|
|
public static byte[] CameraPanTilt(
|
|
uint deviceAddress,
|
|
Pan panAction,
|
|
uint panSpeed,
|
|
Tilt tiltAction,
|
|
uint tiltSpeed
|
|
)
|
|
{
|
|
byte[] m_tiltMessage = CameraTilt(deviceAddress, tiltAction, tiltSpeed);
|
|
byte[] m_panMessage = CameraPan(deviceAddress, panAction, panSpeed);
|
|
byte[] m_bytes = Message.GetMessage(
|
|
deviceAddress,
|
|
0x00,
|
|
(byte)(m_tiltMessage[3] + m_panMessage[3]),
|
|
m_panMessage[4],
|
|
m_tiltMessage[5]
|
|
);
|
|
return m_bytes;
|
|
}
|
|
|
|
public static byte[] CameraStop(uint deviceAddress)
|
|
{
|
|
return Message.GetMessage(deviceAddress, 0x00, 0x00, 0x00, 0x00);
|
|
}
|
|
|
|
#endregion Base Command Set
|
|
|
|
public struct Message
|
|
{
|
|
public static byte Address;
|
|
public static byte CheckSum;
|
|
|
|
public static byte Data1,
|
|
Data2,
|
|
Data3,
|
|
Data4;
|
|
|
|
public static byte[] GetMessage(
|
|
uint address,
|
|
byte data1,
|
|
byte data2,
|
|
byte data3,
|
|
byte data4
|
|
)
|
|
{
|
|
if (address < 0 & address > 32)
|
|
throw new Exception("Protocol Pelco P support 32 devices only");
|
|
Address = byte.Parse((address - 1).ToString());
|
|
Data1 = data1;
|
|
Data2 = data2;
|
|
Data3 = data3;
|
|
Data4 = data4;
|
|
CheckSum = (byte)(STX ^ Address ^ Data1 ^ Data2 ^ Data3 ^ Data4 ^ ETX);
|
|
return new byte[] { STX, Address, Data1, Data2, Data3, Data4, ETX, CheckSum };
|
|
}
|
|
}
|
|
}
|