-
-
Notifications
You must be signed in to change notification settings - Fork 723
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by pedrobaeza
- Loading branch information
Showing
11 changed files
with
724 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../stock_vlm_mgmt_kardex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import setuptools | ||
|
||
setuptools.setup( | ||
setup_requires=['setuptools-odoo'], | ||
odoo_addon=True, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
====================================== | ||
Kardex integration with stock_vlm_mgmt | ||
====================================== | ||
|
||
.. | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! source digest: sha256:cd51efe55ae6d7d00483d20033cb98572c7c06b4755e5b15ccdbe1077187f31f | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png | ||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
:alt: License: AGPL-3 | ||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github | ||
:target: https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_vlm_mgmt_kardex | ||
:alt: OCA/stock-logistics-warehouse | ||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-16-0/stock-logistics-warehouse-16-0-stock_vlm_mgmt_kardex | ||
:alt: Translate me on Weblate | ||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png | ||
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=16.0 | ||
:alt: Try me on Runboat | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
Integration with Kardex VLMs | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us to smash it by providing a detailed and welcomed | ||
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_vlm_mgmt_kardex%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
~~~~~~~ | ||
|
||
* Tecnativa | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* `Tecnativa <https://www.tecnativa.com>`_: | ||
|
||
* David Vidal | ||
|
||
Maintainers | ||
~~~~~~~~~~~ | ||
|
||
This module is maintained by the OCA. | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. | ||
|
||
.. |maintainer-chienandalu| image:: https://github.com/chienandalu.png?size=40px | ||
:target: https://github.com/chienandalu | ||
:alt: chienandalu | ||
|
||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__: | ||
|
||
|maintainer-chienandalu| | ||
|
||
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_vlm_mgmt_kardex>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Copyright 2023 Tecnativa - David Vidal | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
{ | ||
"name": "Kardex integration with stock_vlm_mgmt", | ||
"summary": "Light alternative for Kardex VLM integrations", | ||
"version": "16.0.1.0.0", | ||
"author": "Tecnativa, Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/stock-logistics-warehouse", | ||
"maintainers": ["chienandalu"], | ||
"license": "AGPL-3", | ||
"category": "Stock", | ||
"depends": ["stock_vlm_mgmt"], | ||
"data": [], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import stock_location | ||
from . import kardex_request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
# Copyright 2022 Tecnativa - David Vidal | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
import logging | ||
import socket | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
KARDEX_KEYS = [ | ||
"task_type", | ||
"task_id", | ||
"address", | ||
"carrier", | ||
"pos_x", | ||
"pos_y", | ||
"qty", | ||
"info1", | ||
"info2", | ||
"info3", | ||
"info4", | ||
] | ||
|
||
|
||
KARDEX_OPERATION_CODES = { | ||
"release": "0", | ||
"put": "3", | ||
"get": "4", | ||
"count": "5", | ||
} | ||
|
||
|
||
class KardexRequest: | ||
""" | ||
Interface to Kardex SVMs | ||
To command tasks we send a tcp message to the SVM with this format | ||
TASK_TYPE;TASK_ID;ADDRESS;CARRIER;POS_X;POS_Y;QTY;INFO1;INFO2;INFO3;INFO4<CR><LF> | ||
Each task is enqueued in the SVM and every time it gets finished it returns a | ||
response with a success or error code (0 or 101). | ||
- TASK_TYPE is configured at the machine itself. | ||
- TASK_ID would be a unique id we give to the task so we can identify it when | ||
the JMIF server responds back. | ||
- ADDRESS: Which device to call. | ||
- CARRIER: The tray we want to call | ||
- POSX, POSY: Show the user where the items are located inside the tray | ||
- QTY: How many items to get from the SVM | ||
- The INFO fields are optional to show the user usefull info for the pick. | ||
An example call: | ||
3;001;21;6;7;1;40;PICK002;MAT02;Capacitor 40 mV;Check they're ok<CR><LF> | ||
The message will get to the SVM screen. When the user finishes, the SVM will respond | ||
back with a success message. Notice that in this response, the quantity has been | ||
changed by the user: | ||
0;001;21;6;7;1;25;PICK002;MAT02;Capacitor 40 mV;Check they're ok<CR><LF> | ||
If there'd be an error in the process we'd get an error: | ||
101;001;21;6;7;1;40;PICK002;MAT02;Capacitor 40 mV;Check they're ok<CR><LF> | ||
If we want to release the carriers, we can call the carrier 0 | ||
0;465;21;0;0;0;0;;;;<CR><LF> | ||
""" | ||
|
||
def __init__(self, ip, port, timeout=0, **options): | ||
self.ip = ip | ||
self.port = int(port) | ||
self.timeout = timeout | ||
self.ignore_response = options.get("ignore_response") | ||
|
||
def parse_data(self, data): | ||
"""Transforms csv single string into a dictionary that we can work with. | ||
@param {string} data: semicolon separated values for the kardex payload format | ||
@return {dict} those csv values transformed into key value pairs | ||
""" | ||
parsed_data = dict.fromkeys(KARDEX_KEYS, None) | ||
try: | ||
parsed_data.update({k: v for k, v in zip(KARDEX_KEYS, data.split(";"))}) | ||
except Exception: | ||
_logger.debug(f"Exception parsing data: {data}") | ||
if parsed_data.get("qty"): | ||
# Strip dots | ||
parsed_data["qty"] = parsed_data["qty"].replace(".", "") | ||
return parsed_data | ||
|
||
def prepare_data(self, data): | ||
"""Transforms data dict into kardex csv data string | ||
@param {dict} data | ||
@return {string} | ||
""" | ||
# No support for floats :S | ||
data["qty"] = int(float(data["qty"])) | ||
values = [str(v) for v in data.values()] | ||
return f"{';'.join(values)}\r\n" | ||
|
||
def request_operation(self, data): | ||
""" | ||
@param {string|dict} we can handle either a dictionary with the KARDEX_KEYS | ||
format or the csv formatted values in a string (it must end in \r\n) | ||
@return {dict} with the reponse of the device on the matching task | ||
""" | ||
if isinstance(data, dict): | ||
# We receive the task type with a common code. Transform into the Kardex one | ||
data["task_type"] = KARDEX_OPERATION_CODES.get(data["task_type"], "0") | ||
data = self.prepare_data(data) | ||
_logger.info(f"Request: {data}") | ||
operation_id = self.parse_data(data).get("task_id") | ||
if not operation_id: | ||
return | ||
data = data.encode("utf-8") | ||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as device: | ||
try: | ||
device.connect((self.ip, self.port)) | ||
except ConnectionRefusedError: | ||
return {"code": "-1", "task_id": operation_id} | ||
device.sendall(data) | ||
# Open the request with the optional timeout so the thread isn't halted | ||
# forever | ||
if self.timeout: | ||
device.settimeout(self.timeout) | ||
# Default response | ||
response = {"code": "0", "task_id": operation_id} | ||
# TODO: This is uncomplete: when we do the request, we won't receive the | ||
# response until the VLM user validates the operation from the device screen | ||
# That's an unknown amount of time. | ||
# And what if the system is reset in the meantime? We'd loose the original | ||
# thread and the response would be missed. | ||
# I guess that's why the c2c module has that proxy thing, so they can be | ||
# more resilient on that regard or at least to not block the thread waiting | ||
# for a response. | ||
while True and not self.ignore_response: | ||
# TBE: Will this response window be enough to get it in one shot? | ||
try: | ||
res = device.recv(1024).decode("utf-8") | ||
_logger.info(res) | ||
except socket.timeout: | ||
response["code"] = "-3" | ||
return response | ||
response = self.parse_data(res) | ||
# Deal with response codes. Default to unkown issue code | ||
response["code"] = response.get("task_type", "-999") | ||
# Code 101 for an issue that happens in the VLM hardware itself | ||
if response["code"] == "101": | ||
response["code"] = "-4" | ||
# Task cancelled | ||
if response["code"] == "107": | ||
response["code"] = "-5" | ||
# If it's not our operation we should keep trying | ||
# TBE: But until when? This locks the current thread so the screen | ||
# is indeed locked and the user can't do virtually anything about it | ||
if response["task_id"] == operation_id: | ||
break | ||
if response["task_id"] is None: | ||
# Empty response. Unknow reason error. Could be due to a shutdown | ||
# of the JMIF service. | ||
return {"code": "-2", "task_id": operation_id} | ||
_logger.info(f"Response: {response}") | ||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright 2023 Tecnativa - David Vidal | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
from odoo import fields, models | ||
|
||
from .kardex_request import KardexRequest | ||
|
||
|
||
class StockLocation(models.Model): | ||
_inherit = "stock.location" | ||
|
||
vlm_vendor = fields.Selection( | ||
selection_add=[ | ||
("kardex", "Kardex"), | ||
], | ||
) | ||
|
||
def _kardex_vlm_connector(self) -> KardexRequest: | ||
"""Wildcarded method to return our vendor specific connector""" | ||
return KardexRequest | ||
|
||
def send_vlm_request(self, data, **options): | ||
"""The tray call in Kardex doesn't return anything, so we can release the | ||
thread immediately""" | ||
if self.vlm_vendor == "kardex" and self.env.context.get("vlm_tray_call"): | ||
options["ignore_response"] = True | ||
return super().send_vlm_request(data, **options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* `Tecnativa <https://www.tecnativa.com>`_: | ||
|
||
* David Vidal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Integration with Kardex VLMs |
Oops, something went wrong.