Add release (close) of vertical lift trays

* Rename methods that fetch a tray to prevent confusion
* Add methods to release a tray
* The Kardex method to fetch a tray has to send "0" in the carrier and
  carrierNext field
* The pick and inventory screens release the tray only when there is no next
  line, because the release is implicit when we fetch the next line,
  the put screen releases everytime because the operator may take time
  to start the next line and we don't know if they are going to scan a
  next line or not.
* Exiting the screen or switching screen between put/pick/put-away has
  to release the tray as well.
This commit is contained in:
Guewen Baconnier
2020-07-21 09:26:12 +02:00
committed by Dũng (Trần Đình)
parent 2592d97823
commit b76cabdc87
2 changed files with 74 additions and 22 deletions

View File

@@ -11,25 +11,13 @@ _logger = logging.getLogger(__name__)
class StockLocation(models.Model):
_inherit = "stock.location"
def _hardware_kardex_prepare_payload(self, cell_location=None):
def _hardware_kardex_prepare_fetch_payload(self, cell_location=None):
if self.level is False:
raise exceptions.UserError(
_("Shuttle tray %s has no level. " "Please fix the configuration")
% self.display_name
)
message_template = (
"{code}|{hostId}|{addr}|{carrier}|{carrierNext}|"
"{x}|{y}|{boxType}|{Q}|{order}|{part}|{desc}|\r\n"
)
shuttle = self.vertical_lift_shuttle_id
if shuttle.mode == "pick":
code = "1"
elif shuttle.mode == "put":
code = "2"
elif shuttle.mode == "inventory":
code = "5"
else:
code = "61" # ping
if cell_location:
x, y = cell_location.tray_cell_center_position()
if x == 0 and y == 0:
@@ -45,7 +33,7 @@ class StockLocation(models.Model):
else:
x, y = "", ""
subst = {
"code": code,
"code": shuttle._kardex_shuttle_code(),
"hostId": self.env["ir.sequence"].next_by_code("vertical.lift.command"),
# hard code the gate for now.
# TODO proper handling of multiple gates for 1 lift.
@@ -60,11 +48,10 @@ class StockLocation(models.Model):
"part": "",
"desc": "",
}
payload = message_template.format(**subst)
return payload.encode("iso-8859-1", "replace")
return shuttle._hardware_kardex_format_template(subst)
def _hardware_vertical_lift_tray_payload(self, cell_location=None):
"""Prepare the message to be sent to the vertical lift hardware
def _hardware_vertical_lift_fetch_tray_payload(self, cell_location=None):
"""Prepare "fetch" message to be sent to the vertical lift hardware
Private method, this is where the implementation actually happens.
Addons can add their instructions based on the hardware used for
@@ -100,11 +87,12 @@ class StockLocation(models.Model):
highlighting the cell using a laser pointer.
"""
if self.vertical_lift_shuttle_id.hardware == "kardex":
payload = self._hardware_kardex_prepare_payload(cell_location=cell_location)
_logger.debug("Sending to kardex: {}", payload)
# TODO implement the communication with kardex
payload = self._hardware_kardex_prepare_fetch_payload(
cell_location=cell_location
)
_logger.debug("Sending to kardex (fetch): {}", payload)
else:
payload = super()._hardware_vertical_lift_tray_payload(
payload = super()._hardware_vertical_lift_fetch_tray_payload(
cell_location=cell_location
)
return payload

View File

@@ -1,8 +1,13 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import models
_logger = logging.getLogger(__name__)
JMIF_STATUS = {
0: "success",
101: "common error",
@@ -29,6 +34,65 @@ class VerticalLiftShuttle(models.Model):
values += [("kardex", "Kardex")]
return values
_kardex_message_template = (
"{code}|{hostId}|{addr}|{carrier}|{carrierNext}|"
"{x}|{y}|{boxType}|{Q}|{order}|{part}|{desc}|\r\n"
)
def _hardware_kardex_format_template(self, values):
payload = self._kardex_message_template.format(**values)
return payload.encode("iso-8859-1", "replace")
def _kardex_shuttle_code(self):
mapping = {"pick": "1", "put": "2", "inventory": "5"}
ping = "61"
return mapping.get(self.mode, ping)
def _hardware_kardex_prepare_release_payload(self):
subst = {
"code": self._kardex_shuttle_code(),
"hostId": self.env["ir.sequence"].next_by_code("vertical.lift.command"),
# hard code the gate for now.
"addr": self.name + "-1",
"carrier": "0",
"carrierNext": "0",
"x": "0",
"y": "0",
"boxType": "",
"Q": "",
"order": "",
"part": "",
"desc": "",
}
return self._hardware_kardex_format_template(subst)
def _hardware_vertical_lift_release_tray_payload(self):
"""Prepare "release" message to be sent to the vertical lift hardware
Private method, this is where the implementation actually happens.
Addons can add their instructions based on the hardware used for
this location.
The hardware used for a location can be found in:
``self.vertical_lift_shuttle_id.hardware``
Each addon can implement its own mechanism depending of this value
and must call ``super``.
The method must send the command to the vertical lift to release (close)
the tray.
Returns a message in bytes, that will be sent through
``VerticalLiftShuttle._hardware_send_message()``.
"""
if self.hardware == "kardex":
payload = self._hardware_kardex_prepare_release_payload()
_logger.debug("Sending to kardex (release): {}", payload)
else:
payload = super()._hardware_vertical_lift_release_tray_payload()
return payload
def _check_server_response(self, command):
response = command.answer
code, sep, remaining = response.partition("|")