coffeeproject.py 552 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801
  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. import subprocess
  39. import shutil
  40. import stat
  41. pool = ThreadPoolExecutor(25)
  42. s_sock = 0
  43. lock = threading.Lock()
  44. '''
  45. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  46. password='skyeye', database='Coffee', charset='utf8')
  47. mycursor = mydb.cursor()
  48. '''
  49. # 主頁的訪問路徑
  50. @main.route('/')
  51. def main_index():
  52. # 獲取登入信息
  53. if 'id' in session and 'uname' in session and 'status' in session:
  54. username = session['uname']
  55. status = session['status']
  56. if status == 9:
  57. return render_template('signin_disable.html')
  58. elif status == 8:
  59. return render_template('signin_new.html')
  60. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  61. return render_template('index.html', params=locals())
  62. else:
  63. return render_template('sign_in.html')
  64. # Rita 測試
  65. # sql_get
  66. @main.route('/sql_get', methods=['GET', 'POST'])
  67. def sql_get():
  68. # 取得網頁傳回來的 SQL 指令
  69. # sql = "SELECT * FROM 零件表 WHERE 會計科目 = 04"
  70. info = request.args.to_dict('sql')
  71. datetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  72. sql = info['sql'].replace('current_timestamp()', '"' + datetime + '"')
  73. # ip = request.remote_addr
  74. # sql = info['sql'].replace('IPDATA', '"' + ip + '"')
  75. print("[sql_get]sql: ", sql)
  76. # 存入本機
  77. mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  78. mycursor = mydb.cursor()
  79. try:
  80. mycursor.execute(sql)
  81. sql_data = mycursor.fetchall()
  82. except pymysql.err.IntegrityError:
  83. sql_data = "localhost Mysql 存值錯誤"
  84. mydb.commit()
  85. mydb.close()
  86. # 存入 HOME
  87. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffeemanage', password='skyeye', database='CoffeeManage', charset='utf8')
  88. mycursor = mydb.cursor()
  89. try:
  90. mycursor.execute(sql)
  91. sql_data = mycursor.fetchall()
  92. except pymysql.err.IntegrityError:
  93. sql_data = "Home Mysql 存值錯誤"
  94. mydb.commit()
  95. mydb.close()
  96. return jsonify({"response":sql_data})
  97. # @main.route('/sql_get_HOME', methods=['GET', 'POST'])
  98. # def sql_get_HOME():
  99. # mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee', password='skyeye', database='Coffee', charset='utf8')
  100. # # mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='Coffee', charset='utf8')
  101. # mycursor = mydb.cursor()
  102. # # 取得網頁傳回來的 SQL 指令
  103. # # sql = "SELECT * FROM 零件表 WHERE 會計科目 = 04"
  104. # info = request.args.to_dict('sql')
  105. # sql = info['sql']
  106. # print("[sql_get]sql: ", sql)
  107. # try:
  108. # mycursor.execute(sql)
  109. # sql_data = mycursor.fetchall()
  110. # except pymysql.err.IntegrityError:
  111. # sql_data = "請注意 ! 單據不可新增重複的零件"
  112. # mydb.commit()
  113. # mydb.close()
  114. # return jsonify({"response":"OK"})
  115. # Rita 測試
  116. # 使用者名稱測試
  117. @main.route('/test', methods=['GET', 'POST'])
  118. def test():
  119. info = request.args.to_dict()
  120. print(info)
  121. print("info[command]: ", info['command'])
  122. return json.dumps(info)
  123. # Rita 測試
  124. # 板子燒錄請求
  125. @main.route('/board_programmer')
  126. def board_programmer():
  127. prog_data = request.args.to_dict() # {'tank': 'D1'}
  128. CURRENT_PATH = os.path.dirname(__file__) # c:\Users\USER\Rita\Coffee\CoffeeProject\app\main
  129. # # 取得 hex 檔案內容
  130. file = os.path.join(CURRENT_PATH, 'CTO20220622', 'build', 'SDIO.hex') # c:\Users\USER\Rita\Coffee\CoffeeProject\app\main\CTO20220622\SDIO.hex
  131. f = open(file, 'r')
  132. ota_hex = f.read()
  133. # # MQTT 傳送燒錄
  134. MQTT_dict = {
  135. 'command':'Code_upload',
  136. 'tank_num':prog_data['tank'],
  137. 'url':ota_hex
  138. }
  139. import json
  140. json = json.dumps(MQTT_dict)
  141. # print("MQTT_dict: ", MQTT_dict) # MQTT_dict: {'command': 'Code_upload', 'tank_num': 'F1', 'url': ':020000040801F1\n:1000
  142. # print("json: ", json) # json: {"command": "Code_upload", "tank_num": "F1", "url": ":020000040801F1\n:1000
  143. # topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  144. topic = 'AISKY/Coffee/MK-G/' + str(prog_data['burner_mac'])
  145. mqtt.publish(topic, json)
  146. time.sleep(3)
  147. if board_prog[prog_data['tank']] == 'no reply':
  148. board_prog[prog_data['tank']] = '0'
  149. return 'no reply'
  150. print("===== 下載 Git CoffeeProject_SourceCode ==========================================================")
  151. # # 先下載 Git CoffeeProject_SourceCode
  152. os.system('git clone --single-branch http://60.250.156.230:3000/rita/CoffeeProject_SourceCode.git ' + CURRENT_PATH + '/source_code')
  153. time.sleep(3)
  154. print("===== 將 hex 先複製更名 ==========================================================")
  155. # # 將 hex 先複製更名
  156. copy_old_path = os.path.join(CURRENT_PATH, "CTO20220622", "build", "SDIO.hex")
  157. currentTime = dt.now().strftime("%Y%m%d_%H%M%S")
  158. fileTitle_hex = "[" + currentTime + "_" + prog_data['USERNAME'] + "] " + prog_data['tank'] + "_SDIO.hex"
  159. copy_new_path = os.path.join(CURRENT_PATH, "CTO20220622", "build", fileTitle_hex)
  160. print("copy_new_path: ", copy_new_path)
  161. shutil.copyfile(copy_old_path, copy_new_path)
  162. time.sleep(3)
  163. print("===== 再將 hex 移動到 source_code 資料夾中 ==========================================================")
  164. # # 再將 hex 移動到 source_code 資料夾中
  165. move_new_path = os.path.join(CURRENT_PATH, "source_code", fileTitle_hex)
  166. print("copy_new_path: ", copy_new_path)
  167. print("move_new_path: ", move_new_path)
  168. shutil.move(copy_new_path, move_new_path)
  169. time.sleep(3)
  170. print("===== 將 main.c 先複製更名 ==========================================================")
  171. # # 將 main.c 先複製更名
  172. copy_old_path = os.path.join(CURRENT_PATH, "CTO20220622", "Src", "main.c")
  173. # currentTime = dt.now().strftime("%Y%m%d_%H%M%S") # 同 hex 即可
  174. fileTitle_c = "[" + currentTime + "_" + prog_data['USERNAME'] + "] " + prog_data['tank'] + "_main.c"
  175. copy_new_path = os.path.join(CURRENT_PATH, "CTO20220622", "Src", fileTitle_c)
  176. print("copy_new_path: ", copy_new_path)
  177. shutil.copyfile(copy_old_path, copy_new_path)
  178. time.sleep(3)
  179. print("===== 再將 main.c 移動到 source_code 資料夾中 ==========================================================")
  180. # # 再將 main.c 移動到 source_code 資料夾中
  181. move_new_path = os.path.join(CURRENT_PATH, "source_code", fileTitle_c)
  182. print("copy_new_path: ", copy_new_path)
  183. print("move_new_path: ", move_new_path)
  184. shutil.move(copy_new_path, move_new_path)
  185. time.sleep(3)
  186. print("===== 將 source_code 資料內容 push 到 Git CoffeeProject_SourceCode ==========================================================")
  187. # # 將 source_code 資料內容 push 到 Git CoffeeProject_SourceCode
  188. cwdDATA = os.path.join(CURRENT_PATH, "source_code")
  189. subprocess.call(["git", "add", fileTitle_hex],cwd=cwdDATA)
  190. subprocess.call(["git", "commit","-m", fileTitle_hex],cwd=cwdDATA)
  191. subprocess.call(["git", "add", fileTitle_c],cwd=cwdDATA)
  192. subprocess.call(["git", "commit","-m", fileTitle_c],cwd=cwdDATA)
  193. subprocess.call(["git", "push"],cwd=cwdDATA)
  194. time.sleep(3)
  195. print("===== 刪除 source_code 資料夾 ==========================================================")
  196. # # 刪除 source_code 資料夾
  197. # shutil.rmtree(CURRENT_PATH + "\\source_code", onerror=remove_readonly)
  198. shutil.rmtree(cwdDATA, onerror=remove_readonly)
  199. time.sleep(3)
  200. # # 取得燒錄回傳
  201. print("===== SDIO.hex 燒錄等待中 =====================================================")
  202. res = board_prog[prog_data['tank']]
  203. print("res: ", res)
  204. return "燒錄中..."
  205. # time.sleep(60)
  206. # res = board_prog[prog_data['tank']]
  207. # print("res: ", res)
  208. # if board_prog[prog_data['tank']] == 'no reply':
  209. # board_prog[prog_data['tank']] = '0'
  210. # return 'no reply'
  211. # elif board_prog[prog_data['tank']] == 'success':
  212. # board_prog[prog_data['tank']] = '0'
  213. # return 'success'
  214. # elif board_prog[prog_data['tank']] == 'upload error':
  215. # board_prog[prog_data['tank']] = '0'
  216. # return 'upload error'
  217. # else:
  218. # res = "Code_upload " + prog_data['tank'] + " signal was not received"
  219. # return res
  220. @main.route('/board_programmer_result_<tid>')
  221. def board_programmer_result(tid):
  222. if board_prog[tid] == 'no reply':
  223. board_prog[tid] = '0'
  224. # return board_prog[tid] # 錯誤
  225. return 'no reply'
  226. elif board_prog[tid] == 'success':
  227. board_prog[tid] = '0'
  228. return 'success'
  229. elif board_prog[tid] == 'upload error':
  230. board_prog[tid] = '0'
  231. return 'upload error'
  232. elif board_prog[tid] == '0':
  233. return board_prog[tid]
  234. else:
  235. # res = "Code_upload " + tid + " signal was not received"
  236. return board_prog[tid]
  237. def remove_readonly(func, path, _):
  238. os.chmod(path, stat.S_IWRITE) # 更改權限 stat.S_IWRITE = windows 下取消只读
  239. func(path)
  240. # Rita 測試
  241. # 板子介面測試
  242. @main.route('/board_loadertt')
  243. def board_loadertt():
  244. pin_data = coffee1_0_pin.query.order_by(text('datetime desc')).first()
  245. # DCD1 = block_cond_d1_t.query.order_by(text('datetime desc')).first()
  246. BCD = block_cond_dry_t.query.order_by(text('datetime desc')).first()
  247. return render_template('board_loadertt.html', title="[測試]", **locals())
  248. # 檢視各使用者條件
  249. @main.route('/block_view', methods=['GET', 'POST'])
  250. def block_view():
  251. if request.method == 'GET':
  252. username = session['uname']
  253. status = session['status']
  254. sql = 'SELECT DISTINCT `UserName` FROM `block_cond_dry_t`'
  255. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffeemanage', password='skyeye', database='CoffeeManage', charset='utf8')
  256. mycursor = mydb.cursor()
  257. try:
  258. mycursor.execute(sql)
  259. username_data = mycursor.fetchall()
  260. except pymysql.err.IntegrityError:
  261. username_data = "UserName is empty"
  262. mydb.commit()
  263. mydb.close()
  264. return render_template('block_view.html', title="檢視積木條件", **locals())
  265. # else:
  266. # prog_username = request.values['prog_username']
  267. # prog_tank = request.values['prog_tank']
  268. # print("prog_username: ", prog_username)
  269. # print("prog_tank: ", prog_tank)
  270. # return redirect('/block_view')
  271. # 桶槽間溝通
  272. @main.route('/tanks_comm')
  273. def tanks_comm():
  274. if 'id' in session and 'uname' in session and 'status' in session:
  275. username = session['uname']
  276. status = session['status']
  277. return render_template('tanks_comm.html', title="設備單元整合運作", **locals())
  278. else:
  279. print("NO session['uname']")
  280. return redirect('/login')
  281. @main.route('/select_cond', methods=['GET', 'POST'])
  282. def select_cond():
  283. info = request.args.to_dict()
  284. username = info['username']
  285. print("username: ", username)
  286. tank = info['tank']
  287. print("tank: ", tank)
  288. cond_data = (block_cond_dry_t.query.filter_by(UserName=str(username),tank_num=str(tank)).order_by(text('datetime desc')).first()).cond
  289. # print("cond_data.cond: ", cond_data.cond, "_type(cond_data.cond): ", type(cond_data.cond))
  290. print("cond_data: ", cond_data, type(cond_data))
  291. return cond_data
  292. @main.route('/board_loader_<tankid>')
  293. def board_loader(tankid):
  294. if 'id' in session and 'uname' in session and 'status' in session:
  295. username = session['uname']
  296. status = session['status']
  297. # 取得桶槽編號
  298. TankID = tankid
  299. # 找到目前桶槽的入料儲豆槽
  300. dry_tank_io = dry_tank_relation.query.filter_by(tank_id=tankid).first()
  301. # 若在 dry_tank_relation 桶槽關聯內無此桶槽, 則回到 /board_loader_D1
  302. if dry_tank_io == None:
  303. return redirect("/tank_relation")
  304. print(dry_tank_io.tank_import) # DI1
  305. tank_import = dry_tank_io.tank_import
  306. # 找到目前桶槽的入料儲豆槽
  307. print(dry_tank_io.tank_export)
  308. tank_export = dry_tank_io.tank_export
  309. # 腳位配置
  310. pin_data = coffee1_0_pin.query.filter_by(tid=tankid).order_by(text('datetime desc')).first()
  311. print("pin_data: ", pin_data)
  312. # 積木條件
  313. BCD = block_cond_dry_t.query.filter_by(tank_num=tankid).order_by(text('datetime desc')).first()
  314. if BCD == None:
  315. # 網頁初始只需要 cond
  316. BCD = {"command":"Dry_OTA",
  317. "cond":[
  318. {"cond_add":[],
  319. "cond_com":[],
  320. "cond_main":""}
  321. ],
  322. "tank_num":tankid}
  323. print("BCD: ", BCD)
  324. return render_template('board_loader-1.html', title="板子燒錄介面", **locals())
  325. else:
  326. print("NO session['uname']")
  327. return redirect('/login')
  328. # if 'id' in session and 'uname' in session:
  329. # print("session['uname']: ", session['uname'])
  330. # username = session['uname']
  331. # print("session['status']: ", session['status'])
  332. # status = session['status']
  333. # pin_data = coffee1_0_pin.query.order_by(text('datetime desc')).first()
  334. # # print("pin_data.R1:", pin_data.R1)
  335. # block_data = dry_block_waiting.query.order_by(text('datetime desc')).first()
  336. # # print("block_data.cond_a1_1:", block_data.cond_a1_1)
  337. # DBW = dry_block_waiting.query.order_by(text('datetime desc')).first()
  338. # return render_template('board_loader-1.html', title="板子燒錄介面", **locals())
  339. # else:
  340. # print("NO session['uname']")
  341. # return redirect('/login')
  342. # 桶槽前後關係設定
  343. @main.route('/tank_relation')
  344. def tank_relation():
  345. dtr = dry_tank_relation.query.all()
  346. # for i in dtr:
  347. # print("dtr", i, ": ", i.tank_id)
  348. return render_template('tank_relation.html', title="桶槽關係建立", **locals())
  349. #致動器功能程式定義
  350. def GPIO(relay,status):
  351. if relay=="R1":
  352. if status=="on":
  353. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_13, GPIO_PIN_RESET);\n"
  354. elif status=="off":
  355. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_13, GPIO_PIN_SET);\n"
  356. else:
  357. act=""
  358. elif relay=="R2":
  359. if status=="on":
  360. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12, GPIO_PIN_RESET);\n"
  361. elif status=="off":
  362. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12, GPIO_PIN_SET);\n"
  363. else:
  364. act=""
  365. elif relay=="R3":
  366. if status=="on":
  367. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11, GPIO_PIN_RESET);\n"
  368. elif status=="off":
  369. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11, GPIO_PIN_SET);\n"
  370. else:
  371. act=""
  372. elif relay=="R4":
  373. if status=="on":
  374. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10, GPIO_PIN_RESET);\n"
  375. elif status=="off":
  376. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10, GPIO_PIN_SET);\n"
  377. else:
  378. act=""
  379. elif relay=="R5":
  380. if status=="on":
  381. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9, GPIO_PIN_RESET);\n"
  382. elif status=="off":
  383. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9, GPIO_PIN_SET);\n"
  384. else:
  385. act=""
  386. elif relay=="R6":
  387. if status=="on":
  388. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8, GPIO_PIN_RESET);\n"
  389. elif status=="off":
  390. act=" HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8, GPIO_PIN_SET);\n"
  391. else:
  392. act=""
  393. elif relay=="R7":
  394. if status=="on":
  395. act=" HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9, GPIO_PIN_RESET);\n"
  396. elif status=="off":
  397. act=" HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9, GPIO_PIN_SET);\n"
  398. else:
  399. act=""
  400. elif relay=="R8":
  401. if status=="on":
  402. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15, GPIO_PIN_RESET);\n"
  403. elif status=="off":
  404. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15, GPIO_PIN_SET);\n"
  405. else:
  406. act=""
  407. elif relay=="R9":
  408. if status=="on":
  409. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14, GPIO_PIN_RESET);\n"
  410. elif status=="off":
  411. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14, GPIO_PIN_SET);\n"
  412. else:
  413. act=""
  414. elif relay=="R10":
  415. if status=="on":
  416. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13, GPIO_PIN_RESET);\n"
  417. elif status=="off":
  418. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13, GPIO_PIN_SET);\n"
  419. else:
  420. act=""
  421. elif relay=="R11":
  422. if status=="on":
  423. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12, GPIO_PIN_RESET);\n"
  424. elif status=="off":
  425. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12, GPIO_PIN_SET);\n"
  426. else:
  427. act=""
  428. elif relay=="R12":
  429. if status=="on":
  430. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11, GPIO_PIN_RESET);\n"
  431. elif status=="off":
  432. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11, GPIO_PIN_SET);\n"
  433. else:
  434. act=""
  435. elif relay=="R13":
  436. if status=="on":
  437. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10, GPIO_PIN_RESET);\n"
  438. elif status=="off":
  439. act=" HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10, GPIO_PIN_SET);\n"
  440. else:
  441. act=""
  442. elif relay=="R14":
  443. if status=="on":
  444. act=" HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15, GPIO_PIN_RESET);\n"
  445. elif status=="off":
  446. act=" HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15, GPIO_PIN_SET);\n"
  447. else:
  448. act=""
  449. elif relay=="R15":
  450. if status=="on":
  451. act=" HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14, GPIO_PIN_RESET);\n"
  452. elif status=="off":
  453. act=" HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14, GPIO_PIN_SET);\n"
  454. else:
  455. act=""
  456. elif relay=="R16":
  457. if status=="on":
  458. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15, GPIO_PIN_RESET);\n"
  459. elif status=="off":
  460. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15, GPIO_PIN_SET);\n"
  461. else:
  462. act=""
  463. elif relay=="R17":
  464. if status=="on":
  465. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_14, GPIO_PIN_RESET);\n"
  466. elif status=="off":
  467. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_14, GPIO_PIN_SET);\n"
  468. else:
  469. act=""
  470. elif relay=="R18":
  471. if status=="on":
  472. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_13, GPIO_PIN_RESET);\n"
  473. elif status=="off":
  474. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_13, GPIO_PIN_SET);\n"
  475. else:
  476. act=""
  477. elif relay=="R19":
  478. if status=="on":
  479. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_12, GPIO_PIN_RESET);\n"
  480. elif status=="off":
  481. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_12, GPIO_PIN_SET);\n"
  482. else:
  483. act=""
  484. elif relay=="R20":
  485. if status=="on":
  486. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_11, GPIO_PIN_RESET);\n"
  487. elif status=="off":
  488. act=" HAL_GPIO_WritePin(GPIOE,GPIO_PIN_11, GPIO_PIN_SET);\n"
  489. else:
  490. act=""
  491. elif relay=="sleep":
  492. act=" HAL_Delay("+status+"000);\n"
  493. elif relay=="M10":
  494. if int(status)>0:
  495. act=(" user_pwm_setvalue2(0);\n"
  496. +" user_pwm_setvalue("+status+");\n")
  497. elif int(status)<0:
  498. status=-1*int(status)
  499. act=(" user_pwm_setvalue(0);\n"
  500. +" user_pwm_setvalue2("+str(status)+");\n")
  501. else:
  502. act=""
  503. elif relay=="M2":
  504. if status=="on":
  505. act=" user_pwm_setvalue3(50);\n"
  506. elif status=="off":
  507. act=" user_pwm_setvalue3(180);\n"
  508. else:
  509. act=""
  510. elif relay=="M3":
  511. if status=="on":
  512. act=" user_pwm_setvalue4(50);\n"
  513. elif status=="off":
  514. act=" user_pwm_setvalue4(180);\n"
  515. else:
  516. act=""
  517. else:
  518. act=""
  519. return act
  520. #感測器功能程式定義
  521. def PH(pin_position,pin_type):
  522. global pin_variables,pin_code
  523. if pin_position=="M4":
  524. pin="ADC_CHANNEL_0"
  525. elif pin_position=="M5":
  526. pin="ADC_CHANNEL_3"
  527. elif pin_position=="M7":
  528. pin="ADC_CHANNEL_4"
  529. if pin_type =="PH":
  530. print("PH ok")
  531. pin_variables=("uint16_t "+pin_position+"_AD_Value = 0;\n"
  532. +"float "+pin_position+"_voltage_V =0;\n"
  533. +"float "+pin_position+"_pH_mid = 1.500;\n"
  534. +"float "+pin_position+"_pH_low = 2.030;\n"
  535. +"float "+pin_position+"_pH_high =0.975;\n"
  536. +"float "+pin_position+"_"+pin_type+"=0;\n")
  537. pin_code=(" MX_ADC1_Init1("+pin+");\n"
  538. +" HAL_ADC_Start(&hadc1);\n"
  539. +" HAL_ADC_PollForConversion(&hadc1, 50);\n"
  540. +" if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))\n"
  541. +" {\n"
  542. +" "+pin_position+"_AD_Value = HAL_ADC_GetValue(&hadc1);\n"
  543. +" "+pin_position+"_voltage_V = "+pin_position+"_AD_Value*3.3f/4096;\n"
  544. +" if ("+pin_position+"_voltage_V > "+pin_position+"_pH_mid)\n"
  545. +" {\n"
  546. +" "+pin_position+"_"+pin_type+" = 7.0 - 3.0 / ("+pin_position+"_pH_low - "+pin_position+"_pH_mid) * ("+pin_position+"_voltage_V - "+pin_position+"_pH_mid);\n"
  547. +" }\n"
  548. +" else\n"
  549. +" {\n"
  550. +" "+pin_position+"_"+pin_type+" = 7.0 - 3.0 / ("+pin_position+"_pH_mid - "+pin_position+"_pH_high) * ("+pin_position+"_voltage_V - "+pin_position+"_pH_mid);\n"
  551. +" }\n"
  552. +" }\n"
  553. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",4,10);\n")
  554. else:
  555. pin_variables=""
  556. pin_code=""
  557. def DO(pin_position,pin_type):
  558. global pin_variables,pin_code
  559. if pin_position=="M4":
  560. pin="ADC_CHANNEL_0"
  561. elif pin_position=="M5":
  562. pin="ADC_CHANNEL_3"
  563. elif pin_position=="M7":
  564. pin="ADC_CHANNEL_4"
  565. if pin_type =="DO":
  566. print("DO ok")
  567. pin_variables=("uint16_t "+pin_position+"_AD_Value = 0;\n"
  568. +"float "+pin_position+"_voltage_V =0;\n"
  569. +"float "+pin_position+"_DO_offset =0.44;\n"
  570. +"float "+pin_position+"_"+pin_type+" =0;\n")
  571. pin_code=(" MX_ADC1_Init1("+pin+");\n"
  572. +" HAL_ADC_Start(&hadc1);\n"
  573. +" HAL_ADC_PollForConversion(&hadc1, 50);\n"
  574. +" if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))\n"
  575. +" {\n"
  576. +" "+pin_position+"_AD_Value = HAL_ADC_GetValue(&hadc1);\n"
  577. +" "+pin_position+"_voltage_V = "+pin_position+"_AD_Value*3.3f/4096;\n"
  578. +" "+pin_position+"_"+pin_type+"= ((("+pin_position+"_AD_Value*3.3f/4096)*100)/"+pin_position+"_DO_offset);\n"
  579. +" }\n"
  580. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",4,10);\n")
  581. else:
  582. pin_variables=""
  583. pin_code=""
  584. def WATERLEVEL(pin_position,pin_type):
  585. global pin_variables,pin_code
  586. if pin_position=="M9":
  587. pin="GPIO_PIN_9"
  588. elif pin_position=="M11":
  589. pin="GPIO_PIN_7"
  590. elif pin_position=="M12":
  591. pin="GPIO_PIN_8"
  592. elif pin_position=="M19":
  593. pin="GPIO_PIN_10"
  594. if pin_type =="WATERLEVEL":
  595. print("WATERLEVEL ok")
  596. pin_variables=("int "+pin_position+"_"+pin_type+" =0;\n")
  597. pin_code=(" MX_GPIO_Input1("+pin+");\n"
  598. +" if (HAL_GPIO_ReadPin(GPIOE, "+pin+") == GPIO_PIN_SET)\n"
  599. +" {\n"
  600. +" "+pin_position+"_"+pin_type+" =1;\n"
  601. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  602. +" }\n"
  603. +" else\n"
  604. +" {\n"
  605. +" "+pin_position+"_"+pin_type+" =0;\n"
  606. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  607. +" }\n")
  608. else:
  609. pin_variables=""
  610. pin_code=""
  611. def motorfeedback(pin_position,pin_type):
  612. global pin_variables,pin_code
  613. if pin_position=="M9":
  614. pin="GPIO_PIN_9"
  615. elif pin_position=="M11":
  616. pin="GPIO_PIN_7"
  617. elif pin_position=="M12":
  618. pin="GPIO_PIN_8"
  619. elif pin_position=="M19":
  620. pin="GPIO_PIN_10"
  621. if pin_type =="motorfeedback":
  622. print("feedback ok")
  623. pin_variables=("int "+pin_position+"_"+pin_type+" =0;\n")
  624. pin_code=(" MX_GPIO_Input1("+pin+");\n"
  625. +" if (HAL_GPIO_ReadPin(GPIOE, "+pin+") == GPIO_PIN_SET)\n"
  626. +" {\n"
  627. +" "+pin_position+"_"+pin_type+" =1;\n"
  628. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  629. +" }\n"
  630. +" else\n"
  631. +" {\n"
  632. +" "+pin_position+"_"+pin_type+" =0;\n"
  633. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  634. +" }\n")
  635. else:
  636. pin_variables=""
  637. pin_code=""
  638. def butterflyvalvefeedback(pin_position,pin_type):
  639. global pin_variables,pin_code
  640. if pin_position=="M9":
  641. pin="GPIO_PIN_9"
  642. elif pin_position=="M11":
  643. pin="GPIO_PIN_7"
  644. elif pin_position=="M12":
  645. pin="GPIO_PIN_8"
  646. elif pin_position=="M19":
  647. pin="GPIO_PIN_10"
  648. if pin_type =="butterflyvalvefeedback":
  649. print("butterflyvalvefeedback ok")
  650. pin_variables=("int "+pin_position+"_"+pin_type+" =0;\n")
  651. pin_code=(" MX_GPIO_Input1("+pin+");\n"
  652. +" if (HAL_GPIO_ReadPin(GPIOE, "+pin+") == GPIO_PIN_SET)\n"
  653. +" {\n"
  654. +" "+pin_position+"_"+pin_type+" =1;\n"
  655. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  656. +" }\n"
  657. +" else\n"
  658. +" {\n"
  659. +" "+pin_position+"_"+pin_type+" =0;\n"
  660. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",1,10);\n"
  661. +" }\n")
  662. else:
  663. pin_variables=""
  664. pin_code=""
  665. def ORP(pin_position,pin_type):
  666. global pin_variables,pin_code
  667. if pin_position=="M4":
  668. pin="ADC_CHANNEL_0"
  669. elif pin_position=="M5":
  670. pin="ADC_CHANNEL_3"
  671. elif pin_position=="M7":
  672. pin="ADC_CHANNEL_4"
  673. if pin_type =="ORP":
  674. print("ORP ok")
  675. pin_variables=("uint16_t "+pin_position+"_AD_Value = 0;\n"
  676. +"float "+pin_position+"_voltage_V =0;\n"
  677. +"float "+pin_position+"_ORP_offset =0;\n"
  678. +"float "+pin_position+"_"+pin_type+" =0;\n")
  679. pin_code=(" MX_ADC1_Init1("+pin+");\n"
  680. +" HAL_ADC_Start(&hadc1);\n"
  681. +" HAL_ADC_PollForConversion(&hadc1, 50);\n"
  682. +" if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))\n"
  683. +" {\n"
  684. +" "+pin_position+"_AD_Value = HAL_ADC_GetValue(&hadc1);\n"
  685. +" "+pin_position+"_voltage_V = "+pin_position+"_AD_Value*3.3f/4096;\n"
  686. +" "+pin_position+"_"+pin_type+"= ((("+pin_position+"_AD_Value*3.3f/4096)-(1.5+"+pin_position+"_ORP_offset)));\n"
  687. +" }\n"
  688. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",4,10);\n")
  689. else:
  690. pin_variables=""
  691. pin_code=""
  692. def SonicESMUS07(pin_position,pin_type):
  693. global pin_variables,pin_code,pin_add_code
  694. if pin_position=="M1":
  695. pin="ADC_CHANNEL_6"
  696. if pin_type =="SonicESMUS07":
  697. print("ESMUS07 ok")
  698. pin_variables=("uint16_t "+pin_position+"_AD_Value = 0;\n"
  699. +"float "+pin_position+"_voltage_V =0;\n"
  700. +"float "+pin_position+"_"+pin_type+" =0;\n")
  701. pin_code=(" MX_ADC1_Init1("+pin+");\n"
  702. +" HAL_ADC_Start(&hadc1);\n"
  703. +" HAL_ADC_PollForConversion(&hadc1, 50);\n"
  704. +" if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))\n"
  705. +" {\n"
  706. +" "+pin_position+"_AD_Value = HAL_ADC_GetValue(&hadc1);\n"
  707. +" "+pin_position+"_voltage_V = "+pin_position+"_AD_Value*5.3f/4096;\n"
  708. +" if ("+pin_position+"_voltage_V==0)\n"
  709. +" {\n"
  710. +" "+pin_position+"_"+pin_type+ " = 100;\n"
  711. +" }\n"
  712. +" else\n"
  713. +" {\n"
  714. +" "+pin_position+"_"+pin_type+ " = ("+pin_position+"_voltage_V*180)+100;\n"
  715. +" }\n"
  716. +" }\n"
  717. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",4,10);\n")
  718. else:
  719. pin_variables=""
  720. pin_code=""
  721. pin_add_code=""
  722. def SEN0189(pin_position,pin_type):
  723. global pin_variables,pin_code,pin_add_code
  724. if pin_position=="M6":
  725. pin="ADC_CHANNEL_13"
  726. elif pin_position=="M13":
  727. pin="ADC_CHANNEL_5"
  728. if pin_type =="SEN0189":
  729. print("SEN0189 ok")
  730. pin_variables=("uint16_t "+pin_position+"_AD_Value = 0;\n"
  731. +"float "+pin_position+"_voltage_V =0;\n"
  732. +"float "+pin_position+"_"+pin_type+" =0;\n")
  733. pin_code=(" MX_ADC1_Init1("+pin+");\n"
  734. +" HAL_ADC_Start(&hadc1);\n"
  735. +" HAL_ADC_PollForConversion(&hadc1, 50);\n"
  736. +" if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))\n"
  737. +" {\n"
  738. +" "+pin_position+"_AD_Value = HAL_ADC_GetValue(&hadc1);\n"
  739. +" "+pin_position+"_voltage_V = "+pin_position+"_AD_Value*5.0f/4096;\n"
  740. +" if ("+pin_position+"_voltage_V>4.2)\n"
  741. +" {\n"
  742. +" "+pin_position+"_"+pin_type+ " = 0;\n"
  743. +" }\n"
  744. +" else if ("+pin_position+"_voltage_V<2.5)\n"
  745. +" {\n"
  746. +" "+pin_position+"_"+pin_type+ " = 3000;\n"
  747. +" }\n"
  748. +" else\n"
  749. +" {\n"
  750. +" "+pin_position+"_"+pin_type+"=(-1120.4*"+pin_position+"_voltage_V*"+pin_position+"_voltage_V)+(5742.3*"+pin_position+"_voltage_V)-4352.9;\n"
  751. +" }\n"
  752. +" }\n"
  753. +" HAL_UART_Transmit(&huart4,(unsigned char*)&"+pin_position+"_"+pin_type+",4,10);\n")
  754. print(pin_variables)
  755. print(pin_code)
  756. else:
  757. pin_variables=""
  758. pin_code=""
  759. pin_add_code=""
  760. def SERVO(pin_position, pin_type):
  761. global pin_variables, pin_code
  762. if pin_type == "Servo":
  763. print("Servo ok")
  764. pin_code = (
  765. " HAL_UART_Receive_IT(&huart1, (uint8_t *)checkfeedback,sizeof(checkfeedback));\n")
  766. pin_add_code = (" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)\n"
  767. + "{\n"
  768. + " if(checkfeedback[0]==0xff && checkfeedback[6]==0x0D)\n"
  769. + " {\n"
  770. + " direction=checkfeedback[1];\n"
  771. + " if(direction==0)\n"
  772. + " {\n"
  773. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);\n"
  774. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);\n"
  775. + " user_pwm_setvalue(50);\n"
  776. + " }\n"
  777. + " else if(direction==1)\n"
  778. + " {\n"
  779. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);\n"
  780. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);\n"
  781. + " user_pwm_setvalue(50);\n"
  782. + " }\n"
  783. + " else\n"
  784. + " {\n"
  785. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);\n"
  786. + " HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);\n"
  787. + " user_pwm_setvalue(0);\n"
  788. + " }\n"
  789. + " }\n"
  790. + "}\n")
  791. print(pin_code)
  792. print(pin_add_code)
  793. else:
  794. pin_variables = ""
  795. pin_code = ""
  796. def MOTOR(pin_position, pin_type):
  797. global pin_variables, pin_code
  798. if pin_type == "Servo":
  799. print("Servo ok")
  800. pin_code = (" HAL_UART_Receive_IT(&huart1, (uint8_t *)checkfeedback,sizeof(checkfeedback));\n"
  801. + " HAL_Delay(100);\n"
  802. + " if(direction==0)\n"
  803. + " {\n"
  804. + " user_pwm_setvalue2(0);\n"
  805. + " user_pwm_setvalue(pwm_value);\n"
  806. + " }\n"
  807. + " else\n"
  808. + " {\n"
  809. + " user_pwm_setvalue2(pwm_value);\n"
  810. + " user_pwm_setvalue(0);\n"
  811. + " }\n")
  812. pin_add_code = (" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)\n"
  813. + "{\n"
  814. + " if(checkfeedback[0]==0xff && checkfeedback[6]==0x0D)\n"
  815. + " {\n"
  816. + " pwm_value=checkfeedback[1];\n"
  817. + " direction=checkfeedback[2];\n"
  818. + ' printf("%d",pwm_value);\n'
  819. + " }\n"
  820. + "}\n")
  821. print(pin_code)
  822. print(pin_add_code)
  823. else:
  824. pin_variables = ""
  825. pin_code = ""
  826. def SOIL(pin_position,pin_type):
  827. global pin_variables,pin_code,pin_add_code
  828. if pin_type =="Soil":
  829. print("SOIL ok")
  830. pin_variables=("uint8_t soil[8] ={0x01,0x03,0x00,0x00,0x00,0x03,0x05,0xCB};\n"
  831. +"uint8_t data[11] ={0,0,0,0,0,0,0,0,0,0,0};\n"
  832. +"float "+pin_position+"_"+pin_type+" =0;\n"
  833. +"int rh=0;\n"
  834. +"int temp=0;\n"
  835. +"int ec=0;\n")
  836. pin_code=(" HAL_UART_Transmit(&huart2, (uint8_t *)soil,sizeof(soil),50);\n"
  837. +" HAL_UART_Receive_IT(&huart2, (uint8_t *)data,sizeof(data));\n")
  838. pin_add_code=("void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)\n"
  839. +"{\n"
  840. +" if (huart->Instance == USART2)\n"
  841. +" {\n"
  842. +" if (data[0]==0x01 && data[1]==0x03)\n"
  843. +" {\n"
  844. +" rh = (data[3] << 8) + data[4];\n"
  845. +" temp = (data[5] << 8) + data[6];\n"
  846. +" ec = (data[7] << 8) + data[8];\n"
  847. +" }\n"
  848. +" }\n"
  849. +"}\n")
  850. print(pin_code)
  851. print(pin_add_code)
  852. else:
  853. pin_variables=""
  854. pin_code=""
  855. pin_add_code=""
  856. def EC(pin_position,pin_type):
  857. global pin_variables,pin_code,pin_add_code
  858. if pin_type =="EC":
  859. print("EC ok")
  860. pin_variables=("uint8_t data[4] ={0,0,0,0};\n"
  861. +"float "+pin_position+"_"+pin_type+" =0;\n")
  862. pin_code=(" HAL_UART_Receive_IT(&huart2, (uint8_t *)data,sizeof(data));\n")
  863. pin_add_code=("void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)\n"
  864. +"{\n"
  865. +" if (huart->Instance == USART2)\n"
  866. +" {\n"
  867. +" if (data[0]==0x30 && data[1]==0x2E)\n"
  868. +" {\n"
  869. +" HAL_UART_Transmit(&huart4, (uint8_t *)data,sizeof(data),50);\n"
  870. +" }\n"
  871. +" }\n"
  872. +"}\n")
  873. print(pin_variables)
  874. print(pin_code)
  875. print(pin_add_code)
  876. else:
  877. pin_variables=""
  878. pin_code=""
  879. pin_add_code=""
  880. def SHT11(pin_position,pin_type):
  881. global pin_variables,pin_code,pin_add_code
  882. global sensor_code
  883. if pin_position=="M14":
  884. pin_group="GPIOB"
  885. pin1="GPIO_PIN_0"
  886. pin2="GPIO_PIN_1"
  887. if pin_position=="M17":
  888. pin_group="GPIOC"
  889. pin1="GPIO_PIN_6"
  890. pin2="GPIO_PIN_7"
  891. if pin_type =="SHT11":
  892. print("SHT11 ok")
  893. pin_variables=("uint8_t cmd[7]={0xFF,0x00,0x00,0x00,0x00,0x00,0x0D};\n"
  894. +"uint16_t i,val,value_H,value_L,Cvalue,Hvalue;\n"
  895. +"int error;\n"
  896. +"float C1=-2.0468;\n"
  897. +"float C2=0.0367;\n"
  898. +"float C3=-0.0000015955;\n"
  899. +"float RH_Lin;\n"
  900. +"float RH_Ture;\n"
  901. +"float d1=-39.6;\n"
  902. +"float d2=0.01;\n"
  903. +"float T1=0.01;\n"
  904. +"float T2=0.00008;\n"
  905. +"float temp_C=0;\n"
  906. +"int temp;\n"
  907. +"int RH;\n"
  908. +"float "+pin_position+"_"+pin_type+" =0;\n")
  909. sensor_code=("void SHT10_TransStart(void);\n"
  910. +"void SHT10_WriteByte(void);\n"
  911. +"void SHT10_WriteByte2(void);\n"
  912. +"void SHT10_ReadByte(void);\n"
  913. +"void SHT10_Calculate(void);\n"
  914. +"void MX_GPIO_Input1(unsigned long pin);\n")
  915. pin_code=(" Cvalue=0;\n"
  916. +" Hvalue=0;\n"
  917. +" value_H=0;\n"
  918. +" value_L=0;\n"
  919. +" SHT10_TransStart();\n"
  920. +" SHT10_WriteByte();\n"
  921. +" MX_GPIO_Input1("+pin1+");\n"
  922. +" HAL_Delay(250);\n"
  923. +" if (HAL_GPIO_ReadPin("+pin_group+","+pin1+")==0)\n"
  924. +" {\n"
  925. +" SHT10_ReadByte();\n"
  926. +" value_H=val;\n"
  927. +" SHT10_ReadByte();\n"
  928. +" value_L=val;\n"
  929. +" Cvalue = (value_H<< 8 | value_L);\n"
  930. +" }\n"
  931. +" SHT10_TransStart();\n"
  932. +" SHT10_WriteByte2();\n"
  933. +" MX_GPIO_Input1("+pin1+");\n"
  934. +" HAL_Delay(250);\n"
  935. +" if (HAL_GPIO_ReadPin("+pin_group+","+pin1+")==0)\n"
  936. +" {\n"
  937. +" SHT10_ReadByte();\n"
  938. +" value_H=val;\n"
  939. +" SHT10_ReadByte();\n"
  940. +" value_L=val;\n"
  941. +" Hvalue = (value_H<< 8 | value_L);\n"
  942. +" }\n"
  943. +" SHT10_Calculate();\n")
  944. pin_add_code=(" void SHT10_TransStart(void)\n"
  945. +"{\n"
  946. +" MX_GPIO_Init();\n"
  947. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_SET);\n"
  948. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  949. +" HAL_Delay(10);\n"
  950. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  951. +" HAL_Delay(10);\n"
  952. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_RESET);\n"
  953. +" HAL_Delay(10);\n"
  954. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  955. +" HAL_Delay(10);\n"
  956. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  957. +" HAL_Delay(10);\n"
  958. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_SET);\n"
  959. +" HAL_Delay(10);\n"
  960. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  961. +" HAL_Delay(10);\n"
  962. +"}\n"
  963. +" void SHT10_WriteByte(void)\n"
  964. +"{\n"
  965. +" MX_GPIO_Init();\n"
  966. +" for (i=0x80;i>0;i/=2)\n"
  967. +" {\n"
  968. +" if (i & 0x03)\n"
  969. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_SET);\n"
  970. +" else\n"
  971. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_RESET);\n"
  972. +" HAL_Delay(10);\n"
  973. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  974. +" HAL_Delay(10);\n"
  975. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  976. +" HAL_Delay(10);\n"
  977. +" }\n"
  978. +" MX_GPIO_Input1("+pin1+");\n"
  979. +" HAL_Delay(10);\n"
  980. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  981. +" HAL_Delay(10);\n"
  982. +" error=HAL_GPIO_ReadPin("+pin_group+","+pin1+");\n"
  983. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  984. +" HAL_Delay(10);\n"
  985. +"}\n"
  986. +" void SHT10_WriteByte2(void)\n"
  987. +"{\n"
  988. +" MX_GPIO_Init();\n"
  989. +" for (i=0x80;i>0;i/=2)\n"
  990. +" {\n"
  991. +" if (i & 0x05)\n"
  992. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_SET);\n"
  993. +" else\n"
  994. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_RESET);\n"
  995. +" HAL_Delay(10);\n"
  996. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  997. +" HAL_Delay(10);\n"
  998. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  999. +" HAL_Delay(10);\n"
  1000. +" }\n"
  1001. +" MX_GPIO_Input1("+pin1+");\n"
  1002. +" HAL_Delay(10);\n"
  1003. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  1004. +" HAL_Delay(10);\n"
  1005. +" error=HAL_GPIO_ReadPin("+pin_group+", "+pin1+");\n"
  1006. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  1007. +" HAL_Delay(10);\n"
  1008. +"}\n"
  1009. +" void SHT10_ReadByte(void)\n"
  1010. +"{\n"
  1011. +" val=0;\n"
  1012. +" MX_GPIO_Input1("+pin1+");\n"
  1013. +" for (i=0x80;i>0;i/=2)\n"
  1014. +" {\n"
  1015. +" HAL_Delay(10);\n"
  1016. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  1017. +" HAL_Delay(10);\n"
  1018. +" if(HAL_GPIO_ReadPin("+pin_group+","+pin1+"))\n"
  1019. +" val=( val | i );\n"
  1020. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  1021. +" }\n"
  1022. +" MX_GPIO_Init();\n"
  1023. +" if (1)\n"
  1024. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_RESET);\n"
  1025. +" else\n"
  1026. +" HAL_GPIO_WritePin("+pin_group+","+pin1+",GPIO_PIN_SET);\n"
  1027. +" HAL_Delay(10);\n"
  1028. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_SET);\n"
  1029. +" HAL_Delay(10);\n"
  1030. +" HAL_GPIO_WritePin("+pin_group+","+pin2+",GPIO_PIN_RESET);\n"
  1031. +" HAL_Delay(10);\n"
  1032. +"}\n"
  1033. +" void SHT10_Calculate(void)\n"
  1034. +"{\n"
  1035. +" temp_C=d1+d2*Cvalue;\n"
  1036. +" RH_Lin = C1+C2*Hvalue+C3*Hvalue*Hvalue;\n"
  1037. +" RH_Ture= (temp_C-25)*(T1+T2*Hvalue)+RH_Lin;\n"
  1038. +" if (RH_Ture>100)\n"
  1039. +" RH_Ture= 100;\n"
  1040. +" if (RH_Ture<0.1)\n"
  1041. +" RH_Ture=0.1;\n"
  1042. +" if (temp_C<0)\n"
  1043. +" {\n"
  1044. +" cmd[1]=1;\n"
  1045. +" cmd[2]=-1*temp_C;\n"
  1046. +" temp=(-10*temp_C);\n"
  1047. +" cmd[3]=temp%10;\n"
  1048. +" cmd[4]=RH_Ture;\n"
  1049. +" RH=RH_Ture*10;\n"
  1050. +" cmd[5]=RH%10;\n"
  1051. +" }\n"
  1052. +" else\n"
  1053. +" {\n"
  1054. +" cmd[1]=0;\n"
  1055. +" cmd[2]=temp_C;\n"
  1056. +" temp=(10*temp_C);\n"
  1057. +" cmd[3]=temp%10;\n"
  1058. +" cmd[4]=RH_Ture;\n"
  1059. +" RH=RH_Ture*10;\n"
  1060. +" cmd[5]=RH%10;\n"
  1061. +" }\n"
  1062. +"}\n")
  1063. else:
  1064. pin_variables=""
  1065. pin_code=""
  1066. pin_add_code=""
  1067. sensor_code=""
  1068. def DS18B20(pin_position,pin_type):
  1069. global pin_variables,pin_code,pin_add_code
  1070. global sensor_code
  1071. if pin_position=="M14":
  1072. pin1="GPIO_PIN_0"
  1073. if pin_position=="M16":
  1074. pin1="GPIO_PIN_7"
  1075. if pin_type =="DS18B20":
  1076. print("DS18B20 ok")
  1077. pin_variables=("#define CLR_DS18B20() HAL_GPIO_WritePin (GPIOB, "+pin1+",GPIO_PIN_RESET )\n"
  1078. +"#define SET_DS18B20() HAL_GPIO_WritePin (GPIOB, "+pin1+",GPIO_PIN_SET )\n"
  1079. +"#define DS18B20_DQ_IN HAL_GPIO_ReadPin(GPIOB, "+pin1+")\n"
  1080. +"int16_t temp;\n"
  1081. +"int error;\n"
  1082. +"float "+pin_position+"_"+pin_type+" =0;\n")
  1083. sensor_code=("uint8_t DS18B20_Init(void);\n"
  1084. +"short DS18B20_Get_Temp(void);\n"
  1085. +"void DS18B20_Start(void);\n"
  1086. +"void DS18B20_Write_Byte(uint8_t dat);\n"
  1087. +"uint8_t DS18B20_Read_Byte(void);\n"
  1088. +"uint8_t DS18B20_Read_Bit(void);\n"
  1089. +"uint8_t DS18B20_Check(void);\n"
  1090. +"void DS18B20_Rst(void);\n")
  1091. pin_code=(" temp=DS18B20_Get_Temp();\n")
  1092. pin_add_code=(" void delay_us(uint32_t value)\n"
  1093. +"{\n"
  1094. +" uint32_t i;\n"
  1095. +" i = value * 3;\n"
  1096. +" while(i--);\n"
  1097. +"}\n"
  1098. +" void DS18B20_Rst(void)\n"
  1099. +"{\n"
  1100. +" CLR_DS18B20();\n"
  1101. +" delay_us(750);\n"
  1102. +" SET_DS18B20();\n"
  1103. +" delay_us(15);\n"
  1104. +"}\n"
  1105. +" uint8_t DS18B20_Check(void)\n"
  1106. +"{\n"
  1107. +" uint8_t retry=0;\n"
  1108. +" while (DS18B20_DQ_IN&&retry<200)\n"
  1109. +" {\n"
  1110. +" retry++;\n"
  1111. +" delay_us(1);\n"
  1112. +" }\n"
  1113. +" if(retry>=200)return 1;\n"
  1114. +" else retry=0;\n"
  1115. +" while (!DS18B20_DQ_IN&&retry<240)\n"
  1116. +" {\n"
  1117. +" retry++;\n"
  1118. +" delay_us(1);\n"
  1119. +" }\n"
  1120. +" if(retry>=240)return 1;\n"
  1121. +" return 0;\n"
  1122. +"}\n"
  1123. +" uint8_t DS18B20_Read_Bit(void)\n"
  1124. +"{\n"
  1125. +" uint8_t data;\n"
  1126. +" CLR_DS18B20();\n"
  1127. +" delay_us(2);\n"
  1128. +" SET_DS18B20();\n"
  1129. +" delay_us(12);\n"
  1130. +" if(DS18B20_DQ_IN)data=1;\n"
  1131. +" else data=0;\n"
  1132. +" delay_us(50);\n"
  1133. +" return data;\n"
  1134. +"}\n"
  1135. +" uint8_t DS18B20_Read_Byte(void)\n"
  1136. +"{\n"
  1137. +" uint8_t i,j,dat;\n"
  1138. +" dat=0;\n"
  1139. +" for (i=1;i<=8;i++)\n"
  1140. +" {\n"
  1141. +" j=DS18B20_Read_Bit();\n"
  1142. +" dat=(j<<7)|(dat>>1);\n"
  1143. +" }\n"
  1144. +" return dat;\n"
  1145. +"}\n"
  1146. +" void DS18B20_Write_Byte(uint8_t dat)\n"
  1147. +"{\n"
  1148. +" uint8_t j;\n"
  1149. +" uint8_t testb;\n"
  1150. +" for (j=1;j<=8;j++)\n"
  1151. +" {\n"
  1152. +" testb=dat&0x01;\n"
  1153. +" dat=dat>>1;\n"
  1154. +" if (testb)\n"
  1155. +" {\n"
  1156. +" CLR_DS18B20();\n"
  1157. +" delay_us(2);\n"
  1158. +" SET_DS18B20();\n"
  1159. +" delay_us(60);\n"
  1160. +" }\n"
  1161. +" else\n"
  1162. +" {\n"
  1163. +" CLR_DS18B20();\n"
  1164. +" delay_us(60);\n"
  1165. +" SET_DS18B20();\n"
  1166. +" delay_us(2);\n"
  1167. +" }\n"
  1168. +" }\n"
  1169. +"}\n"
  1170. +" uint8_t DS18B20_Init(void)\n"
  1171. +"{\n"
  1172. +" SET_DS18B20();\n"
  1173. +" DS18B20_Rst();\n"
  1174. +" return DS18B20_Check();\n"
  1175. +"}\n"
  1176. +" void DS18B20_Start(void)\n"
  1177. +"{\n"
  1178. +" DS18B20_Rst();\n"
  1179. +" DS18B20_Check();\n"
  1180. +" DS18B20_Write_Byte(0xcc);\n"
  1181. +" DS18B20_Write_Byte(0x44);\n"
  1182. +"}\n"
  1183. +" short DS18B20_Get_Temp(void)\n"
  1184. +"{\n"
  1185. +" uint8_t temp;\n"
  1186. +" uint8_t TL,TH;\n"
  1187. +" short tem;\n"
  1188. +" DS18B20_Start();\n"
  1189. +" DS18B20_Rst();\n"
  1190. +" DS18B20_Check();\n"
  1191. +" DS18B20_Write_Byte(0xcc);\n"
  1192. +" DS18B20_Write_Byte(0xbe);\n"
  1193. +" TL=DS18B20_Read_Byte();\n"
  1194. +" TH=DS18B20_Read_Byte();\n"
  1195. +" if(TH>7)\n"
  1196. +" {\n"
  1197. +" TH=~TH;\n"
  1198. +" TL=~TL;\n"
  1199. +" temp=0;\n"
  1200. +" }\n"
  1201. +" else temp=1;\n"
  1202. +" tem=TH;\n"
  1203. +" tem<<=8;\n"
  1204. +" tem+=TL;\n"
  1205. +" tem=(float)tem*0.625f;\n"
  1206. +" if(temp)return tem;\n"
  1207. +" else return -tem;\n"
  1208. +"}\n")
  1209. else:
  1210. pin_variables=""
  1211. pin_code=""
  1212. pin_add_code=""
  1213. sensor_code=""
  1214. def BMP280(pin_position,pin_type):
  1215. global pin_variables,pin_code,pin_add_code,init_code
  1216. global sensor_code
  1217. if pin_type =="BMP280":
  1218. print("BMP280 ok")
  1219. pin_variables=("uint8_t cmd[7]={0xFF,0x00,0x00,0x00,0x00,0x00,0x0D};\n"
  1220. +"HAL_StatusTypeDef Status;\n"
  1221. +"#define ADDR_AT24C04_WRITE_FIRST_16_PAGES 0xEC\n"
  1222. +"#define ADDR_AT24C04_WRITE_FIRST_16_PAGES 0xEC\n"
  1223. +"#define ADDR_AT24C04_READ 0xED\n"
  1224. +"#define AT24C04_TIMEOUT 0xED\n"
  1225. +"#define AT24C04_PAGE_SIZE 16\n"
  1226. +"#define BUFFER_SIZE 1\n"
  1227. +"uint16_t dig_T1;\n"
  1228. +"uint16_t dig_T2;\n"
  1229. +"uint16_t dig_T3;\n"
  1230. +"uint16_t dig_P1;\n"
  1231. +"uint16_t dig_P2;\n"
  1232. +"uint16_t dig_P3;\n"
  1233. +"uint16_t dig_P4;\n"
  1234. +"uint16_t dig_P5;\n"
  1235. +"uint16_t dig_P6;\n"
  1236. +"uint16_t dig_P7;\n"
  1237. +"uint16_t dig_P8;\n"
  1238. +"uint16_t dig_P9;\n"
  1239. +"uint32_t adc_P=0;\n"
  1240. +"uint32_t adc_T=0;\n"
  1241. +"uint8_t WriteBuffer[BUFFER_SIZE]={0xb6};\n"
  1242. +"uint8_t WriteBuffer1[BUFFER_SIZE]={0xff};\n"
  1243. +"uint8_t WriteBuffer2[BUFFER_SIZE]={0x00};\n"
  1244. +"uint8_t ReadBuffer[BUFFER_SIZE];\n"
  1245. +"int RH;\n"
  1246. +"float "+pin_position+"_"+pin_type+" =0;\n")
  1247. sensor_code=("HAL_StatusTypeDef AT24C04_Write(I2C_HandleTypeDef *hi2c,uint16_t MemAddress,uint8_t *pData);\n"
  1248. +"HAL_StatusTypeDef AT24C04_Read(I2C_HandleTypeDef *hi2c,uint16_t MemAddress,uint8_t *pData);\n"
  1249. +"long bmp280_T_MultipleReadThree(void);\n"
  1250. +"long bmp280_P_MultipleReadThree(void);\n"
  1251. +"short bmp280_MultipleReadTwo(uint16_t addr);\n")
  1252. init_code=(" AT24C04_Write(&hi2c1,0xe0,WriteBuffer);\n"
  1253. +" AT24C04_Write(&hi2c1,0xf4,WriteBuffer1);\n"
  1254. +" AT24C04_Write(&hi2c1,0xf5,WriteBuffer2);\n"
  1255. +" dig_T1 = bmp280_MultipleReadTwo(0x88);\n"
  1256. +" dig_T2 = bmp280_MultipleReadTwo(0x8A);\n"
  1257. +" dig_T3 = bmp280_MultipleReadTwo(0x8C);\n"
  1258. +" dig_P1 = bmp280_MultipleReadTwo(0x8E);\n"
  1259. +" dig_P2 = bmp280_MultipleReadTwo(0x90);\n"
  1260. +" dig_P3 = bmp280_MultipleReadTwo(0x92);\n"
  1261. +" dig_P4 = bmp280_MultipleReadTwo(0x94);\n"
  1262. +" dig_P5 = bmp280_MultipleReadTwo(0x96);\n"
  1263. +" dig_P6 = bmp280_MultipleReadTwo(0x98);\n"
  1264. +" dig_P7 = bmp280_MultipleReadTwo(0x9A);\n"
  1265. +" dig_P8 = bmp280_MultipleReadTwo(0x9C);\n"
  1266. +" dig_P9 = bmp280_MultipleReadTwo(0x9E);\n")
  1267. pin_code=(" adc_T=bmp280_T_MultipleReadThree();\n"
  1268. +" adc_P=bmp280_P_MultipleReadThree();\n"
  1269. +" double var1, var2,t_fine;\n"
  1270. +" var1 = (((double) adc_T) / 16384.0 - ((double) dig_T1) / 1024.0)* ((double) dig_T2);\n"
  1271. +" var2 = ((((double) adc_T) / 131072.0 - ((double) dig_T1) / 8192.0)* (((double) adc_T) / 131072.0 - ((double) dig_T1) / 8192.0))* ((double) dig_T3);\n"
  1272. +" t_fine = (int32_t) (var1 + var2);\n"
  1273. +" double temperature = (var1 + var2) / 5120.0;\n"
  1274. +" double pressure;\n"
  1275. +" var1 = (t_fine / 2.0) - 64000.0;\n"
  1276. +" var2 = var1 * var1 * ((double) dig_P6) / 32768.0;\n"
  1277. +" var2 = var2 + var1 * ((double) dig_P5) * 2.0;\n"
  1278. +" var2 = (var2 / 4.0) + (((double) dig_P4) * 65536.0);\n"
  1279. +" var1 = (((double) dig_P3) * var1 * var1 / 524288.0+ ((double) dig_P2) * var1) / 524288.0;\n"
  1280. +" var1 = (1.0 + var1 / 32768.0) * ((double) dig_P1);\n"
  1281. +" if (var1 == 0.0)\n"
  1282. +" {\n"
  1283. +" var1 = 0;\n"
  1284. +" }\n"
  1285. +" pressure = 1048576.0 - (double) adc_P;\n"
  1286. +" pressure = (pressure - (var2 / 4096.0)) * 6250.0 / var1;\n"
  1287. +" var1 = ((double) dig_P9) * pressure * pressure / 2147483648.0;"
  1288. +" var2 = pressure * ((double) dig_P8) / 32768.0;\n"
  1289. +" pressure = pressure + (var1 + var2 + ((double) dig_P7)) / 16.0;\n"
  1290. +" cmd[1]=pressure/10000; \n"
  1291. +" int pa =pressure;\n"
  1292. +" cmd[2]=(pa%10000)/100;\n"
  1293. +" cmd[3]=(pa%10000)%100;\n"
  1294. +" HAL_UART_Transmit(&huart4, (uint8_t *)cmd, sizeof(cmd),1);\n")
  1295. pin_add_code=("HAL_StatusTypeDef AT24C04_Write(I2C_HandleTypeDef *hi2c,uint16_t MemAddress,uint8_t *pData)\n"
  1296. +"{\n"
  1297. +" Status = HAL_I2C_Mem_Write(&hi2c1, ADDR_AT24C04_WRITE_FIRST_16_PAGES, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, AT24C04_PAGE_SIZE, AT24C04_TIMEOUT);\n"
  1298. +" return Status;\n"
  1299. +"}\n"
  1300. +"HAL_StatusTypeDef AT24C04_Read(I2C_HandleTypeDef *hi2c,uint16_t MemAddress,uint8_t *pData)\n"
  1301. +"{\n"
  1302. +" Status = HAL_I2C_Mem_Read(&hi2c1, ADDR_AT24C04_READ, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, BUFFER_SIZE, AT24C04_TIMEOUT);\n"
  1303. +" return Status;\n"
  1304. +"}\n"
  1305. +" long bmp280_T_MultipleReadThree()\n"
  1306. +"{\n"
  1307. +" uint8_t msb, lsb, xlsb;\n"
  1308. +" int32_t temp = 0;\n"
  1309. +" AT24C04_Read(&hi2c1,0xfa,ReadBuffer);\n"
  1310. +" msb=ReadBuffer[0];\n"
  1311. +" AT24C04_Read(&hi2c1,0xfb,ReadBuffer);\n"
  1312. +" lsb=ReadBuffer[0];\n"
  1313. +" AT24C04_Read(&hi2c1,0xfc,ReadBuffer);\n"
  1314. +" xlsb=ReadBuffer[0];\n"
  1315. +" temp = ((msb << 12)|(lsb << 4)|(xlsb >> 4));\n"
  1316. +" return temp;\n"
  1317. +"}\n"
  1318. +"long bmp280_P_MultipleReadThree()\n"
  1319. +"{\n"
  1320. +" uint8_t msb, lsb, xlsb;\n"
  1321. +" int32_t pressure = 0;\n"
  1322. +" AT24C04_Read(&hi2c1,0xf7,ReadBuffer);\n"
  1323. +" msb=ReadBuffer[0];\n"
  1324. +" AT24C04_Read(&hi2c1,0xf8,ReadBuffer);\n"
  1325. +" lsb=ReadBuffer[0];\n"
  1326. +" AT24C04_Read(&hi2c1,0xf9,ReadBuffer);\n"
  1327. +" xlsb=ReadBuffer[0];\n"
  1328. +" pressure = ((msb << 12)|(lsb << 4)|(xlsb >> 4));\n"
  1329. +" return pressure;\n"
  1330. +"}\n"
  1331. +" short bmp280_MultipleReadTwo(uint16_t addr )\n"
  1332. +"{\n"
  1333. +" uint8_t msb, lsb;\n"
  1334. +" uint16_t temp = 0;\n"
  1335. +" AT24C04_Read(&hi2c1,addr,ReadBuffer);\n"
  1336. +" lsb = ReadBuffer[0];\n"
  1337. +" AT24C04_Read(&hi2c1,addr+1,ReadBuffer);\n"
  1338. +" msb = ReadBuffer[0];\n"
  1339. +" temp = msb << 8|lsb;\n"
  1340. +" return temp;\n"
  1341. +"}\n")
  1342. else:
  1343. pin_variables=""
  1344. pin_code=""
  1345. pin_add_code=""
  1346. init_code=""
  1347. sensor_code=""
  1348. def motor(pin_position,pin_type):
  1349. global act_code,init_code
  1350. global sensor_code
  1351. if pin_type =="Motor":
  1352. print("motor ok")
  1353. sensor_code=("void user_pwm_setvalue(uint16_t value);\n"
  1354. +"void user_pwm_setvalue2(uint16_t value);\n")
  1355. act_code=("void user_pwm_setvalue(uint16_t value)\n"
  1356. +"{\n"
  1357. +" TIM_OC_InitTypeDef sConfigOC;\n"
  1358. +" sConfigOC.OCMode = TIM_OCMODE_PWM1;\n"
  1359. +" sConfigOC.Pulse = value;\n"
  1360. +" sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;\n"
  1361. +" sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;\n"
  1362. +" HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);\n"
  1363. +" HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);\n"
  1364. +"}\n")
  1365. init_code=(" MX_TIM2_Init();\n")
  1366. else:
  1367. act_code=""
  1368. init_code=""
  1369. sensor_code=""
  1370. def zigbee(pin_type):
  1371. global pin_variables,pin_code,init_code
  1372. if pin_type =="ON":
  1373. print("zigbee ok")
  1374. pin_variables=("uint8_t zigbeecmd1[5]={0xFE,0x00,0x01,0x00,0x01};\n"
  1375. +"uint8_t zigbeecmd2[5]={0xFE,0x00,0x02,0x00,0x02};\n"
  1376. +"uint8_t zigbeestatu[20];\n"
  1377. +"uint8_t zigbeestatu1[5];\n"
  1378. +'uint8_t zigbeecon[7]="connect";\n'
  1379. +'uint8_t zigbeenotcon[11]="not connect";\n'
  1380. +'uint8_t zigbeechang[14]="change is down";\n')
  1381. init_code=(" HAL_UART_Transmit(&huart2, (uint8_t *)zigbeecmd2, sizeof(zigbeecmd2), 10);\n"
  1382. +" HAL_UART_Receive(&huart2, (uint8_t *)zigbeestatu,sizeof(zigbeestatu),2000);\n"
  1383. +" HAL_UART_Transmit(&huart4, (uint8_t *)zigbeestatu, sizeof(zigbeestatu),10);\n"
  1384. +" HAL_UART_Transmit(&huart2, (uint8_t *)zigbeecmd1, sizeof(zigbeecmd1), 10);\n"
  1385. +" HAL_UART_Receive(&huart2, (uint8_t *)zigbeestatu,sizeof(zigbeestatu),2000);\n"
  1386. +" HAL_UART_Transmit(&huart4, (uint8_t *)zigbeestatu, sizeof(zigbeestatu),10);\n"
  1387. +" if (zigbeestatu[18]== 0x01)\n"
  1388. +" {\n"
  1389. +" HAL_UART_Transmit(&huart4, (uint8_t *)zigbeecon, sizeof(zigbeecon),10);\n"
  1390. +" }\n"
  1391. +" else if(zigbeestatu[18]== 0x05 || zigbeestatu[18]== 0x00)\n"
  1392. +" {\n"
  1393. +" HAL_UART_Transmit(&huart4, (uint8_t *)zigbeenotcon, sizeof(zigbeenotcon),10);\n"
  1394. +" }\n")
  1395. else:
  1396. pin_variables=""
  1397. pin_code=""
  1398. init_code=""
  1399. # 控制板燒錄:生成 main.c
  1400. @main.route('/creat_hex')
  1401. def creat_hex():
  1402. info = request.args.to_dict()
  1403. print("info: ", info)
  1404. # 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'}
  1405. # 'mainLength': '1', 'addLength': '0', 'comLength': '22', '
  1406. z_range = int(info['mainLength']) + 1
  1407. x_range = int(info['addLength']) + 1
  1408. y_range = int(info['comLength']) + 1
  1409. tank_num_data = info['tank_num']
  1410. # print("tank_num_data: ", tank_num_data)
  1411. cond_main_all_list = []
  1412. for z in range(1, z_range):
  1413. # 初始
  1414. cond_main_all_dict = {}
  1415. cond_add_list = [] # 附加條件 List
  1416. cond_com_list = [] # 物件動作 List
  1417. # cond_main_dict_all = {}
  1418. # cond_add_dict_all = {}
  1419. # cond_com_dict_all = {}
  1420. # print(z)
  1421. # 總條件
  1422. try:
  1423. cond_main_all_dict['cond_main'] = info['cond_main' + str(z)]
  1424. except(KeyError):
  1425. pass
  1426. # print("cond_main_dict: ", cond_main_dict)
  1427. # 附加條件
  1428. for x in range(1, x_range):
  1429. try:
  1430. cond_add_list.append(info['cond_add' + str(z) + '_' + str(x)])
  1431. except(KeyError):
  1432. pass
  1433. # print("cond_add_list: ", cond_add_list)
  1434. cond_main_all_dict['cond_add'] = cond_add_list
  1435. # print("cond_main_dict: ", cond_main_dict)
  1436. # 物件動作
  1437. for y in range(1, y_range):
  1438. try:
  1439. cond_com_list.append(info['cond_com' + str(z) + '_' + str(y)])
  1440. except(KeyError):
  1441. pass
  1442. # print("cond_com_list: ", cond_com_list)
  1443. cond_main_all_dict['cond_com'] = cond_com_list
  1444. # print("cond_main_dict: ", cond_main_dict)
  1445. if cond_com_list != []:
  1446. cond_main_all_list.append(cond_main_all_dict)
  1447. # cond_main_all_list.append(cond_add_dict_all)
  1448. # cond_main_all_list.append(cond_com_dict_all)
  1449. print("cond_main_all_list: ", cond_main_all_list)
  1450. # 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']}]
  1451. dry_block_sehedule = {'command':'Dry_OTA', 'tank_num':tank_num_data, 'cond':cond_main_all_list}
  1452. msg = dry_block_sehedule
  1453. # ===== 阿超 CTO.py 程式碼 start ========================================================================================
  1454. # msg = request.args.to_dict()
  1455. print("/creat_hex/<msg> msg: ", msg)
  1456. CURRENT_PATH = os.path.dirname(__file__)
  1457. print("CURRENT_PATH: ", CURRENT_PATH)
  1458. f = open(CURRENT_PATH + "//CTO20220622//Src//main.c", mode='w')
  1459. f.write("/* USER CODE BEGIN Header */\n"
  1460. +"/**\n"
  1461. +" ******************************************************************************\n"
  1462. +" * @file : main.c\n"
  1463. +" * @brief : Main program body\n"
  1464. +" * @attention\n"
  1465. +" *\n"
  1466. +" * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.\n"
  1467. +" * All rights reserved.</center></h2>\n"
  1468. +" *\n"
  1469. +" * This software component is licensed by ST under BSD 3-Clause license,\n"
  1470. +" * the License; You may not use this file except in compliance with the\n"
  1471. +" * License. You may obtain a copy of the License at:\n"
  1472. +" * www.st.com/SLA0044\n"
  1473. +" *\n"
  1474. +" ******************************************************************************\n"
  1475. +" */\n"
  1476. +"/* USER CODE END Header */\n"
  1477. +"\n"
  1478. +"/* Includes ------------------------------------------------------------------*/\n")
  1479. # 添加標題檔
  1480. header = ('#include"main.h"\n'
  1481. +'#include "adc.h"\n'
  1482. +'#include "usart.h"\n'
  1483. +'#include "i2c.h"\n'
  1484. +'#include "tim.h"\n'
  1485. +'#include "stm32f4xx_hal.h"\n'
  1486. +'#include "gpio.h"\n')
  1487. f.write(header)
  1488. # 變數宣告說明
  1489. f.write("\n"
  1490. + "/* Private variables ---------------------------------------------------------*/\n")
  1491. f.write("\n"
  1492. + "/* Private variables ---------------------------------------------------------*/\n"
  1493. + "#define VECT_TAB_OFFSET 0x10000\n"
  1494. + "int tankstatus = 0;\n")
  1495. # 連接資料庫
  1496. #conn = sqlite3.connect('/home/pi/coffee.db')
  1497. # conn = pymysql.connect(host="52.69.200.169", port=3306, user='coffeemanage', passwd='skyeye', database='CoffeeManage', charset='utf8')
  1498. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  1499. c = conn.cursor()
  1500. print("connect success")
  1501. # 搜尋最新腳位配置時間
  1502. c.execute("SELECT *from coffee1_0_pin ORDER BY datetime ASC")
  1503. results = c.fetchall()
  1504. for row in results:
  1505. time = row[1]
  1506. c.execute("SELECT *from coffee1_0_pin where datetime='%s'"\
  1507. %(time))
  1508. results=c.fetchall()
  1509. for row in results:
  1510. for i in range (19):
  1511. row[i+26]
  1512. if(row[5]=="ON"):
  1513. print("zigbee on")
  1514. zigbee(row[5])
  1515. f.write(pin_variables)
  1516. for i in range (19):
  1517. if(i==3 or i==4 or i==6):
  1518. PH("M"+str(i+1),row[i+26])
  1519. f.write(pin_variables)
  1520. DO("M"+str(i+1),row[i+26])
  1521. f.write(pin_variables)
  1522. ORP("M"+str(i+1),row[i+26])
  1523. f.write(pin_variables)
  1524. if(i==13 or i== 16):
  1525. SHT11("M"+str(i+1),row[i+26])
  1526. f.write(pin_variables)
  1527. if(i==13 or i== 15):
  1528. DS18B20("M"+str(i+1),row[i+26])
  1529. f.write(pin_variables)
  1530. if(i==14):
  1531. BMP280("M"+str(i+1),row[i+26])
  1532. f.write(pin_variables)
  1533. if(i==5 or i==12):
  1534. SEN0189("M"+str(i+1),row[i+26])
  1535. f.write(pin_variables)
  1536. if(i==0):
  1537. SonicESMUS07("M"+str(i+1),row[i+26])
  1538. f.write(pin_variables)
  1539. if(i==7):
  1540. SOIL("M"+str(i+1),row[i+26])
  1541. f.write(pin_variables)
  1542. if(i==8 or i==11 or i==18 or i==10):
  1543. WATERLEVEL("M"+str(i+1),row[i+26])
  1544. f.write(pin_variables)
  1545. motorfeedback("M"+str(i+1),row[i+26])
  1546. f.write(pin_variables)
  1547. butterflyvalvefeedback("M"+str(i+1),row[i+26])
  1548. f.write(pin_variables)
  1549. if(i==15):
  1550. EC("M"+str(i+1),row[i+26])
  1551. f.write(pin_variables)
  1552. #感測器和致動器副函式宣告----------------------------------------------------------------
  1553. f.write("/* USER CODE BEGIN PV */\n"
  1554. +"typedef void (*pFunction)(void);\n"
  1555. +"/* USER CODE END PV */\n"
  1556. +"/* Private function prototypes -----------------------------------------------*/\n"
  1557. +"void SystemClock_Config(void);\n"
  1558. +"void MX_ADC1_Init1(char pin);\n"
  1559. +"void sensor(void);\n")
  1560. #感測器和致動器副函式宣告----------------------------------------------------------------
  1561. #連接資料庫
  1562. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  1563. c = conn.cursor()
  1564. print ("connect success")
  1565. #搜尋最新腳位配置時間
  1566. c.execute("SELECT *from coffee1_0_pin ORDER BY datetime ASC")
  1567. results=c.fetchall()
  1568. for row in results:
  1569. time = row[1]
  1570. #腳位配置加入
  1571. c.execute("SELECT *from coffee1_0_pin where datetime='%s'"\
  1572. %(time))
  1573. results=c.fetchall()
  1574. for row in results:
  1575. for i in range (19):
  1576. row[i+26]
  1577. for i in range (19):
  1578. if(i==13 or i== 16):
  1579. SHT11("M"+str(i+1),row[i+26])
  1580. f.write(sensor_code)
  1581. if(i==13 or i== 15):
  1582. DS18B20("M"+str(i+1),row[i+26])
  1583. f.write(sensor_code)
  1584. if(i==14):
  1585. BMP280("M"+str(i+1),row[i+26])
  1586. f.write(sensor_code)
  1587. if(i==9):
  1588. motor("M"+str(i+1),row[i+26])
  1589. f.write(sensor_code)
  1590. f.write("/* USER CODE BEGIN PFP */\n"
  1591. +"/* USER CODE END PFP */\n"
  1592. +"/* Private user code ---------------------------------------------------------*/\n"
  1593. +"/* USER CODE BEGIN 0 */\n"
  1594. +"/* USER CODE END 0 */\n"
  1595. +"/**\n"
  1596. +"* @brief The application entry point.\n"
  1597. +"* @retval int\n"
  1598. +"*/\n")
  1599. #主程式撰寫--------------------------------------------------------------------------------
  1600. #main宣告
  1601. f.write("int main(void)\n"
  1602. +"{\n"
  1603. +" SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;\n")
  1604. #致能週邊---------------------------------------------------------------------------------------
  1605. enable=(" HAL_Init();\n"
  1606. +" SystemClock_Config();\n"
  1607. +" MX_GPIO_Init();\n"
  1608. +" MX_USART2_UART_Init();\n"
  1609. +" MX_UART4_Init();\n"
  1610. +" MX_USART1_UART_Init();\n")
  1611. f.write(enable)
  1612. #連接資料庫
  1613. # conn = pymysql.connect(host="52.69.200.169", port=3306, user='coffeemanage', passwd='skyeye', database='CoffeeManage', charset='utf8')
  1614. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  1615. #conn = sqlite3.connect('/home/pi/coffee.db')
  1616. c = conn.cursor()
  1617. print("connect success")
  1618. #搜尋最新腳位配置時間
  1619. c.execute("SELECT *from coffee1_0_pin ORDER BY datetime ASC")
  1620. results = c.fetchall()
  1621. for row in results:
  1622. time = row[1]
  1623. # 腳位配置加入
  1624. c.execute("SELECT *from coffee1_0_pin where datetime='%s'"
  1625. % (time))
  1626. results = c.fetchall()
  1627. for row in results:
  1628. for i in range(19):
  1629. row[i+26]
  1630. if(row[5]=="ON"):
  1631. print("zigbee on")
  1632. zigbee(row[5])
  1633. f.write(init_code)
  1634. for i in range (19):
  1635. if(i==14):
  1636. BMP280("M"+str(i+1),row[i+26])
  1637. f.write(init_code)
  1638. if(i==9):
  1639. motor("M"+str(i+1),row[i+26])
  1640. f.write(init_code)
  1641. #---------------------------------------------------------------------------------------------
  1642. code=(" while (1)\n"
  1643. +" {\n"
  1644. +" sensor();\n")
  1645. f.write(code)
  1646. #MQTT條件分析寫入--------------------------------------------------------------------------------
  1647. for i in range (len(msg['cond'])):
  1648. m=msg['cond'][i]['cond_main'].split(" ")
  1649. if(m[0]=="else" and m[1]=="if"):
  1650. m[0]=m[0]+" "+m[1]
  1651. m[1]=m[1]
  1652. m[2]=m[2]
  1653. m[3]=m[3]
  1654. m[4]=m[4]
  1655. m=""+m[0]+"("+m[1]+m[2]+m[3]
  1656. f.write(" "+m)
  1657. if(m[0] == " "):
  1658. m = ""
  1659. else:
  1660. print(len(msg['cond'][i]['cond_add']))
  1661. if(len(msg['cond'][i]['cond_add'])==0):
  1662. add=")\n"
  1663. f.write(add)
  1664. else:
  1665. for j in range (len(msg['cond'][i]['cond_add'])):
  1666. if(j==len(msg['cond'][i]['cond_add'])-1):
  1667. if(msg['cond'][i]['cond_add'][j]==" "):
  1668. add=")\n"
  1669. else:
  1670. add=" "+str(msg['cond'][i]['cond_add'][j])+")\n"
  1671. f.write(add)
  1672. else:
  1673. if(msg['cond'][i]['cond_add'][j]==" "):
  1674. add=""
  1675. else:
  1676. add=" "+str(msg['cond'][i]['cond_add'][j])
  1677. f.write(add)
  1678. f.write(" {\n")
  1679. for j in range(len(msg['cond'][i]['cond_com'])):
  1680. if(j == len(msg['cond'][i]['cond_com'])-1):
  1681. if(msg['cond'][i]['cond_com'][j] == " "):
  1682. com = "\n}\n"
  1683. else:
  1684. com = msg['cond'][i]['cond_com'][j].split("_")
  1685. comm = msg['cond'][i]['cond_com'][j].split(" ")
  1686. if(comm[0] == "sleep"):
  1687. com[0] = comm[0]
  1688. com = " "+GPIO(com[0], comm[1])+"\n }\n"
  1689. f.write(com)
  1690. else:
  1691. if(msg['cond'][i]['cond_com'][j] == " "):
  1692. com = ""
  1693. else:
  1694. com = msg['cond'][i]['cond_com'][j].split("_")
  1695. comm = msg['cond'][i]['cond_com'][j].split(" ")
  1696. if(comm[0] == "sleep"):
  1697. com[0] = comm[0]
  1698. com = " "+GPIO(com[0], comm[1])+"\n"
  1699. f.write(com)
  1700. f.write(" }\n")
  1701. f.write("}\n")
  1702. # 系統時鐘宣告
  1703. time = ("void SystemClock_Config(void)\n"
  1704. + "{\n"
  1705. + " RCC_OscInitTypeDef RCC_OscInitStruct = {0};\n"
  1706. + " RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};\n"
  1707. + " __HAL_RCC_PWR_CLK_ENABLE();\n"
  1708. + " __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);\n"
  1709. + " RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;\n"
  1710. + " RCC_OscInitStruct.HSIState = RCC_HSI_ON;\n"
  1711. + " RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;\n"
  1712. + " RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;\n"
  1713. + " RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;\n"
  1714. + " RCC_OscInitStruct.PLL.PLLM = 8;\n"
  1715. + " RCC_OscInitStruct.PLL.PLLN = 72;\n"
  1716. + " RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;\n"
  1717. + " RCC_OscInitStruct.PLL.PLLQ = 3;\n"
  1718. + " RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;\n"
  1719. + " if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)\n"
  1720. + " {\n"
  1721. + " Error_Handler();\n"
  1722. + " }\n"
  1723. + " RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK\n"
  1724. + " |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;\n"
  1725. + " RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;\n"
  1726. + " RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;\n"
  1727. + " RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;\n"
  1728. + " RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;\n"
  1729. + " if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)\n"
  1730. + " {\n"
  1731. + " Error_Handler();\n"
  1732. + " }\n"
  1733. + "}\n")
  1734. f.write(time)
  1735. #馬達和伺服馬達副函式------------------------------------------------------------------------------
  1736. add_code2=("void user_pwm_setvalue(uint16_t value)\n"
  1737. +"{\n"
  1738. +" TIM_OC_InitTypeDef sConfigOC;\n"
  1739. +" sConfigOC.OCMode = TIM_OCMODE_PWM1;\n"
  1740. +" sConfigOC.Pulse = value;\n"
  1741. +" sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;\n"
  1742. +" sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;\n"
  1743. +" HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);\n"
  1744. +" HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);\n"
  1745. +"}\n"
  1746. +"void user_pwm_setvalue2(uint16_t value)\n"
  1747. +"{\n"
  1748. +" TIM_OC_InitTypeDef sConfigOC;\n"
  1749. +" sConfigOC.OCMode = TIM_OCMODE_PWM1;\n"
  1750. +" sConfigOC.Pulse = value;\n"
  1751. +" sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;\n"
  1752. +" sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;\n"
  1753. +" HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);\n"
  1754. +" HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);\n"
  1755. +"}\n")
  1756. f.write(add_code2)
  1757. #感測器程式-----------------------------------------------------------------------------------------------------
  1758. sensor=("void sensor(void)\n"
  1759. +"{\n")
  1760. f.write(sensor)
  1761. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  1762. #conn = sqlite3.connect('/home/pi/coffee.db')
  1763. c = conn.cursor()
  1764. print ("connect success")
  1765. #搜尋最新腳位配置時間
  1766. c.execute("SELECT *from coffee1_0_pin ORDER BY datetime ASC")
  1767. results = c.fetchall()
  1768. for row in results:
  1769. time = row[1]
  1770. #腳位配置加入
  1771. c.execute("SELECT *from coffee1_0_pin where datetime='%s'"\
  1772. %(time))
  1773. results = c.fetchall()
  1774. for row in results:
  1775. for i in range (19):
  1776. row[i+26]
  1777. if(row[5]=="ON"):
  1778. print("zigbee on")
  1779. zigbee(row[5])
  1780. f.write(pin_code)
  1781. for i in range (19):
  1782. if(i==3 or i==4 or i==6):
  1783. PH("M"+str(i+1),row[i+26])
  1784. f.write(pin_code)
  1785. DO("M"+str(i+1),row[i+26])
  1786. f.write(pin_code)
  1787. ORP("M"+str(i+1),row[i+26])
  1788. f.write(pin_code)
  1789. if(i==13 or i== 16):
  1790. SHT11("M"+str(i+1),row[i+26])
  1791. f.write(pin_code)
  1792. if(i==13 or i== 15):
  1793. DS18B20("M"+str(i+1),row[i+26])
  1794. f.write(pin_code)
  1795. if(i==14):
  1796. BMP280("M"+str(i+1),row[i+26])
  1797. f.write(pin_code)
  1798. if(i==5 or i==12):
  1799. SEN0189("M"+str(i+1),row[i+26])
  1800. f.write(pin_code)
  1801. if(i==0):
  1802. SonicESMUS07("M"+str(i+1),row[i+26])
  1803. f.write(pin_code)
  1804. if(i==7):
  1805. SOIL("M"+str(i+1),row[i+26])
  1806. f.write(pin_code)
  1807. if(i==8 or i==11 or i==18 or i==10):
  1808. WATERLEVEL("M"+str(i+1),row[i+26])
  1809. f.write(pin_code)
  1810. motorfeedback("M"+str(i+1),row[i+26])
  1811. f.write(pin_code)
  1812. butterflyvalvefeedback("M"+str(i+1),row[i+26])
  1813. f.write(pin_code)
  1814. if(i==15):
  1815. EC("M"+str(i+1),row[i+26])
  1816. f.write(pin_code)
  1817. sensor=(" HAL_Delay(10000);\n"
  1818. +"}\n")
  1819. f.write(sensor)
  1820. #加入感測器副函式程式碼-------------------------------------------------------------------------------
  1821. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='Gold@53743001', database='CoffeeManage', charset='utf8')
  1822. c = conn.cursor()
  1823. print ("connect success")
  1824. #搜尋最新腳位配置時間
  1825. c.execute("SELECT *from coffee1_0_pin ORDER BY datetime ASC")
  1826. results = c.fetchall()
  1827. for row in results:
  1828. time = row[1]
  1829. #腳位配置加入
  1830. c.execute("SELECT *from coffee1_0_pin where datetime='%s'"\
  1831. %(time))
  1832. results = c.fetchall()
  1833. for row in results:
  1834. for i in range (19):
  1835. row[i+26]
  1836. for i in range (19):
  1837. if(i==13 or i== 16):
  1838. SHT11("M"+str(i+1),row[i+26])
  1839. f.write(pin_add_code)
  1840. if(i==13 or i== 15):
  1841. DS18B20("M"+str(i+1),row[i+26])
  1842. f.write(pin_add_code)
  1843. if(i==14):
  1844. BMP280("M"+str(i+1),row[i+26])
  1845. f.write(pin_add_code)
  1846. if(i==0):
  1847. SonicESMUS07("M"+str(i+1),row[i+26])
  1848. f.write(pin_add_code)
  1849. if(i==7):
  1850. SOIL("M"+str(i+1),row[i+26])
  1851. f.write(pin_add_code)
  1852. if(i==15):
  1853. EC("M"+str(i+1),row[i+26])
  1854. f.write(pin_add_code)
  1855. #ADC程式宣告----------------------------------------------------------------------------------
  1856. gpio=("void MX_ADC1_Init1(char pin)\n"
  1857. +"{\n"
  1858. +" ADC_ChannelConfTypeDef sConfig = {0};\n"
  1859. +" hadc1.Instance = ADC1;\n"
  1860. +" hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;\n"
  1861. +" hadc1.Init.Resolution = ADC_RESOLUTION_12B;\n"
  1862. +" hadc1.Init.ScanConvMode = DISABLE;\n"
  1863. +" hadc1.Init.ContinuousConvMode = DISABLE;\n"
  1864. +" hadc1.Init.DiscontinuousConvMode = DISABLE;\n"
  1865. +" hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;\n"
  1866. +" hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;\n"
  1867. +" hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;\n"
  1868. +" hadc1.Init.NbrOfConversion = 1;\n"
  1869. +" hadc1.Init.DMAContinuousRequests = DISABLE;\n"
  1870. +" hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;\n"
  1871. +" if (HAL_ADC_Init(&hadc1) != HAL_OK)\n"
  1872. +" {\n"
  1873. +" Error_Handler();\n"
  1874. +" }\n"
  1875. +" sConfig.Channel = pin;\n"
  1876. +" sConfig.Rank = 1;\n"
  1877. +" sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;\n"
  1878. +" if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)\n"
  1879. +" {\n"
  1880. +" Error_Handler();\n"
  1881. +" }\n"
  1882. +"}\n")
  1883. f.write(gpio)
  1884. #GPIO input程式宣告----------------------------------------------------------------------------------
  1885. gpio2=("void MX_GPIO_Input1(unsigned long pin)\n"
  1886. +"{\n"
  1887. +" GPIO_InitTypeDef GPIO_InitStruct = {0};\n"
  1888. +" __HAL_RCC_GPIOE_CLK_ENABLE();\n"
  1889. +" GPIO_InitStruct.Pin = pin;\n"
  1890. +" GPIO_InitStruct.Mode = GPIO_MODE_INPUT;\n"
  1891. +" GPIO_InitStruct.Pull = GPIO_PULLDOWN;\n"
  1892. +" HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);\n"
  1893. +"}\n")
  1894. f.write(gpio2)
  1895. #錯誤程式-------------------------------------------------------------------------------------
  1896. f.write("void Error_Handler(void)\n{\n}\n")
  1897. f.close()
  1898. f = open(CURRENT_PATH + "//CTO20220622//Src//main.c", mode='r')
  1899. words = f.read()
  1900. # print(words)
  1901. f.close()
  1902. # server_log(msg['command'], "D1", "ok") # 06/15 Rita 原為阿超丟 MQTT 給網頁, 先註解
  1903. # ===== 阿超 CTO.py 程式碼 end ========================================================================================
  1904. # ===== 編譯 CTO20220622整個資料夾並在build資料夾生成所需的hex檔 start ========================
  1905. cwdDATA = os.path.join(CURRENT_PATH, "CTO20220622")
  1906. print("cwdDATA: ", cwdDATA)
  1907. # 以下指令要在 Linux 上測試, Windows 未安裝會報錯
  1908. # make_result = 0
  1909. make_result = subprocess.call(["sudo", "make"],cwd = cwdDATA)
  1910. # ===== 編譯 CTO20220622整個資料夾並在build資料夾生成所需的hex檔 end ========================
  1911. if make_result == 0:
  1912. return "OK"
  1913. else:
  1914. return "NG"
  1915. #
  1916. @main.route('/loader', methods=['GET', 'POST'])
  1917. def loader():
  1918. info = request.args.to_dict()
  1919. # print("info: ", info)
  1920. ethernet_list = info['ethernet_list']
  1921. print("ethernet_list: ", ethernet_list, type(ethernet_list))
  1922. wifi_list = info['wifi_list']
  1923. print("wifi_list: ", wifi_list, type(wifi_list))
  1924. zigbee_list = info['zigbee_list']
  1925. print("zigbee_list: ", zigbee_list, type(zigbee_list))
  1926. # 將 string 以 , 分割成 list
  1927. relay_list = info['relay_list'].split(',')
  1928. print("relay_list: ", relay_list, type(relay_list))
  1929. pwm_list = info['pwm_list'].split(',')
  1930. print("pwm_list: ", pwm_list, type(pwm_list))
  1931. digital_list = info['digital_list'].split(',')
  1932. print("digital_list: ", digital_list, type(digital_list))
  1933. uart_list = info['uart_list'].split(',')
  1934. print("uart_list: ", uart_list, type(uart_list))
  1935. i2c_list = info['i2c_list'].split(',')
  1936. print("i2c_list: ", i2c_list, type(i2c_list))
  1937. s485_list = info['s485_list'].split(',')
  1938. print("s485_list: ", s485_list, type(s485_list))
  1939. ppa_list = info['ppa_list'].split(',')
  1940. print("ppa_list: ", ppa_list, type(ppa_list))
  1941. return jsonify({"response":"OK" })
  1942. # # Rita 測試
  1943. @main.route('/drop_down_list')
  1944. def drop_down_list():
  1945. # 獲取登入信息
  1946. if 'id' in session and 'uname' in session and 'status' in session:
  1947. username = session['uname']
  1948. status = session['status']
  1949. if status == 9:
  1950. return render_template('signin_disable.html')
  1951. elif status == 8:
  1952. return render_template('signin_new.html')
  1953. # TODO
  1954. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  1955. password='skyeye', database='Coffee', charset='utf8')
  1956. mycursor = mydb.cursor()
  1957. conn = pymysql.connect(
  1958. host='52.69.200.169',
  1959. port=3306,
  1960. user='coffee',
  1961. password='skyeye',
  1962. database='Coffee',
  1963. charset='utf8'
  1964. )
  1965. cur = conn.cursor()
  1966. #獲取欄位資料
  1967. sql = "select * from product_info"
  1968. cur.execute(sql)
  1969. content = cur.fetchall()
  1970. #獲取欄位名稱
  1971. sql = "SHOW FIELDS FROM product_info"
  1972. cur.execute(sql)
  1973. labels = cur.fetchall()
  1974. # print("labels: ", labels) # labels: (('產品', 'varchar(4)', 'YES', '', None, ''), ('系統', 'varchar(5)', 'YES', '', None, ''),
  1975. labels = [g[0] for g in labels]
  1976. # print("labels: ", labels) # labels: ['產品', '系統', '系統圖號', '狀態', '進貨狀態', '序號', '組序號',
  1977. return render_template('drop_down_list.html', labels=labels, content=content)
  1978. else:
  1979. return render_template('sign_in.html')
  1980. # !!! AttributeError: 'NoneType' object has no attribute 'vacuum'
  1981. @main.route('/loading/container', methods=['GET', 'POST'])
  1982. def container_loading():
  1983. if request.method == 'GET':
  1984. # 清洗浮選狀態
  1985. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  1986. Clean_container_status_list = [clean_status.Clean_Tank_1,
  1987. clean_status.Clean_Tank_2,
  1988. clean_status.Clean_Tank_3,
  1989. clean_status.Clean_Tank_4]
  1990. CLEAN_Waiting_number = int(Clean_container_status_list.count('C_Waiting'))
  1991. CLEAN_Warning_number = int(Clean_container_status_list.count('C_Warning'))
  1992. if CLEAN_Waiting_number == len(Clean_container_status_list): Clean_container = 'Waiting'
  1993. elif CLEAN_Warning_number >= 1: Clean_container = 'Warning'
  1994. else: Clean_container = 'Working'
  1995. # 清洗浮選狀態
  1996. ColorSelect_container_status_list = [clean_status.ColorSelect_Tank_1,
  1997. clean_status.ColorSelect_Tank_2]
  1998. COLORSELECT_Waiting_number = int(ColorSelect_container_status_list.count('S_Waiting'))
  1999. COLORSELECT_Warning_number = int(ColorSelect_container_status_list.count('S_Warning'))
  2000. if COLORSELECT_Waiting_number == len(ColorSelect_container_status_list): ColorSelect_container = 'Waiting'
  2001. elif COLORSELECT_Warning_number >= 1: ColorSelect_container = 'Warning'
  2002. else: ColorSelect_container = 'Working'
  2003. # 脫皮機
  2004. Peel_container_status_list = [clean_status.Peel_Tank_1,
  2005. clean_status.Peel_Tank_2]
  2006. PEEL_Waiting_number = int(Peel_container_status_list.count('P_Waiting'))
  2007. PEEL_Warning_number = int(Peel_container_status_list.count('P_Warning'))
  2008. if PEEL_Waiting_number == len(Peel_container_status_list): Peel_container = 'Waiting'
  2009. elif PEEL_Warning_number >= 1: Peel_container = 'Warning'
  2010. else: Peel_container = 'Working'
  2011. # 發酵槽
  2012. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2013. Ferment_container_status_list = [ferment_status.Ferment_Tank_1,
  2014. ferment_status.Ferment_Tank_2,
  2015. ferment_status.Ferment_Tank_3,
  2016. ferment_status.Ferment_Tank_4,
  2017. ferment_status.Ferment_Tank_5,
  2018. ferment_status.Ferment_Tank_6,
  2019. ferment_status.Ferment_Tank_7,
  2020. ferment_status.Ferment_Tank_8,
  2021. ferment_status.Ferment_Tank_9,
  2022. ferment_status.Ferment_Tank_10,
  2023. ferment_status.Ferment_Tank_11,
  2024. ferment_status.Ferment_Tank_12]
  2025. FERMENT_Waiting_number = int(Ferment_container_status_list.count('F_Waiting'))
  2026. FERMENT_Warning_number = int(Ferment_container_status_list.count('F_Warning'))
  2027. if FERMENT_Waiting_number == len(Ferment_container_status_list): Ferment_container = 'Waiting'
  2028. elif FERMENT_Warning_number >= 1: Ferment_container = 'Warning'
  2029. else: Ferment_container = 'Working'
  2030. # 乾燥槽
  2031. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2032. Dry_container_status_list = [dry_status.Dry_Tank_1,
  2033. dry_status.Dry_Tank_2,
  2034. dry_status.Dry_Tank_3,
  2035. dry_status.Dry_Tank_4,
  2036. dry_status.Dry_Tank_5,
  2037. dry_status.Dry_Tank_6,
  2038. dry_status.Dry_Tank_7,
  2039. dry_status.Dry_Tank_8,
  2040. dry_status.Dry_Tank_9,
  2041. dry_status.Dry_Tank_10,
  2042. dry_status.Dry_Tank_11,
  2043. dry_status.Dry_Tank_12]
  2044. DRY_Waiting_number= int(Dry_container_status_list.count('D_Waiting'))
  2045. DRY_Warning_number= int(Dry_container_status_list.count('D_Warning'))
  2046. if DRY_Waiting_number == len(Dry_container_status_list): Dry_container = 'Waiting'
  2047. elif DRY_Warning_number >= 1: Dry_container = 'Warning'
  2048. else: Dry_container = 'Working'
  2049. return jsonify({"Clean_container":Clean_container,
  2050. "ColorSelect_container":ColorSelect_container,
  2051. "Peel_container":Peel_container,
  2052. "Ferment_container":Ferment_container,
  2053. "Dry_container":Dry_container
  2054. })
  2055. @main.route('/loading_sensors', methods=['GET', 'POST'])
  2056. def loading_sensors():
  2057. C1_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C1').order_by(text('datetime desc')).first()).UltraSonic
  2058. C2_UltraSonic = (clean_tank_UltraSonic.query.filter_by(tank_num='C2').order_by(text('datetime desc')).first()).UltraSonic
  2059. PO1_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO1').order_by(text('datetime desc')).first()).UltraSonic
  2060. PO2_UltraSonic = (peel_output_UltraSonic.query.filter_by(tank_num='PO2').order_by(text('datetime desc')).first()).UltraSonic
  2061. F1_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).UltraSonic
  2062. F1_SHT11Temp = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Temp
  2063. F1_SHT11Humidity = (ferment_tank_SHT11.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()).SHT11_Humidity
  2064. F2_UltraSonic = (ferment_tank_UltraSonic.query.filter_by(tank_num='F2').order_by(text('datetime desc')).first()).UltraSonic
  2065. D1_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).UltraSonic
  2066. D1_SHT11Temp = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Temp
  2067. D1_SHT11Humidity = (dry_tank_SHT11.query.filter_by(tank_num='D1').order_by(text('datetime desc')).first()).SHT11_Humidity
  2068. D2_UltraSonic = (dry_tank_UltraSonic.query.filter_by(tank_num='D2').order_by(text('datetime desc')).first()).UltraSonic
  2069. DO1_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()).UltraSonic
  2070. DO2_UltraSonic = (dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()).UltraSonic
  2071. return jsonify({"C1_UltraSonic":C1_UltraSonic,
  2072. "C2_UltraSonic":C2_UltraSonic,
  2073. "PO1_UltraSonic":PO1_UltraSonic,
  2074. "PO2_UltraSonic":PO2_UltraSonic,
  2075. "F1_UltraSonic":F1_UltraSonic,
  2076. "F1_SHT11Temp":F1_SHT11Temp,
  2077. "F1_SHT11Humidity":F1_SHT11Humidity,
  2078. "F2_UltraSonic":F2_UltraSonic,
  2079. "D1_UltraSonic":D1_UltraSonic,
  2080. "D1_SHT11Temp":D1_SHT11Temp,
  2081. "D1_SHT11Humidity":D1_SHT11Humidity,
  2082. "D2_UltraSonic":D2_UltraSonic,
  2083. "DO1_UltraSonic":DO1_UltraSonic,
  2084. "DO2_UltraSonic":DO2_UltraSonic
  2085. })
  2086. @main.route('/demo', methods=['GET', 'POST'])
  2087. def demo():
  2088. if 'id' in session and 'uname' in session and 'status' in session:
  2089. username = session['uname']
  2090. status = session['status']
  2091. if status == 9:
  2092. return render_template('signin_disable.html')
  2093. elif status == 8:
  2094. return render_template('signin_new.html')
  2095. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2096. CI1 = clean_status.Clean_Input_1
  2097. CI2 = clean_status.Clean_Input_2
  2098. C1 = clean_status.Clean_Tank_1
  2099. C2 = clean_status.Clean_Tank_2
  2100. R1 = clean_status.Reclaimed_Tank_1
  2101. S1 = clean_status.ColorSelect_Tank_1
  2102. S2 = clean_status.ColorSelect_Tank_2
  2103. SOg1 = clean_status.ColorSelect_Output_g1
  2104. SOb1 = clean_status.ColorSelect_Output_b1
  2105. SOg2 = clean_status.ColorSelect_Output_g2
  2106. SOb2 = clean_status.ColorSelect_Output_b2
  2107. P1 = clean_status.Peel_Tank_1
  2108. P2 = clean_status.Peel_Tank_2
  2109. PO1 = clean_status.Peel_Output_1
  2110. PO2 = clean_status.Peel_Output_2
  2111. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2112. F1 = ferment_status.Ferment_Tank_1
  2113. F2 = ferment_status.Ferment_Tank_2
  2114. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2115. D1 = dry_status.Dry_Tank_1
  2116. D2 = dry_status.Dry_Tank_2
  2117. DO1 = dry_status.Dry_Output_1
  2118. DO2 = dry_status.Dry_Output_2
  2119. POb1 = clean_status.Peel_Output_b1
  2120. return render_template('demo.html', title="[測試] DEMO 貨櫃自動化", **locals())
  2121. else:
  2122. return render_template('sign_in.html')
  2123. @main.route('/demo_auto', methods=['GET', 'POST'])
  2124. def demo_auto():
  2125. if 'id' in session and 'uname' in session and 'status' in session:
  2126. username = session['uname']
  2127. status = session['status']
  2128. if status == 9:
  2129. return render_template('signin_disable.html')
  2130. elif status == 8:
  2131. return render_template('signin_new.html')
  2132. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2133. CI1 = clean_status.Clean_Input_1
  2134. CI2 = clean_status.Clean_Input_2
  2135. C1 = clean_status.Clean_Tank_1
  2136. C2 = clean_status.Clean_Tank_2
  2137. # 中水桶
  2138. S1 = clean_status.ColorSelect_Tank_1
  2139. S2 = clean_status.ColorSelect_Tank_2
  2140. SOg1 = clean_status.ColorSelect_Output_g1
  2141. SOb1 = clean_status.ColorSelect_Output_b1
  2142. SOg2 = clean_status.ColorSelect_Output_g2
  2143. SOb2 = clean_status.ColorSelect_Output_b2
  2144. P1 = clean_status.Peel_Tank_1
  2145. P2 = clean_status.Peel_Tank_2
  2146. PO1 = clean_status.Peel_Output_1
  2147. PO2 = clean_status.Peel_Output_2
  2148. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2149. F1 = ferment_status.Ferment_Tank_1
  2150. F2 = ferment_status.Ferment_Tank_2
  2151. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2152. D1 = dry_status.Dry_Tank_1
  2153. D2 = dry_status.Dry_Tank_2
  2154. DO1 = dry_status.Dry_Output_1
  2155. DO2 = dry_status.Dry_Output_2
  2156. POb1 = clean_status.Peel_Output_b1
  2157. return render_template('demo_auto.html', title="[測試] DEMO 貨櫃自動化", **locals())
  2158. else:
  2159. return render_template('sign_in.html')
  2160. # 脫皮機自動化測試頁
  2161. @main.route('/peel_auto_status', methods=['GET', 'POST'])
  2162. def peel_auto_test():
  2163. info = request.args.to_dict()
  2164. # 寫定出料的空桶標準, 若 <= 2 則為空桶
  2165. Peel_Output_bean_empty = 2
  2166. # 從介面取得 指定生豆高度
  2167. Peel_Tank_bean_height = float(info['Peel_Tank_bean_height'])
  2168. Peel_Tank_motor_rpm = float(info['Peel_Tank_motor_rpm'])
  2169. Peel_Tank_vacuumON_time = float(info['Peel_Tank_vacuumON_time'])
  2170. Peel_Tank_vacuumOFF_time = float(info['Peel_Tank_vacuumOFF_time'])
  2171. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  2172. P1 = clean_status.Peel_Tank_1
  2173. P2 = clean_status.Peel_Tank_2
  2174. PO1 = clean_status.Peel_Output_1
  2175. PO2 = clean_status.Peel_Output_2
  2176. SO1 = 'SO_OutputtingBean' # SO_OutputtingBean SO_Waiting
  2177. SO2 = 'SO_Waiting'
  2178. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  2179. PO_UP_tank_UltraSonic = []
  2180. for i in range(1, 3, 1):
  2181. output_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='PO' + str(i)).order_by(text('datetime desc')).first()
  2182. UltraSonic = float(output_UltraSonic.UltraSonic)
  2183. PO_UP_tank_UltraSonic.append(UltraSonic)
  2184. print('PO_UP_tank_UltraSonic: ', PO_UP_tank_UltraSonic)
  2185. # -- 取得脫皮機 P1~P2 桶內高度 UltraSonic -------------
  2186. if P1 == 'P_Waiting' and PO1 != 'PO_OutputtingBean' and SO1 == 'SO_OutputtingBean':
  2187. P1 = 'P_Peeling'
  2188. PO1 = 'PO_InputtingBean'
  2189. print('------- P1 狀態更新:脫皮中 -------')
  2190. print('------- PO1 狀態更新:入豆中 -------')
  2191. # [致動器] 馬達 指定轉速
  2192. data = { "tank_num": "P1", "command": "tank_motor_status", "value": Peel_Tank_motor_rpm}
  2193. print('data: ', data)
  2194. # mqtt_f(data)
  2195. if P1 == 'P_Peeling':
  2196. if PO_UP_tank_UltraSonic[0] >= Peel_Tank_bean_height:
  2197. # [致動器] 真空吸料機 OFF
  2198. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  2199. print('data: ', data)
  2200. # mqtt_f(data)
  2201. # [致動器] 馬達 0
  2202. data = { "tank_num": "P1", "command": "tank_motor_status", "value": "0" }
  2203. print('data: ', data)
  2204. # mqtt_f(data)
  2205. P1 = 'P_Waiting'
  2206. PO1 = 'PO_OutputtingBean'
  2207. print('------- P1 狀態更新:等待中 -------')
  2208. print('------- PO1 狀態更新:可出豆 -------')
  2209. elif PO_UP_tank_UltraSonic[0] < Peel_Tank_bean_height:
  2210. # [致動器] 真空吸料機 ON
  2211. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "on" }
  2212. print('data: ', data)
  2213. # mqtt_f(data)
  2214. timer = time.time()
  2215. while True:
  2216. if (time.time() - timer) > Peel_Tank_vacuumON_time:
  2217. # [致動器] 真空吸料機 OFF
  2218. data = { "tank_num": "P1", "command": "tank_vacuum_status", "value": "off" }
  2219. print('data: ', data)
  2220. # mqtt_f(data)
  2221. timer = time.time()
  2222. break
  2223. while True:
  2224. if (time.time() - timer) > Peel_Tank_vacuumOFF_time:
  2225. break
  2226. if PO1 == 'PO_OutputtingBean' and PO_UP_tank_UltraSonic[0] <= Peel_Output_bean_empty:
  2227. PO1 = 'PO_Waiting'
  2228. print('------- PO1 狀態更新:空桶等待 -------')
  2229. CI1 = 'CI_Warning'
  2230. CI2 = 'CI_Waiting'
  2231. C1 = 'C_Warning'
  2232. C2 = 'C_Waiting'
  2233. C3 = 'C_Waiting'
  2234. C4 = 'C_Waiting'
  2235. SI1 = 'SI_Warning'
  2236. SI2 = 'SI_Waiting'
  2237. S1 = 'S_Warning'
  2238. S2 = 'S_Waiting'
  2239. SOg1 = 'SO_Warning'
  2240. SOb1 = 'SO_Warning'
  2241. SOg2 = 'SO_Waiting'
  2242. SOb2 = 'SO_Waiting'
  2243. POb1 = 'PO_Waiting'
  2244. # ----- 將狀態寫入資料庫 ------------------------------
  2245. # 獲取文本框的值並賦值給user實體對象
  2246. C_status = clean_container_status()
  2247. C_status.Clean_Input_1 = CI1
  2248. C_status.Clean_Input_2 = CI2
  2249. C_status.Clean_Tank_1 = C1
  2250. C_status.Clean_Tank_2 = C2
  2251. C_status.Clean_Tank_3 = C3
  2252. C_status.Clean_Tank_4 = C4
  2253. C_status.ColorSelect_Input_1 = SI1
  2254. C_status.ColorSelect_Input_2 = SI2
  2255. C_status.ColorSelect_Tank_1 = S1
  2256. C_status.ColorSelect_Tank_2 = S2
  2257. C_status.ColorSelect_Output_g1 = SOg1
  2258. C_status.ColorSelect_Output_b1 = SOb1
  2259. C_status.ColorSelect_Output_g2 = SOg2
  2260. C_status.ColorSelect_Output_b2 = SOb2
  2261. C_status.Peel_Tank_1 = P1
  2262. C_status.Peel_Tank_2 = P2
  2263. C_status.Peel_Output_1 = PO1
  2264. C_status.Peel_Output_2 = PO2
  2265. C_status.Peel_Output_b1 = POb1
  2266. #將數據保存進資料庫
  2267. db.session.add(C_status)
  2268. # 手動提交
  2269. db.session.commit()
  2270. # ----- 將狀態寫入資料庫 ------------------------------
  2271. return jsonify({"Peel_Tank_1":P1,
  2272. "Peel_Tank_2":P2,
  2273. "Peel_Output_1":PO1,
  2274. "Peel_Output_2":PO2
  2275. })
  2276. # 乾燥槽狀態更新
  2277. @main.route('/dry_status_update', methods=['GET', 'POST'])
  2278. def dry_status_update():
  2279. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2280. DI1 = dry_status.Dry_Input_1
  2281. DI2 = dry_status.Dry_Input_2
  2282. D1 = dry_status.Dry_Tank_1
  2283. D2 = dry_status.Dry_Tank_2
  2284. D3 = dry_status.Dry_Tank_3
  2285. D4 = dry_status.Dry_Tank_4
  2286. D5 = dry_status.Dry_Tank_5
  2287. D6 = dry_status.Dry_Tank_6
  2288. D7 = dry_status.Dry_Tank_7
  2289. D8 = dry_status.Dry_Tank_8
  2290. D9 = dry_status.Dry_Tank_9
  2291. D10 = dry_status.Dry_Tank_10
  2292. D11 = dry_status.Dry_Tank_11
  2293. D12 = dry_status.Dry_Tank_12
  2294. DO1 = dry_status.Dry_Output_1
  2295. DO2 = dry_status.Dry_Output_2
  2296. return jsonify({"DI1":DI1,
  2297. "DI2":DI2,
  2298. "D1":D1,
  2299. "D2":D2,
  2300. "D3":D3,
  2301. "D4":D4,
  2302. "D5":D5,
  2303. "D6":D6,
  2304. "D7":D7,
  2305. "D8":D8,
  2306. "D9":D9,
  2307. "D10":D10,
  2308. "D11":D11,
  2309. "D12":D12,
  2310. "DO1":DO1,
  2311. "DO2":DO2
  2312. })
  2313. # 乾燥槽自動化測試頁
  2314. @main.route('/dry_auto', methods=['GET', 'POST'])
  2315. def dry_auto():
  2316. # 獲取登入信息
  2317. if 'id' in session and 'uname' in session and 'status' in session:
  2318. username = session['uname']
  2319. status = session['status']
  2320. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2321. DI1 = dry_status.Dry_Input_1
  2322. DI2 = dry_status.Dry_Input_2
  2323. D1 = dry_status.Dry_Tank_1
  2324. D2 = dry_status.Dry_Tank_2
  2325. D3 = dry_status.Dry_Tank_3
  2326. D4 = dry_status.Dry_Tank_4
  2327. D5 = dry_status.Dry_Tank_5
  2328. D6 = dry_status.Dry_Tank_6
  2329. D7 = dry_status.Dry_Tank_7
  2330. D8 = dry_status.Dry_Tank_8
  2331. D9 = dry_status.Dry_Tank_9
  2332. D10 = dry_status.Dry_Tank_10
  2333. D11 = dry_status.Dry_Tank_11
  2334. D12 = dry_status.Dry_Tank_12
  2335. DO1 = dry_status.Dry_Output_1
  2336. DO2 = dry_status.Dry_Output_2
  2337. return render_template('dry_auto.html', title="[測試] 乾燥自動化", **locals())
  2338. else:
  2339. return render_template('sign_in.html')
  2340. # 乾燥槽 乾燥暫停 出料
  2341. @main.route('/dryDEMO_outputtingBean', methods=['GET', 'POST'])
  2342. def dryDEMO_outputtingBean():
  2343. info = request.args.to_dict()
  2344. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  2345. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  2346. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  2347. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2348. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  2349. DI2 = dry_status.Dry_Input_2
  2350. D1 = dry_status.Dry_Tank_1
  2351. D2 = dry_status.Dry_Tank_2
  2352. D3 = dry_status.Dry_Tank_3
  2353. D4 = dry_status.Dry_Tank_4
  2354. D5 = dry_status.Dry_Tank_5
  2355. D6 = dry_status.Dry_Tank_6
  2356. D7 = dry_status.Dry_Tank_7
  2357. D8 = dry_status.Dry_Tank_8
  2358. D9 = dry_status.Dry_Tank_9
  2359. D10 = dry_status.Dry_Tank_10
  2360. D11 = dry_status.Dry_Tank_11
  2361. D12 = dry_status.Dry_Tank_12
  2362. DO1 = dry_status.Dry_Output_1
  2363. DO2 = dry_status.Dry_Output_2
  2364. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2365. # DO_UP_UltraSoniclist = []
  2366. # for i in range(1, 3, 1):
  2367. # output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  2368. # UltraSonic = float(output_UltraSonic.UltraSonic)
  2369. # DO_UP_UltraSoniclist.append(UltraSonic)
  2370. # print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  2371. # # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2372. # 將桶槽 D1 狀態轉換成可出豆, DO1 狀態轉換成可入豆
  2373. D1 = 'D_OutputtingBean'
  2374. # [致動器] 設定溫度 0.0
  2375. data = { "tank_num": "D1", "command": "tank_temp", "value": "0.0" }
  2376. print('data: ', data)
  2377. # mqtt_f(data)
  2378. # [致動器] 溫控開關 OFF
  2379. data = { "tank_num": "D1", "command": "tank_temp_enable", "value": "off" }
  2380. print('data: ', data)
  2381. # mqtt_f(data)
  2382. # [致動器] 馬達 0
  2383. data = { "tank_num": "D1", "command": "tank_motor_status", "value": "0" }
  2384. print('data: ', data)
  2385. # mqtt_f(data)
  2386. # [致動器] 排水電磁閥 OFF
  2387. data = { "tank_num": "D1", "command": "tank_solenoid_water_out_status", "value": "off" }
  2388. print('data: ', data)
  2389. # mqtt_f(data)
  2390. # [致動器] D1 蝴蝶閥 ON
  2391. data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "on" }
  2392. print('data: ', data)
  2393. # mqtt_f(data)
  2394. # ----- 將狀態寫入資料庫 ------------------------------
  2395. # 獲取文本框的值並賦值給user實體對象
  2396. D_status = dry_container_status()
  2397. D_status.Dry_Input_1 = DI1
  2398. D_status.Dry_Input_2 = DI2
  2399. D_status.Dry_Tank_1 = D1
  2400. D_status.Dry_Tank_2 = D2
  2401. D_status.Dry_Tank_3 = D3
  2402. D_status.Dry_Tank_4 = D4
  2403. D_status.Dry_Tank_5 = D5
  2404. D_status.Dry_Tank_6 = D6
  2405. D_status.Dry_Tank_7 = D7
  2406. D_status.Dry_Tank_8 = D8
  2407. D_status.Dry_Tank_9 = D9
  2408. D_status.Dry_Tank_10 = D10
  2409. D_status.Dry_Tank_11 = D11
  2410. D_status.Dry_Tank_12 = D12
  2411. D_status.Dry_Output_1 = DO1
  2412. D_status.Dry_Output_2 = DO2
  2413. #將數據保存進資料庫
  2414. db.session.add(D_status)
  2415. # 手動提交
  2416. db.session.commit()
  2417. # ----- 將狀態寫入資料庫 ------------------------------
  2418. return jsonify({"Dry_Tank_1":D1,
  2419. "Dry_Tank_2":D2,
  2420. "Dry_Output_1":DO1,
  2421. "Dry_Output_2":DO2
  2422. })
  2423. @main.route('/dryDEMO_auto_status', methods=['GET', 'POST'])
  2424. def dryDEMO_auto_status():
  2425. info = request.args.to_dict()
  2426. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2427. Dry_Tank_bean_empty = 2
  2428. Dry_Output_bean_empty = 2
  2429. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  2430. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  2431. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  2432. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  2433. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  2434. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  2435. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  2436. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  2437. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  2438. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  2439. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  2440. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_timef'])
  2441. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  2442. Dry_btn = True
  2443. # 從資料庫資料表中取得最新狀態
  2444. # ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2445. # FO1 = 'FO_OutputtingBean'
  2446. # FO2 = 'FO_Waiting'
  2447. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  2448. # FO2 = 'FO_Waiting'
  2449. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2450. DI1 = dry_status.Dry_Input_1 # DI1 == 'DI_OutputtingBean'
  2451. DI2 = dry_status.Dry_Input_2
  2452. D1 = dry_status.Dry_Tank_1
  2453. D2 = dry_status.Dry_Tank_2
  2454. D3 = dry_status.Dry_Tank_3
  2455. D4 = dry_status.Dry_Tank_4
  2456. D5 = dry_status.Dry_Tank_5
  2457. D6 = dry_status.Dry_Tank_6
  2458. D7 = dry_status.Dry_Tank_7
  2459. D8 = dry_status.Dry_Tank_8
  2460. D9 = dry_status.Dry_Tank_9
  2461. D10 = dry_status.Dry_Tank_10
  2462. D11 = dry_status.Dry_Tank_11
  2463. D12 = dry_status.Dry_Tank_12
  2464. DO1 = dry_status.Dry_Output_1
  2465. DO2 = dry_status.Dry_Output_2
  2466. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  2467. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  2468. DOutputtingBean_Tank = '' # 出料桶槽號
  2469. DryAuto_cleaning = 0 # 清洗次數
  2470. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  2471. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  2472. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  2473. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  2474. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  2475. DI_UP_UltraSoniclist = []
  2476. for i in range(1, 3, 1):
  2477. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  2478. UltraSonic = float(input_UltraSonic.UltraSonic)
  2479. DI_UP_UltraSoniclist.append(UltraSonic)
  2480. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  2481. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  2482. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  2483. D_UP_tank_UltraSonic = []
  2484. for i in range(1, 7, 1):
  2485. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2486. UltraSonic = float(tank_UltraSonic.UltraSonic)
  2487. D_UP_tank_UltraSonic.append(UltraSonic)
  2488. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  2489. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  2490. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2491. DO_UP_UltraSoniclist = []
  2492. for i in range(1, 3, 1):
  2493. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  2494. UltraSonic = float(output_UltraSonic.UltraSonic)
  2495. DO_UP_UltraSoniclist.append(UltraSonic)
  2496. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  2497. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2498. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  2499. D_UP_tank_SHT11Temp = []
  2500. D_UP_tank_SHT11Humidity = []
  2501. for i in range(1, 7, 1):
  2502. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2503. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2504. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  2505. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  2506. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  2507. print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  2508. print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  2509. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  2510. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  2511. D_UP_tank_SoilTemp = []
  2512. D_UP_tank_SoilHumidity = []
  2513. D_UP_tank_SoilEC = []
  2514. for i in range(1, 7, 1):
  2515. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2516. soil_Temp = float(tank_Soil.soil_Temp)
  2517. D_UP_tank_SoilTemp.append(soil_Temp)
  2518. soil_Humidity = float(tank_Soil.soil_Humidity)
  2519. D_UP_tank_SoilHumidity.append(soil_Humidity)
  2520. soil_EC = float(tank_Soil.soil_EC)
  2521. D_UP_tank_SoilEC.append(soil_EC)
  2522. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  2523. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  2524. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  2525. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  2526. # ----- 發酵排程動作 start ------------------------------------------------------------------
  2527. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  2528. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  2529. # [致動器] 真空吸料機 OFF
  2530. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2531. print('data: ', data)
  2532. # mqtt_f(data)
  2533. # [致動器] 蝴蝶閥 OFF
  2534. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2535. print('data: ', data)
  2536. # mqtt_f(data)
  2537. # # [致動器] F1 蝴蝶閥 OFF [ 1109 測試用 ]
  2538. # data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  2539. # print('data: ', data)
  2540. # # mqtt_f(data)
  2541. # [致動器] 馬達 0
  2542. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2543. print('data: ', data)
  2544. # mqtt_f(data)
  2545. # [致動器] 入料三通閥 ON排氣
  2546. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  2547. print('data: ', data)
  2548. # mqtt_f(data)
  2549. print('------- ', tid,' 狀態更新:入豆完成 -------')
  2550. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  2551. def DInputtingBean_AND_notfilled(tid):
  2552. # [致動器] 蝴蝶閥 OFF
  2553. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2554. print('data: ', data)
  2555. # mqtt_f(data)
  2556. # [致動器] 入料三通閥 OFF入豆
  2557. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2558. print('data: ', data)
  2559. # mqtt_f(data)
  2560. # [致動器] 真空吸料機 ON
  2561. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  2562. print('data: ', data)
  2563. # mqtt_f(data)
  2564. timer = time.time()
  2565. while True:
  2566. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  2567. # [致動器] 真空吸料機 OFF
  2568. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2569. print('data: ', data)
  2570. # mqtt_f(data)
  2571. timer = time.time()
  2572. break
  2573. while True:
  2574. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  2575. break
  2576. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  2577. def DInputtingBean_TO_DInputtingBeanPause(tid):
  2578. # [致動器] 蝴蝶閥 OFF
  2579. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2580. print('data: ', data)
  2581. # mqtt_f(data)
  2582. # [致動器] 真空吸料機 OFF
  2583. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  2584. print('data: ', data)
  2585. # mqtt_f(data)
  2586. # [致動器] 馬達 0
  2587. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2588. print('data: ', data)
  2589. # mqtt_f(data)
  2590. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  2591. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  2592. def DInputtingBeanPause_TO_DInputtingBean(tid):
  2593. # [致動器] 入料三通閥 OFF入豆
  2594. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2595. print('data: ', data)
  2596. # mqtt_f(data)
  2597. # [致動器] 馬達 5
  2598. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2599. print('data: ', data)
  2600. # mqtt_f(data)
  2601. print('------- ', tid, ' 狀態更新:入豆中 -------')
  2602. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  2603. def DWaiting_TO_DInputtingBean(tid):
  2604. # [致動器] F1 蝴蝶閥 ON
  2605. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  2606. print('data: ', data)
  2607. # mqtt_f(data)
  2608. # [致動器] 蝴蝶閥 OFF
  2609. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2610. print('data: ', data)
  2611. # mqtt_f(data)
  2612. # [致動器] 入料三通閥 OFF入豆
  2613. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  2614. print('data: ', data)
  2615. # mqtt_f(data)
  2616. # [致動器] 馬達 5
  2617. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  2618. print('data: ', data)
  2619. # mqtt_f(data)
  2620. print('------- ', tid, ' 狀態更新:入豆中 -------')
  2621. # else: if D1 == 'D_InputtingBean_Finish':
  2622. def DInputtingBeanFinish_TO_DDrying(tid):
  2623. # [致動器] 馬達 指定轉速
  2624. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  2625. print('data: ', data)
  2626. # mqtt_f(data)
  2627. # [致動器] 排水電磁閥 ON
  2628. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2629. print('data: ', data)
  2630. # mqtt_f(data)
  2631. # # [致動器] 鼓風機 ON
  2632. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  2633. # print('data: ', data)
  2634. # # mqtt_f(data)
  2635. # # [致動器] 加熱器 1 ON
  2636. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  2637. # print('data: ', data)
  2638. # # mqtt_f(data)
  2639. # # [致動器] 加熱器 2 ON
  2640. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  2641. # print('data: ', data)
  2642. # # mqtt_f(data)
  2643. # [致動器] 溫控開關 ON
  2644. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on" }
  2645. print('data: ', data)
  2646. # mqtt_f(data)
  2647. # [致動器] 設定溫度 (指定溫度)
  2648. data = { "tank_num": tid, "command": "tank_temp", "value": Dry_Tank_drying_temp }
  2649. print('data: ', data)
  2650. # mqtt_f(data)
  2651. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  2652. # 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:
  2653. def DDrying_TO_DOutputtingBean(tid):
  2654. # # [致動器] 鼓風機 OFF
  2655. # data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  2656. # print('data: ', data)
  2657. # # mqtt_f(data)
  2658. # # [致動器] 加熱器 1 OFF
  2659. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  2660. # print('data: ', data)
  2661. # # mqtt_f(data)
  2662. # # [致動器] 加熱器 2 OFF
  2663. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  2664. # print('data: ', data)
  2665. # # mqtt_f(data)
  2666. # [致動器] 設定溫度 0
  2667. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  2668. print('data: ', data)
  2669. # mqtt_f(data)
  2670. # [致動器] 溫控開關 OFF
  2671. data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  2672. print('data: ', data)
  2673. # mqtt_f(data)
  2674. # [致動器] 馬達 0
  2675. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2676. print('data: ', data)
  2677. # mqtt_f(data)
  2678. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  2679. timer = time.time()
  2680. while True:
  2681. if (time.time() - timer) > Dry_Tank_drying_time:
  2682. # [致動器] 排水電磁閥 OFF
  2683. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2684. print('data: ', data)
  2685. # mqtt_f(data)
  2686. break
  2687. print('------- ', tid, ' 狀態更新:可出豆 -------')
  2688. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  2689. def DOutputtingBean_TO_DWaiting(tid):
  2690. # [致動器] D1 蝴蝶閥 OFF
  2691. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  2692. print('data: ', data)
  2693. # mqtt_f(data)
  2694. # D_Cleaning
  2695. def DCleaning(tid):
  2696. # [致動器] 馬達 10
  2697. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  2698. print('data: ', data)
  2699. # mqtt_f(data)
  2700. # [致動器] 消毒電磁閥 ON
  2701. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  2702. print('data: ', data)
  2703. # mqtt_f(data)
  2704. # [致動器] 排水電磁閥 OFF
  2705. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2706. print('data: ', data)
  2707. # mqtt_f(data)
  2708. # [致動器] TODO 消毒抽水 pump ON
  2709. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  2710. timer = time.time()
  2711. while True:
  2712. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  2713. # [致動器] TODO 消毒抽水 pump OFF
  2714. break
  2715. # [致動器] 消毒電磁閥 OFF
  2716. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  2717. print('data: ', data)
  2718. # mqtt_f(data)
  2719. # [致動器] 馬達 0
  2720. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  2721. print('data: ', data)
  2722. # mqtt_f(data)
  2723. # [致動器] 排水電磁閥 ON
  2724. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  2725. print('data: ', data)
  2726. # mqtt_f(data)
  2727. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  2728. timer = time.time()
  2729. while True:
  2730. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  2731. break
  2732. # [致動器] 排水電磁閥 OFF
  2733. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  2734. print('data: ', data)
  2735. # mqtt_f(data)
  2736. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  2737. # ----- 發酵排程動作 end ------------------------------------------------------------------
  2738. # [介面] 若啟用 乾燥 狀態
  2739. if Dry_btn:
  2740. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  2741. # 若 D1~D6 桶槽中有一個桶槽入豆中
  2742. if DryUp_InputtingBean_number == 1:
  2743. # 若 D1 桶槽為入豆中
  2744. if D1 == 'D_InputtingBean':
  2745. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  2746. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  2747. DInputtingBean_TO_DInputtingBeanFinish("D1")
  2748. D1 = 'D_InputtingBean_Finish'
  2749. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  2750. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  2751. DInputtingBean_AND_notfilled("D1")
  2752. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  2753. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  2754. DInputtingBean_TO_DInputtingBeanPause("D1")
  2755. D1 = 'D_InputtingBean_Pause'
  2756. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  2757. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  2758. if D1 == 'D_InputtingBean_Pause':
  2759. DInputtingBeanPause_TO_DInputtingBean("D1")
  2760. D1 = 'D_InputtingBean'
  2761. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  2762. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  2763. if D1 == 'D_Waiting':
  2764. DWaiting_TO_DInputtingBean("D1")
  2765. D1 = 'D_InputtingBean'
  2766. # 其他
  2767. # else:
  2768. # 以下內容原在此 else 內, 測試無誤後維持
  2769. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  2770. if D1 == 'D_InputtingBean_Finish':
  2771. DInputtingBeanFinish_TO_DDrying("D1")
  2772. D1 = 'D_Drying'
  2773. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  2774. if D1 == 'D_Drying' and D_UP_tank_SHT11Temp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  2775. DDrying_TO_DOutputtingBean("D1")
  2776. D1 = 'D_OutputtingBean'
  2777. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  2778. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  2779. # TODO 發酵次數計算、消毒次數、校正
  2780. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  2781. if DOutputtingBean_Tank == 'D1':
  2782. DOutputtingBean_TO_DWaiting('D1')
  2783. DOutputtingBean_Tank = ''
  2784. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  2785. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  2786. # 避免桶槽可出豆時未賦值
  2787. if DOutputtingBean_Tank == '':
  2788. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  2789. # 乾燥槽消毒
  2790. if D1 == 'D_Cleaning':
  2791. DCleaning("D1")
  2792. D1 = 'D_Waiting'
  2793. else:
  2794. print('未啟用乾燥流程')
  2795. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  2796. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  2797. # # 1109 註解實驗用
  2798. # if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  2799. # # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  2800. # DO1 = 'DO_InputtingBean'
  2801. # print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  2802. # print('------- DO1 狀態更新:入豆中 -------')
  2803. # # [致動器] D1 蝴蝶閥 ON
  2804. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  2805. # print('data: ', data)
  2806. # # mqtt_f(data)
  2807. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  2808. # if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  2809. # # [致動器] 出料真空吸料機 OFF
  2810. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  2811. # print('data: ', data)
  2812. # # mqtt_f(data)
  2813. # # [致動器] D1 蝴蝶閥 OFF
  2814. # data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  2815. # print('data: ', data)
  2816. # # mqtt_f(data)
  2817. # DO1 = 'DO_OutputtingBean'
  2818. # print('------- DO1 狀態更新:可出豆 -------')
  2819. # elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  2820. # # [致動器] 出料真空吸料機 ON
  2821. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  2822. # print('data: ', data)
  2823. # # mqtt_f(data)
  2824. # timer = time.time()
  2825. # while True:
  2826. # if (time.time() - timer) > Dry_Output_vacuumON_time:
  2827. # # [致動器] 出料真空吸料機 OFF
  2828. # data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  2829. # print('data: ', data)
  2830. # # mqtt_f(data)
  2831. # timer = time.time()
  2832. # break
  2833. # while True:
  2834. # if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  2835. # break
  2836. # # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  2837. # elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank == '':
  2838. # if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  2839. # DO1 = 'DO_OutputtingBean'
  2840. # print('------- DO1 狀態更新:可出豆 -------')
  2841. # elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  2842. # DO1 = 'DO_Waiting'
  2843. # print('------- DO1 狀態更新:空桶等待 -------')
  2844. # elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  2845. # DO1 = 'DO_Waiting'
  2846. # # [致動器] D1 蝴蝶閥 OFF
  2847. # data = { "tank_num": "D1", "command": "tank_diskvalve_status", "value": "off" }
  2848. # print('data: ', data)
  2849. # # mqtt_f(data)
  2850. # print('------- DO1 狀態更新:空桶等待 -------')
  2851. # # 1109 註解實驗用
  2852. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  2853. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  2854. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  2855. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  2856. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  2857. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  2858. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  2859. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  2860. # ----- 將狀態寫入資料庫 ------------------------------
  2861. # 獲取文本框的值並賦值給user實體對象
  2862. D_status = dry_container_status()
  2863. D_status.Dry_Input_1 = DI1
  2864. D_status.Dry_Input_2 = DI2
  2865. D_status.Dry_Tank_1 = D1
  2866. D_status.Dry_Tank_2 = D2
  2867. D_status.Dry_Tank_3 = D3
  2868. D_status.Dry_Tank_4 = D4
  2869. D_status.Dry_Tank_5 = D5
  2870. D_status.Dry_Tank_6 = D6
  2871. D_status.Dry_Tank_7 = D7
  2872. D_status.Dry_Tank_8 = D8
  2873. D_status.Dry_Tank_9 = D9
  2874. D_status.Dry_Tank_10 = D10
  2875. D_status.Dry_Tank_11 = D11
  2876. D_status.Dry_Tank_12 = D12
  2877. D_status.Dry_Output_1 = DO1
  2878. D_status.Dry_Output_2 = DO2
  2879. #將數據保存進資料庫
  2880. db.session.add(D_status)
  2881. # 手動提交
  2882. db.session.commit()
  2883. # ----- 將狀態寫入資料庫 ------------------------------
  2884. return jsonify({"Dry_Tank_1":D1,
  2885. "Dry_Tank_2":D2,
  2886. "Dry_Output_1":DO1,
  2887. "Dry_Output_2":DO2
  2888. })
  2889. @main.route('/dry_auto_status', methods=['GET', 'POST'])
  2890. def dry_auto_status():
  2891. info = request.args.to_dict()
  2892. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  2893. Dry_Input_bean_empty = 2
  2894. Dry_Tank_bean_empty = 2
  2895. Dry_Output_bean_empty = 2
  2896. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  2897. Dry_Input_bean_height = float(info['Dry_Input_bean_height'])
  2898. Dry_Input_vacuumON_time = float(info['Dry_Input_vacuumON_time'])
  2899. Dry_Input_vacuumOFF_time = float(info['Dry_Input_vacuumOFF_time'])
  2900. Dry_Tank_bean_height = float(info['Dry_Tank_bean_height'])
  2901. Dry_Tank_vacuumON_time = float(info['Dry_Tank_vacuumON_time'])
  2902. Dry_Tank_vacuumOFF_time = float(info['Dry_Tank_vacuumOFF_time'])
  2903. Dry_Tank_drying_temp = float(info['Dry_Tank_drying_temp'])
  2904. Dry_Tank_drying_time = float(info['Dry_Tank_drying_time'])
  2905. Dry_Tank_drying_EC = float(info['Dry_Tank_drying_EC'])
  2906. Dry_Tank_motor_rpm = float(info['Dry_Tank_motor_rpm'])
  2907. Dry_Tank_TempWeight_SHT11 = float(info['Dry_Tank_TempWeight_SHT11'])
  2908. Dry_Tank_TempWeight_soil = float(info['Dry_Tank_TempWeight_soil'])
  2909. Dry_Tank_drying_Humidity = float(info['Dry_Tank_drying_Humidity'])
  2910. Dry_Output_bean_height = float(info['Dry_Output_bean_height'])
  2911. Dry_Output_vacuumON_time = float(info['Dry_Output_vacuumON_time'])
  2912. Dry_Output_vacuumOFF_time = float(info['Dry_Output_vacuumOFF_time'])
  2913. Dry_Tank_Disinfect_time = float(info['Dry_Tank_Disinfect_time'])
  2914. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  2915. Dry_btn = True
  2916. # 從資料庫資料表中取得最新狀態
  2917. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  2918. FO1 = ferment_status.Ferment_Output_1
  2919. FO2 = ferment_status.Ferment_Output_2
  2920. # FO1 = 'FO_OutputtingBean' # 'FO_OutputtingBean' FO_Waiting
  2921. # FO2 = 'FO_Waiting'
  2922. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  2923. DI1 = dry_status.Dry_Input_1
  2924. DI2 = dry_status.Dry_Input_2
  2925. D1 = dry_status.Dry_Tank_1
  2926. D2 = dry_status.Dry_Tank_2
  2927. D3 = dry_status.Dry_Tank_3
  2928. D4 = dry_status.Dry_Tank_4
  2929. D5 = dry_status.Dry_Tank_5
  2930. D6 = dry_status.Dry_Tank_6
  2931. D7 = dry_status.Dry_Tank_7
  2932. D8 = dry_status.Dry_Tank_8
  2933. D9 = dry_status.Dry_Tank_9
  2934. D10 = dry_status.Dry_Tank_10
  2935. D11 = dry_status.Dry_Tank_11
  2936. D12 = dry_status.Dry_Tank_12
  2937. DO1 = dry_status.Dry_Output_1
  2938. DO2 = dry_status.Dry_Output_2
  2939. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  2940. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  2941. DOutputtingBean_Tank = '' # 出料桶槽號
  2942. DryAuto_cleaning = 0 # 清洗次數
  2943. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  2944. DryUp_Waiting_number = int(D_UP_tanklist.count('D_Waiting'))
  2945. DryUp_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  2946. DryUp_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  2947. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  2948. DI_UP_UltraSoniclist = []
  2949. for i in range(1, 3, 1):
  2950. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  2951. UltraSonic = float(input_UltraSonic.UltraSonic)
  2952. DI_UP_UltraSoniclist.append(UltraSonic)
  2953. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  2954. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  2955. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  2956. D_UP_tank_UltraSonic = []
  2957. for i in range(1, 7, 1):
  2958. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2959. UltraSonic = float(tank_UltraSonic.UltraSonic)
  2960. D_UP_tank_UltraSonic.append(UltraSonic)
  2961. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  2962. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  2963. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2964. DO_UP_UltraSoniclist = []
  2965. for i in range(1, 3, 1):
  2966. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  2967. UltraSonic = float(output_UltraSonic.UltraSonic)
  2968. DO_UP_UltraSoniclist.append(UltraSonic)
  2969. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  2970. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  2971. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  2972. D_UP_tank_SHT11Temp = []
  2973. D_UP_tank_SHT11Humidity = []
  2974. for i in range(1, 7, 1):
  2975. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2976. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  2977. D_UP_tank_SHT11Temp.append(SHT11_Temp)
  2978. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  2979. D_UP_tank_SHT11Humidity.append(SHT11_Humidity)
  2980. # print('D_UP_tank_SHT11Temp: ', D_UP_tank_SHT11Temp)
  2981. # print('D_UP_tank_SHT11Humidity: ', D_UP_tank_SHT11Humidity)
  2982. # -- 取得乾燥桶槽 D1~D6 桶內溫濕度計 SHT11 -------------
  2983. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 Soil -------------
  2984. D_UP_tank_SoilTemp = []
  2985. D_UP_tank_SoilHumidity = []
  2986. D_UP_tank_SoilEC = []
  2987. for i in range(1, 7, 1):
  2988. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  2989. soil_Temp = float(tank_Soil.soil_Temp)
  2990. D_UP_tank_SoilTemp.append(soil_Temp)
  2991. soil_Humidity = float(tank_Soil.soil_Humidity)
  2992. D_UP_tank_SoilHumidity.append(soil_Humidity)
  2993. soil_EC = float(tank_Soil.soil_EC)
  2994. D_UP_tank_SoilEC.append(soil_EC)
  2995. # print('D_UP_tank_SoilTemp: ', D_UP_tank_SoilTemp)
  2996. # print('D_UP_tank_SoilHumidity: ', D_UP_tank_SoilHumidity)
  2997. # print('D_UP_tank_SoilEC: ', D_UP_tank_SoilEC)
  2998. # -- 取得乾燥桶槽 D1~D6 三合一土壤感測器 SHT11 -------------
  2999. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  3000. D_UP_tank_weightTemp = []
  3001. for i in range(1, 7, 1):
  3002. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  3003. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  3004. 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)
  3005. D_UP_tank_weightTemp.append(Temp)
  3006. print('D_UP_tank_weightTemp: ', D_UP_tank_weightTemp)
  3007. # -- 取得乾燥桶槽 D1~D6 權重後溫度值 -------------
  3008. # ----- 發酵排程動作 start ------------------------------------------------------------------
  3009. # if D1 == 'D_InputtingBean': D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  3010. def DInputtingBean_TO_DInputtingBeanFinish(tid):
  3011. # [致動器] 真空吸料機 OFF
  3012. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  3013. print('data: ', data)
  3014. # mqtt_f(data)
  3015. # [致動器] 馬達 0
  3016. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  3017. print('data: ', data)
  3018. # mqtt_f(data)
  3019. # [致動器] 入料三通閥 ON排氣
  3020. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  3021. print('data: ', data)
  3022. # mqtt_f(data)
  3023. print('------- ', tid,' 狀態更新:入豆完成 -------')
  3024. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3025. def DInputtingBean_AND_notfilled(tid):
  3026. # [致動器] 入料三通閥 OFF入豆
  3027. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  3028. print('data: ', data)
  3029. # mqtt_f(data)
  3030. # [致動器] 真空吸料機 ON
  3031. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  3032. print('data: ', data)
  3033. # mqtt_f(data)
  3034. timer = time.time()
  3035. while True:
  3036. if (time.time() - timer) > Dry_Tank_vacuumON_time:
  3037. # [致動器] 真空吸料機 OFF
  3038. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  3039. print('data: ', data)
  3040. # mqtt_f(data)
  3041. timer = time.time()
  3042. break
  3043. while True:
  3044. if (time.time() - timer) > Dry_Tank_vacuumOFF_time:
  3045. break
  3046. # if D1 == 'D_InputtingBean': elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3047. def DInputtingBean_TO_DInputtingBeanPause(tid):
  3048. # [致動器] 真空吸料機 OFF
  3049. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  3050. print('data: ', data)
  3051. # mqtt_f(data)
  3052. # [致動器] 馬達 0
  3053. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  3054. print('data: ', data)
  3055. # mqtt_f(data)
  3056. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  3057. # elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean': if D1 == 'D_InputtingBean_Pause':
  3058. def DInputtingBeanPause_TO_DInputtingBean(tid):
  3059. # [致動器] 入料三通閥 OFF入豆
  3060. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  3061. print('data: ', data)
  3062. # mqtt_f(data)
  3063. # [致動器] 馬達 5
  3064. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  3065. print('data: ', data)
  3066. # mqtt_f(data)
  3067. print('------- ', tid, ' 狀態更新:入豆中 -------')
  3068. # elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  3069. def DWaiting_TO_DInputtingBean(tid):
  3070. # [致動器] 入料三通閥 OFF入豆
  3071. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  3072. print('data: ', data)
  3073. # mqtt_f(data)
  3074. # [致動器] 馬達 5
  3075. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  3076. print('data: ', data)
  3077. # mqtt_f(data)
  3078. print('------- ', tid, ' 狀態更新:入豆中 -------')
  3079. # else: if D1 == 'D_InputtingBean_Finish':
  3080. def DInputtingBeanFinish_TO_DDrying(tid):
  3081. # [致動器] 馬達 指定轉速
  3082. data = { "tank_num": tid, "command": "tank_motor_status", "value": Dry_Tank_motor_rpm }
  3083. print('data: ', data)
  3084. # mqtt_f(data)
  3085. # [致動器] 排水電磁閥 ON
  3086. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  3087. print('data: ', data)
  3088. # mqtt_f(data)
  3089. # [致動器] 鼓風機 ON
  3090. data = { "tank_num": tid, "command": "tank_blower_status", "value": "on" }
  3091. print('data: ', data)
  3092. # mqtt_f(data)
  3093. # [致動器] 加熱器 1 ON
  3094. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  3095. print('data: ', data)
  3096. # mqtt_f(data)
  3097. # [致動器] 加熱器 2 ON
  3098. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  3099. print('data: ', data)
  3100. # mqtt_f(data)
  3101. print('------- ', tid, ' 狀態更新:乾燥中 -------')
  3102. # 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:
  3103. def DDrying_TO_DOutputtingBean(tid):
  3104. # [致動器] 鼓風機 OFF
  3105. data = { "tank_num": tid, "command": "tank_blower_status", "value": "off" }
  3106. print('data: ', data)
  3107. # mqtt_f(data)
  3108. # [致動器] 加熱器 1 OFF
  3109. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  3110. print('data: ', data)
  3111. # mqtt_f(data)
  3112. # [致動器] 加熱器 2 OFF
  3113. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  3114. print('data: ', data)
  3115. # mqtt_f(data)
  3116. # [致動器] 馬達 0
  3117. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  3118. print('data: ', data)
  3119. # mqtt_f(data)
  3120. print("乾燥結束, 返潮暫停 ", Dry_Tank_drying_time, " 秒")
  3121. timer = time.time()
  3122. while True:
  3123. if (time.time() - timer) > Dry_Tank_drying_time:
  3124. # [致動器] 排水電磁閥 OFF
  3125. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  3126. print('data: ', data)
  3127. # mqtt_f(data)
  3128. break
  3129. print('------- ', tid, ' 狀態更新:可出豆 -------')
  3130. # else: if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  3131. def DOutputtingBean_TO_DWaiting(tid):
  3132. # [致動器] D1 蝴蝶閥 OFF
  3133. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  3134. print('data: ', data)
  3135. # mqtt_f(data)
  3136. # D_Cleaning
  3137. def DCleaning(tid):
  3138. # [致動器] 馬達 10
  3139. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  3140. print('data: ', data)
  3141. # mqtt_f(data)
  3142. # [致動器] 消毒電磁閥 ON
  3143. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  3144. print('data: ', data)
  3145. # mqtt_f(data)
  3146. # [致動器] 排水電磁閥 OFF
  3147. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  3148. print('data: ', data)
  3149. # mqtt_f(data)
  3150. # [致動器] TODO 消毒抽水 pump ON
  3151. print("消毒 ", Dry_Tank_Disinfect_time, " 秒")
  3152. timer = time.time()
  3153. while True:
  3154. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  3155. # [致動器] TODO 消毒抽水 pump OFF
  3156. break
  3157. # [致動器] 消毒電磁閥 OFF
  3158. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  3159. print('data: ', data)
  3160. # mqtt_f(data)
  3161. # [致動器] 馬達 0
  3162. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  3163. print('data: ', data)
  3164. # mqtt_f(data)
  3165. # [致動器] 排水電磁閥 ON
  3166. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  3167. print('data: ', data)
  3168. # mqtt_f(data)
  3169. print("桶內排水 ", Dry_Tank_Disinfect_time, " 秒")
  3170. timer = time.time()
  3171. while True:
  3172. if (time.time() - timer) > Dry_Tank_Disinfect_time:
  3173. break
  3174. # [致動器] 排水電磁閥 OFF
  3175. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  3176. print('data: ', data)
  3177. # mqtt_f(data)
  3178. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  3179. # ----- 發酵排程動作 end ------------------------------------------------------------------
  3180. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  3181. # 如果入料儲豆槽 空桶等待, 且發酵出料儲豆槽 FO1 為可出豆, 則開始入豆
  3182. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  3183. DI1 = 'DI_InputtingBean'
  3184. print('------- DI1 狀態更新:入料中 -------')
  3185. # 如果入料儲豆槽 入豆中
  3186. elif DI1 == 'DI_InputtingBean':
  3187. # 如果入豆儲豆槽達指定高度時
  3188. if DI_UP_UltraSoniclist[0] >= Dry_Input_bean_height:
  3189. # [致動器] 入料真空吸料機 OFF
  3190. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  3191. print('data: ', data)
  3192. # mqtt_f(data)
  3193. DI1 = 'DI_OutputtingBean'
  3194. print('------- DI1 狀態更新:可出豆 -------')
  3195. # 如果入豆儲豆槽未達指定高度, 且 發酵出料儲豆槽 可出豆
  3196. elif DI_UP_UltraSoniclist[0] < Dry_Input_bean_height and FO1 == 'FO_OutputtingBean':
  3197. # [致動器] 入料真空吸料機 ON
  3198. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "on" }
  3199. print('data: ', data)
  3200. # mqtt_f(data)
  3201. timer = time.time()
  3202. while True:
  3203. if (time.time() - timer) > Dry_Input_vacuumON_time:
  3204. # [致動器] 入料真空吸料機 OFF
  3205. data = { "tank_num": "D1", "command": "input_vacuum_status", "value": "off" }
  3206. print('data: ', data)
  3207. # mqtt_f(data)
  3208. timer = time.time()
  3209. break
  3210. while True:
  3211. if (time.time() - timer) > Dry_Input_vacuumOFF_time:
  3212. break
  3213. # 如果入料儲豆槽生豆大於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為可出豆
  3214. elif (DI_UP_UltraSoniclist[0] > Dry_Input_bean_empty) and FO1 != 'FO_OutputtingBean':
  3215. DI1 = 'DI_OutputtingBean'
  3216. print('------- DI1 狀態更新:可出豆 -------')
  3217. # 桶槽內小於空桶高度, 且 前方 FO1 非可出豆, 將狀態轉為空桶等待
  3218. elif (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty) and FO1 != 'PO_OutputtingBean':
  3219. DI1 = 'DI_Waiting'
  3220. print('------- FI1 狀態更新:空桶等待 -------')
  3221. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  3222. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] <= Dry_Input_bean_empty):
  3223. DI1 = 'DI_Waiting'
  3224. print('------- DI1 狀態更新:空桶等待 -------')
  3225. # [介面] 若啟用 乾燥 狀態
  3226. if Dry_btn:
  3227. # ----- 乾燥桶槽 D1~D6 入料桶槽優先入料判斷 ------------------------------
  3228. # 若 D1~D6 桶槽中有一個桶槽入豆中
  3229. if DryUp_InputtingBean_number == 1:
  3230. # 若 D1 桶槽為入豆中
  3231. if D1 == 'D_InputtingBean':
  3232. # 若桶槽生豆高度大於指定生豆高度, 則狀態轉換成 入料完成
  3233. if D_UP_tank_UltraSonic[0] >= Dry_Tank_bean_height:
  3234. DInputtingBean_TO_DInputtingBeanFinish("D1")
  3235. D1 = 'D_InputtingBean_Finish'
  3236. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽可出豆
  3237. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3238. DInputtingBean_AND_notfilled("D1")
  3239. # 若桶槽生豆高度未達指定生豆高度, 且 入料儲豆槽 非可出豆
  3240. elif D_UP_tank_UltraSonic[0] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3241. DInputtingBean_TO_DInputtingBeanPause("D1")
  3242. D1 = 'D_InputtingBean_Pause'
  3243. elif D2 == 'D_InputtingBean':
  3244. if D_UP_tank_UltraSonic[1] >= Dry_Tank_bean_height:
  3245. DInputtingBean_TO_DInputtingBeanFinish("D2")
  3246. D2 = 'D_InputtingBean_Finish'
  3247. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3248. DInputtingBean_AND_notfilled("D2")
  3249. elif D_UP_tank_UltraSonic[1] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3250. DInputtingBean_TO_DInputtingBeanPause("D2")
  3251. D2 = 'D_InputtingBean_Pause'
  3252. elif D3 == 'D_InputtingBean':
  3253. if D_UP_tank_UltraSonic[2] >= Dry_Tank_bean_height:
  3254. DInputtingBean_TO_DInputtingBeanFinish("D3")
  3255. D3 = 'D_InputtingBean_Finish'
  3256. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3257. DInputtingBean_AND_notfilled("D2")
  3258. elif D_UP_tank_UltraSonic[2] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3259. DInputtingBean_TO_DInputtingBeanPause("D2")
  3260. D3 = 'D_InputtingBean_Pause'
  3261. elif D4 == 'D_InputtingBean':
  3262. if D_UP_tank_UltraSonic[3] >= Dry_Tank_bean_height:
  3263. DInputtingBean_TO_DInputtingBeanFinish("D4")
  3264. D4 = 'D_InputtingBean_Finish'
  3265. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3266. DInputtingBean_AND_notfilled("D4")
  3267. elif D_UP_tank_UltraSonic[3] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3268. DInputtingBean_TO_DInputtingBeanPause("D4")
  3269. D4 = 'D_InputtingBean_Pause'
  3270. elif D5 == 'D_InputtingBean':
  3271. if D_UP_tank_UltraSonic[4] >= Dry_Tank_bean_height:
  3272. DInputtingBean_TO_DInputtingBeanFinish("D5")
  3273. D5 = 'D_InputtingBean_Finish'
  3274. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3275. DInputtingBean_AND_notfilled("D5")
  3276. elif D_UP_tank_UltraSonic[4] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3277. DInputtingBean_TO_DInputtingBeanPause("D5")
  3278. D5 = 'D_InputtingBean_Pause'
  3279. elif D6 == 'D_InputtingBean':
  3280. if D_UP_tank_UltraSonic[5] >= Dry_Tank_bean_height:
  3281. DInputtingBean_TO_DInputtingBeanFinish("D6")
  3282. D6 = 'D_InputtingBean_Finish'
  3283. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 == 'DI_OutputtingBean':
  3284. DInputtingBean_AND_notfilled("D6")
  3285. elif D_UP_tank_UltraSonic[5] < Dry_Tank_bean_height and DI1 != 'DI_OutputtingBean':
  3286. DInputtingBean_TO_DInputtingBeanPause("D6")
  3287. D6 = 'D_InputtingBean_Pause'
  3288. # 若 D1~D6 桶槽中有一個桶槽入豆暫停
  3289. elif DryUp_InputtingBeanPause_number == 1 and DI1 == 'DI_OutputtingBean':
  3290. if D1 == 'D_InputtingBean_Pause':
  3291. DInputtingBeanPause_TO_DInputtingBean("D1")
  3292. D1 = 'D_InputtingBean'
  3293. elif D2 == 'D_InputtingBean_Pause':
  3294. DInputtingBeanPause_TO_DInputtingBean("D2")
  3295. D2 = 'D_InputtingBean'
  3296. elif D3 == 'D_InputtingBean_Pause':
  3297. DInputtingBeanPause_TO_DInputtingBean("D3")
  3298. D3 = 'D_InputtingBean'
  3299. elif D4 == 'D_InputtingBean_Pause':
  3300. DInputtingBeanPause_TO_DInputtingBean("D4")
  3301. D4 = 'D_InputtingBean'
  3302. elif D5 == 'D_InputtingBean_Pause':
  3303. DInputtingBeanPause_TO_DInputtingBean("D5")
  3304. D5 = 'D_InputtingBean'
  3305. elif D6 == 'D_InputtingBean_Pause':
  3306. DInputtingBeanPause_TO_DInputtingBean("D6")
  3307. D6 = 'D_InputtingBean'
  3308. # 若 D1~D6 桶槽中皆無 入豆中 和 入豆暫停, 且入料儲豆槽可出豆
  3309. elif DryUp_InputtingBean_number == 0 and DryUp_InputtingBeanPause_number == 0 and DI1 == 'DI_OutputtingBean' and DryUp_Waiting_number >= 1:
  3310. if D1 == 'D_Waiting':
  3311. DWaiting_TO_DInputtingBean("D1")
  3312. D1 = 'D_InputtingBean'
  3313. elif D2 == 'D_Waiting':
  3314. DWaiting_TO_DInputtingBean("D2")
  3315. D2 = 'D_InputtingBean'
  3316. elif D3 == 'D_Waiting':
  3317. DWaiting_TO_DInputtingBean("D3")
  3318. D3 = 'D_InputtingBean'
  3319. elif D4 == 'D_Waiting':
  3320. DWaiting_TO_DInputtingBean("D4")
  3321. D4 = 'D_InputtingBean'
  3322. elif D5 == 'D_Waiting':
  3323. DWaiting_TO_DInputtingBean("D5")
  3324. D5 = 'D_InputtingBean'
  3325. elif D6 == 'D_Waiting':
  3326. DWaiting_TO_DInputtingBean("D6")
  3327. D6 = 'D_InputtingBean'
  3328. # 其他
  3329. else:
  3330. # 如果桶槽為 入豆完成, 將狀態轉換成 乾燥中
  3331. if D1 == 'D_InputtingBean_Finish':
  3332. DInputtingBeanFinish_TO_DDrying("D1")
  3333. D1 = 'D_Drying'
  3334. if D2 == 'D_InputtingBean_Finish':
  3335. DInputtingBeanFinish_TO_DDrying("D2")
  3336. D2 = 'D_Drying'
  3337. if D3 == 'D_InputtingBean_Finish':
  3338. DInputtingBeanFinish_TO_DDrying("D3")
  3339. D3 = 'D_Drying'
  3340. if D4 == 'D_InputtingBean_Finish':
  3341. DInputtingBeanFinish_TO_DDrying("D4")
  3342. D4 = 'D_Drying'
  3343. if D5 == 'D_InputtingBean_Finish':
  3344. DInputtingBeanFinish_TO_DDrying("D5")
  3345. D5 = 'D_Drying'
  3346. if D6 == 'D_InputtingBean_Finish':
  3347. DInputtingBeanFinish_TO_DDrying("D6")
  3348. D6 = 'D_Drying'
  3349. # 如果桶槽為 乾燥中, 達乾燥條件後, 將狀態轉換成 可出豆
  3350. if D1 == 'D_Drying' and D_UP_tank_weightTemp[0] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[0] <= Dry_Tank_drying_Humidity:
  3351. DDrying_TO_DOutputtingBean("D1")
  3352. D1 = 'D_OutputtingBean'
  3353. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D1'
  3354. if D2 == 'D_Drying' and D_UP_tank_weightTemp[1] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[1] <= Dry_Tank_drying_Humidity:
  3355. DDrying_TO_DOutputtingBean("D2")
  3356. D2 = 'D_OutputtingBean'
  3357. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D2'
  3358. if D3 == 'D_Drying' and D_UP_tank_weightTemp[2] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[2] <= Dry_Tank_drying_Humidity:
  3359. DDrying_TO_DOutputtingBean("D3")
  3360. D3 = 'D_OutputtingBean'
  3361. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D3'
  3362. if D4 == 'D_Drying' and D_UP_tank_weightTemp[3] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[3] <= Dry_Tank_drying_Humidity:
  3363. DDrying_TO_DOutputtingBean("D4")
  3364. D4 = 'D_OutputtingBean'
  3365. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D4'
  3366. if D5 == 'D_Drying' and D_UP_tank_weightTemp[4] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[4] <= Dry_Tank_drying_Humidity:
  3367. DDrying_TO_DOutputtingBean("D5")
  3368. D5 = 'D_OutputtingBean'
  3369. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D5'
  3370. if D6 == 'D_Drying' and D_UP_tank_weightTemp[5] >= Dry_Tank_drying_temp and D_UP_tank_SHT11Humidity[5] <= Dry_Tank_drying_Humidity:
  3371. DDrying_TO_DOutputtingBean("D6")
  3372. D6 = 'D_OutputtingBean'
  3373. if DOutputtingBean_Tank == '': DOutputtingBean_Tank = 'D6'
  3374. # 如果桶槽 D1~D6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  3375. # TODO 發酵次數計算、消毒次數、校正
  3376. if D1 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[0] <= Dry_Tank_bean_empty):
  3377. if DOutputtingBean_Tank == 'D1':
  3378. DOutputtingBean_TO_DWaiting('D1')
  3379. DOutputtingBean_Tank = ''
  3380. if (DryAuto_cleaning == 0): D1 = 'D_Waiting'
  3381. elif (DryAuto_cleaning != 0): D1 = 'D_Cleaning'
  3382. if D2 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[1] <= Dry_Tank_bean_empty):
  3383. if DOutputtingBean_Tank == 'D2':
  3384. DOutputtingBean_TO_DWaiting('D2')
  3385. DOutputtingBean_Tank = ''
  3386. if (DryAuto_cleaning == 0): D2 = 'D_Waiting'
  3387. elif (DryAuto_cleaning != 0): D2 = 'D_Cleaning'
  3388. if D3 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[2] <= Dry_Tank_bean_empty):
  3389. if DOutputtingBean_Tank == 'D2':
  3390. DOutputtingBean_TO_DWaiting('D2')
  3391. DOutputtingBean_Tank = ''
  3392. if (DryAuto_cleaning == 0): D3 = 'D_Waiting'
  3393. elif (DryAuto_cleaning != 0): D3 = 'D_Cleaning'
  3394. if D4 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[3] <= Dry_Tank_bean_empty):
  3395. if DOutputtingBean_Tank == 'D4':
  3396. DOutputtingBean_TO_DWaiting('D4')
  3397. DOutputtingBean_Tank = ''
  3398. if (DryAuto_cleaning == 0): D4 = 'D_Waiting'
  3399. elif (DryAuto_cleaning != 0): D4 = 'D_Cleaning'
  3400. if D5 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[4] <= Dry_Tank_bean_empty):
  3401. if DOutputtingBean_Tank == 'D5':
  3402. DOutputtingBean_TO_DWaiting('D5')
  3403. DOutputtingBean_Tank = ''
  3404. if (DryAuto_cleaning == 0): D5 = 'D_Waiting'
  3405. elif (DryAuto_cleaning != 0): D5 = 'D_Cleaning'
  3406. if D6 == 'D_OutputtingBean' and (D_UP_tank_UltraSonic[5] <= Dry_Tank_bean_empty):
  3407. if DOutputtingBean_Tank == 'D6':
  3408. DOutputtingBean_TO_DWaiting('D6')
  3409. DOutputtingBean_Tank = ''
  3410. if (DryAuto_cleaning == 0): D6 = 'D_Waiting'
  3411. elif (DryAuto_cleaning != 0): D6 = 'D_Cleaning'
  3412. # 避免桶槽可出豆時未賦值
  3413. if DOutputtingBean_Tank == '':
  3414. if D1 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D1'
  3415. elif D2 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D2'
  3416. elif D3 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D3'
  3417. elif D4 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D4'
  3418. elif D5 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D5'
  3419. elif D6 == 'D_OutputtingBean': DOutputtingBean_Tank = 'D6'
  3420. # 乾燥槽消毒
  3421. if D1 == 'D_Cleaning':
  3422. DCleaning("D1")
  3423. D1 = 'D_Waiting'
  3424. if D2 == 'D_Cleaning':
  3425. DCleaning("D2")
  3426. D2 = 'D_Waiting'
  3427. if D3 == 'D_Cleaning':
  3428. DCleaning("D3")
  3429. D3 = 'D_Waiting'
  3430. if D4 == 'D_Cleaning':
  3431. DCleaning("D4")
  3432. D4 = 'D_Waiting'
  3433. if D5 == 'D_Cleaning':
  3434. DCleaning("D5")
  3435. D5 = 'D_Waiting'
  3436. if D6 == 'D_Cleaning':
  3437. DCleaning("D6")
  3438. D6 = 'D_Waiting'
  3439. else:
  3440. print('未啟用乾燥流程')
  3441. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  3442. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  3443. if DO1 == 'DO_Waiting' and DOutputtingBean_Tank != '':
  3444. # 判斷要對應出料的桶槽為何, 設定成 DOutputtingBean_Tank = 'D1', 待出完料再把 DOutputtingBean_Tank = ''
  3445. DO1 = 'DO_InputtingBean'
  3446. print('------- ' + DOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  3447. print('------- DO1 狀態更新:入豆中 -------')
  3448. # [致動器] D1 蝴蝶閥 ON
  3449. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  3450. print('data: ', data)
  3451. # mqtt_f(data)
  3452. elif DO1 == 'DO_InputtingBean' and DOutputtingBean_Tank != '':
  3453. if DO_UP_UltraSoniclist[0] >= Dry_Output_bean_height:
  3454. # [致動器] 出料真空吸料機 OFF
  3455. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  3456. print('data: ', data)
  3457. # mqtt_f(data)
  3458. # [致動器] D1 蝴蝶閥 OFF
  3459. data = { "tank_num": DOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  3460. print('data: ', data)
  3461. # mqtt_f(data)
  3462. DO1 = 'DO_OutputtingBean'
  3463. print('------- DO1 狀態更新:可出豆 -------')
  3464. elif DO_UP_UltraSoniclist[0] < Dry_Output_bean_height:
  3465. # [致動器] 出料真空吸料機 ON
  3466. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "on" }
  3467. print('data: ', data)
  3468. # mqtt_f(data)
  3469. timer = time.time()
  3470. while True:
  3471. if (time.time() - timer) > Dry_Output_vacuumON_time:
  3472. # [致動器] 出料真空吸料機 OFF
  3473. data = { "tank_num": DOutputtingBean_Tank, "command": "output_vacuum_status", "value": "off" }
  3474. print('data: ', data)
  3475. # mqtt_f(data)
  3476. timer = time.time()
  3477. break
  3478. while True:
  3479. if (time.time() - timer) > Dry_Output_vacuumOFF_time:
  3480. break
  3481. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  3482. elif DOutputtingBean_Tank == '':
  3483. if DO_UP_UltraSoniclist[0] > Dry_Output_bean_empty:
  3484. DO1 = 'DO_OutputtingBean'
  3485. print('------- DO1 狀態更新:可出豆 -------')
  3486. elif DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  3487. DO1 = 'DO_Waiting'
  3488. print('------- DO1 狀態更新:空桶等待 -------')
  3489. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] <= Dry_Output_bean_empty:
  3490. DO1 = 'DO_Waiting'
  3491. print('------- DO1 狀態更新:空桶等待 -------')
  3492. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  3493. # if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  3494. # if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  3495. # if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  3496. # if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  3497. # if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  3498. # if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  3499. # # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  3500. # ----- 將狀態寫入資料庫 ------------------------------
  3501. # 獲取文本框的值並賦值給user實體對象
  3502. D_status = dry_container_status()
  3503. D_status.Dry_Input_1 = DI1
  3504. D_status.Dry_Input_2 = DI2
  3505. D_status.Dry_Tank_1 = D1
  3506. D_status.Dry_Tank_2 = D2
  3507. D_status.Dry_Tank_3 = D3
  3508. D_status.Dry_Tank_4 = D4
  3509. D_status.Dry_Tank_5 = D5
  3510. D_status.Dry_Tank_6 = D6
  3511. D_status.Dry_Tank_7 = D7
  3512. D_status.Dry_Tank_8 = D8
  3513. D_status.Dry_Tank_9 = D9
  3514. D_status.Dry_Tank_10 = D10
  3515. D_status.Dry_Tank_11 = D11
  3516. D_status.Dry_Tank_12 = D12
  3517. D_status.Dry_Output_1 = DO1
  3518. D_status.Dry_Output_2 = DO2
  3519. #將數據保存進資料庫
  3520. db.session.add(D_status)
  3521. # 手動提交
  3522. db.session.commit()
  3523. # ----- 將狀態寫入資料庫 ------------------------------
  3524. return jsonify({"Dry_Input_1":DI1,
  3525. "Dry_Tank_1":D1,
  3526. "Dry_Tank_2":D2,
  3527. "Dry_Tank_3":D3,
  3528. "Dry_Tank_4":D4,
  3529. "Dry_Tank_5":D5,
  3530. "Dry_Tank_6":D6,
  3531. "Dry_Output_1":DO1
  3532. })
  3533. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以下為原備份
  3534. @main.route('/dry_auto_status_1101backup', methods=['GET', 'POST'])
  3535. def dry_auto_test_1101backup():
  3536. # [介面] 讓使用者可以選擇排程內有乾燥/清洗/校正, 此處預設為 True
  3537. Dry_btn = True
  3538. # 從資料庫資料表中取得最新狀態
  3539. dry_status = dry_container_status.query.order_by(text('datetime desc')).first()
  3540. DI1 = dry_status.Dry_Input_1
  3541. DI2 = dry_status.Dry_Input_2
  3542. D1 = dry_status.Dry_Tank_1
  3543. D2 = dry_status.Dry_Tank_2
  3544. D3 = dry_status.Dry_Tank_3
  3545. D4 = dry_status.Dry_Tank_4
  3546. D5 = dry_status.Dry_Tank_5
  3547. D6 = dry_status.Dry_Tank_6
  3548. D7 = dry_status.Dry_Tank_7
  3549. D8 = dry_status.Dry_Tank_8
  3550. D9 = dry_status.Dry_Tank_9
  3551. D10 = dry_status.Dry_Tank_10
  3552. D11 = dry_status.Dry_Tank_11
  3553. D12 = dry_status.Dry_Tank_12
  3554. DO1 = dry_status.Dry_Output_1
  3555. DO2 = dry_status.Dry_Output_2
  3556. FO1 = 'FO_Waiting' # 'FO_OutputtingBean'
  3557. FO2 = 'FO_Waiting'
  3558. D_UP_tanklist = [D1, D2, D3, D4, D5, D6]
  3559. D_DOWN_tanklist = [D7, D8, D9, D10, D11, D12]
  3560. # ----- 乾燥桶槽 D1~D6 入料暫停→入料判斷 ------------------------------
  3561. Dry_InputtingBeanPause_number = int(D_UP_tanklist.count('D_InputtingBean_Pause'))
  3562. # 若入料儲豆槽可出豆, 且 D1~D6 其中有桶槽入料暫停 (就是入料時桶槽豆子未滿 or 儲豆槽=='DI_Waiting' 已空) 時, 優先入豆
  3563. if DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  3564. if D1 == 'D_InputtingBean_Pause':
  3565. D1 = 'D_InputtingBean'
  3566. print('------- D1 狀態更新:入料中 -------')
  3567. elif D2 == 'D_InputtingBean_Pause':
  3568. D2 = 'D_InputtingBean'
  3569. print('------- D2 狀態更新:入料中 -------')
  3570. elif D3 == 'D_InputtingBean_Pause':
  3571. D3 = 'D_InputtingBean'
  3572. print('------- D3 狀態更新:入料中 -------')
  3573. elif D4 == 'D_InputtingBean_Pause':
  3574. D4 = 'D_InputtingBean'
  3575. print('------- D4 狀態更新:入料中 -------')
  3576. elif D5 == 'D_InputtingBean_Pause':
  3577. D5 = 'D_InputtingBean'
  3578. print('------- D5 狀態更新:入料中 -------')
  3579. elif D6 == 'D_InputtingBean_Pause':
  3580. D6 = 'D_InputtingBean'
  3581. print('------- D6 狀態更新:入料中 -------')
  3582. # ----- 乾燥桶槽 D1~D6 等待→入料判斷 ------------------------------
  3583. # 目前乾燥槽 D1~D6 正在入豆的桶槽數量 (應小於一桶)
  3584. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  3585. # [介面] 若未啟用 發酵 狀態
  3586. if not Dry_btn:
  3587. print('未指定乾燥流程')
  3588. # 入料儲豆槽 非可出料狀態
  3589. elif Dry_btn and DI1 != 'DI_OutputtingBean':
  3590. print('入料儲豆槽非可出豆, 無法入料')
  3591. # 若 D1~D6 乾燥桶槽為 入豆暫停, 則狀態改為入豆優先入豆
  3592. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBeanPause_number >= 1:
  3593. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, '優先入料中')
  3594. print('------- D', D_UP_tanklist.index('D_InputtingBean_Pause')+1, ' 入料中 -------')
  3595. # 若 D1~D6 發酵桶槽為 入豆, 則桶槽數字小者 優先入豆
  3596. elif Dry_btn and DI1 == 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  3597. print('乾燥槽 D', D_UP_tanklist.index('D_InputtingBean')+1, '優先入料中')
  3598. print('------- D', D_UP_tanklist.index('D_InputtingBean')+1, ' 入料中 -------')
  3599. elif Dry_btn and DI1 == 'DI_OutputtingBean' \
  3600. and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  3601. # 當達標準入料條件
  3602. if D1 == 'D_Waiting':
  3603. D1 = 'D_InputtingBean'
  3604. print('------- D1 狀態更新:入料中 -------')
  3605. elif D2 == 'D_Waiting':
  3606. D2 = 'D_InputtingBean'
  3607. print('------- D2 狀態更新:入料中 -------')
  3608. elif D3 == 'D_Waiting':
  3609. D3 = 'D_InputtingBean'
  3610. print('------- D3 狀態更新:入料中 -------')
  3611. elif D4 == 'D_Waiting':
  3612. D4 = 'D_InputtingBean'
  3613. print('------- D4 狀態更新:入料中 -------')
  3614. elif D5 == 'D_Waiting':
  3615. D5 = 'D_InputtingBean'
  3616. print('------- D5 狀態更新:入料中 -------')
  3617. elif D6 == 'D_Waiting':
  3618. D6 = 'D_InputtingBean'
  3619. print('------- D6 狀態更新:入料中 -------')
  3620. # ----- 乾燥桶槽 D1~D6 入料→入料暫停判斷 ------------------------------
  3621. Dry_InputtingBean_number = int(D_UP_tanklist.count('D_InputtingBean'))
  3622. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  3623. D_UP_tank_UltraSonic = []
  3624. for i in range(1, 7, 1):
  3625. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  3626. UltraSonic = int(tank_UltraSonic.UltraSonic)
  3627. D_UP_tank_UltraSonic.append(UltraSonic)
  3628. print('D_UP_tank_UltraSonic: ', D_UP_tank_UltraSonic)
  3629. # -- 取得乾燥桶槽 D1~D6 超音波生豆高度 UltraSonic -------------
  3630. if DI1 != 'DI_OutputtingBean' and Dry_InputtingBean_number >= 1:
  3631. if D1 == 'D_InputtingBean' and D_UP_tank_UltraSonic[0] < 110:
  3632. D1 = 'D_InputtingBean_Pause'
  3633. print('------- D1 狀態更新:入料暫停 -------')
  3634. else:
  3635. D1 = 'D_InputtingBean_Finish'
  3636. print('------- D1 狀態更新:入料完成 -------')
  3637. if D2 == 'D_InputtingBean' and D_UP_tank_UltraSonic[1] < 110:
  3638. D2 = 'D_InputtingBean_Pause'
  3639. print('------- D2 狀態更新:入料暫停 -------')
  3640. else:
  3641. D2 = 'D_InputtingBean_Finish'
  3642. print('------- D2 狀態更新:入料完成 -------')
  3643. if D3 == 'D_InputtingBean' and D_UP_tank_UltraSonic[2] < 110:
  3644. D3 = 'D_InputtingBean_Pause'
  3645. print('------- D3 狀態更新:入料暫停 -------')
  3646. else:
  3647. D3 = 'D_InputtingBean_Finish'
  3648. print('------- D3 狀態更新:入料完成 -------')
  3649. if D4 == 'D_InputtingBean' and D_UP_tank_UltraSonic[3] < 110:
  3650. D4 = 'D_InputtingBean_Pause'
  3651. print('------- D4 狀態更新:入料暫停 -------')
  3652. else:
  3653. D4 = 'D_InputtingBean_Finish'
  3654. print('------- D4 狀態更新:入料完成 -------')
  3655. if D5 == 'D_InputtingBean' and D_UP_tank_UltraSonic[4] < 110:
  3656. D5 = 'D_InputtingBean_Pause'
  3657. print('------- D5 狀態更新:入料暫停 -------')
  3658. else:
  3659. D5 = 'D_InputtingBean_Finish'
  3660. print('------- D5 狀態更新:入料完成 -------')
  3661. if D6 == 'D_InputtingBean' and D_UP_tank_UltraSonic[5] < 110:
  3662. D6 = 'D_InputtingBean_Pause'
  3663. print('------- D6 狀態更新:入料暫停 -------')
  3664. else:
  3665. D6 = 'D_InputtingBean_Finish'
  3666. print('------- D6 狀態更新:入料完成 -------')
  3667. # # ----- 乾燥桶槽 D1~D6 入料完成→乾燥判斷 ------------------------------
  3668. # Dry_InputtingBeanFinish_number = int(D_UP_tanklist.count('D_InputtingBean_Finish'))
  3669. # # 乾燥條件:當前桶槽入豆達指定高度, 則開始乾燥 (可以多桶乾燥)
  3670. # # !!! 乾燥槽 D_Drying 狀態應該請硬體判斷
  3671. # # !!! 若狀態為 D_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 D_Drying 乾燥
  3672. # if D1 == 'D_InputtingBean_Finish' or D1 == 'D_InputtingBean_Pause' and D_UP_tank_UltraSonic[0] >= 110:
  3673. # D1 = 'D_Drying'
  3674. # print('------- D1 狀態更新:乾燥中 -------')
  3675. # if D2 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[1] >= 110:
  3676. # D2 = 'D_Drying'
  3677. # print('------- D2 狀態更新:乾燥中 -------')
  3678. # if D3 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[2] >= 110:
  3679. # D3 = 'D_Drying'
  3680. # print('------- D3 狀態更新:乾燥中 -------')
  3681. # if D4 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[3] >= 110:
  3682. # D4 = 'D_Drying'
  3683. # print('------- D4 狀態更新:乾燥中 -------')
  3684. # if D5 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[4] >= 110:
  3685. # D5 = 'D_Drying'
  3686. # print('------- D5 狀態更新:乾燥中 -------')
  3687. # if D6 == 'D_InputtingBean_Finish' and D_UP_tank_UltraSonic[5] >= 110:
  3688. # D6 = 'D_Drying'
  3689. # print('------- D6 狀態更新:乾燥中 -------')
  3690. # ----- 乾燥桶槽 D1~D6 發酵→可出豆 判斷 ------------------------------
  3691. # !!! 發酵槽 D_OutputtingBean 狀態應該請硬體判斷
  3692. # !!! 若狀態為 D_Drying 且 達指定乾燥條件, 狀態改為 D_OutputtingBean 可出豆
  3693. # 可以多桶各自執行發酵排程
  3694. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  3695. if D1 == 'D_InputtingBean_Finish': D1 = 'D_OutputtingBean'
  3696. if D2 == 'D_InputtingBean_Finish': D2 = 'D_OutputtingBean'
  3697. if D3 == 'D_InputtingBean_Finish': D3 = 'D_OutputtingBean'
  3698. if D4 == 'D_InputtingBean_Finish': D4 = 'D_OutputtingBean'
  3699. if D5 == 'D_InputtingBean_Finish': D5 = 'D_OutputtingBean'
  3700. if D6 == 'D_InputtingBean_Finish': D6 = 'D_OutputtingBean'
  3701. # ----- [測試用] !!!!! D1~D6 入料完成→可出豆 判斷 ------------------------------
  3702. # # ----- 乾燥桶槽 D1~D6 可出豆→出料儲豆槽 DO1 判斷 ------------------------------
  3703. Dry_OutputtingBean_number = int(D_UP_tanklist.count('D_OutputtingBean'))
  3704. # # !!! 若出料儲豆槽狀態為 DO_Waiting(空桶等待) 且 桶槽狀態為 D_OutputtingBean 可出豆, 與 DO1 配合開始出豆
  3705. # if DO1 == 'DO_Waiting' and Dry_OutputtingBean_number >= 1:
  3706. # if D1 == 'D_OutputtingBean':
  3707. # DO1 = 'DO_InputtingBean'
  3708. # print('------- D1 狀態更新:出豆中 -------')
  3709. # print('------- DO1 狀態更新:入豆中 -------')
  3710. # elif D2 == 'D_OutputtingBean':
  3711. # DO1 = 'DO_InputtingBean'
  3712. # print('------- D2 狀態更新:出豆中 -------')
  3713. # print('------- DO1 狀態更新:入豆中 -------')
  3714. # elif D3 == 'D_OutputtingBean':
  3715. # DO1 = 'DO_InputtingBean'
  3716. # print('------- D3 狀態更新:出豆中 -------')
  3717. # print('------- DO1 狀態更新:入豆中 -------')
  3718. # elif D4 == 'D_OutputtingBean':
  3719. # DO1 = 'DO_InputtingBean'
  3720. # print('------- D4 狀態更新:出豆中 -------')
  3721. # print('------- DO1 狀態更新:入豆中 -------')
  3722. # elif D5 == 'D_OutputtingBean':
  3723. # DO1 = 'DO_InputtingBean'
  3724. # print('------- D5 狀態更新:出豆中 -------')
  3725. # print('------- DO1 狀態更新:入豆中 -------')
  3726. # elif D6 == 'D_OutputtingBean':
  3727. # DO1 = 'DO_InputtingBean'
  3728. # print('------- D6 狀態更新:出豆中 -------')
  3729. # print('------- DO1 狀態更新:入豆中 -------')
  3730. # ----- 乾燥入料儲豆槽 DI1~DI2 入豆→可出豆判斷 ------------------------------
  3731. # -- 取得乾燥入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  3732. DI_UP_UltraSoniclist = []
  3733. for i in range(1, 3, 1):
  3734. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + str(i)).order_by(text('datetime desc')).first()
  3735. UltraSonic = int(input_UltraSonic.UltraSonic)
  3736. DI_UP_UltraSoniclist.append(UltraSonic)
  3737. print('DI_UP_UltraSoniclist: ', DI_UP_UltraSoniclist)
  3738. # !!! 乾燥入料儲豆槽 D_OutputtingBean 狀態應該請硬體判斷
  3739. # 入料儲豆槽等待中、且發酵槽出料儲豆槽可出豆時, 入料儲豆槽入豆
  3740. if DI1 == 'DI_Waiting' and FO1 == 'FO_OutputtingBean':
  3741. DI1 = 'DI_InputtingBean'
  3742. print('------- DI1 狀態更新:入豆中 -------')
  3743. # 入料儲豆槽入豆時 且 (發酵儲豆槽有入料 或者 前方儲豆槽非可出豆), 則停止入豆
  3744. elif DI1 == 'DI_InputtingBean' and (DI_UP_UltraSoniclist[0] > 35) and (FO1 != 'FO_OutputtingBean') :
  3745. DI1 = 'DI_OutputtingBean'
  3746. print('------- DI1 狀態更新:可出豆 -------')
  3747. # 若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  3748. elif DI1 == 'DI_OutputtingBean' and (DI_UP_UltraSoniclist[0] < 40) and FO1 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  3749. DI1 = 'DI_InputtingBean'
  3750. print('------- DI1 狀態更新:入豆中 -------')
  3751. # if DI2 == 'DI_Waiting' and FO2 == 'FO_OutputtingBean':
  3752. # DI2 = 'DI_InputtingBean'
  3753. # print('------- DI2 狀態更新:入豆中 -------')
  3754. # elif DI2 == 'DI_InputtingBean' and ((DI_DOWN_UltraSoniclist[1] > 35) or (FO2 == 'FO_OutputtingBean')) :
  3755. # DI2 = 'DI_OutputtingBean'
  3756. # print('------- DI2 狀態更新:可出豆 -------')
  3757. # elif DI2 == 'DI_OutputtingBean' and (DI_DOWN_UltraSoniclist[1] < 40) and FO2 == 'FO_OutputtingBean' and Dry_InputtingBean_number == 0 and Dry_InputtingBeanPause_number == 0:
  3758. # DI2 = 'DI_InputtingBean'
  3759. # print('------- DI2 狀態更新:入豆中 -------')
  3760. # ----- 乾燥出料儲豆槽 DO1~DO2 入豆→可出豆判斷 ------------------------------
  3761. # -- 取得乾燥出料儲豆槽 DO1~DO2 桶內高度 UltraSonic -------------
  3762. DO_UP_UltraSoniclist = []
  3763. for i in range(1, 3, 1):
  3764. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + str(i)).order_by(text('datetime desc')).first()
  3765. UltraSonic = int(output_UltraSonic.UltraSonic)
  3766. DO_UP_UltraSoniclist.append(UltraSonic)
  3767. print('DO_UP_UltraSoniclist: ', DO_UP_UltraSoniclist)
  3768. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  3769. # 參考 -- 乾燥桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  3770. # 出料儲豆槽入料 且滿時, 出料儲豆槽可出豆
  3771. if DO1 == ('DO_InputtingBean' and DO_UP_UltraSoniclist[0] > 35):
  3772. DO1 = 'DO_OutputtingBean'
  3773. # 出料儲豆槽入料 且未滿, 桶槽可出豆已空
  3774. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  3775. D_UP_UltraSoniclist = []
  3776. for i in range(1, 7, 1):
  3777. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + str(i)).order_by(text('datetime desc')).first()
  3778. UltraSonic = int(tank_UltraSonic.UltraSonic)
  3779. D_UP_UltraSoniclist.append(UltraSonic)
  3780. print('D_UP_UltraSoniclist: ', D_UP_UltraSoniclist)
  3781. # -- 取得乾燥桶槽 D1~D6 桶內高度 UltraSonic -------------
  3782. if DO1 == 'DO_InputtingBean' and Dry_OutputtingBean_number >= 1:
  3783. if D1 == 'D_OutputtingBean' and D_UP_UltraSoniclist[0] < 5:
  3784. D1 = 'D_Waiting'
  3785. DO1 = 'DO_OutputtingBean'
  3786. print('------- D1 狀態更新:空桶等待 -------')
  3787. print('------- DO1 狀態更新:可出豆 -------')
  3788. elif D2 == 'D_OutputtingBean' and D_UP_UltraSoniclist[1] < 5:
  3789. D2 = 'D_Waiting'
  3790. DO1 = 'DO_OutputtingBean'
  3791. print('------- D2 狀態更新:空桶等待 -------')
  3792. print('------- DO1 狀態更新:可出豆 -------')
  3793. elif D3 == 'D_OutputtingBean' and D_UP_UltraSoniclist[2] < 5:
  3794. D3 = 'D_Waiting'
  3795. DO1 = 'DO_OutputtingBean'
  3796. print('------- D3 狀態更新:空桶等待 -------')
  3797. print('------- DO1 狀態更新:可出豆 -------')
  3798. elif D4 == 'D_OutputtingBean' and D_UP_UltraSoniclist[3] < 5:
  3799. D4 = 'D_Waiting'
  3800. DO1 = 'DO_OutputtingBean'
  3801. print('------- D4 狀態更新:空桶等待 -------')
  3802. print('------- DO1 狀態更新:可出豆 -------')
  3803. elif D5 == 'D_OutputtingBean' and D_UP_UltraSoniclist[4] < 5:
  3804. D5 = 'D_Waiting'
  3805. DO1 = 'DO_OutputtingBean'
  3806. print('------- D5 狀態更新:空桶等待 -------')
  3807. print('------- DO1 狀態更新:可出豆 -------')
  3808. elif D6 == 'D_OutputtingBean' and D_UP_UltraSoniclist[5] < 5:
  3809. D6 = 'D_Waiting'
  3810. DO1 = 'DO_OutputtingBean'
  3811. print('------- D6 狀態更新:空桶等待 -------')
  3812. print('------- DO1 狀態更新:可出豆 -------')
  3813. elif DO1 == 'DO_OutputtingBean' and DO_UP_UltraSoniclist[0] < 5:
  3814. DO1 = 'DO_Waiting'
  3815. # # ----- 將狀態寫入資料庫 ------------------------------
  3816. # # 獲取文本框的值並賦值給user實體對象
  3817. # D_status = dry_container_status()
  3818. # D_status.Dry_Input_1 = DI1
  3819. # D_status.Dry_Input_2 = DI2
  3820. # D_status.Dry_Tank_1 = D1
  3821. # D_status.Dry_Tank_2 = D2
  3822. # D_status.Dry_Tank_3 = D3
  3823. # D_status.Dry_Tank_4 = D4
  3824. # D_status.Dry_Tank_5 = D5
  3825. # D_status.Dry_Tank_6 = D6
  3826. # D_status.Dry_Tank_7 = D7
  3827. # D_status.Dry_Tank_8 = D8
  3828. # D_status.Dry_Tank_9 = D9
  3829. # D_status.Dry_Tank_10 = D10
  3830. # D_status.Dry_Tank_11 = D11
  3831. # D_status.Dry_Tank_12 = D12
  3832. # D_status.Dry_Output_1 = DO1
  3833. # D_status.Dry_Output_2 = DO2
  3834. # #將數據保存進資料庫
  3835. # db.session.add(D_status)
  3836. # # 手動提交
  3837. # db.session.commit()
  3838. # # ----- 將狀態寫入資料庫 ------------------------------
  3839. return jsonify({"Dry_Input_1":DI1,
  3840. "Dry_Tank_1":D1,
  3841. "Dry_Tank_2":D2,
  3842. "Dry_Tank_3":D3,
  3843. "Dry_Tank_4":D4,
  3844. "Dry_Tank_5":D5,
  3845. "Dry_Tank_6":D6,
  3846. "Dry_Output_1":DO1
  3847. })
  3848. # 1101 以流程圖判斷, 改寫 def dry_auto_status, 以上為原備份
  3849. # 發酵槽自動化測試頁
  3850. @main.route('/ferment_auto', methods=['GET', 'POST'])
  3851. def ferment_auto():
  3852. # 獲取登入信息
  3853. if 'id' in session and 'uname' in session and 'status' in session:
  3854. username = session['uname']
  3855. status = session['status']
  3856. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  3857. FI1 = ferment_status.Ferment_Input_1
  3858. FI2 = ferment_status.Ferment_Input_2
  3859. F1 = ferment_status.Ferment_Tank_1
  3860. F2 = ferment_status.Ferment_Tank_2
  3861. F3 = ferment_status.Ferment_Tank_3
  3862. F4 = ferment_status.Ferment_Tank_4
  3863. F5 = ferment_status.Ferment_Tank_5
  3864. F6 = ferment_status.Ferment_Tank_6
  3865. F7 = ferment_status.Ferment_Tank_7
  3866. F8 = ferment_status.Ferment_Tank_8
  3867. F9 = ferment_status.Ferment_Tank_9
  3868. F10 = ferment_status.Ferment_Tank_10
  3869. F11 = ferment_status.Ferment_Tank_11
  3870. F12 = ferment_status.Ferment_Tank_12
  3871. FO1 = ferment_status.Ferment_Output_1
  3872. FO2 = ferment_status.Ferment_Output_2
  3873. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  3874. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  3875. PO2 = clean_status.Peel_Output_2
  3876. # 感測器_發酵桶_SHT11
  3877. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3878. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  3879. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  3880. # 感測器_發酵桶_二氧化碳
  3881. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3882. CO2 = float(tank_CO2.CO2)
  3883. # 感測器_發酵桶_酸鹼值
  3884. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3885. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3886. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3887. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3888. PH = float(tank_PH.PH)
  3889. ORP = float(tank_ORP.ORP)
  3890. DO = float(tank_DO.DO)
  3891. EC = float(tank_EC.EC)
  3892. # 感測器_發酵桶_氣壓
  3893. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3894. PA = float(tank_PA.PA)
  3895. # 感測器_發酵桶_超音波感測器
  3896. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3897. UltraSonic= (float(tank_UltraSonic.UltraSonic))
  3898. # 感測器_發酵桶_保溫夾層水位計
  3899. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  3900. WaterLevel = tank_WaterLevel.WaterLevel
  3901. return render_template('ferment_auto.html', title="[測試] 發酵自動化", **locals())
  3902. else:
  3903. return render_template('sign_in.html')
  3904. @main.route('/fermentDEMO_auto_status', methods=['GET', 'POST'])
  3905. def fermentDEMO_auto_status():
  3906. info = request.args.to_dict()
  3907. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  3908. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  3909. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  3910. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  3911. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  3912. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  3913. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  3914. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  3915. Ferment_btn = True
  3916. # 從資料庫資料表中取得最新狀態
  3917. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  3918. FI1 = ferment_status.Ferment_Input_1 # FI1 = 'FI_OutputtingBean'
  3919. FI2 = ferment_status.Ferment_Input_2
  3920. F1 = ferment_status.Ferment_Tank_1
  3921. F2 = ferment_status.Ferment_Tank_2
  3922. F3 = ferment_status.Ferment_Tank_3
  3923. F4 = ferment_status.Ferment_Tank_4
  3924. F5 = ferment_status.Ferment_Tank_5
  3925. F6 = ferment_status.Ferment_Tank_6
  3926. F7 = ferment_status.Ferment_Tank_7
  3927. F8 = ferment_status.Ferment_Tank_8
  3928. F9 = ferment_status.Ferment_Tank_9
  3929. F10 = ferment_status.Ferment_Tank_10
  3930. F11 = ferment_status.Ferment_Tank_11
  3931. F12 = ferment_status.Ferment_Tank_12
  3932. FO1 = ferment_status.Ferment_Output_1
  3933. FO2 = ferment_status.Ferment_Output_2
  3934. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  3935. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  3936. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  3937. Ferment_Input_bean_empty = 2
  3938. Ferment_Tank_bean_empty = 2
  3939. Ferment_Output_bean_empty = 2
  3940. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  3941. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  3942. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  3943. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  3944. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  3945. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  3946. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  3947. FI_UP_UltraSoniclist = []
  3948. for i in range(1, 3, 1):
  3949. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3950. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  3951. UltraSonic = float(input_UltraSonic.UltraSonic)
  3952. FI_UP_UltraSoniclist.append(UltraSonic)
  3953. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  3954. F_UP_UltraSoniclist = []
  3955. for i in range(1, 7, 1):
  3956. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3957. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  3958. F_UP_UltraSoniclist.append(UltraSonic)
  3959. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  3960. FO_UP_UltraSoniclist = []
  3961. for i in range(1, 3, 1):
  3962. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  3963. UltraSonic = float(output_UltraSonic.UltraSonic)
  3964. FO_UP_UltraSoniclist.append(UltraSonic)
  3965. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  3966. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  3967. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  3968. F_UP_tank_WaterLevel = []
  3969. for i in range(1, 7, 1):
  3970. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3971. WaterLevel = float(tank_WaterLevel.WaterLevel)
  3972. F_UP_tank_WaterLevel.append(WaterLevel)
  3973. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  3974. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  3975. # -- 取得發酵桶槽 F1~F6 pH -------------
  3976. F_UP_tank_PH = []
  3977. for i in range(1, 7, 1):
  3978. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3979. PH = float(tank_PH.PH)
  3980. F_UP_tank_PH.append(PH)
  3981. print('F_UP_tank_PH: ', F_UP_tank_PH)
  3982. # -- 取得發酵桶槽 F1~F6 pH -------------
  3983. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3984. F_UP_tank_SHT11_Temp = []
  3985. for i in range(1, 7, 1):
  3986. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  3987. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  3988. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  3989. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  3990. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  3991. # ----- 發酵排程動作 start ------------------------------------------------------------------
  3992. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  3993. def FInputtingBean_TO_FInputtingBeanFinish(tid): # 1108 [測試] 入豆後直接出豆
  3994. # [致動器] 蝴蝶閥 OFF
  3995. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  3996. print('data: ', data)
  3997. # mqtt_f(data)
  3998. # [致動器] 真空吸料機 OFF
  3999. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4000. print('data: ', data)
  4001. # mqtt_f(data)
  4002. # [致動器] 馬達 0
  4003. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4004. print('data: ', data)
  4005. # mqtt_f(data)
  4006. # [致動器] 入料三通閥 ON排氣
  4007. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  4008. print('data: ', data)
  4009. # mqtt_f(data)
  4010. # print('------- ', tid,' 狀態更新:入料完成 -------')
  4011. print('------- ', tid,' 狀態更新:可出豆 -------')
  4012. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  4013. def FInputtingBean_AND_notfilled(tid):
  4014. # [致動器] 蝴蝶閥 OFF
  4015. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  4016. print('data: ', data)
  4017. # mqtt_f(data)
  4018. # [致動器] 入料三通閥 OFF入豆
  4019. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4020. print('data: ', data)
  4021. # mqtt_f(data)
  4022. # [致動器] 真空吸料機 ON
  4023. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  4024. print('data: ', data)
  4025. # mqtt_f(data)
  4026. timer = time.time()
  4027. while True:
  4028. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  4029. # [致動器] 入料真空吸料機 OFF
  4030. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4031. print('data: ', data)
  4032. # mqtt_f(data)
  4033. timer = time.time()
  4034. break
  4035. while True:
  4036. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  4037. break
  4038. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  4039. def FInputtingBean_TO_FInputtingBeanPause(tid):
  4040. # [致動器] 蝴蝶閥 OFF
  4041. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  4042. print('data: ', data)
  4043. # mqtt_f(data)
  4044. # [致動器] 真空吸料機 OFF
  4045. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4046. print('data: ', data)
  4047. # mqtt_f(data)
  4048. # [致動器] 入料三通閥 OFF入豆
  4049. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4050. print('data: ', data)
  4051. # mqtt_f(data)
  4052. # [致動器] 馬達 0
  4053. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4054. print('data: ', data)
  4055. # mqtt_f(data)
  4056. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  4057. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  4058. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  4059. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  4060. # [致動器] 入料三通閥 OFF入豆
  4061. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4062. print('data: ', data)
  4063. # mqtt_f(data)
  4064. # [致動器] 馬達 5
  4065. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  4066. print('data: ', data)
  4067. # mqtt_f(data)
  4068. print('------- ', tid, ' 狀態更新:入料中 -------')
  4069. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  4070. def FWaiting_TO_FInputtingBean(tid):
  4071. # [致動器] 蝴蝶閥 OFF
  4072. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "off" }
  4073. print('data: ', data)
  4074. # mqtt_f(data)
  4075. # [致動器] 入料三通閥 OFF入豆
  4076. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4077. print('data: ', data)
  4078. # mqtt_f(data)
  4079. # [致動器] 馬達 5
  4080. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  4081. print('data: ', data)
  4082. # mqtt_f(data)
  4083. print('------- ', tid, ' 狀態更新:入料中 -------')
  4084. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  4085. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  4086. print('------- ', tid,' 狀態更新:入水中 -------')
  4087. # # [致動器] 浮選三通閥 ON
  4088. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  4089. # print('data: ', data)
  4090. # # # mqtt_f(data)
  4091. # if (F_UP_tank_WaterLevel[sn] == 0):
  4092. # # [致動器] 桶外進水電磁閥 ON
  4093. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  4094. # print('data: ', data)
  4095. # # mqtt_f(data)
  4096. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  4097. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  4098. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  4099. print('data: ', data)
  4100. # mqtt_f(data)
  4101. # elif FermentUp_InputtingWater_number == 1:
  4102. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  4103. def FInputtingWater_TO_FFermenting(tid):
  4104. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  4105. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  4106. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  4107. # print('data: ', data)
  4108. # # mqtt_f(data)
  4109. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  4110. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  4111. print('data: ', data)
  4112. # mqtt_f(data)
  4113. print('------- ', tid, ' 狀態更新:發酵中 -------')
  4114. # [致動器] 馬達 (指定轉速)
  4115. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  4116. print('data: ', data)
  4117. # mqtt_f(data)
  4118. # [致動器] 溫控開關 ON
  4119. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  4120. # print('data: ', data)
  4121. # # mqtt_f(data)
  4122. # [致動器] 設定溫度、持溫時間
  4123. # [致動器] 加熱器 1 ON
  4124. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  4125. # print('data: ', data)
  4126. # mqtt_f(data)
  4127. # [致動器] 加熱器 2 ON
  4128. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  4129. # print('data: ', data)
  4130. # mqtt_f(data)
  4131. # # [致動器] 雙核薄膜泵 水質檢測 ON
  4132. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  4133. # print('data: ', data)
  4134. # # mqtt_f(data)
  4135. # TODO 增加發酵條件等
  4136. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  4137. def FInputtingWater_AND_WaterLevel1(tid):
  4138. # # [致動器] 桶外進水電磁閥 OFF
  4139. # data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  4140. # print('data: ', data)
  4141. # # mqtt_f(data)
  4142. pass
  4143. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  4144. def FInputtingWater_AND_tankwaterfilled(tid):
  4145. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  4146. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  4147. print('data: ', data)
  4148. # mqtt_f(data)
  4149. # else
  4150. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  4151. def FFermenting_TO_FOutputtingBean(tid):
  4152. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  4153. timer = time.time()
  4154. while True:
  4155. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  4156. # [致動器] 外桶浮選三通閥 OFF
  4157. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  4158. print('data: ', data)
  4159. # mqtt_f(data)
  4160. # [致動器] 馬達 0
  4161. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4162. print('data: ', data)
  4163. # mqtt_f(data)
  4164. # [致動器] 設定溫度 0
  4165. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  4166. # print('data: ', data)
  4167. # # mqtt_f(data)
  4168. # [致動器] 溫控開關 OFF
  4169. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  4170. # print('data: ', data)
  4171. # # mqtt_f(data)
  4172. # [致動器] 加熱器 1 OFF
  4173. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  4174. print('data: ', data)
  4175. # mqtt_f(data)
  4176. # [致動器] 加熱器 2 OFF
  4177. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  4178. print('data: ', data)
  4179. # mqtt_f(data)
  4180. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  4181. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  4182. # print('data: ', data)
  4183. # # mqtt_f(data)
  4184. # TODO 增加發酵條件等
  4185. break
  4186. # [致動器] 廢水排水閥 (桶內) ON
  4187. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  4188. print('data: ', data)
  4189. # mqtt_f(data)
  4190. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  4191. timer = time.time()
  4192. while True:
  4193. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  4194. # [致動器] 廢水排水閥 (桶內) OFF
  4195. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  4196. print('data: ', data)
  4197. # mqtt_f(data)
  4198. break
  4199. print('------- ', tid, ' 狀態更新:可出豆 -------')
  4200. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  4201. def FOutputtingBean_TO_FWaiting(tid):
  4202. # [致動器] F1 蝴蝶閥 ON
  4203. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  4204. print('data: ', data)
  4205. # mqtt_f(data)
  4206. # ----- 發酵排程動作 end ------------------------------------------------------------------
  4207. # [介面] 若啟用 發酵 狀態
  4208. if Ferment_btn:
  4209. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  4210. # 若 F1~F6 桶槽中有一個桶槽入豆中
  4211. if FermentUp_InputtingBean_number == 1:
  4212. # 若 F1 桶槽為入豆中
  4213. if F1 == 'F_InputtingBean':
  4214. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  4215. FInputtingBean_TO_FInputtingBeanFinish("F1")
  4216. # F1 = 'F_InputtingBean_Finish'
  4217. F1 = 'F_OutputtingBean'
  4218. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  4219. FInputtingBean_AND_notfilled("F1")
  4220. elif FI1 != 'FI_OutputtingBean':
  4221. FInputtingBean_TO_FInputtingBeanPause("F1")
  4222. F1 = 'F_InputtingBean_Pause'
  4223. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  4224. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  4225. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  4226. if F1 == 'F_InputtingBean_Pause':
  4227. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  4228. F1 = 'F_InputtingBean'
  4229. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  4230. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  4231. if F1 == 'F_Waiting':
  4232. FWaiting_TO_FInputtingBean("F1")
  4233. F1 = 'F_InputtingBean'
  4234. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  4235. elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  4236. if F1 == 'F_InputtingBean_Finish':
  4237. F1 = 'F_InputtingWater'
  4238. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  4239. elif FermentUp_InputtingWater_number == 1:
  4240. if F1 == 'F_InputtingWater':
  4241. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  4242. F1 = 'F_Fermenting'
  4243. FInputtingWater_TO_FFermenting("F1")
  4244. elif (F_UP_tank_WaterLevel[0] == 1):
  4245. FInputtingWater_AND_WaterLevel1("F1")
  4246. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  4247. FInputtingWater_AND_tankwaterfilled("F1")
  4248. else:
  4249. if F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp:
  4250. FFermenting_TO_FOutputtingBean("F1")
  4251. F1 = 'F_OutputtingBean'
  4252. # 將可出豆桶槽賦值
  4253. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  4254. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  4255. # TODO 發酵次數計算、消毒次數、校正
  4256. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  4257. if FOutputtingBean_Tank == 'F1':
  4258. FOutputtingBean_TO_FWaiting('F1')
  4259. FOutputtingBean_Tank = ''
  4260. F1 = 'F_Waiting'
  4261. print('------- F1 狀態更新:空桶等待 -------')
  4262. # 避免桶槽可出豆時未賦值
  4263. if FOutputtingBean_Tank == '':
  4264. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  4265. # 若桶槽 F1~F6 為清洗中
  4266. if F1 == 'F_Cleaning':
  4267. # FCleaning("F1")
  4268. F1 = 'F_Waiting'
  4269. print('------- F1 狀態更新:空桶等待 -------')
  4270. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  4271. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  4272. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  4273. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  4274. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  4275. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  4276. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  4277. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  4278. else:
  4279. # [介面] 若未啟用 發酵 狀態
  4280. print('未啟用發酵流程')
  4281. # ----- 將狀態寫入資料庫 ------------------------------
  4282. # 獲取文本框的值並賦值給user實體對象
  4283. F_status = ferment_container_status()
  4284. F_status.Ferment_Input_1 = FI1
  4285. F_status.Ferment_Input_2 = FI2
  4286. F_status.Ferment_Tank_1 = F1
  4287. F_status.Ferment_Tank_2 = F2
  4288. F_status.Ferment_Tank_3 = F3
  4289. F_status.Ferment_Tank_4 = F4
  4290. F_status.Ferment_Tank_5 = F5
  4291. F_status.Ferment_Tank_6 = F6
  4292. F_status.Ferment_Tank_7 = F7
  4293. F_status.Ferment_Tank_8 = F8
  4294. F_status.Ferment_Tank_9 = F9
  4295. F_status.Ferment_Tank_10 = F10
  4296. F_status.Ferment_Tank_11 = F11
  4297. F_status.Ferment_Tank_12 = F12
  4298. F_status.Ferment_Output_1 = FO1
  4299. F_status.Ferment_Output_2 = FO2
  4300. #將數據保存進資料庫
  4301. db.session.add(F_status)
  4302. # 手動提交
  4303. db.session.commit()
  4304. # ----- 將狀態寫入資料庫 ------------------------------
  4305. return jsonify({"Ferment_Tank_1":F1,
  4306. "Ferment_Tank_2":F2
  4307. })
  4308. @main.route('/ferment_auto_status', methods=['GET', 'POST'])
  4309. def ferment_auto_test():
  4310. info = request.args.to_dict()
  4311. # 寫定入料、桶槽、出料的空桶標準, 若 <= 2 則為空桶
  4312. Ferment_Input_bean_empty = 2
  4313. Ferment_Tank_bean_empty = 2
  4314. Ferment_Output_bean_empty = 2
  4315. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  4316. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  4317. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  4318. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  4319. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  4320. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  4321. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  4322. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  4323. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  4324. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  4325. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  4326. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  4327. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  4328. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  4329. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  4330. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  4331. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  4332. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  4333. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  4334. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  4335. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  4336. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  4337. Ferment_cb_vacuum = info['Ferment_cb_vacuum'] # 'true' 'false'
  4338. Ferment_cb_vacuum_time = float(info['Ferment_cb_vacuum_time'])
  4339. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  4340. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  4341. # 從資料庫資料表中取得最新狀態
  4342. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  4343. FI1 = ferment_status.Ferment_Input_1
  4344. FI2 = ferment_status.Ferment_Input_2
  4345. F1 = ferment_status.Ferment_Tank_1
  4346. F2 = ferment_status.Ferment_Tank_2
  4347. F3 = ferment_status.Ferment_Tank_3
  4348. F4 = ferment_status.Ferment_Tank_4
  4349. F5 = ferment_status.Ferment_Tank_5
  4350. F6 = ferment_status.Ferment_Tank_6
  4351. F7 = ferment_status.Ferment_Tank_7
  4352. F8 = ferment_status.Ferment_Tank_8
  4353. F9 = ferment_status.Ferment_Tank_9
  4354. F10 = ferment_status.Ferment_Tank_10
  4355. F11 = ferment_status.Ferment_Tank_11
  4356. F12 = ferment_status.Ferment_Tank_12
  4357. FO1 = ferment_status.Ferment_Output_1
  4358. FO2 = ferment_status.Ferment_Output_2
  4359. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  4360. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  4361. PO2 = clean_status.Peel_Output_2
  4362. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  4363. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  4364. FOutputtingBean_Tank = '' # 這是給出料儲豆槽判斷目前出豆的桶槽
  4365. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  4366. FermentUp_Waiting_number = int(F_UP_tanklist.count('F_Waiting'))
  4367. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  4368. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  4369. FermentUp_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  4370. FermentUp_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  4371. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic start -------------
  4372. FI_UP_UltraSoniclist = []
  4373. for i in range(1, 3, 1):
  4374. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  4375. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  4376. UltraSonic = float(input_UltraSonic.UltraSonic)
  4377. FI_UP_UltraSoniclist.append(UltraSonic)
  4378. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  4379. F_UP_UltraSoniclist = []
  4380. for i in range(1, 7, 1):
  4381. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  4382. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  4383. F_UP_UltraSoniclist.append(UltraSonic)
  4384. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  4385. FO_UP_UltraSoniclist = []
  4386. for i in range(1, 3, 1):
  4387. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  4388. UltraSonic = float(output_UltraSonic.UltraSonic)
  4389. FO_UP_UltraSoniclist.append(UltraSonic)
  4390. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  4391. # -- 取得發酵 入料儲豆槽 FI1~FI2 / 桶槽 F1~F6 / 出料 FO1~FO2 桶內高度 UltraSonic end -------------
  4392. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel start -------------
  4393. F_UP_tank_WaterLevel = []
  4394. for i in range(1, 7, 1):
  4395. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  4396. WaterLevel = float(tank_WaterLevel.WaterLevel)
  4397. F_UP_tank_WaterLevel.append(WaterLevel)
  4398. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  4399. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel end -------------
  4400. # -- 取得發酵桶槽 F1~F6 pH -------------
  4401. F_UP_tank_PH = []
  4402. for i in range(1, 7, 1):
  4403. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  4404. PH = float(tank_PH.PH)
  4405. F_UP_tank_PH.append(PH)
  4406. print('F_UP_tank_PH: ', F_UP_tank_PH)
  4407. # -- 取得發酵桶槽 F1~F6 pH -------------
  4408. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  4409. F_UP_tank_SHT11_Temp = []
  4410. for i in range(1, 7, 1):
  4411. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  4412. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  4413. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  4414. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  4415. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  4416. # ----- 發酵排程動作 start ------------------------------------------------------------------
  4417. # FI1 == 'FI_InputtingBean' AND if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  4418. def FIInputtingBean_filled(tid):
  4419. # [致動器] 入料真空吸料機 OFF
  4420. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  4421. print('data: ', data)
  4422. # mqtt_f(data)
  4423. print('------- ', tid, ' 狀態更新:可出豆 -------')
  4424. # FI1 == 'FI_InputtingBean' AND elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  4425. def FIInputtingBean_AND_notfilled(tid):
  4426. # [致動器] 入料真空吸料機 ON
  4427. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "on" }
  4428. print('data: ', data)
  4429. # mqtt_f(data)
  4430. # 暫停 (指定吸料時間) 秒
  4431. time.sleep(Ferment_Input_vacuumON_time)
  4432. # [致動器] 入料真空吸料機 OFF
  4433. data = { "tank_num": tid, "command": "input_vacuum_status", "value": "off" }
  4434. print('data: ', data)
  4435. # mqtt_f(data)
  4436. # 暫停 (指定放料時間) 秒
  4437. time.sleep(Ferment_Input_vacuumOFF_time)
  4438. # F1 == 'F_InputtingBean' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  4439. def FInputtingBean_TO_FInputtingBeanFinish(tid):
  4440. # [致動器] 真空吸料機 OFF
  4441. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4442. print('data: ', data)
  4443. # mqtt_f(data)
  4444. # [致動器] 馬達 0
  4445. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4446. print('data: ', data)
  4447. # mqtt_f(data)
  4448. # [致動器] 入料三通閥 ON排氣
  4449. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  4450. print('data: ', data)
  4451. # mqtt_f(data)
  4452. print('------- ', tid,' 狀態更新:入料完成 -------')
  4453. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  4454. def FInputtingBean_AND_notfilled(tid):
  4455. # [致動器] 入料三通閥 OFF入豆
  4456. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4457. print('data: ', data)
  4458. # mqtt_f(data)
  4459. # [致動器] 真空吸料機 ON
  4460. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  4461. print('data: ', data)
  4462. # mqtt_f(data)
  4463. # 暫停 (指定吸料時間) 秒
  4464. time.sleep(Ferment_Tank_vacuumON_time)
  4465. # [致動器] 入料真空吸料機 OFF
  4466. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4467. print('data: ', data)
  4468. # mqtt_f(data)
  4469. # 暫停 (指定吸料時間) 秒
  4470. time.sleep(Ferment_Tank_vacuumOFF_time)
  4471. # # [致動器] 真空吸料機 ON
  4472. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  4473. # print('data: ', data)
  4474. # # mqtt_f(data)
  4475. # timer = time.time()
  4476. # while True:
  4477. # if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  4478. # # [致動器] 入料真空吸料機 OFF
  4479. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4480. # print('data: ', data)
  4481. # # mqtt_f(data)
  4482. # timer = time.time()
  4483. # break
  4484. # while True:
  4485. # if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  4486. # break
  4487. # (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height) AND FI1 != 'FI_OutputtingBean'
  4488. def FInputtingBean_TO_FInputtingBeanPause(tid):
  4489. # [致動器] 真空吸料機 OFF
  4490. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4491. print('data: ', data)
  4492. # mqtt_f(data)
  4493. # [致動器] 入料三通閥 OFF入豆
  4494. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4495. print('data: ', data)
  4496. # mqtt_f(data)
  4497. # [致動器] 馬達 0
  4498. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4499. print('data: ', data)
  4500. # mqtt_f(data)
  4501. print('------- ', tid,' 狀態更新:入豆暫停 -------')
  4502. # FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean'
  4503. # if F1 == 'F_InputtingBean_Pause' AND FI1 == 'FI_OutputtingBean'
  4504. def FInputtingBeanPause_AND_FIOutputtingBean(tid):
  4505. # [致動器] 入料三通閥 OFF入豆
  4506. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4507. print('data: ', data)
  4508. # mqtt_f(data)
  4509. # [致動器] 馬達 5
  4510. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  4511. print('data: ', data)
  4512. # mqtt_f(data)
  4513. print('------- ', tid, ' 狀態更新:入料中 -------')
  4514. # elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1
  4515. def FWaiting_TO_FInputtingBean(tid):
  4516. # [致動器] 入料三通閥 OFF入豆
  4517. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "off" }
  4518. print('data: ', data)
  4519. # mqtt_f(data)
  4520. # [致動器] 馬達 5
  4521. data = { "tank_num": tid, "command": "tank_motor_status", "value": "5" }
  4522. print('data: ', data)
  4523. # mqtt_f(data)
  4524. print('------- ', tid, ' 狀態更新:入料中 -------')
  4525. # elif FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  4526. def FInputtingBeanFinish_TO_FInputtingWater_UP(tid, sn):
  4527. print('------- ', tid,' 狀態更新:入水中 -------')
  4528. # [致動器] 浮選三通閥 ON
  4529. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  4530. print('data: ', data)
  4531. # mqtt_f(data)
  4532. if (F_UP_tank_WaterLevel[sn] == 0):
  4533. # [致動器] 桶外進水電磁閥 ON
  4534. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "on" }
  4535. print('data: ', data)
  4536. # mqtt_f(data)
  4537. if (F_UP_UltraSoniclist[sn] < Ferment_Tank_water_height):
  4538. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  4539. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "on" }
  4540. print('data: ', data)
  4541. # mqtt_f(data)
  4542. # elif FermentUp_InputtingWater_number == 1:
  4543. # 'F_InputtingWater' if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  4544. def FInputtingWater_TO_FFermenting(tid):
  4545. # 若夾層入水達水位計高度 且 桶內入水達指定水位高度, 狀態轉換為發酵中
  4546. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  4547. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  4548. print('data: ', data)
  4549. # mqtt_f(data)
  4550. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  4551. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  4552. print('data: ', data)
  4553. # mqtt_f(data)
  4554. print('------- ', tid, ' 狀態更新:發酵中 -------')
  4555. # 若勾選 發酵時桶內抽真空?
  4556. if Ferment_cb_vacuum == 'true':
  4557. # [致動器] 入料三通閥 ON排氣
  4558. data = { "tank_num": tid, "command": "tank_threewayvalve_input_status", "value": "on" }
  4559. print('data: ', data)
  4560. # mqtt_f(data)
  4561. # [致動器] 外桶浮選三通閥 OFF
  4562. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  4563. print('data: ', data)
  4564. # mqtt_f(data)
  4565. # [致動器] 真空吸料機 ON
  4566. data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "on" }
  4567. print('data: ', data)
  4568. # mqtt_f(data)
  4569. # 暫停 (桶內抽氣時間) 秒
  4570. print(tid, '真空發酵, 桶槽抽氣 ' , Ferment_cb_vacuum_time, ' 秒')
  4571. time.sleep(Ferment_cb_vacuum_time)
  4572. # timer = time.time()
  4573. # while True:
  4574. # if (time.time() - timer) > Ferment_cb_vacuum_time:
  4575. # # [致動器] 入料真空吸料機 OFF
  4576. # data = { "tank_num": tid, "command": "tank_vacuum_status", "value": "off" }
  4577. # print('data: ', data)
  4578. # # mqtt_f(data)
  4579. # break
  4580. # [致動器] 馬達 (指定轉速)
  4581. data = { "tank_num": tid, "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  4582. print('data: ', data)
  4583. # mqtt_f(data)
  4584. # [致動器] 溫控開關 ON
  4585. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "on", "duration": Ferment_Tank_fermenting_time}
  4586. # print('data: ', data)
  4587. # # mqtt_f(data)
  4588. # [致動器] 設定溫度、持溫時間
  4589. # [致動器] 加熱器 1 ON
  4590. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "on" }
  4591. print('data: ', data)
  4592. # mqtt_f(data)
  4593. # [致動器] 加熱器 2 ON
  4594. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "on" }
  4595. print('data: ', data)
  4596. # mqtt_f(data)
  4597. # [致動器] 雙核薄膜泵 水質檢測 ON
  4598. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "on"}
  4599. print('data: ', data)
  4600. # mqtt_f(data)
  4601. # TODO 增加發酵條件等
  4602. # 'F_InputtingWater' AND (F_UP_tank_WaterLevel[0] == 1)
  4603. def FInputtingWater_AND_WaterLevel1(tid):
  4604. # [致動器] 桶外進水電磁閥 OFF
  4605. data = { "tank_num": tid, "command": "outer_solenoid_water_status", "value": "off" }
  4606. print('data: ', data)
  4607. # mqtt_f(data)
  4608. # 'F_InputtingWater' AND (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height)
  4609. def FInputtingWater_AND_tankwaterfilled(tid):
  4610. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  4611. data = { "tank_num": tid, "command": "tank_solenoid_water_in_status", "value": "off" }
  4612. print('data: ', data)
  4613. # mqtt_f(data)
  4614. # else
  4615. # F1 == 'F_Fermenting' and F_UP_tank_SHT11_Temp[0] >= Ferment_Tank_fermenting_temp and F_UP_tank_PH[0] <= Ferment_Tank_fermenting_pH:
  4616. def FFermenting_TO_FOutputtingBean(tid):
  4617. # 暫停 (桶內抽氣時間) 秒
  4618. print(tid, ' 發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  4619. time.sleep(Ferment_Tank_fermenting_time)
  4620. # [致動器] 外桶浮選三通閥 OFF
  4621. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  4622. print('data: ', data)
  4623. # mqtt_f(data)
  4624. # [致動器] 馬達 0
  4625. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4626. print('data: ', data)
  4627. # mqtt_f(data)
  4628. # [致動器] 設定溫度 0
  4629. data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  4630. print('data: ', data)
  4631. # mqtt_f(data)
  4632. # [致動器] 溫控開關 OFF
  4633. # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  4634. # print('data: ', data)
  4635. # # mqtt_f(data)
  4636. # [致動器] 加熱器 1 OFF
  4637. data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  4638. print('data: ', data)
  4639. # mqtt_f(data)
  4640. # [致動器] 加熱器 2 OFF
  4641. data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  4642. print('data: ', data)
  4643. # mqtt_f(data)
  4644. # [致動器] 雙核薄膜泵 水質檢測 OFF
  4645. data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  4646. print('data: ', data)
  4647. # mqtt_f(data)
  4648. # timer = time.time()
  4649. # while True:
  4650. # if (time.time() - timer) > Ferment_Tank_fermenting_time :
  4651. # # [致動器] 外桶浮選三通閥 OFF
  4652. # data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  4653. # print('data: ', data)
  4654. # # mqtt_f(data)
  4655. # # [致動器] 馬達 0
  4656. # data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4657. # print('data: ', data)
  4658. # # mqtt_f(data)
  4659. # # [致動器] 設定溫度 0
  4660. # data = { "tank_num": tid, "command": "tank_temp", "value": "0" }
  4661. # print('data: ', data)
  4662. # # mqtt_f(data)
  4663. # # [致動器] 溫控開關 OFF
  4664. # # data = { "tank_num": tid, "command": "tank_temp_enable", "value": "off" }
  4665. # # print('data: ', data)
  4666. # # # mqtt_f(data)
  4667. # # [致動器] 加熱器 1 OFF
  4668. # data = { "tank_num": tid, "command": "tank_heater1_status", "value": "off" }
  4669. # print('data: ', data)
  4670. # # mqtt_f(data)
  4671. # # [致動器] 加熱器 2 OFF
  4672. # data = { "tank_num": tid, "command": "tank_heater2_status", "value": "off" }
  4673. # print('data: ', data)
  4674. # # mqtt_f(data)
  4675. # # [致動器] 雙核薄膜泵 水質檢測 OFF
  4676. # data = { "tank_num": tid, "command": "tank_pump_sensor_status", "value": "off"}
  4677. # print('data: ', data)
  4678. # # mqtt_f(data)
  4679. # # TODO 增加發酵條件等
  4680. # break
  4681. # [致動器] 廢水排水閥 (桶內) ON
  4682. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  4683. print('data: ', data)
  4684. # mqtt_f(data)
  4685. # 暫停 (桶內抽氣時間) 秒
  4686. print(tid, '桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  4687. time.sleep(Ferment_Tank_WaterOut_time)
  4688. # [致動器] 廢水排水閥 (桶內) OFF
  4689. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  4690. print('data: ', data)
  4691. # mqtt_f(data)
  4692. # timer = time.time()
  4693. # while True:
  4694. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  4695. # # [致動器] 廢水排水閥 (桶內) OFF
  4696. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  4697. # print('data: ', data)
  4698. # # mqtt_f(data)
  4699. # break
  4700. print('------- ', tid, ' 狀態更新:可出豆 -------')
  4701. # else: if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  4702. def FOutputtingBean_TO_FWaiting(tid):
  4703. # [致動器] F1 蝴蝶閥 ON
  4704. data = { "tank_num": tid, "command": "tank_diskvalve_status", "value": "on" }
  4705. print('data: ', data)
  4706. # mqtt_f(data)
  4707. # F_Cleaning
  4708. def FCleaning(tid):
  4709. # [致動器] 浮選三通閥 OFF
  4710. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "off" }
  4711. print('data: ', data)
  4712. # mqtt_f(data)
  4713. # [致動器] 逆洗雙核薄膜泵電磁閥 ON
  4714. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "on" }
  4715. print('data: ', data)
  4716. # mqtt_f(data)
  4717. # [致動器] 馬達 10
  4718. data = { "tank_num": tid, "command": "tank_motor_status", "value": "10" }
  4719. print('data: ', data)
  4720. # mqtt_f(data)
  4721. # [致動器] 消毒電磁閥 ON
  4722. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "on" }
  4723. print('data: ', data)
  4724. # mqtt_f(data)
  4725. # [致動器] 消毒抽水 Pump ON TODO
  4726. # 暫停 (消毒時間) 秒
  4727. print(tid, ' 桶內消毒 ', Ferment_Tank_Disinfect_time, ' 秒')
  4728. time.sleep(Ferment_Tank_Disinfect_time)
  4729. # [致動器] 消毒電磁閥 OFF
  4730. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  4731. print('data: ', data)
  4732. # mqtt_f(data)
  4733. # timer = time.time()
  4734. # while True:
  4735. # if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  4736. # # [致動器] 消毒電磁閥 OFF
  4737. # data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  4738. # print('data: ', data)
  4739. # # mqtt_f(data)
  4740. # break
  4741. # [致動器] 消毒抽水 Pump OFF TODO
  4742. # [致動器] 馬達 0
  4743. data = { "tank_num": tid, "command": "tank_motor_status", "value": "0" }
  4744. print('data: ', data)
  4745. # mqtt_f(data)
  4746. # [致動器] 浮選三通閥 ON
  4747. data = { "tank_num": tid, "command": "outer_threewayvalve_float_status", "value": "on" }
  4748. print('data: ', data)
  4749. # mqtt_f(data)
  4750. # [致動器] 逆洗雙核薄膜泵電磁閥 OFF
  4751. data = { "tank_num": tid, "command": "solenoid_tank_pump_status", "value": "off" }
  4752. print('data: ', data)
  4753. # mqtt_f(data)
  4754. # [致動器] 消毒電磁閥 OFF
  4755. data = { "tank_num": tid, "command": "tank_solenoid_disinfect_status", "value": "off" }
  4756. print('data: ', data)
  4757. # mqtt_f(data)
  4758. # [致動器] 廢水排水閥 (桶內) ON
  4759. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "on" }
  4760. print('data: ', data)
  4761. # mqtt_f(data)
  4762. print(tid, ' 桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  4763. time.sleep(Ferment_Tank_WaterOut_time)
  4764. # [致動器] 廢水排水閥 (桶內) OFF
  4765. data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  4766. print('data: ', data)
  4767. # mqtt_f(data)
  4768. # timer = time.time()
  4769. # while True:
  4770. # if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  4771. # # [致動器] 廢水排水閥 (桶內) OFF
  4772. # data = { "tank_num": tid, "command": "tank_solenoid_water_out_status", "value": "off" }
  4773. # print('data: ', data)
  4774. # # mqtt_f(data)
  4775. # break
  4776. print('------- ', tid, ' 狀態更新:空桶等待 -------')
  4777. # elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '': AND elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  4778. def FOInputtingBean_filled(tid):
  4779. # [致動器] 出料真空吸料機 ON
  4780. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  4781. print('data: ', data)
  4782. # mqtt_f(data)
  4783. # 暫停 (指定吸料時間) 秒
  4784. time.sleep(Ferment_Output_vacuumON_time)
  4785. # [致動器] 出料真空吸料機 OFF
  4786. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  4787. print('data: ', data)
  4788. # mqtt_f(data)
  4789. # 暫停 (指定放料時間) 秒
  4790. time.sleep(Ferment_Output_vacuumOFF_time)
  4791. # # [致動器] 出料真空吸料機 ON
  4792. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "on" }
  4793. # print('data: ', data)
  4794. # # mqtt_f(data)
  4795. # timer = time.time()
  4796. # while True:
  4797. # if (time.time() - timer) > Ferment_Output_vacuumON_time:
  4798. # # [致動器] 出料真空吸料機 OFF
  4799. # data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  4800. # print('data: ', data)
  4801. # # mqtt_f(data)
  4802. # timer = time.time()
  4803. # break
  4804. # while True:
  4805. # if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  4806. # break
  4807. # ----- 發酵排程動作 end ------------------------------------------------------------------
  4808. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  4809. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  4810. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  4811. FI1 = 'FI_InputtingBean'
  4812. print('------- FI1 狀態更新:入豆中 -------')
  4813. # 入料儲豆槽入豆時
  4814. elif FI1 == 'FI_InputtingBean':
  4815. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  4816. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  4817. FIInputtingBean_filled("FI1")
  4818. FI1 = 'FI_OutputtingBean'
  4819. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  4820. elif (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  4821. FI1_thread = threading.Thread(target=FIInputtingBean_AND_notfilled, args=["FI1"])
  4822. FI1_thread.start()
  4823. # 桶槽內大於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為可出豆
  4824. elif (FI_UP_UltraSoniclist[0] > Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  4825. FI1 = 'FI_OutputtingBean'
  4826. print('------- FI1 狀態更新:可出豆 -------')
  4827. # 桶槽內小於空桶高度, 且 前方 PO1 非可出豆, 將狀態轉為空桶等待
  4828. elif (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty) and PO1 != 'PO_OutputtingBean':
  4829. FI1 = 'FI_Waiting'
  4830. print('------- FI1 狀態更新:空桶等待 -------')
  4831. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  4832. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  4833. FI1 = 'FI_Waiting'
  4834. print('------- FI1 狀態更新:空桶等待 -------')
  4835. # [介面] 若啟用 發酵 狀態
  4836. if Ferment_btn:
  4837. # ----- 發酵桶槽 F1~F6 入料桶槽優先入料判斷 ------------------------------
  4838. # 若 F1~F6 桶槽中有一個桶槽入豆中
  4839. if FermentUp_InputtingBean_number == 1:
  4840. # 若 F1 桶槽為入豆中
  4841. if F1 == 'F_InputtingBean':
  4842. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  4843. FInputtingBean_TO_FInputtingBeanFinish("F1")
  4844. F1 = 'F_InputtingBean_Finish'
  4845. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  4846. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  4847. F1_thread.start()
  4848. elif FI1 != 'FI_OutputtingBean':
  4849. FInputtingBean_TO_FInputtingBeanPause("F1")
  4850. F1 = 'F_InputtingBean_Pause'
  4851. elif F2 == 'F_InputtingBean':
  4852. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  4853. FInputtingBean_TO_FInputtingBeanFinish("F2")
  4854. F2 = 'F_InputtingBean_Finish'
  4855. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  4856. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  4857. F2_thread.start()
  4858. elif FI1 != 'FI_OutputtingBean':
  4859. FInputtingBean_TO_FInputtingBeanPause("F2")
  4860. F2 = 'F_InputtingBean_Pause'
  4861. elif F3 == 'F_InputtingBean':
  4862. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  4863. FInputtingBean_TO_FInputtingBeanFinish("F3")
  4864. F3 = 'F_InputtingBean_Finish'
  4865. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  4866. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  4867. F3_thread.start()
  4868. elif FI1 != 'FI_OutputtingBean':
  4869. FInputtingBean_TO_FInputtingBeanPause("F3")
  4870. F3 = 'F_InputtingBean_Pause'
  4871. elif F4 == 'F_InputtingBean':
  4872. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  4873. FInputtingBean_TO_FInputtingBeanFinish("F4")
  4874. F4 = 'F_InputtingBean_Finish'
  4875. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  4876. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  4877. F4_thread.start()
  4878. elif FI1 != 'FI_OutputtingBean':
  4879. FInputtingBean_TO_FInputtingBeanPause("F4")
  4880. F4 = 'F_InputtingBean_Pause'
  4881. elif F5 == 'F_InputtingBean':
  4882. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  4883. FInputtingBean_TO_FInputtingBeanFinish("F5")
  4884. F5 = 'F_InputtingBean_Finish'
  4885. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  4886. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  4887. F5_thread.start()
  4888. elif FI1 != 'FI_OutputtingBean':
  4889. FInputtingBean_TO_FInputtingBeanPause("F5")
  4890. F5 = 'F_InputtingBean_Pause'
  4891. elif F6 == 'F_InputtingBean':
  4892. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  4893. FInputtingBean_TO_FInputtingBeanFinish("F6")
  4894. F6 = 'F_InputtingBean_Finish'
  4895. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  4896. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  4897. F6_thread.start()
  4898. elif FI1 != 'FI_OutputtingBean':
  4899. FInputtingBean_TO_FInputtingBeanPause("F6")
  4900. F6 = 'F_InputtingBean_Pause'
  4901. # 若 F1~F6 桶槽中有一個桶槽入豆暫停中, 且 FI1 可出豆
  4902. elif FermentUp_InputtingBeanPause_number == 1 and FI1 == 'FI_OutputtingBean':
  4903. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  4904. if F1 == 'F_InputtingBean_Pause':
  4905. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  4906. F1 = 'F_InputtingBean'
  4907. elif F2 == 'F_InputtingBean_Pause':
  4908. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  4909. F2 = 'F_InputtingBean'
  4910. elif F3 == 'F_InputtingBean_Pause':
  4911. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  4912. F3 = 'F_InputtingBean'
  4913. elif F4 == 'F_InputtingBean_Pause':
  4914. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  4915. F4 = 'F_InputtingBean'
  4916. elif F5 == 'F_InputtingBean_Pause':
  4917. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  4918. F5 = 'F_InputtingBean'
  4919. elif F6 == 'F_InputtingBean_Pause':
  4920. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  4921. F6 = 'F_InputtingBean'
  4922. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料中, 則桶號小者優先入料
  4923. elif FermentUp_InputtingBean_number >= 2:
  4924. if F1 == 'F_InputtingBean':
  4925. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  4926. FInputtingBean_TO_FInputtingBeanFinish("F1")
  4927. F1 = 'F_InputtingBean_Finish'
  4928. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height):
  4929. F1_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F1"])
  4930. F1_thread.start()
  4931. elif FI1 != 'FI_OutputtingBean':
  4932. FInputtingBean_TO_FInputtingBeanPause("F1")
  4933. F1 = 'F_InputtingBean_Pause'
  4934. elif F2 == 'F_InputtingBean':
  4935. if (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  4936. FInputtingBean_TO_FInputtingBeanFinish("F2")
  4937. F2 = 'F_InputtingBean_Finish'
  4938. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height):
  4939. F2_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F2"])
  4940. F2_thread.start()
  4941. elif FI1 != 'FI_OutputtingBean':
  4942. FInputtingBean_TO_FInputtingBeanPause("F2")
  4943. F2 = 'F_InputtingBean_Pause'
  4944. elif F3 == 'F_InputtingBean':
  4945. if (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  4946. FInputtingBean_TO_FInputtingBeanFinish("F3")
  4947. F3 = 'F_InputtingBean_Finish'
  4948. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height):
  4949. F3_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F3"])
  4950. F3_thread.start()
  4951. elif FI1 != 'FI_OutputtingBean':
  4952. FInputtingBean_TO_FInputtingBeanPause("F3")
  4953. F3 = 'F_InputtingBean_Pause'
  4954. elif F4 == 'F_InputtingBean':
  4955. if (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  4956. FInputtingBean_TO_FInputtingBeanFinish("F4")
  4957. F4 = 'F_InputtingBean_Finish'
  4958. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height):
  4959. F4_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F4"])
  4960. F4_thread.start()
  4961. elif FI1 != 'FI_OutputtingBean':
  4962. FInputtingBean_TO_FInputtingBeanPause("F4")
  4963. F4 = 'F_InputtingBean_Pause'
  4964. elif F5 == 'F_InputtingBean':
  4965. if (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  4966. FInputtingBean_TO_FInputtingBeanFinish("F5")
  4967. F5 = 'F_InputtingBean_Finish'
  4968. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height):
  4969. F5_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F5"])
  4970. F5_thread.start()
  4971. elif FI1 != 'FI_OutputtingBean':
  4972. FInputtingBean_TO_FInputtingBeanPause("F5")
  4973. F5 = 'F_InputtingBean_Pause'
  4974. elif F6 == 'F_InputtingBean':
  4975. if (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  4976. FInputtingBean_TO_FInputtingBeanFinish("F6")
  4977. F6 = 'F_InputtingBean_Finish'
  4978. elif FI1 == 'FI_OutputtingBean' and (F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height):
  4979. F6_thread = threading.Thread(target=FInputtingBean_AND_notfilled, args=["F6"])
  4980. F6_thread.start()
  4981. elif FI1 != 'FI_OutputtingBean':
  4982. FInputtingBean_TO_FInputtingBeanPause("F6")
  4983. F6 = 'F_InputtingBean_Pause'
  4984. # 若 F1~F6 桶槽中, 兩個桶槽皆為 入料暫停中, 則桶號小者優先入料
  4985. elif FermentUp_InputtingBeanPause_number >= 2 and FI1 == 'FI_OutputtingBean':
  4986. # 若 F1 桶槽為入豆暫停 且 FI1 可出料
  4987. if F1 == 'F_InputtingBean_Pause':
  4988. FInputtingBeanPause_AND_FIOutputtingBean("F1")
  4989. F1 = 'F_InputtingBean'
  4990. elif F2 == 'F_InputtingBean_Pause':
  4991. FInputtingBeanPause_AND_FIOutputtingBean("F2")
  4992. F2 = 'F_InputtingBean'
  4993. elif F3 == 'F_InputtingBean_Pause':
  4994. FInputtingBeanPause_AND_FIOutputtingBean("F3")
  4995. F3 = 'F_InputtingBean'
  4996. elif F4 == 'F_InputtingBean_Pause':
  4997. FInputtingBeanPause_AND_FIOutputtingBean("F4")
  4998. F4 = 'F_InputtingBean'
  4999. elif F5 == 'F_InputtingBean_Pause':
  5000. FInputtingBeanPause_AND_FIOutputtingBean("F5")
  5001. F5 = 'F_InputtingBean'
  5002. elif F6 == 'F_InputtingBean_Pause':
  5003. FInputtingBeanPause_AND_FIOutputtingBean("F6")
  5004. F6 = 'F_InputtingBean'
  5005. # 若 F1~F6 桶槽中 無桶槽正在入料或入料等待, 且 FI1 可出豆時
  5006. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0 and FI1 == 'FI_OutputtingBean' and FermentUp_Waiting_number >= 1:
  5007. if F1 == 'F_Waiting':
  5008. FWaiting_TO_FInputtingBean("F1")
  5009. F1 = 'F_InputtingBean'
  5010. elif F2 == 'F_Waiting':
  5011. FWaiting_TO_FInputtingBean("F2")
  5012. F2 = 'F_InputtingBean'
  5013. elif F3 == 'F_Waiting':
  5014. FWaiting_TO_FInputtingBean("F3")
  5015. F3 = 'F_InputtingBean'
  5016. elif F4 == 'F_Waiting':
  5017. FWaiting_TO_FInputtingBean("F4")
  5018. F4 = 'F_InputtingBean'
  5019. elif F5 == 'F_Waiting':
  5020. FWaiting_TO_FInputtingBean("F5")
  5021. F5 = 'F_InputtingBean'
  5022. elif F6 == 'F_Waiting':
  5023. FWaiting_TO_FInputtingBean("F6")
  5024. F6 = 'F_InputtingBean'
  5025. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  5026. if FermentUp_InputtingWater_number == 0 and FermentUp_InputtingBeanFinish_number >= 1:
  5027. if F1 == 'F_InputtingBean_Finish':
  5028. F1 = 'F_InputtingWater'
  5029. FInputtingBeanFinish_TO_FInputtingWater_UP("F1", 0)
  5030. elif F2 == 'F_InputtingBean_Finish':
  5031. F2 = 'F_InputtingWater'
  5032. FInputtingBeanFinish_TO_FInputtingWater_UP("F2", 1)
  5033. elif F3 == 'F_InputtingBean_Finish':
  5034. F3 = 'F_InputtingWater'
  5035. FInputtingBeanFinish_TO_FInputtingWater_UP("F3", 2)
  5036. elif F4 == 'F_InputtingBean_Finish':
  5037. F4 = 'F_InputtingWater'
  5038. FInputtingBeanFinish_TO_FInputtingWater_UP("F4", 3)
  5039. elif F5 == 'F_InputtingBean_Finish':
  5040. F5 = 'F_InputtingWater'
  5041. FInputtingBeanFinish_TO_FInputtingWater_UP("F5", 4)
  5042. elif F6 == 'F_InputtingBean_Finish':
  5043. F6 = 'F_InputtingWater'
  5044. FInputtingBeanFinish_TO_FInputtingWater_UP("F6", 5)
  5045. # 若 F1~F6 桶槽中 無桶槽正在入水, 則入豆完成者轉換狀態 開始入水
  5046. if FermentUp_InputtingWater_number == 1:
  5047. if F1 == 'F_InputtingWater':
  5048. if (F_UP_tank_WaterLevel[0] == 1) and (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  5049. F1 = 'F_Fermenting'
  5050. F1_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F1"])
  5051. F1_thread.start()
  5052. elif (F_UP_tank_WaterLevel[0] == 1):
  5053. FInputtingWater_AND_WaterLevel1("F1")
  5054. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  5055. FInputtingWater_AND_tankwaterfilled("F1")
  5056. elif F2 == 'F_InputtingWater':
  5057. if (F_UP_tank_WaterLevel[1] == 1) and (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  5058. F2 = 'F_Fermenting'
  5059. F2_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F2"])
  5060. F2_thread.start()
  5061. elif (F_UP_tank_WaterLevel[1] == 1):
  5062. FInputtingWater_AND_WaterLevel1("F2")
  5063. elif (F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height):
  5064. FInputtingWater_AND_tankwaterfilled("F2")
  5065. elif F3 == 'F_InputtingWater':
  5066. if (F_UP_tank_WaterLevel[2] == 1) and (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  5067. F3 = 'F_Fermenting'
  5068. F3_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F3"])
  5069. F3_thread.start()
  5070. elif (F_UP_tank_WaterLevel[2] == 1):
  5071. FInputtingWater_AND_WaterLevel1("F3")
  5072. elif (F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height):
  5073. FInputtingWater_AND_tankwaterfilled("F3")
  5074. elif F4 == 'F_InputtingWater':
  5075. if (F_UP_tank_WaterLevel[3] == 1) and (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  5076. F4 = 'F_Fermenting'
  5077. F4_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F4"])
  5078. F4_thread.start()
  5079. elif (F_UP_tank_WaterLevel[3] == 1):
  5080. FInputtingWater_AND_WaterLevel1("F4")
  5081. elif (F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height):
  5082. FInputtingWater_AND_tankwaterfilled("F4")
  5083. elif F5 == 'F_InputtingWater':
  5084. if (F_UP_tank_WaterLevel[4] == 1) and (F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height):
  5085. F5 = 'F_Fermenting'
  5086. F5_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F5"])
  5087. F5_thread.start()
  5088. elif (F_UP_tank_WaterLevel[0] == 1):
  5089. FInputtingWater_AND_WaterLevel1("F5")
  5090. elif (F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height):
  5091. FInputtingWater_AND_tankwaterfilled("F5")
  5092. elif F6 == 'F_InputtingWater':
  5093. if (F_UP_tank_WaterLevel[5] == 1) and (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  5094. F6 = 'F_Fermenting'
  5095. F6_thread = threading.Thread(target=FInputtingWater_TO_FFermenting, args=["F6"])
  5096. F6_thread.start()
  5097. elif (F_UP_tank_WaterLevel[5] == 1):
  5098. FInputtingWater_AND_WaterLevel1("F6")
  5099. elif (F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height):
  5100. FInputtingWater_AND_tankwaterfilled("F6")
  5101. else:
  5102. print("else ---------------------------- ")
  5103. 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:
  5104. F1_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F1"])
  5105. F1_thread.start()
  5106. F1 = 'F_OutputtingBean'
  5107. # 將可出豆桶槽賦值
  5108. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F1'
  5109. if F2 == 'F_Fermenting':
  5110. F2_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F2"])
  5111. F2_thread.start()
  5112. F2 = 'F_OutputtingBean'
  5113. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F2'
  5114. if F3 == 'F_Fermenting':
  5115. F3_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F3"])
  5116. F3_thread.start()
  5117. F3 = 'F_OutputtingBean'
  5118. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F3'
  5119. if F4 == 'F_Fermenting':
  5120. F4_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F4"])
  5121. F4_thread.start()
  5122. F4 = 'F_OutputtingBean'
  5123. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F4'
  5124. if F5 == 'F_Fermenting':
  5125. F5_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F5"])
  5126. F5_thread.start()
  5127. F5 = 'F_OutputtingBean'
  5128. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F5'
  5129. if F6 == 'F_Fermenting':
  5130. F6_thread = threading.Thread(target=FFermenting_TO_FOutputtingBean, args=["F6"])
  5131. F6_thread.start()
  5132. F6 = 'F_OutputtingBean'
  5133. if FOutputtingBean_Tank == '': FOutputtingBean_Tank = 'F6'
  5134. # 若桶槽 F1~F6 可出豆 且 桶槽內為空桶 且 有指定清洗排程, 進行清洗桶槽
  5135. # TODO 發酵次數計算、消毒次數、校正
  5136. if F1 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[0] <= Ferment_Tank_bean_empty):
  5137. if FOutputtingBean_Tank == 'F1':
  5138. FOutputtingBean_TO_FWaiting('F1')
  5139. FOutputtingBean_Tank = ''
  5140. if (FermentAuto_cleaning == 0): F1 = 'F_Waiting'
  5141. elif (FermentAuto_cleaning != 0): F1 = 'F_Cleaning'
  5142. if F2 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[1] <= Ferment_Tank_bean_empty):
  5143. if FOutputtingBean_Tank == 'F2':
  5144. FOutputtingBean_TO_FWaiting('F2')
  5145. FOutputtingBean_Tank = ''
  5146. if (FermentAuto_cleaning == 0): F2 = 'F_Waiting'
  5147. elif (FermentAuto_cleaning != 0): F2 = 'F_Cleaning'
  5148. if F3 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[2] <= Ferment_Tank_bean_empty):
  5149. if FOutputtingBean_Tank == 'F3':
  5150. FOutputtingBean_TO_FWaiting('F3')
  5151. FOutputtingBean_Tank = ''
  5152. if (FermentAuto_cleaning == 0): F3 = 'F_Waiting'
  5153. elif (FermentAuto_cleaning != 0): F3 = 'F_Cleaning'
  5154. if F4 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[3] <= Ferment_Tank_bean_empty):
  5155. if FOutputtingBean_Tank == 'F4':
  5156. FOutputtingBean_TO_FWaiting('F4')
  5157. FOutputtingBean_Tank = ''
  5158. if (FermentAuto_cleaning == 0): F4 = 'F_Waiting'
  5159. elif (FermentAuto_cleaning != 0): F4 = 'F_Cleaning'
  5160. if F5 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[4] <= Ferment_Tank_bean_empty):
  5161. if FOutputtingBean_Tank == 'F5':
  5162. FOutputtingBean_TO_FWaiting('F5')
  5163. FOutputtingBean_Tank = ''
  5164. if (FermentAuto_cleaning == 0): F5 = 'F_Waiting'
  5165. elif (FermentAuto_cleaning != 0): F5 = 'F_Cleaning'
  5166. if F6 == 'F_OutputtingBean' and (F_UP_UltraSoniclist[5] <= Ferment_Tank_bean_empty):
  5167. if FOutputtingBean_Tank == 'F6':
  5168. FOutputtingBean_TO_FWaiting('F6')
  5169. FOutputtingBean_Tank = ''
  5170. if (FermentAuto_cleaning == 0): F6 = 'F_Waiting'
  5171. elif (FermentAuto_cleaning != 0): F6 = 'F_Cleaning'
  5172. # 避免桶槽可出豆時未賦值
  5173. if FOutputtingBean_Tank == '':
  5174. if F1 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F1'
  5175. elif F2 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F2'
  5176. elif F3 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F3'
  5177. elif F4 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F4'
  5178. elif F5 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F5'
  5179. elif F6 == 'F_OutputtingBean': FOutputtingBean_Tank = 'F6'
  5180. # 若桶槽 F1~F6 為清洗中
  5181. if F1 == 'F_Cleaning':
  5182. F1_thread = threading.Thread(target=FCleaning, args=["F1"])
  5183. F1_thread.start()
  5184. F1 = 'F_Waiting'
  5185. if F2 == 'F_Cleaning':
  5186. F2_thread = threading.Thread(target=FCleaning, args=["F2"])
  5187. F2_thread.start()
  5188. F2 = 'F_Waiting'
  5189. if F3 == 'F_Cleaning':
  5190. F3_thread = threading.Thread(target=FCleaning, args=["F3"])
  5191. F3_thread.start()
  5192. F3 = 'F_Waiting'
  5193. if F4 == 'F_Cleaning':
  5194. F4_thread = threading.Thread(target=FCleaning, args=["F4"])
  5195. F4_thread.start()
  5196. F4 = 'F_Waiting'
  5197. if F5 == 'F_Cleaning':
  5198. F5_thread = threading.Thread(target=FCleaning, args=["F5"])
  5199. F5_thread.start()
  5200. F5 = 'F_Waiting'
  5201. if F6 == 'F_Cleaning':
  5202. F6_thread = threading.Thread(target=FCleaning, args=["F6"])
  5203. F6_thread.start()
  5204. F6 = 'F_Waiting'
  5205. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  5206. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  5207. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  5208. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  5209. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  5210. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  5211. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  5212. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  5213. else:
  5214. # [介面] 若未啟用 發酵 狀態
  5215. print('未啟用發酵流程')
  5216. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  5217. # 目前發酵槽 F1~F6 正在入豆、入水的桶槽數量 (應小於一桶)
  5218. # Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  5219. # 若出料儲豆槽狀態為 空桶等待 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  5220. if FO1 == 'FO_Waiting' and FOutputtingBean_Tank != '':
  5221. # 判斷要對應出料的桶槽為何, 設定成 FOutputtingBean_Tank = 'F1', 待出完料再把 FOutputtingBean_Tank = ''
  5222. FO1 = 'FO_InputtingBean'
  5223. print('------- ' + FOutputtingBean_Tank + ' 狀態更新:出豆中 -------')
  5224. print('------- FO1 狀態更新:入豆中 -------')
  5225. # [致動器] F1 蝴蝶閥 ON
  5226. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "on" }
  5227. print('data: ', data)
  5228. # mqtt_f(data)
  5229. elif FO1 == 'FO_InputtingBean' and FOutputtingBean_Tank != '':
  5230. if FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  5231. # [致動器] 出料真空吸料機 OFF
  5232. data = { "tank_num": FOutputtingBean_Tank, "command": "input_vacuum_status", "value": "off" }
  5233. print('data: ', data)
  5234. # mqtt_f(data)
  5235. # [致動器] F1 蝴蝶閥 OFF
  5236. data = { "tank_num": FOutputtingBean_Tank, "command": "tank_diskvalve_status", "value": "off" }
  5237. print('data: ', data)
  5238. # mqtt_f(data)
  5239. FO1 = 'FO_OutputtingBean'
  5240. print('------- FO1 狀態更新:出豆中 -------')
  5241. elif FO_UP_UltraSoniclist[0] < Ferment_Output_bean_height:
  5242. FO1_thread = threading.Thread(target=FOInputtingBean_filled, args=["FO1"])
  5243. FO1_thread.start()
  5244. # 若是無桶槽可入豆, 出料儲豆槽判斷是否可出豆或空桶等待入豆
  5245. elif FOutputtingBean_Tank == '':
  5246. if FO_UP_UltraSoniclist[0] > Ferment_Output_bean_empty:
  5247. FO1 = 'FO_OutputtingBean'
  5248. print('------- FO1 狀態更新:可出豆 -------')
  5249. elif FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  5250. FO1 = 'FO_Waiting'
  5251. print('------- FO1 狀態更新:空桶等待 -------')
  5252. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] <= Ferment_Output_bean_empty:
  5253. FO1 = 'FO_Waiting'
  5254. print('------- FO1 狀態更新:空桶等待 -------')
  5255. # ----- 等待 thread 多執行緒執行完成 --------
  5256. # 若 FI1_thread 有被定義, 則執行 FI1_thread.join() 等待執行完成 (當入料儲豆槽入料時)
  5257. # 若 FI1_thread 有被定義, 會出現 UnboundLocalError: local variable 'FO1_thread' referenced before assignment 錯誤訊息
  5258. # (非入料儲豆槽入料時) 此時就不進行任何處理
  5259. try:
  5260. FI1_thread.join()
  5261. print("-- FI1_thread complete! --")
  5262. except UnboundLocalError:
  5263. pass
  5264. try:
  5265. F1_thread.join()
  5266. print("-- F1_thread complete! --")
  5267. except UnboundLocalError:
  5268. pass
  5269. try:
  5270. F2_thread.join()
  5271. print("-- F2_thread complete! --")
  5272. except UnboundLocalError:
  5273. pass
  5274. try:
  5275. F3_thread.join()
  5276. print("-- F3_thread complete! --")
  5277. except UnboundLocalError:
  5278. pass
  5279. try:
  5280. F4_thread.join()
  5281. print("-- F4_thread complete! --")
  5282. except UnboundLocalError:
  5283. pass
  5284. try:
  5285. F5_thread.join()
  5286. print("-- F5_thread complete! --")
  5287. except UnboundLocalError:
  5288. pass
  5289. try:
  5290. F6_thread.join()
  5291. print("-- F6_thread complete! --")
  5292. except UnboundLocalError:
  5293. pass
  5294. try:
  5295. FO1_thread.join()
  5296. print("-- FO1_thread complete! --")
  5297. except UnboundLocalError:
  5298. pass
  5299. # ----- 將狀態寫入資料庫 ------------------------------
  5300. # 獲取文本框的值並賦值給user實體對象
  5301. F_status = ferment_container_status()
  5302. F_status.Ferment_Input_1 = FI1
  5303. F_status.Ferment_Input_2 = FI2
  5304. F_status.Ferment_Tank_1 = F1
  5305. F_status.Ferment_Tank_2 = F2
  5306. F_status.Ferment_Tank_3 = F3
  5307. F_status.Ferment_Tank_4 = F4
  5308. F_status.Ferment_Tank_5 = F5
  5309. F_status.Ferment_Tank_6 = F6
  5310. F_status.Ferment_Tank_7 = F7
  5311. F_status.Ferment_Tank_8 = F8
  5312. F_status.Ferment_Tank_9 = F9
  5313. F_status.Ferment_Tank_10 = F10
  5314. F_status.Ferment_Tank_11 = F11
  5315. F_status.Ferment_Tank_12 = F12
  5316. F_status.Ferment_Output_1 = FO1
  5317. F_status.Ferment_Output_2 = FO2
  5318. #將數據保存進資料庫
  5319. db.session.add(F_status)
  5320. # 手動提交
  5321. db.session.commit()
  5322. # ----- 將狀態寫入資料庫 ------------------------------
  5323. return jsonify({"Peel_Output_1":PO1,
  5324. "Ferment_Input_1":FI1,
  5325. "Ferment_Tank_1":F1,
  5326. "Ferment_Tank_2":F2,
  5327. "Ferment_Tank_3":F3,
  5328. "Ferment_Tank_4":F4,
  5329. "Ferment_Tank_5":F5,
  5330. "Ferment_Tank_6":F6,
  5331. "Ferment_Output_1":FO1
  5332. })
  5333. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以下為原備份
  5334. @main.route('/ferment_auto_test_1026backup')
  5335. def ferment_auto_test_1026backup():
  5336. info = request.args.to_dict()
  5337. # 從介面取得 指定生豆高度/發酵桶槽排程:發酵、清洗、校正 EC、校正攪拌棒
  5338. Ferment_Input_bean_empty = 2
  5339. Ferment_Tank_bean_empty = 2
  5340. Ferment_Output_bean_empty = 2
  5341. FermentAuto_fermenting = int(info['FermentAuto_fermenting'])
  5342. FermentAuto_cleaning = int(info['FermentAuto_cleaning'])
  5343. FermentAuto_calibratingEC = int(info['FermentAuto_calibratingEC'])
  5344. FermentAuto_calibratingSTIR = int(info['FermentAuto_calibratingSTIR'])
  5345. Ferment_Input_bean_height = float(info['Ferment_Input_bean_height'])
  5346. Ferment_Input_vacuumON_time = float(info['Ferment_Input_vacuumON_time'])
  5347. Ferment_Input_vacuumOFF_time = float(info['Ferment_Input_vacuumOFF_time'])
  5348. Ferment_Tank_bean_height = float(info['Ferment_Tank_bean_height'])
  5349. Ferment_Tank_vacuumON_time = float(info['Ferment_Tank_vacuumON_time'])
  5350. Ferment_Tank_vacuumOFF_time = float(info['Ferment_Tank_vacuumOFF_time'])
  5351. Ferment_Tank_water_height = float(info['Ferment_Tank_water_height'])
  5352. Ferment_Tank_fermenting_temp = float(info['Ferment_Tank_fermenting_temp'])
  5353. Ferment_Tank_fermenting_time = float(info['Ferment_Tank_fermenting_time'])
  5354. Ferment_Tank_motor_rpm = float(info['Ferment_Tank_motor_rpm'])
  5355. Ferment_Tank_motor_time = float(info['Ferment_Tank_motor_time'])
  5356. Ferment_Tank_fermenting_pH = float(info['Ferment_Tank_fermenting_pH'])
  5357. Ferment_Output_bean_height = float(info['Ferment_Output_bean_height'])
  5358. Ferment_Output_vacuumON_time = float(info['Ferment_Output_vacuumON_time'])
  5359. Ferment_Output_vacuumOFF_time = float(info['Ferment_Output_vacuumOFF_time'])
  5360. Ferment_Tank_WaterOut_time = float(info['Ferment_Tank_WaterOut_time'])
  5361. Ferment_Tank_Disinfect_time = float(info['Ferment_Tank_Disinfect_time'])
  5362. # print('發酵自動化_指定生豆高度: ', Ferment_Tank_bean_height)
  5363. # print('發酵自動化_發酵排程: ', FermentAuto_fermenting, type(FermentAuto_fermenting))
  5364. # print('發酵自動化_清洗排程: ', FermentAuto_cleaning, type(FermentAuto_cleaning))
  5365. # print('發酵自動化_校正 EC 排程: ', FermentAuto_calibratingEC, type(FermentAuto_calibratingEC))
  5366. # print('發酵自動化_校正攪拌棒排程: ', FermentAuto_calibratingSTIR, type(FermentAuto_calibratingSTIR))
  5367. # [介面] 讓使用者可以選擇排程內有發酵/清洗/校正, 此處預設為 True
  5368. Ferment_btn = FermentAuto_fermenting # Ferment_btn = True
  5369. # 從資料庫資料表中取得最新狀態
  5370. ferment_status = ferment_container_status.query.order_by(text('datetime desc')).first()
  5371. FI1 = ferment_status.Ferment_Input_1
  5372. FI2 = ferment_status.Ferment_Input_2
  5373. F1 = ferment_status.Ferment_Tank_1
  5374. F2 = ferment_status.Ferment_Tank_2
  5375. F3 = ferment_status.Ferment_Tank_3
  5376. F4 = ferment_status.Ferment_Tank_4
  5377. F5 = ferment_status.Ferment_Tank_5
  5378. F6 = ferment_status.Ferment_Tank_6
  5379. F7 = ferment_status.Ferment_Tank_7
  5380. F8 = ferment_status.Ferment_Tank_8
  5381. F9 = ferment_status.Ferment_Tank_9
  5382. F10 = ferment_status.Ferment_Tank_10
  5383. F11 = ferment_status.Ferment_Tank_11
  5384. F12 = ferment_status.Ferment_Tank_12
  5385. FO1 = ferment_status.Ferment_Output_1
  5386. FO2 = ferment_status.Ferment_Output_2
  5387. clean_status = clean_container_status.query.order_by(text('datetime desc')).first()
  5388. PO1 = clean_status.Peel_Output_1 # PO_Waiting # PO_OutputtingBean
  5389. PO2 = clean_status.Peel_Output_2
  5390. F_UP_tanklist = [F1, F2, F3, F4, F5, F6]
  5391. F_DOWN_tanklist = [F7, F8, F9, F10, F11, F12]
  5392. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  5393. # 目前發酵槽 F1~F6 正在入豆的桶槽數量 (應小於一桶)
  5394. FermentUp_InputtingBean_number = int(F_UP_tanklist.count('F_InputtingBean'))
  5395. FermentUp_InputtingBeanPause_number = int(F_UP_tanklist.count('F_InputtingBean_Pause'))
  5396. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  5397. FI_UP_UltraSoniclist = []
  5398. for i in range(1, 3, 1):
  5399. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  5400. # UltraSonic = float("{:.2f}".format(34.6 - float(input_UltraSonic.UltraSonic)))
  5401. UltraSonic = float(input_UltraSonic.UltraSonic)
  5402. FI_UP_UltraSoniclist.append(UltraSonic)
  5403. print('FI_UP_UltraSoniclist: ', FI_UP_UltraSoniclist)
  5404. # -- 取得發酵入料儲豆槽 FI1~FI2 桶內高度 UltraSonic -------------
  5405. # 入料儲豆槽等待中、且脫皮機儲豆槽可出豆時, 入料儲豆槽入豆
  5406. if FI1 == 'FI_Waiting' and PO1 == 'PO_OutputtingBean':
  5407. FI1 = 'FI_InputtingBean'
  5408. print('------- FI1 狀態更新:入豆中 -------')
  5409. # [致動器] 入料真空吸料機 ON
  5410. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  5411. print('data: ', data)
  5412. # mqtt_f(data)
  5413. timer = time.time()
  5414. while True:
  5415. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  5416. # [致動器] 入料真空吸料機 OFF
  5417. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  5418. print('data: ', data)
  5419. # mqtt_f(data)
  5420. timer = time.time()
  5421. break
  5422. while True:
  5423. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  5424. break
  5425. # 入料儲豆槽入豆時
  5426. elif FI1 == 'FI_InputtingBean':
  5427. # 桶槽內未達指定生豆高度, 且 前方 PO1 可出豆, 就執行入料動作
  5428. if (FI_UP_UltraSoniclist[0] < Ferment_Input_bean_height) and PO1 == 'PO_OutputtingBean':
  5429. # [致動器] 入料真空吸料機 ON
  5430. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  5431. print('data: ', data)
  5432. # mqtt_f(data)
  5433. timer = time.time()
  5434. while True:
  5435. if (time.time() - timer) > Ferment_Input_vacuumON_time:
  5436. # [致動器] 入料真空吸料機 OFF
  5437. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  5438. print('data: ', data)
  5439. # mqtt_f(data)
  5440. timer = time.time()
  5441. break
  5442. while True:
  5443. if (time.time() - timer) > Ferment_Input_vacuumOFF_time:
  5444. break
  5445. # 桶槽內達指定生豆高度時, 入料儲豆槽狀態轉為 可出豆
  5446. if (FI_UP_UltraSoniclist[0] >= Ferment_Input_bean_height):
  5447. FI1 = 'FI_OutputtingBean'
  5448. print('------- FI1 狀態更新:可出豆 -------')
  5449. # 入料儲豆槽出豆時, 桶槽高度為 空桶高度時, 狀態轉為 空桶等待
  5450. elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] <= Ferment_Input_bean_empty):
  5451. FI1 = 'FI_Waiting'
  5452. print('------- FI1 狀態更新:空桶等待 -------')
  5453. # [1012 刪除, 避免混豆]若入料儲豆槽可出豆 且 儲豆槽內高度低於 40 且 前方脫皮機儲豆槽可出豆 且 目前無桶槽需入料時
  5454. # elif FI1 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[0] < 40) and PO1 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  5455. # FI1 = 'FI_InputtingBean'
  5456. # print('------- FI1 狀態更新:入豆中 -------')
  5457. # if FI2 == 'FI_Waiting' and PO2 == 'PO_OutputtingBean':
  5458. # FI2 = 'FI_InputtingBean'
  5459. # print('------- FI2 狀態更新:入豆中 -------')
  5460. # elif FI2 == 'FI_InputtingBean' and ((FI_UP_UltraSoniclist[1] >= 35) or (PO2 != 'PO_OutputtingBean')) :
  5461. # FI2 = 'FI_OutputtingBean'
  5462. # print('------- FI2 狀態更新:可出豆 -------')
  5463. # elif FI2 == 'FI_OutputtingBean' and (FI_UP_UltraSoniclist[1] < 40) and PO2 == 'PO_OutputtingBean' and FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  5464. # FI2 = 'FI_InputtingBean'
  5465. # print('------- FI2 狀態更新:入豆中 -------')
  5466. # ----- 發酵桶槽 F1~F6 入料暫停→入料判斷 ------------------------------
  5467. ### 移到入料
  5468. # ----- 發酵桶槽 F1~F6 等待→入料判斷 ------------------------------
  5469. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  5470. F_UP_UltraSoniclist = []
  5471. for i in range(1, 7, 1):
  5472. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  5473. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  5474. F_UP_UltraSoniclist.append(UltraSonic)
  5475. print('F_UP_UltraSoniclist: ', F_UP_UltraSoniclist)
  5476. # -- 取得發酵桶槽 F1~F6 桶內高度 UltraSonic -------------
  5477. # [介面] 若啟用 發酵 狀態
  5478. if Ferment_btn:
  5479. # 若入料儲豆槽可出料狀態
  5480. if FI1 == 'FI_OutputtingBean':
  5481. # 若 F1~F6 發酵桶槽為 入豆中, 繼續入豆, 當高度 > 指定生豆高度 時入豆完成
  5482. if F1 == 'F_InputtingBean':
  5483. if (F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height):
  5484. F1 = 'F_InputtingBean_Finish'
  5485. print('------- F1 狀態更新:入料完成 -------')
  5486. # [致動器] 入料三通閥 ON排氣
  5487. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  5488. print('data: ', data)
  5489. # mqtt_f(data)
  5490. # [致動器] 馬達 0
  5491. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  5492. print('data: ', data)
  5493. # mqtt_f(data)
  5494. # [致動器] 真空吸料機 OFF
  5495. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5496. print('data: ', data)
  5497. # mqtt_f(data)
  5498. else:
  5499. # [致動器] 真空吸料機 ON
  5500. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  5501. print('data: ', data)
  5502. # mqtt_f(data)
  5503. timer = time.time()
  5504. while True:
  5505. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  5506. # [致動器] 入料真空吸料機 OFF
  5507. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5508. print('data: ', data)
  5509. # mqtt_f(data)
  5510. timer = time.time()
  5511. break
  5512. while True:
  5513. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  5514. break
  5515. if F2 == 'F_InputtingBean' and (F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height):
  5516. F2 = 'F_InputtingBean_Finish'
  5517. print('------- F2 狀態更新:入料完成 -------')
  5518. if F3 == 'F_InputtingBean' and (F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height):
  5519. F3 = 'F_InputtingBean_Finish'
  5520. print('------- F3 狀態更新:入料完成 -------')
  5521. if F4 == 'F_InputtingBean' and (F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height):
  5522. F4 = 'F_InputtingBean_Finish'
  5523. print('------- F4 狀態更新:入料完成 -------')
  5524. if F5 == 'F_InputtingBean' and (F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height):
  5525. F5 = 'F_InputtingBean_Finish'
  5526. print('------- F5 狀態更新:入料完成 -------')
  5527. if F6 == 'F_InputtingBean' and (F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height):
  5528. F6 = 'F_InputtingBean_Finish'
  5529. print('------- F6 狀態更新:入料完成 -------')
  5530. # 若有兩個以上桶槽入料中, 則桶號最小者優先入料 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  5531. if FermentUp_InputtingBean_number == 1:
  5532. if F1 == 'F_InputtingBean':
  5533. # [致動器] 桶槽真空吸料機 ON
  5534. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  5535. print('data: ', data)
  5536. # mqtt_f(data)
  5537. timer = time.time()
  5538. while True:
  5539. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  5540. # [致動器] 桶槽真空吸料機 OFF
  5541. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5542. print('data: ', data)
  5543. # mqtt_f(data)
  5544. timer = time.time()
  5545. break
  5546. while True:
  5547. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  5548. break
  5549. # else if F2 == ''...
  5550. # 若 F1~F6 發酵桶槽為 入豆暫停, 則狀態改為優先入豆 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1021 優先入豆判斷
  5551. elif FermentUp_InputtingBeanPause_number >= 1:
  5552. if F1 == 'F_InputtingBean_Pause':
  5553. F1 = 'F_InputtingBean'
  5554. print('------- F1 狀態更新:入料中 -------')
  5555. # [致動器] 桶槽真空吸料機 ON
  5556. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  5557. print('data: ', data)
  5558. # mqtt_f(data)
  5559. timer = time.time()
  5560. while True:
  5561. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  5562. # [致動器] 桶槽真空吸料機 OFF
  5563. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5564. print('data: ', data)
  5565. # mqtt_f(data)
  5566. timer = time.time()
  5567. break
  5568. while True:
  5569. if (time.time() - timer) > Ferment_Tank_vacuumOFF_time:
  5570. break
  5571. elif F2 == 'F_InputtingBean_Pause':
  5572. F2 = 'F_InputtingBean'
  5573. print('------- F2 狀態更新:入料中 -------')
  5574. elif F3 == 'F_InputtingBean_Pause':
  5575. F3 = 'F_InputtingBean'
  5576. print('------- F3 狀態更新:入料中 -------')
  5577. elif F4 == 'F_InputtingBean_Pause':
  5578. F4 = 'F_InputtingBean'
  5579. print('------- F4 狀態更新:入料中 -------')
  5580. elif F5 == 'F_InputtingBean_Pause':
  5581. F5 = 'F_InputtingBean'
  5582. print('------- F5 狀態更新:入料中 -------')
  5583. elif F6 == 'F_InputtingBean_Pause':
  5584. F6 = 'F_InputtingBean'
  5585. print('------- F6 狀態更新:入料中 -------')
  5586. # 若 F1~F6 皆無入豆 無入豆暫停, 則桶號最小者開始入豆
  5587. elif FermentUp_InputtingBean_number == 0 and FermentUp_InputtingBeanPause_number == 0:
  5588. if F1 == 'F_Waiting':
  5589. F1 = 'F_InputtingBean'
  5590. print('------- F1 狀態更新:入料中 -------')
  5591. # [致動器] 入料入料三通閥 OFF入豆
  5592. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "off" }
  5593. print('data: ', data)
  5594. # mqtt_f(data)
  5595. # [致動器] 馬達 5
  5596. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "5" }
  5597. print('data: ', data)
  5598. # mqtt_f(data)
  5599. # [致動器] 桶槽真空吸料機 ON
  5600. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "on" }
  5601. print('data: ', data)
  5602. # mqtt_f(data)
  5603. timer = time.time()
  5604. while True:
  5605. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  5606. # [致動器] 桶槽真空吸料機 OFF
  5607. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5608. print('data: ', data)
  5609. # mqtt_f(data)
  5610. timer = time.time()
  5611. break
  5612. while True:
  5613. if (time.time() - timer) > Ferment_Tank_vacuumON_time:
  5614. break
  5615. elif F2 == 'F_Waiting':
  5616. F2 = 'F_InputtingBean'
  5617. print('------- F2 狀態更新:入料中 -------')
  5618. elif F3 == 'F_Waiting':
  5619. F3 = 'F_InputtingBean'
  5620. print('------- F3 狀態更新:入料中 -------')
  5621. elif F4 == 'F_Waiting':
  5622. F4 = 'F_InputtingBean'
  5623. print('------- F4 狀態更新:入料中 -------')
  5624. elif F5 == 'F_Waiting':
  5625. F5 = 'F_InputtingBean'
  5626. print('------- F5 狀態更新:入料中 -------')
  5627. elif F6 == 'F_Waiting':
  5628. F6 = 'F_InputtingBean'
  5629. print('------- F6 狀態更新:入料中 -------')
  5630. # 若入料儲豆槽非可出豆, 且 F1~F6 其中有桶槽入料中, 若桶槽未滿則入料暫停
  5631. elif FI1 != 'FI_InputtingBean' and FermentUp_InputtingBean_number >= 1:
  5632. if F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_height:
  5633. F1 = 'F_InputtingBean_Pause'
  5634. print('------- F1 狀態更新:入料暫停 -------')
  5635. # [致動器] 桶槽真空吸料機 OFF
  5636. data = { "tank_num": "F1", "command": "tank_vacuum_status", "value": "off" }
  5637. print('data: ', data)
  5638. # mqtt_f(data)
  5639. elif F1 == 'F_InputtingBean' and F_UP_UltraSoniclist[0] >= Ferment_Tank_bean_height:
  5640. F1 = 'F_InputtingBean_Finish'
  5641. print('------- F1 狀態更新:入料完成 -------')
  5642. # [致動器] 入料三通閥 ON排氣
  5643. data = { "tank_num": "F1", "command": "tank_threewayvalve_input_status", "value": "on" }
  5644. print('data: ', data)
  5645. # mqtt_f(data)
  5646. # [致動器] 馬達 0
  5647. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  5648. print('data: ', data)
  5649. # mqtt_f(data)
  5650. # [致動器] 入料真空吸料機 OFF
  5651. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  5652. print('data: ', data)
  5653. # mqtt_f(data)
  5654. if F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] < Ferment_Tank_bean_height:
  5655. F2 = 'F_InputtingBean_Pause'
  5656. print('------- F2 狀態更新:入料暫停 -------')
  5657. elif F2 == 'F_InputtingBean' and F_UP_UltraSoniclist[1] >= Ferment_Tank_bean_height:
  5658. F2 = 'F_InputtingBean_Finish'
  5659. print('------- F2 狀態更新:入料完成 -------')
  5660. if F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] < Ferment_Tank_bean_height:
  5661. F3 = 'F_InputtingBean_Pause'
  5662. print('------- F3 狀態更新:入料暫停 -------')
  5663. elif F3 == 'F_InputtingBean' and F_UP_UltraSoniclist[2] >= Ferment_Tank_bean_height:
  5664. F3 = 'F_InputtingBean_Finish'
  5665. print('------- F3 狀態更新:入料完成 -------')
  5666. if F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] < Ferment_Tank_bean_height:
  5667. F4 = 'F_InputtingBean_Pause'
  5668. print('------- F4 狀態更新:入料暫停 -------')
  5669. elif F4 == 'F_InputtingBean' and F_UP_UltraSoniclist[3] >= Ferment_Tank_bean_height:
  5670. F4 = 'F_InputtingBean_Finish'
  5671. print('------- F4 狀態更新:入料完成 -------')
  5672. if F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] < Ferment_Tank_bean_height:
  5673. F5 = 'F_InputtingBean_Pause'
  5674. print('------- F5 狀態更新:入料暫停 -------')
  5675. elif F5 == 'F_InputtingBean' and F_UP_UltraSoniclist[4] >= Ferment_Tank_bean_height:
  5676. F5 = 'F_InputtingBean_Finish'
  5677. print('------- F5 狀態更新:入料完成 -------')
  5678. if F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] < Ferment_Tank_bean_height:
  5679. F6 = 'F_InputtingBean_Pause'
  5680. print('------- F6 狀態更新:入料暫停 -------')
  5681. elif F6 == 'F_InputtingBean' and F_UP_UltraSoniclist[5] >= Ferment_Tank_bean_height:
  5682. F6 = 'F_InputtingBean_Finish'
  5683. print('------- F6 狀態更新:入料完成 -------')
  5684. else:
  5685. # 若入料儲豆槽非可出料狀態
  5686. print('發酵入料儲豆槽空, 桶槽無法入料')
  5687. else:
  5688. # [介面] 若未啟用 發酵 狀態
  5689. print('未啟用發酵流程')
  5690. # ----- 10/07 --------------------------------------------------------------------------------------------------------------------------------
  5691. # ----- 發酵桶槽 F1~F6 入料→入料暫停判斷 ------------------------------
  5692. ### 移到入料
  5693. # ----- 發酵桶槽 F1~F6 入料→入水判斷 ------------------------------
  5694. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  5695. F_UP_tank_WaterLevel = []
  5696. for i in range(1, 7, 1):
  5697. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  5698. WaterLevel = float(tank_WaterLevel.WaterLevel)
  5699. F_UP_tank_WaterLevel.append(WaterLevel)
  5700. print('F_UP_tank_WaterLevel: ', F_UP_tank_WaterLevel)
  5701. # -- 取得發酵桶槽 F1~F6 夾層水位高度 WaterLevel -------------
  5702. Ferment_InputtingBeanFinish_number = int(F_UP_tanklist.count('F_InputtingBean_Finish'))
  5703. Ferment_InputtingWater_number = int(F_UP_tanklist.count('F_InputtingWater'))
  5704. # 入水條件:當前桶槽入豆 + 沒有其他桶槽入水
  5705. if Ferment_InputtingBeanFinish_number >= 1 and Ferment_InputtingWater_number == 0:
  5706. # 當入豆到指定高度時, 狀態轉換為入水 (桶槽編號小者優先)
  5707. # !!! 發酵槽 F_InputtingBean_Finish 狀態應該請硬體判斷
  5708. # !!! 若狀態為 F_InputtingBean 且 超音波值>指定生豆高度, 狀態改為 F_InputtingBean_Finish 並等待入水 F_InputtingWater
  5709. # 這邊是考慮一次僅一個桶槽入水, 多桶入水會不會速度變慢?
  5710. if F1 == 'F_InputtingBean_Finish':
  5711. F1 = 'F_InputtingWater'
  5712. print('------- F1 狀態更新:入水中 -------')
  5713. # [致動器] 外桶浮選三通閥 ON
  5714. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "on" }
  5715. print('data: ', data)
  5716. # mqtt_f(data)
  5717. # 桶內高度若低於水位指定高度, [致動器] 桶內進水電磁閥 ON
  5718. if F_UP_UltraSoniclist[0] < Ferment_Tank_water_height:
  5719. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "on" }
  5720. print('data: ', data)
  5721. # mqtt_f(data)
  5722. # [致動器] 桶內進水電磁閥 OFF
  5723. else:
  5724. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  5725. print('data: ', data)
  5726. # mqtt_f(data)
  5727. # 桶外水位高度若低於水位計高度, [致動器] 桶外進水電磁閥 ON
  5728. if F_UP_tank_WaterLevel[0] != 1:
  5729. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "on" }
  5730. print('data: ', data)
  5731. # mqtt_f(data)
  5732. # [致動器] 桶外進水電磁閥 OFF
  5733. else:
  5734. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  5735. print('data: ', data)
  5736. # mqtt_f(data)
  5737. elif F2 == 'F_InputtingBean_Finish':
  5738. F2 = 'F_InputtingWater'
  5739. print('------- F2 狀態更新:入水中 -------')
  5740. elif F3 == 'F_InputtingBean_Finish':
  5741. F3 = 'F_InputtingWater'
  5742. print('------- F3 狀態更新:入水中 -------')
  5743. elif F4 == 'F_InputtingBean_Finish':
  5744. F4 = 'F_InputtingWater'
  5745. print('------- F4 狀態更新:入水中 -------')
  5746. elif F5 == 'F_InputtingBean_Finish':
  5747. F5 = 'F_InputtingWater'
  5748. print('------- F5 狀態更新:入水中 -------')
  5749. elif F6 == 'F_InputtingBean_Finish':
  5750. F6 = 'F_InputtingWater'
  5751. print('------- F6 狀態更新:入水中 -------')
  5752. # ----- 發酵桶槽 F1~F6 入水→發酵判斷 ------------------------------
  5753. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  5754. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  5755. if F1 == 'F_InputtingWater':
  5756. if F_UP_tank_WaterLevel[0] == 1 and F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  5757. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  5758. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  5759. print('data: ', data)
  5760. # mqtt_f(data)
  5761. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  5762. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  5763. print('data: ', data)
  5764. # mqtt_f(data)
  5765. F1 = 'F_Fermenting'
  5766. print('------- F1 狀態更新:發酵中 -------')
  5767. # [致動器] 馬達 (指定轉速)
  5768. data = { "tank_num": "F1", "command": "tank_motor_status", "value": Ferment_Tank_motor_rpm }
  5769. print('data: ', data)
  5770. # mqtt_f(data)
  5771. # [致動器] 溫控開關 ON
  5772. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "on" }
  5773. # print('data: ', data)
  5774. # # mqtt_f(data)
  5775. # [致動器] 設定溫度、持溫時間
  5776. # [致動器] 加熱器 1 ON
  5777. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "on" }
  5778. print('data: ', data)
  5779. # mqtt_f(data)
  5780. elif F_UP_tank_WaterLevel[0] == 1:
  5781. # 桶外水位高度高於水位計高度, [致動器] 桶外進水電磁閥 OFF
  5782. data = { "tank_num": "F1", "command": "outer_solenoid_water_status", "value": "off" }
  5783. print('data: ', data)
  5784. # mqtt_f(data)
  5785. elif F_UP_UltraSoniclist[0] >= Ferment_Tank_water_height:
  5786. # 桶內高度若高於水位指定高度, [致動器] 桶內進水電磁閥 OFF
  5787. data = { "tank_num": "F1", "command": "tank_solenoid_water_in_status", "value": "off" }
  5788. print('data: ', data)
  5789. # mqtt_f(data)
  5790. if F2 == 'F_InputtingWater' and F_UP_tank_WaterLevel[1] == 1 and F_UP_UltraSoniclist[1] >= Ferment_Tank_water_height:
  5791. F2 = 'F_Fermenting'
  5792. print('------- F2 狀態更新:發酵中 -------')
  5793. if F3 == 'F_InputtingWater' and F_UP_tank_WaterLevel[2] == 1 and F_UP_UltraSoniclist[2] >= Ferment_Tank_water_height:
  5794. F3 = 'F_Fermenting'
  5795. print('------- F3 狀態更新:發酵中 -------')
  5796. if F4 == 'F_InputtingWater' and F_UP_tank_WaterLevel[3] == 1 and F_UP_UltraSoniclist[3] >= Ferment_Tank_water_height:
  5797. F4 = 'F_Fermenting'
  5798. print('------- F4 狀態更新:發酵中 -------')
  5799. if F5 == 'F_InputtingWater' and F_UP_tank_WaterLevel[4] == 1 and F_UP_UltraSoniclist[4] >= Ferment_Tank_water_height:
  5800. F5 = 'F_Fermenting'
  5801. print('------- F5 狀態更新:發酵中 -------')
  5802. if F6 == 'F_InputtingWater' and F_UP_tank_WaterLevel[5] == 1 and F_UP_UltraSoniclist[5] >= Ferment_Tank_water_height:
  5803. F6 = 'F_Fermenting'
  5804. print('------- F6 狀態更新:發酵中 -------')
  5805. # ----- 發酵桶槽 F1~F6 發酵→可出豆 判斷 ------------------------------
  5806. # TODO
  5807. # !!! 發酵槽 F_Fermenting 狀態應該請硬體判斷
  5808. # !!! 若狀態為 F_InputtingWater 且 超音波值>指定水位高度 且 夾層水位計 == 1, 狀態改為 F_Fermenting 發酵
  5809. # 可以多桶各自執行發酵排程
  5810. # -- 取得發酵桶槽 F1~F6 pH -------------
  5811. F_UP_tank_PH = []
  5812. for i in range(1, 7, 1):
  5813. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  5814. PH = float(tank_PH.PH)
  5815. F_UP_tank_PH.append(PH)
  5816. print('F_UP_tank_PH: ', F_UP_tank_PH)
  5817. # -- 取得發酵桶槽 F1~F6 pH -------------
  5818. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  5819. F_UP_tank_SHT11_Temp = []
  5820. for i in range(1, 7, 1):
  5821. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + str(i)).order_by(text('datetime desc')).first()
  5822. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  5823. F_UP_tank_SHT11_Temp.append(SHT11_Temp)
  5824. print('F_UP_tank_SHT11_Temp: ', F_UP_tank_SHT11_Temp)
  5825. # -- 取得發酵桶槽 F1~F6 SHT11_TEMP -------------
  5826. #
  5827. 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:
  5828. print('發酵等待 ', Ferment_Tank_fermenting_time, ' 秒')
  5829. timer = time.time()
  5830. while True:
  5831. if (time.time() - timer) > Ferment_Tank_fermenting_time :
  5832. # [致動器] 外桶浮選三通閥 OFF
  5833. data = { "tank_num": "F1", "command": "outer_threewayvalve_float_status", "value": "off" }
  5834. print('data: ', data)
  5835. # mqtt_f(data)
  5836. # [致動器] 馬達 0
  5837. data = { "tank_num": "F1", "command": "tank_motor_status", "value": "0" }
  5838. print('data: ', data)
  5839. # mqtt_f(data)
  5840. # [致動器] 溫控開關 OFF
  5841. # data = { "tank_num": "F1", "command": "tank_temp_enable", "value": "off" }
  5842. # print('data: ', data)
  5843. # # mqtt_f(data)
  5844. # [致動器] 加熱器 1 OFF
  5845. data = { "tank_num": "F1", "command": "tank_heater1_status", "value": "off" }
  5846. print('data: ', data)
  5847. # mqtt_f(data)
  5848. break
  5849. # [致動器] 廢水排水閥 (桶內) ON
  5850. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "on" }
  5851. print('data: ', data)
  5852. # mqtt_f(data)
  5853. print('桶內廢水排水 ', Ferment_Tank_WaterOut_time, ' 秒')
  5854. timer = time.time()
  5855. while True:
  5856. if (time.time() - timer) > Ferment_Tank_WaterOut_time:
  5857. # [致動器] 廢水排水閥 (桶內) OFF
  5858. data = { "tank_num": "F1", "command": "tank_solenoid_water_out_status", "value": "off" }
  5859. print('data: ', data)
  5860. # mqtt_f(data)
  5861. break
  5862. F1 = 'F_OutputtingBean'
  5863. print('------- F1 狀態更新:可出豆 -------')
  5864. 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:
  5865. F2 = 'F_OutputtingBean'
  5866. print('------- F2 狀態更新:可出豆 -------')
  5867. if F3 == 'F_Fermenting' and F_UP_tank_PH[2] <= Ferment_Tank_fermenting_pH:
  5868. F3 = 'F_OutputtingBean'
  5869. print('------- F3 狀態更新:可出豆 -------')
  5870. if F4 == 'F_Fermenting' and F_UP_tank_PH[3] <= Ferment_Tank_fermenting_pH:
  5871. F4 = 'F_OutputtingBean'
  5872. print('------- F4 狀態更新:可出豆 -------')
  5873. if F5 == 'F_Fermenting' and F_UP_tank_PH[4] <= Ferment_Tank_fermenting_pH:
  5874. F5 = 'F_OutputtingBean'
  5875. print('------- F5 狀態更新:可出豆 -------')
  5876. if F6 == 'F_Fermenting' and F_UP_tank_PH[5] <= Ferment_Tank_fermenting_pH:
  5877. F6 = 'F_OutputtingBean'
  5878. print('------- F6 狀態更新:可出豆 -------')
  5879. if F1 == 'F_OutputtingBean' and F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  5880. # 增加消毒電磁閥開關
  5881. # [致動器] 消毒電磁閥 ON
  5882. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  5883. print('data: ', data)
  5884. # mqtt_f(data)
  5885. # 暫停 (消毒時間) 秒
  5886. timer = time.time()
  5887. while True:
  5888. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  5889. # [致動器] 消毒電磁閥 OFF
  5890. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  5891. print('data: ', data)
  5892. # mqtt_f(data)
  5893. break
  5894. print('------- F1 狀態更新:空桶等待 -------')
  5895. F1 = 'F_Waiting'
  5896. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  5897. # if F1 == 'F_InputtingBean_Finish': F1 = 'F_OutputtingBean'
  5898. # if F2 == 'F_InputtingBean_Finish': F2 = 'F_OutputtingBean'
  5899. # if F3 == 'F_InputtingBean_Finish': F3 = 'F_OutputtingBean'
  5900. # if F4 == 'F_InputtingBean_Finish': F4 = 'F_OutputtingBean'
  5901. # if F5 == 'F_InputtingBean_Finish': F5 = 'F_OutputtingBean'
  5902. # if F6 == 'F_InputtingBean_Finish': F6 = 'F_OutputtingBean'
  5903. # # ----- [測試用] !!!!! F1~F6 入料完成→可出豆 判斷 ------------------------------
  5904. # ----- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 ------------------------------
  5905. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  5906. # -- 取得發酵出料儲豆槽 FO1~FO2 桶內高度 UltraSonic -------------
  5907. FO_UP_UltraSoniclist = []
  5908. for i in range(1, 3, 1):
  5909. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + str(i)).order_by(text('datetime desc')).first()
  5910. UltraSonic = float(output_UltraSonic.UltraSonic)
  5911. FO_UP_UltraSoniclist.append(UltraSonic)
  5912. print('FO_UP_UltraSoniclist: ', FO_UP_UltraSoniclist)
  5913. # 桶槽可出豆, 且出料儲豆槽等待時, 出料儲豆槽入豆
  5914. # 參考 -- 發酵桶槽 F1~F6 可出豆→出料儲豆槽 FO1 判斷 --
  5915. Ferment_OutputtingBean_number = int(F_UP_tanklist.count('F_OutputtingBean'))
  5916. # !!! 若出料儲豆槽狀態為 FO_Waiting(空桶等待) 且 桶槽狀態為 F_OutputtingBean 可出豆, 與 FO1 配合開始出豆
  5917. if FO1 == 'FO_Waiting' and Ferment_OutputtingBean_number >= 1:
  5918. if F1 == 'F_OutputtingBean':
  5919. FO1 = 'FO_InputtingBean'
  5920. print('------- F1 狀態更新:出豆中 -------')
  5921. print('------- FO1 狀態更新:入豆中 -------')
  5922. # [致動器] 出料真空吸料機 ON
  5923. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  5924. print('data: ', data)
  5925. # mqtt_f(data)
  5926. # 暫停 3 秒
  5927. timer = time.time()
  5928. while True:
  5929. if (time.time() - timer) > 3 :
  5930. # [致動器] 蝴蝶閥 ON
  5931. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  5932. print('data: ', data)
  5933. # mqtt_f(data)
  5934. break
  5935. timer = time.time()
  5936. while True:
  5937. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  5938. # [致動器] 出料真空吸料機 OFF
  5939. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  5940. print('data: ', data)
  5941. # mqtt_f(data)
  5942. timer = time.time()
  5943. break
  5944. while True:
  5945. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  5946. break
  5947. elif F2 == 'F_OutputtingBean':
  5948. FO1 = 'FO_InputtingBean'
  5949. print('------- F2 狀態更新:出豆中 -------')
  5950. print('------- FO1 狀態更新:入豆中 -------')
  5951. elif F3 == 'F_OutputtingBean':
  5952. FO1 = 'FO_InputtingBean'
  5953. print('------- F3 狀態更新:出豆中 -------')
  5954. print('------- FO1 狀態更新:入豆中 -------')
  5955. elif F4 == 'F_OutputtingBean':
  5956. FO1 = 'FO_InputtingBean'
  5957. print('------- F4 狀態更新:出豆中 -------')
  5958. print('------- FO1 狀態更新:入豆中 -------')
  5959. elif F5 == 'F_OutputtingBean':
  5960. FO1 = 'FO_InputtingBean'
  5961. print('------- F5 狀態更新:出豆中 -------')
  5962. print('------- FO1 狀態更新:入豆中 -------')
  5963. elif F6 == 'F_OutputtingBean':
  5964. FO1 = 'FO_InputtingBean'
  5965. print('------- F6 狀態更新:出豆中 -------')
  5966. print('------- FO1 狀態更新:入豆中 -------')
  5967. # 出料儲豆槽入料滿時, 出料儲豆槽狀態改為可出豆 (需判斷是哪個桶槽, 好關閉蝴蝶閥)
  5968. elif FO1 == 'FO_InputtingBean' and FO_UP_UltraSoniclist[0] >= Ferment_Output_bean_height:
  5969. if F1 == 'F_OutputtingBean':
  5970. FO1 = 'FO_OutputtingBean'
  5971. print('------- FO1 狀態更新:可出豆 -------')
  5972. # [致動器] 出料真空吸料機 OFF
  5973. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  5974. print('data: ', data)
  5975. # mqtt_f(data)
  5976. # [致動器] 蝴蝶閥 OFF
  5977. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "off" }
  5978. print('data: ', data)
  5979. # mqtt_f(data)
  5980. elif F2 == 'F_OutputtingBean':
  5981. pass # TODO ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 1020 TODO
  5982. # 出料儲豆槽入料時, 桶槽已空, 則桶槽回到空桶等待, 出料儲豆槽可出豆 ←←←←←←←←←←←←←←←←←←←←←←←←←← 1012 這段怪怪的
  5983. elif FO1 == 'FO_InputtingBean' and Ferment_OutputtingBean_number == 1:
  5984. if F1 == 'F_OutputtingBean':
  5985. if F_UP_UltraSoniclist[0] < Ferment_Tank_bean_empty:
  5986. FO1 = 'FO_OutputtingBean'
  5987. print('------- FO1 狀態更新:可出豆 -------')
  5988. # 增加消毒電磁閥開關
  5989. # [致動器] 消毒電磁閥 ON
  5990. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "on" }
  5991. print('data: ', data)
  5992. # mqtt_f(data)
  5993. # 暫停 (消毒時間) 秒
  5994. timer = time.time()
  5995. while True:
  5996. if (time.time() - timer) > Ferment_Tank_Disinfect_time :
  5997. # [致動器] 消毒電磁閥 OFF
  5998. data = { "tank_num": "F1", "command": "tank_solenoid_disinfect_status", "value": "off" }
  5999. print('data: ', data)
  6000. # mqtt_f(data)
  6001. break
  6002. print('------- F1 狀態更新:空桶等待 -------')
  6003. F1 = 'F_Waiting'
  6004. else:
  6005. # [致動器] 出料真空吸料機 ON
  6006. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "on" }
  6007. print('data: ', data)
  6008. # mqtt_f(data)
  6009. # 暫停 3 秒
  6010. timer = time.time()
  6011. while True:
  6012. if (time.time() - timer) > 3 :
  6013. # [致動器] 蝴蝶閥 ON
  6014. data = { "tank_num": "F1", "command": "tank_diskvalve_status", "value": "on" }
  6015. print('data: ', data)
  6016. # mqtt_f(data)
  6017. break
  6018. timer = time.time()
  6019. while True:
  6020. if (time.time() - timer) > Ferment_Output_vacuumON_time:
  6021. # [致動器] 出料真空吸料機 OFF
  6022. data = { "tank_num": "F1", "command": "input_vacuum_status", "value": "off" }
  6023. print('data: ', data)
  6024. # mqtt_f(data)
  6025. timer = time.time()
  6026. break
  6027. while True:
  6028. if (time.time() - timer) > Ferment_Output_vacuumOFF_time:
  6029. break
  6030. elif F2 == 'F_OutputtingBean' and F_UP_UltraSoniclist[1] < 5:
  6031. F2 = 'F_Waiting'
  6032. FO1 = 'FO_OutputtingBean'
  6033. print('------- F2 狀態更新:空桶等待 -------')
  6034. print('------- FO1 狀態更新:可出豆 -------')
  6035. elif F3 == 'F_OutputtingBean' and F_UP_UltraSoniclist[2] < 5:
  6036. F3 = 'F_Waiting'
  6037. FO1 = 'FO_OutputtingBean'
  6038. print('------- F3 狀態更新:空桶等待 -------')
  6039. print('------- FO1 狀態更新:可出豆 -------')
  6040. elif F4 == 'F_OutputtingBean' and F_UP_UltraSoniclist[3] < 5:
  6041. F4 = 'F_Waiting'
  6042. FO1 = 'FO_OutputtingBean'
  6043. print('------- F4 狀態更新:空桶等待 -------')
  6044. print('------- FO1 狀態更新:可出豆 -------')
  6045. elif F5 == 'F_OutputtingBean' and F_UP_UltraSoniclist[4] < 5:
  6046. F5 = 'F_Waiting'
  6047. FO1 = 'FO_OutputtingBean'
  6048. print('------- F5 狀態更新:空桶等待 -------')
  6049. print('------- FO1 狀態更新:可出豆 -------')
  6050. elif F6 == 'F_OutputtingBean' and F_UP_UltraSoniclist[5] < 5:
  6051. F6 = 'F_Waiting'
  6052. FO1 = 'FO_OutputtingBean'
  6053. print('------- F6 狀態更新:空桶等待 -------')
  6054. print('------- FO1 狀態更新:可出豆 -------')
  6055. # 出料儲豆槽出料 且 儲豆槽內高度低於 5 , 為空桶等待
  6056. elif FO1 == 'FO_OutputtingBean' and FO_UP_UltraSoniclist[0] < Ferment_Output_bean_empty:
  6057. FO1 = 'FO_Waiting'
  6058. # ----- 發酵入料儲豆槽 FI1~FI2 入豆→可出豆判斷 ------------------------------
  6059. # 1008 移到桶槽前面
  6060. # ----- 發酵出料儲豆槽 FO1~FO2 入豆→可出豆判斷 ------------------------------
  6061. # 1012 移到桶槽可出豆內
  6062. # ----- 將狀態寫入資料庫 ------------------------------
  6063. # 獲取文本框的值並賦值給user實體對象
  6064. F_status = ferment_container_status()
  6065. F_status.Ferment_Input_1 = FI1
  6066. F_status.Ferment_Input_2 = FI2
  6067. F_status.Ferment_Tank_1 = F1
  6068. F_status.Ferment_Tank_2 = F2
  6069. F_status.Ferment_Tank_3 = F3
  6070. F_status.Ferment_Tank_4 = F4
  6071. F_status.Ferment_Tank_5 = F5
  6072. F_status.Ferment_Tank_6 = F6
  6073. F_status.Ferment_Tank_7 = F7
  6074. F_status.Ferment_Tank_8 = F8
  6075. F_status.Ferment_Tank_9 = F9
  6076. F_status.Ferment_Tank_10 = F10
  6077. F_status.Ferment_Tank_11 = F11
  6078. F_status.Ferment_Tank_12 = F12
  6079. F_status.Ferment_Output_1 = FO1
  6080. F_status.Ferment_Output_2 = FO2
  6081. #將數據保存進資料庫
  6082. db.session.add(F_status)
  6083. # 手動提交
  6084. db.session.commit()
  6085. # ----- 將狀態寫入資料庫 ------------------------------
  6086. return jsonify({"Peel_Output_1":PO1,
  6087. "Ferment_Input_1":FI1,
  6088. "Ferment_Tank_1":F1,
  6089. "Ferment_Tank_2":F2,
  6090. "Ferment_Tank_3":F3,
  6091. "Ferment_Tank_4":F4,
  6092. "Ferment_Tank_5":F5,
  6093. "Ferment_Tank_6":F6,
  6094. "Ferment_Output_1":FO1
  6095. })
  6096. '''
  6097. return jsonify({"Ferment_Input_1":FI1,
  6098. "Ferment_Input_2":FI2,
  6099. "Ferment_Tank_1":F1,
  6100. "Ferment_Tank_2":F2,
  6101. "Ferment_Tank_3":F3,
  6102. "Ferment_Tank_4":F4,
  6103. "Ferment_Tank_5":F5,
  6104. "Ferment_Tank_6":F6,
  6105. "Ferment_Tank_7":F7,
  6106. "Ferment_Tank_8":F8,
  6107. "Ferment_Tank_9":F9,
  6108. "Ferment_Tank_10":F10,
  6109. "Ferment_Tank_11":F11,
  6110. "Ferment_Tank_12":F12,
  6111. "Ferment_Output_1":FO1,
  6112. "Ferment_Output_2":FO2
  6113. })
  6114. '''
  6115. # 1026 以流程圖判斷, 改寫 def ferment_auto_test, 以上為原備份
  6116. # 舊有 video 介面
  6117. @main.route('/video')
  6118. def main_video():
  6119. # 獲取登入信息
  6120. if 'id' in session and 'uname' in session and 'status' in session:
  6121. username = session['uname']
  6122. status = session['status']
  6123. if status == 9:
  6124. return render_template('signin_disable.html')
  6125. elif status == 8:
  6126. return render_template('signin_new.html')
  6127. return render_template('video.html', params=locals())
  6128. else:
  6129. return render_template('sign_in.html')
  6130. @main.route('/sitemap')
  6131. def sitemap():
  6132. if request.method == 'GET':
  6133. if 'id' in session and 'uname' in session and 'status' in session:
  6134. username = session['uname']
  6135. status = session['status']
  6136. print('username: ', username)
  6137. print('status: ', status)
  6138. if status == 9:
  6139. return render_template('signin_disable.html', **locals())
  6140. elif status == 8:
  6141. return render_template('signin_new.html', **locals())
  6142. return render_template('sitemap.html', **locals())
  6143. else:
  6144. return render_template('sign_in.html')
  6145. @main.route('/index_navbar', methods=['GET'])
  6146. def index_navbar():
  6147. return render_template('index_navbar.html')
  6148. @main.route('/camera_dry', methods=['GET', 'POST'])
  6149. def camera_dry():
  6150. if request.method == 'GET':
  6151. if 'id' in session and 'uname' in session and 'status' in session:
  6152. username = session['uname']
  6153. status = session['status']
  6154. if status == 9:
  6155. return render_template('signin_disable.html')
  6156. elif status == 8:
  6157. return render_template('signin_new.html')
  6158. return render_template('camera_dry.html', title='乾燥貨櫃攝影機', **locals())
  6159. else:
  6160. return render_template('sign_in.html')
  6161. @main.route('/camera_ferment', methods=['GET', 'POST'])
  6162. def camera_ferment():
  6163. if request.method == 'GET':
  6164. if 'id' in session and 'uname' in session and 'status' in session:
  6165. username = session['uname']
  6166. status = session['status']
  6167. if status == 9:
  6168. return render_template('signin_disable.html')
  6169. elif status == 8:
  6170. return render_template('signin_new.html')
  6171. return render_template('camera_ferment.html', title='發酵貨櫃攝影機', **locals())
  6172. else:
  6173. return render_template('sign_in.html')
  6174. @main.route('/camera_clean', methods=['GET', 'POST'])
  6175. def camera_clean():
  6176. if request.method == 'GET':
  6177. if 'id' in session and 'uname' in session and 'status' in session:
  6178. username = session['uname']
  6179. status = session['status']
  6180. if status == 9:
  6181. return render_template('signin_disable.html')
  6182. elif status == 8:
  6183. return render_template('signin_new.html')
  6184. return render_template('camera_clean.html', title='清洗貨櫃攝影機', **locals())
  6185. else:
  6186. return render_template('sign_in.html')
  6187. @main.route('/camera_dry_1', methods=['GET', 'POST'])
  6188. def camera_dry_2():
  6189. if request.method == 'GET':
  6190. return render_template('camera_dry_1.html', title='乾燥貨櫃攝影機', **locals())
  6191. @main.route('/camera_<tid>', methods=['GET', 'POST'])
  6192. def camera(tid):
  6193. if request.method == 'GET':
  6194. if 'id' in session and 'uname' in session and 'status' in session:
  6195. username = session['uname']
  6196. status = session['status']
  6197. if status == 9:
  6198. return render_template('signin_disable.html')
  6199. elif status == 8:
  6200. return render_template('signin_new.html')
  6201. if tid == 'CCargo_in':
  6202. WS_URL = 'ws:///60.250.156.230:1111'
  6203. camera_title = '清洗貨櫃內部'
  6204. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6205. elif tid == 'CCargo_out':
  6206. WS_URL = 'ws:///60.250.156.230:1111'
  6207. camera_title = '清洗貨櫃外部'
  6208. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6209. elif tid == 'FCargo_in':
  6210. WS_URL = 'ws:///60.250.156.230:1111'
  6211. camera_title = '發酵貨櫃內部'
  6212. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6213. elif tid == 'FCargo_out':
  6214. WS_URL = 'ws:///60.250.156.230:1111'
  6215. camera_title = '發酵貨櫃外部'
  6216. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6217. elif tid == 'DCargo_in':
  6218. WS_URL = 'ws:///60.250.156.230:1111'
  6219. camera_title = '乾燥貨櫃內部'
  6220. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6221. elif tid == 'DCargo_out':
  6222. WS_URL = 'ws:///60.250.156.230:1111'
  6223. camera_title = '乾燥貨櫃外部'
  6224. return render_template('camera.html', title='[畫面]' + camera_title, **locals())
  6225. elif tid[:2] == 'DO':
  6226. WS_URL_list = ['ws:///60.250.156.230:1111',
  6227. 'ws:///60.250.156.230:2222'
  6228. ]
  6229. WS_URL = WS_URL_list[int(tid[2:])-1]
  6230. camera_title = '乾燥出料儲豆槽'
  6231. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6232. elif tid[:2] == 'DI':
  6233. WS_URL_list = ['ws:///60.250.156.230:1111',
  6234. 'ws:///60.250.156.230:2222'
  6235. ]
  6236. WS_URL = WS_URL_list[int(tid[2:])-1]
  6237. camera_title = '乾燥入料儲豆槽'
  6238. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6239. elif tid[:1] == 'D':
  6240. WS_URL_list = ['ws:///60.250.156.230:8093', # D1 攝影機已安裝
  6241. 'ws:///60.250.156.230:2222',
  6242. 'ws:///60.250.156.230:3333',
  6243. 'ws:///60.250.156.230:4444',
  6244. 'ws:///60.250.156.230:5555',
  6245. 'ws:///60.250.156.230:6666',
  6246. 'ws:///60.250.156.230:7777',
  6247. 'ws:///60.250.156.230:8888',
  6248. 'ws:///60.250.156.230:9999',
  6249. 'ws:///60.250.156.230:1010',
  6250. 'ws:///60.250.156.230:1111',
  6251. 'ws:///60.250.156.230:1212'
  6252. ]
  6253. WS_URL = WS_URL_list[int(tid[1:])-1]
  6254. camera_title = '乾燥槽'
  6255. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6256. elif tid[:2] == 'FO':
  6257. WS_URL_list = ['ws:///60.250.156.230:1111',
  6258. 'ws:///60.250.156.230:2222'
  6259. ]
  6260. WS_URL = WS_URL_list[int(tid[2:])-1]
  6261. camera_title = '發酵出料儲豆槽'
  6262. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6263. elif tid[:2] == 'FI':
  6264. WS_URL_list = ['ws:///60.250.156.230:1111',
  6265. 'ws:///60.250.156.230:2222'
  6266. ]
  6267. WS_URL = WS_URL_list[int(tid[2:])-1]
  6268. camera_title = '發酵入料儲豆槽'
  6269. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6270. elif tid[:1] == 'F':
  6271. WS_URL_list = ['ws:///60.250.156.230:8089', # F1 攝影機已安裝
  6272. 'ws:///60.250.156.230:2222',
  6273. 'ws:///60.250.156.230:3333',
  6274. 'ws:///60.250.156.230:4444',
  6275. 'ws:///60.250.156.230:5555',
  6276. 'ws:///60.250.156.230:6666',
  6277. 'ws:///60.250.156.230:7777',
  6278. 'ws:///60.250.156.230:8888',
  6279. 'ws:///60.250.156.230:9999',
  6280. 'ws:///60.250.156.230:1010',
  6281. 'ws:///60.250.156.230:1111',
  6282. 'ws:///60.250.156.230:1212'
  6283. ]
  6284. WS_URL = WS_URL_list[int(tid[1:])-1]
  6285. camera_title = '發酵槽'
  6286. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6287. elif tid[:2] == 'CO':
  6288. WS_URL_list = ['ws:///60.250.156.230:1111',
  6289. 'ws:///60.250.156.230:2222'
  6290. ]
  6291. WS_URL = WS_URL_list[int(tid[2:])-1]
  6292. camera_title = '清洗浮選出料儲豆槽'
  6293. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6294. elif tid[:1] == 'C':
  6295. WS_URL_list = ['ws:///60.250.156.230:8088', # C1 攝影機已安裝
  6296. 'ws:///60.250.156.230:2222',
  6297. 'ws:///60.250.156.230:3333',
  6298. 'ws:///60.250.156.230:4444'
  6299. ]
  6300. WS_URL = WS_URL_list[int(tid[1:])-1]
  6301. camera_title = '清洗浮選槽'
  6302. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6303. elif tid[:2] == 'SO':
  6304. WS_URL_list = ['ws:///60.250.156.230:1111',
  6305. 'ws:///60.250.156.230:2222'
  6306. ]
  6307. WS_URL = WS_URL_list[int(tid[2:])-1]
  6308. camera_title = '色選機出料儲豆槽'
  6309. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6310. elif tid[:1] == 'S':
  6311. WS_URL_list = ['ws:///60.250.156.230:1111',
  6312. 'ws:///60.250.156.230:2222'
  6313. ]
  6314. WS_URL = WS_URL_list[int(tid[1:])-1]
  6315. camera_title = '色選機'
  6316. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6317. elif tid[:2] == 'PO':
  6318. WS_URL_list = ['ws:///60.250.156.230:1111',
  6319. 'ws:///60.250.156.230:2222'
  6320. ]
  6321. WS_URL = WS_URL_list[int(tid[2:])-1]
  6322. camera_title = '脫皮機出料儲豆槽'
  6323. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6324. elif tid[:1] == 'P':
  6325. WS_URL_list = ['ws:///60.250.156.230:1111',
  6326. 'ws:///60.250.156.230:2222'
  6327. ]
  6328. WS_URL = WS_URL_list[int(tid[1:])-1]
  6329. camera_title = '脫皮機'
  6330. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6331. elif tid[:1] == 'R':
  6332. WS_URL_list = ['ws:///60.250.156.230:1111'
  6333. ]
  6334. WS_URL = WS_URL_list[int(tid[1:])-1]
  6335. camera_title = '中水桶'
  6336. return render_template('camera.html', title='[畫面]' + camera_title + ' ' + tid, **locals())
  6337. else:
  6338. return render_template('sign_in.html')
  6339. else:
  6340. pass
  6341. @main.route('/dry_SHT11_<dtid>', methods=['GET', 'POST'])
  6342. def dry_SHT11(dtid):
  6343. if request.method == 'GET':
  6344. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  6345. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  6346. SHT11_Temp = tank_SHT11.SHT11_Temp
  6347. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6348. Soil_Temp = tank_Soil.soil_Temp
  6349. return jsonify({"SHT11_Temp":SHT11_Temp,
  6350. "SHT11_Humidity":SHT11_Humidity,
  6351. "Soil_Temp":Soil_Temp
  6352. })
  6353. else:
  6354. pass
  6355. @main.route('/dry_UltraSonic_<dtid>', methods=['GET', 'POST'])
  6356. def dry_UltraSonic(dtid):
  6357. if request.method == 'GET':
  6358. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D' + dtid).order_by(text('datetime desc')).first()
  6359. UltraSonic = tank_UltraSonic.UltraSonic
  6360. return jsonify({"UltraSonic":UltraSonic
  6361. })
  6362. else:
  6363. pass
  6364. @main.route('/dry_input_UltraSonic_<dtid>', methods=['GET', 'POST'])
  6365. def dry_input_UltraSonic(dtid):
  6366. if request.method == 'GET':
  6367. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI' + dtid).order_by(text('datetime desc')).first()
  6368. UltraSonic = input_UltraSonic.UltraSonic
  6369. return jsonify({"UltraSonic":UltraSonic
  6370. })
  6371. else:
  6372. pass
  6373. @main.route('/dry_output_UltraSonic_<dtid>', methods=['GET', 'POST'])
  6374. def dry_output_UltraSonic(dtid):
  6375. if request.method == 'GET':
  6376. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO' + dtid).order_by(text('datetime desc')).first()
  6377. UltraSonic = output_UltraSonic.UltraSonic
  6378. return jsonify({"UltraSonic":UltraSonic
  6379. })
  6380. else:
  6381. pass
  6382. @main.route('/ferment_SHT11_<ftid>', methods=['GET', 'POST'])
  6383. def ferment_SHT11(ftid):
  6384. if request.method == 'GET':
  6385. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6386. SHT11_Temp = tank_SHT11.SHT11_Temp
  6387. return jsonify({"SHT11_Temp":SHT11_Temp
  6388. })
  6389. else:
  6390. pass
  6391. @main.route('/ferment_WaterLevel_<ftid>', methods=['GET', 'POST'])
  6392. def ferment_WaterLevel(ftid):
  6393. if request.method == 'GET':
  6394. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6395. WaterLevel = tank_WaterLevel.WaterLevel
  6396. return jsonify({"WaterLevel":WaterLevel
  6397. })
  6398. else:
  6399. pass
  6400. @main.route('/ferment_WaterIn_<ftid>', methods=['GET', 'POST'])
  6401. def ferment_WaterIn(ftid):
  6402. if request.method == 'GET':
  6403. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6404. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  6405. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6406. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  6407. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6408. WaterLevel = tank_WaterLevel.WaterLevel
  6409. return jsonify({"UltraSonic":UltraSonic,
  6410. "WaterLevel":WaterLevel
  6411. })
  6412. else:
  6413. pass
  6414. @main.route('/ferment_UltraSonic_<ftid>', methods=['GET', 'POST'])
  6415. def ferment_UltraSonic(ftid):
  6416. if request.method == 'GET':
  6417. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6418. UltraSonic = (float(tank_UltraSonic.UltraSonic))
  6419. return jsonify({"UltraSonic":UltraSonic
  6420. })
  6421. else:
  6422. pass
  6423. '''
  6424. @main.route('/ferment_LiDAR_<ftid>', methods=['GET', 'POST'])
  6425. def ferment_LiDAR(ftid):
  6426. if request.method == 'GET':
  6427. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6428. LiDAR = tank_LiDAR.LiDAR
  6429. return jsonify({"LiDAR":LiDAR
  6430. })
  6431. else:
  6432. pass
  6433. '''
  6434. @main.route('/ferment_input_UltraSonic_<ftid>', methods=['GET', 'POST'])
  6435. def ferment_input_UltraSonic_(ftid):
  6436. if request.method == 'GET':
  6437. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + ftid).order_by(text('datetime desc')).first()
  6438. UltraSonic = input_UltraSonic.UltraSonic
  6439. return jsonify({"UltraSonic":UltraSonic
  6440. })
  6441. else:
  6442. pass
  6443. @main.route('/ferment_output_UltraSonic_<ftid>', methods=['GET', 'POST'])
  6444. def ferment_output_UltraSonic_(ftid):
  6445. if request.method == 'GET':
  6446. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + ftid).order_by(text('datetime desc')).first()
  6447. UltraSonic = output_UltraSonic.UltraSonic
  6448. return jsonify({"UltraSonic":UltraSonic
  6449. })
  6450. else:
  6451. pass
  6452. @main.route('/ferment_watertesting_<tid>', methods=['GET', 'POST'])
  6453. def ferment_watertesting(tid):
  6454. if request.method == 'GET':
  6455. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6456. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6457. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6458. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  6459. PH = tank_PH.PH
  6460. ORP = tank_ORP.ORP
  6461. DO = tank_DO.DO
  6462. EC = tank_EC.EC
  6463. return jsonify({"PH":PH,
  6464. "ORP":ORP,
  6465. "DO":DO,
  6466. "EC":EC,
  6467. })
  6468. '''
  6469. @main.route('/ferment_PressureWaterLevel_<ftid>', methods=['GET', 'POST'])
  6470. def ferment_PressureWaterLevel(ftid):
  6471. if request.method == 'GET':
  6472. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + ftid).order_by(text('datetime desc')).first()
  6473. PressureWaterLevel = float(tank_PressureWaterLevel.PressureWaterLevel)
  6474. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  6475. print("PressureWaterLevel_start: ", PressureWaterLevel)
  6476. return jsonify({"PressureWaterLevel":PressureWaterLevel
  6477. })
  6478. # 此段刪除
  6479. while int(PressureWaterLevel) < int(testing_water_height):
  6480. tank_water_status = 'NO'
  6481. time.sleep(3)
  6482. # print(ferment_water_height(testing_water_height))
  6483. # [目前桶內水位高度]發酵槽_感測器_壓力式水位計
  6484. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  6485. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  6486. print("-- MySQL --")
  6487. print("tank_PressureWaterLevel: ", tank_PressureWaterLevel)
  6488. # tank_water_height()
  6489. # print("PressureWaterLevel_while: ", PressureWaterLevel)
  6490. ferment_water_height(testing_water_height)
  6491. return jsonify({"testing_water_height":testing_water_height,
  6492. "tank_water_status":tank_water_status
  6493. })
  6494. else:
  6495. tank_water_status = 'OK'
  6496. print("PressureWaterLevel_else: ", PressureWaterLevel)
  6497. return jsonify({"testing_water_height":testing_water_height,
  6498. "tank_water_status":tank_water_status
  6499. })
  6500. '''
  6501. '''
  6502. def tank_water_height():
  6503. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F1').order_by(text('datetime desc')).first()
  6504. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  6505. print("tank_water_height", PressureWaterLevel)
  6506. return PressureWaterLevel
  6507. '''
  6508. @main.route('/loading/R<rtid>', methods=['GET', 'POST'])
  6509. def R_loading(rtid):
  6510. if request.method == 'GET':
  6511. # 致動器_中水桶
  6512. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+rtid).order_by(text('datetime desc')).first()
  6513. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  6514. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  6515. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  6516. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  6517. return jsonify({"tank_solenoid_water_in":tank_solenoid_water_in,
  6518. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  6519. "tank_solenoid_water_out":tank_solenoid_water_out,
  6520. "tank_pump_reclaimed_out":tank_pump_reclaimed_out
  6521. })
  6522. else:
  6523. pass
  6524. @main.route('/loading/SO<sotid>', methods=['GET', 'POST'])
  6525. def SO_loading(sotid):
  6526. if request.method == 'GET':
  6527. # 致動器_脫皮機_ALL
  6528. output_actuator = colorselect_output_actuator.query.filter_by(tank_num='SO'+sotid).order_by(text('datetime desc')).first()
  6529. output_vacuum = output_actuator.vacuum
  6530. return jsonify({"output_vacuum":output_vacuum
  6531. })
  6532. else:
  6533. pass
  6534. @main.route('/loading/S<stid>', methods=['GET', 'POST'])
  6535. def S_loading(stid):
  6536. if request.method == 'GET':
  6537. # 致動器_色選機
  6538. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  6539. tank_vacuum = tank_actuator.vacuum
  6540. tank_motor = tank_actuator.motor
  6541. tank_nozzle = tank_actuator.nozzle
  6542. # 致動器_超音波感測器colorselect_tank_UltraSonic
  6543. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  6544. UltraSonic = tank_UltraSonic.UltraSonic
  6545. # 致動器_顏色感測器
  6546. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+stid).order_by(text('datetime desc')).first()
  6547. color = tank_color.color
  6548. return jsonify({"tank_vacuum":tank_vacuum,
  6549. "tank_motor":tank_motor,
  6550. "tank_nozzle":tank_nozzle,
  6551. "UltraSonic":UltraSonic,
  6552. "color":color
  6553. })
  6554. else:
  6555. pass
  6556. @main.route('/loading/PO<potid>', methods=['GET', 'POST'])
  6557. def PO_loading(potid):
  6558. if request.method == 'GET':
  6559. # 致動器_脫皮機_ALL
  6560. output_actuator = peel_output_actuator.query.filter_by(tank_num='PO'+potid).order_by(text('datetime desc')).first()
  6561. output_vacuum = output_actuator.vacuum
  6562. return jsonify({"output_vacuum":output_vacuum
  6563. })
  6564. else:
  6565. pass
  6566. @main.route('/loading/P<ptid>', methods=['GET', 'POST'])
  6567. def P_loading(ptid):
  6568. if request.method == 'GET':
  6569. # 致動器_脫皮機_ALL
  6570. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+ptid).order_by(text('datetime desc')).first()
  6571. tank_vacuum = tank_actuator.vacuum
  6572. tank_motor = tank_actuator.motor
  6573. return jsonify({"tank_vacuum":tank_vacuum,
  6574. "tank_motor":tank_motor})
  6575. else:
  6576. pass
  6577. @main.route('/loading/CO<cotid>', methods=['GET', 'POST'])
  6578. def CO_loading(cotid):
  6579. if request.method == 'GET':
  6580. output_actuator = clean_output_actuator.query.filter_by(tank_num='CO'+cotid).order_by(text('datetime desc')).first()
  6581. output_vacuum = output_actuator.vacuum
  6582. return jsonify({"output_vacuum":output_vacuum
  6583. })
  6584. else:
  6585. pass
  6586. @main.route('/loading/C<ctid>', methods=['GET', 'POST'])
  6587. def C_loading(ctid):
  6588. if request.method == 'GET':
  6589. # 致動器_浮選清洗_ALL
  6590. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  6591. tank_vacuum = tank_actuator.vacuum
  6592. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  6593. tank_motor = tank_actuator.motor
  6594. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  6595. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  6596. tank_pump_water_in = tank_actuator.pump_water_in
  6597. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  6598. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  6599. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  6600. tank_pump_disinfect = tank_actuator.pump_disinfect
  6601. tank_diskvalve = tank_actuator.diskvalve
  6602. # 感測器_浮選清洗_超音波感測器
  6603. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  6604. UltraSonic = tank_UltraSonic.UltraSonic
  6605. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  6606. Encoder = tank_Encoder.Encoder
  6607. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  6608. tankTurbidity = tank_Turbidity.tankTurbidity
  6609. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(ctid)).order_by(text('datetime desc')).first()
  6610. filterTurbidity = filter_Turbidity.filterTurbidity
  6611. # tank_pump_waterInput = tank_actuator.pump_waterInput
  6612. # tank_pump_waterL2L3 = tank_actuator.pump_waterL2L3
  6613. # tank_pump_waterL4L5 = tank_actuator.pump_waterL4L5
  6614. # tank_solenoid_waterL2L3 = tank_actuator.solenoid_waterL2L3
  6615. # tank_solenoid_waterL4L5 = tank_actuator.solenoid_waterL4L5
  6616. # tank_stepping_motor = tank_actuator.stepping_motor
  6617. return jsonify({"UltraSonic":UltraSonic,
  6618. "Encoder":Encoder,
  6619. "tankTurbidity":tankTurbidity,
  6620. "filterTurbidity":filterTurbidity,
  6621. "tank_vacuum":tank_vacuum,
  6622. "tank_threewayvalve_input":tank_threewayvalve_input,
  6623. "tank_motor":tank_motor,
  6624. "tank_solenoid_reclaimed_in":tank_solenoid_reclaimed_in,
  6625. "tank_solenoid_water_in":tank_solenoid_water_in,
  6626. "tank_pump_water_in":tank_pump_water_in,
  6627. "tank_solenoid_water_out":tank_solenoid_water_out,
  6628. "tank_solenoid_reclaimed_out":tank_solenoid_reclaimed_out,
  6629. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  6630. "tank_pump_disinfect":tank_pump_disinfect,
  6631. "tank_diskvalve":tank_diskvalve
  6632. })
  6633. else:
  6634. pass
  6635. @main.route('/loading/F<ftid>', methods=['GET', 'POST'])
  6636. def F_loading(ftid):
  6637. if request.method == 'GET':
  6638. # 致動器_發酵槽_ALL
  6639. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6640. tank_vacuum = tank_actuator.vacuum
  6641. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  6642. tank_diskvalve = tank_actuator.diskvalve
  6643. solenoid_tank_pump = tank_actuator.solenoid_tank_pump
  6644. tank_solenoid_disinfect = tank_actuator.solenoid_tank_disinfect
  6645. outer_solenoid_water = tank_actuator.solenoid_outer_water
  6646. tank_solenoid_water_in = tank_actuator.solenoid_tank_water_in
  6647. tank_solenoid_water_out = tank_actuator.solenoid_tank_water_out
  6648. tank_pump_sensor = tank_actuator.pump_sensor
  6649. outer_threewayvalve_float = tank_actuator.threewayvalve_outer_float
  6650. tank_motor = tank_actuator.motor
  6651. tank_heater1 = tank_actuator.heater1
  6652. tank_heater2 = tank_actuator.heater2
  6653. tank_temp_enable = tank_actuator.temp_enable
  6654. tank_temp = tank_actuator.temp
  6655. # 感測器_發酵桶_SHT11
  6656. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6657. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  6658. SHT11_Humidity = float(tank_SHT11.SHT11_Humidity)
  6659. # 感測器_發酵桶_二氧化碳
  6660. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6661. CO2 = float(tank_CO2.CO2)
  6662. # 感測器_發酵桶_酸鹼值
  6663. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6664. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6665. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6666. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6667. PH = float(tank_PH.PH)
  6668. ORP = float(tank_ORP.ORP)
  6669. DO = float(tank_DO.DO)
  6670. EC = float(tank_EC.EC)
  6671. # 感測器_發酵桶_氣壓
  6672. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6673. PA = float(tank_PA.PA)
  6674. # 感測器_發酵桶_超音波感測器
  6675. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6676. UltraSonic= (float(tank_UltraSonic.UltraSonic))
  6677. # 感測器_發酵桶_保溫夾層水位計
  6678. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6679. WaterLevel = tank_WaterLevel.WaterLevel
  6680. # 感測器_發酵桶_咖啡生豆高度
  6681. # tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6682. # LiDAR = tank_LiDAR.LiDAR
  6683. # 感測器_發酵桶_水位高度
  6684. # tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6685. # PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  6686. # 感測器_發酵桶_馬達編碼器
  6687. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+ftid).order_by(text('datetime desc')).first()
  6688. motorEncoder = tank_motorEncoder.motorEncoder
  6689. return jsonify({"SHT11_Temp": SHT11_Temp,
  6690. "SHT11_Humidity":SHT11_Humidity,
  6691. "CO2":CO2,
  6692. "PH":PH,
  6693. "ORP":ORP,
  6694. "DO":DO,
  6695. "EC":EC,
  6696. "PA":PA,
  6697. "WaterLevel":WaterLevel,
  6698. "UltraSonic":UltraSonic,
  6699. "motorEncoder":motorEncoder,
  6700. "tank_vacuum":tank_vacuum,
  6701. "tank_threewayvalve_input":tank_threewayvalve_input,
  6702. "tank_diskvalve":tank_diskvalve,
  6703. "solenoid_tank_pump":solenoid_tank_pump,
  6704. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  6705. "outer_solenoid_water":outer_solenoid_water,
  6706. "tank_solenoid_water_in":tank_solenoid_water_in,
  6707. "tank_solenoid_water_out":tank_solenoid_water_out,
  6708. "tank_pump_sensor":tank_pump_sensor,
  6709. "outer_threewayvalve_float":outer_threewayvalve_float,
  6710. "tank_motor":tank_motor,
  6711. "tank_heater1":tank_heater1,
  6712. "tank_heater2":tank_heater2,
  6713. "tank_temp_enable":tank_temp_enable,
  6714. "tank_temp":tank_temp
  6715. })
  6716. else:
  6717. pass
  6718. @main.route('/loading/FI<fitid>', methods=['GET', 'POST'])
  6719. def FI_loading(fitid):
  6720. if request.method == 'GET':
  6721. input_actuator = ferment_input_actuator.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  6722. input_vacuum = input_actuator.vacuum
  6723. input_sensor = ferment_input_UltraSonic.query.filter_by(tank_num='F'+fitid).order_by(text('datetime desc')).first()
  6724. # input_UltraSonic = float("{:.2f}".format(34.6 - float(input_sensor.UltraSonic)))
  6725. input_UltraSonic = float(input_sensor.UltraSonic)
  6726. return jsonify({"input_UltraSonic":input_UltraSonic,
  6727. "input_vacuum":input_vacuum
  6728. })
  6729. else:
  6730. pass
  6731. @main.route('/loading/FO<fotid>', methods=['GET', 'POST'])
  6732. def FO_loading(fotid):
  6733. if request.method == 'GET':
  6734. output_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  6735. output_vacuum = output_actuator.vacuum
  6736. output_sensor = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+fotid).order_by(text('datetime desc')).first()
  6737. output_UltraSonic = output_sensor.UltraSonic
  6738. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+fotid).order_by(text('datetime desc')).first()
  6739. LiDAR = tank_LiDAR.LiDAR
  6740. return jsonify({"output_UltraSonic":output_UltraSonic,
  6741. "output_vacuum":output_vacuum,
  6742. "LiDAR":LiDAR
  6743. })
  6744. else:
  6745. pass
  6746. @main.route('/loading/DI<ditid>', methods=['GET', 'POST'])
  6747. def DI_loading(ditid):
  6748. if request.method == 'GET':
  6749. input_actuator = dry_input_brake.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  6750. input_vacuum = input_actuator.vacuum
  6751. input_sensor = dry_input_sensor.query.filter_by(tank_num='DI'+ditid).order_by(text('datetime desc')).first()
  6752. input_UltraSonic = input_sensor.UltraSonic
  6753. return jsonify({"input_UltraSonic":input_UltraSonic,
  6754. "input_vacuum":input_vacuum
  6755. })
  6756. else:
  6757. pass
  6758. @main.route('/loading/DO<dotid>', methods=['GET', 'POST'])
  6759. def DO_loading(dotid):
  6760. if request.method == 'GET':
  6761. output_actuator = dry_output_brake.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  6762. output_vacuum = output_actuator.vacuum
  6763. output_sensor = dry_output_sensor.query.filter_by(tank_num='DO'+dotid).order_by(text('datetime desc')).first()
  6764. output_UltraSonic = output_sensor.UltraSonic
  6765. return jsonify({"output_vacuum":output_vacuum,
  6766. "output_UltraSonic":output_UltraSonic
  6767. })
  6768. else:
  6769. pass
  6770. @main.route('/loading/D<dtid>', methods=['GET', 'POST'])
  6771. def D_loading(dtid):
  6772. if request.method == 'GET':
  6773. # 感測器_乾燥桶_超音波感測器
  6774. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  6775. UltraSonic = tank_UltraSonic.UltraSonic
  6776. # 感測器_乾燥桶_SHT11
  6777. tonow = dt.now()
  6778. # 感測器_乾燥桶_SHT11
  6779. print("tonow: ", tonow)
  6780. time_del = timedelta(minutes=-60)
  6781. bias_date_time = tonow + time_del
  6782. # print(dt.now() >= dt(2021,11,29,17,35,36))
  6783. # bias_min = tonow.minute + 3
  6784. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(dtid))\
  6785. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  6786. .order_by(text('datetime desc')).first()
  6787. 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'>
  6788. print("hasattr tank_SHT11: ", hasattr(object, 'tank_SHT11'))
  6789. print("hasattr tank_SHT11.SHT11_Temp: ", hasattr(object, 'tank_SHT11.SHT11_Temp'))
  6790. try:
  6791. SHT11_Temp = tank_SHT11.SHT11_Temp
  6792. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6793. except AttributeError:
  6794. SHT11_Temp = " — "
  6795. SHT11_Humidity = " — "
  6796. # if not hasattr(object, 'tank_SHT11.SHT11_Temp'):
  6797. # SHT11_Temp = " — "
  6798. # SHT11_Humidity = " — "
  6799. # else:
  6800. # SHT11_Temp = tank_SHT11.SHT11_Temp
  6801. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6802. # tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  6803. # SHT11_Temp = tank_SHT11.SHT11_Temp
  6804. # SHT11_Humidity = tank_SHT11.SHT11_Humidity
  6805. # 感測器_乾燥桶_土壤三合一
  6806. tank_Soil = dry_tank_Soil.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  6807. soil_Temp = tank_Soil.soil_Temp
  6808. soil_Humidity = tank_Soil.soil_Humidity
  6809. soil_EC = tank_Soil.soil_EC
  6810. # 感測器_乾燥桶_氣壓
  6811. tank_PA = dry_tank_PA.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  6812. PA = tank_PA.PA
  6813. # 致動器_乾燥桶_ALL
  6814. tank_brake = dry_tank_brake.query.filter_by(tank_num="D"+dtid).order_by(text('datetime desc')).first()
  6815. # tank_vacuum = 'ON' if i<100 else 2 if i>100 else 0
  6816. tank_vacuum = tank_brake.vacuum
  6817. tank_threewayvalve_input = tank_brake.threewayvalve_input
  6818. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  6819. tank_diskvalve = tank_brake.diskvalve
  6820. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  6821. tank_solenoid_water = tank_brake.solenoid_water
  6822. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  6823. tank_motor = tank_brake.motor
  6824. tank_blower = tank_brake.blower
  6825. tank_heater1 = tank_brake.heater1
  6826. tank_heater2 = tank_brake.heater2
  6827. tank_temp1_enable = tank_brake.temp1_enable
  6828. tank_temp1 = tank_brake.temp1
  6829. #return jsonify({"peeling": peeling_rpm})
  6830. '''
  6831. info = psutil.virtual_memory()
  6832. print('記憶體使用: ', psutil.Process(os.getpid()).memory_info().rss)
  6833. # print('總記憶體: ', info.total)
  6834. print('記憶體占比: ', info.percent)
  6835. print('cpu 個數: ', psutil.cpu_count())
  6836. '''
  6837. print("SHT11_Temp", SHT11_Temp)
  6838. return jsonify({"UltraSonic":UltraSonic,
  6839. "SHT11_Temp": SHT11_Temp,
  6840. "SHT11_Humidity":SHT11_Humidity,
  6841. "soil_Temp":soil_Temp,
  6842. "soil_Humidity":soil_Humidity,
  6843. "soil_EC":soil_EC,
  6844. "PA":PA,
  6845. "tank_vacuum":tank_vacuum,
  6846. "tank_threewayvalve_input":tank_threewayvalve_input,
  6847. "tank_threewayvalve_bean":tank_threewayvalve_bean,
  6848. "tank_diskvalve":tank_diskvalve,
  6849. "tank_solenoid_disinfect":tank_solenoid_disinfect,
  6850. "tank_solenoid_water":tank_solenoid_water,
  6851. "tank_solenoid_outer_water":tank_solenoid_outer_water,
  6852. "tank_motor":tank_motor,
  6853. "tank_blower":tank_blower,
  6854. "tank_heater1":tank_heater1,
  6855. "tank_heater2":tank_heater2,
  6856. "tank_temp1_enable":tank_temp1_enable,
  6857. "tank_temp1":tank_temp1
  6858. })
  6859. else:
  6860. pass
  6861. @main.route('/index_new')
  6862. def index_new():
  6863. if 'id' in session and 'uname' in session and 'status' in session:
  6864. username = session['uname']
  6865. status = session['status']
  6866. if status == 9:
  6867. return render_template('signin_disable.html', **locals())
  6868. elif status == 8:
  6869. return render_template('signin_new.html', **locals())
  6870. else:
  6871. return render_template('oops.html', **locals())
  6872. return render_template('index_new.html', title='Smart Coffee', **locals())
  6873. @main.route('/user/<name>')
  6874. def user(name):
  6875. return render_template('hello.html', name=name)
  6876. '''
  6877. @main.route('/plot.png')
  6878. def plot():
  6879. # 重新整理會有問題
  6880. # 圖的寬和高
  6881. fig = plt.figure()
  6882. # 在圖中新增子圖, 通常多個圖才會用到?
  6883. axis = fig.add_subplot(1, 1, 1)
  6884. # x、 軸資料
  6885. xs = range(100)
  6886. ys = [random.randint(1, 50) for x in xs]
  6887. axis.plot(xs, ys)
  6888. canvas = FigureCanvas(fig)
  6889. output = io.BytesIO()
  6890. canvas.print_png(output)
  6891. response = make_response(output.getvalue())
  6892. response.mimetype = 'image/png'
  6893. return response
  6894. '''
  6895. @main.route('/chart_<tank>/<sensor_name>/<tid>', methods=['GET', 'POST'])
  6896. def chart_D(tank, sensor_name, tid):
  6897. if request.method == 'GET':
  6898. if 'id' in session and 'uname' in session and 'status' in session:
  6899. username = session['uname']
  6900. status = session['status']
  6901. if status == 9:
  6902. return render_template('signin_disable.html')
  6903. elif status == 8:
  6904. return render_template('signin_new.html')
  6905. else:
  6906. return render_template('oops.html')
  6907. if tank == 'DI':
  6908. return render_template('sensor_chart_DI.html', title='[圖表]' + tank + tid + '乾燥入料儲豆槽', **locals())
  6909. elif tank == 'DO':
  6910. return render_template('sensor_chart_DO.html', title='[圖表]' + tank + tid + '乾燥出料儲豆槽', **locals())
  6911. elif tank == 'FI':
  6912. return render_template('sensor_chart_FI.html', title='[圖表]' + tank + tid + '發酵入料儲豆槽', **locals())
  6913. elif tank == 'FO':
  6914. return render_template('sensor_chart_FO.html', title='[圖表]' + tank + tid + '發酵出料儲豆槽', **locals())
  6915. elif tank == 'F':
  6916. return render_template('sensor_chart_F.html', title='[圖表]' + tank + tid + '發酵槽', **locals())
  6917. else:
  6918. return render_template('sensor_chart_D.html', title='[圖表]' + tank + tid + '乾燥槽', **locals())
  6919. elif request.method == 'POST':
  6920. if 'id' in session and 'uname' in session and 'status' in session:
  6921. username = session['uname']
  6922. status = session['status']
  6923. if status == 9:
  6924. return render_template('signin_disable.html', **locals())
  6925. elif status == 8:
  6926. return render_template('signin_new.html', **locals())
  6927. else:
  6928. return render_template('oops.html', **locals())
  6929. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  6930. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  6931. sensor_name = request.values['sensors']
  6932. print('sensor_name:', sensor_name)
  6933. # 判斷資料索取區間 起<迄
  6934. if starttime < endtime :
  6935. # print('starttime endtime:', starttime, endtime)
  6936. # print('TF:', starttime<endtime ) # 可以比較 起<迄
  6937. # [html]2021-07-19T09:00 轉換成 [python]datetime.datetime(2021, 07, 19, 09, 00, 00)
  6938. start_YY = starttime[:4] # '2021'
  6939. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  6940. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  6941. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  6942. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  6943. start_ss = 0
  6944. end_YY = endtime[:4] # '2021'
  6945. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  6946. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  6947. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  6948. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  6949. end_ss = 0
  6950. time_range = []
  6951. temp_range = []
  6952. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  6953. plt.switch_backend('agg')
  6954. plt.figure()
  6955. if tank == 'DI':
  6956. print('DI')
  6957. if sensor_name == 'UltraSonic':
  6958. for d in db.session.query(dry_input_sensor) \
  6959. .filter_by(tank_num='DI' + tid) \
  6960. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_input_sensor.datetime) \
  6961. .filter(dry_input_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  6962. .order_by(dry_input_sensor.datetime):
  6963. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  6964. time_range.append(str(d.datetime))
  6965. temp_range.append(float(d.UltraSonic))
  6966. print('time_range:', time_range)
  6967. print('temp_range:', temp_range)
  6968. return render_template('sensor_chart_DI.html', **locals())
  6969. elif tank == 'DO':
  6970. print('DO')
  6971. if sensor_name == 'UltraSonic':
  6972. for d in db.session.query(dry_output_sensor) \
  6973. .filter_by(tank_num='DO' + tid) \
  6974. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_output_sensor.datetime) \
  6975. .filter(dry_output_sensor.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  6976. .order_by(dry_output_sensor.datetime):
  6977. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  6978. time_range.append(str(d.datetime))
  6979. temp_range.append(float(d.UltraSonic))
  6980. print('time_range:', time_range)
  6981. print('temp_range:', temp_range)
  6982. return render_template('sensor_chart_DO.html', **locals())
  6983. elif tank == 'D':
  6984. print('D')
  6985. if sensor_name == 'SHT11_Temp':
  6986. for d in db.session.query(dry_tank_SHT11) \
  6987. .filter_by(tank_num='D' + tid) \
  6988. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  6989. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  6990. .order_by(dry_tank_SHT11.datetime):
  6991. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  6992. time_range.append(str(d.datetime))
  6993. temp_range.append(float(d.SHT11_Temp))
  6994. # 畫出 x 軸基準線
  6995. # plt.axhline(28.5, color= 'r')
  6996. elif sensor_name == 'SHT11_Humidity':
  6997. for d in db.session.query(dry_tank_SHT11) \
  6998. .filter_by(tank_num='D' + tid) \
  6999. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_SHT11.datetime) \
  7000. .filter(dry_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7001. .order_by(dry_tank_SHT11.datetime):
  7002. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7003. time_range.append(str(d.datetime))
  7004. temp_range.append(float(d.SHT11_Humidity))
  7005. elif sensor_name == 'UltraSonic':
  7006. for d in db.session.query(dry_tank_UltraSonic) \
  7007. .filter_by(tank_num='D' + tid) \
  7008. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  7009. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7010. .order_by(dry_tank_UltraSonic.datetime):
  7011. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7012. time_range.append(str(d.datetime))
  7013. temp_range.append(float(d.UltraSonic))
  7014. elif sensor_name == 'PA':
  7015. for d in db.session.query(dry_tank_PA) \
  7016. .filter_by(tank_num='D' + tid) \
  7017. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_PA.datetime) \
  7018. .filter(dry_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7019. .order_by(dry_tank_PA.datetime):
  7020. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7021. time_range.append(str(d.datetime))
  7022. temp_range.append(float(d.PA))
  7023. elif sensor_name == 'soil_Temp':
  7024. for d in db.session.query(dry_tank_Soil) \
  7025. .filter_by(tank_num='D' + tid) \
  7026. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  7027. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7028. .order_by(dry_tank_Soil.datetime):
  7029. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7030. time_range.append(str(d.datetime))
  7031. temp_range.append(float(d.soil_Temp))
  7032. # 畫出 x 軸基準線
  7033. plt.axhline(28.5, color= 'r')
  7034. elif sensor_name == 'soil_Humidity':
  7035. for d in db.session.query(dry_tank_Soil) \
  7036. .filter_by(tank_num='D' + tid) \
  7037. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  7038. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7039. .order_by(dry_tank_Soil.datetime):
  7040. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7041. time_range.append(str(d.datetime))
  7042. temp_range.append(float(d.soil_Humidity))
  7043. elif sensor_name == 'soil_EC':
  7044. for d in db.session.query(dry_tank_Soil) \
  7045. .filter_by(tank_num='D' + tid) \
  7046. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_Soil.datetime) \
  7047. .filter(dry_tank_Soil.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7048. .order_by(dry_tank_Soil.datetime):
  7049. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7050. time_range.append(str(d.datetime))
  7051. temp_range.append(float(d.soil_EC))
  7052. print('time_range:', time_range)
  7053. print('temp_range:', temp_range)
  7054. return render_template('sensor_chart_D.html', **locals())
  7055. elif tank == 'FI':
  7056. print('FI')
  7057. if sensor_name == 'UltraSonic':
  7058. for d in db.session.query(ferment_input_UltraSonic) \
  7059. .filter_by(tank_num='FI' + tid) \
  7060. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_input_UltraSonic.datetime) \
  7061. .filter(ferment_input_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7062. .order_by(ferment_input_UltraSonic.datetime):
  7063. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7064. time_range.append(str(d.datetime))
  7065. temp_range.append(float(d.UltraSonic))
  7066. print('time_range:', time_range)
  7067. print('temp_range:', temp_range)
  7068. return render_template('sensor_chart_FI.html', **locals())
  7069. elif tank == 'FO':
  7070. print('FO')
  7071. if sensor_name == 'UltraSonic':
  7072. for d in db.session.query(ferment_output_UltraSonic) \
  7073. .filter_by(tank_num='FO' + tid) \
  7074. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_output_UltraSonic.datetime) \
  7075. .filter(ferment_output_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7076. .order_by(ferment_output_UltraSonic.datetime):
  7077. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7078. time_range.append(str(d.datetime))
  7079. temp_range.append(float(d.UltraSonic))
  7080. print('time_range:', time_range)
  7081. print('temp_range:', temp_range)
  7082. return render_template('sensor_chart_FO.html', **locals())
  7083. elif tank == 'F':
  7084. print('F')
  7085. if sensor_name == 'LiDAR':
  7086. for d in db.session.query(ferment_tank_LiDAR) \
  7087. .filter_by(tank_num='F' + tid) \
  7088. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_LiDAR.datetime) \
  7089. .filter(ferment_tank_LiDAR.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7090. .order_by(ferment_tank_LiDAR.datetime):
  7091. time_range.append(str(d.datetime))
  7092. temp_range.append(float(d.LiDAR))
  7093. elif sensor_name == 'motorEncoder':
  7094. print('sensor_name == motorEncoder')
  7095. for d in db.session.query(ferment_tank_motorEncoder) \
  7096. .filter_by(tank_num='F' + tid) \
  7097. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_motorEncoder.datetime) \
  7098. .filter(ferment_tank_motorEncoder.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7099. .order_by(ferment_tank_motorEncoder.datetime):
  7100. time_range.append(str(d.datetime))
  7101. temp_range.append(float(d.motorEncoder))
  7102. print('time_range: ' + time_range)
  7103. print('temp_range: ' + temp_range)
  7104. elif sensor_name == 'PressureWaterLevel':
  7105. for d in db.session.query(ferment_tank_PressureWaterLevel) \
  7106. .filter_by(tank_num='F' + tid) \
  7107. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  7108. .filter(ferment_tank_PressureWaterLevel.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7109. .order_by(ferment_tank_PressureWaterLevel.datetime):
  7110. time_range.append(str(d.datetime))
  7111. temp_range.append('{:.2f}'.format(float(d.PressureWaterLevel)))
  7112. elif sensor_name == 'SHT11_Temp':
  7113. for d in db.session.query(ferment_tank_SHT11) \
  7114. .filter_by(tank_num='F' + tid) \
  7115. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PressureWaterLevel.datetime) \
  7116. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7117. .order_by(ferment_tank_SHT11.datetime):
  7118. time_range.append(str(d.datetime))
  7119. temp_range.append(float(d.SHT11_Temp))
  7120. elif sensor_name == 'SHT11_Humidity':
  7121. for d in db.session.query(ferment_tank_SHT11) \
  7122. .filter_by(tank_num='F' + tid) \
  7123. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_SHT11.datetime) \
  7124. .filter(ferment_tank_SHT11.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7125. .order_by(ferment_tank_SHT11.datetime):
  7126. time_range.append(str(d.datetime))
  7127. temp_range.append(float(d.SHT11_Humidity))
  7128. elif sensor_name == 'CO2':
  7129. for d in db.session.query(ferment_tank_CO2) \
  7130. .filter_by(tank_num='F' + tid) \
  7131. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_CO2.datetime) \
  7132. .filter(ferment_tank_CO2.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7133. .order_by(ferment_tank_CO2.datetime):
  7134. time_range.append(str(d.datetime))
  7135. temp_range.append(float(d.CO2))
  7136. elif sensor_name == 'PH':
  7137. for d in db.session.query(ferment_tank_PH) \
  7138. .filter_by(tank_num='F' + tid) \
  7139. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PH.datetime) \
  7140. .filter(ferment_tank_PH.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7141. .order_by(ferment_tank_PH.datetime):
  7142. time_range.append(str(d.datetime))
  7143. temp_range.append(float(d.PH))
  7144. elif sensor_name == 'ORP':
  7145. for d in db.session.query(ferment_tank_ORP) \
  7146. .filter_by(tank_num='F' + tid) \
  7147. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_ORP.datetime) \
  7148. .filter(ferment_tank_ORP.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7149. .order_by(ferment_tank_ORP.datetime):
  7150. time_range.append(str(d.datetime))
  7151. temp_range.append(float(d.ORP))
  7152. elif sensor_name == 'DO':
  7153. for d in db.session.query(ferment_tank_DO) \
  7154. .filter_by(tank_num='F' + tid) \
  7155. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_DO.datetime) \
  7156. .filter(ferment_tank_DO.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7157. .order_by(ferment_tank_DO.datetime):
  7158. time_range.append(str(d.datetime))
  7159. temp_range.append(float(d.DO))
  7160. elif sensor_name == 'EC':
  7161. for d in db.session.query(ferment_tank_EC) \
  7162. .filter_by(tank_num='F' + tid) \
  7163. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_EC.datetime) \
  7164. .filter(ferment_tank_EC.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7165. .order_by(ferment_tank_EC.datetime):
  7166. time_range.append(str(d.datetime))
  7167. temp_range.append(float(d.EC))
  7168. elif sensor_name == 'PA':
  7169. for d in db.session.query(ferment_tank_PA) \
  7170. .filter_by(tank_num='F' + tid) \
  7171. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < ferment_tank_PA.datetime) \
  7172. .filter(ferment_tank_PA.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7173. .order_by(ferment_tank_PA.datetime):
  7174. time_range.append(str(d.datetime))
  7175. temp_range.append(float(d.PA))
  7176. print('time_range:', time_range)
  7177. print('temp_range:', temp_range)
  7178. return render_template('sensor_chart_F.html', **locals())
  7179. '''
  7180. # 設定 x 軸資料、y 軸資料、折線顏色
  7181. plt.plot(time_range, temp_range, 'bo')
  7182. # x 軸標題 (中文無法顯示)
  7183. # plt.xlabel('time')
  7184. # plt.ylabel(sensor_name)
  7185. # x 軸 label 和垂直顯示, rotation='vertical'
  7186. plt.xticks(time_range, rotation='vertical' )
  7187. # 設定圖表標題
  7188. plt.title(sensor_name)
  7189. # 調整圖片與周圍的間距
  7190. plt.tight_layout()
  7191. # plt.show()
  7192. # 儲存圖片 應改為相對路徑
  7193. plt.savefig('C:/Users/USER/Rita/Coffee/CoffeeProject/app/static/img/new_plot.png')
  7194. '''
  7195. # 判斷資料索取區間 起>迄
  7196. else:
  7197. return render_template('sensor_chart_D.html', **locals())
  7198. '''
  7199. @main.route('/chart_DI/<sensor_name>/<tid>', methods=['GET', 'POST'])
  7200. def chart_DI(sensor_name, tid):
  7201. if request.method == 'GET':
  7202. return render_template('sensor_chart_DI.html', **locals())
  7203. elif request.method == 'POST':
  7204. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  7205. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  7206. sensor_name = request.values['sensors']
  7207. print('sensor_name:', sensor_name)
  7208. # 判斷資料索取區間 起<迄
  7209. if starttime < endtime :
  7210. start_YY = starttime[:4] # '2021'
  7211. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  7212. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  7213. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  7214. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  7215. start_ss = 0
  7216. end_YY = endtime[:4] # '2021'
  7217. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  7218. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  7219. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  7220. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  7221. end_ss = 0
  7222. time_range = []
  7223. temp_range = []
  7224. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  7225. plt.switch_backend('agg')
  7226. plt.figure()
  7227. if sensor_name == 'UltraSonic':
  7228. for d in db.session.query(dry_input_sensor) \
  7229. .filter_by(tank_num='DI' + tid) \
  7230. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  7231. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7232. .order_by(dry_tank_UltraSonic.datetime):
  7233. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7234. time_range.append(str(d.datetime))
  7235. temp_range.append(float(d.UltraSonic))
  7236. # 畫出 x 軸基準線
  7237. # plt.axhline(28.5, color= 'r')
  7238. print('time_range:', time_range)
  7239. print('temp_range:', temp_range)
  7240. return render_template('sensor_chart_DI.html', **locals())
  7241. # 判斷資料索取區間 起>迄
  7242. else:
  7243. return render_template('sensor_chart_DI.html', **locals())
  7244. @main.route('/chart_DO/<sensor_name>/<tid>', methods=['GET', 'POST'])
  7245. def chart_DO(sensor_name, tid):
  7246. if request.method == 'GET':
  7247. return render_template('sensor_chart_DO.html', **locals())
  7248. elif request.method == 'POST':
  7249. starttime = request.values['sensor_starttime'] # 2021-07-19T09:00
  7250. endtime = request.values['sensor_endtime'] # 2021-07-19T12:00
  7251. sensor_name = request.values['sensors']
  7252. print('sensor_name:', sensor_name)
  7253. # 判斷資料索取區間 起<迄
  7254. if starttime < endtime :
  7255. start_YY = starttime[:4] # '2021'
  7256. start_MM = starttime[6:7] if starttime[5:7][:1] == '0' else starttime[5:7] # '07'
  7257. start_DD = starttime[9:10] if starttime[8:10][:1] == '0' else starttime[8:10] # '19'
  7258. start_hh = starttime[12:13] if starttime[11:13][:1] == '0' else starttime[11:13] # '09'
  7259. start_mm = starttime[15:] if starttime[14:][:1] == '0' else starttime[14:] # '00'
  7260. start_ss = 0
  7261. end_YY = endtime[:4] # '2021'
  7262. end_MM = endtime[6:7] if endtime[5:7][:1] == '0' else endtime[5:7] # '07'
  7263. end_DD = endtime[9:10] if endtime[8:10][:1] == '0' else endtime[8:10] # '19'
  7264. end_hh = endtime[12:13] if endtime[11:13][:1] == '0' else endtime[11:13] # '09'
  7265. end_mm = endtime[15:] if endtime[14:][:1] == '0' else endtime[14:] # '00'
  7266. end_ss = 0
  7267. time_range = []
  7268. temp_range = []
  7269. # 拿掉會 Error, 要使用沒有 GUI 的 matplotlib
  7270. plt.switch_backend('agg')
  7271. plt.figure()
  7272. if sensor_name == 'UltraSonic':
  7273. for d in db.session.query(dry_input_sensor) \
  7274. .filter_by(tank_num='DO' + tid) \
  7275. .filter(dt(int(start_YY), int(start_MM), int(start_DD), int(start_hh), int(start_mm), int(start_ss)) < dry_tank_UltraSonic.datetime) \
  7276. .filter(dry_tank_UltraSonic.datetime < dt(int(end_YY), int(end_MM), int(end_DD), int(end_hh), int(end_mm), int(end_ss))) \
  7277. .order_by(dry_tank_UltraSonic.datetime):
  7278. # print('d_test', f'{d.datetime} - {d.SHT11_Temp}')
  7279. time_range.append(str(d.datetime))
  7280. temp_range.append(float(d.UltraSonic))
  7281. # 畫出 x 軸基準線
  7282. # plt.axhline(28.5, color= 'r')
  7283. print('time_range:', time_range)
  7284. print('temp_range:', temp_range)
  7285. return render_template('sensor_chart_DO.html', **locals())
  7286. # 判斷資料索取區間 起>迄
  7287. else:
  7288. return render_template('sensor_chart_DO.html', **locals())
  7289. '''
  7290. # Rita 測試
  7291. # 乾燥桶感測器/致動器測試
  7292. # Rita 須加上 <tid> 區分桶號 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  7293. @main.route('/dry_tank/1', methods=['GET'])
  7294. def dry_tank():
  7295. if request.method == 'GET':
  7296. return render_template('dry_tank.html')
  7297. @main.route('/clean', methods=['GET'])
  7298. def clean():
  7299. if 'id' in session and 'uname' in session and 'status' in session:
  7300. username = session['uname']
  7301. status = session['status']
  7302. if status == 9:
  7303. return render_template('signin_disable.html')
  7304. elif status == 8:
  7305. return render_template('signin_new.html')
  7306. else:
  7307. return render_template('oops.html')
  7308. return render_template('clean.html', title='清洗貨櫃', **locals())
  7309. @main.route('/ferment', methods=['GET'])
  7310. def ferment():
  7311. if 'id' in session and 'uname' in session and 'status' in session:
  7312. username = session['uname']
  7313. status = session['status']
  7314. if status == 9:
  7315. return render_template('signin_disable.html')
  7316. elif status == 8:
  7317. return render_template('signin_new.html')
  7318. else:
  7319. return render_template('oops.html')
  7320. return render_template('ferment.html', title='發酵貨櫃', **locals())
  7321. @main.route('/dry', methods=['GET'])
  7322. def dry():
  7323. if request.method == 'GET':
  7324. if 'id' in session and 'uname' in session and 'status' in session:
  7325. username = session['uname']
  7326. status = session['status']
  7327. if status == 9:
  7328. return render_template('signin_disable.html')
  7329. elif status == 8:
  7330. return render_template('signin_new.html')
  7331. else:
  7332. return render_template('oops.html')
  7333. return render_template('dry.html', title='乾燥貨櫃', **locals())
  7334. @main.route('/reclaimedwater_tank/<tid>', methods=['GET', 'POST'])
  7335. def reclaimedwater_tank(tid):
  7336. if request.method == 'GET':
  7337. if 'id' in session and 'uname' in session and 'status' in session:
  7338. username = session['uname']
  7339. status = session['status']
  7340. if status == 9:
  7341. return render_template('signin_disable.html')
  7342. elif status == 8:
  7343. return render_template('signin_new.html')
  7344. else:
  7345. return render_template('oops.html')
  7346. # 致動器_中水桶
  7347. tank_actuator = reclaimed_tank_actuator.query.filter_by(tank_num='R'+tid).order_by(text('datetime desc')).first()
  7348. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  7349. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  7350. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  7351. tank_pump_reclaimed_out = tank_actuator.pump_reclaimed_out
  7352. return render_template('reclaimedwater_tank.html', title='[操作] 中水桶操作介面', **locals())
  7353. elif request.method == 'POST':
  7354. pass
  7355. @main.route('/colorselect_container_tank/<tid>', methods=['GET', 'POST'])
  7356. def colorselect_container_tank(tid):
  7357. if request.method == 'GET':
  7358. if 'id' in session and 'uname' in session and 'status' in session:
  7359. username = session['uname']
  7360. status = session['status']
  7361. if status == 9:
  7362. return render_template('signin_disable.html')
  7363. elif status == 8:
  7364. return render_template('signin_new.html')
  7365. else:
  7366. return render_template('oops.html')
  7367. # 致動器_色選機
  7368. tank_actuator = colorselect_tank_actuator.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  7369. tank_vacuum = tank_actuator.vacuum
  7370. tank_motor = tank_actuator.motor
  7371. tank_nozzle = tank_actuator.nozzle
  7372. # 致動器_超音波感測器colorselect_tank_UltraSonic
  7373. tank_UltraSonic = colorselect_tank_UltraSonic.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  7374. # 致動器_顏色感測器
  7375. tank_color = colorselect_tank_color.query.filter_by(tank_num='S'+tid).order_by(text('datetime desc')).first()
  7376. return render_template('colorselect_container_tank.html', title='[操作] S' + tid + ' 色選機操作介面', **locals())
  7377. elif request.method == 'POST':
  7378. pass
  7379. @main.route('/peel_container_tank/<tid>', methods=['GET', 'POST'])
  7380. def peel_container_tank(tid):
  7381. if request.method == 'GET':
  7382. if 'id' in session and 'uname' in session and 'status' in session:
  7383. username = session['uname']
  7384. status = session['status']
  7385. if status == 9:
  7386. return render_template('signin_disable.html')
  7387. elif status == 8:
  7388. return render_template('signin_new.html')
  7389. else:
  7390. return render_template('oops.html')
  7391. # 致動器_脫皮機_ALL
  7392. # tank_num='P'+str(tid)
  7393. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7394. tank_vacuum = tank_actuator.vacuum
  7395. tank_motor = tank_actuator.motor
  7396. # 感測器_脫皮機出料儲豆槽_超音波高度
  7397. tank_UltraSonic = peel_output_UltraSonic.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7398. # 感測器_脫皮機出料儲豆槽_馬達編碼器
  7399. tank_motorEncoder = peel_output_motorEncoder.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7400. return render_template('peel_container_tank.html', title='[操作] P' + tid + ' 脫皮機操作介面', **locals())
  7401. elif request.method == 'POST':
  7402. pass
  7403. @main.route('/peel_container/<tid>', methods=['GET', 'POST'])
  7404. def peel_container(tid):
  7405. if request.method == 'GET':
  7406. if 'id' in session and 'uname' in session and 'status' in session:
  7407. username = session['uname']
  7408. status = session['status']
  7409. if status == 9:
  7410. return render_template('signin_disable.html')
  7411. elif status == 8:
  7412. return render_template('signin_new.html')
  7413. else:
  7414. return render_template('oops.html')
  7415. # 致動器_入料儲豆槽_真空吸料機
  7416. input_vacuum = peel_input_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7417. input_vacuum = input_vacuum.vacuum
  7418. # 致動器_脫皮機_ALL
  7419. tank_actuator = peel_tank_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7420. tank_vacuum = tank_actuator.vacuum
  7421. tank_motor = tank_actuator.motor
  7422. # 致動器_出料儲豆槽_真空吸料機
  7423. output_vacuum = peel_output_actuator.query.filter_by(tank_num='P'+str(tid)).order_by(text('datetime desc')).first()
  7424. output_vacuum = output_vacuum.vacuum
  7425. return render_template('peel_container.html', title='脫皮機P' + tid + '總操作介面', **locals())
  7426. elif request.method == 'POST':
  7427. pass
  7428. @main.route('/clean_container/<tid>', methods=['GET', 'POST'])
  7429. def clean_container(tid):
  7430. if request.method == 'GET':
  7431. if 'id' in session and 'uname' in session and 'status' in session:
  7432. username = session['uname']
  7433. status = session['status']
  7434. if status == 9:
  7435. return render_template('signin_disable.html')
  7436. elif status == 8:
  7437. return render_template('signin_new.html')
  7438. else:
  7439. return render_template('oops.html')
  7440. # 致動器_入料儲豆槽_真空吸料機
  7441. input_vacuum = clean_input_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7442. input_vacuum = 'ON' if (input_vacuum.vacuum == 1) else 'OFF'
  7443. # 致動器_浮選清洗_ALL
  7444. tank_actuator = clean_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7445. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  7446. tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  7447. tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  7448. tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  7449. tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  7450. tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  7451. tank_stepping_motor = tank_actuator.stepping_motor
  7452. # 致動器_出料儲豆槽_真空吸料機
  7453. output_vacuum = clean_output_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7454. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  7455. # 感測器_浮選清洗_超音波感測器
  7456. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7457. return render_template('clean_container.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  7458. elif request.method == 'POST':
  7459. pass
  7460. @main.route('/clean_container_tank/<tid>', methods=['GET', 'POST'])
  7461. def clean_container_tank(tid):
  7462. if request.method == 'GET':
  7463. if 'id' in session and 'uname' in session and 'status' in session:
  7464. username = session['uname']
  7465. status = session['status']
  7466. if status == 9:
  7467. return render_template('signin_disable.html')
  7468. elif status == 8:
  7469. return render_template('signin_new.html')
  7470. else:
  7471. return render_template('oops.html')
  7472. # 致動器_浮選清洗_ALL
  7473. tank_actuator = cleann_tank_actuator.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7474. try:
  7475. tank_vacuum = tank_actuator.vacuum
  7476. except AttributeError:
  7477. tank_vacuum = 'noValue'
  7478. try:
  7479. tank_threewayvalve_input = tank_actuator.threewayvalve_input
  7480. except AttributeError:
  7481. tank_threewayvalve_input = 'noValue'
  7482. try:
  7483. tank_motor = tank_actuator.motor
  7484. except AttributeError:
  7485. tank_motor = 'noValue'
  7486. try:
  7487. tank_solenoid_reclaimed_in = tank_actuator.solenoid_reclaimed_in
  7488. except AttributeError:
  7489. tank_solenoid_reclaimed_in = 'noValue'
  7490. try:
  7491. tank_solenoid_water_in = tank_actuator.solenoid_water_in
  7492. except AttributeError:
  7493. tank_solenoid_water_in = 'noValue'
  7494. try:
  7495. tank_pump_water_in = tank_actuator.pump_water_in
  7496. except AttributeError:
  7497. tank_pump_water_in = 'noValue'
  7498. try:
  7499. tank_solenoid_water_out = tank_actuator.solenoid_water_out
  7500. except AttributeError:
  7501. tank_solenoid_water_out = 'noValue'
  7502. try:
  7503. tank_solenoid_reclaimed_out = tank_actuator.solenoid_reclaimed_out
  7504. except AttributeError:
  7505. tank_solenoid_reclaimed_out = 'noValue'
  7506. try:
  7507. tank_solenoid_disinfect = tank_actuator.solenoid_disinfect
  7508. except AttributeError:
  7509. tank_solenoid_disinfect = 'noValue'
  7510. try:
  7511. tank_pump_disinfect = tank_actuator.pump_disinfect
  7512. except AttributeError:
  7513. tank_pump_disinfect = 'noValue'
  7514. try:
  7515. tank_diskvalve = tank_actuator.diskvalve
  7516. except AttributeError:
  7517. tank_diskvalve = 'noValue'
  7518. # tank_pump_waterInput = 'ON' if tank_actuator.pump_waterInput == 1 else 'OFF'
  7519. # tank_pump_waterL2L3 = 'ON' if tank_actuator.pump_waterL2L3 == 1 else 'OFF'
  7520. # tank_pump_waterL4L5 = 'ON' if tank_actuator.pump_waterL4L5 == 1 else 'OFF'
  7521. # tank_solenoid_waterL2L3 = 'ON' if tank_actuator.solenoid_waterL2L3 == 1 else 'OFF'
  7522. # tank_solenoid_waterL4L5 = 'ON' if tank_actuator.solenoid_waterL4L5 == 1 else 'OFF'
  7523. # tank_stepping_motor = tank_actuator.stepping_motor
  7524. # 感測器_浮選清洗_超音波感測器
  7525. tank_UltraSonic = clean_tank_UltraSonic.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7526. try:
  7527. UltraSonic = tank_UltraSonic.UltraSonic
  7528. except AttributeError:
  7529. UltraSonic = 'noValue'
  7530. tank_Encoder = clean_tank_Encoder.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7531. try:
  7532. Encoder = tank_Encoder.Encoder
  7533. except AttributeError:
  7534. Encoder = 'noValue'
  7535. tank_Turbidity = clean_tank_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7536. try:
  7537. tankTurbidity = tank_Turbidity.tankTurbidity
  7538. except AttributeError:
  7539. tankTurbidity = 'noValue'
  7540. filter_Turbidity = clean_filter_Turbidity.query.filter_by(tank_num='C'+str(tid)).order_by(text('datetime desc')).first()
  7541. try:
  7542. filterTurbidity = filter_Turbidity.filterTurbidity
  7543. except AttributeError:
  7544. filterTurbidity = 'noValue'
  7545. return render_template('clean_container_tank.html', title='[操作] C' + tid + ' 清洗浮選槽操作介面', **locals())
  7546. elif request.method == 'POST':
  7547. pass
  7548. @main.route('/ferment_container/<tid>', methods=['GET', 'POST'])
  7549. def ferment_container(tid):
  7550. if request.method == 'GET':
  7551. if 'id' in session and 'uname' in session and 'status' in session:
  7552. username = session['uname']
  7553. status = session['status']
  7554. if status == 9:
  7555. return render_template('signin_disable.html')
  7556. elif status == 8:
  7557. return render_template('signin_new.html')
  7558. else:
  7559. return render_template('oops.html')
  7560. # 致動器_發酵槽_ALL
  7561. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7562. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  7563. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  7564. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  7565. tank_solenoid_water_total = 'ON' if tank_actuator.solenoid_tank_water_total == 1 else 'OFF'
  7566. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  7567. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  7568. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  7569. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  7570. tank_threewayvalve_bean = 'ON' if tank_actuator.threewayvalve_bean == 1 else 'OFF'
  7571. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  7572. tank_motor = tank_actuator.motor
  7573. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  7574. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  7575. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  7576. tank_temp = tank_actuator.temp
  7577. # 感測器_發酵桶_SHT11
  7578. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7579. # 感測器_發酵桶_二氧化碳
  7580. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7581. # 感測器_發酵桶_酸鹼值
  7582. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7583. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7584. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7585. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7586. # 感測器_發酵桶_氣壓
  7587. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7588. # 感測器_發酵桶_超音波感測器
  7589. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7590. # 感測器_發酵桶_水位計
  7591. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7592. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  7593. print('tank_WaterLevel', tank_WaterLevel.WaterLevel)
  7594. if tank_WaterLevel.WaterLevel == '1':
  7595. WaterLevel = '滿'
  7596. elif tank_WaterLevel.WaterLevel == '0':
  7597. WaterLevel = '未達滿水高度'
  7598. else:
  7599. WaterLevel = 'ERROR'
  7600. # 感測器_發酵桶_咖啡生豆高度
  7601. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7602. LiDAR = tank_LiDAR.LiDAR
  7603. # 感測器_發酵桶_水位高度
  7604. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7605. PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  7606. if tid in ['1', '2', '3', '4', '5', '6']:
  7607. # print("1")
  7608. # 感測器_入料儲豆槽_超音波感測器
  7609. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  7610. # 致動器_入料儲豆槽_真空吸引機
  7611. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI1').order_by(text('datetime desc')).first()
  7612. input_vacuum = input_vacuum.vacuum
  7613. # 感測器_出料儲豆槽_超音波感測器
  7614. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  7615. # 致動器_出料儲豆槽_真空吸引機
  7616. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO1').order_by(text('datetime desc')).first()
  7617. output_vacuum = output_vacuum.vacuum
  7618. elif tid in ['7', '8', '9', '10', '11', '12']:
  7619. # print("2")
  7620. # 感測器_入料儲豆槽_超音波感測器
  7621. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  7622. # 致動器_入料儲豆槽_真空吸引機
  7623. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI2').order_by(text('datetime desc')).first()
  7624. input_vacuum = input_vacuum.vacuum
  7625. print("input_vacuum", input_vacuum)
  7626. # 感測器_出料儲豆槽_超音波感測器
  7627. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  7628. # 致動器_出料儲豆槽_真空吸引機
  7629. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO2').order_by(text('datetime desc')).first()
  7630. output_vacuum = output_vacuum.vacuum
  7631. print("output_vacuum", output_vacuum)
  7632. return render_template('ferment_container.html', title='發酵槽F' + tid + '總操作介面' , **locals())
  7633. elif request.method == 'POST':
  7634. pass
  7635. @main.route('/ferment_container_tank/<tid>', methods=['GET', 'POST'])
  7636. def ferment_container_tank(tid):
  7637. if request.method == 'GET':
  7638. if 'id' in session and 'uname' in session and 'status' in session:
  7639. username = session['uname']
  7640. status = session['status']
  7641. if status == 9:
  7642. return render_template('signin_disable.html')
  7643. elif status == 8:
  7644. return render_template('signin_new.html')
  7645. else:
  7646. return render_template('oops.html')
  7647. # 致動器_發酵槽_ALL
  7648. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7649. tank_vacuum = 'ON' if tank_actuator.vacuum == 1 else 'OFF'
  7650. tank_threewayvalve_input = 'ON' if tank_actuator.threewayvalve_input == 1 else 'OFF'
  7651. tank_diskvalve = 'ON' if tank_actuator.diskvalve == 1 else 'OFF'
  7652. solenoid_tank_pump = 'ON' if tank_actuator.solenoid_tank_pump == 1 else 'OFF'
  7653. tank_solenoid_disinfect = 'ON' if tank_actuator.solenoid_tank_disinfect == 1 else 'OFF'
  7654. outer_solenoid_water = 'ON' if tank_actuator.solenoid_outer_water == 1 else 'OFF'
  7655. tank_solenoid_water_in = 'ON' if tank_actuator.solenoid_tank_water_in == 1 else 'OFF'
  7656. tank_solenoid_water_out = 'ON' if tank_actuator.solenoid_tank_water_out == 1 else 'OFF'
  7657. tank_pump_sensor = 'ON' if tank_actuator.pump_sensor == 1 else 'OFF'
  7658. outer_threewayvalve_float = 'ON' if tank_actuator.threewayvalve_outer_float == 1 else 'OFF'
  7659. tank_motor = tank_actuator.motor
  7660. tank_heater1 = 'ON' if tank_actuator.heater1 == 1 else 'OFF'
  7661. tank_heater2 = 'ON' if tank_actuator.heater2 == 1 else 'OFF'
  7662. tank_temp_enable = 'ON' if tank_actuator.temp_enable == 1 else 'OFF'
  7663. tank_temp = tank_actuator.temp
  7664. # 感測器_發酵桶_SHT11
  7665. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7666. # 感測器_發酵桶_二氧化碳
  7667. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7668. # 感測器_發酵桶_酸鹼值
  7669. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7670. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7671. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7672. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7673. # 感測器_發酵桶_氣壓
  7674. tank_PA = ferment_tank_PA.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7675. # 感測器_發酵桶_超音波感測器
  7676. tank_UltraSonic = ferment_tank_UltraSonic.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7677. # 感測器_發酵桶_水位計
  7678. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7679. num_tank_WaterLevel = float(tank_WaterLevel.WaterLevel)
  7680. if tank_WaterLevel.WaterLevel == '1':
  7681. WaterLevel = '滿'
  7682. elif tank_WaterLevel.WaterLevel == '0':
  7683. WaterLevel = '未達滿水高度'
  7684. else:
  7685. WaterLevel = 'ERROR'
  7686. # 感測器_發酵桶_咖啡生豆高度
  7687. #tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7688. #LiDAR = tank_LiDAR.LiDAR
  7689. # 感測器_發酵桶_水位高度
  7690. #tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7691. #PressureWaterLevel = '{:.2f}'.format((float(tank_PressureWaterLevel.PressureWaterLevel) -15 -90.278)/9.4214)
  7692. # 感測器_發酵桶_馬達編碼器
  7693. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7694. return render_template('ferment_container_tank.html', title='[操作] F' + tid + ' 發酵槽操作介面', **locals())
  7695. elif request.method == 'POST':
  7696. pass
  7697. @main.route('/ferment_container_input/<tid>', methods=['GET', 'POST'])
  7698. def ferment_container_input(tid):
  7699. if request.method == 'GET':
  7700. if 'id' in session and 'uname' in session and 'status' in session:
  7701. username = session['uname']
  7702. status = session['status']
  7703. if status == 9:
  7704. return render_template('signin_disable.html')
  7705. elif status == 8:
  7706. return render_template('signin_new.html')
  7707. else:
  7708. return render_template('oops.html')
  7709. # 感測器_入料儲豆槽_超音波感測器
  7710. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  7711. # 致動器_入料儲豆槽_真空吸引機
  7712. input_vacuum = ferment_input_actuator.query.filter_by(tank_num='FI' + tid).order_by(text('datetime desc')).first()
  7713. input_vacuum = input_vacuum.vacuum
  7714. return render_template('ferment_container_input.html', title='[操作] FI' + tid + ' 發酵入料儲豆槽操作介面', **locals())
  7715. elif request.method == 'POST':
  7716. pass
  7717. @main.route('/ferment_container_output/<tid>', methods=['GET', 'POST'])
  7718. def ferment_container_output(tid):
  7719. if request.method == 'GET':
  7720. if 'id' in session and 'uname' in session and 'status' in session:
  7721. username = session['uname']
  7722. status = session['status']
  7723. if status == 9:
  7724. return render_template('signin_disable.html')
  7725. elif status == 8:
  7726. return render_template('signin_new.html')
  7727. else:
  7728. return render_template('oops.html')
  7729. # 感測器_出料儲豆槽_超音波感測器
  7730. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  7731. # 致動器_出料儲豆槽_真空吸引機
  7732. output_vacuum = ferment_output_actuator.query.filter_by(tank_num='FO' + tid).order_by(text('datetime desc')).first()
  7733. output_vacuum = output_vacuum.vacuum
  7734. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  7735. LiDAR = tank_LiDAR.LiDAR
  7736. return render_template('ferment_container_output.html', title='[操作] FO' + tid + ' 發酵出料儲豆槽操作介面', **locals())
  7737. elif request.method == 'POST':
  7738. pass
  7739. @main.route('/dry_container_schedule', methods=['GET', 'POST'])
  7740. def dry_container_schedule():
  7741. if request.method == 'GET':
  7742. if 'id' in session and 'uname' in session:
  7743. username = session['uname']
  7744. # 感測器_入料儲豆槽_超音波感測器
  7745. input_UltraSonic = dry_input_sensor.query.order_by(text('datetime desc')).first()
  7746. # 感測器_乾燥桶_超音波感測器
  7747. tank_UltraSonic = dry_tank_UltraSonic.query.order_by(text('datetime desc')).first()
  7748. return render_template('dry_container_schedule.html', title='dry_container_schedule', **locals())
  7749. elif request.method == 'POST':
  7750. pass
  7751. @main.route('/dry_block', methods=['GET', 'POST'])
  7752. def dry_block():
  7753. if request.method == 'GET':
  7754. if 'id' in session and 'uname' in session:
  7755. username = session['uname']
  7756. DBW = dry_block_waiting.query.order_by(text('datetime desc')).first()
  7757. pin_data = coffee1_0_pin.query.order_by(text('datetime desc')).first()
  7758. return render_template('dry_block.html', title='積木設定_乾燥空桶等待', **locals())
  7759. elif request.method == 'POST':
  7760. pass
  7761. @main.route('/dry_block_empty', methods=['GET', 'POST'])
  7762. def dry_block_empty():
  7763. if request.method == 'GET':
  7764. if 'id' in session and 'uname' in session:
  7765. username = session['uname']
  7766. return render_template('dry_block_empty.html', title='積木設定空白_乾燥空桶等待', **locals())
  7767. elif request.method == 'POST':
  7768. pass
  7769. # 0323 積木程式 格式調整
  7770. @main.route('/dry_block_format', methods=['GET', 'POST'])
  7771. def dry_block_format():
  7772. if request.method == 'GET':
  7773. info = request.args.to_dict()
  7774. # print("info: ", info)
  7775. # 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'}
  7776. tank_num_data = info['tank_num'] # 桶槽編號:D1
  7777. mainLength_data = int(info['mainLength'])+1 # 總條件數量
  7778. addLength_data = int(info['addLength'])+1 # 子條件數量
  7779. comLength_data = int(info['comLength'])+1 # 子物件數量
  7780. cond_main_all_list = []
  7781. for z in range(1,mainLength_data):
  7782. # 初始
  7783. cond_main_all_dict = {}
  7784. cond_add_list = [] # 附加條件 List
  7785. cond_com_list = [] # 物件動作 List
  7786. # cond_main_dict_all = {}
  7787. # cond_add_dict_all = {}
  7788. # cond_com_dict_all = {}
  7789. # print(z)
  7790. # 總條件
  7791. try:
  7792. cond_main_all_dict['cond_main'] = info['cond_main' + str(z)]
  7793. except(KeyError):
  7794. pass
  7795. # print("cond_main_dict: ", cond_main_dict)
  7796. # 附加條件
  7797. for x in range(1,addLength_data):
  7798. try:
  7799. cond_add_list.append(info['cond_add' + str(z) + '_' + str(x)])
  7800. except(KeyError):
  7801. pass
  7802. # print("cond_add_list: ", cond_add_list)
  7803. cond_main_all_dict['cond_add'] = cond_add_list
  7804. # print("cond_main_dict: ", cond_main_dict)
  7805. # 物件動作
  7806. for y in range(1,comLength_data):
  7807. try:
  7808. cond_com_list.append(info['cond_com' + str(z) + '_' + str(y)])
  7809. except(KeyError):
  7810. pass
  7811. # print("cond_com_list: ", cond_com_list)
  7812. cond_main_all_dict['cond_com'] = cond_com_list
  7813. # print("cond_main_dict: ", cond_main_dict)
  7814. if cond_com_list != []:
  7815. cond_main_all_list.append(cond_main_all_dict)
  7816. # cond_main_all_list.append(cond_add_dict_all)
  7817. # cond_main_all_list.append(cond_com_dict_all)
  7818. print("cond_main_all_list: ", cond_main_all_list)
  7819. # 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']}]
  7820. dry_block_sehedule = {'command':'Dry_OTA', 'tank_num':tank_num_data, 'cond':cond_main_all_list}
  7821. print('dry_block_sehedule:', dry_block_sehedule)
  7822. # 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']}]}
  7823. topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  7824. print('=========================================================')
  7825. print("json.dumps(dry_block_sehedule):", json.dumps(dry_block_sehedule))
  7826. # 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"]}]}
  7827. print('=========================================================')
  7828. # mqtt.publish(topic, json.dumps(dry_block_sehedule))
  7829. return jsonify({"response":dry_block_sehedule})
  7830. # 積木程式
  7831. @main.route('/dry_block_set', methods=['GET', 'POST'])
  7832. def dry_block_set():
  7833. if request.method == 'GET':
  7834. if 'id' in session and 'uname' in session:
  7835. username = session['uname']
  7836. info = request.args.to_dict()
  7837. # print("info: ", info, type(info)) # dict
  7838. # 傳回 總條件物件動作 數量
  7839. condition = int(info['condition'])
  7840. # 傳回 子條件 數量
  7841. cond_add_child = int(info['cond_add_child'])
  7842. # 傳回 子物件動作 數量
  7843. act_add_child = int(info['act_add_child'])
  7844. # 傳回 指令
  7845. set_Schedule = eval(info['set_Schedule']) # 字串轉成字典
  7846. # print("set_Schedule: ", set_Schedule, type(set_Schedule)) # dict
  7847. cond_data = ''
  7848. # mqtt_data("D1", "block_command_test", "condition=" + str(condition)) # 0321 TEST
  7849. # ----- 0321 註解測試 -----
  7850. # # 拆解條件 / 物件 / 動作
  7851. # # # 條件物件取值
  7852. # for z in range(1, condition+1, 1):
  7853. # # 放要執行的判斷式
  7854. # # # if / while
  7855. # cond_data = ''
  7856. # try:
  7857. # z_num = 'cond_z' + str(z) + '_1'
  7858. # # print("cond_z_value[z_num]: ", set_Schedule[z_num]) # if
  7859. # cond_data += set_Schedule[z_num]
  7860. # except KeyError:
  7861. # pass
  7862. # # # 桶槽號取值
  7863. # try:
  7864. # tank_num = 'cond_tank' + str(z) + '_1'
  7865. # except KeyError:
  7866. # pass
  7867. # # # 子條件取值
  7868. # for x in range(1, cond_add_child+1, 1):
  7869. # # d
  7870. # try:
  7871. # x_num_d = 'cond_d' + str(z) + '_' + str(x)
  7872. # # print("cond_d_value[x_num_d]: ", set_Schedule[x_num_d])
  7873. # cond_data += ' ' + set_Schedule[x_num_d]
  7874. # except KeyError:
  7875. # pass
  7876. # # a
  7877. # x_num_a = 'cond_a' + str(z) + '_' + str(x)
  7878. # try:
  7879. # x_num_a = 'cond_a' + str(z) + '_' + str(x)
  7880. # # print("cond_a_value[x_num_a]: ", set_Schedule[x_num_a])
  7881. # cond_data += ' ' + set_Schedule[x_num_a]
  7882. # if set_Schedule[x_num_a] == 'input_vacuum_status':
  7883. # input_vacuum_status = dry_input_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  7884. # print("input_vacuum_status: ", input_vacuum_status)
  7885. # elif set_Schedule[x_num_a] == 'tank_vacuum_status':
  7886. # tank_vacuum_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  7887. # print("tank_vacuum_status: ", tank_vacuum_status)
  7888. # elif set_Schedule[x_num_a] == 'tank_threewayvalve_input_status':
  7889. # tank_threewayvalve_input_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().threewayvalve_input
  7890. # print("tank_threewayvalve_input_status: ", tank_threewayvalve_input_status)
  7891. # elif set_Schedule[x_num_a] == 'tank_motor_status':
  7892. # tank_motor_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().motor
  7893. # print("tank_motor_status: ", tank_motor_status)
  7894. # elif set_Schedule[x_num_a] == 'tank_blower_status':
  7895. # tank_blower_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().blower
  7896. # print("tank_blower_status: ", tank_blower_status)
  7897. # elif set_Schedule[x_num_a] == 'tank_heater1_status':
  7898. # tank_heater1_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater1
  7899. # print("tank_heater1_status: ", tank_heater1_status)
  7900. # elif set_Schedule[x_num_a] == 'tank_heater2_status':
  7901. # tank_heater2_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().heater2
  7902. # print("tank_heater2_status: ", tank_heater2_status)
  7903. # elif set_Schedule[x_num_a] == 'tank_diskvalve_status':
  7904. # tank_diskvalve_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().diskvalve
  7905. # print("tank_diskvalve_status: ", tank_diskvalve_status)
  7906. # elif set_Schedule[x_num_a] == 'tank_solenoid_disinfect_status':
  7907. # tank_solenoid_disinfect_status = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().solenoid_disinfect
  7908. # print("tank_solenoid_disinfect_status: ", tank_solenoid_disinfect_status)
  7909. # elif set_Schedule[x_num_a] == 'tank_solenoid_water_out_status':
  7910. # 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
  7911. # print("tank_solenoid_water_out_status: ", tank_solenoid_water_out_status)
  7912. # elif set_Schedule[x_num_a] == 'outer_solenoid_water_status':
  7913. # 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
  7914. # print("outer_solenoid_water_status: ", outer_solenoid_water_status)
  7915. # elif set_Schedule[x_num_a] == 'tank_temp_enable':
  7916. # tank_temp_enable = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1_enable
  7917. # print("tank_temp_enable: ", tank_temp_enable)
  7918. # elif set_Schedule[x_num_a] == 'tank_temp':
  7919. # tank_temp = dry_tank_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().temp1
  7920. # print("tank_temp: ", tank_temp)
  7921. # elif set_Schedule[x_num_a] == 'output_vacuum':
  7922. # output_vacuum = dry_output_brake.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().vacuum
  7923. # print("output_vacuum: ", output_vacuum)
  7924. # elif set_Schedule[x_num_a] == 'input_UltraSonic':
  7925. # input_UltraSonic = float(dry_input_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  7926. # print("input_UltraSonic: ", input_UltraSonic)
  7927. # elif set_Schedule[x_num_a] == 'tank_UltraSonic':
  7928. # tank_UltraSonic = float(dry_tank_UltraSonic.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  7929. # print("tank_UltraSonic: ", tank_UltraSonic)
  7930. # elif set_Schedule[x_num_a] == 'tank_SHT11_Temp':
  7931. # tank_SHT11_Temp = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Temp)
  7932. # print("tank_SHT11_Temp: ", tank_SHT11_Temp)
  7933. # elif set_Schedule[x_num_a] == 'tank_SHT11_Humidity':
  7934. # tank_SHT11_Humidity = float(dry_tank_SHT11.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().SHT11_Humidity)
  7935. # print("tank_SHT11_Humidity: ", tank_SHT11_Humidity)
  7936. # elif set_Schedule[x_num_a] == 'tank_soil_Temp':
  7937. # tank_soil_Temp = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Temp)
  7938. # print("tank_soil_Temp: ", tank_soil_Temp)
  7939. # elif set_Schedule[x_num_a] == 'tank_soil_Humidity':
  7940. # tank_soil_Humidity = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_Humidity)
  7941. # print("tank_soil_Humidity: ", tank_soil_Temp)
  7942. # elif set_Schedule[x_num_a] == 'tank_soil_EC':
  7943. # tank_soil_EC = float(dry_tank_Soil.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().soil_EC)
  7944. # print("tank_soil_EC: ", tank_soil_EC)
  7945. # elif set_Schedule[x_num_a] == 'tank_PA':
  7946. # tank_PA = float(dry_tank_PA.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().PA)
  7947. # print("tank_PA: ", tank_PA)
  7948. # elif set_Schedule[x_num_a] == 'output_UltraSonic':
  7949. # output_UltraSonic = float(dry_output_sensor.query.filter_by(tank_num=set_Schedule[tank_num]).order_by(text('datetime desc')).first().UltraSonic)
  7950. # print("output_UltraSonic: ", output_UltraSonic)
  7951. # except KeyError:
  7952. # pass
  7953. # # b
  7954. # try:
  7955. # x_num_b = 'cond_b' + str(z) + '_' + str(x)
  7956. # # print("cond_b_value[x_num_b]: ", set_Schedule[x_num_b])
  7957. # cond_b_dict = {'morethan': ' >= ', 'lessthan': ' <= ', 'equal':' == '}
  7958. # cond_data += cond_b_dict[set_Schedule[x_num_b]] # cond_b_dict['equal'] 會輸出 ' == '
  7959. # except KeyError:
  7960. # pass
  7961. # # c
  7962. # try:
  7963. # x_num_c = 'cond_c' + str(z) + '_' + str(x)
  7964. # # print("cond_c_value[x_num_c]: ", set_Schedule[x_num_c])
  7965. # if set_Schedule[x_num_c] == 'on':
  7966. # cond_data += '1'
  7967. # elif set_Schedule[x_num_c] == 'off':
  7968. # cond_data += '0'
  7969. # else:
  7970. # cond_data += set_Schedule[x_num_c]
  7971. # except KeyError:
  7972. # pass
  7973. # if x == cond_add_child:
  7974. # cond_data += ': '
  7975. # # 子物件動作取值
  7976. # for y in range(1, act_add_child+1, 1):
  7977. # # do_obj
  7978. # try:
  7979. # y_num_obj = "do_obj" + str(z) + "_" + str(y)
  7980. # # print("y_num_obj[y_num_obj]: ", set_Schedule[y_num_obj])
  7981. # # cond_data += 'print(\'' + 'mqtt_data("D1", "' + str(set_Schedule[y_num_obj]) + '", '
  7982. # if set_Schedule[y_num_obj] == 'time.sleep':
  7983. # cond_data += '''
  7984. # time.sleep('''
  7985. # else:
  7986. # cond_data += '''
  7987. # mqtt_data('''
  7988. # cond_data += '"' + set_Schedule[tank_num] + '", "' + str(set_Schedule[y_num_obj]) + '", '
  7989. # except KeyError:
  7990. # pass
  7991. # try:
  7992. # y_num_act = "do_act" + str(z) + "_" + str(y)
  7993. # # print("y_num_act[y_num_act]: ", set_Schedule[y_num_act])
  7994. # if set_Schedule[y_num_obj] == 'time.sleep':
  7995. # cond_data += set_Schedule[y_num_act] + ')'
  7996. # else:
  7997. # cond_data += '"' + str(set_Schedule[y_num_act]) + '") '
  7998. # cond_data += '''
  7999. # time.sleep(0.5)'''
  8000. # except KeyError:
  8001. # pass
  8002. # # TODO
  8003. # # set_Schedule[z_num] → if / while
  8004. # # set_Schedule[x_num_a] → actuator / sensor
  8005. # # set_Schedule[x_num_b] → morethan / equal / lessthan
  8006. # # set_Schedule[x_num_c] → 數值 / on / off
  8007. # # set_Schedule[x_num_d] → or / and
  8008. # # set_Schedule[y_num_obj] → actuator
  8009. # # set_Schedule[y_num_act] → on / off / 對應數值
  8010. # print("cond_data: ", cond_data)
  8011. # if cond_data != ': ':
  8012. # # exec(cond_data)
  8013. # # 01/17 新增, 格式待修改
  8014. # mqtt_data("D1", "command_test", "exec(" + cond_data + ")")
  8015. return jsonify({"response":"OK"
  8016. })
  8017. elif request.method == 'POST':
  8018. pass
  8019. # 乾燥貨櫃_各致動器控制
  8020. @main.route('/ctrl_DI_<actuator>/<tid>', methods=['GET', 'POST'])
  8021. def ctrl_DI(actuator, tid):
  8022. if request.method == 'GET':
  8023. if actuator == 'Vacuum':
  8024. if 'id' in session and 'uname' in session and 'status' in session:
  8025. username = session['uname']
  8026. status = session['status']
  8027. if status == 9:
  8028. return render_template('signin_disable.html')
  8029. elif status == 8:
  8030. return render_template('signin_new.html')
  8031. else:
  8032. return render_template('oops.html')
  8033. input_brake = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  8034. input_vacuum = input_brake.vacuum
  8035. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  8036. UltraSonic = tank_UltraSonic.UltraSonic
  8037. return render_template('ctrl_DI_Vacuum.html', title='[操作]DI' + tid + '乾燥槽入料_真空吸料機', **locals())
  8038. elif request.method == 'POST':
  8039. pass
  8040. @main.route('/ctrl_DO_<actuator>/<tid>', methods=['GET', 'POST'])
  8041. def ctrl_DO(actuator, tid):
  8042. if request.method == 'GET':
  8043. if 'id' in session and 'uname' in session and 'status' in session:
  8044. username = session['uname']
  8045. status = session['status']
  8046. if status == 9:
  8047. return render_template('signin_disable.html')
  8048. elif status == 8:
  8049. return render_template('signin_new.html')
  8050. else:
  8051. return render_template('oops.html')
  8052. if actuator == 'Vacuum':
  8053. tank_brake = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  8054. tank_vacuum = tank_brake.vacuum
  8055. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  8056. UltraSonic = tank_UltraSonic.UltraSonic
  8057. return render_template('ctrl_DO_Vacuum.html', title='[操作]DI' + tid + '乾燥槽出料_真空吸料機', **locals())
  8058. elif request.method == 'POST':
  8059. pass
  8060. @main.route('/ctrl_D_<actuator>/<tid>', methods=['GET', 'POST'])
  8061. def ctrl_D(actuator, tid):
  8062. if request.method == 'GET':
  8063. if 'id' in session and 'uname' in session and 'status' in session:
  8064. username = session['uname']
  8065. status = session['status']
  8066. if status == 9:
  8067. return render_template('signin_disable.html')
  8068. elif status == 8:
  8069. return render_template('signin_new.html')
  8070. else:
  8071. return render_template('oops.html')
  8072. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8073. if actuator == 'Vacuum':
  8074. tank_vacuum = tank_brake.vacuum
  8075. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8076. UltraSonic = tank_UltraSonic.UltraSonic
  8077. return render_template('ctrl_D_Vacuum.html', title='[操作]D' + tid + '乾燥槽_真空吸料機', **locals())
  8078. elif actuator == 'ThreeWayValveInput':
  8079. tank_threewayvalve_input = tank_brake.threewayvalve_input
  8080. return render_template('ctrl_D_ThreeWayValveInput.html', title='[操作]D' + tid + '乾燥槽_入料三通閥', **locals())
  8081. elif actuator == 'ThreeWayValveBean':
  8082. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  8083. return render_template('ctrl_D_ThreeWayValveBean.html', title='[操作]D' + tid + '乾燥槽_測豆三通閥', **locals())
  8084. elif actuator == 'DiskValve':
  8085. tank_diskvalve = tank_brake.diskvalve
  8086. return render_template('ctrl_D_DiskValve.html', title='[操作]D' + tid + '乾燥槽_蝴蝶閥', **locals())
  8087. elif actuator == 'SolenoidDisinfect':
  8088. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  8089. return render_template('ctrl_D_SolenoidDisinfect.html', title='[操作]D' + tid + '乾燥槽_消毒電磁閥', **locals())
  8090. elif actuator == 'SolenoidWater':
  8091. tank_solenoid_water = tank_brake.solenoid_water
  8092. return render_template('ctrl_D_SolenoidWater.html', title='[操作]D' + tid + '乾燥槽_排水電磁閥', **locals())
  8093. elif actuator == 'Motor':
  8094. tank_motor = tank_brake.motor
  8095. return render_template('ctrl_D_Motor.html', title='[操作]D' + tid + '乾燥槽_馬達', **locals())
  8096. elif actuator == 'Blower':
  8097. tank_blower = tank_brake.blower
  8098. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8099. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8100. return render_template('ctrl_D_Blower.html', title='[操作]D' + tid + '乾燥槽_鼓風機', **locals())
  8101. elif actuator == 'Heater1':
  8102. tank_heater1 = tank_brake.heater1
  8103. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8104. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8105. return render_template('ctrl_D_Heater1.html', title='[操作]D' + tid + '乾燥槽_加熱器 1', **locals())
  8106. elif actuator == 'Heater2':
  8107. tank_heater2 = tank_brake.heater2
  8108. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8109. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8110. return render_template('ctrl_D_Heater2.html', title='[操作]D' + tid + '乾燥槽_加熱器 2', **locals())
  8111. elif actuator == 'TempEnable':
  8112. tank_temp1_enable = tank_brake.temp1_enable
  8113. return render_template('ctrl_D_TempEnable.html', title='[操作]D' + tid + '乾燥槽_溫控開關', **locals())
  8114. elif actuator == 'Temp':
  8115. tank_temp1_enable = tank_brake.temp1_enable
  8116. tank_temp1 = tank_brake.temp1
  8117. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8118. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8119. return render_template('ctrl_D_Temp.html', title='[操作]D' + tid + '乾燥槽_設定溫度', **locals())
  8120. elif request.method == 'POST':
  8121. pass
  8122. # 發酵貨櫃_各致動器控制
  8123. @main.route('/ctrl_FI_<actuator>/<tid>', methods=['GET', 'POST'])
  8124. def ctrl_FI(actuator, tid):
  8125. if request.method == 'GET':
  8126. if 'id' in session and 'uname' in session and 'status' in session:
  8127. username = session['uname']
  8128. status = session['status']
  8129. if status == 9:
  8130. return render_template('signin_disable.html')
  8131. elif status == 8:
  8132. return render_template('signin_new.html')
  8133. else:
  8134. return render_template('oops.html')
  8135. if actuator == 'Vacuum':
  8136. if 'id' in session and 'uname' in session and 'status' in session:
  8137. username = session['uname']
  8138. status = session['status']
  8139. if status == 9:
  8140. return render_template('signin_disable.html')
  8141. elif status == 8:
  8142. return render_template('signin_new.html')
  8143. else:
  8144. return render_template('oops.html')
  8145. tank_actuator = ferment_input_actuator.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  8146. tank_vacuum = tank_actuator.vacuum
  8147. tank_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num='FI'+str(tid)).order_by(text('datetime desc')).first()
  8148. UltraSonic = tank_UltraSonic.UltraSonic
  8149. return render_template('ctrl_FI_Vacuum.html', title='[操作]FI' + tid + '發酵入料儲豆槽_真空吸料機', **locals())
  8150. elif request.method == 'POST':
  8151. pass
  8152. @main.route('/ctrl_FO_<actuator>/<tid>', methods=['GET', 'POST'])
  8153. def ctrl_FO(actuator, tid):
  8154. if request.method == 'GET':
  8155. if 'id' in session and 'uname' in session and 'status' in session:
  8156. username = session['uname']
  8157. status = session['status']
  8158. if status == 9:
  8159. return render_template('signin_disable.html')
  8160. elif status == 8:
  8161. return render_template('signin_new.html')
  8162. else:
  8163. return render_template('oops.html')
  8164. if actuator == 'Vacuum':
  8165. tank_actuator = ferment_output_actuator.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  8166. tank_vacuum = tank_actuator.vacuum
  8167. tank_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num='FO'+str(tid)).order_by(text('datetime desc')).first()
  8168. UltraSonic = tank_UltraSonic.UltraSonic
  8169. return render_template('ctrl_FO_Vacuum.html', title='[操作]FO' + tid + '發酵出料儲豆槽_真空吸料機', **locals())
  8170. elif request.method == 'POST':
  8171. pass
  8172. @main.route('/ctrl_F_<actuator>/<tid>', methods=['GET', 'POST'])
  8173. def ctrl_F(actuator, tid):
  8174. if request.method == 'GET':
  8175. if 'id' in session and 'uname' in session and 'status' in session:
  8176. username = session['uname']
  8177. status = session['status']
  8178. if status == 9:
  8179. return render_template('signin_disable.html')
  8180. elif status == 8:
  8181. return render_template('signin_new.html')
  8182. else:
  8183. return render_template('oops.html')
  8184. tank_actuator = ferment_tank_actuator.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  8185. if actuator == 'Vacuum':
  8186. tank_vacuum = tank_actuator.vacuum
  8187. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num='F'+str(tid)).order_by(text('datetime desc')).first()
  8188. LiDAR = tank_LiDAR.LiDAR
  8189. return render_template('ctrl_F_Vacuum.html', title='[操作]F' + tid + '發酵槽_真空吸料機', **locals())
  8190. elif actuator == 'ThreeWayValveInput':
  8191. tank_threewayvalveinput = tank_actuator.threewayvalve_input
  8192. return render_template('ctrl_F_ThreeWayValveInput.html', title='[操作]F' + tid + '發酵槽_入料三通閥', **locals())
  8193. elif actuator == 'SolenoidWaterTotal':
  8194. tank_solenoid_tank_water_total = tank_actuator.solenoid_tank_water_total
  8195. return render_template('ctrl_F_SolenoidWaterTotal.html', title='[操作]F' + tid + '發酵槽_總進水電磁閥', **locals())
  8196. elif actuator == 'SolenoidOuterWater':
  8197. tank_solenoid_outer_water = tank_actuator.solenoid_outer_water
  8198. tank_WaterLevel = ferment_tank_WaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8199. WaterLevel = tank_WaterLevel.WaterLevel
  8200. return render_template('ctrl_F_SolenoidOuterWater.html', title='[操作]F' + tid + '發酵槽_保溫夾層進水電磁閥', **locals())
  8201. elif actuator == 'SolenoidWaterIn':
  8202. tank_solenoid_tank_water_in = tank_actuator.solenoid_tank_water_in
  8203. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8204. PressureWaterLevel = tank_PressureWaterLevel.PressureWaterLevel
  8205. return render_template('ctrl_F_SolenoidWaterIn.html', title='[操作]F' + tid + '發酵槽_桶內進水電磁閥', **locals())
  8206. elif actuator == 'PumpSensor':
  8207. tank_pump_sensor = tank_actuator.pump_sensor
  8208. tank_PH = ferment_tank_PH.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8209. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8210. tank_DO = ferment_tank_DO.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8211. tank_EC = ferment_tank_EC.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8212. PH = tank_PH.PH
  8213. ORP = tank_ORP.ORP
  8214. DO = tank_DO.DO
  8215. EC = tank_EC.EC
  8216. return render_template('ctrl_F_PumpSensor.html', title='[操作]F' + tid + '發酵槽_感測器抽水雙核隔膜泵', **locals())
  8217. elif actuator == 'ThreeWayValveBean':
  8218. tank_threewayvalve_bean = tank_actuator.threewayvalve_bean
  8219. return render_template('ctrl_F_ThreeWayValveBean.html', title='[操作]F' + tid + '發酵槽_感測模組下豆三通閥', **locals())
  8220. elif actuator == 'ThreeWayValveFloat':
  8221. tank_threewayvalve_outer_float = tank_actuator.threewayvalve_outer_float
  8222. return render_template('ctrl_F_ThreeWayValveFloat.html', title='[操作]F' + tid + '發酵槽_外桶浮選三通閥', **locals())
  8223. elif actuator == 'SolenoidDisinfect':
  8224. tank_solenoid_tank_disinfect = tank_actuator.solenoid_tank_disinfect
  8225. return render_template('ctrl_F_SolenoidDisinfect.html', title='[操作]F' + tid + '發酵槽_桶內消毒電磁閥', **locals())
  8226. elif actuator == 'Motor':
  8227. tank_motor = tank_actuator.motor
  8228. return render_template('ctrl_F_Motor.html', title='[操作]F' + tid + '發酵槽_馬達', **locals())
  8229. elif actuator == 'Heater1':
  8230. tank_heater1 = tank_actuator.heater1
  8231. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8232. return render_template('ctrl_F_Heater1.html', title='[操作]F' + tid + '發酵槽_加熱器 1', **locals())
  8233. elif actuator == 'Heater2':
  8234. tank_heater2 = tank_actuator.heater2
  8235. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8236. return render_template('ctrl_F_Heater2.html', title='[操作]F' + tid + '發酵槽_加熱器 2', **locals())
  8237. elif actuator == 'TempEnable':
  8238. tank_temp_enable = tank_actuator.temp_enable
  8239. return render_template('ctrl_F_TempEnable.html', title='[操作]F' + tid + '發酵槽_溫控開關', **locals())
  8240. elif actuator == 'Temp':
  8241. tank_temp = tank_actuator.temp
  8242. tank_temp_enable = tank_actuator.temp_enable
  8243. tank_SHT11 = ferment_tank_SHT11.query.filter_by(tank_num='F' + tid).order_by(text('datetime desc')).first()
  8244. return render_template('ctrl_F_Temp.html', title='[操作]F' + tid + '發酵槽_溫度設定', **locals())
  8245. elif actuator == 'DiskValve':
  8246. tank_diskvalve = tank_actuator.diskvalve
  8247. return render_template('ctrl_F_DiskValve.html', title='[操作]F' + tid + '發酵槽_蝴蝶閥', **locals())
  8248. @main.route('/dry_Temp/<tid>/<Temp_Weights_SHT11>/<Temp_Weights_Soil>/<temp_data>', methods=['GET', 'POST'])
  8249. def dry_Temp(tid, Temp_Weights_SHT11, Temp_Weights_Soil, temp_data):
  8250. if request.method == 'GET':
  8251. if 'id' in session and 'uname' in session and 'status' in session:
  8252. username = session['uname']
  8253. status = session['status']
  8254. if status == 9:
  8255. return render_template('signin_disable.html')
  8256. elif status == 8:
  8257. return render_template('signin_new.html')
  8258. else:
  8259. return render_template('oops.html')
  8260. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8261. SHT11_Temp = float(tank_SHT11.SHT11_Temp)
  8262. SHT11_Humidity = tank_SHT11.SHT11_Humidity
  8263. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8264. Soil_Temp = float(tank_Soil.soil_Temp)
  8265. Soil_Humidity = tank_Soil.soil_Humidity
  8266. Temp_Weights_SHT11= float(Temp_Weights_SHT11)
  8267. Temp_Weights_Soil = float(Temp_Weights_Soil)
  8268. temp_data = float(temp_data)
  8269. present_temp = math.ceil( (SHT11_Temp*Temp_Weights_SHT11 + Soil_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil) )
  8270. # Math.round((present_SHT11_Temp*Temp_Weights_SHT11 + present_SOIL_Temp*Temp_Weights_Soil)/(Temp_Weights_SHT11+Temp_Weights_Soil)*100) / 100
  8271. target_temp = math.ceil(temp_data)
  8272. TempUp = {
  8273. 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
  8274. }
  8275. if target_temp in TempUp and present_temp in TempUp:
  8276. TempUpTime = ', 預計 ' + str(TempUp[target_temp] - TempUp[present_temp]) + ' 秒達到指定溫度'
  8277. elif target_temp < 22 or present_temp < 22 :
  8278. TempUpTime = '℃, 指定溫度過低, 持續升溫中'
  8279. elif target_temp > 44 or present_temp > 44 :
  8280. TempUpTime = '℃, 指定溫度過高, 持續升溫中'
  8281. return jsonify({"SHT11_Temp":SHT11_Temp,
  8282. "SHT11_Humidity":SHT11_Humidity,
  8283. "Soil_Temp":Soil_Temp,
  8284. "Soil_Humidity":Soil_Humidity,
  8285. "present_temp":present_temp,
  8286. "TempUpTime":TempUpTime
  8287. })
  8288. else:
  8289. pass
  8290. @main.route('/dry_container_tank/<tid>', methods=['GET', 'POST'])
  8291. def dry_container_tank(tid):
  8292. if request.method == 'GET':
  8293. if 'id' in session and 'uname' in session and 'status' in session:
  8294. username = session['uname']
  8295. status = session['status']
  8296. if status == 9:
  8297. return render_template('signin_disable.html')
  8298. elif status == 8:
  8299. return render_template('signin_new.html')
  8300. else:
  8301. return render_template('oops.html')
  8302. tonow = dt.now()
  8303. print("tonow: ", tonow)
  8304. time_del = timedelta(minutes=-60)
  8305. bias_date_time = tonow + time_del
  8306. # print(dt.now() >= dt(2021,11,29,17,35,36))
  8307. # bias_min = tonow.minute + 3
  8308. # 感測器_乾燥桶_SHT11
  8309. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid))\
  8310. .filter(dry_tank_SHT11.datetime >= bias_date_time)\
  8311. .order_by(text('datetime desc')).first()
  8312. # 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'>
  8313. if not hasattr(object, 'tank_SHT11'):
  8314. tank_SHT11 = {"SHT11_Temp":" — ", "SHT11_Humidity":" — "}
  8315. print(tank_SHT11["SHT11_Temp"])
  8316. # 感測器_乾燥桶_土壤三合一
  8317. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8318. if not hasattr(object, 'tank_Soil'):
  8319. tank_Soil = {"soil_Temp":" — ", "soil_Humidity":" — ", "soil_EC":" — "}
  8320. # 感測器_乾燥桶_氣壓
  8321. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8322. if not hasattr(object, 'tank_PA'):
  8323. tank_PA = {"PA":" — "}
  8324. # 感測器_乾燥桶_超音波感測器
  8325. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8326. if not hasattr(object, 'tank_UltraSonic'):
  8327. tank_UltraSonic = {"UltraSonic":" — "}
  8328. # 致動器_乾燥桶_ALL
  8329. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8330. tank_vacuum = tank_brake.vacuum
  8331. tank_threewayvalve_input = tank_brake.threewayvalve_input
  8332. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  8333. tank_diskvalve = tank_brake.diskvalve
  8334. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  8335. tank_solenoid_water = tank_brake.solenoid_water
  8336. tank_solenoid_outer_water = tank_brake.solenoid_outer_water
  8337. tank_motor = tank_brake.motor
  8338. tank_blower = tank_brake.blower
  8339. tank_heater1 = tank_brake.heater1
  8340. tank_heater2 = tank_brake.heater2
  8341. tank_temp1_enable = tank_brake.temp1_enable
  8342. tank_temp1 = tank_brake.temp1
  8343. # Temp_weight = num_SHT11_temp * 0.5 + num_Soil_temp * 0.5
  8344. return render_template('dry_container_tank.html', title='[操作] D' + tid + ' 乾燥槽操作介面', **locals())
  8345. elif request.method == 'POST':
  8346. pass
  8347. @main.route('/dry_container_input/<tid>', methods=['GET', 'POST'])
  8348. def dry_container_input(tid):
  8349. if request.method == 'GET':
  8350. if 'id' in session and 'uname' in session and 'status' in session:
  8351. username = session['uname']
  8352. status = session['status']
  8353. if status == 9:
  8354. return render_template('signin_disable.html')
  8355. elif status == 8:
  8356. return render_template('signin_new.html')
  8357. else:
  8358. return render_template('oops.html')
  8359. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  8360. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI'+str(tid)).order_by(text('datetime desc')).first()
  8361. input_vacuum = input_vacuum.vacuum
  8362. return render_template('dry_container_input.html', title='[操作] DI' + tid + ' 乾燥入料儲豆槽操作介面', **locals())
  8363. elif request.method == 'POST':
  8364. pass
  8365. @main.route('/dry_container_output/<tid>', methods=['GET', 'POST'])
  8366. def dry_container_output(tid):
  8367. if request.method == 'GET':
  8368. if 'id' in session and 'uname' in session and 'status' in session:
  8369. username = session['uname']
  8370. status = session['status']
  8371. if status == 9:
  8372. return render_template('signin_disable.html')
  8373. elif status == 8:
  8374. return render_template('signin_new.html')
  8375. else:
  8376. return render_template('oops.html')
  8377. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  8378. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO'+str(tid)).order_by(text('datetime desc')).first()
  8379. output_vacuum = output_vacuum.vacuum
  8380. return render_template('dry_container_output.html', title='[操作] DO' + tid + ' 乾燥出料儲豆槽操作介面', **locals())
  8381. elif request.method == 'POST':
  8382. pass
  8383. # 原本的乾燥貨櫃控制, 備份用
  8384. @main.route('/dry_container/<tid>', methods=['GET', 'POST'])
  8385. def dry_container(tid):
  8386. if request.method == 'GET':
  8387. if 'id' in session and 'uname' in session and 'status' in session:
  8388. username = session['uname']
  8389. status = session['status']
  8390. if status == 9:
  8391. return render_template('signin_disable.html')
  8392. elif status == 8:
  8393. return render_template('signin_new.html')
  8394. else:
  8395. return render_template('oops.html')
  8396. # Rita 參數 params 是用來取得參數的 locals=() 所有參數
  8397. '''
  8398. # 開啟本機 coffeetest 資料庫
  8399. # mydb = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='g53743001', database='coffeetest', charset='utf8')
  8400. mydb = pymysql.connect(host='52.69.200.169', port=3306, user='coffee',
  8401. password='skyeye', database='Coffee', charset='utf8')
  8402. mycursor = mydb.cursor()
  8403. '''
  8404. # 感測器_乾燥桶_SHT11
  8405. tank_SHT11 = dry_tank_SHT11.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8406. num_SHT11_temp = float(tank_SHT11.SHT11_Temp)
  8407. # 感測器_乾燥桶_土壤三合一
  8408. tank_Soil = dry_tank_Soil.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8409. num_Soil_temp = float(tank_Soil.soil_Temp)
  8410. # 感測器_乾燥桶_氣壓
  8411. tank_PA = dry_tank_PA.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8412. # 感測器_乾燥桶_超音波感測器
  8413. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8414. # 感測器_出料儲豆槽_超音波感測器
  8415. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8416. # 致動器_乾燥桶_ALL
  8417. tank_brake = dry_tank_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8418. tank_vacuum = tank_brake.vacuum
  8419. tank_threewayvalve_input = tank_brake.threewayvalve_input
  8420. tank_threewayvalve_bean = tank_brake.threewayvalve_bean
  8421. tank_diskvalve = tank_brake.diskvalve
  8422. tank_solenoid_disinfect = tank_brake.solenoid_disinfect
  8423. tank_solenoid_water = tank_brake.solenoid_water
  8424. tank_motor = tank_brake.motor
  8425. tank_blower = tank_brake.blower
  8426. tank_heater1 = tank_brake.heater1
  8427. tank_heater2 = tank_brake.heater2
  8428. tank_temp1_enable = tank_brake.temp1_enable
  8429. tank_temp1 = tank_brake.temp1
  8430. '''
  8431. tank_vacuum = 'ON' if tank_brake.vacuum == 1 else 'OFF'
  8432. tank_threewayvalve = 'ON' if tank_brake.threewayvalve == 1 else 'OFF'
  8433. tank_diskvalve = 'ON' if tank_brake.diskvalve == 1 else 'OFF'
  8434. tank_solenoid_disinfect = 'ON' if tank_brake.solenoid_disinfect == 1 else 'OFF'
  8435. tank_solenoid_water = 'ON' if tank_brake.solenoid_water == 1 else 'OFF'
  8436. tank_motor = tank_brake.motor
  8437. tank_blower = 'ON' if tank_brake.blower == 1 else 'OFF'
  8438. tank_heater1 = 'ON' if tank_brake.heater1 == 1 else 'OFF'
  8439. tank_heater2 = 'ON' if tank_brake.heater2 == 1 else 'OFF'
  8440. tank_temp1_enable = 'ON' if tank_brake.temp1_enable == 1 else 'OFF'
  8441. tank_temp1 = tank_brake.temp1
  8442. '''
  8443. '''
  8444. data = mycursor.execute(
  8445. 'SELECT * FROM dry_tank_brake ORDER BY datetime DESC;')
  8446. data = mycursor.fetchone()
  8447. '''
  8448. if tid in ['1', '2', '3', '4', '5', '6']:
  8449. # print("1")
  8450. # 感測器_入料儲豆槽_超音波感測器
  8451. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  8452. # 致動器_入料儲豆槽_真空吸引機
  8453. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI1').order_by(text('datetime desc')).first()
  8454. input_vacuum = input_vacuum.vacuum
  8455. # 感測器_出料儲豆槽_超音波感測器
  8456. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  8457. # 致動器_出料儲豆槽_真空吸引機
  8458. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO1').order_by(text('datetime desc')).first()
  8459. output_vacuum = output_vacuum.vacuum
  8460. elif tid in ['7', '8', '9', '10', '11', '12']:
  8461. print("2")
  8462. # 感測器_入料儲豆槽_超音波感測器
  8463. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  8464. # 致動器_入料儲豆槽_真空吸引機
  8465. input_vacuum = dry_input_brake.query.filter_by(tank_num='DI2').order_by(text('datetime desc')).first()
  8466. input_vacuum = input_vacuum.vacuum
  8467. # 感測器_出料儲豆槽_超音波感測器
  8468. output_UltraSonic = dry_output_sensor.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  8469. # 致動器_出料儲豆槽_真空吸引機
  8470. output_vacuum = dry_output_brake.query.filter_by(tank_num='DO2').order_by(text('datetime desc')).first()
  8471. output_vacuum = output_vacuum.vacuum
  8472. '''
  8473. # 感測器_入料儲豆槽_超音波感測器
  8474. input_UltraSonic = dry_input_sensor.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8475. # 致動器_入料儲豆槽_真空吸引機
  8476. input_vacuum = dry_input_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8477. # print("input_vacuum:", input_vacuum)
  8478. input_vacuum = input_vacuum.vacuum
  8479. #print('input_vacuum:', input_vacuum.vacuum)
  8480. # 致動器_出料儲豆槽_真空吸引機
  8481. output_vacuum = dry_output_brake.query.filter_by(tank_num='D'+str(tid)).order_by(text('datetime desc')).first()
  8482. #print('output_vacuum.vacuum: ', output_vacuum.vacuum)
  8483. output_vacuum = 'ON' if (output_vacuum.vacuum == 1) else 'OFF'
  8484. #print('output_vacuum: ', output_vacuum)
  8485. '''
  8486. # 傳 MQTT 給阿超, 阿超讓硬體動作, 將資料儲存到資料庫
  8487. input_data = set_dry_input.query.order_by(text('datetime desc')).first()
  8488. schedule_input_height = input_data.input_height
  8489. schedule_input_entertime = input_data.input_entertime
  8490. schedule_input_exittime = input_data.input_exittime
  8491. schedule_tank_height = input_data.tank_height
  8492. return render_template('dry_container.html', title='dry_container', **locals())
  8493. elif request.method == 'POST':
  8494. # 表單輸入處
  8495. print('/dry_input_setting POST')
  8496. set = set_dry_input()
  8497. set.input_height = request.form['schedule_input_height']
  8498. set.input_entertime = request.form['schedule_input_entertime']
  8499. set.input_exittime = request.form['schedule_input_exittime']
  8500. set.tank_height = request.form['schedule_tank_height']
  8501. #將數據保存進資料庫 - 註冊
  8502. db.session.add(set)
  8503. # 手動提交,目的是為了獲取提交後的user的id
  8504. db.session.commit()
  8505. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  8506. # 完成登入的操作
  8507. # setting = Set_dry_input.query.order_by(text('datetime desc')).first()
  8508. #session['id'] = set.userID
  8509. #session['uname'] = set.username
  8510. return redirect('/dry_container')
  8511. # 登入頁面的訪問路徑
  8512. @main.route('/login', methods=['GET', 'POST'])
  8513. def login_views():
  8514. if request.method == 'GET':
  8515. if 'id' in session and 'uname' in session and 'status' in session:
  8516. return redirect('/')
  8517. else:
  8518. return render_template('sign_in.html')
  8519. else:
  8520. # 接收前端傳過來的資料
  8521. username = request.form['username']
  8522. password = request.form['password']
  8523. # 使用接收的用戶和密碼到資料庫中查詢
  8524. user = User.query.filter_by(
  8525. username=username, password=password).first()
  8526. # 如果用戶存在,將信息保存置session並重定向回首頁,否則重定向回登入頁
  8527. if user:
  8528. resp = redirect('/')
  8529. # 判斷是否有記住密碼
  8530. if 'rem' in request.form:
  8531. userID = str(user.userID)
  8532. max_age = 60*60*24*365
  8533. status = str(user.status)
  8534. print('status: ', status)
  8535. # Rita 以秒為單位, 一年
  8536. # Rita 功能和 expires 很像,但此參數並非所有瀏覽器均支持,所以建議使用 expires 參數。
  8537. # Rita expires:指定 Cookie 的有效日期, 當過了有效日期後就不會儲存在瀏覽器
  8538. resp.set_cookie("username", username, max_age=max_age)
  8539. resp.set_cookie("userID", userID, max_age=max_age)
  8540. resp.set_cookie("status", status, max_age=max_age)
  8541. session['uname'] = user.username
  8542. session['id'] = user.userID
  8543. session['status'] = user.status
  8544. return resp
  8545. else:
  8546. errMsg = "Wrong login or password"
  8547. return render_template('sign_in.html', errMsg=errMsg)
  8548. # 登入重設密碼的頁面
  8549. # Rita reset_pwd1 - Email
  8550. # Rita reset_pwd2 - New password / Confirm password
  8551. @main.route('/reset_password', methods=['POST', 'GET'])
  8552. def reset_password_views():
  8553. if request.method == 'GET':
  8554. if 'mail' in session:
  8555. del session['mail']
  8556. return render_template('reset_pwd1.html')
  8557. else:
  8558. # POST
  8559. # 如果有id在session裡,代表從reset_pwd2過來的 ? 對, reset_pwd2 POST (但也有其他可能)
  8560. if "mail" in session:
  8561. new_pwd = request.form['new_pwd']
  8562. confirm_pwd = request.form['confirm_pwd']
  8563. # 判斷密碼是否一致
  8564. if new_pwd == confirm_pwd:
  8565. mail = session['mail']
  8566. user = User.query.filter_by(mail=mail).first()
  8567. print("user: ", user)
  8568. print("user.password_before: ", user.password)
  8569. print("new_pwd: ", new_pwd)
  8570. user.password = new_pwd
  8571. print("user.password_after: ", user.password)
  8572. db.session.add(user)
  8573. db.session.commit()
  8574. del session['mail']
  8575. # 修改完後回登入頁
  8576. return redirect('/login')
  8577. else:
  8578. # Rita errMsg 是指網頁上的 {{errMsg}} 位置
  8579. errMsg = "Passwords does not match"
  8580. return render_template('reset_pwd2.html', errMsg=errMsg)
  8581. email = request.form['email']
  8582. user = User.query.filter_by(mail=email).first()
  8583. if user: # Rita 有找到對應 email
  8584. session['mail'] = user.mail
  8585. return render_template('reset_pwd2.html')
  8586. else:
  8587. errMsg = "Wrong email.Please try again"
  8588. return render_template('reset_pwd1.html', errMsg=errMsg)
  8589. # 註冊頁面的訪問路徑
  8590. @main.route('/register', methods=['POST', "GET"])
  8591. def register_views():
  8592. if request.method == 'GET':
  8593. return render_template('registration.html')
  8594. else:
  8595. # 獲取文本框的值並賦值給user實體對象
  8596. user = User()
  8597. user.firstname = request.form['firstname']
  8598. user.lastname = request.form['lastname']
  8599. user.mail = request.form['email']
  8600. user.phone = request.form['phone']
  8601. user.username = request.form['username']
  8602. user.password = request.form['password']
  8603. user.status = 8 # Rita app\models.py 設定 0:admin;1:new;9:disable [0906 更新] 0:admin;1:superuser;2:enduser;8:new;9:disable
  8604. #將數據保存進資料庫 - 註冊
  8605. db.session.add(user)
  8606. # 手動提交,目的是為了獲取提交後的user的id
  8607. db.session.commit()
  8608. # 當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user
  8609. # 完成登入的操作
  8610. user = User.query.filter_by(username=user.username).first()
  8611. session['status'] = user.status
  8612. session['id'] = user.userID
  8613. session['uname'] = user.username
  8614. return redirect('/')
  8615. # 驗證email訪問路徑
  8616. @main.route('/check_email')
  8617. def check_email_views():
  8618. email = request.args['email']
  8619. user = User.query.filter_by(mail=email).first()
  8620. if user:
  8621. # Rita email 錯誤時會顯示 Incorrect email address
  8622. result = {"errMsg": " "}
  8623. else:
  8624. result = {"pass": " "}
  8625. return json.dumps(result)
  8626. # 驗證username訪問路徑
  8627. @main.route('/check_username')
  8628. def check_username_views():
  8629. username = request.args['username']
  8630. user = User.query.filter_by(username=username).first()
  8631. if user:
  8632. result = {"errMsg": " "}
  8633. else:
  8634. result = {"pass": " "}
  8635. return json.dumps(result)
  8636. # 咖啡貨櫃的訪問路徑
  8637. @main.route('/cargo_list', methods=['GET', 'POST'])
  8638. def cargo_list_views():
  8639. username = session['uname']
  8640. if request.method == 'GET':
  8641. return render_template('cargo_list.html', params=locals())
  8642. else:
  8643. pass
  8644. # 貨櫃1的訪問路徑
  8645. @main.route('/cargo1', methods=['GET', 'POST'])
  8646. def cargo1_views():
  8647. username = session['uname']
  8648. if request.method == 'GET':
  8649. return render_template('cargo1.html', params=locals())
  8650. else:
  8651. pass
  8652. # 貨櫃1排程的訪問路徑
  8653. @main.route('/cargo1_schedule', methods=['GET', 'POST'])
  8654. def cargo1_schedule_views():
  8655. username = session['uname']
  8656. if request.method == 'GET':
  8657. # 將已儲存的排程資料傳給前端
  8658. # 進豆閥
  8659. try:
  8660. bean = BeanValve.query.order_by(text('datetime desc')).first()
  8661. datetime = bean.datetime
  8662. beans = BeanValve.query.filter_by(
  8663. datetime=datetime).all()
  8664. except Exception as e:
  8665. pass
  8666. # 清洗機
  8667. try:
  8668. wash = WashMachine.query.order_by(text('datetime desc')).first()
  8669. datetime = wash.datetime
  8670. washes = WashMachine.query.filter_by(datetime=datetime).all()
  8671. except Exception as e:
  8672. pass
  8673. # 輸送帶1
  8674. try:
  8675. belt1 = ConveyorBelt1.query.order_by(text('datetime desc')).first()
  8676. datetime = belt1.datetime
  8677. belts1 = ConveyorBelt1.query.filter_by(datetime=datetime).all()
  8678. except Exception as e:
  8679. pass
  8680. # ///////////////////////////////////////////////////////////////////////////////////////////
  8681. # 消毒機
  8682. try:
  8683. disinfect = Cargo1Disinfect.query.order_by(
  8684. text('datetime desc')).first()
  8685. datetime = disinfect.datetime
  8686. disinfects = Cargo1Disinfect.query.filter_by(
  8687. datetime=datetime).all()
  8688. except Exception as e:
  8689. pass
  8690. # 色選機
  8691. try:
  8692. color = ColorMachine.query.order_by(text('datetime desc')).first()
  8693. datetime = color.datetime
  8694. colors = ColorMachine.query.filter_by(datetime=datetime).all()
  8695. except Exception as e:
  8696. pass
  8697. # 輸送帶2
  8698. try:
  8699. belt2 = ConveyorBelt2.query.order_by(text('datetime desc')).first()
  8700. datetime = belt2.datetime
  8701. belts2 = ConveyorBelt2.query.filter_by(datetime=datetime).all()
  8702. except Exception as e:
  8703. pass
  8704. # 去皮機
  8705. try:
  8706. peeling = PeelingMachine.query.order_by(
  8707. text('datetime desc')).first()
  8708. datetime = peeling.datetime
  8709. peelings = PeelingMachine.query.filter_by(datetime=datetime).all()
  8710. except Exception as e:
  8711. pass
  8712. # 輸送帶3
  8713. try:
  8714. belt3 = ConveyorBelt3.query.order_by(text('datetime desc')).first()
  8715. datetime = belt3.datetime
  8716. belts3 = ConveyorBelt3.query.filter_by(datetime=datetime).all()
  8717. except Exception as e:
  8718. pass
  8719. return render_template('cargo1_schedule.html', params=locals())
  8720. else:
  8721. current_time = dt.now()
  8722. # 循環從前端提交過來的資料
  8723. for i in request.form:
  8724. # 進豆閥
  8725. if i[:10] == 'inletValve':
  8726. if i[:19] == 'inletValve_duration':
  8727. bean = BeanValve()
  8728. bean.duration = request.form[i]
  8729. elif i[:18] == 'inletValve_from_hr':
  8730. iv_from_hr = request.form[i]
  8731. elif i[:19] == 'inletValve_from_min':
  8732. iv_from_min = request.form[i]
  8733. bean.start = iv_from_hr + ":" + iv_from_min
  8734. elif i[:16] == 'inletValve_to_hr':
  8735. iv_to_hr = request.form[i]
  8736. elif i[:17] == 'inletValve_to_min':
  8737. iv_to_min = request.form[i]
  8738. bean.end = iv_to_hr + ":" + iv_to_min
  8739. bean.datetime = current_time
  8740. db.session.add(bean)
  8741. db.session.commit()
  8742. # 清洗機
  8743. elif i[:4] == 'wash':
  8744. if i[:13] == 'wash_duration':
  8745. wash = WashMachine()
  8746. wash.duration = request.form[i]
  8747. elif i[:12] == 'wash_from_hr':
  8748. wash_from_hr = request.form[i]
  8749. elif i[:13] == 'wash_from_min':
  8750. wash_from_min = request.form[i]
  8751. wash.start = wash_from_hr + ":" + wash_from_min
  8752. elif i[:10] == 'wash_to_hr':
  8753. wash_to_hr = request.form[i]
  8754. elif i[:11] == 'wash_to_min':
  8755. wash_to_min = request.form[i]
  8756. wash.end = wash_to_hr + ":" + wash_to_min
  8757. wash.datetime = current_time
  8758. db.session.add(wash)
  8759. db.session.commit()
  8760. # 輸送帶1
  8761. elif i[:5] == 'belt1':
  8762. if i[:14] == 'belt1_duration':
  8763. belt1 = ConveyorBelt1()
  8764. belt1.duration = request.form[i]
  8765. elif i[:13] == 'belt1_from_hr':
  8766. belt1_from_hr = request.form[i]
  8767. elif i[:14] == 'belt1_from_min':
  8768. belt1_from_min = request.form[i]
  8769. belt1.start = belt1_from_hr + ":" + belt1_from_min
  8770. elif i[:11] == 'belt1_to_hr':
  8771. belt1_to_hr = request.form[i]
  8772. elif i[:12] == 'belt1_to_min':
  8773. belt1_to_min = request.form[i]
  8774. belt1.end = belt1_to_hr + ":" + belt1_to_min
  8775. belt1.datetime = current_time
  8776. db.session.add(belt1)
  8777. db.session.commit()
  8778. # 消毒
  8779. elif i[:9] == 'disinfect':
  8780. if i[:18] == 'disinfect_duration':
  8781. disinfect = Cargo1Disinfect()
  8782. disinfect.duration = request.form[i]
  8783. elif i[:17] == 'disinfect_from_hr':
  8784. di_from_hr = request.form[i]
  8785. elif i[:18] == 'disinfect_from_min':
  8786. di_from_min = request.form[i]
  8787. disinfect.start = di_from_hr + ":" + di_from_min
  8788. elif i[:15] == 'disinfect_to_hr':
  8789. di_to_hr = request.form[i]
  8790. elif i[:16] == 'disinfect_to_min':
  8791. di_to_min = request.form[i]
  8792. disinfect.end = di_to_hr + ":" + di_to_min
  8793. disinfect.datetime = current_time
  8794. db.session.add(disinfect)
  8795. db.session.commit()
  8796. # 色選機
  8797. elif i[:5] == 'color':
  8798. if i[:14] == 'color_duration':
  8799. color = ColorMachine()
  8800. color.duration = request.form[i]
  8801. elif i[:13] == 'color_from_hr':
  8802. color_from_hr = request.form[i]
  8803. elif i[:14] == 'color_from_min':
  8804. color_from_min = request.form[i]
  8805. color.start = color_from_hr + ":" + color_from_min
  8806. elif i[:11] == 'color_to_hr':
  8807. color_to_hr = request.form[i]
  8808. elif i[:12] == 'color_to_min':
  8809. color_to_min = request.form[i]
  8810. color.end = color_to_hr + ":" + color_to_min
  8811. color.datetime = current_time
  8812. db.session.add(color)
  8813. db.session.commit()
  8814. # 輸送帶2
  8815. elif i[:5] == 'belt2':
  8816. if i[:14] == 'belt2_duration':
  8817. belt2 = ConveyorBelt2()
  8818. belt2.duration = request.form[i]
  8819. elif i[:13] == 'belt2_from_hr':
  8820. belt2_from_hr = request.form[i]
  8821. elif i[:14] == 'belt2_from_min':
  8822. belt2_from_min = request.form[i]
  8823. belt2.start = belt2_from_hr + ":" + belt2_from_min
  8824. elif i[:11] == 'belt2_to_hr':
  8825. belt2_to_hr = request.form[i]
  8826. elif i[:12] == 'belt2_to_min':
  8827. belt2_to_min = request.form[i]
  8828. belt2.end = belt2_to_hr + ":" + belt2_to_min
  8829. belt2.datetime = current_time
  8830. db.session.add(belt2)
  8831. db.session.commit()
  8832. # 去皮機
  8833. elif i[:6] == 'peeled':
  8834. if i[:15] == 'peeled_duration':
  8835. peeling = PeelingMachine()
  8836. peeling.duration = request.form[i]
  8837. elif i[:14] == 'peeled_from_hr':
  8838. peeled_from_hr = request.form[i]
  8839. elif i[:15] == 'peeled_from_min':
  8840. peeled_from_min = request.form[i]
  8841. peeling.start = peeled_from_hr + ":" + peeled_from_min
  8842. elif i[:12] == 'peeled_to_hr':
  8843. peeled_to_hr = request.form[i]
  8844. elif i[:13] == 'peeled_to_min':
  8845. peeled_to_min = request.form[i]
  8846. peeling.end = peeled_to_hr + ":" + peeled_to_min
  8847. peeling.datetime = current_time
  8848. db.session.add(peeling)
  8849. db.session.commit()
  8850. # 輸送帶3
  8851. elif i[:5] == 'belt3':
  8852. if i[:14] == 'belt3_duration':
  8853. belt3 = ConveyorBelt3()
  8854. belt3.duration = request.form[i]
  8855. elif i[:13] == 'belt3_from_hr':
  8856. belt3_from_hr = request.form[i]
  8857. elif i[:14] == 'belt3_from_min':
  8858. belt3_from_min = request.form[i]
  8859. belt3.start = belt3_from_hr + ":" + belt3_from_min
  8860. elif i[:11] == 'belt3_to_hr':
  8861. belt3_to_hr = request.form[i]
  8862. elif i[:12] == 'belt3_to_min':
  8863. belt3_to_min = request.form[i]
  8864. belt3.end = belt3_to_hr + ":" + belt3_to_min
  8865. belt3.datetime = current_time
  8866. db.session.add(belt3)
  8867. db.session.commit()
  8868. return render_template('cargo1.html', params=locals())
  8869. # 貨櫃2的訪問路徑
  8870. @main.route('/cargo2', methods=['GET', 'POST'])
  8871. def cargo2_views():
  8872. username = session['uname']
  8873. if request.method == 'GET':
  8874. return render_template('cargo2.html', params=locals())
  8875. else:
  8876. pass
  8877. # 貨櫃2排程的發酵槽訪問路徑
  8878. @main.route('/cargo2_schedule_tanks', methods=['GET', 'POST'])
  8879. def cargo2_schedule_tanks_views():
  8880. username = session['uname']
  8881. if request.method == 'GET':
  8882. return render_template('cargo2_schedule_tanks.html', params=locals())
  8883. else:
  8884. pass
  8885. # 貨櫃2排程發酵槽的清單訪問路徑
  8886. @main.route('/cargo2_schedule/<tid>', methods=['GET', 'POST'])
  8887. def cargo2_schedule_views(tid):
  8888. username = session['uname']
  8889. if request.method == 'GET':
  8890. # 將已儲存的排程資料傳給前端
  8891. # 打菌
  8892. try:
  8893. bacteria = Bacteria.query.filter_by(tank_num=int(
  8894. tid)).order_by(text('datetime desc')).first()
  8895. datetime = bacteria.datetime
  8896. bacterias = Bacteria.query.filter_by(datetime=datetime).all()
  8897. except Exception as e:
  8898. pass
  8899. # 消毒
  8900. try:
  8901. disinfect = Cargo2Disinfect.query.filter_by(
  8902. tank_num=int(tid)).order_by(text('datetime desc')).first()
  8903. datetime = disinfect.datetime
  8904. disinfects = Cargo2Disinfect.query.filter_by(
  8905. datetime=datetime).all()
  8906. except Exception as e:
  8907. pass
  8908. # 加熱
  8909. try:
  8910. heating = Heating.query.filter_by(tank_num=int(
  8911. tid)).order_by(text('datetime desc')).first()
  8912. datetime = heating.datetime
  8913. heatings = Heating.query.filter_by(datetime=datetime).all()
  8914. except Exception as e:
  8915. pass
  8916. # 攪拌
  8917. try:
  8918. stir = Stir.query.filter_by(tank_num=int(tid)).order_by(
  8919. text('datetime desc')).first()
  8920. datetime = stir.datetime
  8921. stirs = Stir.query.filter_by(datetime=datetime).all()
  8922. except Exception as e:
  8923. pass
  8924. # 注水
  8925. try:
  8926. water = WaterInjection.query.filter_by(
  8927. tank_num=int(tid)).order_by(text('datetime desc')).first()
  8928. datetime = water.datetime
  8929. waters = WaterInjection.query.filter_by(datetime=datetime).all()
  8930. except Exception as e:
  8931. pass
  8932. # 開上閥
  8933. try:
  8934. top = TopValve.query.filter_by(tank_num=int(
  8935. tid)).order_by(text('datetime desc')).first()
  8936. datetime = top.datetime
  8937. tops = TopValve.query.filter_by(datetime=datetime).all()
  8938. except Exception as e:
  8939. pass
  8940. # 開下閥
  8941. try:
  8942. bottom = BottomValve.query.filter_by(tank_num=int(
  8943. tid)).order_by(text('datetime desc')).first()
  8944. datetime = bottom.datetime
  8945. bottoms = BottomValve.query.filter_by(datetime=datetime).all()
  8946. except Exception as e:
  8947. pass
  8948. # 溫度
  8949. try:
  8950. tem = Temperature.query.filter_by(tank_num=int(
  8951. tid)).order_by(text('datetime desc')).first()
  8952. datetime = tem.datetime
  8953. tems = Temperature.query.filter_by(datetime=datetime).all()
  8954. except Exception as e:
  8955. pass
  8956. return render_template('cargo2_schedule.html', params=locals())
  8957. else:
  8958. current_time = dt.now()
  8959. # 循環從前端提交過來的資料
  8960. for i in request.form:
  8961. # 打菌
  8962. if i[:8] == 'bacteria':
  8963. if i[:17] == 'bacteria_duration':
  8964. bacteria = Bacteria()
  8965. bacteria.duration = request.form[i]
  8966. elif i[:16] == 'bacteria_from_hr':
  8967. bac_from_hr = request.form[i]
  8968. elif i[:17] == 'bacteria_from_min':
  8969. bac_from_min = request.form[i]
  8970. bacteria.start = bac_from_hr + ":" + bac_from_min
  8971. elif i[:14] == 'bacteria_to_hr':
  8972. bac_to_hr = request.form[i]
  8973. elif i[:15] == 'bacteria_to_min':
  8974. bac_to_min = request.form[i]
  8975. bacteria.end = bac_to_hr + ":" + bac_to_min
  8976. bacteria.datetime = current_time
  8977. bacteria.tank_num = int(tid)
  8978. db.session.add(bacteria)
  8979. db.session.commit()
  8980. # 消毒
  8981. elif i[:9] == 'disinfect':
  8982. if i[:18] == 'disinfect_duration':
  8983. disinfect = Cargo2Disinfect()
  8984. disinfect.duration = request.form[i]
  8985. elif i[:17] == 'disinfect_from_hr':
  8986. di_from_hr = request.form[i]
  8987. elif i[:18] == 'disinfect_from_min':
  8988. di_from_min = request.form[i]
  8989. disinfect.start = di_from_hr + ":" + di_from_min
  8990. elif i[:15] == 'disinfect_to_hr':
  8991. di_to_hr = request.form[i]
  8992. elif i[:16] == 'disinfect_to_min':
  8993. di_to_min = request.form[i]
  8994. disinfect.end = di_to_hr + ":" + di_to_min
  8995. disinfect.datetime = current_time
  8996. disinfect.tank_num = int(tid)
  8997. db.session.add(disinfect)
  8998. db.session.commit()
  8999. # 加熱
  9000. elif i[:7] == 'heating':
  9001. if i[:16] == 'heating_duration':
  9002. heating = Heating()
  9003. heating.duration = request.form[i]
  9004. elif i[:15] == 'heating_from_hr':
  9005. heat_from_hr = request.form[i]
  9006. elif i[:16] == 'heating_from_min':
  9007. heat_from_min = request.form[i]
  9008. heating.start = heat_from_hr + ":" + heat_from_min
  9009. elif i[:13] == 'heating_to_hr':
  9010. heat_to_hr = request.form[i]
  9011. elif i[:14] == 'heating_to_min':
  9012. heat_to_min = request.form[i]
  9013. heating.end = heat_to_hr + ":" + heat_to_min
  9014. heating.datetime = current_time
  9015. heating.tank_num = int(tid)
  9016. db.session.add(heating)
  9017. db.session.commit()
  9018. # 攪拌
  9019. elif i[:4] == 'stir':
  9020. if i[:13] == 'stir_duration':
  9021. stir = Stir()
  9022. stir.duration = request.form[i]
  9023. elif i[:12] == 'stir_from_hr':
  9024. stir_from_hr = request.form[i]
  9025. elif i[:13] == 'stir_from_min':
  9026. stir_from_min = request.form[i]
  9027. stir.start = stir_from_hr + ":" + stir_from_min
  9028. elif i[:10] == 'stir_to_hr':
  9029. stir_to_hr = request.form[i]
  9030. elif i[:11] == 'stir_to_min':
  9031. stir_to_min = request.form[i]
  9032. stir.end = stir_to_hr + ":" + stir_to_min
  9033. stir.datetime = current_time
  9034. stir.tank_num = int(tid)
  9035. db.session.add(stir)
  9036. db.session.commit()
  9037. # 注水
  9038. elif i[:5] == 'water':
  9039. if i[:14] == 'water_duration':
  9040. water = WaterInjection()
  9041. water.duration = request.form[i]
  9042. elif i[:13] == 'water_from_hr':
  9043. water_from_hr = request.form[i]
  9044. elif i[:14] == 'water_from_min':
  9045. water_from_min = request.form[i]
  9046. water.start = water_from_hr + ":" + water_from_min
  9047. elif i[:11] == 'water_to_hr':
  9048. water_to_hr = request.form[i]
  9049. elif i[:12] == 'water_to_min':
  9050. water_to_min = request.form[i]
  9051. water.end = water_to_hr + ":" + water_to_min
  9052. water.datetime = current_time
  9053. water.tank_num = int(tid)
  9054. db.session.add(water)
  9055. db.session.commit()
  9056. # 開上閥
  9057. elif i[:9] == 'highValve':
  9058. if i[:18] == 'highValve_duration':
  9059. top = TopValve()
  9060. top.duration = request.form[i]
  9061. elif i[:17] == 'highValve_from_hr':
  9062. h_valve_from_hr = request.form[i]
  9063. elif i[:18] == 'highValve_from_min':
  9064. h_valve_from_min = request.form[i]
  9065. top.start = h_valve_from_hr + ":" + h_valve_from_min
  9066. elif i[:15] == 'highValve_to_hr':
  9067. h_valve_to_hr = request.form[i]
  9068. elif i[:16] == 'highValve_to_min':
  9069. h_valve_to_min = request.form[i]
  9070. top.end = h_valve_to_hr + ":" + h_valve_to_min
  9071. top.datetime = current_time
  9072. top.tank_num = int(tid)
  9073. db.session.add(top)
  9074. db.session.commit()
  9075. # 開下閥
  9076. elif i[:8] == 'lowValve':
  9077. if i[:17] == 'lowValve_duration':
  9078. bottom = BottomValve()
  9079. bottom.duration = request.form[i]
  9080. elif i[:16] == 'lowValve_from_hr':
  9081. l_valve_from_hr = request.form[i]
  9082. elif i[:17] == 'lowValve_from_min':
  9083. l_valve_from_min = request.form[i]
  9084. bottom.start = l_valve_from_hr + ":" + l_valve_from_min
  9085. elif i[:14] == 'lowValve_to_hr':
  9086. l_valve_to_hr = request.form[i]
  9087. elif i[:15] == 'lowValve_to_min':
  9088. l_valve_to_min = request.form[i]
  9089. bottom.end = l_valve_to_hr + ":" + l_valve_to_min
  9090. bottom.datetime = current_time
  9091. bottom.tank_num = int(tid)
  9092. db.session.add(bottom)
  9093. db.session.commit()
  9094. # 溫度
  9095. elif i[:3] == 'tem':
  9096. if i[:12] == 'tem_duration':
  9097. tem = Temperature()
  9098. tem.duration = request.form[i]
  9099. elif i[:11] == 'tem_from_hr':
  9100. tem_from_hr = request.form[i]
  9101. elif i[:12] == 'tem_from_min':
  9102. tem_from_min = request.form[i]
  9103. tem.start = tem_from_hr + ":" + tem_from_min
  9104. elif i[:9] == 'tem_to_hr':
  9105. tem_to_hr = request.form[i]
  9106. elif i[:10] == 'tem_to_min':
  9107. tem_to_min = request.form[i]
  9108. tem.end = tem_to_hr + ":" + tem_to_min
  9109. tem.datetime = current_time
  9110. tem.tank_num = int(tid)
  9111. db.session.add(tem)
  9112. db.session.commit()
  9113. return render_template('cargo2.html', params=locals())
  9114. # 貨櫃2感測器的發酵槽訪問路徑
  9115. @main.route('/cargo2_sensor_tanks', methods=['GET', 'POST'])
  9116. def cargo2_sensor_tanks_views():
  9117. username = session['uname']
  9118. if request.method == 'GET':
  9119. return render_template('cargo2_sensor_tanks.html', params=locals())
  9120. else:
  9121. pass
  9122. # 貨櫃2感測器發酵槽的清單訪問路徑
  9123. @main.route('/cargo2_sensor/<tid>', methods=['GET', 'POST'])
  9124. def s_tank_views(tid):
  9125. # 判斷用戶是否已關閉瀏覽器或登出後,在訪問這個route,如果沒有session就回登入頁
  9126. try:
  9127. username = session['uname']
  9128. except KeyError:
  9129. return redirect('/')
  9130. if request.method == 'GET':
  9131. # Rita 網頁端 params.tank_tem.tem
  9132. # Coffee/CoffeeProject/app/templates/cargo2_sensor.html
  9133. tank_tem = TankTemSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  9134. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  9135. tank_ec = TankECSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  9136. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tid)).order_by(text('datetime desc')).first()
  9137. return render_template('cargo2_sensor.html', params=locals())
  9138. else:
  9139. pass
  9140. # 貨櫃2感測器發酵槽歷史數據的訪問路徑
  9141. @main.route('/history_data', methods=['GET', 'POST'])
  9142. def history_data_views():
  9143. if request.method == 'GET':
  9144. # json
  9145. # tid:tid_D1
  9146. # sensor_name:soil_Temp
  9147. # avg:1
  9148. # max:1
  9149. # min:1
  9150. # time-interval:month
  9151. # date-start:2021-07-01
  9152. # date-end:2021-07-28
  9153. info = request.args.to_dict()
  9154. evt = info['evt']
  9155. avg = int(info['avg'])
  9156. max = int(info['max'])
  9157. min = int(info['min'])
  9158. time_interval = info['time-interval']
  9159. print(info)
  9160. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  9161. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  9162. # print(info)
  9163. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  9164. # print(D)
  9165. # {'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']],
  9166. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  9167. # 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 -
  9168. date_start = info['date-start']
  9169. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  9170. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  9171. date_end = '-'.join(date_end_list) # '2021-05-19'
  9172. tank_num = evt.split('-')[0] # 1
  9173. sensor = evt.split('-')[1] # 溫濕度
  9174. L = []
  9175. D = {}
  9176. maxData = []
  9177. minData = []
  9178. avgData = []
  9179. def sensorData(data_name): # data_name = "tem"
  9180. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  9181. interval = 0
  9182. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  9183. if time_interval == 'month':
  9184. interval = "M" # interval = "M"
  9185. elif time_interval == 'day':
  9186. interval = "D"
  9187. elif time_interval == 'hour':
  9188. interval = "H"
  9189. if how == "max":
  9190. # data = df.resample(interval, how={data_name:how})
  9191. # 最新版的pandas
  9192. data = df.resample(interval).max() # 取樣頻率 "H"
  9193. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  9194. data = data.dropna(axis=0, how='any')
  9195. if time_interval == ('hour' or 'day'):
  9196. data.index = pd.to_datetime(
  9197. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  9198. for a in range(0, len(data.index)):
  9199. l = []
  9200. # 如果是逐時,才顯示小時分秒
  9201. if time_interval == 'hour':
  9202. l.append(str(data.index[a]))
  9203. else:
  9204. l.append(str(data.index[a]).split(' ')[0])
  9205. l.append(str(data[data_name][a]))
  9206. maxData.append(l)
  9207. D['max'] = maxData
  9208. elif how == "mean":
  9209. # data = df.resample(interval, how={data_name:how})
  9210. # 最新版的pandas
  9211. data = df.resample(interval).mean()
  9212. # 刪除具有NaN的值
  9213. data = data.dropna(axis=0, how='any')
  9214. # 將平均數取自小數1位
  9215. data = data.round({data_name: 1})
  9216. for a in range(0, len(data.index)):
  9217. l = []
  9218. # 如果是逐時,才顯示小時分秒
  9219. if time_interval == 'hour':
  9220. l.append(str(data.index[a]))
  9221. else:
  9222. l.append(str(data.index[a]).split(' ')[0])
  9223. l.append(str(data[data_name][a]))
  9224. avgData.append(l)
  9225. D['avg'] = avgData
  9226. elif how == "min":
  9227. # data = df.resample(interval, how={data_name:how})
  9228. # 最新版的pandas
  9229. data = df.resample(interval).min()
  9230. # 刪除具有NaN的值
  9231. data = data.dropna(axis=0, how='any')
  9232. for a in range(0, len(data.index)):
  9233. # print(data.index[a])
  9234. l = []
  9235. # 如果是逐時,才顯示小時分秒
  9236. if time_interval == 'hour':
  9237. l.append(str(data.index[a]))
  9238. else:
  9239. l.append(str(data.index[a]).split(' ')[0])
  9240. l.append(str(data[data_name][a]))
  9241. minData.append(l)
  9242. D['min'] = minData
  9243. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  9244. df['datetime'] = pd.to_datetime(
  9245. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  9246. # print(df['datetime']) # 0 2021-02-19 16:46:10
  9247. # 1 2021-02-19 16:46:20
  9248. # 2 2021-02-19 16:46:30
  9249. # 3 2021-02-19 16:46:41
  9250. df[data_name] = df[data_name].astype(float)
  9251. df = df.set_index('datetime') # 将datetime设置为index
  9252. # print(df) # datetime tem
  9253. # 2021-02-19 16:46:10 24.4
  9254. # 2021-02-19 16:46:20 24.4
  9255. if time_interval == 'month':
  9256. if max:
  9257. dataResample(time_interval, "max", data_name)
  9258. if avg:
  9259. dataResample(time_interval, "mean", data_name)
  9260. if min:
  9261. dataResample(time_interval, "min", data_name)
  9262. elif time_interval == 'day':
  9263. if max:
  9264. dataResample(time_interval, "max", data_name)
  9265. if avg:
  9266. dataResample(time_interval, "mean", data_name)
  9267. if min:
  9268. dataResample(time_interval, "min", data_name)
  9269. elif time_interval == 'hour':
  9270. if max:
  9271. dataResample(time_interval, "max", data_name)
  9272. if avg:
  9273. dataResample(time_interval, "mean", data_name)
  9274. if min:
  9275. dataResample(time_interval, "min", data_name)
  9276. if sensor == '溫濕度':
  9277. # tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).order_by(text('datetime desc')).all()
  9278. # [7/27 Benson] tank_tem = TankTemSensor.query.filter_by(tank_num=int(tank_num)).filter(TankTemSensor.datetime.between(date_start, date_end)).all()
  9279. tank_tem = dry_tank_SHT11.query.filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  9280. # .filter_by(tank_num="D"+tank_num)
  9281. for tem in tank_tem:
  9282. l = [] # l = []
  9283. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  9284. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9285. l.append(time) # l = ['2021-Feb-19_16:46:10']
  9286. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  9287. l.append(tem.SHT11_Temp)
  9288. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  9289. # print(L)
  9290. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  9291. sensorData("tem")
  9292. elif sensor == '酸鹼值':
  9293. tank_ph = TankPHSensor.query.filter_by(tank_num=int(tank_num)).filter(
  9294. TankPHSensor.datetime.between(date_start, date_end)).all()
  9295. for ph in tank_ph:
  9296. l = []
  9297. time = dt.strftime(ph.datetime, '%Y-%b-%d_%H:%M:%S')
  9298. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9299. l.append(time)
  9300. l.append(ph.ph)
  9301. L.append(l)
  9302. # print(L)
  9303. D['all'] = L
  9304. sensorData("ph")
  9305. elif sensor == 'EC值':
  9306. tank_ec = TankECSensor.query.filter_by(tank_num=int(tank_num)).filter(
  9307. TankECSensor.datetime.between(date_start, date_end)).all()
  9308. for ec in tank_ec:
  9309. l = []
  9310. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  9311. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9312. l.append(time)
  9313. l.append(ec.ec)
  9314. L.append(l)
  9315. # print(L)
  9316. D['all'] = L
  9317. sensorData("ec")
  9318. elif sensor == '超音波':
  9319. tank_sonic = TankSonicSensor.query.filter_by(tank_num=int(tank_num)).filter(
  9320. TankSonicSensor.datetime.between(date_start, date_end)).all()
  9321. for sonic in tank_sonic:
  9322. l = []
  9323. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9324. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9325. l.append(time)
  9326. l.append(sonic.sonic)
  9327. L.append(l)
  9328. # print(L)
  9329. D['all'] = L
  9330. sensorData("sonic")
  9331. print(D)
  9332. return json.dumps(D)
  9333. else:
  9334. pass
  9335. # Rita 改寫
  9336. @main.route('/history_data_new', methods=['GET', 'POST'])
  9337. def history_data_new_views():
  9338. if request.method == 'GET':
  9339. # json
  9340. # tid:tid_D1
  9341. # sensor_name:soil_Temp
  9342. # avg:1
  9343. # max:1
  9344. # min:1
  9345. # time-interval:month
  9346. # date-start:2021-07-01
  9347. # date-end:2021-07-28
  9348. info = request.args.to_dict()
  9349. # evt = info['evt']
  9350. tid = info['tid']
  9351. sensor_name = info['sensor_name']
  9352. avg = int(info['avg'])
  9353. max = int(info['max'])
  9354. min = int(info['min'])
  9355. time_interval = info['time-interval']
  9356. print("info:", info)
  9357. # Rita {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'month',
  9358. # 'date-start': '2021-05-04', 'date-end': '2021-05-18'} {'all': [], 'avg': []}
  9359. # print(info)
  9360. # {'evt': '1-溫濕度', 'avg': '1', 'max': '0', 'min': '0', 'time-interval': 'hour', 'date-start': '2021-01-01', 'date-end': '2021-07-27'}
  9361. # print(D)
  9362. # {'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']],
  9363. # 'avg': [['2021-02-19 16:00:00', '24.5'], ['2021-02-19 18:00:00', '25.3']]}
  9364. # 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 -
  9365. date_start = info['date-start']
  9366. date_end_list = info['date-end'].split('-') # 先把 'date-end' 的 '2021-05-18' 拆成 ['2021', '05', '18']
  9367. date_end_list[2] = str(int(date_end_list[2]) + 1) # 18 + 1 = 19 再轉成 str → '19'
  9368. date_end = '-'.join(date_end_list) # '2021-05-19'
  9369. # tank_num = evt.split('-')[0] # 1
  9370. # sensor = evt.split('-')[1] # 溫濕度
  9371. tank_num = tid # D1
  9372. sensor = sensor_name # soil_Temp
  9373. L = []
  9374. D = {}
  9375. maxData = []
  9376. minData = []
  9377. avgData = []
  9378. def sensorData(data_name): # data_name = "tem"
  9379. def dataResample(time_interval, how, data_name): # dataResample('month', how???, "tem") # 下方 "hour"
  9380. interval = 0
  9381. # 設置resample的第一個參數,要按照逐月、逐日或逐時
  9382. if time_interval == 'month':
  9383. interval = "M" # interval = "M"
  9384. elif time_interval == 'day':
  9385. interval = "D"
  9386. elif time_interval == 'hour':
  9387. interval = "H"
  9388. if how == "max":
  9389. # data = df.resample(interval, how={data_name:how})
  9390. # 最新版的pandas
  9391. data = df.resample(interval).max() # 取樣頻率 'H'
  9392. # 刪除有 NaN 的列, any 任何一欄位為空則刪 (all 全部欄位為空值才刪)
  9393. data = data.dropna(axis=0, how='any')
  9394. if time_interval == ('hour' or 'day'):
  9395. data.index = pd.to_datetime(
  9396. data.index, format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  9397. for a in range(0, len(data.index)):
  9398. l = []
  9399. # 如果是逐時,才顯示小時分秒
  9400. if time_interval == 'hour':
  9401. l.append(str(data.index[a]))
  9402. else:
  9403. l.append(str(data.index[a]).split(' ')[0])
  9404. l.append(str(data[data_name][a]))
  9405. maxData.append(l)
  9406. D['max'] = maxData
  9407. elif how == "mean":
  9408. # data = df.resample(interval, how={data_name:how})
  9409. # 最新版的pandas
  9410. data = df.resample(interval).mean()
  9411. # 刪除具有NaN的值
  9412. data = data.dropna(axis=0, how='any')
  9413. # 將平均數取自小數1位
  9414. data = data.round({data_name: 1})
  9415. for a in range(0, len(data.index)):
  9416. l = []
  9417. # 如果是逐時,才顯示小時分秒
  9418. if time_interval == 'hour':
  9419. l.append(str(data.index[a]))
  9420. else:
  9421. l.append(str(data.index[a]).split(' ')[0])
  9422. l.append(str(data[data_name][a]))
  9423. avgData.append(l)
  9424. D['avg'] = avgData
  9425. elif how == "min":
  9426. # data = df.resample(interval, how={data_name:how})
  9427. # 最新版的pandas
  9428. data = df.resample(interval).min()
  9429. # 刪除具有NaN的值
  9430. data = data.dropna(axis=0, how='any')
  9431. for a in range(0, len(data.index)):
  9432. # print(data.index[a])
  9433. l = []
  9434. # 如果是逐時,才顯示小時分秒
  9435. if time_interval == 'hour':
  9436. l.append(str(data.index[a]))
  9437. else:
  9438. l.append(str(data.index[a]).split(' ')[0])
  9439. l.append(str(data[data_name][a]))
  9440. minData.append(l)
  9441. D['min'] = minData
  9442. df = pd.DataFrame(L, columns=["datetime", data_name]) # 指定欄標籤名稱 為 ["datetime", "tem"]
  9443. df['datetime'] = pd.to_datetime(
  9444. df['datetime'], format='%Y-%b-%d_%H:%M:%S') # 将数据类型转换为日期类型
  9445. # print(df['datetime']) # 0 2021-02-19 16:46:10
  9446. # 1 2021-02-19 16:46:20
  9447. # 2 2021-02-19 16:46:30
  9448. # 3 2021-02-19 16:46:41
  9449. df[data_name] = df[data_name].astype(float)
  9450. df = df.set_index('datetime') # 将datetime设置为index
  9451. # print(df) # datetime tem
  9452. # 2021-02-19 16:46:10 24.4
  9453. # 2021-02-19 16:46:20 24.4
  9454. if time_interval == 'month':
  9455. if max:
  9456. dataResample(time_interval, "max", data_name)
  9457. if avg:
  9458. dataResample(time_interval, "mean", data_name)
  9459. if min:
  9460. dataResample(time_interval, "min", data_name)
  9461. elif time_interval == 'day':
  9462. if max:
  9463. dataResample(time_interval, "max", data_name)
  9464. if avg:
  9465. dataResample(time_interval, "mean", data_name)
  9466. if min:
  9467. dataResample(time_interval, "min", data_name)
  9468. elif time_interval == 'hour':
  9469. if max:
  9470. dataResample(time_interval, "max", data_name)
  9471. if avg:
  9472. dataResample(time_interval, "mean", data_name)
  9473. if min:
  9474. dataResample(time_interval, "min", data_name)
  9475. if tank_num[:2] == 'DI':
  9476. # 乾燥入料儲豆槽
  9477. if sensor == 'UltraSonic':
  9478. tank_UltraSonic = dry_input_sensor.query.filter_by(tank_num=tank_num).filter(dry_input_sensor.datetime.between(date_start, date_end)).all()
  9479. for sonic in tank_UltraSonic:
  9480. l = []
  9481. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9482. l.append(time)
  9483. l.append(sonic.UltraSonic)
  9484. L.append(l)
  9485. D['all'] = L
  9486. sensorData("UltraSonic")
  9487. elif tank_num[:2] == 'DO':
  9488. # 乾燥出料儲豆槽
  9489. if sensor == 'UltraSonic':
  9490. tank_UltraSonic = dry_output_sensor.query.filter_by(tank_num=tank_num).filter(dry_output_sensor.datetime.between(date_start, date_end)).all()
  9491. for sonic in tank_UltraSonic:
  9492. l = []
  9493. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9494. l.append(time)
  9495. l.append(sonic.UltraSonic)
  9496. L.append(l)
  9497. D['all'] = L
  9498. sensorData("UltraSonic")
  9499. elif tank_num[:1] == 'D':
  9500. # 乾燥槽
  9501. if sensor == 'SHT11_Temp':
  9502. tank_tem = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  9503. for tem in tank_tem:
  9504. l = [] # l = []
  9505. time = dt.strftime(tem.datetime, '%Y-%b-%d_%H:%M:%S') # time = '2021-Feb-19_16:46:10' 轉換時間格式
  9506. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9507. l.append(time) # l = ['2021-Feb-19_16:46:10']
  9508. #l.append(tem.tem) # l = ['2021-Feb-19_16:46:10', '24.4']
  9509. l.append(tem.SHT11_Temp)
  9510. L.append(l) # L = [['2021-Feb-19_16:46:10', '24.4']]
  9511. # print(L)
  9512. D['all'] = L # D = {'all': [['2021-Feb-19_16:46:10', '24.4']]} # all 所有符合數據
  9513. sensorData("SHT11_Temp")
  9514. elif sensor == 'SHT11_Humidity':
  9515. tank_hum = dry_tank_SHT11.query.filter_by(tank_num=tank_num).filter(dry_tank_SHT11.datetime.between(date_start, date_end)).all()
  9516. for hum in tank_hum:
  9517. l = []
  9518. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  9519. l.append(time)
  9520. l.append(hum.SHT11_Humidity)
  9521. L.append(l)
  9522. D['all'] = L
  9523. sensorData("SHT11_Humidity")
  9524. elif sensor == 'UltraSonic':
  9525. tank_UltraSonic = dry_tank_UltraSonic.query.filter_by(tank_num=tank_num).filter(dry_tank_UltraSonic.datetime.between(date_start, date_end)).all()
  9526. for sonic in tank_UltraSonic:
  9527. l = []
  9528. time = dt.strftime(sonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9529. l.append(time)
  9530. l.append(sonic.UltraSonic)
  9531. L.append(l)
  9532. D['all'] = L
  9533. sensorData("UltraSonic")
  9534. elif sensor == 'PA':
  9535. tank_PA = dry_tank_PA.query.filter_by(tank_num=tank_num).filter(dry_tank_PA.datetime.between(date_start, date_end)).all()
  9536. for pa in tank_PA:
  9537. l = []
  9538. time = dt.strftime(pa.datetime, '%Y-%b-%d_%H:%M:%S')
  9539. l.append(time)
  9540. l.append(pa.PA)
  9541. L.append(l)
  9542. D['all'] = L
  9543. sensorData("PA")
  9544. elif sensor == 'soil_Temp':
  9545. tank_soiltemp = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  9546. for temp in tank_soiltemp:
  9547. l = []
  9548. time = dt.strftime(temp.datetime, '%Y-%b-%d_%H:%M:%S')
  9549. l.append(time)
  9550. l.append(temp.soil_Temp)
  9551. L.append(l)
  9552. D['all'] = L
  9553. sensorData("soil_Temp")
  9554. elif sensor == 'soil_Humidity':
  9555. tank_soilHum = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  9556. for hum in tank_soilHum:
  9557. l = []
  9558. time = dt.strftime(hum.datetime, '%Y-%b-%d_%H:%M:%S')
  9559. l.append(time)
  9560. l.append(hum.soil_EC)
  9561. L.append(l)
  9562. D['all'] = L
  9563. sensorData("soil_Humidity")
  9564. elif sensor == 'soil_EC':
  9565. tank_soilec = dry_tank_Soil.query.filter_by(tank_num=tank_num).filter(dry_tank_Soil.datetime.between(date_start, date_end)).all()
  9566. for ec in tank_soilec:
  9567. l = []
  9568. time = dt.strftime(ec.datetime, '%Y-%b-%d_%H:%M:%S')
  9569. # time = dt.strftime(tem.datetime, '%Y-%m-%d')
  9570. l.append(time)
  9571. l.append(ec.soil_EC)
  9572. L.append(l)
  9573. D['all'] = L
  9574. sensorData("soil_EC")
  9575. elif tank_num[:2] == 'FI':
  9576. if sensor == 'UltraSonic':
  9577. input_UltraSonic = ferment_input_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_input_UltraSonic.datetime.between(date_start, date_end)).all()
  9578. for UltraSonic in input_UltraSonic:
  9579. l = []
  9580. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9581. l.append(time)
  9582. l.append(UltraSonic.UltraSonic)
  9583. L.append(l)
  9584. D['all'] = L
  9585. sensorData("UltraSonic")
  9586. elif tank_num[:2] == 'FO':
  9587. if sensor == 'UltraSonic':
  9588. output_UltraSonic = ferment_output_UltraSonic.query.filter_by(tank_num=tank_num).filter(ferment_output_UltraSonic.datetime.between(date_start, date_end)).all()
  9589. for UltraSonic in output_UltraSonic:
  9590. l = []
  9591. time = dt.strftime(UltraSonic.datetime, '%Y-%b-%d_%H:%M:%S')
  9592. l.append(time)
  9593. l.append(UltraSonic.UltraSonic)
  9594. L.append(l)
  9595. D['all'] = L
  9596. sensorData("UltraSonic")
  9597. elif tank_num[:1] == 'F':
  9598. if sensor == 'LiDAR':
  9599. tank_LiDAR = ferment_tank_LiDAR.query.filter_by(tank_num = tank_num)\
  9600. .filter(ferment_tank_LiDAR.datetime.between(date_start, date_end)).all()
  9601. for LiDAR in tank_LiDAR:
  9602. l = []
  9603. time = dt.strftime(LiDAR.datetime, '%Y-%b-%d_%H:%M:%S')
  9604. l.append(time)
  9605. l.append(LiDAR.LiDAR)
  9606. L.append(l)
  9607. D['all'] = L
  9608. sensorData("LiDAR")
  9609. elif sensor == 'motorEncoder':
  9610. tank_motorEncoder = ferment_tank_motorEncoder.query.filter_by(tank_num = tank_num)\
  9611. .filter(ferment_tank_motorEncoder.datetime.between(date_start, date_end)).all()
  9612. for motorEncoder in tank_motorEncoder:
  9613. l = []
  9614. time = dt.strftime(motorEncoder.datetime, '%Y-%b-%d_%H:%M:%S')
  9615. l.append(time)
  9616. l.append(motorEncoder.motorEncoder)
  9617. L.append(l)
  9618. D['all'] = L
  9619. sensorData("motorEncoder")
  9620. elif sensor == 'PressureWaterLevel':
  9621. tank_PressureWaterLevel = ferment_tank_PressureWaterLevel.query.filter_by(tank_num = tank_num)\
  9622. .filter(ferment_tank_PressureWaterLevel.datetime.between(date_start, date_end)).all()
  9623. for PressureWaterLevel in tank_PressureWaterLevel:
  9624. l = []
  9625. time = dt.strftime(PressureWaterLevel.datetime, '%Y-%b-%d_%H:%M:%S')
  9626. l.append(time)
  9627. l.append(PressureWaterLevel.PressureWaterLevel)
  9628. l.append('{:.2f}'.format(float(PressureWaterLevel.PressureWaterLevel)))
  9629. L.append(l)
  9630. D['all'] = L
  9631. sensorData("PressureWaterLevel")
  9632. elif sensor == 'SHT11_Temp':
  9633. tank_Temp = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  9634. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  9635. for Temp in tank_Temp:
  9636. l = []
  9637. time = dt.strftime(Temp.datetime, '%Y-%b-%d_%H:%M:%S')
  9638. l.append(time)
  9639. l.append(Temp.SHT11_Temp)
  9640. L.append(l)
  9641. D['all'] = L
  9642. sensorData("SHT11_Temp")
  9643. elif sensor == 'SHT11_Humidity':
  9644. tank_Humidity = ferment_tank_SHT11.query.filter_by(tank_num = tank_num)\
  9645. .filter(ferment_tank_SHT11.datetime.between(date_start, date_end)).all()
  9646. for Humidity in tank_Humidity:
  9647. l = []
  9648. time = dt.strftime(Humidity.datetime, '%Y-%b-%d_%H:%M:%S')
  9649. l.append(time)
  9650. l.append(Humidity.SHT11_Humidity)
  9651. L.append(l)
  9652. D['all'] = L
  9653. sensorData("SHT11_Humidity")
  9654. elif sensor == 'CO2':
  9655. tank_CO2 = ferment_tank_CO2.query.filter_by(tank_num = tank_num)\
  9656. .filter(ferment_tank_CO2.datetime.between(date_start, date_end)).all()
  9657. for CO2 in tank_CO2:
  9658. l = []
  9659. time = dt.strftime(CO2.datetime, '%Y-%b-%d_%H:%M:%S')
  9660. l.append(time)
  9661. l.append(CO2.CO2)
  9662. L.append(l)
  9663. D['all'] = L
  9664. sensorData("CO2")
  9665. elif sensor == 'PH':
  9666. tank_PH = ferment_tank_PH.query.filter_by(tank_num = tank_num)\
  9667. .filter(ferment_tank_PH.datetime.between(date_start, date_end)).all()
  9668. for PH in tank_PH:
  9669. l = []
  9670. time = dt.strftime(PH.datetime, '%Y-%b-%d_%H:%M:%S')
  9671. l.append(time)
  9672. l.append(PH.PH)
  9673. L.append(l)
  9674. D['all'] = L
  9675. sensorData("PH")
  9676. elif sensor == 'ORP':
  9677. tank_ORP = ferment_tank_ORP.query.filter_by(tank_num = tank_num)\
  9678. .filter(ferment_tank_ORP.datetime.between(date_start, date_end)).all()
  9679. for ORP in tank_ORP:
  9680. l = []
  9681. time = dt.strftime(ORP.datetime, '%Y-%b-%d_%H:%M:%S')
  9682. l.append(time)
  9683. l.append(ORP.ORP)
  9684. L.append(l)
  9685. D['all'] = L
  9686. sensorData("ORP")
  9687. elif sensor == 'DO':
  9688. tank_DO = ferment_tank_DO.query.filter_by(tank_num = tank_num)\
  9689. .filter(ferment_tank_DO.datetime.between(date_start, date_end)).all()
  9690. for DO in tank_DO:
  9691. l = []
  9692. time = dt.strftime(DO.datetime, '%Y-%b-%d_%H:%M:%S')
  9693. l.append(time)
  9694. l.append(DO.DO)
  9695. L.append(l)
  9696. D['all'] = L
  9697. sensorData("DO")
  9698. elif sensor == 'EC':
  9699. tank_EC = ferment_tank_EC.query.filter_by(tank_num = tank_num)\
  9700. .filter(ferment_tank_EC.datetime.between(date_start, date_end)).all()
  9701. for EC in tank_EC:
  9702. l = []
  9703. time = dt.strftime(EC.datetime, '%Y-%b-%d_%H:%M:%S')
  9704. l.append(time)
  9705. l.append(EC.EC)
  9706. L.append(l)
  9707. D['all'] = L
  9708. sensorData("EC")
  9709. elif sensor == 'PA':
  9710. tank_PA = ferment_tank_PA.query.filter_by(tank_num = tank_num)\
  9711. .filter(ferment_tank_PA.datetime.between(date_start, date_end)).all()
  9712. for PA in tank_PA:
  9713. l = []
  9714. time = dt.strftime(PA.datetime, '%Y-%b-%d_%H:%M:%S')
  9715. l.append(time)
  9716. l.append(PA.PA)
  9717. L.append(l)
  9718. D['all'] = L
  9719. sensorData("PA")
  9720. print(D)
  9721. return json.dumps(D)
  9722. else:
  9723. pass
  9724. # 貨櫃2致動器的發酵槽訪問路徑
  9725. @main.route('/cargo2_actuator_tanks', methods=['GET', 'POST'])
  9726. def cargo2_actuator_tanks_views():
  9727. username = session['uname']
  9728. if request.method == 'GET':
  9729. return render_template('cargo2_actuator_tanks.html', params=locals())
  9730. else:
  9731. pass
  9732. # 貨櫃2致動器發酵槽的清單訪問路徑
  9733. @main.route('/cargo2_actuator/<tid>', methods=['GET', 'POST'])
  9734. def cargo2_actuator_views(tid):
  9735. username = session['uname']
  9736. if request.method == 'GET':
  9737. return render_template('cargo2_actuator.html', params=locals())
  9738. else:
  9739. pass
  9740. # 貨櫃3的訪問路徑
  9741. @main.route('/cargo3', methods=['GET', 'POST'])
  9742. def cargo3_views():
  9743. username = session['uname']
  9744. if request.method == 'GET':
  9745. return render_template('cargo3.html', params=locals())
  9746. else:
  9747. pass
  9748. # 貨櫃3排程的訪問路徑
  9749. @main.route('/cargo3_schedule', methods=['GET', 'POST'])
  9750. def cargo3_schedule_views():
  9751. username = session['uname']
  9752. if request.method == 'GET':
  9753. # 將已儲存的排程資料傳給前端
  9754. # 提升機
  9755. try:
  9756. hoist = Hoist.query.order_by(text('datetime desc')).first()
  9757. datetime = hoist.datetime
  9758. hoists = Hoist.query.filter_by(datetime=datetime).all()
  9759. except Exception as e:
  9760. pass
  9761. # 烘乾機
  9762. try:
  9763. dryer = Dryer.query.order_by(text('datetime desc')).first()
  9764. datetime = dryer.datetime
  9765. dryers = Dryer.query.filter_by(datetime=datetime).all()
  9766. except Exception as e:
  9767. pass
  9768. return render_template('cargo3_schedule.html', params=locals())
  9769. else:
  9770. # Rita: "POST /b_cargo3 HTTP/1.1" 404 -
  9771. current_time = dt.now()
  9772. # 循環從前端提交過來的資料
  9773. for i in request.form:
  9774. print('Rita test i :', i)
  9775. # 堤升機
  9776. if i[:5] == 'hoist':
  9777. if i[:14] == 'hoist_duration':
  9778. hoist = Hoist()
  9779. hoist.duration = request.form[i]
  9780. elif i[:13] == 'hoist_from_hr':
  9781. ho_from_hr = request.form[i]
  9782. elif i[:14] == 'hoist_from_min':
  9783. ho_from_min = request.form[i]
  9784. hoist.start = ho_from_hr + ":" + ho_from_min
  9785. elif i[:11] == 'hoist_to_hr':
  9786. ho_to_hr = request.form[i]
  9787. elif i[:12] == 'hoist_to_min':
  9788. ho_to_min = request.form[i]
  9789. hoist.end = ho_to_hr + ":" + ho_to_min
  9790. hoist.datetime = current_time
  9791. db.session.add(hoist)
  9792. db.session.commit()
  9793. # 烘乾機
  9794. elif i[:5] == 'dryer':
  9795. if i[:14] == 'dryer_duration':
  9796. dryer = Dryer()
  9797. dryer.duration = request.form[i]
  9798. elif i[:13] == 'dryer_from_hr':
  9799. dry_from_hr = request.form[i]
  9800. elif i[:14] == 'dryer_from_min':
  9801. dry_from_min = request.form[i]
  9802. dryer.start = dry_from_hr + ":" + dry_from_min
  9803. elif i[:11] == 'dryer_to_hr':
  9804. dry_to_hr = request.form[i]
  9805. elif i[:12] == 'dryer_to_min':
  9806. dry_to_min = request.form[i]
  9807. dryer.end = dry_to_hr + ":" + dry_to_min
  9808. dryer.datetime = current_time
  9809. db.session.add(dryer)
  9810. db.session.commit()
  9811. return render_template('cargo3.html', params=locals())
  9812. # 影像串流的訪問路徑
  9813. @main.route('/video', methods=['GET', 'POST'])
  9814. def video_views():
  9815. username = session['uname']
  9816. if request.method == 'GET':
  9817. return render_template('video.html', params=locals())
  9818. else:
  9819. pass
  9820. # 影像的訪問路徑
  9821. @main.route('/learn', methods=['GET', 'POST'])
  9822. def learn_views():
  9823. username = session['uname']
  9824. if request.method == 'GET':
  9825. return render_template('learn.html', params=locals())
  9826. else:
  9827. pass
  9828. # 獲取relay狀態路徑
  9829. @main.route('/relay', methods=['GET', 'POST'])
  9830. def relay_views():
  9831. if request.method == 'GET':
  9832. relay = Relay.query.order_by(text('datetime desc')).first()
  9833. relay_status = relay.status
  9834. return jsonify({"relay": relay_status})
  9835. else:
  9836. pass
  9837. # 獲取脫皮機狀態路徑
  9838. @main.route('/peel', methods=['GET', 'POST'])
  9839. def peeling_views():
  9840. if request.method == 'GET':
  9841. peeling = PeelingMachineRPM.query.order_by(text('datetime desc')).first()
  9842. peeling_rpm = peeling.rpm
  9843. return jsonify({"peeling": peeling_rpm})
  9844. else:
  9845. pass
  9846. # 退出的訪問路徑
  9847. @main.route('/logout')
  9848. def logout_views():
  9849. if 'id' in session and 'uname' in session:
  9850. del session['id']
  9851. del session['uname']
  9852. return redirect('/')
  9853. @main.route("/udp_client", methods=['POST', 'GET'])
  9854. def udp_views():
  9855. # sl(0.5)
  9856. global c_sock
  9857. if request.method == 'GET':
  9858. # def close():
  9859. # global c_sock
  9860. # sl(600)
  9861. # c_sock.close()
  9862. # c_sock = 0
  9863. # print("c_sock is closing")
  9864. max_length = 65000
  9865. # max_length = 95000
  9866. # lab1的IP
  9867. host = "192.168.50.65"
  9868. # lab2的IP
  9869. # host = "192.168.51.160"
  9870. port = 8000
  9871. c_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  9872. # t = threading.Thread(target=close)
  9873. # t.daemon = True
  9874. # t.start()
  9875. print("test")
  9876. # dict = request.args.to_dict()
  9877. # nr = int(dict['nr'])
  9878. # if nr == 1:
  9879. # camara = 0
  9880. # elif nr == 2:
  9881. # camara = 'rtsp://admin:admin@192.168.50.182/av2_0'
  9882. # elif nr == 3:
  9883. # camara = 'rtsp://admin:abcd1234@192.168.51.101/av2_0'
  9884. # 地下室小兵
  9885. # cap = cv2.VideoCapture('rtsp://admin:abcd1234@192.168.51.48/av2_0')
  9886. # 主機攝像頭
  9887. # cap = cv2.VideoCapture(0)
  9888. # 外面小兵
  9889. # cap = cv2.VideoCapture('rtsp://admin:admin@192.168.50.182/av2_0')
  9890. cap = cv2.VideoCapture('rtsp://192.168.50.182/av0_0')
  9891. # cap = cv2.VideoCapture(0)
  9892. # cap = cv2.VideoCapture(camara)
  9893. ret, frame = cap.read()
  9894. while ret:
  9895. # compress frame
  9896. frame = cv2.resize(frame, (550, 400), interpolation=cv2.INTER_AREA)
  9897. retval, buffer = cv2.imencode(".jpg", frame)
  9898. if retval:
  9899. # convert to byte array
  9900. buffer = buffer.tobytes()
  9901. # get size of the frame
  9902. buffer_size = len(buffer)
  9903. num_of_packs = 1
  9904. if buffer_size > max_length:
  9905. num_of_packs = math.ceil(buffer_size / max_length)
  9906. frame_info = {"packs": num_of_packs}
  9907. # send the number of packs to be expected
  9908. # print("Number of packs:", num_of_packs)
  9909. c_sock.sendto(pickle.dumps(frame_info), (host, port))
  9910. left = 0
  9911. right = max_length
  9912. for i in range(num_of_packs):
  9913. # print("left:", left)
  9914. # print("right:", right)
  9915. # truncate data to send
  9916. data = buffer[left:right]
  9917. left = right
  9918. right += max_length
  9919. # send the frames accordingly
  9920. c_sock.sendto(data, (host, port))
  9921. ret, frame = cap.read()
  9922. print("done")
  9923. return "done"
  9924. else:
  9925. c_sock.shutdown(2)
  9926. c_sock.close()
  9927. c_sock = 0
  9928. print("c_sock is closing")
  9929. # 影像串流的路徑
  9930. @main.route("/video_feed", methods=['POST', 'GET'])
  9931. def video_feed_views():
  9932. print("test2")
  9933. global s_sock
  9934. if request.method == 'GET':
  9935. # 於10分鐘之後,自動關閉socket server
  9936. # if s_sock == 0:
  9937. # def socket_server_views():
  9938. # global s_sock
  9939. # print("test")
  9940. # print(s_sock)
  9941. # sl(600)
  9942. # if s_sock != 0:
  9943. # s_sock.close()
  9944. # s_sock = 0
  9945. # print('s_sock is closed')
  9946. #
  9947. # pool.submit(socket_server_views)
  9948. host = "192.168.50.65"
  9949. port = 8000
  9950. max_length = 65540
  9951. # max_length = 95540
  9952. s_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  9953. s_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  9954. s_sock.bind((host, port))
  9955. frame_info = None
  9956. buffer = None
  9957. frame = None
  9958. encodedImage = None
  9959. print("-> waiting for connection")
  9960. # 影像生成器函數,將影像以jpg格式傳給前端
  9961. def generate():
  9962. while True:
  9963. with lock:
  9964. global s_sock, frame_info, buffer, frame, encodedImage
  9965. if s_sock == 0:
  9966. break
  9967. data, address = s_sock.recvfrom(max_length)
  9968. if len(data) < 100:
  9969. frame_info = pickle.loads(data)
  9970. if frame_info:
  9971. nums_of_packs = frame_info["packs"]
  9972. for i in range(nums_of_packs):
  9973. if s_sock == 0:
  9974. break
  9975. data, address = s_sock.recvfrom(max_length)
  9976. if i == 0:
  9977. buffer = data
  9978. else:
  9979. buffer += data
  9980. frame = np.frombuffer(buffer, dtype=np.uint8)
  9981. frame = frame.reshape(frame.shape[0], 1)
  9982. frame = cv2.imdecode(frame, cv2.IMREAD_UNCHANGED)
  9983. # print(frame)
  9984. # 如果frame為None就跳過
  9985. if frame is None:
  9986. continue
  9987. frame = cv2.resize(
  9988. frame, (640, 360), interpolation=cv2.INTER_AREA)
  9989. # encode the frame in JPEG format
  9990. (flag, encodedImage) = cv2.imencode(".jpg", frame)
  9991. # ensure the frame was successfully encoded
  9992. if not flag:
  9993. continue
  9994. # yield the output frame in the byte format
  9995. yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
  9996. bytearray(encodedImage) + b'\r\n')
  9997. # return the response generated along with the specific media
  9998. # type (mime type)
  9999. return Response(generate(), mimetype="multipart/x-mixed-replace; boundary=frame")
  10000. else:
  10001. if s_sock != 0:
  10002. s_sock.close()
  10003. s_sock = 0
  10004. print('s_sock is closed')
  10005. return "s_sock is closed"
  10006. print("test")
  10007. return "s_sock is closed"
  10008. D = {"input_vacuum_status": "0",
  10009. "tank_vacuum_status": "0",
  10010. "tank_threewayvalve_input_status": "0",
  10011. "tank_threewayvalve_bean_status": "0",
  10012. "tank_solenoid_disinfect_status": "0",
  10013. "tank_pump_disinfect_status": "0",
  10014. "outer_threewayvalve_float_status": "0",
  10015. "tank_motor_status": 'none',
  10016. "tank_pump_water_in_status": "0",
  10017. "tank_pump_cleanwater_in_status": "0",
  10018. "outer_solenoid_water_status": "0",
  10019. "tank_solenoid_reclaimed_in_status": "0",
  10020. "tank_solenoid_water_in_status": "0",
  10021. "tank_solenoid_water_out_status": "0",
  10022. "tank_solenoid_reclaimed_out_status": "0",
  10023. "tank_pump_sensor_status": "0",
  10024. "solenoid_tank_pump_status": "0",
  10025. "tank_nozzle_status": "0",
  10026. "tank_blower_status": "0",
  10027. "tank_heater1_status": "0",
  10028. "tank_heater2_status": "0",
  10029. "temp1_enable": "0",
  10030. "temp1": "0",
  10031. "tank_diskvalve_status": "0",
  10032. "output_vacuum_status": "0",
  10033. "tank_temp_enable_status": "0",
  10034. "tank_temp_status": "0",
  10035. # "tank_pump_waterFloat_status": "0",
  10036. # "tank_pump_waterL2_status": "0",
  10037. # "tank_pump_waterL4_status": "0",
  10038. # "tank_solenoid_waterL3_status": "0",
  10039. # "tank_solenoid_waterL5_status": "0",
  10040. # "tank_stepping_motor_status": 'none',
  10041. }
  10042. # pub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  10043. # sub_topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78/Log'
  10044. # mqttObj = MQTT('aisky-client', 'aiskyc', '60.250.156.234', 1883, 60, sub_topic)
  10045. mqttObj = MQTT()
  10046. @main.route('/mqtt_block', methods=['POST'])
  10047. def mqtt_block():
  10048. import json
  10049. dict = request.form.to_dict() # 將表單轉換成字典
  10050. print('dict:', dict)
  10051. # print('dict.keys():', dict.keys())
  10052. # dict = {
  10053. # "command":"Dry_OTA",
  10054. # "cond": [
  10055. # {
  10056. # "cond_main": "if D1 tank_SHT11_Temp == 30",
  10057. # "cond_add": ["and tank_soil_Humidity == 25","and tank_soil_Humidity == 25",],
  10058. # "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]
  10059. # },
  10060. # {
  10061. # "cond_main": "if D1 tank_SHT11_Temp == 30",
  10062. # "cond_add": ["and tank_soil_Humidity == 25","and tank_soil_Humidity == 25",],
  10063. # "cond_com": ["tank_motor_status 10", "tank_motor_status 10"]
  10064. # }
  10065. # ]
  10066. # }
  10067. # 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']"}
  10068. json = json.dumps(dict)
  10069. # 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"]}]}
  10070. print('json:', json)
  10071. # 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']}]}
  10072. topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  10073. mqtt.publish(topic, json)
  10074. return 'OK'
  10075. # mqtt發布
  10076. # @main.route('/mqtt/<tid>', methods=['POST'])
  10077. @main.route('/mqtt/<tid>', methods=['POST'])
  10078. def mqtt_views(tid):
  10079. import json
  10080. dict = request.form.to_dict() # 將表單轉換成字典
  10081. json = json.dumps(dict)
  10082. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  10083. # print('json:', json) # json: {"tank-number": "1", "command": "tank_vacuum_status", "value": "on"}
  10084. topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  10085. # res = mqttObj.mqttPublish(pub_topic, json)
  10086. # print(res)
  10087. # sl(2)
  10088. # print(mqttObj.res)
  10089. #
  10090. # print('test')
  10091. mqtt.publish(topic, json)
  10092. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10093. if dict['command'] == 'input_vacuum_status':
  10094. time.sleep(1)
  10095. # D[input_vacuum_status]: "0"
  10096. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  10097. if D['input_vacuum_status'] == 'on':
  10098. return 'on'
  10099. elif D['input_vacuum_status'] == 'off':
  10100. return 'off'
  10101. else:
  10102. return "input_vacuum_status signal was not received"
  10103. # 真空吸料機
  10104. elif dict['command'] == 'tank_vacuum_status':
  10105. time.sleep(1)
  10106. if D['tank_vacuum_status'] == 'on':
  10107. return 'on'
  10108. elif D['tank_vacuum_status'] == 'off':
  10109. return 'off'
  10110. else:
  10111. return "tank_vacuum_status signal was not received"
  10112. # 入料三通閥(ON吸料/OFF排氣)
  10113. elif dict['command'] == 'tank_threewayvalve_input_status':
  10114. time.sleep(1)
  10115. if D['tank_threewayvalve_input_status'] == 'on':
  10116. return 'on'
  10117. elif D['tank_threewayvalve_input_status'] == 'off':
  10118. return 'off'
  10119. else:
  10120. return "tank_threewayvalve_input_status signal was not received"
  10121. # 測豆三通閥(ON吸料/OFF排氣)
  10122. elif dict['command'] == 'tank_threewayvalve_bean_status':
  10123. time.sleep(1)
  10124. if D['tank_threewayvalve_bean_status'] == 'on':
  10125. return 'on'
  10126. elif D['tank_threewayvalve_bean_status'] == 'off':
  10127. return 'off'
  10128. else:
  10129. return "tank_threewayvalve_bean_status signal was not received"
  10130. # 消毒電磁閥(ON噴灑消毒/OFF關)
  10131. elif dict['command'] == 'tank_solenoid_disinfect_status':
  10132. time.sleep(1)
  10133. if D['tank_solenoid_disinfect_status'] == 'on':
  10134. return 'on'
  10135. elif D['tank_solenoid_disinfect_status'] == 'off':
  10136. return 'off'
  10137. else:
  10138. return "tank_solenoid_disinfect_status signal was not received"
  10139. # 混合槽幫浦(ON抽水消毒/OFF關)
  10140. elif dict['command'] == 'tank_pump_disinfect_status':
  10141. time.sleep(1)
  10142. if D['tank_pump_disinfect_status'] == 'on':
  10143. return 'on'
  10144. elif D['tank_pump_disinfect_status'] == 'off':
  10145. return 'off'
  10146. else:
  10147. return "tank_pump_disinfect_status signal was not received"
  10148. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  10149. elif dict['command'] == 'outer_threewayvalve_float_status':
  10150. time.sleep(1)
  10151. if D['outer_threewayvalve_float_status'] == 'on':
  10152. return 'on'
  10153. elif D['outer_threewayvalve_float_status'] == 'off':
  10154. return 'off'
  10155. else:
  10156. return "outer_threewayvalve_float_status signal was not received"
  10157. # 馬達(單位RPM)
  10158. elif dict['command'] == 'tank_motor_status':
  10159. print("D['tank_motor_status']", D['tank_motor_status'])
  10160. time.sleep(1)
  10161. if D['tank_motor_status'] == '0':
  10162. return 'off'
  10163. elif type(D['tank_motor_status']) == int:
  10164. return 'on'
  10165. else:
  10166. return "tank_motor_status signal was not received"
  10167. # 幫浦(清水入水)(ON開/OFF關)
  10168. elif dict['command'] == 'tank_pump_water_in_status':
  10169. time.sleep(1)
  10170. if D['tank_pump_water_in_status'] == 'on':
  10171. return 'on'
  10172. elif D['tank_pump_water_in_status'] == 'off':
  10173. return 'off'
  10174. else:
  10175. return "tank_pump_water_in_status signal was not received"
  10176. # 幫浦(清洗槽入水)(ON開/OFF關)
  10177. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  10178. time.sleep(1)
  10179. if D['tank_pump_cleanwater_in_status'] == 'on':
  10180. return 'on'
  10181. elif D['tank_pump_cleanwater_in_status'] == 'off':
  10182. return 'off'
  10183. else:
  10184. return "tank_pump_cleanwater_in_status signal was not received"
  10185. # 桶外進水電磁閥(ON開/OFF關)
  10186. elif dict['command'] == 'outer_solenoid_water_status':
  10187. time.sleep(1)
  10188. if D['outer_solenoid_water_status'] == 'on':
  10189. return 'on'
  10190. elif D['outer_solenoid_water_status'] == 'off':
  10191. return 'off'
  10192. else:
  10193. return "outer_solenoid_water_status signal was not received"
  10194. # 中水入水電磁閥(ON開/OFF關)
  10195. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  10196. time.sleep(1)
  10197. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  10198. return 'on'
  10199. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  10200. return 'off'
  10201. else:
  10202. return "tank_solenoid_reclaimed_in_status signal was not received"
  10203. # 清水入水電磁閥(ON開/OFF關)
  10204. elif dict['command'] == 'tank_solenoid_water_in_status':
  10205. time.sleep(1)
  10206. if D['tank_solenoid_water_in_status'] == 'on':
  10207. return 'on'
  10208. elif D['tank_solenoid_water_in_status'] == 'off':
  10209. return 'off'
  10210. else:
  10211. return "tank_solenoid_water_in_status signal was not received"
  10212. # 排水廢水電磁閥(ON開/OFF關)
  10213. elif dict['command'] == 'tank_solenoid_water_out_status':
  10214. time.sleep(1)
  10215. if D['tank_solenoid_water_out_status'] == 'on':
  10216. return 'on'
  10217. elif D['tank_solenoid_water_out_status'] == 'off':
  10218. return 'off'
  10219. else:
  10220. return "tank_solenoid_water_out_status signal was not received"
  10221. # 排水中水電磁閥(ON開/OFF關)
  10222. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  10223. time.sleep(1)
  10224. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  10225. return 'on'
  10226. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  10227. return 'off'
  10228. else:
  10229. return "tank_solenoid_reclaimed_out_status signal was not received"
  10230. # 雙核隔膜泵(ON開/OFF關)
  10231. elif dict['command'] == 'tank_pump_sensor_status':
  10232. time.sleep(1)
  10233. if D['tank_pump_sensor_status'] == 'on':
  10234. return 'on'
  10235. elif D['tank_pump_sensor_status'] == 'off':
  10236. return 'off'
  10237. else:
  10238. return "tank_pump_sensor_status signal was not received"
  10239. # 逆洗 pump 電磁閥(ON開/OFF關)
  10240. elif dict['command'] == 'solenoid_tank_pump_status':
  10241. time.sleep(1)
  10242. if D['solenoid_tank_pump_status'] == 'on':
  10243. return 'on'
  10244. elif D['solenoid_tank_pump_status'] == 'off':
  10245. return 'off'
  10246. else:
  10247. return "solenoid_tank_pump_status signal was not received"
  10248. # 噴嘴(ON開/OFF關)
  10249. elif dict['command'] == 'tank_nozzle_status':
  10250. time.sleep(1)
  10251. if D['tank_nozzle_status'] == 'on':
  10252. return 'on'
  10253. elif D['tank_nozzle_status'] == 'off':
  10254. return 'off'
  10255. else:
  10256. return "tank_nozzle_status signal was not received"
  10257. # 鼓風機(ON開/OFF關)
  10258. elif dict['command'] == 'tank_blower_status':
  10259. time.sleep(1)
  10260. if D['tank_blower_status'] == 'on':
  10261. return 'on'
  10262. elif D['tank_blower_status'] == 'off':
  10263. return 'off'
  10264. else:
  10265. return "tank_blower_status signal was not received"
  10266. # 加熱棒 1(ON開/OFF關)
  10267. elif dict['command'] == 'tank_heater1_status':
  10268. time.sleep(1)
  10269. if D['tank_heater1_status'] == 'on':
  10270. return 'on'
  10271. elif D['tank_heater1_status'] == 'off':
  10272. return 'off'
  10273. else:
  10274. return "tank_heater1_status signal was not received"
  10275. # 加熱棒 2(ON開/OFF關)
  10276. elif dict['command'] == 'tank_heater2_status':
  10277. time.sleep(1)
  10278. if D['tank_heater2_status'] == 'on':
  10279. return 'on'
  10280. elif D['tank_heater2_status'] == 'off':
  10281. return 'off'
  10282. else:
  10283. return "tank_heater2_status signal was not received"
  10284. # 溫度控制(ON開/OFF關)
  10285. elif dict['command'] == 'temp1_enable':
  10286. time.sleep(1)
  10287. if D['temp1_enable'] == 'on':
  10288. return 'on'
  10289. elif D['temp1_enable'] == 'off':
  10290. return 'off'
  10291. else:
  10292. return "temp1_enable_status signal was not received"
  10293. # 設定溫度
  10294. elif dict['command'] == 'temp1':
  10295. time.sleep(1)
  10296. if D['temp1'] == '0':
  10297. return 'off'
  10298. elif type(D['temp1']) == float:
  10299. return 'on'
  10300. else:
  10301. return "temp1 signal was not received"
  10302. # 發酵槽 溫控開關
  10303. elif dict['command'] == 'tank_temp_enable':
  10304. time.sleep(1)
  10305. if D['tank_temp_enable'] == 'on':
  10306. return 'on'
  10307. elif D['tank_temp_enable'] == 'off':
  10308. return 'off'
  10309. else:
  10310. return "tank_temp_enable signal was not received"
  10311. # 發酵槽 設定溫度
  10312. elif dict['command'] == 'tank_temp':
  10313. time.sleep(1)
  10314. if D['tank_temp'] == '0':
  10315. return 'off'
  10316. elif type(D['tank_temp']) == float:
  10317. return 'on'
  10318. else:
  10319. return "tank_temp signal was not received"
  10320. # 蝴蝶閥(ON開/OFF關)
  10321. elif dict['command'] == 'tank_diskvalve_status':
  10322. time.sleep(1)
  10323. if D['tank_diskvalve_status'] == 'on':
  10324. return 'on'
  10325. elif D['tank_diskvalve_status'] == 'off':
  10326. return 'off'
  10327. else:
  10328. return "tank_diskvalve_status signal was not received"
  10329. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10330. elif dict['command'] == 'output_vacuum_status':
  10331. time.sleep(1)
  10332. if D['output_vacuum_status'] == 'on':
  10333. return 'on'
  10334. elif D['output_vacuum_status'] == 'off':
  10335. return 'off'
  10336. else:
  10337. return "output_vacuum_status signal was not received"
  10338. else:
  10339. return "MQTT command NOT FOUND"
  10340. # return "publish done" # 1201 test
  10341. # --- 12/10 ------------------------------------------ start
  10342. @main.route('/mqtt_data/<tid>_<command>_<value>', methods=['POST'])
  10343. def mqtt_data(tank_num, command, value):
  10344. import json
  10345. data = { "tank_num": str(tank_num), "command": str(command), "value": str(value) }
  10346. json = json.dumps(data)
  10347. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  10348. print('json:', json)
  10349. topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  10350. mqtt.publish(topic, json)
  10351. # --- 12/10 ------------------------------------------ finish
  10352. # --- 10/19 ------------------------------------------ start
  10353. # mqtt發布
  10354. # @main.route('/mqtt/<tid>', methods=['POST'])
  10355. @main.route('/mqtt_f/<tid>', methods=['POST'])
  10356. def mqtt_f(data):
  10357. import json
  10358. dict = request.form.to_dict()
  10359. json = json.dumps(data)
  10360. # print('dict:', dict) # dict: {'tank-number': '1', 'command': 'tank_vacuum_status', 'value': 'on'}
  10361. # print('json:', json) # json: {"tank-number": "1", tank_vacuum_status", "value": "on"}
  10362. print('json:', json)
  10363. topic = 'AISKY/Coffee/MK-G/b8:27:eb:7e:24:78'
  10364. # res = mqttObj.mqttPublish(pub_topic, json)
  10365. # print(res)
  10366. # sl(2)
  10367. # print(mqttObj.res)
  10368. #
  10369. # print('test')
  10370. mqtt.publish(topic, json)
  10371. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10372. if dict['command'] == 'input_vacuum_status':
  10373. time.sleep(1)
  10374. # D[input_vacuum_status]: "0"
  10375. print('D[input_vacuum_status]:', D['input_vacuum_status'])
  10376. if D['input_vacuum_status'] == 'on':
  10377. return 'on'
  10378. elif D['input_vacuum_status'] == 'off':
  10379. return 'off'
  10380. else:
  10381. return "input_vacuum_status signal was not received"
  10382. # 真空吸料機
  10383. elif dict['command'] == 'tank_vacuum_status':
  10384. time.sleep(1)
  10385. if D['tank_vacuum_status'] == 'on':
  10386. return 'on'
  10387. elif D['tank_vacuum_status'] == 'off':
  10388. return 'off'
  10389. else:
  10390. return "tank_vacuum_status signal was not received"
  10391. # 入料三通閥(ON吸料/OFF排氣)
  10392. elif dict['command'] == 'tank_threewayvalve_input_status':
  10393. time.sleep(1)
  10394. if D['tank_threewayvalve_input_status'] == 'on':
  10395. return 'on'
  10396. elif D['tank_threewayvalve_input_status'] == 'off':
  10397. return 'off'
  10398. else:
  10399. return "tank_threewayvalve_input_status signal was not received"
  10400. # 測豆三通閥(ON吸料/OFF排氣)
  10401. elif dict['command'] == 'tank_threewayvalve_bean_status':
  10402. time.sleep(1)
  10403. if D['tank_threewayvalve_bean_status'] == 'on':
  10404. return 'on'
  10405. elif D['tank_threewayvalve_bean_status'] == 'off':
  10406. return 'off'
  10407. else:
  10408. return "tank_threewayvalve_bean_status signal was not received"
  10409. # 消毒電磁閥(ON噴灑消毒/OFF關)
  10410. elif dict['command'] == 'tank_solenoid_disinfect_status':
  10411. time.sleep(1)
  10412. if D['tank_solenoid_disinfect_status'] == 'on':
  10413. return 'on'
  10414. elif D['tank_solenoid_disinfect_status'] == 'off':
  10415. return 'off'
  10416. else:
  10417. return "tank_solenoid_disinfect_status signal was not received"
  10418. # 混合槽幫浦(ON抽水消毒/OFF關)
  10419. elif dict['command'] == 'tank_pump_disinfect_status':
  10420. time.sleep(1)
  10421. if D['tank_pump_disinfect_status'] == 'on':
  10422. return 'on'
  10423. elif D['tank_pump_disinfect_status'] == 'off':
  10424. return 'off'
  10425. else:
  10426. return "tank_pump_disinfect_status signal was not received"
  10427. # 外桶浮選三通閥(ON開浮選出口/OFF關)
  10428. elif dict['command'] == 'outer_threewayvalve_float_status':
  10429. time.sleep(1)
  10430. if D['outer_threewayvalve_float_status'] == 'on':
  10431. return 'on'
  10432. elif D['outer_threewayvalve_float_status'] == 'off':
  10433. return 'off'
  10434. else:
  10435. return "outer_threewayvalve_float_status signal was not received"
  10436. # 馬達(單位RPM)
  10437. elif dict['command'] == 'tank_motor_status':
  10438. print("D['tank_motor_status']", D['tank_motor_status'])
  10439. time.sleep(1)
  10440. if D['tank_motor_status'] == '0':
  10441. return 'off'
  10442. elif type(D['tank_motor_status']) == int:
  10443. return 'on'
  10444. else:
  10445. return "tank_motor_status signal was not received"
  10446. # 幫浦(清水入水)(ON開/OFF關)
  10447. elif dict['command'] == 'tank_pump_water_in_status':
  10448. time.sleep(1)
  10449. if D['tank_pump_water_in_status'] == 'on':
  10450. return 'on'
  10451. elif D['tank_pump_water_in_status'] == 'off':
  10452. return 'off'
  10453. else:
  10454. return "tank_pump_water_in_status signal was not received"
  10455. # 幫浦(清洗槽入水)(ON開/OFF關)
  10456. elif dict['command'] == 'tank_pump_cleanwater_in_status':
  10457. time.sleep(1)
  10458. if D['tank_pump_cleanwater_in_status'] == 'on':
  10459. return 'on'
  10460. elif D['tank_pump_cleanwater_in_status'] == 'off':
  10461. return 'off'
  10462. else:
  10463. return "tank_pump_cleanwater_in_status signal was not received"
  10464. # 桶外進水電磁閥(ON開/OFF關)
  10465. elif dict['command'] == 'outer_solenoid_water_status':
  10466. time.sleep(1)
  10467. if D['outer_solenoid_water_status'] == 'on':
  10468. return 'on'
  10469. elif D['outer_solenoid_water_status'] == 'off':
  10470. return 'off'
  10471. else:
  10472. return "outer_solenoid_water_status signal was not received"
  10473. # 中水入水電磁閥(ON開/OFF關)
  10474. elif dict['command'] == 'tank_solenoid_reclaimed_in_status':
  10475. time.sleep(1)
  10476. if D['tank_solenoid_reclaimed_in_status'] == 'on':
  10477. return 'on'
  10478. elif D['tank_solenoid_reclaimed_in_status'] == 'off':
  10479. return 'off'
  10480. else:
  10481. return "tank_solenoid_reclaimed_in_status signal was not received"
  10482. # 清水入水電磁閥(ON開/OFF關)
  10483. elif dict['command'] == 'tank_solenoid_water_in_status':
  10484. time.sleep(1)
  10485. if D['tank_solenoid_water_in_status'] == 'on':
  10486. return 'on'
  10487. elif D['tank_solenoid_water_in_status'] == 'off':
  10488. return 'off'
  10489. else:
  10490. return "tank_solenoid_water_in_status signal was not received"
  10491. # 排水廢水電磁閥(ON開/OFF關)
  10492. elif dict['command'] == 'tank_solenoid_water_out_status':
  10493. time.sleep(1)
  10494. if D['tank_solenoid_water_out_status'] == 'on':
  10495. return 'on'
  10496. elif D['tank_solenoid_water_out_status'] == 'off':
  10497. return 'off'
  10498. else:
  10499. return "tank_solenoid_water_out_status signal was not received"
  10500. # 排水中水電磁閥(ON開/OFF關)
  10501. elif dict['command'] == 'tank_solenoid_reclaimed_out_status':
  10502. time.sleep(1)
  10503. if D['tank_solenoid_reclaimed_out_status'] == 'on':
  10504. return 'on'
  10505. elif D['tank_solenoid_reclaimed_out_status'] == 'off':
  10506. return 'off'
  10507. else:
  10508. return "tank_solenoid_reclaimed_out_status signal was not received"
  10509. # 雙核隔膜泵(ON開/OFF關)
  10510. elif dict['command'] == 'tank_pump_sensor_status':
  10511. time.sleep(1)
  10512. if D['tank_pump_sensor_status'] == 'on':
  10513. return 'on'
  10514. elif D['tank_pump_sensor_status'] == 'off':
  10515. return 'off'
  10516. else:
  10517. return "tank_pump_sensor_status signal was not received"
  10518. # 逆洗 pump 電磁閥(ON開/OFF關)
  10519. elif dict['command'] == 'solenoid_tank_pump_status':
  10520. time.sleep(1)
  10521. if D['solenoid_tank_pump_status'] == 'on':
  10522. return 'on'
  10523. elif D['solenoid_tank_pump_status'] == 'off':
  10524. return 'off'
  10525. else:
  10526. return "solenoid_tank_pump_status signal was not received"
  10527. # 噴嘴(ON開/OFF關)
  10528. elif dict['command'] == 'tank_nozzle_status':
  10529. time.sleep(1)
  10530. if D['tank_nozzle_status'] == 'on':
  10531. return 'on'
  10532. elif D['tank_nozzle_status'] == 'off':
  10533. return 'off'
  10534. else:
  10535. return "tank_nozzle_status signal was not received"
  10536. # 鼓風機(ON開/OFF關)
  10537. elif dict['command'] == 'tank_blower_status':
  10538. time.sleep(1)
  10539. if D['tank_blower_status'] == 'on':
  10540. return 'on'
  10541. elif D['tank_blower_status'] == 'off':
  10542. return 'off'
  10543. else:
  10544. return "tank_blower_status signal was not received"
  10545. # 加熱棒 1(ON開/OFF關)
  10546. elif dict['command'] == 'tank_heater1_status':
  10547. time.sleep(1)
  10548. if D['tank_heater1_status'] == 'on':
  10549. return 'on'
  10550. elif D['tank_heater1_status'] == 'off':
  10551. return 'off'
  10552. else:
  10553. return "tank_heater1_status signal was not received"
  10554. # 加熱棒 2(ON開/OFF關)
  10555. elif dict['command'] == 'tank_heater2_status':
  10556. time.sleep(1)
  10557. if D['tank_heater2_status'] == 'on':
  10558. return 'on'
  10559. elif D['tank_heater2_status'] == 'off':
  10560. return 'off'
  10561. else:
  10562. return "tank_heater2_status signal was not received"
  10563. # 溫度控制(ON開/OFF關)
  10564. elif dict['command'] == 'temp1_enable':
  10565. time.sleep(1)
  10566. if D['temp1_enable'] == 'on':
  10567. return 'on'
  10568. elif D['temp1_enable'] == 'off':
  10569. return 'off'
  10570. else:
  10571. return "temp1_enable_status signal was not received"
  10572. # 設定溫度
  10573. elif dict['command'] == 'temp1':
  10574. time.sleep(1)
  10575. if D['temp1'] == '0':
  10576. return 'off'
  10577. elif type(D['temp1']) == float:
  10578. return 'on'
  10579. else:
  10580. return "temp1 signal was not received"
  10581. # 發酵槽 溫控開關
  10582. elif dict['command'] == 'tank_temp_enable':
  10583. time.sleep(1)
  10584. if D['tank_temp_enable'] == 'on':
  10585. return 'on'
  10586. elif D['tank_temp_enable'] == 'off':
  10587. return 'off'
  10588. else:
  10589. return "tank_temp_enable signal was not received"
  10590. # 發酵槽 設定溫度
  10591. elif dict['command'] == 'tank_temp':
  10592. time.sleep(1)
  10593. if D['tank_temp'] == '0':
  10594. return 'off'
  10595. elif type(D['tank_temp']) == float:
  10596. return 'on'
  10597. else:
  10598. return "tank_temp signal was not received"
  10599. # 蝴蝶閥(ON開/OFF關)
  10600. elif dict['command'] == 'tank_diskvalve_status':
  10601. time.sleep(1)
  10602. if D['tank_diskvalve_status'] == 'on':
  10603. return 'on'
  10604. elif D['tank_diskvalve_status'] == 'off':
  10605. return 'off'
  10606. else:
  10607. return "tank_diskvalve_status signal was not received"
  10608. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10609. elif dict['command'] == 'output_vacuum_status':
  10610. time.sleep(1)
  10611. if D['output_vacuum_status'] == 'on':
  10612. return 'on'
  10613. elif D['output_vacuum_status'] == 'off':
  10614. return 'off'
  10615. else:
  10616. return "output_vacuum_status signal was not received"
  10617. else:
  10618. return "MQTT command NOT FOUND"
  10619. # ---10/19 ------------------------------------------- end
  10620. board_prog = {
  10621. "D1": "0",
  10622. "D2": "0",
  10623. "D3": "0",
  10624. "D4": "0",
  10625. "D5": "0",
  10626. "D6": "0",
  10627. "D7": "0",
  10628. "D8": "0",
  10629. "D9": "0",
  10630. "D10": "0",
  10631. "D11": "0",
  10632. "D12": "0",
  10633. }
  10634. # 處理mqtt訂閱的信息
  10635. # 收到訊息後我們可以用 on_message(),來讀取收到的內容:
  10636. @mqtt.on_message()
  10637. def handle_mqtt_message(client, userdata, message):
  10638. # topic = message.topic # 收到的主題 Rita 原本就沒有此行, 增加說明用
  10639. payload = message.payload.decode() # 收到的內容
  10640. payload = json.loads(payload)
  10641. # print("-------msg-------")
  10642. # print('name :', p['name'])
  10643. # print('email :', p['email'])
  10644. print('payload:', payload)
  10645. # success / upload error / no reply
  10646. # {'command': 'Code_upload', 'device_id': 'b8:27:eb:7e:24:78', 'localtime': '2022-06-13 11:59:07', 'response': 'no reply', 'tank_n 'response': 'no reply', 'tank_number': 'D1'}
  10647. if payload['command'] == 'Code_upload':
  10648. board_prog[payload['tank_number']] = payload['response']
  10649. # res = "on_message" + payload['response']
  10650. # return res
  10651. # 入料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10652. if payload['command'] == 'input_vacuum_status':
  10653. if payload['response'] == 'on':
  10654. D['input_vacuum_status'] = 'on'
  10655. else:
  10656. D['input_vacuum_status'] = 'off'
  10657. # 真空吸料機(ON吸料/OFF排氣)
  10658. elif payload['command'] == 'tank_vacuum_status':
  10659. if payload['response'] == 'on':
  10660. D['tank_vacuum_status'] = 'on'
  10661. else:
  10662. D['tank_vacuum_status'] = 'off'
  10663. # 入料三通閥(ON吸料/OFF排氣)
  10664. elif payload['command'] == 'tank_threewayvalve_input_status':
  10665. if payload['response'] == 'on':
  10666. D['tank_threewayvalve_input_status'] = 'on'
  10667. else:
  10668. D['tank_threewayvalve_input_status'] = 'off'
  10669. # 測豆三通閥(ON測豆/OFF排氣)
  10670. elif payload['command'] == 'tank_threewayvalve_bean_status':
  10671. if payload['response'] == 'on':
  10672. D['tank_threewayvalve_bean_status'] = 'on'
  10673. else:
  10674. D['tank_threewayvalve_bean_status'] = 'off'
  10675. # 消毒電磁閥(ON噴灑消毒/OFF關)
  10676. elif payload['command'] == 'tank_solenoid_disinfect_status':
  10677. if payload['response'] == 'on':
  10678. D['tank_solenoid_disinfect_status'] = 'on'
  10679. else:
  10680. D['tank_solenoid_disinfect_status'] = 'off'
  10681. # 混合槽幫浦(ON消毒槽抽水/OFF關)
  10682. elif payload['command'] == 'tank_pump_disinfect_status':
  10683. if payload['response'] == 'on':
  10684. D['tank_pump_disinfect_status'] = 'on'
  10685. else:
  10686. D['tank_pump_disinfect_status'] = 'off'
  10687. # 外桶浮選三通閥(ON浮選落豆/OFF桶內真空)
  10688. elif payload['command'] == 'outer_threewayvalve_float_status':
  10689. if payload['response'] == 'on':
  10690. D['outer_threewayvalve_float_status'] = 'on'
  10691. else:
  10692. D['outer_threewayvalve_float_status'] = 'off'
  10693. # 馬達(單位RPM)
  10694. elif payload['command'] == 'tank_motor_status':
  10695. if payload['response'] == 'off' or payload['response'] == '0':
  10696. D['tank_motor_status'] = '0'
  10697. else:
  10698. D['tank_motor_status'] = payload['response']
  10699. # 幫浦(清水入水)(ON開/OFF關)
  10700. elif payload['command'] == 'tank_pump_water_in_status':
  10701. if payload['response'] == 'on':
  10702. D['tank_pump_water_in_status'] = 'on'
  10703. else:
  10704. D['tank_pump_water_in_status'] = 'off'
  10705. # 幫浦(清洗槽入水)(ON開/OFF關)
  10706. elif payload['command'] == 'tank_pump_cleanwater_in_status':
  10707. if payload['response'] == 'on':
  10708. D['tank_pump_cleanwater_in_status'] = 'on'
  10709. else:
  10710. D['tank_pump_cleanwater_in_status'] = 'off'
  10711. # 桶外進水電磁閥(ON開/OFF關)
  10712. elif payload['command'] == 'outer_solenoid_water_status':
  10713. if payload['response'] == 'on':
  10714. D['outer_solenoid_water_status'] = 'on'
  10715. else:
  10716. D['outer_solenoid_water_status'] = 'off'
  10717. # 中水入水電磁閥(ON開/OFF關)
  10718. elif payload['command'] == 'tank_solenoid_reclaimed_in_status':
  10719. if payload['response'] == 'on':
  10720. D['tank_solenoid_reclaimed_in_status'] = 'on'
  10721. else:
  10722. D['tank_solenoid_reclaimed_in_status'] = 'off'
  10723. # 清水入水電磁閥(ON開/OFF關)
  10724. elif payload['command'] == 'tank_solenoid_water_in_status':
  10725. if payload['response'] == 'on':
  10726. D['tank_solenoid_water_in_status'] = 'on'
  10727. else:
  10728. D['tank_solenoid_water_in_status'] = 'off'
  10729. # 排水廢水電磁閥(ON開/OFF關)
  10730. elif payload['command'] == 'tank_solenoid_water_out_status':
  10731. if payload['response'] == 'on':
  10732. D['tank_solenoid_water_out_status'] = 'on'
  10733. else:
  10734. D['tank_solenoid_water_out_status'] = 'off'
  10735. # 排水中水電磁閥(ON開/OFF關)
  10736. elif payload['command'] == 'tank_solenoid_reclaimed_out_status':
  10737. if payload['response'] == 'on':
  10738. D['tank_solenoid_reclaimed_out_status'] = 'on'
  10739. else:
  10740. D['tank_solenoid_reclaimed_out_status'] = 'off'
  10741. # 雙核隔膜泵(ON開/OFF關)
  10742. elif payload['command'] == 'tank_pump_sensor_status':
  10743. if payload['response'] == 'on':
  10744. D['tank_pump_sensor_status'] = 'on'
  10745. else:
  10746. D['tank_pump_sensor_status'] = 'off'
  10747. # 逆洗 pump 電磁閥(ON開/OFF關)
  10748. elif payload['command'] == 'solenoid_tank_pump_status':
  10749. if payload['response'] == 'on':
  10750. D['solenoid_tank_pump_status'] = 'on'
  10751. else:
  10752. D['solenoid_tank_pump_status'] = 'off'
  10753. # 噴嘴(ON開/OFF關)
  10754. elif payload['command'] == 'tank_nozzle_status':
  10755. if payload['response'] == 'on':
  10756. D['tank_nozzle_status'] = 'on'
  10757. else:
  10758. D['tank_nozzle_status'] = 'off'
  10759. # 鼓風機(ON開/OFF關)
  10760. elif payload['command'] == 'tank_blower_status':
  10761. if payload['response'] == 'on':
  10762. D['tank_blower_status'] = 'on'
  10763. else:
  10764. D['tank_blower_status'] = 'off'
  10765. # 加熱棒 1(ON開/OFF關)
  10766. elif payload['command'] == 'tank_heater1_status':
  10767. if payload['response'] == 'on':
  10768. D['tank_heater1_status'] = 'on'
  10769. else:
  10770. D['tank_heater1_status'] = 'off'
  10771. # 加熱棒 2(ON開/OFF關)
  10772. elif payload['command'] == 'tank_heater2_status':
  10773. if payload['response'] == 'on':
  10774. D['tank_heater2_status'] = 'on'
  10775. else:
  10776. D['tank_heater2_status'] = 'off'
  10777. # 發酵槽 溫控開關
  10778. elif payload['command'] == 'tank_temp_enable':
  10779. if payload['response'] == 'on':
  10780. D['tank_temp_enable'] = 'on'
  10781. else:
  10782. D['tank_temp_enable'] = 'off'
  10783. # 發酵槽 設定溫度
  10784. elif payload['command'] == 'tank_temp':
  10785. if payload['response'] == 'off':
  10786. D['tank_temp'] = '0'
  10787. else:
  10788. D['tank_temp'] = payload['response']
  10789. # 蝴蝶閥(ON開/OFF關)
  10790. elif payload['command'] == 'tank_diskvalve_status':
  10791. if payload['response'] == 'on':
  10792. D['tank_diskvalve_status'] = 'on'
  10793. else:
  10794. D['tank_diskvalve_status'] = 'off'
  10795. # 出料儲豆槽真空吸料機(ON吸料/OFF排氣)
  10796. elif payload['command'] == 'output_vacuum_status':
  10797. if payload['response'] == 'on':
  10798. D['output_vacuum_status'] = 'on'
  10799. else:
  10800. D['output_vacuum_status'] = 'off'
  10801. else:
  10802. return "MQTT command NOT FOUND"