views.py 477 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790
  1. # 主業務邏輯中的視圖和路由的定義
  2. import os
  3. import datetime
  4. from turtle import title
  5. from flask import Flask, redirect, render_template, request, session, Response, jsonify
  6. from sqlalchemy.sql.expression import desc, false, null
  7. # 導入藍圖程序,用於構建路由
  8. from werkzeug.utils import redirect
  9. from werkzeug.wrappers import response
  10. from . import main
  11. from coffee_manage import mqtt
  12. # 導入db,用於操作數據庫
  13. from coffee_manage import db
  14. # 導入實體類,用於操作數據庫
  15. from ..models import *
  16. import json
  17. from datetime import datetime as dt
  18. from datetime import timedelta
  19. from sqlalchemy import text
  20. import pymysql
  21. import pandas as pd
  22. from concurrent.futures import ThreadPoolExecutor
  23. import cv2
  24. import pickle
  25. import socket
  26. import time
  27. import threading
  28. import numpy as np
  29. import math
  30. from .mqtt import MQTT
  31. from matplotlib import pyplot as plt
  32. # import random
  33. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg as FigureCanvas
  34. # import io
  35. # from flask import make_response
  36. # from distutils.util import strtobool # 將字串 string 轉成布林 boolean
  37. # import psutil
  38. pool = ThreadPoolExecutor(25)
  39. s_sock = 0
  40. lock = threading.Lock()
  41. '''
  42. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  43. password='skyeye', database='Coffee', charset='utf8')
  44. mycursor = mydb.cursor()
  45. '''
  46. # 主頁的訪問路徑
  47. @main.route('/')
  48. def main_index():
  49. # 獲取登入信息
  50. if 'id' in session and 'uname' in session and 'status' in session:
  51. username = session['uname']
  52. status = session['status']
  53. if status == 9:
  54. return render_template('signin_disable.html', params=locals())
  55. elif status == 8:
  56. return render_template('signin_new.html', params=locals())
  57. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  58. return render_template('index.html', params=locals())
  59. else:
  60. return render_template('sign_in.html')
  61. # Rita 測試
  62. # sql_get
  63. @main.route('/sql_get', methods=['GET', 'POST'])
  64. def sql_get():
  65. # mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee', password='skyeye', database='Coffee', charset='utf8')
  66. mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='Coffee', charset='utf8')
  67. mycursor = mydb.cursor()
  68. # 取得網頁傳回來的 SQL 指令
  69. # sql = "SELECT * FROM 零件表 WHERE 會計科目 = 04"
  70. info = request.args.to_dict('sql')
  71. sql = info['sql']
  72. print("[sql_get]sql: ", sql)
  73. try:
  74. mycursor.execute(sql)
  75. sql_data = mycursor.fetchall()
  76. except pymysql.err.IntegrityError:
  77. sql_data = "請注意 ! 單據不可新增重複的零件"
  78. mydb.commit()
  79. mydb.close()
  80. return jsonify({"response":"OK"})
  81. # Rita 測試
  82. # 使用者名稱測試
  83. @main.route('/test', methods=['GET', 'POST'])
  84. def test():
  85. info = request.args.to_dict()
  86. print(info)
  87. print("info[command]: ", info['command'])
  88. return json.dumps(info)
  89. # Rita 測試
  90. # 板子介面測試
  91. @main.route('/board_loader')
  92. def board_loader():
  93. if 'id' in session and 'uname' in session:
  94. print("session['uname']: ", session['uname'])
  95. username = session['uname']
  96. print("session['status']: ", session['status'])
  97. status = session['status']
  98. else:
  99. print("NO session['uname']")
  100. return render_template('board_loader-1.html', title="板子燒錄介面")
  101. #
  102. @main.route('/loader', methods=['GET', 'POST'])
  103. def loader():
  104. info = request.args.to_dict()
  105. # print("info: ", info)
  106. ethernet_list = info['ethernet_list']
  107. print("ethernet_list: ", ethernet_list, type(ethernet_list))
  108. wifi_list = info['wifi_list']
  109. print("wifi_list: ", wifi_list, type(wifi_list))
  110. zigbee_list = info['zigbee_list']
  111. print("zigbee_list: ", zigbee_list, type(zigbee_list))
  112. # 將 string 以 , 分割成 list
  113. relay_list = info['relay_list'].split(',')
  114. print("relay_list: ", relay_list, type(relay_list))
  115. pwm_list = info['pwm_list'].split(',')
  116. print("pwm_list: ", pwm_list, type(pwm_list))
  117. digital_list = info['digital_list'].split(',')
  118. print("digital_list: ", digital_list, type(digital_list))
  119. uart_list = info['uart_list'].split(',')
  120. print("uart_list: ", uart_list, type(uart_list))
  121. i2c_list = info['i2c_list'].split(',')
  122. print("i2c_list: ", i2c_list, type(i2c_list))
  123. s485_list = info['s485_list'].split(',')
  124. print("s485_list: ", s485_list, type(s485_list))
  125. ppa_list = info['ppa_list'].split(',')
  126. print("ppa_list: ", ppa_list, type(ppa_list))
  127. return jsonify({"response":"OK" })
  128. # # Rita 測試
  129. @main.route('/drop_down_list')
  130. def drop_down_list():
  131. # 獲取登入信息
  132. if 'id' in session and 'uname' in session and 'status' in session:
  133. username = session['uname']
  134. status = session['status']
  135. if status == 9:
  136. return render_template('signin_disable.html', params=locals())
  137. elif status == 8:
  138. return render_template('signin_new.html', params=locals())
  139. # TODO
  140. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  141. password='skyeye', database='Coffee', charset='utf8')
  142. mycursor = mydb.cursor()
  143. conn = pymysql.connect(
  144. host='52.69.200.169',
  145. port=3306,
  146. user='coffee',
  147. password='skyeye',
  148. database='Coffee',
  149. charset='utf8'
  150. )
  151. cur = conn.cursor()
  152. #獲取欄位資料
  153. sql = "select * from product_info"
  154. cur.execute(sql)
  155. content = cur.fetchall()
  156. #獲取欄位名稱
  157. sql = "SHOW FIELDS FROM product_info"
  158. cur.execute(sql)
  159. labels = cur.fetchall()
  160. # print("labels: ", labels) # labels: (('產品', 'varchar(4)', 'YES', '', None, ''), ('系統', 'varchar(5)', 'YES', '', None, ''),
  161. labels = [g[0] for g in labels]
  162. # print("labels: ", labels) # labels: ['產品', '系統', '系統圖號', '狀態', '進貨狀態', '序號', '組序號',
  163. return render_template('drop_down_list.html', labels=labels, content=content)
  164. else:
  165. return render_template('sign_in.html')
  166. # !!! AttributeError: 'NoneType' object has no attribute 'vacuum'
  167. @main.route('/loading/container', methods=['GET', 'POST'])
  168. def container_loading():
  169. if request.method == 'GET':
  170. # 清洗浮選狀態
  171. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  172. Clean_container_status_list = [clean_status.Clean_Tank_1,
  173. clean_status.Clean_Tank_2,
  174. clean_status.Clean_Tank_3,
  175. clean_status.Clean_Tank_4]
  176. CLEAN_Waiting_number = int(Clean_container_status_list.count('C_Waiting'))
  177. CLEAN_Warning_number = int(Clean_container_status_list.count('C_Warning'))
  178. if CLEAN_Waiting_number == len(Clean_container_status_list): Clean_container = 'Waiting'
  179. elif CLEAN_Warning_number >= 1: Clean_container = 'Warning'
  180. else: Clean_container = 'Working'
  181. # 清洗浮選狀態
  182. ColorSelect_container_status_list = [clean_status.ColorSelect_Tank_1,
  183. clean_status.ColorSelect_Tank_2]
  184. COLORSELECT_Waiting_number = int(ColorSelect_container_status_list.count('S_Waiting'))
  185. COLORSELECT_Warning_number = int(ColorSelect_container_status_list.count('S_Warning'))
  186. if COLORSELECT_Waiting_number == len(ColorSelect_container_status_list): ColorSelect_container = 'Waiting'
  187. elif COLORSELECT_Warning_number >= 1: ColorSelect_container = 'Warning'
  188. else: ColorSelect_container = 'Working'
  189. # 脫皮機
  190. Peel_container_status_list = [clean_status.Peel_Tank_1,
  191. clean_status.Peel_Tank_2]
  192. PEEL_Waiting_number = int(Peel_container_status_list.count('P_Waiting'))
  193. PEEL_Warning_number = int(Peel_container_status_list.count('P_Warning'))
  194. if PEEL_Waiting_number == len(Peel_container_status_list): Peel_container = 'Waiting'
  195. elif PEEL_Warning_number >= 1: Peel_container = 'Warning'
  196. else: Peel_container = 'Working'
  197. # 發酵槽
  198. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  199. Ferment_container_status_list = [ferment_status.Ferment_Tank_1,
  200. ferment_status.Ferment_Tank_2,
  201. ferment_status.Ferment_Tank_3,
  202. ferment_status.Ferment_Tank_4,
  203. ferment_status.Ferment_Tank_5,
  204. ferment_status.Ferment_Tank_6,
  205. ferment_status.Ferment_Tank_7,
  206. ferment_status.Ferment_Tank_8,
  207. ferment_status.Ferment_Tank_9,
  208. ferment_status.Ferment_Tank_10,
  209. ferment_status.Ferment_Tank_11,
  210. ferment_status.Ferment_Tank_12]
  211. FERMENT_Waiting_number = int(Ferment_container_status_list.count('F_Waiting'))
  212. FERMENT_Warning_number = int(Ferment_container_status_list.count('F_Warning'))
  213. if FERMENT_Waiting_number == len(Ferment_container_status_list): Ferment_container = 'Waiting'
  214. elif FERMENT_Warning_number >= 1: Ferment_container = 'Warning'
  215. else: Ferment_container = 'Working'
  216. # 乾燥槽
  217. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  218. Dry_container_status_list = [dry_status.Dry_Tank_1,
  219. dry_status.Dry_Tank_2,
  220. dry_status.Dry_Tank_3,
  221. dry_status.Dry_Tank_4,
  222. dry_status.Dry_Tank_5,
  223. dry_status.Dry_Tank_6,
  224. dry_status.Dry_Tank_7,
  225. dry_status.Dry_Tank_8,
  226. dry_status.Dry_Tank_9,
  227. dry_status.Dry_Tank_10,
  228. dry_status.Dry_Tank_11,
  229. dry_status.Dry_Tank_12]
  230. DRY_Waiting_number= int(Dry_container_status_list.count('D_Waiting'))
  231. DRY_Warning_number= int(Dry_container_status_list.count('D_Warning'))
  232. if DRY_Waiting_number == len(Dry_container_status_list): Dry_container = 'Waiting'
  233. elif DRY_Warning_number >= 1: Dry_container = 'Warning'
  234. else: Dry_container = 'Working'
  235. return jsonify({"Clean_container":Clean_container,
  236. "ColorSelect_container":ColorSelect_container,
  237. "Peel_container":Peel_container,
  238. "Ferment_container":Ferment_container,
  239. "Dry_container":Dry_container
  240. })
  241. @main.route('/loading_sensors', methods=['GET', 'POST'])
  242. def loading_sensors():
  243. C1_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C1').order_by(text('datetime desc')).first()).UltraSonic
  244. C2_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C2').order_by(text('datetime desc')).first()).UltraSonic
  245. PO1_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO1').order_by(text('datetime desc')).first()).UltraSonic
  246. PO2_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO2').order_by(text('datetime desc')).first()).UltraSonic
  247. F1_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).UltraSonic
  248. F1_SHT11Temp = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Temp
  249. F1_SHT11Humidity = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Humidity
  250. F2_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F2').order_by(text('datetime desc')).first()).UltraSonic
  251. D1_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).UltraSonic
  252. D1_SHT11Temp = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Temp
  253. D1_SHT11Humidity = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Humidity
  254. D2_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D2').order_by(text('datetime desc')).first()).UltraSonic
  255. DO1_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()).UltraSonic
  256. DO2_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()).UltraSonic
  257. return jsonify({"C1_UltraSonic":C1_UltraSonic,
  258. "C2_UltraSonic":C2_UltraSonic,
  259. "PO1_UltraSonic":PO1_UltraSonic,
  260. "PO2_UltraSonic":PO2_UltraSonic,
  261. "F1_UltraSonic":F1_UltraSonic,
  262. "F1_SHT11Temp":F1_SHT11Temp,
  263. "F1_SHT11Humidity":F1_SHT11Humidity,
  264. "F2_UltraSonic":F2_UltraSonic,
  265. "D1_UltraSonic":D1_UltraSonic,
  266. "D1_SHT11Temp":D1_SHT11Temp,
  267. "D1_SHT11Humidity":D1_SHT11Humidity,
  268. "D2_UltraSonic":D2_UltraSonic,
  269. "DO1_UltraSonic":DO1_UltraSonic,
  270. "DO2_UltraSonic":DO2_UltraSonic
  271. })
  272. @main.route('/demo', methods=['GET', 'POST'])
  273. def demo():
  274. if 'id' in session and 'uname' in session and 'status' in session:
  275. username = session['uname']
  276. status = session['status']
  277. if status == 9:
  278. return render_template('signin_disable.html', params=locals())
  279. elif status == 8:
  280. return render_template('signin_new.html', params=locals())
  281. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  282. CI1 = clean_status.Clean_Input_1
  283. CI2 = clean_status.Clean_Input_2
  284. C1 = clean_status.Clean_Tank_1
  285. C2 = clean_status.Clean_Tank_2
  286. R1 = clean_status.Reclaimed_Tank_1
  287. S1 = clean_status.ColorSelect_Tank_1
  288. S2 = clean_status.ColorSelect_Tank_2
  289. SOg1 = clean_status.ColorSelect_Output_g1
  290. SOb1 = clean_status.ColorSelect_Output_b1
  291. SOg2 = clean_status.ColorSelect_Output_g2
  292. SOb2 = clean_status.ColorSelect_Output_b2
  293. P1 = clean_status.Peel_Tank_1
  294. P2 = clean_status.Peel_Tank_2
  295. PO1 = clean_status.Peel_Output_1
  296. PO2 = clean_status.Peel_Output_2
  297. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  298. F1 = ferment_status.Ferment_Tank_1
  299. F2 = ferment_status.Ferment_Tank_2
  300. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  301. D1 = dry_status.Dry_Tank_1
  302. D2 = dry_status.Dry_Tank_2
  303. DO1 = dry_status.Dry_Output_1
  304. DO2 = dry_status.Dry_Output_2
  305. POb1 = clean_status.Peel_Output_b1
  306. return render_template('demo.html', title="[測試] DEMO 貨櫃自動化", **locals())
  307. else:
  308. return render_template('sign_in.html')
  309. @main.route('/demo_auto', methods=['GET', 'POST'])
  310. def demo_auto():
  311. if 'id' in session and 'uname' in session and 'status' in session:
  312. username = session['uname']
  313. status = session['status']
  314. if status == 9:
  315. return render_template('signin_disable.html', params=locals())
  316. elif status == 8:
  317. return render_template('signin_new.html', params=locals())
  318. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  319. CI1 = clean_status.Clean_Input_1
  320. CI2 = clean_status.Clean_Input_2
  321. C1 = clean_status.Clean_Tank_1
  322. C2 = clean_status.Clean_Tank_2
  323. # 中水桶
  324. S1 = clean_status.ColorSelect_Tank_1
  325. S2 = clean_status.ColorSelect_Tank_2
  326. SOg1 = clean_status.ColorSelect_Output_g1
  327. SOb1 = clean_status.ColorSelect_Output_b1
  328. SOg2 = clean_status.ColorSelect_Output_g2
  329. SOb2 = clean_status.ColorSelect_Output_b2
  330. P1 = clean_status.Peel_Tank_1
  331. P2 = clean_status.Peel_Tank_2
  332. PO1 = clean_status.Peel_Output_1
  333. PO2 = clean_status.Peel_Output_2
  334. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  335. F1 = ferment_status.Ferment_Tank_1
  336. F2 = ferment_status.Ferment_Tank_2
  337. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  338. D1 = dry_status.Dry_Tank_1
  339. D2 = dry_status.Dry_Tank_2
  340. DO1 = dry_status.Dry_Output_1
  341. DO2 = dry_status.Dry_Output_2
  342. POb1 = clean_status.Peel_Output_b1
  343. return render_template('demo_auto.html', title="[測試] DEMO 貨櫃自動化", **locals())
  344. else:
  345. return render_template('sign_in.html')
  346. # 脫皮機自動化測試頁
  347. @main.route('/peel_auto_status', methods=['GET', 'POST'])
  348. def peel_auto_test():
  349. info = request.args.to_dict()
  350. # 寫定出料的空桶標準, 若 <= 2 則為空桶
  351. Peel_Output_bean_empty = 2
  352. # 從介面取得 指定生豆高度
  353. Peel_Tank_bean_height = float(info['Peel_Tank_bean_height'])
  354. Peel_Tank_motor_rpm = float(info['Peel_Tank_motor_rpm'])
  355. Peel_Tank_vacuumON_time = float(info['Peel_Tank_vacuumON_time'])
  356. Peel_Tank_vacuumOFF_time = float(info['Peel_Tank_vacuumOFF_time'])
  357. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  358. P1 = clean_status.Peel_Tank_1
  359. P2 = clean_status.Peel_Tank_2
  360. PO1 = clean_status.Peel_Output_1
  361. PO2 = clean_status.Peel_Output_2
  362. SO1 = 'SO_OutputtingBean' # SO_OutputtingBean SO_Waiting
  363. SO2 = 'SO_Waiting'
  364. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  365. PO_UP_tank_UltraSonic = []
  366. for i in range(1, 3, 1):
  367. output_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='PO' + str(i)).order_by(text('datetime desc')).first()
  368. UltraSonic = float(output_UltraSonic.UltraSonic)
  369. PO_UP_tank_UltraSonic.append(UltraSonic)
  370. print('PO_UP_tank_UltraSonic: ', PO_UP_tank_UltraSonic)
  371. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  372. if P1 == 'P_Waiting' and PO1 != 'PO_OutputtingBean' and SO1 == 'SO_OutputtingBean':
  373. P1 = 'P_Peeling'
  374. PO1 = 'PO_InputtingBean'
  375. print('------- P1 狀態更新:脫皮中 -------')
  376. print('------- PO1 狀態更新:入豆中 -------')
  377. # [致動器] 馬達 指定轉速
  378. data = { "tank_num": "P1", "command": "tank_motor_status", "value": Peel_Tank_motor_rpm}
  379. print('data: ', data)
  380. # mqtt_f(data)
  381. if P1 == 'P_Peeling':
  382. if PO_UP_tank_UltraSonic[0] >= Peel_Tank_bean_height:
  383. # [致動器] 真空吸料機 OFF
  384. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  385. print('data: ', data)
  386. # mqtt_f(data)
  387. # [致動器] 馬達 0
  388. data = { "tank_num": "P1", "command": "tank_motor_status", "value": "0" }
  389. print('data: ', data)
  390. # mqtt_f(data)
  391. P1 = 'P_Waiting'
  392. PO1 = 'PO_OutputtingBean'
  393. print('------- P1 狀態更新:等待中 -------')
  394. print('------- PO1 狀態更新:可出豆 -------')
  395. elif PO_UP_tank_UltraSonic[0] < Peel_Tank_bean_height:
  396. # [致動器] 真空吸料機 ON
  397. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "on" }
  398. print('data: ', data)
  399. # mqtt_f(data)
  400. timer = time.time()
  401. while True:
  402. if (time.time() - timer) > Peel_Tank_vacuumON_time:
  403. # [致動器] 真空吸料機 OFF
  404. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  405. print('data: ', data)
  406. # mqtt_f(data)
  407. timer = time.time()
  408. break
  409. while True:
  410. if (time.time() - timer) > Peel_Tank_vacuumOFF_time:
  411. break
  412. if PO1 == 'PO_OutputtingBean' and PO_UP_tank_UltraSonic[0] <= Peel_Output_bean_empty:
  413. PO1 = 'PO_Waiting'
  414. print('------- PO1 狀態更新:空桶等待 -------')
  415. CI1 = 'CI_Warning'
  416. CI2 = 'CI_Waiting'
  417. C1 = 'C_Warning'
  418. C2 = 'C_Waiting'
  419. C3 = 'C_Waiting'
  420. C4 = 'C_Waiting'
  421. SI1 = 'SI_Warning'
  422. SI2 = 'SI_Waiting'
  423. S1 = 'S_Warning'
  424. S2 = 'S_Waiting'
  425. SOg1 = 'SO_Warning'
  426. SOb1 = 'SO_Warning'
  427. SOg2 = 'SO_Waiting'
  428. SOb2 = 'SO_Waiting'
  429. POb1 = 'PO_Waiting'
  430. # ----- 將狀態寫入資料庫 ------------------------------
  431. # 獲取文本框的值並賦值給user實體對象
  432. C_status = clean_container_status()
  433. C_status.Clean_Input_1 = CI1
  434. C_status.Clean_Input_2 = CI2
  435. C_status.Clean_Tank_1 = C1
  436. C_status.Clean_Tank_2 = C2
  437. C_status.Clean_Tank_3 = C3
  438. C_status.Clean_Tank_4 = C4
  439. C_status.ColorSelect_Input_1 = SI1
  440. C_status.ColorSelect_Input_2 = SI2
  441. C_status.ColorSelect_Tank_1 = S1
  442. C_status.ColorSelect_Tank_2 = S2
  443. C_status.ColorSelect_Output_g1 = SOg1
  444. C_status.ColorSelect_Output_b1 = SOb1
  445. C_status.ColorSelect_Output_g2 = SOg2
  446. C_status.ColorSelect_Output_b2 = SOb2
  447. C_status.Peel_Tank_1 = P1
  448. C_status.Peel_Tank_2 = P2
  449. C_status.Peel_Output_1 = PO1
  450. C_status.Peel_Output_2 = PO2
  451. C_status.Peel_Output_b1 = POb1
  452. #將數據保存進資料庫
  453. db.session.add(C_status)
  454. # 手動提交
  455. db.session.commit()
  456. # ----- 將狀態寫入資料庫 ------------------------------
  457. return jsonify({"Peel_Tank_1":P1,
  458. "Peel_Tank_2":P2,
  459. "Peel_Output_1":PO1,
  460. "Peel_Output_2":PO2
  461. })
  462. # 乾燥槽狀態更新
  463. @main.route('/dry_status_update', methods=['GET', 'POST'])
  464. def dry_status_update():
  465. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  466. DI1 = dry_status.Dry_Input_1
  467. DI2 = dry_status.Dry_Input_2
  468. D1 = dry_status.Dry_Tank_1
  469. D2 = dry_status.Dry_Tank_2
  470. D3 = dry_status.Dry_Tank_3
  471. D4 = dry_status.Dry_Tank_4
  472. D5 = dry_status.Dry_Tank_5
  473. D6 = dry_status.Dry_Tank_6
  474. D7 = dry_status.Dry_Tank_7
  475. D8 = dry_status.Dry_Tank_8
  476. D9 = dry_status.Dry_Tank_9
  477. D10 = dry_status.Dry_Tank_10
  478. D11 = dry_status.Dry_Tank_11
  479. D12 = dry_status.Dry_Tank_12
  480. DO1 = dry_status.Dry_Output_1
  481. DO2 = dry_status.Dry_Output_2
  482. return jsonify({"DI1":DI1,
  483. "DI2":DI2,
  484. "D1":D1,
  485. "D2":D2,
  486. "D3":D3,
  487. "D4":D4,
  488. "D5":D5,
  489. "D6":D6,
  490. "D7":D7,
  491. "D8":D8,
  492. "D9":D9,
  493. "D10":D10,
  494. "D11":D11,
  495. "D12":D12,
  496. "DO1":DO1,
  497. "DO2":DO2
  498. })
  499. # 乾燥槽自動化測試頁
  500. @main.route('/dry_auto', methods=['GET', 'POST'])
  501. def dry_auto():
  502. # 獲取登入信息
  503. if 'id' in session and 'uname' in session and 'status' in session:
  504. username = session['uname']
  505. status = session['status']
  506. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  507. DI1 = dry_status.Dry_Input_1
  508. DI2 = dry_status.Dry_Input_2
  509. D1 = dry_status.Dry_Tank_1
  510. D2 = dry_status.Dry_Tank_2
  511. D3 = dry_status.Dry_Tank_3
  512. D4 = dry_status.Dry_Tank_4
  513. D5 = dry_status.Dry_Tank_5
  514. D6 = dry_status.Dry_Tank_6
  515. D7 = dry_status.Dry_Tank_7
  516. D8 = dry_status.Dry_Tank_8
  517. D9 = dry_status.Dry_Tank_9
  518. D10 = dry_status.Dry_Tank_10
  519. D11 = dry_status.Dry_Tank_11
  520. D12 = dry_status.Dry_Tank_12
  521. DO1 = dry_status.Dry_Output_1
  522. DO2 = dry_status.Dry_Output_2
  523. return render_template('dry_auto.html', title="[測試] 乾燥自動化", **locals())
  524. else:
  525. return render_template('sign_in.html')
  526. # 乾燥槽 乾燥暫停 出料
  527. @main.route('/dryDEMO_outputtingBean', methods=['GET', 'POST'])
  528. def dryDEMO_outputtingBean():
  529. info = request.args.to_dict()
  530. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  531. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  532. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  533. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  534. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  535. DI2 = dry_status.Dry_Input_2
  536. D1 = dry_status.Dry_Tank_1
  537. D2 = dry_status.Dry_Tank_2
  538. D3 = dry_status.Dry_Tank_3
  539. D4 = dry_status.Dry_Tank_4
  540. D5 = dry_status.Dry_Tank_5
  541. D6 = dry_status.Dry_Tank_6
  542. D7 = dry_status.Dry_Tank_7
  543. D8 = dry_status.Dry_Tank_8
  544. D9 = dry_status.Dry_Tank_9
  545. D10 = dry_status.Dry_Tank_10
  546. D11 = dry_status.Dry_Tank_11
  547. D12 = dry_status.Dry_Tank_12
  548. DO1 = dry_status.Dry_Output_1
  549. DO2 = dry_status.Dry_Output_2
  550. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  551. # DO_UP_UltraSoniclist = []
  552. # for i in range(1, 3, 1):
  553. # output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  554. # UltraSonic = float(output_UltraSonic.UltraSonic)
  555. # DO_UP_UltraSoniclist.append(UltraSonic)
  556. # print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  557. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  558. # 將桶槽 D1 狀態轉換成可出豆, DO1 狀態轉換成可入豆
  559. D1 = 'D_OutputtingBean'
  560. # [致動器] 設定溫度 0.0
  561. data = { "tank_num": "D1", "command": "tank_temp", "value": "0.0" }
  562. print('data: ', data)
  563. # mqtt_f(data)
  564. # [致動器] 溫控開關 OFF
  565. data = { "tank_num": "D1", "command": "tank_temp_enable", "value": "off" }
  566. print('data: ', data)
  567. # mqtt_f(data)
  568. # [致動器] 馬達 0
  569. data = { "tank_num": "D1", "command": "tank_motor_status", "value": "0" }
  570. print('data: ', data)
  571. # mqtt_f(data)
  572. # [致動器] 排水電磁閥 OFF
  573. data = { "tank_num": "D1", "command": "tank_solenoid_water_out_status", "value": "off" }
  574. print('data: ', data)
  575. # mqtt_f(data)
  576. # [致動器] D1 蝴蝶閥 ON
  577. data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "on" }
  578. print('data: ', data)
  579. # mqtt_f(data)
  580. # ----- 將狀態寫入資料庫 ------------------------------
  581. # 獲取文本框的值並賦值給user實體對象
  582. D_status = dry_container_status()
  583. D_status.Dry_Input_1 = DI1
  584. D_status.Dry_Input_2 = DI2
  585. D_status.Dry_Tank_1 = D1
  586. D_status.Dry_Tank_2 = D2
  587. D_status.Dry_Tank_3 = D3
  588. D_status.Dry_Tank_4 = D4
  589. D_status.Dry_Tank_5 = D5
  590. D_status.Dry_Tank_6 = D6
  591. D_status.Dry_Tank_7 = D7
  592. D_status.Dry_Tank_8 = D8
  593. D_status.Dry_Tank_9 = D9
  594. D_status.Dry_Tank_10 = D10
  595. D_status.Dry_Tank_11 = D11
  596. D_status.Dry_Tank_12 = D12
  597. D_status.Dry_Output_1 = DO1
  598. D_status.Dry_Output_2 = DO2
  599. #將數據保存進資料庫
  600. db.session.add(D_status)
  601. # 手動提交
  602. db.session.commit()
  603. # ----- 將狀態寫入資料庫 ------------------------------
  604. return jsonify({"Dry_Tank_1":D1,
  605. "Dry_Tank_2":D2,
  606. "Dry_Output_1":DO1,
  607. "Dry_Output_2":DO2
  608. })
  609. @main.route('/dryDEMO_auto_status', methods=['GET', 'POST'])
  610. def dryDEMO_auto_status():
  611. info = request.args.to_dict()
  612. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  613. Dry_Tank_bean_empty = 2
  614. Dry_Output_bean_empty = 2
  615. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  616. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  617. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  618. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  619. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  620. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  621. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  622. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  623. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  624. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  625. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  626. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_timef'])
  627. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  628. Dry_btn = True
  629. # 從資料庫資料表中取得最新狀態
  630. # ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  631. # FO1 = 'FO_OutputtingBean'
  632. # FO2 = 'FO_Waiting'
  633. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  634. # FO2 = 'FO_Waiting'
  635. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  636. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  637. DI2 = dry_status.Dry_Input_2
  638. D1 = dry_status.Dry_Tank_1
  639. D2 = dry_status.Dry_Tank_2
  640. D3 = dry_status.Dry_Tank_3
  641. D4 = dry_status.Dry_Tank_4
  642. D5 = dry_status.Dry_Tank_5
  643. D6 = dry_status.Dry_Tank_6
  644. D7 = dry_status.Dry_Tank_7
  645. D8 = dry_status.Dry_Tank_8
  646. D9 = dry_status.Dry_Tank_9
  647. D10 = dry_status.Dry_Tank_10
  648. D11 = dry_status.Dry_Tank_11
  649. D12 = dry_status.Dry_Tank_12
  650. DO1 = dry_status.Dry_Output_1
  651. DO2 = dry_status.Dry_Output_2
  652. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  653. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  654. DOutputtingBean_Tank = '' # 出料桶槽號
  655. DryAuto_cleaning = 0 # 清洗次數
  656. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  657. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  658. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  659. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  660. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  661. DI_UP_UltraSoniclist = []
  662. for i in range(1, 3, 1):
  663. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  664. UltraSonic = float(input_UltraSonic.UltraSonic)
  665. DI_UP_UltraSoniclist.append(UltraSonic)
  666. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  667. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  668. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  669. D_UP_tank_UltraSonic = []
  670. for i in range(1, 7, 1):
  671. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  672. UltraSonic = float(tank_UltraSonic.UltraSonic)
  673. D_UP_tank_UltraSonic.append(UltraSonic)
  674. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  675. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  676. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  677. DO_UP_UltraSoniclist = []
  678. for i in range(1, 3, 1):
  679. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  680. UltraSonic = float(output_UltraSonic.UltraSonic)
  681. DO_UP_UltraSoniclist.append(UltraSonic)
  682. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  683. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  684. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  685. D_UP_tank_SHT11Temp = []
  686. D_UP_tank_SHT11Humidity = []
  687. for i in range(1, 7, 1):
  688. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  689. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  690. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  691. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  692. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  693. print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  694. print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  695. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  696. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  697. D_UP_tank_SoilTemp = []
  698. D_UP_tank_SoilHumidity = []
  699. D_UP_tank_SoilEC = []
  700. for i in range(1, 7, 1):
  701. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  702. soil_Temp = float(tank_Soil.soil_Temp)
  703. D_UP_tank_SoilTemp.append(soil_Temp)
  704. soil_Humidity = float(tank_Soil.soil_Humidity)
  705. D_UP_tank_SoilHumidity.append(soil_Humidity)
  706. soil_EC = float(tank_Soil.soil_EC)
  707. D_UP_tank_SoilEC.append(soil_EC)
  708. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  709. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  710. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  711. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  712. # ----- 發酵排程動作 start ------------------------------------------------------------------
  713. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  714. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  715. # [致動器] 真空吸料機 OFF
  716. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  717. print('data: ', data)
  718. # mqtt_f(data)
  719. # [致動器] 蝴蝶閥 OFF
  720. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  721. print('data: ', data)
  722. # mqtt_f(data)
  723. # # [致動器] F1 蝴蝶閥 OFF [ 1109 測試用 ]
  724. # data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  725. # print('data: ', data)
  726. # # mqtt_f(data)
  727. # [致動器] 馬達 0
  728. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  729. print('data: ', data)
  730. # mqtt_f(data)
  731. # [致動器] 入料三通閥 ON排氣
  732. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  733. print('data: ', data)
  734. # mqtt_f(data)
  735. print('------- ', tid,' 狀態更新:入豆完成 -------')
  736. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  737. def DInputtingBean_AND_notfilled(tid):
  738. # [致動器] 蝴蝶閥 OFF
  739. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  740. print('data: ', data)
  741. # mqtt_f(data)
  742. # [致動器] 入料三通閥 OFF入豆
  743. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  744. print('data: ', data)
  745. # mqtt_f(data)
  746. # [致動器] 真空吸料機 ON
  747. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  748. print('data: ', data)
  749. # mqtt_f(data)
  750. timer = time.time()
  751. while True:
  752. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  753. # [致動器] 真空吸料機 OFF
  754. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  755. print('data: ', data)
  756. # mqtt_f(data)
  757. timer = time.time()
  758. break
  759. while True:
  760. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  761. break
  762. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  763. def DInputtingBean_TO_DInputtingBeanPause(tid):
  764. # [致動器] 蝴蝶閥 OFF
  765. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  766. print('data: ', data)
  767. # mqtt_f(data)
  768. # [致動器] 真空吸料機 OFF
  769. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  770. print('data: ', data)
  771. # mqtt_f(data)
  772. # [致動器] 馬達 0
  773. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  774. print('data: ', data)
  775. # mqtt_f(data)
  776. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  777. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  778. def DInputtingBeanPause_TO_DInputtingBean(tid):
  779. # [致動器] 入料三通閥 OFF入豆
  780. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  781. print('data: ', data)
  782. # mqtt_f(data)
  783. # [致動器] 馬達 5
  784. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  785. print('data: ', data)
  786. # mqtt_f(data)
  787. print('------- ', tid, ' 狀態更新:入豆中 -------')
  788. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  789. def DWaiting_TO_DInputtingBean(tid):
  790. # [致動器] F1 蝴蝶閥 ON
  791. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  792. print('data: ', data)
  793. # mqtt_f(data)
  794. # [致動器] 蝴蝶閥 OFF
  795. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  796. print('data: ', data)
  797. # mqtt_f(data)
  798. # [致動器] 入料三通閥 OFF入豆
  799. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  800. print('data: ', data)
  801. # mqtt_f(data)
  802. # [致動器] 馬達 5
  803. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  804. print('data: ', data)
  805. # mqtt_f(data)
  806. print('------- ', tid, ' 狀態更新:入豆中 -------')
  807. # else: if D1 == 'D_InputtingBean_Finish':
  808. def DInputtingBeanFinish_TO_DDrying(tid):
  809. # [致動器] 馬達 指定轉速
  810. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  811. print('data: ', data)
  812. # mqtt_f(data)
  813. # [致動器] 排水電磁閥 ON
  814. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  815. print('data: ', data)
  816. # mqtt_f(data)
  817. # # [致動器] 鼓風機 ON
  818. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  819. # print('data: ', data)
  820. # # mqtt_f(data)
  821. # # [致動器] 加熱器 1 ON
  822. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  823. # print('data: ', data)
  824. # # mqtt_f(data)
  825. # # [致動器] 加熱器 2 ON
  826. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  827. # print('data: ', data)
  828. # # mqtt_f(data)
  829. # [致動器] 溫控開關 ON
  830. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on" }
  831. print('data: ', data)
  832. # mqtt_f(data)
  833. # [致動器] 設定溫度 (指定溫度)
  834. data = { "tank_num": tid, "command": "tank_temp", "value": Dry_Tank_drying_temp }
  835. print('data: ', data)
  836. # mqtt_f(data)
  837. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  838. # 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:
  839. def DDrying_TO_DOutputtingBean(tid):
  840. # # [致動器] 鼓風機 OFF
  841. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  842. # print('data: ', data)
  843. # # mqtt_f(data)
  844. # # [致動器] 加熱器 1 OFF
  845. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  846. # print('data: ', data)
  847. # # mqtt_f(data)
  848. # # [致動器] 加熱器 2 OFF
  849. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  850. # print('data: ', data)
  851. # # mqtt_f(data)
  852. # [致動器] 設定溫度 0
  853. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  854. print('data: ', data)
  855. # mqtt_f(data)
  856. # [致動器] 溫控開關 OFF
  857. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  858. print('data: ', data)
  859. # mqtt_f(data)
  860. # [致動器] 馬達 0
  861. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  862. print('data: ', data)
  863. # mqtt_f(data)
  864. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  865. timer = time.time()
  866. while True:
  867. if (time.time() - timer) > Dry_Tank_drying_time:
  868. # [致動器] 排水電磁閥 OFF
  869. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  870. print('data: ', data)
  871. # mqtt_f(data)
  872. break
  873. print('------- ', tid, ' 狀態更新:可出豆 -------')
  874. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  875. def DOutputtingBean_TO_DWaiting(tid):
  876. # [致動器] D1 蝴蝶閥 OFF
  877. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  878. print('data: ', data)
  879. # mqtt_f(data)
  880. # D_Cleaning
  881. def DCleaning(tid):
  882. # [致動器] 馬達 10
  883. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  884. print('data: ', data)
  885. # mqtt_f(data)
  886. # [致動器] 消毒電磁閥 ON
  887. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  888. print('data: ', data)
  889. # mqtt_f(data)
  890. # [致動器] 排水電磁閥 OFF
  891. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  892. print('data: ', data)
  893. # mqtt_f(data)
  894. # [致動器] TODO 消毒抽水 pump ON
  895. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  896. timer = time.time()
  897. while True:
  898. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  899. # [致動器] TODO 消毒抽水 pump OFF
  900. break
  901. # [致動器] 消毒電磁閥 OFF
  902. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  903. print('data: ', data)
  904. # mqtt_f(data)
  905. # [致動器] 馬達 0
  906. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  907. print('data: ', data)
  908. # mqtt_f(data)
  909. # [致動器] 排水電磁閥 ON
  910. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  911. print('data: ', data)
  912. # mqtt_f(data)
  913. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  914. timer = time.time()
  915. while True:
  916. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  917. break
  918. # [致動器] 排水電磁閥 OFF
  919. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  920. print('data: ', data)
  921. # mqtt_f(data)
  922. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  923. # ----- 發酵排程動作 end ------------------------------------------------------------------
  924. # [介面] 若啟用 乾燥 狀態
  925. if Dry_btn:
  926. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  927. # 若 D1~D6 桶槽中有一個桶槽入豆中
  928. if DryUp_InputtingBean_number == 1:
  929. # 若 D1 桶槽為入豆中
  930. if D1 == 'D_InputtingBean':
  931. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  932. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  933. DInputtingBean_TO_DInputtingBeanFinish("D1")
  934. D1 = 'D_InputtingBean_Finish'
  935. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  936. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  937. DInputtingBean_AND_notfilled("D1")
  938. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  939. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  940. DInputtingBean_TO_DInputtingBeanPause("D1")
  941. D1 = 'D_InputtingBean_Pause'
  942. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  943. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  944. if D1 == 'D_InputtingBean_Pause':
  945. DInputtingBeanPause_TO_DInputtingBean("D1")
  946. D1 = 'D_InputtingBean'
  947. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  948. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  949. if D1 == 'D_Waiting':
  950. DWaiting_TO_DInputtingBean("D1")
  951. D1 = 'D_InputtingBean'
  952. # 其他
  953. # else:
  954. # 以下內容原在此 else 內, 測試無誤後維持
  955. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  956. if D1 == 'D_InputtingBean_Finish':
  957. DInputtingBeanFinish_TO_DDrying("D1")
  958. D1 = 'D_Drying'
  959. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  960. if D1 == 'D_Drying' and D_UP_tank_SHT11Temp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  961. DDrying_TO_DOutputtingBean("D1")
  962. D1 = 'D_OutputtingBean'
  963. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  964. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  965. # TODO 發酵次數計算、消毒次數、校正
  966. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  967. if DOutputtingBean_Tank == 'D1':
  968. DOutputtingBean_TO_DWaiting('D1')
  969. DOutputtingBean_Tank = ''
  970. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  971. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  972. # 避免桶槽可出豆時未賦值
  973. if DOutputtingBean_Tank == '':
  974. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  975. # 乾燥槽消毒
  976. if D1 == 'D_Cleaning':
  977. DCleaning("D1")
  978. D1 = 'D_Waiting'
  979. else:
  980. print('未啟用乾燥流程')
  981. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  982. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  983. # # 1109 註解實驗用
  984. # if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  985. # # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  986. # DO1 = 'DO_InputtingBean'
  987. # print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  988. # print('------- DO1 狀態更新:入豆中 -------')
  989. # # [致動器] D1 蝴蝶閥 ON
  990. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  991. # print('data: ', data)
  992. # # mqtt_f(data)
  993. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  994. # if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  995. # # [致動器] 出料真空吸料機 OFF
  996. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  997. # print('data: ', data)
  998. # # mqtt_f(data)
  999. # # [致動器] D1 蝴蝶閥 OFF
  1000. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  1001. # print('data: ', data)
  1002. # # mqtt_f(data)
  1003. # DO1 = 'DO_OutputtingBean'
  1004. # print('------- DO1 狀態更新:可出豆 -------')
  1005. # elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  1006. # # [致動器] 出料真空吸料機 ON
  1007. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  1008. # print('data: ', data)
  1009. # # mqtt_f(data)
  1010. # timer = time.time()
  1011. # while True:
  1012. # if (time.time() - timer) > Dry_Output_vacuumON_time:
  1013. # # [致動器] 出料真空吸料機 OFF
  1014. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  1015. # print('data: ', data)
  1016. # # mqtt_f(data)
  1017. # timer = time.time()
  1018. # break
  1019. # while True:
  1020. # if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  1021. # break
  1022. # # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  1023. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank == '':
  1024. # if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  1025. # DO1 = 'DO_OutputtingBean'
  1026. # print('------- DO1 狀態更新:可出豆 -------')
  1027. # elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1028. # DO1 = 'DO_Waiting'
  1029. # print('------- DO1 狀態更新:空桶等待 -------')
  1030. # elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1031. # DO1 = 'DO_Waiting'
  1032. # # [致動器] D1 蝴蝶閥 OFF
  1033. # data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "off" }
  1034. # print('data: ', data)
  1035. # # mqtt_f(data)
  1036. # print('------- DO1 狀態更新:空桶等待 -------')
  1037. # # 1109 註解實驗用
  1038. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1039. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  1040. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  1041. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  1042. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  1043. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  1044. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  1045. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1046. # ----- 將狀態寫入資料庫 ------------------------------
  1047. # 獲取文本框的值並賦值給user實體對象
  1048. D_status = dry_container_status()
  1049. D_status.Dry_Input_1 = DI1
  1050. D_status.Dry_Input_2 = DI2
  1051. D_status.Dry_Tank_1 = D1
  1052. D_status.Dry_Tank_2 = D2
  1053. D_status.Dry_Tank_3 = D3
  1054. D_status.Dry_Tank_4 = D4
  1055. D_status.Dry_Tank_5 = D5
  1056. D_status.Dry_Tank_6 = D6
  1057. D_status.Dry_Tank_7 = D7
  1058. D_status.Dry_Tank_8 = D8
  1059. D_status.Dry_Tank_9 = D9
  1060. D_status.Dry_Tank_10 = D10
  1061. D_status.Dry_Tank_11 = D11
  1062. D_status.Dry_Tank_12 = D12
  1063. D_status.Dry_Output_1 = DO1
  1064. D_status.Dry_Output_2 = DO2
  1065. #將數據保存進資料庫
  1066. db.session.add(D_status)
  1067. # 手動提交
  1068. db.session.commit()
  1069. # ----- 將狀態寫入資料庫 ------------------------------
  1070. return jsonify({"Dry_Tank_1":D1,
  1071. "Dry_Tank_2":D2,
  1072. "Dry_Output_1":DO1,
  1073. "Dry_Output_2":DO2
  1074. })
  1075. @main.route('/dry_auto_status', methods=['GET', 'POST'])
  1076. def dry_auto_status():
  1077. info = request.args.to_dict()
  1078. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  1079. Dry_Input_bean_empty = 2
  1080. Dry_Tank_bean_empty = 2
  1081. Dry_Output_bean_empty = 2
  1082. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  1083. Dry_Input_bean_height = float(info['Dry_Input_bean_height'])
  1084. Dry_Input_vacuumON_time = float(info['Dry_Input_vacuumON_time'])
  1085. Dry_Input_vacuumOFF_time = float(info['Dry_Input_vacuumOFF_time'])
  1086. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  1087. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  1088. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  1089. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  1090. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  1091. Dry_Tank_drying_EC = float(info['Dry_Tank_drying_EC'])
  1092. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  1093. Dry_Tank_TempWeight_SHT11 = float(info['Dry_Tank_TempWeight_SHT11'])
  1094. Dry_Tank_TempWeight_soil = float(info['Dry_Tank_TempWeight_soil'])
  1095. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  1096. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  1097. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  1098. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  1099. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_time'])
  1100. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  1101. Dry_btn = True
  1102. # 從資料庫資料表中取得最新狀態
  1103. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  1104. FO1 = ferment_status.Ferment_Output_1
  1105. FO2 = ferment_status.Ferment_Output_2
  1106. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  1107. # FO2 = 'FO_Waiting'
  1108. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  1109. DI1 = dry_status.Dry_Input_1
  1110. DI2 = dry_status.Dry_Input_2
  1111. D1 = dry_status.Dry_Tank_1
  1112. D2 = dry_status.Dry_Tank_2
  1113. D3 = dry_status.Dry_Tank_3
  1114. D4 = dry_status.Dry_Tank_4
  1115. D5 = dry_status.Dry_Tank_5
  1116. D6 = dry_status.Dry_Tank_6
  1117. D7 = dry_status.Dry_Tank_7
  1118. D8 = dry_status.Dry_Tank_8
  1119. D9 = dry_status.Dry_Tank_9
  1120. D10 = dry_status.Dry_Tank_10
  1121. D11 = dry_status.Dry_Tank_11
  1122. D12 = dry_status.Dry_Tank_12
  1123. DO1 = dry_status.Dry_Output_1
  1124. DO2 = dry_status.Dry_Output_2
  1125. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  1126. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  1127. DOutputtingBean_Tank = '' # 出料桶槽號
  1128. DryAuto_cleaning = 0 # 清洗次數
  1129. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  1130. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  1131. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1132. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  1133. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1134. DI_UP_UltraSoniclist = []
  1135. for i in range(1, 3, 1):
  1136. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  1137. UltraSonic = float(input_UltraSonic.UltraSonic)
  1138. DI_UP_UltraSoniclist.append(UltraSonic)
  1139. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  1140. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1141. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1142. D_UP_tank_UltraSonic = []
  1143. for i in range(1, 7, 1):
  1144. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1145. UltraSonic = float(tank_UltraSonic.UltraSonic)
  1146. D_UP_tank_UltraSonic.append(UltraSonic)
  1147. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  1148. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1149. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1150. DO_UP_UltraSoniclist = []
  1151. for i in range(1, 3, 1):
  1152. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  1153. UltraSonic = float(output_UltraSonic.UltraSonic)
  1154. DO_UP_UltraSoniclist.append(UltraSonic)
  1155. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  1156. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1157. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  1158. D_UP_tank_SHT11Temp = []
  1159. D_UP_tank_SHT11Humidity = []
  1160. for i in range(1, 7, 1):
  1161. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1162. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  1163. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  1164. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  1165. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  1166. # print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  1167. # print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  1168. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  1169. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  1170. D_UP_tank_SoilTemp = []
  1171. D_UP_tank_SoilHumidity = []
  1172. D_UP_tank_SoilEC = []
  1173. for i in range(1, 7, 1):
  1174. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1175. soil_Temp = float(tank_Soil.soil_Temp)
  1176. D_UP_tank_SoilTemp.append(soil_Temp)
  1177. soil_Humidity = float(tank_Soil.soil_Humidity)
  1178. D_UP_tank_SoilHumidity.append(soil_Humidity)
  1179. soil_EC = float(tank_Soil.soil_EC)
  1180. D_UP_tank_SoilEC.append(soil_EC)
  1181. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  1182. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  1183. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  1184. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  1185. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  1186. D_UP_tank_weightTemp = []
  1187. for i in range(1, 7, 1):
  1188. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1189. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1190. 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)
  1191. D_UP_tank_weightTemp.append(Temp)
  1192. print('D_UP_tank_weightTemp: ', D_UP_tank_weightTemp)
  1193. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  1194. # ----- 發酵排程動作 start ------------------------------------------------------------------
  1195. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  1196. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  1197. # [致動器] 真空吸料機 OFF
  1198. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1199. print('data: ', data)
  1200. # mqtt_f(data)
  1201. # [致動器] 馬達 0
  1202. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1203. print('data: ', data)
  1204. # mqtt_f(data)
  1205. # [致動器] 入料三通閥 ON排氣
  1206. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  1207. print('data: ', data)
  1208. # mqtt_f(data)
  1209. print('------- ', tid,' 狀態更新:入豆完成 -------')
  1210. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1211. def DInputtingBean_AND_notfilled(tid):
  1212. # [致動器] 入料三通閥 OFF入豆
  1213. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1214. print('data: ', data)
  1215. # mqtt_f(data)
  1216. # [致動器] 真空吸料機 ON
  1217. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  1218. print('data: ', data)
  1219. # mqtt_f(data)
  1220. timer = time.time()
  1221. while True:
  1222. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  1223. # [致動器] 真空吸料機 OFF
  1224. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1225. print('data: ', data)
  1226. # mqtt_f(data)
  1227. timer = time.time()
  1228. break
  1229. while True:
  1230. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  1231. break
  1232. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1233. def DInputtingBean_TO_DInputtingBeanPause(tid):
  1234. # [致動器] 真空吸料機 OFF
  1235. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  1236. print('data: ', data)
  1237. # mqtt_f(data)
  1238. # [致動器] 馬達 0
  1239. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1240. print('data: ', data)
  1241. # mqtt_f(data)
  1242. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  1243. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  1244. def DInputtingBeanPause_TO_DInputtingBean(tid):
  1245. # [致動器] 入料三通閥 OFF入豆
  1246. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1247. print('data: ', data)
  1248. # mqtt_f(data)
  1249. # [致動器] 馬達 5
  1250. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  1251. print('data: ', data)
  1252. # mqtt_f(data)
  1253. print('------- ', tid, ' 狀態更新:入豆中 -------')
  1254. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  1255. def DWaiting_TO_DInputtingBean(tid):
  1256. # [致動器] 入料三通閥 OFF入豆
  1257. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  1258. print('data: ', data)
  1259. # mqtt_f(data)
  1260. # [致動器] 馬達 5
  1261. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  1262. print('data: ', data)
  1263. # mqtt_f(data)
  1264. print('------- ', tid, ' 狀態更新:入豆中 -------')
  1265. # else: if D1 == 'D_InputtingBean_Finish':
  1266. def DInputtingBeanFinish_TO_DDrying(tid):
  1267. # [致動器] 馬達 指定轉速
  1268. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  1269. print('data: ', data)
  1270. # mqtt_f(data)
  1271. # [致動器] 排水電磁閥 ON
  1272. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  1273. print('data: ', data)
  1274. # mqtt_f(data)
  1275. # [致動器] 鼓風機 ON
  1276. data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  1277. print('data: ', data)
  1278. # mqtt_f(data)
  1279. # [致動器] 加熱器 1 ON
  1280. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  1281. print('data: ', data)
  1282. # mqtt_f(data)
  1283. # [致動器] 加熱器 2 ON
  1284. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  1285. print('data: ', data)
  1286. # mqtt_f(data)
  1287. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  1288. # 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:
  1289. def DDrying_TO_DOutputtingBean(tid):
  1290. # [致動器] 鼓風機 OFF
  1291. data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  1292. print('data: ', data)
  1293. # mqtt_f(data)
  1294. # [致動器] 加熱器 1 OFF
  1295. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  1296. print('data: ', data)
  1297. # mqtt_f(data)
  1298. # [致動器] 加熱器 2 OFF
  1299. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  1300. print('data: ', data)
  1301. # mqtt_f(data)
  1302. # [致動器] 馬達 0
  1303. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1304. print('data: ', data)
  1305. # mqtt_f(data)
  1306. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  1307. timer = time.time()
  1308. while True:
  1309. if (time.time() - timer) > Dry_Tank_drying_time:
  1310. # [致動器] 排水電磁閥 OFF
  1311. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1312. print('data: ', data)
  1313. # mqtt_f(data)
  1314. break
  1315. print('------- ', tid, ' 狀態更新:可出豆 -------')
  1316. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  1317. def DOutputtingBean_TO_DWaiting(tid):
  1318. # [致動器] D1 蝴蝶閥 OFF
  1319. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  1320. print('data: ', data)
  1321. # mqtt_f(data)
  1322. # D_Cleaning
  1323. def DCleaning(tid):
  1324. # [致動器] 馬達 10
  1325. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  1326. print('data: ', data)
  1327. # mqtt_f(data)
  1328. # [致動器] 消毒電磁閥 ON
  1329. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  1330. print('data: ', data)
  1331. # mqtt_f(data)
  1332. # [致動器] 排水電磁閥 OFF
  1333. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1334. print('data: ', data)
  1335. # mqtt_f(data)
  1336. # [致動器] TODO 消毒抽水 pump ON
  1337. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  1338. timer = time.time()
  1339. while True:
  1340. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  1341. # [致動器] TODO 消毒抽水 pump OFF
  1342. break
  1343. # [致動器] 消毒電磁閥 OFF
  1344. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  1345. print('data: ', data)
  1346. # mqtt_f(data)
  1347. # [致動器] 馬達 0
  1348. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  1349. print('data: ', data)
  1350. # mqtt_f(data)
  1351. # [致動器] 排水電磁閥 ON
  1352. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  1353. print('data: ', data)
  1354. # mqtt_f(data)
  1355. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  1356. timer = time.time()
  1357. while True:
  1358. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  1359. break
  1360. # [致動器] 排水電磁閥 OFF
  1361. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  1362. print('data: ', data)
  1363. # mqtt_f(data)
  1364. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  1365. # ----- 發酵排程動作 end ------------------------------------------------------------------
  1366. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  1367. # 如果入料儲豆槽 空桶等待, 且發酵出料儲豆槽 FO1 為可出豆, 則開始入豆
  1368. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  1369. DI1 = 'DI_InputtingBean'
  1370. print('------- DI1 狀態更新:入料中 -------')
  1371. # 如果入料儲豆槽 入豆中
  1372. elif DI1 == 'DI_InputtingBean':
  1373. # 如果入豆儲豆槽達指定高度時
  1374. if DI_UP_UltraSoniclist[0] >= Dry_Input_bean_height:
  1375. # [致動器] 入料真空吸料機 OFF
  1376. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  1377. print('data: ', data)
  1378. # mqtt_f(data)
  1379. DI1 = 'DI_OutputtingBean'
  1380. print('------- DI1 狀態更新:可出豆 -------')
  1381. # 如果入豆儲豆槽未達指定高度, 且 發酵出料儲豆槽 可出豆
  1382. elif DI_UP_UltraSoniclist[0] < Dry_Input_bean_height and FO1 == 'FO_OutputtingBean':
  1383. # [致動器] 入料真空吸料機 ON
  1384. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "on" }
  1385. print('data: ', data)
  1386. # mqtt_f(data)
  1387. timer = time.time()
  1388. while True:
  1389. if (time.time() - timer) > Dry_Input_vacuumON_time:
  1390. # [致動器] 入料真空吸料機 OFF
  1391. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  1392. print('data: ', data)
  1393. # mqtt_f(data)
  1394. timer = time.time()
  1395. break
  1396. while True:
  1397. if (time.time() - timer) > Dry_Input_vacuumOFF_time:
  1398. break
  1399. # 如果入料儲豆槽生豆大於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為可出豆
  1400. elif (DI_UP_UltraSoniclist[0] > Dry_Input_bean_empty) and FO1 != 'FO_OutputtingBean':
  1401. DI1 = 'DI_OutputtingBean'
  1402. print('------- DI1 狀態更新:可出豆 -------')
  1403. # 桶槽內小於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為空桶等待
  1404. elif (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty) and FO1 != 'PO_OutputtingBean':
  1405. DI1 = 'DI_Waiting'
  1406. print('------- FI1 狀態更新:空桶等待 -------')
  1407. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  1408. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty):
  1409. DI1 = 'DI_Waiting'
  1410. print('------- DI1 狀態更新:空桶等待 -------')
  1411. # [介面] 若啟用 乾燥 狀態
  1412. if Dry_btn:
  1413. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  1414. # 若 D1~D6 桶槽中有一個桶槽入豆中
  1415. if DryUp_InputtingBean_number == 1:
  1416. # 若 D1 桶槽為入豆中
  1417. if D1 == 'D_InputtingBean':
  1418. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  1419. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  1420. DInputtingBean_TO_DInputtingBeanFinish("D1")
  1421. D1 = 'D_InputtingBean_Finish'
  1422. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  1423. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1424. DInputtingBean_AND_notfilled("D1")
  1425. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  1426. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1427. DInputtingBean_TO_DInputtingBeanPause("D1")
  1428. D1 = 'D_InputtingBean_Pause'
  1429. elif D2 == 'D_InputtingBean':
  1430. if D_UP_tank_UltraSonic[1] >= Dry_Tank_bean_height:
  1431. DInputtingBean_TO_DInputtingBeanFinish("D2")
  1432. D2 = 'D_InputtingBean_Finish'
  1433. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1434. DInputtingBean_AND_notfilled("D2")
  1435. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1436. DInputtingBean_TO_DInputtingBeanPause("D2")
  1437. D2 = 'D_InputtingBean_Pause'
  1438. elif D3 == 'D_InputtingBean':
  1439. if D_UP_tank_UltraSonic[2] >= Dry_Tank_bean_height:
  1440. DInputtingBean_TO_DInputtingBeanFinish("D3")
  1441. D3 = 'D_InputtingBean_Finish'
  1442. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1443. DInputtingBean_AND_notfilled("D2")
  1444. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1445. DInputtingBean_TO_DInputtingBeanPause("D2")
  1446. D3 = 'D_InputtingBean_Pause'
  1447. elif D4 == 'D_InputtingBean':
  1448. if D_UP_tank_UltraSonic[3] >= Dry_Tank_bean_height:
  1449. DInputtingBean_TO_DInputtingBeanFinish("D4")
  1450. D4 = 'D_InputtingBean_Finish'
  1451. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1452. DInputtingBean_AND_notfilled("D4")
  1453. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1454. DInputtingBean_TO_DInputtingBeanPause("D4")
  1455. D4 = 'D_InputtingBean_Pause'
  1456. elif D5 == 'D_InputtingBean':
  1457. if D_UP_tank_UltraSonic[4] >= Dry_Tank_bean_height:
  1458. DInputtingBean_TO_DInputtingBeanFinish("D5")
  1459. D5 = 'D_InputtingBean_Finish'
  1460. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1461. DInputtingBean_AND_notfilled("D5")
  1462. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1463. DInputtingBean_TO_DInputtingBeanPause("D5")
  1464. D5 = 'D_InputtingBean_Pause'
  1465. elif D6 == 'D_InputtingBean':
  1466. if D_UP_tank_UltraSonic[5] >= Dry_Tank_bean_height:
  1467. DInputtingBean_TO_DInputtingBeanFinish("D6")
  1468. D6 = 'D_InputtingBean_Finish'
  1469. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  1470. DInputtingBean_AND_notfilled("D6")
  1471. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  1472. DInputtingBean_TO_DInputtingBeanPause("D6")
  1473. D6 = 'D_InputtingBean_Pause'
  1474. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  1475. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  1476. if D1 == 'D_InputtingBean_Pause':
  1477. DInputtingBeanPause_TO_DInputtingBean("D1")
  1478. D1 = 'D_InputtingBean'
  1479. elif D2 == 'D_InputtingBean_Pause':
  1480. DInputtingBeanPause_TO_DInputtingBean("D2")
  1481. D2 = 'D_InputtingBean'
  1482. elif D3 == 'D_InputtingBean_Pause':
  1483. DInputtingBeanPause_TO_DInputtingBean("D3")
  1484. D3 = 'D_InputtingBean'
  1485. elif D4 == 'D_InputtingBean_Pause':
  1486. DInputtingBeanPause_TO_DInputtingBean("D4")
  1487. D4 = 'D_InputtingBean'
  1488. elif D5 == 'D_InputtingBean_Pause':
  1489. DInputtingBeanPause_TO_DInputtingBean("D5")
  1490. D5 = 'D_InputtingBean'
  1491. elif D6 == 'D_InputtingBean_Pause':
  1492. DInputtingBeanPause_TO_DInputtingBean("D6")
  1493. D6 = 'D_InputtingBean'
  1494. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  1495. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  1496. if D1 == 'D_Waiting':
  1497. DWaiting_TO_DInputtingBean("D1")
  1498. D1 = 'D_InputtingBean'
  1499. elif D2 == 'D_Waiting':
  1500. DWaiting_TO_DInputtingBean("D2")
  1501. D2 = 'D_InputtingBean'
  1502. elif D3 == 'D_Waiting':
  1503. DWaiting_TO_DInputtingBean("D3")
  1504. D3 = 'D_InputtingBean'
  1505. elif D4 == 'D_Waiting':
  1506. DWaiting_TO_DInputtingBean("D4")
  1507. D4 = 'D_InputtingBean'
  1508. elif D5 == 'D_Waiting':
  1509. DWaiting_TO_DInputtingBean("D5")
  1510. D5 = 'D_InputtingBean'
  1511. elif D6 == 'D_Waiting':
  1512. DWaiting_TO_DInputtingBean("D6")
  1513. D6 = 'D_InputtingBean'
  1514. # 其他
  1515. else:
  1516. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  1517. if D1 == 'D_InputtingBean_Finish':
  1518. DInputtingBeanFinish_TO_DDrying("D1")
  1519. D1 = 'D_Drying'
  1520. if D2 == 'D_InputtingBean_Finish':
  1521. DInputtingBeanFinish_TO_DDrying("D2")
  1522. D2 = 'D_Drying'
  1523. if D3 == 'D_InputtingBean_Finish':
  1524. DInputtingBeanFinish_TO_DDrying("D3")
  1525. D3 = 'D_Drying'
  1526. if D4 == 'D_InputtingBean_Finish':
  1527. DInputtingBeanFinish_TO_DDrying("D4")
  1528. D4 = 'D_Drying'
  1529. if D5 == 'D_InputtingBean_Finish':
  1530. DInputtingBeanFinish_TO_DDrying("D5")
  1531. D5 = 'D_Drying'
  1532. if D6 == 'D_InputtingBean_Finish':
  1533. DInputtingBeanFinish_TO_DDrying("D6")
  1534. D6 = 'D_Drying'
  1535. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  1536. if D1 == 'D_Drying' and D_UP_tank_weightTemp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  1537. DDrying_TO_DOutputtingBean("D1")
  1538. D1 = 'D_OutputtingBean'
  1539. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  1540. if D2 == 'D_Drying' and D_UP_tank_weightTemp[1] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[1] <= Dry_Tank_drying_Humidity:
  1541. DDrying_TO_DOutputtingBean("D2")
  1542. D2 = 'D_OutputtingBean'
  1543. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D2'
  1544. if D3 == 'D_Drying' and D_UP_tank_weightTemp[2] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[2] <= Dry_Tank_drying_Humidity:
  1545. DDrying_TO_DOutputtingBean("D3")
  1546. D3 = 'D_OutputtingBean'
  1547. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D3'
  1548. if D4 == 'D_Drying' and D_UP_tank_weightTemp[3] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[3] <= Dry_Tank_drying_Humidity:
  1549. DDrying_TO_DOutputtingBean("D4")
  1550. D4 = 'D_OutputtingBean'
  1551. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D4'
  1552. if D5 == 'D_Drying' and D_UP_tank_weightTemp[4] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[4] <= Dry_Tank_drying_Humidity:
  1553. DDrying_TO_DOutputtingBean("D5")
  1554. D5 = 'D_OutputtingBean'
  1555. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D5'
  1556. if D6 == 'D_Drying' and D_UP_tank_weightTemp[5] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[5] <= Dry_Tank_drying_Humidity:
  1557. DDrying_TO_DOutputtingBean("D6")
  1558. D6 = 'D_OutputtingBean'
  1559. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D6'
  1560. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  1561. # TODO 發酵次數計算、消毒次數、校正
  1562. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  1563. if DOutputtingBean_Tank == 'D1':
  1564. DOutputtingBean_TO_DWaiting('D1')
  1565. DOutputtingBean_Tank = ''
  1566. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  1567. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  1568. if D2 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[1] <= Dry_Tank_bean_empty):
  1569. if DOutputtingBean_Tank == 'D2':
  1570. DOutputtingBean_TO_DWaiting('D2')
  1571. DOutputtingBean_Tank = ''
  1572. if (DryAuto_cleaning == 0): D2 = 'D_Waiting'
  1573. elif (DryAuto_cleaning != 0): D2 = 'D_Cleaning'
  1574. if D3 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[2] <= Dry_Tank_bean_empty):
  1575. if DOutputtingBean_Tank == 'D2':
  1576. DOutputtingBean_TO_DWaiting('D2')
  1577. DOutputtingBean_Tank = ''
  1578. if (DryAuto_cleaning == 0): D3 = 'D_Waiting'
  1579. elif (DryAuto_cleaning != 0): D3 = 'D_Cleaning'
  1580. if D4 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[3] <= Dry_Tank_bean_empty):
  1581. if DOutputtingBean_Tank == 'D4':
  1582. DOutputtingBean_TO_DWaiting('D4')
  1583. DOutputtingBean_Tank = ''
  1584. if (DryAuto_cleaning == 0): D4 = 'D_Waiting'
  1585. elif (DryAuto_cleaning != 0): D4 = 'D_Cleaning'
  1586. if D5 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[4] <= Dry_Tank_bean_empty):
  1587. if DOutputtingBean_Tank == 'D5':
  1588. DOutputtingBean_TO_DWaiting('D5')
  1589. DOutputtingBean_Tank = ''
  1590. if (DryAuto_cleaning == 0): D5 = 'D_Waiting'
  1591. elif (DryAuto_cleaning != 0): D5 = 'D_Cleaning'
  1592. if D6 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[5] <= Dry_Tank_bean_empty):
  1593. if DOutputtingBean_Tank == 'D6':
  1594. DOutputtingBean_TO_DWaiting('D6')
  1595. DOutputtingBean_Tank = ''
  1596. if (DryAuto_cleaning == 0): D6 = 'D_Waiting'
  1597. elif (DryAuto_cleaning != 0): D6 = 'D_Cleaning'
  1598. # 避免桶槽可出豆時未賦值
  1599. if DOutputtingBean_Tank == '':
  1600. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  1601. elif D2 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D2'
  1602. elif D3 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D3'
  1603. elif D4 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D4'
  1604. elif D5 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D5'
  1605. elif D6 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D6'
  1606. # 乾燥槽消毒
  1607. if D1 == 'D_Cleaning':
  1608. DCleaning("D1")
  1609. D1 = 'D_Waiting'
  1610. if D2 == 'D_Cleaning':
  1611. DCleaning("D2")
  1612. D2 = 'D_Waiting'
  1613. if D3 == 'D_Cleaning':
  1614. DCleaning("D3")
  1615. D3 = 'D_Waiting'
  1616. if D4 == 'D_Cleaning':
  1617. DCleaning("D4")
  1618. D4 = 'D_Waiting'
  1619. if D5 == 'D_Cleaning':
  1620. DCleaning("D5")
  1621. D5 = 'D_Waiting'
  1622. if D6 == 'D_Cleaning':
  1623. DCleaning("D6")
  1624. D6 = 'D_Waiting'
  1625. else:
  1626. print('未啟用乾燥流程')
  1627. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  1628. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  1629. if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  1630. # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  1631. DO1 = 'DO_InputtingBean'
  1632. print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  1633. print('------- DO1 狀態更新:入豆中 -------')
  1634. # [致動器] D1 蝴蝶閥 ON
  1635. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  1636. print('data: ', data)
  1637. # mqtt_f(data)
  1638. elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  1639. if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  1640. # [致動器] 出料真空吸料機 OFF
  1641. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  1642. print('data: ', data)
  1643. # mqtt_f(data)
  1644. # [致動器] D1 蝴蝶閥 OFF
  1645. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  1646. print('data: ', data)
  1647. # mqtt_f(data)
  1648. DO1 = 'DO_OutputtingBean'
  1649. print('------- DO1 狀態更新:可出豆 -------')
  1650. elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  1651. # [致動器] 出料真空吸料機 ON
  1652. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  1653. print('data: ', data)
  1654. # mqtt_f(data)
  1655. timer = time.time()
  1656. while True:
  1657. if (time.time() - timer) > Dry_Output_vacuumON_time:
  1658. # [致動器] 出料真空吸料機 OFF
  1659. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  1660. print('data: ', data)
  1661. # mqtt_f(data)
  1662. timer = time.time()
  1663. break
  1664. while True:
  1665. if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  1666. break
  1667. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  1668. elif DOutputtingBean_Tank == '':
  1669. if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  1670. DO1 = 'DO_OutputtingBean'
  1671. print('------- DO1 狀態更新:可出豆 -------')
  1672. elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1673. DO1 = 'DO_Waiting'
  1674. print('------- DO1 狀態更新:空桶等待 -------')
  1675. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  1676. DO1 = 'DO_Waiting'
  1677. print('------- DO1 狀態更新:空桶等待 -------')
  1678. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1679. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  1680. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  1681. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  1682. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  1683. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  1684. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  1685. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1686. # ----- 將狀態寫入資料庫 ------------------------------
  1687. # 獲取文本框的值並賦值給user實體對象
  1688. D_status = dry_container_status()
  1689. D_status.Dry_Input_1 = DI1
  1690. D_status.Dry_Input_2 = DI2
  1691. D_status.Dry_Tank_1 = D1
  1692. D_status.Dry_Tank_2 = D2
  1693. D_status.Dry_Tank_3 = D3
  1694. D_status.Dry_Tank_4 = D4
  1695. D_status.Dry_Tank_5 = D5
  1696. D_status.Dry_Tank_6 = D6
  1697. D_status.Dry_Tank_7 = D7
  1698. D_status.Dry_Tank_8 = D8
  1699. D_status.Dry_Tank_9 = D9
  1700. D_status.Dry_Tank_10 = D10
  1701. D_status.Dry_Tank_11 = D11
  1702. D_status.Dry_Tank_12 = D12
  1703. D_status.Dry_Output_1 = DO1
  1704. D_status.Dry_Output_2 = DO2
  1705. #將數據保存進資料庫
  1706. db.session.add(D_status)
  1707. # 手動提交
  1708. db.session.commit()
  1709. # ----- 將狀態寫入資料庫 ------------------------------
  1710. return jsonify({"Dry_Input_1":DI1,
  1711. "Dry_Tank_1":D1,
  1712. "Dry_Tank_2":D2,
  1713. "Dry_Tank_3":D3,
  1714. "Dry_Tank_4":D4,
  1715. "Dry_Tank_5":D5,
  1716. "Dry_Tank_6":D6,
  1717. "Dry_Output_1":DO1
  1718. })
  1719. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以下為原備份
  1720. @main.route('/dry_auto_status_1101backup', methods=['GET', 'POST'])
  1721. def dry_auto_test_1101backup():
  1722. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  1723. Dry_btn = True
  1724. # 從資料庫資料表中取得最新狀態
  1725. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  1726. DI1 = dry_status.Dry_Input_1
  1727. DI2 = dry_status.Dry_Input_2
  1728. D1 = dry_status.Dry_Tank_1
  1729. D2 = dry_status.Dry_Tank_2
  1730. D3 = dry_status.Dry_Tank_3
  1731. D4 = dry_status.Dry_Tank_4
  1732. D5 = dry_status.Dry_Tank_5
  1733. D6 = dry_status.Dry_Tank_6
  1734. D7 = dry_status.Dry_Tank_7
  1735. D8 = dry_status.Dry_Tank_8
  1736. D9 = dry_status.Dry_Tank_9
  1737. D10 = dry_status.Dry_Tank_10
  1738. D11 = dry_status.Dry_Tank_11
  1739. D12 = dry_status.Dry_Tank_12
  1740. DO1 = dry_status.Dry_Output_1
  1741. DO2 = dry_status.Dry_Output_2
  1742. FO1 = 'FO_Waiting' # 'FO_OutputtingBean'
  1743. FO2 = 'FO_Waiting'
  1744. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  1745. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  1746. # ----- 乾燥桶槽 D1~D6 入料暫停→入料判斷 ------------------------------
  1747. Dry_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  1748. # 若入料儲豆槽可出豆, 且 D1~D6 其中有桶槽入料暫停 (就是入料時桶槽豆子未滿 or 儲豆槽=='DI_Waiting' 已空) 時, 優先入豆
  1749. if DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  1750. if D1 == 'D_InputtingBean_Pause':
  1751. D1 = 'D_InputtingBean'
  1752. print('------- D1 狀態更新:入料中 -------')
  1753. elif D2 == 'D_InputtingBean_Pause':
  1754. D2 = 'D_InputtingBean'
  1755. print('------- D2 狀態更新:入料中 -------')
  1756. elif D3 == 'D_InputtingBean_Pause':
  1757. D3 = 'D_InputtingBean'
  1758. print('------- D3 狀態更新:入料中 -------')
  1759. elif D4 == 'D_InputtingBean_Pause':
  1760. D4 = 'D_InputtingBean'
  1761. print('------- D4 狀態更新:入料中 -------')
  1762. elif D5 == 'D_InputtingBean_Pause':
  1763. D5 = 'D_InputtingBean'
  1764. print('------- D5 狀態更新:入料中 -------')
  1765. elif D6 == 'D_InputtingBean_Pause':
  1766. D6 = 'D_InputtingBean'
  1767. print('------- D6 狀態更新:入料中 -------')
  1768. # ----- 乾燥桶槽 D1~D6 等待→入料判斷 ------------------------------
  1769. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  1770. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1771. # [介面] 若未啟用 發酵 狀態
  1772. if not Dry_btn:
  1773. print('未指定乾燥流程')
  1774. # 入料儲豆槽 非可出料狀態
  1775. elif Dry_btn and DI1 != 'DI_OutputtingBean':
  1776. print('入料儲豆槽非可出豆, 無法入料')
  1777. # 若 D1~D6 乾燥桶槽為 入豆暫停, 則狀態改為入豆優先入豆
  1778. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  1779. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, '優先入料中')
  1780. print('------- D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, ' 入料中 -------')
  1781. # 若 D1~D6 發酵桶槽為 入豆, 則桶槽數字小者 優先入豆
  1782. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  1783. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean')+1, '優先入料中')
  1784. print('------- D', D_UP_tanklist.index('D_InputtingBean')+1, ' 入料中 -------')
  1785. elif Dry_btn and DI1 == 'DI_OutputtingBean' \
  1786. and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1787. # 當達標準入料條件
  1788. if D1 == 'D_Waiting':
  1789. D1 = 'D_InputtingBean'
  1790. print('------- D1 狀態更新:入料中 -------')
  1791. elif D2 == 'D_Waiting':
  1792. D2 = 'D_InputtingBean'
  1793. print('------- D2 狀態更新:入料中 -------')
  1794. elif D3 == 'D_Waiting':
  1795. D3 = 'D_InputtingBean'
  1796. print('------- D3 狀態更新:入料中 -------')
  1797. elif D4 == 'D_Waiting':
  1798. D4 = 'D_InputtingBean'
  1799. print('------- D4 狀態更新:入料中 -------')
  1800. elif D5 == 'D_Waiting':
  1801. D5 = 'D_InputtingBean'
  1802. print('------- D5 狀態更新:入料中 -------')
  1803. elif D6 == 'D_Waiting':
  1804. D6 = 'D_InputtingBean'
  1805. print('------- D6 狀態更新:入料中 -------')
  1806. # ----- 乾燥桶槽 D1~D6 入料→入料暫停判斷 ------------------------------
  1807. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  1808. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1809. D_UP_tank_UltraSonic = []
  1810. for i in range(1, 7, 1):
  1811. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1812. UltraSonic = int(tank_UltraSonic.UltraSonic)
  1813. D_UP_tank_UltraSonic.append(UltraSonic)
  1814. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  1815. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  1816. if DI1 != 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  1817. if D1 == 'D_InputtingBean' and D_UP_tank_UltraSonic[0] < 110:
  1818. D1 = 'D_InputtingBean_Pause'
  1819. print('------- D1 狀態更新:入料暫停 -------')
  1820. else:
  1821. D1 = 'D_InputtingBean_Finish'
  1822. print('------- D1 狀態更新:入料完成 -------')
  1823. if D2 == 'D_InputtingBean' and D_UP_tank_UltraSonic[1] < 110:
  1824. D2 = 'D_InputtingBean_Pause'
  1825. print('------- D2 狀態更新:入料暫停 -------')
  1826. else:
  1827. D2 = 'D_InputtingBean_Finish'
  1828. print('------- D2 狀態更新:入料完成 -------')
  1829. if D3 == 'D_InputtingBean' and D_UP_tank_UltraSonic[2] < 110:
  1830. D3 = 'D_InputtingBean_Pause'
  1831. print('------- D3 狀態更新:入料暫停 -------')
  1832. else:
  1833. D3 = 'D_InputtingBean_Finish'
  1834. print('------- D3 狀態更新:入料完成 -------')
  1835. if D4 == 'D_InputtingBean' and D_UP_tank_UltraSonic[3] < 110:
  1836. D4 = 'D_InputtingBean_Pause'
  1837. print('------- D4 狀態更新:入料暫停 -------')
  1838. else:
  1839. D4 = 'D_InputtingBean_Finish'
  1840. print('------- D4 狀態更新:入料完成 -------')
  1841. if D5 == 'D_InputtingBean' and D_UP_tank_UltraSonic[4] < 110:
  1842. D5 = 'D_InputtingBean_Pause'
  1843. print('------- D5 狀態更新:入料暫停 -------')
  1844. else:
  1845. D5 = 'D_InputtingBean_Finish'
  1846. print('------- D5 狀態更新:入料完成 -------')
  1847. if D6 == 'D_InputtingBean' and D_UP_tank_UltraSonic[5] < 110:
  1848. D6 = 'D_InputtingBean_Pause'
  1849. print('------- D6 狀態更新:入料暫停 -------')
  1850. else:
  1851. D6 = 'D_InputtingBean_Finish'
  1852. print('------- D6 狀態更新:入料完成 -------')
  1853. # # ----- 乾燥桶槽 D1~D6 入料完成→乾燥判斷 ------------------------------
  1854. # Dry_InputtingBeanFinish_number = int(D_UP_tanklist.count('D_InputtingBean_Finish'))
  1855. # # 乾燥條件:當前桶槽入豆達指定高度, 則開始乾燥 (可以多桶乾燥)
  1856. # # !!! 乾燥槽 D_Drying 狀態應該請硬體判斷
  1857. # # !!! 若狀態為 D_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 D_Drying 乾燥
  1858. # if D1 == 'D_InputtingBean_Finish' or D1 == 'D_InputtingBean_Pause' and D_UP_tank_UltraSonic[0] >= 110:
  1859. # D1 = 'D_Drying'
  1860. # print('------- D1 狀態更新:乾燥中 -------')
  1861. # if D2 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[1] >= 110:
  1862. # D2 = 'D_Drying'
  1863. # print('------- D2 狀態更新:乾燥中 -------')
  1864. # if D3 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[2] >= 110:
  1865. # D3 = 'D_Drying'
  1866. # print('------- D3 狀態更新:乾燥中 -------')
  1867. # if D4 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[3] >= 110:
  1868. # D4 = 'D_Drying'
  1869. # print('------- D4 狀態更新:乾燥中 -------')
  1870. # if D5 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[4] >= 110:
  1871. # D5 = 'D_Drying'
  1872. # print('------- D5 狀態更新:乾燥中 -------')
  1873. # if D6 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[5] >= 110:
  1874. # D6 = 'D_Drying'
  1875. # print('------- D6 狀態更新:乾燥中 -------')
  1876. # ----- 乾燥桶槽 D1~D6 發酵→可出豆 判斷 ------------------------------
  1877. # !!! 發酵槽 D_OutputtingBean 狀態應該請硬體判斷
  1878. # !!! 若狀態為 D_Drying 且 達指定乾燥條件, 狀態改為 D_OutputtingBean 可出豆
  1879. # 可以多桶各自執行發酵排程
  1880. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1881. if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  1882. if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  1883. if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  1884. if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  1885. if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  1886. if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  1887. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  1888. # # ----- 乾燥桶槽 D1~D6 可出豆→出料儲豆槽 DO1 判斷 ------------------------------
  1889. Dry_OutputtingBean_number = int(D_UP_tanklist.count('D_OutputtingBean'))
  1890. # # !!! 若出料儲豆槽狀態為 DO_Waiting(空桶等待) 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 DO1 配合開始出豆
  1891. # if DO1 == 'DO_Waiting' and Dry_OutputtingBean_number >= 1:
  1892. # if D1 == 'D_OutputtingBean':
  1893. # DO1 = 'DO_InputtingBean'
  1894. # print('------- D1 狀態更新:出豆中 -------')
  1895. # print('------- DO1 狀態更新:入豆中 -------')
  1896. # elif D2 == 'D_OutputtingBean':
  1897. # DO1 = 'DO_InputtingBean'
  1898. # print('------- D2 狀態更新:出豆中 -------')
  1899. # print('------- DO1 狀態更新:入豆中 -------')
  1900. # elif D3 == 'D_OutputtingBean':
  1901. # DO1 = 'DO_InputtingBean'
  1902. # print('------- D3 狀態更新:出豆中 -------')
  1903. # print('------- DO1 狀態更新:入豆中 -------')
  1904. # elif D4 == 'D_OutputtingBean':
  1905. # DO1 = 'DO_InputtingBean'
  1906. # print('------- D4 狀態更新:出豆中 -------')
  1907. # print('------- DO1 狀態更新:入豆中 -------')
  1908. # elif D5 == 'D_OutputtingBean':
  1909. # DO1 = 'DO_InputtingBean'
  1910. # print('------- D5 狀態更新:出豆中 -------')
  1911. # print('------- DO1 狀態更新:入豆中 -------')
  1912. # elif D6 == 'D_OutputtingBean':
  1913. # DO1 = 'DO_InputtingBean'
  1914. # print('------- D6 狀態更新:出豆中 -------')
  1915. # print('------- DO1 狀態更新:入豆中 -------')
  1916. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  1917. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  1918. DI_UP_UltraSoniclist = []
  1919. for i in range(1, 3, 1):
  1920. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  1921. UltraSonic = int(input_UltraSonic.UltraSonic)
  1922. DI_UP_UltraSoniclist.append(UltraSonic)
  1923. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  1924. # !!! 乾燥入料儲豆槽 D_OutputtingBean 狀態應該請硬體判斷
  1925. # 入料儲豆槽等待中、且發酵槽出料儲豆槽可出豆時, 入料儲豆槽入豆
  1926. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  1927. DI1 = 'DI_InputtingBean'
  1928. print('------- DI1 狀態更新:入豆中 -------')
  1929. # 入料儲豆槽入豆時 且 (發酵儲豆槽有入料 或者 前方儲豆槽非可出豆), 則停止入豆
  1930. elif DI1 == 'DI_InputtingBean' and (DI_UP_UltraSoniclist[0] > 35) and (FO1 != 'FO_OutputtingBean') :
  1931. DI1 = 'DI_OutputtingBean'
  1932. print('------- DI1 狀態更新:可出豆 -------')
  1933. # 若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  1934. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] < 40) and FO1 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1935. DI1 = 'DI_InputtingBean'
  1936. print('------- DI1 狀態更新:入豆中 -------')
  1937. # if DI2 == 'DI_Waiting' and FO2 == 'FO_OutputtingBean':
  1938. # DI2 = 'DI_InputtingBean'
  1939. # print('------- DI2 狀態更新:入豆中 -------')
  1940. # elif DI2 == 'DI_InputtingBean' and ((DI_DOWN_UltraSoniclist[1] > 35) or (FO2 == 'FO_OutputtingBean')) :
  1941. # DI2 = 'DI_OutputtingBean'
  1942. # print('------- DI2 狀態更新:可出豆 -------')
  1943. # elif DI2 == 'DI_OutputtingBean' and (DI_DOWN_UltraSoniclist[1] < 40) and FO2 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  1944. # DI2 = 'DI_InputtingBean'
  1945. # print('------- DI2 狀態更新:入豆中 -------')
  1946. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  1947. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  1948. DO_UP_UltraSoniclist = []
  1949. for i in range(1, 3, 1):
  1950. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  1951. UltraSonic = int(output_UltraSonic.UltraSonic)
  1952. DO_UP_UltraSoniclist.append(UltraSonic)
  1953. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  1954. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  1955. # 參考 -- 乾燥桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  1956. # 出料儲豆槽入料 且滿時, 出料儲豆槽可出豆
  1957. if DO1 == ('DO_InputtingBean' and DO_UP_UltraSoniclist[0] > 35):
  1958. DO1 = 'DO_OutputtingBean'
  1959. # 出料儲豆槽入料 且未滿, 桶槽可出豆已空
  1960. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  1961. D_UP_UltraSoniclist = []
  1962. for i in range(1, 7, 1):
  1963. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  1964. UltraSonic = int(tank_UltraSonic.UltraSonic)
  1965. D_UP_UltraSoniclist.append(UltraSonic)
  1966. print('D_UP_UltraSoniclist: ', D_UP_UltraSoniclist)
  1967. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  1968. if DO1 == 'DO_InputtingBean' and Dry_OutputtingBean_number >= 1:
  1969. if D1 == 'D_OutputtingBean' and D_UP_UltraSoniclist[0] < 5:
  1970. D1 = 'D_Waiting'
  1971. DO1 = 'DO_OutputtingBean'
  1972. print('------- D1 狀態更新:空桶等待 -------')
  1973. print('------- DO1 狀態更新:可出豆 -------')
  1974. elif D2 == 'D_OutputtingBean' and D_UP_UltraSoniclist[1] < 5:
  1975. D2 = 'D_Waiting'
  1976. DO1 = 'DO_OutputtingBean'
  1977. print('------- D2 狀態更新:空桶等待 -------')
  1978. print('------- DO1 狀態更新:可出豆 -------')
  1979. elif D3 == 'D_OutputtingBean' and D_UP_UltraSoniclist[2] < 5:
  1980. D3 = 'D_Waiting'
  1981. DO1 = 'DO_OutputtingBean'
  1982. print('------- D3 狀態更新:空桶等待 -------')
  1983. print('------- DO1 狀態更新:可出豆 -------')
  1984. elif D4 == 'D_OutputtingBean' and D_UP_UltraSoniclist[3] < 5:
  1985. D4 = 'D_Waiting'
  1986. DO1 = 'DO_OutputtingBean'
  1987. print('------- D4 狀態更新:空桶等待 -------')
  1988. print('------- DO1 狀態更新:可出豆 -------')
  1989. elif D5 == 'D_OutputtingBean' and D_UP_UltraSoniclist[4] < 5:
  1990. D5 = 'D_Waiting'
  1991. DO1 = 'DO_OutputtingBean'
  1992. print('------- D5 狀態更新:空桶等待 -------')
  1993. print('------- DO1 狀態更新:可出豆 -------')
  1994. elif D6 == 'D_OutputtingBean' and D_UP_UltraSoniclist[5] < 5:
  1995. D6 = 'D_Waiting'
  1996. DO1 = 'DO_OutputtingBean'
  1997. print('------- D6 狀態更新:空桶等待 -------')
  1998. print('------- DO1 狀態更新:可出豆 -------')
  1999. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] < 5:
  2000. DO1 = 'DO_Waiting'
  2001. # # ----- 將狀態寫入資料庫 ------------------------------
  2002. # # 獲取文本框的值並賦值給user實體對象
  2003. # D_status = dry_container_status()
  2004. # D_status.Dry_Input_1 = DI1
  2005. # D_status.Dry_Input_2 = DI2
  2006. # D_status.Dry_Tank_1 = D1
  2007. # D_status.Dry_Tank_2 = D2
  2008. # D_status.Dry_Tank_3 = D3
  2009. # D_status.Dry_Tank_4 = D4
  2010. # D_status.Dry_Tank_5 = D5
  2011. # D_status.Dry_Tank_6 = D6
  2012. # D_status.Dry_Tank_7 = D7
  2013. # D_status.Dry_Tank_8 = D8
  2014. # D_status.Dry_Tank_9 = D9
  2015. # D_status.Dry_Tank_10 = D10
  2016. # D_status.Dry_Tank_11 = D11
  2017. # D_status.Dry_Tank_12 = D12
  2018. # D_status.Dry_Output_1 = DO1
  2019. # D_status.Dry_Output_2 = DO2
  2020. # #將數據保存進資料庫
  2021. # db.session.add(D_status)
  2022. # # 手動提交
  2023. # db.session.commit()
  2024. # # ----- 將狀態寫入資料庫 ------------------------------
  2025. return jsonify({"Dry_Input_1":DI1,
  2026. "Dry_Tank_1":D1,
  2027. "Dry_Tank_2":D2,
  2028. "Dry_Tank_3":D3,
  2029. "Dry_Tank_4":D4,
  2030. "Dry_Tank_5":D5,
  2031. "Dry_Tank_6":D6,
  2032. "Dry_Output_1":DO1
  2033. })
  2034. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以上為原備份
  2035. # 發酵槽自動化測試頁
  2036. @main.route('/ferment_auto', methods=['GET', 'POST'])
  2037. def ferment_auto():
  2038. # 獲取登入信息
  2039. if 'id' in session and 'uname' in session and 'status' in session:
  2040. username = session['uname']
  2041. status = session['status']
  2042. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2043. FI1 = ferment_status.Ferment_Input_1
  2044. FI2 = ferment_status.Ferment_Input_2
  2045. F1 = ferment_status.Ferment_Tank_1
  2046. F2 = ferment_status.Ferment_Tank_2
  2047. F3 = ferment_status.Ferment_Tank_3
  2048. F4 = ferment_status.Ferment_Tank_4
  2049. F5 = ferment_status.Ferment_Tank_5
  2050. F6 = ferment_status.Ferment_Tank_6
  2051. F7 = ferment_status.Ferment_Tank_7
  2052. F8 = ferment_status.Ferment_Tank_8
  2053. F9 = ferment_status.Ferment_Tank_9
  2054. F10 = ferment_status.Ferment_Tank_10
  2055. F11 = ferment_status.Ferment_Tank_11
  2056. F12 = ferment_status.Ferment_Tank_12
  2057. FO1 = ferment_status.Ferment_Output_1
  2058. FO2 = ferment_status.Ferment_Output_2
  2059. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2060. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  2061. return render_template('ferment_auto.html', title="[測試] 發酵自動化", **locals())
  2062. else:
  2063. return render_template('sign_in.html')
  2064. @main.route('/fermentDEMO_auto_status', methods=['GET', 'POST'])
  2065. def fermentDEMO_auto_status():
  2066. info = request.args.to_dict()
  2067. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  2068. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  2069. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  2070. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  2071. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  2072. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  2073. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  2074. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  2075. Ferment_btn = True
  2076. # 從資料庫資料表中取得最新狀態
  2077. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2078. FI1 = ferment_status.Ferment_Input_1 # FI1 = 'FI_OutputtingBean'
  2079. FI2 = ferment_status.Ferment_Input_2
  2080. F1 = ferment_status.Ferment_Tank_1
  2081. F2 = ferment_status.Ferment_Tank_2
  2082. F3 = ferment_status.Ferment_Tank_3
  2083. F4 = ferment_status.Ferment_Tank_4
  2084. F5 = ferment_status.Ferment_Tank_5
  2085. F6 = ferment_status.Ferment_Tank_6
  2086. F7 = ferment_status.Ferment_Tank_7
  2087. F8 = ferment_status.Ferment_Tank_8
  2088. F9 = ferment_status.Ferment_Tank_9
  2089. F10 = ferment_status.Ferment_Tank_10
  2090. F11 = ferment_status.Ferment_Tank_11
  2091. F12 = ferment_status.Ferment_Tank_12
  2092. FO1 = ferment_status.Ferment_Output_1
  2093. FO2 = ferment_status.Ferment_Output_2
  2094. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  2095. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  2096. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2097. Ferment_Input_bean_empty = 2
  2098. Ferment_Tank_bean_empty = 2
  2099. Ferment_Output_bean_empty = 2
  2100. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  2101. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  2102. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  2103. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  2104. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  2105. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  2106. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  2107. FI_UP_UltraSoniclist = []
  2108. for i in range(1, 3, 1):
  2109. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2110. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  2111. UltraSonic = float(input_UltraSonic.UltraSonic)
  2112. FI_UP_UltraSoniclist.append(UltraSonic)
  2113. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  2114. F_UP_UltraSoniclist = []
  2115. for i in range(1, 7, 1):
  2116. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2117. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  2118. F_UP_UltraSoniclist.append(UltraSonic)
  2119. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  2120. FO_UP_UltraSoniclist = []
  2121. for i in range(1, 3, 1):
  2122. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  2123. UltraSonic = float(output_UltraSonic.UltraSonic)
  2124. FO_UP_UltraSoniclist.append(UltraSonic)
  2125. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  2126. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  2127. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  2128. F_UP_tank_WaterLevel = []
  2129. for i in range(1, 7, 1):
  2130. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2131. WaterLevel = float(tank_WaterLevel.WaterLevel)
  2132. F_UP_tank_WaterLevel.append(WaterLevel)
  2133. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  2134. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  2135. # -- 取得發酵桶槽 F1~F6 pH -------------
  2136. F_UP_tank_PH = []
  2137. for i in range(1, 7, 1):
  2138. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2139. PH = float(tank_PH.PH)
  2140. F_UP_tank_PH.append(PH)
  2141. print('F_UP_tank_PH: ', F_UP_tank_PH)
  2142. # -- 取得發酵桶槽 F1~F6 pH -------------
  2143. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2144. F_UP_tank_SHT11_Temp = []
  2145. for i in range(1, 7, 1):
  2146. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2147. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2148. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  2149. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  2150. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2151. # ----- 發酵排程動作 start ------------------------------------------------------------------
  2152. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2153. def FInputtingBean_TO_FInputtingBeanFinish(tid): # 1108 [測試] 入豆後直接出豆
  2154. # [致動器] 蝴蝶閥 OFF
  2155. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2156. print('data: ', data)
  2157. # mqtt_f(data)
  2158. # [致動器] 真空吸料機 OFF
  2159. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2160. print('data: ', data)
  2161. # mqtt_f(data)
  2162. # [致動器] 馬達 0
  2163. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2164. print('data: ', data)
  2165. # mqtt_f(data)
  2166. # [致動器] 入料三通閥 ON排氣
  2167. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2168. print('data: ', data)
  2169. # mqtt_f(data)
  2170. # print('------- ', tid,' 狀態更新:入料完成 -------')
  2171. print('------- ', tid,' 狀態更新:可出豆 -------')
  2172. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2173. def FInputtingBean_AND_notfilled(tid):
  2174. # [致動器] 蝴蝶閥 OFF
  2175. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2176. print('data: ', data)
  2177. # mqtt_f(data)
  2178. # [致動器] 入料三通閥 OFF入豆
  2179. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2180. print('data: ', data)
  2181. # mqtt_f(data)
  2182. # [致動器] 真空吸料機 ON
  2183. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2184. print('data: ', data)
  2185. # mqtt_f(data)
  2186. timer = time.time()
  2187. while True:
  2188. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  2189. # [致動器] 入料真空吸料機 OFF
  2190. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2191. print('data: ', data)
  2192. # mqtt_f(data)
  2193. timer = time.time()
  2194. break
  2195. while True:
  2196. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  2197. break
  2198. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  2199. def FInputtingBean_TO_FInputtingBeanPause(tid):
  2200. # [致動器] 蝴蝶閥 OFF
  2201. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2202. print('data: ', data)
  2203. # mqtt_f(data)
  2204. # [致動器] 真空吸料機 OFF
  2205. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2206. print('data: ', data)
  2207. # mqtt_f(data)
  2208. # [致動器] 入料三通閥 OFF入豆
  2209. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2210. print('data: ', data)
  2211. # mqtt_f(data)
  2212. # [致動器] 馬達 0
  2213. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2214. print('data: ', data)
  2215. # mqtt_f(data)
  2216. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  2217. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  2218. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  2219. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  2220. # [致動器] 入料三通閥 OFF入豆
  2221. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2222. print('data: ', data)
  2223. # mqtt_f(data)
  2224. # [致動器] 馬達 5
  2225. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2226. print('data: ', data)
  2227. # mqtt_f(data)
  2228. print('------- ', tid, ' 狀態更新:入料中 -------')
  2229. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  2230. def FWaiting_TO_FInputtingBean(tid):
  2231. # [致動器] 蝴蝶閥 OFF
  2232. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2233. print('data: ', data)
  2234. # mqtt_f(data)
  2235. # [致動器] 入料三通閥 OFF入豆
  2236. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2237. print('data: ', data)
  2238. # mqtt_f(data)
  2239. # [致動器] 馬達 5
  2240. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2241. print('data: ', data)
  2242. # mqtt_f(data)
  2243. print('------- ', tid, ' 狀態更新:入料中 -------')
  2244. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2245. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  2246. print('------- ', tid,' 狀態更新:入水中 -------')
  2247. # # [致動器] 浮選三通閥 ON
  2248. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2249. # print('data: ', data)
  2250. # # # mqtt_f(data)
  2251. # if (F_UP_tank_WaterLevel[sn] == 0):
  2252. # # [致動器] 桶外進水電磁閥 ON
  2253. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  2254. # print('data: ', data)
  2255. # # mqtt_f(data)
  2256. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  2257. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  2258. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  2259. print('data: ', data)
  2260. # mqtt_f(data)
  2261. # elif FermentUp_InputtingWater_number == 1:
  2262. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2263. def FInputtingWater_TO_FFermenting(tid):
  2264. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  2265. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  2266. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2267. # print('data: ', data)
  2268. # # mqtt_f(data)
  2269. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2270. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2271. print('data: ', data)
  2272. # mqtt_f(data)
  2273. print('------- ', tid, ' 狀態更新:發酵中 -------')
  2274. # [致動器] 馬達 (指定轉速)
  2275. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  2276. print('data: ', data)
  2277. # mqtt_f(data)
  2278. # [致動器] 溫控開關 ON
  2279. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  2280. # print('data: ', data)
  2281. # # mqtt_f(data)
  2282. # [致動器] 設定溫度、持溫時間
  2283. # [致動器] 加熱器 1 ON
  2284. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  2285. # print('data: ', data)
  2286. # mqtt_f(data)
  2287. # [致動器] 加熱器 2 ON
  2288. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  2289. # print('data: ', data)
  2290. # mqtt_f(data)
  2291. # # [致動器] 雙核薄膜泵 水質檢測 ON
  2292. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  2293. # print('data: ', data)
  2294. # # mqtt_f(data)
  2295. # TODO 增加發酵條件等
  2296. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  2297. def FInputtingWater_AND_WaterLevel1(tid):
  2298. # # [致動器] 桶外進水電磁閥 OFF
  2299. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2300. # print('data: ', data)
  2301. # # mqtt_f(data)
  2302. pass
  2303. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  2304. def FInputtingWater_AND_tankwaterfilled(tid):
  2305. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2306. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2307. print('data: ', data)
  2308. # mqtt_f(data)
  2309. # else
  2310. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  2311. def FFermenting_TO_FOutputtingBean(tid):
  2312. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  2313. timer = time.time()
  2314. while True:
  2315. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  2316. # [致動器] 外桶浮選三通閥 OFF
  2317. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2318. print('data: ', data)
  2319. # mqtt_f(data)
  2320. # [致動器] 馬達 0
  2321. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2322. print('data: ', data)
  2323. # mqtt_f(data)
  2324. # [致動器] 設定溫度 0
  2325. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2326. # print('data: ', data)
  2327. # # mqtt_f(data)
  2328. # [致動器] 溫控開關 OFF
  2329. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2330. # print('data: ', data)
  2331. # # mqtt_f(data)
  2332. # [致動器] 加熱器 1 OFF
  2333. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2334. print('data: ', data)
  2335. # mqtt_f(data)
  2336. # [致動器] 加熱器 2 OFF
  2337. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2338. print('data: ', data)
  2339. # mqtt_f(data)
  2340. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  2341. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2342. # print('data: ', data)
  2343. # # mqtt_f(data)
  2344. # TODO 增加發酵條件等
  2345. break
  2346. # [致動器] 廢水排水閥 (桶內) ON
  2347. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2348. print('data: ', data)
  2349. # mqtt_f(data)
  2350. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2351. timer = time.time()
  2352. while True:
  2353. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2354. # [致動器] 廢水排水閥 (桶內) OFF
  2355. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2356. print('data: ', data)
  2357. # mqtt_f(data)
  2358. break
  2359. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2360. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2361. def FOutputtingBean_TO_FWaiting(tid):
  2362. # [致動器] F1 蝴蝶閥 ON
  2363. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  2364. print('data: ', data)
  2365. # mqtt_f(data)
  2366. # ----- 發酵排程動作 end ------------------------------------------------------------------
  2367. # [介面] 若啟用 發酵 狀態
  2368. if Ferment_btn:
  2369. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  2370. # 若 F1~F6 桶槽中有一個桶槽入豆中
  2371. if FermentUp_InputtingBean_number == 1:
  2372. # 若 F1 桶槽為入豆中
  2373. if F1 == 'F_InputtingBean':
  2374. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2375. FInputtingBean_TO_FInputtingBeanFinish("F1")
  2376. # F1 = 'F_InputtingBean_Finish'
  2377. F1 = 'F_OutputtingBean'
  2378. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2379. FInputtingBean_AND_notfilled("F1")
  2380. elif FI1 != 'FI_OutputtingBean':
  2381. FInputtingBean_TO_FInputtingBeanPause("F1")
  2382. F1 = 'F_InputtingBean_Pause'
  2383. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  2384. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  2385. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  2386. if F1 == 'F_InputtingBean_Pause':
  2387. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  2388. F1 = 'F_InputtingBean'
  2389. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  2390. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  2391. if F1 == 'F_Waiting':
  2392. FWaiting_TO_FInputtingBean("F1")
  2393. F1 = 'F_InputtingBean'
  2394. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  2395. elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2396. if F1 == 'F_InputtingBean_Finish':
  2397. F1 = 'F_InputtingWater'
  2398. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  2399. elif FermentUp_InputtingWater_number == 1:
  2400. if F1 == 'F_InputtingWater':
  2401. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2402. F1 = 'F_Fermenting'
  2403. FInputtingWater_TO_FFermenting("F1")
  2404. elif (F_UP_tank_WaterLevel[0] == 1):
  2405. FInputtingWater_AND_WaterLevel1("F1")
  2406. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2407. FInputtingWater_AND_tankwaterfilled("F1")
  2408. else:
  2409. if F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp:
  2410. FFermenting_TO_FOutputtingBean("F1")
  2411. F1 = 'F_OutputtingBean'
  2412. # 將可出豆桶槽賦值
  2413. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  2414. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  2415. # TODO 發酵次數計算、消毒次數、校正
  2416. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2417. if FOutputtingBean_Tank == 'F1':
  2418. FOutputtingBean_TO_FWaiting('F1')
  2419. FOutputtingBean_Tank = ''
  2420. F1 = 'F_Waiting'
  2421. print('------- F1 狀態更新:空桶等待 -------')
  2422. # 避免桶槽可出豆時未賦值
  2423. if FOutputtingBean_Tank == '':
  2424. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  2425. # 若桶槽 F1~F6 為清洗中
  2426. if F1 == 'F_Cleaning':
  2427. # FCleaning("F1")
  2428. F1 = 'F_Waiting'
  2429. print('------- F1 狀態更新:空桶等待 -------')
  2430. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  2431. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  2432. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  2433. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  2434. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  2435. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  2436. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  2437. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  2438. else:
  2439. # [介面] 若未啟用 發酵 狀態
  2440. print('未啟用發酵流程')
  2441. # ----- 將狀態寫入資料庫 ------------------------------
  2442. # 獲取文本框的值並賦值給user實體對象
  2443. F_status = ferment_container_status()
  2444. F_status.Ferment_Input_1 = FI1
  2445. F_status.Ferment_Input_2 = FI2
  2446. F_status.Ferment_Tank_1 = F1
  2447. F_status.Ferment_Tank_2 = F2
  2448. F_status.Ferment_Tank_3 = F3
  2449. F_status.Ferment_Tank_4 = F4
  2450. F_status.Ferment_Tank_5 = F5
  2451. F_status.Ferment_Tank_6 = F6
  2452. F_status.Ferment_Tank_7 = F7
  2453. F_status.Ferment_Tank_8 = F8
  2454. F_status.Ferment_Tank_9 = F9
  2455. F_status.Ferment_Tank_10 = F10
  2456. F_status.Ferment_Tank_11 = F11
  2457. F_status.Ferment_Tank_12 = F12
  2458. F_status.Ferment_Output_1 = FO1
  2459. F_status.Ferment_Output_2 = FO2
  2460. #將數據保存進資料庫
  2461. db.session.add(F_status)
  2462. # 手動提交
  2463. db.session.commit()
  2464. # ----- 將狀態寫入資料庫 ------------------------------
  2465. return jsonify({"Ferment_Tank_1":F1,
  2466. "Ferment_Tank_2":F2
  2467. })
  2468. @main.route('/ferment_auto_status', methods=['GET', 'POST'])
  2469. def ferment_auto_test():
  2470. info = request.args.to_dict()
  2471. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2472. Ferment_Input_bean_empty = 2
  2473. Ferment_Tank_bean_empty = 2
  2474. Ferment_Output_bean_empty = 2
  2475. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  2476. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  2477. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  2478. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  2479. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  2480. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  2481. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  2482. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  2483. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  2484. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  2485. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  2486. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  2487. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  2488. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  2489. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  2490. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  2491. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  2492. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  2493. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  2494. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  2495. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  2496. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  2497. Ferment_cb_vacuum = info['Ferment_cb_vacuum'] # 'true' 'false'
  2498. Ferment_cb_vacuum_time = float(info['Ferment_cb_vacuum_time'])
  2499. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  2500. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  2501. # 從資料庫資料表中取得最新狀態
  2502. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2503. FI1 = ferment_status.Ferment_Input_1
  2504. FI2 = ferment_status.Ferment_Input_2
  2505. F1 = ferment_status.Ferment_Tank_1
  2506. F2 = ferment_status.Ferment_Tank_2
  2507. F3 = ferment_status.Ferment_Tank_3
  2508. F4 = ferment_status.Ferment_Tank_4
  2509. F5 = ferment_status.Ferment_Tank_5
  2510. F6 = ferment_status.Ferment_Tank_6
  2511. F7 = ferment_status.Ferment_Tank_7
  2512. F8 = ferment_status.Ferment_Tank_8
  2513. F9 = ferment_status.Ferment_Tank_9
  2514. F10 = ferment_status.Ferment_Tank_10
  2515. F11 = ferment_status.Ferment_Tank_11
  2516. F12 = ferment_status.Ferment_Tank_12
  2517. FO1 = ferment_status.Ferment_Output_1
  2518. FO2 = ferment_status.Ferment_Output_2
  2519. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2520. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  2521. PO2 = clean_status.Peel_Output_2
  2522. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  2523. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  2524. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  2525. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  2526. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  2527. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  2528. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  2529. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  2530. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  2531. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  2532. FI_UP_UltraSoniclist = []
  2533. for i in range(1, 3, 1):
  2534. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2535. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  2536. UltraSonic = float(input_UltraSonic.UltraSonic)
  2537. FI_UP_UltraSoniclist.append(UltraSonic)
  2538. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  2539. F_UP_UltraSoniclist = []
  2540. for i in range(1, 7, 1):
  2541. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2542. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  2543. F_UP_UltraSoniclist.append(UltraSonic)
  2544. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  2545. FO_UP_UltraSoniclist = []
  2546. for i in range(1, 3, 1):
  2547. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  2548. UltraSonic = float(output_UltraSonic.UltraSonic)
  2549. FO_UP_UltraSoniclist.append(UltraSonic)
  2550. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  2551. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  2552. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  2553. F_UP_tank_WaterLevel = []
  2554. for i in range(1, 7, 1):
  2555. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2556. WaterLevel = float(tank_WaterLevel.WaterLevel)
  2557. F_UP_tank_WaterLevel.append(WaterLevel)
  2558. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  2559. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  2560. # -- 取得發酵桶槽 F1~F6 pH -------------
  2561. F_UP_tank_PH = []
  2562. for i in range(1, 7, 1):
  2563. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2564. PH = float(tank_PH.PH)
  2565. F_UP_tank_PH.append(PH)
  2566. print('F_UP_tank_PH: ', F_UP_tank_PH)
  2567. # -- 取得發酵桶槽 F1~F6 pH -------------
  2568. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2569. F_UP_tank_SHT11_Temp = []
  2570. for i in range(1, 7, 1):
  2571. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  2572. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2573. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  2574. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  2575. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  2576. # ----- 發酵排程動作 start ------------------------------------------------------------------
  2577. # FI1 == 'FI_InputtingBean' AND if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  2578. def FIInputtingBean_filled(tid):
  2579. # [致動器] 入料真空吸料機 OFF
  2580. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  2581. print('data: ', data)
  2582. # mqtt_f(data)
  2583. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2584. # FI1 == 'FI_InputtingBean' AND elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  2585. def FIInputtingBean_AND_notfilled(tid):
  2586. # [致動器] 入料真空吸料機 ON
  2587. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "on" }
  2588. print('data: ', data)
  2589. # mqtt_f(data)
  2590. # 暫停 (指定吸料時間) 秒
  2591. time.sleep(Ferment_Input_vacuumON_time)
  2592. # [致動器] 入料真空吸料機 OFF
  2593. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  2594. print('data: ', data)
  2595. # mqtt_f(data)
  2596. # 暫停 (指定放料時間) 秒
  2597. time.sleep(Ferment_Input_vacuumOFF_time)
  2598. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  2599. def FInputtingBean_TO_FInputtingBeanFinish(tid):
  2600. # [致動器] 真空吸料機 OFF
  2601. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2602. print('data: ', data)
  2603. # mqtt_f(data)
  2604. # [致動器] 馬達 0
  2605. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2606. print('data: ', data)
  2607. # mqtt_f(data)
  2608. # [致動器] 入料三通閥 ON排氣
  2609. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2610. print('data: ', data)
  2611. # mqtt_f(data)
  2612. print('------- ', tid,' 狀態更新:入料完成 -------')
  2613. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  2614. def FInputtingBean_AND_notfilled(tid):
  2615. # [致動器] 入料三通閥 OFF入豆
  2616. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2617. print('data: ', data)
  2618. # mqtt_f(data)
  2619. # [致動器] 真空吸料機 ON
  2620. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2621. print('data: ', data)
  2622. # mqtt_f(data)
  2623. # 暫停 (指定吸料時間) 秒
  2624. time.sleep(Ferment_Tank_vacuumON_time)
  2625. # [致動器] 入料真空吸料機 OFF
  2626. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2627. print('data: ', data)
  2628. # mqtt_f(data)
  2629. # 暫停 (指定吸料時間) 秒
  2630. time.sleep(Ferment_Tank_vacuumOFF_time)
  2631. # # [致動器] 真空吸料機 ON
  2632. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2633. # print('data: ', data)
  2634. # # mqtt_f(data)
  2635. # timer = time.time()
  2636. # while True:
  2637. # if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  2638. # # [致動器] 入料真空吸料機 OFF
  2639. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2640. # print('data: ', data)
  2641. # # mqtt_f(data)
  2642. # timer = time.time()
  2643. # break
  2644. # while True:
  2645. # if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  2646. # break
  2647. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  2648. def FInputtingBean_TO_FInputtingBeanPause(tid):
  2649. # [致動器] 真空吸料機 OFF
  2650. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2651. print('data: ', data)
  2652. # mqtt_f(data)
  2653. # [致動器] 入料三通閥 OFF入豆
  2654. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2655. print('data: ', data)
  2656. # mqtt_f(data)
  2657. # [致動器] 馬達 0
  2658. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2659. print('data: ', data)
  2660. # mqtt_f(data)
  2661. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  2662. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  2663. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  2664. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  2665. # [致動器] 入料三通閥 OFF入豆
  2666. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2667. print('data: ', data)
  2668. # mqtt_f(data)
  2669. # [致動器] 馬達 5
  2670. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2671. print('data: ', data)
  2672. # mqtt_f(data)
  2673. print('------- ', tid, ' 狀態更新:入料中 -------')
  2674. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  2675. def FWaiting_TO_FInputtingBean(tid):
  2676. # [致動器] 入料三通閥 OFF入豆
  2677. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2678. print('data: ', data)
  2679. # mqtt_f(data)
  2680. # [致動器] 馬達 5
  2681. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2682. print('data: ', data)
  2683. # mqtt_f(data)
  2684. print('------- ', tid, ' 狀態更新:入料中 -------')
  2685. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  2686. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  2687. print('------- ', tid,' 狀態更新:入水中 -------')
  2688. # [致動器] 浮選三通閥 ON
  2689. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2690. print('data: ', data)
  2691. # mqtt_f(data)
  2692. if (F_UP_tank_WaterLevel[sn] == 0):
  2693. # [致動器] 桶外進水電磁閥 ON
  2694. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  2695. print('data: ', data)
  2696. # mqtt_f(data)
  2697. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  2698. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  2699. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  2700. print('data: ', data)
  2701. # mqtt_f(data)
  2702. # elif FermentUp_InputtingWater_number == 1:
  2703. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  2704. def FInputtingWater_TO_FFermenting(tid):
  2705. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  2706. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  2707. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2708. print('data: ', data)
  2709. # mqtt_f(data)
  2710. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2711. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2712. print('data: ', data)
  2713. # mqtt_f(data)
  2714. print('------- ', tid, ' 狀態更新:發酵中 -------')
  2715. # 若勾選 發酵時桶內抽真空?
  2716. if Ferment_cb_vacuum == 'true':
  2717. # [致動器] 入料三通閥 ON排氣
  2718. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2719. print('data: ', data)
  2720. # mqtt_f(data)
  2721. # [致動器] 外桶浮選三通閥 OFF
  2722. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2723. print('data: ', data)
  2724. # mqtt_f(data)
  2725. # [致動器] 真空吸料機 ON
  2726. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2727. print('data: ', data)
  2728. # mqtt_f(data)
  2729. # 暫停 (桶內抽氣時間) 秒
  2730. print(tid, '真空發酵, 桶槽抽氣 ' , Ferment_cb_vacuum_time, ' 秒')
  2731. time.sleep(Ferment_cb_vacuum_time)
  2732. # timer = time.time()
  2733. # while True:
  2734. # if (time.time() - timer) > Ferment_cb_vacuum_time:
  2735. # # [致動器] 入料真空吸料機 OFF
  2736. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2737. # print('data: ', data)
  2738. # # mqtt_f(data)
  2739. # break
  2740. # [致動器] 馬達 (指定轉速)
  2741. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  2742. print('data: ', data)
  2743. # mqtt_f(data)
  2744. # [致動器] 溫控開關 ON
  2745. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  2746. # print('data: ', data)
  2747. # # mqtt_f(data)
  2748. # [致動器] 設定溫度、持溫時間
  2749. # [致動器] 加熱器 1 ON
  2750. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  2751. print('data: ', data)
  2752. # mqtt_f(data)
  2753. # [致動器] 加熱器 2 ON
  2754. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  2755. print('data: ', data)
  2756. # mqtt_f(data)
  2757. # [致動器] 雙核薄膜泵 水質檢測 ON
  2758. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  2759. print('data: ', data)
  2760. # mqtt_f(data)
  2761. # TODO 增加發酵條件等
  2762. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  2763. def FInputtingWater_AND_WaterLevel1(tid):
  2764. # [致動器] 桶外進水電磁閥 OFF
  2765. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  2766. print('data: ', data)
  2767. # mqtt_f(data)
  2768. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  2769. def FInputtingWater_AND_tankwaterfilled(tid):
  2770. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  2771. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  2772. print('data: ', data)
  2773. # mqtt_f(data)
  2774. # else
  2775. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  2776. def FFermenting_TO_FOutputtingBean(tid):
  2777. # 暫停 (桶內抽氣時間) 秒
  2778. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  2779. time.sleep(Ferment_Tank_fermenting_time)
  2780. # [致動器] 外桶浮選三通閥 OFF
  2781. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2782. print('data: ', data)
  2783. # mqtt_f(data)
  2784. # [致動器] 馬達 0
  2785. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2786. print('data: ', data)
  2787. # mqtt_f(data)
  2788. # [致動器] 設定溫度 0
  2789. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2790. print('data: ', data)
  2791. # mqtt_f(data)
  2792. # [致動器] 溫控開關 OFF
  2793. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2794. # print('data: ', data)
  2795. # # mqtt_f(data)
  2796. # [致動器] 加熱器 1 OFF
  2797. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2798. print('data: ', data)
  2799. # mqtt_f(data)
  2800. # [致動器] 加熱器 2 OFF
  2801. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2802. print('data: ', data)
  2803. # mqtt_f(data)
  2804. # [致動器] 雙核薄膜泵 水質檢測 OFF
  2805. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2806. print('data: ', data)
  2807. # mqtt_f(data)
  2808. # timer = time.time()
  2809. # while True:
  2810. # if (time.time() - timer) > Ferment_Tank_fermenting_time :
  2811. # # [致動器] 外桶浮選三通閥 OFF
  2812. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2813. # print('data: ', data)
  2814. # # mqtt_f(data)
  2815. # # [致動器] 馬達 0
  2816. # data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2817. # print('data: ', data)
  2818. # # mqtt_f(data)
  2819. # # [致動器] 設定溫度 0
  2820. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2821. # print('data: ', data)
  2822. # # mqtt_f(data)
  2823. # # [致動器] 溫控開關 OFF
  2824. # # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2825. # # print('data: ', data)
  2826. # # # mqtt_f(data)
  2827. # # [致動器] 加熱器 1 OFF
  2828. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2829. # print('data: ', data)
  2830. # # mqtt_f(data)
  2831. # # [致動器] 加熱器 2 OFF
  2832. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2833. # print('data: ', data)
  2834. # # mqtt_f(data)
  2835. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  2836. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  2837. # print('data: ', data)
  2838. # # mqtt_f(data)
  2839. # # TODO 增加發酵條件等
  2840. # break
  2841. # [致動器] 廢水排水閥 (桶內) ON
  2842. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2843. print('data: ', data)
  2844. # mqtt_f(data)
  2845. # 暫停 (桶內抽氣時間) 秒
  2846. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2847. time.sleep(Ferment_Tank_WaterOut_time)
  2848. # [致動器] 廢水排水閥 (桶內) OFF
  2849. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2850. print('data: ', data)
  2851. # mqtt_f(data)
  2852. # timer = time.time()
  2853. # while True:
  2854. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2855. # # [致動器] 廢水排水閥 (桶內) OFF
  2856. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2857. # print('data: ', data)
  2858. # # mqtt_f(data)
  2859. # break
  2860. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2861. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  2862. def FOutputtingBean_TO_FWaiting(tid):
  2863. # [致動器] F1 蝴蝶閥 ON
  2864. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  2865. print('data: ', data)
  2866. # mqtt_f(data)
  2867. # F_Cleaning
  2868. def FCleaning(tid):
  2869. # [致動器] 浮選三通閥 OFF
  2870. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  2871. print('data: ', data)
  2872. # mqtt_f(data)
  2873. # [致動器] 逆洗雙核薄膜泵電磁閥 ON
  2874. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "on" }
  2875. print('data: ', data)
  2876. # mqtt_f(data)
  2877. # [致動器] 馬達 10
  2878. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  2879. print('data: ', data)
  2880. # mqtt_f(data)
  2881. # [致動器] 消毒電磁閥 ON
  2882. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  2883. print('data: ', data)
  2884. # mqtt_f(data)
  2885. # [致動器] 消毒抽水 Pump ON TODO
  2886. # 暫停 (消毒時間) 秒
  2887. print(tid, ' 桶內消毒 ', Ferment_Tank_Disinfect_time, ' 秒')
  2888. time.sleep(Ferment_Tank_Disinfect_time)
  2889. # [致動器] 消毒電磁閥 OFF
  2890. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2891. print('data: ', data)
  2892. # mqtt_f(data)
  2893. # timer = time.time()
  2894. # while True:
  2895. # if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  2896. # # [致動器] 消毒電磁閥 OFF
  2897. # data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2898. # print('data: ', data)
  2899. # # mqtt_f(data)
  2900. # break
  2901. # [致動器] 消毒抽水 Pump OFF TODO
  2902. # [致動器] 馬達 0
  2903. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2904. print('data: ', data)
  2905. # mqtt_f(data)
  2906. # [致動器] 浮選三通閥 ON
  2907. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  2908. print('data: ', data)
  2909. # mqtt_f(data)
  2910. # [致動器] 逆洗雙核薄膜泵電磁閥 OFF
  2911. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "off" }
  2912. print('data: ', data)
  2913. # mqtt_f(data)
  2914. # [致動器] 消毒電磁閥 OFF
  2915. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2916. print('data: ', data)
  2917. # mqtt_f(data)
  2918. # [致動器] 廢水排水閥 (桶內) ON
  2919. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2920. print('data: ', data)
  2921. # mqtt_f(data)
  2922. print(tid, ' 桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  2923. time.sleep(Ferment_Tank_WaterOut_time)
  2924. # [致動器] 廢水排水閥 (桶內) OFF
  2925. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2926. print('data: ', data)
  2927. # mqtt_f(data)
  2928. # timer = time.time()
  2929. # while True:
  2930. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  2931. # # [致動器] 廢水排水閥 (桶內) OFF
  2932. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2933. # print('data: ', data)
  2934. # # mqtt_f(data)
  2935. # break
  2936. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  2937. # elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '': AND elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  2938. def FOInputtingBean_filled(tid):
  2939. # [致動器] 出料真空吸料機 ON
  2940. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  2941. print('data: ', data)
  2942. # mqtt_f(data)
  2943. # 暫停 (指定吸料時間) 秒
  2944. time.sleep(Ferment_Output_vacuumON_time)
  2945. # [致動器] 出料真空吸料機 OFF
  2946. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  2947. print('data: ', data)
  2948. # mqtt_f(data)
  2949. # 暫停 (指定放料時間) 秒
  2950. time.sleep(Ferment_Output_vacuumOFF_time)
  2951. # # [致動器] 出料真空吸料機 ON
  2952. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  2953. # print('data: ', data)
  2954. # # mqtt_f(data)
  2955. # timer = time.time()
  2956. # while True:
  2957. # if (time.time() - timer) > Ferment_Output_vacuumON_time:
  2958. # # [致動器] 出料真空吸料機 OFF
  2959. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  2960. # print('data: ', data)
  2961. # # mqtt_f(data)
  2962. # timer = time.time()
  2963. # break
  2964. # while True:
  2965. # if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  2966. # break
  2967. # ----- 發酵排程動作 end ------------------------------------------------------------------
  2968. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  2969. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  2970. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  2971. FI1 = 'FI_InputtingBean'
  2972. print('------- FI1 狀態更新:入豆中 -------')
  2973. # 入料儲豆槽入豆時
  2974. elif FI1 == 'FI_InputtingBean':
  2975. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  2976. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  2977. FIInputtingBean_filled("FI1")
  2978. FI1 = 'FI_OutputtingBean'
  2979. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  2980. elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  2981. FI1_thread = threading.Thread(target=FIInputtingBean_AND_notfilled, args=["FI1"])
  2982. FI1_thread.start()
  2983. # 桶槽內大於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為可出豆
  2984. elif (FI_UP_UltraSoniclist[0] > Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  2985. FI1 = 'FI_OutputtingBean'
  2986. print('------- FI1 狀態更新:可出豆 -------')
  2987. # 桶槽內小於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為空桶等待
  2988. elif (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  2989. FI1 = 'FI_Waiting'
  2990. print('------- FI1 狀態更新:空桶等待 -------')
  2991. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  2992. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  2993. FI1 = 'FI_Waiting'
  2994. print('------- FI1 狀態更新:空桶等待 -------')
  2995. # [介面] 若啟用 發酵 狀態
  2996. if Ferment_btn:
  2997. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  2998. # 若 F1~F6 桶槽中有一個桶槽入豆中
  2999. if FermentUp_InputtingBean_number == 1:
  3000. # 若 F1 桶槽為入豆中
  3001. if F1 == 'F_InputtingBean':
  3002. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  3003. FInputtingBean_TO_FInputtingBeanFinish("F1")
  3004. F1 = 'F_InputtingBean_Finish'
  3005. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  3006. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  3007. F1_thread.start()
  3008. elif FI1 != 'FI_OutputtingBean':
  3009. FInputtingBean_TO_FInputtingBeanPause("F1")
  3010. F1 = 'F_InputtingBean_Pause'
  3011. elif F2 == 'F_InputtingBean':
  3012. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  3013. FInputtingBean_TO_FInputtingBeanFinish("F2")
  3014. F2 = 'F_InputtingBean_Finish'
  3015. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  3016. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  3017. F2_thread.start()
  3018. elif FI1 != 'FI_OutputtingBean':
  3019. FInputtingBean_TO_FInputtingBeanPause("F2")
  3020. F2 = 'F_InputtingBean_Pause'
  3021. elif F3 == 'F_InputtingBean':
  3022. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  3023. FInputtingBean_TO_FInputtingBeanFinish("F3")
  3024. F3 = 'F_InputtingBean_Finish'
  3025. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  3026. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  3027. F3_thread.start()
  3028. elif FI1 != 'FI_OutputtingBean':
  3029. FInputtingBean_TO_FInputtingBeanPause("F3")
  3030. F3 = 'F_InputtingBean_Pause'
  3031. elif F4 == 'F_InputtingBean':
  3032. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  3033. FInputtingBean_TO_FInputtingBeanFinish("F4")
  3034. F4 = 'F_InputtingBean_Finish'
  3035. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  3036. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  3037. F4_thread.start()
  3038. elif FI1 != 'FI_OutputtingBean':
  3039. FInputtingBean_TO_FInputtingBeanPause("F4")
  3040. F4 = 'F_InputtingBean_Pause'
  3041. elif F5 == 'F_InputtingBean':
  3042. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  3043. FInputtingBean_TO_FInputtingBeanFinish("F5")
  3044. F5 = 'F_InputtingBean_Finish'
  3045. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  3046. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  3047. F5_thread.start()
  3048. elif FI1 != 'FI_OutputtingBean':
  3049. FInputtingBean_TO_FInputtingBeanPause("F5")
  3050. F5 = 'F_InputtingBean_Pause'
  3051. elif F6 == 'F_InputtingBean':
  3052. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  3053. FInputtingBean_TO_FInputtingBeanFinish("F6")
  3054. F6 = 'F_InputtingBean_Finish'
  3055. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  3056. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  3057. F6_thread.start()
  3058. elif FI1 != 'FI_OutputtingBean':
  3059. FInputtingBean_TO_FInputtingBeanPause("F6")
  3060. F6 = 'F_InputtingBean_Pause'
  3061. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  3062. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  3063. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  3064. if F1 == 'F_InputtingBean_Pause':
  3065. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  3066. F1 = 'F_InputtingBean'
  3067. elif F2 == 'F_InputtingBean_Pause':
  3068. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  3069. F2 = 'F_InputtingBean'
  3070. elif F3 == 'F_InputtingBean_Pause':
  3071. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  3072. F3 = 'F_InputtingBean'
  3073. elif F4 == 'F_InputtingBean_Pause':
  3074. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  3075. F4 = 'F_InputtingBean'
  3076. elif F5 == 'F_InputtingBean_Pause':
  3077. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  3078. F5 = 'F_InputtingBean'
  3079. elif F6 == 'F_InputtingBean_Pause':
  3080. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  3081. F6 = 'F_InputtingBean'
  3082. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料中, 則桶號小者優先入料
  3083. elif FermentUp_InputtingBean_number >= 2:
  3084. if F1 == 'F_InputtingBean':
  3085. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  3086. FInputtingBean_TO_FInputtingBeanFinish("F1")
  3087. F1 = 'F_InputtingBean_Finish'
  3088. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  3089. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  3090. F1_thread.start()
  3091. elif FI1 != 'FI_OutputtingBean':
  3092. FInputtingBean_TO_FInputtingBeanPause("F1")
  3093. F1 = 'F_InputtingBean_Pause'
  3094. elif F2 == 'F_InputtingBean':
  3095. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  3096. FInputtingBean_TO_FInputtingBeanFinish("F2")
  3097. F2 = 'F_InputtingBean_Finish'
  3098. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  3099. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  3100. F2_thread.start()
  3101. elif FI1 != 'FI_OutputtingBean':
  3102. FInputtingBean_TO_FInputtingBeanPause("F2")
  3103. F2 = 'F_InputtingBean_Pause'
  3104. elif F3 == 'F_InputtingBean':
  3105. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  3106. FInputtingBean_TO_FInputtingBeanFinish("F3")
  3107. F3 = 'F_InputtingBean_Finish'
  3108. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  3109. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  3110. F3_thread.start()
  3111. elif FI1 != 'FI_OutputtingBean':
  3112. FInputtingBean_TO_FInputtingBeanPause("F3")
  3113. F3 = 'F_InputtingBean_Pause'
  3114. elif F4 == 'F_InputtingBean':
  3115. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  3116. FInputtingBean_TO_FInputtingBeanFinish("F4")
  3117. F4 = 'F_InputtingBean_Finish'
  3118. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  3119. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  3120. F4_thread.start()
  3121. elif FI1 != 'FI_OutputtingBean':
  3122. FInputtingBean_TO_FInputtingBeanPause("F4")
  3123. F4 = 'F_InputtingBean_Pause'
  3124. elif F5 == 'F_InputtingBean':
  3125. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  3126. FInputtingBean_TO_FInputtingBeanFinish("F5")
  3127. F5 = 'F_InputtingBean_Finish'
  3128. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  3129. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  3130. F5_thread.start()
  3131. elif FI1 != 'FI_OutputtingBean':
  3132. FInputtingBean_TO_FInputtingBeanPause("F5")
  3133. F5 = 'F_InputtingBean_Pause'
  3134. elif F6 == 'F_InputtingBean':
  3135. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  3136. FInputtingBean_TO_FInputtingBeanFinish("F6")
  3137. F6 = 'F_InputtingBean_Finish'
  3138. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  3139. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  3140. F6_thread.start()
  3141. elif FI1 != 'FI_OutputtingBean':
  3142. FInputtingBean_TO_FInputtingBeanPause("F6")
  3143. F6 = 'F_InputtingBean_Pause'
  3144. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料暫停中, 則桶號小者優先入料
  3145. elif FermentUp_InputtingBeanPause_number >= 2 and FI1 == 'FI_OutputtingBean':
  3146. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  3147. if F1 == 'F_InputtingBean_Pause':
  3148. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  3149. F1 = 'F_InputtingBean'
  3150. elif F2 == 'F_InputtingBean_Pause':
  3151. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  3152. F2 = 'F_InputtingBean'
  3153. elif F3 == 'F_InputtingBean_Pause':
  3154. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  3155. F3 = 'F_InputtingBean'
  3156. elif F4 == 'F_InputtingBean_Pause':
  3157. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  3158. F4 = 'F_InputtingBean'
  3159. elif F5 == 'F_InputtingBean_Pause':
  3160. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  3161. F5 = 'F_InputtingBean'
  3162. elif F6 == 'F_InputtingBean_Pause':
  3163. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  3164. F6 = 'F_InputtingBean'
  3165. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  3166. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  3167. if F1 == 'F_Waiting':
  3168. FWaiting_TO_FInputtingBean("F1")
  3169. F1 = 'F_InputtingBean'
  3170. elif F2 == 'F_Waiting':
  3171. FWaiting_TO_FInputtingBean("F2")
  3172. F2 = 'F_InputtingBean'
  3173. elif F3 == 'F_Waiting':
  3174. FWaiting_TO_FInputtingBean("F3")
  3175. F3 = 'F_InputtingBean'
  3176. elif F4 == 'F_Waiting':
  3177. FWaiting_TO_FInputtingBean("F4")
  3178. F4 = 'F_InputtingBean'
  3179. elif F5 == 'F_Waiting':
  3180. FWaiting_TO_FInputtingBean("F5")
  3181. F5 = 'F_InputtingBean'
  3182. elif F6 == 'F_Waiting':
  3183. FWaiting_TO_FInputtingBean("F6")
  3184. F6 = 'F_InputtingBean'
  3185. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  3186. if FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  3187. if F1 == 'F_InputtingBean_Finish':
  3188. F1 = 'F_InputtingWater'
  3189. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  3190. elif F2 == 'F_InputtingBean_Finish':
  3191. F2 = 'F_InputtingWater'
  3192. FInputtingBeanFinish_TO_FInputtingWater_UP("F2", 1)
  3193. elif F3 == 'F_InputtingBean_Finish':
  3194. F3 = 'F_InputtingWater'
  3195. FInputtingBeanFinish_TO_FInputtingWater_UP("F3", 2)
  3196. elif F4 == 'F_InputtingBean_Finish':
  3197. F4 = 'F_InputtingWater'
  3198. FInputtingBeanFinish_TO_FInputtingWater_UP("F4", 3)
  3199. elif F5 == 'F_InputtingBean_Finish':
  3200. F5 = 'F_InputtingWater'
  3201. FInputtingBeanFinish_TO_FInputtingWater_UP("F5", 4)
  3202. elif F6 == 'F_InputtingBean_Finish':
  3203. F6 = 'F_InputtingWater'
  3204. FInputtingBeanFinish_TO_FInputtingWater_UP("F6", 5)
  3205. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  3206. if FermentUp_InputtingWater_number == 1:
  3207. if F1 == 'F_InputtingWater':
  3208. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3209. F1 = 'F_Fermenting'
  3210. F1_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F1"])
  3211. F1_thread.start()
  3212. elif (F_UP_tank_WaterLevel[0] == 1):
  3213. FInputtingWater_AND_WaterLevel1("F1")
  3214. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3215. FInputtingWater_AND_tankwaterfilled("F1")
  3216. elif F2 == 'F_InputtingWater':
  3217. if (F_UP_tank_WaterLevel[1] == 1) and (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  3218. F2 = 'F_Fermenting'
  3219. F2_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F2"])
  3220. F2_thread.start()
  3221. elif (F_UP_tank_WaterLevel[1] == 1):
  3222. FInputtingWater_AND_WaterLevel1("F2")
  3223. elif (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  3224. FInputtingWater_AND_tankwaterfilled("F2")
  3225. elif F3 == 'F_InputtingWater':
  3226. if (F_UP_tank_WaterLevel[2] == 1) and (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  3227. F3 = 'F_Fermenting'
  3228. F3_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F3"])
  3229. F3_thread.start()
  3230. elif (F_UP_tank_WaterLevel[2] == 1):
  3231. FInputtingWater_AND_WaterLevel1("F3")
  3232. elif (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  3233. FInputtingWater_AND_tankwaterfilled("F3")
  3234. elif F4 == 'F_InputtingWater':
  3235. if (F_UP_tank_WaterLevel[3] == 1) and (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  3236. F4 = 'F_Fermenting'
  3237. F4_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F4"])
  3238. F4_thread.start()
  3239. elif (F_UP_tank_WaterLevel[3] == 1):
  3240. FInputtingWater_AND_WaterLevel1("F4")
  3241. elif (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  3242. FInputtingWater_AND_tankwaterfilled("F4")
  3243. elif F5 == 'F_InputtingWater':
  3244. if (F_UP_tank_WaterLevel[4] == 1) and (F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height):
  3245. F5 = 'F_Fermenting'
  3246. F5_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F5"])
  3247. F5_thread.start()
  3248. elif (F_UP_tank_WaterLevel[0] == 1):
  3249. FInputtingWater_AND_WaterLevel1("F5")
  3250. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  3251. FInputtingWater_AND_tankwaterfilled("F5")
  3252. elif F6 == 'F_InputtingWater':
  3253. if (F_UP_tank_WaterLevel[5] == 1) and (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  3254. F6 = 'F_Fermenting'
  3255. F6_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F6"])
  3256. F6_thread.start()
  3257. elif (F_UP_tank_WaterLevel[5] == 1):
  3258. FInputtingWater_AND_WaterLevel1("F6")
  3259. elif (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  3260. FInputtingWater_AND_tankwaterfilled("F6")
  3261. else:
  3262. print("else ---------------------------- ")
  3263. 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:
  3264. F1_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F1"])
  3265. F1_thread.start()
  3266. F1 = 'F_OutputtingBean'
  3267. # 將可出豆桶槽賦值
  3268. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  3269. if F2 == 'F_Fermenting':
  3270. F2_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F2"])
  3271. F2_thread.start()
  3272. F2 = 'F_OutputtingBean'
  3273. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F2'
  3274. if F3 == 'F_Fermenting':
  3275. F3_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F3"])
  3276. F3_thread.start()
  3277. F3 = 'F_OutputtingBean'
  3278. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F3'
  3279. if F4 == 'F_Fermenting':
  3280. F4_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F4"])
  3281. F4_thread.start()
  3282. F4 = 'F_OutputtingBean'
  3283. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F4'
  3284. if F5 == 'F_Fermenting':
  3285. F5_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F5"])
  3286. F5_thread.start()
  3287. F5 = 'F_OutputtingBean'
  3288. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F5'
  3289. if F6 == 'F_Fermenting':
  3290. F6_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F6"])
  3291. F6_thread.start()
  3292. F6 = 'F_OutputtingBean'
  3293. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F6'
  3294. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  3295. # TODO 發酵次數計算、消毒次數、校正
  3296. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  3297. if FOutputtingBean_Tank == 'F1':
  3298. FOutputtingBean_TO_FWaiting('F1')
  3299. FOutputtingBean_Tank = ''
  3300. if (FermentAuto_cleaning == 0): F1 = 'F_Waiting'
  3301. elif (FermentAuto_cleaning != 0): F1 = 'F_Cleaning'
  3302. if F2 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[1] <= Ferment_Tank_bean_empty):
  3303. if FOutputtingBean_Tank == 'F2':
  3304. FOutputtingBean_TO_FWaiting('F2')
  3305. FOutputtingBean_Tank = ''
  3306. if (FermentAuto_cleaning == 0): F2 = 'F_Waiting'
  3307. elif (FermentAuto_cleaning != 0): F2 = 'F_Cleaning'
  3308. if F3 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[2] <= Ferment_Tank_bean_empty):
  3309. if FOutputtingBean_Tank == 'F3':
  3310. FOutputtingBean_TO_FWaiting('F3')
  3311. FOutputtingBean_Tank = ''
  3312. if (FermentAuto_cleaning == 0): F3 = 'F_Waiting'
  3313. elif (FermentAuto_cleaning != 0): F3 = 'F_Cleaning'
  3314. if F4 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[3] <= Ferment_Tank_bean_empty):
  3315. if FOutputtingBean_Tank == 'F4':
  3316. FOutputtingBean_TO_FWaiting('F4')
  3317. FOutputtingBean_Tank = ''
  3318. if (FermentAuto_cleaning == 0): F4 = 'F_Waiting'
  3319. elif (FermentAuto_cleaning != 0): F4 = 'F_Cleaning'
  3320. if F5 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[4] <= Ferment_Tank_bean_empty):
  3321. if FOutputtingBean_Tank == 'F5':
  3322. FOutputtingBean_TO_FWaiting('F5')
  3323. FOutputtingBean_Tank = ''
  3324. if (FermentAuto_cleaning == 0): F5 = 'F_Waiting'
  3325. elif (FermentAuto_cleaning != 0): F5 = 'F_Cleaning'
  3326. if F6 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[5] <= Ferment_Tank_bean_empty):
  3327. if FOutputtingBean_Tank == 'F6':
  3328. FOutputtingBean_TO_FWaiting('F6')
  3329. FOutputtingBean_Tank = ''
  3330. if (FermentAuto_cleaning == 0): F6 = 'F_Waiting'
  3331. elif (FermentAuto_cleaning != 0): F6 = 'F_Cleaning'
  3332. # 避免桶槽可出豆時未賦值
  3333. if FOutputtingBean_Tank == '':
  3334. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  3335. elif F2 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F2'
  3336. elif F3 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F3'
  3337. elif F4 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F4'
  3338. elif F5 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F5'
  3339. elif F6 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F6'
  3340. # 若桶槽 F1~F6 為清洗中
  3341. if F1 == 'F_Cleaning':
  3342. F1_thread = threading.Thread(target=FCleaning, args=["F1"])
  3343. F1_thread.start()
  3344. F1 = 'F_Waiting'
  3345. if F2 == 'F_Cleaning':
  3346. F2_thread = threading.Thread(target=FCleaning, args=["F2"])
  3347. F2_thread.start()
  3348. F2 = 'F_Waiting'
  3349. if F3 == 'F_Cleaning':
  3350. F3_thread = threading.Thread(target=FCleaning, args=["F3"])
  3351. F3_thread.start()
  3352. F3 = 'F_Waiting'
  3353. if F4 == 'F_Cleaning':
  3354. F4_thread = threading.Thread(target=FCleaning, args=["F4"])
  3355. F4_thread.start()
  3356. F4 = 'F_Waiting'
  3357. if F5 == 'F_Cleaning':
  3358. F5_thread = threading.Thread(target=FCleaning, args=["F5"])
  3359. F5_thread.start()
  3360. F5 = 'F_Waiting'
  3361. if F6 == 'F_Cleaning':
  3362. F6_thread = threading.Thread(target=FCleaning, args=["F6"])
  3363. F6_thread.start()
  3364. F6 = 'F_Waiting'
  3365. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3366. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  3367. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  3368. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  3369. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  3370. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  3371. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  3372. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  3373. else:
  3374. # [介面] 若未啟用 發酵 狀態
  3375. print('未啟用發酵流程')
  3376. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  3377. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  3378. # Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  3379. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  3380. if FO1 == 'FO_Waiting' and FOutputtingBean_Tank != '':
  3381. # 判斷要對應出料的桶槽為何, 設定成 FOutputtingBean_Tank = 'F1', 待出完料再把 FOutputtingBean_Tank = ''
  3382. FO1 = 'FO_InputtingBean'
  3383. print('------- ' + FOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  3384. print('------- FO1 狀態更新:入豆中 -------')
  3385. # [致動器] F1 蝴蝶閥 ON
  3386. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  3387. print('data: ', data)
  3388. # mqtt_f(data)
  3389. elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '':
  3390. if FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  3391. # [致動器] 出料真空吸料機 OFF
  3392. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  3393. print('data: ', data)
  3394. # mqtt_f(data)
  3395. # [致動器] F1 蝴蝶閥 OFF
  3396. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  3397. print('data: ', data)
  3398. # mqtt_f(data)
  3399. FO1 = 'FO_OutputtingBean'
  3400. print('------- FO1 狀態更新:出豆中 -------')
  3401. elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  3402. FO1_thread = threading.Thread(target=FOInputtingBean_filled, args=["FO1"])
  3403. FO1_thread.start()
  3404. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  3405. elif FOutputtingBean_Tank == '':
  3406. if FO_UP_UltraSoniclist[0] > Ferment_Output_bean_empty:
  3407. FO1 = 'FO_OutputtingBean'
  3408. print('------- FO1 狀態更新:可出豆 -------')
  3409. elif FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  3410. FO1 = 'FO_Waiting'
  3411. print('------- FO1 狀態更新:空桶等待 -------')
  3412. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  3413. FO1 = 'FO_Waiting'
  3414. print('------- FO1 狀態更新:空桶等待 -------')
  3415. # ----- 等待 thread 多執行緒執行完成 --------
  3416. # 若 FI1_thread 有被定義, 則執行 FI1_thread.join() 等待執行完成 (當入料儲豆槽入料時)
  3417. # 若 FI1_thread 有被定義, 會出現 UnboundLocalError: local variable 'FO1_thread' referenced before assignment 錯誤訊息
  3418. # (非入料儲豆槽入料時) 此時就不進行任何處理
  3419. try:
  3420. FI1_thread.join()
  3421. print("-- FI1_thread complete! --")
  3422. except UnboundLocalError:
  3423. pass
  3424. try:
  3425. F1_thread.join()
  3426. print("-- F1_thread complete! --")
  3427. except UnboundLocalError:
  3428. pass
  3429. try:
  3430. F2_thread.join()
  3431. print("-- F2_thread complete! --")
  3432. except UnboundLocalError:
  3433. pass
  3434. try:
  3435. F3_thread.join()
  3436. print("-- F3_thread complete! --")
  3437. except UnboundLocalError:
  3438. pass
  3439. try:
  3440. F4_thread.join()
  3441. print("-- F4_thread complete! --")
  3442. except UnboundLocalError:
  3443. pass
  3444. try:
  3445. F5_thread.join()
  3446. print("-- F5_thread complete! --")
  3447. except UnboundLocalError:
  3448. pass
  3449. try:
  3450. F6_thread.join()
  3451. print("-- F6_thread complete! --")
  3452. except UnboundLocalError:
  3453. pass
  3454. try:
  3455. FO1_thread.join()
  3456. print("-- FO1_thread complete! --")
  3457. except UnboundLocalError:
  3458. pass
  3459. # ----- 將狀態寫入資料庫 ------------------------------
  3460. # 獲取文本框的值並賦值給user實體對象
  3461. F_status = ferment_container_status()
  3462. F_status.Ferment_Input_1 = FI1
  3463. F_status.Ferment_Input_2 = FI2
  3464. F_status.Ferment_Tank_1 = F1
  3465. F_status.Ferment_Tank_2 = F2
  3466. F_status.Ferment_Tank_3 = F3
  3467. F_status.Ferment_Tank_4 = F4
  3468. F_status.Ferment_Tank_5 = F5
  3469. F_status.Ferment_Tank_6 = F6
  3470. F_status.Ferment_Tank_7 = F7
  3471. F_status.Ferment_Tank_8 = F8
  3472. F_status.Ferment_Tank_9 = F9
  3473. F_status.Ferment_Tank_10 = F10
  3474. F_status.Ferment_Tank_11 = F11
  3475. F_status.Ferment_Tank_12 = F12
  3476. F_status.Ferment_Output_1 = FO1
  3477. F_status.Ferment_Output_2 = FO2
  3478. #將數據保存進資料庫
  3479. db.session.add(F_status)
  3480. # 手動提交
  3481. db.session.commit()
  3482. # ----- 將狀態寫入資料庫 ------------------------------
  3483. return jsonify({"Peel_Output_1":PO1,
  3484. "Ferment_Input_1":FI1,
  3485. "Ferment_Tank_1":F1,
  3486. "Ferment_Tank_2":F2,
  3487. "Ferment_Tank_3":F3,
  3488. "Ferment_Tank_4":F4,
  3489. "Ferment_Tank_5":F5,
  3490. "Ferment_Tank_6":F6,
  3491. "Ferment_Output_1":FO1
  3492. })
  3493. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以下為原備份
  3494. @main.route('/ferment_auto_test_1026backup')
  3495. def ferment_auto_test_1026backup():
  3496. info = request.args.to_dict()
  3497. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  3498. Ferment_Input_bean_empty = 2
  3499. Ferment_Tank_bean_empty = 2
  3500. Ferment_Output_bean_empty = 2
  3501. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  3502. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  3503. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  3504. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  3505. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  3506. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  3507. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  3508. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  3509. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  3510. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  3511. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  3512. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  3513. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  3514. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  3515. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  3516. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  3517. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  3518. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  3519. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  3520. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  3521. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  3522. # print('發酵自動化_指定生豆高度: ', Ferment_Tank_bean_height)
  3523. # print('發酵自動化_發酵排程: ', FermentAuto_fermenting, type(FermentAuto_fermenting))
  3524. # print('發酵自動化_清洗排程: ', FermentAuto_cleaning, type(FermentAuto_cleaning))
  3525. # print('發酵自動化_校正 EC 排程: ', FermentAuto_calibratingEC, type(FermentAuto_calibratingEC))
  3526. # print('發酵自動化_校正攪拌棒排程: ', FermentAuto_calibratingSTIR, type(FermentAuto_calibratingSTIR))
  3527. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  3528. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  3529. # 從資料庫資料表中取得最新狀態
  3530. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  3531. FI1 = ferment_status.Ferment_Input_1
  3532. FI2 = ferment_status.Ferment_Input_2
  3533. F1 = ferment_status.Ferment_Tank_1
  3534. F2 = ferment_status.Ferment_Tank_2
  3535. F3 = ferment_status.Ferment_Tank_3
  3536. F4 = ferment_status.Ferment_Tank_4
  3537. F5 = ferment_status.Ferment_Tank_5
  3538. F6 = ferment_status.Ferment_Tank_6
  3539. F7 = ferment_status.Ferment_Tank_7
  3540. F8 = ferment_status.Ferment_Tank_8
  3541. F9 = ferment_status.Ferment_Tank_9
  3542. F10 = ferment_status.Ferment_Tank_10
  3543. F11 = ferment_status.Ferment_Tank_11
  3544. F12 = ferment_status.Ferment_Tank_12
  3545. FO1 = ferment_status.Ferment_Output_1
  3546. FO2 = ferment_status.Ferment_Output_2
  3547. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  3548. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  3549. PO2 = clean_status.Peel_Output_2
  3550. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  3551. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  3552. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  3553. # 目前發酵槽 F1~F6 正在入豆的桶槽數量 (應小於一桶)
  3554. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  3555. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  3556. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  3557. FI_UP_UltraSoniclist = []
  3558. for i in range(1, 3, 1):
  3559. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3560. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  3561. UltraSonic = float(input_UltraSonic.UltraSonic)
  3562. FI_UP_UltraSoniclist.append(UltraSonic)
  3563. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  3564. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  3565. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  3566. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  3567. FI1 = 'FI_InputtingBean'
  3568. print('------- FI1 狀態更新:入豆中 -------')
  3569. # [致動器] 入料真空吸料機 ON
  3570. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  3571. print('data: ', data)
  3572. # mqtt_f(data)
  3573. timer = time.time()
  3574. while True:
  3575. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  3576. # [致動器] 入料真空吸料機 OFF
  3577. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3578. print('data: ', data)
  3579. # mqtt_f(data)
  3580. timer = time.time()
  3581. break
  3582. while True:
  3583. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  3584. break
  3585. # 入料儲豆槽入豆時
  3586. elif FI1 == 'FI_InputtingBean':
  3587. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  3588. if (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  3589. # [致動器] 入料真空吸料機 ON
  3590. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  3591. print('data: ', data)
  3592. # mqtt_f(data)
  3593. timer = time.time()
  3594. while True:
  3595. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  3596. # [致動器] 入料真空吸料機 OFF
  3597. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3598. print('data: ', data)
  3599. # mqtt_f(data)
  3600. timer = time.time()
  3601. break
  3602. while True:
  3603. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  3604. break
  3605. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  3606. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  3607. FI1 = 'FI_OutputtingBean'
  3608. print('------- FI1 狀態更新:可出豆 -------')
  3609. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  3610. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  3611. FI1 = 'FI_Waiting'
  3612. print('------- FI1 狀態更新:空桶等待 -------')
  3613. # [1012 刪除, 避免混豆]若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  3614. # elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] < 40) and PO1 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3615. # FI1 = 'FI_InputtingBean'
  3616. # print('------- FI1 狀態更新:入豆中 -------')
  3617. # if FI2 == 'FI_Waiting' and PO2 == 'PO_OutputtingBean':
  3618. # FI2 = 'FI_InputtingBean'
  3619. # print('------- FI2 狀態更新:入豆中 -------')
  3620. # elif FI2 == 'FI_InputtingBean' and ((FI_UP_UltraSoniclist[1] >= 35) or (PO2 != 'PO_OutputtingBean')) :
  3621. # FI2 = 'FI_OutputtingBean'
  3622. # print('------- FI2 狀態更新:可出豆 -------')
  3623. # elif FI2 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[1] < 40) and PO2 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3624. # FI2 = 'FI_InputtingBean'
  3625. # print('------- FI2 狀態更新:入豆中 -------')
  3626. # ----- 發酵桶槽 F1~F6 入料暫停→入料判斷 ------------------------------
  3627. ### 移到入料
  3628. # ----- 發酵桶槽 F1~F6 等待→入料判斷 ------------------------------
  3629. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  3630. F_UP_UltraSoniclist = []
  3631. for i in range(1, 7, 1):
  3632. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3633. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  3634. F_UP_UltraSoniclist.append(UltraSonic)
  3635. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  3636. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  3637. # [介面] 若啟用 發酵 狀態
  3638. if Ferment_btn:
  3639. # 若入料儲豆槽可出料狀態
  3640. if FI1 == 'FI_OutputtingBean':
  3641. # 若 F1~F6 發酵桶槽為 入豆中, 繼續入豆, 當高度 > 指定生豆高度 時入豆完成
  3642. if F1 == 'F_InputtingBean':
  3643. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  3644. F1 = 'F_InputtingBean_Finish'
  3645. print('------- F1 狀態更新:入料完成 -------')
  3646. # [致動器] 入料三通閥 ON排氣
  3647. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  3648. print('data: ', data)
  3649. # mqtt_f(data)
  3650. # [致動器] 馬達 0
  3651. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3652. print('data: ', data)
  3653. # mqtt_f(data)
  3654. # [致動器] 真空吸料機 OFF
  3655. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3656. print('data: ', data)
  3657. # mqtt_f(data)
  3658. else:
  3659. # [致動器] 真空吸料機 ON
  3660. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3661. print('data: ', data)
  3662. # mqtt_f(data)
  3663. timer = time.time()
  3664. while True:
  3665. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3666. # [致動器] 入料真空吸料機 OFF
  3667. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3668. print('data: ', data)
  3669. # mqtt_f(data)
  3670. timer = time.time()
  3671. break
  3672. while True:
  3673. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3674. break
  3675. if F2 == 'F_InputtingBean' and (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  3676. F2 = 'F_InputtingBean_Finish'
  3677. print('------- F2 狀態更新:入料完成 -------')
  3678. if F3 == 'F_InputtingBean' and (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  3679. F3 = 'F_InputtingBean_Finish'
  3680. print('------- F3 狀態更新:入料完成 -------')
  3681. if F4 == 'F_InputtingBean' and (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  3682. F4 = 'F_InputtingBean_Finish'
  3683. print('------- F4 狀態更新:入料完成 -------')
  3684. if F5 == 'F_InputtingBean' and (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  3685. F5 = 'F_InputtingBean_Finish'
  3686. print('------- F5 狀態更新:入料完成 -------')
  3687. if F6 == 'F_InputtingBean' and (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  3688. F6 = 'F_InputtingBean_Finish'
  3689. print('------- F6 狀態更新:入料完成 -------')
  3690. # 若有兩個以上桶槽入料中, 則桶號最小者優先入料 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  3691. if FermentUp_InputtingBean_number == 1:
  3692. if F1 == 'F_InputtingBean':
  3693. # [致動器] 桶槽真空吸料機 ON
  3694. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3695. print('data: ', data)
  3696. # mqtt_f(data)
  3697. timer = time.time()
  3698. while True:
  3699. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3700. # [致動器] 桶槽真空吸料機 OFF
  3701. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3702. print('data: ', data)
  3703. # mqtt_f(data)
  3704. timer = time.time()
  3705. break
  3706. while True:
  3707. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3708. break
  3709. # else if F2 == ''...
  3710. # 若 F1~F6 發酵桶槽為 入豆暫停, 則狀態改為優先入豆 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  3711. elif FermentUp_InputtingBeanPause_number >= 1:
  3712. if F1 == 'F_InputtingBean_Pause':
  3713. F1 = 'F_InputtingBean'
  3714. print('------- F1 狀態更新:入料中 -------')
  3715. # [致動器] 桶槽真空吸料機 ON
  3716. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3717. print('data: ', data)
  3718. # mqtt_f(data)
  3719. timer = time.time()
  3720. while True:
  3721. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3722. # [致動器] 桶槽真空吸料機 OFF
  3723. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3724. print('data: ', data)
  3725. # mqtt_f(data)
  3726. timer = time.time()
  3727. break
  3728. while True:
  3729. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  3730. break
  3731. elif F2 == 'F_InputtingBean_Pause':
  3732. F2 = 'F_InputtingBean'
  3733. print('------- F2 狀態更新:入料中 -------')
  3734. elif F3 == 'F_InputtingBean_Pause':
  3735. F3 = 'F_InputtingBean'
  3736. print('------- F3 狀態更新:入料中 -------')
  3737. elif F4 == 'F_InputtingBean_Pause':
  3738. F4 = 'F_InputtingBean'
  3739. print('------- F4 狀態更新:入料中 -------')
  3740. elif F5 == 'F_InputtingBean_Pause':
  3741. F5 = 'F_InputtingBean'
  3742. print('------- F5 狀態更新:入料中 -------')
  3743. elif F6 == 'F_InputtingBean_Pause':
  3744. F6 = 'F_InputtingBean'
  3745. print('------- F6 狀態更新:入料中 -------')
  3746. # 若 F1~F6 皆無入豆 無入豆暫停, 則桶號最小者開始入豆
  3747. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  3748. if F1 == 'F_Waiting':
  3749. F1 = 'F_InputtingBean'
  3750. print('------- F1 狀態更新:入料中 -------')
  3751. # [致動器] 入料入料三通閥 OFF入豆
  3752. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "off" }
  3753. print('data: ', data)
  3754. # mqtt_f(data)
  3755. # [致動器] 馬達 5
  3756. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "5" }
  3757. print('data: ', data)
  3758. # mqtt_f(data)
  3759. # [致動器] 桶槽真空吸料機 ON
  3760. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  3761. print('data: ', data)
  3762. # mqtt_f(data)
  3763. timer = time.time()
  3764. while True:
  3765. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3766. # [致動器] 桶槽真空吸料機 OFF
  3767. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3768. print('data: ', data)
  3769. # mqtt_f(data)
  3770. timer = time.time()
  3771. break
  3772. while True:
  3773. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  3774. break
  3775. elif F2 == 'F_Waiting':
  3776. F2 = 'F_InputtingBean'
  3777. print('------- F2 狀態更新:入料中 -------')
  3778. elif F3 == 'F_Waiting':
  3779. F3 = 'F_InputtingBean'
  3780. print('------- F3 狀態更新:入料中 -------')
  3781. elif F4 == 'F_Waiting':
  3782. F4 = 'F_InputtingBean'
  3783. print('------- F4 狀態更新:入料中 -------')
  3784. elif F5 == 'F_Waiting':
  3785. F5 = 'F_InputtingBean'
  3786. print('------- F5 狀態更新:入料中 -------')
  3787. elif F6 == 'F_Waiting':
  3788. F6 = 'F_InputtingBean'
  3789. print('------- F6 狀態更新:入料中 -------')
  3790. # 若入料儲豆槽非可出豆, 且 F1~F6 其中有桶槽入料中, 若桶槽未滿則入料暫停
  3791. elif FI1 != 'FI_InputtingBean' and FermentUp_InputtingBean_number >= 1:
  3792. if F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height:
  3793. F1 = 'F_InputtingBean_Pause'
  3794. print('------- F1 狀態更新:入料暫停 -------')
  3795. # [致動器] 桶槽真空吸料機 OFF
  3796. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  3797. print('data: ', data)
  3798. # mqtt_f(data)
  3799. elif F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height:
  3800. F1 = 'F_InputtingBean_Finish'
  3801. print('------- F1 狀態更新:入料完成 -------')
  3802. # [致動器] 入料三通閥 ON排氣
  3803. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  3804. print('data: ', data)
  3805. # mqtt_f(data)
  3806. # [致動器] 馬達 0
  3807. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3808. print('data: ', data)
  3809. # mqtt_f(data)
  3810. # [致動器] 入料真空吸料機 OFF
  3811. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  3812. print('data: ', data)
  3813. # mqtt_f(data)
  3814. if F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height:
  3815. F2 = 'F_InputtingBean_Pause'
  3816. print('------- F2 狀態更新:入料暫停 -------')
  3817. elif F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height:
  3818. F2 = 'F_InputtingBean_Finish'
  3819. print('------- F2 狀態更新:入料完成 -------')
  3820. if F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height:
  3821. F3 = 'F_InputtingBean_Pause'
  3822. print('------- F3 狀態更新:入料暫停 -------')
  3823. elif F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height:
  3824. F3 = 'F_InputtingBean_Finish'
  3825. print('------- F3 狀態更新:入料完成 -------')
  3826. if F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height:
  3827. F4 = 'F_InputtingBean_Pause'
  3828. print('------- F4 狀態更新:入料暫停 -------')
  3829. elif F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height:
  3830. F4 = 'F_InputtingBean_Finish'
  3831. print('------- F4 狀態更新:入料完成 -------')
  3832. if F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height:
  3833. F5 = 'F_InputtingBean_Pause'
  3834. print('------- F5 狀態更新:入料暫停 -------')
  3835. elif F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height:
  3836. F5 = 'F_InputtingBean_Finish'
  3837. print('------- F5 狀態更新:入料完成 -------')
  3838. if F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height:
  3839. F6 = 'F_InputtingBean_Pause'
  3840. print('------- F6 狀態更新:入料暫停 -------')
  3841. elif F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height:
  3842. F6 = 'F_InputtingBean_Finish'
  3843. print('------- F6 狀態更新:入料完成 -------')
  3844. else:
  3845. # 若入料儲豆槽非可出料狀態
  3846. print('發酵入料儲豆槽空, 桶槽無法入料')
  3847. else:
  3848. # [介面] 若未啟用 發酵 狀態
  3849. print('未啟用發酵流程')
  3850. # ----- 10/07 --------------------------------------------------------------------------------------------------------------------------------
  3851. # ----- 發酵桶槽 F1~F6 入料→入料暫停判斷 ------------------------------
  3852. ### 移到入料
  3853. # ----- 發酵桶槽 F1~F6 入料→入水判斷 ------------------------------
  3854. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  3855. F_UP_tank_WaterLevel = []
  3856. for i in range(1, 7, 1):
  3857. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3858. WaterLevel = float(tank_WaterLevel.WaterLevel)
  3859. F_UP_tank_WaterLevel.append(WaterLevel)
  3860. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  3861. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  3862. Ferment_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  3863. Ferment_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  3864. # 入水條件:當前桶槽入豆 + 沒有其他桶槽入水
  3865. if Ferment_InputtingBeanFinish_number >= 1 and Ferment_InputtingWater_number == 0:
  3866. # 當入豆到指定高度時, 狀態轉換為入水 (桶槽編號小者優先)
  3867. # !!! 發酵槽 F_InputtingBean_Finish 狀態應該請硬體判斷
  3868. # !!! 若狀態為 F_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 F_InputtingBean_Finish 並等待入水 F_InputtingWater
  3869. # 這邊是考慮一次僅一個桶槽入水, 多桶入水會不會速度變慢?
  3870. if F1 == 'F_InputtingBean_Finish':
  3871. F1 = 'F_InputtingWater'
  3872. print('------- F1 狀態更新:入水中 -------')
  3873. # [致動器] 外桶浮選三通閥 ON
  3874. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "on" }
  3875. print('data: ', data)
  3876. # mqtt_f(data)
  3877. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  3878. if F_UP_UltraSoniclist[0] < Ferment_Tank_water_height:
  3879. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "on" }
  3880. print('data: ', data)
  3881. # mqtt_f(data)
  3882. # [致動器] 桶內進水電磁閥 OFF
  3883. else:
  3884. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3885. print('data: ', data)
  3886. # mqtt_f(data)
  3887. # 桶外水位高度若低於水位計高度, [致動器] 桶外進水電磁閥 ON
  3888. if F_UP_tank_WaterLevel[0] != 1:
  3889. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "on" }
  3890. print('data: ', data)
  3891. # mqtt_f(data)
  3892. # [致動器] 桶外進水電磁閥 OFF
  3893. else:
  3894. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3895. print('data: ', data)
  3896. # mqtt_f(data)
  3897. elif F2 == 'F_InputtingBean_Finish':
  3898. F2 = 'F_InputtingWater'
  3899. print('------- F2 狀態更新:入水中 -------')
  3900. elif F3 == 'F_InputtingBean_Finish':
  3901. F3 = 'F_InputtingWater'
  3902. print('------- F3 狀態更新:入水中 -------')
  3903. elif F4 == 'F_InputtingBean_Finish':
  3904. F4 = 'F_InputtingWater'
  3905. print('------- F4 狀態更新:入水中 -------')
  3906. elif F5 == 'F_InputtingBean_Finish':
  3907. F5 = 'F_InputtingWater'
  3908. print('------- F5 狀態更新:入水中 -------')
  3909. elif F6 == 'F_InputtingBean_Finish':
  3910. F6 = 'F_InputtingWater'
  3911. print('------- F6 狀態更新:入水中 -------')
  3912. # ----- 發酵桶槽 F1~F6 入水→發酵判斷 ------------------------------
  3913. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  3914. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  3915. if F1 == 'F_InputtingWater':
  3916. if F_UP_tank_WaterLevel[0] == 1 and F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  3917. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  3918. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3919. print('data: ', data)
  3920. # mqtt_f(data)
  3921. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  3922. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3923. print('data: ', data)
  3924. # mqtt_f(data)
  3925. F1 = 'F_Fermenting'
  3926. print('------- F1 狀態更新:發酵中 -------')
  3927. # [致動器] 馬達 (指定轉速)
  3928. data = { "tank_num": "F1", "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  3929. print('data: ', data)
  3930. # mqtt_f(data)
  3931. # [致動器] 溫控開關 ON
  3932. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "on" }
  3933. # print('data: ', data)
  3934. # # mqtt_f(data)
  3935. # [致動器] 設定溫度、持溫時間
  3936. # [致動器] 加熱器 1 ON
  3937. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "on" }
  3938. print('data: ', data)
  3939. # mqtt_f(data)
  3940. elif F_UP_tank_WaterLevel[0] == 1:
  3941. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  3942. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  3943. print('data: ', data)
  3944. # mqtt_f(data)
  3945. elif F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  3946. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  3947. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  3948. print('data: ', data)
  3949. # mqtt_f(data)
  3950. if F2 == 'F_InputtingWater' and F_UP_tank_WaterLevel[1] == 1 and F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height:
  3951. F2 = 'F_Fermenting'
  3952. print('------- F2 狀態更新:發酵中 -------')
  3953. if F3 == 'F_InputtingWater' and F_UP_tank_WaterLevel[2] == 1 and F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height:
  3954. F3 = 'F_Fermenting'
  3955. print('------- F3 狀態更新:發酵中 -------')
  3956. if F4 == 'F_InputtingWater' and F_UP_tank_WaterLevel[3] == 1 and F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height:
  3957. F4 = 'F_Fermenting'
  3958. print('------- F4 狀態更新:發酵中 -------')
  3959. if F5 == 'F_InputtingWater' and F_UP_tank_WaterLevel[4] == 1 and F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height:
  3960. F5 = 'F_Fermenting'
  3961. print('------- F5 狀態更新:發酵中 -------')
  3962. if F6 == 'F_InputtingWater' and F_UP_tank_WaterLevel[5] == 1 and F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height:
  3963. F6 = 'F_Fermenting'
  3964. print('------- F6 狀態更新:發酵中 -------')
  3965. # ----- 發酵桶槽 F1~F6 發酵→可出豆 判斷 ------------------------------
  3966. # TODO
  3967. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  3968. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  3969. # 可以多桶各自執行發酵排程
  3970. # -- 取得發酵桶槽 F1~F6 pH -------------
  3971. F_UP_tank_PH = []
  3972. for i in range(1, 7, 1):
  3973. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3974. PH = float(tank_PH.PH)
  3975. F_UP_tank_PH.append(PH)
  3976. print('F_UP_tank_PH: ', F_UP_tank_PH)
  3977. # -- 取得發酵桶槽 F1~F6 pH -------------
  3978. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3979. F_UP_tank_SHT11_Temp = []
  3980. for i in range(1, 7, 1):
  3981. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3982. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  3983. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  3984. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  3985. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3986. #
  3987. 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:
  3988. print('發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  3989. timer = time.time()
  3990. while True:
  3991. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  3992. # [致動器] 外桶浮選三通閥 OFF
  3993. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "off" }
  3994. print('data: ', data)
  3995. # mqtt_f(data)
  3996. # [致動器] 馬達 0
  3997. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  3998. print('data: ', data)
  3999. # mqtt_f(data)
  4000. # [致動器] 溫控開關 OFF
  4001. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "off" }
  4002. # print('data: ', data)
  4003. # # mqtt_f(data)
  4004. # [致動器] 加熱器 1 OFF
  4005. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "off" }
  4006. print('data: ', data)
  4007. # mqtt_f(data)
  4008. break
  4009. # [致動器] 廢水排水閥 (桶內) ON
  4010. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "on" }
  4011. print('data: ', data)
  4012. # mqtt_f(data)
  4013. print('桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  4014. timer = time.time()
  4015. while True:
  4016. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  4017. # [致動器] 廢水排水閥 (桶內) OFF
  4018. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "off" }
  4019. print('data: ', data)
  4020. # mqtt_f(data)
  4021. break
  4022. F1 = 'F_OutputtingBean'
  4023. print('------- F1 狀態更新:可出豆 -------')
  4024. 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:
  4025. F2 = 'F_OutputtingBean'
  4026. print('------- F2 狀態更新:可出豆 -------')
  4027. if F3 == 'F_Fermenting' and F_UP_tank_PH[2] <= Ferment_Tank_fermenting_pH:
  4028. F3 = 'F_OutputtingBean'
  4029. print('------- F3 狀態更新:可出豆 -------')
  4030. if F4 == 'F_Fermenting' and F_UP_tank_PH[3] <= Ferment_Tank_fermenting_pH:
  4031. F4 = 'F_OutputtingBean'
  4032. print('------- F4 狀態更新:可出豆 -------')
  4033. if F5 == 'F_Fermenting' and F_UP_tank_PH[4] <= Ferment_Tank_fermenting_pH:
  4034. F5 = 'F_OutputtingBean'
  4035. print('------- F5 狀態更新:可出豆 -------')
  4036. if F6 == 'F_Fermenting' and F_UP_tank_PH[5] <= Ferment_Tank_fermenting_pH:
  4037. F6 = 'F_OutputtingBean'
  4038. print('------- F6 狀態更新:可出豆 -------')
  4039. if F1 == 'F_OutputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  4040. # 增加消毒電磁閥開關
  4041. # [致動器] 消毒電磁閥 ON
  4042. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  4043. print('data: ', data)
  4044. # mqtt_f(data)
  4045. # 暫停 (消毒時間) 秒
  4046. timer = time.time()
  4047. while True:
  4048. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  4049. # [致動器] 消毒電磁閥 OFF
  4050. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  4051. print('data: ', data)
  4052. # mqtt_f(data)
  4053. break
  4054. print('------- F1 狀態更新:空桶等待 -------')
  4055. F1 = 'F_Waiting'
  4056. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  4057. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  4058. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  4059. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  4060. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  4061. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  4062. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  4063. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  4064. # ----- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 ------------------------------
  4065. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  4066. # -- 取得發酵出料儲豆槽 FO1~FO2 桶內高度 UltraSonic -------------
  4067. FO_UP_UltraSoniclist = []
  4068. for i in range(1, 3, 1):
  4069. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  4070. UltraSonic = float(output_UltraSonic.UltraSonic)
  4071. FO_UP_UltraSoniclist.append(UltraSonic)
  4072. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  4073. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  4074. # 參考 -- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  4075. Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  4076. # !!! 若出料儲豆槽狀態為 FO_Waiting(空桶等待) 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  4077. if FO1 == 'FO_Waiting' and Ferment_OutputtingBean_number >= 1:
  4078. if F1 == 'F_OutputtingBean':
  4079. FO1 = 'FO_InputtingBean'
  4080. print('------- F1 狀態更新:出豆中 -------')
  4081. print('------- FO1 狀態更新:入豆中 -------')
  4082. # [致動器] 出料真空吸料機 ON
  4083. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  4084. print('data: ', data)
  4085. # mqtt_f(data)
  4086. # 暫停 3 秒
  4087. timer = time.time()
  4088. while True:
  4089. if (time.time() - timer) > 3 :
  4090. # [致動器] 蝴蝶閥 ON
  4091. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  4092. print('data: ', data)
  4093. # mqtt_f(data)
  4094. break
  4095. timer = time.time()
  4096. while True:
  4097. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  4098. # [致動器] 出料真空吸料機 OFF
  4099. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4100. print('data: ', data)
  4101. # mqtt_f(data)
  4102. timer = time.time()
  4103. break
  4104. while True:
  4105. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  4106. break
  4107. elif F2 == 'F_OutputtingBean':
  4108. FO1 = 'FO_InputtingBean'
  4109. print('------- F2 狀態更新:出豆中 -------')
  4110. print('------- FO1 狀態更新:入豆中 -------')
  4111. elif F3 == 'F_OutputtingBean':
  4112. FO1 = 'FO_InputtingBean'
  4113. print('------- F3 狀態更新:出豆中 -------')
  4114. print('------- FO1 狀態更新:入豆中 -------')
  4115. elif F4 == 'F_OutputtingBean':
  4116. FO1 = 'FO_InputtingBean'
  4117. print('------- F4 狀態更新:出豆中 -------')
  4118. print('------- FO1 狀態更新:入豆中 -------')
  4119. elif F5 == 'F_OutputtingBean':
  4120. FO1 = 'FO_InputtingBean'
  4121. print('------- F5 狀態更新:出豆中 -------')
  4122. print('------- FO1 狀態更新:入豆中 -------')
  4123. elif F6 == 'F_OutputtingBean':
  4124. FO1 = 'FO_InputtingBean'
  4125. print('------- F6 狀態更新:出豆中 -------')
  4126. print('------- FO1 狀態更新:入豆中 -------')
  4127. # 出料儲豆槽入料滿時, 出料儲豆槽狀態改為可出豆 (需判斷是哪個桶槽, 好關閉蝴蝶閥)
  4128. elif FO1 == 'FO_InputtingBean' and FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  4129. if F1 == 'F_OutputtingBean':
  4130. FO1 = 'FO_OutputtingBean'
  4131. print('------- FO1 狀態更新:可出豆 -------')
  4132. # [致動器] 出料真空吸料機 OFF
  4133. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4134. print('data: ', data)
  4135. # mqtt_f(data)
  4136. # [致動器] 蝴蝶閥 OFF
  4137. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  4138. print('data: ', data)
  4139. # mqtt_f(data)
  4140. elif F2 == 'F_OutputtingBean':
  4141. pass # TODO ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1020 TODO
  4142. # 出料儲豆槽入料時, 桶槽已空, 則桶槽回到空桶等待, 出料儲豆槽可出豆 ←←←←←←←←←←←←←←←←←←←←←←←←←← 1012 這段怪怪的
  4143. elif FO1 == 'FO_InputtingBean' and Ferment_OutputtingBean_number == 1:
  4144. if F1 == 'F_OutputtingBean':
  4145. if F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  4146. FO1 = 'FO_OutputtingBean'
  4147. print('------- FO1 狀態更新:可出豆 -------')
  4148. # 增加消毒電磁閥開關
  4149. # [致動器] 消毒電磁閥 ON
  4150. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  4151. print('data: ', data)
  4152. # mqtt_f(data)
  4153. # 暫停 (消毒時間) 秒
  4154. timer = time.time()
  4155. while True:
  4156. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  4157. # [致動器] 消毒電磁閥 OFF
  4158. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  4159. print('data: ', data)
  4160. # mqtt_f(data)
  4161. break
  4162. print('------- F1 狀態更新:空桶等待 -------')
  4163. F1 = 'F_Waiting'
  4164. else:
  4165. # [致動器] 出料真空吸料機 ON
  4166. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  4167. print('data: ', data)
  4168. # mqtt_f(data)
  4169. # 暫停 3 秒
  4170. timer = time.time()
  4171. while True:
  4172. if (time.time() - timer) > 3 :
  4173. # [致動器] 蝴蝶閥 ON
  4174. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  4175. print('data: ', data)
  4176. # mqtt_f(data)
  4177. break
  4178. timer = time.time()
  4179. while True:
  4180. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  4181. # [致動器] 出料真空吸料機 OFF
  4182. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  4183. print('data: ', data)
  4184. # mqtt_f(data)
  4185. timer = time.time()
  4186. break
  4187. while True:
  4188. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  4189. break
  4190. elif F2 == 'F_OutputtingBean' and F_UP_UltraSoniclist[1] < 5:
  4191. F2 = 'F_Waiting'
  4192. FO1 = 'FO_OutputtingBean'
  4193. print('------- F2 狀態更新:空桶等待 -------')
  4194. print('------- FO1 狀態更新:可出豆 -------')
  4195. elif F3 == 'F_OutputtingBean' and F_UP_UltraSoniclist[2] < 5:
  4196. F3 = 'F_Waiting'
  4197. FO1 = 'FO_OutputtingBean'
  4198. print('------- F3 狀態更新:空桶等待 -------')
  4199. print('------- FO1 狀態更新:可出豆 -------')
  4200. elif F4 == 'F_OutputtingBean' and F_UP_UltraSoniclist[3] < 5:
  4201. F4 = 'F_Waiting'
  4202. FO1 = 'FO_OutputtingBean'
  4203. print('------- F4 狀態更新:空桶等待 -------')
  4204. print('------- FO1 狀態更新:可出豆 -------')
  4205. elif F5 == 'F_OutputtingBean' and F_UP_UltraSoniclist[4] < 5:
  4206. F5 = 'F_Waiting'
  4207. FO1 = 'FO_OutputtingBean'
  4208. print('------- F5 狀態更新:空桶等待 -------')
  4209. print('------- FO1 狀態更新:可出豆 -------')
  4210. elif F6 == 'F_OutputtingBean' and F_UP_UltraSoniclist[5] < 5:
  4211. F6 = 'F_Waiting'
  4212. FO1 = 'FO_OutputtingBean'
  4213. print('------- F6 狀態更新:空桶等待 -------')
  4214. print('------- FO1 狀態更新:可出豆 -------')
  4215. # 出料儲豆槽出料 且 儲豆槽內高度低於 5 , 為空桶等待
  4216. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] < Ferment_Output_bean_empty:
  4217. FO1 = 'FO_Waiting'
  4218. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  4219. # 1008 移到桶槽前面
  4220. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  4221. # 1012 移到桶槽可出豆內
  4222. # ----- 將狀態寫入資料庫 ------------------------------
  4223. # 獲取文本框的值並賦值給user實體對象
  4224. F_status = ferment_container_status()
  4225. F_status.Ferment_Input_1 = FI1
  4226. F_status.Ferment_Input_2 = FI2
  4227. F_status.Ferment_Tank_1 = F1
  4228. F_status.Ferment_Tank_2 = F2
  4229. F_status.Ferment_Tank_3 = F3
  4230. F_status.Ferment_Tank_4 = F4
  4231. F_status.Ferment_Tank_5 = F5
  4232. F_status.Ferment_Tank_6 = F6
  4233. F_status.Ferment_Tank_7 = F7
  4234. F_status.Ferment_Tank_8 = F8
  4235. F_status.Ferment_Tank_9 = F9
  4236. F_status.Ferment_Tank_10 = F10
  4237. F_status.Ferment_Tank_11 = F11
  4238. F_status.Ferment_Tank_12 = F12
  4239. F_status.Ferment_Output_1 = FO1
  4240. F_status.Ferment_Output_2 = FO2
  4241. #將數據保存進資料庫
  4242. db.session.add(F_status)
  4243. # 手動提交
  4244. db.session.commit()
  4245. # ----- 將狀態寫入資料庫 ------------------------------
  4246. return jsonify({"Peel_Output_1":PO1,
  4247. "Ferment_Input_1":FI1,
  4248. "Ferment_Tank_1":F1,
  4249. "Ferment_Tank_2":F2,
  4250. "Ferment_Tank_3":F3,
  4251. "Ferment_Tank_4":F4,
  4252. "Ferment_Tank_5":F5,
  4253. "Ferment_Tank_6":F6,
  4254. "Ferment_Output_1":FO1
  4255. })
  4256. '''
  4257. return jsonify({"Ferment_Input_1":FI1,
  4258. "Ferment_Input_2":FI2,
  4259. "Ferment_Tank_1":F1,
  4260. "Ferment_Tank_2":F2,
  4261. "Ferment_Tank_3":F3,
  4262. "Ferment_Tank_4":F4,
  4263. "Ferment_Tank_5":F5,
  4264. "Ferment_Tank_6":F6,
  4265. "Ferment_Tank_7":F7,
  4266. "Ferment_Tank_8":F8,
  4267. "Ferment_Tank_9":F9,
  4268. "Ferment_Tank_10":F10,
  4269. "Ferment_Tank_11":F11,
  4270. "Ferment_Tank_12":F12,
  4271. "Ferment_Output_1":FO1,
  4272. "Ferment_Output_2":FO2
  4273. })
  4274. '''
  4275. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以上為原備份
  4276. # 舊有 video 介面
  4277. @main.route('/video')
  4278. def main_video():
  4279. # 獲取登入信息
  4280. if 'id' in session and 'uname' in session and 'status' in session:
  4281. username = session['uname']
  4282. status = session['status']
  4283. if status == 9:
  4284. return render_template('signin_disable.html', params=locals())
  4285. elif status == 8:
  4286. return render_template('signin_new.html', params=locals())
  4287. return render_template('video.html', params=locals())
  4288. else:
  4289. return render_template('sign_in.html')
  4290. @main.route('/sitemap')
  4291. def sitemap():
  4292. if request.method == 'GET':
  4293. if 'id' in session and 'uname' in session and 'status' in session:
  4294. username = session['uname']
  4295. status = session['status']
  4296. print('username: ', username)
  4297. print('status: ', status)
  4298. if status == 9:
  4299. return render_template('signin_disable.html', **locals())
  4300. elif status == 8:
  4301. return render_template('signin_new.html', **locals())
  4302. return render_template('sitemap.html', **locals())
  4303. else:
  4304. return render_template('sign_in.html')
  4305. @main.route('/index_navbar', methods=['GET'])
  4306. def index_navbar():
  4307. return render_template('index_navbar.html')
  4308. @main.route('/camera_dry', methods=['GET', 'POST'])
  4309. def camera_dry():
  4310. if request.method == 'GET':
  4311. if 'id' in session and 'uname' in session and 'status' in session:
  4312. username = session['uname']
  4313. status = session['status']
  4314. if status == 9:
  4315. return render_template('signin_disable.html', params=locals())
  4316. elif status == 8:
  4317. return render_template('signin_new.html', params=locals())
  4318. return render_template('camera_dry.html', title='乾燥貨櫃攝影機', **locals())
  4319. else:
  4320. return render_template('sign_in.html')
  4321. @main.route('/camera_ferment', methods=['GET', 'POST'])
  4322. def camera_ferment():
  4323. if request.method == 'GET':
  4324. if 'id' in session and 'uname' in session and 'status' in session:
  4325. username = session['uname']
  4326. status = session['status']
  4327. if status == 9:
  4328. return render_template('signin_disable.html', params=locals())
  4329. elif status == 8:
  4330. return render_template('signin_new.html', params=locals())
  4331. return render_template('camera_ferment.html', title='發酵貨櫃攝影機', **locals())
  4332. else:
  4333. return render_template('sign_in.html')
  4334. @main.route('/camera_clean', methods=['GET', 'POST'])
  4335. def camera_clean():
  4336. if request.method == 'GET':
  4337. if 'id' in session and 'uname' in session and 'status' in session:
  4338. username = session['uname']
  4339. status = session['status']
  4340. if status == 9:
  4341. return render_template('signin_disable.html', params=locals())
  4342. elif status == 8:
  4343. return render_template('signin_new.html', params=locals())
  4344. return render_template('camera_clean.html', title='清洗貨櫃攝影機', **locals())
  4345. else:
  4346. return render_template('sign_in.html')
  4347. @main.route('/camera_dry_1', methods=['GET', 'POST'])
  4348. def camera_dry_2():
  4349. if request.method == 'GET':
  4350. return render_template('camera_dry_1.html', title='乾燥貨櫃攝影機', **locals())
  4351. @main.route('/camera_<tid>', methods=['GET', 'POST'])
  4352. def camera(tid):
  4353. if request.method == 'GET':
  4354. if 'id' in session and 'uname' in session and 'status' in session:
  4355. username = session['uname']
  4356. status = session['status']
  4357. if status == 9:
  4358. return render_template('signin_disable.html', params=locals())
  4359. elif status == 8:
  4360. return render_template('signin_new.html', params=locals())
  4361. if tid == 'CCargo_in':
  4362. WS_URL = 'ws:///60.250.156.230:1111'
  4363. camera_title = '清洗貨櫃內部'
  4364. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4365. elif tid == 'CCargo_out':
  4366. WS_URL = 'ws:///60.250.156.230:1111'
  4367. camera_title = '清洗貨櫃外部'
  4368. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4369. elif tid == 'FCargo_in':
  4370. WS_URL = 'ws:///60.250.156.230:1111'
  4371. camera_title = '發酵貨櫃內部'
  4372. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4373. elif tid == 'FCargo_out':
  4374. WS_URL = 'ws:///60.250.156.230:1111'
  4375. camera_title = '發酵貨櫃外部'
  4376. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4377. elif tid == 'DCargo_in':
  4378. WS_URL = 'ws:///60.250.156.230:1111'
  4379. camera_title = '乾燥貨櫃內部'
  4380. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4381. elif tid == 'DCargo_out':
  4382. WS_URL = 'ws:///60.250.156.230:1111'
  4383. camera_title = '乾燥貨櫃外部'
  4384. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  4385. elif tid[:2] == 'DO':
  4386. WS_URL_list = ['ws:///60.250.156.230:1111',
  4387. 'ws:///60.250.156.230:2222'
  4388. ]
  4389. WS_URL = WS_URL_list[int(tid[2:])-1]
  4390. camera_title = '乾燥出料儲豆槽'
  4391. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4392. elif tid[:2] == 'DI':
  4393. WS_URL_list = ['ws:///60.250.156.230:1111',
  4394. 'ws:///60.250.156.230:2222'
  4395. ]
  4396. WS_URL = WS_URL_list[int(tid[2:])-1]
  4397. camera_title = '乾燥入料儲豆槽'
  4398. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4399. elif tid[:1] == 'D':
  4400. WS_URL_list = ['ws:///60.250.156.230:8093', # D1 攝影機已安裝
  4401. 'ws:///60.250.156.230:2222',
  4402. 'ws:///60.250.156.230:3333',
  4403. 'ws:///60.250.156.230:4444',
  4404. 'ws:///60.250.156.230:5555',
  4405. 'ws:///60.250.156.230:6666',
  4406. 'ws:///60.250.156.230:7777',
  4407. 'ws:///60.250.156.230:8888',
  4408. 'ws:///60.250.156.230:9999',
  4409. 'ws:///60.250.156.230:1010',
  4410. 'ws:///60.250.156.230:1111',
  4411. 'ws:///60.250.156.230:1212'
  4412. ]
  4413. WS_URL = WS_URL_list[int(tid[1:])-1]
  4414. camera_title = '乾燥槽'
  4415. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4416. elif tid[:2] == 'FO':
  4417. WS_URL_list = ['ws:///60.250.156.230:1111',
  4418. 'ws:///60.250.156.230:2222'
  4419. ]
  4420. WS_URL = WS_URL_list[int(tid[2:])-1]
  4421. camera_title = '發酵出料儲豆槽'
  4422. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4423. elif tid[:2] == 'FI':
  4424. WS_URL_list = ['ws:///60.250.156.230:1111',
  4425. 'ws:///60.250.156.230:2222'
  4426. ]
  4427. WS_URL = WS_URL_list[int(tid[2:])-1]
  4428. camera_title = '發酵入料儲豆槽'
  4429. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4430. elif tid[:1] == 'F':
  4431. WS_URL_list = ['ws:///60.250.156.230:8089', # F1 攝影機已安裝
  4432. 'ws:///60.250.156.230:2222',
  4433. 'ws:///60.250.156.230:3333',
  4434. 'ws:///60.250.156.230:4444',
  4435. 'ws:///60.250.156.230:5555',
  4436. 'ws:///60.250.156.230:6666',
  4437. 'ws:///60.250.156.230:7777',
  4438. 'ws:///60.250.156.230:8888',
  4439. 'ws:///60.250.156.230:9999',
  4440. 'ws:///60.250.156.230:1010',
  4441. 'ws:///60.250.156.230:1111',
  4442. 'ws:///60.250.156.230:1212'
  4443. ]
  4444. WS_URL = WS_URL_list[int(tid[1:])-1]
  4445. camera_title = '發酵槽'
  4446. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4447. elif tid[:2] == 'CO':
  4448. WS_URL_list = ['ws:///60.250.156.230:1111',
  4449. 'ws:///60.250.156.230:2222'
  4450. ]
  4451. WS_URL = WS_URL_list[int(tid[2:])-1]
  4452. camera_title = '清洗浮選出料儲豆槽'
  4453. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4454. elif tid[:1] == 'C':
  4455. WS_URL_list = ['ws:///60.250.156.230:8088', # C1 攝影機已安裝
  4456. 'ws:///60.250.156.230:2222',
  4457. 'ws:///60.250.156.230:3333',
  4458. 'ws:///60.250.156.230:4444'
  4459. ]
  4460. WS_URL = WS_URL_list[int(tid[1:])-1]
  4461. camera_title = '清洗浮選槽'
  4462. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4463. elif tid[:2] == 'SO':
  4464. WS_URL_list = ['ws:///60.250.156.230:1111',
  4465. 'ws:///60.250.156.230:2222'
  4466. ]
  4467. WS_URL = WS_URL_list[int(tid[2:])-1]
  4468. camera_title = '色選機出料儲豆槽'
  4469. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4470. elif tid[:1] == 'S':
  4471. WS_URL_list = ['ws:///60.250.156.230:1111',
  4472. 'ws:///60.250.156.230:2222'
  4473. ]
  4474. WS_URL = WS_URL_list[int(tid[1:])-1]
  4475. camera_title = '色選機'
  4476. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4477. elif tid[:2] == 'PO':
  4478. WS_URL_list = ['ws:///60.250.156.230:1111',
  4479. 'ws:///60.250.156.230:2222'
  4480. ]
  4481. WS_URL = WS_URL_list[int(tid[2:])-1]
  4482. camera_title = '脫皮機出料儲豆槽'
  4483. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4484. elif tid[:1] == 'P':
  4485. WS_URL_list = ['ws:///60.250.156.230:1111',
  4486. 'ws:///60.250.156.230:2222'
  4487. ]
  4488. WS_URL = WS_URL_list[int(tid[1:])-1]
  4489. camera_title = '脫皮機'
  4490. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4491. elif tid[:1] == 'R':
  4492. WS_URL_list = ['ws:///60.250.156.230:1111'
  4493. ]
  4494. WS_URL = WS_URL_list[int(tid[1:])-1]
  4495. camera_title = '中水桶'
  4496. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  4497. else:
  4498. return render_template('sign_in.html')
  4499. else:
  4500. pass
  4501. @main.route('/dry_SHT11_<dtid>', methods=['GET', 'POST'])
  4502. def dry_SHT11(dtid):
  4503. if request.method == 'GET':
  4504. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4505. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4506. SHT11_Temp = tank_SHT11.SHT11_Temp
  4507. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4508. Soil_Temp = tank_Soil.soil_Temp
  4509. return jsonify({"SHT11_Temp":SHT11_Temp,
  4510. "SHT11_Humidity":SHT11_Humidity,
  4511. "Soil_Temp":Soil_Temp
  4512. })
  4513. else:
  4514. pass
  4515. @main.route('/dry_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4516. def dry_UltraSonic(dtid):
  4517. if request.method == 'GET':
  4518. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  4519. UltraSonic = tank_UltraSonic.UltraSonic
  4520. return jsonify({"UltraSonic":UltraSonic
  4521. })
  4522. else:
  4523. pass
  4524. @main.route('/dry_input_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4525. def dry_input_UltraSonic(dtid):
  4526. if request.method == 'GET':
  4527. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + dtid).order_by(text('datetime desc')).first()
  4528. UltraSonic = input_UltraSonic.UltraSonic
  4529. return jsonify({"UltraSonic":UltraSonic
  4530. })
  4531. else:
  4532. pass
  4533. @main.route('/dry_output_UltraSonic_<dtid>', methods=['GET', 'POST'])
  4534. def dry_output_UltraSonic(dtid):
  4535. if request.method == 'GET':
  4536. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + dtid).order_by(text('datetime desc')).first()
  4537. UltraSonic = output_UltraSonic.UltraSonic
  4538. return jsonify({"UltraSonic":UltraSonic
  4539. })
  4540. else:
  4541. pass
  4542. @main.route('/ferment_SHT11_<ftid>', methods=['GET', 'POST'])
  4543. def ferment_SHT11(ftid):
  4544. if request.method == 'GET':
  4545. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4546. SHT11_Temp = tank_SHT11.SHT11_Temp
  4547. return jsonify({"SHT11_Temp":SHT11_Temp
  4548. })
  4549. else:
  4550. pass
  4551. @main.route('/ferment_WaterLevel_<ftid>', methods=['GET', 'POST'])
  4552. def ferment_WaterLevel(ftid):
  4553. if request.method == 'GET':
  4554. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4555. WaterLevel = tank_WaterLevel.WaterLevel
  4556. return jsonify({"WaterLevel":WaterLevel
  4557. })
  4558. else:
  4559. pass
  4560. @main.route('/ferment_WaterIn_<ftid>', methods=['GET', 'POST'])
  4561. def ferment_WaterIn(ftid):
  4562. if request.method == 'GET':
  4563. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4564. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  4565. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4566. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4567. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4568. WaterLevel = tank_WaterLevel.WaterLevel
  4569. return jsonify({"UltraSonic":UltraSonic,
  4570. "WaterLevel":WaterLevel
  4571. })
  4572. else:
  4573. pass
  4574. @main.route('/ferment_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4575. def ferment_UltraSonic(ftid):
  4576. if request.method == 'GET':
  4577. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4578. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  4579. return jsonify({"UltraSonic":UltraSonic
  4580. })
  4581. else:
  4582. pass
  4583. '''
  4584. @main.route('/ferment_LiDAR_<ftid>', methods=['GET', 'POST'])
  4585. def ferment_LiDAR(ftid):
  4586. if request.method == 'GET':
  4587. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4588. LiDAR = tank_LiDAR.LiDAR
  4589. return jsonify({"LiDAR":LiDAR
  4590. })
  4591. else:
  4592. pass
  4593. '''
  4594. @main.route('/ferment_input_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4595. def ferment_input_UltraSonic_(ftid):
  4596. if request.method == 'GET':
  4597. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + ftid).order_by(text('datetime desc')).first()
  4598. UltraSonic = input_UltraSonic.UltraSonic
  4599. return jsonify({"UltraSonic":UltraSonic
  4600. })
  4601. else:
  4602. pass
  4603. @main.route('/ferment_output_UltraSonic_<ftid>', methods=['GET', 'POST'])
  4604. def ferment_output_UltraSonic_(ftid):
  4605. if request.method == 'GET':
  4606. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + ftid).order_by(text('datetime desc')).first()
  4607. UltraSonic = output_UltraSonic.UltraSonic
  4608. return jsonify({"UltraSonic":UltraSonic
  4609. })
  4610. else:
  4611. pass
  4612. @main.route('/ferment_watertesting_<tid>', methods=['GET', 'POST'])
  4613. def ferment_watertesting(tid):
  4614. if request.method == 'GET':
  4615. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4616. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4617. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4618. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  4619. PH = tank_PH.PH
  4620. ORP = tank_ORP.ORP
  4621. DO = tank_DO.DO
  4622. EC = tank_EC.EC
  4623. return jsonify({"PH":PH,
  4624. "ORP":ORP,
  4625. "DO":DO,
  4626. "EC":EC,
  4627. })
  4628. '''
  4629. @main.route('/ferment_PressureWaterLevel_<ftid>', methods=['GET', 'POST'])
  4630. def ferment_PressureWaterLevel(ftid):
  4631. if request.method == 'GET':
  4632. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  4633. PressureWaterLevel = float(tank_PressureWaterLevel.PressureWaterLevel)
  4634. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4635. print("PressureWaterLevel_start: ", PressureWaterLevel)
  4636. return jsonify({"PressureWaterLevel":PressureWaterLevel
  4637. })
  4638. # 此段刪除
  4639. while int(PressureWaterLevel) < int(testing_water_height):
  4640. tank_water_status = 'NO'
  4641. time.sleep(3)
  4642. # print(ferment_water_height(testing_water_height))
  4643. # [目前桶內水位高度]發酵槽_感測器_壓力式水位計
  4644. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  4645. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  4646. print("-- MySQL --")
  4647. print("tank_PressureWaterLevel: ", tank_PressureWaterLevel)
  4648. # tank_water_height()
  4649. # print("PressureWaterLevel_while: ", PressureWaterLevel)
  4650. ferment_water_height(testing_water_height)
  4651. return jsonify({"testing_water_height":testing_water_height,
  4652. "tank_water_status":tank_water_status
  4653. })
  4654. else:
  4655. tank_water_status = 'OK'
  4656. print("PressureWaterLevel_else: ", PressureWaterLevel)
  4657. return jsonify({"testing_water_height":testing_water_height,
  4658. "tank_water_status":tank_water_status
  4659. })
  4660. '''
  4661. '''
  4662. def tank_water_height():
  4663. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  4664. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  4665. print("tank_water_height", PressureWaterLevel)
  4666. return PressureWaterLevel
  4667. '''
  4668. @main.route('/loading/R<rtid>', methods=['GET', 'POST'])
  4669. def R_loading(rtid):
  4670. if request.method == 'GET':
  4671. # 致動器_中水桶
  4672. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+rtid).order_by(text('datetime desc')).first()
  4673. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  4674. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  4675. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  4676. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  4677. return jsonify({"tank_solenoid_water_in":tank_solenoid_water_in,
  4678. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  4679. "tank_solenoid_water_out":tank_solenoid_water_out,
  4680. "tank_pump_reclaimed_out":tank_pump_reclaimed_out
  4681. })
  4682. else:
  4683. pass
  4684. @main.route('/loading/SO<sotid>', methods=['GET', 'POST'])
  4685. def SO_loading(sotid):
  4686. if request.method == 'GET':
  4687. # 致動器_脫皮機_ALL
  4688. output_actuator = colorselect_output_actuator.query.filter_by(tank_num='SO'+sotid).order_by(text('datetime desc')).first()
  4689. output_vacuum = output_actuator.vacuum
  4690. return jsonify({"output_vacuum":output_vacuum
  4691. })
  4692. else:
  4693. pass
  4694. @main.route('/loading/S<stid>', methods=['GET', 'POST'])
  4695. def S_loading(stid):
  4696. if request.method == 'GET':
  4697. # 致動器_色選機
  4698. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4699. tank_vacuum = tank_actuator.vacuum
  4700. tank_motor = tank_actuator.motor
  4701. tank_nozzle = tank_actuator.nozzle
  4702. # 致動器_超音波感測器colorselect_tank_UltraSonic
  4703. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4704. UltraSonic = tank_UltraSonic.UltraSonic
  4705. # 致動器_顏色感測器
  4706. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  4707. color = tank_color.color
  4708. return jsonify({"tank_vacuum":tank_vacuum,
  4709. "tank_motor":tank_motor,
  4710. "tank_nozzle":tank_nozzle,
  4711. "UltraSonic":UltraSonic,
  4712. "color":color
  4713. })
  4714. else:
  4715. pass
  4716. @main.route('/loading/PO<potid>', methods=['GET', 'POST'])
  4717. def PO_loading(potid):
  4718. if request.method == 'GET':
  4719. # 致動器_脫皮機_ALL
  4720. output_actuator = peel_output_actuator.query.filter_by(tank_num='PO'+potid).order_by(text('datetime desc')).first()
  4721. output_vacuum = output_actuator.vacuum
  4722. return jsonify({"output_vacuum":output_vacuum
  4723. })
  4724. else:
  4725. pass
  4726. @main.route('/loading/P<ptid>', methods=['GET', 'POST'])
  4727. def P_loading(ptid):
  4728. if request.method == 'GET':
  4729. # 致動器_脫皮機_ALL
  4730. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+ptid).order_by(text('datetime desc')).first()
  4731. tank_vacuum = tank_actuator.vacuum
  4732. tank_motor = tank_actuator.motor
  4733. return jsonify({"tank_vacuum":tank_vacuum,
  4734. "tank_motor":tank_motor})
  4735. else:
  4736. pass
  4737. @main.route('/loading/CO<cotid>', methods=['GET', 'POST'])
  4738. def CO_loading(cotid):
  4739. if request.method == 'GET':
  4740. output_actuator = clean_output_actuator.query.filter_by(tank_num='CO'+cotid).order_by(text('datetime desc')).first()
  4741. output_vacuum = output_actuator.vacuum
  4742. return jsonify({"output_vacuum":output_vacuum
  4743. })
  4744. else:
  4745. pass
  4746. @main.route('/loading/C<ctid>', methods=['GET', 'POST'])
  4747. def C_loading(ctid):
  4748. if request.method == 'GET':
  4749. # 致動器_浮選清洗_ALL
  4750. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4751. tank_vacuum = tank_actuator.vacuum
  4752. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  4753. tank_motor = tank_actuator.motor
  4754. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  4755. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  4756. tank_pump_water_in = tank_actuator.pump_water_in
  4757. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  4758. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  4759. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  4760. tank_pump_disinfect = tank_actuator.pump_disinfect
  4761. tank_diskvalve = tank_actuator.diskvalve
  4762. # 感測器_浮選清洗_超音波感測器
  4763. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4764. UltraSonic = tank_UltraSonic.UltraSonic
  4765. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4766. Encoder = tank_Encoder.Encoder
  4767. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4768. tankTurbidity = tank_Turbidity.tankTurbidity
  4769. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  4770. filterTurbidity = filter_Turbidity.filterTurbidity
  4771. # tank_pump_waterInput = tank_actuator.pump_waterInput
  4772. # tank_pump_waterL2L3 = tank_actuator.pump_waterL2L3
  4773. # tank_pump_waterL4L5 = tank_actuator.pump_waterL4L5
  4774. # tank_solenoid_waterL2L3 = tank_actuator.solenoid_waterL2L3
  4775. # tank_solenoid_waterL4L5 = tank_actuator.solenoid_waterL4L5
  4776. # tank_stepping_motor = tank_actuator.stepping_motor
  4777. return jsonify({"UltraSonic":UltraSonic,
  4778. "Encoder":Encoder,
  4779. "tankTurbidity":tankTurbidity,
  4780. "filterTurbidity":filterTurbidity,
  4781. "tank_vacuum":tank_vacuum,
  4782. "tank_threewayvalve_input":tank_threewayvalve_input,
  4783. "tank_motor":tank_motor,
  4784. "tank_solenoid_reclaimed_in":tank_solenoid_reclaimed_in,
  4785. "tank_solenoid_water_in":tank_solenoid_water_in,
  4786. "tank_pump_water_in":tank_pump_water_in,
  4787. "tank_solenoid_water_out":tank_solenoid_water_out,
  4788. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  4789. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  4790. "tank_pump_disinfect":tank_pump_disinfect,
  4791. "tank_diskvalve":tank_diskvalve
  4792. })
  4793. else:
  4794. pass
  4795. @main.route('/loading/F<ftid>', methods=['GET', 'POST'])
  4796. def F_loading(ftid):
  4797. if request.method == 'GET':
  4798. # 致動器_發酵槽_ALL
  4799. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4800. tank_vacuum = tank_actuator.vacuum
  4801. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  4802. tank_diskvalve = tank_actuator.diskvalve
  4803. solenoid_tank_pump = tank_actuator.solenoid_tank_pump
  4804. tank_solenoid_disinfect = tank_actuator.solenoid_tank_disinfect
  4805. outer_solenoid_water = tank_actuator.solenoid_outer_water
  4806. tank_solenoid_water_in = tank_actuator.solenoid_tank_water_in
  4807. tank_solenoid_water_out = tank_actuator.solenoid_tank_water_out
  4808. tank_pump_sensor = tank_actuator.pump_sensor
  4809. outer_threewayvalve_float = tank_actuator.threewayvalve_outer_float
  4810. tank_motor = tank_actuator.motor
  4811. tank_heater1 = tank_actuator.heater1
  4812. tank_heater2 = tank_actuator.heater2
  4813. tank_temp_enable = tank_actuator.temp_enable
  4814. tank_temp = tank_actuator.temp
  4815. # 感測器_發酵桶_SHT11
  4816. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4817. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  4818. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  4819. # 感測器_發酵桶_二氧化碳
  4820. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4821. CO2 = float(tank_CO2.CO2)
  4822. # 感測器_發酵桶_酸鹼值
  4823. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4824. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4825. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4826. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4827. PH = float(tank_PH.PH)
  4828. ORP = float(tank_ORP.ORP)
  4829. DO = float(tank_DO.DO)
  4830. EC = float(tank_EC.EC)
  4831. # 感測器_發酵桶_氣壓
  4832. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4833. PA = float(tank_PA.PA)
  4834. # 感測器_發酵桶_超音波感測器
  4835. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4836. UltraSonic= (float(tank_UltraSonic.UltraSonic))
  4837. # 感測器_發酵桶_保溫夾層水位計
  4838. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4839. WaterLevel = tank_WaterLevel.WaterLevel
  4840. # 感測器_發酵桶_咖啡生豆高度
  4841. # tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4842. # LiDAR = tank_LiDAR.LiDAR
  4843. # 感測器_發酵桶_水位高度
  4844. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4845. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  4846. # 感測器_發酵桶_馬達編碼器
  4847. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  4848. motorEncoder = tank_motorEncoder.motorEncoder
  4849. return jsonify({"SHT11_Temp": SHT11_Temp,
  4850. "SHT11_Humidity":SHT11_Humidity,
  4851. "CO2":CO2,
  4852. "PH":PH,
  4853. "ORP":ORP,
  4854. "DO":DO,
  4855. "EC":EC,
  4856. "PA":PA,
  4857. "WaterLevel":WaterLevel,
  4858. "UltraSonic":UltraSonic,
  4859. "motorEncoder":motorEncoder,
  4860. "tank_vacuum":tank_vacuum,
  4861. "tank_threewayvalve_input":tank_threewayvalve_input,
  4862. "tank_diskvalve":tank_diskvalve,
  4863. "solenoid_tank_pump":solenoid_tank_pump,
  4864. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  4865. "outer_solenoid_water":outer_solenoid_water,
  4866. "tank_solenoid_water_in":tank_solenoid_water_in,
  4867. "tank_solenoid_water_out":tank_solenoid_water_out,
  4868. "tank_pump_sensor":tank_pump_sensor,
  4869. "outer_threewayvalve_float":outer_threewayvalve_float,
  4870. "tank_motor":tank_motor,
  4871. "tank_heater1":tank_heater1,
  4872. "tank_heater2":tank_heater2,
  4873. "tank_temp_enable":tank_temp_enable,
  4874. "tank_temp":tank_temp
  4875. })
  4876. else:
  4877. pass
  4878. @main.route('/loading/FI<fitid>', methods=['GET', 'POST'])
  4879. def FI_loading(fitid):
  4880. if request.method == 'GET':
  4881. input_actuator = ferment_input_actuator.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  4882. input_vacuum = input_actuator.vacuum
  4883. input_sensor = ferment_input_UltraSonic.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  4884. # input_UltraSonic = float("{:.2f}".format(34.6 - float(input_sensor.UltraSonic)))
  4885. input_UltraSonic = float(input_sensor.UltraSonic)
  4886. return jsonify({"input_UltraSonic":input_UltraSonic,
  4887. "input_vacuum":input_vacuum
  4888. })
  4889. else:
  4890. pass
  4891. @main.route('/loading/FO<fotid>', methods=['GET', 'POST'])
  4892. def FO_loading(fotid):
  4893. if request.method == 'GET':
  4894. output_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  4895. output_vacuum = output_actuator.vacuum
  4896. output_sensor = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  4897. output_UltraSonic = output_sensor.UltraSonic
  4898. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+fotid).order_by(text('datetime desc')).first()
  4899. LiDAR = tank_LiDAR.LiDAR
  4900. return jsonify({"output_UltraSonic":output_UltraSonic,
  4901. "output_vacuum":output_vacuum,
  4902. "LiDAR":LiDAR
  4903. })
  4904. else:
  4905. pass
  4906. @main.route('/loading/DI<ditid>', methods=['GET', 'POST'])
  4907. def DI_loading(ditid):
  4908. if request.method == 'GET':
  4909. input_actuator = dry_input_brake.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  4910. input_vacuum = input_actuator.vacuum
  4911. input_sensor = dry_input_sensor.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  4912. input_UltraSonic = input_sensor.UltraSonic
  4913. return jsonify({"input_UltraSonic":input_UltraSonic,
  4914. "input_vacuum":input_vacuum
  4915. })
  4916. else:
  4917. pass
  4918. @main.route('/loading/DO<dotid>', methods=['GET', 'POST'])
  4919. def DO_loading(dotid):
  4920. if request.method == 'GET':
  4921. output_actuator = dry_output_brake.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  4922. output_vacuum = output_actuator.vacuum
  4923. output_sensor = dry_output_sensor.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  4924. output_UltraSonic = output_sensor.UltraSonic
  4925. return jsonify({"output_vacuum":output_vacuum,
  4926. "output_UltraSonic":output_UltraSonic
  4927. })
  4928. else:
  4929. pass
  4930. @main.route('/loading/D<dtid>', methods=['GET', 'POST'])
  4931. def D_loading(dtid):
  4932. if request.method == 'GET':
  4933. # 感測器_乾燥桶_超音波感測器
  4934. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4935. UltraSonic = tank_UltraSonic.UltraSonic
  4936. # 感測器_乾燥桶_SHT11
  4937. tonow = dt.now()
  4938. # 感測器_乾燥桶_SHT11
  4939. print("tonow: ", tonow)
  4940. time_del = timedelta(minutes=-60)
  4941. bias_date_time = tonow + time_del
  4942. # print(dt.now() >= dt(2021,11,29,17,35,36))
  4943. # bias_min = tonow.minute + 3
  4944. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(dtid))\
  4945. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  4946. .order_by(text('datetime desc')).first()
  4947. 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'>
  4948. print("hasattr tank_SHT11: ", hasattr(object, 'tank_SHT11'))
  4949. print("hasattr tank_SHT11.SHT11_Temp: ", hasattr(object, 'tank_SHT11.SHT11_Temp'))
  4950. try:
  4951. SHT11_Temp = tank_SHT11.SHT11_Temp
  4952. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4953. except AttributeError:
  4954. SHT11_Temp = " — "
  4955. SHT11_Humidity = " — "
  4956. # if not hasattr(object, 'tank_SHT11.SHT11_Temp'):
  4957. # SHT11_Temp = " — "
  4958. # SHT11_Humidity = " — "
  4959. # else:
  4960. # SHT11_Temp = tank_SHT11.SHT11_Temp
  4961. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4962. # tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4963. # SHT11_Temp = tank_SHT11.SHT11_Temp
  4964. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  4965. # 感測器_乾燥桶_土壤三合一
  4966. tank_Soil = dry_tank_Soil.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4967. soil_Temp = tank_Soil.soil_Temp
  4968. soil_Humidity = tank_Soil.soil_Humidity
  4969. soil_EC = tank_Soil.soil_EC
  4970. # 感測器_乾燥桶_氣壓
  4971. tank_PA = dry_tank_PA.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4972. PA = tank_PA.PA
  4973. # 致動器_乾燥桶_ALL
  4974. tank_brake = dry_tank_brake.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  4975. # tank_vacuum = 'ON' if i<100 else 2 if i>100 else 0
  4976. tank_vacuum = tank_brake.vacuum
  4977. tank_threewayvalve_input = tank_brake.threewayvalve_input
  4978. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  4979. tank_diskvalve = tank_brake.diskvalve
  4980. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  4981. tank_solenoid_water = tank_brake.solenoid_water
  4982. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  4983. tank_motor = tank_brake.motor
  4984. tank_blower = tank_brake.blower
  4985. tank_heater1 = tank_brake.heater1
  4986. tank_heater2 = tank_brake.heater2
  4987. tank_temp1_enable = tank_brake.temp1_enable
  4988. tank_temp1 = tank_brake.temp1
  4989. #return jsonify({"peeling": peeling_rpm})
  4990. '''
  4991. info = psutil.virtual_memory()
  4992. print('記憶體使用: ', psutil.Process(os.getpid()).memory_info().rss)
  4993. # print('總記憶體: ', info.total)
  4994. print('記憶體占比: ', info.percent)
  4995. print('cpu 個數: ', psutil.cpu_count())
  4996. '''
  4997. print("SHT11_Temp", SHT11_Temp)
  4998. return jsonify({"UltraSonic":UltraSonic,
  4999. "SHT11_Temp": SHT11_Temp,
  5000. "SHT11_Humidity":SHT11_Humidity,
  5001. "soil_Temp":soil_Temp,
  5002. "soil_Humidity":soil_Humidity,
  5003. "soil_EC":soil_EC,
  5004. "PA":PA,
  5005. "tank_vacuum":tank_vacuum,
  5006. "tank_threewayvalve_input":tank_threewayvalve_input,
  5007. "tank_threewayvalve_bean":tank_threewayvalve_bean,
  5008. "tank_diskvalve":tank_diskvalve,
  5009. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  5010. "tank_solenoid_water":tank_solenoid_water,
  5011. "tank_solenoid_outer_water":tank_solenoid_outer_water,
  5012. "tank_motor":tank_motor,
  5013. "tank_blower":tank_blower,
  5014. "tank_heater1":tank_heater1,
  5015. "tank_heater2":tank_heater2,
  5016. "tank_temp1_enable":tank_temp1_enable,
  5017. "tank_temp1":tank_temp1
  5018. })
  5019. else:
  5020. pass
  5021. @main.route('/index_new')
  5022. def index_new():
  5023. if 'id' in session and 'uname' in session and 'status' in session:
  5024. username = session['uname']
  5025. status = session['status']
  5026. if status == 9:
  5027. return render_template('signin_disable.html', **locals())
  5028. elif status == 8:
  5029. return render_template('signin_new.html', **locals())
  5030. else:
  5031. return render_template('oops.html', **locals())
  5032. return render_template('index_new.html', title='Smart Coffee', **locals())
  5033. @main.route('/user/<name>')
  5034. def user(name):
  5035. return render_template('hello.html', name=name)
  5036. '''
  5037. @main.route('/plot.png')
  5038. def plot():
  5039. # 重新整理會有問題
  5040. # 圖的寬和高
  5041. fig = plt.figure()
  5042. # 在圖中新增子圖, 通常多個圖才會用到?
  5043. axis = fig.add_subplot(1, 1, 1)
  5044. # x、 軸資料
  5045. xs = range(100)
  5046. ys = [random.randint(1, 50) for x in xs]
  5047. axis.plot(xs, ys)
  5048. canvas = FigureCanvas(fig)
  5049. output = io.BytesIO()
  5050. canvas.print_png(output)
  5051. response = make_response(output.getvalue())
  5052. response.mimetype = 'image/png'
  5053. return response
  5054. '''
  5055. @main.route('/chart_<tank>/<sensor_name>/<tid>', methods=['GET', 'POST'])
  5056. def chart_D(tank, sensor_name, tid):
  5057. if request.method == 'GET':
  5058. if 'id' in session and 'uname' in session and 'status' in session:
  5059. username = session['uname']
  5060. status = session['status']
  5061. if status == 9:
  5062. return render_template('signin_disable.html', params=locals())
  5063. elif status == 8:
  5064. return render_template('signin_new.html', params=locals())
  5065. else:
  5066. return render_template('oops.html', params=locals())
  5067. if tank == 'DI':
  5068. return render_template('sensor_chart_DI.html', title='[圖表]' + tank + tid + '乾燥入料儲豆槽', **locals())
  5069. elif tank == 'DO':
  5070. return render_template('sensor_chart_DO.html', title='[圖表]' + tank + tid + '乾燥出料儲豆槽', **locals())
  5071. elif tank == 'FI':
  5072. return render_template('sensor_chart_FI.html', title='[圖表]' + tank + tid + '發酵入料儲豆槽', **locals())
  5073. elif tank == 'FO':
  5074. return render_template('sensor_chart_FO.html', title='[圖表]' + tank + tid + '發酵出料儲豆槽', **locals())
  5075. elif tank == 'F':
  5076. return render_template('sensor_chart_F.html', title='[圖表]' + tank + tid + '發酵槽', **locals())
  5077. else:
  5078. return render_template('sensor_chart_D.html', title='[圖表]' + tank + tid + '乾燥槽', **locals())
  5079. elif request.method == 'POST':
  5080. if 'id' in session and 'uname' in session and 'status' in session:
  5081. username = session['uname']
  5082. status = session['status']
  5083. if status == 9:
  5084. return render_template('signin_disable.html', **locals())
  5085. elif status == 8:
  5086. return render_template('signin_new.html', **locals())
  5087. else:
  5088. return render_template('oops.html', **locals())
  5089. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  5090. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  5091. sensor_name = request.values['sensors']
  5092. print('sensor_name:', sensor_name)
  5093. # 判斷資料索取區間 起<迄
  5094. if starttime < endtime :
  5095. # print('starttime endtime:', starttime, endtime)
  5096. # print('TF:', starttime<endtime ) # 可以比較 起<迄
  5097. # [html]2021-07-19T09:00 轉換成 [python]datetime.datetime(2021, 07, 19, 09, 00, 00)
  5098. start_YY = starttime[:4] # '2021'
  5099. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5100. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5101. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5102. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5103. start_ss = 0
  5104. end_YY = endtime[:4] # '2021'
  5105. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5106. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5107. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5108. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5109. end_ss = 0
  5110. time_range = []
  5111. temp_range = []
  5112. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5113. plt.switch_backend('agg')
  5114. plt.figure()
  5115. if tank == 'DI':
  5116. print('DI')
  5117. if sensor_name == 'UltraSonic':
  5118. for d in db.session.query(dry_input_sensor) \
  5119. .filter_by(tank_num='DI' + tid) \
  5120. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_input_sensor.datetime) \
  5121. .filter(dry_input_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5122. .order_by(dry_input_sensor.datetime):
  5123. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5124. time_range.append(str(d.datetime))
  5125. temp_range.append(float(d.UltraSonic))
  5126. print('time_range:', time_range)
  5127. print('temp_range:', temp_range)
  5128. return render_template('sensor_chart_DI.html', **locals())
  5129. elif tank == 'DO':
  5130. print('DO')
  5131. if sensor_name == 'UltraSonic':
  5132. for d in db.session.query(dry_output_sensor) \
  5133. .filter_by(tank_num='DO' + tid) \
  5134. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_output_sensor.datetime) \
  5135. .filter(dry_output_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5136. .order_by(dry_output_sensor.datetime):
  5137. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5138. time_range.append(str(d.datetime))
  5139. temp_range.append(float(d.UltraSonic))
  5140. print('time_range:', time_range)
  5141. print('temp_range:', temp_range)
  5142. return render_template('sensor_chart_DO.html', **locals())
  5143. elif tank == 'D':
  5144. print('D')
  5145. if sensor_name == 'SHT11_Temp':
  5146. for d in db.session.query(dry_tank_SHT11) \
  5147. .filter_by(tank_num='D' + tid) \
  5148. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  5149. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5150. .order_by(dry_tank_SHT11.datetime):
  5151. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5152. time_range.append(str(d.datetime))
  5153. temp_range.append(float(d.SHT11_Temp))
  5154. # 畫出 x 軸基準線
  5155. # plt.axhline(28.5, color= 'r')
  5156. elif sensor_name == 'SHT11_Humidity':
  5157. for d in db.session.query(dry_tank_SHT11) \
  5158. .filter_by(tank_num='D' + tid) \
  5159. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  5160. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5161. .order_by(dry_tank_SHT11.datetime):
  5162. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5163. time_range.append(str(d.datetime))
  5164. temp_range.append(float(d.SHT11_Humidity))
  5165. elif sensor_name == 'UltraSonic':
  5166. for d in db.session.query(dry_tank_UltraSonic) \
  5167. .filter_by(tank_num='D' + tid) \
  5168. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5169. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5170. .order_by(dry_tank_UltraSonic.datetime):
  5171. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5172. time_range.append(str(d.datetime))
  5173. temp_range.append(float(d.UltraSonic))
  5174. elif sensor_name == 'PA':
  5175. for d in db.session.query(dry_tank_PA) \
  5176. .filter_by(tank_num='D' + tid) \
  5177. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_PA.datetime) \
  5178. .filter(dry_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5179. .order_by(dry_tank_PA.datetime):
  5180. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5181. time_range.append(str(d.datetime))
  5182. temp_range.append(float(d.PA))
  5183. elif sensor_name == 'soil_Temp':
  5184. for d in db.session.query(dry_tank_Soil) \
  5185. .filter_by(tank_num='D' + tid) \
  5186. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5187. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5188. .order_by(dry_tank_Soil.datetime):
  5189. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5190. time_range.append(str(d.datetime))
  5191. temp_range.append(float(d.soil_Temp))
  5192. # 畫出 x 軸基準線
  5193. plt.axhline(28.5, color= 'r')
  5194. elif sensor_name == 'soil_Humidity':
  5195. for d in db.session.query(dry_tank_Soil) \
  5196. .filter_by(tank_num='D' + tid) \
  5197. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5198. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5199. .order_by(dry_tank_Soil.datetime):
  5200. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5201. time_range.append(str(d.datetime))
  5202. temp_range.append(float(d.soil_Humidity))
  5203. elif sensor_name == 'soil_EC':
  5204. for d in db.session.query(dry_tank_Soil) \
  5205. .filter_by(tank_num='D' + tid) \
  5206. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  5207. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5208. .order_by(dry_tank_Soil.datetime):
  5209. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5210. time_range.append(str(d.datetime))
  5211. temp_range.append(float(d.soil_EC))
  5212. print('time_range:', time_range)
  5213. print('temp_range:', temp_range)
  5214. return render_template('sensor_chart_D.html', **locals())
  5215. elif tank == 'FI':
  5216. print('FI')
  5217. if sensor_name == 'UltraSonic':
  5218. for d in db.session.query(ferment_input_UltraSonic) \
  5219. .filter_by(tank_num='FI' + tid) \
  5220. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_input_UltraSonic.datetime) \
  5221. .filter(ferment_input_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5222. .order_by(ferment_input_UltraSonic.datetime):
  5223. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5224. time_range.append(str(d.datetime))
  5225. temp_range.append(float(d.UltraSonic))
  5226. print('time_range:', time_range)
  5227. print('temp_range:', temp_range)
  5228. return render_template('sensor_chart_FI.html', **locals())
  5229. elif tank == 'FO':
  5230. print('FO')
  5231. if sensor_name == 'UltraSonic':
  5232. for d in db.session.query(ferment_output_UltraSonic) \
  5233. .filter_by(tank_num='FO' + tid) \
  5234. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_output_UltraSonic.datetime) \
  5235. .filter(ferment_output_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5236. .order_by(ferment_output_UltraSonic.datetime):
  5237. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5238. time_range.append(str(d.datetime))
  5239. temp_range.append(float(d.UltraSonic))
  5240. print('time_range:', time_range)
  5241. print('temp_range:', temp_range)
  5242. return render_template('sensor_chart_FO.html', **locals())
  5243. elif tank == 'F':
  5244. print('F')
  5245. if sensor_name == 'LiDAR':
  5246. for d in db.session.query(ferment_tank_LiDAR) \
  5247. .filter_by(tank_num='F' + tid) \
  5248. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_LiDAR.datetime) \
  5249. .filter(ferment_tank_LiDAR.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5250. .order_by(ferment_tank_LiDAR.datetime):
  5251. time_range.append(str(d.datetime))
  5252. temp_range.append(float(d.LiDAR))
  5253. elif sensor_name == 'motorEncoder':
  5254. print('sensor_name == motorEncoder')
  5255. for d in db.session.query(ferment_tank_motorEncoder) \
  5256. .filter_by(tank_num='F' + tid) \
  5257. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_motorEncoder.datetime) \
  5258. .filter(ferment_tank_motorEncoder.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5259. .order_by(ferment_tank_motorEncoder.datetime):
  5260. time_range.append(str(d.datetime))
  5261. temp_range.append(float(d.motorEncoder))
  5262. print('time_range: ' + time_range)
  5263. print('temp_range: ' + temp_range)
  5264. elif sensor_name == 'PressureWaterLevel':
  5265. for d in db.session.query(ferment_tank_PressureWaterLevel) \
  5266. .filter_by(tank_num='F' + tid) \
  5267. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  5268. .filter(ferment_tank_PressureWaterLevel.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5269. .order_by(ferment_tank_PressureWaterLevel.datetime):
  5270. time_range.append(str(d.datetime))
  5271. temp_range.append('{:.2f}'.format(float(d.PressureWaterLevel)))
  5272. elif sensor_name == 'SHT11_Temp':
  5273. for d in db.session.query(ferment_tank_SHT11) \
  5274. .filter_by(tank_num='F' + tid) \
  5275. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  5276. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5277. .order_by(ferment_tank_SHT11.datetime):
  5278. time_range.append(str(d.datetime))
  5279. temp_range.append(float(d.SHT11_Temp))
  5280. elif sensor_name == 'SHT11_Humidity':
  5281. for d in db.session.query(ferment_tank_SHT11) \
  5282. .filter_by(tank_num='F' + tid) \
  5283. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_SHT11.datetime) \
  5284. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5285. .order_by(ferment_tank_SHT11.datetime):
  5286. time_range.append(str(d.datetime))
  5287. temp_range.append(float(d.SHT11_Humidity))
  5288. elif sensor_name == 'CO2':
  5289. for d in db.session.query(ferment_tank_CO2) \
  5290. .filter_by(tank_num='F' + tid) \
  5291. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_CO2.datetime) \
  5292. .filter(ferment_tank_CO2.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5293. .order_by(ferment_tank_CO2.datetime):
  5294. time_range.append(str(d.datetime))
  5295. temp_range.append(float(d.CO2))
  5296. elif sensor_name == 'PH':
  5297. for d in db.session.query(ferment_tank_PH) \
  5298. .filter_by(tank_num='F' + tid) \
  5299. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PH.datetime) \
  5300. .filter(ferment_tank_PH.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5301. .order_by(ferment_tank_PH.datetime):
  5302. time_range.append(str(d.datetime))
  5303. temp_range.append(float(d.PH))
  5304. elif sensor_name == 'ORP':
  5305. for d in db.session.query(ferment_tank_ORP) \
  5306. .filter_by(tank_num='F' + tid) \
  5307. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_ORP.datetime) \
  5308. .filter(ferment_tank_ORP.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5309. .order_by(ferment_tank_ORP.datetime):
  5310. time_range.append(str(d.datetime))
  5311. temp_range.append(float(d.ORP))
  5312. elif sensor_name == 'DO':
  5313. for d in db.session.query(ferment_tank_DO) \
  5314. .filter_by(tank_num='F' + tid) \
  5315. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_DO.datetime) \
  5316. .filter(ferment_tank_DO.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5317. .order_by(ferment_tank_DO.datetime):
  5318. time_range.append(str(d.datetime))
  5319. temp_range.append(float(d.DO))
  5320. elif sensor_name == 'EC':
  5321. for d in db.session.query(ferment_tank_EC) \
  5322. .filter_by(tank_num='F' + tid) \
  5323. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_EC.datetime) \
  5324. .filter(ferment_tank_EC.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5325. .order_by(ferment_tank_EC.datetime):
  5326. time_range.append(str(d.datetime))
  5327. temp_range.append(float(d.EC))
  5328. elif sensor_name == 'PA':
  5329. for d in db.session.query(ferment_tank_PA) \
  5330. .filter_by(tank_num='F' + tid) \
  5331. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PA.datetime) \
  5332. .filter(ferment_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5333. .order_by(ferment_tank_PA.datetime):
  5334. time_range.append(str(d.datetime))
  5335. temp_range.append(float(d.PA))
  5336. print('time_range:', time_range)
  5337. print('temp_range:', temp_range)
  5338. return render_template('sensor_chart_F.html', **locals())
  5339. '''
  5340. # 設定 x 軸資料、y 軸資料、折線顏色
  5341. plt.plot(time_range, temp_range, 'bo')
  5342. # x 軸標題 (中文無法顯示)
  5343. # plt.xlabel('time')
  5344. # plt.ylabel(sensor_name)
  5345. # x 軸 label 和垂直顯示, rotation='vertical'
  5346. plt.xticks(time_range, rotation='vertical' )
  5347. # 設定圖表標題
  5348. plt.title(sensor_name)
  5349. # 調整圖片與周圍的間距
  5350. plt.tight_layout()
  5351. # plt.show()
  5352. # 儲存圖片 應改為相對路徑
  5353. plt.savefig('C:/Users/USER/Rita/Coffee/CoffeeProject/app/static/img/new_plot.png')
  5354. '''
  5355. # 判斷資料索取區間 起>迄
  5356. else:
  5357. return render_template('sensor_chart_D.html', **locals())
  5358. '''
  5359. @main.route('/chart_DI/<sensor_name>/<tid>', methods=['GET', 'POST'])
  5360. def chart_DI(sensor_name, tid):
  5361. if request.method == 'GET':
  5362. return render_template('sensor_chart_DI.html', **locals())
  5363. elif request.method == 'POST':
  5364. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  5365. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  5366. sensor_name = request.values['sensors']
  5367. print('sensor_name:', sensor_name)
  5368. # 判斷資料索取區間 起<迄
  5369. if starttime < endtime :
  5370. start_YY = starttime[:4] # '2021'
  5371. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5372. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5373. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5374. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5375. start_ss = 0
  5376. end_YY = endtime[:4] # '2021'
  5377. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5378. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5379. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5380. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5381. end_ss = 0
  5382. time_range = []
  5383. temp_range = []
  5384. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5385. plt.switch_backend('agg')
  5386. plt.figure()
  5387. if sensor_name == 'UltraSonic':
  5388. for d in db.session.query(dry_input_sensor) \
  5389. .filter_by(tank_num='DI' + tid) \
  5390. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5391. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5392. .order_by(dry_tank_UltraSonic.datetime):
  5393. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5394. time_range.append(str(d.datetime))
  5395. temp_range.append(float(d.UltraSonic))
  5396. # 畫出 x 軸基準線
  5397. # plt.axhline(28.5, color= 'r')
  5398. print('time_range:', time_range)
  5399. print('temp_range:', temp_range)
  5400. return render_template('sensor_chart_DI.html', **locals())
  5401. # 判斷資料索取區間 起>迄
  5402. else:
  5403. return render_template('sensor_chart_DI.html', **locals())
  5404. @main.route('/chart_DO/<sensor_name>/<tid>', methods=['GET', 'POST'])
  5405. def chart_DO(sensor_name, tid):
  5406. if request.method == 'GET':
  5407. return render_template('sensor_chart_DO.html', **locals())
  5408. elif request.method == 'POST':
  5409. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  5410. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  5411. sensor_name = request.values['sensors']
  5412. print('sensor_name:', sensor_name)
  5413. # 判斷資料索取區間 起<迄
  5414. if starttime < endtime :
  5415. start_YY = starttime[:4] # '2021'
  5416. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  5417. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  5418. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  5419. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  5420. start_ss = 0
  5421. end_YY = endtime[:4] # '2021'
  5422. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  5423. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  5424. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  5425. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  5426. end_ss = 0
  5427. time_range = []
  5428. temp_range = []
  5429. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  5430. plt.switch_backend('agg')
  5431. plt.figure()
  5432. if sensor_name == 'UltraSonic':
  5433. for d in db.session.query(dry_input_sensor) \
  5434. .filter_by(tank_num='DO' + tid) \
  5435. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  5436. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  5437. .order_by(dry_tank_UltraSonic.datetime):
  5438. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  5439. time_range.append(str(d.datetime))
  5440. temp_range.append(float(d.UltraSonic))
  5441. # 畫出 x 軸基準線
  5442. # plt.axhline(28.5, color= 'r')
  5443. print('time_range:', time_range)
  5444. print('temp_range:', temp_range)
  5445. return render_template('sensor_chart_DO.html', **locals())
  5446. # 判斷資料索取區間 起>迄
  5447. else:
  5448. return render_template('sensor_chart_DO.html', **locals())
  5449. '''
  5450. # Rita 測試
  5451. # 乾燥桶感測器/致動器測試
  5452. # Rita 須加上 <tid> 區分桶號 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5453. @main.route('/dry_tank/1', methods=['GET'])
  5454. def dry_tank():
  5455. if request.method == 'GET':
  5456. return render_template('dry_tank.html')
  5457. @main.route('/clean', methods=['GET'])
  5458. def clean():
  5459. if 'id' in session and 'uname' in session and 'status' in session:
  5460. username = session['uname']
  5461. status = session['status']
  5462. if status == 9:
  5463. return render_template('signin_disable.html', params=locals())
  5464. elif status == 8:
  5465. return render_template('signin_new.html', params=locals())
  5466. else:
  5467. return render_template('oops.html', params=locals())
  5468. return render_template('clean.html', title='清洗貨櫃', **locals())
  5469. @main.route('/ferment', methods=['GET'])
  5470. def ferment():
  5471. if 'id' in session and 'uname' in session and 'status' in session:
  5472. username = session['uname']
  5473. status = session['status']
  5474. if status == 9:
  5475. return render_template('signin_disable.html', params=locals())
  5476. elif status == 8:
  5477. return render_template('signin_new.html', params=locals())
  5478. else:
  5479. return render_template('oops.html', params=locals())
  5480. return render_template('ferment.html', title='發酵貨櫃', **locals())
  5481. @main.route('/dry', methods=['GET'])
  5482. def dry():
  5483. if request.method == 'GET':
  5484. if 'id' in session and 'uname' in session and 'status' in session:
  5485. username = session['uname']
  5486. status = session['status']
  5487. if status == 9:
  5488. return render_template('signin_disable.html', params=locals())
  5489. elif status == 8:
  5490. return render_template('signin_new.html', params=locals())
  5491. else:
  5492. return render_template('oops.html', params=locals())
  5493. return render_template('dry.html', title='乾燥貨櫃', **locals())
  5494. @main.route('/reclaimedwater_tank/<tid>', methods=['GET', 'POST'])
  5495. def reclaimedwater_tank(tid):
  5496. if request.method == 'GET':
  5497. if 'id' in session and 'uname' in session and 'status' in session:
  5498. username = session['uname']
  5499. status = session['status']
  5500. if status == 9:
  5501. return render_template('signin_disable.html', params=locals())
  5502. elif status == 8:
  5503. return render_template('signin_new.html', params=locals())
  5504. else:
  5505. return render_template('oops.html', params=locals())
  5506. # 致動器_中水桶
  5507. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+tid).order_by(text('datetime desc')).first()
  5508. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  5509. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  5510. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  5511. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  5512. return render_template('reclaimedwater_tank.html', title='[操作] 中水桶操作介面', **locals())
  5513. elif request.method == 'POST':
  5514. pass
  5515. @main.route('/colorselect_container_tank/<tid>', methods=['GET', 'POST'])
  5516. def colorselect_container_tank(tid):
  5517. if request.method == 'GET':
  5518. if 'id' in session and 'uname' in session and 'status' in session:
  5519. username = session['uname']
  5520. status = session['status']
  5521. if status == 9:
  5522. return render_template('signin_disable.html', params=locals())
  5523. elif status == 8:
  5524. return render_template('signin_new.html', params=locals())
  5525. else:
  5526. return render_template('oops.html', params=locals())
  5527. # 致動器_色選機
  5528. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5529. tank_vacuum = tank_actuator.vacuum
  5530. tank_motor = tank_actuator.motor
  5531. tank_nozzle = tank_actuator.nozzle
  5532. # 致動器_超音波感測器colorselect_tank_UltraSonic
  5533. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5534. # 致動器_顏色感測器
  5535. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  5536. return render_template('colorselect_container_tank.html', title='[操作] S' + tid + ' 色選機操作介面', **locals())
  5537. elif request.method == 'POST':
  5538. pass
  5539. @main.route('/peel_container_tank/<tid>', methods=['GET', 'POST'])
  5540. def peel_container_tank(tid):
  5541. if request.method == 'GET':
  5542. if 'id' in session and 'uname' in session and 'status' in session:
  5543. username = session['uname']
  5544. status = session['status']
  5545. if status == 9:
  5546. return render_template('signin_disable.html', params=locals())
  5547. elif status == 8:
  5548. return render_template('signin_new.html', params=locals())
  5549. else:
  5550. return render_template('oops.html', params=locals())
  5551. # 致動器_脫皮機_ALL
  5552. # tank_num='P'+str(tid)
  5553. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5554. tank_vacuum = tank_actuator.vacuum
  5555. tank_motor = tank_actuator.motor
  5556. # 感測器_脫皮機出料儲豆槽_超音波高度
  5557. tank_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5558. # 感測器_脫皮機出料儲豆槽_馬達編碼器
  5559. tank_motorEncoder = peel_output_motorEncoder.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5560. return render_template('peel_container_tank.html', title='[操作] P' + tid + ' 脫皮機操作介面', **locals())
  5561. elif request.method == 'POST':
  5562. pass
  5563. @main.route('/peel_container/<tid>', methods=['GET', 'POST'])
  5564. def peel_container(tid):
  5565. if request.method == 'GET':
  5566. if 'id' in session and 'uname' in session and 'status' in session:
  5567. username = session['uname']
  5568. status = session['status']
  5569. if status == 9:
  5570. return render_template('signin_disable.html', params=locals())
  5571. elif status == 8:
  5572. return render_template('signin_new.html', params=locals())
  5573. else:
  5574. return render_template('oops.html', params=locals())
  5575. # 致動器_入料儲豆槽_真空吸料機
  5576. input_vacuum = peel_input_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5577. input_vacuum = input_vacuum.vacuum
  5578. # 致動器_脫皮機_ALL
  5579. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5580. tank_vacuum = tank_actuator.vacuum
  5581. tank_motor = tank_actuator.motor
  5582. # 致動器_出料儲豆槽_真空吸料機
  5583. output_vacuum = peel_output_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  5584. output_vacuum = output_vacuum.vacuum
  5585. return render_template('peel_container.html', title='脫皮機P' + tid + '總操作介面', **locals())
  5586. elif request.method == 'POST':
  5587. pass
  5588. @main.route('/clean_container/<tid>', methods=['GET', 'POST'])
  5589. def clean_container(tid):
  5590. if request.method == 'GET':
  5591. if 'id' in session and 'uname' in session and 'status' in session:
  5592. username = session['uname']
  5593. status = session['status']
  5594. if status == 9:
  5595. return render_template('signin_disable.html', params=locals())
  5596. elif status == 8:
  5597. return render_template('signin_new.html', params=locals())
  5598. else:
  5599. return render_template('oops.html', params=locals())
  5600. # 致動器_入料儲豆槽_真空吸料機
  5601. input_vacuum = clean_input_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5602. input_vacuum = 'ON' if (input_vacuum.vacuum == 1) else 'OFF'
  5603. # 致動器_浮選清洗_ALL
  5604. tank_actuator = clean_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5605. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5606. tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  5607. tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  5608. tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  5609. tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  5610. tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  5611. tank_stepping_motor = tank_actuator.stepping_motor
  5612. # 致動器_出料儲豆槽_真空吸料機
  5613. output_vacuum = clean_output_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5614. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  5615. # 感測器_浮選清洗_超音波感測器
  5616. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5617. return render_template('clean_container.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  5618. elif request.method == 'POST':
  5619. pass
  5620. @main.route('/clean_container_tank/<tid>', methods=['GET', 'POST'])
  5621. def clean_container_tank(tid):
  5622. if request.method == 'GET':
  5623. if 'id' in session and 'uname' in session and 'status' in session:
  5624. username = session['uname']
  5625. status = session['status']
  5626. if status == 9:
  5627. return render_template('signin_disable.html', params=locals())
  5628. elif status == 8:
  5629. return render_template('signin_new.html', params=locals())
  5630. else:
  5631. return render_template('oops.html', params=locals())
  5632. # 致動器_浮選清洗_ALL
  5633. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5634. tank_vacuum = tank_actuator.vacuum
  5635. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  5636. tank_motor = tank_actuator.motor
  5637. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  5638. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  5639. tank_pump_water_in = tank_actuator.pump_water_in
  5640. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  5641. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  5642. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  5643. tank_pump_disinfect = tank_actuator.pump_disinfect
  5644. tank_diskvalve = tank_actuator.diskvalve
  5645. # tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  5646. # tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  5647. # tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  5648. # tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  5649. # tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  5650. # tank_stepping_motor = tank_actuator.stepping_motor
  5651. # 感測器_浮選清洗_超音波感測器
  5652. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5653. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5654. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5655. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  5656. return render_template('clean_container_tank.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  5657. elif request.method == 'POST':
  5658. pass
  5659. @main.route('/ferment_container/<tid>', methods=['GET', 'POST'])
  5660. def ferment_container(tid):
  5661. if request.method == 'GET':
  5662. if 'id' in session and 'uname' in session and 'status' in session:
  5663. username = session['uname']
  5664. status = session['status']
  5665. if status == 9:
  5666. return render_template('signin_disable.html', params=locals())
  5667. elif status == 8:
  5668. return render_template('signin_new.html', params=locals())
  5669. else:
  5670. return render_template('oops.html', params=locals())
  5671. # 致動器_發酵槽_ALL
  5672. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5673. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5674. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  5675. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  5676. tank_solenoid_water_total = 'ON' if tank_actuator.solenoid_tank_water_total == 1 else 'OFF'
  5677. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  5678. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  5679. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  5680. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  5681. tank_threewayvalve_bean = 'ON' if tank_actuator.threewayvalve_bean == 1 else 'OFF'
  5682. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  5683. tank_motor = tank_actuator.motor
  5684. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  5685. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  5686. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  5687. tank_temp = tank_actuator.temp
  5688. # 感測器_發酵桶_SHT11
  5689. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5690. # 感測器_發酵桶_二氧化碳
  5691. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5692. # 感測器_發酵桶_酸鹼值
  5693. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5694. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5695. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5696. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5697. # 感測器_發酵桶_氣壓
  5698. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5699. # 感測器_發酵桶_超音波感測器
  5700. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5701. # 感測器_發酵桶_水位計
  5702. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5703. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  5704. print('tank_WaterLevel', tank_WaterLevel.WaterLevel)
  5705. if tank_WaterLevel.WaterLevel == '1':
  5706. WaterLevel = '滿'
  5707. elif tank_WaterLevel.WaterLevel == '0':
  5708. WaterLevel = '未達滿水高度'
  5709. else:
  5710. WaterLevel = 'ERROR'
  5711. # 感測器_發酵桶_咖啡生豆高度
  5712. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5713. LiDAR = tank_LiDAR.LiDAR
  5714. # 感測器_發酵桶_水位高度
  5715. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5716. PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  5717. if tid in ['1', '2', '3', '4', '5', '6']:
  5718. # print("1")
  5719. # 感測器_入料儲豆槽_超音波感測器
  5720. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  5721. # 致動器_入料儲豆槽_真空吸引機
  5722. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  5723. input_vacuum = input_vacuum.vacuum
  5724. # 感測器_出料儲豆槽_超音波感測器
  5725. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  5726. # 致動器_出料儲豆槽_真空吸引機
  5727. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  5728. output_vacuum = output_vacuum.vacuum
  5729. elif tid in ['7', '8', '9', '10', '11', '12']:
  5730. # print("2")
  5731. # 感測器_入料儲豆槽_超音波感測器
  5732. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  5733. # 致動器_入料儲豆槽_真空吸引機
  5734. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  5735. input_vacuum = input_vacuum.vacuum
  5736. print("input_vacuum", input_vacuum)
  5737. # 感測器_出料儲豆槽_超音波感測器
  5738. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  5739. # 致動器_出料儲豆槽_真空吸引機
  5740. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  5741. output_vacuum = output_vacuum.vacuum
  5742. print("output_vacuum", output_vacuum)
  5743. return render_template('ferment_container.html', title='發酵槽F' + tid + '總操作介面' , **locals())
  5744. elif request.method == 'POST':
  5745. pass
  5746. @main.route('/ferment_container_tank/<tid>', methods=['GET', 'POST'])
  5747. def ferment_container_tank(tid):
  5748. if request.method == 'GET':
  5749. if 'id' in session and 'uname' in session and 'status' in session:
  5750. username = session['uname']
  5751. status = session['status']
  5752. if status == 9:
  5753. return render_template('signin_disable.html', params=locals())
  5754. elif status == 8:
  5755. return render_template('signin_new.html', params=locals())
  5756. else:
  5757. return render_template('oops.html', params=locals())
  5758. # 致動器_發酵槽_ALL
  5759. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5760. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  5761. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  5762. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  5763. solenoid_tank_pump = 'ON' if tank_actuator.solenoid_tank_pump == 1 else 'OFF'
  5764. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  5765. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  5766. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  5767. tank_solenoid_water_out = 'ON' if tank_actuator.solenoid_tank_water_out == 1 else 'OFF'
  5768. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  5769. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  5770. tank_motor = tank_actuator.motor
  5771. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  5772. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  5773. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  5774. tank_temp = tank_actuator.temp
  5775. # 感測器_發酵桶_SHT11
  5776. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5777. # 感測器_發酵桶_二氧化碳
  5778. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5779. # 感測器_發酵桶_酸鹼值
  5780. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5781. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5782. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5783. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5784. # 感測器_發酵桶_氣壓
  5785. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5786. # 感測器_發酵桶_超音波感測器
  5787. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5788. # 感測器_發酵桶_水位計
  5789. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5790. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  5791. if tank_WaterLevel.WaterLevel == '1':
  5792. WaterLevel = '滿'
  5793. elif tank_WaterLevel.WaterLevel == '0':
  5794. WaterLevel = '未達滿水高度'
  5795. else:
  5796. WaterLevel = 'ERROR'
  5797. # 感測器_發酵桶_咖啡生豆高度
  5798. #tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5799. #LiDAR = tank_LiDAR.LiDAR
  5800. # 感測器_發酵桶_水位高度
  5801. #tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5802. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  5803. # 感測器_發酵桶_馬達編碼器
  5804. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5805. return render_template('ferment_container_tank.html', title='[操作] F' + tid + ' 發酵槽操作介面', **locals())
  5806. elif request.method == 'POST':
  5807. pass
  5808. @main.route('/ferment_container_input/<tid>', methods=['GET', 'POST'])
  5809. def ferment_container_input(tid):
  5810. if request.method == 'GET':
  5811. if 'id' in session and 'uname' in session and 'status' in session:
  5812. username = session['uname']
  5813. status = session['status']
  5814. if status == 9:
  5815. return render_template('signin_disable.html', params=locals())
  5816. elif status == 8:
  5817. return render_template('signin_new.html', params=locals())
  5818. else:
  5819. return render_template('oops.html', params=locals())
  5820. # 感測器_入料儲豆槽_超音波感測器
  5821. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  5822. # 致動器_入料儲豆槽_真空吸引機
  5823. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  5824. input_vacuum = input_vacuum.vacuum
  5825. return render_template('ferment_container_input.html', title='[操作] FI' + tid + ' 發酵入料儲豆槽操作介面', **locals())
  5826. elif request.method == 'POST':
  5827. pass
  5828. @main.route('/ferment_container_output/<tid>', methods=['GET', 'POST'])
  5829. def ferment_container_output(tid):
  5830. if request.method == 'GET':
  5831. if 'id' in session and 'uname' in session and 'status' in session:
  5832. username = session['uname']
  5833. status = session['status']
  5834. if status == 9:
  5835. return render_template('signin_disable.html', params=locals())
  5836. elif status == 8:
  5837. return render_template('signin_new.html', params=locals())
  5838. else:
  5839. return render_template('oops.html', params=locals())
  5840. # 感測器_出料儲豆槽_超音波感測器
  5841. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  5842. # 致動器_出料儲豆槽_真空吸引機
  5843. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  5844. output_vacuum = output_vacuum.vacuum
  5845. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  5846. LiDAR = tank_LiDAR.LiDAR
  5847. return render_template('ferment_container_output.html', title='[操作] FO' + tid + ' 發酵出料儲豆槽操作介面', **locals())
  5848. elif request.method == 'POST':
  5849. pass
  5850. @main.route('/dry_container_schedule', methods=['GET', 'POST'])
  5851. def dry_container_schedule():
  5852. if request.method == 'GET':
  5853. if 'id' in session and 'uname' in session:
  5854. username = session['uname']
  5855. # 感測器_入料儲豆槽_超音波感測器
  5856. input_UltraSonic = dry_input_sensor.query.order_by(text('datetime desc')).first()
  5857. # 感測器_乾燥桶_超音波感測器
  5858. tank_UltraSonic = dry_tank_UltraSonic.query.order_by(text('datetime desc')).first()
  5859. return render_template('dry_container_schedule.html', title='dry_container_schedule', **locals())
  5860. elif request.method == 'POST':
  5861. pass
  5862. @main.route('/dry_block', methods=['GET', 'POST'])
  5863. def dry_block():
  5864. if request.method == 'GET':
  5865. if 'id' in session and 'uname' in session:
  5866. username = session['uname']
  5867. DBW = dry_block_waiting.query.order_by(text('datetime desc')).first()
  5868. return render_template('dry_block.html', title='積木設定_乾燥空桶等待', **locals())
  5869. elif request.method == 'POST':
  5870. pass
  5871. @main.route('/dry_block_empty', methods=['GET', 'POST'])
  5872. def dry_block_empty():
  5873. if request.method == 'GET':
  5874. if 'id' in session and 'uname' in session:
  5875. username = session['uname']
  5876. return render_template('dry_block_empty.html', title='積木設定空白_乾燥空桶等待', **locals())
  5877. elif request.method == 'POST':
  5878. pass
  5879. # 0323 積木程式 格式調整
  5880. @main.route('/dry_block_format', methods=['GET', 'POST'])
  5881. def dry_block_format():
  5882. if request.method == 'GET':
  5883. info = request.args.to_dict()
  5884. print("info: ", info)
  5885. # info = {'cond_z1_1': 'if', 'cond_tank1_1': 'D1', 'cond_a1_1': 'tank_soil_Temp', 'cond_b1_1': 'Equal', 'cond_c1_1': '11', 'cond_d1_2': 'and', 'cond_a1_2': 'tank_soil_Humidity', 'cond_b1_2': 'Equal', 'cond_c1_2': '12', 'cond_d1_3': 'and', 'cond_a1_3': 'tank_soil_EC', 'cond_b1_3': 'Equal', 'cond_c1_3': '13', 'do_obj1_1': 'tank_heater1_status', 'do_act1_1': 'on', 'do_obj1_2': 'tank_heater2_status', 'do_act1_2': 'on'}
  5886. cond_main_all_list = []
  5887. for z in range(1,6):
  5888. # 初始
  5889. cond_main_all_dict = {}
  5890. cond_add_list = [] # 附加條件 List
  5891. cond_com_list = [] # 物件動作 List
  5892. # cond_main_dict_all = {}
  5893. # cond_add_dict_all = {}
  5894. # cond_com_dict_all = {}
  5895. # print(z)
  5896. # 總條件
  5897. try:
  5898. cond_main_all_dict['cond_main'] = info['cond_main' + str(z)]
  5899. except(KeyError):
  5900. pass
  5901. # print("cond_main_dict: ", cond_main_dict)
  5902. # 附加條件
  5903. for x in range(1,6):
  5904. try:
  5905. cond_add_list.append(info['cond_add' + str(z) + '_' + str(x)])
  5906. except(KeyError):
  5907. pass
  5908. # print("cond_add_list: ", cond_add_list)
  5909. cond_main_all_dict['cond_add'] = cond_add_list
  5910. # print("cond_main_dict: ", cond_main_dict)
  5911. # 物件動作
  5912. for y in range(1,6):
  5913. try:
  5914. cond_com_list.append(info['cond_com' + str(z) + '_' + str(y)])
  5915. except(KeyError):
  5916. pass
  5917. # print("cond_com_list: ", cond_com_list)
  5918. cond_main_all_dict['cond_com'] = cond_com_list
  5919. # print("cond_main_dict: ", cond_main_dict)
  5920. if cond_com_list != []:
  5921. cond_main_all_list.append(cond_main_all_dict)
  5922. # cond_main_all_list.append(cond_add_dict_all)
  5923. # cond_main_all_list.append(cond_com_dict_all)
  5924. print("cond_main_all_list: ", cond_main_all_list)
  5925. # cond_main_all_list: [{'cond_main': 'if D1 tank_UltraSonic >= 30', 'cond_add': ['and tank_PA <= 1', 'and tank_soil_Temp <= 30'], 'cond_com': ['tank_vacuum_status on', 'tank_motor_status 15']}]
  5926. dry_block_sehedule = {'command':'Dry_OTA', 'cond':cond_main_all_list}
  5927. print('dry_block_sehedule:', dry_block_sehedule)
  5928. # dry_block_sehedule: {'command': 'Dry_OTA', 'cond': [{'cond_main': 'if D1 tank_UltraSonic >= 30', 'cond_add': ['and tank_PA <= 1', 'and tank_soil_Temp <= 30'], 'cond_com': ['tank_vacuum_status on', 'tank_motor_status 15']}]}
  5929. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  5930. print('=========================================================')
  5931. print("json.dumps(dry_block_sehedule):", json.dumps(dry_block_sehedule))
  5932. # json.dumps(dry_block_sehedule): {"command": "Dry_OTA", "cond": [{"cond_main": "if D1 tank_UltraSonic >= 30", "cond_add": ["and tank_PA <= 1", "and tank_soil_Temp <= 30"], "cond_com": ["tank_vacuum_status on", "tank_motor_status 15"]}]}
  5933. print('=========================================================')
  5934. # mqtt.publish(topic, json.dumps(dry_block_sehedule))
  5935. return jsonify({"response":dry_block_sehedule})
  5936. # 積木程式
  5937. @main.route('/dry_block_set', methods=['GET', 'POST'])
  5938. def dry_block_set():
  5939. if request.method == 'GET':
  5940. if 'id' in session and 'uname' in session:
  5941. username = session['uname']
  5942. info = request.args.to_dict()
  5943. # print("info: ", info, type(info)) # dict
  5944. # 傳回 總條件物件動作 數量
  5945. condition = int(info['condition'])
  5946. # 傳回 子條件 數量
  5947. cond_add_child = int(info['cond_add_child'])
  5948. # 傳回 子物件動作 數量
  5949. act_add_child = int(info['act_add_child'])
  5950. # 傳回 指令
  5951. set_Schedule = eval(info['set_Schedule']) # 字串轉成字典
  5952. print("set_Schedule: ", set_Schedule, type(set_Schedule)) # dict
  5953. cond_data = ''
  5954. mqtt_data("D1", "block_command_test", "condition=" + str(condition)) # 0321 TEST
  5955. # ----- 0321 註解測試 -----
  5956. # # 拆解條件 / 物件 / 動作
  5957. # # # 條件物件取值
  5958. # for z in range(1, condition+1, 1):
  5959. # # 放要執行的判斷式
  5960. # # # if / while
  5961. # cond_data = ''
  5962. # try:
  5963. # z_num = 'cond_z' + str(z) + '_1'
  5964. # # print("cond_z_value[z_num]: ", set_Schedule[z_num]) # if
  5965. # cond_data += set_Schedule[z_num]
  5966. # except KeyError:
  5967. # pass
  5968. # # # 桶槽號取值
  5969. # try:
  5970. # tank_num = 'cond_tank' + str(z) + '_1'
  5971. # except KeyError:
  5972. # pass
  5973. # # # 子條件取值
  5974. # for x in range(1, cond_add_child+1, 1):
  5975. # # d
  5976. # try:
  5977. # x_num_d = 'cond_d' + str(z) + '_' + str(x)
  5978. # # print("cond_d_value[x_num_d]: ", set_Schedule[x_num_d])
  5979. # cond_data += ' ' + set_Schedule[x_num_d]
  5980. # except KeyError:
  5981. # pass
  5982. # # a
  5983. # x_num_a = 'cond_a' + str(z) + '_' + str(x)
  5984. # try:
  5985. # x_num_a = 'cond_a' + str(z) + '_' + str(x)
  5986. # # print("cond_a_value[x_num_a]: ", set_Schedule[x_num_a])
  5987. # cond_data += ' ' + set_Schedule[x_num_a]
  5988. # if set_Schedule[x_num_a] == 'input_vacuum_status':
  5989. # input_vacuum_status = dry_input_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  5990. # print("input_vacuum_status: ", input_vacuum_status)
  5991. # elif set_Schedule[x_num_a] == 'tank_vacuum_status':
  5992. # tank_vacuum_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  5993. # print("tank_vacuum_status: ", tank_vacuum_status)
  5994. # elif set_Schedule[x_num_a] == 'tank_threewayvalve_input_status':
  5995. # tank_threewayvalve_input_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().threewayvalve_input
  5996. # print("tank_threewayvalve_input_status: ", tank_threewayvalve_input_status)
  5997. # elif set_Schedule[x_num_a] == 'tank_motor_status':
  5998. # tank_motor_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().motor
  5999. # print("tank_motor_status: ", tank_motor_status)
  6000. # elif set_Schedule[x_num_a] == 'tank_blower_status':
  6001. # tank_blower_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().blower
  6002. # print("tank_blower_status: ", tank_blower_status)
  6003. # elif set_Schedule[x_num_a] == 'tank_heater1_status':
  6004. # tank_heater1_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater1
  6005. # print("tank_heater1_status: ", tank_heater1_status)
  6006. # elif set_Schedule[x_num_a] == 'tank_heater2_status':
  6007. # tank_heater2_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater2
  6008. # print("tank_heater2_status: ", tank_heater2_status)
  6009. # elif set_Schedule[x_num_a] == 'tank_diskvalve_status':
  6010. # tank_diskvalve_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().diskvalve
  6011. # print("tank_diskvalve_status: ", tank_diskvalve_status)
  6012. # elif set_Schedule[x_num_a] == 'tank_solenoid_disinfect_status':
  6013. # tank_solenoid_disinfect_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().solenoid_disinfect
  6014. # print("tank_solenoid_disinfect_status: ", tank_solenoid_disinfect_status)
  6015. # elif set_Schedule[x_num_a] == 'tank_solenoid_water_out_status':
  6016. # 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
  6017. # print("tank_solenoid_water_out_status: ", tank_solenoid_water_out_status)
  6018. # elif set_Schedule[x_num_a] == 'outer_solenoid_water_status':
  6019. # 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
  6020. # print("outer_solenoid_water_status: ", outer_solenoid_water_status)
  6021. # elif set_Schedule[x_num_a] == 'tank_temp_enable':
  6022. # tank_temp_enable = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1_enable
  6023. # print("tank_temp_enable: ", tank_temp_enable)
  6024. # elif set_Schedule[x_num_a] == 'tank_temp':
  6025. # tank_temp = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1
  6026. # print("tank_temp: ", tank_temp)
  6027. # elif set_Schedule[x_num_a] == 'output_vacuum':
  6028. # output_vacuum = dry_output_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  6029. # print("output_vacuum: ", output_vacuum)
  6030. # elif set_Schedule[x_num_a] == 'input_UltraSonic':
  6031. # input_UltraSonic = float(dry_input_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  6032. # print("input_UltraSonic: ", input_UltraSonic)
  6033. # elif set_Schedule[x_num_a] == 'tank_UltraSonic':
  6034. # tank_UltraSonic = float(dry_tank_UltraSonic.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  6035. # print("tank_UltraSonic: ", tank_UltraSonic)
  6036. # elif set_Schedule[x_num_a] == 'tank_SHT11_Temp':
  6037. # tank_SHT11_Temp = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Temp)
  6038. # print("tank_SHT11_Temp: ", tank_SHT11_Temp)
  6039. # elif set_Schedule[x_num_a] == 'tank_SHT11_Humidity':
  6040. # tank_SHT11_Humidity = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Humidity)
  6041. # print("tank_SHT11_Humidity: ", tank_SHT11_Humidity)
  6042. # elif set_Schedule[x_num_a] == 'tank_soil_Temp':
  6043. # tank_soil_Temp = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Temp)
  6044. # print("tank_soil_Temp: ", tank_soil_Temp)
  6045. # elif set_Schedule[x_num_a] == 'tank_soil_Humidity':
  6046. # tank_soil_Humidity = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Humidity)
  6047. # print("tank_soil_Humidity: ", tank_soil_Temp)
  6048. # elif set_Schedule[x_num_a] == 'tank_soil_EC':
  6049. # tank_soil_EC = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_EC)
  6050. # print("tank_soil_EC: ", tank_soil_EC)
  6051. # elif set_Schedule[x_num_a] == 'tank_PA':
  6052. # tank_PA = float(dry_tank_PA.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().PA)
  6053. # print("tank_PA: ", tank_PA)
  6054. # elif set_Schedule[x_num_a] == 'output_UltraSonic':
  6055. # output_UltraSonic = float(dry_output_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  6056. # print("output_UltraSonic: ", output_UltraSonic)
  6057. # except KeyError:
  6058. # pass
  6059. # # b
  6060. # try:
  6061. # x_num_b = 'cond_b' + str(z) + '_' + str(x)
  6062. # # print("cond_b_value[x_num_b]: ", set_Schedule[x_num_b])
  6063. # cond_b_dict = {'morethan': ' >= ', 'lessthan': ' <= ', 'equal':' == '}
  6064. # cond_data += cond_b_dict[set_Schedule[x_num_b]] # cond_b_dict['equal'] 會輸出 ' == '
  6065. # except KeyError:
  6066. # pass
  6067. # # c
  6068. # try:
  6069. # x_num_c = 'cond_c' + str(z) + '_' + str(x)
  6070. # # print("cond_c_value[x_num_c]: ", set_Schedule[x_num_c])
  6071. # if set_Schedule[x_num_c] == 'on':
  6072. # cond_data += '1'
  6073. # elif set_Schedule[x_num_c] == 'off':
  6074. # cond_data += '0'
  6075. # else:
  6076. # cond_data += set_Schedule[x_num_c]
  6077. # except KeyError:
  6078. # pass
  6079. # if x == cond_add_child:
  6080. # cond_data += ': '
  6081. # # 子物件動作取值
  6082. # for y in range(1, act_add_child+1, 1):
  6083. # # do_obj
  6084. # try:
  6085. # y_num_obj = "do_obj" + str(z) + "_" + str(y)
  6086. # # print("y_num_obj[y_num_obj]: ", set_Schedule[y_num_obj])
  6087. # # cond_data += 'print(\'' + 'mqtt_data("D1", "' + str(set_Schedule[y_num_obj]) + '", '
  6088. # if set_Schedule[y_num_obj] == 'time.sleep':
  6089. # cond_data += '''
  6090. # time.sleep('''
  6091. # else:
  6092. # cond_data += '''
  6093. # mqtt_data('''
  6094. # cond_data += '"' + set_Schedule[tank_num] + '", "' + str(set_Schedule[y_num_obj]) + '", '
  6095. # except KeyError:
  6096. # pass
  6097. # try:
  6098. # y_num_act = "do_act" + str(z) + "_" + str(y)
  6099. # # print("y_num_act[y_num_act]: ", set_Schedule[y_num_act])
  6100. # if set_Schedule[y_num_obj] == 'time.sleep':
  6101. # cond_data += set_Schedule[y_num_act] + ')'
  6102. # else:
  6103. # cond_data += '"' + str(set_Schedule[y_num_act]) + '") '
  6104. # cond_data += '''
  6105. # time.sleep(0.5)'''
  6106. # except KeyError:
  6107. # pass
  6108. # # TODO
  6109. # # set_Schedule[z_num] → if / while
  6110. # # set_Schedule[x_num_a] → actuator / sensor
  6111. # # set_Schedule[x_num_b] → morethan / equal / lessthan
  6112. # # set_Schedule[x_num_c] → 數值 / on / off
  6113. # # set_Schedule[x_num_d] → or / and
  6114. # # set_Schedule[y_num_obj] → actuator
  6115. # # set_Schedule[y_num_act] → on / off / 對應數值
  6116. # print("cond_data: ", cond_data)
  6117. # if cond_data != ': ':
  6118. # # exec(cond_data)
  6119. # # 01/17 新增, 格式待修改
  6120. # mqtt_data("D1", "command_test", "exec(" + cond_data + ")")
  6121. return jsonify({"response":"OK"
  6122. })
  6123. elif request.method == 'POST':
  6124. pass
  6125. # 乾燥貨櫃_各致動器控制
  6126. @main.route('/ctrl_DI_<actuator>/<tid>', methods=['GET', 'POST'])
  6127. def ctrl_DI(actuator, tid):
  6128. if request.method == 'GET':
  6129. if actuator == 'Vacuum':
  6130. if 'id' in session and 'uname' in session and 'status' in session:
  6131. username = session['uname']
  6132. status = session['status']
  6133. if status == 9:
  6134. return render_template('signin_disable.html', params=locals())
  6135. elif status == 8:
  6136. return render_template('signin_new.html', params=locals())
  6137. else:
  6138. return render_template('oops.html', params=locals())
  6139. input_brake = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6140. input_vacuum = input_brake.vacuum
  6141. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6142. UltraSonic = tank_UltraSonic.UltraSonic
  6143. return render_template('ctrl_DI_Vacuum.html', title='[操作]DI' + tid + '乾燥槽入料_真空吸料機', **locals())
  6144. elif request.method == 'POST':
  6145. pass
  6146. @main.route('/ctrl_DO_<actuator>/<tid>', methods=['GET', 'POST'])
  6147. def ctrl_DO(actuator, tid):
  6148. if request.method == 'GET':
  6149. if 'id' in session and 'uname' in session and 'status' in session:
  6150. username = session['uname']
  6151. status = session['status']
  6152. if status == 9:
  6153. return render_template('signin_disable.html', params=locals())
  6154. elif status == 8:
  6155. return render_template('signin_new.html', params=locals())
  6156. else:
  6157. return render_template('oops.html', params=locals())
  6158. if actuator == 'Vacuum':
  6159. tank_brake = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6160. tank_vacuum = tank_brake.vacuum
  6161. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6162. UltraSonic = tank_UltraSonic.UltraSonic
  6163. return render_template('ctrl_DO_Vacuum.html', title='[操作]DI' + tid + '乾燥槽出料_真空吸料機', **locals())
  6164. elif request.method == 'POST':
  6165. pass
  6166. @main.route('/ctrl_D_<actuator>/<tid>', methods=['GET', 'POST'])
  6167. def ctrl_D(actuator, tid):
  6168. if request.method == 'GET':
  6169. if 'id' in session and 'uname' in session and 'status' in session:
  6170. username = session['uname']
  6171. status = session['status']
  6172. if status == 9:
  6173. return render_template('signin_disable.html', params=locals())
  6174. elif status == 8:
  6175. return render_template('signin_new.html', params=locals())
  6176. else:
  6177. return render_template('oops.html', params=locals())
  6178. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6179. if actuator == 'Vacuum':
  6180. tank_vacuum = tank_brake.vacuum
  6181. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6182. UltraSonic = tank_UltraSonic.UltraSonic
  6183. return render_template('ctrl_D_Vacuum.html', title='[操作]D' + tid + '乾燥槽_真空吸料機', **locals())
  6184. elif actuator == 'ThreeWayValveInput':
  6185. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6186. return render_template('ctrl_D_ThreeWayValveInput.html', title='[操作]D' + tid + '乾燥槽_入料三通閥', **locals())
  6187. elif actuator == 'ThreeWayValveBean':
  6188. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6189. return render_template('ctrl_D_ThreeWayValveBean.html', title='[操作]D' + tid + '乾燥槽_測豆三通閥', **locals())
  6190. elif actuator == 'DiskValve':
  6191. tank_diskvalve = tank_brake.diskvalve
  6192. return render_template('ctrl_D_DiskValve.html', title='[操作]D' + tid + '乾燥槽_蝴蝶閥', **locals())
  6193. elif actuator == 'SolenoidDisinfect':
  6194. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6195. return render_template('ctrl_D_SolenoidDisinfect.html', title='[操作]D' + tid + '乾燥槽_消毒電磁閥', **locals())
  6196. elif actuator == 'SolenoidWater':
  6197. tank_solenoid_water = tank_brake.solenoid_water
  6198. return render_template('ctrl_D_SolenoidWater.html', title='[操作]D' + tid + '乾燥槽_排水電磁閥', **locals())
  6199. elif actuator == 'Motor':
  6200. tank_motor = tank_brake.motor
  6201. return render_template('ctrl_D_Motor.html', title='[操作]D' + tid + '乾燥槽_馬達', **locals())
  6202. elif actuator == 'Blower':
  6203. tank_blower = tank_brake.blower
  6204. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6205. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6206. return render_template('ctrl_D_Blower.html', title='[操作]D' + tid + '乾燥槽_鼓風機', **locals())
  6207. elif actuator == 'Heater1':
  6208. tank_heater1 = tank_brake.heater1
  6209. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6210. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6211. return render_template('ctrl_D_Heater1.html', title='[操作]D' + tid + '乾燥槽_加熱器 1', **locals())
  6212. elif actuator == 'Heater2':
  6213. tank_heater2 = tank_brake.heater2
  6214. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6215. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6216. return render_template('ctrl_D_Heater2.html', title='[操作]D' + tid + '乾燥槽_加熱器 2', **locals())
  6217. elif actuator == 'TempEnable':
  6218. tank_temp1_enable = tank_brake.temp1_enable
  6219. return render_template('ctrl_D_TempEnable.html', title='[操作]D' + tid + '乾燥槽_溫控開關', **locals())
  6220. elif actuator == 'Temp':
  6221. tank_temp1_enable = tank_brake.temp1_enable
  6222. tank_temp1 = tank_brake.temp1
  6223. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6224. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6225. return render_template('ctrl_D_Temp.html', title='[操作]D' + tid + '乾燥槽_設定溫度', **locals())
  6226. elif request.method == 'POST':
  6227. pass
  6228. # 發酵貨櫃_各致動器控制
  6229. @main.route('/ctrl_FI_<actuator>/<tid>', methods=['GET', 'POST'])
  6230. def ctrl_FI(actuator, tid):
  6231. if request.method == 'GET':
  6232. if 'id' in session and 'uname' in session and 'status' in session:
  6233. username = session['uname']
  6234. status = session['status']
  6235. if status == 9:
  6236. return render_template('signin_disable.html', params=locals())
  6237. elif status == 8:
  6238. return render_template('signin_new.html', params=locals())
  6239. else:
  6240. return render_template('oops.html', params=locals())
  6241. if actuator == 'Vacuum':
  6242. if 'id' in session and 'uname' in session and 'status' in session:
  6243. username = session['uname']
  6244. status = session['status']
  6245. if status == 9:
  6246. return render_template('signin_disable.html', params=locals())
  6247. elif status == 8:
  6248. return render_template('signin_new.html', params=locals())
  6249. else:
  6250. return render_template('oops.html', params=locals())
  6251. tank_actuator = ferment_input_actuator.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  6252. tank_vacuum = tank_actuator.vacuum
  6253. tank_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  6254. UltraSonic = tank_UltraSonic.UltraSonic
  6255. return render_template('ctrl_FI_Vacuum.html', title='[操作]FI' + tid + '發酵入料儲豆槽_真空吸料機', **locals())
  6256. elif request.method == 'POST':
  6257. pass
  6258. @main.route('/ctrl_FO_<actuator>/<tid>', methods=['GET', 'POST'])
  6259. def ctrl_FO(actuator, tid):
  6260. if request.method == 'GET':
  6261. if 'id' in session and 'uname' in session and 'status' in session:
  6262. username = session['uname']
  6263. status = session['status']
  6264. if status == 9:
  6265. return render_template('signin_disable.html', params=locals())
  6266. elif status == 8:
  6267. return render_template('signin_new.html', params=locals())
  6268. else:
  6269. return render_template('oops.html', params=locals())
  6270. if actuator == 'Vacuum':
  6271. tank_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  6272. tank_vacuum = tank_actuator.vacuum
  6273. tank_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  6274. UltraSonic = tank_UltraSonic.UltraSonic
  6275. return render_template('ctrl_FO_Vacuum.html', title='[操作]FO' + tid + '發酵出料儲豆槽_真空吸料機', **locals())
  6276. elif request.method == 'POST':
  6277. pass
  6278. @main.route('/ctrl_F_<actuator>/<tid>', methods=['GET', 'POST'])
  6279. def ctrl_F(actuator, 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. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  6291. if actuator == 'Vacuum':
  6292. tank_vacuum = tank_actuator.vacuum
  6293. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  6294. LiDAR = tank_LiDAR.LiDAR
  6295. return render_template('ctrl_F_Vacuum.html', title='[操作]F' + tid + '發酵槽_真空吸料機', **locals())
  6296. elif actuator == 'ThreeWayValveInput':
  6297. tank_threewayvalveinput = tank_actuator.threewayvalve_input
  6298. return render_template('ctrl_F_ThreeWayValveInput.html', title='[操作]F' + tid + '發酵槽_入料三通閥', **locals())
  6299. elif actuator == 'SolenoidWaterTotal':
  6300. tank_solenoid_tank_water_total = tank_actuator.solenoid_tank_water_total
  6301. return render_template('ctrl_F_SolenoidWaterTotal.html', title='[操作]F' + tid + '發酵槽_總進水電磁閥', **locals())
  6302. elif actuator == 'SolenoidOuterWater':
  6303. tank_solenoid_outer_water = tank_actuator.solenoid_outer_water
  6304. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6305. WaterLevel = tank_WaterLevel.WaterLevel
  6306. return render_template('ctrl_F_SolenoidOuterWater.html', title='[操作]F' + tid + '發酵槽_保溫夾層進水電磁閥', **locals())
  6307. elif actuator == 'SolenoidWaterIn':
  6308. tank_solenoid_tank_water_in = tank_actuator.solenoid_tank_water_in
  6309. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6310. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  6311. return render_template('ctrl_F_SolenoidWaterIn.html', title='[操作]F' + tid + '發酵槽_桶內進水電磁閥', **locals())
  6312. elif actuator == 'PumpSensor':
  6313. tank_pump_sensor = tank_actuator.pump_sensor
  6314. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6315. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6316. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6317. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6318. PH = tank_PH.PH
  6319. ORP = tank_ORP.ORP
  6320. DO = tank_DO.DO
  6321. EC = tank_EC.EC
  6322. return render_template('ctrl_F_PumpSensor.html', title='[操作]F' + tid + '發酵槽_感測器抽水雙核隔膜泵', **locals())
  6323. elif actuator == 'ThreeWayValveBean':
  6324. tank_threewayvalve_bean = tank_actuator.threewayvalve_bean
  6325. return render_template('ctrl_F_ThreeWayValveBean.html', title='[操作]F' + tid + '發酵槽_感測模組下豆三通閥', **locals())
  6326. elif actuator == 'ThreeWayValveFloat':
  6327. tank_threewayvalve_outer_float = tank_actuator.threewayvalve_outer_float
  6328. return render_template('ctrl_F_ThreeWayValveFloat.html', title='[操作]F' + tid + '發酵槽_外桶浮選三通閥', **locals())
  6329. elif actuator == 'SolenoidDisinfect':
  6330. tank_solenoid_tank_disinfect = tank_actuator.solenoid_tank_disinfect
  6331. return render_template('ctrl_F_SolenoidDisinfect.html', title='[操作]F' + tid + '發酵槽_桶內消毒電磁閥', **locals())
  6332. elif actuator == 'Motor':
  6333. tank_motor = tank_actuator.motor
  6334. return render_template('ctrl_F_Motor.html', title='[操作]F' + tid + '發酵槽_馬達', **locals())
  6335. elif actuator == 'Heater1':
  6336. tank_heater1 = tank_actuator.heater1
  6337. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6338. return render_template('ctrl_F_Heater1.html', title='[操作]F' + tid + '發酵槽_加熱器 1', **locals())
  6339. elif actuator == 'Heater2':
  6340. tank_heater2 = tank_actuator.heater2
  6341. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6342. return render_template('ctrl_F_Heater2.html', title='[操作]F' + tid + '發酵槽_加熱器 2', **locals())
  6343. elif actuator == 'TempEnable':
  6344. tank_temp_enable = tank_actuator.temp_enable
  6345. return render_template('ctrl_F_TempEnable.html', title='[操作]F' + tid + '發酵槽_溫控開關', **locals())
  6346. elif actuator == 'Temp':
  6347. tank_temp = tank_actuator.temp
  6348. tank_temp_enable = tank_actuator.temp_enable
  6349. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6350. return render_template('ctrl_F_Temp.html', title='[操作]F' + tid + '發酵槽_溫度設定', **locals())
  6351. elif actuator == 'DiskValve':
  6352. tank_diskvalve = tank_actuator.diskvalve
  6353. return render_template('ctrl_F_DiskValve.html', title='[操作]F' + tid + '發酵槽_蝴蝶閥', **locals())
  6354. @main.route('/dry_Temp/<tid>/<Temp_Weights_SHT11>/<Temp_Weights_Soil>/<temp_data>', methods=['GET', 'POST'])
  6355. def dry_Temp(tid, Temp_Weights_SHT11, Temp_Weights_Soil, temp_data):
  6356. if request.method == 'GET':
  6357. if 'id' in session and 'uname' in session and 'status' in session:
  6358. username = session['uname']
  6359. status = session['status']
  6360. if status == 9:
  6361. return render_template('signin_disable.html', params=locals())
  6362. elif status == 8:
  6363. return render_template('signin_new.html', params=locals())
  6364. else:
  6365. return render_template('oops.html', params=locals())
  6366. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6367. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  6368. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6369. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6370. Soil_Temp = float(tank_Soil.soil_Temp)
  6371. Soil_Humidity = tank_Soil.soil_Humidity
  6372. Temp_Weights_SHT11= float(Temp_Weights_SHT11)
  6373. Temp_Weights_Soil = float(Temp_Weights_Soil)
  6374. temp_data = float(temp_data)
  6375. present_temp = math.ceil( (SHT11_Temp*Temp_Weights_SHT11 + Soil_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil) )
  6376. # Math.round((present_SHT11_Temp*Temp_Weights_SHT11 + present_SOIL_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil)*100) / 100
  6377. target_temp = math.ceil(temp_data)
  6378. TempUp = {
  6379. 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
  6380. }
  6381. if target_temp in TempUp and present_temp in TempUp:
  6382. TempUpTime = ', 預計 ' + str(TempUp[target_temp] - TempUp[present_temp]) + ' 秒達到指定溫度'
  6383. elif target_temp < 22 or present_temp < 22 :
  6384. TempUpTime = '℃, 指定溫度過低, 持續升溫中'
  6385. elif target_temp > 44 or present_temp > 44 :
  6386. TempUpTime = '℃, 指定溫度過高, 持續升溫中'
  6387. return jsonify({"SHT11_Temp":SHT11_Temp,
  6388. "SHT11_Humidity":SHT11_Humidity,
  6389. "Soil_Temp":Soil_Temp,
  6390. "Soil_Humidity":Soil_Humidity,
  6391. "present_temp":present_temp,
  6392. "TempUpTime":TempUpTime
  6393. })
  6394. else:
  6395. pass
  6396. @main.route('/dry_container_tank/<tid>', methods=['GET', 'POST'])
  6397. def dry_container_tank(tid):
  6398. if request.method == 'GET':
  6399. if 'id' in session and 'uname' in session and 'status' in session:
  6400. username = session['uname']
  6401. status = session['status']
  6402. if status == 9:
  6403. return render_template('signin_disable.html', params=locals())
  6404. elif status == 8:
  6405. return render_template('signin_new.html', params=locals())
  6406. else:
  6407. return render_template('oops.html', params=locals())
  6408. tonow = dt.now()
  6409. print("tonow: ", tonow)
  6410. time_del = timedelta(minutes=-60)
  6411. bias_date_time = tonow + time_del
  6412. # print(dt.now() >= dt(2021,11,29,17,35,36))
  6413. # bias_min = tonow.minute + 3
  6414. # 感測器_乾燥桶_SHT11
  6415. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid))\
  6416. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  6417. .order_by(text('datetime desc')).first()
  6418. # 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'>
  6419. if not hasattr(object, 'tank_SHT11'):
  6420. tank_SHT11 = {"SHT11_Temp":" — ", "SHT11_Humidity":" — "}
  6421. print(tank_SHT11["SHT11_Temp"])
  6422. # 感測器_乾燥桶_土壤三合一
  6423. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6424. if not hasattr(object, 'tank_Soil'):
  6425. tank_Soil = {"soil_Temp":" — ", "soil_Humidity":" — ", "soil_EC":" — "}
  6426. # 感測器_乾燥桶_氣壓
  6427. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6428. if not hasattr(object, 'tank_PA'):
  6429. tank_PA = {"PA":" — "}
  6430. # 感測器_乾燥桶_超音波感測器
  6431. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6432. if not hasattr(object, 'tank_UltraSonic'):
  6433. tank_UltraSonic = {"UltraSonic":" — "}
  6434. # 致動器_乾燥桶_ALL
  6435. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6436. tank_vacuum = tank_brake.vacuum
  6437. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6438. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6439. tank_diskvalve = tank_brake.diskvalve
  6440. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6441. tank_solenoid_water = tank_brake.solenoid_water
  6442. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  6443. tank_motor = tank_brake.motor
  6444. tank_blower = tank_brake.blower
  6445. tank_heater1 = tank_brake.heater1
  6446. tank_heater2 = tank_brake.heater2
  6447. tank_temp1_enable = tank_brake.temp1_enable
  6448. tank_temp1 = tank_brake.temp1
  6449. # Temp_weight = num_SHT11_temp * 0.5 + num_Soil_temp * 0.5
  6450. return render_template('dry_container_tank.html', title='[操作] D' + tid + ' 乾燥槽操作介面', **locals())
  6451. elif request.method == 'POST':
  6452. pass
  6453. @main.route('/dry_container_input/<tid>', methods=['GET', 'POST'])
  6454. def dry_container_input(tid):
  6455. if request.method == 'GET':
  6456. if 'id' in session and 'uname' in session and 'status' in session:
  6457. username = session['uname']
  6458. status = session['status']
  6459. if status == 9:
  6460. return render_template('signin_disable.html', params=locals())
  6461. elif status == 8:
  6462. return render_template('signin_new.html', params=locals())
  6463. else:
  6464. return render_template('oops.html', params=locals())
  6465. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6466. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  6467. input_vacuum = input_vacuum.vacuum
  6468. return render_template('dry_container_input.html', title='[操作] DI' + tid + ' 乾燥入料儲豆槽操作介面', **locals())
  6469. elif request.method == 'POST':
  6470. pass
  6471. @main.route('/dry_container_output/<tid>', methods=['GET', 'POST'])
  6472. def dry_container_output(tid):
  6473. if request.method == 'GET':
  6474. if 'id' in session and 'uname' in session and 'status' in session:
  6475. username = session['uname']
  6476. status = session['status']
  6477. if status == 9:
  6478. return render_template('signin_disable.html', params=locals())
  6479. elif status == 8:
  6480. return render_template('signin_new.html', params=locals())
  6481. else:
  6482. return render_template('oops.html', params=locals())
  6483. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6484. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  6485. output_vacuum = output_vacuum.vacuum
  6486. return render_template('dry_container_output.html', title='[操作] DO' + tid + ' 乾燥出料儲豆槽操作介面', **locals())
  6487. elif request.method == 'POST':
  6488. pass
  6489. # 原本的乾燥貨櫃控制, 備份用
  6490. @main.route('/dry_container/<tid>', methods=['GET', 'POST'])
  6491. def dry_container(tid):
  6492. if request.method == 'GET':
  6493. if 'id' in session and 'uname' in session and 'status' in session:
  6494. username = session['uname']
  6495. status = session['status']
  6496. if status == 9:
  6497. return render_template('signin_disable.html', params=locals())
  6498. elif status == 8:
  6499. return render_template('signin_new.html', params=locals())
  6500. else:
  6501. return render_template('oops.html', params=locals())
  6502. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  6503. '''
  6504. # 開啟本機 coffeetest 資料庫
  6505. # mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='coffeetest', charset='utf8')
  6506. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  6507. password='skyeye', database='Coffee', charset='utf8')
  6508. mycursor = mydb.cursor()
  6509. '''
  6510. # 感測器_乾燥桶_SHT11
  6511. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6512. num_SHT11_temp = float(tank_SHT11.SHT11_Temp)
  6513. # 感測器_乾燥桶_土壤三合一
  6514. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6515. num_Soil_temp = float(tank_Soil.soil_Temp)
  6516. # 感測器_乾燥桶_氣壓
  6517. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6518. # 感測器_乾燥桶_超音波感測器
  6519. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6520. # 感測器_出料儲豆槽_超音波感測器
  6521. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6522. # 致動器_乾燥桶_ALL
  6523. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6524. tank_vacuum = tank_brake.vacuum
  6525. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6526. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6527. tank_diskvalve = tank_brake.diskvalve
  6528. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6529. tank_solenoid_water = tank_brake.solenoid_water
  6530. tank_motor = tank_brake.motor
  6531. tank_blower = tank_brake.blower
  6532. tank_heater1 = tank_brake.heater1
  6533. tank_heater2 = tank_brake.heater2
  6534. tank_temp1_enable = tank_brake.temp1_enable
  6535. tank_temp1 = tank_brake.temp1
  6536. '''
  6537. tank_vacuum = 'ON' if tank_brake.vacuum == 1 else 'OFF'
  6538. tank_threewayvalve = 'ON' if tank_brake.threewayvalve == 1 else 'OFF'
  6539. tank_diskvalve = 'ON' if tank_brake.diskvalve == 1 else 'OFF'
  6540. tank_solenoid_disinfect = 'ON' if tank_brake.solenoid_disinfect == 1 else 'OFF'
  6541. tank_solenoid_water = 'ON' if tank_brake.solenoid_water == 1 else 'OFF'
  6542. tank_motor = tank_brake.motor
  6543. tank_blower = 'ON' if tank_brake.blower == 1 else 'OFF'
  6544. tank_heater1 = 'ON' if tank_brake.heater1 == 1 else 'OFF'
  6545. tank_heater2 = 'ON' if tank_brake.heater2 == 1 else 'OFF'
  6546. tank_temp1_enable = 'ON' if tank_brake.temp1_enable == 1 else 'OFF'
  6547. tank_temp1 = tank_brake.temp1
  6548. '''
  6549. '''
  6550. data = mycursor.execute(
  6551. 'SELECT * FROM dry_tank_brake ORDER BY datetime DESC;')
  6552. data = mycursor.fetchone()
  6553. '''
  6554. if tid in ['1', '2', '3', '4', '5', '6']:
  6555. # print("1")
  6556. # 感測器_入料儲豆槽_超音波感測器
  6557. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  6558. # 致動器_入料儲豆槽_真空吸引機
  6559. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  6560. input_vacuum = input_vacuum.vacuum
  6561. # 感測器_出料儲豆槽_超音波感測器
  6562. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  6563. # 致動器_出料儲豆槽_真空吸引機
  6564. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  6565. output_vacuum = output_vacuum.vacuum
  6566. elif tid in ['7', '8', '9', '10', '11', '12']:
  6567. print("2")
  6568. # 感測器_入料儲豆槽_超音波感測器
  6569. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  6570. # 致動器_入料儲豆槽_真空吸引機
  6571. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  6572. input_vacuum = input_vacuum.vacuum
  6573. # 感測器_出料儲豆槽_超音波感測器
  6574. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  6575. # 致動器_出料儲豆槽_真空吸引機
  6576. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  6577. output_vacuum = output_vacuum.vacuum
  6578. '''
  6579. # 感測器_入料儲豆槽_超音波感測器
  6580. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6581. # 致動器_入料儲豆槽_真空吸引機
  6582. input_vacuum = dry_input_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6583. # print("input_vacuum:", input_vacuum)
  6584. input_vacuum = input_vacuum.vacuum
  6585. #print('input_vacuum:', input_vacuum.vacuum)
  6586. # 致動器_出料儲豆槽_真空吸引機
  6587. output_vacuum = dry_output_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  6588. #print('output_vacuum.vacuum: ', output_vacuum.vacuum)
  6589. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  6590. #print('output_vacuum: ', output_vacuum)
  6591. '''
  6592. # 傳 MQTT 給阿超, 阿超讓硬體動作, 將資料儲存到資料庫
  6593. input_data = set_dry_input.query.order_by(text('datetime desc')).first()
  6594. schedule_input_height = input_data.input_height
  6595. schedule_input_entertime = input_data.input_entertime
  6596. schedule_input_exittime = input_data.input_exittime
  6597. schedule_tank_height = input_data.tank_height
  6598. return render_template('dry_container.html', title='dry_container', **locals())
  6599. elif request.method == 'POST':
  6600. # 表單輸入處
  6601. print('/dry_input_setting POST')
  6602. set = set_dry_input()
  6603. set.input_height = request.form['schedule_input_height']
  6604. set.input_entertime = request.form['schedule_input_entertime']
  6605. set.input_exittime = request.form['schedule_input_exittime']
  6606. set.tank_height = request.form['schedule_tank_height']
  6607. #將數據保存進資料庫 - 註冊
  6608. db.session.add(set)
  6609. # 手動提交,目的是為了獲取提交後的user的id
  6610. db.session.commit()
  6611. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  6612. # 完成登入的操作
  6613. # setting = Set_dry_input.query.order_by(text('datetime desc')).first()
  6614. #session['id'] = set.userID
  6615. #session['uname'] = set.username
  6616. return redirect('/dry_container')
  6617. # 登入頁面的訪問路徑
  6618. @main.route('/login', methods=['GET', 'POST'])
  6619. def login_views():
  6620. if request.method == 'GET':
  6621. if 'id' in session and 'uname' in session and 'status' in session:
  6622. return redirect('/')
  6623. else:
  6624. return render_template('sign_in.html')
  6625. else:
  6626. # 接收前端傳過來的資料
  6627. username = request.form['username']
  6628. password = request.form['password']
  6629. # 使用接收的用戶和密碼到資料庫中查詢
  6630. user = User.query.filter_by(
  6631. username=username, password=password).first()
  6632. # 如果用戶存在,將信息保存置session並重定向回首頁,否則重定向回登入頁
  6633. if user:
  6634. resp = redirect('/')
  6635. # 判斷是否有記住密碼
  6636. if 'rem' in request.form:
  6637. userID = str(user.userID)
  6638. max_age = 60*60*24*365
  6639. status = str(user.status)
  6640. print('status: ', status)
  6641. # Rita 以秒為單位, 一年
  6642. # Rita 功能和 expires 很像,但此參數並非所有瀏覽器均支持,所以建議使用 expires 參數。
  6643. # Rita expires:指定 Cookie 的有效日期, 當過了有效日期後就不會儲存在瀏覽器
  6644. resp.set_cookie("username", username, max_age=max_age)
  6645. resp.set_cookie("userID", userID, max_age=max_age)
  6646. resp.set_cookie("status", status, max_age=max_age)
  6647. session['uname'] = user.username
  6648. session['id'] = user.userID
  6649. session['status'] = user.status
  6650. return resp
  6651. else:
  6652. errMsg = "Wrong login or password"
  6653. return render_template('sign_in.html', errMsg=errMsg)
  6654. # 登入重設密碼的頁面
  6655. # Rita reset_pwd1 - Email
  6656. # Rita reset_pwd2 - New password / Confirm password
  6657. @main.route('/reset_password', methods=['POST', 'GET'])
  6658. def reset_password_views():
  6659. if request.method == 'GET':
  6660. if 'mail' in session:
  6661. del session['mail']
  6662. return render_template('reset_pwd1.html')
  6663. else:
  6664. # POST
  6665. # 如果有id在session裡,代表從reset_pwd2過來的 ? 對, reset_pwd2 POST (但也有其他可能)
  6666. if "mail" in session:
  6667. new_pwd = request.form['new_pwd']
  6668. confirm_pwd = request.form['confirm_pwd']
  6669. # 判斷密碼是否一致
  6670. if new_pwd == confirm_pwd:
  6671. mail = session['mail']
  6672. user = User.query.filter_by(mail=mail).first()
  6673. print("user: ", user)
  6674. print("user.password_before: ", user.password)
  6675. print("new_pwd: ", new_pwd)
  6676. user.password = new_pwd
  6677. print("user.password_after: ", user.password)
  6678. db.session.add(user)
  6679. db.session.commit()
  6680. del session['mail']
  6681. # 修改完後回登入頁
  6682. return redirect('/login')
  6683. else:
  6684. # Rita errMsg 是指網頁上的 {{errMsg}} 位置
  6685. errMsg = "Passwords does not match"
  6686. return render_template('reset_pwd2.html', errMsg=errMsg)
  6687. email = request.form['email']
  6688. user = User.query.filter_by(mail=email).first()
  6689. if user: # Rita 有找到對應 email
  6690. session['mail'] = user.mail
  6691. return render_template('reset_pwd2.html')
  6692. else:
  6693. errMsg = "Wrong email.Please try again"
  6694. return render_template('reset_pwd1.html', errMsg=errMsg)
  6695. # 註冊頁面的訪問路徑
  6696. @main.route('/register', methods=['POST', "GET"])
  6697. def register_views():
  6698. if request.method == 'GET':
  6699. return render_template('registration.html')
  6700. else:
  6701. # 獲取文本框的值並賦值給user實體對象
  6702. user = User()
  6703. user.firstname = request.form['firstname']
  6704. user.lastname = request.form['lastname']
  6705. user.mail = request.form['email']
  6706. user.phone = request.form['phone']
  6707. user.username = request.form['username']
  6708. user.password = request.form['password']
  6709. user.status = 8 # Rita app\models.py 設定 0:admin;1:new;9:disable [0906 更新] 0:admin;1:superuser;2:enduser;8:new;9:disable
  6710. #將數據保存進資料庫 - 註冊
  6711. db.session.add(user)
  6712. # 手動提交,目的是為了獲取提交後的user的id
  6713. db.session.commit()
  6714. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  6715. # 完成登入的操作
  6716. user = User.query.filter_by(username=user.username).first()
  6717. session['status'] = user.status
  6718. session['id'] = user.userID
  6719. session['uname'] = user.username
  6720. return redirect('/')
  6721. # 驗證email訪問路徑
  6722. @main.route('/check_email')
  6723. def check_email_views():
  6724. email = request.args['email']
  6725. user = User.query.filter_by(mail=email).first()
  6726. if user:
  6727. # Rita email 錯誤時會顯示 Incorrect email address
  6728. result = {"errMsg": " "}
  6729. else:
  6730. result = {"pass": " "}
  6731. return json.dumps(result)
  6732. # 驗證username訪問路徑
  6733. @main.route('/check_username')
  6734. def check_username_views():
  6735. username = request.args['username']
  6736. user = User.query.filter_by(username=username).first()
  6737. if user:
  6738. result = {"errMsg": " "}
  6739. else:
  6740. result = {"pass": " "}
  6741. return json.dumps(result)
  6742. # 咖啡貨櫃的訪問路徑
  6743. @main.route('/cargo_list', methods=['GET', 'POST'])
  6744. def cargo_list_views():
  6745. username = session['uname']
  6746. if request.method == 'GET':
  6747. return render_template('cargo_list.html', params=locals())
  6748. else:
  6749. pass
  6750. # 貨櫃1的訪問路徑
  6751. @main.route('/cargo1', methods=['GET', 'POST'])
  6752. def cargo1_views():
  6753. username = session['uname']
  6754. if request.method == 'GET':
  6755. return render_template('cargo1.html', params=locals())
  6756. else:
  6757. pass
  6758. # 貨櫃1排程的訪問路徑
  6759. @main.route('/cargo1_schedule', methods=['GET', 'POST'])
  6760. def cargo1_schedule_views():
  6761. username = session['uname']
  6762. if request.method == 'GET':
  6763. # 將已儲存的排程資料傳給前端
  6764. # 進豆閥
  6765. try:
  6766. bean = BeanValve.query.order_by(text('datetime desc')).first()
  6767. datetime = bean.datetime
  6768. beans = BeanValve.query.filter_by(
  6769. datetime=datetime).all()
  6770. except Exception as e:
  6771. pass
  6772. # 清洗機
  6773. try:
  6774. wash = WashMachine.query.order_by(text('datetime desc')).first()
  6775. datetime = wash.datetime
  6776. washes = WashMachine.query.filter_by(datetime=datetime).all()
  6777. except Exception as e:
  6778. pass
  6779. # 輸送帶1
  6780. try:
  6781. belt1 = ConveyorBelt1.query.order_by(text('datetime desc')).first()
  6782. datetime = belt1.datetime
  6783. belts1 = ConveyorBelt1.query.filter_by(datetime=datetime).all()
  6784. except Exception as e:
  6785. pass
  6786. # ///////////////////////////////////////////////////////////////////////////////////////////
  6787. # 消毒機
  6788. try:
  6789. disinfect = Cargo1Disinfect.query.order_by(
  6790. text('datetime desc')).first()
  6791. datetime = disinfect.datetime
  6792. disinfects = Cargo1Disinfect.query.filter_by(
  6793. datetime=datetime).all()
  6794. except Exception as e:
  6795. pass
  6796. # 色選機
  6797. try:
  6798. color = ColorMachine.query.order_by(text('datetime desc')).first()
  6799. datetime = color.datetime
  6800. colors = ColorMachine.query.filter_by(datetime=datetime).all()
  6801. except Exception as e:
  6802. pass
  6803. # 輸送帶2
  6804. try:
  6805. belt2 = ConveyorBelt2.query.order_by(text('datetime desc')).first()
  6806. datetime = belt2.datetime
  6807. belts2 = ConveyorBelt2.query.filter_by(datetime=datetime).all()
  6808. except Exception as e:
  6809. pass
  6810. # 去皮機
  6811. try:
  6812. peeling = PeelingMachine.query.order_by(
  6813. text('datetime desc')).first()
  6814. datetime = peeling.datetime
  6815. peelings = PeelingMachine.query.filter_by(datetime=datetime).all()
  6816. except Exception as e:
  6817. pass
  6818. # 輸送帶3
  6819. try:
  6820. belt3 = ConveyorBelt3.query.order_by(text('datetime desc')).first()
  6821. datetime = belt3.datetime
  6822. belts3 = ConveyorBelt3.query.filter_by(datetime=datetime).all()
  6823. except Exception as e:
  6824. pass
  6825. return render_template('cargo1_schedule.html', params=locals())
  6826. else:
  6827. current_time = dt.now()
  6828. # 循環從前端提交過來的資料
  6829. for i in request.form:
  6830. # 進豆閥
  6831. if i[:10] == 'inletValve':
  6832. if i[:19] == 'inletValve_duration':
  6833. bean = BeanValve()
  6834. bean.duration = request.form[i]
  6835. elif i[:18] == 'inletValve_from_hr':
  6836. iv_from_hr = request.form[i]
  6837. elif i[:19] == 'inletValve_from_min':
  6838. iv_from_min = request.form[i]
  6839. bean.start = iv_from_hr + ":" + iv_from_min
  6840. elif i[:16] == 'inletValve_to_hr':
  6841. iv_to_hr = request.form[i]
  6842. elif i[:17] == 'inletValve_to_min':
  6843. iv_to_min = request.form[i]
  6844. bean.end = iv_to_hr + ":" + iv_to_min
  6845. bean.datetime = current_time
  6846. db.session.add(bean)
  6847. db.session.commit()
  6848. # 清洗機
  6849. elif i[:4] == 'wash':
  6850. if i[:13] == 'wash_duration':
  6851. wash = WashMachine()
  6852. wash.duration = request.form[i]
  6853. elif i[:12] == 'wash_from_hr':
  6854. wash_from_hr = request.form[i]
  6855. elif i[:13] == 'wash_from_min':
  6856. wash_from_min = request.form[i]
  6857. wash.start = wash_from_hr + ":" + wash_from_min
  6858. elif i[:10] == 'wash_to_hr':
  6859. wash_to_hr = request.form[i]
  6860. elif i[:11] == 'wash_to_min':
  6861. wash_to_min = request.form[i]
  6862. wash.end = wash_to_hr + ":" + wash_to_min
  6863. wash.datetime = current_time
  6864. db.session.add(wash)
  6865. db.session.commit()
  6866. # 輸送帶1
  6867. elif i[:5] == 'belt1':
  6868. if i[:14] == 'belt1_duration':
  6869. belt1 = ConveyorBelt1()
  6870. belt1.duration = request.form[i]
  6871. elif i[:13] == 'belt1_from_hr':
  6872. belt1_from_hr = request.form[i]
  6873. elif i[:14] == 'belt1_from_min':
  6874. belt1_from_min = request.form[i]
  6875. belt1.start = belt1_from_hr + ":" + belt1_from_min
  6876. elif i[:11] == 'belt1_to_hr':
  6877. belt1_to_hr = request.form[i]
  6878. elif i[:12] == 'belt1_to_min':
  6879. belt1_to_min = request.form[i]
  6880. belt1.end = belt1_to_hr + ":" + belt1_to_min
  6881. belt1.datetime = current_time
  6882. db.session.add(belt1)
  6883. db.session.commit()
  6884. # 消毒
  6885. elif i[:9] == 'disinfect':
  6886. if i[:18] == 'disinfect_duration':
  6887. disinfect = Cargo1Disinfect()
  6888. disinfect.duration = request.form[i]
  6889. elif i[:17] == 'disinfect_from_hr':
  6890. di_from_hr = request.form[i]
  6891. elif i[:18] == 'disinfect_from_min':
  6892. di_from_min = request.form[i]
  6893. disinfect.start = di_from_hr + ":" + di_from_min
  6894. elif i[:15] == 'disinfect_to_hr':
  6895. di_to_hr = request.form[i]
  6896. elif i[:16] == 'disinfect_to_min':
  6897. di_to_min = request.form[i]
  6898. disinfect.end = di_to_hr + ":" + di_to_min
  6899. disinfect.datetime = current_time
  6900. db.session.add(disinfect)
  6901. db.session.commit()
  6902. # 色選機
  6903. elif i[:5] == 'color':
  6904. if i[:14] == 'color_duration':
  6905. color = ColorMachine()
  6906. color.duration = request.form[i]
  6907. elif i[:13] == 'color_from_hr':
  6908. color_from_hr = request.form[i]
  6909. elif i[:14] == 'color_from_min':
  6910. color_from_min = request.form[i]
  6911. color.start = color_from_hr + ":" + color_from_min
  6912. elif i[:11] == 'color_to_hr':
  6913. color_to_hr = request.form[i]
  6914. elif i[:12] == 'color_to_min':
  6915. color_to_min = request.form[i]
  6916. color.end = color_to_hr + ":" + color_to_min
  6917. color.datetime = current_time
  6918. db.session.add(color)
  6919. db.session.commit()
  6920. # 輸送帶2
  6921. elif i[:5] == 'belt2':
  6922. if i[:14] == 'belt2_duration':
  6923. belt2 = ConveyorBelt2()
  6924. belt2.duration = request.form[i]
  6925. elif i[:13] == 'belt2_from_hr':
  6926. belt2_from_hr = request.form[i]
  6927. elif i[:14] == 'belt2_from_min':
  6928. belt2_from_min = request.form[i]
  6929. belt2.start = belt2_from_hr + ":" + belt2_from_min
  6930. elif i[:11] == 'belt2_to_hr':
  6931. belt2_to_hr = request.form[i]
  6932. elif i[:12] == 'belt2_to_min':
  6933. belt2_to_min = request.form[i]
  6934. belt2.end = belt2_to_hr + ":" + belt2_to_min
  6935. belt2.datetime = current_time
  6936. db.session.add(belt2)
  6937. db.session.commit()
  6938. # 去皮機
  6939. elif i[:6] == 'peeled':
  6940. if i[:15] == 'peeled_duration':
  6941. peeling = PeelingMachine()
  6942. peeling.duration = request.form[i]
  6943. elif i[:14] == 'peeled_from_hr':
  6944. peeled_from_hr = request.form[i]
  6945. elif i[:15] == 'peeled_from_min':
  6946. peeled_from_min = request.form[i]
  6947. peeling.start = peeled_from_hr + ":" + peeled_from_min
  6948. elif i[:12] == 'peeled_to_hr':
  6949. peeled_to_hr = request.form[i]
  6950. elif i[:13] == 'peeled_to_min':
  6951. peeled_to_min = request.form[i]
  6952. peeling.end = peeled_to_hr + ":" + peeled_to_min
  6953. peeling.datetime = current_time
  6954. db.session.add(peeling)
  6955. db.session.commit()
  6956. # 輸送帶3
  6957. elif i[:5] == 'belt3':
  6958. if i[:14] == 'belt3_duration':
  6959. belt3 = ConveyorBelt3()
  6960. belt3.duration = request.form[i]
  6961. elif i[:13] == 'belt3_from_hr':
  6962. belt3_from_hr = request.form[i]
  6963. elif i[:14] == 'belt3_from_min':
  6964. belt3_from_min = request.form[i]
  6965. belt3.start = belt3_from_hr + ":" + belt3_from_min
  6966. elif i[:11] == 'belt3_to_hr':
  6967. belt3_to_hr = request.form[i]
  6968. elif i[:12] == 'belt3_to_min':
  6969. belt3_to_min = request.form[i]
  6970. belt3.end = belt3_to_hr + ":" + belt3_to_min
  6971. belt3.datetime = current_time
  6972. db.session.add(belt3)
  6973. db.session.commit()
  6974. return render_template('cargo1.html', params=locals())
  6975. # 貨櫃2的訪問路徑
  6976. @main.route('/cargo2', methods=['GET', 'POST'])
  6977. def cargo2_views():
  6978. username = session['uname']
  6979. if request.method == 'GET':
  6980. return render_template('cargo2.html', params=locals())
  6981. else:
  6982. pass
  6983. # 貨櫃2排程的發酵槽訪問路徑
  6984. @main.route('/cargo2_schedule_tanks', methods=['GET', 'POST'])
  6985. def cargo2_schedule_tanks_views():
  6986. username = session['uname']
  6987. if request.method == 'GET':
  6988. return render_template('cargo2_schedule_tanks.html', params=locals())
  6989. else:
  6990. pass
  6991. # 貨櫃2排程發酵槽的清單訪問路徑
  6992. @main.route('/cargo2_schedule/<tid>', methods=['GET', 'POST'])
  6993. def cargo2_schedule_views(tid):
  6994. username = session['uname']
  6995. if request.method == 'GET':
  6996. # 將已儲存的排程資料傳給前端
  6997. # 打菌
  6998. try:
  6999. bacteria = Bacteria.query.filter_by(tank_num=int(
  7000. tid)).order_by(text('datetime desc')).first()
  7001. datetime = bacteria.datetime
  7002. bacterias = Bacteria.query.filter_by(datetime=datetime).all()
  7003. except Exception as e:
  7004. pass
  7005. # 消毒
  7006. try:
  7007. disinfect = Cargo2Disinfect.query.filter_by(
  7008. tank_num=int(tid)).order_by(text('datetime desc')).first()
  7009. datetime = disinfect.datetime
  7010. disinfects = Cargo2Disinfect.query.filter_by(
  7011. datetime=datetime).all()
  7012. except Exception as e:
  7013. pass
  7014. # 加熱
  7015. try:
  7016. heating = Heating.query.filter_by(tank_num=int(
  7017. tid)).order_by(text('datetime desc')).first()
  7018. datetime = heating.datetime
  7019. heatings = Heating.query.filter_by(datetime=datetime).all()
  7020. except Exception as e:
  7021. pass
  7022. # 攪拌
  7023. try:
  7024. stir = Stir.query.filter_by(tank_num=int(tid)).order_by(
  7025. text('datetime desc')).first()
  7026. datetime = stir.datetime
  7027. stirs = Stir.query.filter_by(datetime=datetime).all()
  7028. except Exception as e:
  7029. pass
  7030. # 注水
  7031. try:
  7032. water = WaterInjection.query.filter_by(
  7033. tank_num=int(tid)).order_by(text('datetime desc')).first()
  7034. datetime = water.datetime
  7035. waters = WaterInjection.query.filter_by(datetime=datetime).all()
  7036. except Exception as e:
  7037. pass
  7038. # 開上閥
  7039. try:
  7040. top = TopValve.query.filter_by(tank_num=int(
  7041. tid)).order_by(text('datetime desc')).first()
  7042. datetime = top.datetime
  7043. tops = TopValve.query.filter_by(datetime=datetime).all()
  7044. except Exception as e:
  7045. pass
  7046. # 開下閥
  7047. try:
  7048. bottom = BottomValve.query.filter_by(tank_num=int(
  7049. tid)).order_by(text('datetime desc')).first()
  7050. datetime = bottom.datetime
  7051. bottoms = BottomValve.query.filter_by(datetime=datetime).all()
  7052. except Exception as e:
  7053. pass
  7054. # 溫度
  7055. try:
  7056. tem = Temperature.query.filter_by(tank_num=int(
  7057. tid)).order_by(text('datetime desc')).first()
  7058. datetime = tem.datetime
  7059. tems = Temperature.query.filter_by(datetime=datetime).all()
  7060. except Exception as e:
  7061. pass
  7062. return render_template('cargo2_schedule.html', params=locals())
  7063. else:
  7064. current_time = dt.now()
  7065. # 循環從前端提交過來的資料
  7066. for i in request.form:
  7067. # 打菌
  7068. if i[:8] == 'bacteria':
  7069. if i[:17] == 'bacteria_duration':
  7070. bacteria = Bacteria()
  7071. bacteria.duration = request.form[i]
  7072. elif i[:16] == 'bacteria_from_hr':
  7073. bac_from_hr = request.form[i]
  7074. elif i[:17] == 'bacteria_from_min':
  7075. bac_from_min = request.form[i]
  7076. bacteria.start = bac_from_hr + ":" + bac_from_min
  7077. elif i[:14] == 'bacteria_to_hr':
  7078. bac_to_hr = request.form[i]
  7079. elif i[:15] == 'bacteria_to_min':
  7080. bac_to_min = request.form[i]
  7081. bacteria.end = bac_to_hr + ":" + bac_to_min
  7082. bacteria.datetime = current_time
  7083. bacteria.tank_num = int(tid)
  7084. db.session.add(bacteria)
  7085. db.session.commit()
  7086. # 消毒
  7087. elif i[:9] == 'disinfect':
  7088. if i[:18] == 'disinfect_duration':
  7089. disinfect = Cargo2Disinfect()
  7090. disinfect.duration = request.form[i]
  7091. elif i[:17] == 'disinfect_from_hr':
  7092. di_from_hr = request.form[i]
  7093. elif i[:18] == 'disinfect_from_min':
  7094. di_from_min = request.form[i]
  7095. disinfect.start = di_from_hr + ":" + di_from_min
  7096. elif i[:15] == 'disinfect_to_hr':
  7097. di_to_hr = request.form[i]
  7098. elif i[:16] == 'disinfect_to_min':
  7099. di_to_min = request.form[i]
  7100. disinfect.end = di_to_hr + ":" + di_to_min
  7101. disinfect.datetime = current_time
  7102. disinfect.tank_num = int(tid)
  7103. db.session.add(disinfect)
  7104. db.session.commit()
  7105. # 加熱
  7106. elif i[:7] == 'heating':
  7107. if i[:16] == 'heating_duration':
  7108. heating = Heating()
  7109. heating.duration = request.form[i]
  7110. elif i[:15] == 'heating_from_hr':
  7111. heat_from_hr = request.form[i]
  7112. elif i[:16] == 'heating_from_min':
  7113. heat_from_min = request.form[i]
  7114. heating.start = heat_from_hr + ":" + heat_from_min
  7115. elif i[:13] == 'heating_to_hr':
  7116. heat_to_hr = request.form[i]
  7117. elif i[:14] == 'heating_to_min':
  7118. heat_to_min = request.form[i]
  7119. heating.end = heat_to_hr + ":" + heat_to_min
  7120. heating.datetime = current_time
  7121. heating.tank_num = int(tid)
  7122. db.session.add(heating)
  7123. db.session.commit()
  7124. # 攪拌
  7125. elif i[:4] == 'stir':
  7126. if i[:13] == 'stir_duration':
  7127. stir = Stir()
  7128. stir.duration = request.form[i]
  7129. elif i[:12] == 'stir_from_hr':
  7130. stir_from_hr = request.form[i]
  7131. elif i[:13] == 'stir_from_min':
  7132. stir_from_min = request.form[i]
  7133. stir.start = stir_from_hr + ":" + stir_from_min
  7134. elif i[:10] == 'stir_to_hr':
  7135. stir_to_hr = request.form[i]
  7136. elif i[:11] == 'stir_to_min':
  7137. stir_to_min = request.form[i]
  7138. stir.end = stir_to_hr + ":" + stir_to_min
  7139. stir.datetime = current_time
  7140. stir.tank_num = int(tid)
  7141. db.session.add(stir)
  7142. db.session.commit()
  7143. # 注水
  7144. elif i[:5] == 'water':
  7145. if i[:14] == 'water_duration':
  7146. water = WaterInjection()
  7147. water.duration = request.form[i]
  7148. elif i[:13] == 'water_from_hr':
  7149. water_from_hr = request.form[i]
  7150. elif i[:14] == 'water_from_min':
  7151. water_from_min = request.form[i]
  7152. water.start = water_from_hr + ":" + water_from_min
  7153. elif i[:11] == 'water_to_hr':
  7154. water_to_hr = request.form[i]
  7155. elif i[:12] == 'water_to_min':
  7156. water_to_min = request.form[i]
  7157. water.end = water_to_hr + ":" + water_to_min
  7158. water.datetime = current_time
  7159. water.tank_num = int(tid)
  7160. db.session.add(water)
  7161. db.session.commit()
  7162. # 開上閥
  7163. elif i[:9] == 'highValve':
  7164. if i[:18] == 'highValve_duration':
  7165. top = TopValve()
  7166. top.duration = request.form[i]
  7167. elif i[:17] == 'highValve_from_hr':
  7168. h_valve_from_hr = request.form[i]
  7169. elif i[:18] == 'highValve_from_min':
  7170. h_valve_from_min = request.form[i]
  7171. top.start = h_valve_from_hr + ":" + h_valve_from_min
  7172. elif i[:15] == 'highValve_to_hr':
  7173. h_valve_to_hr = request.form[i]
  7174. elif i[:16] == 'highValve_to_min':
  7175. h_valve_to_min = request.form[i]
  7176. top.end = h_valve_to_hr + ":" + h_valve_to_min
  7177. top.datetime = current_time
  7178. top.tank_num = int(tid)
  7179. db.session.add(top)
  7180. db.session.commit()
  7181. # 開下閥
  7182. elif i[:8] == 'lowValve':
  7183. if i[:17] == 'lowValve_duration':
  7184. bottom = BottomValve()
  7185. bottom.duration = request.form[i]
  7186. elif i[:16] == 'lowValve_from_hr':
  7187. l_valve_from_hr = request.form[i]
  7188. elif i[:17] == 'lowValve_from_min':
  7189. l_valve_from_min = request.form[i]
  7190. bottom.start = l_valve_from_hr + ":" + l_valve_from_min
  7191. elif i[:14] == 'lowValve_to_hr':
  7192. l_valve_to_hr = request.form[i]
  7193. elif i[:15] == 'lowValve_to_min':
  7194. l_valve_to_min = request.form[i]
  7195. bottom.end = l_valve_to_hr + ":" + l_valve_to_min
  7196. bottom.datetime = current_time
  7197. bottom.tank_num = int(tid)
  7198. db.session.add(bottom)
  7199. db.session.commit()
  7200. # 溫度
  7201. elif i[:3] == 'tem':
  7202. if i[:12] == 'tem_duration':
  7203. tem = Temperature()
  7204. tem.duration = request.form[i]
  7205. elif i[:11] == 'tem_from_hr':
  7206. tem_from_hr = request.form[i]
  7207. elif i[:12] == 'tem_from_min':
  7208. tem_from_min = request.form[i]
  7209. tem.start = tem_from_hr + ":" + tem_from_min
  7210. elif i[:9] == 'tem_to_hr':
  7211. tem_to_hr = request.form[i]
  7212. elif i[:10] == 'tem_to_min':
  7213. tem_to_min = request.form[i]
  7214. tem.end = tem_to_hr + ":" + tem_to_min
  7215. tem.datetime = current_time
  7216. tem.tank_num = int(tid)
  7217. db.session.add(tem)
  7218. db.session.commit()
  7219. return render_template('cargo2.html', params=locals())
  7220. # 貨櫃2感測器的發酵槽訪問路徑
  7221. @main.route('/cargo2_sensor_tanks', methods=['GET', 'POST'])
  7222. def cargo2_sensor_tanks_views():
  7223. username = session['uname']
  7224. if request.method == 'GET':
  7225. return render_template('cargo2_sensor_tanks.html', params=locals())
  7226. else:
  7227. pass
  7228. # 貨櫃2感測器發酵槽的清單訪問路徑
  7229. @main.route('/cargo2_sensor/<tid>', methods=['GET', 'POST'])
  7230. def s_tank_views(tid):
  7231. # 判斷用戶是否已關閉瀏覽器或登出後,在訪問這個route,如果沒有session就回登入頁
  7232. try:
  7233. username = session['uname']
  7234. except KeyError:
  7235. return redirect('/')
  7236. if request.method == 'GET':
  7237. # Rita 網頁端 params.tank_tem.tem
  7238. # Coffee/CoffeeProject/app/templates/cargo2_sensor.html
  7239. tank_tem = TankTemSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7240. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7241. tank_ec = TankECSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7242. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  7243. return render_template('cargo2_sensor.html', params=locals())
  7244. else:
  7245. pass
  7246. # 貨櫃2感測器發酵槽歷史數據的訪問路徑
  7247. @main.route('/history_data', methods=['GET', 'POST'])
  7248. def history_data_views():
  7249. if request.method == 'GET':
  7250. # json
  7251. # tid:tid_D1
  7252. # sensor_name:soil_Temp
  7253. # avg:1
  7254. # max:1
  7255. # min:1
  7256. # time-interval:month
  7257. # date-start:2021-07-01
  7258. # date-end:2021-07-28
  7259. info = request.args.to_dict()
  7260. evt = info['evt']
  7261. avg = int(info['avg'])
  7262. max = int(info['max'])
  7263. min = int(info['min'])
  7264. time_interval = info['time-interval']
  7265. print(info)
  7266. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  7267. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  7268. # print(info)
  7269. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  7270. # print(D)
  7271. # {'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']],
  7272. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  7273. # 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 -
  7274. date_start = info['date-start']
  7275. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  7276. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  7277. date_end = '-'.join(date_end_list) # '2021-05-19'
  7278. tank_num = evt.split('-')[0] # 1
  7279. sensor = evt.split('-')[1] # 溫濕度
  7280. L = []
  7281. D = {}
  7282. maxData = []
  7283. minData = []
  7284. avgData = []
  7285. def sensorData(data_name): # data_name = "tem"
  7286. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  7287. interval = 0
  7288. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  7289. if time_interval == 'month':
  7290. interval = "M" # interval = "M"
  7291. elif time_interval == 'day':
  7292. interval = "D"
  7293. elif time_interval == 'hour':
  7294. interval = "H"
  7295. if how == "max":
  7296. # data = df.resample(interval, how={data_name:how})
  7297. # 最新版的pandas
  7298. data = df.resample(interval).max() # 取樣頻率 "H"
  7299. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  7300. data = data.dropna(axis=0, how='any')
  7301. if time_interval == ('hour' or 'day'):
  7302. data.index = pd.to_datetime(
  7303. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7304. for a in range(0, len(data.index)):
  7305. l = []
  7306. # 如果是逐時,才顯示小時分秒
  7307. if time_interval == 'hour':
  7308. l.append(str(data.index[a]))
  7309. else:
  7310. l.append(str(data.index[a]).split(' ')[0])
  7311. l.append(str(data[data_name][a]))
  7312. maxData.append(l)
  7313. D['max'] = maxData
  7314. elif how == "mean":
  7315. # data = df.resample(interval, how={data_name:how})
  7316. # 最新版的pandas
  7317. data = df.resample(interval).mean()
  7318. # 刪除具有NaN的值
  7319. data = data.dropna(axis=0, how='any')
  7320. # 將平均數取自小數1位
  7321. data = data.round({data_name: 1})
  7322. for a in range(0, len(data.index)):
  7323. l = []
  7324. # 如果是逐時,才顯示小時分秒
  7325. if time_interval == 'hour':
  7326. l.append(str(data.index[a]))
  7327. else:
  7328. l.append(str(data.index[a]).split(' ')[0])
  7329. l.append(str(data[data_name][a]))
  7330. avgData.append(l)
  7331. D['avg'] = avgData
  7332. elif how == "min":
  7333. # data = df.resample(interval, how={data_name:how})
  7334. # 最新版的pandas
  7335. data = df.resample(interval).min()
  7336. # 刪除具有NaN的值
  7337. data = data.dropna(axis=0, how='any')
  7338. for a in range(0, len(data.index)):
  7339. # print(data.index[a])
  7340. l = []
  7341. # 如果是逐時,才顯示小時分秒
  7342. if time_interval == 'hour':
  7343. l.append(str(data.index[a]))
  7344. else:
  7345. l.append(str(data.index[a]).split(' ')[0])
  7346. l.append(str(data[data_name][a]))
  7347. minData.append(l)
  7348. D['min'] = minData
  7349. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  7350. df['datetime'] = pd.to_datetime(
  7351. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7352. # print(df['datetime']) # 0 2021-02-19 16:46:10
  7353. # 1 2021-02-19 16:46:20
  7354. # 2 2021-02-19 16:46:30
  7355. # 3 2021-02-19 16:46:41
  7356. df[data_name] = df[data_name].astype(float)
  7357. df = df.set_index('datetime') # 将datetime设置为index
  7358. # print(df) # datetime tem
  7359. # 2021-02-19 16:46:10 24.4
  7360. # 2021-02-19 16:46:20 24.4
  7361. if time_interval == 'month':
  7362. if max:
  7363. dataResample(time_interval, "max", data_name)
  7364. if avg:
  7365. dataResample(time_interval, "mean", data_name)
  7366. if min:
  7367. dataResample(time_interval, "min", data_name)
  7368. elif time_interval == 'day':
  7369. if max:
  7370. dataResample(time_interval, "max", data_name)
  7371. if avg:
  7372. dataResample(time_interval, "mean", data_name)
  7373. if min:
  7374. dataResample(time_interval, "min", data_name)
  7375. elif time_interval == 'hour':
  7376. if max:
  7377. dataResample(time_interval, "max", data_name)
  7378. if avg:
  7379. dataResample(time_interval, "mean", data_name)
  7380. if min:
  7381. dataResample(time_interval, "min", data_name)
  7382. if sensor == '溫濕度':
  7383. # tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).order_by(text('datetime desc')).all()
  7384. # [7/27 Benson] tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).filter(TankTemSensor.datetime.between(date_start, date_end)).all()
  7385. tank_tem = dry_tank_SHT11.query.filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7386. # .filter_by(tank_num="D"+tank_num)
  7387. for tem in tank_tem:
  7388. l = [] # l = []
  7389. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  7390. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7391. l.append(time) # l = ['2021-Feb-19_16:46:10']
  7392. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  7393. l.append(tem.SHT11_Temp)
  7394. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  7395. # print(L)
  7396. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  7397. sensorData("tem")
  7398. elif sensor == '酸鹼值':
  7399. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7400. TankPHSensor.datetime.between(date_start, date_end)).all()
  7401. for ph in tank_ph:
  7402. l = []
  7403. time = dt.strftime(ph.datetime, '%Y-%b-%d_%H:%M:%S')
  7404. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7405. l.append(time)
  7406. l.append(ph.ph)
  7407. L.append(l)
  7408. # print(L)
  7409. D['all'] = L
  7410. sensorData("ph")
  7411. elif sensor == 'EC值':
  7412. tank_ec = TankECSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7413. TankECSensor.datetime.between(date_start, date_end)).all()
  7414. for ec in tank_ec:
  7415. l = []
  7416. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  7417. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7418. l.append(time)
  7419. l.append(ec.ec)
  7420. L.append(l)
  7421. # print(L)
  7422. D['all'] = L
  7423. sensorData("ec")
  7424. elif sensor == '超音波':
  7425. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tank_num)).filter(
  7426. TankSonicSensor.datetime.between(date_start, date_end)).all()
  7427. for sonic in tank_sonic:
  7428. l = []
  7429. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7430. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7431. l.append(time)
  7432. l.append(sonic.sonic)
  7433. L.append(l)
  7434. # print(L)
  7435. D['all'] = L
  7436. sensorData("sonic")
  7437. print(D)
  7438. return json.dumps(D)
  7439. else:
  7440. pass
  7441. # Rita 改寫
  7442. @main.route('/history_data_new', methods=['GET', 'POST'])
  7443. def history_data_new_views():
  7444. if request.method == 'GET':
  7445. # json
  7446. # tid:tid_D1
  7447. # sensor_name:soil_Temp
  7448. # avg:1
  7449. # max:1
  7450. # min:1
  7451. # time-interval:month
  7452. # date-start:2021-07-01
  7453. # date-end:2021-07-28
  7454. info = request.args.to_dict()
  7455. # evt = info['evt']
  7456. tid = info['tid']
  7457. sensor_name = info['sensor_name']
  7458. avg = int(info['avg'])
  7459. max = int(info['max'])
  7460. min = int(info['min'])
  7461. time_interval = info['time-interval']
  7462. print("info:", info)
  7463. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  7464. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  7465. # print(info)
  7466. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  7467. # print(D)
  7468. # {'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']],
  7469. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  7470. # 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 -
  7471. date_start = info['date-start']
  7472. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  7473. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  7474. date_end = '-'.join(date_end_list) # '2021-05-19'
  7475. # tank_num = evt.split('-')[0] # 1
  7476. # sensor = evt.split('-')[1] # 溫濕度
  7477. tank_num = tid # D1
  7478. sensor = sensor_name # soil_Temp
  7479. L = []
  7480. D = {}
  7481. maxData = []
  7482. minData = []
  7483. avgData = []
  7484. def sensorData(data_name): # data_name = "tem"
  7485. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  7486. interval = 0
  7487. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  7488. if time_interval == 'month':
  7489. interval = "M" # interval = "M"
  7490. elif time_interval == 'day':
  7491. interval = "D"
  7492. elif time_interval == 'hour':
  7493. interval = "H"
  7494. if how == "max":
  7495. # data = df.resample(interval, how={data_name:how})
  7496. # 最新版的pandas
  7497. data = df.resample(interval).max() # 取樣頻率 'H'
  7498. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  7499. data = data.dropna(axis=0, how='any')
  7500. if time_interval == ('hour' or 'day'):
  7501. data.index = pd.to_datetime(
  7502. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7503. for a in range(0, len(data.index)):
  7504. l = []
  7505. # 如果是逐時,才顯示小時分秒
  7506. if time_interval == 'hour':
  7507. l.append(str(data.index[a]))
  7508. else:
  7509. l.append(str(data.index[a]).split(' ')[0])
  7510. l.append(str(data[data_name][a]))
  7511. maxData.append(l)
  7512. D['max'] = maxData
  7513. elif how == "mean":
  7514. # data = df.resample(interval, how={data_name:how})
  7515. # 最新版的pandas
  7516. data = df.resample(interval).mean()
  7517. # 刪除具有NaN的值
  7518. data = data.dropna(axis=0, how='any')
  7519. # 將平均數取自小數1位
  7520. data = data.round({data_name: 1})
  7521. for a in range(0, len(data.index)):
  7522. l = []
  7523. # 如果是逐時,才顯示小時分秒
  7524. if time_interval == 'hour':
  7525. l.append(str(data.index[a]))
  7526. else:
  7527. l.append(str(data.index[a]).split(' ')[0])
  7528. l.append(str(data[data_name][a]))
  7529. avgData.append(l)
  7530. D['avg'] = avgData
  7531. elif how == "min":
  7532. # data = df.resample(interval, how={data_name:how})
  7533. # 最新版的pandas
  7534. data = df.resample(interval).min()
  7535. # 刪除具有NaN的值
  7536. data = data.dropna(axis=0, how='any')
  7537. for a in range(0, len(data.index)):
  7538. # print(data.index[a])
  7539. l = []
  7540. # 如果是逐時,才顯示小時分秒
  7541. if time_interval == 'hour':
  7542. l.append(str(data.index[a]))
  7543. else:
  7544. l.append(str(data.index[a]).split(' ')[0])
  7545. l.append(str(data[data_name][a]))
  7546. minData.append(l)
  7547. D['min'] = minData
  7548. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  7549. df['datetime'] = pd.to_datetime(
  7550. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  7551. # print(df['datetime']) # 0 2021-02-19 16:46:10
  7552. # 1 2021-02-19 16:46:20
  7553. # 2 2021-02-19 16:46:30
  7554. # 3 2021-02-19 16:46:41
  7555. df[data_name] = df[data_name].astype(float)
  7556. df = df.set_index('datetime') # 将datetime设置为index
  7557. # print(df) # datetime tem
  7558. # 2021-02-19 16:46:10 24.4
  7559. # 2021-02-19 16:46:20 24.4
  7560. if time_interval == 'month':
  7561. if max:
  7562. dataResample(time_interval, "max", data_name)
  7563. if avg:
  7564. dataResample(time_interval, "mean", data_name)
  7565. if min:
  7566. dataResample(time_interval, "min", data_name)
  7567. elif time_interval == 'day':
  7568. if max:
  7569. dataResample(time_interval, "max", data_name)
  7570. if avg:
  7571. dataResample(time_interval, "mean", data_name)
  7572. if min:
  7573. dataResample(time_interval, "min", data_name)
  7574. elif time_interval == 'hour':
  7575. if max:
  7576. dataResample(time_interval, "max", data_name)
  7577. if avg:
  7578. dataResample(time_interval, "mean", data_name)
  7579. if min:
  7580. dataResample(time_interval, "min", data_name)
  7581. if tank_num[:2] == 'DI':
  7582. # 乾燥入料儲豆槽
  7583. if sensor == 'UltraSonic':
  7584. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num=tank_num).filter(dry_input_sensor.datetime.between(date_start, date_end)).all()
  7585. for sonic in tank_UltraSonic:
  7586. l = []
  7587. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7588. l.append(time)
  7589. l.append(sonic.UltraSonic)
  7590. L.append(l)
  7591. D['all'] = L
  7592. sensorData("UltraSonic")
  7593. elif tank_num[:2] == 'DO':
  7594. # 乾燥出料儲豆槽
  7595. if sensor == 'UltraSonic':
  7596. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num=tank_num).filter(dry_output_sensor.datetime.between(date_start, date_end)).all()
  7597. for sonic in tank_UltraSonic:
  7598. l = []
  7599. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7600. l.append(time)
  7601. l.append(sonic.UltraSonic)
  7602. L.append(l)
  7603. D['all'] = L
  7604. sensorData("UltraSonic")
  7605. elif tank_num[:1] == 'D':
  7606. # 乾燥槽
  7607. if sensor == 'SHT11_Temp':
  7608. tank_tem = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7609. for tem in tank_tem:
  7610. l = [] # l = []
  7611. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  7612. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7613. l.append(time) # l = ['2021-Feb-19_16:46:10']
  7614. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  7615. l.append(tem.SHT11_Temp)
  7616. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  7617. # print(L)
  7618. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  7619. sensorData("SHT11_Temp")
  7620. elif sensor == 'SHT11_Humidity':
  7621. tank_hum = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  7622. for hum in tank_hum:
  7623. l = []
  7624. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  7625. l.append(time)
  7626. l.append(hum.SHT11_Humidity)
  7627. L.append(l)
  7628. D['all'] = L
  7629. sensorData("SHT11_Humidity")
  7630. elif sensor == 'UltraSonic':
  7631. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num=tank_num).filter(dry_tank_UltraSonic.datetime.between(date_start, date_end)).all()
  7632. for sonic in tank_UltraSonic:
  7633. l = []
  7634. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7635. l.append(time)
  7636. l.append(sonic.UltraSonic)
  7637. L.append(l)
  7638. D['all'] = L
  7639. sensorData("UltraSonic")
  7640. elif sensor == 'PA':
  7641. tank_PA = dry_tank_PA.query.filter_by(tank_num=tank_num).filter(dry_tank_PA.datetime.between(date_start, date_end)).all()
  7642. for pa in tank_PA:
  7643. l = []
  7644. time = dt.strftime(pa.datetime, '%Y-%b-%d_%H:%M:%S')
  7645. l.append(time)
  7646. l.append(pa.PA)
  7647. L.append(l)
  7648. D['all'] = L
  7649. sensorData("PA")
  7650. elif sensor == 'soil_Temp':
  7651. tank_soiltemp = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7652. for temp in tank_soiltemp:
  7653. l = []
  7654. time = dt.strftime(temp.datetime, '%Y-%b-%d_%H:%M:%S')
  7655. l.append(time)
  7656. l.append(temp.soil_Temp)
  7657. L.append(l)
  7658. D['all'] = L
  7659. sensorData("soil_Temp")
  7660. elif sensor == 'soil_Humidity':
  7661. tank_soilHum = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7662. for hum in tank_soilHum:
  7663. l = []
  7664. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  7665. l.append(time)
  7666. l.append(hum.soil_EC)
  7667. L.append(l)
  7668. D['all'] = L
  7669. sensorData("soil_Humidity")
  7670. elif sensor == 'soil_EC':
  7671. tank_soilec = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  7672. for ec in tank_soilec:
  7673. l = []
  7674. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  7675. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  7676. l.append(time)
  7677. l.append(ec.soil_EC)
  7678. L.append(l)
  7679. D['all'] = L
  7680. sensorData("soil_EC")
  7681. elif tank_num[:2] == 'FI':
  7682. if sensor == 'UltraSonic':
  7683. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_input_UltraSonic.datetime.between(date_start, date_end)).all()
  7684. for UltraSonic in input_UltraSonic:
  7685. l = []
  7686. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7687. l.append(time)
  7688. l.append(UltraSonic.UltraSonic)
  7689. L.append(l)
  7690. D['all'] = L
  7691. sensorData("UltraSonic")
  7692. elif tank_num[:2] == 'FO':
  7693. if sensor == 'UltraSonic':
  7694. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_output_UltraSonic.datetime.between(date_start, date_end)).all()
  7695. for UltraSonic in output_UltraSonic:
  7696. l = []
  7697. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  7698. l.append(time)
  7699. l.append(UltraSonic.UltraSonic)
  7700. L.append(l)
  7701. D['all'] = L
  7702. sensorData("UltraSonic")
  7703. elif tank_num[:1] == 'F':
  7704. if sensor == 'LiDAR':
  7705. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num = tank_num)\
  7706. .filter(ferment_tank_LiDAR.datetime.between(date_start, date_end)).all()
  7707. for LiDAR in tank_LiDAR:
  7708. l = []
  7709. time = dt.strftime(LiDAR.datetime, '%Y-%b-%d_%H:%M:%S')
  7710. l.append(time)
  7711. l.append(LiDAR.LiDAR)
  7712. L.append(l)
  7713. D['all'] = L
  7714. sensorData("LiDAR")
  7715. elif sensor == 'motorEncoder':
  7716. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num = tank_num)\
  7717. .filter(ferment_tank_motorEncoder.datetime.between(date_start, date_end)).all()
  7718. for motorEncoder in tank_motorEncoder:
  7719. l = []
  7720. time = dt.strftime(motorEncoder.datetime, '%Y-%b-%d_%H:%M:%S')
  7721. l.append(time)
  7722. l.append(motorEncoder.motorEncoder)
  7723. L.append(l)
  7724. D['all'] = L
  7725. sensorData("motorEncoder")
  7726. elif sensor == 'PressureWaterLevel':
  7727. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num = tank_num)\
  7728. .filter(ferment_tank_PressureWaterLevel.datetime.between(date_start, date_end)).all()
  7729. for PressureWaterLevel in tank_PressureWaterLevel:
  7730. l = []
  7731. time = dt.strftime(PressureWaterLevel.datetime, '%Y-%b-%d_%H:%M:%S')
  7732. l.append(time)
  7733. l.append(PressureWaterLevel.PressureWaterLevel)
  7734. l.append('{:.2f}'.format(float(PressureWaterLevel.PressureWaterLevel)))
  7735. L.append(l)
  7736. D['all'] = L
  7737. sensorData("PressureWaterLevel")
  7738. elif sensor == 'SHT11_Temp':
  7739. tank_Temp = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  7740. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  7741. for Temp in tank_Temp:
  7742. l = []
  7743. time = dt.strftime(Temp.datetime, '%Y-%b-%d_%H:%M:%S')
  7744. l.append(time)
  7745. l.append(Temp.SHT11_Temp)
  7746. L.append(l)
  7747. D['all'] = L
  7748. sensorData("SHT11_Temp")
  7749. elif sensor == 'SHT11_Humidity':
  7750. tank_Humidity = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  7751. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  7752. for Humidity in tank_Humidity:
  7753. l = []
  7754. time = dt.strftime(Humidity.datetime, '%Y-%b-%d_%H:%M:%S')
  7755. l.append(time)
  7756. l.append(Humidity.SHT11_Humidity)
  7757. L.append(l)
  7758. D['all'] = L
  7759. sensorData("SHT11_Humidity")
  7760. elif sensor == 'CO2':
  7761. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num = tank_num)\
  7762. .filter(ferment_tank_CO2.datetime.between(date_start, date_end)).all()
  7763. for CO2 in tank_CO2:
  7764. l = []
  7765. time = dt.strftime(CO2.datetime, '%Y-%b-%d_%H:%M:%S')
  7766. l.append(time)
  7767. l.append(CO2.CO2)
  7768. L.append(l)
  7769. D['all'] = L
  7770. sensorData("CO2")
  7771. elif sensor == 'PH':
  7772. tank_PH = ferment_tank_PH.query.filter_by(tank_num = tank_num)\
  7773. .filter(ferment_tank_PH.datetime.between(date_start, date_end)).all()
  7774. for PH in tank_PH:
  7775. l = []
  7776. time = dt.strftime(PH.datetime, '%Y-%b-%d_%H:%M:%S')
  7777. l.append(time)
  7778. l.append(PH.PH)
  7779. L.append(l)
  7780. D['all'] = L
  7781. sensorData("PH")
  7782. elif sensor == 'ORP':
  7783. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num = tank_num)\
  7784. .filter(ferment_tank_ORP.datetime.between(date_start, date_end)).all()
  7785. for ORP in tank_ORP:
  7786. l = []
  7787. time = dt.strftime(ORP.datetime, '%Y-%b-%d_%H:%M:%S')
  7788. l.append(time)
  7789. l.append(ORP.ORP)
  7790. L.append(l)
  7791. D['all'] = L
  7792. sensorData("ORP")
  7793. elif sensor == 'DO':
  7794. tank_DO = ferment_tank_DO.query.filter_by(tank_num = tank_num)\
  7795. .filter(ferment_tank_DO.datetime.between(date_start, date_end)).all()
  7796. for DO in tank_DO:
  7797. l = []
  7798. time = dt.strftime(DO.datetime, '%Y-%b-%d_%H:%M:%S')
  7799. l.append(time)
  7800. l.append(DO.DO)
  7801. L.append(l)
  7802. D['all'] = L
  7803. sensorData("DO")
  7804. elif sensor == 'EC':
  7805. tank_EC = ferment_tank_EC.query.filter_by(tank_num = tank_num)\
  7806. .filter(ferment_tank_EC.datetime.between(date_start, date_end)).all()
  7807. for EC in tank_EC:
  7808. l = []
  7809. time = dt.strftime(EC.datetime, '%Y-%b-%d_%H:%M:%S')
  7810. l.append(time)
  7811. l.append(EC.EC)
  7812. L.append(l)
  7813. D['all'] = L
  7814. sensorData("EC")
  7815. elif sensor == 'PA':
  7816. tank_PA = ferment_tank_PA.query.filter_by(tank_num = tank_num)\
  7817. .filter(ferment_tank_PA.datetime.between(date_start, date_end)).all()
  7818. for PA in tank_PA:
  7819. l = []
  7820. time = dt.strftime(PA.datetime, '%Y-%b-%d_%H:%M:%S')
  7821. l.append(time)
  7822. l.append(PA.PA)
  7823. L.append(l)
  7824. D['all'] = L
  7825. sensorData("PA")
  7826. print(D)
  7827. return json.dumps(D)
  7828. else:
  7829. pass
  7830. # 貨櫃2致動器的發酵槽訪問路徑
  7831. @main.route('/cargo2_actuator_tanks', methods=['GET', 'POST'])
  7832. def cargo2_actuator_tanks_views():
  7833. username = session['uname']
  7834. if request.method == 'GET':
  7835. return render_template('cargo2_actuator_tanks.html', params=locals())
  7836. else:
  7837. pass
  7838. # 貨櫃2致動器發酵槽的清單訪問路徑
  7839. @main.route('/cargo2_actuator/<tid>', methods=['GET', 'POST'])
  7840. def cargo2_actuator_views(tid):
  7841. username = session['uname']
  7842. if request.method == 'GET':
  7843. return render_template('cargo2_actuator.html', params=locals())
  7844. else:
  7845. pass
  7846. # 貨櫃3的訪問路徑
  7847. @main.route('/cargo3', methods=['GET', 'POST'])
  7848. def cargo3_views():
  7849. username = session['uname']
  7850. if request.method == 'GET':
  7851. return render_template('cargo3.html', params=locals())
  7852. else:
  7853. pass
  7854. # 貨櫃3排程的訪問路徑
  7855. @main.route('/cargo3_schedule', methods=['GET', 'POST'])
  7856. def cargo3_schedule_views():
  7857. username = session['uname']
  7858. if request.method == 'GET':
  7859. # 將已儲存的排程資料傳給前端
  7860. # 提升機
  7861. try:
  7862. hoist = Hoist.query.order_by(text('datetime desc')).first()
  7863. datetime = hoist.datetime
  7864. hoists = Hoist.query.filter_by(datetime=datetime).all()
  7865. except Exception as e:
  7866. pass
  7867. # 烘乾機
  7868. try:
  7869. dryer = Dryer.query.order_by(text('datetime desc')).first()
  7870. datetime = dryer.datetime
  7871. dryers = Dryer.query.filter_by(datetime=datetime).all()
  7872. except Exception as e:
  7873. pass
  7874. return render_template('cargo3_schedule.html', params=locals())
  7875. else:
  7876. # Rita: "POST /b_cargo3 HTTP/1.1" 404 -
  7877. current_time = dt.now()
  7878. # 循環從前端提交過來的資料
  7879. for i in request.form:
  7880. print('Rita test i :', i)
  7881. # 堤升機
  7882. if i[:5] == 'hoist':
  7883. if i[:14] == 'hoist_duration':
  7884. hoist = Hoist()
  7885. hoist.duration = request.form[i]
  7886. elif i[:13] == 'hoist_from_hr':
  7887. ho_from_hr = request.form[i]
  7888. elif i[:14] == 'hoist_from_min':
  7889. ho_from_min = request.form[i]
  7890. hoist.start = ho_from_hr + ":" + ho_from_min
  7891. elif i[:11] == 'hoist_to_hr':
  7892. ho_to_hr = request.form[i]
  7893. elif i[:12] == 'hoist_to_min':
  7894. ho_to_min = request.form[i]
  7895. hoist.end = ho_to_hr + ":" + ho_to_min
  7896. hoist.datetime = current_time
  7897. db.session.add(hoist)
  7898. db.session.commit()
  7899. # 烘乾機
  7900. elif i[:5] == 'dryer':
  7901. if i[:14] == 'dryer_duration':
  7902. dryer = Dryer()
  7903. dryer.duration = request.form[i]
  7904. elif i[:13] == 'dryer_from_hr':
  7905. dry_from_hr = request.form[i]
  7906. elif i[:14] == 'dryer_from_min':
  7907. dry_from_min = request.form[i]
  7908. dryer.start = dry_from_hr + ":" + dry_from_min
  7909. elif i[:11] == 'dryer_to_hr':
  7910. dry_to_hr = request.form[i]
  7911. elif i[:12] == 'dryer_to_min':
  7912. dry_to_min = request.form[i]
  7913. dryer.end = dry_to_hr + ":" + dry_to_min
  7914. dryer.datetime = current_time
  7915. db.session.add(dryer)
  7916. db.session.commit()
  7917. return render_template('cargo3.html', params=locals())
  7918. # 影像串流的訪問路徑
  7919. @main.route('/video', methods=['GET', 'POST'])
  7920. def video_views():
  7921. username = session['uname']
  7922. if request.method == 'GET':
  7923. return render_template('video.html', params=locals())
  7924. else:
  7925. pass
  7926. # 影像的訪問路徑
  7927. @main.route('/learn', methods=['GET', 'POST'])
  7928. def learn_views():
  7929. username = session['uname']
  7930. if request.method == 'GET':
  7931. return render_template('learn.html', params=locals())
  7932. else:
  7933. pass
  7934. # 獲取relay狀態路徑
  7935. @main.route('/relay', methods=['GET', 'POST'])
  7936. def relay_views():
  7937. if request.method == 'GET':
  7938. relay = Relay.query.order_by(text('datetime desc')).first()
  7939. relay_status = relay.status
  7940. return jsonify({"relay": relay_status})
  7941. else:
  7942. pass
  7943. # 獲取脫皮機狀態路徑
  7944. @main.route('/peel', methods=['GET', 'POST'])
  7945. def peeling_views():
  7946. if request.method == 'GET':
  7947. peeling = PeelingMachineRPM.query.order_by(text('datetime desc')).first()
  7948. peeling_rpm = peeling.rpm
  7949. return jsonify({"peeling": peeling_rpm})
  7950. else:
  7951. pass
  7952. # 退出的訪問路徑
  7953. @main.route('/logout')
  7954. def logout_views():
  7955. if 'id' in session and 'uname' in session:
  7956. del session['id']
  7957. del session['uname']
  7958. return redirect('/')
  7959. @main.route("/udp_client", methods=['POST', 'GET'])
  7960. def udp_views():
  7961. # sl(0.5)
  7962. global c_sock
  7963. if request.method == 'GET':
  7964. # def close():
  7965. # global c_sock
  7966. # sl(600)
  7967. # c_sock.close()
  7968. # c_sock = 0
  7969. # print("c_sock is closing")
  7970. max_length = 65000
  7971. # max_length = 95000
  7972. # lab1的IP
  7973. host = "192.168.50.65"
  7974. # lab2的IP
  7975. # host = "192.168.51.160"
  7976. port = 8000
  7977. c_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  7978. # t = threading.Thread(target=close)
  7979. # t.daemon = True
  7980. # t.start()
  7981. print("test")
  7982. # dict = request.args.to_dict()
  7983. # nr = int(dict['nr'])
  7984. # if nr == 1:
  7985. # camara = 0
  7986. # elif nr == 2:
  7987. # camara = 'rtsp://admin:admin@192.168.50.182/av2_0'
  7988. # elif nr == 3:
  7989. # camara = 'rtsp://admin:abcd1234@192.168.51.101/av2_0'
  7990. # 地下室小兵
  7991. # cap = cv2.VideoCapture('rtsp://admin:abcd1234@192.168.51.48/av2_0')
  7992. # 主機攝像頭
  7993. # cap = cv2.VideoCapture(0)
  7994. # 外面小兵
  7995. # cap = cv2.VideoCapture('rtsp://admin:admin@192.168.50.182/av2_0')
  7996. cap = cv2.VideoCapture('rtsp://192.168.50.182/av0_0')
  7997. # cap = cv2.VideoCapture(0)
  7998. # cap = cv2.VideoCapture(camara)
  7999. ret, frame = cap.read()
  8000. while ret:
  8001. # compress frame
  8002. frame = cv2.resize(frame, (550, 400), interpolation=cv2.INTER_AREA)
  8003. retval, buffer = cv2.imencode(".jpg", frame)
  8004. if retval:
  8005. # convert to byte array
  8006. buffer = buffer.tobytes()
  8007. # get size of the frame
  8008. buffer_size = len(buffer)
  8009. num_of_packs = 1
  8010. if buffer_size > max_length:
  8011. num_of_packs = math.ceil(buffer_size / max_length)
  8012. frame_info = {"packs": num_of_packs}
  8013. # send the number of packs to be expected
  8014. # print("Number of packs:", num_of_packs)
  8015. c_sock.sendto(pickle.dumps(frame_info), (host, port))
  8016. left = 0
  8017. right = max_length
  8018. for i in range(num_of_packs):
  8019. # print("left:", left)
  8020. # print("right:", right)
  8021. # truncate data to send
  8022. data = buffer[left:right]
  8023. left = right
  8024. right += max_length
  8025. # send the frames accordingly
  8026. c_sock.sendto(data, (host, port))
  8027. ret, frame = cap.read()
  8028. print("done")
  8029. return "done"
  8030. else:
  8031. c_sock.shutdown(2)
  8032. c_sock.close()
  8033. c_sock = 0
  8034. print("c_sock is closing")
  8035. # 影像串流的路徑
  8036. @main.route("/video_feed", methods=['POST', 'GET'])
  8037. def video_feed_views():
  8038. print("test2")
  8039. global s_sock
  8040. if request.method == 'GET':
  8041. # 於10分鐘之後,自動關閉socket server
  8042. # if s_sock == 0:
  8043. # def socket_server_views():
  8044. # global s_sock
  8045. # print("test")
  8046. # print(s_sock)
  8047. # sl(600)
  8048. # if s_sock != 0:
  8049. # s_sock.close()
  8050. # s_sock = 0
  8051. # print('s_sock is closed')
  8052. #
  8053. # pool.submit(socket_server_views)
  8054. host = "192.168.50.65"
  8055. port = 8000
  8056. max_length = 65540
  8057. # max_length = 95540
  8058. s_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  8059. s_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  8060. s_sock.bind((host, port))
  8061. frame_info = None
  8062. buffer = None
  8063. frame = None
  8064. encodedImage = None
  8065. print("-> waiting for connection")
  8066. # 影像生成器函數,將影像以jpg格式傳給前端
  8067. def generate():
  8068. while True:
  8069. with lock:
  8070. global s_sock, frame_info, buffer, frame, encodedImage
  8071. if s_sock == 0:
  8072. break
  8073. data, address = s_sock.recvfrom(max_length)
  8074. if len(data) < 100:
  8075. frame_info = pickle.loads(data)
  8076. if frame_info:
  8077. nums_of_packs = frame_info["packs"]
  8078. for i in range(nums_of_packs):
  8079. if s_sock == 0:
  8080. break
  8081. data, address = s_sock.recvfrom(max_length)
  8082. if i == 0:
  8083. buffer = data
  8084. else:
  8085. buffer += data
  8086. frame = np.frombuffer(buffer, dtype=np.uint8)
  8087. frame = frame.reshape(frame.shape[0], 1)
  8088. frame = cv2.imdecode(frame, cv2.IMREAD_UNCHANGED)
  8089. # print(frame)
  8090. # 如果frame為None就跳過
  8091. if frame is None:
  8092. continue
  8093. frame = cv2.resize(
  8094. frame, (640, 360), interpolation=cv2.INTER_AREA)
  8095. # encode the frame in JPEG format
  8096. (flag, encodedImage) = cv2.imencode(".jpg", frame)
  8097. # ensure the frame was successfully encoded
  8098. if not flag:
  8099. continue
  8100. # yield the output frame in the byte format
  8101. yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
  8102. bytearray(encodedImage) + b'\r\n')
  8103. # return the response generated along with the specific media
  8104. # type (mime type)
  8105. return Response(generate(), mimetype="multipart/x-mixed-replace; boundary=frame")
  8106. else:
  8107. if s_sock != 0:
  8108. s_sock.close()
  8109. s_sock = 0
  8110. print('s_sock is closed')
  8111. return "s_sock is closed"
  8112. print("test")
  8113. return "s_sock is closed"
  8114. D = {"input_vacuum_status": "0",
  8115. "tank_vacuum_status": "0",
  8116. "tank_threewayvalve_input_status": "0",
  8117. "tank_threewayvalve_bean_status": "0",
  8118. "tank_solenoid_disinfect_status": "0",
  8119. "tank_pump_disinfect_status": "0",
  8120. "outer_threewayvalve_float_status": "0",
  8121. "tank_motor_status": 'none',
  8122. "tank_pump_water_in_status": "0",
  8123. "tank_pump_cleanwater_in_status": "0",
  8124. "outer_solenoid_water_status": "0",
  8125. "tank_solenoid_reclaimed_in_status": "0",
  8126. "tank_solenoid_water_in_status": "0",
  8127. "tank_solenoid_water_out_status": "0",
  8128. "tank_solenoid_reclaimed_out_status": "0",
  8129. "tank_pump_sensor_status": "0",
  8130. "solenoid_tank_pump_status": "0",
  8131. "tank_nozzle_status": "0",
  8132. "tank_blower_status": "0",
  8133. "tank_heater1_status": "0",
  8134. "tank_heater2_status": "0",
  8135. "temp1_enable": "0",
  8136. "temp1": "0",
  8137. "tank_diskvalve_status": "0",
  8138. "output_vacuum_status": "0",
  8139. "tank_temp_enable_status": "0",
  8140. "tank_temp_status": "0",
  8141. # "tank_pump_waterFloat_status": "0",
  8142. # "tank_pump_waterL2_status": "0",
  8143. # "tank_pump_waterL4_status": "0",
  8144. # "tank_solenoid_waterL3_status": "0",
  8145. # "tank_solenoid_waterL5_status": "0",
  8146. # "tank_stepping_motor_status": 'none',
  8147. }
  8148. # pub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8149. # sub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e/Log'
  8150. # mqttObj = MQTT('aisky-client', 'aiskyc', '60.250.156.234', 1883, 60, sub_topic)
  8151. mqttObj = MQTT()
  8152. @main.route('/mqtt_block', methods=['POST'])
  8153. def mqtt_block():
  8154. import json
  8155. dict = request.form.to_dict() # 將表單轉換成字典
  8156. print('dict:', dict)
  8157. # print('dict.keys():', dict.keys())
  8158. # dict = {
  8159. # "command":"Dry_OTA",
  8160. # "cond": [
  8161. # {
  8162. # "cond_main": "if D1 tank_SHT11_Temp == 30",
  8163. # "cond_add": ["and tank_soil_Humidity == 25","and tank_soil_Humidity == 25",],
  8164. # "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]
  8165. # },
  8166. # {
  8167. # "cond_main": "if D1 tank_SHT11_Temp == 30",
  8168. # "cond_add": ["and tank_soil_Humidity == 25","and tank_soil_Humidity == 25",],
  8169. # "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]
  8170. # }
  8171. # ]
  8172. # }
  8173. # dict = {"command": "Dry_OTA", "cond": "'cond_main':'if D1 tank_soil_Temp == 11', 'cond_add':['and tank_soil_Humidity == 12', 'and tank_soil_EC == 13'], 'cond_com':['tank_heater1_status on', 'tank_heater2_status on']], ['cond_main':'if D2 tank_solenoid_disinfect_status == 21', 'cond_add':['and tank_solenoid_water_out_status == 22', 'and outer_solenoid_water_status == 23'], 'cond_com':['tank_heater1_status on', 'tank_heater2_status on']"}
  8174. json = json.dumps(dict)
  8175. # json: {"command": "Dry_OTA", "cond": [{"cond_main": "if D1 tank_SHT11_Temp == 30", "cond_add": ["and tank_soil_Humidity == 25", "and tank_soil_Humidity == 25"], "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]}, {"cond_main": "if D1 tank_SHT11_Temp == 30", "cond_add": ["and tank_soil_Humidity == 25", "and tank_soil_Humidity == 25"], "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]}]}
  8176. print('json:', json)
  8177. # dict: {'command': 'Dry_OTA', 'cond': [{'cond_main': 'if D1 tank_SHT11_Temp == 30', 'cond_add': ['and tank_soil_Humidity == 25', 'and tank_soil_Humidity == 25'], 'cond_com': ['tank_motor_status 10', 'tank_motor_status 10']}, {'cond_main': 'if D1 tank_SHT11_Temp == 30', 'cond_add': ['and tank_soil_Humidity == 25', 'and tank_soil_Humidity == 25'], 'cond_com': ['tank_motor_status 10', 'tank_motor_status 10']}]}
  8178. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8179. mqtt.publish(topic, json)
  8180. return 'OK'
  8181. # mqtt發布
  8182. # @main.route('/mqtt/<tid>', methods=['POST'])
  8183. @main.route('/mqtt/<tid>', methods=['POST'])
  8184. def mqtt_views(tid):
  8185. import json
  8186. dict = request.form.to_dict() # 將表單轉換成字典
  8187. json = json.dumps(dict)
  8188. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  8189. # print('json:', json) # json: {"tank-number": "1", "command": "tank_vacuum_status", "value": "on"}
  8190. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8191. # res = mqttObj.mqttPublish(pub_topic, json)
  8192. # print(res)
  8193. # sl(2)
  8194. # print(mqttObj.res)
  8195. #
  8196. # print('test')
  8197. mqtt.publish(topic, json)
  8198. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8199. if dict['command'] == 'input_vacuum_status':
  8200. time.sleep(1)
  8201. # D[input_vacuum_status]: "0"
  8202. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  8203. if D['input_vacuum_status'] == 'on':
  8204. return 'on'
  8205. elif D['input_vacuum_status'] == 'off':
  8206. return 'off'
  8207. else:
  8208. return "input_vacuum_status signal was not received"
  8209. # 真空吸料機
  8210. elif dict['command'] == 'tank_vacuum_status':
  8211. time.sleep(1)
  8212. if D['tank_vacuum_status'] == 'on':
  8213. return 'on'
  8214. elif D['tank_vacuum_status'] == 'off':
  8215. return 'off'
  8216. else:
  8217. return "tank_vacuum_status signal was not received"
  8218. # 入料三通閥(ON吸料/OFF排氣)
  8219. elif dict['command'] == 'tank_threewayvalve_input_status':
  8220. time.sleep(1)
  8221. if D['tank_threewayvalve_input_status'] == 'on':
  8222. return 'on'
  8223. elif D['tank_threewayvalve_input_status'] == 'off':
  8224. return 'off'
  8225. else:
  8226. return "tank_threewayvalve_input_status signal was not received"
  8227. # 測豆三通閥(ON吸料/OFF排氣)
  8228. elif dict['command'] == 'tank_threewayvalve_bean_status':
  8229. time.sleep(1)
  8230. if D['tank_threewayvalve_bean_status'] == 'on':
  8231. return 'on'
  8232. elif D['tank_threewayvalve_bean_status'] == 'off':
  8233. return 'off'
  8234. else:
  8235. return "tank_threewayvalve_bean_status signal was not received"
  8236. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8237. elif dict['command'] == 'tank_solenoid_disinfect_status':
  8238. time.sleep(1)
  8239. if D['tank_solenoid_disinfect_status'] == 'on':
  8240. return 'on'
  8241. elif D['tank_solenoid_disinfect_status'] == 'off':
  8242. return 'off'
  8243. else:
  8244. return "tank_solenoid_disinfect_status signal was not received"
  8245. # 混合槽幫浦(ON抽水消毒/OFF關)
  8246. elif dict['command'] == 'tank_pump_disinfect_status':
  8247. time.sleep(1)
  8248. if D['tank_pump_disinfect_status'] == 'on':
  8249. return 'on'
  8250. elif D['tank_pump_disinfect_status'] == 'off':
  8251. return 'off'
  8252. else:
  8253. return "tank_pump_disinfect_status signal was not received"
  8254. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  8255. elif dict['command'] == 'outer_threewayvalve_float_status':
  8256. time.sleep(1)
  8257. if D['outer_threewayvalve_float_status'] == 'on':
  8258. return 'on'
  8259. elif D['outer_threewayvalve_float_status'] == 'off':
  8260. return 'off'
  8261. else:
  8262. return "outer_threewayvalve_float_status signal was not received"
  8263. # 馬達(單位RPM)
  8264. elif dict['command'] == 'tank_motor_status':
  8265. print("D['tank_motor_status']", D['tank_motor_status'])
  8266. time.sleep(1)
  8267. if D['tank_motor_status'] == '0':
  8268. return 'off'
  8269. elif type(D['tank_motor_status']) == int:
  8270. return 'on'
  8271. else:
  8272. return "tank_motor_status signal was not received"
  8273. # 幫浦(清水入水)(ON開/OFF關)
  8274. elif dict['command'] == 'tank_pump_water_in_status':
  8275. time.sleep(1)
  8276. if D['tank_pump_water_in_status'] == 'on':
  8277. return 'on'
  8278. elif D['tank_pump_water_in_status'] == 'off':
  8279. return 'off'
  8280. else:
  8281. return "tank_pump_water_in_status signal was not received"
  8282. # 幫浦(清洗槽入水)(ON開/OFF關)
  8283. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  8284. time.sleep(1)
  8285. if D['tank_pump_cleanwater_in_status'] == 'on':
  8286. return 'on'
  8287. elif D['tank_pump_cleanwater_in_status'] == 'off':
  8288. return 'off'
  8289. else:
  8290. return "tank_pump_cleanwater_in_status signal was not received"
  8291. # 桶外進水電磁閥(ON開/OFF關)
  8292. elif dict['command'] == 'outer_solenoid_water_status':
  8293. time.sleep(1)
  8294. if D['outer_solenoid_water_status'] == 'on':
  8295. return 'on'
  8296. elif D['outer_solenoid_water_status'] == 'off':
  8297. return 'off'
  8298. else:
  8299. return "outer_solenoid_water_status signal was not received"
  8300. # 中水入水電磁閥(ON開/OFF關)
  8301. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  8302. time.sleep(1)
  8303. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  8304. return 'on'
  8305. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  8306. return 'off'
  8307. else:
  8308. return "tank_solenoid_reclaimed_in_status signal was not received"
  8309. # 清水入水電磁閥(ON開/OFF關)
  8310. elif dict['command'] == 'tank_solenoid_water_in_status':
  8311. time.sleep(1)
  8312. if D['tank_solenoid_water_in_status'] == 'on':
  8313. return 'on'
  8314. elif D['tank_solenoid_water_in_status'] == 'off':
  8315. return 'off'
  8316. else:
  8317. return "tank_solenoid_water_in_status signal was not received"
  8318. # 排水廢水電磁閥(ON開/OFF關)
  8319. elif dict['command'] == 'tank_solenoid_water_out_status':
  8320. time.sleep(1)
  8321. if D['tank_solenoid_water_out_status'] == 'on':
  8322. return 'on'
  8323. elif D['tank_solenoid_water_out_status'] == 'off':
  8324. return 'off'
  8325. else:
  8326. return "tank_solenoid_water_out_status signal was not received"
  8327. # 排水中水電磁閥(ON開/OFF關)
  8328. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  8329. time.sleep(1)
  8330. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  8331. return 'on'
  8332. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  8333. return 'off'
  8334. else:
  8335. return "tank_solenoid_reclaimed_out_status signal was not received"
  8336. # 雙核隔膜泵(ON開/OFF關)
  8337. elif dict['command'] == 'tank_pump_sensor_status':
  8338. time.sleep(1)
  8339. if D['tank_pump_sensor_status'] == 'on':
  8340. return 'on'
  8341. elif D['tank_pump_sensor_status'] == 'off':
  8342. return 'off'
  8343. else:
  8344. return "tank_pump_sensor_status signal was not received"
  8345. # 逆洗 pump 電磁閥(ON開/OFF關)
  8346. elif dict['command'] == 'solenoid_tank_pump_status':
  8347. time.sleep(1)
  8348. if D['solenoid_tank_pump_status'] == 'on':
  8349. return 'on'
  8350. elif D['solenoid_tank_pump_status'] == 'off':
  8351. return 'off'
  8352. else:
  8353. return "solenoid_tank_pump_status signal was not received"
  8354. # 噴嘴(ON開/OFF關)
  8355. elif dict['command'] == 'tank_nozzle_status':
  8356. time.sleep(1)
  8357. if D['tank_nozzle_status'] == 'on':
  8358. return 'on'
  8359. elif D['tank_nozzle_status'] == 'off':
  8360. return 'off'
  8361. else:
  8362. return "tank_nozzle_status signal was not received"
  8363. # 鼓風機(ON開/OFF關)
  8364. elif dict['command'] == 'tank_blower_status':
  8365. time.sleep(1)
  8366. if D['tank_blower_status'] == 'on':
  8367. return 'on'
  8368. elif D['tank_blower_status'] == 'off':
  8369. return 'off'
  8370. else:
  8371. return "tank_blower_status signal was not received"
  8372. # 加熱棒 1(ON開/OFF關)
  8373. elif dict['command'] == 'tank_heater1_status':
  8374. time.sleep(1)
  8375. if D['tank_heater1_status'] == 'on':
  8376. return 'on'
  8377. elif D['tank_heater1_status'] == 'off':
  8378. return 'off'
  8379. else:
  8380. return "tank_heater1_status signal was not received"
  8381. # 加熱棒 2(ON開/OFF關)
  8382. elif dict['command'] == 'tank_heater2_status':
  8383. time.sleep(1)
  8384. if D['tank_heater2_status'] == 'on':
  8385. return 'on'
  8386. elif D['tank_heater2_status'] == 'off':
  8387. return 'off'
  8388. else:
  8389. return "tank_heater2_status signal was not received"
  8390. # 溫度控制(ON開/OFF關)
  8391. elif dict['command'] == 'temp1_enable':
  8392. time.sleep(1)
  8393. if D['temp1_enable'] == 'on':
  8394. return 'on'
  8395. elif D['temp1_enable'] == 'off':
  8396. return 'off'
  8397. else:
  8398. return "temp1_enable_status signal was not received"
  8399. # 設定溫度
  8400. elif dict['command'] == 'temp1':
  8401. time.sleep(1)
  8402. if D['temp1'] == '0':
  8403. return 'off'
  8404. elif type(D['temp1']) == float:
  8405. return 'on'
  8406. else:
  8407. return "temp1 signal was not received"
  8408. # 發酵槽 溫控開關
  8409. elif dict['command'] == 'tank_temp_enable':
  8410. time.sleep(1)
  8411. if D['tank_temp_enable'] == 'on':
  8412. return 'on'
  8413. elif D['tank_temp_enable'] == 'off':
  8414. return 'off'
  8415. else:
  8416. return "tank_temp_enable signal was not received"
  8417. # 發酵槽 設定溫度
  8418. elif dict['command'] == 'tank_temp':
  8419. time.sleep(1)
  8420. if D['tank_temp'] == '0':
  8421. return 'off'
  8422. elif type(D['tank_temp']) == float:
  8423. return 'on'
  8424. else:
  8425. return "tank_temp signal was not received"
  8426. # 蝴蝶閥(ON開/OFF關)
  8427. elif dict['command'] == 'tank_diskvalve_status':
  8428. time.sleep(1)
  8429. if D['tank_diskvalve_status'] == 'on':
  8430. return 'on'
  8431. elif D['tank_diskvalve_status'] == 'off':
  8432. return 'off'
  8433. else:
  8434. return "tank_diskvalve_status signal was not received"
  8435. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8436. elif dict['command'] == 'output_vacuum_status':
  8437. time.sleep(1)
  8438. if D['output_vacuum_status'] == 'on':
  8439. return 'on'
  8440. elif D['output_vacuum_status'] == 'off':
  8441. return 'off'
  8442. else:
  8443. return "output_vacuum_status signal was not received"
  8444. else:
  8445. return "MQTT command NOT FOUND"
  8446. # return "publish done" # 1201 test
  8447. # --- 12/10 ------------------------------------------ start
  8448. @main.route('/mqtt_data/<tid>_<command>_<value>', methods=['POST'])
  8449. def mqtt_data(tank_num, command, value):
  8450. import json
  8451. data = { "tank_num": str(tank_num), "command": str(command), "value": str(value) }
  8452. json = json.dumps(data)
  8453. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  8454. print('json:', json)
  8455. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8456. mqtt.publish(topic, json)
  8457. # --- 12/10 ------------------------------------------ finish
  8458. # --- 10/19 ------------------------------------------ start
  8459. # mqtt發布
  8460. # @main.route('/mqtt/<tid>', methods=['POST'])
  8461. @main.route('/mqtt_f/<tid>', methods=['POST'])
  8462. def mqtt_f(data):
  8463. import json
  8464. dict = request.form.to_dict()
  8465. json = json.dumps(data)
  8466. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  8467. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  8468. print('json:', json)
  8469. topic = 'AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e'
  8470. # res = mqttObj.mqttPublish(pub_topic, json)
  8471. # print(res)
  8472. # sl(2)
  8473. # print(mqttObj.res)
  8474. #
  8475. # print('test')
  8476. mqtt.publish(topic, json)
  8477. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8478. if dict['command'] == 'input_vacuum_status':
  8479. time.sleep(1)
  8480. # D[input_vacuum_status]: "0"
  8481. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  8482. if D['input_vacuum_status'] == 'on':
  8483. return 'on'
  8484. elif D['input_vacuum_status'] == 'off':
  8485. return 'off'
  8486. else:
  8487. return "input_vacuum_status signal was not received"
  8488. # 真空吸料機
  8489. elif dict['command'] == 'tank_vacuum_status':
  8490. time.sleep(1)
  8491. if D['tank_vacuum_status'] == 'on':
  8492. return 'on'
  8493. elif D['tank_vacuum_status'] == 'off':
  8494. return 'off'
  8495. else:
  8496. return "tank_vacuum_status signal was not received"
  8497. # 入料三通閥(ON吸料/OFF排氣)
  8498. elif dict['command'] == 'tank_threewayvalve_input_status':
  8499. time.sleep(1)
  8500. if D['tank_threewayvalve_input_status'] == 'on':
  8501. return 'on'
  8502. elif D['tank_threewayvalve_input_status'] == 'off':
  8503. return 'off'
  8504. else:
  8505. return "tank_threewayvalve_input_status signal was not received"
  8506. # 測豆三通閥(ON吸料/OFF排氣)
  8507. elif dict['command'] == 'tank_threewayvalve_bean_status':
  8508. time.sleep(1)
  8509. if D['tank_threewayvalve_bean_status'] == 'on':
  8510. return 'on'
  8511. elif D['tank_threewayvalve_bean_status'] == 'off':
  8512. return 'off'
  8513. else:
  8514. return "tank_threewayvalve_bean_status signal was not received"
  8515. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8516. elif dict['command'] == 'tank_solenoid_disinfect_status':
  8517. time.sleep(1)
  8518. if D['tank_solenoid_disinfect_status'] == 'on':
  8519. return 'on'
  8520. elif D['tank_solenoid_disinfect_status'] == 'off':
  8521. return 'off'
  8522. else:
  8523. return "tank_solenoid_disinfect_status signal was not received"
  8524. # 混合槽幫浦(ON抽水消毒/OFF關)
  8525. elif dict['command'] == 'tank_pump_disinfect_status':
  8526. time.sleep(1)
  8527. if D['tank_pump_disinfect_status'] == 'on':
  8528. return 'on'
  8529. elif D['tank_pump_disinfect_status'] == 'off':
  8530. return 'off'
  8531. else:
  8532. return "tank_pump_disinfect_status signal was not received"
  8533. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  8534. elif dict['command'] == 'outer_threewayvalve_float_status':
  8535. time.sleep(1)
  8536. if D['outer_threewayvalve_float_status'] == 'on':
  8537. return 'on'
  8538. elif D['outer_threewayvalve_float_status'] == 'off':
  8539. return 'off'
  8540. else:
  8541. return "outer_threewayvalve_float_status signal was not received"
  8542. # 馬達(單位RPM)
  8543. elif dict['command'] == 'tank_motor_status':
  8544. print("D['tank_motor_status']", D['tank_motor_status'])
  8545. time.sleep(1)
  8546. if D['tank_motor_status'] == '0':
  8547. return 'off'
  8548. elif type(D['tank_motor_status']) == int:
  8549. return 'on'
  8550. else:
  8551. return "tank_motor_status signal was not received"
  8552. # 幫浦(清水入水)(ON開/OFF關)
  8553. elif dict['command'] == 'tank_pump_water_in_status':
  8554. time.sleep(1)
  8555. if D['tank_pump_water_in_status'] == 'on':
  8556. return 'on'
  8557. elif D['tank_pump_water_in_status'] == 'off':
  8558. return 'off'
  8559. else:
  8560. return "tank_pump_water_in_status signal was not received"
  8561. # 幫浦(清洗槽入水)(ON開/OFF關)
  8562. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  8563. time.sleep(1)
  8564. if D['tank_pump_cleanwater_in_status'] == 'on':
  8565. return 'on'
  8566. elif D['tank_pump_cleanwater_in_status'] == 'off':
  8567. return 'off'
  8568. else:
  8569. return "tank_pump_cleanwater_in_status signal was not received"
  8570. # 桶外進水電磁閥(ON開/OFF關)
  8571. elif dict['command'] == 'outer_solenoid_water_status':
  8572. time.sleep(1)
  8573. if D['outer_solenoid_water_status'] == 'on':
  8574. return 'on'
  8575. elif D['outer_solenoid_water_status'] == 'off':
  8576. return 'off'
  8577. else:
  8578. return "outer_solenoid_water_status signal was not received"
  8579. # 中水入水電磁閥(ON開/OFF關)
  8580. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  8581. time.sleep(1)
  8582. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  8583. return 'on'
  8584. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  8585. return 'off'
  8586. else:
  8587. return "tank_solenoid_reclaimed_in_status signal was not received"
  8588. # 清水入水電磁閥(ON開/OFF關)
  8589. elif dict['command'] == 'tank_solenoid_water_in_status':
  8590. time.sleep(1)
  8591. if D['tank_solenoid_water_in_status'] == 'on':
  8592. return 'on'
  8593. elif D['tank_solenoid_water_in_status'] == 'off':
  8594. return 'off'
  8595. else:
  8596. return "tank_solenoid_water_in_status signal was not received"
  8597. # 排水廢水電磁閥(ON開/OFF關)
  8598. elif dict['command'] == 'tank_solenoid_water_out_status':
  8599. time.sleep(1)
  8600. if D['tank_solenoid_water_out_status'] == 'on':
  8601. return 'on'
  8602. elif D['tank_solenoid_water_out_status'] == 'off':
  8603. return 'off'
  8604. else:
  8605. return "tank_solenoid_water_out_status signal was not received"
  8606. # 排水中水電磁閥(ON開/OFF關)
  8607. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  8608. time.sleep(1)
  8609. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  8610. return 'on'
  8611. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  8612. return 'off'
  8613. else:
  8614. return "tank_solenoid_reclaimed_out_status signal was not received"
  8615. # 雙核隔膜泵(ON開/OFF關)
  8616. elif dict['command'] == 'tank_pump_sensor_status':
  8617. time.sleep(1)
  8618. if D['tank_pump_sensor_status'] == 'on':
  8619. return 'on'
  8620. elif D['tank_pump_sensor_status'] == 'off':
  8621. return 'off'
  8622. else:
  8623. return "tank_pump_sensor_status signal was not received"
  8624. # 逆洗 pump 電磁閥(ON開/OFF關)
  8625. elif dict['command'] == 'solenoid_tank_pump_status':
  8626. time.sleep(1)
  8627. if D['solenoid_tank_pump_status'] == 'on':
  8628. return 'on'
  8629. elif D['solenoid_tank_pump_status'] == 'off':
  8630. return 'off'
  8631. else:
  8632. return "solenoid_tank_pump_status signal was not received"
  8633. # 噴嘴(ON開/OFF關)
  8634. elif dict['command'] == 'tank_nozzle_status':
  8635. time.sleep(1)
  8636. if D['tank_nozzle_status'] == 'on':
  8637. return 'on'
  8638. elif D['tank_nozzle_status'] == 'off':
  8639. return 'off'
  8640. else:
  8641. return "tank_nozzle_status signal was not received"
  8642. # 鼓風機(ON開/OFF關)
  8643. elif dict['command'] == 'tank_blower_status':
  8644. time.sleep(1)
  8645. if D['tank_blower_status'] == 'on':
  8646. return 'on'
  8647. elif D['tank_blower_status'] == 'off':
  8648. return 'off'
  8649. else:
  8650. return "tank_blower_status signal was not received"
  8651. # 加熱棒 1(ON開/OFF關)
  8652. elif dict['command'] == 'tank_heater1_status':
  8653. time.sleep(1)
  8654. if D['tank_heater1_status'] == 'on':
  8655. return 'on'
  8656. elif D['tank_heater1_status'] == 'off':
  8657. return 'off'
  8658. else:
  8659. return "tank_heater1_status signal was not received"
  8660. # 加熱棒 2(ON開/OFF關)
  8661. elif dict['command'] == 'tank_heater2_status':
  8662. time.sleep(1)
  8663. if D['tank_heater2_status'] == 'on':
  8664. return 'on'
  8665. elif D['tank_heater2_status'] == 'off':
  8666. return 'off'
  8667. else:
  8668. return "tank_heater2_status signal was not received"
  8669. # 溫度控制(ON開/OFF關)
  8670. elif dict['command'] == 'temp1_enable':
  8671. time.sleep(1)
  8672. if D['temp1_enable'] == 'on':
  8673. return 'on'
  8674. elif D['temp1_enable'] == 'off':
  8675. return 'off'
  8676. else:
  8677. return "temp1_enable_status signal was not received"
  8678. # 設定溫度
  8679. elif dict['command'] == 'temp1':
  8680. time.sleep(1)
  8681. if D['temp1'] == '0':
  8682. return 'off'
  8683. elif type(D['temp1']) == float:
  8684. return 'on'
  8685. else:
  8686. return "temp1 signal was not received"
  8687. # 發酵槽 溫控開關
  8688. elif dict['command'] == 'tank_temp_enable':
  8689. time.sleep(1)
  8690. if D['tank_temp_enable'] == 'on':
  8691. return 'on'
  8692. elif D['tank_temp_enable'] == 'off':
  8693. return 'off'
  8694. else:
  8695. return "tank_temp_enable signal was not received"
  8696. # 發酵槽 設定溫度
  8697. elif dict['command'] == 'tank_temp':
  8698. time.sleep(1)
  8699. if D['tank_temp'] == '0':
  8700. return 'off'
  8701. elif type(D['tank_temp']) == float:
  8702. return 'on'
  8703. else:
  8704. return "tank_temp signal was not received"
  8705. # 蝴蝶閥(ON開/OFF關)
  8706. elif dict['command'] == 'tank_diskvalve_status':
  8707. time.sleep(1)
  8708. if D['tank_diskvalve_status'] == 'on':
  8709. return 'on'
  8710. elif D['tank_diskvalve_status'] == 'off':
  8711. return 'off'
  8712. else:
  8713. return "tank_diskvalve_status signal was not received"
  8714. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8715. elif dict['command'] == 'output_vacuum_status':
  8716. time.sleep(1)
  8717. if D['output_vacuum_status'] == 'on':
  8718. return 'on'
  8719. elif D['output_vacuum_status'] == 'off':
  8720. return 'off'
  8721. else:
  8722. return "output_vacuum_status signal was not received"
  8723. else:
  8724. return "MQTT command NOT FOUND"
  8725. # ---10/19 ------------------------------------------- end
  8726. # 處理mqtt訂閱的信息
  8727. # 收到訊息後我們可以用 on_message(),來讀取收到的內容:
  8728. @mqtt.on_message()
  8729. def handle_mqtt_message(client, userdata, message):
  8730. # topic = message.topic # 收到的主題 Rita 原本就沒有此行, 增加說明用
  8731. payload = message.payload.decode() # 收到的內容
  8732. payload = json.loads(payload)
  8733. # print("-------msg-------")
  8734. # print('name :', p['name'])
  8735. # print('email :', p['email'])
  8736. print('payload:', payload)
  8737. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8738. if payload['command'] == 'input_vacuum_status':
  8739. if payload['response'] == 'on':
  8740. D['input_vacuum_status'] = 'on'
  8741. else:
  8742. D['input_vacuum_status'] = 'off'
  8743. # 真空吸料機(ON吸料/OFF排氣)
  8744. elif payload['command'] == 'tank_vacuum_status':
  8745. if payload['response'] == 'on':
  8746. D['tank_vacuum_status'] = 'on'
  8747. else:
  8748. D['tank_vacuum_status'] = 'off'
  8749. # 入料三通閥(ON吸料/OFF排氣)
  8750. elif payload['command'] == 'tank_threewayvalve_input_status':
  8751. if payload['response'] == 'on':
  8752. D['tank_threewayvalve_input_status'] = 'on'
  8753. else:
  8754. D['tank_threewayvalve_input_status'] = 'off'
  8755. # 測豆三通閥(ON測豆/OFF排氣)
  8756. elif payload['command'] == 'tank_threewayvalve_bean_status':
  8757. if payload['response'] == 'on':
  8758. D['tank_threewayvalve_bean_status'] = 'on'
  8759. else:
  8760. D['tank_threewayvalve_bean_status'] = 'off'
  8761. # 消毒電磁閥(ON噴灑消毒/OFF關)
  8762. elif payload['command'] == 'tank_solenoid_disinfect_status':
  8763. if payload['response'] == 'on':
  8764. D['tank_solenoid_disinfect_status'] = 'on'
  8765. else:
  8766. D['tank_solenoid_disinfect_status'] = 'off'
  8767. # 混合槽幫浦(ON消毒槽抽水/OFF關)
  8768. elif payload['command'] == 'tank_pump_disinfect_status':
  8769. if payload['response'] == 'on':
  8770. D['tank_pump_disinfect_status'] = 'on'
  8771. else:
  8772. D['tank_pump_disinfect_status'] = 'off'
  8773. # 外桶浮選三通閥(ON浮選落豆/OFF桶內真空)
  8774. elif payload['command'] == 'outer_threewayvalve_float_status':
  8775. if payload['response'] == 'on':
  8776. D['outer_threewayvalve_float_status'] = 'on'
  8777. else:
  8778. D['outer_threewayvalve_float_status'] = 'off'
  8779. # 馬達(單位RPM)
  8780. elif payload['command'] == 'tank_motor_status':
  8781. if payload['response'] == 'off' or payload['response'] == '0':
  8782. D['tank_motor_status'] = '0'
  8783. else:
  8784. D['tank_motor_status'] = payload['response']
  8785. # 幫浦(清水入水)(ON開/OFF關)
  8786. elif payload['command'] == 'tank_pump_water_in_status':
  8787. if payload['response'] == 'on':
  8788. D['tank_pump_water_in_status'] = 'on'
  8789. else:
  8790. D['tank_pump_water_in_status'] = 'off'
  8791. # 幫浦(清洗槽入水)(ON開/OFF關)
  8792. elif payload['command'] == 'tank_pump_cleanwater_in_status':
  8793. if payload['response'] == 'on':
  8794. D['tank_pump_cleanwater_in_status'] = 'on'
  8795. else:
  8796. D['tank_pump_cleanwater_in_status'] = 'off'
  8797. # 桶外進水電磁閥(ON開/OFF關)
  8798. elif payload['command'] == 'outer_solenoid_water_status':
  8799. if payload['response'] == 'on':
  8800. D['outer_solenoid_water_status'] = 'on'
  8801. else:
  8802. D['outer_solenoid_water_status'] = 'off'
  8803. # 中水入水電磁閥(ON開/OFF關)
  8804. elif payload['command'] == 'tank_solenoid_reclaimed_in_status':
  8805. if payload['response'] == 'on':
  8806. D['tank_solenoid_reclaimed_in_status'] = 'on'
  8807. else:
  8808. D['tank_solenoid_reclaimed_in_status'] = 'off'
  8809. # 清水入水電磁閥(ON開/OFF關)
  8810. elif payload['command'] == 'tank_solenoid_water_in_status':
  8811. if payload['response'] == 'on':
  8812. D['tank_solenoid_water_in_status'] = 'on'
  8813. else:
  8814. D['tank_solenoid_water_in_status'] = 'off'
  8815. # 排水廢水電磁閥(ON開/OFF關)
  8816. elif payload['command'] == 'tank_solenoid_water_out_status':
  8817. if payload['response'] == 'on':
  8818. D['tank_solenoid_water_out_status'] = 'on'
  8819. else:
  8820. D['tank_solenoid_water_out_status'] = 'off'
  8821. # 排水中水電磁閥(ON開/OFF關)
  8822. elif payload['command'] == 'tank_solenoid_reclaimed_out_status':
  8823. if payload['response'] == 'on':
  8824. D['tank_solenoid_reclaimed_out_status'] = 'on'
  8825. else:
  8826. D['tank_solenoid_reclaimed_out_status'] = 'off'
  8827. # 雙核隔膜泵(ON開/OFF關)
  8828. elif payload['command'] == 'tank_pump_sensor_status':
  8829. if payload['response'] == 'on':
  8830. D['tank_pump_sensor_status'] = 'on'
  8831. else:
  8832. D['tank_pump_sensor_status'] = 'off'
  8833. # 逆洗 pump 電磁閥(ON開/OFF關)
  8834. elif payload['command'] == 'solenoid_tank_pump_status':
  8835. if payload['response'] == 'on':
  8836. D['solenoid_tank_pump_status'] = 'on'
  8837. else:
  8838. D['solenoid_tank_pump_status'] = 'off'
  8839. # 噴嘴(ON開/OFF關)
  8840. elif payload['command'] == 'tank_nozzle_status':
  8841. if payload['response'] == 'on':
  8842. D['tank_nozzle_status'] = 'on'
  8843. else:
  8844. D['tank_nozzle_status'] = 'off'
  8845. # 鼓風機(ON開/OFF關)
  8846. elif payload['command'] == 'tank_blower_status':
  8847. if payload['response'] == 'on':
  8848. D['tank_blower_status'] = 'on'
  8849. else:
  8850. D['tank_blower_status'] = 'off'
  8851. # 加熱棒 1(ON開/OFF關)
  8852. elif payload['command'] == 'tank_heater1_status':
  8853. if payload['response'] == 'on':
  8854. D['tank_heater1_status'] = 'on'
  8855. else:
  8856. D['tank_heater1_status'] = 'off'
  8857. # 加熱棒 2(ON開/OFF關)
  8858. elif payload['command'] == 'tank_heater2_status':
  8859. if payload['response'] == 'on':
  8860. D['tank_heater2_status'] = 'on'
  8861. else:
  8862. D['tank_heater2_status'] = 'off'
  8863. # 發酵槽 溫控開關
  8864. elif payload['command'] == 'tank_temp_enable':
  8865. if payload['response'] == 'on':
  8866. D['tank_temp_enable'] = 'on'
  8867. else:
  8868. D['tank_temp_enable'] = 'off'
  8869. # 發酵槽 設定溫度
  8870. elif payload['command'] == 'tank_temp':
  8871. if payload['response'] == 'off':
  8872. D['tank_temp'] = '0'
  8873. else:
  8874. D['tank_temp'] = payload['response']
  8875. # 蝴蝶閥(ON開/OFF關)
  8876. elif payload['command'] == 'tank_diskvalve_status':
  8877. if payload['response'] == 'on':
  8878. D['tank_diskvalve_status'] = 'on'
  8879. else:
  8880. D['tank_diskvalve_status'] = 'off'
  8881. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  8882. elif payload['command'] == 'output_vacuum_status':
  8883. if payload['response'] == 'on':
  8884. D['output_vacuum_status'] = 'on'
  8885. else:
  8886. D['output_vacuum_status'] = 'off'
  8887. else:
  8888. return "MQTT command NOT FOUND"