gravity-controller-operator 0.0.1__py3-none-any.whl
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.
- gravity_controller_operator/__init__.py +0 -0
- gravity_controller_operator/controllers/__init__.py +0 -0
- gravity_controller_operator/controllers/arm_k210.py +55 -0
- gravity_controller_operator/main.py +75 -0
- gravity_controller_operator/tests/__init__.py +0 -0
- gravity_controller_operator/tests/main_tests.py +13 -0
- gravity_controller_operator-0.0.1.dist-info/LICENSE +19 -0
- gravity_controller_operator-0.0.1.dist-info/METADATA +14 -0
- gravity_controller_operator-0.0.1.dist-info/RECORD +11 -0
- gravity_controller_operator-0.0.1.dist-info/WHEEL +5 -0
- gravity_controller_operator-0.0.1.dist-info/top_level.txt +1 -0
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from gravity_controller_operator.main import ControllerInterface
|
|
2
|
+
from pyModbusTCP.client import ModbusClient
|
|
3
|
+
from abc import abstractmethod
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ARMControllerABC(ControllerInterface):
|
|
7
|
+
controller = None
|
|
8
|
+
|
|
9
|
+
def get_phys_dict(self, *args, **kwargs):
|
|
10
|
+
""" Получить состояние входов или выходов с контроллера.
|
|
11
|
+
Перед возвратом привести в вид словаря,
|
|
12
|
+
где ключ - это номер реле или di, значение - 0 или 1.
|
|
13
|
+
"""
|
|
14
|
+
response_dict = {}
|
|
15
|
+
controller_response = self.get_controller_response()
|
|
16
|
+
for i in controller_response:
|
|
17
|
+
response_dict[controller_response.index(i)] = i
|
|
18
|
+
return response_dict
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def get_controller_response(self):
|
|
22
|
+
return []
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ARMK210ControllerDI(ARMControllerABC):
|
|
26
|
+
map_keys_amount = 8
|
|
27
|
+
starts_with = 0
|
|
28
|
+
|
|
29
|
+
def __init__(self, controller):
|
|
30
|
+
self.controller = controller
|
|
31
|
+
|
|
32
|
+
def get_controller_response(self):
|
|
33
|
+
self.controller.read_input_registers(
|
|
34
|
+
self.starts_with, self.map_keys_amount)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ARMK210ControllerRelay(ARMControllerABC):
|
|
38
|
+
map_keys_amount = 8
|
|
39
|
+
starts_with = 0
|
|
40
|
+
|
|
41
|
+
def __init__(self, controller):
|
|
42
|
+
self.controller = controller
|
|
43
|
+
|
|
44
|
+
def get_controller_response(self):
|
|
45
|
+
self.controller.read_holding_registers(
|
|
46
|
+
self.starts_with, self.map_keys_amount)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ARMK210Controller:
|
|
50
|
+
def __init__(self, ip: str, port: int = 8234, name="ARM_K210_Controller"):
|
|
51
|
+
self.controller = ModbusClient(host=ip, port=port)
|
|
52
|
+
self.relay_interface = ARMK210ControllerRelay(self.controller)
|
|
53
|
+
self.di_interface = ARMK210ControllerDI(self.controller)
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
import datetime
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ControllerSoftDict(ABC):
|
|
6
|
+
my_dict = {}
|
|
7
|
+
map_keys_amount: int = None
|
|
8
|
+
starts_with: int = 0
|
|
9
|
+
|
|
10
|
+
def init_dict(self):
|
|
11
|
+
""" Создаем словарь, где ключом будет номер реле,
|
|
12
|
+
а значением: еще один словарь с информацией о реле (состояние и тд)
|
|
13
|
+
|
|
14
|
+
:return {0: {'state': None, "changed": datetime.datetime.now()},
|
|
15
|
+
1: {...}, ...}"""
|
|
16
|
+
relays_map = {}
|
|
17
|
+
for i in range(self.map_keys_amount):
|
|
18
|
+
# Начинаем генерировать, первое значение - 0
|
|
19
|
+
if self.starts_with: # Если номер первого реле НА контроллере > 0
|
|
20
|
+
i += self.starts_with # Плюсуем номер
|
|
21
|
+
relays_map[i] = {"state": None,
|
|
22
|
+
"changed": datetime.datetime.now()}
|
|
23
|
+
return relays_map
|
|
24
|
+
|
|
25
|
+
def set_point_state_in_dict(self, num, state):
|
|
26
|
+
""" Программно задать состояние реле"""
|
|
27
|
+
self.my_dict[num]["state"] = state
|
|
28
|
+
self.my_dict[num]["changed"] = datetime.datetime.now()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ControllerPhysOperator(ABC):
|
|
32
|
+
""" В этом классе задаются функции для реального
|
|
33
|
+
взаимодействия с контроллером. На новых контроллерах нужно будет менять
|
|
34
|
+
(предопределять только эти методы),
|
|
35
|
+
потому что вся остальная логика меняться не должна,
|
|
36
|
+
меняются только способ и вид взаимодействия с контроллерами"""
|
|
37
|
+
ip = None
|
|
38
|
+
port = None
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def get_phys_dict(self, *args, **kwargs):
|
|
42
|
+
""" Получить состояние входов или выходов с контроллера.
|
|
43
|
+
Перед возвратом привести в вид словаря,
|
|
44
|
+
где ключ - это номер реле или di, значение - 0 или 1.
|
|
45
|
+
"""
|
|
46
|
+
return {}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ControllerPhysRelayOperator(ControllerPhysOperator, ABC):
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def change_phys_relay_state(self, num, state: bool):
|
|
52
|
+
""" Физически изменить состояние реле (обратиться к контроллеру) """
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ControllerInterface(ControllerSoftDict, ControllerPhysOperator, ABC):
|
|
57
|
+
""" Интерфейс для работы с контроллером.
|
|
58
|
+
В нем происходят работы и со словарем состояний и с реальными состояниями
|
|
59
|
+
физического контроллера """
|
|
60
|
+
name = None
|
|
61
|
+
|
|
62
|
+
def update_relays_map(self):
|
|
63
|
+
phys_relays_map = self.get_phys_dict()
|
|
64
|
+
if not self.my_dict:
|
|
65
|
+
return {"error": "Init relays map (init_relays_map) first!"}
|
|
66
|
+
for relay, state in phys_relays_map.items():
|
|
67
|
+
self.set_point_state_in_dict(relay, state)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class RelayControllerInterface(ControllerPhysRelayOperator,
|
|
71
|
+
ControllerInterface, ABC):
|
|
72
|
+
def change_relay_state(self, num: int, state: bool):
|
|
73
|
+
""" Изменить состояние реле"""
|
|
74
|
+
self.set_point_state_in_dict(num, state)
|
|
75
|
+
return self.change_phys_relay_state(num, state)
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from gravity_controller_operator.controllers.arm_k210 import ARMK210Controller
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestCase(unittest.TestCase):
|
|
6
|
+
def test_relay_controller(self):
|
|
7
|
+
controller = ARMK210Controller(ip="localhost")
|
|
8
|
+
state = controller.relay_interface.get_phys_dict()
|
|
9
|
+
print(state)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
unittest.main()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: gravity-controller-operator
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Author: PunchyArchy
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Dist: pyModbusTCP
|
|
7
|
+
|
|
8
|
+
Gravity Interface (TK) - написанный на tkinter графический интерфейс, служащий для взаимодействия весовщика
|
|
9
|
+
и Gravity Core.
|
|
10
|
+
|
|
11
|
+
v 0.2.4
|
|
12
|
+
- Иконка версии в углу
|
|
13
|
+
- ar_ip, ar_port, mirrored передаются как аргументы при запуске приложения
|
|
14
|
+
- добавлен cmadb (блокировка дублей)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
gravity_controller_operator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
gravity_controller_operator/main.py,sha256=0dE1Gp4PJvJxA7CrwOOeldPpyyaumCXXQXjCH385-ic,3544
|
|
3
|
+
gravity_controller_operator/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
gravity_controller_operator/controllers/arm_k210.py,sha256=ger4hhj2sIryDAwcUbBzX_amiKp3R7rVZGw0KenCs9Y,1816
|
|
5
|
+
gravity_controller_operator/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
gravity_controller_operator/tests/main_tests.py,sha256=fquSrkegD0X8X-KRlmnQch1H-4q5vyfxucyr10wkiTQ,366
|
|
7
|
+
gravity_controller_operator-0.0.1.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
|
8
|
+
gravity_controller_operator-0.0.1.dist-info/METADATA,sha256=jXyDbtYWZDtIVNxWBm1s-hjzA9xcSkpJgZW5-Cwx_2s,573
|
|
9
|
+
gravity_controller_operator-0.0.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
10
|
+
gravity_controller_operator-0.0.1.dist-info/top_level.txt,sha256=krapbz1cEDGquDJf0DnoTbnybUwi7J_8OgoIumEc0OM,28
|
|
11
|
+
gravity_controller_operator-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gravity_controller_operator
|