Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
顾剑亮
/
AIOBOX
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 709ec17e
由
顾剑亮
编写于
2020-05-12 11:45:48 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
coding
1 个父辈
9a7eb2f5
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
378 行增加
和
1121 行删除
.vs/AIOBOX/v16/.suo
AIOBOX/AIOBOX.cs
AIOBOX/AIOBOX.csproj
AIOBOX/Log.cs
AIOBOX/Properties/AssemblyInfo.cs
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.dll
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.pdb
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.xml
AIOBOX/obj/Debug/AIOBOX.csproj.CoreCompileInputs.cache
AIOBOX/obj/Debug/AIOBOX.csproj.FileListAbsolute.txt
AIOBOX/obj/Debug/AIOBOX.csprojAssemblyReference.cache
AIOBOX/obj/Debug/Asa.IOModule.AIOBOX.dll
AIOBOX/obj/Debug/Asa.IOModule.AIOBOX.pdb
.vs/AIOBOX/v16/.suo
查看文件 @
709ec17
此文件类型无法预览
AIOBOX/AIOBOX.cs
查看文件 @
709ec17
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Net
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Net.Sockets
;
using
System.Threading
;
using
System.Threading
;
using
System.Collections.Generic
;
namespace
Asa.IOModule
namespace
Asa.IOModule
{
{
/// <summary>
/// <summary>
///
AIOBOX
操作类
///
零点IO模块
操作类
/// </summary>
/// </summary>
public
class
AIOBOX
public
class
AIOBOX
{
{
private
Socket
_client
;
//客户端
private
bool
_quit
;
private
bool
_loop
;
private
string
_logPath
;
//日志的文件夹路径
private
LogFile
_log
;
//日志的类
private
LogType
_logType
;
//日志输出类型
private
bool
_frontInputOutput
;
//True:Input False:Output
private
int
countInput
;
//输入总数
private
int
countOutput
;
//输出总数
private
int
sleepInput
;
//自动读取DI间隔
private
int
sleepOutput
;
//自动读取DO间隔
private
Box_Type
_typeInput
;
//输入类型
private
Box_Type
_typeOutput
;
//输出类型
private
byte
[]
_addressInput
;
//输入地址
private
byte
[]
_addressOutput
;
//输出地址
private
bool
_autoReadInput
;
//自动读取DI
private
bool
_autoReadOutput
;
//自动读取DO
private
bool
_manualReadOutput
;
//手动读取DO
private
bool
_changeDI
;
//DI收到数据触发事件
private
bool
_changeDO
;
//DO收到数据触发事件
private
bool
_changeAI
;
//AI收到数据触发事件
private
bool
_changeAO
;
//AO收到数据触发事件
private
Box_Sta
[]
_stateDI
;
//状态
private
Box_Sta
[]
_stateDO
;
//状态
private
int
[]
_valueAI
;
//模拟量
private
int
[]
_valueAO
;
//模拟量
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
ushort
>
_flag
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
_send
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
_receive
;
private
Thread
tRecon
;
private
Thread
tSend
;
//发送命令处理
private
Thread
tReceive
;
//接收信息处理
private
Thread
tListen
;
//监听网络
private
Thread
tTrigger
;
//触发DI、DO改变事件
private
Thread
tReadInput
;
//自动读取DI线程
private
Thread
tReadOutput
;
//自动读取DO线程
private
Thread
tFlag
;
//ModBusTCP标识
private
UdpClient
broadcastClient
;
//广播客户端
private
IPEndPoint
broadcastEndPoint
;
//广播远程节点
private
byte
[]
broadcastBuffer
;
//远程返回数据
/// <summary>
/// 每条命令发送的间隔
/// 不能小于15,会出现IO接收不到的情况
/// 小于30时,会出现接收数据连包的情况
/// </summary>
private
const
int
SEND_SLEEP
=
30
;
/// <summary>
/// ModBus端口
/// </summary>
public
const
int
PORT
=
502
;
/// <summary>
/// <summary>
/// 自动读取DI委托
/// 自动读取DI委托
/// </summary>
/// </summary>
...
@@ -82,180 +25,99 @@ namespace Asa.IOModule
...
@@ -82,180 +25,99 @@ namespace Asa.IOModule
/// 自动读取DO事件触发
/// 自动读取DO事件触发
/// </summary>
/// </summary>
public
event
DIO_Changed
DO_Changed_Event
;
public
event
DIO_Changed
DO_Changed_Event
;
/// <summary>
/// 自动读取AI委托
/// </summary>
/// <param name="box">AIOBOX</param>
/// <param name="val">所有AI的值</param>
public
delegate
void
AIO_Changed
(
AIOBOX
box
,
int
[]
val
);
/// <summary>
/// 自动读取AI事件触发
/// </summary>
public
event
AIO_Changed
AI_Changed_Event
;
/// <summary>
/// 自动读取AO事件触发
/// </summary>
public
event
AIO_Changed
AO_Changed_Event
;
/// <summary>
private
Socket
_client
;
//客户端
/// AIOBOX
private
bool
_loop
;
/// </summary>
private
ushort
_uid
;
public
AIOBOX
()
private
Box_Sta
[]
_stateDI
;
//DI状态
{
private
Box_Sta
[]
_stateDO
;
//DO状态
_log
=
null
;
private
int
[]
_valueAI
;
//AI模拟量
_logPath
=
null
;
private
int
[]
_valueAO
;
//AO模拟量
_autoReadInput
=
false
;
private
List
<
byte
>
_receive
;
_autoReadOutput
=
false
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
_writeDO
;
_manualReadOutput
=
false
;
sleepInput
=
100
;
private
readonly
Box_Type
_typeInput
;
//输入类型
sleepOutput
=
100
;
private
readonly
Box_Type
_typeOutput
;
//输出类型
}
private
readonly
byte
[]
_addressInput
;
//输入地址
private
readonly
byte
[]
_addressOutput
;
//输出地址
/// <summary>
private
const
int
SEND_SLEEP
=
50
;
//每条命令发送的间隔,不能小于15,会出现IO接收不到的情况,小于30时,会出现接收数据连包的情况
/// IP地址
private
const
int
PORT
=
502
;
//端口
/// </summary>
private
const
int
UPLOAD_TIME
=
8000
;
//8秒
public
string
IP
{
set
;
get
;
}
=
"192.168.1.100"
;
private
Thread
tRecon
;
//重连线程
private
Thread
tSend
;
//发送命令处理
private
Thread
tListen
;
//监听网络
/// <summary>
private
UdpClient
broadcastClient
;
//广播客户端
/// 是否连接
private
IPEndPoint
broadcastEndPoint
;
//广播远程节点
/// </summary>
private
byte
[]
broadcastBuffer
;
//远程返回数据
public
bool
IsConn
{
get
;
private
set
;
}
=
false
;
/// <summary>
/// <summary>
///
错误信息
///
零点IO模块操作类
/// </summary>
/// </summary>
public
string
ErrInfo
{
get
;
private
set
;
}
=
""
;
/// <param name="input">输入类型</param>
/// <param name="inputCount">输入数量</param>
/// <param name="output">输出类型</param>
/// <param name="outputCount">输出数量</param>
public
AIOBOX
(
Box_Type
input
,
int
inputCount
,
Box_Type
output
,
int
outputCount
)
{
_typeInput
=
input
;
_typeOutput
=
output
;
byte
n
=
0
;
_addressInput
=
new
byte
[
inputCount
];
for
(
int
i
=
0
;
i
<
inputCount
;
i
++)
_addressInput
[
i
]
=
n
++;
_addressOutput
=
new
byte
[
outputCount
];
for
(
int
i
=
0
;
i
<
outputCount
;
i
++)
_addressOutput
[
i
]
=
n
++;
_stateDI
=
new
Box_Sta
[
inputCount
];
_stateDO
=
new
Box_Sta
[
outputCount
];
_valueAI
=
new
int
[
inputCount
];
_valueAO
=
new
int
[
outputCount
];
}
/// <summary>
/// <summary>
///
日志路径,连接前设置路径会自动保存日志
///
IP地址
/// </summary>
/// </summary>
/// <param name="path">文件夹路径</param>
public
string
IP
{
set
;
get
;
}
=
"192.168.1.100"
;
/// <param name="type">输出类型</param>
public
void
LogPath
(
string
path
,
LogType
type
)
{
_logPath
=
path
;
_logType
=
type
;
}
/// <summary>
/// <summary>
///
设置输入端
///
输入主动上传
/// </summary>
/// </summary>
/// <param name="type">类型</param>
public
bool
Upload
{
set
;
get
;
}
=
false
;
/// <param name="count">数量</param>
public
void
SetInput
(
Box_Type
type
,
int
count
)
{
_typeInput
=
type
;
countInput
=
count
;
_frontInputOutput
=
false
;
}
/// <summary>
/// <summary>
/// 设置输出端
/// 是否连接
/// </summary>
/// <param name="type">类型</param>
/// <param name="count">数量</param>
public
void
SetOutput
(
Box_Type
type
,
int
count
)
{
_typeOutput
=
type
;
countOutput
=
count
;
_frontInputOutput
=
true
;
}
/// <summary>
/// 自动获取IP地址,未连接前使用,必须在同一网段
/// </summary>
/// </summary>
/// <param name="localIP">本地IP地址</param>
public
bool
IsConn
{
get
;
private
set
;
}
=
false
;
/// <returns></returns>
public
bool
AutoIP
(
string
localIP
)
{
try
{
IPEndPoint
local
=
new
IPEndPoint
(
IPAddress
.
Parse
(
localIP
),
55654
);
broadcastClient
=
new
UdpClient
(
local
);
broadcastBuffer
=
null
;
Thread
tTemp
=
new
Thread
(
new
ThreadStart
(
GetIP
));
tTemp
.
Start
();
broadcastEndPoint
=
new
IPEndPoint
(
IPAddress
.
Parse
(
"255.255.255.255"
),
1024
);
byte
[]
dgram
=
new
byte
[]
{
0x05
,
0x00
,
0x07
,
0x00
,
0x00
,
0xC1
,
0x59
};
broadcastClient
.
Send
(
dgram
,
dgram
.
Length
,
broadcastEndPoint
);
Thread
.
Sleep
(
1000
);
tTemp
.
Abort
();
broadcastClient
.
Close
();
ErrInfo
=
"无法访问"
;
if
(
broadcastBuffer
==
null
)
return
false
;
if
(
broadcastBuffer
[
0
]
!=
0x3B
)
return
false
;
byte
[]
buff
=
new
byte
[
broadcastBuffer
[
7
]];
Array
.
Copy
(
broadcastBuffer
,
9
,
buff
,
0
,
buff
.
Length
);
IP
=
buff
[
buff
.
Length
-
12
]
+
"."
+
buff
[
buff
.
Length
-
11
]
+
"."
+
buff
[
buff
.
Length
-
10
]
+
"."
+
buff
[
buff
.
Length
-
9
];
ErrInfo
=
"OK"
;
return
true
;
}
catch
(
Exception
ex
)
{
ErrInfo
=
ex
.
Message
;
return
false
;
}
}
/// <summary>
/// <summary>
///
检查IP地址
///
错误信息
/// </summary>
/// </summary>
/// <param name="ip"></param>
public
string
ErrInfo
{
get
;
private
set
;
}
=
""
;
/// <returns></returns>
public
bool
CheckIP
(
string
ip
)
{
//IP合法
string
pattern
=
@"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"
;
bool
rtn
=
System
.
Text
.
RegularExpressions
.
Regex
.
IsMatch
(
ip
,
pattern
);
if
(!
rtn
)
{
ErrInfo
=
"非法的IP地址"
;
return
false
;
}
//Ping服务端
System
.
Net
.
NetworkInformation
.
Ping
ping
=
new
System
.
Net
.
NetworkInformation
.
Ping
();
System
.
Net
.
NetworkInformation
.
PingReply
result
=
ping
.
Send
(
ip
,
1000
);
ping
.
Dispose
();
if
(
result
.
Status
!=
System
.
Net
.
NetworkInformation
.
IPStatus
.
Success
)
{
ErrInfo
=
"Ping "
+
ip
+
" 请求没有响应"
;
return
false
;
}
return
true
;
}
/// <summary>
/// <summary>
/// 连接
/// 连接
/// </summary>
/// </summary>
public
void
Connect
()
public
void
Connect
()
{
{
if
(
_logPath
==
null
)
_loop
=
true
;
_log
=
null
;
_uid
=
0
;
else
IsConn
=
false
;
_log
=
new
LogFile
(
_logPath
,
IP
);
_receive
=
new
List
<
byte
>();
_writeDO
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_quit
=
false
;
tRecon
=
new
Thread
(
new
ThreadStart
(
Reconn
));
tRecon
=
new
Thread
(
new
ThreadStart
(
Reconn
));
tSend
=
new
Thread
(
new
ThreadStart
(
Send
));
tListen
=
new
Thread
(
new
ThreadStart
(
Listen
));
tRecon
.
Start
();
tRecon
.
Start
();
tSend
.
Start
();
tListen
.
Start
();
int
time
=
0
;
while
(
time
<
3000
)
{
if
(
IsConn
)
break
;
else
time
+=
50
;
Thread
.
Sleep
(
50
);
}
}
}
/// <summary>
/// <summary>
...
@@ -263,82 +125,26 @@ namespace Asa.IOModule
...
@@ -263,82 +125,26 @@ namespace Asa.IOModule
/// </summary>
/// </summary>
public
void
Close
()
public
void
Close
()
{
{
_
quit
=
tru
e
;
_
loop
=
fals
e
;
Exit
()
;
IsConn
=
false
;
if
(
_log
!=
null
)
try
{
{
_log
.
OutData
(
"Close OK"
);
if
(
_client
!=
null
)
_log
.
Close
();
{
_log
=
null
;
_client
.
Shutdown
(
SocketShutdown
.
Both
);
_client
.
Close
();
}
}
}
}
catch
(
Exception
ex
)
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 禁止)
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public
void
AutoReadInput
(
bool
read
,
int
sleep
)
{
if
(
countInput
<
1
)
_autoReadInput
=
false
;
else
if
(
sleep
<
15
)
_autoReadInput
=
false
;
else
if
(
read
)
{
{
_autoReadInput
=
true
;
ErrInfo
=
ex
.
Message
;
sleepInput
=
sleep
;
}
}
else
finally
_autoReadInput
=
false
;
}
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 使能)
/// </summary>
/// <param name="read">是否自动读取</param>
public
void
AutoReadInput
(
bool
read
)
{
if
(
countInput
<
1
)
_autoReadInput
=
false
;
else
if
(
read
)
{
{
_autoReadInput
=
true
;
_client
=
null
;
sleepInput
=
8000
;
//IO模块最大10s,避免超过时间,每8秒发送一次心跳包
}
}
else
_autoReadInput
=
false
;
}
/// <summary>
/// 自动读取输出端,触发事件
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public
void
AutoReadOutput
(
bool
read
,
int
sleep
)
{
if
(
countOutput
<
1
)
{
_autoReadOutput
=
false
;
sleepOutput
=
100
;
}
else
if
(
sleep
<
15
)
{
_autoReadOutput
=
false
;
sleepOutput
=
100
;
}
else
if
(
read
)
{
_autoReadOutput
=
true
;
sleepOutput
=
sleep
;
}
else
{
_autoReadOutput
=
false
;
_manualReadOutput
=
true
;
//用于第一次连接的时候读取一次状态
sleepOutput
=
sleep
;
}
}
}
/// <summary>
/// <summary>
...
@@ -471,9 +277,7 @@ namespace Asa.IOModule
...
@@ -471,9 +277,7 @@ namespace Asa.IOModule
buff
[
7
]
=
5
;
//功能码
buff
[
7
]
=
5
;
//功能码
buff
[
9
]
=
_addressOutput
[
add
];
//地址
buff
[
9
]
=
_addressOutput
[
add
];
//地址
buff
[
10
]
=
(
byte
)
sta
;
//写入值
buff
[
10
]
=
(
byte
)
sta
;
//写入值
_send
.
Enqueue
(
buff
);
_writeDO
.
Enqueue
(
buff
);
if
(!
_autoReadOutput
)
_manualReadOutput
=
true
;
return
true
;
return
true
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
...
@@ -483,523 +287,274 @@ namespace Asa.IOModule
...
@@ -483,523 +287,274 @@ namespace Asa.IOModule
}
}
}
}
/// <summary>
/// 获取本地IPv4地址
/// </summary>
/// <returns></returns>
public
string
[]
GetLocalIP
()
{
List
<
string
>
str
=
new
List
<
string
>();
IPAddress
[]
add
=
Dns
.
GetHostEntry
(
Dns
.
GetHostName
()).
AddressList
;
foreach
(
IPAddress
ip
in
add
)
{
if
(
ip
.
AddressFamily
.
ToString
()
==
"InterNetwork"
)
str
.
Add
(
ip
.
ToString
());
}
return
str
.
ToArray
();
}
/// <summary>
/// <summary>
/// 发送命令
/// 发送命令
线程
/// </summary>
/// </summary>
private
void
Send
()
private
void
Send
()
{
{
bool
shift
=
true
;
//切换
int
time
=
0
;
//上传时间
int
writeTimer
=
0
;
//写入DO次数
bool
writeStop
=
false
;
//写入命令停止
while
(
_loop
)
while
(
_loop
)
{
{
bool
rtn
=
_send
.
TryDequeue
(
out
byte
[]
result
);
if
(
rtn
)
{
try
{
_client
.
Send
(
result
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Send "
,
result
);
}
}
catch
(
Exception
ex
)
{
IsConn
=
false
;
_loop
=
false
;
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
Thread
.
Sleep
(
SEND_SLEEP
);
Thread
.
Sleep
(
SEND_SLEEP
);
}
if
(!
IsConn
)
continue
;
}
byte
[]
buff
;
/// <summary>
if
(
Upload
)
//主动上传
/// 接收命令
/// </summary>
private
void
Receive
()
{
while
(
_loop
)
{
if
(
_receive
.
TryDequeue
(
out
byte
[]
buff
))
{
{
try
if
(
time
>=
UPLOAD_TIME
)
{
{
if
(
_log
!=
null
)
buff
=
GetReadDI_Command
();
{
time
=
0
;
if
(
_logType
==
LogType
.
All
)
}
_log
.
OutData
(
"Receive "
,
buff
);
else
}
{
if
(
buff
.
Length
<
7
)
if
(
writeTimer
>=
3
)
//连续发送WriteDO3次,强制发送DO
continue
;
if
(
buff
[
7
]
==
1
)
{
ReadDO
(
buff
);
_changeDO
=
true
;
}
else
if
(
buff
[
7
]
==
2
)
{
ReadDI
(
buff
);
_changeDI
=
true
;
}
else
if
(
buff
[
7
]
==
4
)
{
{
ReadAI
(
buff
);
buff
=
GetReadDO_Command
(
);
_changeAI
=
true
;
writeTimer
=
0
;
}
}
else
if
(
buff
[
7
]
==
5
)
else
{
{
//ReadSingle(buff);
if
(
_writeDO
.
TryDequeue
(
out
buff
))
{
writeTimer
++;
}
else
{
buff
=
GetReadDO_Command
();
writeTimer
=
0
;
}
}
}
}
}
catch
(
Exception
ex
)
time
+=
SEND_SLEEP
;
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
}
Thread
.
Sleep
(
10
);
else
}
}
/// <summary>
/// 读取写入单个DO,功能码5
/// </summary>
/// <param name="buff"></param>
private
void
ReadSingle
(
byte
[]
buff
)
{
string
s
;
//if (LogOut)
//{
// byte[] bb = new byte[2];
// bb[0] = buff[1];
// bb[1] = buff[0];
// ushort flag = BitConverter.ToUInt16(bb, 0);
// s = string.Format("{0:HH:mm:ss:fff} WriteDO {1} fun={2} len={3}", DateTime.Now, flag, buff[7], buff.Length);
// _log.Add(s);
//}
// int n = 0;
// int move = 0;
// byte val = _receive[0][9];
// for (int i = 0; i < 8; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// if (_receive[0][8] == 2)
// {
// move = 0;
// val = _receive[0][10];
// for (int i = 8; i < 16; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// }
// ErrInfo = "OK";
//}
//catch (Exception ex)
//{
// ErrInfo = ex.Message;
//}
}
/// <summary>
/// 读取所有DO状态,功能码1
/// </summary>
/// <param name="buff"></param>
private
void
ReadDO
(
byte
[]
buff
)
{
try
{
int
idx
=
0
;
int
count
=
buff
[
8
];
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
{
int
n
=
0
;
if
(
writeTimer
>=
3
)
//连续发送WriteDO3次,强制发送DI和DO
int
move
=
0
;
byte
val
=
buff
[
8
+
i
];
for
(
int
j
=
0
;
j
<
8
;
j
++)
{
{
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
if
(
shift
)
_stateDO
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
buff
=
GetReadDI_Command
();
move
++;
else
buff
=
GetReadDO_Command
();
shift
=
!
shift
;
if
(
writeStop
)
writeTimer
=
0
;
else
writeStop
=
true
;
}
else
{
if
(
_writeDO
.
TryDequeue
(
out
buff
))
{
writeTimer
++;
writeStop
=
false
;
}
else
{
if
(
shift
)
buff
=
GetReadDI_Command
();
else
buff
=
GetReadDO_Command
();
shift
=
!
shift
;
writeTimer
=
0
;
}
}
}
}
}
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Read All DO"
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
/// <summary>
try
/// 读取所有DI状态,功能码2
/// </summary>
private
void
ReadDI
(
byte
[]
buff
)
{
try
{
int
idx
=
0
;
int
count
=
buff
[
8
];
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
{
int
n
=
0
;
_client
.
Send
(
buff
);
int
move
=
0
;
byte
val
=
buff
[
8
+
i
];
for
(
int
j
=
0
;
j
<
8
;
j
++)
{
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
_stateDI
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
move
++;
}
}
}
if
(
_log
!=
null
)
catch
(
Exception
ex
)
{
{
if
(
_logType
==
LogType
.
All
)
ErrInfo
=
ex
.
Message
;
_log
.
OutData
(
"Read All DI"
)
;
IsConn
=
false
;
}
}
//Test 方法锁
TestMethod
();
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
}
}
/// <summary>
/// <summary>
///
读取所有AI的值,功能码4
///
获取ReadDI的命令
/// </summary>
/// </summary>
/// <
param name="buff"></param
>
/// <
returns></returns
>
private
void
ReadAI
(
byte
[]
buff
)
private
byte
[]
GetReadDI_Command
(
)
{
{
try
byte
[]
data
=
Command
();
{
byte
[]
buff
=
new
byte
[
12
];
if
(
countInput
*
2
==
buff
[
8
])
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
{
buff
[
5
]
=
6
;
//后面字节数
_valueAI
[
0
]
=
buff
[
9
]
*
256
+
buff
[
10
];
//功能码
_valueAI
[
1
]
=
buff
[
11
]
*
256
+
buff
[
12
];
if
(
_typeInput
==
Box_Type
.
DI
)
_valueAI
[
2
]
=
buff
[
13
]
*
256
+
buff
[
14
];
buff
[
7
]
=
2
;
_valueAI
[
3
]
=
buff
[
15
]
*
256
+
buff
[
16
];
else
if
(
_typeInput
==
Box_Type
.
AI
)
}
buff
[
7
]
=
4
;
if
(
_log
!=
null
)
buff
[
9
]
=
_addressInput
[
0
];
//地址
{
buff
[
11
]
=
(
byte
)
_addressInput
.
Length
;
//个数
if
(
_logType
==
LogType
.
All
)
return
buff
;
_log
.
OutData
(
"Read All AI"
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
}
/// <summary>
/// <summary>
///
命令,前7个字节
///
获取ReadDO的命令
/// </summary>
/// </summary>
/// <returns></returns>
/// <returns></returns>
private
byte
[]
Command
()
private
byte
[]
GetReadDO_
Command
()
{
{
_flag
.
TryDequeue
(
out
ushort
result
);
byte
[]
data
=
Command
();
byte
[]
flag
=
BitConverter
.
GetBytes
(
result
);
byte
[]
buff
=
new
byte
[
12
];
byte
[]
data
=
new
byte
[
7
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
data
[
0
]
=
flag
[
1
];
buff
[
5
]
=
6
;
//后面字节数
data
[
1
]
=
flag
[
0
];
buff
[
7
]
=
1
;
//功能码
data
[
2
]
=
0
;
buff
[
9
]
=
_addressOutput
[
0
];
//地址
data
[
3
]
=
0
;
buff
[
11
]
=
(
byte
)
_addressOutput
.
Length
;
//个数
data
[
4
]
=
0
;
return
buff
;
data
[
5
]
=
0
;
data
[
6
]
=
255
;
return
data
;
}
}
/// <summary>
/// <summary>
///
触发DIO改变事件
///
监听网络线程
/// </summary>
/// </summary>
private
void
TriggerDIO
()
private
void
Listen
()
{
{
while
(
_loop
)
while
(
_loop
)
{
{
if
(
_typeInput
==
Box_Type
.
DI
&&
DI_Changed_Event
!=
null
)
Thread
.
Sleep
(
10
);
{
if
(!
IsConn
)
continue
;
//if (_changeDI)
if
(
_client
==
null
)
continue
;
//{
// _changeDI = false;
// Box_Sta[] staDI = new Box_Sta[countInput];
// Array.Copy(_stateDI, 0, staDI, 0, staDI.Length);
// if (_log != null)
// {
// if (_logType == LogType.All)
// _log.OutData("Trigger DI Event");
// }
// lock (staDI)
// System.Threading.Tasks.Task.Run(() => DI_Changed_Event.Invoke(this, staDI));
//}
}
else
if
(
_typeInput
==
Box_Type
.
AI
&&
AI_Changed_Event
!=
null
)
{
if
(
_changeAI
)
{
_changeAI
=
false
;
int
[]
valAI
=
new
int
[
countInput
];
Array
.
Copy
(
_valueAI
,
0
,
valAI
,
0
,
valAI
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger AI Event"
);
}
lock
(
valAI
)
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
AI_Changed_Event
.
Invoke
(
this
,
valAI
));
}
}
if
(
_typeOutput
==
Box_Type
.
DO
&&
DO_Changed_Event
!=
null
)
try
{
{
if
(
_c
hangeDO
)
if
(
_c
lient
.
Available
>
0
)
{
{
_changeDO
=
false
;
byte
[]
buff
=
new
byte
[
_client
.
ReceiveBufferSize
];
Box_Sta
[]
staDO
=
new
Box_Sta
[
countOutput
];
int
count
=
_client
.
Receive
(
buff
);
Array
.
Copy
(
_stateDO
,
0
,
staDO
,
0
,
staDO
.
Length
);
byte
[]
temp
=
new
byte
[
count
];
if
(
_log
!=
null
)
Array
.
Copy
(
buff
,
0
,
temp
,
0
,
count
);
lock
(
_receive
)
{
{
if
(
_logType
==
LogType
.
All
)
_receive
.
AddRange
(
temp
);
_log
.
OutData
(
"Trigger DO Event"
);
while
(
_receive
.
Count
>
6
)
//分解连包
{
int
len
=
_receive
[
5
]
+
6
;
if
(
len
>
_receive
.
Count
)
break
;
byte
[]
cmd
=
new
byte
[
len
];
_receive
.
CopyTo
(
0
,
cmd
,
0
,
len
);
_receive
.
RemoveRange
(
0
,
len
);
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
CommandProcess
(
cmd
));
}
}
}
lock
(
staDO
)
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
DO_Changed_Event
.
Invoke
(
this
,
staDO
));
}
}
}
}
else
if
(
_typeOutput
==
Box_Type
.
AO
&&
AO_Changed_Event
!=
null
)
catch
(
Exception
ex
)
{
{
if
(
_changeAO
)
ErrInfo
=
ex
.
Message
;
{
IsConn
=
false
;
_changeAO
=
false
;
int
[]
valAO
=
new
int
[
countOutput
];
Array
.
Copy
(
_valueAO
,
0
,
valAO
,
0
,
valAO
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger AO Event"
);
}
lock
(
valAO
)
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
AO_Changed_Event
.
Invoke
(
this
,
valAO
));
}
}
}
Thread
.
Sleep
(
10
);
}
}
}
}
/// <summary>
/// <summary>
///
自动读取输入端线程
///
接收到的命令处理方法,(task多线程)
/// </summary>
/// </summary>
private
void
AutoReadInput
()
/// <param name="cmd"></param>
private
void
CommandProcess
(
byte
[]
cmd
)
{
{
while
(
_loop
)
int
idx
=
0
;
{
int
count
=
cmd
[
8
];
if
(
IsConn
&&
_autoReadInput
)
{
//if (suspendDI && suspend > 0)
//{
// suspendDI = false;
// suspend--;
//}
//else
//{
byte
[]
data
=
Command
();
byte
[]
buff
=
new
byte
[
12
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
buff
[
5
]
=
6
;
//后面字节数
//功能码
if
(
_typeInput
==
Box_Type
.
DI
)
buff
[
7
]
=
2
;
else
if
(
_typeInput
==
Box_Type
.
AI
)
buff
[
7
]
=
4
;
buff
[
9
]
=
_addressInput
[
0
];
//地址
buff
[
11
]
=
(
byte
)
countInput
;
//个数
_send
.
Enqueue
(
buff
);
//suspendDI = true;
//}
}
Thread
.
Sleep
(
sleepInput
);
}
}
/// <summary>
try
/// 自动读取输出端线程
/// </summary>
private
void
AutoReadOutput
()
{
while
(
_loop
)
{
{
Thread
.
Sleep
(
sleepOutput
);
if
(
cmd
[
7
]
==
1
)
//ReadDO
if
(!
IsConn
)
continue
;
if
(!
_autoReadOutput
)
{
{
if
(
_manualReadOutput
)
Box_Sta
[]
staDO
=
new
Box_Sta
[
_stateDO
.
Length
];
_manualReadOutput
=
false
;
lock
(
_stateDO
)
else
{
continue
;
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
int
move
=
0
;
byte
val
=
cmd
[
8
+
i
];
for
(
int
j
=
0
;
j
<
8
;
j
++)
//字节的0-7位
{
int
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
_stateDO
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
move
++;
}
}
Array
.
Copy
(
_stateDO
,
0
,
staDO
,
0
,
staDO
.
Length
);
}
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
DO_Changed_Event
?.
Invoke
(
this
,
staDO
));
}
}
else
if
(
cmd
[
7
]
==
2
)
//ReadDI
byte
[]
data
=
Command
();
byte
[]
buff
=
new
byte
[
12
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
buff
[
5
]
=
6
;
//后面字节数
buff
[
7
]
=
1
;
//功能码
buff
[
9
]
=
_addressOutput
[
0
];
//地址
buff
[
11
]
=
(
byte
)
countOutput
;
//个数
_send
.
Enqueue
(
buff
);
}
}
/// <summary>
/// 监听结果线程
/// </summary>
private
void
Listen
()
{
byte
[]
temp
=
new
byte
[
200
];
int
start
,
len
;
while
(
_loop
)
{
try
{
{
if
(
_client
==
null
)
break
;
Box_Sta
[]
staDI
=
new
Box_Sta
[
_stateDI
.
Length
]
;
if
(
_client
.
Available
>
0
)
lock
(
_stateDI
)
{
{
start
=
0
;
for
(
int
i
=
1
;
i
<=
count
;
i
++)
int
count
=
_client
.
Receive
(
temp
);
while
(
count
-
start
>
6
)
{
{
len
=
temp
[
start
+
5
];
int
move
=
0
;
len
+=
6
;
byte
val
=
cmd
[
8
+
i
];
if
(
start
+
len
>
count
)
break
;
for
(
int
j
=
0
;
j
<
8
;
j
++)
//字节的0-7位
byte
[]
aa
=
new
byte
[
len
];
{
Array
.
Copy
(
temp
,
start
,
aa
,
0
,
len
);
int
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
_receive
.
Enqueue
(
aa
);
_stateDI
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
start
+=
len
;
move
++;
}
}
}
Array
.
Copy
(
_stateDI
,
0
,
staDI
,
0
,
staDI
.
Length
);
}
}
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
DI_Changed_Event
?.
Invoke
(
this
,
staDI
));
}
}
catch
(
Exception
ex
)
else
if
(
cmd
[
7
]
==
5
)
{
{
IsConn
=
false
;
_loop
=
false
;
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
Thread
.
Sleep
(
10
);
}
}
}
catch
(
Exception
ex
)
private
void
InitAddr
()
{
byte
n
=
0
;
if
(
_frontInputOutput
)
{
_addressInput
=
new
byte
[
countInput
];
for
(
int
i
=
0
;
i
<
countInput
;
i
++)
_addressInput
[
i
]
=
n
++;
_addressOutput
=
new
byte
[
countOutput
];
for
(
int
i
=
0
;
i
<
countOutput
;
i
++)
_addressOutput
[
i
]
=
n
++;
}
else
{
{
_addressOutput
=
new
byte
[
countOutput
];
ErrInfo
=
ex
.
Message
;
for
(
int
i
=
0
;
i
<
countOutput
;
i
++)
_addressOutput
[
i
]
=
n
++;
_addressInput
=
new
byte
[
countInput
];
for
(
int
i
=
0
;
i
<
countInput
;
i
++)
_addressInput
[
i
]
=
n
++;
}
}
_stateDI
=
new
Box_Sta
[
countInput
];
_stateDO
=
new
Box_Sta
[
countOutput
];
_valueAI
=
new
int
[
countInput
];
_valueAO
=
new
int
[
countOutput
];
}
}
private
void
GetIP
()
/// <summary>
{
/// 重连线程
broadcastBuffer
=
broadcastClient
.
Receive
(
ref
broadcastEndPoint
);
/// </summary>
}
private
void
Reconn
()
private
void
Flag
()
{
{
ushort
n
=
0
;
while
(
_loop
)
while
(
_loop
)
{
{
if
(
_flag
.
Count
<
10
)
if
(
IsConn
)
{
Thread
.
Sleep
(
1000
);
}
else
{
{
_flag
.
Enqueue
(++
n
);
Thread
.
Sleep
(
100
);
if
(
n
==
ushort
.
MaxValue
)
n
=
0
;
if
(
_loop
)
Open
()
;
}
}
Thread
.
Sleep
(
5
);
}
}
}
}
/// <summary>
/// 打开socket建立连接
/// </summary>
private
void
Open
()
private
void
Open
()
{
{
try
try
{
{
//初始化地址
IsConn
=
false
;
IsConn
=
false
;
InitAddr
();
//检查IP地址
bool
rtn
=
CheckIP
(
IP
);
bool
rtn
=
CheckIP
(
IP
);
if
(!
rtn
)
return
;
if
(!
rtn
)
return
;
_send
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_receive
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_flag
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
ushort
>();
//建立连接
//建立连接
_client
=
new
Socket
(
AddressFamily
.
InterNetwork
,
SocketType
.
Stream
,
ProtocolType
.
Tcp
);
_client
=
new
Socket
(
AddressFamily
.
InterNetwork
,
SocketType
.
Stream
,
ProtocolType
.
Tcp
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
SendTimeout
,
500
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
SendTimeout
,
500
);
...
@@ -1007,108 +562,118 @@ namespace Asa.IOModule
...
@@ -1007,108 +562,118 @@ namespace Asa.IOModule
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
NoDelay
,
1
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
NoDelay
,
1
);
_client
.
Connect
(
IPAddress
.
Parse
(
IP
),
PORT
);
_client
.
Connect
(
IPAddress
.
Parse
(
IP
),
PORT
);
Thread
.
Sleep
(
100
);
//需要等待一会才能获取连接状态
Thread
.
Sleep
(
100
);
//需要等待一会才能获取连接状态
tFlag
=
new
Thread
(
new
ThreadStart
(
Flag
));
tFlag
.
Start
();
Thread
.
Sleep
(
10
);
tSend
=
new
Thread
(
new
ThreadStart
(
Send
));
tReceive
=
new
Thread
(
new
ThreadStart
(
Receive
));
tListen
=
new
Thread
(
new
ThreadStart
(
Listen
));
tTrigger
=
new
Thread
(
new
ThreadStart
(
TriggerDIO
));
tReadInput
=
new
Thread
(
new
ThreadStart
(
AutoReadInput
));
tReadOutput
=
new
Thread
(
new
ThreadStart
(
AutoReadOutput
));
IsConn
=
true
;
IsConn
=
true
;
_loop
=
true
;
tListen
.
Start
();
tTrigger
.
Start
();
tSend
.
Start
();
tReceive
.
Start
();
tReadInput
.
Start
();
tReadOutput
.
Start
();
ErrInfo
=
""
;
ErrInfo
=
""
;
if
(
_log
!=
null
)
_log
.
OutData
(
"Connect OK"
);
return
;
return
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
IsConn
=
false
;
IsConn
=
false
;
ErrInfo
=
ex
.
Message
;
ErrInfo
=
ex
.
Message
;
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
return
;
return
;
}
}
}
}
private
void
Exit
()
/// <summary>
/// 检查IP地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
private
bool
CheckIP
(
string
ip
)
{
{
IsConn
=
false
;
//IP合法
_loop
=
false
;
string
pattern
=
@"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"
;
tListen
=
null
;
bool
rtn
=
System
.
Text
.
RegularExpressions
.
Regex
.
IsMatch
(
ip
,
pattern
);
tReadInput
=
null
;
if
(!
rtn
)
tReadOutput
=
null
;
{
tTrigger
=
null
;
ErrInfo
=
"非法的IP地址"
;
tSend
=
null
;
return
false
;
tReceive
=
null
;
}
tFlag
=
null
;
try
//Ping服务端
System
.
Net
.
NetworkInformation
.
Ping
ping
=
new
System
.
Net
.
NetworkInformation
.
Ping
();
System
.
Net
.
NetworkInformation
.
PingReply
result
=
ping
.
Send
(
ip
,
1000
);
ping
.
Dispose
();
if
(
result
.
Status
!=
System
.
Net
.
NetworkInformation
.
IPStatus
.
Success
)
{
{
if
(
_client
!=
null
)
ErrInfo
=
"Ping "
+
ip
+
" 请求没有响应"
;
{
return
false
;
_client
.
Shutdown
(
SocketShutdown
.
Both
);
_client
.
Close
();
}
}
}
catch
(
Exception
ex
)
return
true
;
}
/// <summary>
/// 自动获取IP地址,未连接前使用,必须在同一网段
/// </summary>
/// <param name="localIP">本地IP地址</param>
/// <returns></returns>
private
bool
AutoIP
(
string
localIP
)
{
try
{
{
if
(
_log
!=
null
)
IPEndPoint
local
=
new
IPEndPoint
(
IPAddress
.
Parse
(
localIP
),
55654
);
_log
.
OutError
(
ex
.
Message
);
broadcastClient
=
new
UdpClient
(
local
);
broadcastBuffer
=
null
;
Thread
tTemp
=
new
Thread
(
new
ThreadStart
(
GetIP
));
tTemp
.
Start
();
broadcastEndPoint
=
new
IPEndPoint
(
IPAddress
.
Parse
(
"255.255.255.255"
),
1024
);
byte
[]
dgram
=
new
byte
[]
{
0x05
,
0x00
,
0x07
,
0x00
,
0x00
,
0xC1
,
0x59
};
broadcastClient
.
Send
(
dgram
,
dgram
.
Length
,
broadcastEndPoint
);
Thread
.
Sleep
(
1000
);
tTemp
.
Abort
();
broadcastClient
.
Close
();
ErrInfo
=
"无法访问"
;
if
(
broadcastBuffer
==
null
)
return
false
;
if
(
broadcastBuffer
[
0
]
!=
0x3B
)
return
false
;
byte
[]
buff
=
new
byte
[
broadcastBuffer
[
7
]];
Array
.
Copy
(
broadcastBuffer
,
9
,
buff
,
0
,
buff
.
Length
);
IP
=
buff
[
buff
.
Length
-
12
]
+
"."
+
buff
[
buff
.
Length
-
11
]
+
"."
+
buff
[
buff
.
Length
-
10
]
+
"."
+
buff
[
buff
.
Length
-
9
];
ErrInfo
=
"OK"
;
return
true
;
}
}
finally
catch
(
Exception
ex
)
{
{
_client
=
null
;
ErrInfo
=
ex
.
Message
;
return
false
;
}
}
}
}
/// <summary>
/// <summary>
/// 测试方法锁
/// 获取IO模块IP地址
/// </summary>
private
void
GetIP
()
{
broadcastBuffer
=
broadcastClient
.
Receive
(
ref
broadcastEndPoint
);
}
/// <summary>
/// 命令,前7个字节
/// </summary>
/// </summary>
/// <returns></returns>
[
System
.
Runtime
.
CompilerServices
.
MethodImpl
(
System
.
Runtime
.
CompilerServices
.
MethodImplOptions
.
Synchronized
)]
[
System
.
Runtime
.
CompilerServices
.
MethodImpl
(
System
.
Runtime
.
CompilerServices
.
MethodImplOptions
.
Synchronized
)]
private
void
TestMetho
d
()
private
byte
[]
Comman
d
()
{
{
Box_Sta
[]
staDI
=
new
Box_Sta
[
countInput
];
byte
[]
flag
=
BitConverter
.
GetBytes
(++
_uid
);
Array
.
Copy
(
_stateDI
,
0
,
staDI
,
0
,
staDI
.
Length
);
if
(
_uid
==
ushort
.
MaxValue
)
_uid
=
0
;
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger DI Event"
);
}
lock
(
staDI
)
System
.
Threading
.
Tasks
.
Task
.
Run
(()
=>
DI_Changed_Event
.
Invoke
(
this
,
staDI
));
byte
[]
data
=
new
byte
[
7
];
data
[
0
]
=
flag
[
1
];
data
[
1
]
=
flag
[
0
];
data
[
2
]
=
0
;
data
[
3
]
=
0
;
data
[
4
]
=
0
;
data
[
5
]
=
0
;
data
[
6
]
=
255
;
return
data
;
}
}
private
void
Reconn
()
{
while
(!
_quit
)
{
if
(
IsConn
)
{
Thread
.
Sleep
(
1000
);
}
else
{
Exit
();
Thread
.
Sleep
(
100
);
if
(!
_quit
)
Open
();
}
}
}
}
}
/// <summary>
/// <summary>
/// IO模块类型
/// IO模块类型
/// </summary>
/// </summary>
...
@@ -1147,23 +712,5 @@ namespace Asa.IOModule
...
@@ -1147,23 +712,5 @@ namespace Asa.IOModule
On
=
255
On
=
255
}
}
/// <summary>
/// 日志类型
/// </summary>
public
enum
LogType
:
int
{
/// <summary>
/// 仅错误信息
/// </summary>
OnlyError
,
/// <summary>
/// 所有
/// </summary>
All
}
}
\ No newline at end of file
\ No newline at end of file
}
AIOBOX/AIOBOX.csproj
查看文件 @
709ec17
...
@@ -64,7 +64,6 @@
...
@@ -64,7 +64,6 @@
</ItemGroup>
</ItemGroup>
<ItemGroup>
<ItemGroup>
<Compile Include="AIOBOX.cs" />
<Compile Include="AIOBOX.cs" />
<Compile Include="Log.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
...
...
AIOBOX/Log.cs
deleted
100644 → 0
查看文件 @
9a7eb2f
using
System
;
using
System.Reflection
;
using
System.Diagnostics
;
namespace
Asa.IOModule
{
/// <summary>
/// 日志操作类
/// </summary>
internal
class
LogFile
{
//private string args;
private
bool
loop
;
private
System
.
IO
.
FileStream
fs
;
private
StackTrace
trace
;
private
StackFrame
frame
;
private
MethodBase
method
;
private
System
.
Threading
.
Thread
tSave
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
string
>
info
;
private
readonly
string
PATH
;
/// <summary>
/// 日志
/// </summary>
/// <param name="path">文件夹路径</param>
/// <param name="ip"></param>
internal
LogFile
(
string
path
,
string
ip
)
{
if
(
path
==
null
)
return
;
//this.args = ip;
PATH
=
path
.
EndsWith
(
"\\"
)
?
path
:
path
+
"\\"
;
if
(!
System
.
IO
.
Directory
.
Exists
(
PATH
))
System
.
IO
.
Directory
.
CreateDirectory
(
PATH
);
loop
=
true
;
tSave
=
new
System
.
Threading
.
Thread
(
new
System
.
Threading
.
ThreadStart
(
SaveLog
));
info
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
string
>();
tSave
.
Start
();
string
file
=
string
.
Format
(
"{0}{1:yyyy-MM-dd}_({2}).log"
,
PATH
,
DateTime
.
Now
,
ip
);
fs
=
System
.
IO
.
File
.
OpenWrite
(
file
);
fs
.
Position
=
fs
.
Length
;
}
/// <summary>
/// 关闭文件
/// </summary>
internal
void
Close
()
{
loop
=
false
;
System
.
Threading
.
Thread
.
Sleep
(
5
);
if
(
fs
!=
null
)
fs
.
Close
();
}
/// <summary>
/// 输出错误
/// </summary>
/// <param name="s"></param>
internal
void
OutError
(
string
s
)
{
if
(
string
.
IsNullOrWhiteSpace
(
s
))
return
;
trace
=
new
StackTrace
(
true
);
frame
=
trace
.
GetFrame
(
1
);
string
name
=
frame
.
GetFileName
();
name
=
System
.
IO
.
Path
.
GetFileName
(
name
);
string
log
=
string
.
Format
(
"[{0:HH:mm:ss.fff}] ERROR {1}({2},{3})\r\n"
,
DateTime
.
Now
,
name
,
frame
.
GetFileLineNumber
(),
frame
.
GetFileColumnNumber
());
string
[]
arr
=
new
string
[
trace
.
FrameCount
-
1
];
for
(
int
i
=
1
;
i
<
trace
.
FrameCount
;
i
++)
//0是本身Out
{
method
=
trace
.
GetFrame
(
i
).
GetMethod
();
arr
[
arr
.
Length
-
i
]
=
" "
+
method
.
DeclaringType
.
FullName
+
" -> "
+
method
.
ToString
();
}
log
+=
string
.
Join
(
"\r\n"
,
arr
)
+
string
.
Format
(
"\r\n {0}\r\n"
,
s
);
//byte[] array = System.Text.Encoding.UTF8.GetBytes(log);
//fs.Write(array, 0, array.Length);
info
.
Enqueue
(
log
);
}
/// <summary>
/// 输出信息
/// </summary>
/// <param name="s"></param>
internal
void
OutInfo
(
string
s
)
{
if
(
string
.
IsNullOrWhiteSpace
(
s
))
return
;
trace
=
new
StackTrace
(
true
);
frame
=
trace
.
GetFrame
(
1
);
method
=
trace
.
GetFrame
(
1
).
GetMethod
();
string
name
=
frame
.
GetFileName
();
name
=
System
.
IO
.
Path
.
GetFileName
(
name
);
string
s1
=
method
.
DeclaringType
.
FullName
;
string
s2
=
method
.
Name
;
string
log
=
string
.
Format
(
"[{0:HH:mm:ss.fff}] INFO {1}({2},{3}) {4} -> {5}\r\n {6}\r\n"
,
DateTime
.
Now
,
name
,
frame
.
GetFileLineNumber
(),
frame
.
GetFileColumnNumber
(),
s1
,
s2
,
s
);
//byte[] array = System.Text.Encoding.UTF8.GetBytes(log);
//fs.Write(array, 0, array.Length);
info
.
Enqueue
(
log
);
}
/// <summary>
/// 输出数据
/// </summary>
/// <param name="tr"></param>
/// <param name="buff"></param>
internal
void
OutData
(
string
tr
,
byte
[]
buff
)
{
string
log
=
string
.
Format
(
"{0:HH:mm:ss.fff} {1} "
,
DateTime
.
Now
,
tr
);
for
(
int
i
=
0
;
i
<
buff
.
Length
;
i
++)
log
+=
buff
[
i
].
ToString
(
"X2"
)
+
" "
;
log
+=
"\r\n"
;
//byte[] array = System.Text.Encoding.UTF8.GetBytes(log);
//fs.Write(array, 0, array.Length);
info
.
Enqueue
(
log
);
}
/// <summary>
/// 输出数据
/// </summary>
/// <param name="s"></param>
internal
void
OutData
(
string
s
)
{
string
log
=
string
.
Format
(
"{0:HH:mm:ss.fff} {1}\r\n"
,
DateTime
.
Now
,
s
);
//byte[] array = System.Text.Encoding.UTF8.GetBytes(log);
//fs.Write(array, 0, array.Length);
info
.
Enqueue
(
log
);
}
internal
void
SaveLog
()
{
while
(
loop
)
{
try
{
if
(
info
.
TryDequeue
(
out
string
result
))
{
byte
[]
array
=
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
result
);
fs
.
Write
(
array
,
0
,
array
.
Length
);
}
}
catch
(
Exception
)
{
}
System
.
Threading
.
Thread
.
Sleep
(
2
);
}
}
}
}
AIOBOX/Properties/AssemblyInfo.cs
查看文件 @
709ec17
...
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
...
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.3.0.
4
")]
[assembly: AssemblyVersion("2.3.0.
6
")]
[assembly: AssemblyFileVersion("2.3.0.
4
")]
[assembly: AssemblyFileVersion("2.3.0.
6
")]
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.dll
查看文件 @
709ec17
此文件类型无法预览
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.pdb
查看文件 @
709ec17
此文件类型无法预览
AIOBOX/bin/Debug/Asa.IOModule.AIOBOX.xml
查看文件 @
709ec17
...
@@ -6,19 +6,7 @@
...
@@ -6,19 +6,7 @@
<members>
<members>
<member
name=
"T:Asa.IOModule.AIOBOX"
>
<member
name=
"T:Asa.IOModule.AIOBOX"
>
<summary>
<summary>
AIOBOX操作类
零点IO模块操作类
</summary>
</member>
<member
name=
"F:Asa.IOModule.AIOBOX.SEND_SLEEP"
>
<summary>
每条命令发送的间隔
不能小于15,会出现IO接收不到的情况
小于30时,会出现接收数据连包的情况
</summary>
</member>
<member
name=
"F:Asa.IOModule.AIOBOX.PORT"
>
<summary>
ModBus端口
</summary>
</summary>
</member>
</member>
<member
name=
"T:Asa.IOModule.AIOBOX.DIO_Changed"
>
<member
name=
"T:Asa.IOModule.AIOBOX.DIO_Changed"
>
...
@@ -38,31 +26,23 @@
...
@@ -38,31 +26,23 @@
自动读取DO事件触发
自动读取DO事件触发
</summary>
</summary>
</member>
</member>
<member
name=
"T:Asa.IOModule.AIOBOX.AIO_Changed"
>
<member
name=
"M:Asa.IOModule.AIOBOX.#ctor(Asa.IOModule.Box_Type,System.Int32,Asa.IOModule.Box_Type,System.Int32)"
>
<summary>
自动读取AI委托
</summary>
<param
name=
"box"
>
AIOBOX
</param>
<param
name=
"val"
>
所有AI的值
</param>
</member>
<member
name=
"E:Asa.IOModule.AIOBOX.AI_Changed_Event"
>
<summary>
<summary>
自动读取AI事件触发
零点IO模块操作类
</summary>
</summary>
<param
name=
"input"
>
输入类型
</param>
<param
name=
"inputCount"
>
输入数量
</param>
<param
name=
"output"
>
输出类型
</param>
<param
name=
"outputCount"
>
输出数量
</param>
</member>
</member>
<member
name=
"E:Asa.IOModule.AIOBOX.AO_Changed_Event"
>
<member
name=
"P:Asa.IOModule.AIOBOX.IP"
>
<summary>
自动读取AO事件触发
</summary>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.#ctor"
>
<summary>
<summary>
AIOBOX
IP地址
</summary>
</summary>
</member>
</member>
<member
name=
"P:Asa.IOModule.AIOBOX.
IP
"
>
<member
name=
"P:Asa.IOModule.AIOBOX.
Upload
"
>
<summary>
<summary>
IP地址
输入主动上传
</summary>
</summary>
</member>
</member>
<member
name=
"P:Asa.IOModule.AIOBOX.IsConn"
>
<member
name=
"P:Asa.IOModule.AIOBOX.IsConn"
>
...
@@ -75,41 +55,6 @@
...
@@ -75,41 +55,6 @@
错误信息
错误信息
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.LogPath(System.String,Asa.IOModule.LogType)"
>
<summary>
日志路径,连接前设置路径会自动保存日志
</summary>
<param
name=
"path"
>
文件夹路径
</param>
<param
name=
"type"
>
输出类型
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.SetInput(Asa.IOModule.Box_Type,System.Int32)"
>
<summary>
设置输入端
</summary>
<param
name=
"type"
>
类型
</param>
<param
name=
"count"
>
数量
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.SetOutput(Asa.IOModule.Box_Type,System.Int32)"
>
<summary>
设置输出端
</summary>
<param
name=
"type"
>
类型
</param>
<param
name=
"count"
>
数量
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.AutoIP(System.String)"
>
<summary>
自动获取IP地址,未连接前使用,必须在同一网段
</summary>
<param
name=
"localIP"
>
本地IP地址
</param>
<returns></returns>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.CheckIP(System.String)"
>
<summary>
检查IP地址
</summary>
<param
name=
"ip"
></param>
<returns></returns>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.Connect"
>
<member
name=
"M:Asa.IOModule.AIOBOX.Connect"
>
<summary>
<summary>
连接
连接
...
@@ -120,26 +65,6 @@
...
@@ -120,26 +65,6 @@
关闭连接
关闭连接
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.AutoReadInput(System.Boolean,System.Int32)"
>
<summary>
自动读取输入端并触发事件(主动上传数据 = 禁止)
</summary>
<param
name=
"read"
>
是否自动读取
</param>
<param
name=
"sleep"
>
间隔,必须大于等于15ms
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.AutoReadInput(System.Boolean)"
>
<summary>
自动读取输入端并触发事件(主动上传数据 = 使能)
</summary>
<param
name=
"read"
>
是否自动读取
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.AutoReadOutput(System.Boolean,System.Int32)"
>
<summary>
自动读取输出端,触发事件
</summary>
<param
name=
"read"
>
是否自动读取
</param>
<param
name=
"sleep"
>
间隔,必须大于等于15ms
</param>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.ReverseStatus(Asa.IOModule.Box_Sta)"
>
<member
name=
"M:Asa.IOModule.AIOBOX.ReverseStatus(Asa.IOModule.Box_Sta)"
>
<summary>
<summary>
相反状态(ON/OFF)
相反状态(ON/OFF)
...
@@ -221,75 +146,68 @@
...
@@ -221,75 +146,68 @@
<param
name=
"sta"
></param>
<param
name=
"sta"
></param>
<returns></returns>
<returns></returns>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.GetLocalIP"
>
<summary>
获取本地IPv4地址
</summary>
<returns></returns>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.Send"
>
<member
name=
"M:Asa.IOModule.AIOBOX.Send"
>
<summary>
<summary>
发送命令
发送命令线程
</summary>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.Receive"
>
<summary>
接收命令
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
ReadSingle(System.Byte[])
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
GetReadDI_Command
"
>
<summary>
<summary>
读取写入单个DO,功能码5
获取ReadDI的命令
</summary>
</summary>
<
param
name=
"buff"
></param
>
<
returns></returns
>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
ReadDO(System.Byte[])
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
GetReadDO_Command
"
>
<summary>
<summary>
读取所有DO状态,功能码1
获取ReadDO的命令
</summary>
</summary>
<
param
name=
"buff"
></param
>
<
returns></returns
>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
ReadDI(System.Byte[])
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
Listen
"
>
<summary>
<summary>
读取所有DI状态,功能码2
监听网络线程
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
ReadAI
(System.Byte[])"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
CommandProcess
(System.Byte[])"
>
<summary>
<summary>
读取所有AI的值,功能码4
接收到的命令处理方法,(task多线程)
</summary>
</summary>
<param
name=
"
buff
"
></param>
<param
name=
"
cmd
"
></param>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
Command
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
Reconn
"
>
<summary>
<summary>
命令,前7个字节
重连线程
</summary>
</summary>
<returns></returns>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
TriggerDIO
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
Open
"
>
<summary>
<summary>
触发DIO改变事件
打开socket建立连接
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
AutoReadInput
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
CheckIP(System.String)
"
>
<summary>
<summary>
自动读取输入端线程
检查IP地址
</summary>
</summary>
<param
name=
"ip"
></param>
<returns></returns>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.Auto
ReadOutput
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.Auto
IP(System.String)
"
>
<summary>
<summary>
自动
读取输出端线程
自动
获取IP地址,未连接前使用,必须在同一网段
</summary>
</summary>
<param
name=
"localIP"
>
本地IP地址
</param>
<returns></returns>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
Listen
"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
GetIP
"
>
<summary>
<summary>
监听结果线程
获取IO模块IP地址
</summary>
</summary>
</member>
</member>
<member
name=
"M:Asa.IOModule.AIOBOX.
TestMetho
d"
>
<member
name=
"M:Asa.IOModule.AIOBOX.
Comman
d"
>
<summary>
<summary>
测试方法锁
命令,前7个字节
</summary>
</summary>
<returns></returns>
</member>
</member>
<member
name=
"T:Asa.IOModule.Box_Type"
>
<member
name=
"T:Asa.IOModule.Box_Type"
>
<summary>
<summary>
...
@@ -331,62 +249,5 @@
...
@@ -331,62 +249,5 @@
闭合,打开,高电平
闭合,打开,高电平
</summary>
</summary>
</member>
</member>
<member
name=
"T:Asa.IOModule.LogType"
>
<summary>
日志类型
</summary>
</member>
<member
name=
"F:Asa.IOModule.LogType.OnlyError"
>
<summary>
仅错误信息
</summary>
</member>
<member
name=
"F:Asa.IOModule.LogType.All"
>
<summary>
所有
</summary>
</member>
<member
name=
"T:Asa.IOModule.LogFile"
>
<summary>
日志操作类
</summary>
</member>
<member
name=
"M:Asa.IOModule.LogFile.#ctor(System.String,System.String)"
>
<summary>
日志
</summary>
<param
name=
"path"
>
文件夹路径
</param>
<param
name=
"ip"
></param>
</member>
<member
name=
"M:Asa.IOModule.LogFile.Close"
>
<summary>
关闭文件
</summary>
</member>
<member
name=
"M:Asa.IOModule.LogFile.OutError(System.String)"
>
<summary>
输出错误
</summary>
<param
name=
"s"
></param>
</member>
<member
name=
"M:Asa.IOModule.LogFile.OutInfo(System.String)"
>
<summary>
输出信息
</summary>
<param
name=
"s"
></param>
</member>
<member
name=
"M:Asa.IOModule.LogFile.OutData(System.String,System.Byte[])"
>
<summary>
输出数据
</summary>
<param
name=
"tr"
></param>
<param
name=
"buff"
></param>
</member>
<member
name=
"M:Asa.IOModule.LogFile.OutData(System.String)"
>
<summary>
输出数据
</summary>
<param
name=
"s"
></param>
</member>
</members>
</members>
</doc>
</doc>
AIOBOX/obj/Debug/AIOBOX.csproj.CoreCompileInputs.cache
查看文件 @
709ec17
9428b515b65d7e804ec8e058ca7770707ab7571d
6b9117074f0ff97736a34c4c150b6b18b33edbb4
AIOBOX/obj/Debug/AIOBOX.csproj.FileListAbsolute.txt
查看文件 @
709ec17
...
@@ -39,3 +39,10 @@ D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\AIOBOX.csp
...
@@ -39,3 +39,10 @@ D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\AIOBOX.csp
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\AIOBOX.csproj.CoreCompileInputs.cache
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\AIOBOX.csproj.CoreCompileInputs.cache
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.dll
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.dll
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.pdb
D:\OneDrive - 上海挚锦科技有限公司\SMD\DLL\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.pdb
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\bin\Debug\Asa.IOModule.AIOBOX.xml
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\bin\Debug\Asa.IOModule.AIOBOX.dll
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\bin\Debug\Asa.IOModule.AIOBOX.pdb
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\obj\Debug\AIOBOX.csproj.CoreCompileInputs.cache
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.dll
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\obj\Debug\Asa.IOModule.AIOBOX.pdb
D:\OneDrive - 上海挚锦科技有限公司\SMD\AIOBOX\AIOBOX\obj\Debug\AIOBOX.csprojAssemblyReference.cache
AIOBOX/obj/Debug/AIOBOX.csprojAssemblyReference.cache
查看文件 @
709ec17
此文件类型无法预览
AIOBOX/obj/Debug/Asa.IOModule.AIOBOX.dll
查看文件 @
709ec17
此文件类型无法预览
AIOBOX/obj/Debug/Asa.IOModule.AIOBOX.pdb
查看文件 @
709ec17
此文件类型无法预览
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论