Project: s41467-024-54067-7 | Function: script_generation_module_node (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Implements algorithm with 8 lines of core logic

**KEY TERMS:** {
  "Central": "Central to this endeavor, is the modularization of independent experimental processes to facilitate widespread equipment sharing across diverse applications",
  "Thus": "Thus, there is a pressing need for extensive research to develop an advanced OS for MAP accessed by multiple users",
  "CPS": "Additionally, the closed-packing schedule (CPS) algorithm enables module resources to be maximally utilized via compact packing",
  "OCTOPUS": "OCTOPUS comprises three core components— an interface node, master node, and module nodes— that facilitate client request handling and experimental task scheduling"
}

**CONTEXT CODE:**         """
        write infomration log message in total.log with info message and show command

        :param part_name (str) : write platorm name
        :param info_msg (str) : Message to log
        :return: True
        """

        msg = "[{}] : {}".format(part_name, info_msg)
        self.mylogger.info(msg)

        return True

    def warning(self, device_name="Doosan M0609", warning_msg="warning!"):
        """
        write warning log message in total.log with warning log and show command

        :param device_name (str) : write hardware machine or software
        :param warning_msg (str) : Message to log
        :return: True
        """

        msg = "[{}] : {}".format(device_name, warning_msg)
        self.mylogger.warning(msg)
        
        return True

    def error(self, device_name="Doosan M0609", error_msg="error!"):
        """
        write error log message in error.log and show command

        :param device_name (str) : write hardware machine or software
        :param error_msg (str) : Message to log
        :return: True
        """

        msg = "[{}] : {}".format(device_name, error_msg)
        self.mylogger.error(msg)

        return True
    '''
    if len(input_device_server_name)!=0:
        path=f"AutoModuleGeneration/{input_module_name}/{input_device_server_name}"
    else:
        path=f"AutoModuleGeneration/{input_module_name}"
    if os.path.isdir(f"{path}/Log") == False:
        os.makedirs(f"{path}/Log")
    with open(f"{path}/Log/Logging_Class.py", 'w') as file:
        file.write(script_content)

def script_generation_module_node(formatted_time:str, author:str, input_module_name:str, device_list:list, ip:str, port:int, input_device_server_config_list:list):
    """Generate module node script for OCTOPUS operation control system"""
    raise NotImplementedError("Function implementation has been masked")

def script_generation_device_server(formatted_time:str, author:str, input_module_name:str, input_device_server_name:str, device_list:list, ip:str, port:int):
    """Generate device server script for OCTOPUS operation control system"""
    raise NotImplementedError("Function implementation has been masked")

class ConfigValidation_DeviceServer(BaseModel):
    server_name: str
    device_type: list
    HOST: str

if __name__ == "__main__":

    #########################
    # please edit this part #
    #########################
    # OpenAI API key setting

    module_node_config={
        "author":"Hyuk Jun Yoo (yoohj9475@kist.re.kr)",
        
        "name":"SolidStateModule",
        "module_type":"Synthesis", # ["Synthesis", "Preprocess", "Evaluation", "Characterization"]
        "module_description":"This module refers to a solid-state synthesis process via powder type.", # More detailed information could improve the quality of GPT generation
        "device_type":["stirrer", "powder dispenser", "weighing machine", "heater", "XRD"],
        
        "task_type":["AddPowder"], # must include this task
        
        "resource":{
            "vialHolder":["?"]*8,
            "heater":["?"]*8,
            "XRD":["?"]*16
        },

        "HOST":"127.0.0.1", # please implement your ip
        "PORT":54009, # Default = 54009, 54010 --> emergency stop PORT
        "gpt_on":True, # True --> using GPT // False --> using previous generated answer (txt file)
    }
    device_server_config_list=[
        {
            "author":"Hyuk Jun Yoo (yoohj9475@kist.re.kr)",
            "name":"RobotArmDeviceServer",
            "device_type":["Robot arm", "Pipette"],
            "HOST":"127.0.0.1", # please implement your ip
            "gpt_on":True, # True --> using GPT // False --> using previous generated answer (txt file)
        },
        {
            "author":"Hyuk Jun Yoo (yoohj9475@kist.re.kr)",
            "name":"PumpDeviceServer",
            "device_type":["Pump"],
            "HOST":"127.0.0.1", # please implement your ip
            "gpt_on":True, # True --> using GPT // False --> using previous generated answer (txt file)
        },
    ]
    for idx in range(len(device_server_config_list)):
        device_server_config_list[idx]["PORT"]=module_node_config["PORT"]+idx+1
    #########################################
    # please edit this part until this line #
    #########################################

    current_time = datetime.now()
    formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")

    modulenode_device_action_dict={}

    for idx, device_server_config in enumerate(device_server_config_list):
        try:
            _ = ConfigValidation_DeviceServer(**device_server_config)
        except ValidationError as e:
            raise ValidationError(e)
        # with open(f"AutoModuleGeneration/GPT_answer_generation/GPT_{device_server_config['name']}.txt", 'r', encoding='utf-8') as file:
        #     answer = file.read()
        device_action_dict, answer = GPT_generate_module_deviceserver(device_server_config["name"], device_server_config["device_type"], device_server_config["gpt_on"])
        modulenode_device_action_dict.update(device_action_dict)
        # code_dict=extract_code_py(answer)
        device_class_name_list=list(answer.keys())
        # print(device_server_config['name'], device_class_name_list)
        device_server_config_list[idx]["converted_device_name_list"]=device_class_name_list
        save_to_files_modulenode(device_server_config["name"], answer)
        script_generation_logging_class(formatted_time=formatted_time, author=module_node_config["author"],input_module_name=module_node_config["name"],
                                        input_device_server_name=device_server_config["name"])
        script_generation_BaseUtils(formatted_time=formatted_time, author=module_node_config["author"],input_module_name=module_node_config["name"],
                                    input_device_server_name=device_server_config["name"])
        script_generation_device_server(formatted_time=formatted_time, author=module_node_config["author"],input_module_name=module_node_config["name"],
                                        input_device_server_name=device_server_config["name"], device_list=device_class_name_list, 
                                        ip=device_server_config["HOST"], port=device_server_config["PORT"])

    try:
        _ = ConfigValidation_DeviceServer(**module_node_config)
    except ValidationError as e:
        raise ValidationError(e)
    # with open(f'AutoModuleGeneration/GPT_answer_generation/GPT_{module_node_config["name"]}.txt', 'r', encoding='utf-8') as file:
    #     answer_module = file.read()
    device_action_dict, answer_module = GPT_generate_module_deviceserver(module_node_config["name"], module_node_config["device_type"], module_node_config["gpt_on"])
    modulenode_device_action_dict.update(device_action_dict)
    # code_dict_module=extract_code_py(answer_module)
    device_class_name_list=list(answer_module.keys())
    # print(module_node_config["name"], device_class_name_list)


Complete the function implementation replacing "raise NotImplementedError".