diff --git a/README.md b/README.md index 8882ceb..fbe3489 100644 --- a/README.md +++ b/README.md @@ -160,25 +160,32 @@ These changes where made intentionally to make further development easier. See t been tested: ### Programming Stations -| Control | Software | -|-------------|----------------| -| TNC640 | 340595 08 SP1 | -| TNC640 | 340595 10 SP2 | -| TNC640 | 340595 11 SP1 | -| TNC640 | 340595 11 SP4 | -| iTNC530 | 606425 04 SP20 | -| iTNC530 | 340494 08 SP2 | -| CNCpilot640 | 1230521 03 SP1 | -| TNC7 | 817625 17 | +| Control | Software | Notes | +|-----------------|----------------|-------| +| TNC320 | 340554 04 SP1 | 1 | +| TNC640 | 340594 01 | | +| TNC640 | 340595 08 SP1 | | +| TNC640 | 340595 10 SP2 | | +| TNC640 | 340595 11 SP1 | | +| TNC640 | 340595 11 SP4 | | +| iTNC530 | 606425 04 SP20 | | +| iTNC530 | 340494 08 SP2 | | +| MANUALplus620 | 634130 02 SP7 | | +| CNCpilot640 | 1230521 03 SP1 | | +| TNC7 | 817625 17 | | +| MillPlusIT V600 | 538956 03 SP15 | 1, 2 | + +1) some tests are failing and have not been analysed yet (screendump and rw_machine_parameter) +2) this control is not officially supported by any other Heidenhain tool but seems to be at least somewhat compatible ### Machines -| Control | Software | -|-------------|----------------| -| TNC620 | 817605 04 SP1 | -| TNC640 | 340595 08 SP1 | -| iTNC530 | 340480 14 SP4 | -| iTNC530 | 606420 02 SP14 | -| iTNC530 | 606420 02 SP3 | +| Control | Software | Notes | +|-----------------|----------------|-------| +| TNC620 | 817605 04 SP1 | | +| TNC640 | 340595 08 SP1 | | +| iTNC530 | 340480 14 SP4 | | +| iTNC530 | 606420 02 SP14 | | +| iTNC530 | 606420 02 SP3 | | If you have tested it on one of your machines with a different software version, please let us know! diff --git a/pyLSV2/client.py b/pyLSV2/client.py index d807725..064c2ca 100644 --- a/pyLSV2/client.py +++ b/pyLSV2/client.py @@ -70,7 +70,7 @@ def versions(self) -> ld.VersionInfo: """version information of the connected control""" return self._versions - @property + @property def parameters(self) -> ld.SystemParameters: """system parameters of the connected control""" return self._sys_par diff --git a/pyLSV2/const.py b/pyLSV2/const.py index 6326a89..6402089 100644 --- a/pyLSV2/const.py +++ b/pyLSV2/const.py @@ -95,6 +95,8 @@ class ControlType(Enum): TNC7 = 5 """the TNC7 is the new control that behaves just a bit different again so we need a special case for it""" + MILLPLUS = 6 + """the MILLPlusIT V600 is officially""" class Login(str, Enum): """Enum for the different login roles""" diff --git a/pyLSV2/dat_cls.py b/pyLSV2/dat_cls.py index bcf7c8e..7243121 100644 --- a/pyLSV2/dat_cls.py +++ b/pyLSV2/dat_cls.py @@ -8,9 +8,11 @@ from datetime import datetime import struct +import re from typing import List from .const import ControlType, LSV2StatusCode, ChannelType +from .err import LSV2DataException class VersionInfo: @@ -27,6 +29,9 @@ def __init__(self): self.id_number = "" self.release = "" + self._ncsw_reg = re.compile(r"(?P\d{5})(?P\d)(?:[ -])(?P\d+)(?: (?P.*))?") + + def __str__(self) -> str: return "%s / %s" % (self.control, self.nc_sw) @@ -57,10 +62,14 @@ def control(self, value: str): self.type = ControlType.MILL_NEW elif value.startswith("TNC128"): self.type = ControlType.MILL_NEW + elif value.startswith("MANUALPLUS"): + self.type = ControlType.LATHE_NEW elif value.startswith("CNCPILOT640"): self.type = ControlType.LATHE_NEW elif value.startswith("TNC7"): self.type = ControlType.TNC7 + elif value.startswith("MILLPLUS"): + self.type = ControlType.MILLPLUS else: self.type = ControlType.UNKNOWN @@ -144,6 +153,14 @@ def is_pilot(self) -> bool: """return ``True`` if control is a CNCPILOT640""" return self._control_type == ControlType.LATHE_NEW + def is_manualplus(self) -> bool: + """return ``True`` if control is a MANUALplus620""" + return self._control_type == ControlType.LATHE_NEW + + def is_millplus(self) -> bool: + """return ``True`` if control is a MillPlus""" + return self._control_type == ControlType.MILLPLUS + def is_tnc7(self) -> bool: """return ```True``` if control is a TNC7""" return self._control_type == ControlType.TNC7 @@ -151,24 +168,38 @@ def is_tnc7(self) -> bool: @property def nc_sw_base(self) -> int: """base nc software as integer""" - return int(self.nc_sw[:5]) * 10 + result = self._ncsw_reg.fullmatch(self.nc_sw) + if result is None or "base" not in result.groupdict(): + raise LSV2DataException("could not parse nc software base version from '%s'" % self.nc_sw) + return int(result.group("base")) * 10 @property def nc_sw_type(self) -> int: """nc software type""" - return int(self.nc_sw[5:6]) + result = self._ncsw_reg.fullmatch(self.nc_sw) + if result is None or "type" not in result.groupdict(): + raise LSV2DataException("could not parse nc software type from '%s'" % self.nc_sw) + return int(result.group("type")) @property def nc_sw_version(self) -> int: """nc software version number""" - return int(self.nc_sw[7:9]) + result = self._ncsw_reg.fullmatch(self.nc_sw) + if result is None or "version" not in result.groupdict(): + raise LSV2DataException("could not parse nc software version from '%s'" % self.nc_sw) + return int(result.group("version")) @property def nc_sw_service_pack(self) -> int: """service pack number""" - if len(self.nc_sw) > 9: - return int(self.nc_sw[12:]) - return 0 + result = self._ncsw_reg.fullmatch(self.nc_sw) + if result is None: + raise LSV2DataException("could not parse service pack from '%s'" % self.nc_sw) + if result.group("sp") is None: + return 0 + sp_str = result.group("sp").lower() + sp_str = sp_str.lstrip("sp") + return int(sp_str) class SystemParameters: diff --git a/pyLSV2/scripts/demo.py b/pyLSV2/scripts/demo.py index 3a4df18..e30e37d 100644 --- a/pyLSV2/scripts/demo.py +++ b/pyLSV2/scripts/demo.py @@ -60,7 +60,12 @@ def comprehensive_demo(): ) ) - print("# Time and date: {:}".format(con.get_remote_datetime())) + if con.versions.nc_sw_type == 4: + print("# Reading time and date on a windows programming station is not supported") + elif con.versions.nc_sw_base == 538950: + print("# Reading time and date on a windows MILLplusIT programming station is not supported") + else: + print("# Time and date: {:}".format(con.get_remote_datetime())) # read error messages via LSV2, works only on iTNC controls print("# read error messages, only available on some iTNC530 versions") diff --git a/tests/test_file_functions.py b/tests/test_file_functions.py index 102413c..a6a92c4 100644 --- a/tests/test_file_functions.py +++ b/tests/test_file_functions.py @@ -14,6 +14,8 @@ def test_read_info(address: str, timeout: float): mdi_path = "TNC:\\$MDI.H" elif lsv2.versions.is_pilot(): mdi_path = "TNC:\\nc_prog\\ncps\\PGM01.nc" + elif lsv2.versions.is_millplus(): + mdi_path = "TNC:\\mdi\\mdi.pm" else: mdi_path = "TNC:\\nc_prog\\$mdi.h" @@ -65,6 +67,9 @@ def test_remote_file_functions(address: str, timeout: float): elif lsv2.versions.is_pilot(): mdi_dir = "TNC:\\nc_prog\\ncps\\" mdi_name = "PGM01.nc" + elif lsv2.versions.is_millplus(): + mdi_dir = "TNC:\\mdi\\" + mdi_name = "mdi.pm" else: mdi_dir = "TNC:\\nc_prog\\" mdi_name = "$mdi.h" @@ -113,6 +118,8 @@ def test_path_formating(address: str, timeout: float): mdi_path = "TNC:/$MDI.H" elif lsv2.versions.is_pilot(): mdi_path = "TNC:/nc_prog/ncps/PGM01.nc" + elif lsv2.versions.is_millplus(): + mdi_path = "TNC:/mdi/mdi.pm" else: mdi_path = "TNC:/nc_prog/$mdi.h" diff --git a/tests/test_transfer.py b/tests/test_transfer.py index 0e40f19..b40efab 100644 --- a/tests/test_transfer.py +++ b/tests/test_transfer.py @@ -19,6 +19,9 @@ def test_file_recive(address: str, timeout: float): elif lsv2.versions.is_pilot(): mdi_path = "TNC:/nc_prog/ncps/PGM01.nc" tool_t_path = "TNC:/table/toolturn.htt" + elif lsv2.versions.is_millplus(): + mdi_path = "TNC:/mdi/mdi.pm" + tool_t_path = "TNC:/table/tool.t" else: mdi_path = "TNC:/nc_prog/$mdi.h" tool_t_path = "TNC:/table/tool.t" @@ -121,6 +124,8 @@ def test_recive_with_path_formating(address: str, timeout: float): mdi_path = "TNC:/$MDI.H" elif lsv2.versions.is_pilot(): mdi_path = "TNC:/nc_prog/ncps/PGM01.nc" + elif lsv2.versions.is_millplus(): + mdi_path = "TNC:/mdi/mdi.pm" else: mdi_path = "TNC:/nc_prog/$mdi.h"