py-ap200-simple-interface 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. py_ap200_simple_interface-0.1.0/LICENSE +21 -0
  2. py_ap200_simple_interface-0.1.0/PKG-INFO +116 -0
  3. py_ap200_simple_interface-0.1.0/README.md +102 -0
  4. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimToolsSample/BONE-1.aimtool +10 -0
  5. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimToolsSample/TEST-1.aimtool +10 -0
  6. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_Connect.py +40 -0
  7. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_Exit.py +20 -0
  8. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetDeviceType.py +39 -0
  9. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetDiscretePoints.py +72 -0
  10. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetIpAddress.py +41 -0
  11. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetManufactureInfo.py +68 -0
  12. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetPhysicalAddress.py +39 -0
  13. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_GetSpecificToolInfo.py +112 -0
  14. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/AimooeExt_Init.py +18 -0
  15. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/Utils.py +18 -0
  16. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/__init__.py +25 -0
  17. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/bin/AimPosition2.3.4.dll +0 -0
  18. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/bin/AimooeExt_Interface2.3.4.dll +0 -0
  19. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/bin/libusb0.dll +0 -0
  20. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExt/bin/opencv_core2413.dll +0 -0
  21. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/AimooeExtDrive.py +144 -0
  22. py_ap200_simple_interface-0.1.0/py_ap200_simple_interface/__init__.py +6 -0
  23. py_ap200_simple_interface-0.1.0/pyproject.toml +21 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GGN_2015
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-ap200-simple-interface
3
+ Version: 0.1.0
4
+ Summary: a simple interface package for aimooe AP-200.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: GGN_2015
8
+ Author-email: neko@jlulug.org
9
+ Requires-Python: >=3.10
10
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
11
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 11
12
+ Description-Content-Type: text/markdown
13
+
14
+ # py_ap200_simple_interface
15
+ a simple interface package for aimooe AP-200.
16
+
17
+ ## Installation
18
+
19
+ > [!WARNING]
20
+ > This package can only be installed under windows10/11 and x86-64 ISA.
21
+
22
+ ```bash
23
+ pip install py_ap200_simple_interface
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ from py_ap200_simple_interface import AimooeExtDrive, I_ConnectionMethod
30
+
31
+ # Initialize AimooeExtDrive
32
+ drive = AimooeExtDrive()
33
+
34
+ # Connect Methods
35
+ # Select from I_USB, I_ETHERNET and I_WIFI
36
+ connect_method = I_ConnectionMethod.I_WIFI
37
+
38
+ # USB:
39
+ if connect_method == I_ConnectionMethod.I_USB:
40
+ drive.connect(I_ConnectionMethod.I_USB)
41
+
42
+ # Ethernets:
43
+ # An IP address should be given for ethernet connection
44
+ # before connecting device with ethernet, you need to confirm that
45
+ # your ethernet adaptor is in the same IP address segment with the device
46
+ # and shutdown all proxy service on your computer which may affect the connection
47
+ if connect_method == I_ConnectionMethod.I_ETHERNET:
48
+ drive.connect(I_ConnectionMethod.I_ETHERNET, "192.168.1.10")
49
+
50
+ # Wifi:
51
+ # The wifi name of Aimooe Device is `AimPosition-XXXXXX`
52
+ # The password of that wireless connection is `aimooe8888`
53
+ if connect_method == I_ConnectionMethod.I_WIFI:
54
+ drive.connect(I_ConnectionMethod.I_WIFI)
55
+
56
+ # Some basic information
57
+ print(drive.get_connect_method())
58
+ print(drive.get_device_type())
59
+ print(drive.get_ip_address())
60
+ print(drive.get_manufacture_info())
61
+ print(drive.get_physical_address())
62
+
63
+ # BONE-1 is a sample specific tool
64
+ # path and toolname should not contain special characters
65
+ print(drive.get_specific_tool_info("./py_ap200_simple_interface/AimooeExt/AimToolsSample/", ["BONE-1"]))
66
+
67
+ # You can reconnect after disconnect
68
+ # After disconnect, you must reconnect before next use
69
+ drive.disconnect()
70
+ ```
71
+
72
+ ### Return value of `drive.get_specific_tool_info`
73
+
74
+ - `_ToolPath`: The selected tool folder.
75
+ - `_DiscretePoints`: The discrete points which do not lie in any tool listed.
76
+ - `_TimeCost`: The length of time between the begin and end of the device call.
77
+ - `<tool_name>`: Gives the specific infomation of a tool.
78
+ - `MeanError` and `RMSError`: Error for markers.
79
+ - `Origin`: The translation vector from tool space to camera space.
80
+ - i.e. The position of gravity point of markers in camera space, if your tool file is generated by aimooe system.
81
+ - `Tooltip`: If tooltip is defined, it shows the coordination of tooltip, otherwise the same as `Origin`.
82
+ - `rMatrix`: The rotation matrix from tool coordination to camera coordination.
83
+ - `qRotation`: Quaternion form in order $(x, y, z, w) = w + xi + yj + zk$ of the rotation matrix .
84
+ - `MarkerCoordinates`: The marker coordinates (in camera space) in this tool.
85
+
86
+ ```
87
+ {
88
+ '_ToolPath': './py_ap200_simple_interface/AimooeExt/AimToolsSample/\\',
89
+ 'BONE-1': {
90
+ 'MeanError': 0.1138331070542336,
91
+ 'RMSError': 0.0003674850158859,
92
+ 'Origin': [-137.575927734375, 120.42643737792969, 793.1155395507812],
93
+ 'Tooltip': [-137.575927734375, 120.42643737792969, 793.1155395507812],
94
+ 'Rotation': [2.061613082885742, 1.6536511182785034, -0.4304990470409393],
95
+ 'qRotation': [0.7492992877960205, 0.601024329662323, -0.1564661413431168, 0.2298665046691895],
96
+ 'rMatrix': [
97
+ [0.2285761088132858, 0.9726269245147705, 0.0418308153748512],
98
+ [0.828761637210846, -0.1718621850013733, -0.5325575470924377],
99
+ [-0.5107907056808472, 0.1563977003097534, -0.8453594446182251]
100
+ ],
101
+ 'MarkerCoordinates': {
102
+ '0': [-132.94031926182967, 137.4289669332182, 782.6069181107938],
103
+ '1': [-164.12739196778332, 120.93405919807722, 791.4971644346351],
104
+ '2': [-115.37230320753432, 126.89401508498568, 790.1637162115628],
105
+ '3': [-137.8636773243661, 96.44871350623225, 808.1944560570211]
106
+ }
107
+ },
108
+ '_DiscretePoints': {
109
+ '0': [-144.17166590597648, -200.3791638982969, 1135.5793169583249],
110
+ '1': [-198.36308760690474, -156.32112285976535, 1102.102245959862],
111
+ '2': [-150.24065470212915, -126.80431827909578, 1094.3467438475025]
112
+ },
113
+ '_TimeCost': 0.006980419158935547
114
+ }
115
+ ```
116
+
@@ -0,0 +1,102 @@
1
+ # py_ap200_simple_interface
2
+ a simple interface package for aimooe AP-200.
3
+
4
+ ## Installation
5
+
6
+ > [!WARNING]
7
+ > This package can only be installed under windows10/11 and x86-64 ISA.
8
+
9
+ ```bash
10
+ pip install py_ap200_simple_interface
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```python
16
+ from py_ap200_simple_interface import AimooeExtDrive, I_ConnectionMethod
17
+
18
+ # Initialize AimooeExtDrive
19
+ drive = AimooeExtDrive()
20
+
21
+ # Connect Methods
22
+ # Select from I_USB, I_ETHERNET and I_WIFI
23
+ connect_method = I_ConnectionMethod.I_WIFI
24
+
25
+ # USB:
26
+ if connect_method == I_ConnectionMethod.I_USB:
27
+ drive.connect(I_ConnectionMethod.I_USB)
28
+
29
+ # Ethernets:
30
+ # An IP address should be given for ethernet connection
31
+ # before connecting device with ethernet, you need to confirm that
32
+ # your ethernet adaptor is in the same IP address segment with the device
33
+ # and shutdown all proxy service on your computer which may affect the connection
34
+ if connect_method == I_ConnectionMethod.I_ETHERNET:
35
+ drive.connect(I_ConnectionMethod.I_ETHERNET, "192.168.1.10")
36
+
37
+ # Wifi:
38
+ # The wifi name of Aimooe Device is `AimPosition-XXXXXX`
39
+ # The password of that wireless connection is `aimooe8888`
40
+ if connect_method == I_ConnectionMethod.I_WIFI:
41
+ drive.connect(I_ConnectionMethod.I_WIFI)
42
+
43
+ # Some basic information
44
+ print(drive.get_connect_method())
45
+ print(drive.get_device_type())
46
+ print(drive.get_ip_address())
47
+ print(drive.get_manufacture_info())
48
+ print(drive.get_physical_address())
49
+
50
+ # BONE-1 is a sample specific tool
51
+ # path and toolname should not contain special characters
52
+ print(drive.get_specific_tool_info("./py_ap200_simple_interface/AimooeExt/AimToolsSample/", ["BONE-1"]))
53
+
54
+ # You can reconnect after disconnect
55
+ # After disconnect, you must reconnect before next use
56
+ drive.disconnect()
57
+ ```
58
+
59
+ ### Return value of `drive.get_specific_tool_info`
60
+
61
+ - `_ToolPath`: The selected tool folder.
62
+ - `_DiscretePoints`: The discrete points which do not lie in any tool listed.
63
+ - `_TimeCost`: The length of time between the begin and end of the device call.
64
+ - `<tool_name>`: Gives the specific infomation of a tool.
65
+ - `MeanError` and `RMSError`: Error for markers.
66
+ - `Origin`: The translation vector from tool space to camera space.
67
+ - i.e. The position of gravity point of markers in camera space, if your tool file is generated by aimooe system.
68
+ - `Tooltip`: If tooltip is defined, it shows the coordination of tooltip, otherwise the same as `Origin`.
69
+ - `rMatrix`: The rotation matrix from tool coordination to camera coordination.
70
+ - `qRotation`: Quaternion form in order $(x, y, z, w) = w + xi + yj + zk$ of the rotation matrix .
71
+ - `MarkerCoordinates`: The marker coordinates (in camera space) in this tool.
72
+
73
+ ```
74
+ {
75
+ '_ToolPath': './py_ap200_simple_interface/AimooeExt/AimToolsSample/\\',
76
+ 'BONE-1': {
77
+ 'MeanError': 0.1138331070542336,
78
+ 'RMSError': 0.0003674850158859,
79
+ 'Origin': [-137.575927734375, 120.42643737792969, 793.1155395507812],
80
+ 'Tooltip': [-137.575927734375, 120.42643737792969, 793.1155395507812],
81
+ 'Rotation': [2.061613082885742, 1.6536511182785034, -0.4304990470409393],
82
+ 'qRotation': [0.7492992877960205, 0.601024329662323, -0.1564661413431168, 0.2298665046691895],
83
+ 'rMatrix': [
84
+ [0.2285761088132858, 0.9726269245147705, 0.0418308153748512],
85
+ [0.828761637210846, -0.1718621850013733, -0.5325575470924377],
86
+ [-0.5107907056808472, 0.1563977003097534, -0.8453594446182251]
87
+ ],
88
+ 'MarkerCoordinates': {
89
+ '0': [-132.94031926182967, 137.4289669332182, 782.6069181107938],
90
+ '1': [-164.12739196778332, 120.93405919807722, 791.4971644346351],
91
+ '2': [-115.37230320753432, 126.89401508498568, 790.1637162115628],
92
+ '3': [-137.8636773243661, 96.44871350623225, 808.1944560570211]
93
+ }
94
+ },
95
+ '_DiscretePoints': {
96
+ '0': [-144.17166590597648, -200.3791638982969, 1135.5793169583249],
97
+ '1': [-198.36308760690474, -156.32112285976535, 1102.102245959862],
98
+ '2': [-150.24065470212915, -126.80431827909578, 1094.3467438475025]
99
+ },
100
+ '_TimeCost': 0.006980419158935547
101
+ }
102
+ ```
@@ -0,0 +1,10 @@
1
+ BONE-1
2
+ T
3
+ 4
4
+ 20.606943 -0.005458 0.040331 15
5
+ -4.885081 -26.211561 -0.023027 15
6
+ 12.012958 20.049110 -0.035819 15
7
+ -27.734814 6.167912 0.018507 15
8
+ 2
9
+ 0.000000 0.000000 0.000000
10
+ 0.000000 0.000000 0.000000
@@ -0,0 +1,10 @@
1
+ TEST-1
2
+ T
3
+ 4
4
+ 42.725300 -0.023240 -0.021435 15
5
+ -11.625416 35.968346 0.023876 15
6
+ 12.000782 -39.477016 0.019787 15
7
+ -43.100666 3.531907 -0.022227 15
8
+ 2
9
+ 0.000000 0.000000 0.000000
10
+ 0.000000 0.000000 0.000000
@@ -0,0 +1,40 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+ from ctypes import c_int, c_ubyte
4
+
5
+ from enum import Enum
6
+
7
+ class I_ConnectionMethod(Enum):
8
+ I_USB = 0
9
+ I_ETHERNET = 1
10
+ I_WIFI = 2
11
+
12
+ def call_AimooeExt_Connect(
13
+ dll: ctypes.CDLL,
14
+ EI_code: I_ConnectionMethod,
15
+ ipa: int = 192,
16
+ ipb: int = 168,
17
+ ipc: int = 31,
18
+ ipd: int = 10
19
+ ) -> int:
20
+ # Define function prototype
21
+ AimooeExt_Connect = dll.AimooeExt_Connect
22
+ # 参数类型:int, unsigned char, unsigned char, unsigned char, unsigned char
23
+ AimooeExt_Connect.argtypes = [c_int, c_ubyte, c_ubyte, c_ubyte, c_ubyte]
24
+ # 返回值类型:int
25
+ AimooeExt_Connect.restype = c_int
26
+
27
+ # Execute the function
28
+ result = AimooeExt_Connect(EI_code.value, ipa, ipb, ipc, ipd)
29
+ return int(result)
30
+
31
+ if __name__ == "__main__":
32
+ from AimooeExt.AimooeExt_Init import call_AimooeExt_Init
33
+ from AimooeExt.AimooeExt_Exit import call_AimooeExt_Exit
34
+ from AimooeExt.Utils import DLL_PATH
35
+ print(DLL_PATH)
36
+ dll = cdll.LoadLibrary(DLL_PATH)
37
+
38
+ print(call_AimooeExt_Init(dll))
39
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
40
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,20 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ def call_AimooeExt_Exit(dll:ctypes.CDLL) -> int:
5
+ # Define function prototype
6
+ AimooeExt_Exit = dll.AimooeExt_Exit
7
+ AimooeExt_Exit.restype = ctypes.c_int # Return type: int
8
+
9
+ # Execute the function
10
+ result = AimooeExt_Exit()
11
+ return int(result)
12
+
13
+ if __name__ == "__main__":
14
+ from AimooeExt_Init import call_AimooeExt_Init
15
+ from Utils import DLL_PATH
16
+ print(DLL_PATH)
17
+ dll = cdll.LoadLibrary(DLL_PATH)
18
+
19
+ print(call_AimooeExt_Init(dll))
20
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,39 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ def call_AimooeExt_GetDeviceType(dll:ctypes.CDLL) -> str:
5
+
6
+ # Define function prototype
7
+ AimooeExt_GetDeviceType = dll.AimooeExt_GetDeviceType
8
+ AimooeExt_GetDeviceType.restype = ctypes.c_int # Return type: int
9
+
10
+ # Execute the function
11
+ result = int(AimooeExt_GetDeviceType())
12
+ if result == 0:
13
+ return "Basic"
14
+ elif result == 1:
15
+ return "Standard"
16
+ elif result == 2:
17
+ return "AP-400 Industry"
18
+ elif result == 3:
19
+ return "Lite"
20
+ elif result == 4:
21
+ return "Ultimate"
22
+ elif result == 100:
23
+ return "None"
24
+ else:
25
+ return "Unknown"
26
+
27
+ if __name__ == "__main__":
28
+ from AimooeExt_Init import call_AimooeExt_Init
29
+ from AimooeExt_Exit import call_AimooeExt_Exit
30
+ from AimooeExt_Connect import call_AimooeExt_Connect
31
+ from AimooeExt_Connect import I_ConnectionMethod
32
+ from Utils import DLL_PATH
33
+ print(DLL_PATH)
34
+ dll = cdll.LoadLibrary(DLL_PATH)
35
+
36
+ print(call_AimooeExt_Init(dll))
37
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
38
+ print(call_AimooeExt_GetDeviceType(dll))
39
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,72 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+ import json
4
+ from typing import Any
5
+
6
+ try:
7
+ from .AimooeExt_Connect import I_ConnectionMethod
8
+ except:
9
+ from AimooeExt_Connect import I_ConnectionMethod
10
+
11
+ def call_AimooeExt_GetDiscretePoints(
12
+ dll: ctypes.CDLL,
13
+ EI: I_ConnectionMethod
14
+ ) -> tuple[int, dict[str, Any]]:
15
+ str_max_len = 65536
16
+
17
+ # 函数原型定义
18
+ AimooeExt_GetDiscretePoints = dll.AimooeExt_GetDiscretePoints
19
+ AimooeExt_GetDiscretePoints.argtypes = [
20
+ ctypes.c_int, # EI
21
+ ctypes.c_char_p, # store_str
22
+ ctypes.c_int # str_max_len
23
+ ]
24
+ AimooeExt_GetDiscretePoints.restype = None # void 返回
25
+
26
+ while True:
27
+ # 分配缓冲区
28
+ store_buffer = ctypes.create_string_buffer(str_max_len)
29
+
30
+ # 调用函数
31
+ AimooeExt_GetDiscretePoints(
32
+ EI.value,
33
+ store_buffer,
34
+ str_max_len
35
+ )
36
+ result = 1 # void 默认成功
37
+
38
+ # 转字符串
39
+ info_str = store_buffer.value.decode('utf-8', errors='ignore')
40
+
41
+ # 判断是否完整(结尾 $)
42
+ if info_str.rstrip().endswith("$"):
43
+ break
44
+
45
+ # 缓冲区不够,自动翻倍
46
+ str_max_len <<= 1
47
+
48
+ # 去掉结尾的 $
49
+ if info_str.rstrip().endswith("$"):
50
+ info_str = info_str.rstrip()[:-1]
51
+
52
+ return int(result), json.loads(info_str)
53
+
54
+
55
+ if __name__ == "__main__":
56
+ from AimooeExt_Init import call_AimooeExt_Init
57
+ from AimooeExt_Exit import call_AimooeExt_Exit
58
+ from AimooeExt_Connect import call_AimooeExt_Connect
59
+ from AimooeExt_Connect import I_ConnectionMethod
60
+ from Utils import DLL_PATH
61
+
62
+ print(DLL_PATH)
63
+ dll = cdll.LoadLibrary(DLL_PATH)
64
+
65
+ print(call_AimooeExt_Init(dll))
66
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
67
+
68
+ # 调用函数
69
+ ret, info = call_AimooeExt_GetDiscretePoints(dll, EI=I_ConnectionMethod.I_USB)
70
+ print(ret, info)
71
+
72
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,41 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ try:
5
+ from .AimooeExt_Connect import I_ConnectionMethod
6
+ except:
7
+ from AimooeExt_Connect import I_ConnectionMethod
8
+
9
+ def call_AimooeExt_GetIpAddress(dll:ctypes.CDLL, EI: I_ConnectionMethod) -> str:
10
+ # Define function prototype
11
+ AimooeExt_GetIpAddress = dll.AimooeExt_GetIpAddress
12
+ AimooeExt_GetIpAddress.argtypes = [ctypes.c_int] # 参数:枚举类型
13
+ AimooeExt_GetIpAddress.restype = ctypes.c_uint # 返回值:unsigned int
14
+
15
+ # Execute the function
16
+ result = AimooeExt_GetIpAddress(EI.value)
17
+ result = result % (1 << 32)
18
+
19
+ # Reconsturct the Ip Address
20
+ addr_list = []
21
+ for _ in range(4):
22
+ addr_list.append(result & 0xFF)
23
+ result >>= 8
24
+
25
+ return ".".join(map(str, addr_list[::-1]))
26
+
27
+ if __name__ == "__main__":
28
+ from AimooeExt_Init import call_AimooeExt_Init
29
+ from AimooeExt_Exit import call_AimooeExt_Exit
30
+ from AimooeExt_Connect import call_AimooeExt_Connect
31
+ from AimooeExt_Connect import I_ConnectionMethod
32
+ from AimooeExt_GetDeviceType import call_AimooeExt_GetDeviceType
33
+ from Utils import DLL_PATH
34
+ print(DLL_PATH)
35
+ dll = cdll.LoadLibrary(DLL_PATH)
36
+
37
+ print(call_AimooeExt_Init(dll))
38
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
39
+ print(call_AimooeExt_GetDeviceType(dll))
40
+ print(call_AimooeExt_GetIpAddress(dll, EI=I_ConnectionMethod.I_USB))
41
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,68 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ try:
5
+ from .AimooeExt_Connect import I_ConnectionMethod
6
+ except:
7
+ from AimooeExt_Connect import I_ConnectionMethod
8
+
9
+ def call_AimooeExt_GetManufactureInfo(dll: ctypes.CDLL, EI: I_ConnectionMethod) -> tuple[int, dict[str, str]]:
10
+ str_max_len = 1024
11
+
12
+ # Define function prototype
13
+ AimooeExt_GetManufactureInfo = dll.AimooeExt_GetManufactureInfo
14
+ AimooeExt_GetManufactureInfo.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
15
+ AimooeExt_GetManufactureInfo.restype = ctypes.c_int
16
+
17
+ while True:
18
+ # Allocate buffer to receive string (核心:创建字符串缓冲区)
19
+ store_buffer = ctypes.create_string_buffer(str_max_len)
20
+
21
+ # Execute the function
22
+ result = AimooeExt_GetManufactureInfo(EI.value, store_buffer, str_max_len)
23
+
24
+ # Convert buffer to Python string
25
+ info_str = store_buffer.value.decode('utf-8', errors='ignore')
26
+
27
+ # Error
28
+ if result != 1:
29
+ info_str = ""
30
+ break
31
+
32
+ # Check & double buffer
33
+ if info_str.rstrip().endswith("$"):
34
+ break
35
+ str_max_len <<= 1
36
+
37
+ # Erase $ at the end
38
+ if info_str.rstrip().endswith("$"):
39
+ info_str = info_str.rstrip()[:-1]
40
+
41
+ # Get Dict Info
42
+ info = dict()
43
+ for line in info_str.split("\n"):
44
+ if line.find(":") != -1:
45
+ lpart, rpart = line.split(":", maxsplit=1)
46
+ lpart = lpart.strip()
47
+ rpart = rpart.strip()
48
+ info[lpart] = rpart
49
+
50
+ return int(result), info
51
+
52
+ if __name__ == "__main__":
53
+ from AimooeExt_Init import call_AimooeExt_Init
54
+ from AimooeExt_Exit import call_AimooeExt_Exit
55
+ from AimooeExt_Connect import call_AimooeExt_Connect
56
+ from AimooeExt_Connect import I_ConnectionMethod
57
+ from AimooeExt_GetDeviceType import call_AimooeExt_GetDeviceType
58
+ from Utils import DLL_PATH
59
+ print(DLL_PATH)
60
+ dll = cdll.LoadLibrary(DLL_PATH)
61
+
62
+ print(call_AimooeExt_Init(dll))
63
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
64
+
65
+ ret, info = call_AimooeExt_GetManufactureInfo(dll, EI=I_ConnectionMethod.I_USB)
66
+ print(ret, info)
67
+
68
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,39 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ def call_AimooeExt_GetPhysicalAddress(dll: ctypes.CDLL) -> tuple[int, str]:
5
+ str_max_len = 20
6
+
7
+ # Define function prototype
8
+ AimooeExt_GetPhysicalAddress = dll.AimooeExt_GetPhysicalAddress
9
+ AimooeExt_GetPhysicalAddress.argtypes = [ctypes.c_char_p, ctypes.c_int]
10
+ AimooeExt_GetPhysicalAddress.restype = ctypes.c_int
11
+
12
+ # Allocate buffer to receive string
13
+ store_buffer = ctypes.create_string_buffer(str_max_len)
14
+
15
+ # Execute the function
16
+ result = AimooeExt_GetPhysicalAddress(store_buffer, str_max_len)
17
+
18
+ # Convert buffer to Python string
19
+ address_str = store_buffer.value.decode('utf-8', errors='ignore')
20
+
21
+ return int(result), address_str
22
+
23
+ if __name__ == "__main__":
24
+ from AimooeExt_Init import call_AimooeExt_Init
25
+ from AimooeExt_Exit import call_AimooeExt_Exit
26
+ from AimooeExt_Connect import call_AimooeExt_Connect
27
+ from AimooeExt_Connect import I_ConnectionMethod
28
+ from AimooeExt_GetDeviceType import call_AimooeExt_GetDeviceType
29
+ from Utils import DLL_PATH
30
+ print(DLL_PATH)
31
+ dll = cdll.LoadLibrary(DLL_PATH)
32
+
33
+ print(call_AimooeExt_Init(dll))
34
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
35
+
36
+ ret, address = call_AimooeExt_GetPhysicalAddress(dll)
37
+ print(ret, address)
38
+
39
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,112 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+ import os
4
+ import json
5
+
6
+ try:
7
+ from .AimooeExt_Connect import I_ConnectionMethod
8
+ except:
9
+ from AimooeExt_Connect import I_ConnectionMethod
10
+
11
+ def has_non_ascii(s: str) -> bool:
12
+ for char in s:
13
+ if ord(char) > 127 or ord(char) < 0:
14
+ return True
15
+ return False
16
+
17
+ def call_AimooeExt_GetSpecificToolInfo(
18
+ dll: ctypes.CDLL,
19
+ EI: I_ConnectionMethod,
20
+ toolpath: str,
21
+ toolname_list: list[str],
22
+ path_encoding="utf-8"
23
+ ) -> tuple[int, dict]:
24
+ str_max_len = 65536
25
+
26
+ if not os.path.isdir(toolpath):
27
+ raise FileNotFoundError("{toolpath} is not an available path.")
28
+
29
+ if has_non_ascii(toolpath):
30
+ raise ValueError(f"path {toolpath} has non ascii character.")
31
+
32
+ if not toolpath.endswith(os.sep):
33
+ toolpath += os.sep
34
+
35
+ # Define function prototype
36
+ AimooeExt_GetSpecificToolInfo = dll.AimooeExt_GetSpecificToolInfo
37
+ AimooeExt_GetSpecificToolInfo.argtypes = [
38
+ ctypes.c_int,
39
+ ctypes.c_char_p,
40
+ ctypes.c_char_p,
41
+ ctypes.c_char_p,
42
+ ctypes.c_int
43
+ ]
44
+
45
+ # 返回类型用 None
46
+ AimooeExt_GetSpecificToolInfo.restype = None
47
+
48
+ # Convert Python strings to C-style bytes
49
+ toolpath_c = toolpath.encode(path_encoding)
50
+ toolname_list_c = "$".join(toolname_list).encode(path_encoding)
51
+
52
+ while True:
53
+ # Allocate buffer to receive string
54
+ store_buffer = ctypes.create_string_buffer(str_max_len)
55
+
56
+ # Execute the function (void 无返回值)
57
+ AimooeExt_GetSpecificToolInfo(
58
+ EI.value,
59
+ toolpath_c,
60
+ toolname_list_c,
61
+ store_buffer,
62
+ str_max_len
63
+ )
64
+
65
+ # 按照你库的规则,默认调用成功 result=1
66
+ result = 1
67
+
68
+ # Convert buffer to Python string
69
+ info_str = store_buffer.value.decode('utf-8', errors='ignore')
70
+
71
+ # Check if string ends with $ (end marker)
72
+ if info_str.rstrip().endswith("$"):
73
+ break
74
+
75
+ # Double buffer size if not complete
76
+ str_max_len <<= 1
77
+
78
+ # Erase $ at the end
79
+ if info_str.rstrip().endswith("$"):
80
+ info_str = info_str.rstrip()[:-1]
81
+
82
+ # Can not find '$', failed.
83
+ else:
84
+ return 0, dict()
85
+
86
+ # Get Dict
87
+ dict_data = json.loads(info_str)
88
+ return int(result), dict_data
89
+
90
+ if __name__ == "__main__":
91
+ from AimooeExt_Init import call_AimooeExt_Init
92
+ from AimooeExt_Exit import call_AimooeExt_Exit
93
+ from AimooeExt_Connect import call_AimooeExt_Connect
94
+ from AimooeExt_Connect import I_ConnectionMethod
95
+ from Utils import DLL_PATH, TOOL_SAMPLE_DIR
96
+ print(DLL_PATH)
97
+ dll = cdll.LoadLibrary(DLL_PATH)
98
+
99
+ print(call_AimooeExt_Init(dll))
100
+ print(call_AimooeExt_Connect(dll, I_ConnectionMethod.I_USB))
101
+
102
+ # 调用示例
103
+ ret, info = call_AimooeExt_GetSpecificToolInfo(
104
+ dll,
105
+ EI=I_ConnectionMethod.I_USB,
106
+ toolpath=os.path.relpath(TOOL_SAMPLE_DIR, os.getcwd()),
107
+ toolname_list=["BONE-1"]
108
+ )
109
+ print(ret)
110
+ print(info)
111
+
112
+ print(call_AimooeExt_Exit(dll))
@@ -0,0 +1,18 @@
1
+ import ctypes
2
+ from ctypes import cdll
3
+
4
+ def call_AimooeExt_Init(dll:ctypes.CDLL) -> int:
5
+
6
+ # Define function prototype
7
+ AimooeExt_Init = dll.AimooeExt_Init
8
+ AimooeExt_Init.restype = ctypes.c_int # Return type: int
9
+
10
+ # Execute the function
11
+ result = AimooeExt_Init()
12
+ return int(result)
13
+
14
+ if __name__ == "__main__":
15
+ from Utils import DLL_PATH
16
+ print(DLL_PATH)
17
+ dll = cdll.LoadLibrary(DLL_PATH)
18
+ print(call_AimooeExt_Init(dll))
@@ -0,0 +1,18 @@
1
+ import os
2
+ import sys
3
+ import platform
4
+
5
+ DIRNOW = os.path.dirname(os.path.abspath(__file__))
6
+ BIN_DIR = os.path.join(DIRNOW, "bin")
7
+ DLL_PATH = os.path.join(BIN_DIR, "AimooeExt_Interface2.3.4.dll")
8
+ TOOL_SAMPLE_DIR = os.path.join(DIRNOW, "AimToolsSample")
9
+
10
+ if not os.path.isfile(DLL_PATH):
11
+ raise FileNotFoundError("py_aimooe_simple_interface: dll not found.")
12
+
13
+ # Check if the system and ISA is windows and x86-64
14
+ def is_windows_x86_64() -> bool:
15
+ is_windows = sys.platform.startswith("win")
16
+ arch = platform.machine().lower()
17
+ is_64bit = arch in ("amd64", "x86_64", "x64")
18
+ return is_windows and is_64bit
@@ -0,0 +1,25 @@
1
+ from .AimooeExt_Connect import call_AimooeExt_Connect, I_ConnectionMethod
2
+ from .AimooeExt_Exit import call_AimooeExt_Exit
3
+ from .AimooeExt_GetDeviceType import call_AimooeExt_GetDeviceType
4
+ from .AimooeExt_GetDiscretePoints import call_AimooeExt_GetDiscretePoints
5
+ from .AimooeExt_GetIpAddress import call_AimooeExt_GetIpAddress
6
+ from .AimooeExt_GetManufactureInfo import call_AimooeExt_GetManufactureInfo
7
+ from .AimooeExt_GetPhysicalAddress import call_AimooeExt_GetPhysicalAddress
8
+ from .AimooeExt_GetSpecificToolInfo import call_AimooeExt_GetSpecificToolInfo
9
+ from .AimooeExt_Init import call_AimooeExt_Init
10
+ from .Utils import DLL_PATH, is_windows_x86_64
11
+
12
+ __all__ = [
13
+ "call_AimooeExt_Connect",
14
+ "call_AimooeExt_Exit",
15
+ "call_AimooeExt_GetDeviceType",
16
+ "call_AimooeExt_GetDiscretePoints",
17
+ "call_AimooeExt_GetIpAddress",
18
+ "call_AimooeExt_GetManufactureInfo",
19
+ "call_AimooeExt_GetPhysicalAddress",
20
+ "call_AimooeExt_GetSpecificToolInfo",
21
+ "call_AimooeExt_Init",
22
+ "I_ConnectionMethod",
23
+ "DLL_PATH",
24
+ "is_windows_x86_64"
25
+ ]
@@ -0,0 +1,144 @@
1
+ from ctypes import cdll
2
+ from typing import Any, Optional
3
+ import atexit
4
+ import time
5
+
6
+ try:
7
+ from . import AimooeExt
8
+ from .AimooeExt import I_ConnectionMethod, is_windows_x86_64
9
+ except:
10
+ import AimooeExt
11
+ from AimooeExt import I_ConnectionMethod, is_windows_x86_64
12
+
13
+ class AimooeExtDrive:
14
+ _instance = None
15
+
16
+ @classmethod
17
+ def __new__(cls, *args, **kwargs):
18
+ if cls._instance is None:
19
+ self = super().__new__(cls)
20
+ cls._instance = self
21
+ return cls._instance
22
+
23
+ def __init__(self) -> None:
24
+ if not is_windows_x86_64():
25
+ raise OSError("Only amd64 and windows system are supported.")
26
+
27
+ # Do not initialize twice
28
+ if hasattr(self, "_connect_method"):
29
+ return
30
+ self._connect_method = None
31
+ self._dll = cdll.LoadLibrary(AimooeExt.DLL_PATH)
32
+
33
+ # Try to initialize
34
+ ret = AimooeExt.call_AimooeExt_Init(self._dll)
35
+ if ret != 1:
36
+ raise RuntimeError("Can not initialize.")
37
+
38
+ def get_connect_method(self) -> Optional[AimooeExt.I_ConnectionMethod]:
39
+ return self._connect_method
40
+
41
+ # The same with connect
42
+ def reconnect(self, _connect_method:AimooeExt.I_ConnectionMethod, _ip_addr:Optional[str]=None):
43
+ self.connect(_connect_method, _ip_addr)
44
+
45
+ def connect(self, _connect_method:AimooeExt.I_ConnectionMethod, _ip_addr:Optional[str]=None):
46
+ if self._connect_method is not None:
47
+ self.disconnect()
48
+
49
+ # Do clean up when exit
50
+ atexit.register(self._clean_up)
51
+
52
+ # _ip_addr must given when I_ETHERNET
53
+ self._connect_method = _connect_method
54
+ self._ip_addr = _ip_addr
55
+ if self._connect_method == I_ConnectionMethod.I_ETHERNET:
56
+ if self._ip_addr is None:
57
+ raise ValueError("")
58
+
59
+ # unpack _ip_addr
60
+ ipa, ipb, ipc, ipd = 192, 168, 31, 10
61
+ if self._ip_addr is not None:
62
+ ipa, ipb, ipc, ipd = map(int, self._ip_addr.split("."))
63
+
64
+ ret = AimooeExt.call_AimooeExt_Connect(
65
+ self._dll, self._connect_method, ipa, ipb, ipc, ipd)
66
+
67
+ if ret != 1:
68
+ self._connect_method = None
69
+ raise RuntimeError("Can not connect.")
70
+
71
+ # Real Exit, Do not call this manually
72
+ def _clean_up(self):
73
+ AimooeExt.call_AimooeExt_Exit(self._dll)
74
+
75
+ def disconnect(self):
76
+ self._connect_method = None
77
+
78
+ def get_device_type(self) -> str:
79
+ if self._connect_method is None:
80
+ raise RuntimeError("Connect first.")
81
+ return AimooeExt.call_AimooeExt_GetDeviceType(self._dll)
82
+
83
+ def get_ip_address(self) -> str:
84
+ if self._connect_method is None:
85
+ raise RuntimeError("Connect first.")
86
+ return AimooeExt.call_AimooeExt_GetIpAddress(
87
+ self._dll, self._connect_method)
88
+
89
+ def get_manufacture_info(self) -> dict[str, str]:
90
+ if self._connect_method is None:
91
+ raise RuntimeError("Connect first.")
92
+
93
+ ret, info = AimooeExt.call_AimooeExt_GetManufactureInfo(
94
+ self._dll, self._connect_method)
95
+ if ret != 1:
96
+ raise RuntimeError("Can not get info.")
97
+ return info
98
+
99
+ def get_physical_address(self) -> str:
100
+ if self._connect_method is None:
101
+ raise RuntimeError("Connect first.")
102
+ ret, info = AimooeExt.call_AimooeExt_GetPhysicalAddress(self._dll)
103
+ if ret != 1:
104
+ raise RuntimeError("Can not get address.")
105
+ return info
106
+
107
+ def get_specific_tool_info(self,
108
+ tool_path:str, tool_list:list[str], path_encoding:str="utf-8") -> dict[str, Any]:
109
+ begin_time = time.time()
110
+
111
+ if self._connect_method is None:
112
+ raise RuntimeError("Connect first.")
113
+ ret, info = AimooeExt.call_AimooeExt_GetSpecificToolInfo(
114
+ self._dll, self._connect_method, tool_path, tool_list, path_encoding)
115
+
116
+ if len(tool_list) == 0:
117
+ ret, info = AimooeExt.call_AimooeExt_GetDiscretePoints(
118
+ self._dll, self._connect_method)
119
+
120
+ if ret != 1:
121
+ raise RuntimeError("Can not get info.")
122
+
123
+ end_time = time.time()
124
+ info["_TimeCost"] = end_time - begin_time
125
+ return info
126
+
127
+ if __name__ == "__main__":
128
+ import os
129
+ DIRNOW = os.path.dirname(os.path.abspath(__file__))
130
+ drive = AimooeExtDrive()
131
+ drive.connect(I_ConnectionMethod.I_USB)
132
+
133
+ print(drive.get_connect_method())
134
+ print(drive.get_device_type())
135
+ print(drive.get_ip_address())
136
+ print(drive.get_manufacture_info())
137
+ print(drive.get_physical_address())
138
+
139
+ print(drive.get_specific_tool_info(
140
+ os.path.relpath(
141
+ os.path.join(DIRNOW, "AimooeExt", "AimToolsSample"),
142
+ os.getcwd()
143
+ ), []))
144
+ drive.disconnect()
@@ -0,0 +1,6 @@
1
+ from .AimooeExtDrive import AimooeExtDrive, I_ConnectionMethod
2
+
3
+ __all__ = [
4
+ "AimooeExtDrive",
5
+ "I_ConnectionMethod"
6
+ ]
@@ -0,0 +1,21 @@
1
+ [project]
2
+ name = "py-ap200-simple-interface"
3
+ version = "0.1.0"
4
+ description = "a simple interface package for aimooe AP-200."
5
+ authors = [
6
+ {name = "GGN_2015",email = "neko@jlulug.org"}
7
+ ]
8
+ license = {text = "MIT"}
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ ]
13
+ classifiers = [
14
+ "Operating System :: Microsoft :: Windows :: Windows 10",
15
+ "Operating System :: Microsoft :: Windows :: Windows 11"
16
+ ]
17
+ platform = "windows-x86_64"
18
+
19
+ [build-system]
20
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
21
+ build-backend = "poetry.core.masonry.api"