fix template

This commit is contained in:
anlicheng 2025-06-27 00:22:31 +08:00
parent 5cf842fa1c
commit 1e0f41f49a
4 changed files with 87 additions and 41 deletions

View File

@ -28,6 +28,18 @@
access_log = "" :: string()
}).
-record(modbus_collect_template, {
name :: binary(),
%%
poll_interval :: integer() | undefined,
%%
retries :: integer(),
retry_timeout :: integer(),
%%
metrics = #{} :: map()
}).
-record(modbus_device, {
%%
name :: string(),
@ -37,6 +49,8 @@
model :: string() | undefined,
description :: string() | undefined,
collect_template :: binary() | undefined,
%%
poll_interval :: integer() | undefined,
@ -89,6 +103,7 @@
-record(ast, {
modbus,
collect_templates = [],
devices = [],
processors = [],
alarms = []

View File

@ -30,6 +30,16 @@ parse(Input) when is_binary(Input) ->
_ -> false
end
end, Trees),
Templates = lists:filter(fun(E) ->
case E of
#modbus_collect_template{} ->
true;
_ ->
false
end
end, Trees),
Devices = lists:filter(fun(E) ->
case E of
#modbus_device{} ->
@ -56,7 +66,7 @@ parse(Input) when is_binary(Input) ->
case length(Modbus) == 1 of
true ->
AST = #ast{modbus = hd(Modbus), devices = Devices, processors = Processors, alarms = Alarms },
AST = #ast{modbus = hd(Modbus), collect_templates = Templates, devices = Devices, processors = Processors, alarms = Alarms },
{ok, AST};
false ->
{error, modbus_block_error}
@ -158,11 +168,21 @@ parse_ast0(#block{ident = <<"modbus">>, props = Props}) ->
access_log = map_of_binary(<<"access_log">>, MapProps, undefined),
error_log = map_of_binary(<<"error_log">>, MapProps, undefined)
};
parse_ast0(#block{ident = <<"collect_template", Name0/binary>>, props = Props}) ->
MapProps = parse_ast1(Props),
#modbus_collect_template {
name = string:trim(Name0),
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),
retries = map_of_integer(<<"retries">>, MapProps, 0),
retry_timeout = maps:get(<<"retry_timeout">>, MapProps, undefined),
metrics = maps:get(<<"metrics">>, MapProps, undefined)
};
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
MapProps = parse_ast1(Props),
#modbus_device {
name = string:trim(Name0),
slave_id = map_of_integer(<<"slave_id">>, MapProps, 0),
collect_template = map_of_binary(<<"collect_template">>, MapProps, undefined),
model = maps:get(<<"model">>, MapProps, undefined),
description = maps:get(<<"description">>, MapProps, undefined),
poll_interval = map_of_time(<<"poll_interval">>, MapProps, 0),

View File

@ -82,15 +82,17 @@ start_link(AST = #ast{}) ->
%% @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
%% process to initialize.
init([AST = #ast{modbus = Modbus = #modbus{error_log = ErrorLog, access_log = AccessLog}, devices = Devices, alarms = Alarms}]) ->
init([AST = #ast{modbus = Modbus = #modbus{error_log = ErrorLog, access_log = AccessLog}, collect_templates = CollectTemplates, devices = Devices, alarms = Alarms}]) ->
lager:debug("[modbus_service] modbus is: ~p", [Modbus]),
lager:debug("[modbus_service] templates is: ~p", [CollectTemplates]),
lager:debug("[modbus_service] devices is: ~p", [Devices]),
%%
erlang:start_timer(0, self(), modbus_connect),
%%
DevicesPids = lists:map(fun(Device = #modbus_device{slave_id = SlaveId}) ->
{ok, DevicePid} = modbus_device:start_link(self(), Device),
{ok, DevicePid} = modbus_device:start_link(self(), merge_template(Device, CollectTemplates)),
{SlaveId, DevicePid}
end, Devices),
DevicesMap = maps:from_list(DevicesPids),
@ -282,4 +284,20 @@ create_log_file(FileName) when is_binary(FileName) ->
FilePid;
_ ->
undefined
end.
merge_template(Device = #modbus_device{collect_template = undefined}, _Templates) ->
Device;
merge_template(Device = #modbus_device{collect_template = TemplateName}, Templates) ->
case lists:search(fun(#modbus_collect_template{name = T0}) -> TemplateName =:= T0 end, Templates) of
{value, #modbus_collect_template{poll_interval = PollInterval, retries = Retries, retry_timeout = RetryTimeout, metrics = Metrics}} ->
%%
Device#modbus_device{
poll_interval = PollInterval,
retries = Retries,
retry_timeout = RetryTimeout,
metrics = Metrics
};
false ->
Device
end.

View File

@ -20,51 +20,44 @@ modbus {
access_log /var/log/modbus_access.log;
}
collect_template t1 {
# 轮询间隔
poll_interval 5s;
# 重试策略
retries 3;
retry_timeout 2s;
# 数据点定义
metrics {
# 温度读取(保持寄存器)
temperature {
address 40001; # Modbus地址表示法
type int16;
scale 0.1;
unit "°C";
poll on;
}
# 压力传感器(输入寄存器)
pressure {
address 30001;
type uint16;
scale 0.01;
unit "kPa";
poll on;
}
}
}
device boiler_controller {
# 设备标识
slave_id 1;
model "Siemens S7-1200";
description "Main boiler controller";
# 轮询间隔
poll_interval 5s;
collect_template t1;
# 重试策略
retries 3;
retry_timeout 2s;
# 数据点定义
metrics {
# 温度读取(保持寄存器)
temperature {
address 40001; # Modbus地址表示法
type int16;
scale 0.1;
unit "°C";
poll on;
}
# 压力传感器(输入寄存器)
pressure {
address 30001;
type uint16;
scale 0.01;
unit "kPa";
poll on;
}
# 状态位(线圈)
#alarm_status {
# address 00001;
# type bool;
# bits {
# 0 "overheat";
# 1 "low_pressure";
# 2 "pump_failure";
# }
# poll on;
#}
}
# 写入控制
controls {