[PYTHON] Une classe qui change librement la valeur de l'automate par communication socket

Qu'est-ce que l'API en premier lieu?

Le PLC est un dispositif mécanique utilisé pour faire fonctionner une grande machine telle qu'une usine. Cet équipement est principalement fabriqué par Keyence et Mitsubishi. Lors de la création d'un programme, il est exprimé dans un schéma graphique tel qu'un schéma électrique au lieu de la langue anglophone utilisée sur un PC.

Déclencheur

Créé au travail à la question "Puis-je communiquer avec l'API avec un programme informatique?" J'ai vérifié PLC à partir de 1 car je suis une personne dans le domaine informatique qui ne connaît pas l'API.

Difficile de communiquer

Il semble que la communication soit possible, mais comme il existe peu d'exemples de codes réalisés avec python, je comprends le mécanisme d'autres langages. La communication -Soket est utilisée pour envoyer la valeur. -Il est nécessaire d'encoder le code ascii lors de la communication. -La valeur à saisir lors de l'envoi est convertie de hexadécimal en décimal. Vous devez convertir le code ascii en décimal. J'ai eu du mal parce que je ne connaissais pas les mathématiques.

Environnement PLC et PC

C'est un environnement où la communication est effectuée via un hub de commutation. PC-Switching Hub-PLC C'est comme ça.

Comment utiliser cette classe


    ip = '10.50.100.32' #Adresse IP côté automate.
    port = 8501 #Numéro de port utilisé pour la communication de la liaison supérieure définie côté API
    #Le nom de l'appareil est EM9000 etc.
    #Le nombre d'appareils est utilisé lorsque le nombre d'appareils est continuellement et dans l'ordre.
    #EM9000,Utilisé lors de l'organisation d'appareils tels que EM9001.
    #La valeur / le message à saisir
       #Les nombres décimaux peuvent être utilisés tels quels.
       #Les nombres hexagonaux peuvent être envoyés en 4x caractères. 4 caractères, 8 caractères,12 caractères
       #Par conséquent, le nombre d'appareils augmente également de 1 à 3.
       
       #ascii ne peut avoir que 2 caractères par appareil.
    #Le nombre d'appareils augmentera en conséquence.

    to_EM9000 = Send_to_PLC(ip,port,"EM9000","3","ABCDEF")
    to_EM9002 = Send_to_PLC(ip,port,"EM9002","2","00200616")
    to_EM9004 = Send_to_PLC(ip,port,"EM9004","1","1")


    to_EM9000.send_ascii_message()    #Envoyer le code ASCII à l'API sous forme de nombre décimal
    to_EM9002.send_16decimal_message() #Envoi hexadécimal à décimal à l'API
    to_EM9004.send_10decimal_message() #Envoyer le nombre décimal à l'automate tel quel

Code source de la classe

Send_to_PLC


import socket

#Une classe qui peut changer la valeur d'un équipement API
class Send_to_PLC(object):

    def __init__(self,ip_address,port_num,device_name,data_length,message):
        self.ip_address =ip_address
        self.port_num = int(port_num)
        self.device_name = device_name
        self.data_length = data_length
        self.message = message

    #Convertir le code ASCII en nombre décimal
    def ascii_to_10decimal(self):
        #Si le nombre de caractères du message est inférieur à la longueur de données spécifiée
        read_device_length = int(self.data_length)
        message_length =  len(self.message)

        if read_device_length >= message_length:
            data_lng_int = message_length
        else:
            data_lng_int = read_device_length

        #Mettez le message dans une liste de 2 octets.
        separate_msg_list =[]
        for i in range(data_lng_int):
            if i == 0:
                separate_msg = self.message[0:2]
                separate_msg_list.append(separate_msg)
            else:
                separate_msg = self.message[2*i:2*(i+1)]
                separate_msg_list.append(separate_msg)

        #Si le nombre de caractères est impair, le dernier caractère est justifié à gauche.
        if len(separate_msg_list[-1]) == 1:
            separate_msg_list[-1] = separate_msg_list[-1]+ " "



        #Convertissez le code ascii en décimal.(ascii → binaire hexadécimal → décimal)
        digit_mesage_list = []
        for msg in separate_msg_list:
            ascii_data = msg.encode(encoding="ascii")
            hex_bina_data = binascii.hexlify(ascii_data)
            digi10_int = int(hex_bina_data,16)
            digi10_str = str(digi10_int)
            digit_mesage_list.append(digi10_str)

        trans_message = " ".join(digit_mesage_list)

        return trans_message


    #Convertir hexadécimal en décimal
    def digit16_to_degit10(self):
        read_device_length = int(self.data_length)
        message_length =  len(self.message)

        if read_device_length >= message_length:
            data_lng_int = message_length
        else:
            data_lng_int = read_device_length


        #Divisez le message en 4 octets et mettez-les dans la liste.
        #Convertir un nombre hexadécimal en nombre décimal après l'entrée
        separate_msg_list =[]
        for i in range(data_lng_int):
            if i == 0:
                separate_msg = self.message[0:4]
                digi10_int = int(separate_msg,16)
                digi10_str = str(digi10_int)
                separate_msg_list.append(digi10_str)
            else:
                separate_msg = self.message[4*i:4*(i+1)]
                digi10_int = int(separate_msg,16)
                digi10_str = str(digi10_int)
                separate_msg_list.append(digi10_str)


        trans_message = " ".join(separate_msg_list)
        return trans_message


    #Envoyer à l'API
    def send_message(self,command_list):
        command_sentence = "".join(command_list)
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect((self.ip_address,self.port_num))
        s.send(command_sentence.encode('ascii'))


    #Après la conversion du code ASCII en nombre décimal,Envoyer à l'API
    #Le nombre de caractères dans le message est un multiple de quatre.
    def send_ascii_message(self):
        tranformed_digi_message = self.ascii_to_10decimal()
        command_list = ['WRS ',self.device_name,".S ",self.data_length," ",tranformed_digi_message,'\r']
        self.send_message(command_list)



    #Après la conversion de l'hexadécimal en décimal,Envoyer à l'API
    def send_16decimal_message(self):
        tranformed_digi_message = self.digit16_to_degit10()
        command_list = ['WRS ',self.device_name,".S ",self.data_length," ",tranformed_digi_message,'\r']
        self.send_message(command_list)


    #Après la conversion de l'hexadécimal en décimal,Envoyer à l'API
    #Prend en charge un seul appareil
    def send_10decimal_message(self):
        command_list = ['WR ',self.device_name,".S ",self.message,'\r']
        self.send_message(command_list)


if __name__ == '__main__':

    ip = '10.50.100.32'
    port = 8501
    #Adresse IP lors de la création d'une instance,numéro de port,Nom du premier appareil, nombre d'appareils,Saisissez la valeur / le message à saisir.
    to_EM9000 = Send_to_PLC(ip,port,"EM9000","3","ABCDEF")
    to_EM9002 = Send_to_PLC(ip,port,"EM9002","2","00200616")
    to_EM9004 = Send_to_PLC(ip,port,"EM9004","1","1")


    to_EM9000.send_ascii_message()    #Envoyer le code ASCII à l'API sous forme de nombre décimal
    to_EM9002.send_16decimal_message() #Envoi hexadécimal à décimal à l'API
    to_EM9004.send_10decimal_message() #Envoyer le nombre décimal à l'automate tel quel

Je pense que l'explication n'est pas bonne, mais je la publierai pour le moment.

Recommended Posts

Une classe qui change librement la valeur de l'automate par communication socket
Classe qui atteint l'API de DMM
Un mémo qui a résolu le problème du sac à dos par la méthode gourmande
Lors de l'incrémentation de la valeur d'une clé qui n'existe pas
[Python] Un programme qui trouve une paire qui peut être divisée par une valeur spécifiée
J'ai essayé de communiquer avec un serveur distant par communication Socket avec Python.
Pandas avec des changements subtils dans les nombres et comment y faire face
Trouvez la valeur minimale de la fonction par la méthode d'optimisation du groupe de particules (PSO)