views.py 465 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550
  1. # 主業務邏輯中的視圖和路由的定義
  2. import os
  3. import datetime
  4. from flask import Flask, redirect, render_template, request, session, Response, jsonify
  5. from sqlalchemy.sql.expression import desc, false, null
  6. # 導入藍圖程序,用於構建路由
  7. from werkzeug.utils import redirect
  8. from werkzeug.wrappers import response
  9. from . import main
  10. from coffee_manage import mqtt
  11. # 導入db,用於操作數據庫
  12. from coffee_manage import db
  13. # 導入實體類,用於操作數據庫
  14. from ..models import *
  15. import json
  16. from datetime import datetime as dt
  17. from datetime import timedelta
  18. from sqlalchemy import text
  19. import pymysql
  20. import pandas as pd
  21. from concurrent.futures import ThreadPoolExecutor
  22. import cv2
  23. import pickle
  24. import socket
  25. import time
  26. import threading
  27. import numpy as np
  28. import math
  29. from .mqtt import MQTT
  30. from matplotlib import pyplot as plt
  31. import random
  32. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg as FigureCanvas
  33. import io
  34. from flask import make_response
  35. from distutils.util import strtobool # 將字串 string 轉成布林 boolean
  36. import psutil
  37. pool = ThreadPoolExecutor(25)
  38. s_sock = 0
  39. lock = threading.Lock()
  40. '''
  41. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  42. password='skyeye', database='Coffee', charset='utf8')
  43. mycursor = mydb.cursor()
  44. '''
  45. # 主頁的訪問路徑
  46. @main.route('/')
  47. def main_index():
  48. # 獲取登入信息
  49. if 'id' in session and 'uname' in session and 'status' in session:
  50. username = session['uname']
  51. status = session['status']
  52. if status == 9:
  53. return render_template('signin_disable.html', params=locals())
  54. elif status == 8:
  55. return render_template('signin_new.html', params=locals())
  56. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  57. return render_template('index.html', params=locals())
  58. else:
  59. return render_template('sign_in.html')
  60. # Rita 測試
  61. # 使用者名稱測試
  62. @main.route('/test', methods=['GET', 'POST'])
  63. def test():
  64. info = request.args.to_dict()
  65. print(info)
  66. print("info[command]: ", info['command'])
  67. return json.dumps(info)
  68. # Rita 測試
  69. @main.route('/drop_down_list')
  70. def drop_down_list():
  71. # 獲取登入信息
  72. if 'id' in session and 'uname' in session and 'status' in session:
  73. username = session['uname']
  74. status = session['status']
  75. if status == 9:
  76. return render_template('signin_disable.html', params=locals())
  77. elif status == 8:
  78. return render_template('signin_new.html', params=locals())
  79. # TODO
  80. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  81. password='skyeye', database='Coffee', charset='utf8')
  82. mycursor = mydb.cursor()
  83. conn = pymysql.connect(
  84. host='52.69.200.169',
  85. port=3306,
  86. user='coffee',
  87. password='skyeye',
  88. database='Coffee',
  89. charset='utf8'
  90. )
  91. cur = conn.cursor()
  92. #獲取欄位資料
  93. sql = "select * from product_info"
  94. cur.execute(sql)
  95. content = cur.fetchall()
  96. #獲取欄位名稱
  97. sql = "SHOW FIELDS FROM product_info"
  98. cur.execute(sql)
  99. labels = cur.fetchall()
  100. # print("labels: ", labels) # labels: (('產品', 'varchar(4)', 'YES', '', None, ''), ('系統', 'varchar(5)', 'YES', '', None, ''),
  101. labels = [g[0] for g in labels]
  102. # print("labels: ", labels) # labels: ['產品', '系統', '系統圖號', '狀態', '進貨狀態', '序號', '組序號',
  103. return render_template('drop_down_list.html', labels=labels, content=content)
  104. else:
  105. return render_template('sign_in.html')
  106. # !!! AttributeError: 'NoneType' object has no attribute 'vacuum'
  107. @main.route('/loading/container', methods=['GET', 'POST'])
  108. def container_loading():
  109. if request.method == 'GET':
  110. # 清洗浮選狀態
  111. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  112. Clean_container_status_list = [clean_status.Clean_Tank_1,
  113. clean_status.Clean_Tank_2,
  114. clean_status.Clean_Tank_3,
  115. clean_status.Clean_Tank_4]
  116. CLEAN_Waiting_number = int(Clean_container_status_list.count('C_Waiting'))
  117. CLEAN_Warning_number = int(Clean_container_status_list.count('C_Warning'))
  118. if CLEAN_Waiting_number == len(Clean_container_status_list): Clean_container = 'Waiting'
  119. elif CLEAN_Warning_number >= 1: Clean_container = 'Warning'
  120. else: Clean_container = 'Working'
  121. # 清洗浮選狀態
  122. ColorSelect_container_status_list = [clean_status.ColorSelect_Tank_1,
  123. clean_status.ColorSelect_Tank_2]
  124. COLORSELECT_Waiting_number = int(ColorSelect_container_status_list.count('S_Waiting'))
  125. COLORSELECT_Warning_number = int(ColorSelect_container_status_list.count('S_Warning'))
  126. if COLORSELECT_Waiting_number == len(ColorSelect_container_status_list): ColorSelect_container = 'Waiting'
  127. elif COLORSELECT_Warning_number >= 1: ColorSelect_container = 'Warning'
  128. else: ColorSelect_container = 'Working'
  129. # 脫皮機
  130. Peel_container_status_list = [clean_status.Peel_Tank_1,
  131. clean_status.Peel_Tank_2]
  132. PEEL_Waiting_number = int(Peel_container_status_list.count('P_Waiting'))
  133. PEEL_Warning_number = int(Peel_container_status_list.count('P_Warning'))
  134. if PEEL_Waiting_number == len(Peel_container_status_list): Peel_container = 'Waiting'
  135. elif PEEL_Warning_number >= 1: Peel_container = 'Warning'
  136. else: Peel_container = 'Working'
  137. # 發酵槽
  138. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  139. Ferment_container_status_list = [ferment_status.Ferment_Tank_1,
  140. ferment_status.Ferment_Tank_2,
  141. ferment_status.Ferment_Tank_3,
  142. ferment_status.Ferment_Tank_4,
  143. ferment_status.Ferment_Tank_5,
  144. ferment_status.Ferment_Tank_6,
  145. ferment_status.Ferment_Tank_7,
  146. ferment_status.Ferment_Tank_8,
  147. ferment_status.Ferment_Tank_9,
  148. ferment_status.Ferment_Tank_10,
  149. ferment_status.Ferment_Tank_11,
  150. ferment_status.Ferment_Tank_12]
  151. FERMENT_Waiting_number = int(Ferment_container_status_list.count('F_Waiting'))
  152. FERMENT_Warning_number = int(Ferment_container_status_list.count('F_Warning'))
  153. if FERMENT_Waiting_number == len(Ferment_container_status_list): Ferment_container = 'Waiting'
  154. elif FERMENT_Warning_number >= 1: Ferment_container = 'Warning'
  155. else: Ferment_container = 'Working'
  156. # 乾燥槽
  157. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  158. Dry_container_status_list = [dry_status.Dry_Tank_1,
  159. dry_status.Dry_Tank_2,
  160. dry_status.Dry_Tank_3,
  161. dry_status.Dry_Tank_4,
  162. dry_status.Dry_Tank_5,
  163. dry_status.Dry_Tank_6,
  164. dry_status.Dry_Tank_7,
  165. dry_status.Dry_Tank_8,
  166. dry_status.Dry_Tank_9,
  167. dry_status.Dry_Tank_10,
  168. dry_status.Dry_Tank_11,
  169. dry_status.Dry_Tank_12]
  170. DRY_Waiting_number= int(Dry_container_status_list.count('D_Waiting'))
  171. DRY_Warning_number= int(Dry_container_status_list.count('D_Warning'))
  172. if DRY_Waiting_number == len(Dry_container_status_list): Dry_container = 'Waiting'
  173. elif DRY_Warning_number >= 1: Dry_container = 'Warning'
  174. else: Dry_container = 'Working'
  175. return jsonify({"Clean_container":Clean_container,
  176. "ColorSelect_container":ColorSelect_container,
  177. "Peel_container":Peel_container,
  178. "Ferment_container":Ferment_container,
  179. "Dry_container":Dry_container
  180. })
  181. @main.route('/loading_sensors', methods=['GET', 'POST'])
  182. def loading_sensors():
  183. C1_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C1').order_by(text('datetime desc')).first()).UltraSonic
  184. C2_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C2').order_by(text('datetime desc')).first()).UltraSonic
  185. PO1_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO1').order_by(text('datetime desc')).first()).UltraSonic
  186. PO2_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO2').order_by(text('datetime desc')).first()).UltraSonic
  187. F1_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).UltraSonic
  188. F1_SHT11Temp = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Temp
  189. F1_SHT11Humidity = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Humidity
  190. F2_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F2').order_by(text('datetime desc')).first()).UltraSonic
  191. D1_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).UltraSonic
  192. D1_SHT11Temp = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Temp
  193. D1_SHT11Humidity = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Humidity
  194. D2_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D2').order_by(text('datetime desc')).first()).UltraSonic
  195. DO1_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()).UltraSonic
  196. DO2_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()).UltraSonic
  197. return jsonify({"C1_UltraSonic":C1_UltraSonic,
  198. "C2_UltraSonic":C2_UltraSonic,
  199. "PO1_UltraSonic":PO1_UltraSonic,
  200. "PO2_UltraSonic":PO2_UltraSonic,
  201. "F1_UltraSonic":F1_UltraSonic,
  202. "F1_SHT11Temp":F1_SHT11Temp,
  203. "F1_SHT11Humidity":F1_SHT11Humidity,
  204. "F2_UltraSonic":F2_UltraSonic,
  205. "D1_UltraSonic":D1_UltraSonic,
  206. "D1_SHT11Temp":D1_SHT11Temp,
  207. "D1_SHT11Humidity":D1_SHT11Humidity,
  208. "D2_UltraSonic":D2_UltraSonic,
  209. "DO1_UltraSonic":DO1_UltraSonic,
  210. "DO2_UltraSonic":DO2_UltraSonic
  211. })
  212. @main.route('/demo', methods=['GET', 'POST'])
  213. def demo():
  214. if 'id' in session and 'uname' in session and 'status' in session:
  215. username = session['uname']
  216. status = session['status']
  217. if status == 9:
  218. return render_template('signin_disable.html', params=locals())
  219. elif status == 8:
  220. return render_template('signin_new.html', params=locals())
  221. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  222. CI1 = clean_status.Clean_Input_1
  223. CI2 = clean_status.Clean_Input_2
  224. C1 = clean_status.Clean_Tank_1
  225. C2 = clean_status.Clean_Tank_2
  226. # 中水桶
  227. S1 = clean_status.ColorSelect_Tank_1
  228. S2 = clean_status.ColorSelect_Tank_2
  229. SOg1 = clean_status.ColorSelect_Output_g1
  230. SOb1 = clean_status.ColorSelect_Output_b1
  231. SOg2 = clean_status.ColorSelect_Output_g2
  232. SOb2 = clean_status.ColorSelect_Output_b2
  233. P1 = clean_status.Peel_Tank_1
  234. P2 = clean_status.Peel_Tank_2
  235. PO1 = clean_status.Peel_Output_1
  236. PO2 = clean_status.Peel_Output_2
  237. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  238. F1 = ferment_status.Ferment_Tank_1
  239. F2 = ferment_status.Ferment_Tank_2
  240. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  241. D1 = dry_status.Dry_Tank_1
  242. D2 = dry_status.Dry_Tank_2
  243. DO1 = dry_status.Dry_Output_1
  244. DO2 = dry_status.Dry_Output_2
  245. POb1 = clean_status.Peel_Output_b1
  246. return render_template('demo.html', title="[測試] DEMO 貨櫃自動化", **locals())
  247. else:
  248. return render_template('sign_in.html')
  249. # 脫皮機自動化測試頁
  250. @main.route('/peel_auto_status', methods=['GET', 'POST'])
  251. def peel_auto_test():
  252. info = request.args.to_dict()
  253. # 寫定出料的空桶標準, 若 <= 2 則為空桶
  254. Peel_Output_bean_empty = 2
  255. # 從介面取得 指定生豆高度
  256. Peel_Tank_bean_height = float(info['Peel_Tank_bean_height'])
  257. Peel_Tank_motor_rpm = float(info['Peel_Tank_motor_rpm'])
  258. Peel_Tank_vacuumON_time = float(info['Peel_Tank_vacuumON_time'])
  259. Peel_Tank_vacuumOFF_time = float(info['Peel_Tank_vacuumOFF_time'])
  260. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  261. P1 = clean_status.Peel_Tank_1
  262. P2 = clean_status.Peel_Tank_2
  263. PO1 = clean_status.Peel_Output_1
  264. PO2 = clean_status.Peel_Output_2
  265. SO1 = 'SO_OutputtingBean' # SO_OutputtingBean SO_Waiting
  266. SO2 = 'SO_Waiting'
  267. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  268. PO_UP_tank_UltraSonic = []
  269. for i in range(1, 3, 1):
  270. output_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='PO' + str(i)).order_by(text('datetime desc')).first()
  271. UltraSonic = float(output_UltraSonic.UltraSonic)
  272. PO_UP_tank_UltraSonic.append(UltraSonic)
  273. print('PO_UP_tank_UltraSonic: ', PO_UP_tank_UltraSonic)
  274. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  275. if P1 == 'P_Waiting' and PO1 != 'PO_OutputtingBean' and SO1 == 'SO_OutputtingBean':
  276. P1 = 'P_Peeling'
  277. PO1 = 'PO_InputtingBean'
  278. print('------- P1 狀態更新:脫皮中 -------')
  279. print('------- PO1 狀態更新:入豆中 -------')
  280. # [致動器] 馬達 指定轉速
  281. data = { "tank_num": "P1", "command": "tank_motor_status", "value": Peel_Tank_motor_rpm}
  282. print('data: ', data)
  283. # mqtt_f(data)
  284. if P1 == 'P_Peeling':
  285. if PO_UP_tank_UltraSonic[0] >= Peel_Tank_bean_height:
  286. # [致動器] 真空吸料機 OFF
  287. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  288. print('data: ', data)
  289. # mqtt_f(data)
  290. # [致動器] 馬達 0
  291. data = { "tank_num": "P1", "command": "tank_motor_status", "value": "0" }
  292. print('data: ', data)
  293. # mqtt_f(data)
  294. P1 = 'P_Waiting'
  295. PO1 = 'PO_OutputtingBean'
  296. print('------- P1 狀態更新:等待中 -------')
  297. print('------- PO1 狀態更新:可出豆 -------')
  298. elif PO_UP_tank_UltraSonic[0] < Peel_Tank_bean_height:
  299. # [致動器] 真空吸料機 ON
  300. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "on" }
  301. print('data: ', data)
  302. # mqtt_f(data)
  303. timer = time.time()
  304. while True:
  305. if (time.time() - timer) > Peel_Tank_vacuumON_time:
  306. # [致動器] 真空吸料機 OFF
  307. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  308. print('data: ', data)
  309. # mqtt_f(data)
  310. timer = time.time()
  311. break
  312. while True:
  313. if (time.time() - timer) > Peel_Tank_vacuumOFF_time:
  314. break
  315. if PO1 == 'PO_OutputtingBean' and PO_UP_tank_UltraSonic[0] <= Peel_Output_bean_empty:
  316. PO1 = 'PO_Waiting'
  317. print('------- PO1 狀態更新:空桶等待 -------')
  318. CI1 = 'CI_Warning'
  319. CI2 = 'CI_Waiting'
  320. C1 = 'C_Warning'
  321. C2 = 'C_Waiting'
  322. C3 = 'C_Waiting'
  323. C4 = 'C_Waiting'
  324. SI1 = 'SI_Warning'
  325. SI2 = 'SI_Waiting'
  326. S1 = 'S_Warning'
  327. S2 = 'S_Waiting'
  328. SOg1 = 'SO_Warning'
  329. SOb1 = 'SO_Warning'
  330. SOg2 = 'SO_Waiting'
  331. SOb2 = 'SO_Waiting'
  332. POb1 = 'PO_Waiting'
  333. # ----- 將狀態寫入資料庫 ------------------------------
  334. # 獲取文本框的值並賦值給user實體對象
  335. C_status = clean_container_status()
  336. C_status.Clean_Input_1 = CI1
  337. C_status.Clean_Input_2 = CI2
  338. C_status.Clean_Tank_1 = C1
  339. C_status.Clean_Tank_2 = C2
  340. C_status.Clean_Tank_3 = C3
  341. C_status.Clean_Tank_4 = C4
  342. C_status.ColorSelect_Input_1 = SI1
  343. C_status.ColorSelect_Input_2 = SI2
  344. C_status.ColorSelect_Tank_1 = S1
  345. C_status.ColorSelect_Tank_2 = S2
  346. C_status.ColorSelect_Output_g1 = SOg1
  347. C_status.ColorSelect_Output_b1 = SOb1
  348. C_status.ColorSelect_Output_g2 = SOg2
  349. C_status.ColorSelect_Output_b2 = SOb2
  350. C_status.Peel_Tank_1 = P1
  351. C_status.Peel_Tank_2 = P2
  352. C_status.Peel_Output_1 = PO1
  353. C_status.Peel_Output_2 = PO2
  354. C_status.Peel_Output_b1 = POb1
  355. #將數據保存進資料庫
  356. db.session.add(C_status)
  357. # 手動提交
  358. db.session.commit()
  359. # ----- 將狀態寫入資料庫 ------------------------------
  360. return jsonify({"Peel_Tank_1":P1,
  361. "Peel_Tank_2":P2,
  362. "Peel_Output_1":PO1,
  363. "Peel_Output_2":PO2
  364. })
  365. # 乾燥槽狀態更新
  366. @main.route('/dry_status_update', methods=['GET', 'POST'])
  367. def dry_status_update():
  368. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  369. DI1 = dry_status.Dry_Input_1
  370. DI2 = dry_status.Dry_Input_2
  371. D1 = dry_status.Dry_Tank_1
  372. D2 = dry_status.Dry_Tank_2
  373. D3 = dry_status.Dry_Tank_3
  374. D4 = dry_status.Dry_Tank_4
  375. D5 = dry_status.Dry_Tank_5
  376. D6 = dry_status.Dry_Tank_6
  377. D7 = dry_status.Dry_Tank_7
  378. D8 = dry_status.Dry_Tank_8
  379. D9 = dry_status.Dry_Tank_9
  380. D10 = dry_status.Dry_Tank_10
  381. D11 = dry_status.Dry_Tank_11
  382. D12 = dry_status.Dry_Tank_12
  383. DO1 = dry_status.Dry_Output_1
  384. DO2 = dry_status.Dry_Output_2
  385. return jsonify({"DI1":DI1,
  386. "DI2":DI2,
  387. "D1":D1,
  388. "D2":D2,
  389. "D3":D3,
  390. "D4":D4,
  391. "D5":D5,
  392. "D6":D6,
  393. "D7":D7,
  394. "D8":D8,
  395. "D9":D9,
  396. "D10":D10,
  397. "D11":D11,
  398. "D12":D12,
  399. "DO1":DO1,
  400. "DO2":DO2
  401. })
  402. # 乾燥槽自動化測試頁
  403. @main.route('/dry_auto', methods=['GET', 'POST'])
  404. def dry_auto():
  405. # 獲取登入信息
  406. if 'id' in session and 'uname' in session and 'status' in session:
  407. username = session['uname']
  408. status = session['status']
  409. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  410. DI1 = dry_status.Dry_Input_1
  411. DI2 = dry_status.Dry_Input_2
  412. D1 = dry_status.Dry_Tank_1
  413. D2 = dry_status.Dry_Tank_2
  414. D3 = dry_status.Dry_Tank_3
  415. D4 = dry_status.Dry_Tank_4
  416. D5 = dry_status.Dry_Tank_5
  417. D6 = dry_status.Dry_Tank_6
  418. D7 = dry_status.Dry_Tank_7
  419. D8 = dry_status.Dry_Tank_8
  420. D9 = dry_status.Dry_Tank_9
  421. D10 = dry_status.Dry_Tank_10
  422. D11 = dry_status.Dry_Tank_11
  423. D12 = dry_status.Dry_Tank_12
  424. DO1 = dry_status.Dry_Output_1
  425. DO2 = dry_status.Dry_Output_2
  426. return render_template('dry_auto.html', title="[測試] 乾燥自動化", **locals())
  427. else:
  428. return render_template('sign_in.html')
  429. # 乾燥槽 乾燥暫停 出料
  430. @main.route('/dryDEMO_outputtingBean', methods=['GET', 'POST'])
  431. def dryDEMO_outputtingBean():
  432. info = request.args.to_dict()
  433. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  434. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  435. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  436. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  437. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  438. DI2 = dry_status.Dry_Input_2
  439. D1 = dry_status.Dry_Tank_1
  440. D2 = dry_status.Dry_Tank_2
  441. D3 = dry_status.Dry_Tank_3
  442. D4 = dry_status.Dry_Tank_4
  443. D5 = dry_status.Dry_Tank_5
  444. D6 = dry_status.Dry_Tank_6
  445. D7 = dry_status.Dry_Tank_7
  446. D8 = dry_status.Dry_Tank_8
  447. D9 = dry_status.Dry_Tank_9
  448. D10 = dry_status.Dry_Tank_10
  449. D11 = dry_status.Dry_Tank_11
  450. D12 = dry_status.Dry_Tank_12
  451. DO1 = dry_status.Dry_Output_1
  452. DO2 = dry_status.Dry_Output_2
  453. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  454. # DO_UP_UltraSoniclist = []
  455. # for i in range(1, 3, 1):
  456. # output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  457. # UltraSonic = float(output_UltraSonic.UltraSonic)
  458. # DO_UP_UltraSoniclist.append(UltraSonic)
  459. # print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  460. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  461. # 將桶槽 D1 狀態轉換成可出豆, DO1 狀態轉換成可入豆
  462. D1 = 'D_OutputtingBean'
  463. # [致動器] 設定溫度 0.0
  464. data = { "tank_num": "D1", "command": "tank_temp", "value": "0.0" }
  465. print('data: ', data)
  466. # mqtt_f(data)
  467. # [致動器] 溫控開關 OFF
  468. data = { "tank_num": "D1", "command": "tank_temp_enable", "value": "off" }
  469. print('data: ', data)
  470. # mqtt_f(data)
  471. # [致動器] 馬達 0
  472. data = { "tank_num": "D1", "command": "tank_motor_status", "value": "0" }
  473. print('data: ', data)
  474. # mqtt_f(data)
  475. # [致動器] 排水電磁閥 OFF
  476. data = { "tank_num": "D1", "command": "tank_solenoid_water_out_status", "value": "off" }
  477. print('data: ', data)
  478. # mqtt_f(data)
  479. # [致動器] D1 蝴蝶閥 ON
  480. data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "on" }
  481. print('data: ', data)
  482. # mqtt_f(data)
  483. # ----- 將狀態寫入資料庫 ------------------------------
  484. # 獲取文本框的值並賦值給user實體對象
  485. D_status = dry_container_status()
  486. D_status.Dry_Input_1 = DI1
  487. D_status.Dry_Input_2 = DI2
  488. D_status.Dry_Tank_1 = D1
  489. D_status.Dry_Tank_2 = D2
  490. D_status.Dry_Tank_3 = D3
  491. D_status.Dry_Tank_4 = D4
  492. D_status.Dry_Tank_5 = D5
  493. D_status.Dry_Tank_6 = D6
  494. D_status.Dry_Tank_7 = D7
  495. D_status.Dry_Tank_8 = D8
  496. D_status.Dry_Tank_9 = D9
  497. D_status.Dry_Tank_10 = D10
  498. D_status.Dry_Tank_11 = D11
  499. D_status.Dry_Tank_12 = D12
  500. D_status.Dry_Output_1 = DO1
  501. D_status.Dry_Output_2 = DO2
  502. #將數據保存進資料庫
  503. db.session.add(D_status)
  504. # 手動提交
  505. db.session.commit()
  506. # ----- 將狀態寫入資料庫 ------------------------------
  507. return jsonify({"Dry_Tank_1":D1,
  508. "Dry_Tank_2":D2,
  509. "Dry_Output_1":DO1,
  510. "Dry_Output_2":DO2
  511. })
  512. @main.route('/dryDEMO_auto_status', methods=['GET', 'POST'])
  513. def dryDEMO_auto_status():
  514. info = request.args.to_dict()
  515. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  516. Dry_Tank_bean_empty = 2
  517. Dry_Output_bean_empty = 2
  518. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  519. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  520. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  521. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  522. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  523. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  524. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  525. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  526. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  527. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  528. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  529. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_timef'])
  530. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  531. Dry_btn = True
  532. # 從資料庫資料表中取得最新狀態
  533. # ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  534. # FO1 = 'FO_OutputtingBean'
  535. # FO2 = 'FO_Waiting'
  536. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  537. # FO2 = 'FO_Waiting'
  538. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  539. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  540. DI2 = dry_status.Dry_Input_2
  541. D1 = dry_status.Dry_Tank_1
  542. D2 = dry_status.Dry_Tank_2
  543. D3 = dry_status.Dry_Tank_3
  544. D4 = dry_status.Dry_Tank_4
  545. D5 = dry_status.Dry_Tank_5
  546. D6 = dry_status.Dry_Tank_6
  547. D7 = dry_status.Dry_Tank_7
  548. D8 = dry_status.Dry_Tank_8
  549. D9 = dry_status.Dry_Tank_9
  550. D10 = dry_status.Dry_Tank_10
  551. D11 = dry_status.Dry_Tank_11
  552. D12 = dry_status.Dry_Tank_12
  553. DO1 = dry_status.Dry_Output_1
  554. DO2 = dry_status.Dry_Output_2
  555. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  556. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  557. DOutputtingBean_Tank = '' # 出料桶槽號
  558. DryAuto_cleaning = 0 # 清洗次數
  559. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  560. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  561. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  562. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  563. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  564. DI_UP_UltraSoniclist = []
  565. for i in range(1, 3, 1):
  566. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  567. UltraSonic = float(input_UltraSonic.UltraSonic)
  568. DI_UP_UltraSoniclist.append(UltraSonic)
  569. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  570. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  571. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  572. D_UP_tank_UltraSonic = []
  573. for i in range(1, 7, 1):
  574. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  575. UltraSonic = float(tank_UltraSonic.UltraSonic)
  576. D_UP_tank_UltraSonic.append(UltraSonic)
  577. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  578. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  579. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  580. DO_UP_UltraSoniclist = []
  581. for i in range(1, 3, 1):
  582. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  583. UltraSonic = float(output_UltraSonic.UltraSonic)
  584. DO_UP_UltraSoniclist.append(UltraSonic)
  585. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  586. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  587. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  588. D_UP_tank_SHT11Temp = []
  589. D_UP_tank_SHT11Humidity = []
  590. for i in range(1, 7, 1):
  591. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  592. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  593. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  594. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  595. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  596. print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  597. print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  598. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  599. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  600. D_UP_tank_SoilTemp = []
  601. D_UP_tank_SoilHumidity = []
  602. D_UP_tank_SoilEC = []
  603. for i in range(1, 7, 1):
  604. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  605. soil_Temp = float(tank_Soil.soil_Temp)
  606. D_UP_tank_SoilTemp.append(soil_Temp)
  607. soil_Humidity = float(tank_Soil.soil_Humidity)
  608. D_UP_tank_SoilHumidity.append(soil_Humidity)
  609. soil_EC = float(tank_Soil.soil_EC)
  610. D_UP_tank_SoilEC.append(soil_EC)
  611. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  612. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  613. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  614. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  615. # ----- 發酵排程動作 start ------------------------------------------------------------------
  616. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  617. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  618. # [致動器] 真空吸料機 OFF
  619. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  620. print('data: ', data)
  621. # mqtt_f(data)
  622. # [致動器] 蝴蝶閥 OFF
  623. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  624. print('data: ', data)
  625. # mqtt_f(data)
  626. # # [致動器] F1 蝴蝶閥 OFF [ 1109 測試用 ]
  627. # data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  628. # print('data: ', data)
  629. # # mqtt_f(data)
  630. # [致動器] 馬達 0
  631. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  632. print('data: ', data)
  633. # mqtt_f(data)
  634. # [致動器] 入料三通閥 ON排氣
  635. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  636. print('data: ', data)
  637. # mqtt_f(data)
  638. print('------- ', tid,' 狀態更新:入豆完成 -------')
  639. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  640. def DInputtingBean_AND_notfilled(tid):
  641. # [致動器] 蝴蝶閥 OFF
  642. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  643. print('data: ', data)
  644. # mqtt_f(data)
  645. # [致動器] 入料三通閥 OFF入豆
  646. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  647. print('data: ', data)
  648. # mqtt_f(data)
  649. # [致動器] 真空吸料機 ON
  650. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  651. print('data: ', data)
  652. # mqtt_f(data)
  653. timer = time.time()
  654. while True:
  655. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  656. # [致動器] 真空吸料機 OFF
  657. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  658. print('data: ', data)
  659. # mqtt_f(data)
  660. timer = time.time()
  661. break
  662. while True:
  663. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  664. break
  665. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  666. def DInputtingBean_TO_DInputtingBeanPause(tid):
  667. # [致動器] 蝴蝶閥 OFF
  668. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  669. print('data: ', data)
  670. # mqtt_f(data)
  671. # [致動器] 真空吸料機 OFF
  672. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  673. print('data: ', data)
  674. # mqtt_f(data)
  675. # [致動器] 馬達 0
  676. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  677. print('data: ', data)
  678. # mqtt_f(data)
  679. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  680. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  681. def DInputtingBeanPause_TO_DInputtingBean(tid):
  682. # [致動器] 入料三通閥 OFF入豆
  683. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  684. print('data: ', data)
  685. # mqtt_f(data)
  686. # [致動器] 馬達 5
  687. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  688. print('data: ', data)
  689. # mqtt_f(data)
  690. print('------- ', tid, ' 狀態更新:入豆中 -------')
  691. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  692. def DWaiting_TO_DInputtingBean(tid):
  693. # [致動器] F1 蝴蝶閥 ON
  694. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  695. print('data: ', data)
  696. # mqtt_f(data)
  697. # [致動器] 蝴蝶閥 OFF
  698. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  699. print('data: ', data)
  700. # mqtt_f(data)
  701. # [致動器] 入料三通閥 OFF入豆
  702. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  703. print('data: ', data)
  704. # mqtt_f(data)
  705. # [致動器] 馬達 5
  706. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  707. print('data: ', data)
  708. # mqtt_f(data)
  709. print('------- ', tid, ' 狀態更新:入豆中 -------')
  710. # else: if D1 == 'D_InputtingBean_Finish':
  711. def DInputtingBeanFinish_TO_DDrying(tid):
  712. # [致動器] 馬達 指定轉速
  713. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  714. print('data: ', data)
  715. # mqtt_f(data)
  716. # [致動器] 排水電磁閥 ON
  717. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  718. print('data: ', data)
  719. # mqtt_f(data)
  720. # # [致動器] 鼓風機 ON
  721. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  722. # print('data: ', data)
  723. # # mqtt_f(data)
  724. # # [致動器] 加熱器 1 ON
  725. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  726. # print('data: ', data)
  727. # # mqtt_f(data)
  728. # # [致動器] 加熱器 2 ON
  729. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  730. # print('data: ', data)
  731. # # mqtt_f(data)
  732. # [致動器] 溫控開關 ON
  733. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on" }
  734. print('data: ', data)
  735. # mqtt_f(data)
  736. # [致動器] 設定溫度 (指定溫度)
  737. data = { "tank_num": tid, "command": "tank_temp", "value": Dry_Tank_drying_temp }
  738. print('data: ', data)
  739. # mqtt_f(data)
  740. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  741. # else: if D1 == 'D_Drying' and D_UP_tank_weightTemp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  742. def DDrying_TO_DOutputtingBean(tid):
  743. # # [致動器] 鼓風機 OFF
  744. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  745. # print('data: ', data)
  746. # # mqtt_f(data)
  747. # # [致動器] 加熱器 1 OFF
  748. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  749. # print('data: ', data)
  750. # # mqtt_f(data)
  751. # # [致動器] 加熱器 2 OFF
  752. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  753. # print('data: ', data)
  754. # # mqtt_f(data)
  755. # [致動器] 設定溫度 0
  756. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  757. print('data: ', data)
  758. # mqtt_f(data)
  759. # [致動器] 溫控開關 OFF
  760. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  761. print('data: ', data)
  762. # mqtt_f(data)
  763. # [致動器] 馬達 0
  764. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  765. print('data: ', data)
  766. # mqtt_f(data)
  767. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  768. timer = time.time()
  769. while True:
  770. if (time.time() - timer) > Dry_Tank_drying_time:
  771. # [致動器] 排水電磁閥 OFF
  772. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  773. print('data: ', data)
  774. # mqtt_f(data)
  775. break
  776. print('------- ', tid, ' 狀態更新:可出豆 -------')
  777. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  778. def DOutputtingBean_TO_DWaiting(tid):
  779. # [致動器] D1 蝴蝶閥 OFF
  780. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  781. print('data: ', data)
  782. # mqtt_f(data)
  783. # D_Cleaning
  784. def DCleaning(tid):
  785. # [致動器] 馬達 10
  786. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  787. print('data: ', data)
  788. # mqtt_f(data)
  789. # [致動器] 消毒電磁閥 ON
  790. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  791. print('data: ', data)
  792. # mqtt_f(data)
  793. # [致動器] 排水電磁閥 OFF
  794. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  795. print('data: ', data)
  796. # mqtt_f(data)
  797. # [致動器] TODO 消毒抽水 pump ON
  798. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  799. timer = time.time()
  800. while True:
  801. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  802. # [致動器] TODO 消毒抽水 pump OFF
  803. break
  804. # [致動器] 消毒電磁閥 OFF
  805. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  806. print('data: ', data)
  807. # mqtt_f(data)
  808. # [致動器] 馬達 0
  809. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  810. print('data: ', data)
  811. # mqtt_f(data)
  812. # [致動器] 排水電磁閥 ON
  813. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  814. print('data: ', data)
  815. # mqtt_f(data)
  816. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  817. timer = time.time()
  818. while True:
  819. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  820. break
  821. # [致動器] 排水電磁閥 OFF
  822. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  823. print('data: ', data)
  824. # mqtt_f(data)
  825. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  826. # ----- 發酵排程動作 end ------------------------------------------------------------------
  827. # [介面] 若啟用 乾燥 狀態
  828. if Dry_btn:
  829. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  830. # 若 D1~D6 桶槽中有一個桶槽入豆中
  831. if DryUp_InputtingBean_number == 1:
  832. # 若 D1 桶槽為入豆中
  833. if D1 == 'D_InputtingBean':
  834. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  835. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  836. DInputtingBean_TO_DInputtingBeanFinish("D1")
  837. D1 = 'D_InputtingBean_Finish'
  838. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  839. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  840. DInputtingBean_AND_notfilled("D1")
  841. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  842. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  843. DInputtingBean_TO_DInputtingBeanPause("D1")
  844. D1 = 'D_InputtingBean_Pause'
  845. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  846. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  847. if D1 == 'D_InputtingBean_Pause':
  848. DInputtingBeanPause_TO_DInputtingBean("D1")
  849. D1 = 'D_InputtingBean'
  850. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  851. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  852. if D1 == 'D_Waiting':
  853. DWaiting_TO_DInputtingBean("D1")
  854. D1 = 'D_InputtingBean'
  855. # 其他
  856. # else:
  857. # 以下內容原在此 else 內, 測試無誤後維持
  858. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  859. if D1 == 'D_InputtingBean_Finish':
  860. DInputtingBeanFinish_TO_DDrying("D1")
  861. D1 = 'D_Drying'
  862. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  863. if D1 == 'D_Drying' and D_UP_tank_SHT11Temp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  864. DDrying_TO_DOutputtingBean("D1")
  865. D1 = 'D_OutputtingBean'
  866. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  867. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  868. # TODO 發酵次數計算、消毒次數、校正
  869. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  870. if DOutputtingBean_Tank == 'D1':
  871. DOutputtingBean_TO_DWaiting('D1')
  872. DOutputtingBean_Tank = ''
  873. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  874. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  875. # 避免桶槽可出豆時未賦值
  876. if DOutputtingBean_Tank == '':
  877. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  878. # 乾燥槽消毒
  879. if D1 == 'D_Cleaning':
  880. DCleaning("D1")
  881. D1 = 'D_Waiting'
  882. else:
  883. print('未啟用乾燥流程')
  884. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  885. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  886. # # 1109 註解實驗用
  887. # if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  888. # # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  889. # DO1 = 'DO_InputtingBean'
  890. # print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  891. # print('------- DO1 狀態更新:入豆中 -------')
  892. # # [致動器] D1 蝴蝶閥 ON
  893. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  894. # print('data: ', data)
  895. # # mqtt_f(data)
  896. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  897. # if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  898. # # [致動器] 出料真空吸料機 OFF
  899. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  900. # print('data: ', data)
  901. # # mqtt_f(data)
  902. # # [致動器] D1 蝴蝶閥 OFF
  903. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  904. # print('data: ', data)
  905. # # mqtt_f(data)
  906. # DO1 = 'DO_OutputtingBean'
  907. # print('------- DO1 狀態更新:可出豆 -------')
  908. # elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  909. # # [致動器] 出料真空吸料機 ON
  910. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  911. # print('data: ', data)
  912. # # mqtt_f(data)
  913. # timer = time.time()
  914. # while True:
  915. # if (time.time() - timer) > Dry_Output_vacuumON_time:
  916. # # [致動器] 出料真空吸料機 OFF
  917. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  918. # print('data: ', data)
  919. # # mqtt_f(data)
  920. # timer = time.time()
  921. # break
  922. # while True:
  923. # if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  924. # break
  925. # # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  926. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank == '':
  927. # if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  928. # DO1 = 'DO_OutputtingBean'
  929. # print('------- DO1 狀態更新:可出豆 -------')
  930. # elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  931. # DO1 = 'DO_Waiting'
  932. # print('------- DO1 狀態更新:空桶等待 -------')
  933. # elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  934. # DO1 = 'DO_Waiting'
  935. # # [致動器] D1 蝴蝶閥 OFF
  936. # data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "off" }
  937. # print('data: ', data)
  938. # # mqtt_f(data)
  939. # print('------- DO1 狀態更新:空桶等待 -------')
  940. # # 1109 註解實驗用
  941. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  942. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  943. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  944. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  945. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  946. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  947. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  948. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  949. # ----- 將狀態寫入資料庫 ------------------------------
  950. # 獲取文本框的值並賦值給user實體對象
  951. D_status = dry_container_status()
  952. D_status.Dry_Input_1 = DI1
  953. D_status.Dry_Input_2 = DI2
  954. D_status.Dry_Tank_1 = D1
  955. D_status.Dry_Tank_2 = D2
  956. D_status.Dry_Tank_3 = D3
  957. D_status.Dry_Tank_4 = D4
  958. D_status.Dry_Tank_5 = D5
  959. D_status.Dry_Tank_6 = D6
  960. D_status.Dry_Tank_7 = D7
  961. D_status.Dry_Tank_8 = D8
  962. D_status.Dry_Tank_9 = D9
  963. D_status.Dry_Tank_10 = D10
  964. D_status.Dry_Tank_11 = D11
  965. D_status.Dry_Tank_12 = D12
  966. D_status.Dry_Output_1 = DO1
  967. D_status.Dry_Output_2 = DO2
  968. #將數據保存進資料庫
  969. db.session.add(D_status)
  970. # 手動提交
  971. db.session.commit()
  972. # ----- 將狀態寫入資料庫 ------------------------------
  973. return jsonify({"Dry_Tank_1":D1,
  974. "Dry_Tank_2":D2,
  975. "Dry_Output_1":DO1,
  976. "Dry_Output_2":DO2
  977. })
  978. @main.route('/dry_auto_status', methods=['GET', 'POST'])
  979. def dry_auto_status():
  980. info = request.args.to_dict()
  981. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  982. Dry_Input_bean_empty = 2
  983. Dry_Tank_bean_empty = 2
  984. Dry_Output_bean_empty = 2
  985. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  986. Dry_Input_bean_height = float(info['Dry_Input_bean_height'])
  987. Dry_Input_vacuumON_time = float(info['Dry_Input_vacuumON_time'])
  988. Dry_Input_vacuumOFF_time = float(info['Dry_Input_vacuumOFF_time'])
  989. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  990. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  991. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  992. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  993. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  994. Dry_Tank_drying_EC = float(info['Dry_Tank_drying_EC'])
  995. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  996. Dry_Tank_TempWeight_SHT11 = float(info['Dry_Tank_TempWeight_SHT11'])
  997. Dry_Tank_TempWeight_soil = float(info['Dry_Tank_TempWeight_soil'])
  998. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  999. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  1000. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  1001. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  1002. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_time'])
  1003. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  1004. Dry_btn = True
  1005. # 從資料庫資料表中取得最新狀態
  1006. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  1007. FO1 = ferment_status.Ferment_Output_1
  1008. FO2 = ferment_status.Ferment_Output_2
  1009. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  1010. # FO2 = 'FO_Waiting'
  1011. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  1012. DI1 = dry_status.Dry_Input_1
  1013. DI2 = dry_status.Dry_Input_2
  1014. D1 = dry_status.Dry_Tank_1
  1015. D2 = dry_status.Dry_Tank_2
  1016. D3 = dry_status.Dry_Tank_3
  1017. D4 = dry_status.Dry_Tank_4
  1018. D5 = dry_status.Dry_Tank_5
  1019. D6 = dry_status.Dry_Tank_6
  1020. D7 = dry_status.Dry_Tank_7
  1021. D8 = dry_status.Dry_Tank_8
  1022. D9 = dry_status.Dry_Tank_9
  1023. D10 = dry_status.Dry_Tank_10
  1024. D11 = dry_status.Dry_Tank_11
  1025. D12 = dry_status.Dry_Tank_12
  1026. DO1 = dry_status.Dry_Output_1
  1027. DO2 = dry_status.Dry_Output_2
  1028. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  1029. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  1030. DOutputtingBean_Tank = '' # 出料桶槽號
  1031. DryAuto_cleaning = 0 # 清洗次數
  1032. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  1033. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  1034. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1035. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  1036. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1037. DI_UP_UltraSoniclist = []
  1038. for i in range(1, 3, 1):
  1039. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  1040. UltraSonic = float(input_UltraSonic.UltraSonic)
  1041. DI_UP_UltraSoniclist.append(UltraSonic)
  1042. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  1043. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1044. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1045. D_UP_tank_UltraSonic = []
  1046. for i in range(1, 7, 1):
  1047. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1048. UltraSonic = float(tank_UltraSonic.UltraSonic)
  1049. D_UP_tank_UltraSonic.append(UltraSonic)
  1050. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  1051. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1052. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1053. DO_UP_UltraSoniclist = []
  1054. for i in range(1, 3, 1):
  1055. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  1056. UltraSonic = float(output_UltraSonic.UltraSonic)
  1057. DO_UP_UltraSoniclist.append(UltraSonic)
  1058. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  1059. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1060. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  1061. D_UP_tank_SHT11Temp = []
  1062. D_UP_tank_SHT11Humidity = []
  1063. for i in range(1, 7, 1):
  1064. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1065. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  1066. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  1067. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  1068. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  1069. # print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  1070. # print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  1071. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  1072. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  1073. D_UP_tank_SoilTemp = []
  1074. D_UP_tank_SoilHumidity = []
  1075. D_UP_tank_SoilEC = []
  1076. for i in range(1, 7, 1):
  1077. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1078. soil_Temp = float(tank_Soil.soil_Temp)
  1079. D_UP_tank_SoilTemp.append(soil_Temp)
  1080. soil_Humidity = float(tank_Soil.soil_Humidity)
  1081. D_UP_tank_SoilHumidity.append(soil_Humidity)
  1082. soil_EC = float(tank_Soil.soil_EC)
  1083. D_UP_tank_SoilEC.append(soil_EC)
  1084. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  1085. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  1086. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  1087. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  1088. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  1089. D_UP_tank_weightTemp = []
  1090. for i in range(1, 7, 1):
  1091. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1092. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1093. Temp = (Dry_Tank_TempWeight_SHT11*float(tank_SHT11.SHT11_Temp) + Dry_Tank_TempWeight_soil*float(tank_Soil.soil_Temp))/(Dry_Tank_TempWeight_SHT11+Dry_Tank_TempWeight_soil)
  1094. D_UP_tank_weightTemp.append(Temp)
  1095. print('D_UP_tank_weightTemp: ', D_UP_tank_weightTemp)
  1096. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  1097. # ----- 發酵排程動作 start ------------------------------------------------------------------
  1098. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  1099. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  1100. # [致動器] 真空吸料機 OFF
  1101. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1102. print('data: ', data)
  1103. # mqtt_f(data)
  1104. # [致動器] 馬達 0
  1105. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1106. print('data: ', data)
  1107. # mqtt_f(data)
  1108. # [致動器] 入料三通閥 ON排氣
  1109. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  1110. print('data: ', data)
  1111. # mqtt_f(data)
  1112. print('------- ', tid,' 狀態更新:入豆完成 -------')
  1113. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1114. def DInputtingBean_AND_notfilled(tid):
  1115. # [致動器] 入料三通閥 OFF入豆
  1116. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1117. print('data: ', data)
  1118. # mqtt_f(data)
  1119. # [致動器] 真空吸料機 ON
  1120. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  1121. print('data: ', data)
  1122. # mqtt_f(data)
  1123. timer = time.time()
  1124. while True:
  1125. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  1126. # [致動器] 真空吸料機 OFF
  1127. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1128. print('data: ', data)
  1129. # mqtt_f(data)
  1130. timer = time.time()
  1131. break
  1132. while True:
  1133. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  1134. break
  1135. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1136. def DInputtingBean_TO_DInputtingBeanPause(tid):
  1137. # [致動器] 真空吸料機 OFF
  1138. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1139. print('data: ', data)
  1140. # mqtt_f(data)
  1141. # [致動器] 馬達 0
  1142. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1143. print('data: ', data)
  1144. # mqtt_f(data)
  1145. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  1146. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  1147. def DInputtingBeanPause_TO_DInputtingBean(tid):
  1148. # [致動器] 入料三通閥 OFF入豆
  1149. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1150. print('data: ', data)
  1151. # mqtt_f(data)
  1152. # [致動器] 馬達 5
  1153. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  1154. print('data: ', data)
  1155. # mqtt_f(data)
  1156. print('------- ', tid, ' 狀態更新:入豆中 -------')
  1157. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  1158. def DWaiting_TO_DInputtingBean(tid):
  1159. # [致動器] 入料三通閥 OFF入豆
  1160. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1161. print('data: ', data)
  1162. # mqtt_f(data)
  1163. # [致動器] 馬達 5
  1164. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  1165. print('data: ', data)
  1166. # mqtt_f(data)
  1167. print('------- ', tid, ' 狀態更新:入豆中 -------')
  1168. # else: if D1 == 'D_InputtingBean_Finish':
  1169. def DInputtingBeanFinish_TO_DDrying(tid):
  1170. # [致動器] 馬達 指定轉速
  1171. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  1172. print('data: ', data)
  1173. # mqtt_f(data)
  1174. # [致動器] 排水電磁閥 ON
  1175. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  1176. print('data: ', data)
  1177. # mqtt_f(data)
  1178. # [致動器] 鼓風機 ON
  1179. data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  1180. print('data: ', data)
  1181. # mqtt_f(data)
  1182. # [致動器] 加熱器 1 ON
  1183. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  1184. print('data: ', data)
  1185. # mqtt_f(data)
  1186. # [致動器] 加熱器 2 ON
  1187. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  1188. print('data: ', data)
  1189. # mqtt_f(data)
  1190. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  1191. # else: if D1 == 'D_Drying' and D_UP_tank_weightTemp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  1192. def DDrying_TO_DOutputtingBean(tid):
  1193. # [致動器] 鼓風機 OFF
  1194. data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  1195. print('data: ', data)
  1196. # mqtt_f(data)
  1197. # [致動器] 加熱器 1 OFF
  1198. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  1199. print('data: ', data)
  1200. # mqtt_f(data)
  1201. # [致動器] 加熱器 2 OFF
  1202. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  1203. print('data: ', data)
  1204. # mqtt_f(data)
  1205. # [致動器] 馬達 0
  1206. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1207. print('data: ', data)
  1208. # mqtt_f(data)
  1209. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  1210. timer = time.time()
  1211. while True:
  1212. if (time.time() - timer) > Dry_Tank_drying_time:
  1213. # [致動器] 排水電磁閥 OFF
  1214. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1215. print('data: ', data)
  1216. # mqtt_f(data)
  1217. break
  1218. print('------- ', tid, ' 狀態更新:可出豆 -------')
  1219. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  1220. def DOutputtingBean_TO_DWaiting(tid):
  1221. # [致動器] D1 蝴蝶閥 OFF
  1222. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  1223. print('data: ', data)
  1224. # mqtt_f(data)
  1225. # D_Cleaning
  1226. def DCleaning(tid):
  1227. # [致動器] 馬達 10
  1228. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  1229. print('data: ', data)
  1230. # mqtt_f(data)
  1231. # [致動器] 消毒電磁閥 ON
  1232. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  1233. print('data: ', data)
  1234. # mqtt_f(data)
  1235. # [致動器] 排水電磁閥 OFF
  1236. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1237. print('data: ', data)
  1238. # mqtt_f(data)
  1239. # [致動器] TODO 消毒抽水 pump ON
  1240. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  1241. timer = time.time()
  1242. while True:
  1243. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  1244. # [致動器] TODO 消毒抽水 pump OFF
  1245. break
  1246. # [致動器] 消毒電磁閥 OFF
  1247. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  1248. print('data: ', data)
  1249. # mqtt_f(data)
  1250. # [致動器] 馬達 0
  1251. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1252. print('data: ', data)
  1253. # mqtt_f(data)
  1254. # [致動器] 排水電磁閥 ON
  1255. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  1256. print('data: ', data)
  1257. # mqtt_f(data)
  1258. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  1259. timer = time.time()
  1260. while True:
  1261. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  1262. break
  1263. # [致動器] 排水電磁閥 OFF
  1264. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1265. print('data: ', data)
  1266. # mqtt_f(data)
  1267. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  1268. # ----- 發酵排程動作 end ------------------------------------------------------------------
  1269. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  1270. # 如果入料儲豆槽 空桶等待, 且發酵出料儲豆槽 FO1 為可出豆, 則開始入豆
  1271. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  1272. DI1 = 'DI_InputtingBean'
  1273. print('------- DI1 狀態更新:入料中 -------')
  1274. # 如果入料儲豆槽 入豆中
  1275. elif DI1 == 'DI_InputtingBean':
  1276. # 如果入豆儲豆槽達指定高度時
  1277. if DI_UP_UltraSoniclist[0] >= Dry_Input_bean_height:
  1278. # [致動器] 入料真空吸料機 OFF
  1279. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  1280. print('data: ', data)
  1281. # mqtt_f(data)
  1282. DI1 = 'DI_OutputtingBean'
  1283. print('------- DI1 狀態更新:可出豆 -------')
  1284. # 如果入豆儲豆槽未達指定高度, 且 發酵出料儲豆槽 可出豆
  1285. elif DI_UP_UltraSoniclist[0] < Dry_Input_bean_height and FO1 == 'FO_OutputtingBean':
  1286. # [致動器] 入料真空吸料機 ON
  1287. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "on" }
  1288. print('data: ', data)
  1289. # mqtt_f(data)
  1290. timer = time.time()
  1291. while True:
  1292. if (time.time() - timer) > Dry_Input_vacuumON_time:
  1293. # [致動器] 入料真空吸料機 OFF
  1294. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  1295. print('data: ', data)
  1296. # mqtt_f(data)
  1297. timer = time.time()
  1298. break
  1299. while True:
  1300. if (time.time() - timer) > Dry_Input_vacuumOFF_time:
  1301. break
  1302. # 如果入料儲豆槽生豆大於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為可出豆
  1303. elif (DI_UP_UltraSoniclist[0] > Dry_Input_bean_empty) and FO1 != 'FO_OutputtingBean':
  1304. DI1 = 'DI_OutputtingBean'
  1305. print('------- DI1 狀態更新:可出豆 -------')
  1306. # 桶槽內小於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為空桶等待
  1307. elif (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty) and FO1 != 'PO_OutputtingBean':
  1308. DI1 = 'DI_Waiting'
  1309. print('------- FI1 狀態更新:空桶等待 -------')
  1310. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  1311. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty):
  1312. DI1 = 'DI_Waiting'
  1313. print('------- DI1 狀態更新:空桶等待 -------')
  1314. # [介面] 若啟用 乾燥 狀態
  1315. if Dry_btn:
  1316. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  1317. # 若 D1~D6 桶槽中有一個桶槽入豆中
  1318. if DryUp_InputtingBean_number == 1:
  1319. # 若 D1 桶槽為入豆中
  1320. if D1 == 'D_InputtingBean':
  1321. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  1322. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  1323. DInputtingBean_TO_DInputtingBeanFinish("D1")
  1324. D1 = 'D_InputtingBean_Finish'
  1325. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  1326. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1327. DInputtingBean_AND_notfilled("D1")
  1328. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  1329. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1330. DInputtingBean_TO_DInputtingBeanPause("D1")
  1331. D1 = 'D_InputtingBean_Pause'
  1332. elif D2 == 'D_InputtingBean':
  1333. if D_UP_tank_UltraSonic[1] >= Dry_Tank_bean_height:
  1334. DInputtingBean_TO_DInputtingBeanFinish("D2")
  1335. D2 = 'D_InputtingBean_Finish'
  1336. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1337. DInputtingBean_AND_notfilled("D2")
  1338. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1339. DInputtingBean_TO_DInputtingBeanPause("D2")
  1340. D2 = 'D_InputtingBean_Pause'
  1341. elif D3 == 'D_InputtingBean':
  1342. if D_UP_tank_UltraSonic[2] >= Dry_Tank_bean_height:
  1343. DInputtingBean_TO_DInputtingBeanFinish("D3")
  1344. D3 = 'D_InputtingBean_Finish'
  1345. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1346. DInputtingBean_AND_notfilled("D2")
  1347. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1348. DInputtingBean_TO_DInputtingBeanPause("D2")
  1349. D3 = 'D_InputtingBean_Pause'
  1350. elif D4 == 'D_InputtingBean':
  1351. if D_UP_tank_UltraSonic[3] >= Dry_Tank_bean_height:
  1352. DInputtingBean_TO_DInputtingBeanFinish("D4")
  1353. D4 = 'D_InputtingBean_Finish'
  1354. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1355. DInputtingBean_AND_notfilled("D4")
  1356. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1357. DInputtingBean_TO_DInputtingBeanPause("D4")
  1358. D4 = 'D_InputtingBean_Pause'
  1359. elif D5 == 'D_InputtingBean':
  1360. if D_UP_tank_UltraSonic[4] >= Dry_Tank_bean_height:
  1361. DInputtingBean_TO_DInputtingBeanFinish("D5")
  1362. D5 = 'D_InputtingBean_Finish'
  1363. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1364. DInputtingBean_AND_notfilled("D5")
  1365. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1366. DInputtingBean_TO_DInputtingBeanPause("D5")
  1367. D5 = 'D_InputtingBean_Pause'
  1368. elif D6 == 'D_InputtingBean':
  1369. if D_UP_tank_UltraSonic[5] >= Dry_Tank_bean_height:
  1370. DInputtingBean_TO_DInputtingBeanFinish("D6")
  1371. D6 = 'D_InputtingBean_Finish'
  1372. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1373. DInputtingBean_AND_notfilled("D6")
  1374. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1375. DInputtingBean_TO_DInputtingBeanPause("D6")
  1376. D6 = 'D_InputtingBean_Pause'
  1377. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  1378. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  1379. if D1 == 'D_InputtingBean_Pause':
  1380. DInputtingBeanPause_TO_DInputtingBean("D1")
  1381. D1 = 'D_InputtingBean'
  1382. elif D2 == 'D_InputtingBean_Pause':
  1383. DInputtingBeanPause_TO_DInputtingBean("D2")
  1384. D2 = 'D_InputtingBean'
  1385. elif D3 == 'D_InputtingBean_Pause':
  1386. DInputtingBeanPause_TO_DInputtingBean("D3")
  1387. D3 = 'D_InputtingBean'
  1388. elif D4 == 'D_InputtingBean_Pause':
  1389. DInputtingBeanPause_TO_DInputtingBean("D4")
  1390. D4 = 'D_InputtingBean'
  1391. elif D5 == 'D_InputtingBean_Pause':
  1392. DInputtingBeanPause_TO_DInputtingBean("D5")
  1393. D5 = 'D_InputtingBean'
  1394. elif D6 == 'D_InputtingBean_Pause':
  1395. DInputtingBeanPause_TO_DInputtingBean("D6")
  1396. D6 = 'D_InputtingBean'
  1397. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  1398. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  1399. if D1 == 'D_Waiting':
  1400. DWaiting_TO_DInputtingBean("D1")
  1401. D1 = 'D_InputtingBean'
  1402. elif D2 == 'D_Waiting':
  1403. DWaiting_TO_DInputtingBean("D2")
  1404. D2 = 'D_InputtingBean'
  1405. elif D3 == 'D_Waiting':
  1406. DWaiting_TO_DInputtingBean("D3")
  1407. D3 = 'D_InputtingBean'
  1408. elif D4 == 'D_Waiting':
  1409. DWaiting_TO_DInputtingBean("D4")
  1410. D4 = 'D_InputtingBean'
  1411. elif D5 == 'D_Waiting':
  1412. DWaiting_TO_DInputtingBean("D5")
  1413. D5 = 'D_InputtingBean'
  1414. elif D6 == 'D_Waiting':
  1415. DWaiting_TO_DInputtingBean("D6")
  1416. D6 = 'D_InputtingBean'
  1417. # 其他
  1418. else:
  1419. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  1420. if D1 == 'D_InputtingBean_Finish':
  1421. DInputtingBeanFinish_TO_DDrying("D1")
  1422. D1 = 'D_Drying'
  1423. if D2 == 'D_InputtingBean_Finish':
  1424. DInputtingBeanFinish_TO_DDrying("D2")
  1425. D2 = 'D_Drying'
  1426. if D3 == 'D_InputtingBean_Finish':
  1427. DInputtingBeanFinish_TO_DDrying("D3")
  1428. D3 = 'D_Drying'
  1429. if D4 == 'D_InputtingBean_Finish':
  1430. DInputtingBeanFinish_TO_DDrying("D4")
  1431. D4 = 'D_Drying'
  1432. if D5 == 'D_InputtingBean_Finish':
  1433. DInputtingBeanFinish_TO_DDrying("D5")
  1434. D5 = 'D_Drying'
  1435. if D6 == 'D_InputtingBean_Finish':
  1436. DInputtingBeanFinish_TO_DDrying("D6")
  1437. D6 = 'D_Drying'
  1438. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  1439. if D1 == 'D_Drying' and D_UP_tank_weightTemp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  1440. DDrying_TO_DOutputtingBean("D1")
  1441. D1 = 'D_OutputtingBean'
  1442. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  1443. if D2 == 'D_Drying' and D_UP_tank_weightTemp[1] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[1] <= Dry_Tank_drying_Humidity:
  1444. DDrying_TO_DOutputtingBean("D2")
  1445. D2 = 'D_OutputtingBean'
  1446. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D2'
  1447. if D3 == 'D_Drying' and D_UP_tank_weightTemp[2] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[2] <= Dry_Tank_drying_Humidity:
  1448. DDrying_TO_DOutputtingBean("D3")
  1449. D3 = 'D_OutputtingBean'
  1450. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D3'
  1451. if D4 == 'D_Drying' and D_UP_tank_weightTemp[3] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[3] <= Dry_Tank_drying_Humidity:
  1452. DDrying_TO_DOutputtingBean("D4")
  1453. D4 = 'D_OutputtingBean'
  1454. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D4'
  1455. if D5 == 'D_Drying' and D_UP_tank_weightTemp[4] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[4] <= Dry_Tank_drying_Humidity:
  1456. DDrying_TO_DOutputtingBean("D5")
  1457. D5 = 'D_OutputtingBean'
  1458. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D5'
  1459. if D6 == 'D_Drying' and D_UP_tank_weightTemp[5] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[5] <= Dry_Tank_drying_Humidity:
  1460. DDrying_TO_DOutputtingBean("D6")
  1461. D6 = 'D_OutputtingBean'
  1462. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D6'
  1463. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  1464. # TODO 發酵次數計算、消毒次數、校正
  1465. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  1466. if DOutputtingBean_Tank == 'D1':
  1467. DOutputtingBean_TO_DWaiting('D1')
  1468. DOutputtingBean_Tank = ''
  1469. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  1470. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  1471. if D2 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[1] <= Dry_Tank_bean_empty):
  1472. if DOutputtingBean_Tank == 'D2':
  1473. DOutputtingBean_TO_DWaiting('D2')
  1474. DOutputtingBean_Tank = ''
  1475. if (DryAuto_cleaning == 0): D2 = 'D_Waiting'
  1476. elif (DryAuto_cleaning != 0): D2 = 'D_Cleaning'
  1477. if D3 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[2] <= Dry_Tank_bean_empty):
  1478. if DOutputtingBean_Tank == 'D2':
  1479. DOutputtingBean_TO_DWaiting('D2')
  1480. DOutputtingBean_Tank = ''
  1481. if (DryAuto_cleaning == 0): D3 = 'D_Waiting'
  1482. elif (DryAuto_cleaning != 0): D3 = 'D_Cleaning'
  1483. if D4 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[3] <= Dry_Tank_bean_empty):
  1484. if DOutputtingBean_Tank == 'D4':
  1485. DOutputtingBean_TO_DWaiting('D4')
  1486. DOutputtingBean_Tank = ''
  1487. if (DryAuto_cleaning == 0): D4 = 'D_Waiting'
  1488. elif (DryAuto_cleaning != 0): D4 = 'D_Cleaning'
  1489. if D5 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[4] <= Dry_Tank_bean_empty):
  1490. if DOutputtingBean_Tank == 'D5':
  1491. DOutputtingBean_TO_DWaiting('D5')
  1492. DOutputtingBean_Tank = ''
  1493. if (DryAuto_cleaning == 0): D5 = 'D_Waiting'
  1494. elif (DryAuto_cleaning != 0): D5 = 'D_Cleaning'
  1495. if D6 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[5] <= Dry_Tank_bean_empty):
  1496. if DOutputtingBean_Tank == 'D6':
  1497. DOutputtingBean_TO_DWaiting('D6')
  1498. DOutputtingBean_Tank = ''
  1499. if (DryAuto_cleaning == 0): D6 = 'D_Waiting'
  1500. elif (DryAuto_cleaning != 0): D6 = 'D_Cleaning'
  1501. # 避免桶槽可出豆時未賦值
  1502. if DOutputtingBean_Tank == '':
  1503. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  1504. elif D2 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D2'
  1505. elif D3 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D3'
  1506. elif D4 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D4'
  1507. elif D5 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D5'
  1508. elif D6 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D6'
  1509. # 乾燥槽消毒
  1510. if D1 == 'D_Cleaning':
  1511. DCleaning("D1")
  1512. D1 = 'D_Waiting'
  1513. if D2 == 'D_Cleaning':
  1514. DCleaning("D2")
  1515. D2 = 'D_Waiting'
  1516. if D3 == 'D_Cleaning':
  1517. DCleaning("D3")
  1518. D3 = 'D_Waiting'
  1519. if D4 == 'D_Cleaning':
  1520. DCleaning("D4")
  1521. D4 = 'D_Waiting'
  1522. if D5 == 'D_Cleaning':
  1523. DCleaning("D5")
  1524. D5 = 'D_Waiting'
  1525. if D6 == 'D_Cleaning':
  1526. DCleaning("D6")
  1527. D6 = 'D_Waiting'
  1528. else:
  1529. print('未啟用乾燥流程')
  1530. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  1531. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  1532. if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  1533. # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  1534. DO1 = 'DO_InputtingBean'
  1535. print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  1536. print('------- DO1 狀態更新:入豆中 -------')
  1537. # [致動器] D1 蝴蝶閥 ON
  1538. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  1539. print('data: ', data)
  1540. # mqtt_f(data)
  1541. elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  1542. if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  1543. # [致動器] 出料真空吸料機 OFF
  1544. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  1545. print('data: ', data)
  1546. # mqtt_f(data)
  1547. # [致動器] D1 蝴蝶閥 OFF
  1548. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  1549. print('data: ', data)
  1550. # mqtt_f(data)
  1551. DO1 = 'DO_OutputtingBean'
  1552. print('------- DO1 狀態更新:可出豆 -------')
  1553. elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  1554. # [致動器] 出料真空吸料機 ON
  1555. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  1556. print('data: ', data)
  1557. # mqtt_f(data)
  1558. timer = time.time()
  1559. while True:
  1560. if (time.time() - timer) > Dry_Output_vacuumON_time:
  1561. # [致動器] 出料真空吸料機 OFF
  1562. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  1563. print('data: ', data)
  1564. # mqtt_f(data)
  1565. timer = time.time()
  1566. break
  1567. while True:
  1568. if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  1569. break
  1570. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  1571. elif DOutputtingBean_Tank == '':
  1572. if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  1573. DO1 = 'DO_OutputtingBean'
  1574. print('------- DO1 狀態更新:可出豆 -------')
  1575. elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1576. DO1 = 'DO_Waiting'
  1577. print('------- DO1 狀態更新:空桶等待 -------')
  1578. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1579. DO1 = 'DO_Waiting'
  1580. print('------- DO1 狀態更新:空桶等待 -------')
  1581. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1582. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  1583. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  1584. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  1585. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  1586. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  1587. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  1588. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1589. # ----- 將狀態寫入資料庫 ------------------------------
  1590. # 獲取文本框的值並賦值給user實體對象
  1591. D_status = dry_container_status()
  1592. D_status.Dry_Input_1 = DI1
  1593. D_status.Dry_Input_2 = DI2
  1594. D_status.Dry_Tank_1 = D1
  1595. D_status.Dry_Tank_2 = D2
  1596. D_status.Dry_Tank_3 = D3
  1597. D_status.Dry_Tank_4 = D4
  1598. D_status.Dry_Tank_5 = D5
  1599. D_status.Dry_Tank_6 = D6
  1600. D_status.Dry_Tank_7 = D7
  1601. D_status.Dry_Tank_8 = D8
  1602. D_status.Dry_Tank_9 = D9
  1603. D_status.Dry_Tank_10 = D10
  1604. D_status.Dry_Tank_11 = D11
  1605. D_status.Dry_Tank_12 = D12
  1606. D_status.Dry_Output_1 = DO1
  1607. D_status.Dry_Output_2 = DO2
  1608. #將數據保存進資料庫
  1609. db.session.add(D_status)
  1610. # 手動提交
  1611. db.session.commit()
  1612. # ----- 將狀態寫入資料庫 ------------------------------
  1613. return jsonify({"Dry_Input_1":DI1,
  1614. "Dry_Tank_1":D1,
  1615. "Dry_Tank_2":D2,
  1616. "Dry_Tank_3":D3,
  1617. "Dry_Tank_4":D4,
  1618. "Dry_Tank_5":D5,
  1619. "Dry_Tank_6":D6,
  1620. "Dry_Output_1":DO1
  1621. })
  1622. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以下為原備份
  1623. @main.route('/dry_auto_status_1101backup', methods=['GET', 'POST'])
  1624. def dry_auto_test_1101backup():
  1625. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  1626. Dry_btn = True
  1627. # 從資料庫資料表中取得最新狀態
  1628. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  1629. DI1 = dry_status.Dry_Input_1
  1630. DI2 = dry_status.Dry_Input_2
  1631. D1 = dry_status.Dry_Tank_1
  1632. D2 = dry_status.Dry_Tank_2
  1633. D3 = dry_status.Dry_Tank_3
  1634. D4 = dry_status.Dry_Tank_4
  1635. D5 = dry_status.Dry_Tank_5
  1636. D6 = dry_status.Dry_Tank_6
  1637. D7 = dry_status.Dry_Tank_7
  1638. D8 = dry_status.Dry_Tank_8
  1639. D9 = dry_status.Dry_Tank_9
  1640. D10 = dry_status.Dry_Tank_10
  1641. D11 = dry_status.Dry_Tank_11
  1642. D12 = dry_status.Dry_Tank_12
  1643. DO1 = dry_status.Dry_Output_1
  1644. DO2 = dry_status.Dry_Output_2
  1645. FO1 = 'FO_Waiting' # 'FO_OutputtingBean'
  1646. FO2 = 'FO_Waiting'
  1647. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  1648. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  1649. # ----- 乾燥桶槽 D1~D6 入料暫停→入料判斷 ------------------------------
  1650. Dry_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  1651. # 若入料儲豆槽可出豆, 且 D1~D6 其中有桶槽入料暫停 (就是入料時桶槽豆子未滿 or 儲豆槽=='DI_Waiting' 已空) 時, 優先入豆
  1652. if DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  1653. if D1 == 'D_InputtingBean_Pause':
  1654. D1 = 'D_InputtingBean'
  1655. print('------- D1 狀態更新:入料中 -------')
  1656. elif D2 == 'D_InputtingBean_Pause':
  1657. D2 = 'D_InputtingBean'
  1658. print('------- D2 狀態更新:入料中 -------')
  1659. elif D3 == 'D_InputtingBean_Pause':
  1660. D3 = 'D_InputtingBean'
  1661. print('------- D3 狀態更新:入料中 -------')
  1662. elif D4 == 'D_InputtingBean_Pause':
  1663. D4 = 'D_InputtingBean'
  1664. print('------- D4 狀態更新:入料中 -------')
  1665. elif D5 == 'D_InputtingBean_Pause':
  1666. D5 = 'D_InputtingBean'
  1667. print('------- D5 狀態更新:入料中 -------')
  1668. elif D6 == 'D_InputtingBean_Pause':
  1669. D6 = 'D_InputtingBean'
  1670. print('------- D6 狀態更新:入料中 -------')
  1671. # ----- 乾燥桶槽 D1~D6 等待→入料判斷 ------------------------------
  1672. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  1673. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1674. # [介面] 若未啟用 發酵 狀態
  1675. if not Dry_btn:
  1676. print('未指定乾燥流程')
  1677. # 入料儲豆槽 非可出料狀態
  1678. elif Dry_btn and DI1 != 'DI_OutputtingBean':
  1679. print('入料儲豆槽非可出豆, 無法入料')
  1680. # 若 D1~D6 乾燥桶槽為 入豆暫停, 則狀態改為入豆優先入豆
  1681. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  1682. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, '優先入料中')
  1683. print('------- D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, ' 入料中 -------')
  1684. # 若 D1~D6 發酵桶槽為 入豆, 則桶槽數字小者 優先入豆
  1685. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  1686. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean')+1, '優先入料中')
  1687. print('------- D', D_UP_tanklist.index('D_InputtingBean')+1, ' 入料中 -------')
  1688. elif Dry_btn and DI1 == 'DI_OutputtingBean' \
  1689. and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1690. # 當達標準入料條件
  1691. if D1 == 'D_Waiting':
  1692. D1 = 'D_InputtingBean'
  1693. print('------- D1 狀態更新:入料中 -------')
  1694. elif D2 == 'D_Waiting':
  1695. D2 = 'D_InputtingBean'
  1696. print('------- D2 狀態更新:入料中 -------')
  1697. elif D3 == 'D_Waiting':
  1698. D3 = 'D_InputtingBean'
  1699. print('------- D3 狀態更新:入料中 -------')
  1700. elif D4 == 'D_Waiting':
  1701. D4 = 'D_InputtingBean'
  1702. print('------- D4 狀態更新:入料中 -------')
  1703. elif D5 == 'D_Waiting':
  1704. D5 = 'D_InputtingBean'
  1705. print('------- D5 狀態更新:入料中 -------')
  1706. elif D6 == 'D_Waiting':
  1707. D6 = 'D_InputtingBean'
  1708. print('------- D6 狀態更新:入料中 -------')
  1709. # ----- 乾燥桶槽 D1~D6 入料→入料暫停判斷 ------------------------------
  1710. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1711. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1712. D_UP_tank_UltraSonic = []
  1713. for i in range(1, 7, 1):
  1714. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1715. UltraSonic = int(tank_UltraSonic.UltraSonic)
  1716. D_UP_tank_UltraSonic.append(UltraSonic)
  1717. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  1718. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1719. if DI1 != 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  1720. if D1 == 'D_InputtingBean' and D_UP_tank_UltraSonic[0] < 110:
  1721. D1 = 'D_InputtingBean_Pause'
  1722. print('------- D1 狀態更新:入料暫停 -------')
  1723. else:
  1724. D1 = 'D_InputtingBean_Finish'
  1725. print('------- D1 狀態更新:入料完成 -------')
  1726. if D2 == 'D_InputtingBean' and D_UP_tank_UltraSonic[1] < 110:
  1727. D2 = 'D_InputtingBean_Pause'
  1728. print('------- D2 狀態更新:入料暫停 -------')
  1729. else:
  1730. D2 = 'D_InputtingBean_Finish'
  1731. print('------- D2 狀態更新:入料完成 -------')
  1732. if D3 == 'D_InputtingBean' and D_UP_tank_UltraSonic[2] < 110:
  1733. D3 = 'D_InputtingBean_Pause'
  1734. print('------- D3 狀態更新:入料暫停 -------')
  1735. else:
  1736. D3 = 'D_InputtingBean_Finish'
  1737. print('------- D3 狀態更新:入料完成 -------')
  1738. if D4 == 'D_InputtingBean' and D_UP_tank_UltraSonic[3] < 110:
  1739. D4 = 'D_InputtingBean_Pause'
  1740. print('------- D4 狀態更新:入料暫停 -------')
  1741. else:
  1742. D4 = 'D_InputtingBean_Finish'
  1743. print('------- D4 狀態更新:入料完成 -------')
  1744. if D5 == 'D_InputtingBean' and D_UP_tank_UltraSonic[4] < 110:
  1745. D5 = 'D_InputtingBean_Pause'
  1746. print('------- D5 狀態更新:入料暫停 -------')
  1747. else:
  1748. D5 = 'D_InputtingBean_Finish'
  1749. print('------- D5 狀態更新:入料完成 -------')
  1750. if D6 == 'D_InputtingBean' and D_UP_tank_UltraSonic[5] < 110:
  1751. D6 = 'D_InputtingBean_Pause'
  1752. print('------- D6 狀態更新:入料暫停 -------')
  1753. else:
  1754. D6 = 'D_InputtingBean_Finish'
  1755. print('------- D6 狀態更新:入料完成 -------')
  1756. # # ----- 乾燥桶槽 D1~D6 入料完成→乾燥判斷 ------------------------------
  1757. # Dry_InputtingBeanFinish_number = int(D_UP_tanklist.count('D_InputtingBean_Finish'))
  1758. # # 乾燥條件:當前桶槽入豆達指定高度, 則開始乾燥 (可以多桶乾燥)
  1759. # # !!! 乾燥槽 D_Drying 狀態應該請硬體判斷
  1760. # # !!! 若狀態為 D_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 D_Drying 乾燥
  1761. # if D1 == 'D_InputtingBean_Finish' or D1 == 'D_InputtingBean_Pause' and D_UP_tank_UltraSonic[0] >= 110:
  1762. # D1 = 'D_Drying'
  1763. # print('------- D1 狀態更新:乾燥中 -------')
  1764. # if D2 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[1] >= 110:
  1765. # D2 = 'D_Drying'
  1766. # print('------- D2 狀態更新:乾燥中 -------')
  1767. # if D3 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[2] >= 110:
  1768. # D3 = 'D_Drying'
  1769. # print('------- D3 狀態更新:乾燥中 -------')
  1770. # if D4 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[3] >= 110:
  1771. # D4 = 'D_Drying'
  1772. # print('------- D4 狀態更新:乾燥中 -------')
  1773. # if D5 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[4] >= 110:
  1774. # D5 = 'D_Drying'
  1775. # print('------- D5 狀態更新:乾燥中 -------')
  1776. # if D6 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[5] >= 110:
  1777. # D6 = 'D_Drying'
  1778. # print('------- D6 狀態更新:乾燥中 -------')
  1779. # ----- 乾燥桶槽 D1~D6 發酵→可出豆 判斷 ------------------------------
  1780. # !!! 發酵槽 D_OutputtingBean 狀態應該請硬體判斷
  1781. # !!! 若狀態為 D_Drying 且 達指定乾燥條件, 狀態改為 D_OutputtingBean 可出豆
  1782. # 可以多桶各自執行發酵排程
  1783. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1784. if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  1785. if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  1786. if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  1787. if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  1788. if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  1789. if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  1790. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1791. # # ----- 乾燥桶槽 D1~D6 可出豆→出料儲豆槽 DO1 判斷 ------------------------------
  1792. Dry_OutputtingBean_number = int(D_UP_tanklist.count('D_OutputtingBean'))
  1793. # # !!! 若出料儲豆槽狀態為 DO_Waiting(空桶等待) 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 DO1 配合開始出豆
  1794. # if DO1 == 'DO_Waiting' and Dry_OutputtingBean_number >= 1:
  1795. # if D1 == 'D_OutputtingBean':
  1796. # DO1 = 'DO_InputtingBean'
  1797. # print('------- D1 狀態更新:出豆中 -------')
  1798. # print('------- DO1 狀態更新:入豆中 -------')
  1799. # elif D2 == 'D_OutputtingBean':
  1800. # DO1 = 'DO_InputtingBean'
  1801. # print('------- D2 狀態更新:出豆中 -------')
  1802. # print('------- DO1 狀態更新:入豆中 -------')
  1803. # elif D3 == 'D_OutputtingBean':
  1804. # DO1 = 'DO_InputtingBean'
  1805. # print('------- D3 狀態更新:出豆中 -------')
  1806. # print('------- DO1 狀態更新:入豆中 -------')
  1807. # elif D4 == 'D_OutputtingBean':
  1808. # DO1 = 'DO_InputtingBean'
  1809. # print('------- D4 狀態更新:出豆中 -------')
  1810. # print('------- DO1 狀態更新:入豆中 -------')
  1811. # elif D5 == 'D_OutputtingBean':
  1812. # DO1 = 'DO_InputtingBean'
  1813. # print('------- D5 狀態更新:出豆中 -------')
  1814. # print('------- DO1 狀態更新:入豆中 -------')
  1815. # elif D6 == 'D_OutputtingBean':
  1816. # DO1 = 'DO_InputtingBean'
  1817. # print('------- D6 狀態更新:出豆中 -------')
  1818. # print('------- DO1 狀態更新:入豆中 -------')
  1819. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  1820. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1821. DI_UP_UltraSoniclist = []
  1822. for i in range(1, 3, 1):
  1823. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  1824. UltraSonic = int(input_UltraSonic.UltraSonic)
  1825. DI_UP_UltraSoniclist.append(UltraSonic)
  1826. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  1827. # !!! 乾燥入料儲豆槽 D_OutputtingBean 狀態應該請硬體判斷
  1828. # 入料儲豆槽等待中、且發酵槽出料儲豆槽可出豆時, 入料儲豆槽入豆
  1829. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  1830. DI1 = 'DI_InputtingBean'
  1831. print('------- DI1 狀態更新:入豆中 -------')
  1832. # 入料儲豆槽入豆時 且 (發酵儲豆槽有入料 或者 前方儲豆槽非可出豆), 則停止入豆
  1833. elif DI1 == 'DI_InputtingBean' and (DI_UP_UltraSoniclist[0] > 35) and (FO1 != 'FO_OutputtingBean') :
  1834. DI1 = 'DI_OutputtingBean'
  1835. print('------- DI1 狀態更新:可出豆 -------')
  1836. # 若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  1837. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] < 40) and FO1 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1838. DI1 = 'DI_InputtingBean'
  1839. print('------- DI1 狀態更新:入豆中 -------')
  1840. # if DI2 == 'DI_Waiting' and FO2 == 'FO_OutputtingBean':
  1841. # DI2 = 'DI_InputtingBean'
  1842. # print('------- DI2 狀態更新:入豆中 -------')
  1843. # elif DI2 == 'DI_InputtingBean' and ((DI_DOWN_UltraSoniclist[1] > 35) or (FO2 == 'FO_OutputtingBean')) :
  1844. # DI2 = 'DI_OutputtingBean'
  1845. # print('------- DI2 狀態更新:可出豆 -------')
  1846. # elif DI2 == 'DI_OutputtingBean' and (DI_DOWN_UltraSoniclist[1] < 40) and FO2 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1847. # DI2 = 'DI_InputtingBean'
  1848. # print('------- DI2 狀態更新:入豆中 -------')
  1849. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  1850. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1851. DO_UP_UltraSoniclist = []
  1852. for i in range(1, 3, 1):
  1853. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  1854. UltraSonic = int(output_UltraSonic.UltraSonic)
  1855. DO_UP_UltraSoniclist.append(UltraSonic)
  1856. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  1857. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  1858. # 參考 -- 乾燥桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  1859. # 出料儲豆槽入料 且滿時, 出料儲豆槽可出豆
  1860. if DO1 == ('DO_InputtingBean' and DO_UP_UltraSoniclist[0] > 35):
  1861. DO1 = 'DO_OutputtingBean'
  1862. # 出料儲豆槽入料 且未滿, 桶槽可出豆已空
  1863. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  1864. D_UP_UltraSoniclist = []
  1865. for i in range(1, 7, 1):
  1866. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1867. UltraSonic = int(tank_UltraSonic.UltraSonic)
  1868. D_UP_UltraSoniclist.append(UltraSonic)
  1869. print('D_UP_UltraSoniclist: ', D_UP_UltraSoniclist)
  1870. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  1871. if DO1 == 'DO_InputtingBean' and Dry_OutputtingBean_number >= 1:
  1872. if D1 == 'D_OutputtingBean' and D_UP_UltraSoniclist[0] < 5:
  1873. D1 = 'D_Waiting'
  1874. DO1 = 'DO_OutputtingBean'
  1875. print('------- D1 狀態更新:空桶等待 -------')
  1876. print('------- DO1 狀態更新:可出豆 -------')
  1877. elif D2 == 'D_OutputtingBean' and D_UP_UltraSoniclist[1] < 5:
  1878. D2 = 'D_Waiting'
  1879. DO1 = 'DO_OutputtingBean'
  1880. print('------- D2 狀態更新:空桶等待 -------')
  1881. print('------- DO1 狀態更新:可出豆 -------')
  1882. elif D3 == 'D_OutputtingBean' and D_UP_UltraSoniclist[2] < 5:
  1883. D3 = 'D_Waiting'
  1884. DO1 = 'DO_OutputtingBean'
  1885. print('------- D3 狀態更新:空桶等待 -------')
  1886. print('------- DO1 狀態更新:可出豆 -------')
  1887. elif D4 == 'D_OutputtingBean' and D_UP_UltraSoniclist[3] < 5:
  1888. D4 = 'D_Waiting'
  1889. DO1 = 'DO_OutputtingBean'
  1890. print('------- D4 狀態更新:空桶等待 -------')
  1891. print('------- DO1 狀態更新:可出豆 -------')
  1892. elif D5 == 'D_OutputtingBean' and D_UP_UltraSoniclist[4] < 5:
  1893. D5 = 'D_Waiting'
  1894. DO1 = 'DO_OutputtingBean'
  1895. print('------- D5 狀態更新:空桶等待 -------')
  1896. print('------- DO1 狀態更新:可出豆 -------')
  1897. elif D6 == 'D_OutputtingBean' and D_UP_UltraSoniclist[5] < 5:
  1898. D6 = 'D_Waiting'
  1899. DO1 = 'DO_OutputtingBean'
  1900. print('------- D6 狀態更新:空桶等待 -------')
  1901. print('------- DO1 狀態更新:可出豆 -------')
  1902. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] < 5:
  1903. DO1 = 'DO_Waiting'
  1904. # # ----- 將狀態寫入資料庫 ------------------------------
  1905. # # 獲取文本框的值並賦值給user實體對象
  1906. # D_status = dry_container_status()
  1907. # D_status.Dry_Input_1 = DI1
  1908. # D_status.Dry_Input_2 = DI2
  1909. # D_status.Dry_Tank_1 = D1
  1910. # D_status.Dry_Tank_2 = D2
  1911. # D_status.Dry_Tank_3 = D3
  1912. # D_status.Dry_Tank_4 = D4
  1913. # D_status.Dry_Tank_5 = D5
  1914. # D_status.Dry_Tank_6 = D6
  1915. # D_status.Dry_Tank_7 = D7
  1916. # D_status.Dry_Tank_8 = D8
  1917. # D_status.Dry_Tank_9 = D9
  1918. # D_status.Dry_Tank_10 = D10
  1919. # D_status.Dry_Tank_11 = D11
  1920. # D_status.Dry_Tank_12 = D12
  1921. # D_status.Dry_Output_1 = DO1
  1922. # D_status.Dry_Output_2 = DO2
  1923. # #將數據保存進資料庫
  1924. # db.session.add(D_status)
  1925. # # 手動提交
  1926. # db.session.commit()
  1927. # # ----- 將狀態寫入資料庫 ------------------------------
  1928. return jsonify({"Dry_Input_1":DI1,
  1929. "Dry_Tank_1":D1,
  1930. "Dry_Tank_2":D2,
  1931. "Dry_Tank_3":D3,
  1932. "Dry_Tank_4":D4,
  1933. "Dry_Tank_5":D5,
  1934. "Dry_Tank_6":D6,
  1935. "Dry_Output_1":DO1
  1936. })
  1937. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以上為原備份
  1938. # 發酵槽自動化測試頁
  1939. @main.route('/ferment_auto', methods=['GET', 'POST'])
  1940. def ferment_auto():
  1941. # 獲取登入信息
  1942. if 'id' in session and 'uname' in session and 'status' in session:
  1943. username = session['uname']
  1944. status = session['status']
  1945. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  1946. FI1 = ferment_status.Ferment_Input_1
  1947. FI2 = ferment_status.Ferment_Input_2
  1948. F1 = ferment_status.Ferment_Tank_1
  1949. F2 = ferment_status.Ferment_Tank_2
  1950. F3 = ferment_status.Ferment_Tank_3
  1951. F4 = ferment_status.Ferment_Tank_4
  1952. F5 = ferment_status.Ferment_Tank_5
  1953. F6 = ferment_status.Ferment_Tank_6
  1954. F7 = ferment_status.Ferment_Tank_7
  1955. F8 = ferment_status.Ferment_Tank_8
  1956. F9 = ferment_status.Ferment_Tank_9
  1957. F10 = ferment_status.Ferment_Tank_10
  1958. F11 = ferment_status.Ferment_Tank_11
  1959. F12 = ferment_status.Ferment_Tank_12
  1960. FO1 = ferment_status.Ferment_Output_1
  1961. FO2 = ferment_status.Ferment_Output_2
  1962. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  1963. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  1964. return render_template('ferment_auto.html', title="[測試] 發酵自動化", **locals())
  1965. else:
  1966. return render_template('sign_in.html')
  1967. @main.route('/fermentDEMO_auto_status', methods=['GET', 'POST'])
  1968. def fermentDEMO_auto_status():
  1969. info = request.args.to_dict()
  1970. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  1971. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  1972. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  1973. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  1974. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  1975. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  1976. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  1977. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  1978. Ferment_btn = True
  1979. # 從資料庫資料表中取得最新狀態
  1980. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  1981. FI1 = ferment_status.Ferment_Input_1 # FI1 = 'FI_OutputtingBean'
  1982. FI2 = ferment_status.Ferment_Input_2
  1983. F1 = ferment_status.Ferment_Tank_1
  1984. F2 = ferment_status.Ferment_Tank_2
  1985. F3 = ferment_status.Ferment_Tank_3
  1986. F4 = ferment_status.Ferment_Tank_4
  1987. F5 = ferment_status.Ferment_Tank_5
  1988. F6 = ferment_status.Ferment_Tank_6
  1989. F7 = ferment_status.Ferment_Tank_7
  1990. F8 = ferment_status.Ferment_Tank_8
  1991. F9 = ferment_status.Ferment_Tank_9
  1992. F10 = ferment_status.Ferment_Tank_10
  1993. F11 = ferment_status.Ferment_Tank_11
  1994. F12 = ferment_status.Ferment_Tank_12
  1995. FO1 = ferment_status.Ferment_Output_1
  1996. FO2 = ferment_status.Ferment_Output_2
  1997. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  1998. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  1999. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2000. Ferment_Input_bean_empty = 2
  2001. Ferment_Tank_bean_empty = 2
  2002. Ferment_Output_bean_empty = 2
  2003. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  2004. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  2005. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  2006. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  2007. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  2008. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  2009. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  2010. FI_UP_UltraSoniclist = []
  2011. for i in range(1, 3, 1):
  2012. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2013. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  2014. UltraSonic = float(input_UltraSonic.UltraSonic)
  2015. FI_UP_UltraSoniclist.append(UltraSonic)
  2016. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  2017. F_UP_UltraSoniclist = []
  2018. for i in range(1, 7, 1):
  2019. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2020. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  2021. F_UP_UltraSoniclist.append(UltraSonic)
  2022. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  2023. FO_UP_UltraSoniclist = []
  2024. for i in range(1, 3, 1):
  2025. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  2026. UltraSonic = float(output_UltraSonic.UltraSonic)
  2027. FO_UP_UltraSoniclist.append(UltraSonic)
  2028. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  2029. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  2030. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  2031. F_UP_tank_WaterLevel = []
  2032. for i in range(1, 7, 1):
  2033. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2034. WaterLevel = float(tank_WaterLevel.WaterLevel)
  2035. F_UP_tank_WaterLevel.append(WaterLevel)
  2036. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  2037. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  2038. # -- 取得發酵桶槽 F1~F6 pH -------------
  2039. F_UP_tank_PH = []
  2040. for i in range(1, 7, 1):
  2041. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2042. PH = float(tank_PH.PH)
  2043. F_UP_tank_PH.append(PH)
  2044. print('F_UP_tank_PH: ', F_UP_tank_PH)
  2045. # -- 取得發酵桶槽 F1~F6 pH -------------
  2046. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2047. F_UP_tank_SHT11_Temp = []
  2048. for i in range(1, 7, 1):
  2049. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2050. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2051. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  2052. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  2053. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2054. # ----- 發酵排程動作 start ------------------------------------------------------------------
  2055. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2056. def FInputtingBean_TO_FInputtingBeanFinish(tid): # 1108 [測試] 入豆後直接出豆
  2057. # [致動器] 蝴蝶閥 OFF
  2058. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2059. print('data: ', data)
  2060. # mqtt_f(data)
  2061. # [致動器] 真空吸料機 OFF
  2062. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2063. print('data: ', data)
  2064. # mqtt_f(data)
  2065. # [致動器] 馬達 0
  2066. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2067. print('data: ', data)
  2068. # mqtt_f(data)
  2069. # [致動器] 入料三通閥 ON排氣
  2070. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2071. print('data: ', data)
  2072. # mqtt_f(data)
  2073. # print('------- ', tid,' 狀態更新:入料完成 -------')
  2074. print('------- ', tid,' 狀態更新:可出豆 -------')
  2075. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2076. def FInputtingBean_AND_notfilled(tid):
  2077. # [致動器] 蝴蝶閥 OFF
  2078. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2079. print('data: ', data)
  2080. # mqtt_f(data)
  2081. # [致動器] 入料三通閥 OFF入豆
  2082. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2083. print('data: ', data)
  2084. # mqtt_f(data)
  2085. # [致動器] 真空吸料機 ON
  2086. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2087. print('data: ', data)
  2088. # mqtt_f(data)
  2089. timer = time.time()
  2090. while True:
  2091. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  2092. # [致動器] 入料真空吸料機 OFF
  2093. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2094. print('data: ', data)
  2095. # mqtt_f(data)
  2096. timer = time.time()
  2097. break
  2098. while True:
  2099. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  2100. break
  2101. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  2102. def FInputtingBean_TO_FInputtingBeanPause(tid):
  2103. # [致動器] 蝴蝶閥 OFF
  2104. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2105. print('data: ', data)
  2106. # mqtt_f(data)
  2107. # [致動器] 真空吸料機 OFF
  2108. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2109. print('data: ', data)
  2110. # mqtt_f(data)
  2111. # [致動器] 入料三通閥 OFF入豆
  2112. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2113. print('data: ', data)
  2114. # mqtt_f(data)
  2115. # [致動器] 馬達 0
  2116. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2117. print('data: ', data)
  2118. # mqtt_f(data)
  2119. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  2120. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  2121. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  2122. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  2123. # [致動器] 入料三通閥 OFF入豆
  2124. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2125. print('data: ', data)
  2126. # mqtt_f(data)
  2127. # [致動器] 馬達 5
  2128. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2129. print('data: ', data)
  2130. # mqtt_f(data)
  2131. print('------- ', tid, ' 狀態更新:入料中 -------')
  2132. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  2133. def FWaiting_TO_FInputtingBean(tid):
  2134. # [致動器] 蝴蝶閥 OFF
  2135. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2136. print('data: ', data)
  2137. # mqtt_f(data)
  2138. # [致動器] 入料三通閥 OFF入豆
  2139. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2140. print('data: ', data)
  2141. # mqtt_f(data)
  2142. # [致動器] 馬達 5
  2143. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2144. print('data: ', data)
  2145. # mqtt_f(data)
  2146. print('------- ', tid, ' 狀態更新:入料中 -------')
  2147. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2148. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  2149. print('------- ', tid,' 狀態更新:入水中 -------')
  2150. # # [致動器] 浮選三通閥 ON
  2151. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2152. # print('data: ', data)
  2153. # # # mqtt_f(data)
  2154. # if (F_UP_tank_WaterLevel[sn] == 0):
  2155. # # [致動器] 桶外進水電磁閥 ON
  2156. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  2157. # print('data: ', data)
  2158. # # mqtt_f(data)
  2159. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  2160. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  2161. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  2162. print('data: ', data)
  2163. # mqtt_f(data)
  2164. # elif FermentUp_InputtingWater_number == 1:
  2165. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2166. def FInputtingWater_TO_FFermenting(tid):
  2167. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  2168. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  2169. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2170. # print('data: ', data)
  2171. # # mqtt_f(data)
  2172. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2173. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2174. print('data: ', data)
  2175. # mqtt_f(data)
  2176. print('------- ', tid, ' 狀態更新:發酵中 -------')
  2177. # [致動器] 馬達 (指定轉速)
  2178. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  2179. print('data: ', data)
  2180. # mqtt_f(data)
  2181. # [致動器] 溫控開關 ON
  2182. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  2183. # print('data: ', data)
  2184. # # mqtt_f(data)
  2185. # [致動器] 設定溫度、持溫時間
  2186. # [致動器] 加熱器 1 ON
  2187. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  2188. # print('data: ', data)
  2189. # mqtt_f(data)
  2190. # [致動器] 加熱器 2 ON
  2191. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  2192. # print('data: ', data)
  2193. # mqtt_f(data)
  2194. # # [致動器] 雙核薄膜泵 水質檢測 ON
  2195. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  2196. # print('data: ', data)
  2197. # # mqtt_f(data)
  2198. # TODO 增加發酵條件等
  2199. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  2200. def FInputtingWater_AND_WaterLevel1(tid):
  2201. # # [致動器] 桶外進水電磁閥 OFF
  2202. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2203. # print('data: ', data)
  2204. # # mqtt_f(data)
  2205. pass
  2206. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  2207. def FInputtingWater_AND_tankwaterfilled(tid):
  2208. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2209. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2210. print('data: ', data)
  2211. # mqtt_f(data)
  2212. # else
  2213. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  2214. def FFermenting_TO_FOutputtingBean(tid):
  2215. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  2216. timer = time.time()
  2217. while True:
  2218. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  2219. # [致動器] 外桶浮選三通閥 OFF
  2220. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2221. print('data: ', data)
  2222. # mqtt_f(data)
  2223. # [致動器] 馬達 0
  2224. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2225. print('data: ', data)
  2226. # mqtt_f(data)
  2227. # [致動器] 設定溫度 0
  2228. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2229. # print('data: ', data)
  2230. # # mqtt_f(data)
  2231. # [致動器] 溫控開關 OFF
  2232. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2233. # print('data: ', data)
  2234. # # mqtt_f(data)
  2235. # [致動器] 加熱器 1 OFF
  2236. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2237. print('data: ', data)
  2238. # mqtt_f(data)
  2239. # [致動器] 加熱器 2 OFF
  2240. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2241. print('data: ', data)
  2242. # mqtt_f(data)
  2243. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  2244. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2245. # print('data: ', data)
  2246. # # mqtt_f(data)
  2247. # TODO 增加發酵條件等
  2248. break
  2249. # [致動器] 廢水排水閥 (桶內) ON
  2250. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2251. print('data: ', data)
  2252. # mqtt_f(data)
  2253. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2254. timer = time.time()
  2255. while True:
  2256. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2257. # [致動器] 廢水排水閥 (桶內) OFF
  2258. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2259. print('data: ', data)
  2260. # mqtt_f(data)
  2261. break
  2262. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2263. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2264. def FOutputtingBean_TO_FWaiting(tid):
  2265. # [致動器] F1 蝴蝶閥 ON
  2266. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  2267. print('data: ', data)
  2268. # mqtt_f(data)
  2269. # ----- 發酵排程動作 end ------------------------------------------------------------------
  2270. # [介面] 若啟用 發酵 狀態
  2271. if Ferment_btn:
  2272. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  2273. # 若 F1~F6 桶槽中有一個桶槽入豆中
  2274. if FermentUp_InputtingBean_number == 1:
  2275. # 若 F1 桶槽為入豆中
  2276. if F1 == 'F_InputtingBean':
  2277. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2278. FInputtingBean_TO_FInputtingBeanFinish("F1")
  2279. # F1 = 'F_InputtingBean_Finish'
  2280. F1 = 'F_OutputtingBean'
  2281. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2282. FInputtingBean_AND_notfilled("F1")
  2283. elif FI1 != 'FI_OutputtingBean':
  2284. FInputtingBean_TO_FInputtingBeanPause("F1")
  2285. F1 = 'F_InputtingBean_Pause'
  2286. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  2287. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  2288. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  2289. if F1 == 'F_InputtingBean_Pause':
  2290. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  2291. F1 = 'F_InputtingBean'
  2292. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  2293. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  2294. if F1 == 'F_Waiting':
  2295. FWaiting_TO_FInputtingBean("F1")
  2296. F1 = 'F_InputtingBean'
  2297. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  2298. elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2299. if F1 == 'F_InputtingBean_Finish':
  2300. F1 = 'F_InputtingWater'
  2301. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  2302. elif FermentUp_InputtingWater_number == 1:
  2303. if F1 == 'F_InputtingWater':
  2304. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2305. F1 = 'F_Fermenting'
  2306. FInputtingWater_TO_FFermenting("F1")
  2307. elif (F_UP_tank_WaterLevel[0] == 1):
  2308. FInputtingWater_AND_WaterLevel1("F1")
  2309. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2310. FInputtingWater_AND_tankwaterfilled("F1")
  2311. else:
  2312. if F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp:
  2313. FFermenting_TO_FOutputtingBean("F1")
  2314. F1 = 'F_OutputtingBean'
  2315. # 將可出豆桶槽賦值
  2316. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  2317. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  2318. # TODO 發酵次數計算、消毒次數、校正
  2319. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2320. if FOutputtingBean_Tank == 'F1':
  2321. FOutputtingBean_TO_FWaiting('F1')
  2322. FOutputtingBean_Tank = ''
  2323. F1 = 'F_Waiting'
  2324. print('------- F1 狀態更新:空桶等待 -------')
  2325. # 避免桶槽可出豆時未賦值
  2326. if FOutputtingBean_Tank == '':
  2327. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  2328. # 若桶槽 F1~F6 為清洗中
  2329. if F1 == 'F_Cleaning':
  2330. # FCleaning("F1")
  2331. F1 = 'F_Waiting'
  2332. print('------- F1 狀態更新:空桶等待 -------')
  2333. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  2334. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  2335. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  2336. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  2337. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  2338. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  2339. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  2340. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  2341. else:
  2342. # [介面] 若未啟用 發酵 狀態
  2343. print('未啟用發酵流程')
  2344. # ----- 將狀態寫入資料庫 ------------------------------
  2345. # 獲取文本框的值並賦值給user實體對象
  2346. F_status = ferment_container_status()
  2347. F_status.Ferment_Input_1 = FI1
  2348. F_status.Ferment_Input_2 = FI2
  2349. F_status.Ferment_Tank_1 = F1
  2350. F_status.Ferment_Tank_2 = F2
  2351. F_status.Ferment_Tank_3 = F3
  2352. F_status.Ferment_Tank_4 = F4
  2353. F_status.Ferment_Tank_5 = F5
  2354. F_status.Ferment_Tank_6 = F6
  2355. F_status.Ferment_Tank_7 = F7
  2356. F_status.Ferment_Tank_8 = F8
  2357. F_status.Ferment_Tank_9 = F9
  2358. F_status.Ferment_Tank_10 = F10
  2359. F_status.Ferment_Tank_11 = F11
  2360. F_status.Ferment_Tank_12 = F12
  2361. F_status.Ferment_Output_1 = FO1
  2362. F_status.Ferment_Output_2 = FO2
  2363. #將數據保存進資料庫
  2364. db.session.add(F_status)
  2365. # 手動提交
  2366. db.session.commit()
  2367. # ----- 將狀態寫入資料庫 ------------------------------
  2368. return jsonify({"Ferment_Tank_1":F1,
  2369. "Ferment_Tank_2":F2
  2370. })
  2371. @main.route('/ferment_auto_status', methods=['GET', 'POST'])
  2372. def ferment_auto_test():
  2373. info = request.args.to_dict()
  2374. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2375. Ferment_Input_bean_empty = 2
  2376. Ferment_Tank_bean_empty = 2
  2377. Ferment_Output_bean_empty = 2
  2378. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  2379. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  2380. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  2381. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  2382. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  2383. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  2384. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  2385. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  2386. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  2387. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  2388. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  2389. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  2390. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  2391. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  2392. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  2393. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  2394. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  2395. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  2396. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  2397. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  2398. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  2399. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  2400. Ferment_cb_vacuum = info['Ferment_cb_vacuum'] # 'true' 'false'
  2401. Ferment_cb_vacuum_time = float(info['Ferment_cb_vacuum_time'])
  2402. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  2403. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  2404. # 從資料庫資料表中取得最新狀態
  2405. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2406. FI1 = ferment_status.Ferment_Input_1
  2407. FI2 = ferment_status.Ferment_Input_2
  2408. F1 = ferment_status.Ferment_Tank_1
  2409. F2 = ferment_status.Ferment_Tank_2
  2410. F3 = ferment_status.Ferment_Tank_3
  2411. F4 = ferment_status.Ferment_Tank_4
  2412. F5 = ferment_status.Ferment_Tank_5
  2413. F6 = ferment_status.Ferment_Tank_6
  2414. F7 = ferment_status.Ferment_Tank_7
  2415. F8 = ferment_status.Ferment_Tank_8
  2416. F9 = ferment_status.Ferment_Tank_9
  2417. F10 = ferment_status.Ferment_Tank_10
  2418. F11 = ferment_status.Ferment_Tank_11
  2419. F12 = ferment_status.Ferment_Tank_12
  2420. FO1 = ferment_status.Ferment_Output_1
  2421. FO2 = ferment_status.Ferment_Output_2
  2422. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2423. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  2424. PO2 = clean_status.Peel_Output_2
  2425. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  2426. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  2427. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  2428. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  2429. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  2430. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  2431. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  2432. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  2433. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  2434. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  2435. FI_UP_UltraSoniclist = []
  2436. for i in range(1, 3, 1):
  2437. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2438. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  2439. UltraSonic = float(input_UltraSonic.UltraSonic)
  2440. FI_UP_UltraSoniclist.append(UltraSonic)
  2441. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  2442. F_UP_UltraSoniclist = []
  2443. for i in range(1, 7, 1):
  2444. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2445. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  2446. F_UP_UltraSoniclist.append(UltraSonic)
  2447. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  2448. FO_UP_UltraSoniclist = []
  2449. for i in range(1, 3, 1):
  2450. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  2451. UltraSonic = float(output_UltraSonic.UltraSonic)
  2452. FO_UP_UltraSoniclist.append(UltraSonic)
  2453. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  2454. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  2455. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  2456. F_UP_tank_WaterLevel = []
  2457. for i in range(1, 7, 1):
  2458. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2459. WaterLevel = float(tank_WaterLevel.WaterLevel)
  2460. F_UP_tank_WaterLevel.append(WaterLevel)
  2461. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  2462. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  2463. # -- 取得發酵桶槽 F1~F6 pH -------------
  2464. F_UP_tank_PH = []
  2465. for i in range(1, 7, 1):
  2466. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2467. PH = float(tank_PH.PH)
  2468. F_UP_tank_PH.append(PH)
  2469. print('F_UP_tank_PH: ', F_UP_tank_PH)
  2470. # -- 取得發酵桶槽 F1~F6 pH -------------
  2471. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2472. F_UP_tank_SHT11_Temp = []
  2473. for i in range(1, 7, 1):
  2474. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2475. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2476. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  2477. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  2478. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2479. # ----- 發酵排程動作 start ------------------------------------------------------------------
  2480. # FI1 == 'FI_InputtingBean' AND if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  2481. def FIInputtingBean_filled(tid):
  2482. # [致動器] 入料真空吸料機 OFF
  2483. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  2484. print('data: ', data)
  2485. # mqtt_f(data)
  2486. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2487. # FI1 == 'FI_InputtingBean' AND elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  2488. def FIInputtingBean_AND_notfilled(tid):
  2489. # [致動器] 入料真空吸料機 ON
  2490. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "on" }
  2491. print('data: ', data)
  2492. # mqtt_f(data)
  2493. # 暫停 (指定吸料時間) 秒
  2494. time.sleep(Ferment_Input_vacuumON_time)
  2495. # [致動器] 入料真空吸料機 OFF
  2496. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  2497. print('data: ', data)
  2498. # mqtt_f(data)
  2499. # 暫停 (指定放料時間) 秒
  2500. time.sleep(Ferment_Input_vacuumOFF_time)
  2501. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2502. def FInputtingBean_TO_FInputtingBeanFinish(tid):
  2503. # [致動器] 真空吸料機 OFF
  2504. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2505. print('data: ', data)
  2506. # mqtt_f(data)
  2507. # [致動器] 馬達 0
  2508. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2509. print('data: ', data)
  2510. # mqtt_f(data)
  2511. # [致動器] 入料三通閥 ON排氣
  2512. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2513. print('data: ', data)
  2514. # mqtt_f(data)
  2515. print('------- ', tid,' 狀態更新:入料完成 -------')
  2516. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2517. def FInputtingBean_AND_notfilled(tid):
  2518. # [致動器] 入料三通閥 OFF入豆
  2519. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2520. print('data: ', data)
  2521. # mqtt_f(data)
  2522. # [致動器] 真空吸料機 ON
  2523. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2524. print('data: ', data)
  2525. # mqtt_f(data)
  2526. # 暫停 (指定吸料時間) 秒
  2527. time.sleep(Ferment_Tank_vacuumON_time)
  2528. # [致動器] 入料真空吸料機 OFF
  2529. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2530. print('data: ', data)
  2531. # mqtt_f(data)
  2532. # 暫停 (指定吸料時間) 秒
  2533. time.sleep(Ferment_Tank_vacuumOFF_time)
  2534. # # [致動器] 真空吸料機 ON
  2535. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2536. # print('data: ', data)
  2537. # # mqtt_f(data)
  2538. # timer = time.time()
  2539. # while True:
  2540. # if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  2541. # # [致動器] 入料真空吸料機 OFF
  2542. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2543. # print('data: ', data)
  2544. # # mqtt_f(data)
  2545. # timer = time.time()
  2546. # break
  2547. # while True:
  2548. # if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  2549. # break
  2550. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  2551. def FInputtingBean_TO_FInputtingBeanPause(tid):
  2552. # [致動器] 真空吸料機 OFF
  2553. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2554. print('data: ', data)
  2555. # mqtt_f(data)
  2556. # [致動器] 入料三通閥 OFF入豆
  2557. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2558. print('data: ', data)
  2559. # mqtt_f(data)
  2560. # [致動器] 馬達 0
  2561. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2562. print('data: ', data)
  2563. # mqtt_f(data)
  2564. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  2565. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  2566. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  2567. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  2568. # [致動器] 入料三通閥 OFF入豆
  2569. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2570. print('data: ', data)
  2571. # mqtt_f(data)
  2572. # [致動器] 馬達 5
  2573. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2574. print('data: ', data)
  2575. # mqtt_f(data)
  2576. print('------- ', tid, ' 狀態更新:入料中 -------')
  2577. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  2578. def FWaiting_TO_FInputtingBean(tid):
  2579. # [致動器] 入料三通閥 OFF入豆
  2580. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2581. print('data: ', data)
  2582. # mqtt_f(data)
  2583. # [致動器] 馬達 5
  2584. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2585. print('data: ', data)
  2586. # mqtt_f(data)
  2587. print('------- ', tid, ' 狀態更新:入料中 -------')
  2588. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2589. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  2590. print('------- ', tid,' 狀態更新:入水中 -------')
  2591. # [致動器] 浮選三通閥 ON
  2592. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2593. print('data: ', data)
  2594. # mqtt_f(data)
  2595. if (F_UP_tank_WaterLevel[sn] == 0):
  2596. # [致動器] 桶外進水電磁閥 ON
  2597. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  2598. print('data: ', data)
  2599. # mqtt_f(data)
  2600. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  2601. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  2602. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  2603. print('data: ', data)
  2604. # mqtt_f(data)
  2605. # elif FermentUp_InputtingWater_number == 1:
  2606. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2607. def FInputtingWater_TO_FFermenting(tid):
  2608. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  2609. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  2610. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2611. print('data: ', data)
  2612. # mqtt_f(data)
  2613. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2614. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2615. print('data: ', data)
  2616. # mqtt_f(data)
  2617. print('------- ', tid, ' 狀態更新:發酵中 -------')
  2618. # 若勾選 發酵時桶內抽真空?
  2619. if Ferment_cb_vacuum == 'true':
  2620. # [致動器] 入料三通閥 ON排氣
  2621. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2622. print('data: ', data)
  2623. # mqtt_f(data)
  2624. # [致動器] 外桶浮選三通閥 OFF
  2625. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2626. print('data: ', data)
  2627. # mqtt_f(data)
  2628. # [致動器] 真空吸料機 ON
  2629. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2630. print('data: ', data)
  2631. # mqtt_f(data)
  2632. # 暫停 (桶內抽氣時間) 秒
  2633. print(tid, '真空發酵, 桶槽抽氣 ' , Ferment_cb_vacuum_time, ' 秒')
  2634. time.sleep(Ferment_cb_vacuum_time)
  2635. # timer = time.time()
  2636. # while True:
  2637. # if (time.time() - timer) > Ferment_cb_vacuum_time:
  2638. # # [致動器] 入料真空吸料機 OFF
  2639. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2640. # print('data: ', data)
  2641. # # mqtt_f(data)
  2642. # break
  2643. # [致動器] 馬達 (指定轉速)
  2644. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  2645. print('data: ', data)
  2646. # mqtt_f(data)
  2647. # [致動器] 溫控開關 ON
  2648. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  2649. # print('data: ', data)
  2650. # # mqtt_f(data)
  2651. # [致動器] 設定溫度、持溫時間
  2652. # [致動器] 加熱器 1 ON
  2653. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  2654. print('data: ', data)
  2655. # mqtt_f(data)
  2656. # [致動器] 加熱器 2 ON
  2657. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  2658. print('data: ', data)
  2659. # mqtt_f(data)
  2660. # [致動器] 雙核薄膜泵 水質檢測 ON
  2661. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  2662. print('data: ', data)
  2663. # mqtt_f(data)
  2664. # TODO 增加發酵條件等
  2665. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  2666. def FInputtingWater_AND_WaterLevel1(tid):
  2667. # [致動器] 桶外進水電磁閥 OFF
  2668. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2669. print('data: ', data)
  2670. # mqtt_f(data)
  2671. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  2672. def FInputtingWater_AND_tankwaterfilled(tid):
  2673. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2674. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2675. print('data: ', data)
  2676. # mqtt_f(data)
  2677. # else
  2678. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  2679. def FFermenting_TO_FOutputtingBean(tid):
  2680. # 暫停 (桶內抽氣時間) 秒
  2681. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  2682. time.sleep(Ferment_Tank_fermenting_time)
  2683. # [致動器] 外桶浮選三通閥 OFF
  2684. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2685. print('data: ', data)
  2686. # mqtt_f(data)
  2687. # [致動器] 馬達 0
  2688. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2689. print('data: ', data)
  2690. # mqtt_f(data)
  2691. # [致動器] 設定溫度 0
  2692. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2693. print('data: ', data)
  2694. # mqtt_f(data)
  2695. # [致動器] 溫控開關 OFF
  2696. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2697. # print('data: ', data)
  2698. # # mqtt_f(data)
  2699. # [致動器] 加熱器 1 OFF
  2700. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2701. print('data: ', data)
  2702. # mqtt_f(data)
  2703. # [致動器] 加熱器 2 OFF
  2704. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2705. print('data: ', data)
  2706. # mqtt_f(data)
  2707. # [致動器] 雙核薄膜泵 水質檢測 OFF
  2708. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2709. print('data: ', data)
  2710. # mqtt_f(data)
  2711. # timer = time.time()
  2712. # while True:
  2713. # if (time.time() - timer) > Ferment_Tank_fermenting_time :
  2714. # # [致動器] 外桶浮選三通閥 OFF
  2715. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2716. # print('data: ', data)
  2717. # # mqtt_f(data)
  2718. # # [致動器] 馬達 0
  2719. # data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2720. # print('data: ', data)
  2721. # # mqtt_f(data)
  2722. # # [致動器] 設定溫度 0
  2723. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2724. # print('data: ', data)
  2725. # # mqtt_f(data)
  2726. # # [致動器] 溫控開關 OFF
  2727. # # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2728. # # print('data: ', data)
  2729. # # # mqtt_f(data)
  2730. # # [致動器] 加熱器 1 OFF
  2731. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2732. # print('data: ', data)
  2733. # # mqtt_f(data)
  2734. # # [致動器] 加熱器 2 OFF
  2735. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2736. # print('data: ', data)
  2737. # # mqtt_f(data)
  2738. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  2739. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2740. # print('data: ', data)
  2741. # # mqtt_f(data)
  2742. # # TODO 增加發酵條件等
  2743. # break
  2744. # [致動器] 廢水排水閥 (桶內) ON
  2745. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2746. print('data: ', data)
  2747. # mqtt_f(data)
  2748. # 暫停 (桶內抽氣時間) 秒
  2749. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2750. time.sleep(Ferment_Tank_WaterOut_time)
  2751. # [致動器] 廢水排水閥 (桶內) OFF
  2752. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2753. print('data: ', data)
  2754. # mqtt_f(data)
  2755. # timer = time.time()
  2756. # while True:
  2757. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2758. # # [致動器] 廢水排水閥 (桶內) OFF
  2759. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2760. # print('data: ', data)
  2761. # # mqtt_f(data)
  2762. # break
  2763. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2764. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2765. def FOutputtingBean_TO_FWaiting(tid):
  2766. # [致動器] F1 蝴蝶閥 ON
  2767. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  2768. print('data: ', data)
  2769. # mqtt_f(data)
  2770. # F_Cleaning
  2771. def FCleaning(tid):
  2772. # [致動器] 浮選三通閥 OFF
  2773. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2774. print('data: ', data)
  2775. # mqtt_f(data)
  2776. # [致動器] 逆洗雙核薄膜泵電磁閥 ON
  2777. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "on" }
  2778. print('data: ', data)
  2779. # mqtt_f(data)
  2780. # [致動器] 馬達 10
  2781. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  2782. print('data: ', data)
  2783. # mqtt_f(data)
  2784. # [致動器] 消毒電磁閥 ON
  2785. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  2786. print('data: ', data)
  2787. # mqtt_f(data)
  2788. # [致動器] 消毒抽水 Pump ON TODO
  2789. # 暫停 (消毒時間) 秒
  2790. print(tid, ' 桶內消毒 ', Ferment_Tank_Disinfect_time, ' 秒')
  2791. time.sleep(Ferment_Tank_Disinfect_time)
  2792. # [致動器] 消毒電磁閥 OFF
  2793. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2794. print('data: ', data)
  2795. # mqtt_f(data)
  2796. # timer = time.time()
  2797. # while True:
  2798. # if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  2799. # # [致動器] 消毒電磁閥 OFF
  2800. # data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2801. # print('data: ', data)
  2802. # # mqtt_f(data)
  2803. # break
  2804. # [致動器] 消毒抽水 Pump OFF TODO
  2805. # [致動器] 馬達 0
  2806. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2807. print('data: ', data)
  2808. # mqtt_f(data)
  2809. # [致動器] 浮選三通閥 ON
  2810. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2811. print('data: ', data)
  2812. # mqtt_f(data)
  2813. # [致動器] 逆洗雙核薄膜泵電磁閥 OFF
  2814. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "off" }
  2815. print('data: ', data)
  2816. # mqtt_f(data)
  2817. # [致動器] 消毒電磁閥 OFF
  2818. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2819. print('data: ', data)
  2820. # mqtt_f(data)
  2821. # [致動器] 廢水排水閥 (桶內) ON
  2822. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2823. print('data: ', data)
  2824. # mqtt_f(data)
  2825. print(tid, ' 桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2826. time.sleep(Ferment_Tank_WaterOut_time)
  2827. # [致動器] 廢水排水閥 (桶內) OFF
  2828. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2829. print('data: ', data)
  2830. # mqtt_f(data)
  2831. # timer = time.time()
  2832. # while True:
  2833. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2834. # # [致動器] 廢水排水閥 (桶內) OFF
  2835. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2836. # print('data: ', data)
  2837. # # mqtt_f(data)
  2838. # break
  2839. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  2840. # elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '': AND elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  2841. def FOInputtingBean_filled(tid):
  2842. # [致動器] 出料真空吸料機 ON
  2843. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  2844. print('data: ', data)
  2845. # mqtt_f(data)
  2846. # 暫停 (指定吸料時間) 秒
  2847. time.sleep(Ferment_Output_vacuumON_time)
  2848. # [致動器] 出料真空吸料機 OFF
  2849. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  2850. print('data: ', data)
  2851. # mqtt_f(data)
  2852. # 暫停 (指定放料時間) 秒
  2853. time.sleep(Ferment_Output_vacuumOFF_time)
  2854. # # [致動器] 出料真空吸料機 ON
  2855. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  2856. # print('data: ', data)
  2857. # # mqtt_f(data)
  2858. # timer = time.time()
  2859. # while True:
  2860. # if (time.time() - timer) > Ferment_Output_vacuumON_time:
  2861. # # [致動器] 出料真空吸料機 OFF
  2862. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  2863. # print('data: ', data)
  2864. # # mqtt_f(data)
  2865. # timer = time.time()
  2866. # break
  2867. # while True:
  2868. # if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  2869. # break
  2870. # ----- 發酵排程動作 end ------------------------------------------------------------------
  2871. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  2872. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  2873. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  2874. FI1 = 'FI_InputtingBean'
  2875. print('------- FI1 狀態更新:入豆中 -------')
  2876. # 入料儲豆槽入豆時
  2877. elif FI1 == 'FI_InputtingBean':
  2878. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  2879. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  2880. FIInputtingBean_filled("FI1")
  2881. FI1 = 'FI_OutputtingBean'
  2882. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  2883. elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  2884. FI1_thread = threading.Thread(target=FIInputtingBean_AND_notfilled, args=["FI1"])
  2885. FI1_thread.start()
  2886. # 桶槽內大於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為可出豆
  2887. elif (FI_UP_UltraSoniclist[0] > Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  2888. FI1 = 'FI_OutputtingBean'
  2889. print('------- FI1 狀態更新:可出豆 -------')
  2890. # 桶槽內小於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為空桶等待
  2891. elif (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  2892. FI1 = 'FI_Waiting'
  2893. print('------- FI1 狀態更新:空桶等待 -------')
  2894. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  2895. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  2896. FI1 = 'FI_Waiting'
  2897. print('------- FI1 狀態更新:空桶等待 -------')
  2898. # [介面] 若啟用 發酵 狀態
  2899. if Ferment_btn:
  2900. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  2901. # 若 F1~F6 桶槽中有一個桶槽入豆中
  2902. if FermentUp_InputtingBean_number == 1:
  2903. # 若 F1 桶槽為入豆中
  2904. if F1 == 'F_InputtingBean':
  2905. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2906. FInputtingBean_TO_FInputtingBeanFinish("F1")
  2907. F1 = 'F_InputtingBean_Finish'
  2908. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2909. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  2910. F1_thread.start()
  2911. elif FI1 != 'FI_OutputtingBean':
  2912. FInputtingBean_TO_FInputtingBeanPause("F1")
  2913. F1 = 'F_InputtingBean_Pause'
  2914. elif F2 == 'F_InputtingBean':
  2915. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  2916. FInputtingBean_TO_FInputtingBeanFinish("F2")
  2917. F2 = 'F_InputtingBean_Finish'
  2918. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  2919. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  2920. F2_thread.start()
  2921. elif FI1 != 'FI_OutputtingBean':
  2922. FInputtingBean_TO_FInputtingBeanPause("F2")
  2923. F2 = 'F_InputtingBean_Pause'
  2924. elif F3 == 'F_InputtingBean':
  2925. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  2926. FInputtingBean_TO_FInputtingBeanFinish("F3")
  2927. F3 = 'F_InputtingBean_Finish'
  2928. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  2929. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  2930. F3_thread.start()
  2931. elif FI1 != 'FI_OutputtingBean':
  2932. FInputtingBean_TO_FInputtingBeanPause("F3")
  2933. F3 = 'F_InputtingBean_Pause'
  2934. elif F4 == 'F_InputtingBean':
  2935. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  2936. FInputtingBean_TO_FInputtingBeanFinish("F4")
  2937. F4 = 'F_InputtingBean_Finish'
  2938. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  2939. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  2940. F4_thread.start()
  2941. elif FI1 != 'FI_OutputtingBean':
  2942. FInputtingBean_TO_FInputtingBeanPause("F4")
  2943. F4 = 'F_InputtingBean_Pause'
  2944. elif F5 == 'F_InputtingBean':
  2945. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  2946. FInputtingBean_TO_FInputtingBeanFinish("F5")
  2947. F5 = 'F_InputtingBean_Finish'
  2948. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  2949. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  2950. F5_thread.start()
  2951. elif FI1 != 'FI_OutputtingBean':
  2952. FInputtingBean_TO_FInputtingBeanPause("F5")
  2953. F5 = 'F_InputtingBean_Pause'
  2954. elif F6 == 'F_InputtingBean':
  2955. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  2956. FInputtingBean_TO_FInputtingBeanFinish("F6")
  2957. F6 = 'F_InputtingBean_Finish'
  2958. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  2959. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  2960. F6_thread.start()
  2961. elif FI1 != 'FI_OutputtingBean':
  2962. FInputtingBean_TO_FInputtingBeanPause("F6")
  2963. F6 = 'F_InputtingBean_Pause'
  2964. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  2965. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  2966. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  2967. if F1 == 'F_InputtingBean_Pause':
  2968. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  2969. F1 = 'F_InputtingBean'
  2970. elif F2 == 'F_InputtingBean_Pause':
  2971. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  2972. F2 = 'F_InputtingBean'
  2973. elif F3 == 'F_InputtingBean_Pause':
  2974. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  2975. F3 = 'F_InputtingBean'
  2976. elif F4 == 'F_InputtingBean_Pause':
  2977. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  2978. F4 = 'F_InputtingBean'
  2979. elif F5 == 'F_InputtingBean_Pause':
  2980. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  2981. F5 = 'F_InputtingBean'
  2982. elif F6 == 'F_InputtingBean_Pause':
  2983. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  2984. F6 = 'F_InputtingBean'
  2985. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料中, 則桶號小者優先入料
  2986. elif FermentUp_InputtingBean_number >= 2:
  2987. if F1 == 'F_InputtingBean':
  2988. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2989. FInputtingBean_TO_FInputtingBeanFinish("F1")
  2990. F1 = 'F_InputtingBean_Finish'
  2991. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2992. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  2993. F1_thread.start()
  2994. elif FI1 != 'FI_OutputtingBean':
  2995. FInputtingBean_TO_FInputtingBeanPause("F1")
  2996. F1 = 'F_InputtingBean_Pause'
  2997. elif F2 == 'F_InputtingBean':
  2998. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  2999. FInputtingBean_TO_FInputtingBeanFinish("F2")
  3000. F2 = 'F_InputtingBean_Finish'
  3001. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  3002. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  3003. F2_thread.start()
  3004. elif FI1 != 'FI_OutputtingBean':
  3005. FInputtingBean_TO_FInputtingBeanPause("F2")
  3006. F2 = 'F_InputtingBean_Pause'
  3007. elif F3 == 'F_InputtingBean':
  3008. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  3009. FInputtingBean_TO_FInputtingBeanFinish("F3")
  3010. F3 = 'F_InputtingBean_Finish'
  3011. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  3012. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  3013. F3_thread.start()
  3014. elif FI1 != 'FI_OutputtingBean':
  3015. FInputtingBean_TO_FInputtingBeanPause("F3")
  3016. F3 = 'F_InputtingBean_Pause'
  3017. elif F4 == 'F_InputtingBean':
  3018. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  3019. FInputtingBean_TO_FInputtingBeanFinish("F4")
  3020. F4 = 'F_InputtingBean_Finish'
  3021. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  3022. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  3023. F4_thread.start()
  3024. elif FI1 != 'FI_OutputtingBean':
  3025. FInputtingBean_TO_FInputtingBeanPause("F4")
  3026. F4 = 'F_InputtingBean_Pause'
  3027. elif F5 == 'F_InputtingBean':
  3028. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  3029. FInputtingBean_TO_FInputtingBeanFinish("F5")
  3030. F5 = 'F_InputtingBean_Finish'
  3031. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  3032. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  3033. F5_thread.start()
  3034. elif FI1 != 'FI_OutputtingBean':
  3035. FInputtingBean_TO_FInputtingBeanPause("F5")
  3036. F5 = 'F_InputtingBean_Pause'
  3037. elif F6 == 'F_InputtingBean':
  3038. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  3039. FInputtingBean_TO_FInputtingBeanFinish("F6")
  3040. F6 = 'F_InputtingBean_Finish'
  3041. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  3042. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  3043. F6_thread.start()
  3044. elif FI1 != 'FI_OutputtingBean':
  3045. FInputtingBean_TO_FInputtingBeanPause("F6")
  3046. F6 = 'F_InputtingBean_Pause'
  3047. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料暫停中, 則桶號小者優先入料
  3048. elif FermentUp_InputtingBeanPause_number >= 2 and FI1 == 'FI_OutputtingBean':
  3049. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  3050. if F1 == 'F_InputtingBean_Pause':
  3051. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  3052. F1 = 'F_InputtingBean'
  3053. elif F2 == 'F_InputtingBean_Pause':
  3054. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  3055. F2 = 'F_InputtingBean'
  3056. elif F3 == 'F_InputtingBean_Pause':
  3057. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  3058. F3 = 'F_InputtingBean'
  3059. elif F4 == 'F_InputtingBean_Pause':
  3060. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  3061. F4 = 'F_InputtingBean'
  3062. elif F5 == 'F_InputtingBean_Pause':
  3063. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  3064. F5 = 'F_InputtingBean'
  3065. elif F6 == 'F_InputtingBean_Pause':
  3066. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  3067. F6 = 'F_InputtingBean'
  3068. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  3069. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  3070. if F1 == 'F_Waiting':
  3071. FWaiting_TO_FInputtingBean("F1")
  3072. F1 = 'F_InputtingBean'
  3073. elif F2 == 'F_Waiting':
  3074. FWaiting_TO_FInputtingBean("F2")
  3075. F2 = 'F_InputtingBean'
  3076. elif F3 == 'F_Waiting':
  3077. FWaiting_TO_FInputtingBean("F3")
  3078. F3 = 'F_InputtingBean'
  3079. elif F4 == 'F_Waiting':
  3080. FWaiting_TO_FInputtingBean("F4")
  3081. F4 = 'F_InputtingBean'
  3082. elif F5 == 'F_Waiting':
  3083. FWaiting_TO_FInputtingBean("F5")
  3084. F5 = 'F_InputtingBean'
  3085. elif F6 == 'F_Waiting':
  3086. FWaiting_TO_FInputtingBean("F6")
  3087. F6 = 'F_InputtingBean'
  3088. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  3089. if FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  3090. if F1 == 'F_InputtingBean_Finish':
  3091. F1 = 'F_InputtingWater'
  3092. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  3093. elif F2 == 'F_InputtingBean_Finish':
  3094. F2 = 'F_InputtingWater'
  3095. FInputtingBeanFinish_TO_FInputtingWater_UP("F2", 1)
  3096. elif F3 == 'F_InputtingBean_Finish':
  3097. F3 = 'F_InputtingWater'
  3098. FInputtingBeanFinish_TO_FInputtingWater_UP("F3", 2)
  3099. elif F4 == 'F_InputtingBean_Finish':
  3100. F4 = 'F_InputtingWater'
  3101. FInputtingBeanFinish_TO_FInputtingWater_UP("F4", 3)
  3102. elif F5 == 'F_InputtingBean_Finish':
  3103. F5 = 'F_InputtingWater'
  3104. FInputtingBeanFinish_TO_FInputtingWater_UP("F5", 4)
  3105. elif F6 == 'F_InputtingBean_Finish':
  3106. F6 = 'F_InputtingWater'
  3107. FInputtingBeanFinish_TO_FInputtingWater_UP("F6", 5)
  3108. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  3109. if FermentUp_InputtingWater_number == 1:
  3110. if F1 == 'F_InputtingWater':
  3111. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3112. F1 = 'F_Fermenting'
  3113. F1_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F1"])
  3114. F1_thread.start()
  3115. elif (F_UP_tank_WaterLevel[0] == 1):
  3116. FInputtingWater_AND_WaterLevel1("F1")
  3117. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3118. FInputtingWater_AND_tankwaterfilled("F1")
  3119. elif F2 == 'F_InputtingWater':
  3120. if (F_UP_tank_WaterLevel[1] == 1) and (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  3121. F2 = 'F_Fermenting'
  3122. F2_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F2"])
  3123. F2_thread.start()
  3124. elif (F_UP_tank_WaterLevel[1] == 1):
  3125. FInputtingWater_AND_WaterLevel1("F2")
  3126. elif (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  3127. FInputtingWater_AND_tankwaterfilled("F2")
  3128. elif F3 == 'F_InputtingWater':
  3129. if (F_UP_tank_WaterLevel[2] == 1) and (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  3130. F3 = 'F_Fermenting'
  3131. F3_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F3"])
  3132. F3_thread.start()
  3133. elif (F_UP_tank_WaterLevel[2] == 1):
  3134. FInputtingWater_AND_WaterLevel1("F3")
  3135. elif (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  3136. FInputtingWater_AND_tankwaterfilled("F3")
  3137. elif F4 == 'F_InputtingWater':
  3138. if (F_UP_tank_WaterLevel[3] == 1) and (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  3139. F4 = 'F_Fermenting'
  3140. F4_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F4"])
  3141. F4_thread.start()
  3142. elif (F_UP_tank_WaterLevel[3] == 1):
  3143. FInputtingWater_AND_WaterLevel1("F4")
  3144. elif (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  3145. FInputtingWater_AND_tankwaterfilled("F4")
  3146. elif F5 == 'F_InputtingWater':
  3147. if (F_UP_tank_WaterLevel[4] == 1) and (F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height):
  3148. F5 = 'F_Fermenting'
  3149. F5_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F5"])
  3150. F5_thread.start()
  3151. elif (F_UP_tank_WaterLevel[0] == 1):
  3152. FInputtingWater_AND_WaterLevel1("F5")
  3153. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3154. FInputtingWater_AND_tankwaterfilled("F5")
  3155. elif F6 == 'F_InputtingWater':
  3156. if (F_UP_tank_WaterLevel[5] == 1) and (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  3157. F6 = 'F_Fermenting'
  3158. F6_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F6"])
  3159. F6_thread.start()
  3160. elif (F_UP_tank_WaterLevel[5] == 1):
  3161. FInputtingWater_AND_WaterLevel1("F6")
  3162. elif (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  3163. FInputtingWater_AND_tankwaterfilled("F6")
  3164. else:
  3165. print("else ---------------------------- ")
  3166. if F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  3167. F1_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F1"])
  3168. F1_thread.start()
  3169. F1 = 'F_OutputtingBean'
  3170. # 將可出豆桶槽賦值
  3171. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  3172. if F2 == 'F_Fermenting':
  3173. F2_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F2"])
  3174. F2_thread.start()
  3175. F2 = 'F_OutputtingBean'
  3176. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F2'
  3177. if F3 == 'F_Fermenting':
  3178. F3_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F3"])
  3179. F3_thread.start()
  3180. F3 = 'F_OutputtingBean'
  3181. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F3'
  3182. if F4 == 'F_Fermenting':
  3183. F4_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F4"])
  3184. F4_thread.start()
  3185. F4 = 'F_OutputtingBean'
  3186. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F4'
  3187. if F5 == 'F_Fermenting':
  3188. F5_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F5"])
  3189. F5_thread.start()
  3190. F5 = 'F_OutputtingBean'
  3191. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F5'
  3192. if F6 == 'F_Fermenting':
  3193. F6_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F6"])
  3194. F6_thread.start()
  3195. F6 = 'F_OutputtingBean'
  3196. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F6'
  3197. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  3198. # TODO 發酵次數計算、消毒次數、校正
  3199. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  3200. if FOutputtingBean_Tank == 'F1':
  3201. FOutputtingBean_TO_FWaiting('F1')
  3202. FOutputtingBean_Tank = ''
  3203. if (FermentAuto_cleaning == 0): F1 = 'F_Waiting'
  3204. elif (FermentAuto_cleaning != 0): F1 = 'F_Cleaning'
  3205. if F2 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[1] <= Ferment_Tank_bean_empty):
  3206. if FOutputtingBean_Tank == 'F2':
  3207. FOutputtingBean_TO_FWaiting('F2')
  3208. FOutputtingBean_Tank = ''
  3209. if (FermentAuto_cleaning == 0): F2 = 'F_Waiting'
  3210. elif (FermentAuto_cleaning != 0): F2 = 'F_Cleaning'
  3211. if F3 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[2] <= Ferment_Tank_bean_empty):
  3212. if FOutputtingBean_Tank == 'F3':
  3213. FOutputtingBean_TO_FWaiting('F3')
  3214. FOutputtingBean_Tank = ''
  3215. if (FermentAuto_cleaning == 0): F3 = 'F_Waiting'
  3216. elif (FermentAuto_cleaning != 0): F3 = 'F_Cleaning'
  3217. if F4 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[3] <= Ferment_Tank_bean_empty):
  3218. if FOutputtingBean_Tank == 'F4':
  3219. FOutputtingBean_TO_FWaiting('F4')
  3220. FOutputtingBean_Tank = ''
  3221. if (FermentAuto_cleaning == 0): F4 = 'F_Waiting'
  3222. elif (FermentAuto_cleaning != 0): F4 = 'F_Cleaning'
  3223. if F5 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[4] <= Ferment_Tank_bean_empty):
  3224. if FOutputtingBean_Tank == 'F5':
  3225. FOutputtingBean_TO_FWaiting('F5')
  3226. FOutputtingBean_Tank = ''
  3227. if (FermentAuto_cleaning == 0): F5 = 'F_Waiting'
  3228. elif (FermentAuto_cleaning != 0): F5 = 'F_Cleaning'
  3229. if F6 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[5] <= Ferment_Tank_bean_empty):
  3230. if FOutputtingBean_Tank == 'F6':
  3231. FOutputtingBean_TO_FWaiting('F6')
  3232. FOutputtingBean_Tank = ''
  3233. if (FermentAuto_cleaning == 0): F6 = 'F_Waiting'
  3234. elif (FermentAuto_cleaning != 0): F6 = 'F_Cleaning'
  3235. # 避免桶槽可出豆時未賦值
  3236. if FOutputtingBean_Tank == '':
  3237. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  3238. elif F2 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F2'
  3239. elif F3 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F3'
  3240. elif F4 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F4'
  3241. elif F5 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F5'
  3242. elif F6 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F6'
  3243. # 若桶槽 F1~F6 為清洗中
  3244. if F1 == 'F_Cleaning':
  3245. F1_thread = threading.Thread(target=FCleaning, args=["F1"])
  3246. F1_thread.start()
  3247. F1 = 'F_Waiting'
  3248. if F2 == 'F_Cleaning':
  3249. F2_thread = threading.Thread(target=FCleaning, args=["F2"])
  3250. F2_thread.start()
  3251. F2 = 'F_Waiting'
  3252. if F3 == 'F_Cleaning':
  3253. F3_thread = threading.Thread(target=FCleaning, args=["F3"])
  3254. F3_thread.start()
  3255. F3 = 'F_Waiting'
  3256. if F4 == 'F_Cleaning':
  3257. F4_thread = threading.Thread(target=FCleaning, args=["F4"])
  3258. F4_thread.start()
  3259. F4 = 'F_Waiting'
  3260. if F5 == 'F_Cleaning':
  3261. F5_thread = threading.Thread(target=FCleaning, args=["F5"])
  3262. F5_thread.start()
  3263. F5 = 'F_Waiting'
  3264. if F6 == 'F_Cleaning':
  3265. F6_thread = threading.Thread(target=FCleaning, args=["F6"])
  3266. F6_thread.start()
  3267. F6 = 'F_Waiting'
  3268. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3269. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  3270. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  3271. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  3272. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  3273. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  3274. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  3275. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3276. else:
  3277. # [介面] 若未啟用 發酵 狀態
  3278. print('未啟用發酵流程')
  3279. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  3280. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  3281. # Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  3282. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  3283. if FO1 == 'FO_Waiting' and FOutputtingBean_Tank != '':
  3284. # 判斷要對應出料的桶槽為何, 設定成 FOutputtingBean_Tank = 'F1', 待出完料再把 FOutputtingBean_Tank = ''
  3285. FO1 = 'FO_InputtingBean'
  3286. print('------- ' + FOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  3287. print('------- FO1 狀態更新:入豆中 -------')
  3288. # [致動器] F1 蝴蝶閥 ON
  3289. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  3290. print('data: ', data)
  3291. # mqtt_f(data)
  3292. elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '':
  3293. if FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  3294. # [致動器] 出料真空吸料機 OFF
  3295. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  3296. print('data: ', data)
  3297. # mqtt_f(data)
  3298. # [致動器] F1 蝴蝶閥 OFF
  3299. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  3300. print('data: ', data)
  3301. # mqtt_f(data)
  3302. FO1 = 'FO_OutputtingBean'
  3303. print('------- FO1 狀態更新:出豆中 -------')
  3304. elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  3305. FO1_thread = threading.Thread(target=FOInputtingBean_filled, args=["FO1"])
  3306. FO1_thread.start()
  3307. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  3308. elif FOutputtingBean_Tank == '':
  3309. if FO_UP_UltraSoniclist[0] > Ferment_Output_bean_empty:
  3310. FO1 = 'FO_OutputtingBean'
  3311. print('------- FO1 狀態更新:可出豆 -------')
  3312. elif FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  3313. FO1 = 'FO_Waiting'
  3314. print('------- FO1 狀態更新:空桶等待 -------')
  3315. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  3316. FO1 = 'FO_Waiting'
  3317. print('------- FO1 狀態更新:空桶等待 -------')
  3318. # ----- 等待 thread 多執行緒執行完成 --------
  3319. # 若 FI1_thread 有被定義, 則執行 FI1_thread.join() 等待執行完成 (當入料儲豆槽入料時)
  3320. # 若 FI1_thread 有被定義, 會出現 UnboundLocalError: local variable 'FO1_thread' referenced before assignment 錯誤訊息
  3321. # (非入料儲豆槽入料時) 此時就不進行任何處理
  3322. try:
  3323. FI1_thread.join()
  3324. print("-- FI1_thread complete! --")
  3325. except UnboundLocalError:
  3326. pass
  3327. try:
  3328. F1_thread.join()
  3329. print("-- F1_thread complete! --")
  3330. except UnboundLocalError:
  3331. pass
  3332. try:
  3333. F2_thread.join()
  3334. print("-- F2_thread complete! --")
  3335. except UnboundLocalError:
  3336. pass
  3337. try:
  3338. F3_thread.join()
  3339. print("-- F3_thread complete! --")
  3340. except UnboundLocalError:
  3341. pass
  3342. try:
  3343. F4_thread.join()
  3344. print("-- F4_thread complete! --")
  3345. except UnboundLocalError:
  3346. pass
  3347. try:
  3348. F5_thread.join()
  3349. print("-- F5_thread complete! --")
  3350. except UnboundLocalError:
  3351. pass
  3352. try:
  3353. F6_thread.join()
  3354. print("-- F6_thread complete! --")
  3355. except UnboundLocalError:
  3356. pass
  3357. try:
  3358. FO1_thread.join()
  3359. print("-- FO1_thread complete! --")
  3360. except UnboundLocalError:
  3361. pass
  3362. # ----- 將狀態寫入資料庫 ------------------------------
  3363. # 獲取文本框的值並賦值給user實體對象
  3364. F_status = ferment_container_status()
  3365. F_status.Ferment_Input_1 = FI1
  3366. F_status.Ferment_Input_2 = FI2
  3367. F_status.Ferment_Tank_1 = F1
  3368. F_status.Ferment_Tank_2 = F2
  3369. F_status.Ferment_Tank_3 = F3
  3370. F_status.Ferment_Tank_4 = F4
  3371. F_status.Ferment_Tank_5 = F5
  3372. F_status.Ferment_Tank_6 = F6
  3373. F_status.Ferment_Tank_7 = F7
  3374. F_status.Ferment_Tank_8 = F8
  3375. F_status.Ferment_Tank_9 = F9
  3376. F_status.Ferment_Tank_10 = F10
  3377. F_status.Ferment_Tank_11 = F11
  3378. F_status.Ferment_Tank_12 = F12
  3379. F_status.Ferment_Output_1 = FO1
  3380. F_status.Ferment_Output_2 = FO2
  3381. #將數據保存進資料庫
  3382. db.session.add(F_status)
  3383. # 手動提交
  3384. db.session.commit()
  3385. # ----- 將狀態寫入資料庫 ------------------------------
  3386. return jsonify({"Peel_Output_1":PO1,
  3387. "Ferment_Input_1":FI1,
  3388. "Ferment_Tank_1":F1,
  3389. "Ferment_Tank_2":F2,
  3390. "Ferment_Tank_3":F3,
  3391. "Ferment_Tank_4":F4,
  3392. "Ferment_Tank_5":F5,
  3393. "Ferment_Tank_6":F6,
  3394. "Ferment_Output_1":FO1
  3395. })
  3396. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以下為原備份
  3397. @main.route('/ferment_auto_test_1026backup')
  3398. def ferment_auto_test_1026backup():
  3399. info = request.args.to_dict()
  3400. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  3401. Ferment_Input_bean_empty = 2
  3402. Ferment_Tank_bean_empty = 2
  3403. Ferment_Output_bean_empty = 2
  3404. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  3405. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  3406. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  3407. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  3408. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  3409. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  3410. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  3411. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  3412. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  3413. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  3414. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  3415. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  3416. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  3417. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  3418. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  3419. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  3420. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  3421. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  3422. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  3423. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  3424. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  3425. # print('發酵自動化_指定生豆高度: ', Ferment_Tank_bean_height)
  3426. # print('發酵自動化_發酵排程: ', FermentAuto_fermenting, type(FermentAuto_fermenting))
  3427. # print('發酵自動化_清洗排程: ', FermentAuto_cleaning, type(FermentAuto_cleaning))
  3428. # print('發酵自動化_校正 EC 排程: ', FermentAuto_calibratingEC, type(FermentAuto_calibratingEC))
  3429. # print('發酵自動化_校正攪拌棒排程: ', FermentAuto_calibratingSTIR, type(FermentAuto_calibratingSTIR))
  3430. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  3431. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  3432. # 從資料庫資料表中取得最新狀態
  3433. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  3434. FI1 = ferment_status.Ferment_Input_1
  3435. FI2 = ferment_status.Ferment_Input_2
  3436. F1 = ferment_status.Ferment_Tank_1
  3437. F2 = ferment_status.Ferment_Tank_2
  3438. F3 = ferment_status.Ferment_Tank_3
  3439. F4 = ferment_status.Ferment_Tank_4
  3440. F5 = ferment_status.Ferment_Tank_5
  3441. F6 = ferment_status.Ferment_Tank_6
  3442. F7 = ferment_status.Ferment_Tank_7
  3443. F8 = ferment_status.Ferment_Tank_8
  3444. F9 = ferment_status.Ferment_Tank_9
  3445. F10 = ferment_status.Ferment_Tank_10
  3446. F11 = ferment_status.Ferment_Tank_11
  3447. F12 = ferment_status.Ferment_Tank_12
  3448. FO1 = ferment_status.Ferment_Output_1
  3449. FO2 = ferment_status.Ferment_Output_2
  3450. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  3451. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  3452. PO2 = clean_status.Peel_Output_2
  3453. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  3454. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  3455. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  3456. # 目前發酵槽 F1~F6 正在入豆的桶槽數量 (應小於一桶)
  3457. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  3458. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  3459. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  3460. FI_UP_UltraSoniclist = []
  3461. for i in range(1, 3, 1):
  3462. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3463. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  3464. UltraSonic = float(input_UltraSonic.UltraSonic)
  3465. FI_UP_UltraSoniclist.append(UltraSonic)
  3466. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  3467. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  3468. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  3469. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  3470. FI1 = 'FI_InputtingBean'
  3471. print('------- FI1 狀態更新:入豆中 -------')
  3472. # [致動器] 入料真空吸料機 ON
  3473. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  3474. print('data: ', data)
  3475. # mqtt_f(data)
  3476. timer = time.time()
  3477. while True:
  3478. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  3479. # [致動器] 入料真空吸料機 OFF
  3480. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3481. print('data: ', data)
  3482. # mqtt_f(data)
  3483. timer = time.time()
  3484. break
  3485. while True:
  3486. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  3487. break
  3488. # 入料儲豆槽入豆時
  3489. elif FI1 == 'FI_InputtingBean':
  3490. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  3491. if (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  3492. # [致動器] 入料真空吸料機 ON
  3493. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  3494. print('data: ', data)
  3495. # mqtt_f(data)
  3496. timer = time.time()
  3497. while True:
  3498. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  3499. # [致動器] 入料真空吸料機 OFF
  3500. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3501. print('data: ', data)
  3502. # mqtt_f(data)
  3503. timer = time.time()
  3504. break
  3505. while True:
  3506. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  3507. break
  3508. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  3509. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  3510. FI1 = 'FI_OutputtingBean'
  3511. print('------- FI1 狀態更新:可出豆 -------')
  3512. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  3513. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  3514. FI1 = 'FI_Waiting'
  3515. print('------- FI1 狀態更新:空桶等待 -------')
  3516. # [1012 刪除, 避免混豆]若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  3517. # elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] < 40) and PO1 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3518. # FI1 = 'FI_InputtingBean'
  3519. # print('------- FI1 狀態更新:入豆中 -------')
  3520. # if FI2 == 'FI_Waiting' and PO2 == 'PO_OutputtingBean':
  3521. # FI2 = 'FI_InputtingBean'
  3522. # print('------- FI2 狀態更新:入豆中 -------')
  3523. # elif FI2 == 'FI_InputtingBean' and ((FI_UP_UltraSoniclist[1] >= 35) or (PO2 != 'PO_OutputtingBean')) :
  3524. # FI2 = 'FI_OutputtingBean'
  3525. # print('------- FI2 狀態更新:可出豆 -------')
  3526. # elif FI2 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[1] < 40) and PO2 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3527. # FI2 = 'FI_InputtingBean'
  3528. # print('------- FI2 狀態更新:入豆中 -------')
  3529. # ----- 發酵桶槽 F1~F6 入料暫停→入料判斷 ------------------------------
  3530. ### 移到入料
  3531. # ----- 發酵桶槽 F1~F6 等待→入料判斷 ------------------------------
  3532. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  3533. F_UP_UltraSoniclist = []
  3534. for i in range(1, 7, 1):
  3535. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3536. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  3537. F_UP_UltraSoniclist.append(UltraSonic)
  3538. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  3539. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  3540. # [介面] 若啟用 發酵 狀態
  3541. if Ferment_btn:
  3542. # 若入料儲豆槽可出料狀態
  3543. if FI1 == 'FI_OutputtingBean':
  3544. # 若 F1~F6 發酵桶槽為 入豆中, 繼續入豆, 當高度 > 指定生豆高度 時入豆完成
  3545. if F1 == 'F_InputtingBean':
  3546. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  3547. F1 = 'F_InputtingBean_Finish'
  3548. print('------- F1 狀態更新:入料完成 -------')
  3549. # [致動器] 入料三通閥 ON排氣
  3550. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  3551. print('data: ', data)
  3552. # mqtt_f(data)
  3553. # [致動器] 馬達 0
  3554. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3555. print('data: ', data)
  3556. # mqtt_f(data)
  3557. # [致動器] 真空吸料機 OFF
  3558. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3559. print('data: ', data)
  3560. # mqtt_f(data)
  3561. else:
  3562. # [致動器] 真空吸料機 ON
  3563. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3564. print('data: ', data)
  3565. # mqtt_f(data)
  3566. timer = time.time()
  3567. while True:
  3568. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3569. # [致動器] 入料真空吸料機 OFF
  3570. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3571. print('data: ', data)
  3572. # mqtt_f(data)
  3573. timer = time.time()
  3574. break
  3575. while True:
  3576. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3577. break
  3578. if F2 == 'F_InputtingBean' and (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  3579. F2 = 'F_InputtingBean_Finish'
  3580. print('------- F2 狀態更新:入料完成 -------')
  3581. if F3 == 'F_InputtingBean' and (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  3582. F3 = 'F_InputtingBean_Finish'
  3583. print('------- F3 狀態更新:入料完成 -------')
  3584. if F4 == 'F_InputtingBean' and (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  3585. F4 = 'F_InputtingBean_Finish'
  3586. print('------- F4 狀態更新:入料完成 -------')
  3587. if F5 == 'F_InputtingBean' and (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  3588. F5 = 'F_InputtingBean_Finish'
  3589. print('------- F5 狀態更新:入料完成 -------')
  3590. if F6 == 'F_InputtingBean' and (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  3591. F6 = 'F_InputtingBean_Finish'
  3592. print('------- F6 狀態更新:入料完成 -------')
  3593. # 若有兩個以上桶槽入料中, 則桶號最小者優先入料 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  3594. if FermentUp_InputtingBean_number == 1:
  3595. if F1 == 'F_InputtingBean':
  3596. # [致動器] 桶槽真空吸料機 ON
  3597. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3598. print('data: ', data)
  3599. # mqtt_f(data)
  3600. timer = time.time()
  3601. while True:
  3602. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3603. # [致動器] 桶槽真空吸料機 OFF
  3604. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3605. print('data: ', data)
  3606. # mqtt_f(data)
  3607. timer = time.time()
  3608. break
  3609. while True:
  3610. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3611. break
  3612. # else if F2 == ''...
  3613. # 若 F1~F6 發酵桶槽為 入豆暫停, 則狀態改為優先入豆 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  3614. elif FermentUp_InputtingBeanPause_number >= 1:
  3615. if F1 == 'F_InputtingBean_Pause':
  3616. F1 = 'F_InputtingBean'
  3617. print('------- F1 狀態更新:入料中 -------')
  3618. # [致動器] 桶槽真空吸料機 ON
  3619. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3620. print('data: ', data)
  3621. # mqtt_f(data)
  3622. timer = time.time()
  3623. while True:
  3624. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3625. # [致動器] 桶槽真空吸料機 OFF
  3626. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3627. print('data: ', data)
  3628. # mqtt_f(data)
  3629. timer = time.time()
  3630. break
  3631. while True:
  3632. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3633. break
  3634. elif F2 == 'F_InputtingBean_Pause':
  3635. F2 = 'F_InputtingBean'
  3636. print('------- F2 狀態更新:入料中 -------')
  3637. elif F3 == 'F_InputtingBean_Pause':
  3638. F3 = 'F_InputtingBean'
  3639. print('------- F3 狀態更新:入料中 -------')
  3640. elif F4 == 'F_InputtingBean_Pause':
  3641. F4 = 'F_InputtingBean'
  3642. print('------- F4 狀態更新:入料中 -------')
  3643. elif F5 == 'F_InputtingBean_Pause':
  3644. F5 = 'F_InputtingBean'
  3645. print('------- F5 狀態更新:入料中 -------')
  3646. elif F6 == 'F_InputtingBean_Pause':
  3647. F6 = 'F_InputtingBean'
  3648. print('------- F6 狀態更新:入料中 -------')
  3649. # 若 F1~F6 皆無入豆 無入豆暫停, 則桶號最小者開始入豆
  3650. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3651. if F1 == 'F_Waiting':
  3652. F1 = 'F_InputtingBean'
  3653. print('------- F1 狀態更新:入料中 -------')
  3654. # [致動器] 入料入料三通閥 OFF入豆
  3655. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "off" }
  3656. print('data: ', data)
  3657. # mqtt_f(data)
  3658. # [致動器] 馬達 5
  3659. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "5" }
  3660. print('data: ', data)
  3661. # mqtt_f(data)
  3662. # [致動器] 桶槽真空吸料機 ON
  3663. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3664. print('data: ', data)
  3665. # mqtt_f(data)
  3666. timer = time.time()
  3667. while True:
  3668. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3669. # [致動器] 桶槽真空吸料機 OFF
  3670. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3671. print('data: ', data)
  3672. # mqtt_f(data)
  3673. timer = time.time()
  3674. break
  3675. while True:
  3676. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3677. break
  3678. elif F2 == 'F_Waiting':
  3679. F2 = 'F_InputtingBean'
  3680. print('------- F2 狀態更新:入料中 -------')
  3681. elif F3 == 'F_Waiting':
  3682. F3 = 'F_InputtingBean'
  3683. print('------- F3 狀態更新:入料中 -------')
  3684. elif F4 == 'F_Waiting':
  3685. F4 = 'F_InputtingBean'
  3686. print('------- F4 狀態更新:入料中 -------')
  3687. elif F5 == 'F_Waiting':
  3688. F5 = 'F_InputtingBean'
  3689. print('------- F5 狀態更新:入料中 -------')
  3690. elif F6 == 'F_Waiting':
  3691. F6 = 'F_InputtingBean'
  3692. print('------- F6 狀態更新:入料中 -------')
  3693. # 若入料儲豆槽非可出豆, 且 F1~F6 其中有桶槽入料中, 若桶槽未滿則入料暫停
  3694. elif FI1 != 'FI_InputtingBean' and FermentUp_InputtingBean_number >= 1:
  3695. if F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height:
  3696. F1 = 'F_InputtingBean_Pause'
  3697. print('------- F1 狀態更新:入料暫停 -------')
  3698. # [致動器] 桶槽真空吸料機 OFF
  3699. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3700. print('data: ', data)
  3701. # mqtt_f(data)
  3702. elif F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height:
  3703. F1 = 'F_InputtingBean_Finish'
  3704. print('------- F1 狀態更新:入料完成 -------')
  3705. # [致動器] 入料三通閥 ON排氣
  3706. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  3707. print('data: ', data)
  3708. # mqtt_f(data)
  3709. # [致動器] 馬達 0
  3710. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3711. print('data: ', data)
  3712. # mqtt_f(data)
  3713. # [致動器] 入料真空吸料機 OFF
  3714. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3715. print('data: ', data)
  3716. # mqtt_f(data)
  3717. if F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height:
  3718. F2 = 'F_InputtingBean_Pause'
  3719. print('------- F2 狀態更新:入料暫停 -------')
  3720. elif F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height:
  3721. F2 = 'F_InputtingBean_Finish'
  3722. print('------- F2 狀態更新:入料完成 -------')
  3723. if F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height:
  3724. F3 = 'F_InputtingBean_Pause'
  3725. print('------- F3 狀態更新:入料暫停 -------')
  3726. elif F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height:
  3727. F3 = 'F_InputtingBean_Finish'
  3728. print('------- F3 狀態更新:入料完成 -------')
  3729. if F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height:
  3730. F4 = 'F_InputtingBean_Pause'
  3731. print('------- F4 狀態更新:入料暫停 -------')
  3732. elif F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height:
  3733. F4 = 'F_InputtingBean_Finish'
  3734. print('------- F4 狀態更新:入料完成 -------')
  3735. if F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height:
  3736. F5 = 'F_InputtingBean_Pause'
  3737. print('------- F5 狀態更新:入料暫停 -------')
  3738. elif F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height:
  3739. F5 = 'F_InputtingBean_Finish'
  3740. print('------- F5 狀態更新:入料完成 -------')
  3741. if F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height:
  3742. F6 = 'F_InputtingBean_Pause'
  3743. print('------- F6 狀態更新:入料暫停 -------')
  3744. elif F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height:
  3745. F6 = 'F_InputtingBean_Finish'
  3746. print('------- F6 狀態更新:入料完成 -------')
  3747. else:
  3748. # 若入料儲豆槽非可出料狀態
  3749. print('發酵入料儲豆槽空, 桶槽無法入料')
  3750. else:
  3751. # [介面] 若未啟用 發酵 狀態
  3752. print('未啟用發酵流程')
  3753. # ----- 10/07 --------------------------------------------------------------------------------------------------------------------------------
  3754. # ----- 發酵桶槽 F1~F6 入料→入料暫停判斷 ------------------------------
  3755. ### 移到入料
  3756. # ----- 發酵桶槽 F1~F6 入料→入水判斷 ------------------------------
  3757. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  3758. F_UP_tank_WaterLevel = []
  3759. for i in range(1, 7, 1):
  3760. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3761. WaterLevel = float(tank_WaterLevel.WaterLevel)
  3762. F_UP_tank_WaterLevel.append(WaterLevel)
  3763. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  3764. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  3765. Ferment_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  3766. Ferment_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  3767. # 入水條件:當前桶槽入豆 + 沒有其他桶槽入水
  3768. if Ferment_InputtingBeanFinish_number >= 1 and Ferment_InputtingWater_number == 0:
  3769. # 當入豆到指定高度時, 狀態轉換為入水 (桶槽編號小者優先)
  3770. # !!! 發酵槽 F_InputtingBean_Finish 狀態應該請硬體判斷
  3771. # !!! 若狀態為 F_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 F_InputtingBean_Finish 並等待入水 F_InputtingWater
  3772. # 這邊是考慮一次僅一個桶槽入水, 多桶入水會不會速度變慢?
  3773. if F1 == 'F_InputtingBean_Finish':
  3774. F1 = 'F_InputtingWater'
  3775. print('------- F1 狀態更新:入水中 -------')
  3776. # [致動器] 外桶浮選三通閥 ON
  3777. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "on" }
  3778. print('data: ', data)
  3779. # mqtt_f(data)
  3780. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  3781. if F_UP_UltraSoniclist[0] < Ferment_Tank_water_height:
  3782. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "on" }
  3783. print('data: ', data)
  3784. # mqtt_f(data)
  3785. # [致動器] 桶內進水電磁閥 OFF
  3786. else:
  3787. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3788. print('data: ', data)
  3789. # mqtt_f(data)
  3790. # 桶外水位高度若低於水位計高度, [致動器] 桶外進水電磁閥 ON
  3791. if F_UP_tank_WaterLevel[0] != 1:
  3792. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "on" }
  3793. print('data: ', data)
  3794. # mqtt_f(data)
  3795. # [致動器] 桶外進水電磁閥 OFF
  3796. else:
  3797. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3798. print('data: ', data)
  3799. # mqtt_f(data)
  3800. elif F2 == 'F_InputtingBean_Finish':
  3801. F2 = 'F_InputtingWater'
  3802. print('------- F2 狀態更新:入水中 -------')
  3803. elif F3 == 'F_InputtingBean_Finish':
  3804. F3 = 'F_InputtingWater'
  3805. print('------- F3 狀態更新:入水中 -------')
  3806. elif F4 == 'F_InputtingBean_Finish':
  3807. F4 = 'F_InputtingWater'
  3808. print('------- F4 狀態更新:入水中 -------')
  3809. elif F5 == 'F_InputtingBean_Finish':
  3810. F5 = 'F_InputtingWater'
  3811. print('------- F5 狀態更新:入水中 -------')
  3812. elif F6 == 'F_InputtingBean_Finish':
  3813. F6 = 'F_InputtingWater'
  3814. print('------- F6 狀態更新:入水中 -------')
  3815. # ----- 發酵桶槽 F1~F6 入水→發酵判斷 ------------------------------
  3816. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  3817. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  3818. if F1 == 'F_InputtingWater':
  3819. if F_UP_tank_WaterLevel[0] == 1 and F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  3820. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  3821. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3822. print('data: ', data)
  3823. # mqtt_f(data)
  3824. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  3825. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3826. print('data: ', data)
  3827. # mqtt_f(data)
  3828. F1 = 'F_Fermenting'
  3829. print('------- F1 狀態更新:發酵中 -------')
  3830. # [致動器] 馬達 (指定轉速)
  3831. data = { "tank_num": "F1", "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  3832. print('data: ', data)
  3833. # mqtt_f(data)
  3834. # [致動器] 溫控開關 ON
  3835. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "on" }
  3836. # print('data: ', data)
  3837. # # mqtt_f(data)
  3838. # [致動器] 設定溫度、持溫時間
  3839. # [致動器] 加熱器 1 ON
  3840. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "on" }
  3841. print('data: ', data)
  3842. # mqtt_f(data)
  3843. elif F_UP_tank_WaterLevel[0] == 1:
  3844. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  3845. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3846. print('data: ', data)
  3847. # mqtt_f(data)
  3848. elif F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  3849. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  3850. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3851. print('data: ', data)
  3852. # mqtt_f(data)
  3853. if F2 == 'F_InputtingWater' and F_UP_tank_WaterLevel[1] == 1 and F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height:
  3854. F2 = 'F_Fermenting'
  3855. print('------- F2 狀態更新:發酵中 -------')
  3856. if F3 == 'F_InputtingWater' and F_UP_tank_WaterLevel[2] == 1 and F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height:
  3857. F3 = 'F_Fermenting'
  3858. print('------- F3 狀態更新:發酵中 -------')
  3859. if F4 == 'F_InputtingWater' and F_UP_tank_WaterLevel[3] == 1 and F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height:
  3860. F4 = 'F_Fermenting'
  3861. print('------- F4 狀態更新:發酵中 -------')
  3862. if F5 == 'F_InputtingWater' and F_UP_tank_WaterLevel[4] == 1 and F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height:
  3863. F5 = 'F_Fermenting'
  3864. print('------- F5 狀態更新:發酵中 -------')
  3865. if F6 == 'F_InputtingWater' and F_UP_tank_WaterLevel[5] == 1 and F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height:
  3866. F6 = 'F_Fermenting'
  3867. print('------- F6 狀態更新:發酵中 -------')
  3868. # ----- 發酵桶槽 F1~F6 發酵→可出豆 判斷 ------------------------------
  3869. # TODO
  3870. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  3871. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  3872. # 可以多桶各自執行發酵排程
  3873. # -- 取得發酵桶槽 F1~F6 pH -------------
  3874. F_UP_tank_PH = []
  3875. for i in range(1, 7, 1):
  3876. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3877. PH = float(tank_PH.PH)
  3878. F_UP_tank_PH.append(PH)
  3879. print('F_UP_tank_PH: ', F_UP_tank_PH)
  3880. # -- 取得發酵桶槽 F1~F6 pH -------------
  3881. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3882. F_UP_tank_SHT11_Temp = []
  3883. for i in range(1, 7, 1):
  3884. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3885. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  3886. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  3887. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  3888. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3889. #
  3890. if F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  3891. print('發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  3892. timer = time.time()
  3893. while True:
  3894. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  3895. # [致動器] 外桶浮選三通閥 OFF
  3896. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "off" }
  3897. print('data: ', data)
  3898. # mqtt_f(data)
  3899. # [致動器] 馬達 0
  3900. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3901. print('data: ', data)
  3902. # mqtt_f(data)
  3903. # [致動器] 溫控開關 OFF
  3904. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "off" }
  3905. # print('data: ', data)
  3906. # # mqtt_f(data)
  3907. # [致動器] 加熱器 1 OFF
  3908. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "off" }
  3909. print('data: ', data)
  3910. # mqtt_f(data)
  3911. break
  3912. # [致動器] 廢水排水閥 (桶內) ON
  3913. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "on" }
  3914. print('data: ', data)
  3915. # mqtt_f(data)
  3916. print('桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  3917. timer = time.time()
  3918. while True:
  3919. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  3920. # [致動器] 廢水排水閥 (桶內) OFF
  3921. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "off" }
  3922. print('data: ', data)
  3923. # mqtt_f(data)
  3924. break
  3925. F1 = 'F_OutputtingBean'
  3926. print('------- F1 狀態更新:可出豆 -------')
  3927. if F2 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[1] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[1] <= Ferment_Tank_fermenting_pH:
  3928. F2 = 'F_OutputtingBean'
  3929. print('------- F2 狀態更新:可出豆 -------')
  3930. if F3 == 'F_Fermenting' and F_UP_tank_PH[2] <= Ferment_Tank_fermenting_pH:
  3931. F3 = 'F_OutputtingBean'
  3932. print('------- F3 狀態更新:可出豆 -------')
  3933. if F4 == 'F_Fermenting' and F_UP_tank_PH[3] <= Ferment_Tank_fermenting_pH:
  3934. F4 = 'F_OutputtingBean'
  3935. print('------- F4 狀態更新:可出豆 -------')
  3936. if F5 == 'F_Fermenting' and F_UP_tank_PH[4] <= Ferment_Tank_fermenting_pH:
  3937. F5 = 'F_OutputtingBean'
  3938. print('------- F5 狀態更新:可出豆 -------')
  3939. if F6 == 'F_Fermenting' and F_UP_tank_PH[5] <= Ferment_Tank_fermenting_pH:
  3940. F6 = 'F_OutputtingBean'
  3941. print('------- F6 狀態更新:可出豆 -------')
  3942. if F1 == 'F_OutputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  3943. # 增加消毒電磁閥開關
  3944. # [致動器] 消毒電磁閥 ON
  3945. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  3946. print('data: ', data)
  3947. # mqtt_f(data)
  3948. # 暫停 (消毒時間) 秒
  3949. timer = time.time()
  3950. while True:
  3951. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  3952. # [致動器] 消毒電磁閥 OFF
  3953. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  3954. print('data: ', data)
  3955. # mqtt_f(data)
  3956. break
  3957. print('------- F1 狀態更新:空桶等待 -------')
  3958. F1 = 'F_Waiting'
  3959. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3960. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  3961. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  3962. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  3963. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  3964. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  3965. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  3966. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3967. # ----- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 ------------------------------
  3968. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  3969. # -- 取得發酵出料儲豆槽 FO1~FO2 桶內高度 UltraSonic -------------
  3970. FO_UP_UltraSoniclist = []
  3971. for i in range(1, 3, 1):
  3972. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  3973. UltraSonic = float(output_UltraSonic.UltraSonic)
  3974. FO_UP_UltraSoniclist.append(UltraSonic)
  3975. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  3976. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  3977. # 參考 -- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  3978. Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  3979. # !!! 若出料儲豆槽狀態為 FO_Waiting(空桶等待) 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  3980. if FO1 == 'FO_Waiting' and Ferment_OutputtingBean_number >= 1:
  3981. if F1 == 'F_OutputtingBean':
  3982. FO1 = 'FO_InputtingBean'
  3983. print('------- F1 狀態更新:出豆中 -------')
  3984. print('------- FO1 狀態更新:入豆中 -------')
  3985. # [致動器] 出料真空吸料機 ON
  3986. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  3987. print('data: ', data)
  3988. # mqtt_f(data)
  3989. # 暫停 3 秒
  3990. timer = time.time()
  3991. while True:
  3992. if (time.time() - timer) > 3 :
  3993. # [致動器] 蝴蝶閥 ON
  3994. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  3995. print('data: ', data)
  3996. # mqtt_f(data)
  3997. break
  3998. timer = time.time()
  3999. while True:
  4000. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  4001. # [致動器] 出料真空吸料機 OFF
  4002. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4003. print('data: ', data)
  4004. # mqtt_f(data)
  4005. timer = time.time()
  4006. break
  4007. while True:
  4008. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  4009. break
  4010. elif F2 == 'F_OutputtingBean':
  4011. FO1 = 'FO_InputtingBean'
  4012. print('------- F2 狀態更新:出豆中 -------')
  4013. print('------- FO1 狀態更新:入豆中 -------')
  4014. elif F3 == 'F_OutputtingBean':
  4015. FO1 = 'FO_InputtingBean'
  4016. print('------- F3 狀態更新:出豆中 -------')
  4017. print('------- FO1 狀態更新:入豆中 -------')
  4018. elif F4 == 'F_OutputtingBean':
  4019. FO1 = 'FO_InputtingBean'
  4020. print('------- F4 狀態更新:出豆中 -------')
  4021. print('------- FO1 狀態更新:入豆中 -------')
  4022. elif F5 == 'F_OutputtingBean':
  4023. FO1 = 'FO_InputtingBean'
  4024. print('------- F5 狀態更新:出豆中 -------')
  4025. print('------- FO1 狀態更新:入豆中 -------')
  4026. elif F6 == 'F_OutputtingBean':
  4027. FO1 = 'FO_InputtingBean'
  4028. print('------- F6 狀態更新:出豆中 -------')
  4029. print('------- FO1 狀態更新:入豆中 -------')
  4030. # 出料儲豆槽入料滿時, 出料儲豆槽狀態改為可出豆 (需判斷是哪個桶槽, 好關閉蝴蝶閥)
  4031. elif FO1 == 'FO_InputtingBean' and FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  4032. if F1 == 'F_OutputtingBean':
  4033. FO1 = 'FO_OutputtingBean'
  4034. print('------- FO1 狀態更新:可出豆 -------')
  4035. # [致動器] 出料真空吸料機 OFF
  4036. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4037. print('data: ', data)
  4038. # mqtt_f(data)
  4039. # [致動器] 蝴蝶閥 OFF
  4040. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  4041. print('data: ', data)
  4042. # mqtt_f(data)
  4043. elif F2 == 'F_OutputtingBean':
  4044. pass # TODO ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1020 TODO
  4045. # 出料儲豆槽入料時, 桶槽已空, 則桶槽回到空桶等待, 出料儲豆槽可出豆 ←←←←←←←←←←←←←←←←←←←←←←←←←← 1012 這段怪怪的
  4046. elif FO1 == 'FO_InputtingBean' and Ferment_OutputtingBean_number == 1:
  4047. if F1 == 'F_OutputtingBean':
  4048. if F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  4049. FO1 = 'FO_OutputtingBean'
  4050. print('------- FO1 狀態更新:可出豆 -------')
  4051. # 增加消毒電磁閥開關
  4052. # [致動器] 消毒電磁閥 ON
  4053. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  4054. print('data: ', data)
  4055. # mqtt_f(data)
  4056. # 暫停 (消毒時間) 秒
  4057. timer = time.time()
  4058. while True:
  4059. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  4060. # [致動器] 消毒電磁閥 OFF
  4061. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  4062. print('data: ', data)
  4063. # mqtt_f(data)
  4064. break
  4065. print('------- F1 狀態更新:空桶等待 -------')
  4066. F1 = 'F_Waiting'
  4067. else:
  4068. # [致動器] 出料真空吸料機 ON
  4069. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  4070. print('data: ', data)
  4071. # mqtt_f(data)
  4072. # 暫停 3 秒
  4073. timer = time.time()
  4074. while True:
  4075. if (time.time() - timer) > 3 :
  4076. # [致動器] 蝴蝶閥 ON
  4077. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  4078. print('data: ', data)
  4079. # mqtt_f(data)
  4080. break
  4081. timer = time.time()
  4082. while True:
  4083. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  4084. # [致動器] 出料真空吸料機 OFF
  4085. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4086. print('data: ', data)
  4087. # mqtt_f(data)
  4088. timer = time.time()
  4089. break
  4090. while True:
  4091. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  4092. break
  4093. elif F2 == 'F_OutputtingBean' and F_UP_UltraSoniclist[1] < 5:
  4094. F2 = 'F_Waiting'
  4095. FO1 = 'FO_OutputtingBean'
  4096. print('------- F2 狀態更新:空桶等待 -------')
  4097. print('------- FO1 狀態更新:可出豆 -------')
  4098. elif F3 == 'F_OutputtingBean' and F_UP_UltraSoniclist[2] < 5:
  4099. F3 = 'F_Waiting'
  4100. FO1 = 'FO_OutputtingBean'
  4101. print('------- F3 狀態更新:空桶等待 -------')
  4102. print('------- FO1 狀態更新:可出豆 -------')
  4103. elif F4 == 'F_OutputtingBean' and F_UP_UltraSoniclist[3] < 5:
  4104. F4 = 'F_Waiting'
  4105. FO1 = 'FO_OutputtingBean'
  4106. print('------- F4 狀態更新:空桶等待 -------')
  4107. print('------- FO1 狀態更新:可出豆 -------')
  4108. elif F5 == 'F_OutputtingBean' and F_UP_UltraSoniclist[4] < 5:
  4109. F5 = 'F_Waiting'
  4110. FO1 = 'FO_OutputtingBean'
  4111. print('------- F5 狀態更新:空桶等待 -------')
  4112. print('------- FO1 狀態更新:可出豆 -------')
  4113. elif F6 == 'F_OutputtingBean' and F_UP_UltraSoniclist[5] < 5:
  4114. F6 = 'F_Waiting'
  4115. FO1 = 'FO_OutputtingBean'
  4116. print('------- F6 狀態更新:空桶等待 -------')
  4117. print('------- FO1 狀態更新:可出豆 -------')
  4118. # 出料儲豆槽出料 且 儲豆槽內高度低於 5 , 為空桶等待
  4119. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] < Ferment_Output_bean_empty:
  4120. FO1 = 'FO_Waiting'
  4121. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  4122. # 1008 移到桶槽前面
  4123. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  4124. # 1012 移到桶槽可出豆內
  4125. # ----- 將狀態寫入資料庫 ------------------------------
  4126. # 獲取文本框的值並賦值給user實體對象
  4127. F_status = ferment_container_status()
  4128. F_status.Ferment_Input_1 = FI1
  4129. F_status.Ferment_Input_2 = FI2
  4130. F_status.Ferment_Tank_1 = F1
  4131. F_status.Ferment_Tank_2 = F2
  4132. F_status.Ferment_Tank_3 = F3
  4133. F_status.Ferment_Tank_4 = F4
  4134. F_status.Ferment_Tank_5 = F5
  4135. F_status.Ferment_Tank_6 = F6
  4136. F_status.Ferment_Tank_7 = F7
  4137. F_status.Ferment_Tank_8 = F8
  4138. F_status.Ferment_Tank_9 = F9
  4139. F_status.Ferment_Tank_10 = F10
  4140. F_status.Ferment_Tank_11 = F11
  4141. F_status.Ferment_Tank_12 = F12
  4142. F_status.Ferment_Output_1 = FO1
  4143. F_status.Ferment_Output_2 = FO2
  4144. #將數據保存進資料庫
  4145. db.session.add(F_status)
  4146. # 手動提交
  4147. db.session.commit()
  4148. # ----- 將狀態寫入資料庫 ------------------------------
  4149. return jsonify({"Peel_Output_1":PO1,
  4150. "Ferment_Input_1":FI1,
  4151. "Ferment_Tank_1":F1,
  4152. "Ferment_Tank_2":F2,
  4153. "Ferment_Tank_3":F3,
  4154. "Ferment_Tank_4":F4,
  4155. "Ferment_Tank_5":F5,
  4156. "Ferment_Tank_6":F6,
  4157. "Ferment_Output_1":FO1
  4158. })
  4159. '''
  4160. return jsonify({"Ferment_Input_1":FI1,
  4161. "Ferment_Input_2":FI2,
  4162. "Ferment_Tank_1":F1,
  4163. "Ferment_Tank_2":F2,
  4164. "Ferment_Tank_3":F3,
  4165. "Ferment_Tank_4":F4,
  4166. "Ferment_Tank_5":F5,
  4167. "Ferment_Tank_6":F6,
  4168. "Ferment_Tank_7":F7,
  4169. "Ferment_Tank_8":F8,
  4170. "Ferment_Tank_9":F9,
  4171. "Ferment_Tank_10":F10,
  4172. "Ferment_Tank_11":F11,
  4173. "Ferment_Tank_12":F12,
  4174. "Ferment_Output_1":FO1,
  4175. "Ferment_Output_2":FO2
  4176. })
  4177. '''
  4178. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以上為原備份
  4179. # 舊有 video 介面
  4180. @main.route('/video')
  4181. def main_video():
  4182. # 獲取登入信息
  4183. if 'id' in session and 'uname' in session and 'status' in session:
  4184. username = session['uname']
  4185. status = session['status']
  4186. if status == 9:
  4187. return render_template('signin_disable.html', params=locals())
  4188. elif status == 8:
  4189. return render_template('signin_new.html', params=locals())
  4190. return render_template('video.html', params=locals())
  4191. else:
  4192. return render_template('sign_in.html')
  4193. @main.route('/sitemap')
  4194. def sitemap():
  4195. if request.method == 'GET':
  4196. if 'id' in session and 'uname' in session and 'status' in session:
  4197. username = session['uname']
  4198. status = session['status']
  4199. print('username: ', username)
  4200. print('status: ', status)
  4201. if status == 9:
  4202. return render_template('signin_disable.html', **locals())
  4203. elif status == 8:
  4204. return render_template('signin_new.html', **locals())
  4205. return render_template('sitemap.html', **locals())
  4206. else:
  4207. return render_template('sign_in.html')
  4208. @main.route('/index_navbar', methods=['GET'])
  4209. def index_navbar():
  4210. return render_template('index_navbar.html')
  4211. @main.route('/camera_dry', methods=['GET', 'POST'])
  4212. def camera_dry():
  4213. if request.method == 'GET':
  4214. if 'id' in session and 'uname' in session and 'status' in session:
  4215. username = session['uname']
  4216. status = session['status']
  4217. if status == 9:
  4218. return render_template('signin_disable.html', params=locals())
  4219. elif status == 8:
  4220. return render_template('signin_new.html', params=locals())
  4221. return render_template('camera_dry.html', title='乾燥貨櫃攝影機', **locals())
  4222. else:
  4223. return render_template('sign_in.html')
  4224. @main.route('/camera_ferment', methods=['GET', 'POST'])
  4225. def camera_ferment():
  4226. if request.method == 'GET':
  4227. if 'id' in session and 'uname' in session and 'status' in session:
  4228. username = session['uname']
  4229. status = session['status']
  4230. if status == 9:
  4231. return render_template('signin_disable.html', params=locals())
  4232. elif status == 8:
  4233. return render_template('signin_new.html', params=locals())
  4234. return render_template('camera_ferment.html', title='發酵貨櫃攝影機', **locals())
  4235. else:
  4236. return render_template('sign_in.html')
  4237. @main.route('/camera_clean', methods=['GET', 'POST'])
  4238. def camera_clean():
  4239. if request.method == 'GET':
  4240. if 'id' in session and 'uname' in session and 'status' in session:
  4241. username = session['uname']
  4242. status = session['status']
  4243. if status == 9:
  4244. return render_template('signin_disable.html', params=locals())
  4245. elif status == 8:
  4246. return render_template('signin_new.html', params=locals())
  4247. return render_template('camera_clean.html', title='清洗貨櫃攝影機', **locals())
  4248. else:
  4249. return render_template('sign_in.html')
  4250. @main.route('/camera_dry_1', methods=['GET', 'POST'])
  4251. def camera_dry_2():
  4252. if request.method == 'GET':
  4253. return render_template('camera_dry_1.html', title='乾燥貨櫃攝影機', **locals())
  4254. @main.route('/camera_<tid>', methods=['GET', 'POST'])
  4255. def camera(tid):
  4256. if request.method == 'GET':
  4257. if 'id' in session and 'uname' in session and 'status' in session:
  4258. username = session['uname']
  4259. status = session['status']
  4260. if status == 9:
  4261. return render_template('signin_disable.html', params=locals())
  4262. elif status == 8:
  4263. return render_template('signin_new.html', params=locals())
  4264. if tid == 'CCargo_in':
  4265. WS_URL = 'ws:///60.250.156.230:1111'
  4266. camera_title = '清洗貨櫃內部'
  4267. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4268. elif tid == 'CCargo_out':
  4269. WS_URL = 'ws:///60.250.156.230:1111'
  4270. camera_title = '清洗貨櫃外部'
  4271. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4272. elif tid == 'FCargo_in':
  4273. WS_URL = 'ws:///60.250.156.230:1111'
  4274. camera_title = '發酵貨櫃內部'
  4275. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4276. elif tid == 'FCargo_out':
  4277. WS_URL = 'ws:///60.250.156.230:1111'
  4278. camera_title = '發酵貨櫃外部'
  4279. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4280. elif tid == 'DCargo_in':
  4281. WS_URL = 'ws:///60.250.156.230:1111'
  4282. camera_title = '乾燥貨櫃內部'
  4283. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4284. elif tid == 'DCargo_out':
  4285. WS_URL = 'ws:///60.250.156.230:1111'
  4286. camera_title = '乾燥貨櫃外部'
  4287. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4288. elif tid[:2] == 'DO':
  4289. WS_URL_list = ['ws:///60.250.156.230:1111',
  4290. 'ws:///60.250.156.230:2222'
  4291. ]
  4292. WS_URL = WS_URL_list[int(tid[2:])-1]
  4293. camera_title = '乾燥出料儲豆槽'
  4294. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4295. elif tid[:2] == 'DI':
  4296. WS_URL_list = ['ws:///60.250.156.230:1111',
  4297. 'ws:///60.250.156.230:2222'
  4298. ]
  4299. WS_URL = WS_URL_list[int(tid[2:])-1]
  4300. camera_title = '乾燥入料儲豆槽'
  4301. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4302. elif tid[:1] == 'D':
  4303. WS_URL_list = ['ws:///60.250.156.230:8093', # D1 攝影機已安裝
  4304. 'ws:///60.250.156.230:2222',
  4305. 'ws:///60.250.156.230:3333',
  4306. 'ws:///60.250.156.230:4444',
  4307. 'ws:///60.250.156.230:5555',
  4308. 'ws:///60.250.156.230:6666',
  4309. 'ws:///60.250.156.230:7777',
  4310. 'ws:///60.250.156.230:8888',
  4311. 'ws:///60.250.156.230:9999',
  4312. 'ws:///60.250.156.230:1010',
  4313. 'ws:///60.250.156.230:1111',
  4314. 'ws:///60.250.156.230:1212'
  4315. ]
  4316. WS_URL = WS_URL_list[int(tid[1:])-1]
  4317. camera_title = '乾燥槽'
  4318. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4319. elif tid[:2] == 'FO':
  4320. WS_URL_list = ['ws:///60.250.156.230:1111',
  4321. 'ws:///60.250.156.230:2222'
  4322. ]
  4323. WS_URL = WS_URL_list[int(tid[2:])-1]
  4324. camera_title = '發酵出料儲豆槽'
  4325. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4326. elif tid[:2] == 'FI':
  4327. WS_URL_list = ['ws:///60.250.156.230:1111',
  4328. 'ws:///60.250.156.230:2222'
  4329. ]
  4330. WS_URL = WS_URL_list[int(tid[2:])-1]
  4331. camera_title = '發酵入料儲豆槽'
  4332. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4333. elif tid[:1] == 'F':
  4334. WS_URL_list = ['ws:///60.250.156.230:8089', # F1 攝影機已安裝
  4335. 'ws:///60.250.156.230:2222',
  4336. 'ws:///60.250.156.230:3333',
  4337. 'ws:///60.250.156.230:4444',
  4338. 'ws:///60.250.156.230:5555',
  4339. 'ws:///60.250.156.230:6666',
  4340. 'ws:///60.250.156.230:7777',
  4341. 'ws:///60.250.156.230:8888',
  4342. 'ws:///60.250.156.230:9999',
  4343. 'ws:///60.250.156.230:1010',
  4344. 'ws:///60.250.156.230:1111',
  4345. 'ws:///60.250.156.230:1212'
  4346. ]
  4347. WS_URL = WS_URL_list[int(tid[1:])-1]
  4348. camera_title = '發酵槽'
  4349. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4350. elif tid[:2] == 'CO':
  4351. WS_URL_list = ['ws:///60.250.156.230:1111',
  4352. 'ws:///60.250.156.230:2222'
  4353. ]
  4354. WS_URL = WS_URL_list[int(tid[2:])-1]
  4355. camera_title = '清洗浮選出料儲豆槽'
  4356. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4357. elif tid[:1] == 'C':
  4358. WS_URL_list = ['ws:///60.250.156.230:8088', # C1 攝影機已安裝
  4359. 'ws:///60.250.156.230:2222',
  4360. 'ws:///60.250.156.230:3333',
  4361. 'ws:///60.250.156.230:4444'
  4362. ]
  4363. WS_URL = WS_URL_list[int(tid[1:])-1]
  4364. camera_title = '清洗浮選槽'
  4365. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4366. elif tid[:2] == 'SO':
  4367. WS_URL_list = ['ws:///60.250.156.230:1111',
  4368. 'ws:///60.250.156.230:2222'
  4369. ]
  4370. WS_URL = WS_URL_list[int(tid[2:])-1]
  4371. camera_title = '色選機出料儲豆槽'
  4372. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4373. elif tid[:1] == 'S':
  4374. WS_URL_list = ['ws:///60.250.156.230:1111',
  4375. 'ws:///60.250.156.230:2222'
  4376. ]
  4377. WS_URL = WS_URL_list[int(tid[1:])-1]
  4378. camera_title = '色選機'
  4379. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4380. elif tid[:2] == 'PO':
  4381. WS_URL_list = ['ws:///60.250.156.230:1111',
  4382. 'ws:///60.250.156.230:2222'
  4383. ]
  4384. WS_URL = WS_URL_list[int(tid[2:])-1]
  4385. camera_title = '脫皮機出料儲豆槽'
  4386. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4387. elif tid[:1] == 'P':
  4388. WS_URL_list = ['ws:///60.250.156.230:1111',
  4389. 'ws:///60.250.156.230:2222'
  4390. ]
  4391. WS_URL = WS_URL_list[int(tid[1:])-1]
  4392. camera_title = '脫皮機'
  4393. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4394. elif tid[:1] == 'R':
  4395. WS_URL_list = ['ws:///60.250.156.230:1111'
  4396. ]
  4397. WS_URL = WS_URL_list[int(tid[1:])-1]
  4398. camera_title = '中水桶'
  4399. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4400. else:
  4401. return render_template('sign_in.html')
  4402. else:
  4403. pass
  4404. @main.route('/dry_SHT11_<dtid>', methods=['GET', 'POST'])
  4405. def dry_SHT11(dtid):
  4406. if request.method == 'GET':
  4407. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4408. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4409. SHT11_Temp = tank_SHT11.SHT11_Temp
  4410. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4411. Soil_Temp = tank_Soil.soil_Temp
  4412. return jsonify({"SHT11_Temp":SHT11_Temp,
  4413. "SHT11_Humidity":SHT11_Humidity,
  4414. "Soil_Temp":Soil_Temp
  4415. })
  4416. else:
  4417. pass
  4418. @main.route('/dry_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4419. def dry_UltraSonic(dtid):
  4420. if request.method == 'GET':
  4421. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4422. UltraSonic = tank_UltraSonic.UltraSonic
  4423. return jsonify({"UltraSonic":UltraSonic
  4424. })
  4425. else:
  4426. pass
  4427. @main.route('/dry_input_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4428. def dry_input_UltraSonic(dtid):
  4429. if request.method == 'GET':
  4430. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + dtid).order_by(text('datetime desc')).first()
  4431. UltraSonic = input_UltraSonic.UltraSonic
  4432. return jsonify({"UltraSonic":UltraSonic
  4433. })
  4434. else:
  4435. pass
  4436. @main.route('/dry_output_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4437. def dry_output_UltraSonic(dtid):
  4438. if request.method == 'GET':
  4439. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + dtid).order_by(text('datetime desc')).first()
  4440. UltraSonic = output_UltraSonic.UltraSonic
  4441. return jsonify({"UltraSonic":UltraSonic
  4442. })
  4443. else:
  4444. pass
  4445. @main.route('/ferment_SHT11_<ftid>', methods=['GET', 'POST'])
  4446. def ferment_SHT11(ftid):
  4447. if request.method == 'GET':
  4448. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4449. SHT11_Temp = tank_SHT11.SHT11_Temp
  4450. return jsonify({"SHT11_Temp":SHT11_Temp
  4451. })
  4452. else:
  4453. pass
  4454. @main.route('/ferment_WaterLevel_<ftid>', methods=['GET', 'POST'])
  4455. def ferment_WaterLevel(ftid):
  4456. if request.method == 'GET':
  4457. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4458. WaterLevel = tank_WaterLevel.WaterLevel
  4459. return jsonify({"WaterLevel":WaterLevel
  4460. })
  4461. else:
  4462. pass
  4463. @main.route('/ferment_WaterIn_<ftid>', methods=['GET', 'POST'])
  4464. def ferment_WaterIn(ftid):
  4465. if request.method == 'GET':
  4466. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4467. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  4468. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4469. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4470. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4471. WaterLevel = tank_WaterLevel.WaterLevel
  4472. return jsonify({"UltraSonic":UltraSonic,
  4473. "WaterLevel":WaterLevel
  4474. })
  4475. else:
  4476. pass
  4477. @main.route('/ferment_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4478. def ferment_UltraSonic(ftid):
  4479. if request.method == 'GET':
  4480. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4481. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  4482. return jsonify({"UltraSonic":UltraSonic
  4483. })
  4484. else:
  4485. pass
  4486. '''
  4487. @main.route('/ferment_LiDAR_<ftid>', methods=['GET', 'POST'])
  4488. def ferment_LiDAR(ftid):
  4489. if request.method == 'GET':
  4490. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4491. LiDAR = tank_LiDAR.LiDAR
  4492. return jsonify({"LiDAR":LiDAR
  4493. })
  4494. else:
  4495. pass
  4496. '''
  4497. @main.route('/ferment_input_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4498. def ferment_input_UltraSonic_(ftid):
  4499. if request.method == 'GET':
  4500. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + ftid).order_by(text('datetime desc')).first()
  4501. UltraSonic = input_UltraSonic.UltraSonic
  4502. return jsonify({"UltraSonic":UltraSonic
  4503. })
  4504. else:
  4505. pass
  4506. @main.route('/ferment_output_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4507. def ferment_output_UltraSonic_(ftid):
  4508. if request.method == 'GET':
  4509. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + ftid).order_by(text('datetime desc')).first()
  4510. UltraSonic = output_UltraSonic.UltraSonic
  4511. return jsonify({"UltraSonic":UltraSonic
  4512. })
  4513. else:
  4514. pass
  4515. @main.route('/ferment_watertesting_<tid>', methods=['GET', 'POST'])
  4516. def ferment_watertesting(tid):
  4517. if request.method == 'GET':
  4518. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4519. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4520. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4521. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4522. PH = tank_PH.PH
  4523. ORP = tank_ORP.ORP
  4524. DO = tank_DO.DO
  4525. EC = tank_EC.EC
  4526. return jsonify({"PH":PH,
  4527. "ORP":ORP,
  4528. "DO":DO,
  4529. "EC":EC,
  4530. })
  4531. '''
  4532. @main.route('/ferment_PressureWaterLevel_<ftid>', methods=['GET', 'POST'])
  4533. def ferment_PressureWaterLevel(ftid):
  4534. if request.method == 'GET':
  4535. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4536. PressureWaterLevel = float(tank_PressureWaterLevel.PressureWaterLevel)
  4537. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4538. print("PressureWaterLevel_start: ", PressureWaterLevel)
  4539. return jsonify({"PressureWaterLevel":PressureWaterLevel
  4540. })
  4541. # 此段刪除
  4542. while int(PressureWaterLevel) < int(testing_water_height):
  4543. tank_water_status = 'NO'
  4544. time.sleep(3)
  4545. # print(ferment_water_height(testing_water_height))
  4546. # [目前桶內水位高度]發酵槽_感測器_壓力式水位計
  4547. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  4548. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  4549. print("-- MySQL --")
  4550. print("tank_PressureWaterLevel: ", tank_PressureWaterLevel)
  4551. # tank_water_height()
  4552. # print("PressureWaterLevel_while: ", PressureWaterLevel)
  4553. ferment_water_height(testing_water_height)
  4554. return jsonify({"testing_water_height":testing_water_height,
  4555. "tank_water_status":tank_water_status
  4556. })
  4557. else:
  4558. tank_water_status = 'OK'
  4559. print("PressureWaterLevel_else: ", PressureWaterLevel)
  4560. return jsonify({"testing_water_height":testing_water_height,
  4561. "tank_water_status":tank_water_status
  4562. })
  4563. '''
  4564. '''
  4565. def tank_water_height():
  4566. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  4567. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  4568. print("tank_water_height", PressureWaterLevel)
  4569. return PressureWaterLevel
  4570. '''
  4571. @main.route('/loading/R<rtid>', methods=['GET', 'POST'])
  4572. def R_loading(rtid):
  4573. if request.method == 'GET':
  4574. # 致動器_中水桶
  4575. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+rtid).order_by(text('datetime desc')).first()
  4576. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  4577. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  4578. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  4579. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  4580. return jsonify({"tank_solenoid_water_in":tank_solenoid_water_in,
  4581. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  4582. "tank_solenoid_water_out":tank_solenoid_water_out,
  4583. "tank_pump_reclaimed_out":tank_pump_reclaimed_out
  4584. })
  4585. else:
  4586. pass
  4587. @main.route('/loading/SO<sotid>', methods=['GET', 'POST'])
  4588. def SO_loading(sotid):
  4589. if request.method == 'GET':
  4590. # 致動器_脫皮機_ALL
  4591. output_actuator = colorselect_output_actuator.query.filter_by(tank_num='SO'+sotid).order_by(text('datetime desc')).first()
  4592. output_vacuum = output_actuator.vacuum
  4593. return jsonify({"output_vacuum":output_vacuum
  4594. })
  4595. else:
  4596. pass
  4597. @main.route('/loading/S<stid>', methods=['GET', 'POST'])
  4598. def S_loading(stid):
  4599. if request.method == 'GET':
  4600. # 致動器_色選機
  4601. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4602. tank_vacuum = tank_actuator.vacuum
  4603. tank_motor = tank_actuator.motor
  4604. tank_nozzle = tank_actuator.nozzle
  4605. # 致動器_超音波感測器colorselect_tank_UltraSonic
  4606. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4607. UltraSonic = tank_UltraSonic.UltraSonic
  4608. # 致動器_顏色感測器
  4609. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4610. color = tank_color.color
  4611. return jsonify({"tank_vacuum":tank_vacuum,
  4612. "tank_motor":tank_motor,
  4613. "tank_nozzle":tank_nozzle,
  4614. "UltraSonic":UltraSonic,
  4615. "color":color
  4616. })
  4617. else:
  4618. pass
  4619. @main.route('/loading/PO<potid>', methods=['GET', 'POST'])
  4620. def PO_loading(potid):
  4621. if request.method == 'GET':
  4622. # 致動器_脫皮機_ALL
  4623. output_actuator = peel_output_actuator.query.filter_by(tank_num='PO'+potid).order_by(text('datetime desc')).first()
  4624. output_vacuum = output_actuator.vacuum
  4625. return jsonify({"output_vacuum":output_vacuum
  4626. })
  4627. else:
  4628. pass
  4629. @main.route('/loading/P<ptid>', methods=['GET', 'POST'])
  4630. def P_loading(ptid):
  4631. if request.method == 'GET':
  4632. # 致動器_脫皮機_ALL
  4633. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+ptid).order_by(text('datetime desc')).first()
  4634. tank_vacuum = tank_actuator.vacuum
  4635. tank_motor = tank_actuator.motor
  4636. return jsonify({"tank_vacuum":tank_vacuum,
  4637. "tank_motor":tank_motor})
  4638. else:
  4639. pass
  4640. @main.route('/loading/CO<cotid>', methods=['GET', 'POST'])
  4641. def CO_loading(cotid):
  4642. if request.method == 'GET':
  4643. output_actuator = clean_output_actuator.query.filter_by(tank_num='CO'+cotid).order_by(text('datetime desc')).first()
  4644. output_vacuum = output_actuator.vacuum
  4645. return jsonify({"output_vacuum":output_vacuum
  4646. })
  4647. else:
  4648. pass
  4649. @main.route('/loading/C<ctid>', methods=['GET', 'POST'])
  4650. def C_loading(ctid):
  4651. if request.method == 'GET':
  4652. # 致動器_浮選清洗_ALL
  4653. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4654. tank_vacuum = tank_actuator.vacuum
  4655. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  4656. tank_motor = tank_actuator.motor
  4657. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  4658. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  4659. tank_pump_water_in = tank_actuator.pump_water_in
  4660. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  4661. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  4662. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  4663. tank_pump_disinfect = tank_actuator.pump_disinfect
  4664. tank_diskvalve = tank_actuator.diskvalve
  4665. # 感測器_浮選清洗_超音波感測器
  4666. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4667. UltraSonic = tank_UltraSonic.UltraSonic
  4668. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4669. Encoder = tank_Encoder.Encoder
  4670. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4671. tankTurbidity = tank_Turbidity.tankTurbidity
  4672. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4673. filterTurbidity = filter_Turbidity.filterTurbidity
  4674. # tank_pump_waterInput = tank_actuator.pump_waterInput
  4675. # tank_pump_waterL2L3 = tank_actuator.pump_waterL2L3
  4676. # tank_pump_waterL4L5 = tank_actuator.pump_waterL4L5
  4677. # tank_solenoid_waterL2L3 = tank_actuator.solenoid_waterL2L3
  4678. # tank_solenoid_waterL4L5 = tank_actuator.solenoid_waterL4L5
  4679. # tank_stepping_motor = tank_actuator.stepping_motor
  4680. return jsonify({"UltraSonic":UltraSonic,
  4681. "Encoder":Encoder,
  4682. "tankTurbidity":tankTurbidity,
  4683. "filterTurbidity":filterTurbidity,
  4684. "tank_vacuum":tank_vacuum,
  4685. "tank_threewayvalve_input":tank_threewayvalve_input,
  4686. "tank_motor":tank_motor,
  4687. "tank_solenoid_reclaimed_in":tank_solenoid_reclaimed_in,
  4688. "tank_solenoid_water_in":tank_solenoid_water_in,
  4689. "tank_pump_water_in":tank_pump_water_in,
  4690. "tank_solenoid_water_out":tank_solenoid_water_out,
  4691. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  4692. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  4693. "tank_pump_disinfect":tank_pump_disinfect,
  4694. "tank_diskvalve":tank_diskvalve
  4695. })
  4696. else:
  4697. pass
  4698. @main.route('/loading/F<ftid>', methods=['GET', 'POST'])
  4699. def F_loading(ftid):
  4700. if request.method == 'GET':
  4701. # 致動器_發酵槽_ALL
  4702. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4703. tank_vacuum = tank_actuator.vacuum
  4704. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  4705. tank_diskvalve = tank_actuator.diskvalve
  4706. solenoid_tank_pump = tank_actuator.solenoid_tank_pump
  4707. tank_solenoid_disinfect = tank_actuator.solenoid_tank_disinfect
  4708. outer_solenoid_water = tank_actuator.solenoid_outer_water
  4709. tank_solenoid_water_in = tank_actuator.solenoid_tank_water_in
  4710. tank_solenoid_water_out = tank_actuator.solenoid_tank_water_out
  4711. tank_pump_sensor = tank_actuator.pump_sensor
  4712. outer_threewayvalve_float = tank_actuator.threewayvalve_outer_float
  4713. tank_motor = tank_actuator.motor
  4714. tank_heater1 = tank_actuator.heater1
  4715. tank_heater2 = tank_actuator.heater2
  4716. tank_temp_enable = tank_actuator.temp_enable
  4717. tank_temp = tank_actuator.temp
  4718. # 感測器_發酵桶_SHT11
  4719. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4720. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  4721. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  4722. # 感測器_發酵桶_二氧化碳
  4723. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4724. CO2 = float(tank_CO2.CO2)
  4725. # 感測器_發酵桶_酸鹼值
  4726. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4727. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4728. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4729. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4730. PH = float(tank_PH.PH)
  4731. ORP = float(tank_ORP.ORP)
  4732. DO = float(tank_DO.DO)
  4733. EC = float(tank_EC.EC)
  4734. # 感測器_發酵桶_氣壓
  4735. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4736. PA = float(tank_PA.PA)
  4737. # 感測器_發酵桶_超音波感測器
  4738. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4739. UltraSonic= (float(tank_UltraSonic.UltraSonic))
  4740. # 感測器_發酵桶_保溫夾層水位計
  4741. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4742. WaterLevel = tank_WaterLevel.WaterLevel
  4743. # 感測器_發酵桶_咖啡生豆高度
  4744. # tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4745. # LiDAR = tank_LiDAR.LiDAR
  4746. # 感測器_發酵桶_水位高度
  4747. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4748. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4749. # 感測器_發酵桶_馬達編碼器
  4750. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4751. motorEncoder = tank_motorEncoder.motorEncoder
  4752. return jsonify({"SHT11_Temp": SHT11_Temp,
  4753. "SHT11_Humidity":SHT11_Humidity,
  4754. "CO2":CO2,
  4755. "PH":PH,
  4756. "ORP":ORP,
  4757. "DO":DO,
  4758. "EC":EC,
  4759. "PA":PA,
  4760. "WaterLevel":WaterLevel,
  4761. "UltraSonic":UltraSonic,
  4762. "motorEncoder":motorEncoder,
  4763. "tank_vacuum":tank_vacuum,
  4764. "tank_threewayvalve_input":tank_threewayvalve_input,
  4765. "tank_diskvalve":tank_diskvalve,
  4766. "solenoid_tank_pump":solenoid_tank_pump,
  4767. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  4768. "outer_solenoid_water":outer_solenoid_water,
  4769. "tank_solenoid_water_in":tank_solenoid_water_in,
  4770. "tank_solenoid_water_out":tank_solenoid_water_out,
  4771. "tank_pump_sensor":tank_pump_sensor,
  4772. "outer_threewayvalve_float":outer_threewayvalve_float,
  4773. "tank_motor":tank_motor,
  4774. "tank_heater1":tank_heater1,
  4775. "tank_heater2":tank_heater2,
  4776. "tank_temp_enable":tank_temp_enable,
  4777. "tank_temp":tank_temp
  4778. })
  4779. else:
  4780. pass
  4781. @main.route('/loading/FI<fitid>', methods=['GET', 'POST'])
  4782. def FI_loading(fitid):
  4783. if request.method == 'GET':
  4784. input_actuator = ferment_input_actuator.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  4785. input_vacuum = input_actuator.vacuum
  4786. input_sensor = ferment_input_UltraSonic.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  4787. # input_UltraSonic = float("{:.2f}".format(34.6 - float(input_sensor.UltraSonic)))
  4788. input_UltraSonic = float(input_sensor.UltraSonic)
  4789. return jsonify({"input_UltraSonic":input_UltraSonic,
  4790. "input_vacuum":input_vacuum
  4791. })
  4792. else:
  4793. pass
  4794. @main.route('/loading/FO<fotid>', methods=['GET', 'POST'])
  4795. def FO_loading(fotid):
  4796. if request.method == 'GET':
  4797. output_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  4798. output_vacuum = output_actuator.vacuum
  4799. output_sensor = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  4800. output_UltraSonic = output_sensor.UltraSonic
  4801. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+fotid).order_by(text('datetime desc')).first()
  4802. LiDAR = tank_LiDAR.LiDAR
  4803. return jsonify({"output_UltraSonic":output_UltraSonic,
  4804. "output_vacuum":output_vacuum,
  4805. "LiDAR":LiDAR
  4806. })
  4807. else:
  4808. pass
  4809. @main.route('/loading/DI<ditid>', methods=['GET', 'POST'])
  4810. def DI_loading(ditid):
  4811. if request.method == 'GET':
  4812. input_actuator = dry_input_brake.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  4813. input_vacuum = input_actuator.vacuum
  4814. input_sensor = dry_input_sensor.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  4815. input_UltraSonic = input_sensor.UltraSonic
  4816. return jsonify({"input_UltraSonic":input_UltraSonic,
  4817. "input_vacuum":input_vacuum
  4818. })
  4819. else:
  4820. pass
  4821. @main.route('/loading/DO<dotid>', methods=['GET', 'POST'])
  4822. def DO_loading(dotid):
  4823. if request.method == 'GET':
  4824. output_actuator = dry_output_brake.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  4825. output_vacuum = output_actuator.vacuum
  4826. output_sensor = dry_output_sensor.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  4827. output_UltraSonic = output_sensor.UltraSonic
  4828. return jsonify({"output_vacuum":output_vacuum,
  4829. "output_UltraSonic":output_UltraSonic
  4830. })
  4831. else:
  4832. pass
  4833. @main.route('/loading/D<dtid>', methods=['GET', 'POST'])
  4834. def D_loading(dtid):
  4835. if request.method == 'GET':
  4836. # 感測器_乾燥桶_超音波感測器
  4837. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4838. UltraSonic = tank_UltraSonic.UltraSonic
  4839. # 感測器_乾燥桶_SHT11
  4840. tonow = dt.now()
  4841. # 感測器_乾燥桶_SHT11
  4842. print("tonow: ", tonow)
  4843. time_del = timedelta(minutes=-60)
  4844. bias_date_time = tonow + time_del
  4845. # print(dt.now() >= dt(2021,11,29,17,35,36))
  4846. # bias_min = tonow.minute + 3
  4847. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(dtid))\
  4848. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  4849. .order_by(text('datetime desc')).first()
  4850. print("tank_SHT11: ", tank_SHT11, type(tank_SHT11)) # tank_SHT11: <dry_tank_SHT11 2021-12-03 15:39:16> <class 'app.models.dry_tank_SHT11'>
  4851. print("hasattr tank_SHT11: ", hasattr(object, 'tank_SHT11'))
  4852. print("hasattr tank_SHT11.SHT11_Temp: ", hasattr(object, 'tank_SHT11.SHT11_Temp'))
  4853. try:
  4854. SHT11_Temp = tank_SHT11.SHT11_Temp
  4855. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4856. except AttributeError:
  4857. SHT11_Temp = " — "
  4858. SHT11_Humidity = " — "
  4859. # if not hasattr(object, 'tank_SHT11.SHT11_Temp'):
  4860. # SHT11_Temp = " — "
  4861. # SHT11_Humidity = " — "
  4862. # else:
  4863. # SHT11_Temp = tank_SHT11.SHT11_Temp
  4864. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4865. # tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4866. # SHT11_Temp = tank_SHT11.SHT11_Temp
  4867. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4868. # 感測器_乾燥桶_土壤三合一
  4869. tank_Soil = dry_tank_Soil.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4870. soil_Temp = tank_Soil.soil_Temp
  4871. soil_Humidity = tank_Soil.soil_Humidity
  4872. soil_EC = tank_Soil.soil_EC
  4873. # 感測器_乾燥桶_氣壓
  4874. tank_PA = dry_tank_PA.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4875. PA = tank_PA.PA
  4876. # 致動器_乾燥桶_ALL
  4877. tank_brake = dry_tank_brake.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4878. # tank_vacuum = 'ON' if i<100 else 2 if i>100 else 0
  4879. tank_vacuum = tank_brake.vacuum
  4880. tank_threewayvalve_input = tank_brake.threewayvalve_input
  4881. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  4882. tank_diskvalve = tank_brake.diskvalve
  4883. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  4884. tank_solenoid_water = tank_brake.solenoid_water
  4885. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  4886. tank_motor = tank_brake.motor
  4887. tank_blower = tank_brake.blower
  4888. tank_heater1 = tank_brake.heater1
  4889. tank_heater2 = tank_brake.heater2
  4890. tank_temp1_enable = tank_brake.temp1_enable
  4891. tank_temp1 = tank_brake.temp1
  4892. #return jsonify({"peeling": peeling_rpm})
  4893. '''
  4894. info = psutil.virtual_memory()
  4895. print('記憶體使用: ', psutil.Process(os.getpid()).memory_info().rss)
  4896. # print('總記憶體: ', info.total)
  4897. print('記憶體占比: ', info.percent)
  4898. print('cpu 個數: ', psutil.cpu_count())
  4899. '''
  4900. print("SHT11_Temp", SHT11_Temp)
  4901. return jsonify({"UltraSonic":UltraSonic,
  4902. "SHT11_Temp": SHT11_Temp,
  4903. "SHT11_Humidity":SHT11_Humidity,
  4904. "soil_Temp":soil_Temp,
  4905. "soil_Humidity":soil_Humidity,
  4906. "soil_EC":soil_EC,
  4907. "PA":PA,
  4908. "tank_vacuum":tank_vacuum,
  4909. "tank_threewayvalve_input":tank_threewayvalve_input,
  4910. "tank_threewayvalve_bean":tank_threewayvalve_bean,
  4911. "tank_diskvalve":tank_diskvalve,
  4912. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  4913. "tank_solenoid_water":tank_solenoid_water,
  4914. "tank_solenoid_outer_water":tank_solenoid_outer_water,
  4915. "tank_motor":tank_motor,
  4916. "tank_blower":tank_blower,
  4917. "tank_heater1":tank_heater1,
  4918. "tank_heater2":tank_heater2,
  4919. "tank_temp1_enable":tank_temp1_enable,
  4920. "tank_temp1":tank_temp1
  4921. })
  4922. else:
  4923. pass
  4924. @main.route('/index_new')
  4925. def index_new():
  4926. if 'id' in session and 'uname' in session and 'status' in session:
  4927. username = session['uname']
  4928. status = session['status']
  4929. if status == 9:
  4930. return render_template('signin_disable.html', **locals())
  4931. elif status == 8:
  4932. return render_template('signin_new.html', **locals())
  4933. else:
  4934. return render_template('oops.html', **locals())
  4935. return render_template('index_new.html', title='Smart Coffee', **locals())
  4936. @main.route('/user/<name>')
  4937. def user(name):
  4938. return render_template('hello.html', name=name)
  4939. '''
  4940. @main.route('/plot.png')
  4941. def plot():
  4942. # 重新整理會有問題
  4943. # 圖的寬和高
  4944. fig = plt.figure()
  4945. # 在圖中新增子圖, 通常多個圖才會用到?
  4946. axis = fig.add_subplot(1, 1, 1)
  4947. # x、 軸資料
  4948. xs = range(100)
  4949. ys = [random.randint(1, 50) for x in xs]
  4950. axis.plot(xs, ys)
  4951. canvas = FigureCanvas(fig)
  4952. output = io.BytesIO()
  4953. canvas.print_png(output)
  4954. response = make_response(output.getvalue())
  4955. response.mimetype = 'image/png'
  4956. return response
  4957. '''
  4958. @main.route('/chart_<tank>/<sensor_name>/<tid>', methods=['GET', 'POST'])
  4959. def chart_D(tank, sensor_name, tid):
  4960. if request.method == 'GET':
  4961. if 'id' in session and 'uname' in session and 'status' in session:
  4962. username = session['uname']
  4963. status = session['status']
  4964. if status == 9:
  4965. return render_template('signin_disable.html', params=locals())
  4966. elif status == 8:
  4967. return render_template('signin_new.html', params=locals())
  4968. else:
  4969. return render_template('oops.html', params=locals())
  4970. if tank == 'DI':
  4971. return render_template('sensor_chart_DI.html', title='[圖表]' + tank + tid + '乾燥入料儲豆槽', **locals())
  4972. elif tank == 'DO':
  4973. return render_template('sensor_chart_DO.html', title='[圖表]' + tank + tid + '乾燥出料儲豆槽', **locals())
  4974. elif tank == 'FI':
  4975. return render_template('sensor_chart_FI.html', title='[圖表]' + tank + tid + '發酵入料儲豆槽', **locals())
  4976. elif tank == 'FO':
  4977. return render_template('sensor_chart_FO.html', title='[圖表]' + tank + tid + '發酵出料儲豆槽', **locals())
  4978. elif tank == 'F':
  4979. return render_template('sensor_chart_F.html', title='[圖表]' + tank + tid + '發酵槽', **locals())
  4980. else:
  4981. return render_template('sensor_chart_D.html', title='[圖表]' + tank + tid + '乾燥槽', **locals())
  4982. elif request.method == 'POST':
  4983. if 'id' in session and 'uname' in session and 'status' in session:
  4984. username = session['uname']
  4985. status = session['status']
  4986. if status == 9:
  4987. return render_template('signin_disable.html', **locals())
  4988. elif status == 8:
  4989. return render_template('signin_new.html', **locals())
  4990. else:
  4991. return render_template('oops.html', **locals())
  4992. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  4993. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  4994. sensor_name = request.values['sensors']
  4995. print('sensor_name:', sensor_name)
  4996. # 判斷資料索取區間 起<迄
  4997. if starttime < endtime :
  4998. # print('starttime endtime:', starttime, endtime)
  4999. # print('TF:', starttime<endtime ) # 可以比較 起<迄
  5000. # [html]2021-07-19T09:00 轉換成 [python]datetime.datetime(2021, 07, 19, 09, 00, 00)
  5001. start_YY = starttime[:4] # '2021'
  5002. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5003. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5004. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5005. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5006. start_ss = 0
  5007. end_YY = endtime[:4] # '2021'
  5008. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5009. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5010. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5011. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5012. end_ss = 0
  5013. time_range = []
  5014. temp_range = []
  5015. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5016. plt.switch_backend('agg')
  5017. plt.figure()
  5018. if tank == 'DI':
  5019. print('DI')
  5020. if sensor_name == 'UltraSonic':
  5021. for d in db.session.query(dry_input_sensor) \
  5022. .filter_by(tank_num='DI' + tid) \
  5023. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_input_sensor.datetime) \
  5024. .filter(dry_input_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5025. .order_by(dry_input_sensor.datetime):
  5026. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5027. time_range.append(str(d.datetime))
  5028. temp_range.append(float(d.UltraSonic))
  5029. print('time_range:', time_range)
  5030. print('temp_range:', temp_range)
  5031. return render_template('sensor_chart_DI.html', **locals())
  5032. elif tank == 'DO':
  5033. print('DO')
  5034. if sensor_name == 'UltraSonic':
  5035. for d in db.session.query(dry_output_sensor) \
  5036. .filter_by(tank_num='DO' + tid) \
  5037. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_output_sensor.datetime) \
  5038. .filter(dry_output_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5039. .order_by(dry_output_sensor.datetime):
  5040. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5041. time_range.append(str(d.datetime))
  5042. temp_range.append(float(d.UltraSonic))
  5043. print('time_range:', time_range)
  5044. print('temp_range:', temp_range)
  5045. return render_template('sensor_chart_DO.html', **locals())
  5046. elif tank == 'D':
  5047. print('D')
  5048. if sensor_name == 'SHT11_Temp':
  5049. for d in db.session.query(dry_tank_SHT11) \
  5050. .filter_by(tank_num='D' + tid) \
  5051. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  5052. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5053. .order_by(dry_tank_SHT11.datetime):
  5054. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5055. time_range.append(str(d.datetime))
  5056. temp_range.append(float(d.SHT11_Temp))
  5057. # 畫出 x 軸基準線
  5058. # plt.axhline(28.5, color= 'r')
  5059. elif sensor_name == 'SHT11_Humidity':
  5060. for d in db.session.query(dry_tank_SHT11) \
  5061. .filter_by(tank_num='D' + tid) \
  5062. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  5063. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5064. .order_by(dry_tank_SHT11.datetime):
  5065. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5066. time_range.append(str(d.datetime))
  5067. temp_range.append(float(d.SHT11_Humidity))
  5068. elif sensor_name == 'UltraSonic':
  5069. for d in db.session.query(dry_tank_UltraSonic) \
  5070. .filter_by(tank_num='D' + tid) \
  5071. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5072. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5073. .order_by(dry_tank_UltraSonic.datetime):
  5074. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5075. time_range.append(str(d.datetime))
  5076. temp_range.append(float(d.UltraSonic))
  5077. elif sensor_name == 'PA':
  5078. for d in db.session.query(dry_tank_PA) \
  5079. .filter_by(tank_num='D' + tid) \
  5080. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_PA.datetime) \
  5081. .filter(dry_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5082. .order_by(dry_tank_PA.datetime):
  5083. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5084. time_range.append(str(d.datetime))
  5085. temp_range.append(float(d.PA))
  5086. elif sensor_name == 'soil_Temp':
  5087. for d in db.session.query(dry_tank_Soil) \
  5088. .filter_by(tank_num='D' + tid) \
  5089. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5090. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5091. .order_by(dry_tank_Soil.datetime):
  5092. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5093. time_range.append(str(d.datetime))
  5094. temp_range.append(float(d.soil_Temp))
  5095. # 畫出 x 軸基準線
  5096. plt.axhline(28.5, color= 'r')
  5097. elif sensor_name == 'soil_Humidity':
  5098. for d in db.session.query(dry_tank_Soil) \
  5099. .filter_by(tank_num='D' + tid) \
  5100. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5101. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5102. .order_by(dry_tank_Soil.datetime):
  5103. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5104. time_range.append(str(d.datetime))
  5105. temp_range.append(float(d.soil_Humidity))
  5106. elif sensor_name == 'soil_EC':
  5107. for d in db.session.query(dry_tank_Soil) \
  5108. .filter_by(tank_num='D' + tid) \
  5109. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5110. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5111. .order_by(dry_tank_Soil.datetime):
  5112. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5113. time_range.append(str(d.datetime))
  5114. temp_range.append(float(d.soil_EC))
  5115. print('time_range:', time_range)
  5116. print('temp_range:', temp_range)
  5117. return render_template('sensor_chart_D.html', **locals())
  5118. elif tank == 'FI':
  5119. print('FI')
  5120. if sensor_name == 'UltraSonic':
  5121. for d in db.session.query(ferment_input_UltraSonic) \
  5122. .filter_by(tank_num='FI' + tid) \
  5123. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_input_UltraSonic.datetime) \
  5124. .filter(ferment_input_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5125. .order_by(ferment_input_UltraSonic.datetime):
  5126. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5127. time_range.append(str(d.datetime))
  5128. temp_range.append(float(d.UltraSonic))
  5129. print('time_range:', time_range)
  5130. print('temp_range:', temp_range)
  5131. return render_template('sensor_chart_FI.html', **locals())
  5132. elif tank == 'FO':
  5133. print('FO')
  5134. if sensor_name == 'UltraSonic':
  5135. for d in db.session.query(ferment_output_UltraSonic) \
  5136. .filter_by(tank_num='FO' + tid) \
  5137. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_output_UltraSonic.datetime) \
  5138. .filter(ferment_output_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5139. .order_by(ferment_output_UltraSonic.datetime):
  5140. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5141. time_range.append(str(d.datetime))
  5142. temp_range.append(float(d.UltraSonic))
  5143. print('time_range:', time_range)
  5144. print('temp_range:', temp_range)
  5145. return render_template('sensor_chart_FO.html', **locals())
  5146. elif tank == 'F':
  5147. print('F')
  5148. if sensor_name == 'LiDAR':
  5149. for d in db.session.query(ferment_tank_LiDAR) \
  5150. .filter_by(tank_num='F' + tid) \
  5151. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_LiDAR.datetime) \
  5152. .filter(ferment_tank_LiDAR.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5153. .order_by(ferment_tank_LiDAR.datetime):
  5154. time_range.append(str(d.datetime))
  5155. temp_range.append(float(d.LiDAR))
  5156. elif sensor_name == 'motorEncoder':
  5157. print('sensor_name == motorEncoder')
  5158. for d in db.session.query(ferment_tank_motorEncoder) \
  5159. .filter_by(tank_num='F' + tid) \
  5160. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_motorEncoder.datetime) \
  5161. .filter(ferment_tank_motorEncoder.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5162. .order_by(ferment_tank_motorEncoder.datetime):
  5163. time_range.append(str(d.datetime))
  5164. temp_range.append(float(d.motorEncoder))
  5165. print('time_range: ' + time_range)
  5166. print('temp_range: ' + temp_range)
  5167. elif sensor_name == 'PressureWaterLevel':
  5168. for d in db.session.query(ferment_tank_PressureWaterLevel) \
  5169. .filter_by(tank_num='F' + tid) \
  5170. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  5171. .filter(ferment_tank_PressureWaterLevel.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5172. .order_by(ferment_tank_PressureWaterLevel.datetime):
  5173. time_range.append(str(d.datetime))
  5174. temp_range.append('{:.2f}'.format(float(d.PressureWaterLevel)))
  5175. elif sensor_name == 'SHT11_Temp':
  5176. for d in db.session.query(ferment_tank_SHT11) \
  5177. .filter_by(tank_num='F' + tid) \
  5178. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  5179. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5180. .order_by(ferment_tank_SHT11.datetime):
  5181. time_range.append(str(d.datetime))
  5182. temp_range.append(float(d.SHT11_Temp))
  5183. elif sensor_name == 'SHT11_Humidity':
  5184. for d in db.session.query(ferment_tank_SHT11) \
  5185. .filter_by(tank_num='F' + tid) \
  5186. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_SHT11.datetime) \
  5187. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5188. .order_by(ferment_tank_SHT11.datetime):
  5189. time_range.append(str(d.datetime))
  5190. temp_range.append(float(d.SHT11_Humidity))
  5191. elif sensor_name == 'CO2':
  5192. for d in db.session.query(ferment_tank_CO2) \
  5193. .filter_by(tank_num='F' + tid) \
  5194. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_CO2.datetime) \
  5195. .filter(ferment_tank_CO2.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5196. .order_by(ferment_tank_CO2.datetime):
  5197. time_range.append(str(d.datetime))
  5198. temp_range.append(float(d.CO2))
  5199. elif sensor_name == 'PH':
  5200. for d in db.session.query(ferment_tank_PH) \
  5201. .filter_by(tank_num='F' + tid) \
  5202. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PH.datetime) \
  5203. .filter(ferment_tank_PH.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5204. .order_by(ferment_tank_PH.datetime):
  5205. time_range.append(str(d.datetime))
  5206. temp_range.append(float(d.PH))
  5207. elif sensor_name == 'ORP':
  5208. for d in db.session.query(ferment_tank_ORP) \
  5209. .filter_by(tank_num='F' + tid) \
  5210. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_ORP.datetime) \
  5211. .filter(ferment_tank_ORP.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5212. .order_by(ferment_tank_ORP.datetime):
  5213. time_range.append(str(d.datetime))
  5214. temp_range.append(float(d.ORP))
  5215. elif sensor_name == 'DO':
  5216. for d in db.session.query(ferment_tank_DO) \
  5217. .filter_by(tank_num='F' + tid) \
  5218. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_DO.datetime) \
  5219. .filter(ferment_tank_DO.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5220. .order_by(ferment_tank_DO.datetime):
  5221. time_range.append(str(d.datetime))
  5222. temp_range.append(float(d.DO))
  5223. elif sensor_name == 'EC':
  5224. for d in db.session.query(ferment_tank_EC) \
  5225. .filter_by(tank_num='F' + tid) \
  5226. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_EC.datetime) \
  5227. .filter(ferment_tank_EC.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5228. .order_by(ferment_tank_EC.datetime):
  5229. time_range.append(str(d.datetime))
  5230. temp_range.append(float(d.EC))
  5231. elif sensor_name == 'PA':
  5232. for d in db.session.query(ferment_tank_PA) \
  5233. .filter_by(tank_num='F' + tid) \
  5234. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PA.datetime) \
  5235. .filter(ferment_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5236. .order_by(ferment_tank_PA.datetime):
  5237. time_range.append(str(d.datetime))
  5238. temp_range.append(float(d.PA))
  5239. print('time_range:', time_range)
  5240. print('temp_range:', temp_range)
  5241. return render_template('sensor_chart_F.html', **locals())
  5242. '''
  5243. # 設定 x 軸資料、y 軸資料、折線顏色
  5244. plt.plot(time_range, temp_range, 'bo')
  5245. # x 軸標題 (中文無法顯示)
  5246. # plt.xlabel('time')
  5247. # plt.ylabel(sensor_name)
  5248. # x 軸 label 和垂直顯示, rotation='vertical'
  5249. plt.xticks(time_range, rotation='vertical' )
  5250. # 設定圖表標題
  5251. plt.title(sensor_name)
  5252. # 調整圖片與周圍的間距
  5253. plt.tight_layout()
  5254. # plt.show()
  5255. # 儲存圖片 應改為相對路徑
  5256. plt.savefig('C:/Users/USER/Rita/Coffee/CoffeeProject/app/static/img/new_plot.png')
  5257. '''
  5258. # 判斷資料索取區間 起>迄
  5259. else:
  5260. return render_template('sensor_chart_D.html', **locals())
  5261. '''
  5262. @main.route('/chart_DI/<sensor_name>/<tid>', methods=['GET', 'POST'])
  5263. def chart_DI(sensor_name, tid):
  5264. if request.method == 'GET':
  5265. return render_template('sensor_chart_DI.html', **locals())
  5266. elif request.method == 'POST':
  5267. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  5268. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  5269. sensor_name = request.values['sensors']
  5270. print('sensor_name:', sensor_name)
  5271. # 判斷資料索取區間 起<迄
  5272. if starttime < endtime :
  5273. start_YY = starttime[:4] # '2021'
  5274. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5275. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5276. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5277. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5278. start_ss = 0
  5279. end_YY = endtime[:4] # '2021'
  5280. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5281. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5282. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5283. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5284. end_ss = 0
  5285. time_range = []
  5286. temp_range = []
  5287. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5288. plt.switch_backend('agg')
  5289. plt.figure()
  5290. if sensor_name == 'UltraSonic':
  5291. for d in db.session.query(dry_input_sensor) \
  5292. .filter_by(tank_num='DI' + tid) \
  5293. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5294. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5295. .order_by(dry_tank_UltraSonic.datetime):
  5296. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5297. time_range.append(str(d.datetime))
  5298. temp_range.append(float(d.UltraSonic))
  5299. # 畫出 x 軸基準線
  5300. # plt.axhline(28.5, color= 'r')
  5301. print('time_range:', time_range)
  5302. print('temp_range:', temp_range)
  5303. return render_template('sensor_chart_DI.html', **locals())
  5304. # 判斷資料索取區間 起>迄
  5305. else:
  5306. return render_template('sensor_chart_DI.html', **locals())
  5307. @main.route('/chart_DO/<sensor_name>/<tid>', methods=['GET', 'POST'])
  5308. def chart_DO(sensor_name, tid):
  5309. if request.method == 'GET':
  5310. return render_template('sensor_chart_DO.html', **locals())
  5311. elif request.method == 'POST':
  5312. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  5313. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  5314. sensor_name = request.values['sensors']
  5315. print('sensor_name:', sensor_name)
  5316. # 判斷資料索取區間 起<迄
  5317. if starttime < endtime :
  5318. start_YY = starttime[:4] # '2021'
  5319. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5320. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5321. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5322. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5323. start_ss = 0
  5324. end_YY = endtime[:4] # '2021'
  5325. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5326. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5327. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5328. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5329. end_ss = 0
  5330. time_range = []
  5331. temp_range = []
  5332. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5333. plt.switch_backend('agg')
  5334. plt.figure()
  5335. if sensor_name == 'UltraSonic':
  5336. for d in db.session.query(dry_input_sensor) \
  5337. .filter_by(tank_num='DO' + tid) \
  5338. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5339. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5340. .order_by(dry_tank_UltraSonic.datetime):
  5341. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5342. time_range.append(str(d.datetime))
  5343. temp_range.append(float(d.UltraSonic))
  5344. # 畫出 x 軸基準線
  5345. # plt.axhline(28.5, color= 'r')
  5346. print('time_range:', time_range)
  5347. print('temp_range:', temp_range)
  5348. return render_template('sensor_chart_DO.html', **locals())
  5349. # 判斷資料索取區間 起>迄
  5350. else:
  5351. return render_template('sensor_chart_DO.html', **locals())
  5352. '''
  5353. # Rita 測試
  5354. # 乾燥桶感測器/致動器測試
  5355. # Rita 須加上 <tid> 區分桶號 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5356. @main.route('/dry_tank/1', methods=['GET'])
  5357. def dry_tank():
  5358. if request.method == 'GET':
  5359. return render_template('dry_tank.html')
  5360. @main.route('/clean', methods=['GET'])
  5361. def clean():
  5362. if 'id' in session and 'uname' in session and 'status' in session:
  5363. username = session['uname']
  5364. status = session['status']
  5365. if status == 9:
  5366. return render_template('signin_disable.html', params=locals())
  5367. elif status == 8:
  5368. return render_template('signin_new.html', params=locals())
  5369. else:
  5370. return render_template('oops.html', params=locals())
  5371. return render_template('clean.html', title='清洗貨櫃', **locals())
  5372. @main.route('/ferment', methods=['GET'])
  5373. def ferment():
  5374. if 'id' in session and 'uname' in session and 'status' in session:
  5375. username = session['uname']
  5376. status = session['status']
  5377. if status == 9:
  5378. return render_template('signin_disable.html', params=locals())
  5379. elif status == 8:
  5380. return render_template('signin_new.html', params=locals())
  5381. else:
  5382. return render_template('oops.html', params=locals())
  5383. return render_template('ferment.html', title='發酵貨櫃', **locals())
  5384. @main.route('/dry', methods=['GET'])
  5385. def dry():
  5386. if request.method == 'GET':
  5387. if 'id' in session and 'uname' in session and 'status' in session:
  5388. username = session['uname']
  5389. status = session['status']
  5390. if status == 9:
  5391. return render_template('signin_disable.html', params=locals())
  5392. elif status == 8:
  5393. return render_template('signin_new.html', params=locals())
  5394. else:
  5395. return render_template('oops.html', params=locals())
  5396. return render_template('dry.html', title='乾燥貨櫃', **locals())
  5397. @main.route('/reclaimedwater_tank/<tid>', methods=['GET', 'POST'])
  5398. def reclaimedwater_tank(tid):
  5399. if request.method == 'GET':
  5400. if 'id' in session and 'uname' in session and 'status' in session:
  5401. username = session['uname']
  5402. status = session['status']
  5403. if status == 9:
  5404. return render_template('signin_disable.html', params=locals())
  5405. elif status == 8:
  5406. return render_template('signin_new.html', params=locals())
  5407. else:
  5408. return render_template('oops.html', params=locals())
  5409. # 致動器_中水桶
  5410. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+tid).order_by(text('datetime desc')).first()
  5411. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  5412. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  5413. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  5414. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  5415. return render_template('reclaimedwater_tank.html', title='[操作] 中水桶操作介面', **locals())
  5416. elif request.method == 'POST':
  5417. pass
  5418. @main.route('/colorselect_container_tank/<tid>', methods=['GET', 'POST'])
  5419. def colorselect_container_tank(tid):
  5420. if request.method == 'GET':
  5421. if 'id' in session and 'uname' in session and 'status' in session:
  5422. username = session['uname']
  5423. status = session['status']
  5424. if status == 9:
  5425. return render_template('signin_disable.html', params=locals())
  5426. elif status == 8:
  5427. return render_template('signin_new.html', params=locals())
  5428. else:
  5429. return render_template('oops.html', params=locals())
  5430. # 致動器_色選機
  5431. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5432. tank_vacuum = tank_actuator.vacuum
  5433. tank_motor = tank_actuator.motor
  5434. tank_nozzle = tank_actuator.nozzle
  5435. # 致動器_超音波感測器colorselect_tank_UltraSonic
  5436. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5437. # 致動器_顏色感測器
  5438. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5439. return render_template('colorselect_container_tank.html', title='[操作] S' + tid + ' 色選機操作介面', **locals())
  5440. elif request.method == 'POST':
  5441. pass
  5442. @main.route('/peel_container_tank/<tid>', methods=['GET', 'POST'])
  5443. def peel_container_tank(tid):
  5444. if request.method == 'GET':
  5445. if 'id' in session and 'uname' in session and 'status' in session:
  5446. username = session['uname']
  5447. status = session['status']
  5448. if status == 9:
  5449. return render_template('signin_disable.html', params=locals())
  5450. elif status == 8:
  5451. return render_template('signin_new.html', params=locals())
  5452. else:
  5453. return render_template('oops.html', params=locals())
  5454. # 致動器_脫皮機_ALL
  5455. # tank_num='P'+str(tid)
  5456. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5457. tank_vacuum = tank_actuator.vacuum
  5458. tank_motor = tank_actuator.motor
  5459. # 感測器_脫皮機出料儲豆槽_超音波高度
  5460. tank_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5461. # 感測器_脫皮機出料儲豆槽_馬達編碼器
  5462. tank_motorEncoder = peel_output_motorEncoder.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5463. return render_template('peel_container_tank.html', title='[操作] P' + tid + ' 脫皮機操作介面', **locals())
  5464. elif request.method == 'POST':
  5465. pass
  5466. @main.route('/peel_container/<tid>', methods=['GET', 'POST'])
  5467. def peel_container(tid):
  5468. if request.method == 'GET':
  5469. if 'id' in session and 'uname' in session and 'status' in session:
  5470. username = session['uname']
  5471. status = session['status']
  5472. if status == 9:
  5473. return render_template('signin_disable.html', params=locals())
  5474. elif status == 8:
  5475. return render_template('signin_new.html', params=locals())
  5476. else:
  5477. return render_template('oops.html', params=locals())
  5478. # 致動器_入料儲豆槽_真空吸料機
  5479. input_vacuum = peel_input_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5480. input_vacuum = input_vacuum.vacuum
  5481. # 致動器_脫皮機_ALL
  5482. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5483. tank_vacuum = tank_actuator.vacuum
  5484. tank_motor = tank_actuator.motor
  5485. # 致動器_出料儲豆槽_真空吸料機
  5486. output_vacuum = peel_output_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5487. output_vacuum = output_vacuum.vacuum
  5488. return render_template('peel_container.html', title='脫皮機P' + tid + '總操作介面', **locals())
  5489. elif request.method == 'POST':
  5490. pass
  5491. @main.route('/clean_container/<tid>', methods=['GET', 'POST'])
  5492. def clean_container(tid):
  5493. if request.method == 'GET':
  5494. if 'id' in session and 'uname' in session and 'status' in session:
  5495. username = session['uname']
  5496. status = session['status']
  5497. if status == 9:
  5498. return render_template('signin_disable.html', params=locals())
  5499. elif status == 8:
  5500. return render_template('signin_new.html', params=locals())
  5501. else:
  5502. return render_template('oops.html', params=locals())
  5503. # 致動器_入料儲豆槽_真空吸料機
  5504. input_vacuum = clean_input_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5505. input_vacuum = 'ON' if (input_vacuum.vacuum == 1) else 'OFF'
  5506. # 致動器_浮選清洗_ALL
  5507. tank_actuator = clean_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5508. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5509. tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  5510. tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  5511. tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  5512. tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  5513. tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  5514. tank_stepping_motor = tank_actuator.stepping_motor
  5515. # 致動器_出料儲豆槽_真空吸料機
  5516. output_vacuum = clean_output_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5517. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  5518. # 感測器_浮選清洗_超音波感測器
  5519. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5520. return render_template('clean_container.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  5521. elif request.method == 'POST':
  5522. pass
  5523. @main.route('/clean_container_tank/<tid>', methods=['GET', 'POST'])
  5524. def clean_container_tank(tid):
  5525. if request.method == 'GET':
  5526. if 'id' in session and 'uname' in session and 'status' in session:
  5527. username = session['uname']
  5528. status = session['status']
  5529. if status == 9:
  5530. return render_template('signin_disable.html', params=locals())
  5531. elif status == 8:
  5532. return render_template('signin_new.html', params=locals())
  5533. else:
  5534. return render_template('oops.html', params=locals())
  5535. # 致動器_浮選清洗_ALL
  5536. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5537. tank_vacuum = tank_actuator.vacuum
  5538. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  5539. tank_motor = tank_actuator.motor
  5540. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  5541. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  5542. tank_pump_water_in = tank_actuator.pump_water_in
  5543. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  5544. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  5545. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  5546. tank_pump_disinfect = tank_actuator.pump_disinfect
  5547. tank_diskvalve = tank_actuator.diskvalve
  5548. # tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  5549. # tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  5550. # tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  5551. # tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  5552. # tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  5553. # tank_stepping_motor = tank_actuator.stepping_motor
  5554. # 感測器_浮選清洗_超音波感測器
  5555. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5556. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5557. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5558. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5559. return render_template('clean_container_tank.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  5560. elif request.method == 'POST':
  5561. pass
  5562. @main.route('/ferment_container/<tid>', methods=['GET', 'POST'])
  5563. def ferment_container(tid):
  5564. if request.method == 'GET':
  5565. if 'id' in session and 'uname' in session and 'status' in session:
  5566. username = session['uname']
  5567. status = session['status']
  5568. if status == 9:
  5569. return render_template('signin_disable.html', params=locals())
  5570. elif status == 8:
  5571. return render_template('signin_new.html', params=locals())
  5572. else:
  5573. return render_template('oops.html', params=locals())
  5574. # 致動器_發酵槽_ALL
  5575. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5576. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5577. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  5578. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  5579. tank_solenoid_water_total = 'ON' if tank_actuator.solenoid_tank_water_total == 1 else 'OFF'
  5580. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  5581. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  5582. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  5583. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  5584. tank_threewayvalve_bean = 'ON' if tank_actuator.threewayvalve_bean == 1 else 'OFF'
  5585. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  5586. tank_motor = tank_actuator.motor
  5587. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  5588. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  5589. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  5590. tank_temp = tank_actuator.temp
  5591. # 感測器_發酵桶_SHT11
  5592. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5593. # 感測器_發酵桶_二氧化碳
  5594. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5595. # 感測器_發酵桶_酸鹼值
  5596. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5597. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5598. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5599. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5600. # 感測器_發酵桶_氣壓
  5601. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5602. # 感測器_發酵桶_超音波感測器
  5603. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5604. # 感測器_發酵桶_水位計
  5605. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5606. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  5607. print('tank_WaterLevel', tank_WaterLevel.WaterLevel)
  5608. if tank_WaterLevel.WaterLevel == '1':
  5609. WaterLevel = '滿'
  5610. elif tank_WaterLevel.WaterLevel == '0':
  5611. WaterLevel = '未達滿水高度'
  5612. else:
  5613. WaterLevel = 'ERROR'
  5614. # 感測器_發酵桶_咖啡生豆高度
  5615. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5616. LiDAR = tank_LiDAR.LiDAR
  5617. # 感測器_發酵桶_水位高度
  5618. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5619. PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  5620. if tid in ['1', '2', '3', '4', '5', '6']:
  5621. # print("1")
  5622. # 感測器_入料儲豆槽_超音波感測器
  5623. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  5624. # 致動器_入料儲豆槽_真空吸引機
  5625. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  5626. input_vacuum = input_vacuum.vacuum
  5627. # 感測器_出料儲豆槽_超音波感測器
  5628. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  5629. # 致動器_出料儲豆槽_真空吸引機
  5630. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  5631. output_vacuum = output_vacuum.vacuum
  5632. elif tid in ['7', '8', '9', '10', '11', '12']:
  5633. # print("2")
  5634. # 感測器_入料儲豆槽_超音波感測器
  5635. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  5636. # 致動器_入料儲豆槽_真空吸引機
  5637. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  5638. input_vacuum = input_vacuum.vacuum
  5639. print("input_vacuum", input_vacuum)
  5640. # 感測器_出料儲豆槽_超音波感測器
  5641. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  5642. # 致動器_出料儲豆槽_真空吸引機
  5643. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  5644. output_vacuum = output_vacuum.vacuum
  5645. print("output_vacuum", output_vacuum)
  5646. return render_template('ferment_container.html', title='發酵槽F' + tid + '總操作介面' , **locals())
  5647. elif request.method == 'POST':
  5648. pass
  5649. @main.route('/ferment_container_tank/<tid>', methods=['GET', 'POST'])
  5650. def ferment_container_tank(tid):
  5651. if request.method == 'GET':
  5652. if 'id' in session and 'uname' in session and 'status' in session:
  5653. username = session['uname']
  5654. status = session['status']
  5655. if status == 9:
  5656. return render_template('signin_disable.html', params=locals())
  5657. elif status == 8:
  5658. return render_template('signin_new.html', params=locals())
  5659. else:
  5660. return render_template('oops.html', params=locals())
  5661. # 致動器_發酵槽_ALL
  5662. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5663. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5664. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  5665. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  5666. solenoid_tank_pump = 'ON' if tank_actuator.solenoid_tank_pump == 1 else 'OFF'
  5667. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  5668. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  5669. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  5670. tank_solenoid_water_out = 'ON' if tank_actuator.solenoid_tank_water_out == 1 else 'OFF'
  5671. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  5672. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  5673. tank_motor = tank_actuator.motor
  5674. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  5675. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  5676. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  5677. tank_temp = tank_actuator.temp
  5678. # 感測器_發酵桶_SHT11
  5679. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5680. # 感測器_發酵桶_二氧化碳
  5681. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5682. # 感測器_發酵桶_酸鹼值
  5683. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5684. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5685. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5686. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5687. # 感測器_發酵桶_氣壓
  5688. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5689. # 感測器_發酵桶_超音波感測器
  5690. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5691. # 感測器_發酵桶_水位計
  5692. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5693. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  5694. if tank_WaterLevel.WaterLevel == '1':
  5695. WaterLevel = '滿'
  5696. elif tank_WaterLevel.WaterLevel == '0':
  5697. WaterLevel = '未達滿水高度'
  5698. else:
  5699. WaterLevel = 'ERROR'
  5700. # 感測器_發酵桶_咖啡生豆高度
  5701. #tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5702. #LiDAR = tank_LiDAR.LiDAR
  5703. # 感測器_發酵桶_水位高度
  5704. #tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5705. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  5706. # 感測器_發酵桶_馬達編碼器
  5707. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5708. return render_template('ferment_container_tank.html', title='[操作] F' + tid + ' 發酵槽操作介面', **locals())
  5709. elif request.method == 'POST':
  5710. pass
  5711. @main.route('/ferment_container_input/<tid>', methods=['GET', 'POST'])
  5712. def ferment_container_input(tid):
  5713. if request.method == 'GET':
  5714. if 'id' in session and 'uname' in session and 'status' in session:
  5715. username = session['uname']
  5716. status = session['status']
  5717. if status == 9:
  5718. return render_template('signin_disable.html', params=locals())
  5719. elif status == 8:
  5720. return render_template('signin_new.html', params=locals())
  5721. else:
  5722. return render_template('oops.html', params=locals())
  5723. # 感測器_入料儲豆槽_超音波感測器
  5724. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  5725. # 致動器_入料儲豆槽_真空吸引機
  5726. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  5727. input_vacuum = input_vacuum.vacuum
  5728. return render_template('ferment_container_input.html', title='[操作] FI' + tid + ' 發酵入料儲豆槽操作介面', **locals())
  5729. elif request.method == 'POST':
  5730. pass
  5731. @main.route('/ferment_container_output/<tid>', methods=['GET', 'POST'])
  5732. def ferment_container_output(tid):
  5733. if request.method == 'GET':
  5734. if 'id' in session and 'uname' in session and 'status' in session:
  5735. username = session['uname']
  5736. status = session['status']
  5737. if status == 9:
  5738. return render_template('signin_disable.html', params=locals())
  5739. elif status == 8:
  5740. return render_template('signin_new.html', params=locals())
  5741. else:
  5742. return render_template('oops.html', params=locals())
  5743. # 感測器_出料儲豆槽_超音波感測器
  5744. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  5745. # 致動器_出料儲豆槽_真空吸引機
  5746. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  5747. output_vacuum = output_vacuum.vacuum
  5748. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5749. LiDAR = tank_LiDAR.LiDAR
  5750. return render_template('ferment_container_output.html', title='[操作] FO' + tid + ' 發酵出料儲豆槽操作介面', **locals())
  5751. elif request.method == 'POST':
  5752. pass
  5753. @main.route('/dry_container_schedule', methods=['GET', 'POST'])
  5754. def dry_container_schedule():
  5755. if request.method == 'GET':
  5756. if 'id' in session and 'uname' in session:
  5757. username = session['uname']
  5758. # 感測器_入料儲豆槽_超音波感測器
  5759. input_UltraSonic = dry_input_sensor.query.order_by(text('datetime desc')).first()
  5760. # 感測器_乾燥桶_超音波感測器
  5761. tank_UltraSonic = dry_tank_UltraSonic.query.order_by(text('datetime desc')).first()
  5762. return render_template('dry_container_schedule.html', title='dry_container_schedule', **locals())
  5763. elif request.method == 'POST':
  5764. pass
  5765. @main.route('/dry_block', methods=['GET', 'POST'])
  5766. def dry_block():
  5767. if request.method == 'GET':
  5768. if 'id' in session and 'uname' in session:
  5769. username = session['uname']
  5770. return render_template('dry_block.html', title='dry_container_schedule', **locals())
  5771. elif request.method == 'POST':
  5772. pass
  5773. # 積木程式
  5774. @main.route('/dry_block_set', methods=['GET', 'POST'])
  5775. def dry_block_set():
  5776. if request.method == 'GET':
  5777. if 'id' in session and 'uname' in session:
  5778. username = session['uname']
  5779. info = request.args.to_dict()
  5780. # print("info: ", info, type(info)) # dict
  5781. # 傳回 總條件物件動作 數量
  5782. condition = int(info['condition'])
  5783. # 傳回 子條件 數量
  5784. cond_add_child = int(info['cond_add_child'])
  5785. # 傳回 子物件動作 數量
  5786. act_add_child = int(info['act_add_child'])
  5787. # 傳回 指令
  5788. set_Schedule = eval(info['set_Schedule']) # 字串轉成字典
  5789. # print("set_Schedule: ", set_Schedule, type(set_Schedule)) # dict
  5790. # 拆解條件 / 物件 / 動作
  5791. # # 條件物件取值
  5792. for z in range(1, condition+1, 1):
  5793. # 放要執行的判斷式
  5794. # # if / while
  5795. cond_data = ''
  5796. try:
  5797. z_num = 'cond_z' + str(z) + '_1'
  5798. # print("cond_z_value[z_num]: ", set_Schedule[z_num]) # if
  5799. cond_data += set_Schedule[z_num]
  5800. except KeyError:
  5801. pass
  5802. # # 桶槽號取值
  5803. try:
  5804. tank_num = 'cond_tank' + str(z) + '_1'
  5805. except KeyError:
  5806. pass
  5807. # # 子條件取值
  5808. for x in range(1, cond_add_child+1, 1):
  5809. # d
  5810. try:
  5811. x_num_d = 'cond_d' + str(z) + '_' + str(x)
  5812. # print("cond_d_value[x_num_d]: ", set_Schedule[x_num_d])
  5813. cond_data += ' ' + set_Schedule[x_num_d]
  5814. except KeyError:
  5815. pass
  5816. # a
  5817. x_num_a = 'cond_a' + str(z) + '_' + str(x)
  5818. try:
  5819. x_num_a = 'cond_a' + str(z) + '_' + str(x)
  5820. # print("cond_a_value[x_num_a]: ", set_Schedule[x_num_a])
  5821. cond_data += ' ' + set_Schedule[x_num_a]
  5822. if set_Schedule[x_num_a] == 'input_vacuum_status':
  5823. input_vacuum_status = dry_input_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  5824. print("input_vacuum_status: ", input_vacuum_status)
  5825. elif set_Schedule[x_num_a] == 'tank_vacuum_status':
  5826. tank_vacuum_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  5827. print("tank_vacuum_status: ", tank_vacuum_status)
  5828. elif set_Schedule[x_num_a] == 'tank_threewayvalve_input_status':
  5829. tank_threewayvalve_input_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().threewayvalve_input
  5830. print("tank_threewayvalve_input_status: ", tank_threewayvalve_input_status)
  5831. elif set_Schedule[x_num_a] == 'tank_motor_status':
  5832. tank_motor_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().motor
  5833. print("tank_motor_status: ", tank_motor_status)
  5834. elif set_Schedule[x_num_a] == 'tank_blower_status':
  5835. tank_blower_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().blower
  5836. print("tank_blower_status: ", tank_blower_status)
  5837. elif set_Schedule[x_num_a] == 'tank_heater1_status':
  5838. tank_heater1_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater1
  5839. print("tank_heater1_status: ", tank_heater1_status)
  5840. elif set_Schedule[x_num_a] == 'tank_heater2_status':
  5841. tank_heater2_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater2
  5842. print("tank_heater2_status: ", tank_heater2_status)
  5843. elif set_Schedule[x_num_a] == 'tank_diskvalve_status':
  5844. tank_diskvalve_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().diskvalve
  5845. print("tank_diskvalve_status: ", tank_diskvalve_status)
  5846. elif set_Schedule[x_num_a] == 'tank_solenoid_disinfect_status':
  5847. tank_solenoid_disinfect_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().solenoid_disinfect
  5848. print("tank_solenoid_disinfect_status: ", tank_solenoid_disinfect_status)
  5849. elif set_Schedule[x_num_a] == 'tank_solenoid_water_out_status':
  5850. tank_solenoid_water_out_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().solenoid_water
  5851. print("tank_solenoid_water_out_status: ", tank_solenoid_water_out_status)
  5852. elif set_Schedule[x_num_a] == 'outer_solenoid_water_status':
  5853. outer_solenoid_water_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().solenoid_outer_water
  5854. print("outer_solenoid_water_status: ", outer_solenoid_water_status)
  5855. elif set_Schedule[x_num_a] == 'tank_temp_enable':
  5856. tank_temp_enable = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1_enable
  5857. print("tank_temp_enable: ", tank_temp_enable)
  5858. elif set_Schedule[x_num_a] == 'tank_temp':
  5859. tank_temp = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1
  5860. print("tank_temp: ", tank_temp)
  5861. elif set_Schedule[x_num_a] == 'output_vacuum':
  5862. output_vacuum = dry_output_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  5863. print("output_vacuum: ", output_vacuum)
  5864. elif set_Schedule[x_num_a] == 'input_UltraSonic':
  5865. input_UltraSonic = float(dry_input_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  5866. print("input_UltraSonic: ", input_UltraSonic)
  5867. elif set_Schedule[x_num_a] == 'tank_UltraSonic':
  5868. tank_UltraSonic = float(dry_tank_UltraSonic.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  5869. print("tank_UltraSonic: ", tank_UltraSonic)
  5870. elif set_Schedule[x_num_a] == 'tank_SHT11_Temp':
  5871. tank_SHT11_Temp = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Temp)
  5872. print("tank_SHT11_Temp: ", tank_SHT11_Temp)
  5873. elif set_Schedule[x_num_a] == 'tank_SHT11_Humidity':
  5874. tank_SHT11_Humidity = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Humidity)
  5875. print("tank_SHT11_Humidity: ", tank_SHT11_Humidity)
  5876. elif set_Schedule[x_num_a] == 'tank_soil_Temp':
  5877. tank_soil_Temp = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Temp)
  5878. print("tank_soil_Temp: ", tank_soil_Temp)
  5879. elif set_Schedule[x_num_a] == 'tank_soil_Humidity':
  5880. tank_soil_Humidity = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Humidity)
  5881. print("tank_soil_Humidity: ", tank_soil_Temp)
  5882. elif set_Schedule[x_num_a] == 'tank_soil_EC':
  5883. tank_soil_EC = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_EC)
  5884. print("tank_soil_EC: ", tank_soil_EC)
  5885. elif set_Schedule[x_num_a] == 'tank_PA':
  5886. tank_PA = float(dry_tank_PA.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().PA)
  5887. print("tank_PA: ", tank_PA)
  5888. elif set_Schedule[x_num_a] == 'output_UltraSonic':
  5889. output_UltraSonic = float(dry_output_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  5890. print("output_UltraSonic: ", output_UltraSonic)
  5891. except KeyError:
  5892. pass
  5893. # b
  5894. try:
  5895. x_num_b = 'cond_b' + str(z) + '_' + str(x)
  5896. # print("cond_b_value[x_num_b]: ", set_Schedule[x_num_b])
  5897. cond_b_dict = {'morethan': ' >= ', 'lessthan': ' <= ', 'equal':' == '}
  5898. cond_data += cond_b_dict[set_Schedule[x_num_b]] # cond_b_dict['equal'] 會輸出 ' == '
  5899. except KeyError:
  5900. pass
  5901. # c
  5902. try:
  5903. x_num_c = 'cond_c' + str(z) + '_' + str(x)
  5904. # print("cond_c_value[x_num_c]: ", set_Schedule[x_num_c])
  5905. if set_Schedule[x_num_c] == 'on':
  5906. cond_data += '1'
  5907. elif set_Schedule[x_num_c] == 'off':
  5908. cond_data += '0'
  5909. else:
  5910. cond_data += set_Schedule[x_num_c]
  5911. except KeyError:
  5912. pass
  5913. if x == cond_add_child:
  5914. cond_data += ': '
  5915. # 子物件動作取值
  5916. for y in range(1, act_add_child+1, 1):
  5917. # do_obj
  5918. try:
  5919. y_num_obj = "do_obj" + str(z) + "_" + str(y)
  5920. # print("y_num_obj[y_num_obj]: ", set_Schedule[y_num_obj])
  5921. # cond_data += 'print(\'' + 'mqtt_data("D1", "' + str(set_Schedule[y_num_obj]) + '", '
  5922. if set_Schedule[y_num_obj] == 'time.sleep':
  5923. cond_data += '''
  5924. time.sleep('''
  5925. else:
  5926. cond_data += '''
  5927. mqtt_data('''
  5928. cond_data += '"' + set_Schedule[tank_num] + '", "' + str(set_Schedule[y_num_obj]) + '", '
  5929. except KeyError:
  5930. pass
  5931. try:
  5932. y_num_act = "do_act" + str(z) + "_" + str(y)
  5933. # print("y_num_act[y_num_act]: ", set_Schedule[y_num_act])
  5934. if set_Schedule[y_num_obj] == 'time.sleep':
  5935. cond_data += set_Schedule[y_num_act] + ')'
  5936. else:
  5937. cond_data += '"' + str(set_Schedule[y_num_act]) + '") '
  5938. cond_data += '''
  5939. time.sleep(0.5)'''
  5940. except KeyError:
  5941. pass
  5942. # TODO
  5943. # set_Schedule[z_num] → if / while
  5944. # set_Schedule[x_num_a] → actuator / sensor
  5945. # set_Schedule[x_num_b] → morethan / equal / lessthan
  5946. # set_Schedule[x_num_c] → 數值 / on / off
  5947. # set_Schedule[x_num_d] → or / and
  5948. # set_Schedule[y_num_obj] → actuator
  5949. # set_Schedule[y_num_act] → on / off / 對應數值
  5950. print("cond_data: ", cond_data)
  5951. if cond_data != ': ':
  5952. exec(cond_data)
  5953. return jsonify({"response":"OK"
  5954. })
  5955. elif request.method == 'POST':
  5956. pass
  5957. # 乾燥貨櫃_各致動器控制
  5958. @main.route('/ctrl_DI_<actuator>/<tid>', methods=['GET', 'POST'])
  5959. def ctrl_DI(actuator, tid):
  5960. if request.method == 'GET':
  5961. if actuator == 'Vacuum':
  5962. if 'id' in session and 'uname' in session and 'status' in session:
  5963. username = session['uname']
  5964. status = session['status']
  5965. if status == 9:
  5966. return render_template('signin_disable.html', params=locals())
  5967. elif status == 8:
  5968. return render_template('signin_new.html', params=locals())
  5969. else:
  5970. return render_template('oops.html', params=locals())
  5971. input_brake = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  5972. input_vacuum = input_brake.vacuum
  5973. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  5974. UltraSonic = tank_UltraSonic.UltraSonic
  5975. return render_template('ctrl_DI_Vacuum.html', title='[操作]DI' + tid + '乾燥槽入料_真空吸料機', **locals())
  5976. elif request.method == 'POST':
  5977. pass
  5978. @main.route('/ctrl_DO_<actuator>/<tid>', methods=['GET', 'POST'])
  5979. def ctrl_DO(actuator, tid):
  5980. if request.method == 'GET':
  5981. if 'id' in session and 'uname' in session and 'status' in session:
  5982. username = session['uname']
  5983. status = session['status']
  5984. if status == 9:
  5985. return render_template('signin_disable.html', params=locals())
  5986. elif status == 8:
  5987. return render_template('signin_new.html', params=locals())
  5988. else:
  5989. return render_template('oops.html', params=locals())
  5990. if actuator == 'Vacuum':
  5991. tank_brake = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  5992. tank_vacuum = tank_brake.vacuum
  5993. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  5994. UltraSonic = tank_UltraSonic.UltraSonic
  5995. return render_template('ctrl_DO_Vacuum.html', title='[操作]DI' + tid + '乾燥槽出料_真空吸料機', **locals())
  5996. elif request.method == 'POST':
  5997. pass
  5998. @main.route('/ctrl_D_<actuator>/<tid>', methods=['GET', 'POST'])
  5999. def ctrl_D(actuator, tid):
  6000. if request.method == 'GET':
  6001. if 'id' in session and 'uname' in session and 'status' in session:
  6002. username = session['uname']
  6003. status = session['status']
  6004. if status == 9:
  6005. return render_template('signin_disable.html', params=locals())
  6006. elif status == 8:
  6007. return render_template('signin_new.html', params=locals())
  6008. else:
  6009. return render_template('oops.html', params=locals())
  6010. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6011. if actuator == 'Vacuum':
  6012. tank_vacuum = tank_brake.vacuum
  6013. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6014. UltraSonic = tank_UltraSonic.UltraSonic
  6015. return render_template('ctrl_D_Vacuum.html', title='[操作]D' + tid + '乾燥槽_真空吸料機', **locals())
  6016. elif actuator == 'ThreeWayValveInput':
  6017. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6018. return render_template('ctrl_D_ThreeWayValveInput.html', title='[操作]D' + tid + '乾燥槽_入料三通閥', **locals())
  6019. elif actuator == 'ThreeWayValveBean':
  6020. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6021. return render_template('ctrl_D_ThreeWayValveBean.html', title='[操作]D' + tid + '乾燥槽_測豆三通閥', **locals())
  6022. elif actuator == 'DiskValve':
  6023. tank_diskvalve = tank_brake.diskvalve
  6024. return render_template('ctrl_D_DiskValve.html', title='[操作]D' + tid + '乾燥槽_蝴蝶閥', **locals())
  6025. elif actuator == 'SolenoidDisinfect':
  6026. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6027. return render_template('ctrl_D_SolenoidDisinfect.html', title='[操作]D' + tid + '乾燥槽_消毒電磁閥', **locals())
  6028. elif actuator == 'SolenoidWater':
  6029. tank_solenoid_water = tank_brake.solenoid_water
  6030. return render_template('ctrl_D_SolenoidWater.html', title='[操作]D' + tid + '乾燥槽_排水電磁閥', **locals())
  6031. elif actuator == 'Motor':
  6032. tank_motor = tank_brake.motor
  6033. return render_template('ctrl_D_Motor.html', title='[操作]D' + tid + '乾燥槽_馬達', **locals())
  6034. elif actuator == 'Blower':
  6035. tank_blower = tank_brake.blower
  6036. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6037. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6038. return render_template('ctrl_D_Blower.html', title='[操作]D' + tid + '乾燥槽_鼓風機', **locals())
  6039. elif actuator == 'Heater1':
  6040. tank_heater1 = tank_brake.heater1
  6041. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6042. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6043. return render_template('ctrl_D_Heater1.html', title='[操作]D' + tid + '乾燥槽_加熱器 1', **locals())
  6044. elif actuator == 'Heater2':
  6045. tank_heater2 = tank_brake.heater2
  6046. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6047. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6048. return render_template('ctrl_D_Heater2.html', title='[操作]D' + tid + '乾燥槽_加熱器 2', **locals())
  6049. elif actuator == 'TempEnable':
  6050. tank_temp1_enable = tank_brake.temp1_enable
  6051. return render_template('ctrl_D_TempEnable.html', title='[操作]D' + tid + '乾燥槽_溫控開關', **locals())
  6052. elif actuator == 'Temp':
  6053. tank_temp1_enable = tank_brake.temp1_enable
  6054. tank_temp1 = tank_brake.temp1
  6055. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6056. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6057. return render_template('ctrl_D_Temp.html', title='[操作]D' + tid + '乾燥槽_設定溫度', **locals())
  6058. elif request.method == 'POST':
  6059. pass
  6060. # 發酵貨櫃_各致動器控制
  6061. @main.route('/ctrl_FI_<actuator>/<tid>', methods=['GET', 'POST'])
  6062. def ctrl_FI(actuator, tid):
  6063. if request.method == 'GET':
  6064. if 'id' in session and 'uname' in session and 'status' in session:
  6065. username = session['uname']
  6066. status = session['status']
  6067. if status == 9:
  6068. return render_template('signin_disable.html', params=locals())
  6069. elif status == 8:
  6070. return render_template('signin_new.html', params=locals())
  6071. else:
  6072. return render_template('oops.html', params=locals())
  6073. if actuator == 'Vacuum':
  6074. if 'id' in session and 'uname' in session and 'status' in session:
  6075. username = session['uname']
  6076. status = session['status']
  6077. if status == 9:
  6078. return render_template('signin_disable.html', params=locals())
  6079. elif status == 8:
  6080. return render_template('signin_new.html', params=locals())
  6081. else:
  6082. return render_template('oops.html', params=locals())
  6083. tank_actuator = ferment_input_actuator.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  6084. tank_vacuum = tank_actuator.vacuum
  6085. tank_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  6086. UltraSonic = tank_UltraSonic.UltraSonic
  6087. return render_template('ctrl_FI_Vacuum.html', title='[操作]FI' + tid + '發酵入料儲豆槽_真空吸料機', **locals())
  6088. elif request.method == 'POST':
  6089. pass
  6090. @main.route('/ctrl_FO_<actuator>/<tid>', methods=['GET', 'POST'])
  6091. def ctrl_FO(actuator, tid):
  6092. if request.method == 'GET':
  6093. if 'id' in session and 'uname' in session and 'status' in session:
  6094. username = session['uname']
  6095. status = session['status']
  6096. if status == 9:
  6097. return render_template('signin_disable.html', params=locals())
  6098. elif status == 8:
  6099. return render_template('signin_new.html', params=locals())
  6100. else:
  6101. return render_template('oops.html', params=locals())
  6102. if actuator == 'Vacuum':
  6103. tank_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  6104. tank_vacuum = tank_actuator.vacuum
  6105. tank_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  6106. UltraSonic = tank_UltraSonic.UltraSonic
  6107. return render_template('ctrl_FO_Vacuum.html', title='[操作]FO' + tid + '發酵出料儲豆槽_真空吸料機', **locals())
  6108. elif request.method == 'POST':
  6109. pass
  6110. @main.route('/ctrl_F_<actuator>/<tid>', methods=['GET', 'POST'])
  6111. def ctrl_F(actuator, tid):
  6112. if request.method == 'GET':
  6113. if 'id' in session and 'uname' in session and 'status' in session:
  6114. username = session['uname']
  6115. status = session['status']
  6116. if status == 9:
  6117. return render_template('signin_disable.html', params=locals())
  6118. elif status == 8:
  6119. return render_template('signin_new.html', params=locals())
  6120. else:
  6121. return render_template('oops.html', params=locals())
  6122. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  6123. if actuator == 'Vacuum':
  6124. tank_vacuum = tank_actuator.vacuum
  6125. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  6126. LiDAR = tank_LiDAR.LiDAR
  6127. return render_template('ctrl_F_Vacuum.html', title='[操作]F' + tid + '發酵槽_真空吸料機', **locals())
  6128. elif actuator == 'ThreeWayValveInput':
  6129. tank_threewayvalveinput = tank_actuator.threewayvalve_input
  6130. return render_template('ctrl_F_ThreeWayValveInput.html', title='[操作]F' + tid + '發酵槽_入料三通閥', **locals())
  6131. elif actuator == 'SolenoidWaterTotal':
  6132. tank_solenoid_tank_water_total = tank_actuator.solenoid_tank_water_total
  6133. return render_template('ctrl_F_SolenoidWaterTotal.html', title='[操作]F' + tid + '發酵槽_總進水電磁閥', **locals())
  6134. elif actuator == 'SolenoidOuterWater':
  6135. tank_solenoid_outer_water = tank_actuator.solenoid_outer_water
  6136. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6137. WaterLevel = tank_WaterLevel.WaterLevel
  6138. return render_template('ctrl_F_SolenoidOuterWater.html', title='[操作]F' + tid + '發酵槽_保溫夾層進水電磁閥', **locals())
  6139. elif actuator == 'SolenoidWaterIn':
  6140. tank_solenoid_tank_water_in = tank_actuator.solenoid_tank_water_in
  6141. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6142. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  6143. return render_template('ctrl_F_SolenoidWaterIn.html', title='[操作]F' + tid + '發酵槽_桶內進水電磁閥', **locals())
  6144. elif actuator == 'PumpSensor':
  6145. tank_pump_sensor = tank_actuator.pump_sensor
  6146. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6147. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6148. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6149. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6150. PH = tank_PH.PH
  6151. ORP = tank_ORP.ORP
  6152. DO = tank_DO.DO
  6153. EC = tank_EC.EC
  6154. return render_template('ctrl_F_PumpSensor.html', title='[操作]F' + tid + '發酵槽_感測器抽水雙核隔膜泵', **locals())
  6155. elif actuator == 'ThreeWayValveBean':
  6156. tank_threewayvalve_bean = tank_actuator.threewayvalve_bean
  6157. return render_template('ctrl_F_ThreeWayValveBean.html', title='[操作]F' + tid + '發酵槽_感測模組下豆三通閥', **locals())
  6158. elif actuator == 'ThreeWayValveFloat':
  6159. tank_threewayvalve_outer_float = tank_actuator.threewayvalve_outer_float
  6160. return render_template('ctrl_F_ThreeWayValveFloat.html', title='[操作]F' + tid + '發酵槽_外桶浮選三通閥', **locals())
  6161. elif actuator == 'SolenoidDisinfect':
  6162. tank_solenoid_tank_disinfect = tank_actuator.solenoid_tank_disinfect
  6163. return render_template('ctrl_F_SolenoidDisinfect.html', title='[操作]F' + tid + '發酵槽_桶內消毒電磁閥', **locals())
  6164. elif actuator == 'Motor':
  6165. tank_motor = tank_actuator.motor
  6166. return render_template('ctrl_F_Motor.html', title='[操作]F' + tid + '發酵槽_馬達', **locals())
  6167. elif actuator == 'Heater1':
  6168. tank_heater1 = tank_actuator.heater1
  6169. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6170. return render_template('ctrl_F_Heater1.html', title='[操作]F' + tid + '發酵槽_加熱器 1', **locals())
  6171. elif actuator == 'Heater2':
  6172. tank_heater2 = tank_actuator.heater2
  6173. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6174. return render_template('ctrl_F_Heater2.html', title='[操作]F' + tid + '發酵槽_加熱器 2', **locals())
  6175. elif actuator == 'TempEnable':
  6176. tank_temp_enable = tank_actuator.temp_enable
  6177. return render_template('ctrl_F_TempEnable.html', title='[操作]F' + tid + '發酵槽_溫控開關', **locals())
  6178. elif actuator == 'Temp':
  6179. tank_temp = tank_actuator.temp
  6180. tank_temp_enable = tank_actuator.temp_enable
  6181. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6182. return render_template('ctrl_F_Temp.html', title='[操作]F' + tid + '發酵槽_溫度設定', **locals())
  6183. elif actuator == 'DiskValve':
  6184. tank_diskvalve = tank_actuator.diskvalve
  6185. return render_template('ctrl_F_DiskValve.html', title='[操作]F' + tid + '發酵槽_蝴蝶閥', **locals())
  6186. @main.route('/dry_Temp/<tid>/<Temp_Weights_SHT11>/<Temp_Weights_Soil>/<temp_data>', methods=['GET', 'POST'])
  6187. def dry_Temp(tid, Temp_Weights_SHT11, Temp_Weights_Soil, temp_data):
  6188. if request.method == 'GET':
  6189. if 'id' in session and 'uname' in session and 'status' in session:
  6190. username = session['uname']
  6191. status = session['status']
  6192. if status == 9:
  6193. return render_template('signin_disable.html', params=locals())
  6194. elif status == 8:
  6195. return render_template('signin_new.html', params=locals())
  6196. else:
  6197. return render_template('oops.html', params=locals())
  6198. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6199. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  6200. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6201. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6202. Soil_Temp = float(tank_Soil.soil_Temp)
  6203. Soil_Humidity = tank_Soil.soil_Humidity
  6204. Temp_Weights_SHT11= float(Temp_Weights_SHT11)
  6205. Temp_Weights_Soil = float(Temp_Weights_Soil)
  6206. temp_data = float(temp_data)
  6207. present_temp = math.ceil( (SHT11_Temp*Temp_Weights_SHT11 + Soil_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil) )
  6208. # Math.round((present_SHT11_Temp*Temp_Weights_SHT11 + present_SOIL_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil)*100) / 100
  6209. target_temp = math.ceil(temp_data)
  6210. TempUp = {
  6211. 22:0, 23:6, 24:12, 25:18, 26:24, 27:28, 28:32, 29:36, 30:40, 31:44, 32:48, 33:56, 34:64, 35:72, 36:96, 37:168, 38:288, 39:384, 40:529, 41:697, 42:793, 43:865, 44:1394
  6212. }
  6213. if target_temp in TempUp and present_temp in TempUp:
  6214. TempUpTime = ', 預計 ' + str(TempUp[target_temp] - TempUp[present_temp]) + ' 秒達到指定溫度'
  6215. elif target_temp < 22 or present_temp < 22 :
  6216. TempUpTime = '℃, 指定溫度過低, 持續升溫中'
  6217. elif target_temp > 44 or present_temp > 44 :
  6218. TempUpTime = '℃, 指定溫度過高, 持續升溫中'
  6219. return jsonify({"SHT11_Temp":SHT11_Temp,
  6220. "SHT11_Humidity":SHT11_Humidity,
  6221. "Soil_Temp":Soil_Temp,
  6222. "Soil_Humidity":Soil_Humidity,
  6223. "present_temp":present_temp,
  6224. "TempUpTime":TempUpTime
  6225. })
  6226. else:
  6227. pass
  6228. @main.route('/dry_container_tank/<tid>', methods=['GET', 'POST'])
  6229. def dry_container_tank(tid):
  6230. if request.method == 'GET':
  6231. if 'id' in session and 'uname' in session and 'status' in session:
  6232. username = session['uname']
  6233. status = session['status']
  6234. if status == 9:
  6235. return render_template('signin_disable.html', params=locals())
  6236. elif status == 8:
  6237. return render_template('signin_new.html', params=locals())
  6238. else:
  6239. return render_template('oops.html', params=locals())
  6240. tonow = dt.now()
  6241. # 感測器_乾燥桶_SHT11
  6242. print("tonow: ", tonow)
  6243. time_del = timedelta(minutes=-60)
  6244. bias_date_time = tonow + time_del
  6245. # print(dt.now() >= dt(2021,11,29,17,35,36))
  6246. # bias_min = tonow.minute + 3
  6247. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid))\
  6248. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  6249. .order_by(text('datetime desc')).first()
  6250. print("tank_SHT11: ", tank_SHT11, type(tank_SHT11)) # tank_SHT11: <dry_tank_SHT11 2021-12-03 15:39:16> <class 'app.models.dry_tank_SHT11'>
  6251. if not hasattr(object, 'tank_SHT11'):
  6252. tank_SHT11 = {"SHT11_Temp":" — "}
  6253. # 感測器_乾燥桶_土壤三合一
  6254. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6255. # 感測器_乾燥桶_氣壓
  6256. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6257. # 感測器_乾燥桶_超音波感測器
  6258. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6259. # 致動器_乾燥桶_ALL
  6260. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6261. tank_vacuum = tank_brake.vacuum
  6262. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6263. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6264. tank_diskvalve = tank_brake.diskvalve
  6265. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6266. tank_solenoid_water = tank_brake.solenoid_water
  6267. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  6268. tank_motor = tank_brake.motor
  6269. tank_blower = tank_brake.blower
  6270. tank_heater1 = tank_brake.heater1
  6271. tank_heater2 = tank_brake.heater2
  6272. tank_temp1_enable = tank_brake.temp1_enable
  6273. tank_temp1 = tank_brake.temp1
  6274. # Temp_weight = num_SHT11_temp * 0.5 + num_Soil_temp * 0.5
  6275. return render_template('dry_container_tank.html', title='[操作] D' + tid + ' 乾燥槽操作介面', **locals())
  6276. elif request.method == 'POST':
  6277. pass
  6278. @main.route('/dry_container_input/<tid>', methods=['GET', 'POST'])
  6279. def dry_container_input(tid):
  6280. if request.method == 'GET':
  6281. if 'id' in session and 'uname' in session and 'status' in session:
  6282. username = session['uname']
  6283. status = session['status']
  6284. if status == 9:
  6285. return render_template('signin_disable.html', params=locals())
  6286. elif status == 8:
  6287. return render_template('signin_new.html', params=locals())
  6288. else:
  6289. return render_template('oops.html', params=locals())
  6290. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6291. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6292. input_vacuum = input_vacuum.vacuum
  6293. return render_template('dry_container_input.html', title='[操作] DI' + tid + ' 乾燥入料儲豆槽操作介面', **locals())
  6294. elif request.method == 'POST':
  6295. pass
  6296. @main.route('/dry_container_output/<tid>', methods=['GET', 'POST'])
  6297. def dry_container_output(tid):
  6298. if request.method == 'GET':
  6299. if 'id' in session and 'uname' in session and 'status' in session:
  6300. username = session['uname']
  6301. status = session['status']
  6302. if status == 9:
  6303. return render_template('signin_disable.html', params=locals())
  6304. elif status == 8:
  6305. return render_template('signin_new.html', params=locals())
  6306. else:
  6307. return render_template('oops.html', params=locals())
  6308. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6309. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6310. output_vacuum = output_vacuum.vacuum
  6311. return render_template('dry_container_output.html', title='[操作] DO' + tid + ' 乾燥出料儲豆槽操作介面', **locals())
  6312. elif request.method == 'POST':
  6313. pass
  6314. # 原本的乾燥貨櫃控制, 備份用
  6315. @main.route('/dry_container/<tid>', methods=['GET', 'POST'])
  6316. def dry_container(tid):
  6317. if request.method == 'GET':
  6318. if 'id' in session and 'uname' in session and 'status' in session:
  6319. username = session['uname']
  6320. status = session['status']
  6321. if status == 9:
  6322. return render_template('signin_disable.html', params=locals())
  6323. elif status == 8:
  6324. return render_template('signin_new.html', params=locals())
  6325. else:
  6326. return render_template('oops.html', params=locals())
  6327. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  6328. '''
  6329. # 開啟本機 coffeetest 資料庫
  6330. # mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='coffeetest', charset='utf8')
  6331. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  6332. password='skyeye', database='Coffee', charset='utf8')
  6333. mycursor = mydb.cursor()
  6334. '''
  6335. # 感測器_乾燥桶_SHT11
  6336. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6337. num_SHT11_temp = float(tank_SHT11.SHT11_Temp)
  6338. # 感測器_乾燥桶_土壤三合一
  6339. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6340. num_Soil_temp = float(tank_Soil.soil_Temp)
  6341. # 感測器_乾燥桶_氣壓
  6342. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6343. # 感測器_乾燥桶_超音波感測器
  6344. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6345. # 感測器_出料儲豆槽_超音波感測器
  6346. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6347. # 致動器_乾燥桶_ALL
  6348. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6349. tank_vacuum = tank_brake.vacuum
  6350. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6351. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6352. tank_diskvalve = tank_brake.diskvalve
  6353. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6354. tank_solenoid_water = tank_brake.solenoid_water
  6355. tank_motor = tank_brake.motor
  6356. tank_blower = tank_brake.blower
  6357. tank_heater1 = tank_brake.heater1
  6358. tank_heater2 = tank_brake.heater2
  6359. tank_temp1_enable = tank_brake.temp1_enable
  6360. tank_temp1 = tank_brake.temp1
  6361. '''
  6362. tank_vacuum = 'ON' if tank_brake.vacuum == 1 else 'OFF'
  6363. tank_threewayvalve = 'ON' if tank_brake.threewayvalve == 1 else 'OFF'
  6364. tank_diskvalve = 'ON' if tank_brake.diskvalve == 1 else 'OFF'
  6365. tank_solenoid_disinfect = 'ON' if tank_brake.solenoid_disinfect == 1 else 'OFF'
  6366. tank_solenoid_water = 'ON' if tank_brake.solenoid_water == 1 else 'OFF'
  6367. tank_motor = tank_brake.motor
  6368. tank_blower = 'ON' if tank_brake.blower == 1 else 'OFF'
  6369. tank_heater1 = 'ON' if tank_brake.heater1 == 1 else 'OFF'
  6370. tank_heater2 = 'ON' if tank_brake.heater2 == 1 else 'OFF'
  6371. tank_temp1_enable = 'ON' if tank_brake.temp1_enable == 1 else 'OFF'
  6372. tank_temp1 = tank_brake.temp1
  6373. '''
  6374. '''
  6375. data = mycursor.execute(
  6376. 'SELECT * FROM dry_tank_brake ORDER BY datetime DESC;')
  6377. data = mycursor.fetchone()
  6378. '''
  6379. if tid in ['1', '2', '3', '4', '5', '6']:
  6380. # print("1")
  6381. # 感測器_入料儲豆槽_超音波感測器
  6382. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  6383. # 致動器_入料儲豆槽_真空吸引機
  6384. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  6385. input_vacuum = input_vacuum.vacuum
  6386. # 感測器_出料儲豆槽_超音波感測器
  6387. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  6388. # 致動器_出料儲豆槽_真空吸引機
  6389. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  6390. output_vacuum = output_vacuum.vacuum
  6391. elif tid in ['7', '8', '9', '10', '11', '12']:
  6392. print("2")
  6393. # 感測器_入料儲豆槽_超音波感測器
  6394. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  6395. # 致動器_入料儲豆槽_真空吸引機
  6396. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  6397. input_vacuum = input_vacuum.vacuum
  6398. # 感測器_出料儲豆槽_超音波感測器
  6399. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  6400. # 致動器_出料儲豆槽_真空吸引機
  6401. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  6402. output_vacuum = output_vacuum.vacuum
  6403. '''
  6404. # 感測器_入料儲豆槽_超音波感測器
  6405. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6406. # 致動器_入料儲豆槽_真空吸引機
  6407. input_vacuum = dry_input_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6408. # print("input_vacuum:", input_vacuum)
  6409. input_vacuum = input_vacuum.vacuum
  6410. #print('input_vacuum:', input_vacuum.vacuum)
  6411. # 致動器_出料儲豆槽_真空吸引機
  6412. output_vacuum = dry_output_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6413. #print('output_vacuum.vacuum: ', output_vacuum.vacuum)
  6414. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  6415. #print('output_vacuum: ', output_vacuum)
  6416. '''
  6417. # 傳 MQTT 給阿超, 阿超讓硬體動作, 將資料儲存到資料庫
  6418. input_data = set_dry_input.query.order_by(text('datetime desc')).first()
  6419. schedule_input_height = input_data.input_height
  6420. schedule_input_entertime = input_data.input_entertime
  6421. schedule_input_exittime = input_data.input_exittime
  6422. schedule_tank_height = input_data.tank_height
  6423. return render_template('dry_container.html', title='dry_container', **locals())
  6424. elif request.method == 'POST':
  6425. # 表單輸入處
  6426. print('/dry_input_setting POST')
  6427. set = set_dry_input()
  6428. set.input_height = request.form['schedule_input_height']
  6429. set.input_entertime = request.form['schedule_input_entertime']
  6430. set.input_exittime = request.form['schedule_input_exittime']
  6431. set.tank_height = request.form['schedule_tank_height']
  6432. #將數據保存進資料庫 - 註冊
  6433. db.session.add(set)
  6434. # 手動提交,目的是為了獲取提交後的user的id
  6435. db.session.commit()
  6436. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  6437. # 完成登入的操作
  6438. # setting = Set_dry_input.query.order_by(text('datetime desc')).first()
  6439. #session['id'] = set.userID
  6440. #session['uname'] = set.username
  6441. return redirect('/dry_container')
  6442. # 登入頁面的訪問路徑
  6443. @main.route('/login', methods=['GET', 'POST'])
  6444. def login_views():
  6445. if request.method == 'GET':
  6446. if 'id' in session and 'uname' in session and 'status' in session:
  6447. return redirect('/')
  6448. else:
  6449. return render_template('sign_in.html')
  6450. else:
  6451. # 接收前端傳過來的資料
  6452. username = request.form['username']
  6453. password = request.form['password']
  6454. # 使用接收的用戶和密碼到資料庫中查詢
  6455. user = User.query.filter_by(
  6456. username=username, password=password).first()
  6457. # 如果用戶存在,將信息保存置session並重定向回首頁,否則重定向回登入頁
  6458. if user:
  6459. resp = redirect('/')
  6460. # 判斷是否有記住密碼
  6461. if 'rem' in request.form:
  6462. userID = str(user.userID)
  6463. max_age = 60*60*24*365
  6464. status = str(user.status)
  6465. print('status: ', status)
  6466. # Rita 以秒為單位, 一年
  6467. # Rita 功能和 expires 很像,但此參數並非所有瀏覽器均支持,所以建議使用 expires 參數。
  6468. # Rita expires:指定 Cookie 的有效日期, 當過了有效日期後就不會儲存在瀏覽器
  6469. resp.set_cookie("username", username, max_age=max_age)
  6470. resp.set_cookie("userID", userID, max_age=max_age)
  6471. resp.set_cookie("status", status, max_age=max_age)
  6472. session['uname'] = user.username
  6473. session['id'] = user.userID
  6474. session['status'] = user.status
  6475. return resp
  6476. else:
  6477. errMsg = "Wrong login or password"
  6478. return render_template('sign_in.html', errMsg=errMsg)
  6479. # 登入重設密碼的頁面
  6480. # Rita reset_pwd1 - Email
  6481. # Rita reset_pwd2 - New password / Confirm password
  6482. @main.route('/reset_password', methods=['POST', 'GET'])
  6483. def reset_password_views():
  6484. if request.method == 'GET':
  6485. if 'mail' in session:
  6486. del session['mail']
  6487. return render_template('reset_pwd1.html')
  6488. else:
  6489. # POST
  6490. # 如果有id在session裡,代表從reset_pwd2過來的 ? 對, reset_pwd2 POST (但也有其他可能)
  6491. if "mail" in session:
  6492. new_pwd = request.form['new_pwd']
  6493. confirm_pwd = request.form['confirm_pwd']
  6494. # 判斷密碼是否一致
  6495. if new_pwd == confirm_pwd:
  6496. mail = session['mail']
  6497. user = User.query.filter_by(mail=mail).first()
  6498. print("user: ", user)
  6499. print("user.password_before: ", user.password)
  6500. print("new_pwd: ", new_pwd)
  6501. user.password = new_pwd
  6502. print("user.password_after: ", user.password)
  6503. db.session.add(user)
  6504. db.session.commit()
  6505. del session['mail']
  6506. # 修改完後回登入頁
  6507. return redirect('/login')
  6508. else:
  6509. # Rita errMsg 是指網頁上的 {{errMsg}} 位置
  6510. errMsg = "Passwords does not match"
  6511. return render_template('reset_pwd2.html', errMsg=errMsg)
  6512. email = request.form['email']
  6513. user = User.query.filter_by(mail=email).first()
  6514. if user: # Rita 有找到對應 email
  6515. session['mail'] = user.mail
  6516. return render_template('reset_pwd2.html')
  6517. else:
  6518. errMsg = "Wrong email.Please try again"
  6519. return render_template('reset_pwd1.html', errMsg=errMsg)
  6520. # 註冊頁面的訪問路徑
  6521. @main.route('/register', methods=['POST', "GET"])
  6522. def register_views():
  6523. if request.method == 'GET':
  6524. return render_template('registration.html')
  6525. else:
  6526. # 獲取文本框的值並賦值給user實體對象
  6527. user = User()
  6528. user.firstname = request.form['firstname']
  6529. user.lastname = request.form['lastname']
  6530. user.mail = request.form['email']
  6531. user.phone = request.form['phone']
  6532. user.username = request.form['username']
  6533. user.password = request.form['password']
  6534. user.status = 8 # Rita app\models.py 設定 0:admin;1:new;9:disable [0906 更新] 0:admin;1:superuser;2:enduser;8:new;9:disable
  6535. #將數據保存進資料庫 - 註冊
  6536. db.session.add(user)
  6537. # 手動提交,目的是為了獲取提交後的user的id
  6538. db.session.commit()
  6539. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  6540. # 完成登入的操作
  6541. user = User.query.filter_by(username=user.username).first()
  6542. session['status'] = user.status
  6543. session['id'] = user.userID
  6544. session['uname'] = user.username
  6545. return redirect('/')
  6546. # 驗證email訪問路徑
  6547. @main.route('/check_email')
  6548. def check_email_views():
  6549. email = request.args['email']
  6550. user = User.query.filter_by(mail=email).first()
  6551. if user:
  6552. # Rita email 錯誤時會顯示 Incorrect email address
  6553. result = {"errMsg": " "}
  6554. else:
  6555. result = {"pass": " "}
  6556. return json.dumps(result)
  6557. # 驗證username訪問路徑
  6558. @main.route('/check_username')
  6559. def check_username_views():
  6560. username = request.args['username']
  6561. user = User.query.filter_by(username=username).first()
  6562. if user:
  6563. result = {"errMsg": " "}
  6564. else:
  6565. result = {"pass": " "}
  6566. return json.dumps(result)
  6567. # 咖啡貨櫃的訪問路徑
  6568. @main.route('/cargo_list', methods=['GET', 'POST'])
  6569. def cargo_list_views():
  6570. username = session['uname']
  6571. if request.method == 'GET':
  6572. return render_template('cargo_list.html', params=locals())
  6573. else:
  6574. pass
  6575. # 貨櫃1的訪問路徑
  6576. @main.route('/cargo1', methods=['GET', 'POST'])
  6577. def cargo1_views():
  6578. username = session['uname']
  6579. if request.method == 'GET':
  6580. return render_template('cargo1.html', params=locals())
  6581. else:
  6582. pass
  6583. # 貨櫃1排程的訪問路徑
  6584. @main.route('/cargo1_schedule', methods=['GET', 'POST'])
  6585. def cargo1_schedule_views():
  6586. username = session['uname']
  6587. if request.method == 'GET':
  6588. # 將已儲存的排程資料傳給前端
  6589. # 進豆閥
  6590. try:
  6591. bean = BeanValve.query.order_by(text('datetime desc')).first()
  6592. datetime = bean.datetime
  6593. beans = BeanValve.query.filter_by(
  6594. datetime=datetime).all()
  6595. except Exception as e:
  6596. pass
  6597. # 清洗機
  6598. try:
  6599. wash = WashMachine.query.order_by(text('datetime desc')).first()
  6600. datetime = wash.datetime
  6601. washes = WashMachine.query.filter_by(datetime=datetime).all()
  6602. except Exception as e:
  6603. pass
  6604. # 輸送帶1
  6605. try:
  6606. belt1 = ConveyorBelt1.query.order_by(text('datetime desc')).first()
  6607. datetime = belt1.datetime
  6608. belts1 = ConveyorBelt1.query.filter_by(datetime=datetime).all()
  6609. except Exception as e:
  6610. pass
  6611. # ///////////////////////////////////////////////////////////////////////////////////////////
  6612. # 消毒機
  6613. try:
  6614. disinfect = Cargo1Disinfect.query.order_by(
  6615. text('datetime desc')).first()
  6616. datetime = disinfect.datetime
  6617. disinfects = Cargo1Disinfect.query.filter_by(
  6618. datetime=datetime).all()
  6619. except Exception as e:
  6620. pass
  6621. # 色選機
  6622. try:
  6623. color = ColorMachine.query.order_by(text('datetime desc')).first()
  6624. datetime = color.datetime
  6625. colors = ColorMachine.query.filter_by(datetime=datetime).all()
  6626. except Exception as e:
  6627. pass
  6628. # 輸送帶2
  6629. try:
  6630. belt2 = ConveyorBelt2.query.order_by(text('datetime desc')).first()
  6631. datetime = belt2.datetime
  6632. belts2 = ConveyorBelt2.query.filter_by(datetime=datetime).all()
  6633. except Exception as e:
  6634. pass
  6635. # 去皮機
  6636. try:
  6637. peeling = PeelingMachine.query.order_by(
  6638. text('datetime desc')).first()
  6639. datetime = peeling.datetime
  6640. peelings = PeelingMachine.query.filter_by(datetime=datetime).all()
  6641. except Exception as e:
  6642. pass
  6643. # 輸送帶3
  6644. try:
  6645. belt3 = ConveyorBelt3.query.order_by(text('datetime desc')).first()
  6646. datetime = belt3.datetime
  6647. belts3 = ConveyorBelt3.query.filter_by(datetime=datetime).all()
  6648. except Exception as e:
  6649. pass
  6650. return render_template('cargo1_schedule.html', params=locals())
  6651. else:
  6652. current_time = dt.now()
  6653. # 循環從前端提交過來的資料
  6654. for i in request.form:
  6655. # 進豆閥
  6656. if i[:10] == 'inletValve':
  6657. if i[:19] == 'inletValve_duration':
  6658. bean = BeanValve()
  6659. bean.duration = request.form[i]
  6660. elif i[:18] == 'inletValve_from_hr':
  6661. iv_from_hr = request.form[i]
  6662. elif i[:19] == 'inletValve_from_min':
  6663. iv_from_min = request.form[i]
  6664. bean.start = iv_from_hr + ":" + iv_from_min
  6665. elif i[:16] == 'inletValve_to_hr':
  6666. iv_to_hr = request.form[i]
  6667. elif i[:17] == 'inletValve_to_min':
  6668. iv_to_min = request.form[i]
  6669. bean.end = iv_to_hr + ":" + iv_to_min
  6670. bean.datetime = current_time
  6671. db.session.add(bean)
  6672. db.session.commit()
  6673. # 清洗機
  6674. elif i[:4] == 'wash':
  6675. if i[:13] == 'wash_duration':
  6676. wash = WashMachine()
  6677. wash.duration = request.form[i]
  6678. elif i[:12] == 'wash_from_hr':
  6679. wash_from_hr = request.form[i]
  6680. elif i[:13] == 'wash_from_min':
  6681. wash_from_min = request.form[i]
  6682. wash.start = wash_from_hr + ":" + wash_from_min
  6683. elif i[:10] == 'wash_to_hr':
  6684. wash_to_hr = request.form[i]
  6685. elif i[:11] == 'wash_to_min':
  6686. wash_to_min = request.form[i]
  6687. wash.end = wash_to_hr + ":" + wash_to_min
  6688. wash.datetime = current_time
  6689. db.session.add(wash)
  6690. db.session.commit()
  6691. # 輸送帶1
  6692. elif i[:5] == 'belt1':
  6693. if i[:14] == 'belt1_duration':
  6694. belt1 = ConveyorBelt1()
  6695. belt1.duration = request.form[i]
  6696. elif i[:13] == 'belt1_from_hr':
  6697. belt1_from_hr = request.form[i]
  6698. elif i[:14] == 'belt1_from_min':
  6699. belt1_from_min = request.form[i]
  6700. belt1.start = belt1_from_hr + ":" + belt1_from_min
  6701. elif i[:11] == 'belt1_to_hr':
  6702. belt1_to_hr = request.form[i]
  6703. elif i[:12] == 'belt1_to_min':
  6704. belt1_to_min = request.form[i]
  6705. belt1.end = belt1_to_hr + ":" + belt1_to_min
  6706. belt1.datetime = current_time
  6707. db.session.add(belt1)
  6708. db.session.commit()
  6709. # 消毒
  6710. elif i[:9] == 'disinfect':
  6711. if i[:18] == 'disinfect_duration':
  6712. disinfect = Cargo1Disinfect()
  6713. disinfect.duration = request.form[i]
  6714. elif i[:17] == 'disinfect_from_hr':
  6715. di_from_hr = request.form[i]
  6716. elif i[:18] == 'disinfect_from_min':
  6717. di_from_min = request.form[i]
  6718. disinfect.start = di_from_hr + ":" + di_from_min
  6719. elif i[:15] == 'disinfect_to_hr':
  6720. di_to_hr = request.form[i]
  6721. elif i[:16] == 'disinfect_to_min':
  6722. di_to_min = request.form[i]
  6723. disinfect.end = di_to_hr + ":" + di_to_min
  6724. disinfect.datetime = current_time
  6725. db.session.add(disinfect)
  6726. db.session.commit()
  6727. # 色選機
  6728. elif i[:5] == 'color':
  6729. if i[:14] == 'color_duration':
  6730. color = ColorMachine()
  6731. color.duration = request.form[i]
  6732. elif i[:13] == 'color_from_hr':
  6733. color_from_hr = request.form[i]
  6734. elif i[:14] == 'color_from_min':
  6735. color_from_min = request.form[i]
  6736. color.start = color_from_hr + ":" + color_from_min
  6737. elif i[:11] == 'color_to_hr':
  6738. color_to_hr = request.form[i]
  6739. elif i[:12] == 'color_to_min':
  6740. color_to_min = request.form[i]
  6741. color.end = color_to_hr + ":" + color_to_min
  6742. color.datetime = current_time
  6743. db.session.add(color)
  6744. db.session.commit()
  6745. # 輸送帶2
  6746. elif i[:5] == 'belt2':
  6747. if i[:14] == 'belt2_duration':
  6748. belt2 = ConveyorBelt2()
  6749. belt2.duration = request.form[i]
  6750. elif i[:13] == 'belt2_from_hr':
  6751. belt2_from_hr = request.form[i]
  6752. elif i[:14] == 'belt2_from_min':
  6753. belt2_from_min = request.form[i]
  6754. belt2.start = belt2_from_hr + ":" + belt2_from_min
  6755. elif i[:11] == 'belt2_to_hr':
  6756. belt2_to_hr = request.form[i]
  6757. elif i[:12] == 'belt2_to_min':
  6758. belt2_to_min = request.form[i]
  6759. belt2.end = belt2_to_hr + ":" + belt2_to_min
  6760. belt2.datetime = current_time
  6761. db.session.add(belt2)
  6762. db.session.commit()
  6763. # 去皮機
  6764. elif i[:6] == 'peeled':
  6765. if i[:15] == 'peeled_duration':
  6766. peeling = PeelingMachine()
  6767. peeling.duration = request.form[i]
  6768. elif i[:14] == 'peeled_from_hr':
  6769. peeled_from_hr = request.form[i]
  6770. elif i[:15] == 'peeled_from_min':
  6771. peeled_from_min = request.form[i]
  6772. peeling.start = peeled_from_hr + ":" + peeled_from_min
  6773. elif i[:12] == 'peeled_to_hr':
  6774. peeled_to_hr = request.form[i]
  6775. elif i[:13] == 'peeled_to_min':
  6776. peeled_to_min = request.form[i]
  6777. peeling.end = peeled_to_hr + ":" + peeled_to_min
  6778. peeling.datetime = current_time
  6779. db.session.add(peeling)
  6780. db.session.commit()
  6781. # 輸送帶3
  6782. elif i[:5] == 'belt3':
  6783. if i[:14] == 'belt3_duration':
  6784. belt3 = ConveyorBelt3()
  6785. belt3.duration = request.form[i]
  6786. elif i[:13] == 'belt3_from_hr':
  6787. belt3_from_hr = request.form[i]
  6788. elif i[:14] == 'belt3_from_min':
  6789. belt3_from_min = request.form[i]
  6790. belt3.start = belt3_from_hr + ":" + belt3_from_min
  6791. elif i[:11] == 'belt3_to_hr':
  6792. belt3_to_hr = request.form[i]
  6793. elif i[:12] == 'belt3_to_min':
  6794. belt3_to_min = request.form[i]
  6795. belt3.end = belt3_to_hr + ":" + belt3_to_min
  6796. belt3.datetime = current_time
  6797. db.session.add(belt3)
  6798. db.session.commit()
  6799. return render_template('cargo1.html', params=locals())
  6800. # 貨櫃2的訪問路徑
  6801. @main.route('/cargo2', methods=['GET', 'POST'])
  6802. def cargo2_views():
  6803. username = session['uname']
  6804. if request.method == 'GET':
  6805. return render_template('cargo2.html', params=locals())
  6806. else:
  6807. pass
  6808. # 貨櫃2排程的發酵槽訪問路徑
  6809. @main.route('/cargo2_schedule_tanks', methods=['GET', 'POST'])
  6810. def cargo2_schedule_tanks_views():
  6811. username = session['uname']
  6812. if request.method == 'GET':
  6813. return render_template('cargo2_schedule_tanks.html', params=locals())
  6814. else:
  6815. pass
  6816. # 貨櫃2排程發酵槽的清單訪問路徑
  6817. @main.route('/cargo2_schedule/<tid>', methods=['GET', 'POST'])
  6818. def cargo2_schedule_views(tid):
  6819. username = session['uname']
  6820. if request.method == 'GET':
  6821. # 將已儲存的排程資料傳給前端
  6822. # 打菌
  6823. try:
  6824. bacteria = Bacteria.query.filter_by(tank_num=int(
  6825. tid)).order_by(text('datetime desc')).first()
  6826. datetime = bacteria.datetime
  6827. bacterias = Bacteria.query.filter_by(datetime=datetime).all()
  6828. except Exception as e:
  6829. pass
  6830. # 消毒
  6831. try:
  6832. disinfect = Cargo2Disinfect.query.filter_by(
  6833. tank_num=int(tid)).order_by(text('datetime desc')).first()
  6834. datetime = disinfect.datetime
  6835. disinfects = Cargo2Disinfect.query.filter_by(
  6836. datetime=datetime).all()
  6837. except Exception as e:
  6838. pass
  6839. # 加熱
  6840. try:
  6841. heating = Heating.query.filter_by(tank_num=int(
  6842. tid)).order_by(text('datetime desc')).first()
  6843. datetime = heating.datetime
  6844. heatings = Heating.query.filter_by(datetime=datetime).all()
  6845. except Exception as e:
  6846. pass
  6847. # 攪拌
  6848. try:
  6849. stir = Stir.query.filter_by(tank_num=int(tid)).order_by(
  6850. text('datetime desc')).first()
  6851. datetime = stir.datetime
  6852. stirs = Stir.query.filter_by(datetime=datetime).all()
  6853. except Exception as e:
  6854. pass
  6855. # 注水
  6856. try:
  6857. water = WaterInjection.query.filter_by(
  6858. tank_num=int(tid)).order_by(text('datetime desc')).first()
  6859. datetime = water.datetime
  6860. waters = WaterInjection.query.filter_by(datetime=datetime).all()
  6861. except Exception as e:
  6862. pass
  6863. # 開上閥
  6864. try:
  6865. top = TopValve.query.filter_by(tank_num=int(
  6866. tid)).order_by(text('datetime desc')).first()
  6867. datetime = top.datetime
  6868. tops = TopValve.query.filter_by(datetime=datetime).all()
  6869. except Exception as e:
  6870. pass
  6871. # 開下閥
  6872. try:
  6873. bottom = BottomValve.query.filter_by(tank_num=int(
  6874. tid)).order_by(text('datetime desc')).first()
  6875. datetime = bottom.datetime
  6876. bottoms = BottomValve.query.filter_by(datetime=datetime).all()
  6877. except Exception as e:
  6878. pass
  6879. # 溫度
  6880. try:
  6881. tem = Temperature.query.filter_by(tank_num=int(
  6882. tid)).order_by(text('datetime desc')).first()
  6883. datetime = tem.datetime
  6884. tems = Temperature.query.filter_by(datetime=datetime).all()
  6885. except Exception as e:
  6886. pass
  6887. return render_template('cargo2_schedule.html', params=locals())
  6888. else:
  6889. current_time = dt.now()
  6890. # 循環從前端提交過來的資料
  6891. for i in request.form:
  6892. # 打菌
  6893. if i[:8] == 'bacteria':
  6894. if i[:17] == 'bacteria_duration':
  6895. bacteria = Bacteria()
  6896. bacteria.duration = request.form[i]
  6897. elif i[:16] == 'bacteria_from_hr':
  6898. bac_from_hr = request.form[i]
  6899. elif i[:17] == 'bacteria_from_min':
  6900. bac_from_min = request.form[i]
  6901. bacteria.start = bac_from_hr + ":" + bac_from_min
  6902. elif i[:14] == 'bacteria_to_hr':
  6903. bac_to_hr = request.form[i]
  6904. elif i[:15] == 'bacteria_to_min':
  6905. bac_to_min = request.form[i]
  6906. bacteria.end = bac_to_hr + ":" + bac_to_min
  6907. bacteria.datetime = current_time
  6908. bacteria.tank_num = int(tid)
  6909. db.session.add(bacteria)
  6910. db.session.commit()
  6911. # 消毒
  6912. elif i[:9] == 'disinfect':
  6913. if i[:18] == 'disinfect_duration':
  6914. disinfect = Cargo2Disinfect()
  6915. disinfect.duration = request.form[i]
  6916. elif i[:17] == 'disinfect_from_hr':
  6917. di_from_hr = request.form[i]
  6918. elif i[:18] == 'disinfect_from_min':
  6919. di_from_min = request.form[i]
  6920. disinfect.start = di_from_hr + ":" + di_from_min
  6921. elif i[:15] == 'disinfect_to_hr':
  6922. di_to_hr = request.form[i]
  6923. elif i[:16] == 'disinfect_to_min':
  6924. di_to_min = request.form[i]
  6925. disinfect.end = di_to_hr + ":" + di_to_min
  6926. disinfect.datetime = current_time
  6927. disinfect.tank_num = int(tid)
  6928. db.session.add(disinfect)
  6929. db.session.commit()
  6930. # 加熱
  6931. elif i[:7] == 'heating':
  6932. if i[:16] == 'heating_duration':
  6933. heating = Heating()
  6934. heating.duration = request.form[i]
  6935. elif i[:15] == 'heating_from_hr':
  6936. heat_from_hr = request.form[i]
  6937. elif i[:16] == 'heating_from_min':
  6938. heat_from_min = request.form[i]
  6939. heating.start = heat_from_hr + ":" + heat_from_min
  6940. elif i[:13] == 'heating_to_hr':
  6941. heat_to_hr = request.form[i]
  6942. elif i[:14] == 'heating_to_min':
  6943. heat_to_min = request.form[i]
  6944. heating.end = heat_to_hr + ":" + heat_to_min
  6945. heating.datetime = current_time
  6946. heating.tank_num = int(tid)
  6947. db.session.add(heating)
  6948. db.session.commit()
  6949. # 攪拌
  6950. elif i[:4] == 'stir':
  6951. if i[:13] == 'stir_duration':
  6952. stir = Stir()
  6953. stir.duration = request.form[i]
  6954. elif i[:12] == 'stir_from_hr':
  6955. stir_from_hr = request.form[i]
  6956. elif i[:13] == 'stir_from_min':
  6957. stir_from_min = request.form[i]
  6958. stir.start = stir_from_hr + ":" + stir_from_min
  6959. elif i[:10] == 'stir_to_hr':
  6960. stir_to_hr = request.form[i]
  6961. elif i[:11] == 'stir_to_min':
  6962. stir_to_min = request.form[i]
  6963. stir.end = stir_to_hr + ":" + stir_to_min
  6964. stir.datetime = current_time
  6965. stir.tank_num = int(tid)
  6966. db.session.add(stir)
  6967. db.session.commit()
  6968. # 注水
  6969. elif i[:5] == 'water':
  6970. if i[:14] == 'water_duration':
  6971. water = WaterInjection()
  6972. water.duration = request.form[i]
  6973. elif i[:13] == 'water_from_hr':
  6974. water_from_hr = request.form[i]
  6975. elif i[:14] == 'water_from_min':
  6976. water_from_min = request.form[i]
  6977. water.start = water_from_hr + ":" + water_from_min
  6978. elif i[:11] == 'water_to_hr':
  6979. water_to_hr = request.form[i]
  6980. elif i[:12] == 'water_to_min':
  6981. water_to_min = request.form[i]
  6982. water.end = water_to_hr + ":" + water_to_min
  6983. water.datetime = current_time
  6984. water.tank_num = int(tid)
  6985. db.session.add(water)
  6986. db.session.commit()
  6987. # 開上閥
  6988. elif i[:9] == 'highValve':
  6989. if i[:18] == 'highValve_duration':
  6990. top = TopValve()
  6991. top.duration = request.form[i]
  6992. elif i[:17] == 'highValve_from_hr':
  6993. h_valve_from_hr = request.form[i]
  6994. elif i[:18] == 'highValve_from_min':
  6995. h_valve_from_min = request.form[i]
  6996. top.start = h_valve_from_hr + ":" + h_valve_from_min
  6997. elif i[:15] == 'highValve_to_hr':
  6998. h_valve_to_hr = request.form[i]
  6999. elif i[:16] == 'highValve_to_min':
  7000. h_valve_to_min = request.form[i]
  7001. top.end = h_valve_to_hr + ":" + h_valve_to_min
  7002. top.datetime = current_time
  7003. top.tank_num = int(tid)
  7004. db.session.add(top)
  7005. db.session.commit()
  7006. # 開下閥
  7007. elif i[:8] == 'lowValve':
  7008. if i[:17] == 'lowValve_duration':
  7009. bottom = BottomValve()
  7010. bottom.duration = request.form[i]
  7011. elif i[:16] == 'lowValve_from_hr':
  7012. l_valve_from_hr = request.form[i]
  7013. elif i[:17] == 'lowValve_from_min':
  7014. l_valve_from_min = request.form[i]
  7015. bottom.start = l_valve_from_hr + ":" + l_valve_from_min
  7016. elif i[:14] == 'lowValve_to_hr':
  7017. l_valve_to_hr = request.form[i]
  7018. elif i[:15] == 'lowValve_to_min':
  7019. l_valve_to_min = request.form[i]
  7020. bottom.end = l_valve_to_hr + ":" + l_valve_to_min
  7021. bottom.datetime = current_time
  7022. bottom.tank_num = int(tid)
  7023. db.session.add(bottom)
  7024. db.session.commit()
  7025. # 溫度
  7026. elif i[:3] == 'tem':
  7027. if i[:12] == 'tem_duration':
  7028. tem = Temperature()
  7029. tem.duration = request.form[i]
  7030. elif i[:11] == 'tem_from_hr':
  7031. tem_from_hr = request.form[i]
  7032. elif i[:12] == 'tem_from_min':
  7033. tem_from_min = request.form[i]
  7034. tem.start = tem_from_hr + ":" + tem_from_min
  7035. elif i[:9] == 'tem_to_hr':
  7036. tem_to_hr = request.form[i]
  7037. elif i[:10] == 'tem_to_min':
  7038. tem_to_min = request.form[i]
  7039. tem.end = tem_to_hr + ":" + tem_to_min
  7040. tem.datetime = current_time
  7041. tem.tank_num = int(tid)
  7042. db.session.add(tem)
  7043. db.session.commit()
  7044. return render_template('cargo2.html', params=locals())
  7045. # 貨櫃2感測器的發酵槽訪問路徑
  7046. @main.route('/cargo2_sensor_tanks', methods=['GET', 'POST'])
  7047. def cargo2_sensor_tanks_views():
  7048. username = session['uname']
  7049. if request.method == 'GET':
  7050. return render_template('cargo2_sensor_tanks.html', params=locals())
  7051. else:
  7052. pass
  7053. # 貨櫃2感測器發酵槽的清單訪問路徑
  7054. @main.route('/cargo2_sensor/<tid>', methods=['GET', 'POST'])
  7055. def s_tank_views(tid):
  7056. # 判斷用戶是否已關閉瀏覽器或登出後,在訪問這個route,如果沒有session就回登入頁
  7057. try:
  7058. username = session['uname']
  7059. except KeyError:
  7060. return redirect('/')
  7061. if request.method == 'GET':
  7062. # Rita 網頁端 params.tank_tem.tem
  7063. # Coffee/CoffeeProject/app/templates/cargo2_sensor.html
  7064. tank_tem = TankTemSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7065. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7066. tank_ec = TankECSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7067. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7068. return render_template('cargo2_sensor.html', params=locals())
  7069. else:
  7070. pass
  7071. # 貨櫃2感測器發酵槽歷史數據的訪問路徑
  7072. @main.route('/history_data', methods=['GET', 'POST'])
  7073. def history_data_views():
  7074. if request.method == 'GET':
  7075. # json
  7076. # tid:tid_D1
  7077. # sensor_name:soil_Temp
  7078. # avg:1
  7079. # max:1
  7080. # min:1
  7081. # time-interval:month
  7082. # date-start:2021-07-01
  7083. # date-end:2021-07-28
  7084. info = request.args.to_dict()
  7085. evt = info['evt']
  7086. avg = int(info['avg'])
  7087. max = int(info['max'])
  7088. min = int(info['min'])
  7089. time_interval = info['time-interval']
  7090. print(info)
  7091. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  7092. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  7093. # print(info)
  7094. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  7095. # print(D)
  7096. # {'all': [['2021-Feb-19_16:46:10', '24.4'], ['2021-Feb-19_16:46:20', '24.4'], ['2021-Feb-19_16:46:30', '24.4'], ['2021-Feb-19_16:46:41', '24.4'], ['2021-Feb-19_16:46:50', '24.4'], ['2021-Feb-19_16:47:00', '24.4'], ['2021-Feb-19_16:47:10', '24.4'], ['2021-Feb-19_16:47:20', '24.4'], ['2021-Feb-19_16:47:30', '24.4'], ['2021-Feb-19_16:47:40', '24.5'], ['2021-Feb-19_16:47:50', '24.5'], ['2021-Feb-19_16:48:00', '24.5'], ['2021-Feb-19_16:48:10', '24.5'], ['2021-Feb-19_16:48:20', '24.5'], ['2021-Feb-19_16:48:29', '24.5'], ['2021-Feb-19_16:48:39', '24.5'], ['2021-Feb-19_16:48:50', '24.5'], ['2021-Feb-19_16:49:00', '24.5'], ['2021-Feb-19_16:49:10', '24.5'], ['2021-Feb-19_16:49:19', '24.5'], ['2021-Feb-19_16:49:29', '24.5'], ['2021-Feb-19_16:49:39', '24.5'], ['2021-Feb-19_16:49:49', '24.5'], ['2021-Feb-19_16:49:59', '24.5'], ['2021-Feb-19_16:50:10', '24.5'], ['2021-Feb-19_16:50:19', '24.5'], ['2021-Feb-19_16:50:29', '24.5'], ['2021-Feb-19_16:50:39', '24.5'], ['2021-Feb-19_16:50:49', '24.5'], ['2021-Feb-19_16:50:59', '24.5'], ['2021-Feb-19_18:07:10', '25.3'], ['2021-Feb-19_18:07:20', '25.3'], ['2021-Feb-19_18:07:30', '25.3'], ['2021-Feb-19_18:07:40', '25.3'], ['2021-Feb-19_18:07:49', '25.3'], ['2021-Feb-19_18:07:59', '25.3'], ['2021-Feb-19_18:08:10', '25.3'], ['2021-Feb-19_18:08:20', '25.3'], ['2021-Feb-19_18:08:30', '25.2'], ['2021-Feb-19_18:08:39', '25.2'], ['2021-Feb-19_18:08:49', '25.2']],
  7097. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  7098. # 192.168.50.65 - - [27/Jul/2021 11:57:23] "GET /history_data?evt=1-溫濕度&avg=1&max=0&min=0&time-interval=hour&date-start=2021-01-01&date-end=2021-07-27 HTTP/1.1" 200 -
  7099. date_start = info['date-start']
  7100. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  7101. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  7102. date_end = '-'.join(date_end_list) # '2021-05-19'
  7103. tank_num = evt.split('-')[0] # 1
  7104. sensor = evt.split('-')[1] # 溫濕度
  7105. L = []
  7106. D = {}
  7107. maxData = []
  7108. minData = []
  7109. avgData = []
  7110. def sensorData(data_name): # data_name = "tem"
  7111. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  7112. interval = 0
  7113. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  7114. if time_interval == 'month':
  7115. interval = "M" # interval = "M"
  7116. elif time_interval == 'day':
  7117. interval = "D"
  7118. elif time_interval == 'hour':
  7119. interval = "H"
  7120. if how == "max":
  7121. # data = df.resample(interval, how={data_name:how})
  7122. # 最新版的pandas
  7123. data = df.resample(interval).max() # 取樣頻率 "H"
  7124. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  7125. data = data.dropna(axis=0, how='any')
  7126. if time_interval == ('hour' or 'day'):
  7127. data.index = pd.to_datetime(
  7128. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7129. for a in range(0, len(data.index)):
  7130. l = []
  7131. # 如果是逐時,才顯示小時分秒
  7132. if time_interval == 'hour':
  7133. l.append(str(data.index[a]))
  7134. else:
  7135. l.append(str(data.index[a]).split(' ')[0])
  7136. l.append(str(data[data_name][a]))
  7137. maxData.append(l)
  7138. D['max'] = maxData
  7139. elif how == "mean":
  7140. # data = df.resample(interval, how={data_name:how})
  7141. # 最新版的pandas
  7142. data = df.resample(interval).mean()
  7143. # 刪除具有NaN的值
  7144. data = data.dropna(axis=0, how='any')
  7145. # 將平均數取自小數1位
  7146. data = data.round({data_name: 1})
  7147. for a in range(0, len(data.index)):
  7148. l = []
  7149. # 如果是逐時,才顯示小時分秒
  7150. if time_interval == 'hour':
  7151. l.append(str(data.index[a]))
  7152. else:
  7153. l.append(str(data.index[a]).split(' ')[0])
  7154. l.append(str(data[data_name][a]))
  7155. avgData.append(l)
  7156. D['avg'] = avgData
  7157. elif how == "min":
  7158. # data = df.resample(interval, how={data_name:how})
  7159. # 最新版的pandas
  7160. data = df.resample(interval).min()
  7161. # 刪除具有NaN的值
  7162. data = data.dropna(axis=0, how='any')
  7163. for a in range(0, len(data.index)):
  7164. # print(data.index[a])
  7165. l = []
  7166. # 如果是逐時,才顯示小時分秒
  7167. if time_interval == 'hour':
  7168. l.append(str(data.index[a]))
  7169. else:
  7170. l.append(str(data.index[a]).split(' ')[0])
  7171. l.append(str(data[data_name][a]))
  7172. minData.append(l)
  7173. D['min'] = minData
  7174. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  7175. df['datetime'] = pd.to_datetime(
  7176. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7177. # print(df['datetime']) # 0 2021-02-19 16:46:10
  7178. # 1 2021-02-19 16:46:20
  7179. # 2 2021-02-19 16:46:30
  7180. # 3 2021-02-19 16:46:41
  7181. df[data_name] = df[data_name].astype(float)
  7182. df = df.set_index('datetime') # 将datetime设置为index
  7183. # print(df) # datetime tem
  7184. # 2021-02-19 16:46:10 24.4
  7185. # 2021-02-19 16:46:20 24.4
  7186. if time_interval == 'month':
  7187. if max:
  7188. dataResample(time_interval, "max", data_name)
  7189. if avg:
  7190. dataResample(time_interval, "mean", data_name)
  7191. if min:
  7192. dataResample(time_interval, "min", data_name)
  7193. elif time_interval == 'day':
  7194. if max:
  7195. dataResample(time_interval, "max", data_name)
  7196. if avg:
  7197. dataResample(time_interval, "mean", data_name)
  7198. if min:
  7199. dataResample(time_interval, "min", data_name)
  7200. elif time_interval == 'hour':
  7201. if max:
  7202. dataResample(time_interval, "max", data_name)
  7203. if avg:
  7204. dataResample(time_interval, "mean", data_name)
  7205. if min:
  7206. dataResample(time_interval, "min", data_name)
  7207. if sensor == '溫濕度':
  7208. # tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).order_by(text('datetime desc')).all()
  7209. # [7/27 Benson] tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).filter(TankTemSensor.datetime.between(date_start, date_end)).all()
  7210. tank_tem = dry_tank_SHT11.query.filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7211. # .filter_by(tank_num="D"+tank_num)
  7212. for tem in tank_tem:
  7213. l = [] # l = []
  7214. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  7215. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7216. l.append(time) # l = ['2021-Feb-19_16:46:10']
  7217. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  7218. l.append(tem.SHT11_Temp)
  7219. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  7220. # print(L)
  7221. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  7222. sensorData("tem")
  7223. elif sensor == '酸鹼值':
  7224. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7225. TankPHSensor.datetime.between(date_start, date_end)).all()
  7226. for ph in tank_ph:
  7227. l = []
  7228. time = dt.strftime(ph.datetime, '%Y-%b-%d_%H:%M:%S')
  7229. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7230. l.append(time)
  7231. l.append(ph.ph)
  7232. L.append(l)
  7233. # print(L)
  7234. D['all'] = L
  7235. sensorData("ph")
  7236. elif sensor == 'EC值':
  7237. tank_ec = TankECSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7238. TankECSensor.datetime.between(date_start, date_end)).all()
  7239. for ec in tank_ec:
  7240. l = []
  7241. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  7242. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7243. l.append(time)
  7244. l.append(ec.ec)
  7245. L.append(l)
  7246. # print(L)
  7247. D['all'] = L
  7248. sensorData("ec")
  7249. elif sensor == '超音波':
  7250. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7251. TankSonicSensor.datetime.between(date_start, date_end)).all()
  7252. for sonic in tank_sonic:
  7253. l = []
  7254. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7255. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7256. l.append(time)
  7257. l.append(sonic.sonic)
  7258. L.append(l)
  7259. # print(L)
  7260. D['all'] = L
  7261. sensorData("sonic")
  7262. print(D)
  7263. return json.dumps(D)
  7264. else:
  7265. pass
  7266. # Rita 改寫
  7267. @main.route('/history_data_new', methods=['GET', 'POST'])
  7268. def history_data_new_views():
  7269. if request.method == 'GET':
  7270. # json
  7271. # tid:tid_D1
  7272. # sensor_name:soil_Temp
  7273. # avg:1
  7274. # max:1
  7275. # min:1
  7276. # time-interval:month
  7277. # date-start:2021-07-01
  7278. # date-end:2021-07-28
  7279. info = request.args.to_dict()
  7280. # evt = info['evt']
  7281. tid = info['tid']
  7282. sensor_name = info['sensor_name']
  7283. avg = int(info['avg'])
  7284. max = int(info['max'])
  7285. min = int(info['min'])
  7286. time_interval = info['time-interval']
  7287. print("info:", info)
  7288. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  7289. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  7290. # print(info)
  7291. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  7292. # print(D)
  7293. # {'all': [['2021-Feb-19_16:46:10', '24.4'], ['2021-Feb-19_16:46:20', '24.4'], ['2021-Feb-19_16:46:30', '24.4'], ['2021-Feb-19_16:46:41', '24.4'], ['2021-Feb-19_16:46:50', '24.4'], ['2021-Feb-19_16:47:00', '24.4'], ['2021-Feb-19_16:47:10', '24.4'], ['2021-Feb-19_16:47:20', '24.4'], ['2021-Feb-19_16:47:30', '24.4'], ['2021-Feb-19_16:47:40', '24.5'], ['2021-Feb-19_16:47:50', '24.5'], ['2021-Feb-19_16:48:00', '24.5'], ['2021-Feb-19_16:48:10', '24.5'], ['2021-Feb-19_16:48:20', '24.5'], ['2021-Feb-19_16:48:29', '24.5'], ['2021-Feb-19_16:48:39', '24.5'], ['2021-Feb-19_16:48:50', '24.5'], ['2021-Feb-19_16:49:00', '24.5'], ['2021-Feb-19_16:49:10', '24.5'], ['2021-Feb-19_16:49:19', '24.5'], ['2021-Feb-19_16:49:29', '24.5'], ['2021-Feb-19_16:49:39', '24.5'], ['2021-Feb-19_16:49:49', '24.5'], ['2021-Feb-19_16:49:59', '24.5'], ['2021-Feb-19_16:50:10', '24.5'], ['2021-Feb-19_16:50:19', '24.5'], ['2021-Feb-19_16:50:29', '24.5'], ['2021-Feb-19_16:50:39', '24.5'], ['2021-Feb-19_16:50:49', '24.5'], ['2021-Feb-19_16:50:59', '24.5'], ['2021-Feb-19_18:07:10', '25.3'], ['2021-Feb-19_18:07:20', '25.3'], ['2021-Feb-19_18:07:30', '25.3'], ['2021-Feb-19_18:07:40', '25.3'], ['2021-Feb-19_18:07:49', '25.3'], ['2021-Feb-19_18:07:59', '25.3'], ['2021-Feb-19_18:08:10', '25.3'], ['2021-Feb-19_18:08:20', '25.3'], ['2021-Feb-19_18:08:30', '25.2'], ['2021-Feb-19_18:08:39', '25.2'], ['2021-Feb-19_18:08:49', '25.2']],
  7294. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  7295. # 192.168.50.65 - - [27/Jul/2021 11:57:23] "GET /history_data?evt=1-溫濕度&avg=1&max=0&min=0&time-interval=hour&date-start=2021-01-01&date-end=2021-07-27 HTTP/1.1" 200 -
  7296. date_start = info['date-start']
  7297. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  7298. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  7299. date_end = '-'.join(date_end_list) # '2021-05-19'
  7300. # tank_num = evt.split('-')[0] # 1
  7301. # sensor = evt.split('-')[1] # 溫濕度
  7302. tank_num = tid # D1
  7303. sensor = sensor_name # soil_Temp
  7304. L = []
  7305. D = {}
  7306. maxData = []
  7307. minData = []
  7308. avgData = []
  7309. def sensorData(data_name): # data_name = "tem"
  7310. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  7311. interval = 0
  7312. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  7313. if time_interval == 'month':
  7314. interval = "M" # interval = "M"
  7315. elif time_interval == 'day':
  7316. interval = "D"
  7317. elif time_interval == 'hour':
  7318. interval = "H"
  7319. if how == "max":
  7320. # data = df.resample(interval, how={data_name:how})
  7321. # 最新版的pandas
  7322. data = df.resample(interval).max() # 取樣頻率 'H'
  7323. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  7324. data = data.dropna(axis=0, how='any')
  7325. if time_interval == ('hour' or 'day'):
  7326. data.index = pd.to_datetime(
  7327. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7328. for a in range(0, len(data.index)):
  7329. l = []
  7330. # 如果是逐時,才顯示小時分秒
  7331. if time_interval == 'hour':
  7332. l.append(str(data.index[a]))
  7333. else:
  7334. l.append(str(data.index[a]).split(' ')[0])
  7335. l.append(str(data[data_name][a]))
  7336. maxData.append(l)
  7337. D['max'] = maxData
  7338. elif how == "mean":
  7339. # data = df.resample(interval, how={data_name:how})
  7340. # 最新版的pandas
  7341. data = df.resample(interval).mean()
  7342. # 刪除具有NaN的值
  7343. data = data.dropna(axis=0, how='any')
  7344. # 將平均數取自小數1位
  7345. data = data.round({data_name: 1})
  7346. for a in range(0, len(data.index)):
  7347. l = []
  7348. # 如果是逐時,才顯示小時分秒
  7349. if time_interval == 'hour':
  7350. l.append(str(data.index[a]))
  7351. else:
  7352. l.append(str(data.index[a]).split(' ')[0])
  7353. l.append(str(data[data_name][a]))
  7354. avgData.append(l)
  7355. D['avg'] = avgData
  7356. elif how == "min":
  7357. # data = df.resample(interval, how={data_name:how})
  7358. # 最新版的pandas
  7359. data = df.resample(interval).min()
  7360. # 刪除具有NaN的值
  7361. data = data.dropna(axis=0, how='any')
  7362. for a in range(0, len(data.index)):
  7363. # print(data.index[a])
  7364. l = []
  7365. # 如果是逐時,才顯示小時分秒
  7366. if time_interval == 'hour':
  7367. l.append(str(data.index[a]))
  7368. else:
  7369. l.append(str(data.index[a]).split(' ')[0])
  7370. l.append(str(data[data_name][a]))
  7371. minData.append(l)
  7372. D['min'] = minData
  7373. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  7374. df['datetime'] = pd.to_datetime(
  7375. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7376. # print(df['datetime']) # 0 2021-02-19 16:46:10
  7377. # 1 2021-02-19 16:46:20
  7378. # 2 2021-02-19 16:46:30
  7379. # 3 2021-02-19 16:46:41
  7380. df[data_name] = df[data_name].astype(float)
  7381. df = df.set_index('datetime') # 将datetime设置为index
  7382. # print(df) # datetime tem
  7383. # 2021-02-19 16:46:10 24.4
  7384. # 2021-02-19 16:46:20 24.4
  7385. if time_interval == 'month':
  7386. if max:
  7387. dataResample(time_interval, "max", data_name)
  7388. if avg:
  7389. dataResample(time_interval, "mean", data_name)
  7390. if min:
  7391. dataResample(time_interval, "min", data_name)
  7392. elif time_interval == 'day':
  7393. if max:
  7394. dataResample(time_interval, "max", data_name)
  7395. if avg:
  7396. dataResample(time_interval, "mean", data_name)
  7397. if min:
  7398. dataResample(time_interval, "min", data_name)
  7399. elif time_interval == 'hour':
  7400. if max:
  7401. dataResample(time_interval, "max", data_name)
  7402. if avg:
  7403. dataResample(time_interval, "mean", data_name)
  7404. if min:
  7405. dataResample(time_interval, "min", data_name)
  7406. if tank_num[:2] == 'DI':
  7407. # 乾燥入料儲豆槽
  7408. if sensor == 'UltraSonic':
  7409. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num=tank_num).filter(dry_input_sensor.datetime.between(date_start, date_end)).all()
  7410. for sonic in tank_UltraSonic:
  7411. l = []
  7412. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7413. l.append(time)
  7414. l.append(sonic.UltraSonic)
  7415. L.append(l)
  7416. D['all'] = L
  7417. sensorData("UltraSonic")
  7418. elif tank_num[:2] == 'DO':
  7419. # 乾燥出料儲豆槽
  7420. if sensor == 'UltraSonic':
  7421. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num=tank_num).filter(dry_output_sensor.datetime.between(date_start, date_end)).all()
  7422. for sonic in tank_UltraSonic:
  7423. l = []
  7424. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7425. l.append(time)
  7426. l.append(sonic.UltraSonic)
  7427. L.append(l)
  7428. D['all'] = L
  7429. sensorData("UltraSonic")
  7430. elif tank_num[:1] == 'D':
  7431. # 乾燥槽
  7432. if sensor == 'SHT11_Temp':
  7433. tank_tem = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7434. for tem in tank_tem:
  7435. l = [] # l = []
  7436. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  7437. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7438. l.append(time) # l = ['2021-Feb-19_16:46:10']
  7439. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  7440. l.append(tem.SHT11_Temp)
  7441. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  7442. # print(L)
  7443. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  7444. sensorData("SHT11_Temp")
  7445. elif sensor == 'SHT11_Humidity':
  7446. tank_hum = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7447. for hum in tank_hum:
  7448. l = []
  7449. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  7450. l.append(time)
  7451. l.append(hum.SHT11_Humidity)
  7452. L.append(l)
  7453. D['all'] = L
  7454. sensorData("SHT11_Humidity")
  7455. elif sensor == 'UltraSonic':
  7456. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num=tank_num).filter(dry_tank_UltraSonic.datetime.between(date_start, date_end)).all()
  7457. for sonic in tank_UltraSonic:
  7458. l = []
  7459. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7460. l.append(time)
  7461. l.append(sonic.UltraSonic)
  7462. L.append(l)
  7463. D['all'] = L
  7464. sensorData("UltraSonic")
  7465. elif sensor == 'PA':
  7466. tank_PA = dry_tank_PA.query.filter_by(tank_num=tank_num).filter(dry_tank_PA.datetime.between(date_start, date_end)).all()
  7467. for pa in tank_PA:
  7468. l = []
  7469. time = dt.strftime(pa.datetime, '%Y-%b-%d_%H:%M:%S')
  7470. l.append(time)
  7471. l.append(pa.PA)
  7472. L.append(l)
  7473. D['all'] = L
  7474. sensorData("PA")
  7475. elif sensor == 'soil_Temp':
  7476. tank_soiltemp = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7477. for temp in tank_soiltemp:
  7478. l = []
  7479. time = dt.strftime(temp.datetime, '%Y-%b-%d_%H:%M:%S')
  7480. l.append(time)
  7481. l.append(temp.soil_Temp)
  7482. L.append(l)
  7483. D['all'] = L
  7484. sensorData("soil_Temp")
  7485. elif sensor == 'soil_Humidity':
  7486. tank_soilHum = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7487. for hum in tank_soilHum:
  7488. l = []
  7489. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  7490. l.append(time)
  7491. l.append(hum.soil_EC)
  7492. L.append(l)
  7493. D['all'] = L
  7494. sensorData("soil_Humidity")
  7495. elif sensor == 'soil_EC':
  7496. tank_soilec = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7497. for ec in tank_soilec:
  7498. l = []
  7499. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  7500. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7501. l.append(time)
  7502. l.append(ec.soil_EC)
  7503. L.append(l)
  7504. D['all'] = L
  7505. sensorData("soil_EC")
  7506. elif tank_num[:2] == 'FI':
  7507. if sensor == 'UltraSonic':
  7508. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_input_UltraSonic.datetime.between(date_start, date_end)).all()
  7509. for UltraSonic in input_UltraSonic:
  7510. l = []
  7511. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7512. l.append(time)
  7513. l.append(UltraSonic.UltraSonic)
  7514. L.append(l)
  7515. D['all'] = L
  7516. sensorData("UltraSonic")
  7517. elif tank_num[:2] == 'FO':
  7518. if sensor == 'UltraSonic':
  7519. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_output_UltraSonic.datetime.between(date_start, date_end)).all()
  7520. for UltraSonic in output_UltraSonic:
  7521. l = []
  7522. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7523. l.append(time)
  7524. l.append(UltraSonic.UltraSonic)
  7525. L.append(l)
  7526. D['all'] = L
  7527. sensorData("UltraSonic")
  7528. elif tank_num[:1] == 'F':
  7529. if sensor == 'LiDAR':
  7530. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num = tank_num)\
  7531. .filter(ferment_tank_LiDAR.datetime.between(date_start, date_end)).all()
  7532. for LiDAR in tank_LiDAR:
  7533. l = []
  7534. time = dt.strftime(LiDAR.datetime, '%Y-%b-%d_%H:%M:%S')
  7535. l.append(time)
  7536. l.append(LiDAR.LiDAR)
  7537. L.append(l)
  7538. D['all'] = L
  7539. sensorData("LiDAR")
  7540. elif sensor == 'motorEncoder':
  7541. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num = tank_num)\
  7542. .filter(ferment_tank_motorEncoder.datetime.between(date_start, date_end)).all()
  7543. for motorEncoder in tank_motorEncoder:
  7544. l = []
  7545. time = dt.strftime(motorEncoder.datetime, '%Y-%b-%d_%H:%M:%S')
  7546. l.append(time)
  7547. l.append(motorEncoder.motorEncoder)
  7548. L.append(l)
  7549. D['all'] = L
  7550. sensorData("motorEncoder")
  7551. elif sensor == 'PressureWaterLevel':
  7552. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num = tank_num)\
  7553. .filter(ferment_tank_PressureWaterLevel.datetime.between(date_start, date_end)).all()
  7554. for PressureWaterLevel in tank_PressureWaterLevel:
  7555. l = []
  7556. time = dt.strftime(PressureWaterLevel.datetime, '%Y-%b-%d_%H:%M:%S')
  7557. l.append(time)
  7558. l.append(PressureWaterLevel.PressureWaterLevel)
  7559. l.append('{:.2f}'.format(float(PressureWaterLevel.PressureWaterLevel)))
  7560. L.append(l)
  7561. D['all'] = L
  7562. sensorData("PressureWaterLevel")
  7563. elif sensor == 'SHT11_Temp':
  7564. tank_Temp = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  7565. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  7566. for Temp in tank_Temp:
  7567. l = []
  7568. time = dt.strftime(Temp.datetime, '%Y-%b-%d_%H:%M:%S')
  7569. l.append(time)
  7570. l.append(Temp.SHT11_Temp)
  7571. L.append(l)
  7572. D['all'] = L
  7573. sensorData("SHT11_Temp")
  7574. elif sensor == 'SHT11_Humidity':
  7575. tank_Humidity = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  7576. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  7577. for Humidity in tank_Humidity:
  7578. l = []
  7579. time = dt.strftime(Humidity.datetime, '%Y-%b-%d_%H:%M:%S')
  7580. l.append(time)
  7581. l.append(Humidity.SHT11_Humidity)
  7582. L.append(l)
  7583. D['all'] = L
  7584. sensorData("SHT11_Humidity")
  7585. elif sensor == 'CO2':
  7586. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num = tank_num)\
  7587. .filter(ferment_tank_CO2.datetime.between(date_start, date_end)).all()
  7588. for CO2 in tank_CO2:
  7589. l = []
  7590. time = dt.strftime(CO2.datetime, '%Y-%b-%d_%H:%M:%S')
  7591. l.append(time)
  7592. l.append(CO2.CO2)
  7593. L.append(l)
  7594. D['all'] = L
  7595. sensorData("CO2")
  7596. elif sensor == 'PH':
  7597. tank_PH = ferment_tank_PH.query.filter_by(tank_num = tank_num)\
  7598. .filter(ferment_tank_PH.datetime.between(date_start, date_end)).all()
  7599. for PH in tank_PH:
  7600. l = []
  7601. time = dt.strftime(PH.datetime, '%Y-%b-%d_%H:%M:%S')
  7602. l.append(time)
  7603. l.append(PH.PH)
  7604. L.append(l)
  7605. D['all'] = L
  7606. sensorData("PH")
  7607. elif sensor == 'ORP':
  7608. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num = tank_num)\
  7609. .filter(ferment_tank_ORP.datetime.between(date_start, date_end)).all()
  7610. for ORP in tank_ORP:
  7611. l = []
  7612. time = dt.strftime(ORP.datetime, '%Y-%b-%d_%H:%M:%S')
  7613. l.append(time)
  7614. l.append(ORP.ORP)
  7615. L.append(l)
  7616. D['all'] = L
  7617. sensorData("ORP")
  7618. elif sensor == 'DO':
  7619. tank_DO = ferment_tank_DO.query.filter_by(tank_num = tank_num)\
  7620. .filter(ferment_tank_DO.datetime.between(date_start, date_end)).all()
  7621. for DO in tank_DO:
  7622. l = []
  7623. time = dt.strftime(DO.datetime, '%Y-%b-%d_%H:%M:%S')
  7624. l.append(time)
  7625. l.append(DO.DO)
  7626. L.append(l)
  7627. D['all'] = L
  7628. sensorData("DO")
  7629. elif sensor == 'EC':
  7630. tank_EC = ferment_tank_EC.query.filter_by(tank_num = tank_num)\
  7631. .filter(ferment_tank_EC.datetime.between(date_start, date_end)).all()
  7632. for EC in tank_EC:
  7633. l = []
  7634. time = dt.strftime(EC.datetime, '%Y-%b-%d_%H:%M:%S')
  7635. l.append(time)
  7636. l.append(EC.EC)
  7637. L.append(l)
  7638. D['all'] = L
  7639. sensorData("EC")
  7640. elif sensor == 'PA':
  7641. tank_PA = ferment_tank_PA.query.filter_by(tank_num = tank_num)\
  7642. .filter(ferment_tank_PA.datetime.between(date_start, date_end)).all()
  7643. for PA in tank_PA:
  7644. l = []
  7645. time = dt.strftime(PA.datetime, '%Y-%b-%d_%H:%M:%S')
  7646. l.append(time)
  7647. l.append(PA.PA)
  7648. L.append(l)
  7649. D['all'] = L
  7650. sensorData("PA")
  7651. print(D)
  7652. return json.dumps(D)
  7653. else:
  7654. pass
  7655. # 貨櫃2致動器的發酵槽訪問路徑
  7656. @main.route('/cargo2_actuator_tanks', methods=['GET', 'POST'])
  7657. def cargo2_actuator_tanks_views():
  7658. username = session['uname']
  7659. if request.method == 'GET':
  7660. return render_template('cargo2_actuator_tanks.html', params=locals())
  7661. else:
  7662. pass
  7663. # 貨櫃2致動器發酵槽的清單訪問路徑
  7664. @main.route('/cargo2_actuator/<tid>', methods=['GET', 'POST'])
  7665. def cargo2_actuator_views(tid):
  7666. username = session['uname']
  7667. if request.method == 'GET':
  7668. return render_template('cargo2_actuator.html', params=locals())
  7669. else:
  7670. pass
  7671. # 貨櫃3的訪問路徑
  7672. @main.route('/cargo3', methods=['GET', 'POST'])
  7673. def cargo3_views():
  7674. username = session['uname']
  7675. if request.method == 'GET':
  7676. return render_template('cargo3.html', params=locals())
  7677. else:
  7678. pass
  7679. # 貨櫃3排程的訪問路徑
  7680. @main.route('/cargo3_schedule', methods=['GET', 'POST'])
  7681. def cargo3_schedule_views():
  7682. username = session['uname']
  7683. if request.method == 'GET':
  7684. # 將已儲存的排程資料傳給前端
  7685. # 提升機
  7686. try:
  7687. hoist = Hoist.query.order_by(text('datetime desc')).first()
  7688. datetime = hoist.datetime
  7689. hoists = Hoist.query.filter_by(datetime=datetime).all()
  7690. except Exception as e:
  7691. pass
  7692. # 烘乾機
  7693. try:
  7694. dryer = Dryer.query.order_by(text('datetime desc')).first()
  7695. datetime = dryer.datetime
  7696. dryers = Dryer.query.filter_by(datetime=datetime).all()
  7697. except Exception as e:
  7698. pass
  7699. return render_template('cargo3_schedule.html', params=locals())
  7700. else:
  7701. # Rita: "POST /b_cargo3 HTTP/1.1" 404 -
  7702. current_time = dt.now()
  7703. # 循環從前端提交過來的資料
  7704. for i in request.form:
  7705. print('Rita test i :', i)
  7706. # 堤升機
  7707. if i[:5] == 'hoist':
  7708. if i[:14] == 'hoist_duration':
  7709. hoist = Hoist()
  7710. hoist.duration = request.form[i]
  7711. elif i[:13] == 'hoist_from_hr':
  7712. ho_from_hr = request.form[i]
  7713. elif i[:14] == 'hoist_from_min':
  7714. ho_from_min = request.form[i]
  7715. hoist.start = ho_from_hr + ":" + ho_from_min
  7716. elif i[:11] == 'hoist_to_hr':
  7717. ho_to_hr = request.form[i]
  7718. elif i[:12] == 'hoist_to_min':
  7719. ho_to_min = request.form[i]
  7720. hoist.end = ho_to_hr + ":" + ho_to_min
  7721. hoist.datetime = current_time
  7722. db.session.add(hoist)
  7723. db.session.commit()
  7724. # 烘乾機
  7725. elif i[:5] == 'dryer':
  7726. if i[:14] == 'dryer_duration':
  7727. dryer = Dryer()
  7728. dryer.duration = request.form[i]
  7729. elif i[:13] == 'dryer_from_hr':
  7730. dry_from_hr = request.form[i]
  7731. elif i[:14] == 'dryer_from_min':
  7732. dry_from_min = request.form[i]
  7733. dryer.start = dry_from_hr + ":" + dry_from_min
  7734. elif i[:11] == 'dryer_to_hr':
  7735. dry_to_hr = request.form[i]
  7736. elif i[:12] == 'dryer_to_min':
  7737. dry_to_min = request.form[i]
  7738. dryer.end = dry_to_hr + ":" + dry_to_min
  7739. dryer.datetime = current_time
  7740. db.session.add(dryer)
  7741. db.session.commit()
  7742. return render_template('cargo3.html', params=locals())
  7743. # 影像串流的訪問路徑
  7744. @main.route('/video', methods=['GET', 'POST'])
  7745. def video_views():
  7746. username = session['uname']
  7747. if request.method == 'GET':
  7748. return render_template('video.html', params=locals())
  7749. else:
  7750. pass
  7751. # 影像的訪問路徑
  7752. @main.route('/learn', methods=['GET', 'POST'])
  7753. def learn_views():
  7754. username = session['uname']
  7755. if request.method == 'GET':
  7756. return render_template('learn.html', params=locals())
  7757. else:
  7758. pass
  7759. # 獲取relay狀態路徑
  7760. @main.route('/relay', methods=['GET', 'POST'])
  7761. def relay_views():
  7762. if request.method == 'GET':
  7763. relay = Relay.query.order_by(text('datetime desc')).first()
  7764. relay_status = relay.status
  7765. return jsonify({"relay": relay_status})
  7766. else:
  7767. pass
  7768. # 獲取脫皮機狀態路徑
  7769. @main.route('/peel', methods=['GET', 'POST'])
  7770. def peeling_views():
  7771. if request.method == 'GET':
  7772. peeling = PeelingMachineRPM.query.order_by(text('datetime desc')).first()
  7773. peeling_rpm = peeling.rpm
  7774. return jsonify({"peeling": peeling_rpm})
  7775. else:
  7776. pass
  7777. # 退出的訪問路徑
  7778. @main.route('/logout')
  7779. def logout_views():
  7780. if 'id' in session and 'uname' in session:
  7781. del session['id']
  7782. del session['uname']
  7783. return redirect('/')
  7784. @main.route("/udp_client", methods=['POST', 'GET'])
  7785. def udp_views():
  7786. # sl(0.5)
  7787. global c_sock
  7788. if request.method == 'GET':
  7789. # def close():
  7790. # global c_sock
  7791. # sl(600)
  7792. # c_sock.close()
  7793. # c_sock = 0
  7794. # print("c_sock is closing")
  7795. max_length = 65000
  7796. # max_length = 95000
  7797. # lab1的IP
  7798. host = "192.168.50.65"
  7799. # lab2的IP
  7800. # host = "192.168.51.160"
  7801. port = 8000
  7802. c_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  7803. # t = threading.Thread(target=close)
  7804. # t.daemon = True
  7805. # t.start()
  7806. print("test")
  7807. # dict = request.args.to_dict()
  7808. # nr = int(dict['nr'])
  7809. # if nr == 1:
  7810. # camara = 0
  7811. # elif nr == 2:
  7812. # camara = 'rtsp://admin:admin@192.168.50.182/av2_0'
  7813. # elif nr == 3:
  7814. # camara = 'rtsp://admin:abcd1234@192.168.51.101/av2_0'
  7815. # 地下室小兵
  7816. # cap = cv2.VideoCapture('rtsp://admin:abcd1234@192.168.51.48/av2_0')
  7817. # 主機攝像頭
  7818. # cap = cv2.VideoCapture(0)
  7819. # 外面小兵
  7820. # cap = cv2.VideoCapture('rtsp://admin:admin@192.168.50.182/av2_0')
  7821. cap = cv2.VideoCapture('rtsp://192.168.50.182/av0_0')
  7822. # cap = cv2.VideoCapture(0)
  7823. # cap = cv2.VideoCapture(camara)
  7824. ret, frame = cap.read()
  7825. while ret:
  7826. # compress frame
  7827. frame = cv2.resize(frame, (550, 400), interpolation=cv2.INTER_AREA)
  7828. retval, buffer = cv2.imencode(".jpg", frame)
  7829. if retval:
  7830. # convert to byte array
  7831. buffer = buffer.tobytes()
  7832. # get size of the frame
  7833. buffer_size = len(buffer)
  7834. num_of_packs = 1
  7835. if buffer_size > max_length:
  7836. num_of_packs = math.ceil(buffer_size / max_length)
  7837. frame_info = {"packs": num_of_packs}
  7838. # send the number of packs to be expected
  7839. # print("Number of packs:", num_of_packs)
  7840. c_sock.sendto(pickle.dumps(frame_info), (host, port))
  7841. left = 0
  7842. right = max_length
  7843. for i in range(num_of_packs):
  7844. # print("left:", left)
  7845. # print("right:", right)
  7846. # truncate data to send
  7847. data = buffer[left:right]
  7848. left = right
  7849. right += max_length
  7850. # send the frames accordingly
  7851. c_sock.sendto(data, (host, port))
  7852. ret, frame = cap.read()
  7853. print("done")
  7854. return "done"
  7855. else:
  7856. c_sock.shutdown(2)
  7857. c_sock.close()
  7858. c_sock = 0
  7859. print("c_sock is closing")
  7860. # 影像串流的路徑
  7861. @main.route("/video_feed", methods=['POST', 'GET'])
  7862. def video_feed_views():
  7863. print("test2")
  7864. global s_sock
  7865. if request.method == 'GET':
  7866. # 於10分鐘之後,自動關閉socket server
  7867. # if s_sock == 0:
  7868. # def socket_server_views():
  7869. # global s_sock
  7870. # print("test")
  7871. # print(s_sock)
  7872. # sl(600)
  7873. # if s_sock != 0:
  7874. # s_sock.close()
  7875. # s_sock = 0
  7876. # print('s_sock is closed')
  7877. #
  7878. # pool.submit(socket_server_views)
  7879. host = "192.168.50.65"
  7880. port = 8000
  7881. max_length = 65540
  7882. # max_length = 95540
  7883. s_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  7884. s_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  7885. s_sock.bind((host, port))
  7886. frame_info = None
  7887. buffer = None
  7888. frame = None
  7889. encodedImage = None
  7890. print("-> waiting for connection")
  7891. # 影像生成器函數,將影像以jpg格式傳給前端
  7892. def generate():
  7893. while True:
  7894. with lock:
  7895. global s_sock, frame_info, buffer, frame, encodedImage
  7896. if s_sock == 0:
  7897. break
  7898. data, address = s_sock.recvfrom(max_length)
  7899. if len(data) < 100:
  7900. frame_info = pickle.loads(data)
  7901. if frame_info:
  7902. nums_of_packs = frame_info["packs"]
  7903. for i in range(nums_of_packs):
  7904. if s_sock == 0:
  7905. break
  7906. data, address = s_sock.recvfrom(max_length)
  7907. if i == 0:
  7908. buffer = data
  7909. else:
  7910. buffer += data
  7911. frame = np.frombuffer(buffer, dtype=np.uint8)
  7912. frame = frame.reshape(frame.shape[0], 1)
  7913. frame = cv2.imdecode(frame, cv2.IMREAD_UNCHANGED)
  7914. # print(frame)
  7915. # 如果frame為None就跳過
  7916. if frame is None:
  7917. continue
  7918. frame = cv2.resize(
  7919. frame, (640, 360), interpolation=cv2.INTER_AREA)
  7920. # encode the frame in JPEG format
  7921. (flag, encodedImage) = cv2.imencode(".jpg", frame)
  7922. # ensure the frame was successfully encoded
  7923. if not flag:
  7924. continue
  7925. # yield the output frame in the byte format
  7926. yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
  7927. bytearray(encodedImage) + b'\r\n')
  7928. # return the response generated along with the specific media
  7929. # type (mime type)
  7930. return Response(generate(), mimetype="multipart/x-mixed-replace; boundary=frame")
  7931. else:
  7932. if s_sock != 0:
  7933. s_sock.close()
  7934. s_sock = 0
  7935. print('s_sock is closed')
  7936. return "s_sock is closed"
  7937. print("test")
  7938. return "s_sock is closed"
  7939. D = {"input_vacuum_status": "0",
  7940. "tank_vacuum_status": "0",
  7941. "tank_threewayvalve_input_status": "0",
  7942. "tank_threewayvalve_bean_status": "0",
  7943. "tank_solenoid_disinfect_status": "0",
  7944. "tank_pump_disinfect_status": "0",
  7945. "outer_threewayvalve_float_status": "0",
  7946. "tank_motor_status": 'none',
  7947. "tank_pump_water_in_status": "0",
  7948. "tank_pump_cleanwater_in_status": "0",
  7949. "outer_solenoid_water_status": "0",
  7950. "tank_solenoid_reclaimed_in_status": "0",
  7951. "tank_solenoid_water_in_status": "0",
  7952. "tank_solenoid_water_out_status": "0",
  7953. "tank_solenoid_reclaimed_out_status": "0",
  7954. "tank_pump_sensor_status": "0",
  7955. "solenoid_tank_pump_status": "0",
  7956. "tank_nozzle_status": "0",
  7957. "tank_blower_status": "0",
  7958. "tank_heater1_status": "0",
  7959. "tank_heater2_status": "0",
  7960. "temp1_enable": "0",
  7961. "temp1": "0",
  7962. "tank_diskvalve_status": "0",
  7963. "output_vacuum_status": "0",
  7964. "tank_temp_enable_status": "0",
  7965. "tank_temp_status": "0",
  7966. # "tank_pump_waterFloat_status": "0",
  7967. # "tank_pump_waterL2_status": "0",
  7968. # "tank_pump_waterL4_status": "0",
  7969. # "tank_solenoid_waterL3_status": "0",
  7970. # "tank_solenoid_waterL5_status": "0",
  7971. # "tank_stepping_motor_status": 'none',
  7972. }
  7973. # pub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  7974. # sub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e/Log'
  7975. # mqttObj = MQTT('aisky-client', 'aiskyc', '60.250.156.234', 1883, 60, sub_topic)
  7976. mqttObj = MQTT()
  7977. # mqtt發布
  7978. # @main.route('/mqtt/<tid>', methods=['POST'])
  7979. @main.route('/mqtt/<tid>', methods=['POST'])
  7980. def mqtt_views(tid):
  7981. import json
  7982. dict = request.form.to_dict() # 將表單轉換成字典
  7983. json = json.dumps(dict)
  7984. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  7985. # print('json:', json) # json: {"tank-number": "1", "command": "tank_vacuum_status", "value": "on"}
  7986. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  7987. # res = mqttObj.mqttPublish(pub_topic, json)
  7988. # print(res)
  7989. # sl(2)
  7990. # print(mqttObj.res)
  7991. #
  7992. # print('test')
  7993. mqtt.publish(topic, json)
  7994. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  7995. if dict['command'] == 'input_vacuum_status':
  7996. time.sleep(1)
  7997. # D[input_vacuum_status]: "0"
  7998. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  7999. if D['input_vacuum_status'] == 'on':
  8000. return 'on'
  8001. elif D['input_vacuum_status'] == 'off':
  8002. return 'off'
  8003. else:
  8004. return "input_vacuum_status signal was not received"
  8005. # 真空吸料機
  8006. elif dict['command'] == 'tank_vacuum_status':
  8007. time.sleep(1)
  8008. if D['tank_vacuum_status'] == 'on':
  8009. return 'on'
  8010. elif D['tank_vacuum_status'] == 'off':
  8011. return 'off'
  8012. else:
  8013. return "tank_vacuum_status signal was not received"
  8014. # 入料三通閥(ON吸料/OFF排氣)
  8015. elif dict['command'] == 'tank_threewayvalve_input_status':
  8016. time.sleep(1)
  8017. if D['tank_threewayvalve_input_status'] == 'on':
  8018. return 'on'
  8019. elif D['tank_threewayvalve_input_status'] == 'off':
  8020. return 'off'
  8021. else:
  8022. return "tank_threewayvalve_input_status signal was not received"
  8023. # 測豆三通閥(ON吸料/OFF排氣)
  8024. elif dict['command'] == 'tank_threewayvalve_bean_status':
  8025. time.sleep(1)
  8026. if D['tank_threewayvalve_bean_status'] == 'on':
  8027. return 'on'
  8028. elif D['tank_threewayvalve_bean_status'] == 'off':
  8029. return 'off'
  8030. else:
  8031. return "tank_threewayvalve_bean_status signal was not received"
  8032. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8033. elif dict['command'] == 'tank_solenoid_disinfect_status':
  8034. time.sleep(1)
  8035. if D['tank_solenoid_disinfect_status'] == 'on':
  8036. return 'on'
  8037. elif D['tank_solenoid_disinfect_status'] == 'off':
  8038. return 'off'
  8039. else:
  8040. return "tank_solenoid_disinfect_status signal was not received"
  8041. # 混合槽幫浦(ON抽水消毒/OFF關)
  8042. elif dict['command'] == 'tank_pump_disinfect_status':
  8043. time.sleep(1)
  8044. if D['tank_pump_disinfect_status'] == 'on':
  8045. return 'on'
  8046. elif D['tank_pump_disinfect_status'] == 'off':
  8047. return 'off'
  8048. else:
  8049. return "tank_pump_disinfect_status signal was not received"
  8050. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  8051. elif dict['command'] == 'outer_threewayvalve_float_status':
  8052. time.sleep(1)
  8053. if D['outer_threewayvalve_float_status'] == 'on':
  8054. return 'on'
  8055. elif D['outer_threewayvalve_float_status'] == 'off':
  8056. return 'off'
  8057. else:
  8058. return "outer_threewayvalve_float_status signal was not received"
  8059. # 馬達(單位RPM)
  8060. elif dict['command'] == 'tank_motor_status':
  8061. print("D['tank_motor_status']", D['tank_motor_status'])
  8062. time.sleep(1)
  8063. if D['tank_motor_status'] == '0':
  8064. return 'off'
  8065. elif type(D['tank_motor_status']) == int:
  8066. return 'on'
  8067. else:
  8068. return "tank_motor_status signal was not received"
  8069. # 幫浦(清水入水)(ON開/OFF關)
  8070. elif dict['command'] == 'tank_pump_water_in_status':
  8071. time.sleep(1)
  8072. if D['tank_pump_water_in_status'] == 'on':
  8073. return 'on'
  8074. elif D['tank_pump_water_in_status'] == 'off':
  8075. return 'off'
  8076. else:
  8077. return "tank_pump_water_in_status signal was not received"
  8078. # 幫浦(清洗槽入水)(ON開/OFF關)
  8079. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  8080. time.sleep(1)
  8081. if D['tank_pump_cleanwater_in_status'] == 'on':
  8082. return 'on'
  8083. elif D['tank_pump_cleanwater_in_status'] == 'off':
  8084. return 'off'
  8085. else:
  8086. return "tank_pump_cleanwater_in_status signal was not received"
  8087. # 桶外進水電磁閥(ON開/OFF關)
  8088. elif dict['command'] == 'outer_solenoid_water_status':
  8089. time.sleep(1)
  8090. if D['outer_solenoid_water_status'] == 'on':
  8091. return 'on'
  8092. elif D['outer_solenoid_water_status'] == 'off':
  8093. return 'off'
  8094. else:
  8095. return "outer_solenoid_water_status signal was not received"
  8096. # 中水入水電磁閥(ON開/OFF關)
  8097. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  8098. time.sleep(1)
  8099. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  8100. return 'on'
  8101. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  8102. return 'off'
  8103. else:
  8104. return "tank_solenoid_reclaimed_in_status signal was not received"
  8105. # 清水入水電磁閥(ON開/OFF關)
  8106. elif dict['command'] == 'tank_solenoid_water_in_status':
  8107. time.sleep(1)
  8108. if D['tank_solenoid_water_in_status'] == 'on':
  8109. return 'on'
  8110. elif D['tank_solenoid_water_in_status'] == 'off':
  8111. return 'off'
  8112. else:
  8113. return "tank_solenoid_water_in_status signal was not received"
  8114. # 排水廢水電磁閥(ON開/OFF關)
  8115. elif dict['command'] == 'tank_solenoid_water_out_status':
  8116. time.sleep(1)
  8117. if D['tank_solenoid_water_out_status'] == 'on':
  8118. return 'on'
  8119. elif D['tank_solenoid_water_out_status'] == 'off':
  8120. return 'off'
  8121. else:
  8122. return "tank_solenoid_water_out_status signal was not received"
  8123. # 排水中水電磁閥(ON開/OFF關)
  8124. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  8125. time.sleep(1)
  8126. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  8127. return 'on'
  8128. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  8129. return 'off'
  8130. else:
  8131. return "tank_solenoid_reclaimed_out_status signal was not received"
  8132. # 雙核隔膜泵(ON開/OFF關)
  8133. elif dict['command'] == 'tank_pump_sensor_status':
  8134. time.sleep(1)
  8135. if D['tank_pump_sensor_status'] == 'on':
  8136. return 'on'
  8137. elif D['tank_pump_sensor_status'] == 'off':
  8138. return 'off'
  8139. else:
  8140. return "tank_pump_sensor_status signal was not received"
  8141. # 逆洗 pump 電磁閥(ON開/OFF關)
  8142. elif dict['command'] == 'solenoid_tank_pump_status':
  8143. time.sleep(1)
  8144. if D['solenoid_tank_pump_status'] == 'on':
  8145. return 'on'
  8146. elif D['solenoid_tank_pump_status'] == 'off':
  8147. return 'off'
  8148. else:
  8149. return "solenoid_tank_pump_status signal was not received"
  8150. # 噴嘴(ON開/OFF關)
  8151. elif dict['command'] == 'tank_nozzle_status':
  8152. time.sleep(1)
  8153. if D['tank_nozzle_status'] == 'on':
  8154. return 'on'
  8155. elif D['tank_nozzle_status'] == 'off':
  8156. return 'off'
  8157. else:
  8158. return "tank_nozzle_status signal was not received"
  8159. # 鼓風機(ON開/OFF關)
  8160. elif dict['command'] == 'tank_blower_status':
  8161. time.sleep(1)
  8162. if D['tank_blower_status'] == 'on':
  8163. return 'on'
  8164. elif D['tank_blower_status'] == 'off':
  8165. return 'off'
  8166. else:
  8167. return "tank_blower_status signal was not received"
  8168. # 加熱棒 1(ON開/OFF關)
  8169. elif dict['command'] == 'tank_heater1_status':
  8170. time.sleep(1)
  8171. if D['tank_heater1_status'] == 'on':
  8172. return 'on'
  8173. elif D['tank_heater1_status'] == 'off':
  8174. return 'off'
  8175. else:
  8176. return "tank_heater1_status signal was not received"
  8177. # 加熱棒 2(ON開/OFF關)
  8178. elif dict['command'] == 'tank_heater2_status':
  8179. time.sleep(1)
  8180. if D['tank_heater2_status'] == 'on':
  8181. return 'on'
  8182. elif D['tank_heater2_status'] == 'off':
  8183. return 'off'
  8184. else:
  8185. return "tank_heater2_status signal was not received"
  8186. # 溫度控制(ON開/OFF關)
  8187. elif dict['command'] == 'temp1_enable':
  8188. time.sleep(1)
  8189. if D['temp1_enable'] == 'on':
  8190. return 'on'
  8191. elif D['temp1_enable'] == 'off':
  8192. return 'off'
  8193. else:
  8194. return "temp1_enable_status signal was not received"
  8195. # 設定溫度
  8196. elif dict['command'] == 'temp1':
  8197. time.sleep(1)
  8198. if D['temp1'] == '0':
  8199. return 'off'
  8200. elif type(D['temp1']) == float:
  8201. return 'on'
  8202. else:
  8203. return "temp1 signal was not received"
  8204. # 發酵槽 溫控開關
  8205. elif dict['command'] == 'tank_temp_enable':
  8206. time.sleep(1)
  8207. if D['tank_temp_enable'] == 'on':
  8208. return 'on'
  8209. elif D['tank_temp_enable'] == 'off':
  8210. return 'off'
  8211. else:
  8212. return "tank_temp_enable signal was not received"
  8213. # 發酵槽 設定溫度
  8214. elif dict['command'] == 'tank_temp':
  8215. time.sleep(1)
  8216. if D['tank_temp'] == '0':
  8217. return 'off'
  8218. elif type(D['tank_temp']) == float:
  8219. return 'on'
  8220. else:
  8221. return "tank_temp signal was not received"
  8222. # 蝴蝶閥(ON開/OFF關)
  8223. elif dict['command'] == 'tank_diskvalve_status':
  8224. time.sleep(1)
  8225. if D['tank_diskvalve_status'] == 'on':
  8226. return 'on'
  8227. elif D['tank_diskvalve_status'] == 'off':
  8228. return 'off'
  8229. else:
  8230. return "tank_diskvalve_status signal was not received"
  8231. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8232. elif dict['command'] == 'output_vacuum_status':
  8233. time.sleep(1)
  8234. if D['output_vacuum_status'] == 'on':
  8235. return 'on'
  8236. elif D['output_vacuum_status'] == 'off':
  8237. return 'off'
  8238. else:
  8239. return "output_vacuum_status signal was not received"
  8240. else:
  8241. return "MQTT command NOT FOUND"
  8242. # return "publish done" # 1201 test
  8243. # --- 12/10 ------------------------------------------ start
  8244. @main.route('/mqtt_data/<tid>', methods=['POST'])
  8245. def mqtt_data(tank_num, command, value):
  8246. import json
  8247. data = { "tank_num": str(tank_num), "command": str(command), "value": str(value) }
  8248. json = json.dumps(data)
  8249. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  8250. print('json:', json)
  8251. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8252. mqtt.publish(topic, json)
  8253. # --- 12/10 ------------------------------------------ finish
  8254. # --- 10/19 ------------------------------------------ start
  8255. # mqtt發布
  8256. # @main.route('/mqtt/<tid>', methods=['POST'])
  8257. @main.route('/mqtt_f/<tid>', methods=['POST'])
  8258. def mqtt_f(data):
  8259. import json
  8260. dict = request.form.to_dict()
  8261. json = json.dumps(data)
  8262. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  8263. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  8264. print('json:', json)
  8265. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8266. # res = mqttObj.mqttPublish(pub_topic, json)
  8267. # print(res)
  8268. # sl(2)
  8269. # print(mqttObj.res)
  8270. #
  8271. # print('test')
  8272. mqtt.publish(topic, json)
  8273. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8274. if dict['command'] == 'input_vacuum_status':
  8275. time.sleep(1)
  8276. # D[input_vacuum_status]: "0"
  8277. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  8278. if D['input_vacuum_status'] == 'on':
  8279. return 'on'
  8280. elif D['input_vacuum_status'] == 'off':
  8281. return 'off'
  8282. else:
  8283. return "input_vacuum_status signal was not received"
  8284. # 真空吸料機
  8285. elif dict['command'] == 'tank_vacuum_status':
  8286. time.sleep(1)
  8287. if D['tank_vacuum_status'] == 'on':
  8288. return 'on'
  8289. elif D['tank_vacuum_status'] == 'off':
  8290. return 'off'
  8291. else:
  8292. return "tank_vacuum_status signal was not received"
  8293. # 入料三通閥(ON吸料/OFF排氣)
  8294. elif dict['command'] == 'tank_threewayvalve_input_status':
  8295. time.sleep(1)
  8296. if D['tank_threewayvalve_input_status'] == 'on':
  8297. return 'on'
  8298. elif D['tank_threewayvalve_input_status'] == 'off':
  8299. return 'off'
  8300. else:
  8301. return "tank_threewayvalve_input_status signal was not received"
  8302. # 測豆三通閥(ON吸料/OFF排氣)
  8303. elif dict['command'] == 'tank_threewayvalve_bean_status':
  8304. time.sleep(1)
  8305. if D['tank_threewayvalve_bean_status'] == 'on':
  8306. return 'on'
  8307. elif D['tank_threewayvalve_bean_status'] == 'off':
  8308. return 'off'
  8309. else:
  8310. return "tank_threewayvalve_bean_status signal was not received"
  8311. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8312. elif dict['command'] == 'tank_solenoid_disinfect_status':
  8313. time.sleep(1)
  8314. if D['tank_solenoid_disinfect_status'] == 'on':
  8315. return 'on'
  8316. elif D['tank_solenoid_disinfect_status'] == 'off':
  8317. return 'off'
  8318. else:
  8319. return "tank_solenoid_disinfect_status signal was not received"
  8320. # 混合槽幫浦(ON抽水消毒/OFF關)
  8321. elif dict['command'] == 'tank_pump_disinfect_status':
  8322. time.sleep(1)
  8323. if D['tank_pump_disinfect_status'] == 'on':
  8324. return 'on'
  8325. elif D['tank_pump_disinfect_status'] == 'off':
  8326. return 'off'
  8327. else:
  8328. return "tank_pump_disinfect_status signal was not received"
  8329. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  8330. elif dict['command'] == 'outer_threewayvalve_float_status':
  8331. time.sleep(1)
  8332. if D['outer_threewayvalve_float_status'] == 'on':
  8333. return 'on'
  8334. elif D['outer_threewayvalve_float_status'] == 'off':
  8335. return 'off'
  8336. else:
  8337. return "outer_threewayvalve_float_status signal was not received"
  8338. # 馬達(單位RPM)
  8339. elif dict['command'] == 'tank_motor_status':
  8340. print("D['tank_motor_status']", D['tank_motor_status'])
  8341. time.sleep(1)
  8342. if D['tank_motor_status'] == '0':
  8343. return 'off'
  8344. elif type(D['tank_motor_status']) == int:
  8345. return 'on'
  8346. else:
  8347. return "tank_motor_status signal was not received"
  8348. # 幫浦(清水入水)(ON開/OFF關)
  8349. elif dict['command'] == 'tank_pump_water_in_status':
  8350. time.sleep(1)
  8351. if D['tank_pump_water_in_status'] == 'on':
  8352. return 'on'
  8353. elif D['tank_pump_water_in_status'] == 'off':
  8354. return 'off'
  8355. else:
  8356. return "tank_pump_water_in_status signal was not received"
  8357. # 幫浦(清洗槽入水)(ON開/OFF關)
  8358. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  8359. time.sleep(1)
  8360. if D['tank_pump_cleanwater_in_status'] == 'on':
  8361. return 'on'
  8362. elif D['tank_pump_cleanwater_in_status'] == 'off':
  8363. return 'off'
  8364. else:
  8365. return "tank_pump_cleanwater_in_status signal was not received"
  8366. # 桶外進水電磁閥(ON開/OFF關)
  8367. elif dict['command'] == 'outer_solenoid_water_status':
  8368. time.sleep(1)
  8369. if D['outer_solenoid_water_status'] == 'on':
  8370. return 'on'
  8371. elif D['outer_solenoid_water_status'] == 'off':
  8372. return 'off'
  8373. else:
  8374. return "outer_solenoid_water_status signal was not received"
  8375. # 中水入水電磁閥(ON開/OFF關)
  8376. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  8377. time.sleep(1)
  8378. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  8379. return 'on'
  8380. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  8381. return 'off'
  8382. else:
  8383. return "tank_solenoid_reclaimed_in_status signal was not received"
  8384. # 清水入水電磁閥(ON開/OFF關)
  8385. elif dict['command'] == 'tank_solenoid_water_in_status':
  8386. time.sleep(1)
  8387. if D['tank_solenoid_water_in_status'] == 'on':
  8388. return 'on'
  8389. elif D['tank_solenoid_water_in_status'] == 'off':
  8390. return 'off'
  8391. else:
  8392. return "tank_solenoid_water_in_status signal was not received"
  8393. # 排水廢水電磁閥(ON開/OFF關)
  8394. elif dict['command'] == 'tank_solenoid_water_out_status':
  8395. time.sleep(1)
  8396. if D['tank_solenoid_water_out_status'] == 'on':
  8397. return 'on'
  8398. elif D['tank_solenoid_water_out_status'] == 'off':
  8399. return 'off'
  8400. else:
  8401. return "tank_solenoid_water_out_status signal was not received"
  8402. # 排水中水電磁閥(ON開/OFF關)
  8403. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  8404. time.sleep(1)
  8405. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  8406. return 'on'
  8407. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  8408. return 'off'
  8409. else:
  8410. return "tank_solenoid_reclaimed_out_status signal was not received"
  8411. # 雙核隔膜泵(ON開/OFF關)
  8412. elif dict['command'] == 'tank_pump_sensor_status':
  8413. time.sleep(1)
  8414. if D['tank_pump_sensor_status'] == 'on':
  8415. return 'on'
  8416. elif D['tank_pump_sensor_status'] == 'off':
  8417. return 'off'
  8418. else:
  8419. return "tank_pump_sensor_status signal was not received"
  8420. # 逆洗 pump 電磁閥(ON開/OFF關)
  8421. elif dict['command'] == 'solenoid_tank_pump_status':
  8422. time.sleep(1)
  8423. if D['solenoid_tank_pump_status'] == 'on':
  8424. return 'on'
  8425. elif D['solenoid_tank_pump_status'] == 'off':
  8426. return 'off'
  8427. else:
  8428. return "solenoid_tank_pump_status signal was not received"
  8429. # 噴嘴(ON開/OFF關)
  8430. elif dict['command'] == 'tank_nozzle_status':
  8431. time.sleep(1)
  8432. if D['tank_nozzle_status'] == 'on':
  8433. return 'on'
  8434. elif D['tank_nozzle_status'] == 'off':
  8435. return 'off'
  8436. else:
  8437. return "tank_nozzle_status signal was not received"
  8438. # 鼓風機(ON開/OFF關)
  8439. elif dict['command'] == 'tank_blower_status':
  8440. time.sleep(1)
  8441. if D['tank_blower_status'] == 'on':
  8442. return 'on'
  8443. elif D['tank_blower_status'] == 'off':
  8444. return 'off'
  8445. else:
  8446. return "tank_blower_status signal was not received"
  8447. # 加熱棒 1(ON開/OFF關)
  8448. elif dict['command'] == 'tank_heater1_status':
  8449. time.sleep(1)
  8450. if D['tank_heater1_status'] == 'on':
  8451. return 'on'
  8452. elif D['tank_heater1_status'] == 'off':
  8453. return 'off'
  8454. else:
  8455. return "tank_heater1_status signal was not received"
  8456. # 加熱棒 2(ON開/OFF關)
  8457. elif dict['command'] == 'tank_heater2_status':
  8458. time.sleep(1)
  8459. if D['tank_heater2_status'] == 'on':
  8460. return 'on'
  8461. elif D['tank_heater2_status'] == 'off':
  8462. return 'off'
  8463. else:
  8464. return "tank_heater2_status signal was not received"
  8465. # 溫度控制(ON開/OFF關)
  8466. elif dict['command'] == 'temp1_enable':
  8467. time.sleep(1)
  8468. if D['temp1_enable'] == 'on':
  8469. return 'on'
  8470. elif D['temp1_enable'] == 'off':
  8471. return 'off'
  8472. else:
  8473. return "temp1_enable_status signal was not received"
  8474. # 設定溫度
  8475. elif dict['command'] == 'temp1':
  8476. time.sleep(1)
  8477. if D['temp1'] == '0':
  8478. return 'off'
  8479. elif type(D['temp1']) == float:
  8480. return 'on'
  8481. else:
  8482. return "temp1 signal was not received"
  8483. # 發酵槽 溫控開關
  8484. elif dict['command'] == 'tank_temp_enable':
  8485. time.sleep(1)
  8486. if D['tank_temp_enable'] == 'on':
  8487. return 'on'
  8488. elif D['tank_temp_enable'] == 'off':
  8489. return 'off'
  8490. else:
  8491. return "tank_temp_enable signal was not received"
  8492. # 發酵槽 設定溫度
  8493. elif dict['command'] == 'tank_temp':
  8494. time.sleep(1)
  8495. if D['tank_temp'] == '0':
  8496. return 'off'
  8497. elif type(D['tank_temp']) == float:
  8498. return 'on'
  8499. else:
  8500. return "tank_temp signal was not received"
  8501. # 蝴蝶閥(ON開/OFF關)
  8502. elif dict['command'] == 'tank_diskvalve_status':
  8503. time.sleep(1)
  8504. if D['tank_diskvalve_status'] == 'on':
  8505. return 'on'
  8506. elif D['tank_diskvalve_status'] == 'off':
  8507. return 'off'
  8508. else:
  8509. return "tank_diskvalve_status signal was not received"
  8510. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8511. elif dict['command'] == 'output_vacuum_status':
  8512. time.sleep(1)
  8513. if D['output_vacuum_status'] == 'on':
  8514. return 'on'
  8515. elif D['output_vacuum_status'] == 'off':
  8516. return 'off'
  8517. else:
  8518. return "output_vacuum_status signal was not received"
  8519. else:
  8520. return "MQTT command NOT FOUND"
  8521. # ---10/19 ------------------------------------------- end
  8522. # 處理mqtt訂閱的信息
  8523. # 收到訊息後我們可以用 on_message(),來讀取收到的內容:
  8524. @mqtt.on_message()
  8525. def handle_mqtt_message(client, userdata, message):
  8526. # topic = message.topic # 收到的主題 Rita 原本就沒有此行, 增加說明用
  8527. payload = message.payload.decode() # 收到的內容
  8528. payload = json.loads(payload)
  8529. # print("-------msg-------")
  8530. # print('name :', p['name'])
  8531. # print('email :', p['email'])
  8532. print('payload:', payload)
  8533. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8534. if payload['command'] == 'input_vacuum_status':
  8535. if payload['response'] == 'on':
  8536. D['input_vacuum_status'] = 'on'
  8537. else:
  8538. D['input_vacuum_status'] = 'off'
  8539. # 真空吸料機(ON吸料/OFF排氣)
  8540. elif payload['command'] == 'tank_vacuum_status':
  8541. if payload['response'] == 'on':
  8542. D['tank_vacuum_status'] = 'on'
  8543. else:
  8544. D['tank_vacuum_status'] = 'off'
  8545. # 入料三通閥(ON吸料/OFF排氣)
  8546. elif payload['command'] == 'tank_threewayvalve_input_status':
  8547. if payload['response'] == 'on':
  8548. D['tank_threewayvalve_input_status'] = 'on'
  8549. else:
  8550. D['tank_threewayvalve_input_status'] = 'off'
  8551. # 測豆三通閥(ON測豆/OFF排氣)
  8552. elif payload['command'] == 'tank_threewayvalve_bean_status':
  8553. if payload['response'] == 'on':
  8554. D['tank_threewayvalve_bean_status'] = 'on'
  8555. else:
  8556. D['tank_threewayvalve_bean_status'] = 'off'
  8557. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8558. elif payload['command'] == 'tank_solenoid_disinfect_status':
  8559. if payload['response'] == 'on':
  8560. D['tank_solenoid_disinfect_status'] = 'on'
  8561. else:
  8562. D['tank_solenoid_disinfect_status'] = 'off'
  8563. # 混合槽幫浦(ON消毒槽抽水/OFF關)
  8564. elif payload['command'] == 'tank_pump_disinfect_status':
  8565. if payload['response'] == 'on':
  8566. D['tank_pump_disinfect_status'] = 'on'
  8567. else:
  8568. D['tank_pump_disinfect_status'] = 'off'
  8569. # 外桶浮選三通閥(ON浮選落豆/OFF桶內真空)
  8570. elif payload['command'] == 'outer_threewayvalve_float_status':
  8571. if payload['response'] == 'on':
  8572. D['outer_threewayvalve_float_status'] = 'on'
  8573. else:
  8574. D['outer_threewayvalve_float_status'] = 'off'
  8575. # 馬達(單位RPM)
  8576. elif payload['command'] == 'tank_motor_status':
  8577. if payload['response'] == 'off' or payload['response'] == '0':
  8578. D['tank_motor_status'] = '0'
  8579. else:
  8580. D['tank_motor_status'] = payload['response']
  8581. # 幫浦(清水入水)(ON開/OFF關)
  8582. elif payload['command'] == 'tank_pump_water_in_status':
  8583. if payload['response'] == 'on':
  8584. D['tank_pump_water_in_status'] = 'on'
  8585. else:
  8586. D['tank_pump_water_in_status'] = 'off'
  8587. # 幫浦(清洗槽入水)(ON開/OFF關)
  8588. elif payload['command'] == 'tank_pump_cleanwater_in_status':
  8589. if payload['response'] == 'on':
  8590. D['tank_pump_cleanwater_in_status'] = 'on'
  8591. else:
  8592. D['tank_pump_cleanwater_in_status'] = 'off'
  8593. # 桶外進水電磁閥(ON開/OFF關)
  8594. elif payload['command'] == 'outer_solenoid_water_status':
  8595. if payload['response'] == 'on':
  8596. D['outer_solenoid_water_status'] = 'on'
  8597. else:
  8598. D['outer_solenoid_water_status'] = 'off'
  8599. # 中水入水電磁閥(ON開/OFF關)
  8600. elif payload['command'] == 'tank_solenoid_reclaimed_in_status':
  8601. if payload['response'] == 'on':
  8602. D['tank_solenoid_reclaimed_in_status'] = 'on'
  8603. else:
  8604. D['tank_solenoid_reclaimed_in_status'] = 'off'
  8605. # 清水入水電磁閥(ON開/OFF關)
  8606. elif payload['command'] == 'tank_solenoid_water_in_status':
  8607. if payload['response'] == 'on':
  8608. D['tank_solenoid_water_in_status'] = 'on'
  8609. else:
  8610. D['tank_solenoid_water_in_status'] = 'off'
  8611. # 排水廢水電磁閥(ON開/OFF關)
  8612. elif payload['command'] == 'tank_solenoid_water_out_status':
  8613. if payload['response'] == 'on':
  8614. D['tank_solenoid_water_out_status'] = 'on'
  8615. else:
  8616. D['tank_solenoid_water_out_status'] = 'off'
  8617. # 排水中水電磁閥(ON開/OFF關)
  8618. elif payload['command'] == 'tank_solenoid_reclaimed_out_status':
  8619. if payload['response'] == 'on':
  8620. D['tank_solenoid_reclaimed_out_status'] = 'on'
  8621. else:
  8622. D['tank_solenoid_reclaimed_out_status'] = 'off'
  8623. # 雙核隔膜泵(ON開/OFF關)
  8624. elif payload['command'] == 'tank_pump_sensor_status':
  8625. if payload['response'] == 'on':
  8626. D['tank_pump_sensor_status'] = 'on'
  8627. else:
  8628. D['tank_pump_sensor_status'] = 'off'
  8629. # 逆洗 pump 電磁閥(ON開/OFF關)
  8630. elif payload['command'] == 'solenoid_tank_pump_status':
  8631. if payload['response'] == 'on':
  8632. D['solenoid_tank_pump_status'] = 'on'
  8633. else:
  8634. D['solenoid_tank_pump_status'] = 'off'
  8635. # 噴嘴(ON開/OFF關)
  8636. elif payload['command'] == 'tank_nozzle_status':
  8637. if payload['response'] == 'on':
  8638. D['tank_nozzle_status'] = 'on'
  8639. else:
  8640. D['tank_nozzle_status'] = 'off'
  8641. # 鼓風機(ON開/OFF關)
  8642. elif payload['command'] == 'tank_blower_status':
  8643. if payload['response'] == 'on':
  8644. D['tank_blower_status'] = 'on'
  8645. else:
  8646. D['tank_blower_status'] = 'off'
  8647. # 加熱棒 1(ON開/OFF關)
  8648. elif payload['command'] == 'tank_heater1_status':
  8649. if payload['response'] == 'on':
  8650. D['tank_heater1_status'] = 'on'
  8651. else:
  8652. D['tank_heater1_status'] = 'off'
  8653. # 加熱棒 2(ON開/OFF關)
  8654. elif payload['command'] == 'tank_heater2_status':
  8655. if payload['response'] == 'on':
  8656. D['tank_heater2_status'] = 'on'
  8657. else:
  8658. D['tank_heater2_status'] = 'off'
  8659. # 發酵槽 溫控開關
  8660. elif payload['command'] == 'tank_temp_enable':
  8661. if payload['response'] == 'on':
  8662. D['tank_temp_enable'] = 'on'
  8663. else:
  8664. D['tank_temp_enable'] = 'off'
  8665. # 發酵槽 設定溫度
  8666. elif payload['command'] == 'tank_temp':
  8667. if payload['response'] == 'off':
  8668. D['tank_temp'] = '0'
  8669. else:
  8670. D['tank_temp'] = payload['response']
  8671. # 蝴蝶閥(ON開/OFF關)
  8672. elif payload['command'] == 'tank_diskvalve_status':
  8673. if payload['response'] == 'on':
  8674. D['tank_diskvalve_status'] = 'on'
  8675. else:
  8676. D['tank_diskvalve_status'] = 'off'
  8677. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8678. elif payload['command'] == 'output_vacuum_status':
  8679. if payload['response'] == 'on':
  8680. D['output_vacuum_status'] = 'on'
  8681. else:
  8682. D['output_vacuum_status'] = 'off'
  8683. else:
  8684. return "MQTT command NOT FOUND"