import os
import sys

# Use TIA Scripting via file import (Only if TIA Scripting is not installed as package)
# need to set a global environment variable “TIA_SCRIPTING” with path containing TIA Scripting binaries
if os.getenv('TIA_SCRIPTING')  == None:
    # if TIA_SCRIPTING global environment variable is not set
    # set local variable with the path to TIA Scripting binaries
    tia_scripting_directory = "C:\\your\\path\\to\\tia-scripting-python"
    sys.path.append(tia_scripting_directory)
else:
    # TIA_SCRIPTING global environment variable is set and will be used for import
    sys.path.append(os.getenv('TIA_SCRIPTING'))

try:
    # import TIA Scripting binaries
    # if TIA Scripting is installed as package, global environment variable will be ignored
    import siemens_tia_scripting as ts
except ImportError:
    # you will run into ImportError also if you are using Python version which is not 3.12.X
    print("siemens_tia_scripting could not be found")
    sys.exit(0)

portal_mode_ui = True
keep_tia_portal = False
# example values for directories
project_file_path = "D:\\TiaScripting\\PLC_ExportAll\\PLC_ExportAll.ap19"
export_target_dir = "D:\\TiaScripting\\Export"
keep_folder_structure = True
# need to specify target version e.g. "17.0", requires that TIA portal V17 is installed
version = "19.0"
export_options = ts.Enums.ExportOptions.WithDefaults
export_format = ts.Enums.ExportFormats.SimaticML

if portal_mode_ui == True:
    portal = ts.open_portal(ts.Enums.PortalMode.WithGraphicalUserInterface, version = version)
    print("- open/attach tia portal with ui")
else:
    portal = ts.open_portal(ts.Enums.PortalMode.WithoutGraphicalUserInterface, version = version)
    print("- open/attach tia portal without ui")
    
project = portal.open_project(project_file_path = project_file_path, server_project_view = False)
print("- open project")

plcs = project.get_plcs()
for plc in plcs:
    print(plc.get_name())
    for tag_table in plc.get_plc_tag_tables():
        tag_table.export(target_directory_path = export_target_dir + "\\PlcTags", export_options = export_options, keep_folder_structure = keep_folder_structure)
    for program_block in plc.get_program_blocks():
        if program_block.is_consistent() == False:
            program_block.compile()
        if program_block.is_consistent() == True:
            program_block.export(target_directory_path = export_target_dir + "\\ProgramBlocks", export_options = export_options, keep_folder_structure = keep_folder_structure)
        if program_block.get_property(name="ProgrammingLanguage") == "SCL":
            program_block.export(target_directory_path = export_target_dir + "\\ProgramBlocks", export_options = export_options, export_format = ts.Enums.ExportFormats.ExternalSource, keep_folder_structure = keep_folder_structure)
        
    for system_block in plc.get_system_blocks():
        if system_block.is_consistent() == False:
            system_block.compile()
        if system_block.is_consistent() == True:
            system_block.export(target_directory_path = export_target_dir + "\\ProgramBlocks", export_options = export_options)
        
    for udt in plc.get_user_data_types():
        if udt.is_consistent() == False:
            udt.compile()
        if udt.is_consistent() == True:
            udt.export(target_directory_path = export_target_dir + "\\PlcDataTypes", export_options = export_options, keep_folder_structure = keep_folder_structure)
        udt.export(target_directory_path = export_target_dir + "\\PlcDataTypes", export_options = export_options, keep_folder_structure = True)
    
    for force_table in plc.get_force_tables():        
        if force_table.is_consistent() == True:
            force_table.export(target_directory_path = export_target_dir + "\\WatchAndForceTables", export_options = export_options)

    for watch_table in plc.get_watch_tables():
        if watch_table.is_consistent() == False:
            watch_table.compile()
        if watch_table.is_consistent() == True:
            watch_table.export(target_directory_path = export_target_dir + "\\WatchAndForceTables", export_options = export_options, keep_folder_structure = keep_folder_structure)
                
    for to in plc.get_technology_objects():
        if to.is_consistent() == False:
            to.compile()
        if to.is_consistent() == True:
            to.export(target_directory_path = export_target_dir + "\\TechnologyObjects", export_options = export_options, keep_folder_structure = keep_folder_structure)

    for software_unit in plc.get_software_units():
        target_dir_su= export_target_dir + "\\SoftwareUnits\\" + software_unit.get_name()
        software_unit.export_configuration(target_directory_path = target_dir_su)
        for program_block in software_unit.get_program_blocks():
            if program_block.is_consistent() == False:
                program_block.compile()
            if program_block.is_consistent() == True:
                program_block.export(target_directory_path = target_dir_su + "\\ProgramBlocks", export_options = export_options, keep_folder_structure = keep_folder_structure)
            if program_block.get_property(name="ProgrammingLanguage") == "SCL":
                program_block.export(target_directory_path = export_target_dir + "\\ProgramBlocks", export_options = export_options, export_format = ts.Enums.ExportFormats.ExternalSource, keep_folder_structure = keep_folder_structure)
        

        for udt in software_unit.get_user_data_types():
            if udt.is_consistent() == False:
                udt.compile()
            if udt.is_consistent() == True:
                udt.export(target_directory_path = target_dir_su+ "\\PlcDataTypes", export_options = export_options, keep_folder_structure = keep_folder_structure)
            udt.export(target_directory_path = target_dir_su + "\\PlcDataTypes", export_options = export_options, keep_folder_structure = True)
       

if keep_tia_portal == "False":
    portal.close_portal()
    print("- close tia portal")

if keep_tia_portal == "True":
    print("- keep tia portal")

sys.exit(0)