Z
8 months ago
commit
507f5b408d
44 changed files with 30891 additions and 0 deletions
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
#EGSave-Specific ignores |
||||
SaveData/ |
||||
|
||||
#Csharp Build |
||||
bin/ |
||||
|
||||
#CSharp Cache |
||||
obj/ |
||||
|
||||
#VS cache |
||||
.vs/ |
||||
.vscode/ |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using Newtonsoft.Json; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Net; |
||||
using System.Net.Sockets; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class AlgorithmTCP |
||||
{ |
||||
static Socket socket_commu; |
||||
public static string Connect(string picPath, string targetname) |
||||
{ |
||||
//IP地址192.168.1.32 |
||||
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
||||
IPAddress serverAddress = IPAddress.Parse("192.168.10.104"); |
||||
int port = 20000; |
||||
client.Connect(new IPEndPoint(serverAddress, port)); |
||||
Console.WriteLine("连接成功"); |
||||
//发送图片地址和识别目标名字 |
||||
var json = new |
||||
{ |
||||
picadress = picPath, |
||||
targetname = targetname |
||||
}; |
||||
//将JSON数据对象序列化为字符串 |
||||
string jsonString = JsonConvert.SerializeObject(json); |
||||
//将JSON字符串转换为字节数组 |
||||
byte[] dataBytes = Encoding.UTF8.GetBytes(jsonString); |
||||
socket_commu.Send(dataBytes); |
||||
|
||||
|
||||
//等待算法识别结果 |
||||
//接收数据 |
||||
byte[] buffer = new byte[1024 * 1024]; |
||||
int bytesRead = socket_commu.Receive(buffer); |
||||
//将接收到的数据转换为字符串 |
||||
string result = Encoding.UTF8.GetString(buffer, 0, bytesRead); |
||||
return result; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,514 @@
@@ -0,0 +1,514 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Runtime.InteropServices; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using static Guidaoji.Camera.CHCNetSDK; |
||||
|
||||
namespace Guidaoji.Camera |
||||
{ |
||||
public class CHNetHelp |
||||
{ |
||||
private int counter = 0; |
||||
private static CHNetHelp _instance; |
||||
// 私有构造函数以防止外部实例化 |
||||
public CHNetHelp() { } |
||||
//海康辅助函数:add by lee start |
||||
private static uint iLastErr = 0; |
||||
private static Int32 m_lUserID = -1; |
||||
private static bool m_bInitSDK = false; |
||||
private static bool m_bRecord = false; |
||||
private static bool m_bTalk = false; |
||||
private static Int32 m_lRealHandle = -1;//m_lRealHandle |
||||
private static int lVoiceComHandle = -1; |
||||
private static string str; |
||||
//相机参数通过PtzGet()获得 |
||||
private static float WPanPos, WTiltPos, WZoomPos; |
||||
private static bool m_param_get_flag = false;//当获取成功后设置为true |
||||
private static int[] iChannelNum = new int[96]; |
||||
|
||||
// 公共静态方法用于获取类的实例 |
||||
public static CHNetHelp GetInstance() |
||||
{ |
||||
if (_instance == null) |
||||
{ |
||||
_instance = new CHNetHelp(); |
||||
} |
||||
return _instance; |
||||
} |
||||
|
||||
|
||||
//登录相关 |
||||
static CHCNetSDK.REALDATACALLBACK RealData = null; |
||||
static CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null; |
||||
public static CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg; |
||||
public static CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo; |
||||
public static CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo; |
||||
|
||||
public delegate void UpdateTextStatusCallback(string strLogStatus, IntPtr lpDeviceInfo); |
||||
|
||||
//云台相关 |
||||
private bool bAuto = false; |
||||
//private uint iLastErr = 0; |
||||
public static int PreSetNo = 0; |
||||
//public CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg; |
||||
public static CHCNetSDK.NET_DVR_PTZSCOPE m_struPtzCfg1; |
||||
public static CHCNetSDK.NET_DVR_PRESET_NAME[] m_struPreSetCfg = new CHCNetSDK.NET_DVR_PRESET_NAME[300]; |
||||
|
||||
public static void cbLoginCallBack(int lUserID, int dwResult, IntPtr lpDeviceInfo, IntPtr pUser) |
||||
{ |
||||
string strLoginCallBack = "登录设备,lUserID:" + lUserID + ",dwResult:" + dwResult; |
||||
|
||||
if (dwResult == 0) |
||||
{ |
||||
uint iErrCode = CHCNetSDK.NET_DVR_GetLastError(); |
||||
strLoginCallBack = strLoginCallBack + ",错误号:" + iErrCode; |
||||
} |
||||
} |
||||
|
||||
//初始化并用固定IP的登录 |
||||
public static bool CameraInit(string sIP, string sPassword) |
||||
{ |
||||
PrintInfo("登录....."); |
||||
for (int i = 0; i < 64; i++) |
||||
{ |
||||
iChannelNum[i] = i; |
||||
} |
||||
m_bInitSDK = CHCNetSDK.NET_DVR_Init(); |
||||
if (m_bInitSDK == false) |
||||
{ |
||||
//MessageBox.Show("NET_DVR_Init error!"); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
//保存SDK日志 To save the SDK log |
||||
CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true); |
||||
} |
||||
//MessageBox.Show("camera Init m_bInitSDK=="+ m_bInitSDK); |
||||
|
||||
//登录 |
||||
// 固定的设备IP地址192.168.10.102 |
||||
string fixedIP = sIP; |
||||
byte[] byIP = System.Text.Encoding.Default.GetBytes(fixedIP); |
||||
struLogInfo.sDeviceAddress = new byte[129]; |
||||
byIP.CopyTo(struLogInfo.sDeviceAddress, 0); |
||||
|
||||
//设备用户名 |
||||
string fixedName = "admin"; |
||||
byte[] byUserName = System.Text.Encoding.Default.GetBytes(fixedName); |
||||
struLogInfo.sUserName = new byte[64]; |
||||
byUserName.CopyTo(struLogInfo.sUserName, 0); |
||||
|
||||
//设备密码ch123456 |
||||
string fixedPassword = sPassword; |
||||
byte[] byPassword = System.Text.Encoding.Default.GetBytes(fixedPassword); |
||||
struLogInfo.sPassword = new byte[64]; |
||||
byPassword.CopyTo(struLogInfo.sPassword, 0); |
||||
|
||||
struLogInfo.wPort = ushort.Parse("8000");//设备服务端口号 |
||||
if (LoginCallBack == null) |
||||
{ |
||||
LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK(cbLoginCallBack);//注册回调函数 |
||||
} |
||||
struLogInfo.cbLoginResult = LoginCallBack; |
||||
struLogInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是 |
||||
DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40(); |
||||
|
||||
//登录设备 Login the device |
||||
m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo); |
||||
if (m_lUserID < 0) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败,输出错误号 |
||||
//MessageBox.Show(str); |
||||
} |
||||
else |
||||
{ |
||||
//登录成功 |
||||
//MessageBox.Show("Login Success!"); |
||||
} |
||||
PrintInfo("登录结束....."); |
||||
return true; |
||||
} |
||||
|
||||
//显示视频画面 |
||||
//public static void StartStopLiveView(System.Windows.Forms.Panel panel, string channel, bool isStreamID = false, string streamID = "") |
||||
//{ |
||||
// if (m_lUserID < 0) |
||||
// { |
||||
// MessageBox.Show("Please login to the device first."); |
||||
// return; |
||||
// } |
||||
|
||||
// if (m_lRealHandle < 0) |
||||
// { |
||||
// CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); |
||||
// lpPreviewInfo.hPlayWnd = panel.Handle; // 预览窗口 |
||||
// lpPreviewInfo.lChannel = Int16.Parse(channel); // 预览的设备通道 |
||||
|
||||
// lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 |
||||
// lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP |
||||
// lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流 |
||||
// lpPreviewInfo.dwDisplayBufNum = 1; //播放库播放缓冲区最大缓冲帧数 |
||||
// lpPreviewInfo.byProtoType = 0; |
||||
// lpPreviewInfo.byPreviewMode = 0; |
||||
|
||||
// if (isStreamID) |
||||
// { |
||||
// lpPreviewInfo.lChannel = -1; |
||||
// byte[] byStreamID = System.Text.Encoding.Default.GetBytes(streamID); |
||||
// lpPreviewInfo.byStreamID = new byte[32]; |
||||
// byStreamID.CopyTo(lpPreviewInfo.byStreamID, 0); |
||||
// } |
||||
|
||||
// // ... 实时流回调函数和预览逻辑 ... |
||||
// if (RealData == null) |
||||
// { |
||||
// RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数 |
||||
// } |
||||
|
||||
// m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, RealData, IntPtr.Zero); |
||||
// if (m_lRealHandle < 0) |
||||
// { |
||||
// // ... 处理预览失败逻辑 ... |
||||
// iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
// str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号 |
||||
// MessageBox.Show(str); |
||||
// return; |
||||
// } |
||||
// } |
||||
// else |
||||
// { |
||||
// // 停止预览 |
||||
// if (CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle)) |
||||
// { |
||||
// m_lRealHandle = -1; |
||||
// } |
||||
// else |
||||
// { |
||||
// // ... 处理停止预览失败逻辑 ... |
||||
// } |
||||
// } |
||||
//} |
||||
|
||||
//你可以定义一个方法 RealDataCallBack,它将在有新的视频数据到达时被调用。 |
||||
public static void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser) |
||||
{ |
||||
if (dwBufSize > 0) |
||||
{ |
||||
byte[] sData = new byte[dwBufSize]; |
||||
Marshal.Copy(pBuffer, sData, 0, (Int32)dwBufSize); |
||||
|
||||
string str = "实时流数据.ps"; |
||||
FileStream fs = new FileStream(str, FileMode.Create); |
||||
int iLen = (int)dwBufSize; |
||||
fs.Write(sData, 0, iLen); |
||||
fs.Close(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 抓拍并保存图片 |
||||
/// </summary> |
||||
/// <param name="iSelIndex">选择通道</param> |
||||
/// <param name="sFilePath">照片存放路径</param> |
||||
/// <returns></returns> |
||||
|
||||
public static bool JPEG(int iSelIndex, string sFilePath) |
||||
{ |
||||
PrintInfo("抓图开始....."); |
||||
int lChannel = iChannelNum[iSelIndex]; //通道号 Channel number |
||||
|
||||
CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA(); |
||||
lpJpegPara.wPicQuality = 0; //图像质量 Image quality |
||||
lpJpegPara.wPicSize = 0xff; //抓图分辨率 Picture size: 0xff-Auto(使用当前码流分辨率) |
||||
//抓图分辨率需要设备支持,更多取值请参考SDK文档 |
||||
|
||||
//JPEG抓图保存成文件 Capture a JPEG picture |
||||
//string sJpegPicFileName; |
||||
//sJpegPicFileName = "filetest.jpg";//图片保存路径和文件名 the path and file name to save |
||||
if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, lChannel, ref lpJpegPara, sFilePath)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_CaptureJPEGPicture failed, error code= " + iLastErr; |
||||
PrintInfo(str); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
str = "NET_DVR_CaptureJPEGPicture succ and the saved file is " + sFilePath; |
||||
PrintInfo(str); |
||||
} |
||||
|
||||
//JEPG抓图,数据保存在缓冲区中 Capture a JPEG picture and save in the buffer |
||||
uint iBuffSize = 400000; //缓冲区大小需要不小于一张图片数据的大小 The buffer size should not be less than the picture size |
||||
byte[] byJpegPicBuffer = new byte[iBuffSize]; |
||||
uint dwSizeReturned = 0; |
||||
|
||||
if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(m_lUserID, lChannel, ref lpJpegPara, byJpegPicBuffer, iBuffSize, ref dwSizeReturned)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_CaptureJPEGPicture_NEW failed, error code= " + iLastErr; |
||||
PrintInfo(str); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
//将缓冲区里的JPEG图片数据写入文件 save the data into a file |
||||
FileStream fs = new FileStream(sFilePath, FileMode.Create); |
||||
int iLen = (int)dwSizeReturned; |
||||
fs.Write(byJpegPicBuffer, 0, iLen); |
||||
fs.Close(); |
||||
|
||||
str = "NET_DVR_CaptureJPEGPicture_NEW succ and save the data in buffer to 'buffertest.jpg'."; |
||||
PrintInfo(str); |
||||
} |
||||
PrintInfo("抓图结束....."); |
||||
return true; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 设置摄像头移动 |
||||
/// </summary> |
||||
/// <param name="operationType">运动类型</param> |
||||
/// <param name="fP">水平移动</param> |
||||
/// <param name="fT">垂直移动</param> |
||||
/// <param name="fZ">焦距</param> |
||||
public static bool PtzSet(OperationType operationType, float fP, float fT, float fZ) |
||||
{ |
||||
PrintInfo("摄像头移动开始....."); |
||||
int flag = 1; |
||||
String str1, str2, str3; |
||||
|
||||
switch ((int)operationType)//操作类型 |
||||
{ |
||||
case 0: |
||||
flag = 0; |
||||
m_struPtzCfg.wAction = 1; |
||||
|
||||
str1 = Convert.ToString(fP * 10); |
||||
m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); |
||||
str2 = Convert.ToString(fT * 10); |
||||
m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); |
||||
str3 = Convert.ToString(fZ * 10); |
||||
m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16(str3, 16)); |
||||
break; |
||||
case 1: |
||||
flag = 0; |
||||
m_struPtzCfg.wAction = 2; |
||||
|
||||
str1 = Convert.ToString(fP * 10); |
||||
m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); |
||||
break; |
||||
case 2: |
||||
flag = 0; |
||||
m_struPtzCfg.wAction = 3; |
||||
|
||||
str2 = Convert.ToString(fT * 10); |
||||
m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); |
||||
break; |
||||
case 3: |
||||
flag = 0; |
||||
m_struPtzCfg.wAction = 4; |
||||
|
||||
str3 = Convert.ToString(fZ * 10); |
||||
m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16(str3, 16)); |
||||
break; |
||||
case 4: |
||||
flag = 0; |
||||
m_struPtzCfg.wAction = 5; |
||||
|
||||
str1 = Convert.ToString(fP * 10); |
||||
m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); |
||||
str2 = Convert.ToString(fT * 10); |
||||
m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); |
||||
break; |
||||
} |
||||
|
||||
bool bFlag = false; |
||||
if (flag == 0) |
||||
{ |
||||
Int32 nSize = Marshal.SizeOf(m_struPtzCfg); |
||||
IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); |
||||
Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); |
||||
|
||||
if (!CHCNetSDK.NET_DVR_SetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_SET_PTZPOS, 1, ptrPtzCfg, (UInt32)nSize)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_SetDVRConfig failed, error code= " + iLastErr; |
||||
//设置POS参数失败 |
||||
//MessageBox.Show(str); |
||||
} |
||||
else |
||||
{ |
||||
bFlag = true; |
||||
//MessageBox.Show("设置成功!"); |
||||
} |
||||
Marshal.FreeHGlobal(ptrPtzCfg); |
||||
} |
||||
PrintInfo("摄像头移动结束....."); |
||||
return bFlag; |
||||
} |
||||
|
||||
//获取相机焦距位置相关,P,T(ilt),zoom,m_param_get_flag 设置为true; |
||||
public static float[] PtzGet() |
||||
{ |
||||
float[] ret = { -1F, -1F, -1F }; |
||||
UInt32 dwReturn = 0; |
||||
Int32 nSize = Marshal.SizeOf(m_struPtzCfg); |
||||
IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); |
||||
Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); |
||||
//获取参数失败 |
||||
if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_PTZPOS, -1, ptrPtzCfg, (UInt32)nSize, ref dwReturn)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_GetDVRConfig failed, error code= " + iLastErr; |
||||
//MessageBox.Show(str); |
||||
return ret; |
||||
} |
||||
else |
||||
{ |
||||
m_struPtzCfg = (CHCNetSDK.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPtzCfg, typeof(CHCNetSDK.NET_DVR_PTZPOS)); |
||||
//成功获取显示ptz参数 |
||||
ushort wPanPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wPanPos, 16)); |
||||
ret[0] = WPanPos = wPanPos * 0.1f; |
||||
//textBoxPanPos.Text = Convert.ToString(WPanPos); |
||||
ushort wTiltPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wTiltPos, 16)); |
||||
ret[1] = WTiltPos = wTiltPos * 0.1f; |
||||
// textBoxTiltPos.Text = Convert.ToString(WTiltPos); |
||||
ushort wZoomPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wZoomPos, 16)); |
||||
ret[2] = WZoomPos = wZoomPos * 0.1f; |
||||
//textBoxZoomPos.Text = Convert.ToString(WZoomPos); |
||||
m_param_get_flag = true; |
||||
return ret; |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// 保存录像 |
||||
/// </summary> |
||||
/// <param name="bTranscribe">true:开始录像;false:停止录像</param> |
||||
/// <param name="iSelIndex">选择通道</param> |
||||
/// <param name="sViedoPath">视频保存路径</param> |
||||
public static bool SaveViedo(bool bTranscribe, int iSelIndex, string sViedoPath) |
||||
{ |
||||
PrintInfo(sViedoPath); |
||||
if (bTranscribe == true) |
||||
{ |
||||
PrintInfo("保存录像开始....."); |
||||
//强制I帧 Make one key frame |
||||
int lChannel = iChannelNum[iSelIndex]; //通道号 Channel number |
||||
CHCNetSDK.NET_DVR_MakeKeyFrame(m_lUserID, lChannel); |
||||
|
||||
//开始录像 Start recording |
||||
if (!CHCNetSDK.NET_DVR_SaveRealData(m_lRealHandle, sViedoPath)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_SaveRealData failed, error code= " + iLastErr; |
||||
PrintInfo(str); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
PrintInfo("NET_DVR_SaveRealData succ!"); |
||||
return true; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
PrintInfo("保存录像结束....."); |
||||
//停止录像 Stop recording |
||||
if (!CHCNetSDK.NET_DVR_StopSaveRealData(m_lRealHandle)) |
||||
{ |
||||
iLastErr = CHCNetSDK.NET_DVR_GetLastError(); |
||||
str = "NET_DVR_StopSaveRealData failed, error code= " + iLastErr; |
||||
PrintInfo(str); |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
str = "NET_DVR_StopSaveRealData succ and the saved file is " + sViedoPath; |
||||
PrintInfo(str); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 移动摄像头过程 |
||||
/// </summary> |
||||
/// <param name="operationType">控制类型</param> |
||||
/// <param name="fP">水平移动</param> |
||||
/// <param name="fT">垂直移动</param> |
||||
/// <param name="fZ">焦距</param> |
||||
/// <param name="iSelIndex">选择通道</param> |
||||
/// <param name="sFilePath">抓拍路径</param> |
||||
/// <returns></returns> |
||||
public static bool SetCameraProcess(OperationType operationType, float fP, float fT, float fZ, int iSelIndex, string sFilePath) |
||||
{ |
||||
//移动摄像头 |
||||
if (PtzSet(operationType, fP, fT, fZ)) |
||||
{ |
||||
while (true) |
||||
{ |
||||
float[] fCameraPose = PtzGet(); |
||||
if (fCameraPose[0] == fP && fCameraPose[1] == fT && fCameraPose[2] == fZ) |
||||
{ |
||||
break; |
||||
} |
||||
Thread.Sleep(100); |
||||
} |
||||
//拍照 |
||||
if (JPEG(iSelIndex, sFilePath)) |
||||
return true; |
||||
else return false; |
||||
} |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
public static void PrintInfo(string str) |
||||
{ |
||||
string Folder = Environment.CurrentDirectory + @"\Logs"; |
||||
string FileNamme = Environment.CurrentDirectory + @"\Logs\Info_" + DateTime.Now.ToString("yyyyMMdd") + ".txt"; |
||||
if (!System.IO.Directory.Exists(Folder)) |
||||
{ |
||||
System.IO.Directory.CreateDirectory(Folder); |
||||
} |
||||
using (TextWriter fw = new StreamWriter(FileNamme, true)) |
||||
{ |
||||
try |
||||
{ |
||||
FileInfo fi = new FileInfo(FileNamme); |
||||
fw.WriteLine(str); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
fw.WriteLine(ex.Message); |
||||
} |
||||
finally |
||||
{ |
||||
fw.Close(); |
||||
fw.Dispose(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 操作类型 |
||||
/// </summary> |
||||
public enum OperationType |
||||
{ |
||||
PTZ, //倾斜+焦距 |
||||
P, //水平运动 |
||||
T, //上下运动 |
||||
Z, //焦距 |
||||
PT //倾斜运动 |
||||
} |
||||
} |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
using Newtonsoft.Json; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Net.Http; |
||||
using System.Text; |
||||
using System.Text.Json; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class DAY |
||||
{ |
||||
public List<DayOfWeek> DayOfWeeks(PatrolClass item) |
||||
{ |
||||
DayOfWeek dayOfWeek; |
||||
List<DayOfWeek> dayOfWeeks = new List<DayOfWeek>(); |
||||
var runRule = item.RunRule; |
||||
string[] days = runRule.Split(','); |
||||
foreach (var day in days) |
||||
{ |
||||
switch (day) |
||||
{ |
||||
case "周一": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周一"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周二": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周二"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周三": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周三"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周四": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周四"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周五": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周五"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周六": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周六"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
case "周日": |
||||
dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "周日"); |
||||
dayOfWeeks.Add(dayOfWeek); |
||||
break; |
||||
} |
||||
} |
||||
return dayOfWeeks; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<OutputType>Exe</OutputType> |
||||
<TargetFramework>net8.0</TargetFramework> |
||||
<ImplicitUsings>enable</ImplicitUsings> |
||||
<Nullable>enable</Nullable> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> |
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.0" /> |
||||
<PackageReference Include="System.Management" Version="8.0.0" /> |
||||
<PackageReference Include="WebDav.Client" Version="2.8.0" /> |
||||
<PackageReference Include="Makaretu.Dns.Multicast" Version="0.27.0" /> |
||||
<PackageReference Include="System.IO.Ports" Version="8.0.0" /> |
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" /> |
||||
<PackageReference Include="Quartz" Version="3.8.1" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
# Visual Studio Version 17 |
||||
VisualStudioVersion = 17.5.002.0 |
||||
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmergencyPlatform", "EmergencyPlatform.csproj", "{91F53C8C-AE0B-41BA-988F-1127F4BD7381}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Any CPU = Debug|Any CPU |
||||
Release|Any CPU = Release|Any CPU |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{91F53C8C-AE0B-41BA-988F-1127F4BD7381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{91F53C8C-AE0B-41BA-988F-1127F4BD7381}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
{91F53C8C-AE0B-41BA-988F-1127F4BD7381}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{91F53C8C-AE0B-41BA-988F-1127F4BD7381}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
EndGlobalSection |
||||
GlobalSection(SolutionProperties) = preSolution |
||||
HideSolutionNode = FALSE |
||||
EndGlobalSection |
||||
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
SolutionGuid = {9BE62E3A-8CAB-4FD2-9CFA-4CDA65C4A110} |
||||
EndGlobalSection |
||||
EndGlobal |
@ -0,0 +1,216 @@
@@ -0,0 +1,216 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
#region Architecture & Module |
||||
public class EGArchitecture<T> : IArchitecture where T : EGArchitecture<T>, new() |
||||
{ |
||||
private static T Architecture; |
||||
public static IArchitecture Interface |
||||
{ |
||||
get |
||||
{ |
||||
if (Architecture == null) |
||||
{ |
||||
MakeSureArchitecture(); |
||||
} |
||||
return Architecture; |
||||
} |
||||
} |
||||
|
||||
private static void MakeSureArchitecture() |
||||
{ |
||||
if (Architecture == null) |
||||
{ |
||||
Architecture = new T(); |
||||
Architecture.Init(); |
||||
} |
||||
} |
||||
|
||||
protected virtual void Init() |
||||
{ |
||||
|
||||
} |
||||
|
||||
private IOCContainer ModuleContainer = new IOCContainer(); |
||||
|
||||
public void RegisterModule<TModule>(TModule module) where TModule : IModule |
||||
{ |
||||
ModuleContainer.Register<TModule>(module); |
||||
module.Init(); |
||||
} |
||||
public TModule GetModule<TModule>() where TModule : class, IModule,new() |
||||
{ |
||||
if (!ModuleContainer.self.ContainsKey(typeof(TModule))) |
||||
{ |
||||
this.RegisterModule(new TModule()); |
||||
} |
||||
return ModuleContainer.Get<TModule>(); |
||||
} |
||||
public bool IsInitModule<TModule>() where TModule : class, IModule,new() |
||||
{ |
||||
if (!ModuleContainer.self.ContainsKey(typeof(TModule))) |
||||
{ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public abstract class EGModule:IModule{ |
||||
IArchitecture IBelongToArchitecture.GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
void IModule.Init() |
||||
{ |
||||
this.Init(); |
||||
} |
||||
public abstract void Init(); |
||||
} |
||||
#endregion |
||||
|
||||
#region Interface |
||||
public interface IArchitecture |
||||
{ |
||||
void RegisterModule<T>(T model) where T : IModule; |
||||
T GetModule<T>() where T : class, IModule,new(); |
||||
bool IsInitModule<T>() where T : class, IModule,new(); |
||||
} |
||||
public interface IModule : IBelongToArchitecture |
||||
{ |
||||
void Init(); |
||||
} |
||||
public interface IBelongToArchitecture |
||||
{ |
||||
IArchitecture GetArchitecture(); |
||||
} |
||||
|
||||
public static class CanGetModuleExtension |
||||
{ |
||||
public static T GetModule<T>(this IBelongToArchitecture self) where T : class, IModule,new() |
||||
{ |
||||
return self.GetArchitecture().GetModule<T>(); |
||||
} |
||||
} |
||||
|
||||
#endregion |
||||
|
||||
#region IOC |
||||
public class IOCContainer |
||||
{ |
||||
private Dictionary<Type, object> Instances = new Dictionary<Type, object>(); |
||||
public void Register<T>(T instance) |
||||
{ |
||||
var key = typeof(T); |
||||
if (Instances.ContainsKey(key)) |
||||
{ |
||||
Instances[key] = instance; |
||||
} |
||||
else |
||||
{ |
||||
Instances.Add(key, instance); |
||||
} |
||||
} |
||||
public T Get<T>() where T : class
|
||||
{ |
||||
var key = typeof(T); |
||||
if (Instances.TryGetValue(key, out var retInstance)) |
||||
{ |
||||
return retInstance as T; |
||||
} |
||||
return null; |
||||
} |
||||
public Dictionary<Type, object> self => Instances; |
||||
} |
||||
#endregion |
||||
|
||||
#region Event |
||||
public interface IEasyEvent { |
||||
|
||||
} |
||||
public interface IUnRegister |
||||
{ |
||||
void UnRegister(); |
||||
} |
||||
|
||||
public class EasyEvent<T> : IEasyEvent |
||||
{ |
||||
private Action<T> OnEvent = e => { }; |
||||
public IUnRegister Register(Action<T> onEvent) |
||||
{ |
||||
OnEvent += onEvent; |
||||
return new CustomUnRegister(() => { UnRegister(onEvent); }); |
||||
} |
||||
public void UnRegister(Action<T> onEvent) |
||||
{ |
||||
OnEvent -= onEvent; |
||||
} |
||||
public void Invoke(T t) |
||||
{ |
||||
OnEvent?.Invoke(t); |
||||
} |
||||
} |
||||
|
||||
public class EasyEvent : IEasyEvent |
||||
{ |
||||
private Action OnEvent = () => { }; |
||||
public IUnRegister Register(Action onEvent) |
||||
{ |
||||
OnEvent += onEvent; |
||||
return new CustomUnRegister(() => { UnRegister(onEvent); }); |
||||
} |
||||
public void UnRegister(Action onEvent) |
||||
{ |
||||
OnEvent -= onEvent; |
||||
} |
||||
public void Invoke() |
||||
{ |
||||
OnEvent?.Invoke(); |
||||
} |
||||
} |
||||
public struct CustomUnRegister : IUnRegister |
||||
{ |
||||
/// <summary> |
||||
/// 委托对象 |
||||
/// </summary> |
||||
private Action OnUnRegister { get; set; } |
||||
/// <summary> |
||||
/// 带参构造函数 |
||||
/// </summary> |
||||
/// <param name="onDispose"></param> |
||||
public CustomUnRegister(Action onUnRegister) |
||||
{ |
||||
OnUnRegister = onUnRegister; |
||||
} |
||||
/// <summary> |
||||
/// 资源释放 |
||||
/// </summary> |
||||
public void UnRegister() |
||||
{ |
||||
OnUnRegister.Invoke(); |
||||
OnUnRegister = null; |
||||
} |
||||
} |
||||
#endregion |
||||
|
||||
#region FrameworkExtension |
||||
public interface IEGFramework{} |
||||
|
||||
public class EGArchitectureImplement:EGArchitecture<EGArchitectureImplement>{ |
||||
protected override void Init() |
||||
{ |
||||
//base.Init(); |
||||
} |
||||
} |
||||
|
||||
public static class EGArchitectureImplementExtension{ |
||||
public static T GetModule<T>(this IEGFramework self) where T : class, IModule,new() |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<T>(); |
||||
} |
||||
} |
||||
#endregion |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) .NET Foundation and Contributors |
||||
|
||||
All rights reserved. |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2007 James Newton-King |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||||
the Software, and to permit persons to whom the Software is furnished to do so, |
||||
subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font |
||||
Name 'Source'. Source is a trademark of Adobe in the United States |
||||
and/or other countries. |
||||
|
||||
This Font Software is licensed under the SIL Open Font License, |
||||
Version 1.1. |
||||
|
||||
This license is copied below, and is also available with a FAQ at: |
||||
http://scripts.sil.org/OFL |
||||
|
||||
----------------------------------------------------------- |
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 |
||||
----------------------------------------------------------- |
||||
|
||||
PREAMBLE |
||||
The goals of the Open Font License (OFL) are to stimulate worldwide |
||||
development of collaborative font projects, to support the font |
||||
creation efforts of academic and linguistic communities, and to |
||||
provide a free and open framework in which fonts may be shared and |
||||
improved in partnership with others. |
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and |
||||
redistributed freely as long as they are not sold by themselves. The |
||||
fonts, including any derivative works, can be bundled, embedded, |
||||
redistributed and/or sold with any software provided that any reserved |
||||
names are not used by derivative works. The fonts and derivatives, |
||||
however, cannot be released under any other type of license. The |
||||
requirement for fonts to remain under this license does not apply to |
||||
any document created using the fonts or their derivatives. |
||||
|
||||
DEFINITIONS |
||||
"Font Software" refers to the set of files released by the Copyright |
||||
Holder(s) under this license and clearly marked as such. This may |
||||
include source files, build scripts and documentation. |
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the |
||||
copyright statement(s). |
||||
|
||||
"Original Version" refers to the collection of Font Software |
||||
components as distributed by the Copyright Holder(s). |
||||
|
||||
"Modified Version" refers to any derivative made by adding to, |
||||
deleting, or substituting -- in part or in whole -- any of the |
||||
components of the Original Version, by changing formats or by porting |
||||
the Font Software to a new environment. |
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical |
||||
writer or other person who contributed to the Font Software. |
||||
|
||||
PERMISSION & CONDITIONS |
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of the Font Software, to use, study, copy, merge, embed, |
||||
modify, redistribute, and sell modified and unmodified copies of the |
||||
Font Software, subject to the following conditions: |
||||
|
||||
1) Neither the Font Software nor any of its individual components, in |
||||
Original or Modified Versions, may be sold by itself. |
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, |
||||
redistributed and/or sold with any software, provided that each copy |
||||
contains the above copyright notice and this license. These can be |
||||
included either as stand-alone text files, human-readable headers or |
||||
in the appropriate machine-readable metadata fields within text or |
||||
binary files as long as those fields can be easily viewed by the user. |
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font |
||||
Name(s) unless explicit written permission is granted by the |
||||
corresponding Copyright Holder. This restriction only applies to the |
||||
primary font name as presented to the users. |
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font |
||||
Software shall not be used to promote, endorse or advertise any |
||||
Modified Version, except to acknowledge the contribution(s) of the |
||||
Copyright Holder(s) and the Author(s) or with their explicit written |
||||
permission. |
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, |
||||
must be distributed entirely under this license, and must not be |
||||
distributed under any other license. The requirement for fonts to |
||||
remain under this license does not apply to any document created using |
||||
the Font Software. |
||||
|
||||
TERMINATION |
||||
This license becomes null and void if any of the above conditions are |
||||
not met. |
||||
|
||||
DISCLAIMER |
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE |
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL |
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM |
||||
OTHER DEALINGS IN THE FONT SOFTWARE. |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
#region Interface |
||||
public interface ICommand |
||||
{ |
||||
void Execute(); |
||||
} |
||||
public interface IQuery<TResult> |
||||
{ |
||||
TResult Do(); |
||||
} |
||||
|
||||
public interface IEGCQRS |
||||
{ |
||||
void SendCommand(ICommand command); |
||||
TResult DoQuery<TResult>(IQuery<TResult> query); |
||||
} |
||||
#endregion |
||||
|
||||
public class EGCQRS :EGModule, IEGCQRS |
||||
{ |
||||
public void SendCommand(ICommand command) |
||||
{ |
||||
command.Execute(); |
||||
} |
||||
public TResult DoQuery<TResult>(IQuery<TResult> query) |
||||
{ |
||||
return query.Do(); |
||||
} |
||||
public override void Init() |
||||
{ |
||||
|
||||
} |
||||
} |
||||
|
||||
#region Extension |
||||
public static class CanSendCommandExtension |
||||
{ |
||||
public static void EGSendCommand(this IEGFramework self, ICommand command) |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGCQRS>().SendCommand(command); |
||||
} |
||||
} |
||||
|
||||
public static class CanQueryDataExtension |
||||
{ |
||||
public static TResult EGQueryData<TResult>(this IEGFramework self, IQuery<TResult> query) |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGCQRS>().DoQuery(query); |
||||
} |
||||
} |
||||
#endregion |
||||
} |
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
public interface IEGEvent{ |
||||
void SendEvent<T>() where T : new(); |
||||
void SendEvent<T>(T e); |
||||
IUnRegister RegisterEvent<T>(Action<T> onEvent); |
||||
void UnRegisterEvent<T>(Action<T> onEvent); |
||||
} |
||||
public class EGEvent : EGModule,IEGEvent |
||||
{ |
||||
public override void Init() |
||||
{ |
||||
|
||||
} |
||||
private readonly EasyEvents Events = new EasyEvents(); |
||||
public void SendEvent<TEvent>() where TEvent : new() |
||||
{ |
||||
Events.GetEvent<EasyEvent<TEvent>>()?.Invoke(new TEvent()); |
||||
} |
||||
|
||||
public void SendEvent<TEvent>(TEvent e) |
||||
{ |
||||
Events.GetEvent<EasyEvent<TEvent>>()?.Invoke(e); |
||||
} |
||||
|
||||
public IUnRegister RegisterEvent<TEvent>(Action<TEvent> onEvent) |
||||
{ |
||||
var e = Events.GetOrAddEvent<EasyEvent<TEvent>>(); |
||||
return e.Register(onEvent); |
||||
} |
||||
|
||||
public void UnRegisterEvent<TEvent>(Action<TEvent> onEvent) |
||||
{ |
||||
var e = Events.GetEvent<EasyEvent<TEvent>>(); |
||||
if (e != null) |
||||
{ |
||||
e.UnRegister(onEvent); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class EasyEvents |
||||
{ |
||||
private static EasyEvents GlobalEvents = new EasyEvents(); |
||||
public static T Get<T>() where T : IEasyEvent |
||||
{ |
||||
return GlobalEvents.GetEvent<T>(); |
||||
} |
||||
public static void Register<T>() where T : IEasyEvent, new() |
||||
{ |
||||
GlobalEvents.AddEvent<T>(); |
||||
} |
||||
private Dictionary<Type, IEasyEvent> TypeEvents = new Dictionary<Type, IEasyEvent>(); |
||||
public void AddEvent<T>() where T : IEasyEvent, new() |
||||
{ |
||||
TypeEvents.Add(typeof(T), new T()); |
||||
} |
||||
public T GetEvent<T>() where T : IEasyEvent |
||||
{ |
||||
IEasyEvent e; |
||||
if (TypeEvents.TryGetValue(typeof(T), out e)) |
||||
{ |
||||
return (T)e; |
||||
} |
||||
return default; |
||||
} |
||||
public T GetOrAddEvent<T>() where T : IEasyEvent, new() |
||||
{ |
||||
var eType = typeof(T); |
||||
if (TypeEvents.TryGetValue(eType, out var e)) |
||||
{ |
||||
return (T)e; |
||||
} |
||||
var t = new T(); |
||||
TypeEvents.Add(eType, t); |
||||
return t; |
||||
} |
||||
} |
||||
|
||||
|
||||
public static class CanRegisterEventExtension |
||||
{ |
||||
public static IUnRegister EGRegisterEvent<T>(this IEGFramework self, Action<T> onEvent) |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGEvent>().RegisterEvent<T>(onEvent); |
||||
} |
||||
public static void EGUnRegisterEvent<T>(this IEGFramework self, Action<T> onEvent) |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGEvent>().UnRegisterEvent<T>(onEvent); |
||||
} |
||||
} |
||||
|
||||
public static class CanSendEventExtension |
||||
{ |
||||
public static void EGSendEvent<T>(this IEGFramework self) where T : new() |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGEvent>().SendEvent<T>(); |
||||
} |
||||
public static void EGSendEvent<T>(this IEGFramework self, T e) |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGEvent>().SendEvent<T>(e); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,320 @@
@@ -0,0 +1,320 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Timers; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
//before use this module,you should install NewtonSoft.Json Nuget Package |
||||
//in vscode,you can install this package by install vscode extension NuGet Package Manager GUI |
||||
//search 'Newton' and choose Newtonsoft.Json |
||||
//EGMessage, Every Message tools will be based in this class |
||||
public class EGMessage : EGModule |
||||
{ |
||||
public EasyEvent<ResponseMsg> OnDataReceived { set; get; } = new EasyEvent<ResponseMsg>(); |
||||
public EasyEvent<ResponseMsgEvent> OnResponse { set; get; } = new EasyEvent<ResponseMsgEvent>(); |
||||
public EasyEvent<RequestMsgEvent> OnRequest { set; get; } = new EasyEvent<RequestMsgEvent>(); |
||||
|
||||
/// <summary> |
||||
/// Send delay in millisecond,if you don't need a Timer to delay send message,you can set it to 0. |
||||
/// </summary> |
||||
/// <value></value> |
||||
public int SendDelay { set; get; } = 100; |
||||
public Queue<RequestMsgEvent> RequestCache { set; get; } = new Queue<RequestMsgEvent>(); |
||||
private System.Timers.Timer RequestTimer { set; get; } |
||||
|
||||
public override void Init() |
||||
{ |
||||
if(SendDelay>0){ |
||||
RequestTimer = new System.Timers.Timer(SendDelay); |
||||
RequestTimer.Elapsed += ExecuteRequest; |
||||
RequestTimer.AutoReset = true; |
||||
RequestTimer.Enabled = true; |
||||
} |
||||
} |
||||
#region ReceiveFunctions |
||||
private void ReceiveResponse<T>(ResponseMsg msg) where T :IResponse, new() |
||||
{ |
||||
this.ExecuteResponse(new T(),msg.stringData,msg.byteData,msg.sender,msg.protocolType); |
||||
} |
||||
/// <summary> |
||||
/// Start to receive type of T data |
||||
/// </summary> |
||||
/// <typeparam name="T">Data class of message</typeparam> |
||||
public void OnReceive<T>() where T : IResponse, new() |
||||
{ |
||||
OnDataReceived.Register(ReceiveResponse<T>); |
||||
} |
||||
/// <summary> |
||||
/// Stop to receive type of T data |
||||
/// </summary> |
||||
/// <typeparam name="T">Data class of message</typeparam> |
||||
public void OffReceive<T>() where T : IResponse, new() |
||||
{ |
||||
OnDataReceived.UnRegister(ReceiveResponse<T>); |
||||
} |
||||
#endregion |
||||
#region request & response |
||||
|
||||
public void SendRequest<TRequest>(TRequest request,string sender,ProtocolType protocolType) where TRequest:IRequest |
||||
{ |
||||
if(SendDelay>0){ |
||||
RequestCache.Enqueue(new RequestMsgEvent(request,sender,protocolType)); |
||||
}else{ |
||||
OnRequest.Invoke(new RequestMsgEvent(request,sender,protocolType)); |
||||
} |
||||
//ExecuteRequest(); |
||||
//OnRequest.Invoke(requestCache.Dequeue()); |
||||
} |
||||
|
||||
private void ExecuteRequest(object source, ElapsedEventArgs e){ |
||||
if(RequestCache.Count>0){ |
||||
OnRequest.Invoke(RequestCache.Dequeue()); |
||||
} |
||||
} |
||||
|
||||
private void ExecuteResponse<TResponse>(TResponse response,string protocolString,byte[] protocolBytes,string sender,ProtocolType protocolType) where TResponse:IResponse |
||||
{ |
||||
bool isSet = response.TrySetData(protocolString,protocolBytes); |
||||
if (isSet) |
||||
{ |
||||
//this.SendEvent(new ResponseMsgEvent(response, sender)); |
||||
OnResponse.Invoke(new ResponseMsgEvent(response,sender,protocolType)); |
||||
} |
||||
} |
||||
#endregion |
||||
|
||||
public void SetDelay(int millisecond){ |
||||
this.SendDelay = millisecond; |
||||
} |
||||
} |
||||
|
||||
#region interface |
||||
public interface IResponse |
||||
{ |
||||
/// <summary> |
||||
/// Attempt to fill in the data. If it does not comply with the relevant protocol rules, it is recommended to return false. If false is returned here, the data response will be ignored. |
||||
/// </summary> |
||||
/// <param name="protocolData">original received</param> |
||||
/// <returns></returns> |
||||
bool TrySetData(string protocolData,byte[] protocolBytes); |
||||
} |
||||
public interface IRequest |
||||
{ |
||||
/// <summary> |
||||
/// define you message info in this function,and this return will be send to server&client by request. |
||||
/// </summary> |
||||
/// <returns>request info</returns> |
||||
string ToProtocolData(); |
||||
|
||||
byte[] ToProtocolByteData(); |
||||
} |
||||
#endregion |
||||
#region AbstractClass |
||||
|
||||
public class BaseJsonResponse : IResponse |
||||
{ |
||||
private string ExceptionMsg; |
||||
public virtual string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
public virtual bool TrySetData(string json,byte[] bytes) |
||||
{ |
||||
try |
||||
{ |
||||
return true; |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
ExceptionMsg = e.ToString(); |
||||
//PrintErr(ExceptionMsg); |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class StringRequest : IRequest |
||||
{ |
||||
private string RequestStr; |
||||
public StringRequest() { |
||||
RequestStr = "No message"; |
||||
} |
||||
public StringRequest(string str) { |
||||
RequestStr = str; |
||||
} |
||||
|
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return RequestStr; |
||||
} |
||||
} |
||||
#endregion |
||||
#region Extension |
||||
public static class CanRegisterMessageExtension { |
||||
/// <summary> |
||||
/// To register event until message received,if you only need message,please use: |
||||
/// this.RegisterMessageEvent<BaseJsonResponse>(e=>{ //To execute your message}) |
||||
/// if you want to get sender,you also can to: |
||||
/// this.RegisterMessageEvent<BaseJsonResponse>((res,sender))=>{ //To execute your message |
||||
/// Print(res.toProtocolData()); |
||||
/// Print(sender); |
||||
/// }) |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="onEvent"></param> |
||||
/// <typeparam name="TResponse"></typeparam> |
||||
/// <returns></returns> |
||||
public static IUnRegister EGRegisterMessageEvent<TResponse>(this IEGFramework self, Action<TResponse> onEvent)where TResponse : IResponse |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGMessage>().OnResponse.Register(e=> { |
||||
if (e.res.GetType() == typeof(TResponse)) { |
||||
onEvent.Invoke((TResponse)e.res); |
||||
} |
||||
}); |
||||
} |
||||
/// <summary> |
||||
/// To register event until message received,if you only need message,please use: |
||||
/// this.RegisterMessageEvent<BaseJsonResponse>(e=>{ //To execute your message}) |
||||
/// if you want to get sender,you also can to: |
||||
/// this.RegisterMessageEvent<BaseJsonResponse>((res,sender))=>{ //To execute your message |
||||
/// Print(res.toProtocolData()); |
||||
/// Print(sender); |
||||
/// }) |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="onEvent"></param> |
||||
/// <typeparam name="TResponse"></typeparam> |
||||
/// <returns></returns> |
||||
public static IUnRegister EGRegisterMessageEvent<TResponse>(this IEGFramework self, Action<TResponse,string> onEvent)where TResponse : IResponse |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGMessage>().OnResponse.Register(e=> { |
||||
if (e.res.GetType() == typeof(TResponse)) { |
||||
onEvent.Invoke((TResponse)e.res,e.sender); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public static IUnRegister EGRegisterMessageEvent<TResponse>(this IEGFramework self, Action<TResponse,string,ProtocolType> onEvent)where TResponse : IResponse |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGMessage>().OnResponse.Register(e=> { |
||||
if (e.res.GetType() == typeof(TResponse)) { |
||||
onEvent.Invoke((TResponse)e.res,e.sender,e.protocolType); |
||||
} |
||||
}); |
||||
} |
||||
/// <summary> |
||||
/// Start to receive type of TResponse data |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <typeparam name="TResponse"></typeparam> |
||||
public static void EGOnMessage<TResponse>(this IEGFramework self) where TResponse : IResponse,new() |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGMessage>().OnReceive<TResponse>(); |
||||
} |
||||
/// <summary> |
||||
/// Stop to receive type of TResponse data |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <typeparam name="TResponse"></typeparam> |
||||
public static void EGOffMessage<TResponse>(this IEGFramework self) where TResponse : IResponse,new() |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGMessage>().OffReceive<TResponse>(); |
||||
} |
||||
} |
||||
public static class CanSendMessageExtension { |
||||
/// <summary> |
||||
/// to send message by request and define sender |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="request"></param> |
||||
/// <param name="sender"></param> |
||||
/// <typeparam name="TRequest"></typeparam> |
||||
public static void EGSendMessage<TRequest>(this IEGFramework self, TRequest request,string sender,ProtocolType protocolType)where TRequest : IRequest |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGMessage>().SendRequest(request,sender,protocolType); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// this extension to link with protocol tools,such as tcp,udp,serial port,etc... |
||||
/// </summary> |
||||
public static class EGMessageEventExtension{ |
||||
public static void EGOnReceivedData(this IModule self, ResponseMsg receivedData) |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGMessage>().OnDataReceived.Invoke(receivedData); |
||||
} |
||||
public static void EGRegisterSendAction(this IModule self, Action<RequestMsgEvent> sendAction){ |
||||
EGArchitectureImplement.Interface.GetModule<EGMessage>().OnRequest.Register(sendAction); |
||||
} |
||||
} |
||||
#endregion |
||||
#region event |
||||
|
||||
public struct ResponseMsg |
||||
{ |
||||
public string sender; |
||||
public string stringData; |
||||
public byte[] byteData; |
||||
|
||||
public ProtocolType protocolType; |
||||
public ResponseMsg(string stringData_,byte[] byteData_,string sender_,ProtocolType protocolType_) |
||||
{ |
||||
stringData = stringData_; |
||||
byteData = byteData_; |
||||
sender = sender_; |
||||
protocolType = protocolType_; |
||||
} |
||||
} |
||||
|
||||
public struct ResponseMsgEvent |
||||
{ |
||||
public IResponse res; |
||||
public string sender; |
||||
public ProtocolType protocolType; |
||||
public ResponseMsgEvent(IResponse res_,string sender_,ProtocolType protocolType_) |
||||
{ |
||||
res = res_; |
||||
sender = sender_; |
||||
protocolType = protocolType_; |
||||
} |
||||
} |
||||
|
||||
public struct RequestMsgEvent |
||||
{ |
||||
public IRequest req; |
||||
public string sender; |
||||
public ProtocolType protocolType; |
||||
public RequestMsgEvent(IRequest req_ ,string sender_,ProtocolType protocolType_) |
||||
{ |
||||
req = req_; |
||||
sender = sender_; |
||||
protocolType = protocolType_; |
||||
} |
||||
} |
||||
#endregion |
||||
|
||||
public enum ProtocolType{ |
||||
TCPClient = 0x00, |
||||
TCPServer = 0x01, |
||||
UDP = 0x02, |
||||
SerialPort = 0x03, |
||||
WebSocketClient = 0x10, |
||||
WebSocketServer = 0x11, |
||||
HttpServer = 0x20, |
||||
HttpGet = 0x21, |
||||
HttpPost = 0x22, |
||||
HttpPut = 0x23, |
||||
HttpPatch = 0x24, |
||||
HttpDelete = 0x25, |
||||
DLTSClient = 0x30, |
||||
DLTSServer = 0x31, |
||||
SSLClient = 0x40, |
||||
SSLServer = 0x41 |
||||
//MQTT,SSH,etc... |
||||
} |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
public interface IEGObject |
||||
{ |
||||
void RegisterObject<T>(T object_); |
||||
T GetObject<T>() where T : class,new(); |
||||
|
||||
} |
||||
public class EGObject : EGModule,IEGObject |
||||
{ |
||||
private IOCContainer ObjectContainer = new IOCContainer(); |
||||
public override void Init() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public TObject GetObject<TObject>() where TObject : class,new() |
||||
{ |
||||
if (!ObjectContainer.self.ContainsKey(typeof(TObject))) |
||||
{ |
||||
this.RegisterObject(new TObject()); |
||||
} |
||||
return ObjectContainer.Get<TObject>(); |
||||
} |
||||
|
||||
public void RegisterObject<TObject>(TObject object_) |
||||
{ |
||||
ObjectContainer.Register(object_); |
||||
} |
||||
|
||||
public bool ContainsObject<TObject>(){ |
||||
return ObjectContainer.self.ContainsKey(typeof(TObject)); |
||||
} |
||||
} |
||||
|
||||
public static class CanGetObjectExtension |
||||
{ |
||||
public static T EGGetObject<T>(this IEGFramework self) where T : class,new() |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGObject>().GetObject<T>(); |
||||
} |
||||
} |
||||
public static class CanRegisterObjectExtension |
||||
{ |
||||
public static void EGRegisterObject<T>(this IArchitecture self,T object_) where T : class,new() |
||||
{ |
||||
self.GetModule<EGObject>().RegisterObject(object_); |
||||
} |
||||
public static void EGRegisterObject<T>(this IEGFramework self,T object_) where T : class,new() |
||||
{ |
||||
EGArchitectureImplement.Interface.GetModule<EGObject>().RegisterObject(object_); |
||||
} |
||||
} |
||||
|
||||
public static class CanContainsObjectExtension{ |
||||
public static bool EGContainsObject<T>(this IEGFramework self) |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGObject>().ContainsObject<T>(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
using System; |
||||
using System.IO; |
||||
using System.Collections.Generic; |
||||
using Newtonsoft.Json; |
||||
using Newtonsoft.Json.Linq; |
||||
|
||||
namespace EGFramework |
||||
{ |
||||
public interface IEGSave{ |
||||
void SetDataToFile<TData>(TData data); |
||||
TData GetDataByFile<TData>() where TData : class,new(); |
||||
void InitSaveData(string fileName); |
||||
} |
||||
public class EGSave : EGModule,IEGSave |
||||
{ |
||||
private string DefaultSaveFile = "Default"; |
||||
private string DefaultSaveFolder = "SaveData"; |
||||
private JObject _SaveObject; |
||||
private JObject SaveObject{ |
||||
get { |
||||
if(_SaveObject == null){ |
||||
InitSaveObject(); |
||||
} |
||||
return _SaveObject; |
||||
} |
||||
} |
||||
|
||||
public EGSave(){ |
||||
|
||||
} |
||||
/// <summary> |
||||
/// if you want to define default save data file name, please use "this.RegisterModule(new EGSave("FileName"))"in your architecture code(Init function); |
||||
/// </summary> |
||||
/// <param name="fileName"></param> |
||||
public EGSave(string fileName){ |
||||
this.DefaultSaveFile = fileName; |
||||
} |
||||
public override void Init() |
||||
{ |
||||
if (!Directory.Exists(DefaultSaveFolder)) |
||||
{ |
||||
Directory.CreateDirectory(DefaultSaveFolder); |
||||
File.WriteAllText(DefaultSaveFolder + "/" + DefaultSaveFile + ".json","{}"); |
||||
}else if(!File.Exists(DefaultSaveFolder + "/" + DefaultSaveFile + ".json")){ |
||||
File.WriteAllText(DefaultSaveFolder + "/" + DefaultSaveFile + ".json","{}"); |
||||
} |
||||
} |
||||
|
||||
private void InitSaveObject(){ |
||||
using (StreamReader reader = File.OpenText(DefaultSaveFolder + "/" + DefaultSaveFile + ".json")) |
||||
{ |
||||
_SaveObject = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Push SaveObject data set to file |
||||
/// </summary> |
||||
public void SaveToFile(){ |
||||
SaveToFile(DefaultSaveFile); |
||||
} |
||||
private void SaveToFile(string fileName){ |
||||
File.WriteAllText(DefaultSaveFolder + "/" + fileName + ".json",JsonConvert.SerializeObject(SaveObject,Formatting.Indented)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Push data to SaveObject object cache, this function will not save data to file, if you hope not to IO operation frequently, you can use this with SaveToFile. |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
/// <typeparam name="TData"></typeparam> |
||||
public void SetData<TData>(TData data){ |
||||
//SaveObject = JObject.FromObject(data); |
||||
if(SaveObject.ContainsKey(typeof(TData).ToString())){ |
||||
SaveObject[typeof(TData).ToString()] = JToken.FromObject(data); |
||||
}else{ |
||||
SaveObject.Add(typeof(TData).ToString(),JToken.FromObject(data)); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Get data from file, if your data is not in file, then get null. |
||||
/// </summary> |
||||
/// <typeparam name="TData"></typeparam> |
||||
public TData GetDataByFile<TData>() where TData : class,new(){ |
||||
if(!SaveObject.ContainsKey(typeof(TData).ToString())){ |
||||
return null; |
||||
} |
||||
TData data = SaveObject[typeof(TData).ToString()].ToObject<TData>(); |
||||
return data; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Save data to file |
||||
/// </summary> |
||||
/// <param name="data">your any type of data</param> |
||||
/// <typeparam name="TData"></typeparam> |
||||
public void SetDataToFile<TData>(TData data) |
||||
{ |
||||
SetData(data); |
||||
SaveToFile(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Init a new save data file or load an other file with json suffix, if you want to load other save data, please use this function to reload; |
||||
/// </summary> |
||||
/// <param name="fileName"></param> |
||||
public void InitSaveData(string fileName) |
||||
{ |
||||
DefaultSaveFile = fileName; |
||||
if(!File.Exists(DefaultSaveFolder + "/" + DefaultSaveFile + ".json")){ |
||||
File.WriteAllText(DefaultSaveFolder + "/" + DefaultSaveFile + ".json","{}"); |
||||
} |
||||
InitSaveObject(); |
||||
} |
||||
} |
||||
|
||||
public static class CanGetEGSaveExtension{ |
||||
public static EGSave EGSave(this IEGFramework self){ |
||||
return EGArchitectureImplement.Interface.GetModule<EGSave>(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,203 @@
@@ -0,0 +1,203 @@
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace EGFramework { |
||||
//协议规则解析通用方法扩展 |
||||
public static class EGConvertExtension |
||||
{ |
||||
/// <summary> |
||||
/// Hex string data to byte array,such as a string like "0x00 0xff 0x06" |
||||
/// </summary> |
||||
/// <param name="self">Only include A-F,0-9,hex</param> |
||||
/// <returns></returns> |
||||
public static byte[] ToByteArrayByHex(this string self) { |
||||
int hexLen = self.Length; |
||||
byte[] result; |
||||
if (hexLen % 2 == 1) |
||||
{ |
||||
//奇数 |
||||
hexLen++; |
||||
result = new byte[(hexLen / 2)]; |
||||
self += "0" ; |
||||
} |
||||
else |
||||
{ |
||||
//偶数 |
||||
result = new byte[(hexLen / 2)]; |
||||
} |
||||
int j = 0; |
||||
for (int i = 0; i < hexLen; i += 2) |
||||
{ |
||||
result[j] = (byte)int.Parse(self.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); |
||||
j++; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// get string from hex array ,like hex array {0x0a,0x11} => "0x0a 0x11" |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <returns></returns> |
||||
public static string ToStringByHex(this byte[] self) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
|
||||
foreach (byte b in self) |
||||
{ |
||||
sb.Append("0x" + b.ToString("X2") + " "); |
||||
} |
||||
string result = sb.ToString().Trim(); |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// get hex from string ,like string "0x0a 0x11" => {0x0a,0x11} |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <returns></returns> |
||||
public static byte[] ToHexByString(this string self) |
||||
{ |
||||
if (self.Length <= 2 && self.Substring(0, 2) != "0x") { |
||||
return null; |
||||
} |
||||
string[] hexStrings = self.Split(' '); |
||||
byte[] byteArray = new byte[hexStrings.Length]; |
||||
for (int i = 0; i < hexStrings.Length; i++) |
||||
{ |
||||
byteArray[i] = Convert.ToByte(hexStrings[i], 16); |
||||
} |
||||
return byteArray; |
||||
} |
||||
|
||||
public static byte[] ToBytes(this ushort self){ |
||||
byte[] byteArray = BitConverter.GetBytes(self); |
||||
if (BitConverter.IsLittleEndian) |
||||
{ |
||||
Array.Reverse(byteArray); |
||||
} |
||||
return byteArray; |
||||
} |
||||
|
||||
public static ushort ToUShort(this byte[] self){ |
||||
if (BitConverter.IsLittleEndian) |
||||
{ |
||||
Array.Reverse(self); |
||||
} |
||||
return BitConverter.ToUInt16(self, 0); |
||||
} |
||||
|
||||
public static byte[] ToBytes(this uint self){ |
||||
byte[] byteArray = BitConverter.GetBytes(self); |
||||
if (BitConverter.IsLittleEndian) |
||||
{ |
||||
Array.Reverse(byteArray); |
||||
} |
||||
return byteArray; |
||||
} |
||||
|
||||
public static uint ToUINT(this byte[] self){ |
||||
if (BitConverter.IsLittleEndian) |
||||
{ |
||||
Array.Reverse(self); |
||||
} |
||||
return BitConverter.ToUInt32(self, 0); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// convert and resize byte array,such as uint is 0x00FF7799 => byte array {0xFF,0x77,0x99} |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <returns></returns> |
||||
public static byte[] ToBytesAndResizeArray(this uint self){ |
||||
byte[] byteArray = BitConverter.GetBytes(self); |
||||
if (BitConverter.IsLittleEndian) |
||||
{ |
||||
Array.Reverse(byteArray); |
||||
} |
||||
int startIndex = Array.FindIndex(byteArray, b => b != 0); |
||||
if (startIndex == -1) |
||||
{ |
||||
byteArray = new byte[1]; |
||||
} |
||||
else |
||||
{ |
||||
byteArray = byteArray.Skip(startIndex).ToArray(); |
||||
} |
||||
return byteArray; |
||||
} |
||||
|
||||
public static byte[] ToByteArray(this bool[] boolArray) |
||||
{ |
||||
int numBool = boolArray.Length; |
||||
int numBytes = (numBool + 7) / 8; |
||||
byte[] byteArray = new byte[numBytes]; |
||||
|
||||
for (int i = 0; i < numBool; i++) |
||||
{ |
||||
int byteIndex = i / 8; |
||||
int bitIndex = i % 8; |
||||
if (boolArray[i]) |
||||
{ |
||||
byteArray[byteIndex] |= (byte)(1 << bitIndex); |
||||
} |
||||
} |
||||
|
||||
return byteArray; |
||||
} |
||||
|
||||
public static bool[] ToBoolArray(this byte[] byteArray) |
||||
{ |
||||
bool[] boolArray = new bool[byteArray.Length * 8]; |
||||
for (int i = 0; i < byteArray.Length; i++) |
||||
{ |
||||
byte currentByte = byteArray[i]; |
||||
|
||||
for (int j = 0; j < 8; j++) |
||||
{ |
||||
boolArray[i * 8 + j] = (currentByte & (1 << j)) != 0; |
||||
} |
||||
} |
||||
|
||||
return boolArray; |
||||
} |
||||
public static bool[] ToBoolArray(this int value) |
||||
{ |
||||
string binaryString = Convert.ToString(value, 2); |
||||
bool[] boolArray = new bool[binaryString.Length]; |
||||
if(binaryString.Length < 8){ |
||||
boolArray = new bool[8]; |
||||
} |
||||
for (int i = 0; i < binaryString.Length; i++) |
||||
{ |
||||
boolArray[binaryString.Length - i - 1] = binaryString[i] == '1'; |
||||
} |
||||
return boolArray; |
||||
} |
||||
|
||||
public static int ToInt(this bool[] boolArray) |
||||
{ |
||||
int result = 0; |
||||
for (int i = 0; i < boolArray.Length; i++) |
||||
{ |
||||
if (boolArray[i]) |
||||
{ |
||||
result |= (1 << i); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public static ushort[] ToUShortArray(this byte[] byteArray){ |
||||
ushort[] ushortArray = new ushort[byteArray.Length / 2]; |
||||
for (int i = 0, j = 0; i < byteArray.Length; i += 2, j++) |
||||
{ |
||||
ushortArray[j] = (ushort)((byteArray[i] << 8) | byteArray[i + 1]); |
||||
} |
||||
return ushortArray; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
using System; |
||||
using System.Security.Cryptography; |
||||
|
||||
namespace EGFramework{ |
||||
public static class EGCrcModbusExtension |
||||
{ |
||||
/// CRC calculate is a common device verify algorithm |
||||
/// use |
||||
// hex = {0x80,0x05}; |
||||
// Polynomial = x^16+x^15+x^2+1 = 1 80 05 |
||||
public const ushort CRC_16_Modbus_Polynomial = 0x8005; |
||||
// hex = {0xFF,0xFF} |
||||
public const ushort CRC_16_Modbus_Start = 0xFFFF; |
||||
// hex = {0x00,0x00} |
||||
public const ushort CRC_16_Modbus_ResultXOR = 0x0000; |
||||
private static readonly ushort[] Crc_16_Table_Modbus ={ |
||||
0x00,0xC0C1,0xC181,0x140,0xC301,0x3C0,0x280,0xC241,0xC601,0x6C0,0x780,0xC741,0x500,0xC5C1,0xC481,0x440, |
||||
0xCC01,0xCC0,0xD80,0xCD41,0xF00,0xCFC1,0xCE81,0xE40,0xA00,0xCAC1,0xCB81,0xB40,0xC901,0x9C0,0x880,0xC841, |
||||
0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41, |
||||
0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040, |
||||
0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441, |
||||
0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840, |
||||
0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40, |
||||
0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041, |
||||
0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441, |
||||
0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840, |
||||
0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40, |
||||
0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041, |
||||
0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440, |
||||
0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841, |
||||
0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41, |
||||
0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040, |
||||
}; |
||||
public static ushort CalculateCRC16Modbus(this byte[] bytes) |
||||
{ |
||||
CRC16 provider = new CRC16(Crc_16_Table_Modbus); |
||||
byte[] hash = provider.ComputeHash(bytes); |
||||
|
||||
ushort crc16 = BitConverter.ToUInt16(hash, 0); |
||||
|
||||
ushort reversedResult = (ushort)((crc16 >> 8) | (crc16 << 8)); |
||||
return reversedResult; |
||||
} |
||||
|
||||
} |
||||
public static class EGCrcUtility |
||||
{ |
||||
//Crc with table |
||||
public static uint CalculateCrc(byte[] data, uint initialValue, uint xorValue, bool inputReverse, bool outputReverse,uint[] CrcTable) |
||||
{ |
||||
uint crc = initialValue; |
||||
|
||||
for (int i = 0; i < data.Length; i++) |
||||
{ |
||||
if (inputReverse) |
||||
data[i] = ReverseBits(data[i]); |
||||
|
||||
crc ^= (uint)(data[i] << 24); |
||||
|
||||
for (int j = 0; j < 8; j++) |
||||
{ |
||||
crc = (crc << 8) ^ CrcTable[crc >> 24]; |
||||
} |
||||
} |
||||
|
||||
if (outputReverse) |
||||
crc = ReverseBits(crc); |
||||
|
||||
return crc ^ xorValue; |
||||
} |
||||
|
||||
//Crc without table |
||||
public static uint CalculateCrc(byte[] data, uint polynomial, uint initialValue, uint xorValue, bool inputReverse, bool outputReverse) |
||||
{ |
||||
uint crc = initialValue; |
||||
|
||||
for (int i = 0; i < data.Length; i++) |
||||
{ |
||||
if (inputReverse) |
||||
data[i] = ReverseBits(data[i]); |
||||
|
||||
crc ^= (uint)(data[i] << 24); |
||||
|
||||
for (int j = 0; j < 8; j++) |
||||
{ |
||||
if ((crc & 0x80000000) != 0) |
||||
{ |
||||
crc = (crc << 1) ^ polynomial; |
||||
} |
||||
else |
||||
{ |
||||
crc <<= 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (outputReverse) |
||||
crc = ReverseBits(crc); |
||||
|
||||
return crc ^ xorValue; |
||||
} |
||||
|
||||
private static uint ReverseBits(uint value) |
||||
{ |
||||
uint result = 0; |
||||
for (int i = 0; i < 8; i++) |
||||
{ |
||||
result = (result << 1) | ((value >> i) & 1); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
private static byte ReverseBits(byte value) |
||||
{ |
||||
byte result = 0; |
||||
for (int i = 0; i < 8; i++) |
||||
{ |
||||
result = (byte)((result << 1) | ((value >> i) & 1)); |
||||
} |
||||
return result; |
||||
} |
||||
} |
||||
public class CRC16 : HashAlgorithm |
||||
{ |
||||
private const ushort polynomial = 0x8005; |
||||
private ushort[] table = new ushort[256]; |
||||
private ushort crc = 0xFFFF; |
||||
|
||||
public CRC16(ushort[] table) |
||||
{ |
||||
HashSizeValue = 16; |
||||
this.table = table; |
||||
} |
||||
|
||||
protected override void HashCore(byte[] array, int ibStart, int cbSize) |
||||
{ |
||||
for (int i = ibStart; i < ibStart + cbSize; i++) |
||||
{ |
||||
byte index = (byte)(crc ^ array[i]); |
||||
crc = (ushort)((crc >> 8) ^ table[index]); |
||||
} |
||||
} |
||||
|
||||
protected override byte[] HashFinal() |
||||
{ |
||||
return BitConverter.GetBytes(crc); |
||||
} |
||||
|
||||
public override void Initialize() |
||||
{ |
||||
crc = ushort.MaxValue; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using System; |
||||
namespace EGFramework{ |
||||
public static class EGDateTimeExtension |
||||
{ |
||||
public static string GetFullDateMsg(this IEGFramework self) |
||||
{ |
||||
return DateTime.Now.ToString("yyyy-MM-dd") + " " + DateTime.Now.ToString("HH:mm:ss"); |
||||
} |
||||
public static string GetDayDateMsg(this IEGFramework self) |
||||
{ |
||||
return DateTime.Now.ToString("HH:mm:ss"); |
||||
} |
||||
public static long GetTimeStamp(this IEGFramework self) |
||||
{ |
||||
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 8, 0, 0, 0); |
||||
return System.Convert.ToInt64(ts.TotalSeconds); |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
using System; |
||||
using System.Text; |
||||
|
||||
namespace EGFramework{ |
||||
//use this extension,you should add System.Text.Encoding.CodePages package from Nuget |
||||
public static class EGEncodingExtension |
||||
{ |
||||
public static bool IsInit{ set; get; } |
||||
|
||||
/// <summary> |
||||
/// get encoding from encoding params(string). |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="encodingTxt"></param> |
||||
/// <returns></returns> |
||||
public static Encoding GetEncoding(this IEGFramework self,string encodingTxt){ |
||||
if(!IsInit){ |
||||
IsInit = true; |
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
} |
||||
return Encoding.GetEncoding(encodingTxt); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Make a string to bytes with encoding params(string). |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="encodingTxt"></param> |
||||
/// <returns></returns> |
||||
public static byte[] ToBytesByEncoding(this string self,string encodingTxt){ |
||||
if(!IsInit){ |
||||
IsInit = true; |
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
} |
||||
return Encoding.GetEncoding(encodingTxt).GetBytes(self); |
||||
} |
||||
/// <summary> |
||||
/// Make a string to bytes with encoding. |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="encoding"></param> |
||||
/// <returns></returns> |
||||
public static byte[] ToBytesByEncoding(this string self,Encoding encoding){ |
||||
if(!IsInit){ |
||||
IsInit = true; |
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
} |
||||
return encoding.GetBytes(self); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Make a bytes to string with encoding params(string). |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="encodingTxt"></param> |
||||
/// <returns></returns> |
||||
public static string ToStringByEncoding(this byte[] self,string encodingTxt){ |
||||
if(!IsInit){ |
||||
IsInit = true; |
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
} |
||||
return Encoding.GetEncoding(encodingTxt).GetString(self); |
||||
} |
||||
/// <summary> |
||||
/// Make a bytes to string with encoding. |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <param name="encodingTxt"></param> |
||||
/// <returns></returns> |
||||
public static string ToStringByEncoding(this byte[] self,Encoding encoding){ |
||||
if(!IsInit){ |
||||
IsInit = true; |
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
||||
} |
||||
return encoding.GetString(self); |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
using System; |
||||
|
||||
namespace EGFramework { |
||||
public static class EGIpExtension |
||||
{ |
||||
/// <summary> |
||||
/// Get host from IP. Such as 192.168.0.1:5555 => get 192.168.0.1 |
||||
/// </summary> |
||||
/// <param name="self"></param> |
||||
/// <returns></returns> |
||||
public static string GetHostByIp(this string ip) |
||||
{ |
||||
int colonIndex = ip.IndexOf(":"); |
||||
string host = ""; |
||||
if (colonIndex != -1) |
||||
{ |
||||
host = ip.Substring(0, colonIndex); |
||||
} |
||||
return host; |
||||
} |
||||
|
||||
public static int GetPortByIp(this string ip) |
||||
{ |
||||
int colonIndex = ip.IndexOf(":"); |
||||
string portString = ip.Substring(colonIndex + 1); |
||||
int port; |
||||
if (int.TryParse(portString, out port)) |
||||
{ |
||||
//nothing to do |
||||
} |
||||
else |
||||
{ |
||||
port = 0; |
||||
} |
||||
return port; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,299 @@
@@ -0,0 +1,299 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace EGFramework{ |
||||
/// <summary> |
||||
/// Support a class for analysis the .local(mdns) or other www.com(dns) protocol to get the message, |
||||
/// mdns protocol format type reference from https://github.com/richardschneider/net-mdns |
||||
/// nuget package is Makaretu.Dns.Multicast |
||||
/// mdns reference from https://www.rfc-editor.org/rfc/rfc6763.html |
||||
/// </summary> |
||||
public static class EGDnsExtension |
||||
{ |
||||
public const string DefaultDnsServer = "1.1.1.1"; |
||||
public const int DefaultDnsPort = 53; |
||||
public const string DefaultMDnsServerIpv4 = "224.0.0.251"; |
||||
public const string DefaultMDnsServerIpv6 = "FF02::FB"; |
||||
public const int DefaultMDnsPort = 5353; |
||||
|
||||
public const string DNS_SRV_RR = "_services._dns-sd._udp.local"; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Dns's OpCode |
||||
/// </summary> |
||||
public enum DnsOpCode : ushort{ |
||||
/// <summary> |
||||
/// Standard query. |
||||
/// </summary> |
||||
Query = 0x0000, |
||||
/// <summary> |
||||
/// Inverse query (obsolete), see https://tools.ietf.org/html/rfc3425. |
||||
/// </summary> |
||||
InverseQuery = 0x0800, |
||||
/// <summary> |
||||
/// A server status request. |
||||
/// </summary> |
||||
Status = 0x1000, |
||||
/// <summary> |
||||
/// Zone change, see https://tools.ietf.org/html/rfc1996. |
||||
/// </summary> |
||||
Notify = 0x2000, |
||||
/// <summary> |
||||
/// Update message, see https://tools.ietf.org/html/rfc2136. |
||||
/// </summary> |
||||
Update = 0x2800 |
||||
} |
||||
|
||||
/// <summary> |
||||
/// A resource record or query type. |
||||
/// </summary> |
||||
public enum DnsType{ |
||||
/// <summary> |
||||
/// A host address. |
||||
/// </summary> |
||||
A = 1, |
||||
/// <summary> |
||||
/// An authoritative name server. |
||||
/// </summary> |
||||
NS = 2, |
||||
/// <summary> |
||||
/// The canonical name for an alias. |
||||
/// </summary> |
||||
CNAME = 5, |
||||
/// <summary> |
||||
/// Marks the start of a zone of authority. |
||||
/// </summary> |
||||
SOA = 6, |
||||
/// <summary> |
||||
/// A mailbox domain name (EXPERIMENTAL). |
||||
/// </summary> |
||||
MB = 7, |
||||
/// <summary> |
||||
/// A mail group member (EXPERIMENTAL). |
||||
/// </summary> |
||||
MG = 8, |
||||
/// <summary> |
||||
/// A mailbox rename domain name (EXPERIMENTAL). |
||||
/// </summary> |
||||
MR = 9, |
||||
/// <summary> |
||||
/// A Null resource record (EXPERIMENTAL). |
||||
/// </summary> |
||||
NULL = 10, |
||||
/// <summary> |
||||
/// A well known service description. |
||||
/// </summary> |
||||
WKS = 11, |
||||
/// <summary> |
||||
/// A domain name pointer. |
||||
/// </summary> |
||||
PTR = 12, |
||||
/// <summary> |
||||
/// Host information. |
||||
/// </summary> |
||||
HINFO = 13, |
||||
/// <summary> |
||||
/// Mailbox or mail list information. |
||||
/// </summary> |
||||
MINFO = 14, |
||||
/// <summary> |
||||
/// Mail exchange. |
||||
/// </summary> |
||||
MX = 15, |
||||
/// <summary> |
||||
/// Text resources. |
||||
/// </summary> |
||||
TXT = 16, |
||||
/// <summary> |
||||
/// Responsible Person. |
||||
/// </summary> |
||||
RP = 17, |
||||
/// <summary> |
||||
/// AFS Data Base location. |
||||
/// </summary> |
||||
AFSDB = 18, |
||||
/// <summary> |
||||
/// An IPv6 host address. |
||||
/// </summary> |
||||
AAAA = 28, |
||||
/// <summary> |
||||
/// A resource record which specifies the location of the server(s) for a specific protocol and domain. |
||||
/// </summary> |
||||
SRV = 33, |
||||
/// <summary> |
||||
/// Maps an entire domain name. |
||||
/// </summary> |
||||
DNAME = 39, |
||||
/// <summary> |
||||
/// Option record. |
||||
/// </summary> |
||||
OPT = 41, |
||||
/// <summary> |
||||
/// Delegation Signer. |
||||
/// </summary> |
||||
DS = 43, |
||||
/// <summary> |
||||
/// Signature for a RRSET with a particular name, class, and type. |
||||
/// </summary> |
||||
RRSIG = 46, |
||||
/// <summary> |
||||
/// Next secure owener. |
||||
/// </summary> |
||||
NSEC = 47, |
||||
/// <summary> |
||||
/// Public key cryptography to sign and authenticate resource records. |
||||
/// </summary> |
||||
DNSKEY = 48, |
||||
/// <summary> |
||||
/// Authenticated next secure owner. |
||||
/// </summary> |
||||
NSEC3 = 50, |
||||
/// <summary> |
||||
/// Parameters needed by authoritative servers to calculate hashed owner names. |
||||
/// </summary> |
||||
NSEC3PARAM = 51, |
||||
/// <summary> |
||||
/// Shared secret key. |
||||
/// </summary> |
||||
TKEY = 249, |
||||
/// <summary> |
||||
/// Transactional Signature. |
||||
/// </summary> |
||||
TSIG = 250, |
||||
/// <summary> |
||||
/// A request for a transfer of an entire zone. |
||||
/// </summary> |
||||
AXFR = 252, |
||||
/// <summary> |
||||
/// A request for mailbox-related records (MB, MG or MR). |
||||
/// </summary> |
||||
MAILB = 253, |
||||
/// <summary> |
||||
/// A request for any record(s). |
||||
/// </summary> |
||||
ANY = 255, |
||||
/// <summary> |
||||
/// A Uniform Resource Identifier (URI) resource record. |
||||
/// </summary> |
||||
URI = 256, |
||||
/// <summary> |
||||
/// A certification authority authorization. |
||||
/// </summary> |
||||
CAA = 257 |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The values are maintained by IANA at https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2. |
||||
/// </summary> |
||||
public enum DnsClass : ushort |
||||
{ |
||||
/// <summary> |
||||
/// The Internet. |
||||
/// </summary> |
||||
IN = 1, |
||||
/// <summary> |
||||
/// The CSNET class (Obsolete - used only for examples insome obsolete RFCs). |
||||
/// </summary> |
||||
CS = 2, |
||||
/// <summary> |
||||
/// The CHAOS class. |
||||
/// </summary> |
||||
CH = 3, |
||||
/// <summary> |
||||
/// Hesiod[Dyer 87]. |
||||
/// </summary> |
||||
HS = 4, |
||||
/// <summary> |
||||
/// Used in UPDATE message to signify no class. |
||||
/// </summary> |
||||
None = 254, |
||||
/// <summary> |
||||
/// Only used in QCLASS. |
||||
/// </summary> |
||||
ANY = 255 |
||||
} |
||||
|
||||
public struct DnsHead{ |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// MDns Head |
||||
/// | TransactionID (2 bytes) | OpCode (2 bytes) | Dns Sign (2 byte) |
||||
/// </summary> |
||||
public struct MDnsHead { |
||||
/// <summary> |
||||
/// |
||||
/// </summary> |
||||
/// <value></value> |
||||
public ushort TransactionID { set; get; } |
||||
|
||||
|
||||
/// <summary> |
||||
/// The requested operation. |
||||
/// </summary> |
||||
/// <value></value> |
||||
public DnsOpCode OpCode { set; get; } |
||||
#region Sign Code |
||||
/// <summary> |
||||
/// A one bit field that specifies whether this message is a query(0), or a response(1). |
||||
/// </summary> |
||||
/// <value></value> |
||||
public bool QR { set; get; } |
||||
|
||||
public bool AA { set; get; } |
||||
|
||||
public bool TC { set; get; } |
||||
|
||||
public bool RD { set; get; } |
||||
public bool RA { set; get; } |
||||
|
||||
public byte OpCode4Bit { set; get; } |
||||
/// <summary> |
||||
/// Reserved for future use. |
||||
/// </summary> |
||||
/// <value>Must be zero in all queries and responses.</value> |
||||
public byte Z { set; get; } |
||||
/// <summary> |
||||
/// Authentic data. |
||||
/// </summary> |
||||
/// <value> true if the response data is authentic; otherwise, false.</value> |
||||
public bool AD { get; set; } |
||||
/// <summary> |
||||
/// Checking disabled. |
||||
/// </summary> |
||||
/// <value>true if the query does not require authenticated data; otherwise, false.</value> |
||||
public bool CD { get; set; } |
||||
#endregion |
||||
} |
||||
|
||||
public struct DnsQuestionRequest : IRequest |
||||
{ |
||||
|
||||
public byte ReplyCode { set; get; } |
||||
public ushort QuestionsCount { set; get; } |
||||
public ushort AnswerRRs { set; get; } |
||||
public ushort AuthorityRRs { set; get; } |
||||
public ushort Additional { set; get; } |
||||
|
||||
public List<byte[]> Data { set; get; } |
||||
|
||||
public byte QuestionType { set; get; } |
||||
|
||||
public byte QuestionClass { set; get; } |
||||
|
||||
|
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,838 @@
@@ -0,0 +1,838 @@
|
||||
using System; |
||||
using System.Linq; |
||||
|
||||
namespace EGFramework{ |
||||
/// <summary> |
||||
/// some extensions function about Modbus-TCP and Modbus-RTU (Physic layer used RS-485) |
||||
/// not include Modbus-ASCII,because LRC verify not developed |
||||
/// </summary> |
||||
public static class EGModbusExtension |
||||
{ |
||||
|
||||
//Send Protocol |
||||
//---------Modbus-TCP's Prefix--------- |
||||
//[00 00 00 00 00 06] 01 03 00 00 00 08 |
||||
//00 00 ----- info head (check for reply Any things can be defined) |
||||
//xx xx 00 00 00 06 info length ( Max length 65535 ) |
||||
public static byte[] MakeModbusTCPPrefix(this object self,ushort messageId,uint length){ |
||||
return messageId.ToBytes().Concat(length.ToBytes()).ToArray(); |
||||
} |
||||
public static byte[] MakeModbusTCPPrefix(this object self,ushort messageId,byte[] sendData){ |
||||
return messageId.ToBytes().Concat(((uint)sendData.Length).ToBytes()).ToArray(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Modbus FunctionCode |
||||
/// 0x01 => Read Coils ---- OK |
||||
/// 0x02 => Read Discrete input ---- OK |
||||
/// 0x03 => Read Holding registers ---- OK |
||||
/// 0x04 => Read Input registers ---- OK |
||||
/// 0x05 => Write Single Coils ---- OK |
||||
/// 0x06 => Write Single Holding registers ---- OK |
||||
/// 0x0F => Write Multi Coils ---- OK |
||||
/// 0x10 => Write Multi Holding registers ---- OK |
||||
/// </summary> |
||||
|
||||
#region Modbus TCP Request and Response |
||||
public struct ModbusTCP_ReadCoils : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x01; |
||||
public const ushort MessageId = 0xFF01; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusTCP_ReadCoils(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>2000){ |
||||
ReadCount = 2000; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_ReadDiscreteInput : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x02; |
||||
public const ushort MessageId = 0xFF02; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusTCP_ReadDiscreteInput(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>2000){ |
||||
ReadCount = 2000; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_ReadHoldingRegisters : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x03; |
||||
|
||||
public const ushort MessageId = 0xFF03; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 125</param> |
||||
public ModbusTCP_ReadHoldingRegisters(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>125){ |
||||
ReadCount = 125; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_ReadInputRegisters : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x04; |
||||
|
||||
public const ushort MessageId = 0xFF04; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 125</param> |
||||
public ModbusTCP_ReadInputRegisters(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>125){ |
||||
ReadCount = 125; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_WriteSingleCoil : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x05; |
||||
|
||||
public const ushort MessageId = 0xFF05; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public bool Value { set; get; } |
||||
|
||||
public ModbusTCP_WriteSingleCoil(byte deviceAddress,ushort registerAddress,bool value){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
Value = value; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
byte[] registerValues = {0x00,0x00}; |
||||
if(Value){ |
||||
registerValues[0]=0xFF; |
||||
} |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_WriteSingleHoldingRegister : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x06; |
||||
|
||||
public const ushort MessageId = 0xFF06; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort Value { set; get; } |
||||
|
||||
public ModbusTCP_WriteSingleHoldingRegister(byte deviceAddress,ushort registerAddress,ushort value){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
Value = value; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = this.MakeModbusTCPPrefix(MessageId,6); |
||||
protocolRequest = protocolRequest.Append(DeviceAddress).ToArray(); |
||||
protocolRequest = protocolRequest.Append(FunctionCode).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
byte[] registerValues = Value.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_WriteMultiCoil : IRequest{ |
||||
public const byte FunctionCode = 0x0F; |
||||
|
||||
public const ushort MessageId = 0xFF0F; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
public bool[] Values { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress">usual use 0x01 for device address</param> |
||||
/// <param name="registerStartAddress"></param> |
||||
/// <param name="values">Values length should be less than 2000</param> |
||||
public ModbusTCP_WriteMultiCoil(byte deviceAddress,ushort registerStartAddress,bool[] values){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterStartAddress = registerStartAddress; |
||||
Values = values; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
|
||||
byte[] protocolRequest = {DeviceAddress,FunctionCode}; |
||||
protocolRequest = protocolRequest.Concat(RegisterStartAddress.ToBytes()).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(((ushort)Values.Length).ToBytes()).ToArray(); |
||||
|
||||
//Length range should be 1-2000 0x0001-0x07D0,otherwise delete the data after 2000 |
||||
if(Values.Length>2000){ |
||||
bool[] SourceValues = Values; |
||||
Values = new bool[2000]; |
||||
Array.Copy(Values,0,SourceValues,0,2000); |
||||
} |
||||
//bool array 2000 => byte array 250 |
||||
byte[] valueGroup = Values.ToByteArray(); |
||||
byte valueLength = (byte)valueGroup.Length; |
||||
protocolRequest = protocolRequest.Append(valueLength).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(valueGroup).ToArray(); |
||||
byte[] protocolPrefix = this.MakeModbusTCPPrefix(MessageId,protocolRequest); |
||||
protocolRequest = protocolPrefix.Concat(protocolRequest).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Start write at Register start address,such as 0x03,write order by order like 0x03,0x04,0x05...,write count is the value array length |
||||
/// </summary> |
||||
public struct ModbusTCP_WriteMultiHoldingRegister : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x10; |
||||
|
||||
public const ushort MessageId = 0xFF10; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
public ushort[] Values { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress">usual use 0x01 for device address</param> |
||||
/// <param name="registerStartAddress"></param> |
||||
/// <param name="values">Values length should be less than 125</param> |
||||
public ModbusTCP_WriteMultiHoldingRegister(byte deviceAddress,ushort registerStartAddress,ushort[] values){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterStartAddress = registerStartAddress; |
||||
Values = values; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
|
||||
byte[] protocolRequest = {DeviceAddress,FunctionCode}; |
||||
protocolRequest = protocolRequest.Concat(RegisterStartAddress.ToBytes()).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(((ushort)Values.Length).ToBytes()).ToArray(); |
||||
|
||||
//Length range should be 1-125 0x0001-0x07D,otherwise delete the data after 125 |
||||
if(Values.Length>125){ |
||||
ushort[] SourceValues = Values; |
||||
Values = new ushort[125]; |
||||
Array.Copy(Values,0,SourceValues,0,125); |
||||
} |
||||
//ushort array 125 => byte array 250 |
||||
byte[] valueGroup = {}; |
||||
foreach(ushort value in Values){ |
||||
byte[] registerValues = value.ToBytes(); |
||||
valueGroup = valueGroup.Concat(registerValues).ToArray(); |
||||
} |
||||
byte valueLength = (byte)valueGroup.Length; |
||||
protocolRequest = protocolRequest.Append(valueLength).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(valueGroup).ToArray(); |
||||
byte[] protocolPrefix = this.MakeModbusTCPPrefix(MessageId,protocolRequest); |
||||
protocolRequest = protocolPrefix.Concat(protocolRequest).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusTCP_Response : IResponse |
||||
{ |
||||
public bool[] Coil { set; get; } |
||||
public bool[] DiscreteInput { set; get; } |
||||
public ushort[] HoldingRegister { set; get; } |
||||
public ushort[] InputRegister { set; get; } |
||||
public byte FunctionCode { set; get; } |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
public uint DataLength { set; get; } |
||||
|
||||
public byte[] SourceData { set; get; } |
||||
public ModbusFunctionType FunctionType { set; get; } |
||||
|
||||
public bool TrySetData(string protocolData, byte[] protocolBytes) |
||||
{ |
||||
try |
||||
{ |
||||
if(protocolBytes==null && protocolBytes.Length < 10){ |
||||
return false; |
||||
} |
||||
SourceData = protocolBytes; |
||||
DeviceAddress = protocolBytes[6]; |
||||
FunctionType = (ModbusFunctionType)protocolBytes[7]; |
||||
byte[] dataLength = new byte[4]; |
||||
Array.Copy(protocolBytes,2,dataLength,0,4); |
||||
DataLength = dataLength.ToUINT(); |
||||
if(protocolBytes.Length != DataLength+6){ |
||||
return false; |
||||
} |
||||
//every response's start should be 0xff,because the request's start is 0xff |
||||
if(protocolBytes[0]==0xff){ |
||||
switch(FunctionType){ |
||||
case ModbusFunctionType.ReadCoil: |
||||
byte readCoilLength = protocolBytes[8]; |
||||
byte[] CoilBytes = new byte[readCoilLength]; |
||||
Array.Copy(protocolBytes,9,CoilBytes,0,readCoilLength); |
||||
Coil = CoilBytes.ToBoolArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadDiscreteInput: |
||||
byte readDiscreteInputLength = protocolBytes[8]; |
||||
byte[] DiscreteInputBytes = new byte[readDiscreteInputLength]; |
||||
Array.Copy(protocolBytes,9,DiscreteInputBytes,0,readDiscreteInputLength); |
||||
DiscreteInput = DiscreteInputBytes.ToBoolArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadHoldingRegisters: |
||||
byte readHoldingRegistersLength = protocolBytes[8]; |
||||
byte[] HoldingRegistersBytes = new byte[readHoldingRegistersLength]; |
||||
Array.Copy(protocolBytes,9,HoldingRegistersBytes,0,readHoldingRegistersLength); |
||||
HoldingRegister = HoldingRegistersBytes.ToUShortArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadInputRegisters: |
||||
byte readInputRegistersLength = protocolBytes[8]; |
||||
byte[] InputRegistersBytes = new byte[readInputRegistersLength]; |
||||
Array.Copy(protocolBytes,9,InputRegistersBytes,0,readInputRegistersLength); |
||||
InputRegister = InputRegistersBytes.ToUShortArray(); |
||||
return true; |
||||
case ModbusFunctionType.WriteSingleCoil: |
||||
return true; |
||||
case ModbusFunctionType.WriteSingleHoldingRegister: |
||||
return true; |
||||
case ModbusFunctionType.WriteMultiCoil: |
||||
return true; |
||||
case ModbusFunctionType.WriteMultiHoldingRegister: |
||||
return true; |
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
#endregion |
||||
|
||||
#region Modbus RTU Request and Response,Used RS-485 for Physic layer |
||||
public struct ModbusRTU_ReadCoils : IRequest{ |
||||
public const byte FunctionCode = 0x01; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusRTU_ReadCoils(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>2000){ |
||||
ReadCount = 2000; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_ReadDiscreteInput : IRequest{ |
||||
public const byte FunctionCode = 0x02; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusRTU_ReadDiscreteInput(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>2000){ |
||||
ReadCount = 2000; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_ReadHoldingRegisters : IRequest{ |
||||
public const byte FunctionCode = 0x03; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusRTU_ReadHoldingRegisters(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>125){ |
||||
ReadCount = 125; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_ReadInputRegisters : IRequest{ |
||||
public const byte FunctionCode = 0x04; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort ReadCount { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress"></param> |
||||
/// <param name="registerAddress"></param> |
||||
/// <param name="readCount">Read count should be less than 2000</param> |
||||
public ModbusRTU_ReadInputRegisters(byte deviceAddress,ushort registerAddress,ushort readCount){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
ReadCount = readCount; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
if(ReadCount>125){ |
||||
ReadCount = 125; |
||||
} |
||||
byte[] registerValues = ReadCount.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_WriteSingleCoil : IRequest{ |
||||
public const byte FunctionCode = 0x05; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public bool Value { set; get; } |
||||
|
||||
public ModbusRTU_WriteSingleCoil(byte deviceAddress,ushort registerAddress,bool value){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
Value = value; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
byte[] registerValues = {0x00,0x00}; |
||||
if(Value){ |
||||
registerValues[0]=0xFF; |
||||
} |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_WriteSingleHoldingRegister : IRequest{ |
||||
public const byte FunctionCode = 0x06; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterAddress { set; get; } |
||||
public ushort Value { set; get; } |
||||
|
||||
public ModbusRTU_WriteSingleHoldingRegister(byte deviceAddress,ushort registerAddress,ushort value){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterAddress = registerAddress; |
||||
Value = value; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
byte[] protocolRequest = { DeviceAddress , FunctionCode }; |
||||
protocolRequest = protocolRequest.Concat(RegisterAddress.ToBytes()).ToArray(); |
||||
byte[] registerValues = Value.ToBytes(); |
||||
protocolRequest = protocolRequest.Concat(registerValues).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_WriteMultiCoil : IRequest{ |
||||
public const byte FunctionCode = 0x0F; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
public bool[] Values { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress">usual use 0x01 for device address</param> |
||||
/// <param name="registerStartAddress"></param> |
||||
/// <param name="values">Values length should be less than 2000</param> |
||||
public ModbusRTU_WriteMultiCoil(byte deviceAddress,ushort registerStartAddress,bool[] values){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterStartAddress = registerStartAddress; |
||||
Values = values; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
|
||||
byte[] protocolRequest = {DeviceAddress,FunctionCode}; |
||||
protocolRequest = protocolRequest.Concat(RegisterStartAddress.ToBytes()).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(((ushort)Values.Length).ToBytes()).ToArray(); |
||||
|
||||
//Length range should be 1-2000 0x0001-0x07D0,otherwise delete the data after 2000 |
||||
if(Values.Length>2000){ |
||||
bool[] SourceValues = Values; |
||||
Values = new bool[2000]; |
||||
Array.Copy(Values,0,SourceValues,0,2000); |
||||
} |
||||
//bool array 2000 => byte array 250 |
||||
byte[] valueGroup = Values.ToByteArray(); |
||||
byte valueLength = (byte)valueGroup.Length; |
||||
protocolRequest = protocolRequest.Append(valueLength).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(valueGroup).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Start write at Register start address,such as 0x03,write order by order like 0x03,0x04,0x05...,write count is the value array length |
||||
/// </summary> |
||||
public struct ModbusRTU_WriteMultiHoldingRegister : IRequest |
||||
{ |
||||
public const byte FunctionCode = 0x10; |
||||
|
||||
public const ushort MessageId = 0xFF10; |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
public ushort[] Values { set; get; } |
||||
|
||||
/// <summary> |
||||
/// Construct the protocol |
||||
/// </summary> |
||||
/// <param name="deviceAddress">usual use 0x01 for device address</param> |
||||
/// <param name="registerStartAddress"></param> |
||||
/// <param name="values">Values length should be less than 125</param> |
||||
public ModbusRTU_WriteMultiHoldingRegister(byte deviceAddress,ushort registerStartAddress,ushort[] values){ |
||||
DeviceAddress = deviceAddress; |
||||
RegisterStartAddress = registerStartAddress; |
||||
Values = values; |
||||
} |
||||
public byte[] ToProtocolByteData() |
||||
{ |
||||
|
||||
byte[] protocolRequest = {DeviceAddress,FunctionCode}; |
||||
protocolRequest = protocolRequest.Concat(RegisterStartAddress.ToBytes()).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(((ushort)Values.Length).ToBytes()).ToArray(); |
||||
|
||||
//Length range should be 1-125 0x0001-0x07D,otherwise delete the data after 125 |
||||
if(Values.Length>125){ |
||||
ushort[] SourceValues = Values; |
||||
Values = new ushort[125]; |
||||
Array.Copy(Values,0,SourceValues,0,125); |
||||
} |
||||
//ushort array 125 => byte array 250 |
||||
byte[] valueGroup = {}; |
||||
foreach(ushort value in Values){ |
||||
byte[] registerValues = value.ToBytes(); |
||||
valueGroup = valueGroup.Concat(registerValues).ToArray(); |
||||
} |
||||
byte valueLength = (byte)valueGroup.Length; |
||||
protocolRequest = protocolRequest.Append(valueLength).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(valueGroup).ToArray(); |
||||
protocolRequest = protocolRequest.Concat(protocolRequest.CalculateCRC16Modbus().ToBytes()).ToArray(); |
||||
return protocolRequest; |
||||
} |
||||
|
||||
public string ToProtocolData() |
||||
{ |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
public struct ModbusRTU_Response : IResponse |
||||
{ |
||||
public bool[] Coil { set; get; } |
||||
public bool[] DiscreteInput { set; get; } |
||||
public ushort[] HoldingRegister { set; get; } |
||||
public ushort[] InputRegister { set; get; } |
||||
public byte FunctionCode { set; get; } |
||||
public byte DeviceAddress { set; get; } |
||||
public ushort RegisterStartAddress { set; get; } |
||||
|
||||
public byte[] SourceData { set; get; } |
||||
public ModbusFunctionType FunctionType { set; get; } |
||||
|
||||
public bool TrySetData(string protocolData, byte[] protocolBytes) |
||||
{ |
||||
try |
||||
{ |
||||
if(protocolBytes==null && protocolBytes.Length < 6){ |
||||
return false; |
||||
} |
||||
SourceData = protocolBytes; |
||||
DeviceAddress = protocolBytes[0]; |
||||
FunctionCode = protocolBytes[1]; |
||||
FunctionType = (ModbusFunctionType)protocolBytes[1]; |
||||
|
||||
//check crc verify is success |
||||
byte[] resultArray = new byte[protocolBytes.Length - 2]; |
||||
Array.Copy(protocolBytes, 0, resultArray, 0, protocolBytes.Length - 2); |
||||
byte[] crcArray = new byte[2]; |
||||
Array.Copy(protocolBytes, protocolBytes.Length - 2, crcArray, 0, 2); |
||||
if(resultArray.CalculateCRC16Modbus()!=crcArray.ToUShort()){ |
||||
return false; |
||||
} |
||||
|
||||
//every response's start should be 0xff,because the request's start is 0xff |
||||
switch(FunctionType){ |
||||
case ModbusFunctionType.ReadCoil: |
||||
byte readCoilLength = protocolBytes[2]; |
||||
byte[] CoilBytes = new byte[readCoilLength]; |
||||
Array.Copy(protocolBytes,3,CoilBytes,0,readCoilLength); |
||||
Coil = CoilBytes.ToBoolArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadDiscreteInput: |
||||
byte readDiscreteInputLength = protocolBytes[2]; |
||||
byte[] DiscreteInputBytes = new byte[readDiscreteInputLength]; |
||||
Array.Copy(protocolBytes,3,DiscreteInputBytes,0,readDiscreteInputLength); |
||||
DiscreteInput = DiscreteInputBytes.ToBoolArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadHoldingRegisters: |
||||
byte readHoldingRegistersLength = protocolBytes[2]; |
||||
byte[] HoldingRegistersBytes = new byte[readHoldingRegistersLength]; |
||||
Array.Copy(protocolBytes,3,HoldingRegistersBytes,0,readHoldingRegistersLength); |
||||
HoldingRegister = HoldingRegistersBytes.ToUShortArray(); |
||||
return true; |
||||
case ModbusFunctionType.ReadInputRegisters: |
||||
byte readInputRegistersLength = protocolBytes[2]; |
||||
byte[] InputRegistersBytes = new byte[readInputRegistersLength]; |
||||
Array.Copy(protocolBytes,3,InputRegistersBytes,0,readInputRegistersLength); |
||||
InputRegister = InputRegistersBytes.ToUShortArray(); |
||||
return true; |
||||
case ModbusFunctionType.WriteSingleCoil: |
||||
return true; |
||||
case ModbusFunctionType.WriteSingleHoldingRegister: |
||||
return true; |
||||
case ModbusFunctionType.WriteMultiCoil: |
||||
return true; |
||||
case ModbusFunctionType.WriteMultiHoldingRegister: |
||||
return true; |
||||
default: |
||||
return false; |
||||
} |
||||
|
||||
} |
||||
catch (Exception) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
#endregion |
||||
|
||||
public enum ModbusFunctionType{ |
||||
None = 0x00, |
||||
ReadCoil = 0x01, |
||||
ReadDiscreteInput = 0x02, |
||||
ReadHoldingRegisters = 0x03, |
||||
ReadInputRegisters = 0x04, |
||||
WriteSingleCoil = 0x05, |
||||
WriteSingleHoldingRegister = 0x06, |
||||
WriteMultiCoil = 0x0f, |
||||
WriteMultiHoldingRegister = 0x10 |
||||
} |
||||
} |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Drawing.Printing; |
||||
using System.IO; |
||||
using System.Net.Http; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGHttpClient : IEGFramework, IModule |
||||
{ |
||||
public HttpClient HTTPClient { set; get; } = new HttpClient(); |
||||
|
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
|
||||
public void Init() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public async Task<TResponse> HttpRequest<TResponse>(string hostUrl,IRequest request,ProtocolType protocolType = ProtocolType.HttpGet,EGFormData formData = null) where TResponse : IResponse,new(){ |
||||
// Call asynchronous network methods in a try/catch block to handle exceptions. |
||||
try |
||||
{ |
||||
HttpContent httpContent = new StringContent("",Encoding.UTF8,"application/json"); |
||||
if(formData != null){ |
||||
MultipartFormDataContent formContent = new MultipartFormDataContent(); |
||||
foreach(KeyValuePair<string,string> pair in formData.FormStrings){ |
||||
formContent.Add(new StringContent(pair.Value,Encoding.UTF8),pair.Key); |
||||
} |
||||
foreach(KeyValuePair<string,byte[]> pair in formData.FormBytes){ |
||||
formContent.Add(new ByteArrayContent(pair.Value),pair.Key,pair.Key+"."+formData.Suffix); |
||||
} |
||||
foreach(KeyValuePair<string,Stream> pair in formData.FormStreams){ |
||||
formContent.Add(new StreamContent(pair.Value),pair.Key,pair.Key+"."+formData.Suffix); |
||||
} |
||||
httpContent = formContent; |
||||
} |
||||
else if(request.ToProtocolData() != null && request.ToProtocolData() != ""){ |
||||
httpContent = new StringContent(request.ToProtocolData(),Encoding.UTF8,"application/json"); |
||||
}else if (request.ToProtocolByteData() != null){ |
||||
httpContent = new ByteArrayContent(request.ToProtocolByteData()); |
||||
} |
||||
HttpResponseMessage httpResponse; |
||||
switch(protocolType){ |
||||
case ProtocolType.HttpGet: |
||||
httpResponse = await HTTPClient.GetAsync(hostUrl); |
||||
break; |
||||
case ProtocolType.HttpPost: |
||||
httpResponse = await HTTPClient.PostAsync(hostUrl,httpContent); |
||||
break; |
||||
case ProtocolType.HttpPut: |
||||
httpResponse = await HTTPClient.PostAsync(hostUrl,httpContent); |
||||
break; |
||||
case ProtocolType.HttpPatch: |
||||
httpResponse = await HTTPClient.PostAsync(hostUrl,httpContent); |
||||
break; |
||||
case ProtocolType.HttpDelete: |
||||
httpResponse = await HTTPClient.DeleteAsync(hostUrl); |
||||
break; |
||||
default: |
||||
httpResponse = await HTTPClient.GetAsync(hostUrl); |
||||
break; |
||||
} |
||||
httpResponse.EnsureSuccessStatusCode(); |
||||
byte[] responseBytes = await httpResponse.Content.ReadAsByteArrayAsync(); |
||||
string responseBody = await httpResponse.Content.ReadAsStringAsync(); |
||||
TResponse response = new TResponse(); |
||||
response.TrySetData(responseBody,responseBytes); |
||||
return response; |
||||
} |
||||
catch (HttpRequestException e) |
||||
{ |
||||
Console.WriteLine(e.Message); |
||||
return default; |
||||
} |
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
} |
||||
|
||||
public class EGFormData{ |
||||
public string Suffix = ""; |
||||
public Dictionary<string,string> FormStrings = new Dictionary<string, string>(); |
||||
public Dictionary<string,byte[]> FormBytes = new Dictionary<string, byte[]>(); |
||||
public Dictionary<string,System.IO.Stream> FormStreams = new Dictionary<string, System.IO.Stream>(); |
||||
} |
||||
public static class CanGetEGHttpClientExtension{ |
||||
public static EGHttpClient EGHttpClient(this IEGFramework self){ |
||||
return self.GetModule<EGHttpClient>(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Specialized; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Net; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using Newtonsoft.Json; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGHttpServer : IEGFramework, IModule |
||||
{ |
||||
public HttpListener HttpServer { set; get; } |
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
|
||||
public Dictionary<string,HttpListenerResponse> ResponsePools { set; get; } = new Dictionary<string, HttpListenerResponse>(); |
||||
public void Init() |
||||
{ |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// if you are in Win7 or newest system, you should add prefix in urlacl by cmd for example: netsh http add urlacl url=http://+:6555/index/ user=Everyone |
||||
/// </summary> |
||||
/// <param name="prefix"></param> |
||||
/// <returns></returns> |
||||
public async void Listen(string prefix){ |
||||
if(!HttpListener.IsSupported){ |
||||
return; |
||||
} |
||||
if(HttpServer == null){ |
||||
HttpServer = new HttpListener(); |
||||
} |
||||
HttpServer.Prefixes.Add(prefix); |
||||
if(!HttpServer.IsListening){ |
||||
HttpServer.Start(); |
||||
HttpListenerContext context = await HttpServer.GetContextAsync(); |
||||
|
||||
HttpListenerRequest request = context.Request; |
||||
string responseKey = ""; |
||||
switch (request.HttpMethod) |
||||
{ |
||||
case "POST": |
||||
{ |
||||
Stream stream = context.Request.InputStream; |
||||
StreamReader reader = new StreamReader(stream, Encoding.UTF8); |
||||
byte[] postBuffer = new byte[stream.Length]; |
||||
stream.Read(postBuffer,0,postBuffer.Length); |
||||
string postString = reader.ReadToEnd(); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(postString,postBuffer,"GET:"+context.User.ToString(), ProtocolType.HttpServer); |
||||
this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
break; |
||||
case "GET": |
||||
{ |
||||
NameValueCollection data = request.QueryString; |
||||
Dictionary<string,string> getDic = data.AllKeys.ToDictionary(k=>k,k=>data[k]); |
||||
string getData = JsonConvert.SerializeObject(getDic); |
||||
byte[] getBuffer = StringEncoding.GetBytes(getData); |
||||
responseKey = "GET:"+this.GetTimeStamp().ToString(); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(getData,getBuffer,responseKey, ProtocolType.HttpServer); |
||||
this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
break; |
||||
case "PUT": |
||||
{ |
||||
Stream stream = context.Request.InputStream; |
||||
StreamReader reader = new StreamReader(stream, Encoding.UTF8); |
||||
byte[] postBuffer = new byte[stream.Length]; |
||||
stream.Read(postBuffer,0,postBuffer.Length); |
||||
string postData = reader.ReadToEnd(); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(postData,postBuffer,"PUT:"+context.User.ToString(), ProtocolType.HttpServer); |
||||
this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
break; |
||||
case "PATCH": |
||||
{ |
||||
Stream stream = context.Request.InputStream; |
||||
StreamReader reader = new StreamReader(stream, Encoding.UTF8); |
||||
byte[] postBuffer = new byte[stream.Length]; |
||||
stream.Read(postBuffer,0,postBuffer.Length); |
||||
string postData = reader.ReadToEnd(); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(postData,postBuffer,"PATCH:"+context.User.ToString(), ProtocolType.HttpServer); |
||||
this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
break; |
||||
case "DELETE": |
||||
{ |
||||
NameValueCollection data = request.QueryString; |
||||
Dictionary<string,string> getDic = data.AllKeys.ToDictionary(k=>k,k=>data[k]); |
||||
string getData = JsonConvert.SerializeObject(getDic); |
||||
byte[] getBuffer = StringEncoding.GetBytes(getData); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(getData,getBuffer,"DELETE:"+context.User.ToString(), ProtocolType.HttpServer); |
||||
this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
break; |
||||
} |
||||
HttpListenerResponse response = context.Response; |
||||
response.AppendHeader("Access-Control-Allow-Origin", "*"); |
||||
response.AppendHeader("Access-Control-Allow-Credentials", "true"); |
||||
response.AppendHeader("Server", "MyIIS"); |
||||
response.StatusCode = 200; |
||||
|
||||
ResponsePools.Add("",response); |
||||
|
||||
} |
||||
} |
||||
|
||||
public async void Response(string responseKey,string responseString = "",byte[] responseByte = null){ |
||||
#region 返回应答 |
||||
// Construct a response. |
||||
byte[] buffer = StringEncoding.GetBytes(responseString); |
||||
// Get a response stream and write the response to it. |
||||
ResponsePools[responseKey].ContentLength64 = buffer.Length; |
||||
System.IO.Stream output = ResponsePools[responseKey].OutputStream; |
||||
await output.WriteAsync(buffer, 0, buffer.Length); |
||||
// You must close the output stream. |
||||
output.Close(); |
||||
#endregion |
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
|
||||
} |
||||
|
||||
public static class CanGetEGHttpServerExtension{ |
||||
public static EGHttpServer EGHttpServer(this IEGFramework self){ |
||||
return self.GetModule<EGHttpServer>(); |
||||
} |
||||
|
||||
public static void EGHttpServerListen(this IEGFramework self ,string prefix){ |
||||
self.GetModule<EGHttpServer>().Listen(prefix); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
using System.IO.Ports; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGSerialPort : IModule,IEGFramework,IProtocolSend,IProtocolReceived |
||||
{ |
||||
public Dictionary<string,SerialPort> SerialPortDevices { set; get; } = new Dictionary<string, SerialPort>(); |
||||
public Dictionary<string,int> SerialPortMapping { set; get; } = new Dictionary<string, int>(); |
||||
|
||||
public int DefaultBaudRate { set; get; } = 115200; |
||||
|
||||
public string ErrorLogs { set; get; } |
||||
|
||||
public string ReceivedStr { set; get; } = ""; |
||||
|
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
|
||||
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>(); |
||||
|
||||
public void Init() |
||||
{ |
||||
this.EGRegisterSendAction(request=>{ |
||||
if(request.protocolType == ProtocolType.SerialPort){ |
||||
if(request.req.ToProtocolData() != "" && request.req.ToProtocolData() != null){ |
||||
this.SendSerialStringData(request.sender,request.req.ToProtocolData()); |
||||
} |
||||
if(request.req.ToProtocolByteData().Length > 0 && request.req.ToProtocolByteData() != null){ |
||||
this.SendSerialByteData(request.sender,request.req.ToProtocolByteData()); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Queue<ResponseMsg> GetReceivedMsg() |
||||
{ |
||||
return this.ResponseMsgs; |
||||
} |
||||
|
||||
public void SetEncoding(Encoding encoding){ |
||||
this.StringEncoding = encoding; |
||||
} |
||||
|
||||
public Encoding GetEncoding(){ |
||||
return StringEncoding; |
||||
} |
||||
|
||||
public List<string> RefreshSerialPort(){ |
||||
string[] portNames = SerialPort.GetPortNames(); |
||||
SerialPortMapping.Clear(); |
||||
int index = 0; |
||||
foreach (string portName in portNames) |
||||
{ |
||||
SerialPortMapping.Add(portName,index); |
||||
index++; |
||||
} |
||||
return SerialPortMapping.Keys.ToList(); |
||||
} |
||||
|
||||
public void SetBaudRate(int baudRate){ |
||||
this.DefaultBaudRate = baudRate; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Open serial port with check if target serial port isOpen. |
||||
/// </summary> |
||||
/// <param name="serialPort"></param> |
||||
public bool Open(string serialPort){ |
||||
try{ |
||||
if(!SerialPortDevices.ContainsKey(serialPort)){ |
||||
SerialPort newPort = new SerialPort(serialPort, DefaultBaudRate, Parity.None, 8, StopBits.One); |
||||
SerialPortDevices.Add(serialPort,newPort); |
||||
if (!SerialPortDevices[serialPort].IsOpen) |
||||
{ |
||||
SerialPortDevices[serialPort].Open(); |
||||
SerialPortDevices[serialPort].DataReceived += SerialPort_DataReceived; |
||||
} |
||||
}else{ |
||||
if(!SerialPortDevices[serialPort].IsOpen){ |
||||
SerialPortDevices[serialPort].Open(); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
catch(Exception e){ |
||||
ErrorLogs = "[open port error]" + e.ToString(); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Close serial port with check if target serial port isOpen. |
||||
/// </summary> |
||||
/// <param name="serialPort"></param> |
||||
public void Close(string serialPort){ |
||||
if(SerialPortDevices.ContainsKey(serialPort)){ |
||||
if (SerialPortDevices[serialPort].IsOpen) |
||||
{ |
||||
SerialPortDevices[serialPort].Close(); |
||||
SerialPortDevices.Remove(serialPort); |
||||
} |
||||
}else{ |
||||
//Not found in SerialPortDevices,need add? |
||||
} |
||||
} |
||||
|
||||
public bool SendSerialByteData(string serialPort,byte[] data){ |
||||
// if serial port not open,open first |
||||
try{ |
||||
bool isSuccessPort = Open(serialPort); |
||||
if(isSuccessPort){ |
||||
SerialPortDevices[serialPort].Write(data, 0, data.Length); |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}catch(Exception e){ |
||||
ErrorLogs = "[write error]" + e.ToString(); |
||||
return false; |
||||
} |
||||
} |
||||
public void SendByteData(string destination,byte[] data){ |
||||
SendSerialByteData(destination,data); |
||||
} |
||||
|
||||
public bool SendByteDataOnce(string serialPort,byte[] data){ |
||||
bool isSuccessSend = SendSerialByteData(serialPort,data); |
||||
if(isSuccessSend){ |
||||
SerialPortDevices[serialPort].Close(); |
||||
SerialPortDevices.Remove(serialPort); |
||||
} |
||||
return isSuccessSend; |
||||
} |
||||
|
||||
public bool SendSerialStringData(string serialPort,string data){ |
||||
// if serial port not open,open first |
||||
try{ |
||||
bool isSuccessPort = Open(serialPort); |
||||
if(isSuccessPort){ |
||||
byte[] encodingData = StringEncoding.GetBytes(data); |
||||
SerialPortDevices[serialPort].Write(encodingData, 0, encodingData.Length); |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}catch(Exception e){ |
||||
ErrorLogs = "[write error]" + e.ToString(); |
||||
return false; |
||||
} |
||||
} |
||||
public void SendStringData(string destination,string data){ |
||||
SendSerialStringData(destination,data); |
||||
} |
||||
|
||||
public bool SendStringDataOnce(string serialPort,string data){ |
||||
bool isSuccessSend = SendSerialStringData(serialPort,data); |
||||
if(isSuccessSend){ |
||||
SerialPortDevices[serialPort].Close(); |
||||
SerialPortDevices.Remove(serialPort); |
||||
} |
||||
return isSuccessSend; |
||||
} |
||||
|
||||
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) |
||||
{ |
||||
//await Task.Run(() => {}).ConfigureAwait(false); |
||||
SerialPort serialPort = (SerialPort)sender; |
||||
if(serialPort.BytesToRead > 0){ |
||||
int bufferSize = serialPort.BytesToRead; |
||||
byte[] buffer = new byte[bufferSize]; |
||||
serialPort.Read(buffer,0,serialPort.BytesToRead); |
||||
string str = StringEncoding.GetString(buffer); |
||||
Console.WriteLine(buffer.ToStringByHex()); |
||||
ResponseMsgs.Enqueue(new ResponseMsg(str,buffer,serialPort.PortName,ProtocolType.SerialPort)); |
||||
//this.EGOnReceivedData(new ResponseMsg(str,buffer,serialPort.PortName,ProtocolType.SerialPort)); |
||||
} |
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
} |
||||
public static class CanGetEGSerialPortExtension{ |
||||
public static EGSerialPort EGSerialPort(this IEGFramework self){ |
||||
return self.GetModule<EGSerialPort>(); |
||||
} |
||||
|
||||
public static SerialPort EGGetSerialPort(this IEGFramework self,string serial){ |
||||
return self.GetModule<EGSerialPort>().SerialPortDevices[serial]; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Net.Sockets; |
||||
using System.Threading.Tasks; |
||||
using System.Net; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGTCPClient : IModule, IEGFramework, IProtocolSend, IProtocolReceived |
||||
{ |
||||
public Dictionary<string,TcpClient> TCPClientDevices { set; get; } = new Dictionary<string, TcpClient>(); |
||||
|
||||
public string ErrorLogs { set; get; } |
||||
|
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
|
||||
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>(); |
||||
|
||||
public void Init() |
||||
{ |
||||
this.EGRegisterSendAction(request=>{ |
||||
if(request.protocolType == ProtocolType.TCPClient){ |
||||
if(request.req.ToProtocolData() != null && request.req.ToProtocolData() != ""){ |
||||
this.SendStringData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolData()); |
||||
} |
||||
if(request.req.ToProtocolByteData() != null && request.req.ToProtocolByteData().Length > 0){ |
||||
this.SendByteData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolByteData()); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Connect Tcp client to server with check if target server is listened. |
||||
/// </summary> |
||||
public async Task<bool> ConnectTCP(string host,int port){ |
||||
try{ |
||||
if(!TCPClientDevices.ContainsKey(host + ":" + port)){ |
||||
TcpClient tcpClient = new TcpClient(); |
||||
await tcpClient.ConnectAsync(host,port); |
||||
//Print("Connect Tcp success in "+tcpClient.Client.RemoteEndPoint.ToString()); |
||||
TCPClientDevices.Add(host + ":" + port,tcpClient); |
||||
_ = HandleClientAsync(tcpClient,host,port); |
||||
}else{ |
||||
if(!TCPClientDevices[host + ":" + port].Connected){ |
||||
await TCPClientDevices[host + ":" + port].ConnectAsync(host,port); |
||||
_ = HandleClientAsync(TCPClientDevices[host + ":" + port],host,port); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
catch(Exception e){ |
||||
ErrorLogs = "[open port error]" + e.ToString(); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Disconnect Tcp client to server. |
||||
/// </summary> |
||||
public void DisconnectTCP(string host,int port){ |
||||
if(TCPClientDevices.ContainsKey(host + ":" + port)){ |
||||
if (TCPClientDevices[host + ":" + port].Connected) |
||||
{ |
||||
TCPClientDevices[host + ":" + port].Close(); |
||||
TCPClientDevices.Remove(host + ":" + port); |
||||
} |
||||
}else{ |
||||
//Not found in TCPClientDevices,need add? |
||||
} |
||||
} |
||||
|
||||
|
||||
public void SetEncoding(Encoding textEncoding) |
||||
{ |
||||
this.StringEncoding = textEncoding; |
||||
} |
||||
public async void SendByteData(string host,int port,byte[] data){ |
||||
// if serial port not open,open first |
||||
try{ |
||||
bool result = await ConnectTCP(host,port); |
||||
if(result){ |
||||
await TCPClientDevices[host + ":" + port].GetStream().WriteAsync(data,0,data.Length); |
||||
} |
||||
}catch(Exception e){ |
||||
ErrorLogs = "[write error]" + e.ToString(); |
||||
} |
||||
} |
||||
public void SendByteData(string destination,byte[] data){ |
||||
SendByteData(destination.GetHostByIp(),destination.GetPortByIp(),data); |
||||
} |
||||
|
||||
public void SendByteDataOnce(string host,int port,byte[] data){ |
||||
SendByteData(host,port,data); |
||||
DisconnectTCP(host,port); |
||||
} |
||||
|
||||
public void SendStringData(string host,int port,string str){ |
||||
SendByteData(host,port,StringEncoding.GetBytes(str)); |
||||
} |
||||
|
||||
public void SendStringData(string destination,string data){ |
||||
SendStringData(destination.GetHostByIp(),destination.GetPortByIp(),data); |
||||
} |
||||
public void SendStringDataOnce(string host,int port,string str){ |
||||
SendStringData(host,port,str); |
||||
DisconnectTCP(host,port); |
||||
} |
||||
|
||||
public Queue<ResponseMsg> GetReceivedMsg() |
||||
{ |
||||
return ResponseMsgs; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// UpdateStatus |
||||
/// </summary> |
||||
public async void CheckAndRelink(){ |
||||
foreach(TcpClient tcpClient in TCPClientDevices.Values){ |
||||
if(!tcpClient.Connected){ |
||||
await tcpClient.ConnectAsync((IPEndPoint)tcpClient.Client.RemoteEndPoint); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public async Task HandleClientAsync(TcpClient client,string host,int port) |
||||
{ |
||||
try |
||||
{ |
||||
NetworkStream stream = client.GetStream(); |
||||
string ClientName = host+":"+port; |
||||
while (true) |
||||
{ |
||||
byte[] buffer = new byte[1024]; |
||||
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); |
||||
if (bytesRead == 0) |
||||
{ |
||||
break; |
||||
} |
||||
string data = StringEncoding.GetString(buffer, 0, bytesRead); |
||||
byte[] receivedByte = new byte[bytesRead]; |
||||
Array.Copy(buffer, 0, receivedByte, 0, bytesRead); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(data,receivedByte,ClientName, ProtocolType.TCPClient); |
||||
ResponseMsgs.Enqueue(receivedMsgs); |
||||
//this.EGOnReceivedData(receivedMsgs); |
||||
} |
||||
DeleteClient(client,host,port); |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public void DeleteClient(TcpClient client,string host,int port) |
||||
{ |
||||
client.Close(); |
||||
string clientName = host+":"+port; |
||||
if (TCPClientDevices.ContainsKey(clientName)) { |
||||
TCPClientDevices.Remove(clientName); |
||||
} |
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
public static class CanGetEGTCPClientExtension{ |
||||
public static EGTCPClient EGTCPClient(this IEGFramework self){ |
||||
return self.GetModule<EGTCPClient>(); |
||||
} |
||||
|
||||
public static TcpClient EGGetTCPClient(this IEGFramework self,string host,int port){ |
||||
return self.GetModule<EGTCPClient>().TCPClientDevices[host + ":" + port]; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Net; |
||||
using System.Net.Sockets; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using System.Threading; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGTCPServer : IModule, IEGFramework,IProtocolReceived |
||||
{ |
||||
public TcpListener TcpServer { set; get; } |
||||
|
||||
public bool IsListening { set; get; } |
||||
public Dictionary<string, TcpClient> LinkedClients { set; get; } = new Dictionary<string, TcpClient>(); |
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
public List<string> ClientNames = new List<string>(); |
||||
|
||||
public EasyEvent<string> OnClientConnect { set; get; } = new EasyEvent<string>(); |
||||
public EasyEvent<string> OnClientDisconnect { set; get; } = new EasyEvent<string>(); |
||||
|
||||
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>(); |
||||
|
||||
public string ErrorLogs { set; get; } |
||||
public void Init() |
||||
{ |
||||
this.EGRegisterSendAction(request => { |
||||
if(request.protocolType == ProtocolType.TCPServer){ |
||||
if(request.req.ToProtocolData() != null && request.req.ToProtocolData() != ""){ |
||||
ResponseStringData(request.sender,request.req.ToProtocolData()); |
||||
} |
||||
if(request.req.ToProtocolByteData() != null && request.req.ToProtocolByteData().Length > 0){ |
||||
ResponseByteData(request.sender,request.req.ToProtocolByteData()); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Queue<ResponseMsg> GetReceivedMsg() |
||||
{ |
||||
return ResponseMsgs; |
||||
} |
||||
|
||||
public async void StartServer(int port) |
||||
{ |
||||
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, port); |
||||
TcpServer = new(ipEndPoint); |
||||
try |
||||
{ |
||||
TcpServer.Start(); |
||||
IsListening = true; |
||||
while (IsListening) |
||||
{ |
||||
TcpClient client = await TcpServer.AcceptTcpClientAsync(); |
||||
ClientNames.Add(client.Client.RemoteEndPoint.ToString()); |
||||
LinkedClients.Add(client.Client.RemoteEndPoint.ToString(), client); |
||||
OnClientConnect.Invoke(client.Client.RemoteEndPoint.ToString()); |
||||
_ = HandleClientAsync(client); |
||||
} |
||||
TcpServer.Stop(); |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public async Task HandleClientAsync(TcpClient client) |
||||
{ |
||||
try |
||||
{ |
||||
NetworkStream stream = client.GetStream(); |
||||
string ClientName = client.Client.RemoteEndPoint.ToString(); |
||||
while (true) |
||||
{ |
||||
byte[] buffer = new byte[1024]; |
||||
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); |
||||
if (bytesRead == 0) |
||||
{ |
||||
break; |
||||
} |
||||
string data = StringEncoding.GetString(buffer, 0, bytesRead); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(data,buffer,ClientName, ProtocolType.TCPServer); |
||||
//await Task.Run(() => OnDataReceived(receivedMsgs)).ConfigureAwait(false); |
||||
//this.EGOnReceivedData(receivedMsgs); |
||||
ResponseMsgs.Enqueue(receivedMsgs); |
||||
} |
||||
//await Task.Run(() => DeleteClient(client)).ConfigureAwait(false); |
||||
DeleteClient(client); |
||||
client.Close(); |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public async void ResponseByteData(string clientName,byte[] data){ |
||||
// if serial port not open,open first |
||||
try{ |
||||
await this.LinkedClients[clientName]?.GetStream().WriteAsync(data, 0, data.Length); |
||||
}catch(Exception e){ |
||||
ErrorLogs = "[write error]" + e.ToString(); |
||||
} |
||||
} |
||||
public void ResponseStringData(string clientName,string str){ |
||||
byte[] buffer = StringEncoding.GetBytes(str); |
||||
ResponseByteData(clientName,buffer); |
||||
} |
||||
|
||||
public void DeleteClient(TcpClient client) |
||||
{ |
||||
string clientName = client.Client.RemoteEndPoint.ToString(); |
||||
if (ClientNames.Contains(clientName)) { |
||||
ClientNames.Remove(clientName); |
||||
} |
||||
if (LinkedClients.ContainsKey(clientName)) { |
||||
LinkedClients.Remove(clientName); |
||||
} |
||||
OnClientDisconnect.Invoke(clientName); |
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
|
||||
} |
||||
|
||||
public static class CanGetEGTCPServerExtension{ |
||||
public static EGTCPServer EGTCPServer(this IEGFramework self){ |
||||
return self.GetModule<EGTCPServer>(); |
||||
} |
||||
|
||||
public static void EGTCPServerListen(this IEGFramework self ,int port){ |
||||
self.GetModule<EGTCPServer>().StartServer(port); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Net; |
||||
using System.Net.Sockets; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace EGFramework{ |
||||
public class EGUDP : IEGFramework, IModule, IProtocolSend, IProtocolReceived |
||||
{ |
||||
public Dictionary<int,UdpClient> UDPDevices { set; get; } = new Dictionary<int, UdpClient>(); |
||||
|
||||
public Encoding StringEncoding { set; get; } = Encoding.UTF8; |
||||
|
||||
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>(); |
||||
|
||||
public void Init() |
||||
{ |
||||
this.EGRegisterSendAction(request => { |
||||
if(request.protocolType == ProtocolType.UDP){ |
||||
if(request.req.ToProtocolData() != null && request.req.ToProtocolData() != ""){ |
||||
this.SendStringData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolData()); |
||||
} |
||||
if(request.req.ToProtocolByteData() != null && request.req.ToProtocolByteData().Length > 0){ |
||||
this.SendByteData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolByteData()); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public void ListenUDP(int localPort){ |
||||
if (!UDPDevices.ContainsKey(localPort)) { |
||||
try |
||||
{ |
||||
UdpClient udpDevice = new UdpClient(localPort); |
||||
UDPDevices.Add(localPort,udpDevice); |
||||
HandleUDPListenAsync(udpDevice); |
||||
//StartListening(localPort); |
||||
} |
||||
catch (Exception e){ |
||||
Console.WriteLine("Error" + e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void EndListenUDP(int localPort){ |
||||
if (UDPDevices.ContainsKey(localPort)) { |
||||
UDPDevices[localPort].Close(); |
||||
UDPDevices.Remove(localPort); |
||||
} |
||||
} |
||||
|
||||
public async void HandleUDPListenAsync(UdpClient client) |
||||
{ |
||||
try |
||||
{ |
||||
while (true) |
||||
{ |
||||
UdpReceiveResult data = await client.ReceiveAsync(); |
||||
string dataStr = StringEncoding.GetString(data.Buffer); |
||||
ResponseMsg receivedMsgs = new ResponseMsg(dataStr,data.Buffer,data.RemoteEndPoint.ToString(), ProtocolType.UDP); |
||||
//this.EGOnReceivedData(receivedMsgs); |
||||
ResponseMsgs.Enqueue(receivedMsgs); |
||||
} |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public void SendByteData(string host,int port,byte[] data){ |
||||
UdpClient udpClient = new UdpClient(); |
||||
try{ |
||||
udpClient.Send(data, data.Length, host, port); |
||||
} |
||||
catch ( Exception e ){ |
||||
Console.WriteLine(e.ToString()); |
||||
} |
||||
udpClient.Close(); |
||||
udpClient.Dispose(); |
||||
} |
||||
public void SendByteData(string destination,byte[] data){ |
||||
SendByteData(destination.GetHostByIp(),destination.GetPortByIp(),data); |
||||
} |
||||
|
||||
public void SendStringData(string host,int port,string data){ |
||||
byte[] buffer = StringEncoding.GetBytes(data); |
||||
this.SendByteData(host,port,buffer); |
||||
} |
||||
public void SendStringData(string destination,string data){ |
||||
SendStringData(destination.GetHostByIp(),destination.GetPortByIp(),data); |
||||
} |
||||
|
||||
public void SetEncoding(Encoding textEncoding){ |
||||
StringEncoding = textEncoding; |
||||
} |
||||
|
||||
public void BroadCastUDPMessage(string host,int port,byte[] message){ |
||||
|
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
|
||||
public Queue<ResponseMsg> GetReceivedMsg() |
||||
{ |
||||
return ResponseMsgs; |
||||
} |
||||
} |
||||
|
||||
public static class CanGetEGUDPExtension{ |
||||
public static EGUDP EGUDP(this IEGFramework self){ |
||||
return self.GetModule<EGUDP>(); |
||||
} |
||||
|
||||
public static void EGUDPListen(this IEGFramework self ,int port){ |
||||
self.GetModule<EGUDP>().ListenUDP(port); |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace EGFramework{ |
||||
public interface IProtocolSend{ |
||||
public void SendByteData(string destination,byte[] data); |
||||
public void SendStringData(string destination,string data); |
||||
public void SetEncoding(Encoding textEncoding); |
||||
} |
||||
public interface IProtocolReceived{ |
||||
public Queue<ResponseMsg> GetReceivedMsg(); |
||||
} |
||||
|
||||
public interface IProtocolListener{ |
||||
public bool IsEnabled(string ServiceName); |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,247 @@
@@ -0,0 +1,247 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using Microsoft.Data.Sqlite; |
||||
using Newtonsoft.Json; |
||||
|
||||
namespace EGFramework{ |
||||
public interface IEGSqlite{ |
||||
void SaveData<TData>(TData data) where TData : new(); |
||||
List<TData> GetDataSet<TData>() where TData : new(); |
||||
void InitDatabase(string dataBaseName); |
||||
} |
||||
public class EGSqlite : EGModule,IEGSqlite |
||||
{ |
||||
public string DBName = "Default"; |
||||
private string DefaultDBFolder = "SaveData"; |
||||
public SqliteConnection SqliteConn; |
||||
public string ExceptionMsg; |
||||
|
||||
public override void Init() |
||||
{ |
||||
if (!Directory.Exists(DefaultDBFolder)) |
||||
{ |
||||
Directory.CreateDirectory(DefaultDBFolder); |
||||
} |
||||
InitDatabase(DBName); |
||||
} |
||||
|
||||
public void InitDatabase(string dataBaseName) |
||||
{ |
||||
SqliteConn = new SqliteConnection("Data Source="+DefaultDBFolder+"/"+dataBaseName+".db;Mode=ReadWriteCreate;"); // Open the connection: |
||||
try |
||||
{ |
||||
SqliteConn.Open(); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
ExceptionMsg = ex.ToString(); |
||||
} |
||||
} |
||||
|
||||
//Save data to default sqlite database; |
||||
public void SaveData<TData>(TData data) where TData : new() |
||||
{ |
||||
// if table is not exist, create table and insert data to table,else insert into data to table |
||||
if(IsTableExist<TData>()){ |
||||
InsertData(data); |
||||
}else{ |
||||
CreateTable<TData>(); |
||||
InsertData(data); |
||||
} |
||||
} |
||||
/// <summary> |
||||
/// Get data from table where named type of TData |
||||
/// </summary> |
||||
/// <typeparam name="TData">Table name</typeparam> |
||||
/// <returns></returns> |
||||
public List<TData> GetDataSet<TData>() where TData : new() |
||||
{ |
||||
// query dataSet from table TData_List |
||||
List<TData> dataSet = new List<TData>(); |
||||
if(IsTableExist<TData>()){ |
||||
dataSet = SelectData<TData>(); |
||||
}else{ |
||||
ExceptionMsg = "No such table,ensure one data with type of TData has been saved at least!"; |
||||
return null; |
||||
} |
||||
return dataSet; |
||||
} |
||||
|
||||
#region SQL Operation |
||||
/// <summary> |
||||
/// Create table where table name is type of TData |
||||
/// </summary> |
||||
/// <typeparam name="TData"></typeparam> |
||||
/// <returns></returns> |
||||
public string CreateTable<TData>() where TData: new() { |
||||
string result = "Success:"; |
||||
try |
||||
{ |
||||
string sqlCommand = "CREATE TABLE " + typeof(TData).Name; |
||||
sqlCommand += "(\"ID\" INTEGER NOT NULL UNIQUE,"; |
||||
var properties = typeof(TData).GetFields(); |
||||
foreach(var property in properties){ |
||||
if(property.FieldType == typeof(int) || property.FieldType == typeof(bool) || property.FieldType.IsEnum){ |
||||
sqlCommand += "\"" + property.Name + "\" INTEGER" + " NOT NULL,"; |
||||
}else if(property.FieldType == typeof(double) || property.FieldType == typeof(float)){ |
||||
sqlCommand += "\"" + property.Name + "\" REAL" + " NOT NULL,"; |
||||
} |
||||
else{ |
||||
sqlCommand += "\"" + property.Name + "\" TEXT" + " NOT NULL,"; |
||||
} |
||||
} |
||||
sqlCommand += "PRIMARY KEY(\"ID\" AUTOINCREMENT))"; |
||||
SqliteCommand createCommand = new SqliteCommand(sqlCommand,SqliteConn); |
||||
result = result + createCommand.ExecuteNonQuery().ToString(); |
||||
} |
||||
catch (System.Exception e) |
||||
{ |
||||
return "Error:"+e; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Drop table where table name is type of TData |
||||
/// </summary> |
||||
/// <typeparam name="TData"></typeparam> |
||||
/// <returns></returns> |
||||
public string DropTable<TData>() where TData: new(){ |
||||
string result = "Success:"; |
||||
try |
||||
{ |
||||
string sqlCommand = "DROP TABLE " + typeof(TData).Name; |
||||
SqliteCommand createCommand = new SqliteCommand(sqlCommand,SqliteConn); |
||||
result = result + createCommand.ExecuteNonQuery().ToString(); |
||||
} |
||||
catch (System.Exception e) |
||||
{ |
||||
return "Error:"+e; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Insert data to table where table name is type of TData |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
/// <typeparam name="TData"></typeparam> |
||||
/// <returns>success or error</returns> |
||||
public string InsertData<TData>(TData data) where TData: new(){ |
||||
string result = "Success:"; |
||||
try |
||||
{ |
||||
string sqlCommand = "INSERT INTO " + typeof(TData).Name; |
||||
var properties = typeof(TData).GetFields(); |
||||
Dictionary<string,object> dataParams = new Dictionary<string, object>(); |
||||
foreach(var property in properties){ |
||||
dataParams.Add(property.Name,property.GetValue(data)); |
||||
if(property.FieldType==typeof(bool) || property.FieldType.IsEnum){ |
||||
// If property is bool type , save data to data base should be 0 or 1 instead of false or true; |
||||
// If property is Enum type , then transform data to int; |
||||
dataParams[property.Name] = System.Convert.ToInt32(dataParams[property.Name]); |
||||
}else if(property.FieldType.IsClass || property.FieldType.IsValueType && !property.FieldType.IsPrimitive && property.FieldType != typeof(string)){ |
||||
dataParams[property.Name] = JsonConvert.SerializeObject(dataParams[property.Name]); |
||||
} |
||||
} |
||||
sqlCommand += "("; |
||||
string keySet = ""; |
||||
foreach(string key in dataParams.Keys){ |
||||
keySet += key + ","; |
||||
} |
||||
keySet = keySet.TrimEnd(','); |
||||
sqlCommand += keySet; |
||||
sqlCommand += ") VALUES ("; |
||||
string valueSet = ""; |
||||
foreach(var value in dataParams.Values){ |
||||
if(value.GetType() == typeof(int) || value.GetType() == typeof(float) || value.GetType() == typeof(double)){ |
||||
valueSet += value + ","; |
||||
}else{ |
||||
valueSet += "'" + value + "',"; |
||||
} |
||||
} |
||||
valueSet = valueSet.TrimEnd(','); |
||||
sqlCommand += valueSet; |
||||
sqlCommand += ")"; |
||||
SqliteCommand createCommand = new SqliteCommand(sqlCommand,SqliteConn); |
||||
result = result + createCommand.ExecuteNonQuery().ToString(); |
||||
} |
||||
catch (System.Exception e) |
||||
{ |
||||
ExceptionMsg = e.ToString(); |
||||
return "Error:"+ExceptionMsg; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Query Data and return object list with TData type,Support Data Type:ClassObject,Enum,int,string.float,struct.Not support double,if double then auto convert to float |
||||
/// </summary> |
||||
/// <returns>List of TData or null ,if null then you can print ExceptionMsg to check your error</returns> |
||||
public List<TData> SelectData<TData>() where TData: new(){ |
||||
List<TData> resultList = new List<TData>(); |
||||
try |
||||
{ |
||||
string sqlCommand = "SELECT * FROM " + typeof(TData).Name; |
||||
SqliteCommand selectCommand = new SqliteCommand(sqlCommand,SqliteConn); |
||||
SqliteDataReader reader = selectCommand.ExecuteReader(); |
||||
var properties = typeof(TData).GetFields(); |
||||
|
||||
while (reader.Read()) |
||||
{ |
||||
TData dataRow = new TData(); |
||||
foreach(var property in properties){ |
||||
if(property.FieldType == reader[property.Name].GetType()){ |
||||
property.SetValue(dataRow,reader[property.Name]); |
||||
}else if(property.FieldType.IsEnum){ |
||||
object propertyEnum = Enum.Parse(property.FieldType,reader[property.Name].ToString()); |
||||
property.SetValue(dataRow,propertyEnum); |
||||
} |
||||
else if(property.FieldType.IsPrimitive) { |
||||
object propertyObject = System.Convert.ChangeType(reader[property.Name],property.FieldType); |
||||
property.SetValue(dataRow,propertyObject); |
||||
}else{ |
||||
object classObject = JsonConvert.DeserializeObject(reader[property.Name].ToString(),property.FieldType); |
||||
property.SetValue(dataRow,classObject); |
||||
} |
||||
} |
||||
resultList.Add(dataRow); |
||||
} |
||||
} |
||||
catch (System.Exception e) |
||||
{ |
||||
ExceptionMsg = e.ToString(); |
||||
return null; |
||||
} |
||||
return resultList; |
||||
} |
||||
|
||||
public bool IsTableExist<TData>() where TData:new(){ |
||||
try |
||||
{ |
||||
string sqlCommand = "SELECT name FROM sqlite_sequence"; |
||||
SqliteCommand selectCommand = new SqliteCommand(sqlCommand,SqliteConn); |
||||
SqliteDataReader reader = selectCommand.ExecuteReader(); |
||||
while (reader.Read()){ |
||||
if(reader["name"].ToString()==typeof(TData).Name){ |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
catch (System.Exception e) |
||||
{ |
||||
ExceptionMsg = e.ToString(); |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
#endregion |
||||
} |
||||
|
||||
public static class CanGetEGSqliteExtension{ |
||||
public static EGSqlite EGSqlite(this IEGFramework self){ |
||||
return EGArchitectureImplement.Interface.GetModule<EGSqlite>(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,232 @@
@@ -0,0 +1,232 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Net; |
||||
using System.Threading.Tasks; |
||||
using WebDav; |
||||
using System.Web; |
||||
using System.Net.Http; |
||||
|
||||
|
||||
namespace EGFramework{ |
||||
public class EGWebDav : IModule |
||||
{ |
||||
public string ServerUrl { set; get; } = ""; |
||||
private string UserName { set; get; } = ""; |
||||
private string Password { set; get; } = ""; |
||||
public bool IsInit { set; get; } |
||||
private WebDavClient WebDavClient { set; get; } |
||||
private string CurrentPath { set; get; } = "/"; |
||||
|
||||
public List<WebDavFileMsg> CurrentFileList { set; get; } = new List<WebDavFileMsg>(); |
||||
public void Init() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public IArchitecture GetArchitecture() |
||||
{ |
||||
return EGArchitectureImplement.Interface; |
||||
} |
||||
|
||||
public void InitClient(string serverUrl, string userName,string password){ |
||||
this.ServerUrl = serverUrl; |
||||
this.UserName = userName; |
||||
this.Password = password; |
||||
Dictionary<string,string> headersAdd = new Dictionary<string, string> |
||||
{ |
||||
{ "Connection", "keep-alive" }, |
||||
{ "Authorization", "Basic "+ EGWebDavExtension.EncodeCredentials(userName,password) } |
||||
}; |
||||
WebDavClient = new WebDavClient(new WebDavClientParams |
||||
{ |
||||
BaseAddress = new Uri(ServerUrl), |
||||
Credentials = new NetworkCredential(userName, password), |
||||
DefaultRequestHeaders = headersAdd |
||||
}); |
||||
Console.WriteLine("Client has been init"); |
||||
} |
||||
|
||||
//---------download or upload from WebDav server---------// |
||||
|
||||
/// <summary> |
||||
/// Download a file from dav path |
||||
/// </summary> |
||||
/// <param name="downloadUri">Such as /dav/Picture/Picture1.jpg</param> |
||||
/// <param name="localPath">download destination,such as C:\Users\W35\Pictures</param> |
||||
/// <param name="fileName">you can define file by this name,or by uri</param> |
||||
/// <returns></returns> |
||||
public async Task<bool> DownloadFile(string downloadUri,string localPath,string fileName = ""){ |
||||
if (fileName.Equals("")){ |
||||
fileName = Path.GetFileName(downloadUri); |
||||
} |
||||
using (var response = await WebDavClient.GetRawFile(downloadUri)) |
||||
{ |
||||
if(response.IsSuccessful == true){ |
||||
// use response.Stream |
||||
using (FileStream DestinationStream = File.Create(localPath + "/" + fileName)) |
||||
{ |
||||
await response.Stream.CopyToAsync(DestinationStream); |
||||
//Print("【WebDav】" + fileName + "下载成功!"); |
||||
} |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
public async Task<bool> DownloadFilProcessed(string downloadUri,string localPath,string fileName = ""){ |
||||
if (fileName.Equals("")){ |
||||
fileName = Path.GetFileName(downloadUri); |
||||
} |
||||
using (var response = await WebDavClient.GetProcessedFile(downloadUri)) |
||||
{ |
||||
if(response.IsSuccessful == true){ |
||||
// use response.Stream |
||||
using (FileStream DestinationStream = File.Create(localPath + "/" + fileName)) |
||||
{ |
||||
await response.Stream.CopyToAsync(DestinationStream); |
||||
//Print("【WebDav】" + fileName + "下载成功!"); |
||||
} |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Upload a file by localUrl |
||||
/// </summary> |
||||
/// <param name="localUrl">Such as C:\Users\W35\Pictures\Picture1.jpg</param> |
||||
/// <param name="uploadPath">upload destination,such as /dav/Picture</param> |
||||
/// <param name="fileName">you can define file by this name,or by local url</param> |
||||
/// <returns></returns> |
||||
public async Task<bool> UploadFile(string localUrl,string uploadPath,string fileName = ""){ |
||||
if (fileName.Equals("")){ |
||||
fileName = Path.GetFileName(localUrl); |
||||
} |
||||
// use response.Stream |
||||
var result = await WebDavClient.PutFile(uploadPath+"/"+fileName, File.OpenRead(localUrl)); |
||||
if(result.IsSuccessful){ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
//-----------operate disk-----------// |
||||
|
||||
/// <summary> |
||||
/// Default root path is "/",any path should be start with "/" |
||||
/// </summary> |
||||
/// <param name="currentPath"></param> |
||||
/// <returns></returns> |
||||
public async Task<List<WebDavFileMsg>> GetList(string currentPath){ |
||||
PropfindResponse result = await WebDavClient.Propfind(ServerUrl+currentPath); |
||||
List<WebDavFileMsg> ResultFileList = new List<WebDavFileMsg>(); |
||||
if (result.IsSuccessful) |
||||
{ |
||||
foreach (WebDavResource res in result.Resources) |
||||
{ |
||||
ResultFileList.Add(new WebDavFileMsg{ |
||||
FileName = res.DisplayName , |
||||
IsCollection = res.IsCollection , |
||||
ContentLength = res.ContentLength , |
||||
Uri = res.Uri , |
||||
LastUpdateTime = res.LastModifiedDate |
||||
}); |
||||
} |
||||
} |
||||
return ResultFileList; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// simple CD command, prop find all file message to CurrentFileList. |
||||
/// </summary> |
||||
/// <param name="destinationPath"></param> |
||||
/// <returns></returns> |
||||
public async Task ChangeDictionary(string destinationPath){ |
||||
CurrentPath = destinationPath; |
||||
PropfindResponse result = await WebDavClient.Propfind(ServerUrl+CurrentPath); |
||||
CurrentFileList.Clear(); |
||||
if (result.IsSuccessful) |
||||
{ |
||||
foreach (WebDavResource res in result.Resources) |
||||
{ |
||||
CurrentFileList.Add(new WebDavFileMsg{ |
||||
FileName = res.DisplayName , |
||||
IsCollection = res.IsCollection , |
||||
ContentLength = res.ContentLength , |
||||
Uri = res.Uri , |
||||
LastUpdateTime = res.LastModifiedDate |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// create a directory |
||||
/// </summary> |
||||
/// <param name="dictionaryName"></param> |
||||
/// <returns></returns> |
||||
public async Task MakeDictionary(string dictionaryName){ |
||||
await WebDavClient.Mkcol(dictionaryName); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// simple cp command, copy a file with differentName. |
||||
/// </summary> |
||||
/// <param name="sourceFile"></param> |
||||
/// <param name="copyFile"></param> |
||||
/// <returns></returns> |
||||
public async Task Copy(string sourceFile,string copyFile){ |
||||
await WebDavClient.Copy(sourceFile,copyFile); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// simple mv command, move a file with change fileName or different path. |
||||
/// </summary> |
||||
/// <param name="sourceFile"></param> |
||||
/// <param name="moveFile"></param> |
||||
/// <returns></returns> |
||||
public async Task Move(string sourceFile,string moveFile){ |
||||
await WebDavClient.Move(sourceFile,moveFile); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// simple rm command,delete a file. |
||||
/// </summary> |
||||
/// <param name="fileName"></param> |
||||
/// <returns></returns> |
||||
public async Task Remove(string fileName){ |
||||
await WebDavClient.Delete(fileName); |
||||
} |
||||
} |
||||
|
||||
public struct WebDavFileMsg{ |
||||
public string FileName { set; get; } |
||||
public bool IsCollection { set; get; } |
||||
|
||||
/// <summary> |
||||
/// unit is kb |
||||
/// </summary> |
||||
public long? ContentLength { set; get; } |
||||
public string Uri { set; get; } |
||||
public DateTime? LastUpdateTime { set; get; } |
||||
} |
||||
|
||||
public static class EGWebDavExtension{ |
||||
public static EGWebDav EGWebDav(this IEGFramework self) |
||||
{ |
||||
return EGArchitectureImplement.Interface.GetModule<EGWebDav>(); |
||||
} |
||||
public static string EncodeCredentials(string username, string password) |
||||
{ |
||||
string credentials = $"{username}:{password}"; |
||||
byte[] credentialsBytes = System.Text.Encoding.UTF8.GetBytes(credentials); |
||||
string encodedCredentials = Convert.ToBase64String(credentialsBytes); |
||||
return encodedCredentials; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,262 @@
@@ -0,0 +1,262 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Guidaoji |
||||
{ |
||||
internal class GuiDaoJi |
||||
{ |
||||
/// <summary> |
||||
/// 轨道电机控制器编号 |
||||
/// </summary> |
||||
public string uid { get; set; } |
||||
/// <summary> |
||||
/// 动作类别 |
||||
/// </summary> |
||||
public string action { get; set; } |
||||
/// <summary> |
||||
/// 时间 |
||||
/// </summary> |
||||
public string date { get; set; } |
||||
/// <summary> |
||||
/// 设备名称 |
||||
/// </summary> |
||||
public string name { get; set; } = "CA"; |
||||
/// <summary> |
||||
/// 主动上报时间间隔 |
||||
/// 0:不上传,1...n默认2s,单位:秒主动上报时间间隔,0:不上传,1...n默认2s,单位:秒 |
||||
/// </summary> |
||||
public int send_gap { get; set; } |
||||
/// <summary> |
||||
/// 0,不执行命令 1为执行命令 |
||||
/// </summary> |
||||
public int cont { get; set; } |
||||
/// <summary> |
||||
/// 位置复位 |
||||
/// 0:不操作,1:复位到原点 |
||||
/// </summary> |
||||
public int @return { get; set; } |
||||
/// <summary> |
||||
/// 故障复位 |
||||
/// 0:不操作,1:故障复位 |
||||
/// </summary> |
||||
public int reset { get; set; } |
||||
/// <summary> |
||||
/// 灯光状态 |
||||
/// 0为关,1为红灯,2为红灯闪烁,3为绿灯,4为绿灯闪烁,5为黄灯,6为黄灯闪烁 |
||||
/// </summary> |
||||
public int lamp { get; set; } |
||||
/// <summary> |
||||
/// 0 不执行行走 1 为执行行走 |
||||
/// </summary> |
||||
public int move { get; set; } |
||||
/// <summary> |
||||
/// 运行速度 |
||||
/// 0为停止,1-10为低速运行等级,11-20为高速运行等级 |
||||
/// </summary> |
||||
public double rate { get; set; } |
||||
/// <summary> |
||||
/// 指定摄像机x轴坐标,单位cm,在轨道的距离 |
||||
/// </summary> |
||||
public string x { get; set; } |
||||
/// <summary> |
||||
/// 指定摄像机Y轴坐标,单位cm,推杆退出的距离 |
||||
/// </summary> |
||||
public string y { get; set; } |
||||
/// <summary> |
||||
/// 0 不播报语音 1 播报语音 |
||||
/// </summary> |
||||
public int voice { get; set; } |
||||
/// <summary> |
||||
/// 语音播放内容 |
||||
/// </summary> |
||||
public string @string { get; set; } |
||||
} |
||||
|
||||
internal class GuiDaoJiRet |
||||
{ |
||||
/// <summary> |
||||
/// 轨道电机控制器编号 |
||||
/// </summary> |
||||
public string uid { get; set; } |
||||
/// <summary> |
||||
/// 动作类别 |
||||
/// </summary> |
||||
public string action { get; set; } |
||||
/// <summary> |
||||
/// 时间 |
||||
/// </summary> |
||||
public string date { get; set; } |
||||
/// <summary> |
||||
/// 设备名称 |
||||
/// </summary> |
||||
public retData data { get; set; } = new retData(); |
||||
/// <summary> |
||||
/// 返回结果 |
||||
/// </summary> |
||||
public string result { get; set; } |
||||
} |
||||
|
||||
public class retData |
||||
{ |
||||
/// <summary> |
||||
/// 设备名称 |
||||
/// </summary> |
||||
public string name { get; set; } = "轨道电机控制"; |
||||
|
||||
/// <summary> |
||||
/// 主动上报时间间隔 |
||||
/// 0:不上传,1...n默认2s,单位:秒主动上报时间间隔,0:不上传,1...n默认2s,单位:秒 |
||||
/// </summary> |
||||
public int send_gap { get; set; } = 2; |
||||
|
||||
/// <summary> |
||||
/// 轨道机启停状态【0——停;1——前进中;2——后退中;3——下降中;4——上升中】 |
||||
/// </summary> |
||||
public string type { get; set; } = "1"; |
||||
|
||||
/// <summary> |
||||
/// 灯光状态 |
||||
/// 0为关,1为红灯,2为红灯闪烁,3为绿灯,4为绿灯闪烁,5为黄灯,6为黄灯闪烁 |
||||
/// </summary> |
||||
public int lamp { get; set; } = 2; |
||||
|
||||
/// <summary> |
||||
/// 运行速度 |
||||
/// 0为停止,1-10为低速运行等级,11-20为高速运行等级 |
||||
/// </summary> |
||||
public string rate { get; set; } |
||||
|
||||
/// <summary> |
||||
/// 指定摄像机x轴坐标,单位cm,在轨道的距离 |
||||
/// </summary> |
||||
public string x { get; set; } |
||||
|
||||
/// <summary> |
||||
/// 指定摄像机Y轴坐标,单位cm,推杆退出的距离 |
||||
/// </summary> |
||||
public string y { get; set; } |
||||
|
||||
/// <summary> |
||||
/// 终端供电电压,单位V |
||||
/// </summary> |
||||
public string vol { get; set; } |
||||
|
||||
/// <summary> |
||||
/// 终端工作电流,单位A |
||||
/// </summary> |
||||
public string cur { get; set; } |
||||
|
||||
/// <summary> |
||||
/// 故障 |
||||
/// </summary> |
||||
public int[] alarm { get; set; } |
||||
} |
||||
|
||||
public class GuiDaoJiSet |
||||
{ |
||||
/// <summary> |
||||
/// 轨道电机控制器编号 |
||||
/// </summary> |
||||
public string uid { get; set; } |
||||
/// <summary> |
||||
/// 动作类别 |
||||
/// </summary> |
||||
public string action { get; set; } |
||||
/// <summary> |
||||
/// 时间 |
||||
/// </summary> |
||||
public string date { get; set; } |
||||
/// <summary> |
||||
/// 设备名称 |
||||
/// </summary> |
||||
public string name { get; set; } = "CA"; |
||||
/// <summary> |
||||
/// 主动上报时间间隔 |
||||
/// 0:不上传,1...n默认2s,单位:秒主动上报时间间隔,0:不上传,1...n默认2s,单位:秒 |
||||
/// </summary> |
||||
public int send_gap { get; set; } |
||||
/// <summary> |
||||
/// 0,不执行命令 1为执行命令 |
||||
/// </summary> |
||||
public int cont { get; set; } |
||||
/// <summary> |
||||
/// 0,不执行命令 1为执行命令 |
||||
/// </summary> |
||||
public Contda contda { get; set; } = new Contda(); |
||||
/// <summary> |
||||
/// 0 不执行行走 1 为执行行走 |
||||
/// </summary> |
||||
public int move { get; set; } |
||||
/// <summary> |
||||
/// 数据为数组,数组大小根据分控器数量而定 |
||||
/// </summary> |
||||
public Moveda moveda { get; set; } = new Moveda(); |
||||
/// <summary> |
||||
/// 0 不播报语音 1 播报语音 |
||||
/// </summary> |
||||
public int voice { get; set; } |
||||
/// <summary> |
||||
/// 数据为数组,数组大小根据分控器数量而定 |
||||
/// </summary> |
||||
//public List<Voiceda> voiceda { get; set; } = new List<Voiceda>(); |
||||
public Voiceda voiceda { get; set; } = new Voiceda(); |
||||
} |
||||
|
||||
public class Contda |
||||
{ |
||||
/// <summary> |
||||
/// 位置复位 |
||||
/// 0:不操作,1:复位到原点 |
||||
/// </summary> |
||||
public int @return { get; set; } = 0; |
||||
/// <summary> |
||||
/// 故障复位 |
||||
/// 0:不操作,1:故障复位 |
||||
/// </summary> |
||||
public int reset { get; set; } |
||||
/// <summary> |
||||
/// 灯光状态 |
||||
/// 0为关,1为红灯,2为红灯闪烁,3为绿灯,4为绿灯闪烁,5为黄灯,6为黄灯闪烁 |
||||
/// </summary> |
||||
public int lamp { get; set; } |
||||
} |
||||
|
||||
public class Moveda |
||||
{ |
||||
/// <summary> |
||||
/// 运行速度 |
||||
/// 0为停止,1-10为低速运行等级,11-20为高速运行等级 |
||||
/// </summary> |
||||
public double rate { get; set; } |
||||
/// <summary> |
||||
/// 指定摄像机x轴坐标,单位cm,在轨道的距离 |
||||
/// </summary> |
||||
public string x { get; set; } |
||||
/// <summary> |
||||
/// 指定摄像机Y轴坐标,单位cm,推杆退出的距离 |
||||
/// </summary> |
||||
public string y { get; set; } |
||||
} |
||||
|
||||
public class Voiceda |
||||
{ |
||||
/// <summary> |
||||
/// 语音播放内容 |
||||
/// </summary> |
||||
public string @string { get; set; } |
||||
} |
||||
|
||||
public enum ControlCommands |
||||
{ |
||||
F = 'F', //前进 |
||||
B = 'B', //后退 |
||||
U = 'U', //上升 |
||||
D = 'D', //下降 |
||||
S = 'S', //停止 |
||||
R = 'R', //位置复位 |
||||
E = 'E', //故障复位 |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Guidaoji |
||||
{ |
||||
internal class ModbusCRC16 |
||||
{ |
||||
public static ushort CalculateCrc(byte[] bytes) |
||||
{ |
||||
const ushort polynomial = 0xA001; |
||||
ushort crc = 0xFFFF; |
||||
for (int i = 0; i < bytes.Length; i++) |
||||
{ |
||||
crc ^= (ushort)(bytes[i] & 0xFF); |
||||
for (int j = 0; j < 8; j++) |
||||
{ |
||||
if ((crc & 0x0001) == 0x0001) |
||||
{ |
||||
crc >>= 1; |
||||
crc ^= polynomial; |
||||
} |
||||
else |
||||
{ |
||||
crc >>= 1; |
||||
} |
||||
} |
||||
} |
||||
return crc; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class MyClass |
||||
{ |
||||
public string name { get; set; } |
||||
public string result { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class MyObject |
||||
{ |
||||
public string[] cabinetid { get; set; } |
||||
public string action { get; set; } |
||||
public string taskid { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
using Newtonsoft.Json; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Net.Http; |
||||
using System.Net.Http.Json; |
||||
using System.Text; |
||||
using System.Text.Json; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class Patrol |
||||
{ |
||||
public async void PatrolD() |
||||
{ |
||||
DAY day = new DAY(); |
||||
int j = 0; |
||||
while (true) |
||||
{ |
||||
using (var httpClient = new HttpClient()) |
||||
{ |
||||
//发送post请求 |
||||
var response = await httpClient.GetAsync("http://192.168.10.104:8080/api/Patrol"); |
||||
if (response.IsSuccessStatusCode) |
||||
{ |
||||
var responseBody = await response.Content.ReadAsStringAsync(); |
||||
//Console.WriteLine(responseBody); |
||||
JsonDocument jsonDocument = JsonDocument.Parse(responseBody); |
||||
var dataElement = jsonDocument.RootElement.GetProperty("data").ToString(); |
||||
List<PatrolClass> dataList = JsonConvert.DeserializeObject<List<PatrolClass>>(dataElement); |
||||
foreach (var item in dataList) |
||||
{ |
||||
bool state = item.State; |
||||
//Console.WriteLine(state); |
||||
if (state == true) |
||||
{ |
||||
if (item.RunRule == "每日") |
||||
{ |
||||
await TimedTask.DailyJob(item.StartTime.ToString(), "2,2;3,3;4,4"); |
||||
} |
||||
else |
||||
{ |
||||
j++; |
||||
List<DayOfWeek> dayOfWeeks = day.DayOfWeeks(item); |
||||
var daysOfWeek = new HashSet<DayOfWeek>(); |
||||
foreach (var i in dayOfWeeks) |
||||
{ |
||||
daysOfWeek.Add(i); |
||||
} |
||||
await TimedTask.WeeklyJob(daysOfWeek, item.StartTime.ToString(),j, "2,2;3,3;4,4"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
//处理错误响应 |
||||
Console.WriteLine("请求失败"); |
||||
} |
||||
} |
||||
await Task.Delay(TimeSpan.FromDays(1)); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class PatrolClass |
||||
{ |
||||
public int Id { get; set; } |
||||
public DateTime StartTime { get; set; } |
||||
public string PatrolPoint { get; set; } |
||||
public string RunRule { get; set; } |
||||
public bool State { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Net.Sockets; |
||||
using System.Net; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using System.Timers; |
||||
using static System.Collections.Specialized.BitVector32; |
||||
using System.Security.Cryptography; |
||||
using System.Text.Json; |
||||
using Newtonsoft.Json.Linq; |
||||
using Newtonsoft.Json; |
||||
using System.IO; |
||||
using System.Runtime.Serialization.Formatters.Binary; |
||||
using Guidaoji.Camera; |
||||
using Guidaoji.Common; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class Program |
||||
{ |
||||
|
||||
|
||||
static void Main(string[] args) |
||||
{ |
||||
|
||||
TCP tcp = new TCP(); |
||||
Patrol patrol = new Patrol(); |
||||
//IP |
||||
string sIP = "192.168.10.102"; |
||||
//端口号 |
||||
string sPassword = "tschkj88"; |
||||
//连接轨道机服务器 |
||||
//TcpClientWrapper.Socket("192.168.10.104", 20000); |
||||
//tcp.Socket(); |
||||
//patrol.PatrolD(); |
||||
Console.WriteLine("InitSuccess"); |
||||
//登录摄像头 |
||||
//CHNetHelp.CameraInit(sIP, sPassword); |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
// 有关程序集的一般信息由以下 |
||||
// 控制。更改这些特性值可修改 |
||||
// 与程序集关联的信息。 |
||||
/*[assembly: AssemblyTitle("Emergency platform")] |
||||
[assembly: AssemblyDescription("")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("")] |
||||
[assembly: AssemblyProduct("Emergency platform")] |
||||
[assembly: AssemblyCopyright("Copyright © 2024")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型 |
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 |
||||
//请将此类型的 ComVisible 特性设置为 true。 |
||||
[assembly: ComVisible(false)] |
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID |
||||
[assembly: Guid("dfadd01d-9845-42dc-ace6-0982365da0b2")] |
||||
|
||||
// 程序集的版本信息由下列四个值组成: |
||||
// |
||||
// 主版本 |
||||
// 次版本 |
||||
// 生成号 |
||||
// 修订号 |
||||
// |
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 |
||||
//通过使用 "*",如下所示: |
||||
// [assembly: AssemblyVersion("1.0.*")] |
||||
[assembly: AssemblyVersion("1.0.0.0")] |
||||
[assembly: AssemblyFileVersion("1.0.0.0")] |
||||
*/ |
@ -0,0 +1,299 @@
@@ -0,0 +1,299 @@
|
||||
using Quartz.Impl; |
||||
using Quartz; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Newtonsoft.Json.Linq; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
internal class TimedTask:IJob |
||||
{ |
||||
public TimedTask() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public void pp() |
||||
{ |
||||
HashSet<DayOfWeek> hashSet2 = new HashSet<DayOfWeek>(); |
||||
foreach (object value in Enum.GetValues(typeof(DayOfWeek))) |
||||
{ |
||||
var allDaysOfTheWeek = new HashSet<DayOfWeek>(); |
||||
foreach (var d in Enum.GetValues(typeof(DayOfWeek))) |
||||
{ |
||||
var dayOfWeek = (DayOfWeek)d; |
||||
allDaysOfTheWeek.Add(dayOfWeek); |
||||
|
||||
if (dayOfWeek >= DayOfWeek.Monday && dayOfWeek <= DayOfWeek.Friday) |
||||
{ |
||||
//mondayThroughFriday.Add(dayOfWeek); |
||||
} |
||||
} |
||||
} |
||||
//DayOfWeek dayOfWeek = (DayOfWeek)value; |
||||
//hashSet.Add(dayOfWeek); |
||||
//if (dayOfWeek >= DayOfWeek.Monday && dayOfWeek <= DayOfWeek.Friday) |
||||
//{ |
||||
// hashSet2.Add(dayOfWeek); |
||||
//} |
||||
} |
||||
|
||||
public virtual Task Execute(IJobExecutionContext context) |
||||
{ |
||||
//执行控制轨道机巡逻任务 |
||||
//取出巡逻点位集合 |
||||
string[] sPatrols = context.JobDetail.JobDataMap.GetString("parameter").Split(';'); |
||||
for (int i = 0; i < sPatrols.Length; i++) |
||||
{ |
||||
string[] sPatrol = sPatrols[i].Split(','); |
||||
//下达巡逻指令 |
||||
//GuiDaoJiMove(sPatrol[0], sPatrol[1]); |
||||
} |
||||
Console.WriteLine("业务逻辑" + DateTime.Now); |
||||
PrintInfo("业务逻辑" + DateTime.Now); |
||||
Thread.Sleep(60000); |
||||
return Task.CompletedTask; |
||||
} |
||||
|
||||
/////// <summary> |
||||
/////// 每天HH:mm:ss进行任务 |
||||
/////// </summary> |
||||
/////// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
/////// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
////public static void DailyJob(string sTime, string sPatrols) |
||||
////{ |
||||
//// int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
//// int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
//// int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
//// //创建一个调度器 |
||||
//// IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
//// // 创建作业 |
||||
//// IJobDetail job = JobBuilder.Create<TimedTask>() |
||||
//// .WithIdentity("dailyTaskJob", "group1") |
||||
//// .Build(); |
||||
|
||||
//// // 创建触发器,每天九点 |
||||
//// ITrigger trigger = TriggerBuilder.Create() |
||||
//// .WithIdentity("dailyTaskTrigger", "group1") |
||||
//// .StartNow() |
||||
//// .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(iHour, iMinute)) // 每天9:00执行 |
||||
//// .Build(); |
||||
|
||||
//// // 将作业和触发器加入调度器 |
||||
//// _temp_schheduler.ScheduleJob(job, trigger); |
||||
//// _temp_schheduler.Start(); |
||||
////} |
||||
|
||||
/// <summary> |
||||
/// 每天HH:mm:ss进行任务 |
||||
/// </summary> |
||||
/// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
/// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
public static async Task DailyJob(string sTime, string sPatrols) |
||||
{ |
||||
if (sTime == null) |
||||
{ |
||||
return; |
||||
} |
||||
int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
string sJob = "job" + iHour + iMinute + iSecond; |
||||
string sGroup = "group" + iHour + iMinute + iSecond; |
||||
string sTrigger = "trigger" + iHour + iMinute + iSecond; |
||||
//每天每天HH:mm:ss进行任务 |
||||
string cronExpression = string.Format("{0} {1} {2} ? * *", iSecond, iMinute, iHour); |
||||
//创建一个调度器 |
||||
IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
// 创建作业 |
||||
IJobDetail job = JobBuilder.Create<TimedTask>() |
||||
.WithIdentity(sJob, sGroup) |
||||
.UsingJobData("parameter", sPatrols) |
||||
.Build(); |
||||
// 创建触发器,每天上午sTime执行 |
||||
ITrigger trigger = TriggerBuilder.Create().WithIdentity(sTrigger, sGroup) |
||||
.WithCronSchedule(cronExpression) |
||||
.WithPriority(10) // 设置优先级,范围是0到255,数字越高,优先级越高 |
||||
.Build(); |
||||
// 将作业和触发器加入调度器 |
||||
await _temp_schheduler.ScheduleJob(job, trigger); |
||||
await _temp_schheduler.Start(); |
||||
} |
||||
|
||||
///// <summary> |
||||
///// 每天HH:mm:ss进行任务 |
||||
///// </summary> |
||||
///// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
///// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
//public static void DailyJob(string sTime, string sPatrols) |
||||
//{ |
||||
// if (sTime == null) |
||||
// { |
||||
// return; |
||||
// } |
||||
// int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
// int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
// int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
// string sJob = "job" + iHour + iMinute + iSecond; |
||||
// string sGroup = "group" + iHour + iMinute + iSecond; |
||||
// string sTrigger = "trigger" + iHour + iMinute + iSecond; |
||||
// //创建一个调度器 |
||||
// IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
// // 创建作业 |
||||
// IJobDetail job = JobBuilder.Create<TimedTask>() |
||||
// .WithIdentity(sJob, sGroup) |
||||
// //.UsingJobData("parameter", sPatrols) |
||||
// .Build(); |
||||
// // 创建触发器,每天上午sTime执行 |
||||
// ITrigger trigger = TriggerBuilder.Create() |
||||
// .WithIdentity(sTrigger, sGroup) |
||||
// .WithDailyTimeIntervalSchedule(a => |
||||
// a.WithIntervalInHours(24) |
||||
// .OnEveryDay() |
||||
// .StartingDailyAt(TimeOfDay.HourMinuteAndSecondOfDay(iHour, iMinute, iSecond))) |
||||
// //.WithPriority(10) // 设置优先级,范围是0到255,数字越高,优先级越高 |
||||
// .Build(); |
||||
// // 将作业和触发器加入调度器 |
||||
// _temp_schheduler.ScheduleJob(job, trigger); |
||||
// _temp_schheduler.Start(); |
||||
//} |
||||
|
||||
/// <summary> |
||||
/// 每周中的某几天进行任务 |
||||
/// </summary> |
||||
/// <param name="onDaysOfWeek">周中某几天</param> |
||||
/// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
/// <param name="iNo">编号(不能重复)</param> |
||||
/// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
public static async Task WeeklyJob(IReadOnlyCollection<DayOfWeek> onDaysOfWeek, string sTime, int iNo, string sPatrols) |
||||
{ |
||||
int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
string sJob = "jobWeek" + iNo; |
||||
string sGroup = "groupWeek" + iNo; |
||||
string sTrigger = "triggerWeek" + iNo; |
||||
//创建一个调度器 |
||||
IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
// 创建作业 |
||||
IJobDetail job = JobBuilder.Create<TimedTask>() |
||||
.WithIdentity(sJob, sGroup) |
||||
.UsingJobData("parameter", sPatrols) |
||||
.Build(); |
||||
// 创建触发器,每天上午sTime执行 |
||||
ITrigger trigger = TriggerBuilder.Create() |
||||
.WithIdentity(sTrigger, sGroup) |
||||
.WithDailyTimeIntervalSchedule(a => |
||||
a.OnDaysOfTheWeek(onDaysOfWeek) |
||||
.StartingDailyAt(TimeOfDay.HourMinuteAndSecondOfDay(iHour, iMinute, iSecond))) |
||||
//.WithPriority(10) // 设置优先级,范围是0到255,数字越高,优先级越高 |
||||
.Build(); |
||||
// 将作业和触发器加入调度器 |
||||
await _temp_schheduler.ScheduleJob(job, trigger); |
||||
await _temp_schheduler.Start(); |
||||
} |
||||
|
||||
///// <summary> |
||||
///// 每周中的某几天进行任务(暂时无法实现) |
||||
///// </summary> |
||||
///// <param name="sDaysOfWeek">周中某几天,如"1,2,3"即每周的周一周二周三,用半角逗号隔开</param> |
||||
///// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
///// <param name="iNo">编号(不能重复)</param> |
||||
///// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
//public static void WeeklyJob(string sDaysOfWeek, string sTime, int iNo, string sPatrols) |
||||
//{ |
||||
// if (sTime == null) |
||||
// { |
||||
// return; |
||||
// } |
||||
// int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
// int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
// int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
// string sJob = "jobWeek" + iNo; |
||||
// string sGroup = "groupWeek" + iNo; |
||||
// string sTrigger = "triggerWeek" + iNo; |
||||
// //每周中的某几天某点进行任务 |
||||
// string cronExpression = string.Format("{0} {1} {2} ? * {3}", iSecond, iMinute, iHour, sDaysOfWeek); |
||||
// //创建一个调度器 |
||||
// IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
// // 创建作业 |
||||
// IJobDetail job = JobBuilder.Create<TimedTask>().WithIdentity(sJob, sGroup).Build(); |
||||
// //给任务传参 |
||||
// job.JobDataMap.Add("parameter", sPatrols); |
||||
// // 创建触发器,每周某几天某点进行作业 |
||||
// ITrigger trigger = TriggerBuilder.Create().WithIdentity(sTrigger, sGroup) |
||||
// .WithCronSchedule(cronExpression) |
||||
// .WithPriority(10) // 设置优先级,范围是0到255,数字越高,优先级越高 |
||||
// .Build(); |
||||
// // 将作业和触发器加入调度器 |
||||
// _temp_schheduler.ScheduleJob(job, trigger); |
||||
// _temp_schheduler.Start(); |
||||
//} |
||||
|
||||
/// <summary> |
||||
/// 每月中的某几天进行任务 |
||||
/// </summary> |
||||
/// <param name="sDays">每月的某几天,如"1,5,10"即每月的1号,5号,10号执行。用半角逗号隔开</param> |
||||
/// <param name="sTime">时间:格式必须为“HH:mm:ss”</param> |
||||
/// <param name="iNo">编号(不能重复)</param> |
||||
/// <param name="sPatrols">巡逻点位计集合:格式必须为“x1,y1;x2,y2;......”</param> |
||||
public static async Task CertainDaysJob(string sDays, string sTime, int iNo, string sPatrols) |
||||
{ |
||||
int iHour = Convert.ToInt32(sTime.Substring(0, 2)); |
||||
int iMinute = Convert.ToInt32(sTime.Substring(3, 2)); |
||||
int iSecond = Convert.ToInt32(sTime.Substring(6, 2)); |
||||
string sJob = "jobDays" + iNo; |
||||
string sGroup = "groupDays" + iNo; |
||||
string sTrigger = "triggerDays" + iNo; |
||||
// 在Quartz.NET中使用Cron表达式 |
||||
//string cronExpression = "0 15 10 5,15 * ?"; // 每月的第5号和第15号上午10点15分 |
||||
string cronExpression = string.Format("{0} {1} {2} {3} * ?", iSecond, iMinute, iHour, sDays); |
||||
//创建一个调度器 |
||||
IScheduler _temp_schheduler = StdSchedulerFactory.GetDefaultScheduler().Result; |
||||
// 创建作业 |
||||
IJobDetail job = JobBuilder.Create<TimedTask>().WithIdentity(sJob, sGroup).Build(); |
||||
//给任务传参 |
||||
job.JobDataMap.Add("parameter", sPatrols); |
||||
// 创建触发器,每周某几天0点进行作业 |
||||
ITrigger trigger = TriggerBuilder.Create().WithIdentity(sTrigger, sGroup) |
||||
.WithCronSchedule(cronExpression) |
||||
.WithPriority(10) // 设置优先级,范围是0到255,数字越高,优先级越高 |
||||
.Build(); |
||||
// 将作业和触发器加入调度器 |
||||
await _temp_schheduler.ScheduleJob(job, trigger); |
||||
await _temp_schheduler.Start(); |
||||
} |
||||
|
||||
public static void PrintInfo(string str) |
||||
{ |
||||
string Folder = Environment.CurrentDirectory + @"\Logs"; |
||||
string FileNamme = Environment.CurrentDirectory + @"\Logs\Info_" + DateTime.Now.ToString("yyyyMMdd") + ".txt"; |
||||
if (!System.IO.Directory.Exists(Folder)) |
||||
{ |
||||
System.IO.Directory.CreateDirectory(Folder); |
||||
} |
||||
using (TextWriter fw = new StreamWriter(FileNamme, true)) |
||||
{ |
||||
try |
||||
{ |
||||
FileInfo fi = new FileInfo(FileNamme); |
||||
fw.WriteLine(str); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
fw.WriteLine(ex.Message); |
||||
} |
||||
finally |
||||
{ |
||||
fw.Close(); |
||||
fw.Dispose(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
using Guidaoji; |
||||
using Guidaoji.Common; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Emergency_platform |
||||
{ |
||||
public class Track |
||||
{ |
||||
public void DS() |
||||
{ |
||||
Timer timer = new Timer(TimerCallback, null, 0, 2000); |
||||
} |
||||
public void TimerCallback(object state) |
||||
{ |
||||
for (int i = 0; i <TcpClientWrapper.uploadRet.data.alarm.Length; i++) |
||||
{ |
||||
if (TcpClientWrapper.uploadRet.data.alarm[i] == 1) |
||||
{ |
||||
switch (i) |
||||
{ |
||||
case 0: |
||||
TcpClientWrapper.SendDataAlarm("总故障"); |
||||
break; |
||||
case 1: |
||||
TcpClientWrapper.SendDataAlarm("电压过高或过低报警"); |
||||
break; |
||||
case 2: |
||||
TcpClientWrapper.SendDataAlarm("过载报警"); |
||||
break; |
||||
case 3: |
||||
TcpClientWrapper.SendDataAlarm("行走电机故障"); |
||||
break; |
||||
case 4: |
||||
TcpClientWrapper.SendDataAlarm("伸缩电机故障"); |
||||
break; |
||||
case 5: |
||||
TcpClientWrapper.SendDataAlarm("打滑报警"); |
||||
break; |
||||
case 6: |
||||
TcpClientWrapper.SendDataAlarm("坐标故障报警"); |
||||
break; |
||||
case 7: |
||||
TcpClientWrapper.SendDataAlarm("预留"); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue