fix
This commit is contained in:
parent
1e0f41f49a
commit
4a3f302308
@ -28,7 +28,7 @@
|
|||||||
access_log = "" :: string()
|
access_log = "" :: string()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-record(modbus_collect_template, {
|
-record(modbus_device_io, {
|
||||||
name :: binary(),
|
name :: binary(),
|
||||||
%% 轮询间隔
|
%% 轮询间隔
|
||||||
poll_interval :: integer() | undefined,
|
poll_interval :: integer() | undefined,
|
||||||
@ -37,7 +37,10 @@
|
|||||||
retry_timeout :: integer(),
|
retry_timeout :: integer(),
|
||||||
|
|
||||||
%% 数据定义
|
%% 数据定义
|
||||||
metrics = #{} :: map()
|
metrics :: list() | undefined,
|
||||||
|
|
||||||
|
%% 写入控制器
|
||||||
|
controls :: list() | undefined
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-record(modbus_device, {
|
-record(modbus_device, {
|
||||||
@ -49,7 +52,7 @@
|
|||||||
model :: string() | undefined,
|
model :: string() | undefined,
|
||||||
description :: string() | undefined,
|
description :: string() | undefined,
|
||||||
|
|
||||||
collect_template :: binary() | undefined,
|
device_io :: binary() | undefined,
|
||||||
|
|
||||||
%% 轮询间隔
|
%% 轮询间隔
|
||||||
poll_interval :: integer() | undefined,
|
poll_interval :: integer() | undefined,
|
||||||
@ -71,6 +74,13 @@
|
|||||||
unit
|
unit
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
-record(modbus_control, {
|
||||||
|
name,
|
||||||
|
address,
|
||||||
|
type,
|
||||||
|
precision
|
||||||
|
}).
|
||||||
|
|
||||||
-record(modbus_processor, {
|
-record(modbus_processor, {
|
||||||
name :: string(),
|
name :: string(),
|
||||||
input :: string(),
|
input :: string(),
|
||||||
@ -103,7 +113,7 @@
|
|||||||
|
|
||||||
-record(ast, {
|
-record(ast, {
|
||||||
modbus,
|
modbus,
|
||||||
collect_templates = [],
|
device_ios = [],
|
||||||
devices = [],
|
devices = [],
|
||||||
processors = [],
|
processors = [],
|
||||||
alarms = []
|
alarms = []
|
||||||
|
|||||||
@ -47,6 +47,9 @@ start_link(ParentPid, Device = #modbus_device{}) when is_pid(ParentPid) ->
|
|||||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term()} | ignore).
|
{stop, Reason :: term()} | ignore).
|
||||||
init([ParentPid, Device = #modbus_device{metrics = Metrics0, poll_interval = PollInterval}]) ->
|
init([ParentPid, Device = #modbus_device{metrics = Metrics0, poll_interval = PollInterval}]) ->
|
||||||
|
|
||||||
|
lager:debug("device is: ~p", [Device]),
|
||||||
|
|
||||||
%% 处理采集项目
|
%% 处理采集项目
|
||||||
MetricsMap = maps:from_list(lists:map(fun(Metric0 = #modbus_metric{name = Name}) -> {Name, Metric0} end, Metrics0)),
|
MetricsMap = maps:from_list(lists:map(fun(Metric0 = #modbus_metric{name = Name}) -> {Name, Metric0} end, Metrics0)),
|
||||||
%% 初步启动的过程中按照step提交任务
|
%% 初步启动的过程中按照step提交任务
|
||||||
|
|||||||
@ -33,7 +33,7 @@ parse(Input) when is_binary(Input) ->
|
|||||||
|
|
||||||
Templates = lists:filter(fun(E) ->
|
Templates = lists:filter(fun(E) ->
|
||||||
case E of
|
case E of
|
||||||
#modbus_collect_template{} ->
|
#modbus_device_io{} ->
|
||||||
true;
|
true;
|
||||||
_ ->
|
_ ->
|
||||||
false
|
false
|
||||||
@ -66,7 +66,7 @@ parse(Input) when is_binary(Input) ->
|
|||||||
|
|
||||||
case length(Modbus) == 1 of
|
case length(Modbus) == 1 of
|
||||||
true ->
|
true ->
|
||||||
AST = #ast{modbus = hd(Modbus), collect_templates = Templates, devices = Devices, processors = Processors, alarms = Alarms },
|
AST = #ast{modbus = hd(Modbus), device_ios = Templates, devices = Devices, processors = Processors, alarms = Alarms },
|
||||||
{ok, AST};
|
{ok, AST};
|
||||||
false ->
|
false ->
|
||||||
{error, modbus_block_error}
|
{error, modbus_block_error}
|
||||||
@ -168,21 +168,22 @@ parse_ast0(#block{ident = <<"modbus">>, props = Props}) ->
|
|||||||
access_log = map_of_binary(<<"access_log">>, MapProps, undefined),
|
access_log = map_of_binary(<<"access_log">>, MapProps, undefined),
|
||||||
error_log = map_of_binary(<<"error_log">>, MapProps, undefined)
|
error_log = map_of_binary(<<"error_log">>, MapProps, undefined)
|
||||||
};
|
};
|
||||||
parse_ast0(#block{ident = <<"collect_template", Name0/binary>>, props = Props}) ->
|
parse_ast0(#block{ident = <<"device_io", Name0/binary>>, props = Props}) ->
|
||||||
MapProps = parse_ast1(Props),
|
MapProps = parse_ast1(Props),
|
||||||
#modbus_collect_template {
|
#modbus_device_io {
|
||||||
name = string:trim(Name0),
|
name = string:trim(Name0),
|
||||||
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),
|
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),
|
||||||
retries = map_of_integer(<<"retries">>, MapProps, 0),
|
retries = map_of_integer(<<"retries">>, MapProps, 0),
|
||||||
retry_timeout = maps:get(<<"retry_timeout">>, MapProps, undefined),
|
retry_timeout = maps:get(<<"retry_timeout">>, MapProps, undefined),
|
||||||
metrics = maps:get(<<"metrics">>, MapProps, undefined)
|
metrics = maps:get(<<"metrics">>, MapProps, undefined),
|
||||||
|
controls = maps:get(<<"controls">>, MapProps, undefined)
|
||||||
};
|
};
|
||||||
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
|
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
|
||||||
MapProps = parse_ast1(Props),
|
MapProps = parse_ast1(Props),
|
||||||
#modbus_device {
|
#modbus_device {
|
||||||
name = string:trim(Name0),
|
name = string:trim(Name0),
|
||||||
slave_id = map_of_integer(<<"slave_id">>, MapProps, 0),
|
slave_id = map_of_integer(<<"slave_id">>, MapProps, 0),
|
||||||
collect_template = map_of_binary(<<"collect_template">>, MapProps, undefined),
|
device_io = map_of_binary(<<"device_io">>, MapProps, undefined),
|
||||||
model = maps:get(<<"model">>, MapProps, undefined),
|
model = maps:get(<<"model">>, MapProps, undefined),
|
||||||
description = maps:get(<<"description">>, MapProps, undefined),
|
description = maps:get(<<"description">>, MapProps, undefined),
|
||||||
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),
|
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),
|
||||||
@ -237,8 +238,21 @@ parse_ast1([#block{ident = <<"metrics">>, props = Metrics0}|T], Acc) ->
|
|||||||
end, Metrics0),
|
end, Metrics0),
|
||||||
parse_ast1(T, [{<<"metrics">>, Metrics}|Acc]);
|
parse_ast1(T, [{<<"metrics">>, Metrics}|Acc]);
|
||||||
|
|
||||||
parse_ast1([#block{ident = <<"controls">>, props = Props}|T], Acc) ->
|
parse_ast1([#block{ident = <<"controls">>, props = Controls0}|T], Acc) ->
|
||||||
parse_ast1(T, [{<<"controls">>, Props}|Acc]);
|
Controls = lists:map(fun(#block{ident = MetricName, props = Props0}) ->
|
||||||
|
Props = lists:map(fun(Prop0) ->
|
||||||
|
[Name|Vars] = binary:split(Prop0, <<" ">>, [trim]),
|
||||||
|
{Name, Vars}
|
||||||
|
end, Props0),
|
||||||
|
PropsMap = maps:from_list(Props),
|
||||||
|
#modbus_control{
|
||||||
|
name = MetricName,
|
||||||
|
address = map_of_integer(<<"address">>, PropsMap, 0),
|
||||||
|
type = map_of_binary(<<"type">>, PropsMap, <<"">>),
|
||||||
|
precision = map_of_float(<<"precision">>, PropsMap, <<"">>)
|
||||||
|
}
|
||||||
|
end, Controls0),
|
||||||
|
parse_ast1(T, [{<<"controls">>, Controls}|Acc]);
|
||||||
parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc) ->
|
parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc) ->
|
||||||
PropsMap = parse_ast1(Props),
|
PropsMap = parse_ast1(Props),
|
||||||
Transport = case string:trim(Name0) of
|
Transport = case string:trim(Name0) of
|
||||||
@ -308,6 +322,15 @@ map_of_binary(Key, M, Def) ->
|
|||||||
Def
|
Def
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
map_of_float(Key, M, Def) ->
|
||||||
|
case maps:is_key(Key, M) of
|
||||||
|
true ->
|
||||||
|
[Val0] = maps:get(Key, M),
|
||||||
|
binary_to_float(Val0);
|
||||||
|
false ->
|
||||||
|
Def
|
||||||
|
end.
|
||||||
|
|
||||||
map_of_time(Key, M, Def) ->
|
map_of_time(Key, M, Def) ->
|
||||||
case maps:is_key(Key, M) of
|
case maps:is_key(Key, M) of
|
||||||
true ->
|
true ->
|
||||||
|
|||||||
@ -82,9 +82,9 @@ start_link(AST = #ast{}) ->
|
|||||||
%% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or
|
%% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or
|
||||||
%% gen_statem:start_link/[3,4], this function is called by the new
|
%% gen_statem:start_link/[3,4], this function is called by the new
|
||||||
%% process to initialize.
|
%% process to initialize.
|
||||||
init([AST = #ast{modbus = Modbus = #modbus{error_log = ErrorLog, access_log = AccessLog}, collect_templates = CollectTemplates, devices = Devices, alarms = Alarms}]) ->
|
init([AST = #ast{modbus = Modbus = #modbus{error_log = ErrorLog, access_log = AccessLog}, device_ios = IOs, devices = Devices, alarms = Alarms}]) ->
|
||||||
lager:debug("[modbus_service] modbus is: ~p", [Modbus]),
|
lager:debug("[modbus_service] ast is: ~p", [AST]),
|
||||||
lager:debug("[modbus_service] templates is: ~p", [CollectTemplates]),
|
lager:debug("[modbus_service] io is: ~p", [IOs]),
|
||||||
lager:debug("[modbus_service] devices is: ~p", [Devices]),
|
lager:debug("[modbus_service] devices is: ~p", [Devices]),
|
||||||
|
|
||||||
%% 建立连接
|
%% 建立连接
|
||||||
@ -92,7 +92,7 @@ init([AST = #ast{modbus = Modbus = #modbus{error_log = ErrorLog, access_log = Ac
|
|||||||
|
|
||||||
%% 启动设备相关的进程
|
%% 启动设备相关的进程
|
||||||
DevicesPids = lists:map(fun(Device = #modbus_device{slave_id = SlaveId}) ->
|
DevicesPids = lists:map(fun(Device = #modbus_device{slave_id = SlaveId}) ->
|
||||||
{ok, DevicePid} = modbus_device:start_link(self(), merge_template(Device, CollectTemplates)),
|
{ok, DevicePid} = modbus_device:start_link(self(), merge_io(Device, IOs)),
|
||||||
{SlaveId, DevicePid}
|
{SlaveId, DevicePid}
|
||||||
end, Devices),
|
end, Devices),
|
||||||
DevicesMap = maps:from_list(DevicesPids),
|
DevicesMap = maps:from_list(DevicesPids),
|
||||||
@ -286,17 +286,18 @@ create_log_file(FileName) when is_binary(FileName) ->
|
|||||||
undefined
|
undefined
|
||||||
end.
|
end.
|
||||||
|
|
||||||
merge_template(Device = #modbus_device{collect_template = undefined}, _Templates) ->
|
merge_io(Device = #modbus_device{device_io = undefined}, _Templates) ->
|
||||||
Device;
|
Device;
|
||||||
merge_template(Device = #modbus_device{collect_template = TemplateName}, Templates) ->
|
merge_io(Device = #modbus_device{device_io = IOName}, Templates) ->
|
||||||
case lists:search(fun(#modbus_collect_template{name = T0}) -> TemplateName =:= T0 end, Templates) of
|
case lists:search(fun(#modbus_device_io{name = T0}) -> IOName =:= T0 end, Templates) of
|
||||||
{value, #modbus_collect_template{poll_interval = PollInterval, retries = Retries, retry_timeout = RetryTimeout, metrics = Metrics}} ->
|
{value, #modbus_device_io{poll_interval = PollInterval, retries = Retries, retry_timeout = RetryTimeout, metrics = Metrics, controls = Controls}} ->
|
||||||
%% 合并配置项目
|
%% 合并配置项目
|
||||||
Device#modbus_device{
|
Device#modbus_device{
|
||||||
poll_interval = PollInterval,
|
poll_interval = PollInterval,
|
||||||
retries = Retries,
|
retries = Retries,
|
||||||
retry_timeout = RetryTimeout,
|
retry_timeout = RetryTimeout,
|
||||||
metrics = Metrics
|
metrics = Metrics,
|
||||||
|
controls = Controls
|
||||||
};
|
};
|
||||||
false ->
|
false ->
|
||||||
Device
|
Device
|
||||||
|
|||||||
25
modbus.conf
25
modbus.conf
@ -20,7 +20,7 @@ modbus {
|
|||||||
access_log /var/log/modbus_access.log;
|
access_log /var/log/modbus_access.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
collect_template t1 {
|
device_io t1 {
|
||||||
# 轮询间隔
|
# 轮询间隔
|
||||||
poll_interval 5s;
|
poll_interval 5s;
|
||||||
|
|
||||||
@ -48,6 +48,26 @@ collect_template t1 {
|
|||||||
poll on;
|
poll on;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 写入控制
|
||||||
|
controls {
|
||||||
|
# 启停控制
|
||||||
|
power_switch {
|
||||||
|
address 00010;
|
||||||
|
type bool;
|
||||||
|
safe_value off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# PID设定值
|
||||||
|
pid_setpoint {
|
||||||
|
address 40010;
|
||||||
|
type float32;
|
||||||
|
min 0.0;
|
||||||
|
max 100.0;
|
||||||
|
precision 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device boiler_controller {
|
device boiler_controller {
|
||||||
@ -56,8 +76,7 @@ device boiler_controller {
|
|||||||
model "Siemens S7-1200";
|
model "Siemens S7-1200";
|
||||||
description "Main boiler controller";
|
description "Main boiler controller";
|
||||||
|
|
||||||
collect_template t1;
|
io t1;
|
||||||
|
|
||||||
|
|
||||||
# 写入控制
|
# 写入控制
|
||||||
controls {
|
controls {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user