Files
IoTManager/PrepareProject.py

202 lines
11 KiB
Python
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.
# PrepareProject.py - инструмент для подготовки проекта к компиляции.
# Необходимо вызвать при изменении персональных настроек или состава модулей.
#
# При отсутствии файла с персональными настройками, myProfile.json будет создан автоматически
# python PrepareProject.py
#
# Если myProfile.json уже существует, можно запустить PrepareProject.py с параметром -u или --update для обновления списка модулей.
# Данная функция будет полезна для разработчиков при добавлении модуля в папку src/modules
# python PrepareProject.py --update
# python PrepareProject.py -u
#
# Возможно использовать несколько вариантов персональных настроек и уточнять имя файла при запуске с использованием параметра -p или -profile
# python PrepareProject.py --profile <ИмяФайла>
# python PrepareProject.py -p <ИмяФайла>
#
#
import configparser
import os, json, sys, getopt
from pathlib import Path
config = configparser.ConfigParser() # создаём объекта парсера INI
def printHelp():
print('''Usage:
PrepareProject.py
-p --profile <file.json_in_root_folder>
-u --update
-h --help''')
def updateModulesInProfile(profJson):
profJson["modules"] = {}
for root,d_names,f_names in os.walk("src/modules"):
for fname in f_names:
if fname == "modinfo.json":
with open(os.path.join(root, fname), "r", encoding='utf-8') as read_file:
modinfoJson = json.load(read_file)
# проверяем есть ли уже узловой элемент и если нет, то создаем
if not modinfoJson['menuSection'] in profJson["modules"]:
listFromFirstElement = {modinfoJson['menuSection']: []}
listFromFirstElement.update(profJson["modules"])
profJson["modules"] = listFromFirstElement
# добавляем информацию о модуле в узловой элемент
profJson["modules"][modinfoJson['menuSection']].append({
'path': os.path.normpath(root).replace("\\", "/"),
'active': modinfoJson['defActive']
})
update = False # признак необходимости обновить список модулей
profile = 'myProfile.json' # имя профиля. Будет заменено из консоли, если указано при старте
argv = sys.argv[1:]
try:
opts, args = getopt.getopt(argv, 'hp:u', ['help', 'profile=', 'update'])
except getopt.GetoptError:
print('Ошибка обработки параметров!')
printHelp()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
printHelp()
sys.exit()
elif opt in ("-p", "--profile"):
profile = arg
elif opt in ("-u", "--update"):
update = True
if Path(profile).is_file():
# подтягиваем уже существующий профиль
with open(profile, "r", encoding='utf-8') as read_file:
profJson = json.load(read_file)
# если хотим обновить список модулей в существующем профиле
if update:
updateModulesInProfile(profJson)
# sortedListNames = sorted(profJson["modules"])
# sortedModules = {}
# for sortedModulName in sortedList:
# print(profJson)
with open(profile, "w", encoding='utf-8') as write_file:
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
else:
# если файла нет - создаем по образу настроек из проекта
profJson = json.loads('{}')
# копируем параметры IOTM из settings.json в новый профиль
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
profJson['iotmSettings'] = json.load(read_file)
# устанавливаем параметры сборки
profJson['projectProp'] = {
'platformio': {
'default_envs': 'esp8266_4mb',
'data_dir': 'data_svelte'
}
}
# загружаем список модулей для сборки
updateModulesInProfile(profJson)
# сохраняем новый профиль
with open(profile, "w", encoding='utf-8') as write_file:
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
# генерируем файлы проекта на основе подготовленного профиля
# заполняем конфигурационный файл прошивки параметрами из профиля
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
iotmJson = json.load(read_file)
for key, value in profJson['iotmSettings'].items():
iotmJson[key] = value
with open("data_svelte/settings.json", "w", encoding='utf-8') as write_file:
json.dump(iotmJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
# определяем какое устройство используется в профиле
deviceName = profJson['projectProp']['platformio']['default_envs']
# собираем меню прошивки из модулей
# параллельно формируем список имен активных модулей
# параллельно собираем необходимые активным модулям библиотеки для включения в компиляцию для текущего типа устройства (esp8266_4m, esp32_4mb)
activeModulesName = [] # список имен активных модулей
allLibs = "" # подборка всех библиотек необходимых модулям для дальнейшей записи в конфигурацию platformio
itemsCount = 1;
includeDirs = "" # подборка путей ко всем модулям для дальнейшей записи в конфигурацию platformio
itemsJson = json.loads('[{"name": "Выберите элемент", "num": 0}]')
for section, modules in profJson['modules'].items():
itemsJson.append({"header": section})
for module in modules:
if module['active']:
with open(module['path'] + "/modinfo.json", "r", encoding='utf-8') as read_file:
moduleJson = json.load(read_file)
if deviceName in moduleJson['usedLibs']: # проверяем поддерживает ли модуль текущее устройство
activeModulesName.append(moduleJson['about']['moduleName']) # запоминаем имена для использования на след шагах
includeDirs = includeDirs + "\n+<" + module['path'].replace("src/", "") + ">" # запоминаем пути к модулям для компиляции
for libPath in moduleJson['usedLibs'][deviceName]: # запоминаем библиотеки необходимые модулю для текущей платы
allLibs = allLibs + "\n" + libPath
for configItemsJson in moduleJson['configItem']:
configItemsJson['num'] = itemsCount
configItemsJson['name'] = str(itemsCount) + ". " + configItemsJson['name']
itemsCount = itemsCount + 1
itemsJson.append(configItemsJson)
with open("data_svelte/items.json", "w", encoding='utf-8') as write_file:
json.dump(itemsJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
# учитываем вызовы модулей в API.cpp
allAPI_head = ""
allAPI_exec = ""
for activModuleName in activeModulesName:
allAPI_head = allAPI_head + "\nvoid* getAPI_" + activModuleName + "(String subtype, String params);"
allAPI_exec = allAPI_exec + "\nif ((tmpAPI = getAPI_" + activModuleName + "(subtype, params)) != nullptr) return tmpAPI;"
apicpp = '#include "ESPConfiguration.h"\n'
apicpp = apicpp + allAPI_head
apicpp = apicpp + '\n\nvoid* getAPI(String subtype, String params) {\nvoid* tmpAPI;'
apicpp = apicpp + allAPI_exec
apicpp = apicpp + '\nreturn nullptr;\n}'
with open('src/modules/API.cpp', 'w') as f:
f.write(apicpp)
# корректируем параметры platformio
# собираем пути всех отключенных модулей для исключения их из процесса компиляции
# excludeDirs = ""
# for root,d_names,f_names in os.walk("src\\modules"):
# for fname in f_names:
# if fname == "modinfo.json":
# with open(root + "\\" + fname, "r", encoding='utf-8') as read_file:
# modinfoJson = json.load(read_file)
# if not modinfoJson['about']['moduleName'] in activeModulesName:
# excludeDirs = excludeDirs + "\n-<" + root.replace("src\\", "") + ">"
# фиксируем изменения в platformio.ini
config.clear()
config.read("platformio.ini")
config["env:" + deviceName + "_fromitems"]["lib_deps"] = allLibs
config["env:" + deviceName + "_fromitems"]["build_src_filter"] = includeDirs
config["platformio"]["default_envs"] = deviceName
config["platformio"]["data_dir"] = profJson['projectProp']['platformio']['data_dir']
with open("platformio.ini", 'w') as configFile:
config.write(configFile)
# import ctypes # An included library with Python install.
# if update:
# ctypes.windll.user32.MessageBoxW(0, "Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
# else:
# ctypes.windll.user32.MessageBoxW(0, "Профиль " + profile + " применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
if update:
print(f"\x1b[1;31;42m Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.\x1b[0m")
else:
print(f"\x1b[1;31;42m Профиль ", profile, " применен, можно запускать компиляцию и прошивку.\x1b[0m")
# print(f"\x1b[1;32;41m Операция завершена. \x1b[0m")