Initial Start Commit
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ storage.cfg
|
||||
*.AppleDouble/
|
||||
.DS_Store
|
||||
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