天津康师傅调度系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

370 lines
15 KiB

1 month ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Snap7;
using Model;
using DBFactory;
using System.Data;
using Snap7Client;
namespace Snap7Server
{
public static class CSnap7Server
{
public static object obj = new object();
private static S7Server.TSrvCallback TheEventCallBack; // <== Static var containig the callback
private static S7Server.TSrvCallback TheReadCallBack;
private static Dictionary<string, S7Server> server_dic = new Dictionary<string, S7Server>();//ip与s7server
private static Dictionary<string, int> callback_para = new Dictionary<string, int>();//plc名与ip
private static Dictionary<string, byte[]> db1_dic = new Dictionary<string, byte[]>();//ip与db1
private static Dictionary<string, byte[]> db2_dic = new Dictionary<string, byte[]>();//ip与db2
private static Dictionary<string, int[]> db_length = new Dictionary<string, int[]>();//ip与每个设备的db长度
public static Dictionary<string, List<int>> conveyorRouteList = new Dictionary<string, List<int>>();//Task 的所有输送机
public static Dictionary<string, Queue<MDevice>> taskDeviceList = new Dictionary<string, Queue<MDevice>>();//Task 的所有设备
public static DBOperator dbo = new DBOperator();
static StringBuilder sql = new StringBuilder();
public static void InitSnap7Server()
{
//根据数据库初始化字典,
sql.Remove(0, sql.Length);
sql.Append("select distinct F_RemoteIP from T_Base_Device where (F_RemoteIP is not null) ");
DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
for (int i=0; i<dv.Count; i++)
{
Callback_para.Add(dv[i]["F_RemoteIP"].ToString(), i);
initServer(dv[i]["F_RemoteIP"].ToString());
}
}
private static void initServer(string IP)
{
//数据库中 db1 / db2 的长度
int db1_length = 0, db2_length = 0;
db1_length = Snap7Client.CCommonSnap7Client.GetDB1Length(IP);
db2_length = Snap7Client.CCommonSnap7Client.GetDB2Length(IP);
//选择最大的值进行初始化
if (db1_length != 0 || db2_length != 0)
{
int len = db1_length > db2_length ? db1_length : db2_length;
byte[] db1_temp = new byte[len];
byte[] db2_temp = new byte[len];
for (int i=0; i<len; i++)
{
db1_temp[i] = 0;
db2_temp[i] = 0;
}
Db1_dic.Add(IP, db1_temp);
Db2_dic.Add(IP, db2_temp);
}
// 对堆垛机的 XY 坐标初始化
sql.Remove(0, sql.Length);
sql.Append("SELECT F_DeviceIndex, F_DBW2Address FROM T_Base_Device WHERE F_DeviceKindIndex = 1 and F_RemoteIP = '" + IP + "' order by F_DBW2Address");
DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
for (int i = 0; i < dv.Count; i++)
{
Db2_dic[IP][Convert.ToInt32(dv[i]["F_DBW2Address"].ToString()) + 7] = 1; //X坐标为1
Db2_dic[IP][Convert.ToInt32(dv[i]["F_DBW2Address"].ToString()) + 11] = 1; //Y坐标为1
//Db2_dic[IP][Convert.ToInt32(dv[i]["F_DBW2Address"].ToString()) + 12] = 1;
//Db2_dic[IP][Convert.ToInt32(dv[i]["F_DBW2Address"].ToString()) + 13] = 1;
}
// 对取放货站台的光电信息初始化,.3,.4
sql.Remove(0, sql.Length);
sql.Append("SELECT F_DeviceIndex, F_DBW2Address FROM T_Base_Device WHERE F_DeviceIndex in (SELECT F_LaneGateDeviceIndex FROM T_Base_Lane_Gate ) order by F_DBW2Address");
dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
for (int i = 0; i < dv.Count; i++)
{
Db2_dic[IP][Convert.ToInt32(dv[i]["F_DBW2Address"].ToString()) + 4] = 8 + 16; //X坐标为1
}
sql.Remove(0, sql.Length);
sql.Append("SELECT F_DBW2Address, F_DBWGetLength FROM T_Base_Device WHERE F_DBW2Address is not NULL and F_RemoteIP = '" + IP + "' order by F_DBW2Address");
dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
int[] length = new int[dv.Count];
for (int i=0; i< dv.Count; i++)
{
if (i != dv.Count-1)
{
length[i] = Convert.ToInt32(dv[i + 1]["F_DBW2Address"]) - Convert.ToInt32(dv[i]["F_DBW2Address"]);
}
else
{
length[i] = Convert.ToInt32(dv[i]["F_DBWGetLength"]);
}
}
Db_length.Add(IP, length);
S7Server s7 = createSnap7Server(IP);
Server_dic.Add(IP, s7);
}
private static S7Server createSnap7Server(string IP)
{
S7Server s7 = new S7Server();
byte[] DB1 = Db1_dic[IP];
byte[] DB2 = Db2_dic[IP];
// Share some resources with our virtual PLC
s7.RegisterArea(S7Server.srvAreaDB, // We are registering a DB
1, // Its number is 1 (DB1)
ref DB1, // Our buffer for DB1
DB1.Length); // Its size
// Do the same for DB2 and DB3
s7.RegisterArea(S7Server.srvAreaDB, 2, ref DB2, DB2.Length);
// Exclude read event to avoid the double report
// Set the callbacks (using the static var to avoid the garbage collect)
TheEventCallBack = new S7Server.TSrvCallback(EventCallback);
TheReadCallBack = new S7Server.TSrvCallback(ReadEventCallback);
s7.EventMask = ~S7Server.evcDataRead;
//int num = 0;
s7.SetEventsCallBack(TheEventCallBack, new IntPtr(Callback_para[IP]));
s7.SetReadEventsCallBack(TheReadCallBack, new IntPtr(Callback_para[IP]));
string _ip = IP.Split(':')[0];
string local = "127.0.0.1";
int Error = s7.StartTo(_ip);
return s7;
}
static Model.MDevice askDevinfo;
public static Dictionary<string, S7Server> Server_dic { get => server_dic; set => server_dic = value; }
public static Dictionary<string, byte[]> Db1_dic { get => db1_dic; set => db1_dic = value; }
public static Dictionary<string, byte[]> Db2_dic { get => db2_dic; set => db2_dic = value; }
public static Dictionary<string, int[]> Db_length { get => db_length; set => db_length = value; }
public static Dictionary<string, int> Callback_para { get => callback_para; set => callback_para = value; }
public static Dictionary<string, List<int>> ConveyorRouteList { get => conveyorRouteList; set => conveyorRouteList = value; }
//根据设备号,获取DB1
//根据设备号,获取DB2
//根据设备号,返回设备信息
public static Model.MDevice GetDeviceInfo(int DeviceIndex)
{
return Model.CGetInfo.GetDeviceInfo(DeviceIndex);
}
//根据设备号,自动改变状态,
public static bool AutoChangeAllState(int DeviceIndex)
{
foreach(var ip in Db2_dic.Keys)
{
foreach(var device in CGetInfo.DeviceInfo.Values)
{
if(device.RemoteIP == ip)
{
//if
}
}
}
return true;
}
//根据设备号,清零 DB2
public static void ClearDeviceDB2(int DeviceIndex)
{
askDevinfo = GetDeviceInfo(DeviceIndex);
//for (int i=askDevinfo.Dbw2Address; i<askDevinfo.Dbw2Address+askDevinfo.Dbw2Getlength; i++)
for (int i=askDevinfo.Dbw2Address; i<askDevinfo.Dbw2Address+4; i++)
{
Db2_dic[askDevinfo.RemoteIP][i] = 0;
}
}
//根据设备号,改变设备状态(参数)
public static void ChangeDeviceDate(int DeviceIndex, int State)
{
askDevinfo = GetDeviceInfo(DeviceIndex);
Db2_dic[askDevinfo.RemoteIP][askDevinfo.Dbw2Address + 1] = (byte)State;
}
static void EventCallback(IntPtr usrPtr, ref S7Server.USrvEvent Event, int Size)
{
//Console.WriteLine(Server.EventText(ref Event));
//var temp = Server.EventText(ref Event);
//Form1.MainForm.listBox1.Items.Add(num2server[usrPtr.ToInt32()].EventText(ref Event));
}
static void ReadEventCallback(IntPtr usrPtr, ref S7Server.USrvEvent Event, int Size)
{
//Console.WriteLine(Server.EventText(ref Event));
}
// 将 DB1 的信息复制到 DB2
//public static void
// 根据 IP 和 db2 的开始地址,从数据库中找到该设备
public static int getDevice(string ip, int dbAddress, out int devKind)
{
devKind = 0;
sql.Remove(0, sql.Length);
sql.Append("select F_DeviceIndex, F_DeviceKindIndex from T_Base_Device where (F_RemoteIP='" + ip + "' and F_DBW2Address=" + dbAddress + ")");
DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
if (dv.Count > 0)
{
devKind = Convert.ToInt32(dv[0]["F_DeviceKindIndex"].ToString());
return Convert.ToInt32(dv[0]["F_DeviceIndex"].ToString());
}
return 0;
}
public static void initTaskRoute(string task)
{
if (ConveyorRouteList.ContainsKey(task) == true) return;
sql.Remove(0, sql.Length);
sql.Append("select FCONTROLTASKTYPE from T_Manage_Task, T_Monitor_task where fid = F_ManageTaskIndex and F_MonitorIndex = '" + task + "'");
DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
string nextDeviceName = "";
if (dv.Count > 0)
{
int type = Convert.ToInt32(dv[0]["FCONTROLTASKTYPE"].ToString());
if (type == 1)
{
nextDeviceName = "F_InputNextDevice";
}
else
{
nextDeviceName = "F_OutputNextDevice";
}
}
sql.Remove(0, sql.Length);
sql.Append("select F_NumParam1,F_NumParam4 from T_Monitor_Task where F_MonitorIndex = '" + task + "'");
dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
int startDev = 0; int endDev = 0;
if (dv.Count > 0)
{
startDev = Convert.ToInt32(dv[0]["F_NumParam1"].ToString());
endDev = Convert.ToInt32(dv[0]["F_NumParam4"].ToString());
List<List<int>> devs = RecursionDevices(startDev, endDev, nextDeviceName);
if (devs.Count > 0)
{
if (conveyorRouteList.ContainsKey(task.ToString()) == false)
{
conveyorRouteList.Add(task.ToString(), devs[0]);
}
}
}
return ;
}
public static List<List<int>> RecursionDevices(int startdev, int enddev, string IONextDevice)
{
string sql = "";
DataView dv;
string nextdev = "";
string[] spl;
char[] cc = new char[1] { ';' };
List<List<int>> routedevs = new List<List<int>>();
sql = "SELECT " + IONextDevice + " FROM T_Base_Device where F_DeviceIndex=" + startdev;
dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
if (dv.Count > 0)
{
nextdev = dv[0][IONextDevice].ToString();
if (nextdev.Length > 0)
{
spl = nextdev.Split(cc);
for (int i = spl.GetLowerBound(0); i <= spl.GetUpperBound(0); i++)
{
if (routedevs.Count != 0 && routedevs[0].Contains(enddev) == true)
return routedevs;
List<List<int>> rs = RecursionSingle(Convert.ToInt32(spl[i]), enddev, IONextDevice);
if (rs.Count > 0)
{
//返回多条路经设备集合的集合
List<int> rss = new List<int>();
for (int ii = 0; ii < rs.Count; ii++)
{
rss = rs[ii];
if (rss.Contains(Convert.ToInt32(spl[i])) == false)
{
rss.Add(Convert.ToInt32(spl[i]));
}
if (rss.Contains(startdev) == false)
{
rss.Add(startdev);
}
if (routedevs.Contains(rss) == false)
{
routedevs.Add(rss);
}
} //Predicate<List<int>> FindValue = delegate(List<int> obj) { return obj.Contains(Convert.ToInt32(spl[i])); };
}
}
return routedevs;
}
}
return routedevs;
}
static List<List<int>> RecursionSingle(int startdev, int enddev, string IONextDevice)
{
char[] cc = new char[1] { ';' };
List<int> routedevs = new List<int>();
List<List<int>> mutiRoute = new List<List<int>>();
#region 递归获得多条路径详细设备集合
if (startdev == enddev)//找到了终点设备
{
if (routedevs.Contains(enddev) == false)
{
routedevs.Add(enddev);
}
if (routedevs.Contains(startdev) == false)
{
routedevs.Add(startdev);
}
mutiRoute.Add(routedevs);
return mutiRoute;
}
else//接着找
{
List<List<int>> mutireturndevs = RecursionDevices(startdev, enddev, IONextDevice);
if (mutireturndevs.Count > 0)
{
for (int k = 0; k < mutireturndevs.Count; k++)
{
if (mutireturndevs[k].Contains(startdev) == false)
{
mutireturndevs[k].Add(startdev);
}
mutiRoute.Add(mutireturndevs[k]);
}
}
return mutiRoute;
}
#endregion
}
}
}