namespace JiLinApp.Docking.Ptz; /// /// dot.NET Implementation of Pelco P Protocol /// 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 }; } } }