This commit is contained in:
2017-11-26 15:47:38 +01:00
parent c51b755024
commit 63f634f771
7 changed files with 513 additions and 59 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
*~
*.pyc
*.AppleDouble/
lactor.cfg
.DS_Store
sampledata

24
DB.py
View File

@@ -80,7 +80,7 @@ class DB:
Return all Data of animals
"""
try:
cursor = self.executesql ("SELECT animalnr, earmark, rfid, forbidmilk FROM animals;")
cursor = self.executesql ("SELECT animalnr, earmark, rfid, tsforbidstart, tsforbidend FROM animals;")
except:
return None
@@ -93,18 +93,29 @@ class DB:
Add animal
"""
try:
cursor = self.executesql ("INSERT OR REPLACE INTO animals (animalnr, earmark, rfid, forbidmilk ) VALUES ('%(animalnr)d', '%(earmark)s', '%(rfid)s', '%(forbidmilk)s');" % data)
cursor = self.executesql ("INSERT OR REPLACE INTO animals (animalnr, earmark, rfid) VALUES ('%(animalnr)d', '%(earmark)s', '%(rfid)s');" % data)
except:
print ("Couldnt insert into animals")
raise Warning
def updatemilkingforbid (self, data):
"""
Update Milking Forbid
"""
try:
cursor = self.executesql ("UPDATE animals set tsforbidstart = '%(tsforbidstart)s', tsforbidend = '%(tsforbidend)s' WHERE animalnr = '%(animalnr)d';" % data)
except:
print ("Couldnt update milkforbid information")
raise Warning
def getanimal (self, animalnr):
"""
Get Animaldata
"""
try:
cursor = self.executesql ("SELECT animalnr, earmark, rfid, forbidmilk FROM animals WHERE animalnr = '%s';" % animalnr)
cursor = self.executesql ("SELECT animalnr, earmark, rfid, tsforbidstart, tsforbidend FROM animals WHERE animalnr = '%s';" % animalnr)
except:
print ("Couldnt read from animals")
@@ -127,7 +138,6 @@ class DB:
Add Milkingdata
"""
try:
print ("UPDATE milkdata SET ammount = '%(ammount)s', time = '%(time)s' WHERE ts='%(ts)s' AND animalnr = '%(animalnr)d';" % data)
cursor = self.executesql ("UPDATE milkdata SET ammount = '%(ammount)s', time = '%(time)s' WHERE ts='%(ts)s' AND animalnr = '%(animalnr)d';" % data)
except:
print ("Couldnt update milkdata")
@@ -152,7 +162,7 @@ class DB:
Return Milkingdata of Animal
"""
try:
cursor = self.executesql ("SELECT ts, animalnr, ammount, time FROM milkdata WHERE animalnr = '%d' ORDER BY ts DESC LIMIT %d;" % (int (animalnr), last))
cursor = self.executesql ("SELECT ts, animalnr, ammount, time, milkplace FROM milkdata WHERE animalnr = '%d' ORDER BY ts DESC LIMIT %d;" % (int (animalnr), last))
except:
return None
@@ -167,8 +177,8 @@ if __name__ == "__main__":
conn = DB ('/opt/data/animaldb.sqlite', '/tmp/talog.sql', logtest, errlogtest)
data = {'animalnr' : 711,
'earmark' : 'DE09 4711',
'rfid' : '123543546',
'forbidmilk': '0'}
'rfid' : '123543546'
}
#conn.addanimal (data)
print (conn.getanimals ())

305
Taurus.py Normal file
View File

@@ -0,0 +1,305 @@
from time import time, strftime
from DB import *
entities = {}
"""
Entity 201861
Header
"""
#NR, ART, ITEM, NAME, TYPE, LEN, RESOLUTION, UNIT, CODE
entities ['201861'] = [
(1, 'KEY', '00000000', 'Typ', 'AN', 8, 0, '', 0),
(2, 'MAN', '00201575', 'Erstelldatum', 'N', 8, 0, 'CCYYMMDD', 0),
(3, 'MAN', '00201576', 'Erstellzeit', 'N', 6, 0, 'hhmmss', 0),
(2, 'MAN', '00201577', 'Systemstatus', 'N', 1, 0, '', 0),
(3, 'MAN', '00201681', 'Absender', 'AN', 24, 0, '', 0),
(4, 'MAN', '00201682', 'Empfaenger', 'AN', 24, 0, '', 0),
(7, 'MAN', '00502012', 'Software', 'AN', 10, 0, '', 0),
(8, 'MAN', '00201684', 'Senderversion', 'AN', 8, 0, '', 0),
(9, 'MAN', '00201685', 'ADED-Nation.-Vers.', 'AN', 8, 0, '', 0)
]
"""
Entity 201863
Tierdaten
"""
#NR, ART, ITEM, NAME, TYPE, LEN, RESOLUTION, UNIT, CODE
entities ['201863'] = [
(1, 'KEY', '00201896', 'Stallnummer', 'N', 6, 0, '', 0),
(2, 'MAN', '00201812', 'Elektron. ID', 'AN', 15, 0, '', 0),
(3, 'MAN', '00200064', 'Gruppe', 'N', 2, 0, '', 0),
(4, 'MAN', '00201695', 'Geburtsdatum', 'N', 8, 0, 'CCYYMMDD', 0),
(5, 'MAN', '00200042', 'Kalbdatum', 'N', 8, 0, 'CCYYMMDD', 0),
(6, 'MAN', '00200060', 'Belegungsdatum', 'N', 8, 0, 'CCYYMMDD', 0),
(7, 'MAN', '00200513', 'Trockenstelldatum', 'N', 8, 0, 'CCYYMMDD', 0),
(8, 'MAN', '00201743', 'Datum Brunstkontrolle', 'N', 8, 0, 'CCYYMMDD', 0),
(9, 'MAN', '00900085', 'Tieruntersuchung', 'N', 1, 0, '', 0),
(10, 'MAN', '00900059', 'Datum Tieruntersuchung', 'N', 8, 0, 'CCYYMMDD', 0),
(11, 'MAN', '00900058', 'Laktationsnummer', 'N', 2, 0, '', 0),
(13, 'OPT', '00900080', 'Ohrnummer', 'N', 15, 0, '', 0)
]
"""
Entity 201865
Futterdaten
"""
#NR, ART, ITEM, NAME, TYPE, LEN, RESOLUTION, UNIT, CODE
entities ['201865'] = [
(1, 'KEY', '00201896', 'Stallnummer', 'N', 6, 0, '', 0),
(2, 'MAN', '00201859', 'Futter Nr 1/2', 'N', 1, 0, '', 0),
(3, 'MAN', '00201828', 'Futter Soll', 'N', 6, 3, '', 0),
(4, 'MAN', '00201831', 'Futter Rest', 'N', 6, 3, '', 0),
(5, 'MAN', '00201856', 'Futter Gesamt', 'N', 8, 3, '', 0)
]
"""
Entity 201867
Melkverbot
"""
#NR, ART, ITEM, NAME, TYPE, LEN, RESOLUTION, UNIT, CODE
entities ['201867'] = [
(1, 'KEY', '00201896', 'Stallnummer', 'N', 6, 0, '', 0),
(2, 'OPT', '00900080', 'Ohrnummer', 'N', 15, 0, '', 0),
(3, 'MAN', '00004401', 'Start Melkverbot', 'N', 8, 0, 'CCYYMMDD', 0),
(4, 'MAN', '00004402', 'Ende Melkverbot', 'N', 8, 0, 'CCYYMMDD', 0)
]
"""
Entity 201866
Gemelkerfassung
"""
#NR, ART, ITEM, NAME, TYPE, LEN, RESOLUTION, UNIT, CODE
entities ['201866'] = [
(1, 'KEY', '00201896', 'Stallnummer', 'N', 6, 0, '', 0),
(2, 'MAN', '00201729', 'Melkdatum', 'N', 8, 0, 'CCYYMMDD', 0),
(3, 'MAN', '00202513', 'Melkzeit', 'N', 6, 0, 'hhmmss', 0),
(4, 'MAN', '00200488', 'Milch', 'N', 3, 1, '', 0),
(5, 'MAN', '00201596', 'Durchschn. Melkgeschwindigkeit', 'N', 3, 2, '', 0),
(6, 'OPT', '00200489', 'Temperatur', 'N', 3, 1, '', 0),
(7, 'MAN', '00201830', 'Milchflussdauer', 'N', 3, 1, '', 0),
(8, 'MAN', '00201860', 'Melkplatz', 'N',2, 0, '', 0)
]
class TAURUS:
def __init__ (self, db, loglevel, writefilename):
self.db = db
self.loglevel = loglevel
#Optional Fields for an entity
self.entityfields = {'880022': ['800702', '900070']}
self.writefilename = writefilename
def log (self, msg, _level = 3):
"""
Logfile
Loglevel 9 = print to console
"""
if self.loglevel == 9:
print (msg)
if _level <= self.loglevel:
file = open ("/var/log/lactor/" + os.getcwd().split('/')[-1] + '.err', "a")
dt = datetime.now ()
file.write ("%4d-%02d-%02d %02d:%02d:%02d.%06d: " %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond) + msg + "\n")
file.close ()
def parsefile (self, path, filename):
"parse taurus file"
file = open (path + filename)
currententity = 0
currentd = []
request = []
for line in file.readlines ():
if len (line) > 2:
self.log ("Line: %s" % line)
linetype = line [0]
linestatus = line [1]
linedata = line [2:]
if linetype == 'D':
#Definition
if linestatus == 'H':
self.log ("Definition Header", 9)
currententity, currentd = self.parsed (linedata)
elif linestatus == 'N':
self.log ("Definition Normaldaten", 9)
currententity, currentd = self.parsed (linedata)
elif linetype == 'R':
#Request
if linestatus == 'N':
self.log ("Request Normaldaten", 9)
reqentity, reqd = self.parsed (linedata)
self.log ("Request Normaldaten entity %s" % reqentity, 9)
request.append ((reqentity, reqd))
elif linetype == 'V':
#Values
entity = linedata [:6]
linevalues = linedata [6:]
if currententity == entity:
values = self.parsev (currentd, linevalues)
self.log (repr (values), 9)
if linestatus == 'H':
self.log ("Header Daten", 9)
elif linestatus == 'N':
self.log ("Normaldaten", 9)
if currententity == '201863':
self.log ("Tierdaten updaten", 6)
animaldata = {'animalnr' : values ['00201896'],
'earmark' : values ['00900080'],
'rfid' : values ['00201812'],
'forbidmilk' : 0}
self.db.addanimal (animaldata)
elif currententity == '201867':
self.log ("Melkverbot updaten", 6)
forbiddata = {'animalnr' : values ['00201896'],
'tsforbidstart' : '',
'tsforbidend' :''}
try:
tsstart = datetime.strptime (str (values ['00004401']), '%Y%m%d')
forbiddata ['tsforbidstart'] = tsstart
except:
self.log ("Wertfehler Melkverbot Startzeitstempel : %s"% values ['00004401'])
try:
tsend = datetime.strptime (str (values ['00004402']) + '235959', '%Y%m%d%H%M%S')
forbiddata ['tsforbidend'] = tsend
except:
self.log ("Wertfehler Melkverbot Endzeitstempel : %s"% values ['00004402'])
self.db.updatemilkingforbid (forbiddata)
elif linetype == 'E':
#End of Logical File
self.log ("Ende Logisches File")
elif linetype == 'Z':
#End of Physical File
break
file.close ()
# Handle Requests
if request:
file = open (path + self.writefilename, 'w')
for reqentity, reqd in request:
self.log ("Request %s ausfuehren" % reqentity)
if reqentity == '201865':
wline = self.generated (reqentity, reqd)
file.write (wline + '\n')
if reqentity == '201866':
wline = self.generated (reqentity, reqd)
file.write (wline + '\n')
for animalinfo in self.db.getanimals ():
wline = self.createmilkdataset (animalinfo, reqd, 10)
if wline:
file.write (wline + '\n')
file.write (wline + 'EN\n')
file.write (wline + 'ZN\n')
file.close ()
def generated (self, entity, ddef):
#Generate Datadefiniton
l = 'DN' + entity
for nr, art, item, name, datatype, length, resolution, unit, code in ddef:
l += '%s%02d%01d' % (item, length, resolution)
return l
def parsed (self, data):
"parse an Dx and return datasetdefinition"
entityid = data [:6]
_data = data [6:].replace ('\n', '').replace ('\r', '')
entity = entities [entityid]
self.log ("Defdata length: %d" % len(_data))
ds = []
for i in range (0, len (_data) , 11):
_item = _data [i: i + 8]
_len = int (_data [i + 8: i + 10])
_unit = _data [i + 10:]
self.log ("Itemid %s" % _item, 9)
for nr, art, item, name, datatype, length, resolution, unit, code in entity:
if _item == item:
ds.append ((nr, art, item, name, datatype, length, resolution, unit, code))
if _len != length:
self.log ("Error Size was %d instead of %d" % (_len, length), 1)
return entityid,ds
def parsev (self, definition, data):
"""
parse value
"""
_data = data
values = {}
for nr, art, item, name, datatype, length, resolution, unit, code in definition:
_value = _data[:length]
if datatype == 'N':
try:
_value = int (_value)
except:
if '?' in _value:
_value = 0
else:
self.log ("Wertfehler %s" % _value)
values [item] = _value
_data = _data[length:]
return values
def createmilkdataset (self, animalinfo, ddef, nr):
"""
Creating entity for 880022
"""
animalnr, earmark, rfid, tsforbidstart, tsforbidend = animalinfo
#Check milking forbidden
milkforbid = 0
if tsforbidstart:
dttsforbidstart = datetime.strptime (tsforbidstart, '%Y-%m-%d %H:%M:%S')
if datetime.now () > dttsforbidstart:
if tsforbidend:
dttsforbidend = datetime.strptime (tsforbidend, '%Y-%m-%d %H:%M:%S')
if datetime.now () <= dttsforbidend:
milkforbid = 1
else:
milkforbid = 1
retval = ''
mds = self.db.getlastmilkdatabyanimal (animalnr, nr)
for md in mds:
ts, animalnr, ammount, time, milkplace = md
dt = datetime.strptime (ts, '%Y-%m-%d %H:%M:%S')
mdate = dt.strftime ('%Y%m%d')
mtime = dt.strftime ('%H%M%S')
data = {'00201896': animalnr}
data ['00201729'] = mdate
data ['00202513'] = mtime
data ['00200488'] = float (ammount) / 1000.0
data ['00201830'] = float (time) / 60.0
data ['00201860'] = milkplace
ds = "VN201866"
for nr, art, item, name, datatype, length, resolution, unit, code in ddef:
if item in data:
if datatype == 'AN':
ds += data[item].rjust (int (length + 1))
elif datatype == 'N':
_v = "%d" % (int (data[item] * (10**int (resolution))))
ds += _v.rjust (int (length))
else:
ds += '?' * length
if retval:
retval += '\n'
retval += ds
self.log (ds, 9)
return retval
if __name__ == "__main__":
taurus = TAURUS (DB ('/opt/data/animaldb.sqlite', '/tmp/talog.sql', logtest, errlogtest), loglevel = 9, writefilename = 'rep.taur')
taurus.parsefile ('sampledata/', 'Update.taur')
taurus.parsefile ('sampledata/', 'Melkverbot.taur')
taurus.parsefile ('sampledata/', 'Request.taur')

View File

@@ -2,12 +2,15 @@ CREATE TABLE animals (
animalnr INTEGER UNIQUE NOT NULL,
earmark CHAR (25) NOT NULL,
rfid INTEGER,
forbidmilk CHAR (1) default '0'
forbidmilk CHAR (1) default '0',
tsforbidstart timestamp (14),
tsforbidend timestamp (14)
);
CREATE TABLE milkdata (
ts timestamp (14) NOT NULL,
animalnr INTEGER NOT NULL,
ammount decimal(10,2) NOT NULL default '0',
time integer NOT NULL
time integer NOT NULL,
milkplace INTEGER NOT NULL default 1
);

19
lactor.cfg.tpl Normal file
View File

@@ -0,0 +1,19 @@
[Settings]
dbfile = /opt/data/animaldb.sqlite
candev = can0
[DEBUG]
loglevel = 6
debuglevel = 1
[HERDE]
herde = 1
herdepath = /srv/herde
herdereadfile = Tau_ms.2
herdewritefile = Tau_prc.2
[Animal Recognition]
animalrecognition = 0
rfiddev = /dev/serial0

206
lactor.py
View File

@@ -1,7 +1,13 @@
#!/usr/bin/env python3
import sys, os
from pathlib import Path
import can
import serial
from DB import *
from time import sleep, time, strftime
from datetime import *
from configparser import *
from Taurus import *
bus = None
infotype = {0 : 'S-Buffer deleted',
@@ -18,8 +24,8 @@ class CanListener (can.Listener):
print ("Received Data")
self.CanDecode (msg)
def set_db (self, dbpath = '/opt/lactor/animaldb.sqlite'):
self.db_con = DB (dbpath, '/tmp/talog.sql', logtest, errlogtest)
def set_db (self, dbcon):
self.db_con = dbcon
self.dataset = [None] * 128
self.waitack = [0] * 128
self.waitackst = [0] * 128
@@ -49,41 +55,41 @@ class CanListener (can.Listener):
Decoding Can Telegram
"""
if msg.is_extended_id:
self.log ("Rcvd Msg with Extended ID", 0)
self.log ("Msg Mit Erweiterter ID erhalten", 0)
return
if msg.is_error_frame:
self.log ("Rcvd Msg Error Frame", 0)
self.log ("Msg Error Frame erhalten", 0)
return
if msg.is_remote_frame:
self.log ("Rcvd Msg Remote Frame", 0)
self.log ("Msg Remote Frame erhalten", 0)
return
_id = msg.arbitration_id
self.log ("Msg %s" % msg, 9)
self.log ("Msg: %s" % msg, 9)
#Pos 11 Direction
if not is_set (_id, 10):
self.log ("Received Data to xLactor", 0)
self.log ("Daten fur xLactor Steuerung erhalten", 0)
return
#Pos 8-10 Infotype
_info_type = (_id & 0b01110000000) >> 7
self.log ("Infotype: %s %s" % (hex (_id), infotype [_info_type]), 3)
self.log ("Infotyp: %s %s" % (hex (_id), infotype [_info_type]), 3)
#Pos 1-7 Address
_address = (_id & 0b00001111111)
self.log ("Address: %d" % _address, 4)
self.log ("Addresse: %d" % _address, 4)
#Determine Addresstype
if ((_address & 0b1000000) == 0b0000000):
self.log ("Terminal %d" % _address, 3)
elif ((_address & 0b1110000) == 0b1000000):
#Obsolete
self.log ("Gatecontrol %d" % _address, 3)
self.log ("Tuersteuerung obsolete %d" % _address, 3)
elif ((_address & 0b1110000) == 0b1010000):
#Obsolete
self.log ("Animalrecognition %d" % _address, 3)
self.log ("Tiererkennung obsolete %d" % _address, 3)
elif ((_address & 0b1110000) == 0b1100000):
#Obsolete
self.log ("WateringPlace %d" & _address, 3)
self.log ("Wasserplatz obsolete %d" & _address, 3)
elif ((_address & 0b1110000) == 0b1110000):
#Obsolete
self.log ("Other %d" % _address, 1)
@@ -95,7 +101,7 @@ class CanListener (can.Listener):
#Animalnr request
if infotype [_info_type] == 'animal nr':
if 'REQ' in str (_data):
self.log ("Requested AnimalNr from Recognition", 3)
self.log ("Anforderung Tiernummer von Tiererkennung", 3)
#FixMe AnimalNr from rFID
animalnr = 12
#_sendecho = 0
@@ -103,63 +109,74 @@ class CanListener (can.Listener):
self.waitack [_address] = 1
elif self.waitack [_address]:
self.log ("Received Echo", 3)
self.log ("Echo erhalten", 3)
self.waitack [_address] = 0
_sendecho = 0
else:
self.log ("New Milking Data", 3)
self.log ("Neue Melkdaten erhalten", 3)
_animalnr = int (_data)
if _animalnr:
if self.dataset [_address]:
self.log ("A Milkingdataset already esists %s" % self.dataset [_address])
self.log ("Es existiert bereits ein Melkdatensatz %s" % self.dataset [_address])
self.dataset [_address] = {'animalnr' : _animalnr,
'ts' : strftime ("%Y-%m-%d %H:%M:%S"),
'ammount' : 0}
else:
self.dataset [_address] = None
self.log ("AnimalNr is 0 ignore Milkingdata")
self.log ("Tiernummer ist 0 ignoriere Melkdaten")
#State requeset
elif infotype [_info_type] == 'state':
_sendecho = 0 #No Echo on State telegram
if self.waitackst [_address]:
self.log ("Received Echo for Status", 3)
self.log ("Echo fuer Status erhalten", 3)
self.waitackst [_address] = 0
_sendecho = 0
else:
animalnr = int (_data)
self.log ("Statusrequest for animal %d" % animalnr)
self.log ("Statusanfrage fuer Tiernummer %d" % animalnr)
animalinfo = self.db_con.getanimal (animalnr)
_ammountestimated = 12
if len (animalinfo):
_aianimalnr, _aiearmark, _airfid, _aiforbidmilk = animalinfo[0]
if _aiforbidmilk != '0':
self.log ("Milking is forbidden %s" % _aiforbidmilk, 1)
_aianimalnr, _aiearmark, _airfid, _aitsforbidstart, _aitsforbidend = animalinfo[0]
_milkforbid = 0
if _aitsforbidstart:
dttsforbidstart = datetime.strptime (_aitsforbidstart, '%Y-%m-%d %H:%M:%S')
if datetime.now () > dttsforbidstart:
if _aitsforbidend:
dttsforbidend = datetime.strptime (_aitsforbidend, '%Y-%m-%d %H:%M:%S')
if datetime.now () <= dttsforbidend:
_milkforbid = 1
else:
_milkforbid = 1
if _milkforbid:
self.log ("Melksperre ist gesetzt" , 1)
_repdata = bytearray ('GESP '.encode ())
self.waitackst [_address] = 1
else:
self.log ("Animal is Ok check milking data", 1)
self.log ("Tier ist Ok checke Melkdaten", 1)
_lastmilkdata = self.db_con.getlastmilkdatabyanimal (animalnr, 1)
if len (_lastmilkdata):
_mdts, _mdanimalnr, _mdammount, _mdtime = _lastmilkdata [0]
_mdts, _mdanimalnr, _mdammount, _mdtime, _mplace = _lastmilkdata [0]
_mddt = datetime.strptime (_mdts, '%Y-%m-%d %H:%M:%S')
_lmdelta = (datetime.now() - _mddt).seconds
self.log ("Delta to Last Milking was %s s" % _lmdelta, 5)
self.log ("Letze Melkung war vor %s s" % _lmdelta, 5)
if (_lmdelta < 7200):
self.log ("2nd Milking", 1)
self.log ("2te Melkung", 1)
_repdata = bytearray ('2MEL '.encode ())
self.waitackst [_address] = 1
else:
self.log ("All Ok", 5)
self.log ("Alles Ok", 5)
_repdata = bytearray ((' OK%04d' % int (_ammountestimated)).encode ())
self.waitackst [_address] = 1
else:
self.log ("All Ok", 5)
self.log ("Alles Ok", 5)
_repdata = bytearray ((' OK%04d' % int (_ammountestimated)).encode ())
self.waitackst [_address] = 1
else:
self.log ("Animal not in DB", 1)
self.log ("Tier nicht in DB", 1)
_repdata = bytearray ('UNBE '.encode ())
self.waitackst [_address] = 1
@@ -167,46 +184,45 @@ class CanListener (can.Listener):
if self.dataset [_address]:
self.dataset [_address] ['ammount'] = int (_data)
else:
self.log ("Dataset empty ignoring Milking ammount", 1)
self.log ("Datensatzpuffer leer ignore Milchmenge", 1)
elif infotype [_info_type] == 'milking time':
if self.dataset [_address]:
self.log ("Milking Time for existing Dataset %s" % self.dataset [_address])
self.log ("Melkzeit fuer vorhandenen Datensatz im Puffer %s" % self.dataset [_address])
self.dataset [_address] ['time'] = int (_data)
animalinfo = self.db_con.getanimal (self.dataset [_address]['animalnr'])
if len (animalinfo):
self.log ("Found animal in DB", 5)
self.log ("Tier in DB gefunden", 5)
else:
self.log ("Animal %d not found in animaldb create" % (self.dataset [_address]['animalnr']), 1)
self.log ("Tier %d nicht in DB gefunden - wird autmatisch angelewgt" % (self.dataset [_address]['animalnr']), 1)
#FixMe Check Animal Nr Range + x
_animaldata = {'animalnr' : self.dataset [_address]['animalnr'],
'earmark' : '2730000000000000',
'rfid' : '',
'forbidmilk' : '0'}
'rfid' : ''}
self.db_con.addanimal (_animaldata)
self.log ("Check last milking data", 1)
self.log ("Letzte Melkdaten pruefen", 1)
_lastmilkdata = self.db_con.getlastmilkdatabyanimal (self.dataset [_address]['animalnr'], 1)
if len (_lastmilkdata):
_mdts, _mdanimalnr, _mdammount, _mdtime = _lastmilkdata [0]
_mdts, _mdanimalnr, _mdammount, _mdtime, _mplace = _lastmilkdata [0]
_mddt = datetime.strptime (_mdts, '%Y-%m-%d %H:%M:%S')
_lmdelta = (datetime.now() - _mddt).seconds
self.log ("Delta to Last Milking was %s s" % _lmdelta, 5)
self.log ("Letzte Melkung war vor %s s" % _lmdelta, 5)
if _lmdelta < 7200:
self.log ("2nd Milking", 1)
self.log ("Adding Ammount Old %d New %d, Time Old %d New %d" % ( self.dataset [_address] ['ammount'], int (_mdammount), self.dataset [_address] ['time'],int (_mdtime)), 5)
self.log ("2te Melkung", 1)
self.log ("Addiere Mlichmenge Ald %d Neu %d, Zeit Alt %dNeu %d" % ( self.dataset [_address] ['ammount'], int (_mdammount), self.dataset [_address] ['time'],int (_mdtime)), 5)
self.dataset [_address] ['ts'] = _mdts
self.dataset [_address] ['ammount'] = self.dataset [_address] ['ammount'] + int (_mdammount)
self.dataset [_address] ['time'] = self.dataset [_address] ['time'] + int (_mdtime)
self.db_con.updatemilkdata (self.dataset [_address])
else:
self.log ("All Ok", 5)
self.log ("Alles Ok Speichere Melkdaten", 5)
self.db_con.addmilkdata (self.dataset [_address])
else:
self.log ("All Ok", 5)
self.log ("Alles Ok Speichere Melkdaten", 5)
self.db_con.addmilkdata (self.dataset [_address])
self.dataset [_address] = None
else:
self.log ("Dataset empty ignoring Milking time", 1)
self.log ("Datensatzpuffer leer ignore Melkzeit", 1)
@@ -233,13 +249,103 @@ def is_set (x, n):
return x & 2**n != 0
if __name__ == "__main__":
bus = can.interface.Bus (channel='can0', bustype='socketcan_native')
config = ConfigParser ()
config.read ('lactor.cfg')
c_dbfile = config.get ('Settings', 'dbfile')
if not c_dbfile:
print ('No DB File configured')
sys.exit (0)
c_candev = config.get ('Settings', 'candev')
if not c_candev:
print ('No CAN Device configured')
sys.exit (0)
dbcon = DB (c_dbfile, '/tmp/talog.sql', logtest, errlogtest)
bus = can.interface.Bus (channel = c_candev, bustype = 'socketcan_native')
a_listener = CanListener ()
a_listener.set_db (dbpath = '/opt/data/animaldb.sqlite')
a_listener.set_db (dbcon)
notifier = can.Notifier (bus, [a_listener])
try:
while True:
sleep (1)
except KeyboardInterrupt:
bus.shutdown ()
c_loglevel = int (config.get ('DEBUG', 'loglevel'))
c_herde = config.get ('HERDE', 'herde')
c_herdepath = config.get ('HERDE', 'herdepath').rstrip ('/')
if c_herde and not c_herdepath:
print ('No Path for HERDE Couppling defined')
sys.exit (0)
c_herdepath += '/'
if c_herdepath and not Path (c_herdepath).exists ():
print ('Path to HERDE doesnt exist')
sys.exit (0)
c_herdereadfile = config.get ('HERDE', 'herdereadfile')
if c_herde and not c_herdereadfile:
print ('No Readfile für HERDE Coupplingdefined')
sys.exit (0)
c_herdewritefile = config.get ('HERDE', 'herdewritefile')
if c_herde and not c_herdewritefile:
print ('No Readfile für HERDE Coupplingdefined')
sys.exit (0)
if c_herde:
taurus = TAURUS (dbcon, c_loglevel, c_herdewritefile)
c_animalrecognition = config.get ('Animal Recognition', 'animalrecognition')
if c_animalrecognition:
c_rfiddev = config.get ('Animal Recognition', 'rfiddev')
if not c_rfiddev:
print ('No RFID Device configured')
sys.exit (0)
"""
Nedap RFID Reader
"""
rfid = serial.Serial (port = c_rfiddev,\
baudrate = "9600",\
bytesize = 8,\
parity = "N",\
stopbits = 1,\
timeout = 0,\
xonxoff = 0,\
rtscts = 0,\
writeTimeout = None)
herdefiletslatch = None
herdechanged = 0
readbuffer = ''
online = 0
animalnr = ''
while 1:
if c_herde:
if Path (c_herdepath + c_herdereadfile).exists ():
_herdets = os.stat (c_herdepath + c_herdereadfile).st_mtime
if herdefiletslatch and not herdechanged and herdefiletslatch != _herdets:
print ("New Herdefile wait for changes done")
herdechanged = 1
elif herdefiletslatch and herdechanged and (herdefiletslatch == _herdets) and (time () - _herdets) > 2:
print ("Parse File")
taurus.parsefile (c_herdepath, c_herdereadfile)
herdechanged = 0
herdefiletslatch = _herdets
#Tiererkennung
if c_animalrecognition:
try:
d = rfid.read ()
if len (d):
readbuffer += d.decode("utf-8")
if readbuffer [-2:] == '\r\n':
if online:
data = readbuffer.split (' ')
if len (data) == 3:
newanimalnr = data [2]
if newanimalnr != animalnr:
print ("Neue Tiernummer %s" % newanimalnr)
animalnr = newanimalnr
readbuffer = ''
online = 1
except KeyboardInterrupt:
bus.shutdown ()
rfid.close ()

9
startlactor.sh Normal file
View File

@@ -0,0 +1,9 @@
#! /bin/bash
while true; do
echo "Starting Lactor in `pwd` at `date`" >> /var/log/lactor/startstop.log
#echo "BDE restarted" | mail -s "BDE Restart" admin@apc910.finoba.by
python3 ./lactor.py `pwd` 2>&1 >> log_`date -Idate`.txt
echo "Lactor stopped in `pwd` at `date`" >> /var/log/bde/startstop.log
sleep 2
done