Initial Start Commit
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ storage.cfg
|
|||||||
*.AppleDouble/
|
*.AppleDouble/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
doc/build/*
|
doc/build/*
|
||||||
|
log.txt
|
||||||
|
|||||||
39
CSB_LEBE.py
Executable file
39
CSB_LEBE.py
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Michael rest"
|
||||||
|
__date__ = "2006/02/13"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from cr_tpdu import CR_TPDU
|
||||||
|
from dt_tpdu import DT_TPDU
|
||||||
|
from tpkt import TPKT
|
||||||
|
from socket import *
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
def print_lebe (data):
|
||||||
|
print '\nLivebeat an SPS'
|
||||||
|
print ' Telegrammnr: %d ' %((ord (data[0]) << 8) + ord (data[1]))
|
||||||
|
print ' Sender : %s ' %data [2:4]
|
||||||
|
print ' Empfaenger : %s ' %data [4:6]
|
||||||
|
print ' Typ : %s ' %data [6:10]
|
||||||
|
print ' Telegrammnr: %d ' %((ord (data[10]) << 8) + ord (data[11]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#LEBE
|
||||||
|
tpdu = CR_TPDU ("LEBE", "LEBE", srcref=0x0015)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
tel = 'LV' + 'TP' + 'LEBE' + '%c%c' %(0,1)
|
||||||
|
dt = '%c%c' %(id >> 8, id % 256) + tel
|
||||||
|
id = id + 1
|
||||||
|
print_lebe (dt)
|
||||||
|
tpdu = DT_TPDU (dt)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
sleb.send(`tpkt`+`tpdu`)
|
||||||
|
sleep (4.1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
112
DB_ERP.py
Executable file
112
DB_ERP.py
Executable file
@@ -0,0 +1,112 @@
|
|||||||
|
#/usr/bin/python2.4
|
||||||
|
#!/opt/local/bin/python3.0
|
||||||
|
|
||||||
|
import sqlite3 as sqlite
|
||||||
|
#from pysqlite2 import dbapi2 as sqlite
|
||||||
|
from sys import exit
|
||||||
|
from time import strftime
|
||||||
|
from locations import *
|
||||||
|
|
||||||
|
def connectdb (dbfile):
|
||||||
|
"""
|
||||||
|
Create connection to database
|
||||||
|
return DB Object
|
||||||
|
user gets information if failure
|
||||||
|
"""
|
||||||
|
print ("Verbindung zu %s herstellen" %dbfile)
|
||||||
|
try:
|
||||||
|
db = sqlite.connect (dbfile)
|
||||||
|
return db
|
||||||
|
except:
|
||||||
|
print ("Konnte DB Verbindung nicht herstellen")
|
||||||
|
exit (1)
|
||||||
|
|
||||||
|
|
||||||
|
class DB_ERP:
|
||||||
|
# Database Stuff
|
||||||
|
# --------------
|
||||||
|
def __init__ (self, dbfile):
|
||||||
|
self.db = connectdb (dbfile)
|
||||||
|
|
||||||
|
|
||||||
|
def executesql (self, dbstring, arguments = ()):
|
||||||
|
"""
|
||||||
|
Fuehre den uebergebenen SQL-Befehl aus und liefere ein Cursor-Objekt
|
||||||
|
zurueck.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.db.cursor ()
|
||||||
|
cursor.execute (dbstring, arguments)
|
||||||
|
except OperationalError: #, msg:
|
||||||
|
print ("Datenbankausfuehrung fehlgeschlagen. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except IntegrityError: #, msg:
|
||||||
|
print ("Doppelter Eintrag. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except ProgrammingError: #, msg:
|
||||||
|
print ("Fehlerhaftes SQL. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except Warning: #, msg:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.db.commit ()
|
||||||
|
return cursor
|
||||||
|
|
||||||
|
|
||||||
|
def getinsertions (self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("SELECT kistennummer, artikelnummer, charge, menge, einheit, rfzts from ERPTrace where action = 'In Puffer inserted'")
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return cursor.fetchall ()
|
||||||
|
|
||||||
|
|
||||||
|
def getinsertionsgrouped (self):
|
||||||
|
"""
|
||||||
|
Get summarized information of insertions grouped by article / charge
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("SELECT artikelnummer, charge, sum(menge), einheit from ERPTrace where action = 'In Puffer inserted' GROUP BY artikelnummer, charge;")
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return cursor.fetchall ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def addinsertion (self, kistennummer, artikelnummer, charge, menge, einheit):
|
||||||
|
"""
|
||||||
|
log insertion
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("INSERT INTO ERPTrace (kistennummer, artikelnummer, charge, menge, einheit, rfzts, action) VALUES ('%s', '%s', '%s', '%s', '%s', current_timestamp, 'In Puffer inserted')"\
|
||||||
|
%(kistennummer, artikelnummer, charge, menge, einheit))
|
||||||
|
except:
|
||||||
|
print ("Couldn't add insertion to ERPTrace")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def markinsertionsasread (self):
|
||||||
|
"""
|
||||||
|
Mark all insertions as read
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("UPDATE ERPTrace set action = 'Logged Puffer insertion' where action = 'In Puffer inserted';")
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
conn = DB_ERP ("/opt/data/storage_ERPTrace.db3")
|
||||||
|
conn.markinsertionsasread ()
|
||||||
|
conn.addinsertion ('123456', '1235','12','1234','KG')
|
||||||
|
print conn.getinsertions ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
112
DB_Trace.py
Executable file
112
DB_Trace.py
Executable file
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/python2.4
|
||||||
|
#!/opt/local/bin/python3.0
|
||||||
|
|
||||||
|
#import sqlite3 as sqlite
|
||||||
|
from pysqlite2 import dbapi2 as sqlite
|
||||||
|
from sys import exit
|
||||||
|
|
||||||
|
from locations import *
|
||||||
|
|
||||||
|
def connectdb (dbfile):
|
||||||
|
"""
|
||||||
|
Create connection to database
|
||||||
|
return DB Object
|
||||||
|
user gets information if failure
|
||||||
|
"""
|
||||||
|
print ("Verbindung zu %s herstellen" %dbfile)
|
||||||
|
try:
|
||||||
|
db = sqlite.connect (dbfile)
|
||||||
|
return db
|
||||||
|
except:
|
||||||
|
print ("Konnte DB Verbindung nicht herstellen")
|
||||||
|
exit (1)
|
||||||
|
|
||||||
|
|
||||||
|
class DB:
|
||||||
|
# Database Stuff
|
||||||
|
# --------------
|
||||||
|
def __init__ (self, dbfile):
|
||||||
|
self.db = connectdb (dbfile)
|
||||||
|
|
||||||
|
def executesql (self, dbstring):
|
||||||
|
"""
|
||||||
|
Fuehre den uebergebenen SQL-Befehl aus und liefere ein Cursor-Objekt
|
||||||
|
zurueck.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.db.cursor ()
|
||||||
|
cursor.execute (dbstring)
|
||||||
|
except OperationalError: #, msg:
|
||||||
|
print ("Datenbankausfuehrung fehlgeschlagen. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except IntegrityError: #, msg:
|
||||||
|
print ("Doppelter Eintrag. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except ProgrammingError: #, msg:
|
||||||
|
print ("Fehlerhaftes SQL. Ausgeloest durch: " + dbstring)
|
||||||
|
raise Warning
|
||||||
|
except Warning: #, msg:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.db.commit ()
|
||||||
|
return cursor
|
||||||
|
|
||||||
|
# Trace
|
||||||
|
#------------------
|
||||||
|
def ghosts (self):
|
||||||
|
"""
|
||||||
|
Suche als Geisterkisten entfernte Kisten
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("SELECT * FROM Trace WHERE action='as Ghost removed'")
|
||||||
|
except:
|
||||||
|
print ("Konnte Kisten nicht finden")
|
||||||
|
raise Warning
|
||||||
|
|
||||||
|
boxes = cursor.fetchall ()
|
||||||
|
|
||||||
|
return boxes
|
||||||
|
|
||||||
|
# Dayly insertions
|
||||||
|
#-----------------
|
||||||
|
def daylyinsertions (self):
|
||||||
|
"""
|
||||||
|
Liefert eine Auflistung aller Einlagerungen der letzten 24h
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor = self.executesql ("SELECT kistennummer,rfzts FROM Trace WHERE (action='in Puffer inserted') AND ((julianday(current_timestamp) - julianday(rfzts)) * 24) <= 24 ORDER BY kistennummer;")
|
||||||
|
cursor2 = self.executesql ("SELECT kistennummer,artikelnummer,charge,gewicht FROM Trace WHERE (action='in Puffer reserved') AND ((julianday(current_timestamp) - julianday(rfzts)) * 24) <= 24 ORDER BY kistennummer;")
|
||||||
|
except:
|
||||||
|
print ("Konnte Daten nicht ermitteln")
|
||||||
|
|
||||||
|
reservations = cursor2.fetchall ()
|
||||||
|
reservationdict = {}
|
||||||
|
for knr, anr, lot, weight in reservations:
|
||||||
|
reservationdict [knr] = (anr, lot, int (weight))
|
||||||
|
sumary = {}
|
||||||
|
artboxes = {}
|
||||||
|
insertions = cursor.fetchall ()
|
||||||
|
for knr, rfzts in insertions:
|
||||||
|
key = (reservationdict [knr][0], reservationdict [knr][1])
|
||||||
|
curval = sumary.get (key, (0,0))
|
||||||
|
sumary [key] = (curval[0] + 1, curval[1] + reservationdict [knr][2])
|
||||||
|
curval = artboxes.get (key)
|
||||||
|
if not curval: artboxes[key] = []
|
||||||
|
artboxes [key].append ((knr, reservationdict [knr][2], rfzts))
|
||||||
|
|
||||||
|
return sumary, artboxes
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
#conn = DB ("/opt/data/storage.db3")
|
||||||
|
conn = DB ("/home/michi/storage.db3.1")
|
||||||
|
insertions, artboxes = conn.daylyinsertions ()
|
||||||
|
print 'Artikel;Charge;Kisten;Gewicht'
|
||||||
|
for key in insertions:
|
||||||
|
print ('%s;%s;%d;%0.2f' %(key[0], key[1], insertions[key][0], insertions[key][1]/100.0))
|
||||||
|
|
||||||
|
print ('\nArtikel;Charge;Kiste;Gewicht;Timestamp')
|
||||||
|
for key in artboxes:
|
||||||
|
for knr, weight, rfzts in artboxes [key]:
|
||||||
|
print ('%s;%s;%s;%0.2f;%s' % (key[0], key[1], knr, weight / 100.0, rfzts))
|
||||||
|
|
||||||
151
IPKT.py
Normal file
151
IPKT.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#l!/usr/bin/env python2.6
|
||||||
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "1 August 2010"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.0 $"[11:-2]
|
||||||
|
|
||||||
|
class IPKT:
|
||||||
|
def ipkt (self, values):
|
||||||
|
ipoint_id = values ['location']
|
||||||
|
|
||||||
|
boxnr = values ['box_nr']
|
||||||
|
try:
|
||||||
|
boxnr = int (boxnr)
|
||||||
|
except:
|
||||||
|
self.log ( "At IPKT: Bad Box Nr reset to 0")
|
||||||
|
boxnr = 0
|
||||||
|
|
||||||
|
gtin = values ['gtin']
|
||||||
|
article = values ['article']
|
||||||
|
duedate = values ['duedate']
|
||||||
|
pieces = values ['pieces']
|
||||||
|
try:
|
||||||
|
pieces = int (pieces)
|
||||||
|
except:
|
||||||
|
self.log ( "At IPKT: Bad Pieces '%s' reset to 0 " % pieces)
|
||||||
|
pieces = 0
|
||||||
|
|
||||||
|
destination = values ['destination']
|
||||||
|
try:
|
||||||
|
destination = int (destination)
|
||||||
|
except:
|
||||||
|
self.log ( "At IPKT: Bad Destination reset to 99")
|
||||||
|
destination = 99
|
||||||
|
|
||||||
|
lotnr = values ['lotnr']
|
||||||
|
try:
|
||||||
|
int (lotnr)
|
||||||
|
except:
|
||||||
|
lotnr = '0'
|
||||||
|
lotnr2 = values ['lotnr2']
|
||||||
|
|
||||||
|
# IPKT Telegram --> check data and rem. place in Storage and res in Iqueue
|
||||||
|
DB_con = self.connections['DB']
|
||||||
|
if ipoint_id not in self.transportmatrix['dstbysrc']:
|
||||||
|
self.log ( "At IPKT: Not Transports in Matrix for IPKT %s" % ipoint_id)
|
||||||
|
|
||||||
|
|
||||||
|
if not boxnr:
|
||||||
|
self.message (6, ' At IPKT bad Boxnr')
|
||||||
|
return 98 # Bad BoxNr
|
||||||
|
|
||||||
|
_state = 0
|
||||||
|
|
||||||
|
boxes = DB_con.searchbox (boxnr)
|
||||||
|
storage = 'NONE'
|
||||||
|
if not _state and boxes:
|
||||||
|
self.message (6, ' At IPKT Box is already in Storage further checks')
|
||||||
|
for _rid, _rboxnr, _rarticle, _rlotnr, _rlotnr2, _duedate, _rpieces, _rx, _ry, _rz, _rrfzts in boxes:
|
||||||
|
if _rrfzts:
|
||||||
|
#Already Inserted
|
||||||
|
_state = 94 #Already exists
|
||||||
|
self.log ( "At IPKT: box %s already inserted in Storage %s" % (boxnr, _rid))
|
||||||
|
self.message (6, " At IPKT Box %s is already inserted in %s X:%d, Y:%d, Z:%d with article %s" \
|
||||||
|
% (_rboxnr, _rid, _rx, _ry, _rz, _rarticle))
|
||||||
|
else:
|
||||||
|
#Just reserved
|
||||||
|
if len (boxes) == 1:
|
||||||
|
self.message (6, " At IPKT Box is only reserved (one time) in %s" % _rid)
|
||||||
|
DB_con.deletetransport (ipoint_id, boxnr)
|
||||||
|
#DB_con.removebox (_boxnr)
|
||||||
|
|
||||||
|
DB_con.deletealltransports (boxnr)
|
||||||
|
DB_con.deleteincomingbox (boxnr)
|
||||||
|
DB_con.removebox (_rid , boxnr)
|
||||||
|
|
||||||
|
if DB_con.getincomingbox (boxnr):
|
||||||
|
self.message (6, " At IPKT Box %s is already in Inqueue delete first" % boxnr)
|
||||||
|
DB_con.deleteincomingbox (boxnr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if not _state:
|
||||||
|
#Box not existing - Reserve Box
|
||||||
|
self.log ( "At IPKT: box %s not inserted try to find a Place" % boxnr)
|
||||||
|
DB_con.deletealltransports (boxnr)
|
||||||
|
|
||||||
|
#Get Article information
|
||||||
|
if article not in self.articlemaster and not _state:
|
||||||
|
self.message (5,' IPKT Article not in Articlebase')
|
||||||
|
if self.parameter.get ('articlemustbedefined', 1):
|
||||||
|
_state = 91 #Article not existent
|
||||||
|
else:
|
||||||
|
_anr = article
|
||||||
|
_cap = 'undefined',
|
||||||
|
_gtin = ''
|
||||||
|
_normam = 0
|
||||||
|
_minam = 0
|
||||||
|
_zone = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
_cap, _gtin, _normam, _minam, _zone = self.articlemaster[article]
|
||||||
|
|
||||||
|
|
||||||
|
#Disabled
|
||||||
|
#_state = 93 #Younger Lots in Storage
|
||||||
|
|
||||||
|
_deststorage = ''
|
||||||
|
if not _state:
|
||||||
|
#All Ok till now so check the weight
|
||||||
|
self.message (5,' IPKT Check Pieces')
|
||||||
|
if not pieces:
|
||||||
|
_state = 90 #90 Bad weight
|
||||||
|
elif (pieces >= _normam) or 1: #Assume Full Pallet
|
||||||
|
#Full Pallet into T001
|
||||||
|
if ipoint_id in ['I001', 'I002']:
|
||||||
|
_deststorage = 'T001'
|
||||||
|
else:
|
||||||
|
_deststorage = 'S002'
|
||||||
|
elif pieces >= _minam:
|
||||||
|
#Full Pallet into S001
|
||||||
|
if ipoint_id in ['I001', 'I002']:
|
||||||
|
_deststorage = 'S001'
|
||||||
|
else:
|
||||||
|
_deststorage = 'S002'
|
||||||
|
|
||||||
|
if not _state:
|
||||||
|
#default article try to find a Place
|
||||||
|
self.message (5,' IPKT Reserve Place Article at %s' %_deststorage)
|
||||||
|
_res = None
|
||||||
|
for storage, rfzNr, rfzOut, mode, prio in self.transportmatrix['dstbysrc'][ipoint_id]:
|
||||||
|
#Normal article
|
||||||
|
if (storage == _deststorage):
|
||||||
|
self.message (6, " At IPKT: check possible Transport for Std Article to %s by RFZ %s with prio %s" % (storage, rfzNr, prio))
|
||||||
|
_res = self.boxreserve ('RFZ%s' % rfzNr, ipoint_id, 0, 0, 0, \
|
||||||
|
boxnr, article, lotnr, lotnr2, duedate, pieces, storage, _zone, noreserve = 1)
|
||||||
|
|
||||||
|
|
||||||
|
if not _res:
|
||||||
|
_state = 92 #No Place
|
||||||
|
|
||||||
|
if not _state:
|
||||||
|
DB_con.addincomingbox (ipoint_id, boxnr, article, gtin, lotnr, lotnr2, duedate, pieces, _deststorage, destination)
|
||||||
|
self.message (6, " At IPKT: Create Transport with State %s" % (_state))
|
||||||
|
DB_con.createtransport (boxnr, ipoint_id, ipoint_id, 0, 0, 0, storage, destination, 0, _state)
|
||||||
|
self.generatetransport (ipoint_id, boxnr)
|
||||||
|
#DB_con.deletetransport ('IPKT', int (boxnr))
|
||||||
|
|
||||||
|
return _state
|
||||||
|
|
||||||
113
IPKT_tel.py
Normal file
113
IPKT_tel.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python2.6
|
||||||
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_IPKT
|
||||||
|
from utility import *
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a IPKT from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TELEGRAM
|
||||||
|
"""
|
||||||
|
tel = TEL_IPKT ()
|
||||||
|
tel.attrib['nr'] = (ord (data [0]) << 8) + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
tel.attrib['box_nr'] = data [12:12 + ord (data [11])]
|
||||||
|
#tel.attrib['box_nr'] = (ord (data [10]) << 24) + (ord (data [11]) << 16) + (ord (data [12]) << 8) + ord (data [13])
|
||||||
|
tel.attrib['location'] = data [22:26].strip ().lstrip ('0')
|
||||||
|
tel.attrib['gtin'] = data [28:28 + ord (data [27])].strip ().lstrip ('0')
|
||||||
|
tel.attrib['article'] = data [44:44 + ord (data [43])].strip ().lstrip ('0')
|
||||||
|
tel.attrib['duedate'] = data [56:56 + ord (data [55])].strip ().lstrip ('0')
|
||||||
|
tel.attrib['lotnr'] = data [66:66 + ord (data [65])].strip ().lstrip ('0')
|
||||||
|
tel.attrib['lotnr2'] = data [74:74 + ord (data [73])].replace (' ','0') #99,99 Kilos
|
||||||
|
tel.attrib['pieces'] = data [82:82 + ord (data [81])].replace (' ','0').lstrip ('0')
|
||||||
|
#tel.attrib['destination'] = (ord (data [60]) << 8) + ord (data [59])
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_IPKT (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', location = 'I001', boxnr = 123 , artnr ='12345', lotnr='123', duedate='123456', weight='12.34', pieces='1234', destination = 123, *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_IPKT
|
||||||
|
self.data = ''
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = src
|
||||||
|
self.attrib['dst'] = dst
|
||||||
|
self.attrib['type'] = 'IPKT'
|
||||||
|
self.attrib['box_nr'] = boxnr
|
||||||
|
self.attrib['location'] = location
|
||||||
|
self.attrib['gtin'] = artnr
|
||||||
|
self.attrib['article'] = artnr
|
||||||
|
self.attrib['duedate'] = duedate
|
||||||
|
self.attrib['lotnr'] = lotnr
|
||||||
|
self.attrib['lotnr2'] = lotnr
|
||||||
|
self.attrib['pieces'] = pieces
|
||||||
|
self.attrib['destination'] = destination
|
||||||
|
|
||||||
|
self.__buildstring ()
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "IPKT TELEGRAM\n"
|
||||||
|
|
||||||
|
def __buildstring (self):
|
||||||
|
"""
|
||||||
|
Creates Datastring from Attributes
|
||||||
|
"""
|
||||||
|
self.data = chr ((self.attrib['nr'] >> 8) & 0xFF) + chr (self.attrib['nr'] & 0xFF) +\
|
||||||
|
self.attrib['src'] +\
|
||||||
|
self.attrib['dst'] +\
|
||||||
|
self.attrib['type'] +\
|
||||||
|
chr ((self.attrib['box_nr'] >> 24) & 0xFF) + chr ((self.attrib['box_nr'] >> 16) & 0xFF) + chr((self.attrib['box_nr'] >> 8) & 0xFF) + chr (self.attrib['box_nr'] & 0xFF) +\
|
||||||
|
self.attrib['location'] +\
|
||||||
|
fillchar (str (self.attrib['article']), 10) +\
|
||||||
|
fillchar (str (self.attrib['lotnr']), 10) +\
|
||||||
|
fillchar (str (self.attrib['pieces']), 10) +\
|
||||||
|
chr ((self.attrib['destination'] >> 8) & 0xFF) + chr (self.attrib['destination'] & 0xFF)
|
||||||
|
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + 4l
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = self.identify () #+ DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
104
LEBE_tel.py
Normal file
104
LEBE_tel.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
"""
|
||||||
|
lifebeat (LEBE) - Telegram
|
||||||
|
.. module:: LEBE
|
||||||
|
|
||||||
|
.. todo: Test
|
||||||
|
|
||||||
|
.. _lebe-content:
|
||||||
|
|
||||||
|
Lifebeat
|
||||||
|
========
|
||||||
|
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
ID Byte-Pos Type Value Description
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
Sequence-Nr 0:2 SINT16 0..32767 Telegramcounter
|
||||||
|
Tel-Source 2:4 CHAR[2] ['TP','LV'] Source of Telegram (to be removed in next versions)
|
||||||
|
Tel-Destination 4:6 CHAR[2] ['TP','LV'] Destination of Telegram (to be removed in next versions)
|
||||||
|
Tel-Type 6:10 CHAR[4] 'LEBE' Ident of Telegram (prepared to multiplex Channels)
|
||||||
|
STATE 10:12 WORD irrelevant for future use
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
"""
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_LEBE
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a LEBE_Tel from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
tel = TEL_LEBE ()
|
||||||
|
tel.attrib['nr'] = ord (data [0]) << 8 + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
tel.attrib['state'] = data [10:12]
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_LEBE (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_LEBE
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = src
|
||||||
|
self.attrib['dst'] = dst
|
||||||
|
self.attrib['type'] = 'LEBE'
|
||||||
|
self.attrib['state'] = '%c%c' % (1, 0)
|
||||||
|
|
||||||
|
self.__buildstring ()
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "LEBE TELEGRAM\n"
|
||||||
|
|
||||||
|
def __buildstring (self):
|
||||||
|
"""
|
||||||
|
Creates Datastring from Attribs
|
||||||
|
"""
|
||||||
|
self.data = chr ((self.attrib['nr'] >> 8) & 0xFF) + chr (self.attrib['nr'] & 0xFF) +\
|
||||||
|
self.attrib['src'] + self.attrib['dst'] + self.attrib['type'] + self.attrib['state']
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = self.identify () # + DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
110
Ordering.py
Executable file
110
Ordering.py
Executable file
@@ -0,0 +1,110 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import sys,string
|
||||||
|
from datetime import datetime
|
||||||
|
import os
|
||||||
|
import codecs
|
||||||
|
|
||||||
|
|
||||||
|
class ORDERING:
|
||||||
|
def __init__ (self, *dummy, **args):
|
||||||
|
"""
|
||||||
|
Initialize an new Ordering module
|
||||||
|
"""
|
||||||
|
self.path = args.get ("path", "/opt/sap")
|
||||||
|
self.path += self.path[-1] != '/' and '/' or ''
|
||||||
|
|
||||||
|
def setloggingmethods (self, log, message):
|
||||||
|
self.log = log
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
def message (self, level, msg):
|
||||||
|
"""
|
||||||
|
Dummy Message if not overloaded
|
||||||
|
"""
|
||||||
|
dt = datetime.now ()
|
||||||
|
print ("DB-LOG %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):
|
||||||
|
"""
|
||||||
|
Dummy Logging if not overloaded
|
||||||
|
"""
|
||||||
|
dt = datetime.now ()
|
||||||
|
print ("DB-LOG %4d-%02d-%02d %02d:%02d:%02d.%06d: " %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond)),
|
||||||
|
print msg
|
||||||
|
|
||||||
|
|
||||||
|
def orderfiles (self):
|
||||||
|
"""
|
||||||
|
returns list of exportfiles found in path
|
||||||
|
"""
|
||||||
|
#return filter (lambda f: ".exp" in f, os.listdir (self.path))
|
||||||
|
return filter (lambda f: "O_" == f[:2], os.listdir (self.path))
|
||||||
|
|
||||||
|
|
||||||
|
def archiveorderfile (self, filename):
|
||||||
|
"""
|
||||||
|
Move file to archive
|
||||||
|
processed Subfolder is obligatoric
|
||||||
|
"""
|
||||||
|
os.rename (self.path + filename, self.path + "processed/" + filename)
|
||||||
|
|
||||||
|
|
||||||
|
def orderheader (self, data):
|
||||||
|
"""
|
||||||
|
E2VPPIH 03400000000024436740000010000000100011835090001 002010100620101006 44.850 KG 0.000 MENSA UNI KLAGENFURT OESTERR.MENSEN BETRIEBSGMBH UNI - BUFFET UNIVERSITAETSSTR. 65-67 AT 9020 KLAGENFURT
|
||||||
|
"""
|
||||||
|
ret_val = {}
|
||||||
|
ret_val ['orderid'] = data [63:73].lstrip ('0')
|
||||||
|
ret_val ['overall_weight'] = data [121:135].lstrip (' ')
|
||||||
|
ret_val ['overall_weight_unit'] = data [135:138].lstrip (' ')
|
||||||
|
ret_val ['deliverydate'] = data [113:121]
|
||||||
|
ret_val ['cust'] = data [153:192].lstrip (' ').rstrip (' ').replace ("'",'')
|
||||||
|
ret_val ['cust2'] = data [192:254].lstrip (' ').rstrip (' ').replace ("'",'')
|
||||||
|
ret_val ['cust_street'] = data [254:335].lstrip (' ').rstrip (' ')
|
||||||
|
ret_val ['cust_country'] = data [335:370].lstrip (' ').rstrip (' ')
|
||||||
|
ret_val ['cust_postcode'] = data [370:374].lstrip (' ').rstrip (' ')
|
||||||
|
ret_val ['cust_city'] = data [376:390].lstrip (' ').rstrip (' ')
|
||||||
|
return ret_val
|
||||||
|
|
||||||
|
def orderline (self, data):
|
||||||
|
"""
|
||||||
|
E2VPPII 0.00 14.780 034000000000241359800000300000102000116862300004001 000000000000001320R-KALBIN H?FTE AT 0001001 15.000 15.000 15.000 KG KG 1 1 601000 20100902 0011149314 15.000 15.000 KG 0.000
|
||||||
|
E2VPPII002 034000000000244361100000400000102008018550500003002 000000000000007603K?RNTNER ROHWURST 300g 0001001 4.000 4.000 4.000 ST ST 1 1 647000 20101006 4500185836 1.200 1.200 KG 0.000
|
||||||
|
"""
|
||||||
|
ret_val = {}
|
||||||
|
ret_val ['article'] = data [121:139].lstrip ('0')
|
||||||
|
ret_val ['caption'] = data [139:179].rstrip (' ')
|
||||||
|
ret_val ['order_amount'] = data [236:251].lstrip (' ')
|
||||||
|
ret_val ['order_amount_unit'] = data [251:254].lstrip (' ')
|
||||||
|
ret_val ['order_weight'] = data [334:349].lstrip (' ')
|
||||||
|
ret_val ['order_weight_unit'] = data [349:352].lstrip (' ')
|
||||||
|
return ret_val
|
||||||
|
|
||||||
|
def decodefile (self, filename):
|
||||||
|
"""
|
||||||
|
Decodes Orderfile and returns (orderheader, [orderlines])
|
||||||
|
"""
|
||||||
|
_header = None
|
||||||
|
_orderlines = []
|
||||||
|
self.message (6, "Ordering: Decoding Orderfile %s" % filename)
|
||||||
|
sfile = codecs.open (self.path + filename, "r", "latin-1")
|
||||||
|
for line in sfile:
|
||||||
|
if line.find ("EDI_DC40") >= 0:
|
||||||
|
self.message (6, "Ordering: EDoc-Header found")
|
||||||
|
elif line.find ("E2VPPIH") >= 0:
|
||||||
|
self.message (6, "Ordering: Order-Header found")
|
||||||
|
_header = self.orderheader (line)
|
||||||
|
elif line.find ("E2VPPII") >= 0:
|
||||||
|
_orderlines.append (self.orderline (line))
|
||||||
|
else:
|
||||||
|
self.log ("Ordering: found invalid line in Orderfile: '%s'" % line)
|
||||||
|
sfile.close ()
|
||||||
|
return (_header, _orderlines)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ordering = ORDERING (path ='/opt/sap')
|
||||||
|
for i in ordering.orderfiles ():
|
||||||
|
print ordering.decodefile (i)
|
||||||
|
|
||||||
75
QUIT_tel.py
Executable file
75
QUIT_tel.py
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_QUIT
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a LEBE_Tel from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
tel = TELLEBE ()
|
||||||
|
tel.attrib['nr'] = ord (data [0]) << 8 + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TELQUIT (TELEGRAM):
|
||||||
|
def __init__ (self, data = "", *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_LEBE
|
||||||
|
self.attrib['nr'] = data [0:2]
|
||||||
|
self.attrib['src'] = data [2:4]
|
||||||
|
self.attrib['dst'] = data [4:6]
|
||||||
|
self.attrib['type'] = data [6:10]
|
||||||
|
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "LEBE TELEGRAM\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = self.identify () # + DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
173
SCLS.py
Normal file
173
SCLS.py
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
from time import time
|
||||||
|
class SCLS:
|
||||||
|
def scls (self, ret_val):
|
||||||
|
DB_con = self.connections['DB']
|
||||||
|
# SCLS Telegram --> act according to Read position
|
||||||
|
if ret_val ['location'] == 'IPKT':
|
||||||
|
#IKPT
|
||||||
|
self.log ( "SCLS at IPKT box %(box_nr)s destiation %(destination)d" % ret_val)
|
||||||
|
|
||||||
|
elif ret_val ['location'] in ['RFZ1', 'RFZ2']:
|
||||||
|
#FiXMe
|
||||||
|
_quit = 0
|
||||||
|
#RFZ
|
||||||
|
_dz = 0
|
||||||
|
self.log ( "SCLS at %(location)s box %(box_nr)s destiation %(destination)d" % ret_val)
|
||||||
|
self.message (6, "SCLS at %(location)s box %(box_nr)s destiation %(destination)d" % ret_val)
|
||||||
|
if ret_val ['destination'] == 0:
|
||||||
|
#Destination 0 - Box from Pickup Position loaded --> get TAUF
|
||||||
|
self.message (3, ' DT_handler : SCLS from %s (Box from Pickuppos) --> generate TAUF for RFZ' % ret_val ['location'])
|
||||||
|
_box = None
|
||||||
|
sboxnr = int (ret_val['box_nr'])
|
||||||
|
if sboxnr != 0:
|
||||||
|
#No NOREAD
|
||||||
|
_boxes = DB_con.getincomingbox (sboxnr)
|
||||||
|
if _boxes and len(_boxes):
|
||||||
|
_box = _boxes [0]
|
||||||
|
|
||||||
|
if _box:
|
||||||
|
self.message (3, ' DT_handler : SCLS Box is in Inqueue search a Place')
|
||||||
|
_boxes = DB_con.searchbox (sboxnr)
|
||||||
|
storage = 'NONE'
|
||||||
|
if _boxes:
|
||||||
|
self.message (6, ' DT_handler : SCLS Box is already in Storage further checks')
|
||||||
|
for _rid, _rboxnr, _rarticle, _rlotnr, _rlotnr2, _duedate, _rpieces, _rx, _ry, _rz, _rrfzts in _boxes:
|
||||||
|
if _rrfzts:
|
||||||
|
self.log ( " DT_handler : SCLS Box %s is already inserted in Storage %s" % (sboxnr, _rid))
|
||||||
|
print ("Already in Storage impossible")
|
||||||
|
raise Warning
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (6, " DT_handler : SCLS Box is only reserved in %s" % _rid)
|
||||||
|
#Just reserved
|
||||||
|
if len (_boxes) == 1:
|
||||||
|
self.message (6, " DT_handler : SCLS Box is only reserved (one time) in %s" % _rid)
|
||||||
|
|
||||||
|
DB_con.removebox (_rid , sboxnr)
|
||||||
|
|
||||||
|
DB_con.deletealltransports (sboxnr)
|
||||||
|
|
||||||
|
location, boxnr, article, gtin, lotnr, lotnr2, duedate, pieces, deststorage, destination = _box
|
||||||
|
#Fixme Zone from Articlebase
|
||||||
|
_zone = 1
|
||||||
|
_res = 0
|
||||||
|
for storage, rfzNr, rfzOut, mode, prio in self.transportmatrix['dstbysrc'][location]:
|
||||||
|
#Normal article
|
||||||
|
if (storage == deststorage):
|
||||||
|
self.message (6, " DT_handler : SCLSTransport for Std Article to %s by RFZ %s with prio %s" % (storage, rfzNr, prio))
|
||||||
|
_res = self.boxreserve ('RFZ%s' % rfzNr, location, 0, 0, 0, \
|
||||||
|
boxnr, article, lotnr, lotnr2, duedate, pieces, storage, _zone, noreserve = 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if not _res:
|
||||||
|
print ("Kann nicht sein dass kein Platz ist")
|
||||||
|
raise Warning
|
||||||
|
self.generatetransport (ret_val['location'], sboxnr)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print ("Scheisse")
|
||||||
|
raise Warning
|
||||||
|
#Box is not in Inqueue
|
||||||
|
self.log ( "At %(location)s: box %(box_nr)s is not in Inqueue --> try to find Transport or generate Errorslot" % ret_val)
|
||||||
|
if ret_val ['location'] in self.transportmatrix['errordst']:
|
||||||
|
_dst, _dstx, _dsty, _prio = self.transportmatrix['errordst'][ret_val ['location']]
|
||||||
|
DB_con.createtransport (ret_val['box_nr'], ret_val['location'], 'IRFZ', 0, 0, 0, _dst, _dstx, _dsty, 0)
|
||||||
|
self.generatetransport (ret_val['location'], ret_val['box_nr'])
|
||||||
|
else:
|
||||||
|
self.log ( "At %(location)s: Nor Errordestination for this Position - send Takeoff Transport" % ret_val)
|
||||||
|
DB_con.createtransport (ret_val['box_nr'], ret_val['location'], 'IRFZ', 0, 0, 0, ret_val['location'], 0, 0, 1)
|
||||||
|
self.generatetransport (ret_val['location'], ret_val['box_nr'])
|
||||||
|
|
||||||
|
|
||||||
|
elif ret_val ['destination'] == 2:
|
||||||
|
self.message (3, ' DT_handler : SCLS from RFZ1 --> deletebox')
|
||||||
|
self.log ( "SCLS at RFZ1 box %(box_nr)s destiation %(destination)d" % ret_val)
|
||||||
|
|
||||||
|
# Make sure that manual intervention gets rid of the box also
|
||||||
|
article = None
|
||||||
|
box = None
|
||||||
|
if _storage_type != 4:
|
||||||
|
box = DB_con.searchbox (ret_val['box_nr'], 'Puffer')
|
||||||
|
if box:
|
||||||
|
self.removebox ('Puffer', ret_val['box_nr'])
|
||||||
|
article = box[1]
|
||||||
|
|
||||||
|
# space is available
|
||||||
|
# NewPRIO
|
||||||
|
#if article:
|
||||||
|
# self.checkspaceandmove (article)
|
||||||
|
|
||||||
|
elif ret_val ['location'] == 'HBCL1':
|
||||||
|
_quit = 0
|
||||||
|
self.message (3, ' DT_handler : SCLS from HBCL1 --> delete Boxes from Storage')
|
||||||
|
self.log ( "SCLS at HBCL1 box %(box_nr)s destination %(destination)d " % ret_val)
|
||||||
|
try:
|
||||||
|
_boxnr = int (ret_val['box_nr'])
|
||||||
|
_dest = ret_val['destination']
|
||||||
|
if int (_dest) > 0:
|
||||||
|
DB_con.deletetauf ('DEST', _boxnr)
|
||||||
|
self.createtauf (_boxnr, 'DEST', 'MDES', 0, 0, 0, 'Puffer', 0, 0, _dest)
|
||||||
|
self.generatetauf ('DEST', _boxnr)
|
||||||
|
DB_con.deletetauf ('DEST', _boxnr)
|
||||||
|
except:
|
||||||
|
_dest = 0
|
||||||
|
print ('Shit')
|
||||||
|
raise Warning
|
||||||
|
|
||||||
|
|
||||||
|
# Make sure that manual intervention gets rid of the box also
|
||||||
|
article = None
|
||||||
|
box = None
|
||||||
|
if _storage_type != 4:
|
||||||
|
box = DB_con.searchbox (ret_val['box_nr'], 'Puffer')
|
||||||
|
if box:
|
||||||
|
self.removebox ('Puffer', ret_val['box_nr'])
|
||||||
|
article = box[1]
|
||||||
|
if not box:
|
||||||
|
box = DB_con.searchbox (ret_val['box_nr'], 'Pick')
|
||||||
|
if box: #DANI return war scheie wg. counter zaehlung
|
||||||
|
self.log ( "SCLS at HBCL1 box %(box_nr)s was in Pick %(destination)d " % ret_val)
|
||||||
|
self.removebox ('Pick', ret_val['box_nr'])
|
||||||
|
article = box[1]
|
||||||
|
if not box:
|
||||||
|
box = DB_con.searchbox (ret_val['box_nr'], 'ENESPi')
|
||||||
|
if box:
|
||||||
|
self.removebox ('ENESPi' , ret_val['box_nr'])
|
||||||
|
|
||||||
|
|
||||||
|
elif ret_val ['location'] in ['B004', 'B006']:
|
||||||
|
self.log ("SCLS at %(location)s for box %(box_nr)s with destination %(destination)d Delete from Outqueue" % ret_val)
|
||||||
|
deletedz = DB_con.removebox ('Outqueue', int (ret_val['box_nr']))
|
||||||
|
_waitinjection = 0
|
||||||
|
DB_con.createtransport (int (ret_val['box_nr']), _pusher, _pusher, 0, 0, 0, _pusher, 0, _waitinjection, 0)
|
||||||
|
self.generatetransport (_pusher, int (ret_val['box_nr']))
|
||||||
|
_quit = 0
|
||||||
|
|
||||||
|
elif ret_val ['location'] in ['B005', 'B007', 'H001', 'H002']:
|
||||||
|
deletedz = DB_con.removebox ('Outqueue', int (ret_val['box_nr']))
|
||||||
|
self.log ( "SCLS at %(location)s for box %(box_nr)s with destination %(destination)d Sending TAUF to indicate new Box" % ret_val)
|
||||||
|
if ret_val ['location'] in ['B005', 'H002']:
|
||||||
|
_opoint = 'O001'
|
||||||
|
elif ret_val ['location'] in ['B007', 'H001']:
|
||||||
|
_opoint = 'O002'
|
||||||
|
|
||||||
|
|
||||||
|
if self.parameter.get ('triggerbox-%s' % _opoint, -1) == int (ret_val['box_nr']):
|
||||||
|
self.message (3, "SCLS resetting triggerbox for %s" % _opoint)
|
||||||
|
self.parameter['triggerbox-%s' % _opoint] = 0
|
||||||
|
|
||||||
|
elif ret_val ['location'][0] == 'B':
|
||||||
|
self.log ( "SCLS at %(location)s for box %(box_nr)s with destination %(destination)d " % ret_val)
|
||||||
|
_quit = 0
|
||||||
|
|
||||||
|
elif ret_val ['location'][0] == 'H':
|
||||||
|
self.log ( "SCLS at %(location)s for box %(box_nr)s with destination %(destination)d " % ret_val)
|
||||||
|
_quit = 0
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.log ( "SCLS at undefined postion %(location)s for box %(box_nr)s with destination %(destination)d " % ret_val)
|
||||||
|
_quit = 20
|
||||||
|
|
||||||
|
#Return Value for Quit telegram
|
||||||
|
return _quit
|
||||||
125
SCLS_tel.py
Executable file
125
SCLS_tel.py
Executable file
@@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
"""
|
||||||
|
Scanner (SCLS) - Telegram
|
||||||
|
.. module:: SCLS
|
||||||
|
|
||||||
|
.. _scls-content:
|
||||||
|
|
||||||
|
Scanner
|
||||||
|
=======
|
||||||
|
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
ID Byte-Pos Type Value Description
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
Sequence-Nr 0:2 SINT16 0..32767 Telegramcounter
|
||||||
|
Tel-Source 2:4 CHAR[2] ['TP','LV'] Source of Telegram (to be removed in next versions)
|
||||||
|
Tel-Destination 4:6 CHAR[2] ['TP','LV'] Destination of Telegram (to be removed in next versions)
|
||||||
|
Tel-Type 6:10 CHAR[4] 'SCLS' Ident of Telegram (prepared to multiplex Channels)
|
||||||
|
BoxNr 10:14 UINT32 '2147483647' BoxNr - PLC uses UINT32 by now so Max=2147483647
|
||||||
|
Positon 14:18 CHAR[4] '0001', 'RFZ1' Position of Scanner
|
||||||
|
Destination 18:20 SINT16 0..32767 Destination (e.g. to tell state / content of box)
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
|
||||||
|
Positions
|
||||||
|
=========
|
||||||
|
A Scanner telegram leads to different actions according to the Position. So the positions are in several Domains.
|
||||||
|
Valid Positiondomains are. (every Position may have higher Numbers)
|
||||||
|
|
||||||
|
======== ==================== ===========================================================
|
||||||
|
Position Pos-Type Action
|
||||||
|
======== ==================== ===========================================================
|
||||||
|
'I001' I-Point No Action - just logging - future Usage
|
||||||
|
'RFZ1' Shelf access equ. | Depending on Destination (Beta State: ToDo declare dests)
|
||||||
|
| 0: Box from Pickuppostiion --> generate Transport
|
||||||
|
| 1: Box from Reefedslot (will be changed)
|
||||||
|
| 2: just logging
|
||||||
|
'C001' Commisioning Shelf | PLC generated BCL - Read for storages with virtual BoxNrs
|
||||||
|
| Dest contains slotNr and indicates box removal
|
||||||
|
'B001' Scanner at conveyors Just a Scanner read anywhere log or do special funcitons
|
||||||
|
'H001' Handheld Reader Delete from Storage, and further fuctions
|
||||||
|
just for PLC hosted Handheld readers.
|
||||||
|
======== ==================== ===========================================================
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_SCLS
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a SCLS_tel from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TELEGRAM
|
||||||
|
"""
|
||||||
|
tel = TEL_SCLS ()
|
||||||
|
tel.attrib['nr'] = (ord (data [0]) << 8) + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
#tel.attrib['box_nr'] = (ord (data [10]) << 24) + (ord (data [11]) << 16) + (ord (data [12]) << 8) + ord (data [13]) #data [10:14].strip ()
|
||||||
|
tel.attrib['box_nr'] = data [12:12 + ord (data [11])]
|
||||||
|
tel.attrib['location'] = data [22:26].strip ().lstrip ('0')
|
||||||
|
tel.attrib['destination'] = (ord (data [26]) << 8) + ord (data [27])
|
||||||
|
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_SCLS (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', loc = 123, box = 123, dest=123 , *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_SCLS
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = src
|
||||||
|
self.attrib['dst'] = dst
|
||||||
|
self.attrib['type'] = 'SCLS'
|
||||||
|
self.attrib['location'] = loc
|
||||||
|
self.attrib['box_nr'] = box
|
||||||
|
self.attrib['destination'] = dest
|
||||||
|
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "LEBE TELEGRAM\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + 4l
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
print self.attrib
|
||||||
|
string = self.identify () #+ DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
82
STAT_tel.py
Executable file
82
STAT_tel.py
Executable file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_STAT
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a STAT_tel from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TELEGRAM
|
||||||
|
"""
|
||||||
|
tel = TEL_STAT ()
|
||||||
|
tel.attrib['nr'] = (ord (data [0]) << 8) + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
tel.attrib['location'] = data [10:14]
|
||||||
|
tel.attrib['state'] = data [14:16]
|
||||||
|
tel.attrib['error'] = data [16:len(data)]
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_STAT (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', loc = '1000', state='00', error = '0000' , *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_STAT
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = src
|
||||||
|
self.attrib['dst'] = dst
|
||||||
|
self.attrib['type'] = 'STAT'
|
||||||
|
self.attrib['location'] = loc
|
||||||
|
self.attrib['state'] = state
|
||||||
|
self.attrib['error'] = error
|
||||||
|
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "STAT TELEGRAM\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + 4l
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
print self.attrib
|
||||||
|
string = self.identify () #+ DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
203
TAUF_tel.py
Normal file
203
TAUF_tel.py
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
"""
|
||||||
|
transport (TAUF) - Telegram
|
||||||
|
.. module:: TAUF
|
||||||
|
|
||||||
|
.. _tauf-content:
|
||||||
|
|
||||||
|
Transport content
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
ID Byte-Pos Type Value Description
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
Sequence-Nr 0:2 SINT16 0..32767 Telegramcounter
|
||||||
|
Tel-Source 2:4 CHAR[2] ['TP','LV'] Source of Telegram (to be removed in next versions)
|
||||||
|
Tel-Destination 4:6 CHAR[2] ['TP','LV'] Destination of Telegram (to be removed in next versions)
|
||||||
|
Tel-Type 6:10 CHAR[4] 'TAUF' Ident of Telegram (prepared to multiplex Channels)
|
||||||
|
BoxNr 10:30 CHAR[20] '2147483647' BoxNr - PLC uses UINT32 by now so Max=2147483647
|
||||||
|
Positon 30:34 CHAR[4] 'I001', 'RFZ1' Position for executing Transport
|
||||||
|
Source 34:38 CHAR[4] 'I001', 'RFZ1', 'S001','T001' Sourcearea (I-Point, RFZ1, Storage) for Transport
|
||||||
|
SourceXX 38:40 CHAR[2] '00' Source-Coordinates X where neccersary
|
||||||
|
SourceYY 40:42 CHAR[2] '00' Source-Coordinates Y where neccersary
|
||||||
|
SourceZZ 42:44 CHAR[2] '00' Source-Coordinates Z where neccersary
|
||||||
|
Destination 44:48 CHAR[4] 'S001', 'T001' DestinationArea (Storage, Outfeedposition) for Transport
|
||||||
|
DestinationXX 48:50 CHAR[2] '00' Destination-Coordinates X where neccersary
|
||||||
|
DestinationYY 50:52 CHAR[2] '00' Destination-Coordinates Y where neccersary
|
||||||
|
DestinationZZ 52:54 CHAR[2] '00' Destination-Coordinates Z where neccersary
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
|
||||||
|
Positions
|
||||||
|
---------
|
||||||
|
Valid positions for Transports Indices may differ.
|
||||||
|
|
||||||
|
In case Source is a Storage, the fine Sources (XX, YY, ZZ) will also beused.
|
||||||
|
|
||||||
|
+---------+---------------------+-------+------------------------------------------------------+
|
||||||
|
|Position |Pos Type |Source |Action |
|
||||||
|
+=========+=====================+=======+======================================================+
|
||||||
|
|I001 |I-Point |I001 | | Start Box |
|
||||||
|
| | | | | DestinationXX finedestination put in PLC Hashtable |
|
||||||
|
| | | | | DestinationZZ errorcodes (see later) |
|
||||||
|
+---------+---------------------+-------+------------------------------------------------------+
|
||||||
|
|RFZ1 |Storage retrival eqm.| | I001| | Transport generated by an Scanner telegram on RFZ |
|
||||||
|
| | | | | | for inserting a box from an Pickup position |
|
||||||
|
| | | | RFZ1| | Alternative Transport (in case of overfill e.g.) |
|
||||||
|
| | | | T,S | | Automatic transport from a storage (refill, move) |
|
||||||
|
+---------+---------------------+-------+------------------------------------------------------+
|
||||||
|
|PU01 |Pusher |P001 | | Duouble function |
|
||||||
|
| | | | | DestinationXX finedestination put in PLC Hashtable |
|
||||||
|
| | | | | DestinationYY Unlock (0) Wait injection (1) |
|
||||||
|
+---------+---------------------+-------+------------------------------------------------------+
|
||||||
|
|O001 |Outpoint |O001 | | Indicate a new Order |
|
||||||
|
+---------+---------------------+-------+------------------------------------------------------+
|
||||||
|
|
||||||
|
Destinations
|
||||||
|
------------
|
||||||
|
The destinations for Transports are
|
||||||
|
|
||||||
|
+---------+---------------------+-----------------------------------------+
|
||||||
|
|T001 |Troughfeedshelf |Using fine Destinations (XX, YY, ZZ) |
|
||||||
|
+=========+=====================+=========================================+
|
||||||
|
|S002 |Single-Place-shelf | | Using fine Destinations (XX, YY, ZZ) |
|
||||||
|
| | | | ZZ == 1, will be used inf future |
|
||||||
|
+---------+---------------------+-----------------------------------------+
|
||||||
|
|C001 |Commisioning-shelf |Using fine Destinations (XX, YY, ZZ) |
|
||||||
|
+---------+---------------------+-----------------------------------------+
|
||||||
|
|O001 |Outfeedposition | | XX : Destination for PLC Hashtable |
|
||||||
|
| | | | Multiplexing 50 + |
|
||||||
|
| | | | ZZ : Order in ordered Outqueue |
|
||||||
|
+---------+---------------------+-----------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
I-Point Errorcodes (in DestZZ)
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Errorcodes handled (displayed) on the PLC
|
||||||
|
|
||||||
|
- 90 : Bad Weight (weightcheck active)
|
||||||
|
- 91 : Article not defined in articlemaster
|
||||||
|
- 92 : No place in storage
|
||||||
|
- 93 : Lotcheck failed (FIFO error)
|
||||||
|
- 94 : Box already in system
|
||||||
|
- 99 : Invalid BoxNr
|
||||||
|
|
||||||
|
Return Codes
|
||||||
|
------------
|
||||||
|
|
||||||
|
Transport specific Codes extenging the overall valid Codes
|
||||||
|
|
||||||
|
- 20 : Invalid source (main or finesource) in Transport
|
||||||
|
- 30 : Invalid destination (main or finedest) in Transport
|
||||||
|
- 5x : RFZx Occupied - Transport will be resent later
|
||||||
|
|
||||||
|
"""
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_TAUF
|
||||||
|
from utility import *
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TAUF from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TELEGRAM
|
||||||
|
"""
|
||||||
|
tel = TEL_TAUF ()
|
||||||
|
tel.attrib['nr'] = (ord (data [0]) << 8) + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
tel.attrib['state'] = (ord (data [10]) << 8) + ord (data [11])
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_TAUF (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', boxnr = 20 * ['0'], position = 'XXXX', source = 'XXXX', srcx = 'XX', srcy = 'YY', srcz = 'ZZ', dest = 'DDDD', destx = 'XX', desty = 'YY',destz = 'ZZ', *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_TAUF
|
||||||
|
self.data = ''
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = str (src)
|
||||||
|
self.attrib['dst'] = str (dst)
|
||||||
|
self.attrib['type'] = 'TAUF'
|
||||||
|
self.attrib['boxnr'] = str (boxnr)
|
||||||
|
self.attrib['position'] = str (position)
|
||||||
|
self.attrib['source'] = str (source)
|
||||||
|
self.attrib['srcx'] = str (srcx)
|
||||||
|
self.attrib['srcy'] = str (srcy)
|
||||||
|
self.attrib['srcz'] = str (srcz)
|
||||||
|
self.attrib['dest'] = str (dest)
|
||||||
|
self.attrib['destx'] = str (destx)
|
||||||
|
self.attrib['desty'] = str (desty)
|
||||||
|
self.attrib['destz'] = str (destz)
|
||||||
|
|
||||||
|
self.__buildstring ()
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "TAUF TELEGRAM\n"
|
||||||
|
|
||||||
|
def __buildstring (self):
|
||||||
|
"""
|
||||||
|
Creates Datastring from Attributes
|
||||||
|
chr (len (str (self.attrib['boxnr']))) +\
|
||||||
|
"""
|
||||||
|
self.data = chr ((self.attrib['nr'] >> 8) & 0xFF) + chr (self.attrib['nr'] & 0xFF) +\
|
||||||
|
self.attrib['src'] +\
|
||||||
|
self.attrib['dst'] +\
|
||||||
|
self.attrib['type'] +\
|
||||||
|
chr (10) +\
|
||||||
|
chr (10) +\
|
||||||
|
fillchar (str (self.attrib['boxnr']), 10) +\
|
||||||
|
self.attrib['position'] +\
|
||||||
|
self.attrib['source'] +\
|
||||||
|
doublechar (self.attrib['srcx']) +\
|
||||||
|
doublechar (self.attrib['srcy']) +\
|
||||||
|
doublechar (self.attrib['srcz']) +\
|
||||||
|
self.attrib['dest'] +\
|
||||||
|
doublechar (self.attrib['destx']) +\
|
||||||
|
doublechar (self.attrib['desty']) +\
|
||||||
|
doublechar (self.attrib['destz'])
|
||||||
|
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + 4l
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = self.identify () #+ DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
322
TQUI.py
Normal file
322
TQUI.py
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
class TQUI:
|
||||||
|
def tqui (self, ret_val):
|
||||||
|
_quit = 0
|
||||||
|
DB_con = self.connections['DB']
|
||||||
|
self.log ( " DT_handler : TQUI at %(location)s box %(box_nr)s src %(src_id)s dst %(dst_id)s state %(state)s" % ret_val)
|
||||||
|
# TQUI Telegram --> update DB
|
||||||
|
|
||||||
|
|
||||||
|
# 01 Order Complete, 11 Order Complete Dummy detected
|
||||||
|
if (ret_val ['state'] == "01"):
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Order complete')
|
||||||
|
if int (ret_val['box_nr'] >= 0):
|
||||||
|
if ret_val['location'] in ['RFZ1', 'RFZ2']:
|
||||||
|
DB_con.deletetransport (ret_val['location'], int (ret_val['box_nr']))
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI invalid Position - IGNORE')
|
||||||
|
|
||||||
|
if ret_val['location'] in ['RFZ1', 'RFZ2']:
|
||||||
|
self.message (3, ' DT_handler : TQUI location is %(location)s for box %(box_nr)s into storage %(dst_id)s' % ret_val)
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Update Box remove ghosts')
|
||||||
|
#Use Timestamp on storage moves
|
||||||
|
|
||||||
|
#Disabled Setting Insertiondate
|
||||||
|
_rfzts = None
|
||||||
|
|
||||||
|
#Other Transport
|
||||||
|
DB_con.setboxtimefillgap (ret_val['dst_id'], int (ret_val['box_nr']), _rfzts and _rfzts[0] or '')
|
||||||
|
#Box was From I-Point
|
||||||
|
if ret_val['src_id'][0:2] == 'I0':
|
||||||
|
DB_con.removebox ('Inqueue', int (ret_val['box_nr']))
|
||||||
|
else:
|
||||||
|
DB_con.removebox (ret_val['src_id'], int (ret_val['box_nr']))
|
||||||
|
|
||||||
|
if ret_val['src_id'] != 'IRFZ' and ret_val['dst_id'][0:2] == 'OP':
|
||||||
|
#Checking Transportmatrix what destination is kind of
|
||||||
|
self.message (6, ' DT_handler : TQUI for Transport to Outpoint')
|
||||||
|
DB_con.deleteoutgoingbox (int (ret_val['box_nr']), queueid = ret_val['dst_id'])
|
||||||
|
for dest, rfzNr, rfzOut, mode, prio in self.transportmatrix['dstbysrc'][ret_val['src_id']]:
|
||||||
|
if 'RFZ%d' % rfzNr == ret_val['location'] and 'OP%s' % rfzOut == ret_val['dst_id']:
|
||||||
|
#FixMe check also source
|
||||||
|
self.message (6, ' DT_handler : TQUI - Outpoint is at primary RFZ')
|
||||||
|
#In This case Check the box where to go
|
||||||
|
if 'ordering' in self.parameter and int (ret_val['dst_xx']) == int (dest[1:]) + 50:
|
||||||
|
#self.message (6, ' DT_handler : TQUI - Ordering is active add box to outqueue %s' % dest)
|
||||||
|
#DB_con.addoutgoingbox (dest, ret_val ['box_nr'], '', '', '', '', 99)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
#Errorboxes
|
||||||
|
boxnr = int (ret_val['box_nr'])
|
||||||
|
if ret_val['dst_id'][0] == 'T':
|
||||||
|
slot = None # DB_con.finderrorslot (ret_val['dst_id'])
|
||||||
|
if slot:
|
||||||
|
_dx, _dy = slot
|
||||||
|
if int (ret_val['dst_xx']) == _dx and int (ret_val['dst_yy']) == _dy:
|
||||||
|
#NoRead Boxes
|
||||||
|
boxes = DB_con.getboxesslot (ret_val['dst_id'], int (_dx), int (_dy))
|
||||||
|
boxnr = 0
|
||||||
|
if boxes:
|
||||||
|
nrs = [int (i[1]) for i in boxes]
|
||||||
|
print nrs
|
||||||
|
for i in range (999999800, 999999900):
|
||||||
|
if i not in nrs:
|
||||||
|
boxnr = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
boxnr = 999999800
|
||||||
|
|
||||||
|
if not boxnr:
|
||||||
|
self.log (" DT_handler couldn't find a boxNr for Errorslot")
|
||||||
|
DB_con.insertbox (ret_val['dst_id'], boxnr, int (_dx), int (_dy))
|
||||||
|
self.message (3, ' DT_handler : TQUI for Box in %s Errorslot with boxnr %s' % (ret_val['dst_id'], str (boxnr)))
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI location was %s' %ret_val['location'] )
|
||||||
|
#was setboxtime
|
||||||
|
#DB_con.setboxtimefillgap (ret_val['dst_id'], ret_val['box_nr'], '')
|
||||||
|
|
||||||
|
# 02 Order Aborted
|
||||||
|
elif ret_val ['state'] == "02":
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Order aborted')
|
||||||
|
#if ret_val['location'] == 'RFZ1':
|
||||||
|
#self.message (3, ' DT_handler : TQUI location was illegal')
|
||||||
|
#self.debug ()
|
||||||
|
|
||||||
|
#elif ret_val['location'] == 'RFZ2':
|
||||||
|
#self.deletetauf (ret_val['location'], ret_val['box_nr'])
|
||||||
|
#if (ret_val['dst_id'] is not 'Nota'):
|
||||||
|
# DB_con.removebox ('Puffer', ret_val['box_nr'])
|
||||||
|
# DB_con.removebox ('Pick', ret_val['box_nr'])
|
||||||
|
#if (ret_val['dst_id'] is 'Expr'):
|
||||||
|
# DB_con.removebox ('Express', ret_val['box_nr'])
|
||||||
|
|
||||||
|
# 03 Src result no crate --> getting boxes
|
||||||
|
elif ret_val ['state'] == "03":
|
||||||
|
self.message (3, ' DT_handler : TQUI -- No Crate ')
|
||||||
|
_unusableslots = DB_con.getunusableslots (ret_val['src_id'])
|
||||||
|
_x = int (ret_val['src_xx'])
|
||||||
|
_y = int (ret_val['src_yy'])
|
||||||
|
if (ret_val['src_id'], _x, _y) in _unusableslots:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- No Crate from Unusable slot')
|
||||||
|
else:
|
||||||
|
self.log ( " DT_handler : TQUI No Crate %(location)s box %(box_nr)s src %(src_id)s x %(src_xx)s y %(src_yy)s dst %(dst_id)s state %(state)s" % ret_val)
|
||||||
|
|
||||||
|
# 04 Dest result occupied --> lock slot assign box --> alternative
|
||||||
|
# TAUF Prio 1
|
||||||
|
elif ret_val ['state'] == "04":
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Dest Occupied')
|
||||||
|
#FixMe alternative jobs
|
||||||
|
if ret_val['location'] == 'RFZ':
|
||||||
|
self.deletetauf (ret_val['location'], ret_val['box_nr'])
|
||||||
|
DB_con.removebox ('Inqueue', ret_val['box_nr'])
|
||||||
|
|
||||||
|
_dx, _dy = DB_con.finderrorslot (_dest)
|
||||||
|
_dz = 0
|
||||||
|
self.createtauf (ret_val['box_nr'], 'RFZ1', 'RFZ1', 0, 0, 0, _dest, _dx, _dy, _dz)
|
||||||
|
self.generatetransport ('RFZ1', ret_val['box_nr'])
|
||||||
|
|
||||||
|
|
||||||
|
# 05 Wrong box loaded
|
||||||
|
elif ret_val ['state'] == "05":
|
||||||
|
crtauf = 0
|
||||||
|
self.log (' DT_handler : TQUI -- Wrong Box Loaded at %s' % ret_val['location'])
|
||||||
|
if ret_val['location'] in ['RFZ1', 'RFZ2']:
|
||||||
|
ttauf = DB_con.getmovetransport (ret_val['location'], state = 'Sent')
|
||||||
|
if ttauf:
|
||||||
|
#Tauf for RFZ exists
|
||||||
|
tboxnr, tposition, tsrc, tsrcx, tsrcy, tsrcz, tdst, tdstx, tdsty, tdstz, tstate, tts = ttauf
|
||||||
|
#Box was from Throughfeed shelf
|
||||||
|
if (tsrc[0] == 'T'):
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box Loaded from %s" % tsrc)
|
||||||
|
locked = DB_con. getunusableslots (tsrc)
|
||||||
|
srcbox = DB_con.searchbox (int (ret_val['box_nr']), tsrc)
|
||||||
|
if not srcbox:
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box doesnt exist in source %s" % tsrc)
|
||||||
|
#Box is not in Source so create transport to errorslot and regenerate Transport because correct box may come
|
||||||
|
if tstate == 'Sent':
|
||||||
|
DB_con.setsenttransportnew (ret_val['location'], int (tboxnr), self.dummysrc)
|
||||||
|
#check if box is anywhere else
|
||||||
|
wboxes = DB_con.searchbox (int (ret_val['box_nr']))
|
||||||
|
for wbox in wboxes:
|
||||||
|
wboxstorage, wboxnr, wboxart, wboxlotnr, wboxweight, wboxx, wboxy, wboxz, wboxts = wbox
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box is in %s at x:%s y:%s z:%s" % (wboxstorage, wboxx, wboxy, wboxy))
|
||||||
|
DB_con.removebox (int (ret_val['box_nr']))
|
||||||
|
|
||||||
|
#Fixme Check if Box is in Refeed
|
||||||
|
#rfbox = DB_con.findrefeedbox (ret_val['box_nr'])
|
||||||
|
#if rfbox:
|
||||||
|
# rfknr, rfanr, rflog, rfgew, rfz, rfts = rfbox
|
||||||
|
# DB_con.deletefromrefeedatz (rfz)
|
||||||
|
DB_con.deletealltransports (ret_val['box_nr'])
|
||||||
|
if ret_val ['location'] in self.transportmatrix['errordst']:
|
||||||
|
_dst, _dstx, _dsty, _prio = self.transportmatrix['errordst'][ret_val ['location']]
|
||||||
|
_dest = _dst
|
||||||
|
_dx, _dy = _dstx, _dsty
|
||||||
|
_dz = 0
|
||||||
|
else:
|
||||||
|
self.log ( "At %(location)s: Nor Errordestination for this Position - send Takeoff Transport" % ret_val)
|
||||||
|
_dest = ret_val ['location']
|
||||||
|
_dx, _dy = 0, 0
|
||||||
|
_dz = 1
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
#elif True:
|
||||||
|
# print "FixMe TQUI"
|
||||||
|
else:
|
||||||
|
# Box exists in source
|
||||||
|
self.log (" Wrong loaded box exists in Source - sending Takeoff Transport")
|
||||||
|
_dest = ret_val ['location']
|
||||||
|
_dx, _dy = 0,0
|
||||||
|
_dz = 1
|
||||||
|
crtauf = 0
|
||||||
|
orgbnr = DB_con.getsenttrasnport (ret_val['location'], ret_val['src_id'], int (ret_val['src_xx']), int (ret_val['src_yy']))
|
||||||
|
try:
|
||||||
|
orgbnr = int (orgbnr[0])
|
||||||
|
except:
|
||||||
|
orgbnr = 0
|
||||||
|
|
||||||
|
if orgbnr:
|
||||||
|
#check if box is anywhere else
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box will be deleted from Outqucue ")
|
||||||
|
DB_con.removebox ('Outqueue', orgbnr)
|
||||||
|
wboxes = DB_con.searchbox (orgbnr)
|
||||||
|
for wbox in wboxes:
|
||||||
|
wboxstorage, wboxnr, wboxart, wboxlotnr, wboxduedate, wboxweight, wboxx, wboxy, wboxz, wboxts = wbox
|
||||||
|
if (ret_val['src_id'] <> wboxstorage):
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box exists also in %s at x:%s y:%s z:%s" % (wboxstorage, wboxx, wboxy, wboxy))
|
||||||
|
if not wboxts:
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box is only reserved in other location and will be deleted ")
|
||||||
|
DB_con.removebox (wboxstorage, orgbnr)
|
||||||
|
else:
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box is also in other location PROBLEM")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DB_con.deletetransport (ret_val['location'], orgbnr)
|
||||||
|
DB_con.createtransport (orgbnr, ret_val['location'], ret_val['location'], 0, 0, 0, ret_val['location'], 0, 0, 1)
|
||||||
|
self.generatetransport (ret_val['location'], orgbnr)
|
||||||
|
|
||||||
|
"""
|
||||||
|
srcboxstorage, srcboxnr, srcboxart, srcboxlotnr, srcboxweight, srcboxx, srcboxy, srcboxz, srcboxts = srcbox
|
||||||
|
if (int (tsrcx) == int (srcboxx)) and (int (tsrcy) == int (srcboxy)):
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box is from same Sourceslot")
|
||||||
|
#Correct slot -1st delete Transport and box as original reservation
|
||||||
|
self.deletettransport (ret_val['location'], tboxnr)
|
||||||
|
if (int (srcboxz) > 2):
|
||||||
|
self.message (3, " DT_handler : TQUI -- Wrong Box is from same Sourceslot and z > 2 delete also previous")
|
||||||
|
#FixMecheck for Chaotic slot
|
||||||
|
#if locked.get ((pbx, pby), 'None') == 'chaotisch':
|
||||||
|
# self.message (3, ' DT_handler : TQUI -- Wrong Box is from same Pufferslot, slot was chaotic')
|
||||||
|
# find boxes, check for TAUFs and for reservations chaos is impossible
|
||||||
|
zs = range (1, int (srcboxz))
|
||||||
|
zs.reverse ()
|
||||||
|
for i in zs:
|
||||||
|
self.message (5, "DT_handler : TQUI --Wrong Box from is from same Sourceslot an z > 2 cleaning x:%d, y:%d, z:%d" \
|
||||||
|
% (int (srcboxx), int (srcboxy), i))
|
||||||
|
prebox = DB_con.getboxbycoordinates (srcboxstorage, int (srcboxx), int (srcboxy), i)
|
||||||
|
#No check - MUST NOT FAIL
|
||||||
|
prbstorage, prbknr, prbanr, prbcharge, prbweight, prbx, prby, prbz, prbts = prebox
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Delete Box %s from %s x%s y%s z%s' % (prbknr, prbstorage, prbx, prby, prbz))
|
||||||
|
wbtauf = DB_con.gettransport ('RFZ2', int (prbknr))
|
||||||
|
#position, boxnr, state = ''
|
||||||
|
self.deletetauf ('RFZ2', int (prbknr))
|
||||||
|
DB_con.removepufferbox (int (prbknr))
|
||||||
|
DB_con.removepickbox (int (prbknr))
|
||||||
|
DB_con.removebox ('Express', int (prbknr)) # kill eventual reservation
|
||||||
|
rfbox = DB_con.findrefeedbox (ret_val['box_nr'])
|
||||||
|
if rfbox:
|
||||||
|
rfknr, rfanr, rflog, rfgew, rfz, rfts = rfbox
|
||||||
|
DB_con.deletefromrefeedatz (rfz)
|
||||||
|
|
||||||
|
|
||||||
|
DB_con.removepufferbox (int (tboxnr))
|
||||||
|
DB_con.removepickbox (int (tboxnr))
|
||||||
|
#Check for TAUFs on wrong box from same slot
|
||||||
|
wbtauf = DB_con.gettauf ('RFZ2', int (pbknr))
|
||||||
|
if wbtauf:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box already has TAUF')
|
||||||
|
wbtboxnr, wbtposition, wbtsrc, wbtsrcx, wbtsrcy, wbtsrcz, wbtdst, wbtdstx, wbtdsty, wbtdstz, wbtstate, wbtts = wbtauf[0]
|
||||||
|
if (wbtdst == tdst) and (wbtdstx == tdstx) and (wbtdsty == tdsty):
|
||||||
|
#Same destination so delete Transport and generat new one
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box already has Transport destination is ok so go on')
|
||||||
|
self.deletetauf ('RFZ2', int (wbtboxnr))
|
||||||
|
_dest = wbtdst
|
||||||
|
_dx = wbtdstx
|
||||||
|
_dy = wbtdsty
|
||||||
|
_dz = wbtdstz
|
||||||
|
crtauf = 1
|
||||||
|
elif (locked.get ((pbx, pby), 'None') != 'chaotisch'):
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box doesnt have Transport try to make pickreservation because from normal slot')
|
||||||
|
stamminfo = DB_con.getschachtstammarticle (pbanr)
|
||||||
|
if stamminfo:
|
||||||
|
stx, sty, stanr, stbez, stzone = stamminfo [0]
|
||||||
|
fill = DB_con.getfilllevel ('Pick')
|
||||||
|
stz = int (fill.get ((stx, sty), 0))
|
||||||
|
if stz < int (self.parameter["Z_PI"][int (stx) -1][int (sty) - 1]):
|
||||||
|
#Pick Rerservation is ok
|
||||||
|
DB_con.reservepickbox ('RFZ2', 'RFZ2', '0', '0', '0', int (pbknr), pbanr, pbweight, pbcharge, stx, sty, str (stz + 1))
|
||||||
|
self.deletetauf ('RFZ2', int (pbknr))
|
||||||
|
_dest = 'Pick'
|
||||||
|
_dx = stx
|
||||||
|
_dy = sty
|
||||||
|
_dz = str (stz + 1)
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box doesnt have Place in Pick so move to Errorslot')
|
||||||
|
_dest = 'Pick'
|
||||||
|
_dx, _dy = DB_con.finderrorslot ('Pick')
|
||||||
|
_dz = 0
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box doesnt have Stamminfo so move to Errrorslot')
|
||||||
|
_dest = 'Pick'
|
||||||
|
_dx, _dy = DB_con.finderrorslot ('Pick')
|
||||||
|
_dz = 0
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box doesnt have Transport and is from chaotic slot so move to Errrorslot')
|
||||||
|
_dest = 'Pick'
|
||||||
|
_dx, _dy = DB_con.finderrorslot ('Pick')
|
||||||
|
_dz = 0
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
#Other slot
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box is from other Pufferslot x:%s y:%s instead of x:%s y:%s ' %(pbx, pby, tsrcx, tsrcy))
|
||||||
|
DB_con.removepufferbox (ret_val['box_nr'])
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box move to Errrorslot')
|
||||||
|
_dest = 'Pick'
|
||||||
|
_dx, _dy = DB_con.finderrorslot ('Pick')
|
||||||
|
_dz = 0
|
||||||
|
crtauf = 1
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- No Sent TAUF')
|
||||||
|
self.log (" Wrong box Loaded")
|
||||||
|
#raise Warning
|
||||||
|
#There is no Transport for RFZ2 in sent taufs
|
||||||
|
|
||||||
|
if crtauf:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box create alternative job')
|
||||||
|
DB_con.createtransport (ret_val['box_nr'], ret_val['location'], ret_val['location'], 0, 0, 0, _dest, _dx, _dy, _dz)
|
||||||
|
self.generatetransport (ret_val['location'], ret_val['box_nr'])
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.message (3, ' DT_handler : TQUI -- Wrong Box Loaded invalid Position')
|
||||||
|
|
||||||
|
# unknown result
|
||||||
|
else:
|
||||||
|
self.message (2, ' DT_handler : TQUI -- unknown result')
|
||||||
|
_quit = 98
|
||||||
|
self.debug()
|
||||||
|
|
||||||
|
#Return Value for Quit telegram
|
||||||
|
return _quit
|
||||||
|
|
||||||
132
TQUI_tel.py
Executable file
132
TQUI_tel.py
Executable file
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
"""
|
||||||
|
transport result (TQUI) - Telegram
|
||||||
|
.. module:: TQUI
|
||||||
|
|
||||||
|
.. _tqui-content:
|
||||||
|
|
||||||
|
Transport result
|
||||||
|
================
|
||||||
|
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
ID Byte-Pos Type Value Description
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
Sequence-Nr 0:2 SINT16 0..32767 Telegramcounter
|
||||||
|
Tel-Source 2:4 CHAR[2] ['TP','LV'] Source of Telegram (to be removed in next versions)
|
||||||
|
Tel-Destination 4:6 CHAR[2] ['TP','LV'] Destination of Telegram (to be removed in next versions)
|
||||||
|
Tel-Type 6:10 CHAR[4] 'TQUI' Ident of Telegram (prepared to multiplex Channels)
|
||||||
|
BoxNr 10:30 CHAR[20] '2147483647' BoxNr - PLC uses UINT32 by now so Max=2147483647
|
||||||
|
Positon 30:34 CHAR[4] 'I001', 'RFZ1' Position for executing Transport
|
||||||
|
Source 34:38 CHAR[4] 'I001', 'RFZ1', 'S001','T001' Sourcearea (I-Point, RFZ1, Storage) for Transport
|
||||||
|
SourceXX 38:40 CHAR[2] '00' Source-Coordinates X where neccersary
|
||||||
|
SourceYY 40:42 CHAR[2] '00' Source-Coordinates Y where neccersary
|
||||||
|
SourceZZ 42:44 CHAR[2] '00' Source-Coordinates Z where neccersary
|
||||||
|
Destination 44:48 CHAR[4] 'S001', 'T001' DestinationArea (Storage, Outfeedposition) for Transport
|
||||||
|
DestinationXX 48:50 CHAR[2] '00' Destination-Coordinates X where neccersary
|
||||||
|
DestinationYY 50:52 CHAR[2] '00' Destination-Coordinates Y where neccersary
|
||||||
|
DestinationZZ 52:54 CHAR[2] '00' Destination-Coordinates Z where neccersary
|
||||||
|
State 54:56 CHAR[2] '00' State of Transport - Result
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
|
||||||
|
.. _tqui-results:
|
||||||
|
|
||||||
|
Transport results
|
||||||
|
=================
|
||||||
|
Every Transport of a Shelf access equipment returns a TQUI with the following states
|
||||||
|
|
||||||
|
- 01: Order complete - box was transported correctly
|
||||||
|
- 02: Order aborted - no transport happened
|
||||||
|
- 03: No crate - there was no box in the source of the Transport may cause dummybox transport
|
||||||
|
- 04: Destination occupied - there is no place for the box in destination
|
||||||
|
- 05: Wrong box loaded - generate alternate Transport
|
||||||
|
- 11: Order complete Dummy - detected dummy and return it to depot
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import TELEGRAM, TEL_TQUI
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TQUI from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TELEGRAM
|
||||||
|
"""
|
||||||
|
tel = TEL_TQUI ()
|
||||||
|
tel.attrib['nr'] = (ord (data [0]) << 8) + ord (data [1])
|
||||||
|
tel.attrib['src'] = data [2:4]
|
||||||
|
tel.attrib['dst'] = data [4:6]
|
||||||
|
tel.attrib['type'] = data [6:10]
|
||||||
|
#tel.attrib['box_nr'] =data [10:30]
|
||||||
|
tel.attrib['box_nr'] = data [12:12 + ord (data [11])]
|
||||||
|
tel.attrib['location'] = data [22:26]
|
||||||
|
tel.attrib['src_id'] = data [26:30]
|
||||||
|
tel.attrib['src_xx'] = data [30:32]
|
||||||
|
tel.attrib['src_yy'] = data [32:34]
|
||||||
|
tel.attrib['src_zz'] = data [34:36]
|
||||||
|
tel.attrib['dst_id'] = data [36:40]
|
||||||
|
tel.attrib['dst_xx'] = data [40:42]
|
||||||
|
tel.attrib['dst_yy'] = data [42:44]
|
||||||
|
tel.attrib['dst_zz'] = data [44:46]
|
||||||
|
tel.attrib['state'] = data [46:len(data)]
|
||||||
|
return tel
|
||||||
|
|
||||||
|
|
||||||
|
class TEL_TQUI (TELEGRAM):
|
||||||
|
def __init__ (self, nr = 0, src = 'LV', dst = 'TP', state='00', *args, **args2):
|
||||||
|
TELEGRAM.__init__(self)
|
||||||
|
self.code = TEL_TQUI
|
||||||
|
self.attrib['nr'] = nr
|
||||||
|
self.attrib['src'] = src
|
||||||
|
self.attrib['dst'] = dst
|
||||||
|
self.attrib['type'] = 'TQUI'
|
||||||
|
self.attrib['state'] = state
|
||||||
|
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TELEGRAM by string.
|
||||||
|
"""
|
||||||
|
return "TQUI TELEGRAM\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + 4l
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
print self.attrib
|
||||||
|
string = self.identify () #+ DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
238
cany_telegram.py
Executable file
238
cany_telegram.py
Executable file
@@ -0,0 +1,238 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from telegram import telegram
|
||||||
|
|
||||||
|
__all__ = ["cany_telegram"]
|
||||||
|
|
||||||
|
# String representation for any C type telegram
|
||||||
|
CANY_STRING = \
|
||||||
|
"""\
|
||||||
|
Counter: %d
|
||||||
|
Destination reference: 0x%04x
|
||||||
|
Source reference: 0x%04x
|
||||||
|
Class option: 0x%x
|
||||||
|
Parameter packets:
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# List of all possible parameters in a c-type TPDU
|
||||||
|
possible_parameters = [
|
||||||
|
PARM_NR,
|
||||||
|
PARM_SRC,
|
||||||
|
PARM_DST,
|
||||||
|
PARM_TYPE
|
||||||
|
]
|
||||||
|
|
||||||
|
def internal_formatbytes (list):
|
||||||
|
"""
|
||||||
|
This is a special hack to output data based on information in
|
||||||
|
a list. This is for internal use only!
|
||||||
|
"""
|
||||||
|
string = ""
|
||||||
|
for i in list:
|
||||||
|
bytes, value = i
|
||||||
|
# Special case: seems to be a 4bit value
|
||||||
|
if bytes == 0:
|
||||||
|
string += "%c" % (value << 4)
|
||||||
|
elif bytes == 1:
|
||||||
|
string += "%c" % value
|
||||||
|
elif bytes == 2:
|
||||||
|
string += "%c%c" % ((value >> 8) & 0xff, value & 0xff)
|
||||||
|
else:
|
||||||
|
raise Error, "Can only output one or two bytes hexadecimals"
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
class CANY_TEL (TEL):
|
||||||
|
def __init__ (self, nr, src, dst, type, *args, **args2):
|
||||||
|
self.parms = {}
|
||||||
|
self.code = type
|
||||||
|
|
||||||
|
self.dstref = args2.get ("dstref", 0x0000)
|
||||||
|
self.srcref = args2.get ("srcref", 0x0000)
|
||||||
|
self.classoption = args2.get ("classoption", 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
# Auskommentiert, da nur AK TPDUs von CP im Fetch-Modus
|
||||||
|
#self.parms[PARM_OPTIONS] = 0x0
|
||||||
|
self.parms[PARM_NR] = nr
|
||||||
|
self.parms[PARM_SRC] = src
|
||||||
|
self.parms[PARM_DST] = dst
|
||||||
|
self.parms[PARM_TYPE] = type
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
return "C type Telegram\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1 for the code, 2 for the destination reference
|
||||||
|
# 2 for the source reference and 1 for the class
|
||||||
|
# option -> 6
|
||||||
|
length = 6
|
||||||
|
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
# The code and the size each are one byte
|
||||||
|
length += 2
|
||||||
|
if i == PARM_SIZE or i == PARM_OPTIONS:
|
||||||
|
length += 1
|
||||||
|
else:
|
||||||
|
length += len (self.parms[i])
|
||||||
|
|
||||||
|
self.len = length
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Fixed header information
|
||||||
|
list = [
|
||||||
|
(1, self.len),
|
||||||
|
(0, self.code),
|
||||||
|
(2, self.dstref),
|
||||||
|
(2, self.srcref),
|
||||||
|
(1, self.classoption)]
|
||||||
|
|
||||||
|
# Dynamically add all remaining parms
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
content = self.parms[i]
|
||||||
|
list.append ((1, i))
|
||||||
|
if i == PARM_SIZE or i == PARM_OPTIONS:
|
||||||
|
list.append ((1, 1))
|
||||||
|
list.append ((1, chr (content)))
|
||||||
|
else:
|
||||||
|
list.append ((1, len (content)))
|
||||||
|
for j in content:
|
||||||
|
list.append ((1, j))
|
||||||
|
|
||||||
|
return internal_formatbytes (list)
|
||||||
|
|
||||||
|
|
||||||
|
def fromstring (self, data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TPDU from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.len = ord (data[0])
|
||||||
|
self.code = ord (data[1]) >> 4
|
||||||
|
self.dstref = (ord (data[2]) << 8) | ord (data[3])
|
||||||
|
self.srcref = (ord (data[4]) << 8) | ord (data[5])
|
||||||
|
self.classoption = ord (data[6])
|
||||||
|
|
||||||
|
index = 7
|
||||||
|
while index < len (data):
|
||||||
|
code = ord (data[index])
|
||||||
|
size = ord (data[index+1])
|
||||||
|
# The acknowledge time is only used in class 4 which we don't
|
||||||
|
# implement. The time is given in milliseconds.
|
||||||
|
# The throughput is only set when not in class 0 which we
|
||||||
|
# implement here. It denotes the throughput in Octets/s.
|
||||||
|
|
||||||
|
if code in possible_parameters:
|
||||||
|
if code == PARM_SIZE or code == PARM_OPTIONS:
|
||||||
|
self.parms[code] = ord (data[index+2])
|
||||||
|
else:
|
||||||
|
self.parms[code] = data[index+2:index+2+size]
|
||||||
|
else:
|
||||||
|
raise Warning, "Unknown parameter 0x%02x" % code
|
||||||
|
|
||||||
|
index += (size + 2)
|
||||||
|
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
|
||||||
|
string = self.identify () + CANY_STRING % (self.len, self.dstref, self.srcref, self.classoption)
|
||||||
|
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
arg = self.parms[i]
|
||||||
|
if i == PARM_SIZE:
|
||||||
|
string += " TPDU size: %d\n" % 2**arg
|
||||||
|
elif i == PARM_SRCTSAP:
|
||||||
|
string += " Sender: %s (" % arg
|
||||||
|
for i in arg:
|
||||||
|
string += "0x%x " % ord (i)
|
||||||
|
string = string[:-1] + ")\n"
|
||||||
|
elif i == PARM_DSTTSAP:
|
||||||
|
string += " Receiver: %s (" % arg
|
||||||
|
for i in arg:
|
||||||
|
string += "0x%x " % ord (i)
|
||||||
|
string = string[:-1] + ")\n"
|
||||||
|
elif i == PARM_ACKTIME:
|
||||||
|
string += " Acknowledge time: %s (ms) [Not used in Class 0]\n" % arg
|
||||||
|
elif i == PARM_THROUGHPUT:
|
||||||
|
string += " Throughput: %d (octects/s) [Not used in Class 0]\n" % arg
|
||||||
|
elif i == PARM_CHECKSUM:
|
||||||
|
string += " Checksum: %s\n" % arg
|
||||||
|
elif i == PARM_VERSION:
|
||||||
|
string += " Version: %d (default: 1)\n" % arg
|
||||||
|
elif i == PARM_PROTECTION:
|
||||||
|
string += " Protection: %s\n" % arg
|
||||||
|
elif i == PARM_OPTIONS:
|
||||||
|
string += " Options:\n"
|
||||||
|
if arg & 8 != 0:
|
||||||
|
string += " Use network expedited (Class 1)\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use network expedited (Class 1)\n"
|
||||||
|
if arg & 4 != 0:
|
||||||
|
string += " Use receipt confirmation (Class 1)\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use receipt confirmation (Class 1)\n"
|
||||||
|
if arg & 2 != 0:
|
||||||
|
string += " 16 bit checksum (Class 4)\n"
|
||||||
|
else:
|
||||||
|
string += " No 16 bit checksum (Class 4)\n"
|
||||||
|
if arg & 1 != 0:
|
||||||
|
string += " Use transport expedited data transfer service\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use transport expedited data transfer service\n"
|
||||||
|
elif i == PARM_ALTERNATIVE:
|
||||||
|
string += " Alternative: %s\n" % arg
|
||||||
|
else:
|
||||||
|
string += UNKNOWN_PARM_STRING % i
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
# Integrated tests start here
|
||||||
|
if __name__ == '__main__':
|
||||||
|
testnum = 1
|
||||||
|
|
||||||
|
tpdu = CANY_TPDU (0x1, "SOURCE", "DEST")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
print tpdu
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
tpdu2 = CANY_TPDU (0x1, "SOURCE", "DEST")
|
||||||
|
tpdu3 = CANY_TPDU (0x1, "", "")
|
||||||
|
tpdu3.fromstring (`tpdu2`)
|
||||||
|
|
||||||
|
if `tpdu` != `tpdu3`:
|
||||||
|
raise Warning, "Serialisation/Deserialisation test failed"
|
||||||
|
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
257
cany_tpdu.py
Executable file
257
cany_tpdu.py
Executable file
@@ -0,0 +1,257 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from tpdu import TPDU, PARM_ACKTIME, PARM_THROUGHPUT, PARM_SIZE, PARM_SRCTSAP, PARM_DSTTSAP, PARM_CHECKSUM, PARM_VERSION, PARM_PROTECTION, PARM_OPTIONS, PARM_ALTERNATIVE
|
||||||
|
|
||||||
|
__all__ = ["CANY_TPDU"]
|
||||||
|
|
||||||
|
# String representation for any C type TPDU
|
||||||
|
CANY_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Destination reference: 0x%04x
|
||||||
|
Source reference: 0x%04x
|
||||||
|
Class option: 0x%x
|
||||||
|
Parameter packets:
|
||||||
|
"""
|
||||||
|
|
||||||
|
# String representation for an unknown parameter
|
||||||
|
# in a c-type TPDU. Shouldn't happen anymore since
|
||||||
|
# all parameters are at least mentioned now.
|
||||||
|
UNKNOWN_PARM_STRING = \
|
||||||
|
"""\
|
||||||
|
Unknown param:
|
||||||
|
Parameter code: 0x%x
|
||||||
|
Parameter length: 0x%x
|
||||||
|
Parameter argument: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
# List of all possible parameters in a c-type TPDU
|
||||||
|
possible_parameters = [
|
||||||
|
PARM_ACKTIME,
|
||||||
|
PARM_THROUGHPUT,
|
||||||
|
PARM_SIZE,
|
||||||
|
PARM_SRCTSAP,
|
||||||
|
PARM_DSTTSAP,
|
||||||
|
PARM_CHECKSUM,
|
||||||
|
PARM_VERSION,
|
||||||
|
PARM_PROTECTION,
|
||||||
|
PARM_OPTIONS,
|
||||||
|
PARM_ALTERNATIVE
|
||||||
|
]
|
||||||
|
|
||||||
|
def internal_formatbytes (list):
|
||||||
|
"""
|
||||||
|
This is a special hack to output data based on information in
|
||||||
|
a list. This is for internal use only!
|
||||||
|
"""
|
||||||
|
string = ""
|
||||||
|
for i in list:
|
||||||
|
bytes, value = i
|
||||||
|
# Special case: seems to be a 4bit value
|
||||||
|
if bytes == 0:
|
||||||
|
string += "%c" % (value << 4)
|
||||||
|
elif bytes == 1:
|
||||||
|
string += "%c" % value
|
||||||
|
elif bytes == 2:
|
||||||
|
string += "%c%c" % ((value >> 8) & 0xff, value & 0xff)
|
||||||
|
else:
|
||||||
|
raise Error, "Can only output one or two bytes hexadecimals"
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
class CANY_TPDU (TPDU):
|
||||||
|
def __init__ (self, type, srctsap, dsttsap, *args, **args2):
|
||||||
|
self.parms = {}
|
||||||
|
self.code = type
|
||||||
|
|
||||||
|
self.dstref = args2.get ("dstref", 0x0000)
|
||||||
|
self.srcref = args2.get ("srcref", 0x0000)
|
||||||
|
self.classoption = args2.get ("classoption", 0x00)
|
||||||
|
|
||||||
|
|
||||||
|
# Auskommentiert, da nur AK TPDUs von CP im Fetch-Modus
|
||||||
|
#self.parms[PARM_OPTIONS] = 0x0
|
||||||
|
self.parms[PARM_SIZE] = 0x9
|
||||||
|
self.parms[PARM_SRCTSAP] = srctsap
|
||||||
|
self.parms[PARM_DSTTSAP] = dsttsap
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def srctsap (self):
|
||||||
|
return self.parms [PARM_SRCTSAP]
|
||||||
|
|
||||||
|
def dsttsap (self):
|
||||||
|
return self.parms [PARM_DSTTSAP]
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
return "C type TPDU\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1 for the code, 2 for the destination reference
|
||||||
|
# 2 for the source reference and 1 for the class
|
||||||
|
# option -> 6
|
||||||
|
length = 6
|
||||||
|
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
# The code and the size each are one byte
|
||||||
|
length += 2
|
||||||
|
if i == PARM_SIZE or i == PARM_OPTIONS:
|
||||||
|
length += 1
|
||||||
|
else:
|
||||||
|
length += len (self.parms[i])
|
||||||
|
|
||||||
|
self.len = length
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Fixed header information
|
||||||
|
list = [
|
||||||
|
(1, self.len),
|
||||||
|
(0, self.code),
|
||||||
|
(2, self.dstref),
|
||||||
|
(2, self.srcref),
|
||||||
|
(1, self.classoption)]
|
||||||
|
|
||||||
|
# Dynamically add all remaining parms
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
content = self.parms[i]
|
||||||
|
list.append ((1, i))
|
||||||
|
if i == PARM_SIZE or i == PARM_OPTIONS:
|
||||||
|
list.append ((1, 1))
|
||||||
|
list.append ((1, chr (content)))
|
||||||
|
else:
|
||||||
|
list.append ((1, len (content)))
|
||||||
|
for j in content:
|
||||||
|
list.append ((1, j))
|
||||||
|
|
||||||
|
return internal_formatbytes (list)
|
||||||
|
|
||||||
|
|
||||||
|
def fromstring (self, data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TPDU from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.len = ord (data[0])
|
||||||
|
self.code = ord (data[1]) >> 4
|
||||||
|
self.dstref = (ord (data[2]) << 8) | ord (data[3])
|
||||||
|
self.srcref = (ord (data[4]) << 8) | ord (data[5])
|
||||||
|
self.classoption = ord (data[6])
|
||||||
|
|
||||||
|
index = 7
|
||||||
|
while index < len (data):
|
||||||
|
code = ord (data[index])
|
||||||
|
size = ord (data[index+1])
|
||||||
|
# The acknowledge time is only used in class 4 which we don't
|
||||||
|
# implement. The time is given in milliseconds.
|
||||||
|
# The throughput is only set when not in class 0 which we
|
||||||
|
# implement here. It denotes the throughput in Octets/s.
|
||||||
|
|
||||||
|
if code in possible_parameters:
|
||||||
|
if code == PARM_SIZE or code == PARM_OPTIONS:
|
||||||
|
self.parms[code] = ord (data[index+2])
|
||||||
|
else:
|
||||||
|
self.parms[code] = data[index+2:index+2+size]
|
||||||
|
else:
|
||||||
|
raise Warning, "Unknown parameter 0x%02x" % code
|
||||||
|
|
||||||
|
index += (size + 2)
|
||||||
|
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
|
||||||
|
string = self.identify () + CANY_STRING % (self.len, self.dstref, self.srcref, self.classoption)
|
||||||
|
|
||||||
|
for i in self.parms.keys ():
|
||||||
|
arg = self.parms[i]
|
||||||
|
if i == PARM_SIZE:
|
||||||
|
string += " TPDU size: %d\n" % 2**arg
|
||||||
|
elif i == PARM_SRCTSAP:
|
||||||
|
string += " Sender: %s (" % arg
|
||||||
|
for i in arg:
|
||||||
|
string += "0x%x " % ord (i)
|
||||||
|
string = string[:-1] + ")\n"
|
||||||
|
elif i == PARM_DSTTSAP:
|
||||||
|
string += " Receiver: %s (" % arg
|
||||||
|
for i in arg:
|
||||||
|
string += "0x%x " % ord (i)
|
||||||
|
string = string[:-1] + ")\n"
|
||||||
|
elif i == PARM_ACKTIME:
|
||||||
|
string += " Acknowledge time: %s (ms) [Not used in Class 0]\n" % arg
|
||||||
|
elif i == PARM_THROUGHPUT:
|
||||||
|
string += " Throughput: %d (octects/s) [Not used in Class 0]\n" % arg
|
||||||
|
elif i == PARM_CHECKSUM:
|
||||||
|
string += " Checksum: %s\n" % arg
|
||||||
|
elif i == PARM_VERSION:
|
||||||
|
string += " Version: %d (default: 1)\n" % arg
|
||||||
|
elif i == PARM_PROTECTION:
|
||||||
|
string += " Protection: %s\n" % arg
|
||||||
|
elif i == PARM_OPTIONS:
|
||||||
|
string += " Options:\n"
|
||||||
|
if arg & 8 != 0:
|
||||||
|
string += " Use network expedited (Class 1)\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use network expedited (Class 1)\n"
|
||||||
|
if arg & 4 != 0:
|
||||||
|
string += " Use receipt confirmation (Class 1)\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use receipt confirmation (Class 1)\n"
|
||||||
|
if arg & 2 != 0:
|
||||||
|
string += " 16 bit checksum (Class 4)\n"
|
||||||
|
else:
|
||||||
|
string += " No 16 bit checksum (Class 4)\n"
|
||||||
|
if arg & 1 != 0:
|
||||||
|
string += " Use transport expedited data transfer service\n"
|
||||||
|
else:
|
||||||
|
string += " Don't use transport expedited data transfer service\n"
|
||||||
|
elif i == PARM_ALTERNATIVE:
|
||||||
|
string += " Alternative: %s\n" % arg
|
||||||
|
else:
|
||||||
|
string += UNKNOWN_PARM_STRING % i
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
# Integrated tests start here
|
||||||
|
if __name__ == '__main__':
|
||||||
|
testnum = 1
|
||||||
|
|
||||||
|
tpdu = CANY_TPDU (0x1, "SOURCE", "DEST")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
print tpdu
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
tpdu2 = CANY_TPDU (0x1, "SOURCE", "DEST")
|
||||||
|
tpdu3 = CANY_TPDU (0x1, "", "")
|
||||||
|
tpdu3.fromstring (`tpdu2`)
|
||||||
|
|
||||||
|
if `tpdu` != `tpdu3`:
|
||||||
|
raise Warning, "Serialisation/Deserialisation test failed"
|
||||||
|
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
54
cc_tpdu.py
Executable file
54
cc_tpdu.py
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from cany_tpdu import CANY_TPDU
|
||||||
|
from tpdu import TPDU_CC
|
||||||
|
|
||||||
|
__all__ = ["fromstring", "CC_TPDU"]
|
||||||
|
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TPDU from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
tpdu = CC_TPDU ()
|
||||||
|
tpdu.fromstring (data)
|
||||||
|
return tpdu
|
||||||
|
|
||||||
|
|
||||||
|
class CC_TPDU (CANY_TPDU):
|
||||||
|
def __init__ (self, srctsap = "", dsttsap = "", *args, **args2):
|
||||||
|
CANY_TPDU.__init__ (self, TPDU_CC, srctsap, dsttsap, *args, **args2)
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TPDU by string.
|
||||||
|
"""
|
||||||
|
return "CC TPDU (Connection request reply)\n"
|
||||||
|
|
||||||
|
|
||||||
|
# Integrated tests start here
|
||||||
|
if __name__ == '__main__':
|
||||||
|
testnum = 1
|
||||||
|
|
||||||
|
tpdu = CC_TPDU ("SOURCE", "DEST")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
tpdu = CC_TPDU ("TCP-1", "TCP", dstref=0x005, srcref=0x4431)
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
print tpdu
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
46
client.py
Executable file
46
client.py
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from cr_tpdu import CR_TPDU
|
||||||
|
from dt_tpdu import DT_TPDU
|
||||||
|
from tpkt import TPKT
|
||||||
|
from socket import *
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
BUFSIZE = 1024
|
||||||
|
|
||||||
|
tpdu = CR_TPDU ("TAUF", "TAUF", srcref=0x0015)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
print "Laenge: " + str (len (tpdu))
|
||||||
|
|
||||||
|
s = socket(AF_INET, SOCK_STREAM)
|
||||||
|
s.connect(("192.168.0.130", 102))
|
||||||
|
s.send(`tpkt`+`tpdu`)
|
||||||
|
|
||||||
|
data = s.recv (16384)
|
||||||
|
print data
|
||||||
|
|
||||||
|
id =32000
|
||||||
|
dt = '%c%c' %( id >> 8, id % 256) +\
|
||||||
|
'SE' +\
|
||||||
|
'EM' +\
|
||||||
|
'SCLS' +\
|
||||||
|
'12345678901234567890' +\
|
||||||
|
'XXXX'
|
||||||
|
|
||||||
|
print dt
|
||||||
|
tpdu = DT_TPDU (dt)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
#s.send(`tpkt`+`tpdu`)
|
||||||
|
sleep (0.1)
|
||||||
|
#tpdu = DT_TPDU ("And another test message")
|
||||||
|
#tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
#s.send(`tpkt`+`tpdu`, MSG_WAITALL)
|
||||||
|
#sleep (0.1)
|
||||||
|
sleep (25.1)
|
||||||
|
s.close ()
|
||||||
53
cr_tpdu.py
Executable file
53
cr_tpdu.py
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from cany_tpdu import CANY_TPDU
|
||||||
|
from tpdu import TPDU_CR
|
||||||
|
|
||||||
|
__all__ = ["fromstring", "CR_TPDU"]
|
||||||
|
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TPDU from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
tpdu = CR_TPDU ()
|
||||||
|
tpdu.fromstring (data)
|
||||||
|
return tpdu
|
||||||
|
|
||||||
|
class CR_TPDU (CANY_TPDU):
|
||||||
|
def __init__ (self, srctsap = "", dsttsap = "", *args, **args2):
|
||||||
|
CANY_TPDU.__init__ (self, TPDU_CR, srctsap, dsttsap, *args, **args2)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TPDU by string.
|
||||||
|
"""
|
||||||
|
return "CR TPDU (Connection request)\n"
|
||||||
|
|
||||||
|
|
||||||
|
# Integrated tests start here
|
||||||
|
if __name__ == '__main__':
|
||||||
|
testnum = 1
|
||||||
|
|
||||||
|
tpdu = CR_TPDU ("SOURCE", "DEST")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
tpdu = CR_TPDU ("TCP-1", "TCP", srcref=0x0005)
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
print tpdu
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
52
decode.py
Executable file
52
decode.py
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from tpdu import TPDU_CC, TPDU_CR, TPDU_DT
|
||||||
|
|
||||||
|
__all__ = ["decode_packet"]
|
||||||
|
|
||||||
|
|
||||||
|
def decode_cc (data):
|
||||||
|
from cc_tpdu import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
|
||||||
|
def decode_cr (data):
|
||||||
|
from cr_tpdu import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
|
||||||
|
def decode_dt (data):
|
||||||
|
from dt_tpdu import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
decoderlist = [
|
||||||
|
(TPDU_CC, decode_cc),
|
||||||
|
(TPDU_CR, decode_cr),
|
||||||
|
(TPDU_DT, decode_dt)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def decodepacket (data):
|
||||||
|
if not ord (data[0]) == 0x03:
|
||||||
|
print ("No valid tpkt header")
|
||||||
|
return
|
||||||
|
size = (ord (data[2]) << 8) | ord (data[3])
|
||||||
|
#print "TPKT size %d" % size
|
||||||
|
|
||||||
|
if len (data) < size:
|
||||||
|
print ("Packet too short! Is %d" % len (data))
|
||||||
|
return
|
||||||
|
|
||||||
|
type = (ord (data[5]) >> 4)
|
||||||
|
for i in decoderlist:
|
||||||
|
id, function = i
|
||||||
|
if id == type:
|
||||||
|
return function (data[4:size])
|
||||||
|
|
||||||
|
print "Undhandled packettype"
|
||||||
|
#raise Warning, "Undhandled packettype"
|
||||||
89
doc/Makefile
Normal file
89
doc/Makefile
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line.
|
||||||
|
SPHINXOPTS =
|
||||||
|
SPHINXBUILD = sphinx-build
|
||||||
|
PAPER =
|
||||||
|
BUILDDIR = build
|
||||||
|
|
||||||
|
# Internal variables.
|
||||||
|
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||||
|
PAPEROPT_letter = -D latex_paper_size=letter
|
||||||
|
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||||
|
|
||||||
|
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Please use \`make <target>' where <target> is one of"
|
||||||
|
@echo " html to make standalone HTML files"
|
||||||
|
@echo " dirhtml to make HTML files named index.html in directories"
|
||||||
|
@echo " pickle to make pickle files"
|
||||||
|
@echo " json to make JSON files"
|
||||||
|
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||||
|
@echo " qthelp to make HTML files and a qthelp project"
|
||||||
|
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||||
|
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||||
|
@echo " linkcheck to check all external links for integrity"
|
||||||
|
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -rf $(BUILDDIR)/*
|
||||||
|
|
||||||
|
html:
|
||||||
|
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||||
|
|
||||||
|
dirhtml:
|
||||||
|
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||||
|
|
||||||
|
pickle:
|
||||||
|
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can process the pickle files."
|
||||||
|
|
||||||
|
json:
|
||||||
|
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can process the JSON files."
|
||||||
|
|
||||||
|
htmlhelp:
|
||||||
|
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||||
|
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||||
|
|
||||||
|
qthelp:
|
||||||
|
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||||
|
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||||
|
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LV.qhcp"
|
||||||
|
@echo "To view the help file:"
|
||||||
|
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LV.qhc"
|
||||||
|
|
||||||
|
latex:
|
||||||
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||||
|
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||||
|
"run these through (pdf)latex."
|
||||||
|
|
||||||
|
changes:
|
||||||
|
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||||
|
@echo
|
||||||
|
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||||
|
|
||||||
|
linkcheck:
|
||||||
|
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||||
|
@echo
|
||||||
|
@echo "Link check complete; look for any errors in the above output " \
|
||||||
|
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||||
|
|
||||||
|
doctest:
|
||||||
|
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||||
|
@echo "Testing of doctests in the sources finished, look at the " \
|
||||||
|
"results in $(BUILDDIR)/doctest/output.txt."
|
||||||
194
doc/source/conf.py
Normal file
194
doc/source/conf.py
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# LV documentation build configuration file, created by
|
||||||
|
# sphinx-quickstart on Fri Oct 8 11:35:36 2010.
|
||||||
|
#
|
||||||
|
# This file is execfile()d with the current directory set to its containing dir.
|
||||||
|
#
|
||||||
|
# Note that not all possible configuration values are present in this
|
||||||
|
# autogenerated file.
|
||||||
|
#
|
||||||
|
# All configuration values have a default; values that are commented out
|
||||||
|
# serve to show the default.
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
sys.path.append(os.path.abspath('../../'))
|
||||||
|
|
||||||
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
|
extensions = ['sphinx.ext.todo', 'sphinx.ext.autodoc']
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# The suffix of source filenames.
|
||||||
|
source_suffix = '.rst'
|
||||||
|
|
||||||
|
# The encoding of source files.
|
||||||
|
#source_encoding = 'utf-8'
|
||||||
|
|
||||||
|
# The master toctree document.
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
# General information about the project.
|
||||||
|
project = u'LV'
|
||||||
|
copyright = u'2010, Daniel Egger, Michael Rest'
|
||||||
|
|
||||||
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
# built documents.
|
||||||
|
#
|
||||||
|
# The short X.Y version.
|
||||||
|
version = '1.0'
|
||||||
|
# The full version, including alpha/beta/rc tags.
|
||||||
|
release = '1.0'
|
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
# for a list of supported languages.
|
||||||
|
#language = None
|
||||||
|
|
||||||
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
|
# non-false value, then it is used:
|
||||||
|
#today = ''
|
||||||
|
# Else, today_fmt is used as the format for a strftime call.
|
||||||
|
#today_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
|
# List of documents that shouldn't be included in the build.
|
||||||
|
#unused_docs = []
|
||||||
|
|
||||||
|
# List of directories, relative to source directory, that shouldn't be searched
|
||||||
|
# for source files.
|
||||||
|
exclude_trees = []
|
||||||
|
|
||||||
|
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||||
|
#default_role = None
|
||||||
|
|
||||||
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
|
#add_function_parentheses = True
|
||||||
|
|
||||||
|
# If true, the current module name will be prepended to all description
|
||||||
|
# unit titles (such as .. function::).
|
||||||
|
#add_module_names = True
|
||||||
|
|
||||||
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
|
# output. They are ignored by default.
|
||||||
|
#show_authors = False
|
||||||
|
|
||||||
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
# A list of ignored prefixes for module index sorting.
|
||||||
|
#modindex_common_prefix = []
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output ---------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||||
|
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||||
|
html_theme = 'default'
|
||||||
|
|
||||||
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
|
# further. For a list of options available for each theme, see the
|
||||||
|
# documentation.
|
||||||
|
#html_theme_options = {}
|
||||||
|
|
||||||
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
|
#html_theme_path = []
|
||||||
|
|
||||||
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
|
# "<project> v<release> documentation".
|
||||||
|
#html_title = None
|
||||||
|
|
||||||
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||||
|
#html_short_title = None
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
|
# of the sidebar.
|
||||||
|
#html_logo = None
|
||||||
|
|
||||||
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
|
# pixels large.
|
||||||
|
#html_favicon = None
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['_static']
|
||||||
|
|
||||||
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
|
# using the given strftime format.
|
||||||
|
#html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
|
||||||
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
|
# typographically correct entities.
|
||||||
|
#html_use_smartypants = True
|
||||||
|
|
||||||
|
# Custom sidebar templates, maps document names to template names.
|
||||||
|
#html_sidebars = {}
|
||||||
|
|
||||||
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
|
# template names.
|
||||||
|
#html_additional_pages = {}
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#html_use_modindex = True
|
||||||
|
|
||||||
|
# If false, no index is generated.
|
||||||
|
#html_use_index = True
|
||||||
|
|
||||||
|
# If true, the index is split into individual pages for each letter.
|
||||||
|
#html_split_index = False
|
||||||
|
|
||||||
|
# If true, links to the reST sources are added to the pages.
|
||||||
|
#html_show_sourcelink = True
|
||||||
|
|
||||||
|
# If true, an OpenSearch description file will be output, and all pages will
|
||||||
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
|
# base URL from which the finished HTML is served.
|
||||||
|
#html_use_opensearch = ''
|
||||||
|
|
||||||
|
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||||
|
#html_file_suffix = ''
|
||||||
|
|
||||||
|
# Output file base name for HTML help builder.
|
||||||
|
htmlhelp_basename = 'LVdoc'
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for LaTeX output --------------------------------------------------
|
||||||
|
|
||||||
|
# The paper size ('letter' or 'a4').
|
||||||
|
#latex_paper_size = 'letter'
|
||||||
|
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
|
#latex_font_size = '10pt'
|
||||||
|
|
||||||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
|
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||||
|
latex_documents = [
|
||||||
|
('index', 'LV.tex', u'LV Documentation',
|
||||||
|
u'Daniel Egger, Michael Rest', 'manual'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
# the title page.
|
||||||
|
#latex_logo = None
|
||||||
|
|
||||||
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
|
# not chapters.
|
||||||
|
#latex_use_parts = False
|
||||||
|
|
||||||
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#latex_preamble = ''
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#latex_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#latex_use_modindex = True
|
||||||
BIN
doc/source/images/ela_logo.png
Normal file
BIN
doc/source/images/ela_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
36
doc/source/index.rst
Normal file
36
doc/source/index.rst
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
.. LV documentation master file, created by
|
||||||
|
sphinx-quickstart on Fri Oct 8 11:35:36 2010.
|
||||||
|
You can adapt this file completely to your liking, but it should at least
|
||||||
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
|
Storage Control documentation
|
||||||
|
#############################
|
||||||
|
.. image:: images/ela_logo.png
|
||||||
|
|
||||||
|
Contents:
|
||||||
|
This document contains confidential developer infomation about the (`ELA <http://www.ela-ft.de/>`_)-Storage Control System and may not be used without
|
||||||
|
explicit acknowlede of the authors).
|
||||||
|
|
||||||
|
In the Following sections the developer-level configuration and options of the system and the used telegram syntax
|
||||||
|
(in order to give other sytems the ability to connect the ELA storage retival system with the main counfiguration.)
|
||||||
|
will be explained.
|
||||||
|
|
||||||
|
This document is still in Beta - State.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
|
||||||
|
telegrams.rst
|
||||||
|
|
||||||
|
transportmatrix.rst
|
||||||
|
|
||||||
|
.. database.rst.
|
||||||
|
|
||||||
|
|
||||||
|
Indices and tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
||||||
|
* :ref:`modindex`
|
||||||
|
* :ref:`search`
|
||||||
3
doc/source/loglevels.rst
Normal file
3
doc/source/loglevels.rst
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
11 - unused
|
||||||
|
7 - Very verbose information about movements
|
||||||
|
6 - startup information
|
||||||
25
doc/source/startup.rst
Normal file
25
doc/source/startup.rst
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.. _plc_comm:
|
||||||
|
|
||||||
|
|
||||||
|
*****************
|
||||||
|
Safety
|
||||||
|
*****************
|
||||||
|
|
||||||
|
|
||||||
|
E-Stop Check
|
||||||
|
==================
|
||||||
|
|
||||||
|
Every E-Stop / Saftey Switch has to be activated seperately. After that the errormessages have to
|
||||||
|
be checked and the Safety Circle reseted.
|
||||||
|
This is to be done again with a responsible Person of the customer which signs a E-Stop Protocol.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Startup
|
||||||
|
===================
|
||||||
|
Every machine protection (Gap-Sensors) has to be dropout and the errormessage has to be checked.
|
||||||
|
|
||||||
|
Automatic
|
||||||
|
=============
|
||||||
|
On every Insertion Point the singularization of queued boxes has to be tested exactly.
|
||||||
|
|
||||||
90
doc/source/telegrams.rst
Normal file
90
doc/source/telegrams.rst
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
.. _plc_comm:
|
||||||
|
|
||||||
|
|
||||||
|
*****************
|
||||||
|
PLC-Communication
|
||||||
|
*****************
|
||||||
|
|
||||||
|
.. _plc-comm_iscomm_iso:
|
||||||
|
|
||||||
|
Transport-Protocol
|
||||||
|
==================
|
||||||
|
|
||||||
|
The communication between the storage control system and the PLC is Ethernetbased and uses
|
||||||
|
ISOonTCP (`RFC1006 <http://www.faqs.org/rfcs/rfc1006.html/>`_) as Transport protocol.
|
||||||
|
|
||||||
|
The PLC uses the following Channels for communication, the local_TSAP, remote_TSAP are identical
|
||||||
|
to the Telegramtype.
|
||||||
|
|
||||||
|
==== ================================
|
||||||
|
Type Connection mode (view from PLC)
|
||||||
|
==== ================================
|
||||||
|
LEBE active
|
||||||
|
SLCS active
|
||||||
|
TAUF passive
|
||||||
|
TQUI active
|
||||||
|
STAT active
|
||||||
|
==== ================================
|
||||||
|
|
||||||
|
Communication-Cycle
|
||||||
|
===================
|
||||||
|
After restart or Sequence-Errors, every channel has to be initialized. Therefore the to-be-sent telegram
|
||||||
|
will be sent 1st with Sequence-Nr = 0. The Init-Telegram is not checked and not processed. After Acknowledge the
|
||||||
|
Telegram will be sent again with Sequence-Nr = 1, now it will run through the content checks and may be processed.
|
||||||
|
Now the Channel is initialized (The lifebeat channel is excluded from this procedure).
|
||||||
|
|
||||||
|
Answer-Telegram
|
||||||
|
***************
|
||||||
|
Every Telegram (except from the lifebeat) is replied by an Answer-telegram, containing an return code with Errorinformation.
|
||||||
|
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
ID Byte-Pos Type Value Description
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
Sequence-Nr 0:2 SINT16 0..32767 Telegramcounter
|
||||||
|
Tel-Source 2:4 CHAR[2] ['TP','LV'] Source of Telegram (to be removed in next versions)
|
||||||
|
Tel-Destination 4:6 CHAR[2] ['TP','LV'] Destination of Telegram (to be removed in next versions)
|
||||||
|
Tel-Type 6:10 CHAR[4] like Answered Telegram Ident of Telegram (prepared to multiplex Channels)
|
||||||
|
STATE 10:12 WORD depend on Telegramtype Contains Replycode to identify errors
|
||||||
|
=============== ======== ======== ============================= ========================================================
|
||||||
|
|
||||||
|
Return-codes
|
||||||
|
------------
|
||||||
|
Returncodes valid for all Telegramtypes, supporting anwser telegrams.
|
||||||
|
|
||||||
|
- 0 : OK - Transport will be processed
|
||||||
|
- 97 : Wrong Telegram length
|
||||||
|
- 98 : Wrong Telegram type
|
||||||
|
- 99 : Counter error - resend Transport with Sequence-Nr 0 then 1 to resync
|
||||||
|
|
||||||
|
TelegramTypes
|
||||||
|
=============
|
||||||
|
The listed TelegramTypes containing information as followed.
|
||||||
|
|
||||||
|
LEBE
|
||||||
|
****
|
||||||
|
.. automodule:: LEBE_tel
|
||||||
|
:members:
|
||||||
|
:exclude-members: fromstring
|
||||||
|
|
||||||
|
SCLS
|
||||||
|
****
|
||||||
|
.. automodule:: SCLS_tel
|
||||||
|
:members:
|
||||||
|
:exclude-members: fromstring
|
||||||
|
|
||||||
|
TAUF
|
||||||
|
****
|
||||||
|
.. automodule:: TAUF_tel
|
||||||
|
:members:
|
||||||
|
:exclude-members: fromstring
|
||||||
|
|
||||||
|
TQUI
|
||||||
|
****
|
||||||
|
.. automodule:: TQUI_tel
|
||||||
|
:members:
|
||||||
|
:exclude-members: fromstring
|
||||||
|
|
||||||
|
STAT
|
||||||
|
****
|
||||||
|
Sending Error, State, Process information from PLC.
|
||||||
|
Will be documentated in future.
|
||||||
26
doc/source/transportmatrix.rst
Normal file
26
doc/source/transportmatrix.rst
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.. _transportmatrix:
|
||||||
|
|
||||||
|
|
||||||
|
***************
|
||||||
|
Transportmatrix
|
||||||
|
***************
|
||||||
|
|
||||||
|
The Transportmatrix keeps all availiable transport connections.
|
||||||
|
|
||||||
|
.. _transportmatrix_modes:
|
||||||
|
|
||||||
|
Modes
|
||||||
|
=====
|
||||||
|
|
||||||
|
The communication between the storage control system and the PLC is Ethernetbased and uses
|
||||||
|
ISOonTCP (`RFC1006 <http://www.faqs.org/rfcs/rfc1006.html/>`_) as Transport protocol.
|
||||||
|
|
||||||
|
The PLC uses the following Channels for communication, the local_TSAP, remote_TSAP are identical
|
||||||
|
to the Telegramtype.
|
||||||
|
|
||||||
|
========== ================================
|
||||||
|
Mode Description
|
||||||
|
========== ================================
|
||||||
|
auto Automatic Reload of C,T Shelfes
|
||||||
|
autosched Scheduled Auto
|
||||||
|
========== ================================
|
||||||
98
dt_tpdu.py
Normal file
98
dt_tpdu.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from tpdu import TPDU, TPDU_DT
|
||||||
|
|
||||||
|
# String representation for a DT TPDU
|
||||||
|
DT_STRING = \
|
||||||
|
"""\
|
||||||
|
Length: %d
|
||||||
|
Number: 0x%02x
|
||||||
|
Contained Data: %s
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fromstring (data):
|
||||||
|
"""
|
||||||
|
Decode the binary representation of a TPDU from the given
|
||||||
|
parameter and note the data in the instance of the object.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
data: The binary form of the TPDU
|
||||||
|
"""
|
||||||
|
tpdu = DT_TPDU ()
|
||||||
|
tpdu.data = data[3:]
|
||||||
|
return tpdu
|
||||||
|
|
||||||
|
|
||||||
|
class DT_TPDU (TPDU):
|
||||||
|
def __init__ (self, data = "", *args, **args2):
|
||||||
|
self.code = TPDU_DT
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
# Bit 8 indicates complete DT Packet, may need to
|
||||||
|
# be fixed though
|
||||||
|
self.number = 0x80
|
||||||
|
#self.number = 0x00 # is fragment
|
||||||
|
self.__recalclen ()
|
||||||
|
return
|
||||||
|
|
||||||
|
def identify (self):
|
||||||
|
"""
|
||||||
|
This method can be used to identify a TPDU by string.
|
||||||
|
"""
|
||||||
|
return "DT type TPDU (Data transmit)\n"
|
||||||
|
|
||||||
|
def __recalclen (self):
|
||||||
|
"""
|
||||||
|
Return the length of the TPDU. This function is for
|
||||||
|
internal use only!
|
||||||
|
"""
|
||||||
|
self.len = 2 + len (self.data)
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c%c" % (2, self.code << 4, self.number) + self.data
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = self.identify () + DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
|
|
||||||
|
# Integrated tests start here
|
||||||
|
if __name__ == '__main__':
|
||||||
|
testnum = 1
|
||||||
|
|
||||||
|
tpdu = DT_TPDU ("")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
tpdu = DT_TPDU (" Noch")
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
print tpdu
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
if tpdu.len == 14:
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
else:
|
||||||
|
raise Warning, "Test %0d failed" % testnum
|
||||||
|
|
||||||
|
print tpdu
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
|
|
||||||
|
print `tpdu`
|
||||||
|
print "Test %0d sucessful" % testnum
|
||||||
|
testnum += 1
|
||||||
29
generatemails.py
Normal file
29
generatemails.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import os
|
||||||
|
import smtplib
|
||||||
|
|
||||||
|
sender = 'lvr@gustavogusto.com'
|
||||||
|
receivers = ['w.niedersetz@gustavogusto.com']
|
||||||
|
|
||||||
|
message = """From: ELA LVR <lvr@gustavogusto.com>
|
||||||
|
To: Waldemar Niedersetz <w.niedersetz@gustavogusto.com>
|
||||||
|
Subject: SMTP e-mail test
|
||||||
|
|
||||||
|
This is a test e-mail message.
|
||||||
|
"""
|
||||||
|
mailpath = '/opt/mails'
|
||||||
|
if __name__ == "__main__":
|
||||||
|
while 1:
|
||||||
|
files = os.listdir (mailpath)
|
||||||
|
for fname in files:
|
||||||
|
f = open ("/opt/mails/" + fname, "r")
|
||||||
|
data = f.read ()
|
||||||
|
print data
|
||||||
|
f.close ()
|
||||||
|
try:
|
||||||
|
smtpObj = smtplib.SMTP('104.47.10.36') #, 587)
|
||||||
|
smtpObj.sendmail(sender, receivers, message)
|
||||||
|
os.remove ("/opt/mails/" + fname)
|
||||||
|
print "Successfully sent email"
|
||||||
|
except:
|
||||||
|
print "Error: unable to send email"
|
||||||
9
initdata/Fresco/Articlemaster.sql
Normal file
9
initdata/Fresco/Articlemaster.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
--Articlemaster Karnerta Teigwaren--
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
DELETE FROM Articlemaster;
|
||||||
|
INSERT INTO Articlemaster (article, caption, gtin, normammount, minammount, zone) VALUES (118, 'Pizza Margherita', '4260414150685', 81, 50, 1);
|
||||||
|
INSERT INTO Articlemaster (article, caption, gtin, normammount, minammount, zone) VALUES (119, 'Pizza Prosciutto Funghi', '4260414150692', 81, 50, 1);
|
||||||
|
INSERT INTO Articlemaster (article, caption, gtin, normammount, minammount, zone) VALUES (129, 'Pizza Salame', '4250414150715', 81, 50, 1);
|
||||||
|
INSERT INTO Articlemaster (article, caption, gtin, normammount, minammount, zone) VALUES (218, 'Pizza Tonno e Cipolla', '4260414150722', 81, 50, 1);
|
||||||
|
INSERT INTO Articlemaster (article, caption, gtin, normammount, minammount, zone) VALUES (342, 'Pizza Spinaci e Ricotta', '4260414150623', 81, 50, 1);
|
||||||
|
END TRANSACTION;
|
||||||
8
initdata/Fresco/Locked.sql
Normal file
8
initdata/Fresco/Locked.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
--Locked Slots Karnerta -Wurst--
|
||||||
|
DELETE FROM Lockedslots;
|
||||||
|
--INSERT INTO Lockedslots VALUES ('T001', 16, 2, 'dummy');
|
||||||
|
-- INSERT INTO Lockedslots VALUES ('T001', 17, 5, 'express');
|
||||||
|
-- INSERT INTO Lockedslots VALUES ('T001', 18, 7, 'error');
|
||||||
|
--INSERT INTO Lockedslots VALUES ('T001', 18, 6, 'throughfeed-I001');
|
||||||
|
-- INSERT INTO Lockedslots VALUES ('T001', 18, 5, 'throughfeed-I002');
|
||||||
|
-- INSERT INTO Lockedslots VALUES ('T002', 1, 1, 'blocked');
|
||||||
41
initdata/Fresco/Physics_Slotbase.sql
Normal file
41
initdata/Fresco/Physics_Slotbase.sql
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-- Storages configured
|
||||||
|
DELETE FROM Physics;
|
||||||
|
-- RFZs configured
|
||||||
|
INSERT INTO Physics VALUES ('RFZs', '2');
|
||||||
|
INSERT INTO Physics VALUES ('Storages', '3');
|
||||||
|
-- Throughfeed shelf configured
|
||||||
|
INSERT INTO Physics VALUES ('Storage0', 'T001');
|
||||||
|
INSERT INTO Physics VALUES ('X_T001','14');
|
||||||
|
INSERT INTO Physics VALUES ('Y_T001','3');
|
||||||
|
INSERT INTO Physics VALUES ('ZONES_T001','1');
|
||||||
|
INSERT INTO Physics VALUES ('ZONESTART_T001_1','1');
|
||||||
|
INSERT INTO Physics VALUES ('XMid_T001_1','5');
|
||||||
|
INSERT INTO Physics VALUES ('YMid_T001_1','3');
|
||||||
|
INSERT INTO Physics VALUES ('Z_T001','21');
|
||||||
|
-- INSERT INTO Physics VALUES ('T001_Managed', 1);
|
||||||
|
-- Singleplace shelf configured
|
||||||
|
INSERT INTO Physics VALUES ('Storage1', 'S001');
|
||||||
|
INSERT INTO Physics VALUES ('Z_S001','1');
|
||||||
|
INSERT INTO Physics VALUES ('X_S001','10');
|
||||||
|
INSERT INTO Physics VALUES ('Y_S001','3');
|
||||||
|
INSERT INTO Physics VALUES ('ZONES_S001','1');
|
||||||
|
INSERT INTO Physics VALUES ('ZONESTART_S001_1','1');
|
||||||
|
INSERT INTO Physics VALUES ('XMid_S001_1','2');
|
||||||
|
INSERT INTO Physics VALUES ('YMid_S001_1','3');
|
||||||
|
-- Singleplace shelf configured
|
||||||
|
INSERT INTO Physics VALUES ('Storage2', 'S002');
|
||||||
|
INSERT INTO Physics VALUES ('Z_S002','1');
|
||||||
|
INSERT INTO Physics VALUES ('X_S002','10');
|
||||||
|
INSERT INTO Physics VALUES ('Y_S002','3');
|
||||||
|
INSERT INTO Physics VALUES ('ZONES_S002','1');
|
||||||
|
INSERT INTO Physics VALUES ('ZONESTART_S002_1','1');
|
||||||
|
INSERT INTO Physics VALUES ('XMid_S002_1','2');
|
||||||
|
INSERT INTO Physics VALUES ('YMid_S002_1','3');
|
||||||
|
-- BoxNrStart for I-Point
|
||||||
|
INSERT INTO Physics VALUES ('BoxNr_I002', '2000100');
|
||||||
|
INSERT INTO Physics VALUES ('BoxNr_I001', '1000100');
|
||||||
|
-- Ordering --
|
||||||
|
-- Slotbase --
|
||||||
|
DELETE FROM Slotbase;
|
||||||
|
-- Build Slotbase for managed Throughfeed Storage T002 --
|
||||||
|
--INSERT INTO Slotbase (id, x, y, article) VALUES ('T002', 1, 1, 'dynamic');
|
||||||
14
initdata/Fresco/Transportmatix.sql
Normal file
14
initdata/Fresco/Transportmatix.sql
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- Transportmatrix
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
DELETE FROM Transportmatrix;
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('I001', 'T001', 1, '', 1);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('I001', 'S001', 1, '', 1);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('I002', 'S001', 1, '', 1);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('I003', 'S002', 2, '', 1);
|
||||||
|
--INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('T001', 'T002', 2, 'autosched', 1);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('S001', 'O001', '1_D1', '', 0);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('S002', 'O002', '2_A1', '', 0);
|
||||||
|
INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('T001', 'O002', '2_A1', '', 1);
|
||||||
|
--Error-Transport-RFZ2
|
||||||
|
--INSERT INTO Transportmatrix (src, dst, rfz, mode, prio) VALUES ('RFZ2', 'OPD3', 2, '', 'error', 0);
|
||||||
|
END TRANSACTION;
|
||||||
0
initdata/Fresco/storage_karnertaWU.sqlite
Normal file
0
initdata/Fresco/storage_karnertaWU.sqlite
Normal file
9
initdata/dblayout_Articlemaster.sql
Executable file
9
initdata/dblayout_Articlemaster.sql
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE Articlemaster (
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
caption varchar(50) NOT NULL default '',
|
||||||
|
gtin varchar(14) NOT NULL default '',
|
||||||
|
normammount INTEGER NULL default '',
|
||||||
|
minammount INTEGER NULL default '',
|
||||||
|
zone INTEGER NOT NULL default '1',
|
||||||
|
PRIMARY KEY (article)
|
||||||
|
);
|
||||||
272
initdata/dblayout_sqlite.sql
Normal file
272
initdata/dblayout_sqlite.sql
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
-- sqldum : sqlite
|
||||||
|
--
|
||||||
|
-- Database : storage
|
||||||
|
-- ------------------------------------------------------
|
||||||
|
-- Server version 4.0.24_Debian-10sarge1-log
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Physics
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Physics (
|
||||||
|
k varchar(30) NOT NULL default '',
|
||||||
|
v varchar(255) default NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for Transportmartrix
|
||||||
|
--
|
||||||
|
CREATE TABLE Transportmatrix (
|
||||||
|
src varchar(4) NOT NULL,
|
||||||
|
dst varchar(4) NOT NULL,
|
||||||
|
rfz varchar (4) NOT NULL,
|
||||||
|
mode varchar (10) default '',
|
||||||
|
prio integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Inqueue
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Inqueue (
|
||||||
|
location varchar (4) NOT NULL default 'I001',
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
gtin varchar(20) NOT NULL default '',
|
||||||
|
lotnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr2 varchar(20) NOT NULL default '',
|
||||||
|
duedate varchar(20) NOT NULL default '',
|
||||||
|
pieces varchar(20) NOT NULL default '',
|
||||||
|
deststorage varchar(4) NOT NULL default '',
|
||||||
|
destination INTEGER NOT NULL default '0',
|
||||||
|
PRIMARY KEY (location, boxnr)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Storage
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Storage (
|
||||||
|
id varchar (4) NOT NULL default '',
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
lotnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr2 varchar(20) NOT NULL default '',
|
||||||
|
duedate varchar(20) NOT NULL default '',
|
||||||
|
pieces INTEGER NOT NULL default '0',
|
||||||
|
x INTEGER NOT NULL default '0',
|
||||||
|
y INTEGER NOT NULL default '0',
|
||||||
|
z INTEGER NOT NULL default '0',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
PRIMARY KEY (id, boxnr)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX Storage_xyz ON Storage (id, x, y, z);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Insertiontimestamps
|
||||||
|
--
|
||||||
|
CREATE TABLE Insertiontimestamps (
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
PRIMARY KEY (boxnr)
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Outqueue
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Outqueue (
|
||||||
|
id varchar (4) NOT NULL default 'O001',
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
lotnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr2 varchar(20) NOT NULL default '',
|
||||||
|
duedate varchar(20) NOT NULL default '',
|
||||||
|
pieces varchar(20) NOT NULL default '',
|
||||||
|
x INTEGER NOT NULL default '0',
|
||||||
|
y INTEGER NOT NULL default '0',
|
||||||
|
z INTEGER NOT NULL default '0',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
PRIMARY KEY (id, boxnr)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Slotbase
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Slotbase (
|
||||||
|
id varchar (4) NOT NULL default '',
|
||||||
|
x INTEGER NOT NULL default '0',
|
||||||
|
y INTEGER NOT NULL default '0',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
PRIMARY KEY (id, x, y)
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Lockedslots
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Lockedslots (
|
||||||
|
id INTEGER NOT NULL default '0',
|
||||||
|
x INTEGER NOT NULL default '0',
|
||||||
|
y INTEGER NOT NULL default '0',
|
||||||
|
reason varchar(255) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX Lockedslots_idcy ON Lockedslots (id, x, y);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Transports
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Transports (
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
position varchar(6) NOT NULL default '',
|
||||||
|
src varchar(6) NOT NULL default '',
|
||||||
|
src_x varchar(2) NOT NULL default '',
|
||||||
|
src_y varchar(2) NOT NULL default '',
|
||||||
|
src_z varchar(2) NOT NULL default '',
|
||||||
|
dst varchar(6) NOT NULL default '',
|
||||||
|
dst_x varchar(2) NOT NULL default '',
|
||||||
|
dst_y varchar(2) NOT NULL default '',
|
||||||
|
dst_z varchar(2) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
ts timestamp(14)
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for Trace
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Trace (
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
lotnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr2 varchar(20) NOT NULL default '',
|
||||||
|
pieces INTEGER NOT NULL default '0',
|
||||||
|
x INTEGER NOT NULL default '0',
|
||||||
|
y INTEGER NOT NULL default '0',
|
||||||
|
z INTEGER NOT NULL default '0',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
action varchar(20) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Expressjobs
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Expressjobs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
source varchar(6) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
customer varchar(20) NOT NULL default '',
|
||||||
|
packlist varchar(20) NOT NULL default '',
|
||||||
|
article varchar(20) NOT NULL default '',
|
||||||
|
boxes integer not NULL default '0',
|
||||||
|
boxes_delivered integer not NULL default '0',
|
||||||
|
created timestamp(14) NOT NULL,
|
||||||
|
info varchar(50) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for Expresslog
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Expresslog (
|
||||||
|
expressjob INTEGER NOT NULL,
|
||||||
|
boxnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr varchar(20) NOT NULL default '',
|
||||||
|
lotnr2 varchar(20) NOT NULL default '',
|
||||||
|
pieces INTEGER NOT NULL default '0',
|
||||||
|
rfzts timestamp(14) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table Reefeed
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Refeed (
|
||||||
|
kistennummer varchar(20) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
charge varchar(20) NOT NULL default '',
|
||||||
|
gewicht decimal(10,0) NOT NULL default '0',
|
||||||
|
z INTEGER NOT NULL default '0',
|
||||||
|
reserved timestamp(14) NOT NULL,
|
||||||
|
PRIMARY KEY (kistennummer)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Compression Jobs
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Compressionjobs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
position varchar(6) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
created timestamp(14) NOT NULL,
|
||||||
|
info varchar(50) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Umlager Jobs Chaos
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Umlagerchaosjobs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
position varchar(6) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
sourcex INTEGER NOT NULL default '0',
|
||||||
|
sourcey INTEGER NOT NULL default '0',
|
||||||
|
created timestamp(14) NOT NULL,
|
||||||
|
info varchar(50) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Umlager Jobs ES
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE Umlageresjobs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
position varchar(6) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
sourcex INTEGER NOT NULL default '0',
|
||||||
|
sourcey INTEGER NOT NULL default '0',
|
||||||
|
created timestamp(14) NOT NULL,
|
||||||
|
info varchar(50) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Umlager Jobs ES
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE singlemovejobs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
position varchar(6) NOT NULL default '',
|
||||||
|
state varchar(5) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
src_id varchar (4) NOT NULL default '',
|
||||||
|
sourcex INTEGER NOT NULL default '0',
|
||||||
|
sourcey INTEGER NOT NULL default '0',
|
||||||
|
created timestamp(14) NOT NULL,
|
||||||
|
info varchar(50) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
initdata/dblayout_sqlite_ERPTrace.sql
Normal file
16
initdata/dblayout_sqlite_ERPTrace.sql
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for ERP Trace
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE ERPTrace (
|
||||||
|
kistennummer varchar(20) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
charge varchar(20) NOT NULL default '',
|
||||||
|
menge decimal(10,0) NOT NULL default '0',
|
||||||
|
einheit varchar(20) NOT NULL default 'KP',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
action varchar(20) NOT NULL default ''
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
25
initdata/dblayout_sqlite_order.sqlite
Normal file
25
initdata/dblayout_sqlite_order.sqlite
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
CREATE TABLE Orders (
|
||||||
|
id INT NOT NULL ,
|
||||||
|
customer_name VARCHAR(45) NULL ,
|
||||||
|
customer_address VARCHAR(45) NULL ,
|
||||||
|
deliverydate VARCHAR(10) NOT NULL ,
|
||||||
|
state VARCHAR(10) NULL DEFAULT 'New' ,
|
||||||
|
destination VARCHAR(10) NOT NULL ,
|
||||||
|
prio INT NOT NULL,
|
||||||
|
PRIMARY KEY (id) );
|
||||||
|
|
||||||
|
CREATE TABLE Orderlines (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
orderid INT NOT NULL ,
|
||||||
|
article INT NOT NULL ,
|
||||||
|
caption VARCHAR(45) NULL ,
|
||||||
|
amount DECIMAL(10,0) NOT NULL ,
|
||||||
|
amount_unit VARCHAR(2) NOT NULL DEFAULT 'KG' ,
|
||||||
|
amount_delivered DECIMAL(10,0) NOT NULL DEFAULT 0.0 ,
|
||||||
|
weight DECIMAL(10,0) NOT NULL ,
|
||||||
|
weight_unit VARCHAR(2) NOT NULL DEFAULT 'KG' ,
|
||||||
|
weight_delivered DECIMAL(10,0) NOT NULL DEFAULT 0.0 ,
|
||||||
|
state VARCHAR(10) NULL DEFAULT 'New' ,
|
||||||
|
CONSTRAINT uk_IdOrderId UNIQUE (id, orderid) ,
|
||||||
|
CONSTRAINT fk_OrderId FOREIGN KEY (orderid) REFERENCES Orders (id)
|
||||||
|
);
|
||||||
9
initdata/dblayout_storage_ERPTrace.sql
Normal file
9
initdata/dblayout_storage_ERPTrace.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE ERPTrace (
|
||||||
|
kistennummer varchar(20) NOT NULL default '',
|
||||||
|
artikelnummer varchar(20) NOT NULL default '',
|
||||||
|
charge varchar(20) NOT NULL default '',
|
||||||
|
menge decimal(10,0) NOT NULL default '0',
|
||||||
|
einheit varchar(20) NOT NULL default 'KG',
|
||||||
|
rfzts timestamp(14) NOT NULL,
|
||||||
|
action varchar(20) NOT NULL default ''
|
||||||
|
);
|
||||||
10
initdata/locked.py
Normal file
10
initdata/locked.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
storages = ['S001','S002','S003','S004']
|
||||||
|
x = 16
|
||||||
|
y = 12
|
||||||
|
for i in range (1, x + 1):
|
||||||
|
for j in range (1, y + 1):
|
||||||
|
for storage in storages:
|
||||||
|
print ("INSERT INTO Lockedslots VALUES ('%s', %d, %d, 'startup');" % (storage, i, j))
|
||||||
|
|
||||||
5
initdata/simulationdataSchachtstamm.sql
Normal file
5
initdata/simulationdataSchachtstamm.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
UPDATE Schachtstamm SET artikelnummer = '801', zone = 1 WHERE x = 2 AND y = 1;
|
||||||
|
UPDATE Schachtstamm SET artikelnummer = '802', zone = 1 WHERE x = 2 AND y = 2;
|
||||||
|
UPDATE Schachtstamm SET artikelnummer = '803', zone = 1 WHERE x = 2 AND y = 3;
|
||||||
|
UPDATE Schachtstamm SET artikelnummer = '804', zone = 2 WHERE x = 2 AND y = 4;
|
||||||
|
UPDATE Schachtstamm SET artikelnummer = '805', zone = 2 WHERE x = 2 AND y = 5;
|
||||||
91
initdata/storagephysics.py
Executable file
91
initdata/storagephysics.py
Executable file
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
"""
|
||||||
|
Generate Physics Databasecontent
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
storages = ['T001', 'T002', 'S001']
|
||||||
|
rfzs = 2
|
||||||
|
xSt = [18, 18, 39]
|
||||||
|
ySt = [7, 7, 8]
|
||||||
|
#Number of zones, followed by list with Zonestart X-Values
|
||||||
|
zones = [1, 1, 1, 1, 1]
|
||||||
|
zonestart = [[1], [1], [1], [1], [1]]
|
||||||
|
#Midvalue - where to start inserting Boxes (liste for each storage, with Tuple for each zone)
|
||||||
|
midSt = [[(18, 9), (12, 1)],\
|
||||||
|
[(16, 9)],\
|
||||||
|
[(16, 9)],\
|
||||||
|
[(16, 9)],\
|
||||||
|
[(1, 1)]]
|
||||||
|
#Z-value for Throughfeed shelfes
|
||||||
|
zTr = {'T001' : 7, \
|
||||||
|
'T002' : 7}
|
||||||
|
#Decide if a Throughfeed Storage is managed by a Slotbase
|
||||||
|
TrManaged = ['T002']
|
||||||
|
|
||||||
|
#Z-value dict for Commisioning shelfes
|
||||||
|
zCo = {'C001' : [1, 1, 1, 1, 1]}
|
||||||
|
|
||||||
|
#BoxnrCircles for IPoints
|
||||||
|
Nrs = {'I001': 1000100,\
|
||||||
|
'I002': 2000100}
|
||||||
|
|
||||||
|
idx = 0
|
||||||
|
print ("-- Storages configured")
|
||||||
|
print ("DELETE FROM Physics;")
|
||||||
|
print ("-- RFZs configured")
|
||||||
|
print ("INSERT INTO Physics VALUES ('RFZs', '%d');" % rfzs)
|
||||||
|
print ("INSERT INTO Physics VALUES ('Storages', '%d');" %len (storages))
|
||||||
|
for storage in storages:
|
||||||
|
print ("INSERT INTO Physics VALUES ('Storage%d', '%s');" %(idx, storage))
|
||||||
|
print ("INSERT INTO Physics VALUES ('X_%s','%d');" %(storage, xSt[idx]))
|
||||||
|
print ("INSERT INTO Physics VALUES ('Y_%s','%d');" %(storage, ySt[idx]))
|
||||||
|
#FixMe
|
||||||
|
if storage[0] in ['S', 'T']:
|
||||||
|
print ("INSERT INTO Physics VALUES ('ZONES_%s','%d');" %(storage, zones[idx]))
|
||||||
|
for i in range (1, zones[idx] + 1):
|
||||||
|
print ("INSERT INTO Physics VALUES ('ZONESTART_%s_%d','%d');" %(storage, i, zonestart[idx][i - 1]))
|
||||||
|
print ("INSERT INTO Physics VALUES ('XMid_%s_%d','%d');" %(storage, i, midSt[idx][i - 1][0]))
|
||||||
|
print ("INSERT INTO Physics VALUES ('YMid_%s_%d','%d');" %(storage, i, midSt[idx][i - 1][1]))
|
||||||
|
|
||||||
|
if storage[0] == 'S':
|
||||||
|
print ("-- Singleplace shelf configured")
|
||||||
|
print ("INSERT INTO Physics VALUES ('Z_%s','1');" %(storage))
|
||||||
|
elif storage[0] == 'T':
|
||||||
|
print ("-- Throughfeed shelf configured")
|
||||||
|
print ("INSERT INTO Physics VALUES ('Z_%s','%d');" %(storage, zTr[storage]))
|
||||||
|
elif storage[0] == 'C':
|
||||||
|
print ("-- Commisioning shelf configured")
|
||||||
|
for x in range (1 , xSt[idx] + 1):
|
||||||
|
for y in range (1, ySt[idx] + 1):
|
||||||
|
print ("INSERT INTO Physics VALUES ('Z_%s_%d_%d','%d');" %(storage, x, y, zCo[storage][y - 1]))
|
||||||
|
else:
|
||||||
|
print ("Invalid Storage")
|
||||||
|
sys.exit (0)
|
||||||
|
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
|
||||||
|
idx = 0
|
||||||
|
#slotbase for Commisioning shelfes
|
||||||
|
print ("-- Slotbase --")
|
||||||
|
print ("DELETE FROM Slotbase;")
|
||||||
|
for storage in storages:
|
||||||
|
if storage[0] == 'C':
|
||||||
|
print ("-- Build Slotbase for Commisioning storage %s --" % storage)
|
||||||
|
for x in range (1, xSt[idx] + 1):
|
||||||
|
for y in range (1, ySt[idx] + 1):
|
||||||
|
print ("INSERT INTO Slotbase (id, x, y) VALUES ('%s', %d, %d);" %(storage, x, y))
|
||||||
|
|
||||||
|
elif storage[0] == 'T' and storage in TrManaged:
|
||||||
|
print ("INSERT INTO Physics VALUES ('%s_Managed', 1);" %storage)
|
||||||
|
print ("-- Build Slotbase for managed Throughfeed Storage %s --" % storage)
|
||||||
|
for x in range (1, xSt[idx] + 1):
|
||||||
|
for y in range (1, ySt[idx] + 1):
|
||||||
|
print ("INSERT INTO Slotbase (id, x, y, article) VALUES ('%s', %d, %d, 'dynamic');" %(storage, x, y))
|
||||||
|
|
||||||
|
idx += 1
|
||||||
|
print ("-- BoxNrStart for I-Point")
|
||||||
|
for ipoint in Nrs:
|
||||||
|
print ("INSERT INTO Physics VALUES ('BoxNr_%s', '%d');" %(ipoint, Nrs[ipoint]))
|
||||||
39
locations.py
Executable file
39
locations.py
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger, Michael Rest"
|
||||||
|
__date__ = "22 Okt 2007"
|
||||||
|
__email__ = "egger@interearth.com, michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.2 $"[11:-2]
|
||||||
|
|
||||||
|
|
||||||
|
#Locations
|
||||||
|
locations = {}
|
||||||
|
locations ['Pick'] = ''
|
||||||
|
locations ['Puffer'] = ''
|
||||||
|
locations ['RFZ1'] = ''
|
||||||
|
locations ['RFZ2'] = ''
|
||||||
|
locations ['RFZ3'] = ''
|
||||||
|
locations ['IPKT'] = ''
|
||||||
|
locations ['DEST'] = ''
|
||||||
|
locations ['VF01'] = ''
|
||||||
|
|
||||||
|
|
||||||
|
#scanners
|
||||||
|
scanners = {}
|
||||||
|
scanners ['IPKT'] = 1
|
||||||
|
scanners ['RFZ1'] = 2
|
||||||
|
scanners ['RFZ2'] = 3
|
||||||
|
scanners ['RFZ3'] = 4
|
||||||
|
|
||||||
|
scanners ['BCL1'] = 101
|
||||||
|
scanners ['BCL2'] = 102
|
||||||
|
scanners ['BCL3'] = 103
|
||||||
|
scanners ['BCL4'] = 104
|
||||||
|
scanners ['BCL5'] = 105
|
||||||
|
scanners ['BCL6'] = 106
|
||||||
|
|
||||||
|
scanners ['HBCL1'] = 201
|
||||||
|
|
||||||
|
|
||||||
|
scanners ['MDE'] = 300
|
||||||
|
HBCL1 = 201
|
||||||
32
log.py
Normal file
32
log.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from time import time, strftime
|
||||||
|
loglevel = 7
|
||||||
|
def log (msg, _level = 3):
|
||||||
|
"""
|
||||||
|
Print message if in verbose mode.
|
||||||
|
"""
|
||||||
|
if _level <= loglevel:
|
||||||
|
file = open ("log.txt", "a")
|
||||||
|
file.write (strftime ("%Y-%m-%d %H:%M:%S "))
|
||||||
|
file.write (msg + "\n")
|
||||||
|
file.close ()
|
||||||
|
|
||||||
|
|
||||||
|
def strlog (instr):
|
||||||
|
"""
|
||||||
|
Converts String into readable format
|
||||||
|
"""
|
||||||
|
oustr = ''
|
||||||
|
for c in instr:
|
||||||
|
#if (ord (c) >= 33) & (ord (c) <= 127):
|
||||||
|
# oustr = oustr + c
|
||||||
|
#else:
|
||||||
|
oustr = oustr + " x%2X " %ord(c)
|
||||||
|
return oustr
|
||||||
|
|
||||||
|
def doublechar (i):
|
||||||
|
"""
|
||||||
|
build double char val out of int
|
||||||
|
"""
|
||||||
|
return chr (i % 256) + chr ((i >> 8) % 256)
|
||||||
|
|
||||||
|
|
||||||
71
lvr_BEAT.py
Executable file
71
lvr_BEAT.py
Executable file
@@ -0,0 +1,71 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Michael rest"
|
||||||
|
__date__ = "2006/02/13"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from cr_tpdu import CR_TPDU
|
||||||
|
from dt_tpdu import DT_TPDU
|
||||||
|
from tpkt import TPKT
|
||||||
|
from socket import *
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
BUFSIZE = 1024
|
||||||
|
def print_lebe (data):
|
||||||
|
print '\nTransportauftrag'
|
||||||
|
print ' Telegrammnr: %d ' %((ord (data[0]) << 8) + ord (data[1]))
|
||||||
|
print ' Sender : %s ' %data [2:4]
|
||||||
|
print ' Empfaenger : %s ' %data [4:6]
|
||||||
|
print ' Typ : %s ' %data [6:10]
|
||||||
|
print ' Telegrammnr: %d ' %((ord (data[10]) << 8) + ord (data[11]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#LEBE
|
||||||
|
tpdu = CR_TPDU ("BEAT", "BEAT", srcref=0x0015)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
print "Laenge: " + str (len (tpdu))
|
||||||
|
|
||||||
|
sleb = socket(AF_INET, SOCK_STREAM)
|
||||||
|
sleb.connect(("192.168.0.130", 102))
|
||||||
|
sleb.send(`tpkt`+`tpdu`)
|
||||||
|
|
||||||
|
data = sleb.recv (16384)
|
||||||
|
|
||||||
|
#Telegramme
|
||||||
|
id =0
|
||||||
|
|
||||||
|
#An I-Punkt
|
||||||
|
tel = 'LV' + 'TP' + 'LEBE' + '%c%c' %(0,1)
|
||||||
|
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
print '========================='
|
||||||
|
dt = '%c%c' %(id >> 8, id % 256) + tel
|
||||||
|
|
||||||
|
id = id + 1
|
||||||
|
print_lebe (dt)
|
||||||
|
tpdu = DT_TPDU (dt)
|
||||||
|
tpkt = TPKT (len (tpdu) + 1)
|
||||||
|
sleb.send(`tpkt`+`tpdu`)
|
||||||
|
data = sleb.recv (16384)
|
||||||
|
print_lebe (data[7:20])
|
||||||
|
sleep (4.1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
self.message ("Interrupted by user")
|
||||||
|
|
||||||
|
sleep (25.1)
|
||||||
|
|
||||||
|
#close connecthons
|
||||||
|
sleb.close ()
|
||||||
|
#while 1:
|
||||||
|
# data = sstau.recv(BUFSIZE)
|
||||||
|
#
|
||||||
|
# if not data:
|
||||||
|
# print "Stopping"
|
||||||
|
# sys.exit (0)
|
||||||
|
|
||||||
|
|
||||||
58
maillog.py
Normal file
58
maillog.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
from time import time, strftime
|
||||||
|
|
||||||
|
def mailexplog (expjob, explog):
|
||||||
|
"""
|
||||||
|
Creates Mail for Expressjob
|
||||||
|
"""
|
||||||
|
_expjob, _source, _state, _customer, _packl, _article, _boxes, _boxes_delivered, _ts, _info = expjob
|
||||||
|
lotnrs = ''
|
||||||
|
pcssum = 0
|
||||||
|
for elboxnr, ellotnr, ellotnr2, elpieces, elrfzts in explog:
|
||||||
|
if ellotnr and not ellotnr in lotnrs:
|
||||||
|
lotnrs = lotnrs + ellotnr +', '
|
||||||
|
if ellotnr2 and not ellotnr2 in lotnrs:
|
||||||
|
lotnrs = lotnrs + ellotnr +', '
|
||||||
|
pcs = 0
|
||||||
|
try:
|
||||||
|
pcs = int (elpieces)
|
||||||
|
except:
|
||||||
|
print ("Is hoid so")
|
||||||
|
pcssum = pcssum + pcs
|
||||||
|
|
||||||
|
prettyexplog = ''
|
||||||
|
for i in explog:
|
||||||
|
prettyexplog = prettyexplog + str (i).replace ("u''", '__').replace ("u'", "").replace ("'","") + '\n '
|
||||||
|
|
||||||
|
|
||||||
|
message = """From: ELA LVR <lvr@gustavogusto.com>
|
||||||
|
To: Waldemar Niedersetz <w.niedersetz@gustavogusto.com>
|
||||||
|
Subject: Auslagerung Kunde %s Lieferschein %s
|
||||||
|
Fuer den Kunden %s mit Lieferschein %s wurden
|
||||||
|
vom Artikel %s in Summe %s Paletten mit %s Gebinden ausgelagert.
|
||||||
|
|
||||||
|
Es waren folgende Chargen enthalten
|
||||||
|
%s
|
||||||
|
|
||||||
|
Auslagerauftrag %s vom %s
|
||||||
|
|
||||||
|
Die Ausgelagerten Paletten
|
||||||
|
(PaletteNr, Charge1, Charge 2, Anzahl Geb, Einlagerdatum)
|
||||||
|
%s
|
||||||
|
Ende
|
||||||
|
""" % (_customer, _packl,
|
||||||
|
_customer, _packl,
|
||||||
|
_article, len (explog), pcssum,
|
||||||
|
lotnrs,
|
||||||
|
_expjob, _ts,
|
||||||
|
prettyexplog)
|
||||||
|
|
||||||
|
file = open ("/opt/mails/" + strftime ("%Y-%m-%d_%H%M%S-mail.txt"), "a")
|
||||||
|
file.write (message)
|
||||||
|
file.close ()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
expjob = (23, u'T001', u'Done', u'0', u'0', u'119', 10, 10, u'2019-05-23 11:07:16', u'Job done')
|
||||||
|
explog = [(u'239', u'14319', u'', 81, u'2019-05-23 11:07:18'), (u'240', u'14319', u'', 81, u'2019-05-23 11:08:03'), (u'241', u'14319', u'', 81, u'2019-05-23 11:09:06'), (u'242', u'14319', u'', 81, u'2019-05-23 11:10:10'), (u'243', u'14319', u'', 81, u'2019-05-23 11:11:14'), (u'244', u'14319', u'', 81, u'2019-05-23 11:12:18'), (u'245', u'14319', u'', 81, u'2019-05-23 11:13:21'), (u'246', u'14319', u'', 81, u'2019-05-23 11:20:03'), (u'247', u'14319', u'', 81, u'2019-05-23 11:21:06'), (u'248', u'14319', u'', 81, u'2019-05-23 11:22:05')]
|
||||||
|
mailexplog (expjob, explog)
|
||||||
|
|
||||||
42
pySAP.py
Executable file
42
pySAP.py
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
sys.path.append (".")
|
||||||
|
from time import time, strftime, sleep
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class pySAP:
|
||||||
|
def __init__ (self, *dummy, **args):
|
||||||
|
"""
|
||||||
|
Initialize a new SAP exporter
|
||||||
|
"""
|
||||||
|
self.path = args.get ("path", "/opt/sap/")
|
||||||
|
self.time = time ()
|
||||||
|
|
||||||
|
def log (self, msg):
|
||||||
|
"""
|
||||||
|
Print message if in verbose mode.
|
||||||
|
"""
|
||||||
|
mins = int (strftime ("%M"))
|
||||||
|
file = open (self.path + strftime ("%Y_%m_%d_%H_") + '%02d' %(mins), "a")
|
||||||
|
file.write ( msg )
|
||||||
|
file.close ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from pySAP import *
|
||||||
|
from DB_ERP import DB_ERP
|
||||||
|
#sapfile = pySAP (path = "/opt/sap/")
|
||||||
|
sapfile = pySAP (path = "/Users/michi/logtest/")
|
||||||
|
|
||||||
|
#conn = DB_ERP ("/opt/data/storage_ERPTrace.db3")
|
||||||
|
conn = DB_ERP ("/Users/michi/devel/S7ISO/data/storage_ERPTrace.db3")
|
||||||
|
conn.markinsertionsasunread ()
|
||||||
|
sapfile.log ('')
|
||||||
|
for a, c, m, u in conn.getinsertions ():
|
||||||
|
if c=='':
|
||||||
|
c = 0
|
||||||
|
sapfile.log ('%05d;%010d;%s;%s\n' % (int (a), int (c), m, u))
|
||||||
|
conn.markinsertionsasread ()
|
||||||
36
scripts/cron_move.sh
Executable file
36
scripts/cron_move.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
#
|
||||||
|
# move files to storage
|
||||||
|
#
|
||||||
|
DATER=`date +%b%_3d%_9T`
|
||||||
|
#
|
||||||
|
#
|
||||||
|
echo $DATER chargencopy: starting procedure
|
||||||
|
FILES=`/usr/bin/find /opt/smb_lotnr -maxdepth 1 -name "*txt" -type f | /usr/bin/wc -l`
|
||||||
|
if [ $FILES -eq 0 ];
|
||||||
|
then
|
||||||
|
echo $DATER chargencopy: Nothing to do
|
||||||
|
echo $DATER chargencopy: terminated with error 2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if !(/bin/mount -t smbfs -o user=ela,password=matstamm,domain=linznet //172.41.31.16/input/pick /mnt/chargen_bizerba)
|
||||||
|
then
|
||||||
|
#/bin/umount //172.41.31.16/input
|
||||||
|
echo $DATER chargencopy: mount failed: could not mount remote share
|
||||||
|
echo $DATER chargencopy: terminated with error 1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#if !(/usr/bin/find /opt/smb_lotnr -maxdepth 1 -name "*txt" )
|
||||||
|
if [ $FILES -eq 0 ];
|
||||||
|
then
|
||||||
|
/bin/umount //172.41.31.16/input
|
||||||
|
echo $DATER chargencopy: no files
|
||||||
|
echo $DATER chargencopy: terminated with error 2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
cp /opt/smb_lotnr/*txt /mnt/chargen_bizerba
|
||||||
|
#mv /opt/smb_lotnr/*txt /opt/smb_lotnr/archive
|
||||||
|
rm /opt/smb_lotnr/*txt
|
||||||
|
/bin/umount //172.41.31.16/input
|
||||||
21
scripts/smbmove.sh
Executable file
21
scripts/smbmove.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
DATER=`date +%b%_3d%_9T`
|
||||||
|
echo $DATER IPointlog: starting procedure
|
||||||
|
FILES=`/usr/bin/find /opt/sap -maxdepth 1 -name "*txt" -type f | /usr/bin/wc -l`
|
||||||
|
if [ $FILES -eq 0 ]; then
|
||||||
|
echo $DATER IPointlog: Nothing to do
|
||||||
|
echo $DATER IPointlog: terminated with error 2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#mount | grep "/opt/sap/remote" /etc/mtab > /dev/null
|
||||||
|
#if [ $? -ne 0 ]; then
|
||||||
|
if !(smbmount //172.41.3.8/ELA /opt/sap/remote -o user=ela,pass=matstamm ,dom=LANDHOF) then
|
||||||
|
echo $DATER IPointlog: mount failed: could not mount remote share
|
||||||
|
echo $DATER IPointlog: terminated with error 1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv /opt/sap/20*.txt /opt/sap/remote/IPOINTLOG
|
||||||
|
/bin/umount /opt/sap/remote
|
||||||
9
start.sh
Executable file
9
start.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
echo "Starting LVR in `pwd` at `date`" >> /var/log/lvr/startstop.log
|
||||||
|
#python ./storage.py `pwd` 2>&1 >> log_`date -Idate`.txt
|
||||||
|
python ./storage.py `pwd` 2>&1 >> log.txt
|
||||||
|
echo "LVR stopped in `pwd` at `date`" >> /var/log/lvr/startstop.log
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
32
storage.cfg.tpl
Normal file
32
storage.cfg.tpl
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[IP Settings]
|
||||||
|
iplvr = 192.168.0.100
|
||||||
|
ipsps = 192.168.0.106
|
||||||
|
|
||||||
|
[DB Settings]
|
||||||
|
dbfile = /opt/data/storageWu.db3
|
||||||
|
logfile = /opt/data/storageWu_talog.sql
|
||||||
|
|
||||||
|
[DEBUG]
|
||||||
|
loglevel = 6
|
||||||
|
debuglevel = 1
|
||||||
|
|
||||||
|
[PARAM]
|
||||||
|
ipktreservation = 1
|
||||||
|
keepinqueue = 0
|
||||||
|
articlemustbedefined = 1
|
||||||
|
dummyactive = 0
|
||||||
|
ordering = 0
|
||||||
|
expressendtovf = 0
|
||||||
|
|
||||||
|
[OPTIONS]
|
||||||
|
rk512 = 0
|
||||||
|
rkdev = /dev/ttyS0
|
||||||
|
ERPTrace = 1
|
||||||
|
ERPDB = /opt/data/storage_ERPTrace.db3
|
||||||
|
ERPType = 1
|
||||||
|
ERPCycl = 30
|
||||||
|
MDE = 1
|
||||||
|
MDEDB = /opt/data/mdedata.db3
|
||||||
|
CSBCOM = 1
|
||||||
|
CSBSOCK = /tmp/lv_csb.socket
|
||||||
|
OrderPath = /opt/sap
|
||||||
98
storage.init
Executable file
98
storage.init
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: skeleton
|
||||||
|
# Required-Start: $local_fs $remote_fs
|
||||||
|
# Required-Stop: $local_fs $remote_fs
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: S 0 1 6
|
||||||
|
# Short-Description: Example initscript
|
||||||
|
# Description: This file should be used to construct scripts to be
|
||||||
|
# placed in /etc/init.d.
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
# Author: Foo Bar <foobar@baz.org>
|
||||||
|
#
|
||||||
|
# Please remove the "Author" lines above and replace them
|
||||||
|
# with your own name if you copy and modify this script.
|
||||||
|
|
||||||
|
# Do NOT "set -e"
|
||||||
|
|
||||||
|
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||||
|
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
DESC="Storage System"
|
||||||
|
NAME=storage
|
||||||
|
STORAGE=/opt/storage-karnertaWU
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
# Define LSB log_* functions.
|
||||||
|
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that starts the daemon/service
|
||||||
|
#
|
||||||
|
do_start()
|
||||||
|
{
|
||||||
|
pushd $STORAGE
|
||||||
|
$STORAGE/start.sh &
|
||||||
|
popd
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that stops the daemon/service
|
||||||
|
#
|
||||||
|
do_stop()
|
||||||
|
{
|
||||||
|
pkill -f $STORAGE/start.sh
|
||||||
|
sleep 5s
|
||||||
|
pkill -KILL -f $STORAGE/start.sh
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
#
|
||||||
|
# If the "reload" option is implemented then remove the
|
||||||
|
# 'force-reload' alias
|
||||||
|
#
|
||||||
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1)
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0) log_end_msg 0 ;;
|
||||||
|
1) log_end_msg 1 ;; # Old process is still running
|
||||||
|
*) log_end_msg 1 ;; # Failed to start
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Failed to stop
|
||||||
|
log_end_msg 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
:
|
||||||
1333
storage.py
Executable file
1333
storage.py
Executable file
File diff suppressed because it is too large
Load Diff
54
tel_decode.py
Executable file
54
tel_decode.py
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger, Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
from telegram import TEL_LEBE, TEL_TAUF, TEL_TQUI, TEL_SCLS, TEL_STAT, TEL_IPKT
|
||||||
|
|
||||||
|
__all__ = ["decode_packet"]
|
||||||
|
|
||||||
|
|
||||||
|
def decode_LEBE (data):
|
||||||
|
from LEBE_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
def decode_TQUI (data):
|
||||||
|
from TQUI_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
def decode_SCLS (data):
|
||||||
|
from SCLS_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
def decode_STAT (data):
|
||||||
|
from STAT_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
def decode_IPKT (data):
|
||||||
|
from IPKT_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
def decode_TAUF (data):
|
||||||
|
from TAUF_tel import fromstring
|
||||||
|
return fromstring (data)
|
||||||
|
|
||||||
|
decoderlist = {
|
||||||
|
'LEBE': decode_LEBE,
|
||||||
|
'TQUI': decode_TQUI,
|
||||||
|
'SCLS': decode_SCLS,
|
||||||
|
'STAT': decode_STAT,
|
||||||
|
'IPKT': decode_IPKT,
|
||||||
|
'TAUF': decode_TAUF
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def decodetelegram (data):
|
||||||
|
type = data[6:10]
|
||||||
|
if type in decoderlist:
|
||||||
|
return decoderlist[type](data)
|
||||||
|
else:
|
||||||
|
print ("Unhandled telegramtype %s" %type)
|
||||||
|
raise Warning, "Undhandled packettype"
|
||||||
|
return
|
||||||
66
telegram.py
Normal file
66
telegram.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "2006/02/15"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
# Packet types
|
||||||
|
TEL_LEBE = 0xa #
|
||||||
|
TEL_TAUF = 0xb #
|
||||||
|
TEL_TQUI = 0xc #
|
||||||
|
TEL_SCLS = 0xd #
|
||||||
|
TEL_STAT = 0xe #
|
||||||
|
TEL_QUIT = 0xf #
|
||||||
|
TEL_IPKT = 0x9 #
|
||||||
|
|
||||||
|
class TELEGRAM:
|
||||||
|
def __init__ (self):
|
||||||
|
self.len = 0
|
||||||
|
self.code = 0
|
||||||
|
self.attrib = {'src': ' ', 'dst': ' ', 'type': 'NONE', 'check' : 0}
|
||||||
|
|
||||||
|
def type (self):
|
||||||
|
"""
|
||||||
|
Return type hexadecimal type of the TELEGRAM. This function is
|
||||||
|
common for all TPDUs.
|
||||||
|
"""
|
||||||
|
return self.code
|
||||||
|
|
||||||
|
def __len__ (self):
|
||||||
|
"""
|
||||||
|
Return the calcuclated length of the TELEGRAM. The value is
|
||||||
|
always WITHOUT the coded type, add 1 to it if in doubt.
|
||||||
|
"""
|
||||||
|
return self.len
|
||||||
|
|
||||||
|
def __getitem__ (self, key):
|
||||||
|
"""
|
||||||
|
Return Attrib
|
||||||
|
"""
|
||||||
|
return self.attrib[key]
|
||||||
|
|
||||||
|
def has_key (self, key):
|
||||||
|
"""
|
||||||
|
Check for Key
|
||||||
|
"""
|
||||||
|
return self.attrib.has_key(key)
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TELEGRAM. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c" % (2, self.code << 4, self.number)
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
67
tpdu.py
Executable file
67
tpdu.py
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
# Packet types
|
||||||
|
TPDU_CC = 0xd # Connection reply
|
||||||
|
TPDU_CR = 0xe # Connection request
|
||||||
|
TPDU_DT = 0xf # Datapacket transfer
|
||||||
|
|
||||||
|
# Packet parameters
|
||||||
|
PARM_ACKTIME = 0x85 # Acknowledge time
|
||||||
|
PARM_RER = 0x86 # Residual error rate
|
||||||
|
PARM_PRIORITY = 0x87 # Priority
|
||||||
|
PARM_TRANSITDELAY = 0x88 # Transit delay
|
||||||
|
PARM_THROUGHPUT = 0x89 # Troughput
|
||||||
|
PARM_SUBSEQNUM = 0x8a # Subsequence number
|
||||||
|
PARM_REASSTIME = 0x8b # Reassignment time
|
||||||
|
PARM_FLOWCTRLCON = 0x8c # Flow control confirmation
|
||||||
|
PARM_SIZE = 0xc0 # Size of the TPDU
|
||||||
|
PARM_SRCTSAP = 0xc1 # The calling TSAP
|
||||||
|
PARM_DSTTSAP = 0xc2 # The called TSAP
|
||||||
|
PARM_CHECKSUM = 0xc3 # Checksum
|
||||||
|
PARM_VERSION = 0xc4 # Version number
|
||||||
|
PARM_PROTECTION = 0xc5 # Protection
|
||||||
|
PARM_OPTIONS = 0xc6 # Additional option selection
|
||||||
|
PARM_ALTERNATIVE = 0xc7 # Alternative protocol classes
|
||||||
|
|
||||||
|
class TPDU:
|
||||||
|
len = 0
|
||||||
|
code = 0
|
||||||
|
|
||||||
|
def type (self):
|
||||||
|
"""
|
||||||
|
Return type hexadecimal type of the TPDU. This function is
|
||||||
|
common for all TPDUs.
|
||||||
|
"""
|
||||||
|
return self.code
|
||||||
|
|
||||||
|
def __len__ (self):
|
||||||
|
"""
|
||||||
|
Return the calcuclated length of the TPDU. The value is
|
||||||
|
always WITHOUT the coded type, add 1 to it if in doubt.
|
||||||
|
"""
|
||||||
|
return self.len
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
"""
|
||||||
|
Print a representation of the TPDU. Use this method via
|
||||||
|
`-pair to transfer it over the wire. This will just return
|
||||||
|
the header data and not the real data!
|
||||||
|
"""
|
||||||
|
# Note that the data is not included in the length
|
||||||
|
return "%c%c" % (2, self.code << 4, self.number)
|
||||||
|
|
||||||
|
def __str__ (self):
|
||||||
|
"""
|
||||||
|
Return a readable and quite verbose overview of the TPDU instance.
|
||||||
|
Use this for debugging purposes or if you're just curious.
|
||||||
|
"""
|
||||||
|
string = DT_STRING % (self.len, self.number, self.data)
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
18
tpkt.py
Executable file
18
tpkt.py
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Daniel Egger"
|
||||||
|
__date__ = "22 March 2002"
|
||||||
|
__email__ = "egger@interearth.com"
|
||||||
|
__version__ = "$Revision: 1.1 $"[11:-2]
|
||||||
|
|
||||||
|
class TPKT:
|
||||||
|
def __init__ (self, len):
|
||||||
|
self.version = 3
|
||||||
|
self.reserved = 0
|
||||||
|
# Also include length of trailer
|
||||||
|
self.len = len + 4
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
return "%c%c%c%c" % (self.version, self.reserved, (self.len >> 8) & 0xff,
|
||||||
|
self.len & 0xff)
|
||||||
|
|
||||||
23
utility.py
Normal file
23
utility.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python2.6
|
||||||
|
#-*- coding: utf-8 -*-
|
||||||
|
__author__ = "Michael Rest"
|
||||||
|
__date__ = "1 August 2010"
|
||||||
|
__email__ = "michi@rosstein.de"
|
||||||
|
__version__ = "$Revision: 1.0 $"[11:-2]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
Reference in New Issue
Block a user