C# SCADA
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.

541 lines
19 KiB

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using DataService;
namespace FileDriver
{
[Description("SQL 数据库")]
public class DataBaseReader : IFileDriver, IMultiReadWrite
{
public bool IsClosed
{
get
{
return m_Conn == null || m_Conn.State != ConnectionState.Open;
}
}
short _id;
public short ID
{
get
{
return _id;
}
}
int _timeOut;
public int TimeOut
{
get { return m_Conn == null ? _timeOut : m_Conn.ConnectionTimeout; }
set
{
_timeOut = value;
}
}
string _name;
public string Name
{
get
{
return _name;
}
}
string _serverIP;
public string ServerName
{
get
{
return _serverIP;
}
set
{
_serverIP = value;
}
}
string _ins;
public string Instance
{
get
{
return _ins;
}
set
{
_ins = value;
}
}
string _database;
public string FileName
{
get
{
return _database;
}
set
{
_database = value;
}
}
List<IGroup> _groups = new List<IGroup>();
public IEnumerable<IGroup> Groups
{
get { return _groups; }
}
IDataServer _server;
public IDataServer Parent
{
get { return _server; }
}
public DataBaseReader(IDataServer parent, short id, string name, string server = ".", int timeOut = 2, string databaseName = "SharpSCADA", string ins = null)
{
_id = id;
_name = name;
_server = parent;
_database = databaseName;
_serverIP = server;
_ins = ins;
_timeOut = timeOut / 1000;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = (ins == null ? server : string.Format(@"{0}\{1}", _serverIP, _ins));
builder.InitialCatalog = _database;
builder.ConnectTimeout = _timeOut;
builder.IntegratedSecurity = true;
m_ConnStr = builder.ConnectionString;
}
string m_ConnStr;
SqlConnection m_Conn;
public bool Connect()
{
m_Conn = new SqlConnection(m_ConnStr);
//mySqlConnection.ConnectionTimeout = 1;//设置连接超时的时间,写在连接字符串内
try
{
//Open DataBase
//打开数据库
m_Conn.Open();
return m_Conn.State == ConnectionState.Open;
}
catch (Exception e)
{
if (OnClose != null)
OnClose(this, new ShutdownRequestEventArgs(e.Message));
return false;
}
}
public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false)
{
FileDeviceGroup grp = new FileDeviceGroup(id, name, updateRate, active, this);
_groups.Add(grp);
return grp;
}
public bool RemoveGroup(IGroup grp)
{
grp.IsActive = false;
return _groups.Remove(grp);
}
public void Dispose()
{
foreach (IGroup grp in _groups)
{
grp.Dispose();
}
_groups.Clear();
m_Conn.Close(); m_Conn.Dispose();
}
public SqlDataReader ExecuteProcedureReader(string sSQL, params SqlParameter[] ParaName)
{
SqlCommand command = new SqlCommand(sSQL, m_Conn);
command.CommandType = CommandType.StoredProcedure;
if (ParaName != null)
{
command.Parameters.AddRange(ParaName);
}
try
{
if (m_Conn.State == ConnectionState.Closed)
m_Conn.Open();
return command.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception e)
{
if (OnClose != null)
OnClose(this, new ShutdownRequestEventArgs(e.Message));
return null;
}
}
public int ExecuteStoredProcedure(string ProName, params SqlParameter[] ParaName)
{
try
{
SqlCommand cmd = new SqlCommand(ProName, m_Conn);
cmd.CommandType = CommandType.StoredProcedure;
if (ParaName != null)
{
cmd.Parameters.AddRange(ParaName);
}
SqlParameter param = new SqlParameter();
cmd.Parameters.Add(param);
param.Direction = ParameterDirection.ReturnValue;
if (m_Conn.State == ConnectionState.Closed)
m_Conn.Open();
cmd.ExecuteNonQuery();
m_Conn.Close();
return (int)param.Value;
}
catch (Exception e)
{
m_Conn.Close();
if (OnClose != null)
OnClose(this, new ShutdownRequestEventArgs(e.Message));
return -1;
}
}
public byte[] ReadBytes(DeviceAddress address, ushort size)
{
using (var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType }))
{
if (dataReader != null)
{
while (dataReader.Read())
{
return dataReader[0] as byte[];
}
}
}
return null;
}
public ItemData<int> ReadInt32(DeviceAddress address)
{
ItemData<int> data = new ItemData<int>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetInt32(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<short> ReadInt16(DeviceAddress address)
{
ItemData<short> data = new ItemData<short>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetInt16(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<byte> ReadByte(DeviceAddress address)
{
ItemData<byte> data = new ItemData<byte>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetByte(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<string> ReadString(DeviceAddress address, ushort size)
{
ItemData<string> data = new ItemData<string>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetString(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<float> ReadFloat(DeviceAddress address)
{
ItemData<float> data = new ItemData<float>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetFloat(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<bool> ReadBit(DeviceAddress address)
{
ItemData<bool> data = new ItemData<bool>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetBoolean(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public ItemData<object> ReadValue(DeviceAddress address)
{
ItemData<object> data = new ItemData<object>();
var dataReader = ExecuteProcedureReader("ReadValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@DATATYPE", SqlDbType.TinyInt) { Value = address.VarType });
if (dataReader == null)
{
data.Quality = QUALITIES.QUALITY_BAD;
return data;
}
while (dataReader.Read())
{
data.Value = dataReader.GetValue(0);
data.Quality = QUALITIES.QUALITY_GOOD;
}
dataReader.Close();
return data;
}
public int WriteBytes(DeviceAddress address, byte[] bits)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = bits });
}
public int WriteBit(DeviceAddress address, bool bit)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = bit });
}
public int WriteBits(DeviceAddress address, byte bits)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = bits });
}
public int WriteInt16(DeviceAddress address, short value)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
}
public int WriteInt32(DeviceAddress address, int value)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
}
public int WriteFloat(DeviceAddress address, float value)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant) { Value = value });
}
public int WriteString(DeviceAddress address, string str)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant, address.DataSize) { Value = str });
}
public int WriteValue(DeviceAddress address, object value)
{
return ExecuteStoredProcedure("UpdateValueByID",
new SqlParameter("@ID", SqlDbType.SmallInt) { Value = address.CacheIndex },
new SqlParameter("@Value", SqlDbType.Variant, address.DataSize) { Value = value });
}
public ItemData<Storage>[] ReadMultiple(DeviceAddress[] addrsArr)
{
int len = addrsArr.Length;
SqlParameter param = new SqlParameter("@IDARRAY", SqlDbType.VarChar);
string str = string.Empty;
for (int i = 0; i < len; i++)
{
str += addrsArr[i].CacheIndex + '|' + (int)addrsArr[i].VarType + ',';
}
param.Value = str;
var dataReader = ExecuteProcedureReader("BatchReadByID", param);//可以采用IN 操作符+,
if (dataReader == null)
return null;
else
{
ItemData<Storage>[] itemArr = new ItemData<Storage>[len];
int i = 0;
while (dataReader.Read())
{
switch (addrsArr[i].VarType)
{
case DataType.BOOL:
itemArr[i].Value.Boolean = dataReader.GetBoolean(0);
break;
case DataType.BYTE:
itemArr[i].Value.Byte = dataReader.GetByte(0);
break;
case DataType.WORD:
case DataType.SHORT:
itemArr[i].Value.Int16 = dataReader.GetInt16(0);
break;
case DataType.TIME:
case DataType.INT:
itemArr[i].Value.Int32 = dataReader.GetInt32(0);
break;
case DataType.FLOAT:
itemArr[i].Value.Single = dataReader.GetFloat(0);
break;
}
i++;
}
dataReader.Close();
return itemArr;
}
}
public int WriteMultiple(DeviceAddress[] addrArr, object[] buffer)
{
int len = addrArr.Length;
SqlParameter param = new SqlParameter("@IDARRAY", SqlDbType.VarChar);
string str = string.Empty;
for (int i = 0; i < len; i++)
{
str += addrArr[i].CacheIndex.ToString() + "|" + buffer[i].ToString() + ",";
}
param.Value = str;
return ExecuteStoredProcedure("BatchUpdateByID", param);
}
public FileData[] ReadAll(short groupId)
{
FileData[] list = null;
using (var reader = ExecuteProcedureReader("ReadAll", new SqlParameter("@GroupId", groupId)))
{
if (reader == null) return null;
if (reader.Read())
{
int count = reader.GetInt32(0);
list = new FileData[count];
reader.NextResult();
int i = 0;
while (reader.Read())
{
if (i < count)
{
list[i].ID = reader.GetInt16(0);
switch ((DataType)reader.GetByte(1))
{
case DataType.BOOL:
list[i].Value.Boolean = Convert.ToBoolean(reader.GetValue(2));
break;
case DataType.BYTE:
list[i].Value.Byte = Convert.ToByte(reader.GetValue(2));
break;
case DataType.WORD:
case DataType.SHORT:
list[i].Value.Int16 = Convert.ToInt16(reader.GetValue(2));
break;
case DataType.TIME:
case DataType.INT:
list[i].Value.Int32 = Convert.ToInt32(reader.GetValue(2));
break;
case DataType.FLOAT:
list[i].Value.Single = Convert.ToSingle(reader.GetValue(2));
break;
case DataType.STR:
list[i].Text = Convert.ToString(reader.GetValue(2));
//如何传送字符串?
break;
}
i++;
}
}
}
}
return list;
}
public int Limit
{
get { return 0x100; }
}
public event ShutdownRequestEventHandler OnClose;
}
}