mcu_matlab/McuLib/m/configJs.m
2025-11-07 14:52:52 +03:00

177 lines
8.8 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

classdef configJs
% Класс для работы с JSON конфигурацией периферии в масках Simulink
% Обеспечивает чтение, запись и обновление конфигов из/в JSON файлы
methods(Static)
function config = update(blockPath, config)
% Обновляет конфигурацию значениями из маски Simulink
% blockPath - путь к блоку с маской
% config - структура конфигурации для обновления
if isempty(config)
return;
end
% Получаем маску и все её параметры
mask = Simulink.Mask.get(blockPath);
maskParams = mask.Parameters;
paramNames = arrayfun(@(p) p.Name, maskParams, 'UniformOutput', false);
% Обрабатываем все секции периферии в конфиге
periphs = fieldnames(config);
for i = 1:numel(periphs)
periph = periphs{i};
% Проверяем есть ли секция Defines в этой периферии
if ~isfield(config.(periph), 'Defines')
continue;
end
% Получаем все определения (defines) для этой периферии
defines = config.(periph).Defines;
defNames = fieldnames(defines);
% Обходим все определения и обновляем их значения из маски
for j = 1:numel(defNames)
defPrompt = defNames{j};
paramName = matlab.lang.makeValidName(defPrompt); % Создаем валидное имя параметра
% Проверяем существует ли параметр с таким именем в маске
if ismember(paramName, paramNames)
param = mask.getParameter(paramName);
valStr = param.Value; % Значение как строка из маски
% Проверяем существует ли элемент defPrompt в структуре defines
if isfield(defines, defPrompt)
% Преобразуем строку из маски в соответствующий тип данных
if strcmpi(defines.(defPrompt).Type, 'checkbox')
% Для чекбоксов преобразуем 'on'/'off' в true/false
config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on');
elseif strcmpi(defines.(defPrompt).Type, 'edit')
% Для текстовых полей пробуем преобразовать в число
valNum = str2double(valStr);
if isnan(valNum)
% Если не число - оставляем строкой
config.(periph).Defines.(defPrompt).Default = valStr;
else
% Если число - сохраняем как число
config.(periph).Defines.(defPrompt).Default = valNum;
end
end
end
end
end
end
end
function config = read(blockPath)
% Читает JSON конфигурацию из файла указанного в маске
% blockPath - путь к блоку с маской
% Возвращает структуру конфигурации или пустой массив
mask = Simulink.Mask.get(blockPath);
% Получаем путь к конфигурационному файлу из параметра маски
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
if ~isempty(config_path)
% Читаем и декодируем JSON файл
jsonText = fileread(config_path);
config = jsondecode(jsonText);
else
config = [];
end
end
function write(config)
% Записывает конфигурацию обратно в JSON файл
% config - структура конфигурации для записи
if isempty(config)
return
end
% Получаем handle текущего блока и его маску
blockHandle = gcbh;
mask = Simulink.Mask.get(blockHandle);
% Получаем путь к конфигурационному файлу из маски
pathparam = mask.getParameter('periphPath');
config_path = pathparam.Value;
% Кодируем структуру в JSON с красивым форматированием
jsonText = jsonencode(config, 'PrettyPrint', true);
% Записываем JSON в файл
fid = fopen(config_path, 'w', 'n', 'UTF-8');
if fid == -1
error('Не удалось открыть файл periph_config.json для записи.');
end
fwrite(fid, jsonText, 'char');
fclose(fid);
end
function value = get_field(configStruct, targetConfig)
% Рекурсивно ищет поле в структуре конфигурации
% configStruct - структура для поиска
% targetConfig - имя целевого поля
% Возвращает значение поля или пустой массив если не найдено
value = [];
fields = fieldnames(configStruct);
for i = 1:numel(fields)
key = fields{i};
if strcmp(key, targetConfig)
% Нашли прямое совпадение
value = configStruct.(key);
return;
elseif isstruct(configStruct.(key))
% Рекурсивно ищем во вложенной структуре
value = configJs.get_field(configStruct.(key), targetConfig);
if ~isempty(value)
return; % Нашли во вложенной структуре
end
end
end
% Если не нашли - возвращаем пустой массив
if isempty(value)
% Можно раскомментировать для отладки:
% error('Поле "%s" не найдено в структуре.', targetConfig);
end
end
function short = get_final_name_from_prefix(prefix)
% Извлекает короткое имя из префикса (последняя часть после '_')
% prefix - строка с префиксом вида 'PREFIX_NAME'
% Возвращает последнюю часть после последнего '_'
parts = strsplit(prefix, '_');
short = parts{end}; % Берём последний элемент
end
function value = convert_code_value(codeField)
% Преобразует значение поля Options в строку для отображения
% Обрабатывает разные типы данных: char, string, cell array
if ischar(codeField)
value = codeField;
elseif isstring(codeField)
value = char(codeField);
elseif iscell(codeField)
% Объединяем ячейки в одну строку с переносами
value = strjoin(codeField, newline);
else
% Для неподдерживаемых типов возвращаем пустую строку
value = '';
end
end
end
methods(Static, Access=private)
% Приватные методы могут быть добавлены здесь при необходимости
end
end