Files
storage_fresco/storage.py

1357 lines
53 KiB
Python
Executable File

#!/usr/bin/env python2.6
#-*- coding: utf-8 -*-
__author__ = "Daniel Egger, Michael Rest"
__date__ = "22 March 2002"
__email__ = "egger@interearth.com, michi@rosstein.de"
__version__ = "$Revision: 1.2 $"[11:-2]
import sys, os
from ConfigParser import *
from log import strlog
from maillog import *
from cr_tpdu import CR_TPDU
from dt_tpdu import DT_TPDU
import pdb
from LEBE_tel import TEL_LEBE
from TAUF_tel import TEL_TAUF
import decode
import tel_decode
import tpdu
import tpkt
from DB import DB
from socket import *
from select import select
from time import time
from datetime import datetime
from locations import *
from IPKT import IPKT
from SCLS import SCLS
from TQUI import TQUI
STATE_CLOSED = 0 # Nothing happened yet
STATE_CONNECTED = 1 # Client connected and we're ready to serve
STATE_REQUESTPENDING = 2 # We're ready to establish an ISO connection
STATE_ESTABLISHED = 3 # ISO connection established
CONN_NEW = 0 # New connection not assigned to Comm. Channel
CONN_ASSIGNED = 1 # Connection is assigned to an Comm. Channel
#Reservation at ipoint
prioexp = 0
prioexp2= 0
def acknowledge (packet):
from cc_tpdu import CC_TPDU
reply = CC_TPDU (packet.srctsap (), packet.dsttsap (), srcref=packet.dstref + 1, dstref=packet.srcref)
_tpkt = tpkt.TPKT (len (reply) + 1)
return `_tpkt` + `reply`
def con_request (loc_TSAP, rem_TSAP):
_tpdu = CR_TPDU (loc_TSAP, rem_TSAP, srcref=0x0015)
_tpkt = tpkt.TPKT (len (_tpdu) + 1)
return `_tpkt`+`_tpdu`
def doublechar (value):
if len (value) == 1:
return '0' + value
elif len (value) > 2:
return value [len (value) -2: len (value)]
return value
def fillchar (value, l):
if len (value.rstrip()) < l:
_retval = ''
for i in range (0, l - len (value.rstrip())):
_retval += '0'
return _retval + value.rstrip()
return value
class ISOServer (IPKT, SCLS, TQUI):
def __init__ (self, *dummy, **args):
"""
Initialise a new server object: Open the socket, bind to it
and listen. This will NOT handle incomming connections.
Possible variable parameters are:
port: the port to listen on (default: 102)
address: the address to listen on (default: '' i.e. any)
verbose: if true be anal about anything (default: 0)
"""
self.connections = {}
self.parameter = {}
self.sockets = {}
# Parameter action
self.address = args.get ("address", '')
port = args.get ("port", 102)
self.verbose = args.get ("verbose", 0)
self.setdebug = args.get ("debug", 0)
#Later Articlebase wil be received via SOAP
self.articlemaster = {}
# ('article') : ['caption', 'ammountunit','normweight', 'weightunit', 'normammount', 'RLZ', 'zone', 'weightcheck', 'lottype'],
# '12345' : ['Testartikel', 'ST','1.0', 'KG', '1', '1', '1', '0', '0'],
# '23456' : ['Testartikel2', 'ST','1.0', 'KG', '1', '1', '1', '0', '0']}
self.lastsweep = time ()
self.lasterpsweep = 0
self.lastarticleupdate = time ()
self.lastordersweep = 0
self.lastordermovesweep = 0
self.lastodredelsweep = 0
self.listener_socket = socket (AF_INET, SOCK_STREAM)
self.listener_socket.setsockopt (SOL_SOCKET, SO_REUSEADDR, 1)
self.sockets[('listener', '102')] = (self.listener_socket, STATE_CLOSED)
while 1:
try:
self.listener_socket.bind ((self.address, port))
except error, msg:
self.message (0, "ISOServer Bind Socket error %d %s, Started as root?" % (msg[0], msg[1]))
sys.exit (0)
else:
break
self.listener_socket.listen (1)
self.sockets['listener', '102'] = (self.listener_socket, STATE_CONNECTED)
self.message (1, "Initialized serversocket")
def message (self, level, msg):
"""
Print message if in verbose mode.
"""
if self.verbose >= level:
dt = datetime.now ()
print ("%4d-%02d-%02d %02d:%02d:%02d.%06d:" %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond)),
print msg
def log (self, msg):
"""
Log message
also print if in verbose mode.
"""
lager = self.connections['client']
file = open ("/var/log/lvr/" + os.getcwd().split('/')[-1] + '-' + lager, "a")
dt = datetime.now ()
file.write ("%4d-%02d-%02d %02d:%02d:%02d.%06d: %s\n" %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, msg))
self.message (1, msg)
file.close ()
def debug (self):
"""
Debuging
"""
if self.setdebug:
pdb.set_trace()
def add_client (self, client_id, parameter, DB_con, DB_ERP = None, Ordering = None):
"""
Add a Client to connections.dict
"""
if 'client' in self.connections:
self.message (1,"Client already exists")
raise Warning, "Client already exists"
self.message (0, "Added Client Storage")
self.connections['client'] = client_id
#Connectionditcs
self.connections['ISO'] = {}
#Sendqueue
self.connections['Queue'] = []
self.connections['LastBeat'] = time ()
#Databasees
self.connections['DB'] = DB_con
DB_con.setloggingmethods (self.log, self.message)
self.connections['DB_ERP'] = DB_ERP
#Ordering
self.connections['Ordering'] = Ordering
#Parameter came from config file
self.parameter = parameter
self.parameter.update (DB_con.getphysics ())
#Articlemaster
self.articlemaster.update (DB_con.getarticlemaster ())
#Transportmatrx
self.transportmatrix = {}
self.transportmatrix['dstbysrc'] = DB_con.gettransportmatrix_dstbysrc ()
self.transportmatrix['srcbydst'] = DB_con.gettransportmatrix_srcbydst ()
self.transportmatrix['errordst'] = DB_con.geterrordstbyposition ()
DB_con.checktransportmatrix (self.parameter, self.transportmatrix['dstbysrc'], DB_con.getstoragedict ())
def add_conn (self, loc_TSAP, rem_TSAP, mode = "passive"):
"""
Add a passive ISO connetion to connections.dict
"""
if mode not in ["passive", "active"]:
print "ISO Connection mode is not valid"
raise Warning
if 'client' not in self.connections:
self.message (1, "Client doesn't exist")
raise Warning, "Client doesnt't exist"
if (loc_TSAP, rem_TSAP) in self.connections['ISO']:
self.message (1, "Connection " + loc_TSAP + "-" + rem_TSAP + " already exists")
raise Warning, "Connection " + loc_TSAP + "-" + rem_TSAP + " already exists"
self.message (1, "Connection : " + loc_TSAP + "-" + rem_TSAP + " added " + mode)
#Socket , Counter, Mode
self.connections['ISO'][(loc_TSAP, rem_TSAP)] = [None, 0, mode]
def makeactiveisoconnection (self, loc_TSAP, rem_TSAP):
"""
Create a new active connection and place it in the connectionslist
possibly overwriting dead connections.
"""
# Loop until we successfuly managed to get a new connection
#while 1:
try:
self.message (2, "(Re-)open Socket to %s" % self.connections['client'])
s = socket (AF_INET, SOCK_STREAM)
s.connect ((self.connections['client'], 102))
self.connections['ISO'][(loc_TSAP, rem_TSAP)] = [s, 0, "active"]
return s
except:
self.message (1, "Couldn't open active socket to %s;" % self.connections['client'])
return None
def dt_handler (self, packet, client_id, source = ''):
"""
Handler for data telegrams
"""
self.message (3,'DT_handler : data packet Len %d "%s"' % (len(packet.data), packet.data[2:]))
self.message (3,'DT_handler : data packet Type %s' % (packet.data[6:10]))
ret_val = tel_decode.decodetelegram (packet.data)
teltype = ret_val['type']
key2 = teltype
if teltype == 'LEBE':
# Nothing to do any further with LEBE telegramms
# FIXME
count = ret_val['nr']
self.message (2,' DT_handler : LEBE Tel. Counter %d' % (count))
return 0
DB_con = self.connections['DB']
DB_ERP_con = self.connections['DB_ERP']
# Do counter checking if a valid telegram arrived
count_old = self.connections['ISO'][(teltype, key2)][1]
#if 'nr' in ret_val: FixMe add method to Telegram
if ret_val.has_key ('nr'):
count = ret_val['nr']
self.message (2,' DT_handler : Tel. Counter old %d new %d' % (count_old, count))
if ret_val ['type'] == "TAUF":
# Transport Telegram (only Quit) --> check and clear Transport from DB
_quit = -1 # block quit telegram
if not (count_old == count):
self.message (2, "DT_hander : TAUF Quit -> Nr inconsistence")
# FIXME repeat TAUF ??
self.message (1, " DT_handler : Taufquit inconssistence because of restart OK")
self.message (3, " DT_handler : TAUF Quit was: %s" %ret_val['state'])
# All right, received positive feedback
if ret_val['state'] == 0:
self.log ( " DT_handler positive TAUF Quit received %d" % (self.connections['ISO'][('TAUF' , 'TAUF')][1]))
self.connections['ISO'][('TAUF' , 'TAUF')][1] = (self.connections['ISO'][('TAUF' , 'TAUF')][1] % 32767) + 1
# Not so good, there was a problem
else:
self.log ( "Negative TAUF QUI received %d state %d" % (self.connections['ISO'][('TAUF' , 'TAUF')][1], ret_val['state']))
if ret_val['state'] == 20:
self.message (2, " DT_handler : TAUF Neg. Quit -->> Tel. Source invalid")
elif ret_val['state'] == 30:
self.message (2, " DT_handler : TAUF Neg. Quit -->> Tel. Destination invalid")
elif ret_val['state'] in range (51, 55):
self.message (2, " DT_handler : TAUF Neg.Quit -->> RFZ%d occupied " % (ret_val['state'] -50))
DB_con.setsenttransportnew ('RFZ%d' % (ret_val['state'] - 50), dummysrc = self.dummysrc)
elif ret_val['state'] == 97:
self.message (2, " DT_handler : TAUF Neg.Quit -->> Tel. length wrong")
elif ret_val['state'] == 98:
self.message (2, " DT_handler : TAUF Neg.Quit -->> Wrong Type ??")
elif ret_val['state'] == 99:
# Counter Error
self.message (2, " DT_handler : TAUF Counter errror -> reset and init tel")
self.connections['ISO'][('TAUF' , 'TAUF')][1] = 0
#============================================================================================
elif (count == 0):
self.log (' DT_handler : Tel counter 0 Synchronisation Tel accept')
_quit = 0
elif (count == count_old):
self.log ( "DT_handler : FixMe Repeated telegram %d" % (count))
_quit = 0
elif (count == (count_old % 32767) + 1) or (count == -1):
#Other Telegram received
self.message (3, " DT_handler Valid telegram counter %d" % (count))
_quit = ret_val['check']
if _quit == 0:
self.message (2,' DT_handler : Telegram specific header check passed ')
#============================================================================================
#IKT Telegrams - handled external
if (count <> -1) and ret_val ['type'] == "IPKT":
# IPKT Telegram --> reserve Box in Inquee
self.log ( "IPKT for Pos '%(location)s' box '%(box_nr)s' article '%(article)s' lotnr '%(lotnr)s' lotnr2 '%(lotnr2)s' gtin '%(gtin)s' pieces '%(pieces)s' with destination '%(destination)d'" \
% ret_val)
#Dest LVR and EXOT Create TAUFs for IPKT and RFZ1
_quit = self.ipkt (ret_val)
self.log ( "IPKT Quit is %d" % _quit)
#elif ret_val ['destination'] in range (1, 9):
#self.createtauf (ret_val ['box_nr'], 'IPKT', 'IPKT', 0, 0, 0, 'Puffer', 8, 0, 0)
#self.generatetransport ('IPKT', ret_val ['box_nr'])
#DB_con.deletetauf ('IPKT', int (ret_val ['box_nr']))
#FIXME Plausibility Check
#============================================================================================
#Scannerreads - handled external
elif (count <> -1) and ret_val ['type'] == "SCLS":
_quit = self.scls (ret_val)
#============================================================================================
#Transport results - handled external
elif ret_val ['type'] == "TQUI":
_quit = self.tqui (ret_val)
#============================================================================================
else:
self.message (2, ' DT_handler : Undefined Telegram or Counter')
_quit = 80
else:
# Countercheck failed negative quit telegram to force synchronisation
_quit = 99
self.log ( " DT_Handler Telegram counter FAILED --> Synchronization")
if _quit > -1:
# Prepare Quit teltgramm
self.generatequit (count, 'ISO', teltype, key2, ret_val ['src'], ret_val ['dst'], _quit)
self.message (5, ' DT_handler : Quit Tel queued:"')
self.connections['ISO'][(teltype, key2)][1] = count
else:
self.message (1,'"DT_Handler : unknown Telegram type, no Number')
self.debug ()
def generatequit (self, count, channel, msgtype, key2, src, dst, retval):
"""
Generate an ISO QUIT telegram and send it
"""
self. message (3, " generatequit : generate Quit Telegram for %s on channel %s, with retval %d" % (msgtype, channel, retval))
_data = chr((count >> 8) & 0xFF) + chr (count & 0xFF)
_data = _data +\
doublechar (src) +\
doublechar (dst) +\
msgtype +\
'%c%c' %(retval >> 8, retval % 256)
_tpdu = DT_TPDU (_data)
self.log (" generatequit Data: %s" % _data[2:])
_tpkt = tpkt.TPKT (len (_tpdu) + 1)
self.queue_add (channel, (msgtype, key2), `_tpkt` + `_tpdu`, 0, 0)
return
def findstorageplace (self, storage, article):
"""
Find a free (not locked) slot/place in an unmanaged storage
according to zone in article
returns Coordinate Tuple or None in case of no place (or undefined article)
"""
DB_con = self.connections['DB']
usedslots = DB_con.usedstorageslots (storage)
zones = int (self.parameter['ZONES_%s' % storage])
if zones > 1:
self.message (1, ' findstorageplace : get Zone from Articlebase')
if article not in self.articlemaster:
self.message (1, ' findstorageplace : Article not in Articlebase')
return None
zone = int (self.articlemaster[article][6])
if zone:
self.message (5, ' findstorageplace : zone %d for article in Articlebase found' %zone)
if zone >= 1 and zone <= zones:
xmin = int (self.parameter["ZONESTART_%s_%d" % (storage, zone)])
if zone == zones:
xmax = int (self.parameter['X_%s' % storage])
else:
xmax = int (self.parameter["ZONESTART_%s_%d" %(storage, zone + 1)]) - 1
else:
self.message (5, ' findstorageplace : no zone for Article')
return None
else:
#No zones defined
zone = 1
xmin = 1
xmax = int (self.parameter['X_%s' % storage])
ymax = int (self.parameter['Y_%s' % storage])
unusableslots = DB_con.getunusableslots (storage)
self.log ("Unusable Slots: %s" % repr (unusableslots))
#Specific code for multiple zones
mid = (int (self.parameter.get('XMid_%s_%d' % (storage, zone) , 1)),\
int (self.parameter.get('YMid_%s_%d' % (storage, zone), 1)))
self.message (5, ' findstorageplace : search x from %d to %d with mid x:%d y:%d' %(xmin, xmax, mid[0], mid[1]))
slots = [(x, y) for x in range (xmin, xmax + 1) for y in range (1, ymax + 1) if (not usedslots or ((x, y) not in usedslots)) and (not unusableslots or ((storage, x, y) not in unusableslots))]
slots.sort (lambda arg1, arg2: cmp (pow (arg1[0] - mid[0], 2) + pow (arg1[1] - mid[1], 2), pow (arg2[0] - mid[0], 2) + pow (arg2[1] - mid[1], 2)))
self.log ("Remaining Slots: %s" % repr (slots))
if len (slots) >= 1:
self.message (6, ' findstorageplace : using x %d y %d' %(slots[0][0], slots[0][1]))
return ((slots[0][0], slots[0][1], 1), len (slots))
return None
def lifebeat (self):
"""
Generate lifebeat
"""
count = self.connections['ISO'][('LEBE', 'LEBE')][1]
dt = TEL_LEBE (nr = count).data
self.connections['ISO'][('LEBE', 'LEBE')][1] = (count % 32767) + 1
td = DT_TPDU (dt)
tk = tpkt.TPKT (len (td) + 1)
try:
self.write ('LEBE','LEBE',`tk`+`td`)
except:
print ("FixMe Lifebeat")
def sendmovetransports (self, position):
"""
Send ISO TAUF pending for RFZ
"""
DB_con = self.connections['DB']
l = DB_con.getmovetransport (position)
if not l:
return 0
_data =''
self.message (3, " sendmovetransports : TAUF found in DB")
if l[10] == 'New':
count = self.connections['ISO'][('TAUF' , 'TAUF')][1]
_data = chr((count >> 8) & 0xFF) + chr (count & 0xFF)
_data = _data +\
'LV' +\
'TR' +\
'TAUF' +\
chr (10) +\
chr (10) +\
fillchar (str (l[0]), 10) +\
str (l[1]) +\
str (l[2]) +\
doublechar (str (l[3])) +\
doublechar (str (l[4])) +\
doublechar (str (l[5])) +\
str (l[6]) +\
doublechar (str (l[7])) +\
doublechar (str (l[8])) +\
doublechar (str (l[9]))
_tpdu = DT_TPDU (_data)
self.message (3, " sendmovetransports : " + _data)
_tpkt = tpkt.TPKT (len (_tpdu) + 1)
self.queue_add ('ISO', ('TAUF','TAUF'), `_tpkt` + `_tpdu`, position, int (fillchar (str (l[0]), 20)))
DB_con.settransportsending (position, int (l[0]))
return 1
return 0
def generatetransport (self, position, boxnr):
"""
Generate an ISO TAUF telegram from DB TAUF for boxes from IPKT or at VF
"""
DB_con =self.connections['DB']
self. message (3, " generatetransport : getting TAUF for Box %s at position %s " % (boxnr, position))
tauf = DB_con.gettransport (position, boxnr)
if tauf:
self.message (3, " generatetransport : TAUF found in DB")
count = self.connections['ISO'][('TAUF' , 'TAUF')][1]
tel = TEL_TAUF ( nr = count,\
src = 'LV',\
dst = 'TR',\
type = 'TAUF',\
boxnr = str (boxnr),\
position = tauf [1], \
source = tauf [2], \
srcx = tauf [3],\
srcy = tauf [4],\
srcz = tauf [5],\
dest = tauf [6],\
destx = tauf [7],\
desty = tauf [8],\
destz = tauf [9])
_tpdu = DT_TPDU (tel.data)
self.log ( " generatetransport : " + str (tel.attrib))
self.log ( " generatetransport : Data '%s' " % tel.data)
_tpkt = tpkt.TPKT (len (_tpdu) + 1)
self.queue_add ('ISO', ('TAUF','TAUF'), `_tpkt` + `_tpdu`, position, boxnr)
DB_con.settransportsending (position, boxnr)
else:
self.log (" generatetransport : No TAUF in DB --> FixMe ??")
return
return
def generateTFnoreadTAUF (self, boxnr):
# Throughfeed box in no read slot
DB_con = self.connections['DB']
ux, uy = DB_con.findthroughfeedslot ()
count = self.connections['ISO'][('TAUF' , 'TAUF')][1]
_data = chr((count >> 8) & 0xFF) + chr (count & 0xFF)
_data = _data +\
'LV' +\
'TR' +\
'TAUF' +\
chr (10) +\
chr (10) +\
fillchar (boxnr, 10) +\
RFZ2 +\
PUFFER +\
doublechar (str(ux)) +\
doublechar (str(uy)) +\
'01' +\
PICK +\
'19' +\
'06' +\
'00'
_tpdu = DT_TPDU (_data)
_tpkt = tpkt.TPKT (len (_tpdu) + 1)
self.queue_add ('ISO', ('TAUF','TAUF'), `_tpkt` + `_tpdu`)
DB_con.settaufsent (RFZ1, boxnr)
def checkarticletransfer (self, article, transferdest, transfersource):
"""
Move box from a specific article to external destination
Multiplexed Outqueues for Orderlines identified by findest 50+
Mainorder identifies a global Order for interlocking RBGs against each other
triggerbox tells boxnr which triggers the transport
"""
DB_con = self.connections['DB']
self.message (6, " Checkarticletransfer for article %d from %s to %s" \
% (article, transferdest, transfersource))
sources = []
for src, rfz, rfzOut, mode, prio in self.transportmatrix['srcbydst'][transferdest]:
if src == transfersource:
self.message (6, " Checkarticletransfer Possible Transport from %s to %s with RFZ%d%s with prio %s" %\
(src, transferdest, rfz, rfzOut and " Outfeedpoint %s" % rfzOut or '', prio))
sources.append (src)
arts = []
_resactive = 0
for src in sources:
srcarts = DB_con.findarticle (src, article)
if srcarts:
for i in srcarts:
arts.append (i)
locked = DB_con.getunusableslots ('')
# Found matching article Storage included in Transportmatrix
if arts:
# Check if box already
# is reserved in Destination
# is reserved for a Outjob (Express e.g.)
# id, boxnr, article, lotnr, duedate, weight, x, y, z, rfzts
# id, boxnr, article, lotnr, lotnr2, duedate, pieces, x, y, z, rfzts
# 0 1 2 3 4 5 6 7 8 9 10
boxes = [(str(box[10]).replace(' ','').replace('-',''), box[7], box[8], box[9], box[1], box[3], box[4], box[5], box[6], box[0]) for box in arts if box[10]\
and not DB_con.searchbox (int (box[1]), box[0], excl = 1) and not DB_con.searchbox (int (box[1]), 'Outqueue') and (box[0], box[7], box[8]) not in locked]
boxes.sort ()
if not boxes:
if _resactive:
return -1
return None
box = boxes [0]
if box:
rfzts, x, y, z, boxnr, lotnr, lotnr2, duedate, pieces, source = box
for src, rfzNr, rfzOut, mode, prio in self.transportmatrix['srcbydst'][transferdest]:
rfz = "RFZ%d" % rfzNr
destination = transferdest[0] == 'O' and "OP%s" % rfzOut or transferdest
if src == source:
#FixMe Get from Transportmatrix
self.log ( " Checkarticletransfer Creating Transport at %s for %s from %s to %s"\
% (rfz, boxnr, source, transferdest))
DB_con.reservebox (rfz, source, x, y, z, int (boxnr), article, lotnr, lotnr2, duedate, pieces, destination, 0, 0, 0)
#if transferdest in ['O001', 'O002'] and source [0] == 'T':
# self.message (3, "Cheackarticletransfer storing next triggerbox %d for %s" % (int (boxnr), transferdest))
# self.parameter['triggerbox-%s' % transferdest] = int (boxnr)
return box
else:
self.message (6, " Checkarticletransfer didn't find article %s" % article)
return None
def boxreserve (self, location, source, src_x, src_y, src_z, boxnr, article, lotnr, lotnr2, duedate, pieces, storage, zone, noreserve):
"""
Assign reservation for a Box from IPKT
try to find a place in storage
location - RFZ
source - IPoint ID
"""
DB_con = self.connections['DB']
self.message (3, " boxreserve : assign place for Box %s" %boxnr)
place = None
tshelffull = 0
if storage[0] == 'T':
#Storage with Throughfeed Check for Refill an Slot
self.message (3, " boxreserve : check if article is in Througfeedstorage --> get a free place")
place = DB_con.placeinthroughfeed (storage, article, zone, self.parameter)
if place == (0, 0, 0):
# Slots for article in Throughfeed occupied
if '%s_Managed' % storage in self.parameter:
self.message (3, " boxreserve: All slots for article in managed T-Shelf are occupied")
else:
self.message (3, " boxreserve: Used for article in unmanaged T-Shelf are occupied --> assign new slot")
place, emptyslots = self.findstorageplace (storage, article)
self.message (3, " boxreserve: Used for article in unmanaged T-Shelf are occupied Nr of Emtpy Slots %d" % emptyslots)
if not place:
tshelffull = 1
if place:
#Found place in Throughfeed
self.message (3, " boxreserve : Box Found Place in T Storage %s at %s" % (storage, repr (place)))
_dx = place[0]
_dy = place[1]
_dz = place[2]
if noreserve:
inqsize = DB_con.getinqueuesize (storage)
self.message (3, " boxreserve : Box Found Place in T Storage no Reservation so from Ixx Test Spare Queuesize is %d" % inqsize)
slotlen = int (self.parameter['Z_%s' % storage])
if int (_dz) > (slotlen - inqsize - 1):
self.message (3, " boxreserve : Box Found Place in T Storage no Reservation Rem. Slotspace to small check rem. Slots")
testplace = self.findstorageplace (storage, article)
if not testplace:
self.message (3, " boxreserve : Box Found Place in T Storage no Reservation Rem. No more Space")
return None
if not noreserve:
DB_con.reservebox (location, source, src_x, src_y, src_z, int (boxnr), article, lotnr, lotnr2, duedate, pieces, storage, place[0], place[1], place[2])
self.message (3, " boxreserve : Box reserved in T Storage %s at %s" % (storage, repr (place)))
else:
self.message (3, " boxreserve : article not in Storage (or not Throughfeed) yet -> try to find a place")
inqsize = DB_con.getinqueuesize (storage)
place, emptyslots = self.findstorageplace (storage, article)
if not place:
self.message (3, " boxreserve : No Place in Storage return and maybe get another place")
return None
if storage in ['S001', 'S002']:
self.message (3, " boxreserve : Singleplace Storage check remaining Space %d against queuesize %d" % (emptyslots, inqsize))
if emptyslots <= inqsize:
self.message (3, " boxreserve : Singleplace Storage does not have enough space")
return None
#Do boxreservatoion
self.message (3, " boxreserve : Box Found Place in Storage %s " % storage + str (place))
_dx = place[0]
_dy = place[1]
_dz = place[2]
if not noreserve:
DB_con.reservebox (location, source, src_x, src_y, src_z, int (boxnr), article, lotnr, lotnr2, duedate, pieces, storage, place[0], place[1], place[2])
self.message (3, " boxreserve : Box reserved in Storage %s " % storage + str (place))
return (storage, _dx, _dy, _dz)
def queue_add (self, channel, connection, data, position, boxnr):
"""
Add a telegram to sendqueue
for SOAP telegrams data is a list of (RPCfunction, data)
"""
self.message (3, "Added telegram to sendqueue")
self.connections['Queue'].append ([channel, connection, data, position, boxnr])
def listen (self, socket):
"""
Wait for a client to open a connection to our socket.
"""
try:
new_socket, client = socket.accept ()
self.message (1, "Server connected by %s port %s" % client)
if self.connections['client'] == client[0]:
self.sockets [client]= (new_socket, CONN_NEW)
self.message (3, "** Checking for active Connections to request")
else:
self.message (1, "Unauthorized connection from %s port %s " % client)
except KeyboardInterrupt:
self.message (1,"Interrupted by user")
return
def blocknxmit (self):
"""
Wait for incomming data on any of the open connections, decode it and take
appropriate action and also check for outgoing data and free channels to
transmit it.
"""
global prioexp, prioexp2
# lifebeats
nt = time ()
DB_con = self.connections['DB']
# Send lifebeat every 5s
if nt - self.connections['LastBeat'] > 5:
self.lifebeat ()
self.connections['LastBeat'] = nt
writecons = []
#Check for active ISO connections
for c in self.connections['ISO']:
if len (c) != 2 and type (c) != type (()):
raise Warning, "Invalid item in ISO connections"
# Connection Tuple found
loc_TSAP, rem_TSAP = c
socket, counter, mode = self.connections['ISO'][c]
if mode == 'active' and not socket:
s = self.makeactiveisoconnection (loc_TSAP, rem_TSAP)
if s:
self.message (3, "*** queue CR for connection: %s - %s " %(loc_TSAP, rem_TSAP))
_tel = con_request (loc_TSAP, rem_TSAP)
self.queue_add ('ISO', (loc_TSAP, rem_TSAP), _tel, 0, 0)
self.sockets[s.getpeername ()] = (s, CONN_NEW)
if len (self.connections['Queue']):
channel, conn_name, data, position, boxnr = self.connections['Queue'][0]
if channel == 'ISO':
#conn_name == ISO-Tuple
self.message (3, "blocknxmit - Found to-be-send telegramm %s" % repr (conn_name))
con = self.connections[channel][conn_name][0]
if con:
writecons.append ((con, data, self.connections['client'], conn_name))
# Select free sockets for transmission
# self.sockets = {(socket, STATE)}
writes = [i[0] for i in writecons]
reads = [self.sockets[i] for i in self.sockets]
(read, writes, xlist) = select ([i[0] for i in reads], writes, [], 0.1)
readcons = [i for i in reads if i[0] in read]
writecons = [i for i in writecons if i[0] in writes]
# First write all remaining messages
for conn, data, client_id, contyp in writecons:
self.message (1, "blocknxmit - Write to Socket %s" % str (conn))
# Loop until we successfuly got the data through
while 1:
try:
conn.send (data)
except error, msg:
# In case of a failure we'll need a new connection
self.message (1, "blocknxmit - Error on write: %d %s" %(msg[0], msg[1]))
if len (contyp) == 2 and type (contyp) == type (()):
socket, counter, mode = self.connections[c]
if mode == 'active':
print "hoit"
raise Warning
loc_TSAP, rem_TSAP = contyp
self.makeactiveisoconnection (loc_TSAP, rem_TSAP)
conn = self.connections['ISO'][(loc_TSAP, rem_TSAP)][0]
else:
# Break on success
break
channel, conn_name, data, position, boxnr = self.connections['Queue'][0]
self.message (3, "Channel: '%s' Connection '%s' Data '%s' positon %s boxnr %s" % (channel, conn_name[0], data[9:], position, boxnr))
if conn_name == ('TAUF', 'TAUF') and position:
if position[0] in ['I', 'P', 'O']:
self.message (6, "Delete %s Tauf After Sending" % position)
DB_con.deletetransport (position, boxnr)
elif (position[0:3] == 'RFZ') and '%sIRFZ000000%s000001' % (position, position) in data[9:]:
self.message (7, "Delete %s Take Off Tauf after Sending" % position)
DB_con.deletetransport (position, boxnr)
elif (position[0:3] == 'RFZ') and '%s%s000000%s000001' % (position, position, position) in data[9:]:
self.message (7, "Delete %s Take Off Tauf after Sending" % position)
DB_con.deletetransport (position, boxnr)
else:
self.message (6, "Set Transport Sent at Position %s" % position)
DB_con.settransportsent (position, boxnr)
del self.connections['Queue'][0]
# Then read all remaining messages from ready sockets
for conn in readcons:
#self.message (1, "blocknxmit - Read from Socket " )
if conn[0] == self.listener_socket:
self.message (3, " blocknxmit - Read on listener socket")
self.listen (conn[0])
else:
#self.message (3, " blocknxmit - Read on other socket")
self.read (conn)
# Update Articlemaster
nt = time ()
if nt -self.lastarticleupdate > 120:
self.articlemaster.update (DB_con.getarticlemaster ())
self.lastarticleupdate = nt
# Sweep over DB for empty space in pick every once in a while
nt = time ()
if nt - self.lastsweep > 1:
self.message (3, "Sweeping for jobs")
_max = 4
DB_con = self.connections['DB']
self.parameter.update (DB_con.getphysics ())
#1st send pending Transports
for i in range (int (self.parameter['RFZs'])):
self.message (3, "Queue Pending Move Transports for RFZ %d" % (i + 1))
_r = self.sendmovetransports ('RFZ%d' % (i + 1))
if _r:
break
#FixmMe ToDo New methods for Chaos, Move and Expressjobs
for i in range (int (self.parameter['RFZs'])):
_count = DB_con.getnewmovetransportcount ('RFZ%d' % (i + 1))
_sentcount = DB_con.getmovetransportsentcount ('RFZ%d' % (i + 1))
self.message (3, "Queue Move Transports for RFZ %d Count %d Sent %d" % (i + 1, _count[0], _sentcount[0]))
#Check if Errorboxes have to be moved
_count = DB_con.getnewmovetransportcount ('RFZ%d' % (i + 1))
_count = [0]
#automatic Storage moves - add timecontrol
if 'ordering' in self.parameter:
nt = time ()
if 0 and nt - self.lastordersweep > 30:
self.message (6, "Ordering Time to check if new Orders arived")
Ordering = self.connections ['Ordering']
for orderfile in Ordering.orderfiles ():
self.log ("Ordering: Processing new File %s" % orderfile)
_ordhd, _ordln = Ordering.decodefile (orderfile)
if _ordhd:
if DB_con.searchorder (id = int (_ordhd['orderid'])):
self.log ("Ordering: Processed Files contains already existing Order %d" % int (_ordhd['orderid']))
else:
DB_con.addorder (orderid = int (_ordhd['orderid']), \
customer_name = _ordhd['cust'] + "\n" + _ordhd['cust2'], \
customer_address = _ordhd['cust_country'] + "-" + _ordhd['cust_postcode'] + " " + \
_ordhd['cust_city'] + "\n" + _ordhd['cust_street'],
deliverydate = _ordhd['deliverydate'])
for _ln in _ordln:
DB_con.addorderline (orderid = int (_ordhd['orderid']), \
article = int (_ln['article']), \
caption = _ln['caption'], \
amount = _ln ['order_amount'], \
amount_unit = _ln ['order_amount_unit'], \
weight = _ln ['order_weight'], \
weight_unit = _ln ['order_weight_unit'])
Ordering.archiveorderfile (orderfile)
self.lastordersweep = nt
nt = time ()
if 0 and nt - self.lastodredelsweep >= 3600:
self.lastodredelsweep = nt
self.message (6, "Ordering Time to delete old orders")
for oldorder in DB_con.getoldorders ():
_orderid, _deldate, _state = oldorder
DB_con.deleteorder (int (_orderid))
nt = time ()
if nt - self.lastordermovesweep >= 1:
self.lastordermovesweep = nt
self.message (6, "Ordering Time to check for new moves")
for _dest in filter (lambda a: a[0] == 'O', self.transportmatrix['srcbydst'].keys ()):
if 3 >= 1:
self.message (6, "Ordereng Current Outqueuesize %d for dest %s reached maximum - stop sweep" % (1, _dest))
continue
#FixMe ignore Expressdestinations
_activeorders = DB_con.searchorder (id = 0, destination = _dest, state = 'Active')
if _activeorders:
self.message (6, "Found active Order, scan orderlines")
_orderid, _state, _dest = _activeorders [0]
_activeorderlines = DB_con.searchorderline (orderid = int (_orderid), state = 'Active')
if _activeorderlines:
key = 'OrderingMainorder_%s' % _dest
if key not in self.parameter:
self.message (6, "Mainorder for Outqueue doesn't exist, create value")
self.parameter[key] = 0
DB_con.addphysics (key, str (self.parameter[key]))
mainorder = int (self.parameter[key])
_olid, _art, _amnt, amnt_unit, amnt_dlrd, weight, weight_unit, weight_dlrd, state = _activeorderlines[0]
triggerbox = 0
if int (self.parameter.get ('triggertransports-%s' % _dest, 0)):
triggerbox = int (self.parameter.get ('triggerbox-%s' % _dest, 0))
self.message (6, "Found active Orderline for Odrer %d with Article %d%s" % (int (_orderid), _art, triggerbox and ' and Trigger %d' %triggerbox or ''))
_box = self.checkarticletransfer (_art, _dest, finedest = int (_dest[1:]) + 50, mainorder = mainorder, triggerbox = triggerbox)
_weight = 0.0
if _box and _box != -1:
_rfzts, _x, _y, _z, _boxnr, _lotnr, _duedate, _weight, _source = _box
if self.parameter.get ('triggerbox-%s' % _dest, 0) == -1:
self.message (6, ' : Ordering box %d reserved for Triggertransport so not adding to outqueue %s' % (int (_boxnr), _dest))
self.parameter['triggerbox-%s' % _dest] = 0
else:
self.message (6, ' : Ordering add box %d to outqueue %s' % (int (_boxnr), _dest))
DB_con.addoutgoingbox (_dest, int (_boxnr), '', '', '', '', 99)
DB_con.setphysics (key, str ((mainorder + 1) % 100))
#ToDo add box to order
self.log ("Orderline generate Triggertransport to show Orderid on Panel for Box %d" % int (_boxnr))
DB_con.createtransport (int (_orderid), _dest, _dest, 0, 0, 0, _dest, 0, 0, 0, state = 'Trigger-%d' % int (_boxnr))
DB_con.orderlineaddweight (_olid, _weight)
elif _box and _box == -1:
self.message (6, "Waiting for done Storagemoves for Orderline")
#DB_con.setorderlinestate (orderlineid = int (_olid), state = 'Paused')
#self.lastordermovesweep = nt - 1
else:
self.message (6, "Didn't find any box for Orderline")
if str (_art) not in DB_con.getslotbasearticles ('T002'):
#FixMe Startup Stuff
self.log ("Article of Orderline not in Base close")
DB_con.setorderlinestate (orderlineid = int (_olid), state = 'Done')
self.lastordermovesweep = nt - 1
else:
DB_con.setorderlinestate (orderlineid = int (_olid), state = 'Paused')
self.lastordermovesweep = nt - 1
if weight_dlrd +_weight >= weight:
self.message (6, "Requested Weight of Orderline reached, close")
DB_con.setorderlinestate (orderlineid = int (_olid), state = 'Done')
else:
_neworderlines = DB_con.searchorderline (orderid = int (_orderid), state = 'New')
if _neworderlines:
_olid, _art, _amnt, amnt_unit, amnt_dlrd, weight, weight_unit, weight_dlrd, state = _neworderlines[0]
self.message (6, "Activating Orderline %d for order %d with article %d" % (int (_olid), int (_orderid), int (_art)))
DB_con.setorderlinestate (orderlineid = int (_olid), state = 'Active')
else:
_pausedorderlines = DB_con.searchorderline (orderid = int (_orderid), state = 'Paused')
if _pausedorderlines:
for i in _pausedorderlines:
_olid, _art, _amnt, amnt_unit, amnt_dlrd, weight, weight_unit, weight_dlrd, state = i
DB_con.setorderlinestate (orderlineid = int (_olid), state = 'New')
self.log ("Pausing Order %d due to no more Orderlines to process" % int (_orderid))
DB_con.setorderstate (orderid = int (_orderid), state = 'Paused')
else:
self.log ("Closing Order %d due to no more Orderlines to process" % int (_orderid))
DB_con.setorderstate (orderid = int (_orderid), state = 'Done')
self.lastordermovesweep = nt - 1
else:
_neworders = DB_con.searchorder (id = 0, destination = _dest, state = 'New')
if _neworders:
_orderid, _state, _dest = _neworders[0]
self.message (6, "Activating Order %d" % int (_orderid))
DB_con.setorderstate (orderid = int (_orderid), state = 'Active')
prioexp = 1
if prioexp:
prioexp = 0
self.message (3, " Sweep over Expressjobs")
_exp = 1
if _exp:
self.message (3, "Exp: Sweeping over Expressjobs for ")
_count = DB_con.getnewmovetransportcount ('RFZ2')
_sentcount = DB_con.getmovetransportsentcount ('RFZ2')
self.message (3, " Exp: count for RFZ2 Taufs %d sent %d" % (_count[0], _sentcount[0]))
DB_con = self.connections['DB']
job = DB_con.findactiveexpressjob ()
if job:
self.message (3, "Exp: found active job")
_expjob, _source, _state, _customer, _packl, _article, _boxes, _boxes_delivered, _ts, _info = job
if (int (_boxes) and (int (_boxes_delivered) >= int (_boxes))):
self.message (3, "Exp: Job is finished now")
DB_con.closeexpressjob (job[0], 'Auftrag beendet')
try:
explog = DB_con.expressloggetdata (_expjob)
mailexplog (job, explog)
except:
print ('Problem')
elif _sentcount[0] == 0 and _count[0] == 0:
#FixMe just RBG 2 at the moment
if _source == 'T001':
self.message (3, "Exp: Check Article From T001 due to no Move Job active")
_box = self.checkarticletransfer (int (_article), 'O002', 'T001')
if _box and _box != -1:
_brfzts, _bx, _by, _bz, _boxnr, _lotnr, _lotnr2, _duedate, _bpieces, _bsource = _box
DB_con.expressjobaddbox (job[0])
DB_con.expresslogaddbox (_expjob, _boxnr, _lotnr, _lotnr2, _bpieces)
else:
DB_con.closeexpressjob (job[0], 'Paletten fehlen')
else:
self.message (3, "Exp : Look for new express job")
for j in DB_con.findnewexpressjobs ():
self.message (3, "Exp: Assigned new Express Job")
DB_con.activateexpressjob (j[0])
break
self.message (3, "Exp: Sweeping over Expressjobs Done")
#ES Move Jobs
_esjob = DB_con.findnewesmovejobs ()
_count = DB_con.getnewmovetransportcount ('RFZ2')
self.message (3, " Sweep: count for RFZ2 Taufs %d" %_count[0])
if _esjob and _count[0] > 0:
self.message (3, " Sweep: Found Singletransfer jobs so 1st block all further jobs")
elif _esjob:
self.message (3, " Sweep: Found Singletransfer jobs and no other job")
c_id, c_pos, c_state, c_anr, c_srcid, c_srcx, c_srcy, c_ts = _esjob[0]
DB_con.assignesmovejob (c_id, 'RFZ2')
aboxes = {}
c_anr = int (c_anr)
srcboxes = DB_con.getboxesslot (c_srcid, c_srcx, c_srcy)
if srcboxes:
self.message (3, " Sweep: Found Boxes for Singleplacetransfer")
for a_id, a_knr, a_anr, a_lnr, a_due, a_w, a_x, a_y, a_z, a_ts in srcboxes:
aboxes [(a_x, a_y, a_z)] = (a_id, a_knr, a_anr, a_lnr, a_due, a_w, a_ts)
nusage = len (aboxes)
unusableslots = DB_con.getunusableslots ('S001')
usedslots = DB_con.usedstorageslots (storage)
xmin = 5
mid = (20, 4)
xmax = 35
ymax = 8
l = [(x, y) for x in range (xmin, xmax + 1) for y in range (1, ymax + 1) if (x, y) not in usedslots and ('S001', x, y) not in unusableslots]
l.sort (lambda arg1, arg2: cmp (pow (arg1[0] - mid[0], 2) + pow (arg1[1] - mid[1], 2), pow (arg2[0] - mid[0], 2) + pow (arg2[1] - mid[1], 2)))
nstart = 1
for slot in l:
if nstart > nusage:
break
cx, cy = slot
self.message (3, " Sweep: Singleplacetransfer moving box %s from 'T002' %d %d %d to 'S001' %d %d %d " %( str (aboxes [(c_srcx, c_srcy, nstart)]) ,c_srcx, c_srcy, nstart, cx, cy, 1))
boxdata = aboxes [(c_srcx, c_srcy, nstart)]
#Reserve Here
if boxdata[0] <> 'T001':
print "Not Allowed"
sys.exit (0)
if int (boxdata[1]) > 999999900:
self.message (4, "Sweep: Stopping because of Dummy in slot")
nstart = nusage + 1
else:
DB_con.reservebox ('RFZ2', 'T001', c_srcx, c_srcy, nstart, int (boxdata[1]), boxdata[2], boxdata[3], boxdata[4], boxdata[5], 'S001', cx, cy, 1, '', '')
nstart += 1
if nstart > nusage:
self.message (3, " Sweep: Chaos finished")
DB_con.closeesmovejob (c_id, 'OK')
else:
self.message (3, " Sweep: Chaos broken no Space")
DB_con.closeesmovejob (c_id, 'No Space')
else:
self.message (3, " Sweep: Singletransfer broken no Boxes exist in Slot")
DB_con.closeesmovejob (c_id, 'No Boxes')
self.lastsweep = time ()
# Sweep over ERP Entrys and create file
DB_ERP_con = self.connections['DB_ERP']
if DB_ERP_con:
nt = time ()
_erpsweepcycle = 300
try:
config = ConfigParser ()
config.read ('/opt/sap/sap.cfg')
_erpsweepcycle = 60 * config.getint ('SAP', 'cycletime')
except:
_erpsweepcycle = 300
if _erpsweepcycle <= 0 or _erpsweepcycle > 3600:
_erpsweepcycle = 300
if (nt - self.lasterpsweep > _erpsweepcacle):
self.message (3, " Sweeping over ERP msgs")
sapfile = pySAP (path = "/opt/sap/")
DB_ERP_con = self.connections['DB_ERP']
for a, c, m, u in DB_ERP_con.getinsertions ():
sapfile.log ('%05d;%010d;%s;%s' % (int (a), int (c), m, u))
DB_ERP_con.markinsertionsasread ()
self.lasterpsweep = nt
def read (self, conn):
sock, state = conn
try:
data = sock.recv (32768)
except error, msg:
self.message (1, 'Socket error on read: ' + msg[1])
return
# Bail out if connection closed by client
if not data:
try:
client_ip, client_port = sock.getpeername ()
except:
client_ip, client_port = '0.0.0.0', 0
self.message (1, ' read empty telegramm - client %s %d closed connection - close socket !!!!'% (client_ip, client_port))
if (client_ip, client_port) in self.sockets:
socket, state = self.sockets [(client_ip, client_port)]
self.message (2, ' delete socket')
del self.sockets[(client_ip, client_port)]
for typ in self.connections:
try:
if self.connections[typ][0] == sock:
self.message (2, ' found socket in connection delete Reference %s' % str (typ))
self.connections[typ][0] = None
except:
a = 0
sock.close ()
else:
self.log ("Socket not in self.sockets")
print self.sockets
print sock
for (client_ip, client_port) in self.sockets.keys ():
if self.sockets [(client_ip, client_port)][0] == sock:
self.log (" Closing Socket with empty telegram")
del self.sockets[(client_ip, client_port)]
for typ in self.connections:
try:
if self.connections[typ][0] == sock:
self.log ("Found socket in connection delete Reference %s" % str (typ))
self.connections[typ][0] = None
except:
a = 0
sock.close ()
return
packet = decode.decodepacket (data)
ptype = packet.type ()
# Check for connection request
if ptype == tpdu.TPDU_CR:
self.message (1," read : Received CR "+ packet.srctsap () + packet.dsttsap ())
connreq = (packet.srctsap (), packet.dsttsap ())
client_ip, client_port = sock.getpeername ()
#if conn[1] <> CONN_NEW:
# raise RuntimeError, "Connection already assigned"
if connreq in self.connections['ISO']:
if self.connections['ISO'][connreq][0] == None:
self.message (1, " Request acknowledged")
else:
self.message (1, " Client tried to open an established connection Closing Socket")
oldsock = self.connections['ISO'][connreq][0]
oldsock.close ()
for ip, port in self.sockets:
if self.sockets[(ip, port)][0] == oldsock:
self.message (1, " read delete socket")
del self.sockets[(ip, port)]
break
#Socket , Counter, Mode
self.connections['ISO'][connreq] = [sock, 0, 'passive']
sock.send (acknowledge (packet))
else:
self.message (1," Received undefined connection request Close Socket")
self.message (1, " "+ packet.srctsap () + packet.dsttsap ())
self.message (1," " + client_ip)
if (client_ip, client_port) in self.sockets:
self.message (2, 'delete socket')
del self.sockets[(client_ip, client_port)]
sock.close ()
# Check for connection confirmation
elif ptype == tpdu.TPDU_CC:
self.message (1, " read : Received CC "+ packet.srctsap () + packet.dsttsap ())
self.message (1, " read : FixME State was %d" % state)
# Check for data transfer
elif ptype == tpdu.TPDU_DT:
self.message (1," read : Received data packet")
"""
if state != STATE_ESTABLISHED:
raise RuntimeError, "Connection not established but data received"
else:
"""
client_id = conn[0].getpeername()[0]
ret_val = self.dt_handler (packet, client_id, source = '')
else:
self.message (1, " read : Unknown packet received : 's%'" %str (packet))
def write (self, loc_TSAP, rem_TSAP, data):
"""
Send Data via ISO Connection
"""
if 'client' in self.connections:
if (loc_TSAP, rem_TSAP) in self.connections['ISO']:
conn_data = self.connections['ISO'][(loc_TSAP, rem_TSAP)]
conn = conn_data[0]
if conn:
if conn_data[1] == "active":
# Loop until we successfuly got the data through
while 1:
try:
conn.send (data)
# In case of a failure we'll need a new connection
except error:
self.makeactiveisoconnection (loc_TSAP, rem_TSAP)
conn = self.connections['ISO'][(loc_TSAP, rem_TSAP)][0]
# Break on success
else:
break
else:
try:
conn.send (data)
except error:
print "ISO Send Error"
else:
self.message (1,"write: Connection" + loc_TSAP + "-" + rem_TSAP + " not active")
else:
self.message (1,"write: Connection " + loc_TSAP + "-" + rem_TSAP + " doesn't exist")
else:
self.message (1,"write: Client " + " doesn't exist")
def shutdown (self):
"""
Shut down socket and cleanup.
"""
self.socket.close ()
self.message (1,"Server shut down normally")
if __name__ == '__main__':
config = ConfigParser ()
config.read ('storage.cfg')
IP_LVR = config.get ('IP Settings', 'iplvr')
if not IP_LVR:
print ('No IP for LVR')
sys.exit (0)
print ('LVR configured for IP %s' %IP_LVR)
IP_LAGER1 = config.get ('IP Settings', 'ipsps')
if not IP_LAGER1:
print ('No IP for PLC')
sys.exit (0)
print ('PLC configured for IP %s' %IP_LAGER1)
DBFILE = config.get ('DB Settings', 'dbfile')
if not DBFILE:
print ('No DB file configured')
sys.exit (0)
DBTALOG = config.get ('DB Settings', 'logfile')
if not DBTALOG:
print ('No DB TA Logfile configured')
sys.exit (0)
loglevel = config.getint ('DEBUG', 'loglevel')
if not loglevel:
loglevel = 0
print ('loglevel :%d' %loglevel)
debuglevel = config.getint ('DEBUG', 'debuglevel')
if not debuglevel:
debuglevel = 0
print ('debuglevel :%d' %debuglevel)
# PARAM
parameter = {}
for param in config.options ('PARAM'):
val = config.getint ('PARAM', param)
print ("Added Parameter %s with value %d" % (param,val))
parameter [param] = val
if parameter.get ('ordering', 0):
print ("Ordering active")
orderpath = config.get ('OPTIONS', 'OrderPath')
if not orderpath:
print ("Need Path to orderfiles")
sys.exit (0)
print ("Configured Path for Orders '%s'" % orderpath)
from Ordering import ORDERING
_Ordering = ORDERING (path = orderpath)
#ERP Trace
if config.getint ('OPTIONS', 'ERPTrace'):
print ('ERPTrace configured')
erptype = config.get ('OPTIONS', 'ERPType')
if not erptype:
print ('No ERPType configured')
sys.exit (0)
print ('ERPType %s' %erptype)
erpdbfile = config.get ('OPTIONS', 'ERPDB')
if not erpdbfile:
print ('No Database file configured')
sys.exit (0)
from DB_ERP import DB_ERP
#from pySAP import pySAP
_DB_ERP = DB_ERP (erpdbfile)
else:
_DB_ERP = None
server = ISOServer (address = IP_LVR, verbose = loglevel, debug = debuglevel)
server.add_client (IP_LAGER1, parameter, DB (DBFILE, DBTALOG), _DB_ERP, _Ordering)
server.add_conn ('LEBE','LEBE')
server.add_conn ('TQUI','TQUI')
server.add_conn ('SCLS','SCLS')
server.add_conn ('IPKT','IPKT')
server.add_conn ('TAUF','TAUF', 'active')
ot = time ()
while 1:
server.blocknxmit ()
server.shutdown ()
sys.exit (0)