From a5de31254faf2deeb7b49128ad044792add7c428 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 24 Jun 2024 19:18:02 +0200 Subject: [PATCH] add support for MillPlusIT V600 and MANUALPlus 620 Testing for both controls is limited to windows programming stations Support for MillPlusIT V600 is still in beat phase and not all functions are supported. Earlier versions of the MillPlus, eg. V530 do not support LSV2! --- README.md | 41 ++++++++++++++++++++-------------- pyLSV2/client.py | 2 +- pyLSV2/const.py | 2 ++ pyLSV2/dat_cls.py | 43 +++++++++++++++++++++++++++++++----- pyLSV2/scripts/demo.py | 7 +++++- tests/test_file_functions.py | 7 ++++++ tests/test_transfer.py | 5 +++++ 7 files changed, 82 insertions(+), 25 deletions(-) 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"