etherlab/EthercatSlave.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Mon, 13 Aug 2018 18:19:17 +0300
changeset 2282 73f95ba6d3af
parent 2165 02a2b5dee5e3
child 2353 8f1a2846b2f5
child 2641 c9deff128c37
permissions -rw-r--r--
Rename extension instance 'wxHMI' to 'wxglade_hmi'

It is necessary because of following commit 7f59aa398669 ('WxGlade HMI extension now does
only instanciate wx object who's name match extension's name. If no
object match the name and no code is provided in 'start' user python
code section, then a warning is issued')
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file is part of Beremiz
#
# Copyright (C) 2011-2014: Laurent BESSARD, Edouard TISSERANT
#                          RTES Lab : CRKim, JBLee, youcu
#                          Higen Motor : Donggu Kang
#
# See COPYING file for copyrights details.

import wx

from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
from ConfigTreeNode import ConfigTreeNode

from ConfigEditor import NodeEditor

#------------------------------------------
from CommonEtherCATFunction import _CommonSlave 
#------------------------------------------


TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L",
    "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", 
    "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L"}

DATATYPECONVERSION = {"BOOL" : "BIT", "SINT" : "S8", "INT" : "S16", "DINT" : "S32", "LINT" : "S64",
    "USINT" : "U8", "UINT" : "U16", "UDINT" : "U32", "ULINT" : "U64", 
    "BYTE" : "U8", "WORD" : "U16", "DWORD" : "U32", "LWORD" : "U64"}

VARCLASSCONVERSION = {"T": LOCATION_VAR_INPUT, "R": LOCATION_VAR_OUTPUT, "RT": LOCATION_VAR_MEMORY}

def ExtractHexDecValue(value):
    try:
        return int(value)
    except:
        pass
    try:
        return int(value.replace("#", "0"), 16)
    except:
        raise ValueError, "Invalid value for HexDecValue \"%s\"" % value

def GenerateHexDecValue(value, base=10):
    if base == 10:
        return str(value)
    elif base == 16:
        return "#x%.8x" % value
    else:
        raise ValueError, "Not supported base"

def ExtractName(names, default=None):
    if len(names) == 1:
        return names[0].getcontent()
    else:
        for name in names:
            if name.getLcId() == 1033:
                return name.getcontent()
    return default


#--------------------------------------------------
#                    Ethercat Node
#--------------------------------------------------

class _EthercatSlaveCTN:
    NODE_PROFILE = None
    EditorType = NodeEditor
    
    def __init__(self):
        # ----------- call ethercat mng. function --------------
        self.CommonMethod = _CommonSlave(self)
    
    def GetIconName(self):
        return "Slave"
    
    def ExtractHexDecValue(self, value):
        return ExtractHexDecValue(value)
    
    def GetSizeOfType(self, type):
        return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None)
    
    def GetSlavePos(self):
        return self.BaseParams.getIEC_Channel()
    
    def GetParamsAttributes(self, path = None):
        if path:
            parts = path.split(".", 1)
            if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
                return self.MandatoryParams[1].getElementInfos(parts[0], parts[1])
            elif self.CTNParams and parts[0] == self.CTNParams[0]:
                return self.CTNParams[1].getElementInfos(parts[0], parts[1])
        else:
            params = []
            if self.CTNParams:
                params.append(self.CTNParams[1].getElementInfos(self.CTNParams[0]))
            else:
                params.append({
                    'use': 'required', 
                    'type': 'element', 
                    'name': 'SlaveParams', 
                    'value': None, 
                    'children': []
                })
            
            slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
            params[0]['children'].insert(0,
                   {'use': 'optional', 
                    'type': self.CTNParent.GetSlaveTypesLibrary(self.NODE_PROFILE), 
                    'name': 'Type', 
                    'value': (slave_type["device_type"], slave_type)}) 
            params[0]['children'].insert(1,
                   {'use': 'optional', 
                    'type': 'unsignedLong', 
                    'name': 'Alias', 
                    'value': self.CTNParent.GetSlaveAlias(self.GetSlavePos())})
            return params
        
    def SetParamsAttribute(self, path, value):
        self.GetSlaveInfos()
        position = self.BaseParams.getIEC_Channel()
        
        if path == "SlaveParams.Type":
            self.CTNParent.SetSlaveType(position, value)
            slave_type = self.CTNParent.GetSlaveType(self.GetSlavePos())
            value = (slave_type["device_type"], slave_type)
            #if self._View is not None:
                #wx.CallAfter(self._View.EtherCATManagementTreebook.SlaveStatePanel.RefreshSlaveInfos())
                #self._View.EtherCATManagementTreebook.SlaveStatePanel.RefreshSlaveInfos()
                #self._View.EtherCATManagementTreebook.PDOMonitoringPanel.PDOInfoUpdate()
                #self._View.EtherCATManagementTreebook.SmartView.Create_SmartView()
            return value, True
        elif path == "SlaveParams.Alias":
            self.CTNParent.SetSlaveAlias(position, value)
            return value, True
        
        value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value)
        
        # Filter IEC_Channel, Slave_Type and Alias that have specific behavior
        if path == "BaseParams.IEC_Channel" and value != position:
            self.CTNParent.SetSlavePosition(position, value)
        
        return value, refresh
        
    def GetSlaveInfos(self):
        return self.CTNParent.GetSlaveInfos(self.GetSlavePos())
    
    def GetSlaveVariables(self, limits):
        return self.CTNParent.GetSlaveVariables(self.GetSlavePos(), limits)
    
    def GetVariableLocationTree(self):
        return  {"name": self.BaseParams.getName(),
                 "type": LOCATION_CONFNODE,
                 "location": self.GetFullIEC_Channel(),
                 "children": self.CTNParent.GetDeviceLocationTree(self.GetSlavePos(), self.GetCurrentLocation(), self.BaseParams.getName())
        }

    def CTNGenerate_C(self, buildpath, locations):
        return [],"",False