Simpy - Harjoitus 1

Wikikirjastosta

Harjoitustehtävä 1[muokkaa | muokkaa wikitekstiä]

Tee ohjelma, joka simuloi puusepänverstasta, jossa valmistetaan yhtä tuotetta: hyllyjä. Tuotantolinja koostuu sahasta, kahdesta höylästä ja hiomakoneesta.

Työn kulku on seuraava: Hyllyn aihioita tulee sahausvarastoon 1-6 minuutin välein, josta saha ottaa hyllyn käsittelyyn. Sahaus kestää 2-5 minuuttia, jonka jälkeen hylly menee höyläysvarastoon. Höyläysvarastosta tuote menee jommalle kummalle höylälle työstettäväksi – työstä kestää kummallakin koneella 3-7 minuuttia, minkä jälkeen tuote joutuu hiontavarastoon. Hiontavarastosta hiomakone ottaa tuotteen hiontaan, joka kestää 1-4 minuuttia, minkä jälkeen tuote on valmisvarastoon.

Tuotantolinja ei kuitenkaan toimi 100% varmuudella, vaan jokin neljästä koneesta menee rikki keskimäärin 45 minuutin välein, hajonta +/- 15 minuuttia. Koneiden luotettavuus on saman suuruista. Korjausaika vaihtelee 10-40 minuutin välein. Kun jokin kone menee rikki, sillä hetkellä koneessa oleva hylly meni piloille ja joutaa hylkyvarastoon. (Huom! Koneen vioittuminen ei keskeytä koko tuotantolinjaa, vaan ainoastaan ko. koneen). (Huom! Korjauksen alla oleva kone ei voi mennä korjauksen aikana uudelleen rikki)

Simuloin yhden 8 tunnin työpäivän tuotanto ja raportoi kuinka paljon hyllyjä tuli sahatuksi, höylätyksi ja valmiiksi ja kuinka paljon tuli hylkyä. Laske myös keskimääräiset tuotantoajat eri koneille sekä hyllyn keskimääräinen odotusaika höyläykseen ja hiontaan. Raportoi myös huoltokerrat ja huoltoon käytetty aika sekä keskimääräinen huoltoaika.

Esimerkkiratkaisu

Lähdetäänpä tutkimaan prosessia. Simpyn kannalta huomaamme, että tuotantoprosessi koostuu neljästä työprosessista (sahaus, 2xhöyläys,hionta), joista jokainen ottaa tavaran jostain varastosta ja tehtyään työnsä panee tavaran toiseen varastoon. Lisäksi tarvitsemme yhden prosessin, joka luo tavara-aihion ensimmäiseen sahausvarastoon.


Työprosessit ovat kaikki samanlaisia suoraviivaisia itsenäisiä toisistaa riippumattomia prosesseja, jonka toiminto on :

  1. Ota tavara varastosta
  2. Suorita työstö (env.timeout)
  3. Pane tavara seuraavaan varastoon


Helppo kuin heinänteko, ellei nuo koneet menisi rikki. Kappaleessa 4 opimme kuinka prosessin keskeytetään ulkopuolelta Interrupt-menetelmällä. Sitä käytämme tälläkin kertaa. Se merkitsee, että itse työprosesseissa joudumme käyttämään Pythonin try-except –rakennelmaa.

Lisäksi meidän pitää huolta, että emme keskeytä prosessia, joka on jo keskeytetty. Tämän voimme hoitaa ”lipputiedolla” – eli merkitsemällä kunkin koneen ”huoltomuuttujan” arvon esim. 1= kone huollossa, 0=kone kunnossa. Koskassa Simpyssä ei voi käyttää globaaleja muuttujia prosessien välisessä kommunikoinnissa, ”huoltomuuttujan” tulee olla List-muuttuja.

Joudumme simuloinnin lopussa tulostamaan varsin paljon tilastotietoa päivän tuotannosta, joten prosessin aikana joudumme kerämään kustakin tuotetusta hyllystä paljon tilastotietoa. Tuo tieto voidaan tallentaa prosessin aikana kätevästi hylly-olioon, joka sitten hyllyn eri vaiheiden aikana a voidaan aina tallentaa Directoryyn, josta simuloinnin lopettua voidaan ajaa erilaisia tilastotietoja.

Aloitetaan ohjelmointi tällä kertaa simulointiympäristön luomisesta. Ympäristöä luotaessa, voimme antaa Environment-määrittelyssä alkuajan, josta simulointi alkaa. Jos Simpyn yksi aikayksikkö on 1 minuutti, aamun kello 8:00 on siten ajankohta 480)

Luodaan tarvittavat varastot simpy.Store – määrittelyillä. Annetaan varastojen maksimikapasiteeksi arviolta vaikka 300.

Kaikki tuotantovaiheet ovat itsenäisiä prosesseja, jotka käynnistämme env.process – komennolla (siis ilman yield’iä), mutta prosessit, jotka saattavat keskeytyä Interrupt-menetelmällä tulee osoittaa ”konemuuttuja” - nimeile. Tuotantoprosessille pitää parametreinä viedä aina sen tarvitsevat varastot (get/put) sekä kaikille prosesseille yhteinen hylkyvarasto, johon menee tuotteet, jotka on työn alla, kun kone menee rikki ja joutuu huoltoon.

Lisäksi tarvitsemme huoltoprosessin, joka ”rikkoo” satunnaisesti jonkin koneen (tuotantoprosessin) satunnaiseksi ajaksi. Sen parametreinä ovat kaikki tuotantoprosessien ”konemuuttujat”.

env = simpy.Environment(480) #Aloitetaan klo 08:00 = 480
sahausvarasto = simpy.Store(env,capacity=300) #Kapasiteettimääritys on turha?
hoylaysvarasto = simpy.Store(env, capacity = 300)
hiontavarasto = simpy.Store(env, capacity = 200)
valmisvarasto = simpy.Store(env, capacity = 500)
hylkyvarasto = simpy.Store(env, capacity = 100)
"#Jokainen prosessi on itsenäinen
gen = env.process(generointi(env,sahausvarasto))
saha = env.process(sahaus(env, sahausvarasto,hoylaysvarasto, hylkyvarasto))
hoyla1 = env.process(hoylays(env, hoylaysvarasto, hiontavarasto, hylkyvarasto))
hoyla2 = env.process(hoylays2(env, hoylaysvarasto, hiontavarasto, hylkyvarasto))
hioma = env.process(hionta(env, hiontavarasto, valmisvarasto, hylkyvarasto))
env.process(huolto(env, saha, hoyla1, hoyla2, hioma))
env.run(until=960) #Aika 960 = klo 16:00

Sitten voisimme katsoa, minkälaisen Hylly-olion tarvitsemme. Jodumme keräämään olioon koko joukon tilastotietoa ja kaikille teemme myös setteri ja getterit.

class Hylly:
   def __init__(self,numero, luonti):
       self.__numero = numero
       self.__luonti = luonti  #Aika jolloin hyllyaihio sahausvarastoon
       self.__odotus1 = 0  #Varalla myöhempiä tehtäviä varten
       self.__odotus2 = 0  #Höyläykseen odottamisen aika
       self.__odotus3 = 0  #Hiontaan odottamisen aika
       self.__sahaus = 0   #Sahaukseen kulunut aika
       self.__hoylays = 0  #Häyläykseen kulunut aika
       self.__hionta = 0   #Kokonaistuotantoaika
       self.__valmis = 0   #Varalla myöhempiä tehtäviä varten
       self.__hylky = 0    #Hylkyyn joutunut tuote: hylky = 1, ok-tuote = 0

Vielä ennen varsinaisten prosessien koodaamista, voisimme tehdä yhden ”mukavuus” aliohjleman, joka muuttaat Simpyn sisäisen kellon ajan helpommin luettavaksi (esim. 480 = klo 08:00) string-muuttujaksi.

def kello(env):
   aika = env.now
   minuutit = aika
   tunnit = int(minuutit/60)
   minuutit = minuutit - tunnit*60
   if tunnit < 10:
       stunnit='0'+str(tunnit)
   else:
       stunnit = str(tunnit)
   if minuutit < 10:
        sminuutit = '0'+str(minuutit)
   else:
       sminuutit = str(minuutit)
   staika = stunnit+":"+sminuutit
   return staika  

Vielä tarvitsemme nuo rakenteet, joihin voimme taltiota tuotanto- ja huolto tiedot sekä ”huoltomuuttujan”.

tiedot = {} #Tuotettujen hyllyjen tiedot tallennetaan tiedot-dictionaryyn
hdata = []  # Huoltoaikojen tallennus 
hflag = [0,0,0,0,0] #List-muuttuja, joka kertoo, että kone on huollossa eikä
                   "# voi mennä uudelleen rikki (= hflag[x] = 1)

Prosessien koodamisen voisimme aloittaa Hylly-aihioiden tuottamisesta sahausvarastoon. Sille ei oltu asetettu muita vaatimuksia,kuin että hyllyaihiota syntyy 1-6 minuutin välein. Helppo homma siis.

def generointi(env, sahausvarasto):
   i=0
   while True:
       aika = random.randint(1,6)
       yield env.timeout(aika)
       aika = env.now
       hylly = Hylly(i,aika)
       yield sahausvarasto.put(hylly)
       tiedot[i]=hylly  #Luodaan hyllyn tiedot heti directoryyn
       print(kello(env),'Hyllyn', i,'aihio laitettu sahausvarastoon')
       i+=1
    

Ohjelmoidaan sitten tuo huoltoprosessi, joka siis katkaiseen satunnaisen prosessin eli koneen (saha, höylä1, höylä2, hioma) tuotannon tehtävän annon mukaisin ajoi.

def huolto(env, saha, hoyla1, hoyla2, hioma):
   while True:
       vikatiheys = random.randint(30,60) #Keskimäärin 45 minuuttia
       yield env.timeout(vikatiheys)
       korjausaika = random.randint(10,40)
       hdata.append(korjausaika) #Laitetaan korjausaika talteen tilastointi varten
       #Mikä kone menee rikki: 1 = saha, 2=höylä1, 3= höylä2, 4=hiomakone
       mika = random.randint(1,4)
       #Huom. Testataan, ettei kone ole korjauksen alaisena hflag[x] != 1,  Jos ok, niin
       # tehdään koneelle interrupt ja merkataan kone huoltotilaan hflag[x] = 1
       if mika == 1 and hflag[1] != 1:
           saha.interrupt(korjausaika)
           hflag[1] = 1
       if mika == 2 and hflag[2] != 1:
           hoyla1.interrupt(korjausaika)
           hflag[2] = 1
       if mika == 3 and hflag[3] != 1:
           hoyla2.interrupt(korjausaika)
           hflag[3] = 1
       if mika == 4 and hflag[4] != 1:
           hioma.interrupt(korjausaika)
           hflag[4] = 1

Viimein pääsemme koodaamaan varsinaista tuotantoprosessia. Otetaan ensimmäinen kone eli saha tähän esimerkiksi. Koska meillä on keskeytyvä prosessi toteutamme sen try-except – menetelmässä, jossa try – osio on ”normaali” tuotanto ja except huoltokatkon aiheuttama tila.

Koska koneen työ voi keskeytyä tuotannon (env.timeout) aikana rikkoontumisen vuoksi (Interrtupt) meidän tulee tarkastaa ennen hyllyn laittamista seuraavaan varastoon, ettei huoltoprosessi ole merkannut hyllyä hylyksi. Jos testausta ei tehtäisi ja estettäisi siirtoa seuraavaan tuotantovarastoon, niin hylätty tuote jatkaisi tuotantoprosessissa normaalisti eteenpäin. Tässä tyypillinen pieni simuloinnin virhelähde.

Lisäksi on huomattava, kun hyllyn tietoja päivitetään tiedot-Directoryyn, indeksitieto on oltava kokonaisluku, minkä vuoksi se tulee koodata tiedot[int(hylly.get_numero())] = hylly

def sahaus(env, sahausvarasto, hoylaysvarasto, hylkyvarasto):
   while True:
       try:
           hylly = yield sahausvarasto.get() #Otetaan seuraava hylly sahaukseen
           aika = random.randint(2,5)
           print(kello(env), 'Hyllyn', hylly.get_numero(),'sahaus alkaa')
           yield env.timeout(aika) #Itse sahaus
           if hylly.get_hylky() == 0: # Hylly kunnossa eikä hylkytavaraa
               yield hoylaysvarasto.put(hylly)
               print(kello(env), 'Hylly', hylly.get_numero(),' toimitettu höyläysvarastoon')
               hylly.set_sahaus(aika)  #Sahausaika talteen
               tiedot[int(hylly.get_numero())] = hylly #Päivitetään hyllyn tiedot sahauksesta
       except simpy.Interrupt as vika:
           print (kello(env), 'Sahaus keskeytyi huollon vuoksi')
           hylly.set_hylky(1) #Merkataan hylly hylyksi
           print(kello(env),'***Hylly', hylly.get_numero(), 'meni pilolle')
           yield hylkyvarasto.put(hylly) #Piloille mennyt hylly hylkyvarastoon
           yield env.timeout(vika.cause)
           print (kello(env),'Sahaus huollettu. Huoltoaika', vika.cause)
           hflag[1] = 0  #hflag 0 kertoo, että kone on korjattu

Muiden koneiden prosessit ovat edellä kuvatun kaltaisia, joten niiden koodaminen käy melkein copy/paste – menetelmien, kunhan pitää huolto oikeista muuttuja nimistä.

Ohjelman loppuun sitten meidän pitää vielä koodata tilastointiosuus. Meillähän on Hylly-olioiden data tiedot-directoryssa ja huolto-ajat hdata-listassa. Käydään ne läpi ja kerätään sopiviin summa muuttujiin tiedot myös keskiarvojen laskentaa varten.

"#Kussakin varastossa olevan tavaran määrä saadaan len(store.items
print('Päivän tuontantotiedot:')
print('Sahausvarastossa tuotteita:', len(sahausvarasto.items))
print("Höyläysvarastossa tuotteita", len(hoylaysvarasto.items))
print("Hiontavarastossa tuotteita", len(hiontavarasto.items))
print("Hylkyvarastossa tuotteita", len(hylkyvarasto.items))
"#Summamuuttujat
sahatut = 0
hoylatyt = 0
valmiit = 0
hylyt = 0
ksahaus = 0 #Keskimääräinen sahausaika
khoylays = 0 #Keskimääräinen höyläysaika
khionta = 0 #Keskimääräinen tuotantoaika
odotus2 = 0 #Keskimääräinen höyläykseen odottamisen aika
odotus3 = 0 #Keskimääräinen hiontaan odottamisen aika
"#Laskteaan keskiarvot hyllyistä tiedot - dictionarystä, johon hylly-oliot tallennettu
for i in range(1,len(tiedot)):  #len(tiedot) = luotujen hyllyaihioiden määrä
   hylly = tiedot.get(i)
   if i in tiedot:
       if hylly.get_hylky() == 0:
           if hylly.get_sahaus() > 0: #Hylly sahattu, mikäli sahausaika olemassa
                   sahatut +=1
           ksahaus += hylly.get_sahaus()
           if hylly.get_hoylays() > 0: #Hylly myös höylätty
               hoylatyt +=1
               khoylays += hylly.get_hoylays()
               odotus2 += hylly.get_odotus2()
           if hylly.get_hionta() > 0: #Hylly myös hiottu
               valmiit += 1
               khionta += hylly.get_hionta()
               odotus3 += hylly.get_odotus3()
       else:    #Muussa tapatuksessa hylly meni hylyksi koneen rikkoutumisen vuoksi
           hylyt +=1
print('Sahatut:', sahatut, 'höylätyt:', hoylatyt,'valmiit:', valmiit, 'hylätyt:', hylyt)
print('Keskimääräiset tuotantoajat:')
print('Sahaus:', int(ksahaus/sahatut), 'höyläys:', int(khoylays/hoylatyt),'hionta:',    int(khionta/valmiit))
print('Keskmääräinen odotusaika:')
print('Höylöyksessä:', int(odotus2/hoylatyt), 'hionnassa:', int(odotus3/valmiit))
"# Lasketaan huoltoajat
huoltoaika = 0
for i in range(0,len(hdata)): #hdata - listassa kaikki korjausajat
   huoltoaika = huoltoaika + hdata[i]
print('Huoltokertoja työvuoron aikana:', len(hdata)) #Kuinka monta rikkoutumista
print('Huoltoon käytettiin aikaa yhteensä', huoltoaika)
print('Huoltoaika keskimäärin:', int(huoltoaika/len(hdata)))

Esimerkkiratkaisu kokonaisuudessaan

import simpy
import random
tiedot = {} #Tuotettujen hyllyjen tiedot tallennetaan tiedot-dictionaryyn
hdata = []  # Huoltoaikojen tallennus 
hflag = [0,0,0,0,0] #List-muuttuja, joka kertoo, että kone on huollossa eikä
                   "# voi mennä uudelleen rikki (= hflag[x] = 1)
class Hylly:
   def __init__(self,numero, luonti):
       self.__numero = numero
       self.__luonti = luonti  #Aika jolloin hyllyaihio sahausvarastoon
       self.__odotus1 = 0  #Varalla myöhempiä tehtäviä varten
       self.__odotus2 = 0  #Höyläykseen odottamisen aika
       self.__odotus3 = 0  #Hiontaan odottamisen aika
       self.__sahaus = 0   #Sahaukseen kulunut aika
       self.__hoylays = 0  #Häyläykseen kulunut aika
       self.__hionta = 0   #Kokonaistuotantoaika
       self.__valmis = 0   #Varalla myöhempiä tehtäviä varten
       self.__hylky = 0    #Hylkyyn joutunut tuote: hylky = 1, ok-tuote = 0
   def get_numero(self):
       return self.__numero
   def get_luonti(self):
       return self.__luonti
   def get_odotus1(self):
       return self.__odotus1
   def get_odotus2(self):
       return self.__odotus2
   def get_odotus3(self):
       return self.__odotus3
   def get_sahaus(self):
       return self.__sahaus
   def get_hoylays(self):
       return self.__hoylays
   def get_hionta(self):
       return self.__hionta
   def get_hylky(self):
       return self.__hylky
   def set_odotus1(self, aika):
       self.__odotus1 = aika
   def set_odotus2(self, aika):
       self.__odotus2 = aika
   def set_odotus3(self, aika):
       self.__odotus3 = aika
   def set_sahaus(self, aika):
       self.__sahaus = aika
   def set_hoylays(self, aika):
       self.__hoylays = aika
   def set_hionta(self, aika):
       self.__hionta = aika
   def set_hylky(self,hylky):
       self.__hylky = hylky
def kello(env):
   aika = env.now
   minuutit = aika
   tunnit = int(minuutit/60)
   minuutit = minuutit - tunnit*60
   if tunnit < 10:
       stunnit='0'+str(tunnit)
   else:
       stunnit = str(tunnit)
   if minuutit < 10:
        sminuutit = '0'+str(minuutit)
   else:
       sminuutit = str(minuutit)
   staika = stunnit+":"+sminuutit
   return staika        
"# Aihioiden generointi sahausvarastoon
def generointi(env, sahausvarasto):
   i=0
   while True:
       aika = random.randint(1,6)
       yield env.timeout(aika)
       aika = env.now
       hylly = Hylly(i,aika)
       yield sahausvarasto.put(hylly)
       tiedot[i]=hylly
       print(kello(env),'Hyllyn', i,'aihio laitettu sahausvarastoon')
       i+=1
def sahaus(env, sahausvarasto, hoylaysvarasto, hylkyvarasto):
   while True:
       try:
           hylly = yield sahausvarasto.get() #Otetaan seuraava hylly sahaukseen
           aika = random.randint(2,5)
           print(kello(env), 'Hyllyn', hylly.get_numero(),'sahaus alkaa')
           yield env.timeout(aika)
           if hylly.get_hylky() == 0:
               yield hoylaysvarasto.put(hylly)
               print(kello(env), 'Hylly', hylly.get_numero(),' toimitettu höyläysvarastoon')
               hylly.set_sahaus(aika)  #Sahausaika talteen
               tiedot[int(hylly.get_numero())] = hylly #Päivitetään hyllyn tiedot sahauksesta
       except simpy.Interrupt as vika:
           print (kello(env), 'Sahaus keskeytyi huollon vuoksi')
           hylly.set_hylky(1)
           print(kello(env),'***Hylly', hylly.get_numero(), 'meni pilolle')
           yield hylkyvarasto.put(hylly) #Piloille mennyt hylly hylkyvarastoon
           yield env.timeout(vika.cause)
           print (kello(env),'Sahaus huollettu. Huoltoaika', vika.cause)
           hflag[1] = 0  #hflag 0 kertoo, että kone on korjattu
"#Höyläyslinja 1
def hoylays(env,hoylaysvarasto, hiontavarasto, hylkyvarasto):
   while True:
       try:
           tuotantoaika = random.randint(3,7)
           aika = env.now
           hylly = yield hoylaysvarasto.get()
           aika = env.now - aika  #Lasketaan mahdollinen odotusaika ja
           hylly.set_odotus2(aika) #laitetaan odotusaika talteen
           print(kello(env),'Hyllyn', hylly.get_numero(),'höyläys alkaa linjalla I')
           yield env.timeout(tuotantoaika)
           if hylly.get_hylky() == 0:
               yield hiontavarasto.put(hylly)
               hylly.set_hoylays(tuotantoaika)
               print(kello(env),'Hylly', hylly.get_numero(),'höylätty I ja toimitettu hiontavarastoon')
       except simpy.Interrupt as vika:
           print (kello(env), 'Höyläys 1 keskeytyi huollon vuoksi')
           hylly.set_hylky(1)
           print(kello(env),'***Hylly', hylly.get_numero(), 'meni pilolle')
           yield hylkyvarasto.put(hylly)
           yield env.timeout(vika.cause)
           print (kello(env),'Höyläys 1 huollettu. Huoltoaika:', vika.cause)
           hflag[2] = 0
"#Höyläyslinja 2 identtinen linja 1 kanssa
def hoylays2(env,hoylaysvarasto, hiontavarasto, hylkyvarasto):
   while True:
       try:
           tuotantoaika = random.randint(3,7)
           aika = env.now
           hylly = yield hoylaysvarasto.get()
           aika = env.now - aika
           hylly.set_odotus2(aika)
           print(kello(env),'Hyllyn', hylly.get_numero(), 'höyläys alkaa linjalla II')
           yield env.timeout(tuotantoaika)
           if hylly.get_hylky() == 0:
               yield hiontavarasto.put(hylly)
               hylly.set_hoylays(tuotantoaika)
               print(kello(env),'Hylly', hylly.get_numero(),'höylätty II ja toimitettu hiontavarastoon')
       except simpy.Interrupt as vika:
           print (kello(env), 'Höyläys 2 keskeytyi huollon vuoksi')
           hylly.set_hylky(1)
           print(kello(env),'***Hylly', hylly.get_numero(), 'meni pilolle')
           yield hylkyvarasto.put(hylly)
           yield env.timeout(vika.cause)
           print (kello(env),'Höyläys 2 huollettu. Huoltoaika', vika.cause)
           hflag[3] = 0      
def hionta(env, hiontavarasto, valmisvarasto, hylkyvarasto):
   while True:
       try:
           tuotantoaika = random.randint(1,4)
           aika = env.now
           hylly = yield hiontavarasto.get()
           aika = env.now - aika
           hylly.set_odotus3(aika)
           print(kello(env), 'Hyllyn', hylly.get_numero(), 'hionta alkaa')
           yield env.timeout(tuotantoaika)
           if hylly.get_hylky() == 0:
               print(kello(env),'Hylly', hylly.get_numero(),'valmis')
               #Lasketaan kokonaistuotantoaika
               total = hylly.get_sahaus() + hylly.get_hoylays() + hylly.get_hionta()
               #Lasketaan kokonaisosotusaika Huom! tulostetaan vain tässä yhteydessä
               odotus = hylly.get_odotus2() + hylly.get_odotus3()
               #Laitetaan tuotantoaika talteen
               hylly.set_hionta(tuotantoaika)
               print(kello(env),'Hyllyn', hylly.get_numero(),'tuotantoaika:', total,
               'odotusaika:', odotus,'kokonaisaika:', total+odotus)
               yield valmisvarasto.put(hylly)
        except simpy.Interrupt as vika:
           print (kello(env), 'Hionta keskeytyi huollon vuoksi')
           hylly.set_hylky(1)
           print(kello(env),'***Hylly', hylly.get_numero(), 'meni pilolle')
           yield hylkyvarasto.put(hylly)
           yield env.timeout(vika.cause)
           print (kello(env),'Hionta huollettu. Huoltoaika', vika.cause)
           hflag[4] = 0
def huolto(env, saha, hoyla1, hoyla2, hioma):
   while True:
       vikatiheys = random.randint(30,60)
       yield env.timeout(vikatiheys)
       korjausaika = random.randint(10,40)
       hdata.append(korjausaika) #Laitetaan korjausaika talteen tilastointi varten
       #Mikä kone menee rikki: 1 = saha, 2=höylä1, 3= höylä2, 4=hiomakone
       #Huom. Testataan, ettei kone ole korjauksen alaisena hflag[x] != 1
       mika = random.randint(1,4)
       if mika == 1 and hflag[1] != 1:
           saha.interrupt(korjausaika)
           hflag[1] = 1
       if mika == 2 and hflag[2] != 1:
           hoyla1.interrupt(korjausaika)
           hflag[2] = 1
       if mika == 3 and hflag[3] != 1:
           hoyla2.interrupt(korjausaika)
           hflag[3] = 1
       if mika == 4 and hflag[4] != 1:
           hioma.interrupt(korjausaika)
           hflag[4] = 1
env = simpy.Environment(480) #Aloitetaan klo 08:00 = 480
sahausvarasto = simpy.Store(env,capacity=300) #Kapasiteettimääritys on turha?
hoylaysvarasto = simpy.Store(env, capacity = 300)
hiontavarasto = simpy.Store(env, capacity = 200)
valmisvarasto = simpy.Store(env, capacity = 500)
hylkyvarasto = simpy.Store(env, capacity = 100)
"#Jokainen prosessi on itsenäinen
gen = env.process(generointi(env,sahausvarasto))
saha = env.process(sahaus(env, sahausvarasto,hoylaysvarasto, hylkyvarasto))
hoyla1 = env.process(hoylays(env, hoylaysvarasto, hiontavarasto, hylkyvarasto))
hoyla2 = env.process(hoylays2(env, hoylaysvarasto, hiontavarasto, hylkyvarasto))
hioma = env.process(hionta(env, hiontavarasto, valmisvarasto, hylkyvarasto))
env.process(huolto(env, saha, hoyla1, hoyla2, hioma))
env.run(until=960)
"#Kussakin varastossa olevan tavaran määrä saadaan len(store.items
print('Päivän tuontantotiedot:')
print('Sahausvarastossa tuotteita:', len(sahausvarasto.items))
print("Höyläysvarastossa tuotteita", len(hoylaysvarasto.items))
print("Hiontavarastossa tuotteita", len(hiontavarasto.items))
print("Hylkyvarastossa tuotteita", len(hylkyvarasto.items))
sahatut = 0
hoylatyt = 0
valmiit = 0
hylyt = 0
ksahaus = 0 #Keskimääräinen sahausaika
khoylays = 0 #Keskimääräinen höyläysaika
khionta = 0 #Keskimääräinen tuotantoaika
odotus2 = 0 #Keskimääräinen höyläykseen odottamisen aika
odotus3 = 0 #Keskimääräinen hiontaan odottamisen aika
"#Laskteaan keskiarvot hyllyistä tiedot - dictionarystä, johon hylly-oliot tallennettu
for i in range(1,len(tiedot)): #len(tiedot) = luotujen hyllyaihioiden määrä
   hylly = tiedot.get(i)
   if i in tiedot:
       if hylly.get_hylky() == 0:
           if hylly.get_sahaus() > 0: #Hylly sahattu, mikäli sahausaika olemassa
                   sahatut +=1
           ksahaus += hylly.get_sahaus()
           if hylly.get_hoylays() > 0:
               hoylatyt +=1
               khoylays += hylly.get_hoylays()
               odotus2 += hylly.get_odotus2()
           if hylly.get_hionta() > 0:
               valmiit += 1
               khionta += hylly.get_hionta()
               odotus3 += hylly.get_odotus3()
       else:
           hylyt +=1
print('Sahatut:', sahatut, 'höylätyt:', hoylatyt,'valmiit:', valmiit, 'hylätyt:', hylyt)
print('Keskimääräiset tuotantoajat:')
print('Sahaus:', int(ksahaus/sahatut), 'höyläys:', int(khoylays/hoylatyt),'hionta:',   int(khionta/valmiit))
print('Keskmääräinen odotusaika:')
print('Höylöyksessä:', int(odotus2/hoylatyt), 'hionnassa:', int(odotus3/valmiit))
huoltoaika = 0
for i in range(0,len(hdata)): #hdata - listassa kaikki korjausajat
   huoltoaika = huoltoaika + hdata[i]
print('Huoltokertoja työvuoron aikana:', len(hdata))
print('Huoltoon käytettiin aikaa yhteensä', huoltoaika)
print('Huoltoaika keskimäärin:', int(huoltoaika/len(hdata)))