ReadJSShifts plugin updated to create rolling patterns for a given...

ReadJSShifts plugin updated to create rolling patterns for a given (hard-coded) period of time. To be tested
parent 03f7ef7f
from copy import copy from copy import copy
import json import json
import math
import time import time
import random import random
import copy import copy
...@@ -35,20 +36,24 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin): ...@@ -35,20 +36,24 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin):
# read the current date and define dateFormat from it # read the current date and define dateFormat from it
try: try:
now = strptime(data['general']['currentDate'], '%Y/%m/%d %H:%M') now = strptime(data['general']['currentDate'], '%Y/%m/%d %H:%M')
# calculate the hours to end the first day
hoursToEndFirstDay = datetime.datetime.combine(now.date(), datetime.time(23,59,59)) - datetime.datetime.combine(now.date(), now.time())
data['general']['dateFormat']='%Y/%m/%d %H:%M' data['general']['dateFormat']='%Y/%m/%d %H:%M'
except ValueError: except ValueError:
now = strptime(data['general']['currentDate'], '%Y/%m/%d') now = strptime(data['general']['currentDate'], '%Y/%m/%d')
hoursToEndFirstDay = datetime.time(23,59,59)
data['general']['dateFormat']='%Y/%m/%d' data['general']['dateFormat']='%Y/%m/%d'
self.initializeTimeSupport(data) self.initializeTimeSupport(data)
shiftData = data["input"].get("shift_spreadsheet",[]) shiftData = data["input"].get("shift_spreadsheet",[])
nodes = data["graph"]["node"] nodes = data["graph"]["node"]
shiftPattern = {} #shift pattern dictionary defaultShiftPattern = {} #default shift pattern dictionary (if no pattern is defined for certain dates)
exceptionShiftPattern = {} # exceptions for shift pattern dictionary as defined in the spreadsheet
if shiftData: if shiftData:
shiftData.pop(0) shiftData.pop(0)
#iteration through the raw data to structure it into ManPy config #iteration through the raw data to structure it into ManPy config
for line in shiftData: for line in shiftData:
# if all the records of that line are none then continue # if all the records of that line are none then continue
toContinue = False toContinue = False
...@@ -104,16 +109,21 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin): ...@@ -104,16 +109,21 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin):
end = timeEndList[index] end = timeEndList[index]
if not start and not end: if not start and not end:
continue continue
shiftPattern[lastrec].append([start, end]) exceptionShiftPattern[lastrec].append([start, end])
#if resource name is defined #if resource name is defined
elif str(entityID) not in shiftPattern: elif str(entityID) not in exceptionShiftPattern:
#take the name of the last entered resource from here #take the name of the last entered resource from here
lastrec = str(entityID) lastrec = str(entityID)
exceptionShiftPattern[lastrec] = []
for index, start in enumerate(timeStartList): for index, start in enumerate(timeStartList):
end = timeEndList[index] end = timeEndList[index]
if not start and not end: if not start and not end:
continue continue
shiftPattern[lastrec] = [[start, end]] # if there is no other entry
if not len(exceptionShiftPattern[lastrec]):
exceptionShiftPattern[lastrec] = [[start, end]]
else:
exceptionShiftPattern[lastrec].append([start, end])
#to avoid overwriting existing records, if there is another entry for a resource but does not follow it immediately (e.g. W2-FS) #to avoid overwriting existing records, if there is another entry for a resource but does not follow it immediately (e.g. W2-FS)
else: else:
lastrec = str(entityID) lastrec = str(entityID)
...@@ -122,18 +132,78 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin): ...@@ -122,18 +132,78 @@ class ReadJSShifts(plugin.InputPreparationPlugin, TimeSupportMixin):
end = timeEndList[index] end = timeEndList[index]
if not start and not end: if not start and not end:
continue continue
shiftPattern[lastrec].append([start, end]) exceptionShiftPattern[lastrec].append([start, end])
#sorts the list in case the records were not entered in correct ascending order #sorts the list in case the records were not entered in correct ascending order
for info in shiftPattern: for info in exceptionShiftPattern:
shiftPattern[info].sort(key=itemgetter(0)) exceptionShiftPattern[info].sort(key=itemgetter(0))
# ================================================================
#create default pattern for all operators (10 days long)
timeStartList = []
timeEndList = []
for dayNumber in range(0,10):
startTime = "08:00"
endTime = "18:00"
upDate = now.date()+datetime.timedelta(days=dayNumber)
shiftStart = self.convertToSimulationTime(strptime("%s %s" % (upDate, startTime), '%Y-%m-%d %H:%M'))
shiftEnd = self.convertToSimulationTime(strptime("%s %s" % (upDate, endTime), '%Y-%m-%d %H:%M'))
timePair = self.correctTimePair(shiftStart, shiftEnd)
shiftStart, shiftEnd = timePair
timeStartList.append(shiftStart)
timeEndList.append(shiftEnd)
#for every operator (can be also machine) create an entry on the defaultShiftPattern
for node, node_data in nodes.iteritems():
#if the node is an operator
if node_data.get('_class', None) == 'Dream.Operator':
for index, start in enumerate(timeStartList):
end = timeEndList[index]
if not start and not end:
continue
if not node in defaultShiftPattern:
defaultShiftPattern[node] = [[start, end]]
else:
defaultShiftPattern[node].append([start, end])
# ================================================================
for node, node_data in nodes.items(): for node, node_data in nodes.items():
if node in shiftPattern: modifiedDefaultDays = [] # the days of the defaultShiftPattern that have been modified according to the exceptionShiftPattern
if node in exceptionShiftPattern:
for index1, exception in enumerate(exceptionShiftPattern[node]):
# XXX think of the case where the exception starts one day and finishes the next
# calculate the time difference in hours from the end of the first day to the end of the exception
# check if we are still in the first day
if hoursToEndFirstDay.total_seconds()/3600 > exception[-1]:
exceptionDay = 0
# calculate the number of days till the end of the exception
else:
exceptionDay = math.floor((exception[-1] - hoursToEndFirstDay.total_seconds()/3600)/24) + 1
for index2, default in enumerate(defaultShiftPattern[node]):
# check if we still are in the first day
if hoursToEndFirstDay.total_seconds()/3600 > default[-1]:
defaultDay = 0
# calculate the number of days till the end of the default shift
else:
defaultDay = math.floor((default[-1] - hoursToEndFirstDay.total_seconds()/3600)/24) + 1
if exceptionDay == defaultDay:
# update the defaultShiftPattern of the node (operator or machine)
# if the exception day has not been modified then delete the previous entry and use the first exception that occurs
if not exceptionDay in modifiedDefaultDays:
defaultShiftPattern[node][index2] = exception
# otherwise append it at the end
else:
defaultShiftPattern[node].append(exception)
modifiedDefaultDays.append(exceptionDay) # the day has been modified, add to the modified days
break
# update the interruptions of the nodes that have a defaultShiftPattern
if node in defaultShiftPattern:
# sort the shift pattern of every node
defaultShiftPattern[node].sort(key=itemgetter(0))
# get the interruptions of the object
interruptions = node_data.get("interruptions", {}) interruptions = node_data.get("interruptions", {})
if not interruptions: if not interruptions:
node_data["interruptions"] = {} node_data["interruptions"] = {}
node_data["interruptions"]["shift"] = {"shiftPattern": shiftPattern.pop(node), node_data["interruptions"]["shift"] = {"shiftPattern": defaultShiftPattern.pop(node),
"endUnfinished": 0} "endUnfinished": 0}
return data return data
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment