diff --git a/BrewManiacEx/BrewManiacEx.ino b/BrewManiacEx/BrewManiacEx.ino index 08c10c2..db87964 100644 --- a/BrewManiacEx/BrewManiacEx.ino +++ b/BrewManiacEx/BrewManiacEx.ino @@ -36,6 +36,9 @@ extern void brewmaniac_setup(); extern void brewmaniac_loop(); + +#define ResponseAppleCNA true + /**************************************************************************************/ /**************************************************************************************/ @@ -161,6 +164,7 @@ R"END( } )END"; +void requestRestart(bool disc); class NetworkConfig:public AsyncWebHandler { @@ -189,6 +193,12 @@ public: request->send(400); return; } + if(root.containsKey("disconnect")){ + requestRestart(true); + request->send(200); + return; + } + File config=SPIFFS.open(CONFIG_FILENAME,"w+"); if(!config){ request->send(500); @@ -538,16 +548,37 @@ void bmwEventHandler(BrewManiacWeb* bmw, BmwEventType event) } } +#if ResponseAppleCNA == true -HttpUpdateHandler httpUpdateHandler(FIRMWARE_UPDATE_URL,JS_UPDATE_URL); -unsigned long _connectionTime; -byte _wifiState; +class AppleCNAHandler: public AsyncWebHandler +{ +public: + AppleCNAHandler(){} + void handleRequest(AsyncWebServerRequest *request){ + request->send(200, "text/html", "SuccessSuccess"); + } + bool canHandle(AsyncWebServerRequest *request){ + String host=request->host(); + //DBG_PRINTF("Request host:"); + //DBG_PRINTF(host.c_str()); + //DBG_PRINTF("\n"); + if(host.indexOf(String("apple")) >=0 + || host.indexOf(String("itools")) >=0 + || host.indexOf(String("ibook")) >=0 + || host.indexOf(String("airport")) >=0 + || host.indexOf(String("thinkdifferent")) >=0 + || host.indexOf(String("akamai")) >=0 ){ + return true; + } + return false; + } +}; -#define WiFiStateConnected 0 -#define WiFiStateWaitToConnect 1 -#define WiFiStateConnecting 2 -#define TIME_WAIT_TO_CONNECT 10000 -#define TIME_RECONNECT_TIMEOUT 10000 +AppleCNAHandler appleCNAHandler; + +#endif //#if ResponseAppleCNA == true + +HttpUpdateHandler httpUpdateHandler(FIRMWARE_UPDATE_URL,JS_UPDATE_URL); bool testSPIFFS(void) { @@ -574,12 +605,23 @@ bool testSPIFFS(void) DebugOut(c.c_str()); return true; } -#define PROFILING true +#define PROFILING false #if PROFILING == true unsigned long _profileMaximumLoop=0; unsigned long _profileLoopBegin; #endif +void displayIP(bool apmode){ + IPV4Address ip; + if(apmode){ + ip.dword = WiFi.softAPIP(); + bmWeb.setIp(ip.bytes,true); + }else{ + ip.dword = WiFi.localIP(); + bmWeb.setIp(ip.bytes); + } +} + void setup(void){ //0. initilze debug port #if SerialDebug == true @@ -611,8 +653,7 @@ void setup(void){ //3. Start WiFi - WiFiSetup::begin(_gHostname); - _wifiState=WiFiStateConnected; + WiFiSetup.begin(_gHostname); DebugOut("Connected! IP address: "); DebugOut(WiFi.localIP()); @@ -620,8 +661,10 @@ void setup(void){ DebugOut("Error setting mDNS responder"); } // TODO: SSDP responder - - TimeKeeper.begin("time.nist.gov","time.windows.com","de.pool.ntp.org"); + if(WiFiSetup.isApMode()) + TimeKeeper.begin(false); + else + TimeKeeper.begin("time.nist.gov","time.windows.com","de.pool.ntp.org"); //4. check version bool forcedUpdate; @@ -656,17 +699,21 @@ void setup(void){ //5.2 Normal serving pages //5.2.1 status report through SSE #if UseWebSocket == true - ws.onEvent(onWsEvent); - server.addHandler(&ws); + ws.onEvent(onWsEvent); + server.addHandler(&ws); #endif #if UseServerSideEvent == true - sse.onConnect(sseConnect); - server.addHandler(&sse); + sse.onConnect(sseConnect); + server.addHandler(&sse); #endif server.addHandler(&networkConfig); server.addHandler(&bmwHandler); +#if ResponseAppleCNA == true + if(WiFiSetup.isApMode()) + server.addHandler(&appleCNAHandler); +#endif server.addHandler(&logHandler); //5.2.2 SPIFFS is part of the serving pages //securedAccess need additional check @@ -705,12 +752,27 @@ void setup(void){ ESPUpdateServer_setup(_gUsername,_gPassword); // 9. display IP - IPV4Address ip; - ip.dword = WiFi.localIP(); - bmWeb.setIp(ip.bytes); + displayIP(WiFiSetup.isApMode()); + DebugOut("End Setup\n"); } +#define SystemStateOperating 0 +#define SystemStateRestartPending 1 +#define SystemStateWaitRestart 2 + +#define TIME_RESTART_TIMEOUT 3000 + +bool _disconnectBeforeRestart; +static unsigned long _time; +byte _systemState=SystemStateOperating; +void requestRestart(bool disc) +{ + _disconnectBeforeRestart=disc; + _systemState =SystemStateRestartPending; +} + +#define IS_RESTARTING (_systemState!=SystemStateOperating) void loop(void){ @@ -723,39 +785,37 @@ void loop(void){ brewmaniac_loop(); - if(WiFi.status() != WL_CONNECTED) - { - if(_wifiState==WiFiStateConnected) - { - byte nullIp[4]={0,0,0,0}; - bmWeb.setIp(nullIp); - - _connectionTime=millis(); - _wifiState = WiFiStateWaitToConnect; - } - else if(_wifiState==WiFiStateWaitToConnect) - { - if((millis() - _connectionTime) > TIME_WAIT_TO_CONNECT) - { - WiFi.begin(); - _connectionTime=millis(); - _wifiState = WiFiStateConnecting; - } - } - else if(_wifiState==WiFiStateConnecting) - { - if((millis() - _connectionTime) > TIME_RECONNECT_TIMEOUT){ - ESP.restart(); + if(WiFiSetup.stayConnected()){ + if(WiFiSetup.isApMode()){ + TimeKeeper.setInternetAccessibility(false); + displayIP(true); + }else{ + if(WiFi.status() != WL_CONNECTED){ + uint8_t nullip[]={0,0,0,0}; + bmWeb.setIp(nullip); + }else{ + displayIP(false); } } - } - else - { - _wifiState=WiFiStateConnected; - } + } httpUpdateHandler.runUpdate(); + if(_systemState ==SystemStateRestartPending){ + _time=millis(); + _systemState =SystemStateWaitRestart; + }else if(_systemState ==SystemStateWaitRestart){ + if((millis() - _time) > TIME_RESTART_TIMEOUT){ + if(_disconnectBeforeRestart){ + WiFi.disconnect(); + WiFiSetup.setAutoReconnect(false); + delay(1000); + } +// ESP.restart(); + } + } + + #if PROFILING == true unsigned long thisloop = millis() - _profileLoopBegin; if(thisloop > _profileMaximumLoop) _profileMaximumLoop = thisloop; diff --git a/BrewManiacEx/BrewManiacProxy.cpp b/BrewManiacEx/BrewManiacProxy.cpp index a70e540..46e7f48 100644 --- a/BrewManiacEx/BrewManiacProxy.cpp +++ b/BrewManiacEx/BrewManiacProxy.cpp @@ -20,7 +20,7 @@ extern void wiReadRecipe(AutomationRecipe *recipe); extern byte readSetting(int addr); extern void updateSetting(int addr,byte value); -extern void wiSetDeviceAddress(byte ip[]); +extern void wiSetDeviceAddress(byte ip[],bool apmode); extern void wiUpdateSetting(int address,byte value); #if MaximumNumberOfSensors > 1 @@ -213,9 +213,9 @@ void BrewManiacProxy::setButtonLabel(byte btns) if(_eventHandler) _eventHandler(BMNotifyButtonLabel); } -void BrewManiacProxy::setIp(byte ip[]) +void BrewManiacProxy::setIp(byte ip[], bool apmode) { - wiSetDeviceAddress(ip); + wiSetDeviceAddress(ip,apmode); } diff --git a/BrewManiacEx/BrewManiacProxy.h b/BrewManiacEx/BrewManiacProxy.h index fb24a1d..fd17da5 100644 --- a/BrewManiacEx/BrewManiacProxy.h +++ b/BrewManiacEx/BrewManiacProxy.h @@ -38,7 +38,7 @@ class BrewManiacProxy{ // from Web void sendButton(byte mask,bool longPressed); - void setIp(byte ip[]); + void setIp(byte ip[],bool apmode=false); // recipe AutomationRecipe automationRecipe; diff --git a/BrewManiacEx/BrewManiacWeb.cpp b/BrewManiacEx/BrewManiacWeb.cpp index 0ff0bf3..10cfab2 100644 --- a/BrewManiacEx/BrewManiacWeb.cpp +++ b/BrewManiacEx/BrewManiacWeb.cpp @@ -57,9 +57,9 @@ void BrewManiacWeb::updateSensorSetting(String& json) #endif -void BrewManiacWeb::setIp(uint8_t ip[]) +void BrewManiacWeb::setIp(uint8_t ip[],bool apmode) { - bmproxy.setIp(ip); + bmproxy.setIp(ip,apmode); } BrewManiacWeb::BrewManiacWeb(void) diff --git a/BrewManiacEx/BrewManiacWeb.h b/BrewManiacEx/BrewManiacWeb.h index 1e1730f..66be0d9 100644 --- a/BrewManiacEx/BrewManiacWeb.h +++ b/BrewManiacEx/BrewManiacWeb.h @@ -37,7 +37,7 @@ class BrewManiacWeb bool isBrewing(void); byte brewingStage(void); byte lastBrewEvent(void); - void setIp(uint8_t ip[]); + void setIp(uint8_t ip[],bool apmode=false); void loop(void); // get data diff --git a/BrewManiacEx/HttpUpdateHandler.cpp b/BrewManiacEx/HttpUpdateHandler.cpp index a8effe7..8c0ba0a 100644 --- a/BrewManiacEx/HttpUpdateHandler.cpp +++ b/BrewManiacEx/HttpUpdateHandler.cpp @@ -334,7 +334,7 @@ void HttpFileDownloader::download(void) _http.begin(_url); - DEBUGF("[HTTP] GET...\n"); + DEBUGF("[HTTP] GET %s...\n",_url.c_str()); // start connection and send HTTP header int httpCode = _http.GET(); if(httpCode > 0) { diff --git a/BrewManiacEx/TimeKeeper.cpp b/BrewManiacEx/TimeKeeper.cpp index 336635e..46d3f84 100644 --- a/BrewManiacEx/TimeKeeper.cpp +++ b/BrewManiacEx/TimeKeeper.cpp @@ -36,15 +36,20 @@ void TimeKeeperClass::setCurrentTime(time_t now) // saveTime(now); } -void TimeKeeperClass::begin(void) +void TimeKeeperClass::begin(bool useSaved) { //_online = false; - - _referenceSeconds=loadTime(); - _referenceSeconds += 300; // add 5 minutes. - _referenceSystemTime = millis(); - _lastSaved=_referenceSeconds; - DBG_PRINTF("Load saved time:%ld\n",_referenceSeconds); + if(useSaved){ +/* _referenceSeconds=loadTime(); + _referenceSeconds += 300; // add 5 minutes. + _referenceSystemTime = millis(); + _lastSaved=_referenceSeconds; + DBG_PRINTF("Load saved time:%ld\n",_referenceSeconds); +*/ + }else{ + _referenceSystemTime = millis(); + _referenceSeconds = 0; + } } void TimeKeeperClass::begin(char* server1,char* server2,char* server3) diff --git a/BrewManiacEx/TimeKeeper.h b/BrewManiacEx/TimeKeeper.h index 738535f..ee3e40a 100644 --- a/BrewManiacEx/TimeKeeper.h +++ b/BrewManiacEx/TimeKeeper.h @@ -6,7 +6,7 @@ class TimeKeeperClass public: TimeKeeperClass(void):_referenceSeconds(0),_referenceSystemTime(0){} void begin(char* server1,char* server2,char* server3); - void begin(void); + void begin(bool useSaved=false); time_t getTimeSeconds(void); // get Epoch time const char *getDateTimeStr(void); diff --git a/BrewManiacEx/WiFiSetup.cpp b/BrewManiacEx/WiFiSetup.cpp index 201a8d3..628ee28 100644 --- a/BrewManiacEx/WiFiSetup.cpp +++ b/BrewManiacEx/WiFiSetup.cpp @@ -1,5 +1,4 @@ #include //https://github.com/esp8266/Arduino - //needed for library #include #include @@ -7,40 +6,142 @@ #include "config.h" #include "WiFiSetup.h" +WiFiSetupClass WiFiSetup; +#if SerialDebug == true +#define DebugOut(a) DebugPort.print(a) +#define DBG_PRINTF(...) DebugPort.printf(__VA_ARGS__) +#else +#define DebugOut(a) +#define DBG_PRINTF(...) +#endif -void WiFiSetup::begin(char const *ssid,const char *passwd) +void WiFiSetupClass::setupNetwork(void) { + WiFi.mode(WIFI_AP_STA); + if (_apPassword != NULL) { + WiFi.softAP(_apName, _apPassword); + } else { + WiFi.softAP(_apName); + } +} + +void WiFiSetupClass::enterApMode(void) +{ + + WiFi.disconnect(); + DBG_PRINTF("AP Mode\n"); + _apMode=true; + + dnsServer.reset(new DNSServer()); + dnsServer->setErrorReplyCode(DNSReplyCode::NoError); + dnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); + delay(500); +} +static bool _apEntered=false; +void WiFiSetupClass::startWiFiManager(bool portal) +{ WiFiManager wifiManager; #if SerialDebug != true wifiManager.setDebugOutput(false); #endif //reset saved settings //wifiManager.resetSettings(); - + if(_apTimeout !=0) + wifiManager.setTimeout(_apTimeout); //set custom ip for portal //and goes into a blocking loop awaiting configuration - wifiManager.autoConnect(ssid,passwd); - //or use this for auto generated name ESP + ChipID + wifiManager.setAPCallback([](WiFiManager*){ _apEntered=true;}); + + bool connected; + if(portal){ + connected=wifiManager.startConfigPortal(_apName,_apPassword); + }else{ + connected=wifiManager.autoConnect(_apName,_apPassword); + } + if(!connected) // not connected. setup AP mode + enterApMode(); + else{ + // onced it enter AP mode, tcp_bind() lf lwip will return failure. + // thereore, restart the system. + if(_apEntered) ESP.restart(); + } } -void WiFiSetup::beginAP(char const *ssid,const char *passwd) +void WiFiSetupClass::begin(char const *ssid,const char *passwd) { + _apName=ssid; + _apPassword=passwd; + startWiFiManager(false); +} - WiFiManager wifiManager; +void WiFiSetupClass::beginAP(char const *ssid,const char *passwd) +{ + _apName=ssid; + _apPassword=passwd; + startWiFiManager(true); +} - #if SerialDebug != true - wifiManager.setDebugOutput(false); - #endif - //reset saved settings - //wifiManager.resetSettings(); - - //set custom ip for portal - //and goes into a blocking loop awaiting configuration - wifiManager.startConfigPortal(ssid,passwd); - //or use this for auto generated name ESP + ChipID +bool WiFiSetupClass::stayConnected(void) +{ + if(_apMode){ + dnsServer->processNextRequest(); + }else{ + if(WiFi.status() != WL_CONNECTED) + { + if(_wifiState==WiFiStateConnected) + { + _time=millis(); + DBG_PRINTF("Lost Network. auto reconnect %d\n",_autoReconnect); + if(_autoReconnect){ + _wifiState = WiFiStateWaitToConnect; + }else{ + _wifiState = WiFiStateDisconnected; + } + return true; + } + else if(_wifiState==WiFiStateWaitToConnect) + { + if((millis() - _time) > TIME_WAIT_TO_CONNECT) + { + WiFi.begin(); + _time=millis(); + _wifiState = WiFiStateConnecting; + DBG_PRINTF("Reconnect...\n"); + } + } + else if(_wifiState==WiFiStateConnecting) + { + if((millis() - _time) > TIME_RECONNECT_TIMEOUT){ + _time=millis(); + _wifiState = WiFiStateWaitToConnect; + _reconnect++; + DBG_PRINTF("Reconnect fail\n"); + + if(_switchToAp){ + if(_maxReconnect !=0 && _reconnect>=_maxReconnect){ + DBG_PRINTF("Fail to reconnect. Setup AP mode.\n"); + + setupNetwork(); + enterApMode(); + return true; + } + } + } + } + // WiFiStateDisconnected else do nothing. + } + else + { + byte oldState=_wifiState; + _wifiState=WiFiStateConnected; + _reconnect=0; + if(oldState != _wifiState) return true; + } + } + return false; } @@ -48,3 +149,55 @@ void WiFiSetup::beginAP(char const *ssid,const char *passwd) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BrewManiacEx/WiFiSetup.h b/BrewManiacEx/WiFiSetup.h index e8be015..b5d4f68 100644 --- a/BrewManiacEx/WiFiSetup.h +++ b/BrewManiacEx/WiFiSetup.h @@ -1,14 +1,55 @@ #ifndef WiFiSetup_H #define WiFiSetup_H -class WiFiSetup +#include + +#define WiFiStateConnected 0 +#define WiFiStateWaitToConnect 1 +#define WiFiStateConnecting 2 +#define WiFiStateDisconnected 3 + +#define TIME_WAIT_TO_CONNECT 20000 +#define TIME_RECONNECT_TIMEOUT 20000 +#define DNS_PORT 53 + +class WiFiSetupClass { public: - static void begin(void){WiFiSetup::begin("BrewManiac");} - static void begin(char const *ssid,const char *passwd=NULL); - static void beginAP(char const *ssid,const char *passwd=NULL); + WiFiSetupClass():_apTimeout(0),_switchToAp(false),_autoReconnect(true){_wifiState=WiFiStateConnected;_apMode=false; _maxReconnect=0;} + + void begin(void){begin("BrewPiLess");} + void begin(char const *ssid,const char *passwd=NULL); + void beginAP(char const *ssid,const char *passwd=NULL); + + bool stayConnected(void); + bool isApMode(void) {return _apMode;} + + void setTimeout(unsigned long timeout){ _apTimeout=timeout;} + void setMaxReconnect(unsigned int reconnect){_maxReconnect=reconnect;} + void setSwitchToApWhenDisconnected(bool toAp){ _switchToAp= toAp; } + void setAutoReconnect(bool reconnect){ _autoReconnect=reconnect; } +private: + unsigned int _maxReconnect; + unsigned int _reconnect; + + unsigned long _time; + byte _wifiState; + bool _apMode; + bool _switchToAp; + bool _autoReconnect; + + std::unique_ptr dnsServer; + + const char *_apName; + const char *_apPassword; + unsigned long _apTimeout; + + void setupNetwork(void); + void enterApMode(void); + void startWiFiManager(bool portal); }; +extern WiFiSetupClass WiFiSetup; #endif diff --git a/BrewManiacEx/config.h b/BrewManiacEx/config.h index cc0dab6..256f886 100644 --- a/BrewManiacEx/config.h +++ b/BrewManiacEx/config.h @@ -110,7 +110,7 @@ /* Don't touch them if you don't know what they are. */ /**************************************************************************************/ -#define BME8266_VERSION "0.1.1" +#define BME8266_VERSION "0.1.2" #define FIRMWARE_UPDATE_URL "http://brew.vito.tw/bmeupdate.php?info" #define JS_UPDATE_URL "http://brew.vito.tw/bmejsupdate.php?v=" diff --git a/BrewManiacEx/data/bm.js b/BrewManiacEx/data/bm.js index 5bf2eac..84fd635 100644 --- a/BrewManiacEx/data/bm.js +++ b/BrewManiacEx/data/bm.js @@ -1 +1 @@ -function setCookie(a,b,c){var d=new Date();d.setTime(d.getTime()+(c*24*60*60*1000));var e="expires="+d.toUTCString();document.cookie=a+"="+b+"; "+e}function getCookie(a){var b=a+"=";var d=document.cookie.split(';');for(var i=0;i9)?c:"0"+c)+':'+((b>9)?b:"0"+b))};BrewChart.prototype.incTime=function(){this.config.data.labels.push(this.ftime(this.ctime));this.ctime+=this.interval};BrewChart.prototype.addData=function(i,a){if(!this.celius&&!isNaN(a))a=C2F(a);this.config.data.datasets[i].data.push(a)};BrewChart.prototype.chart=function(){var t=this;var a=document.getElementById(t.cid).getContext("2d");var b={label:t.spLabel,data:[],fill:false,borderColor:BrewChart.spcolor,backgroundColor:BrewChart.spcolor,pointBorderColor:BrewChart.spcolor,pointBackgroundColor:BrewChart.spcolor,borderDash:[8,4],pointBorderWidth:1,pointRadius:1,pointStyle:'dash',lineTension:0,cubicInterpolationMode:'linear'};t.config.data.datasets.push(b);for(i=0;i0&&a[a.length-1].value==b){if(a[a.length-1].dt=='e'){a.pop()}}var c=$.extend(true,{},BrewChart.stageAnno);if(s<=10){c.label.text=STR.stageName[s]}else if(s==100){c.label.text=STR.ManualMode}else if(s==103){c.label.text=STR.PIDAutoTune}else{return}c.value=b;this.config.options.annotation.annotations.push(c)};BrewChart.prototype.addEvent=function(s){if(s==1||s==10){var a=this.config.options.annotation.annotations;var b=this.ftime(this.ctime);if(a.length>0&&a[a.length-1].value==b){return}var c=$.extend(true,{},BrewChart.eventAnno);c.label.text=STR.event[s];c.value=b;this.config.options.annotation.annotations.push(c)}};BrewChart.prototype.addResume=function(s){this.incTime();for(i=0;i5)return false;return{sensor:s,f:a[1]&0x10}};BrewChart.prototype.process=function(a){var t=this;for(var i=0;i12000){t.addData(t.lidx+1,NaN)}else{t.addData(t.lidx+1,f/100)}if(++t.lidx>=t.numLine)t.lidx=0}}t.myLine.update()};var EEPROM={"s_kp":{max:100,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_ki":{max:155,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_kd":{max:100,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_sample_time":{max:3500,min:1500,inc:250,decode:function(v){return v*250},encode:function(v){return Math.round(v/250)}},"s_window":{max:7500,min:4000,inc:250,decode:function(v){return v*250},encode:function(v){return Math.round(v/250)}},"s_pwm":{max:100,min:0,inc:1},"s_cal":{max:5,min:-5,inc:0.1,decode:function(v){return(v-50)/10},encode:function(v){return v*10+50}},"s_pidstart":{max:3.5,min:1.0,inc:0.1,decode:function(v){return(v)/10},encode:function(v){return v*10}},"s_unit":{max:1,min:0,inc:1,labels:["°C","°F"],},"s_nodelay":{max:1,min:0,inc:1,labels:["No","Yes"]},"s_boil":{max:120,min:80,inc:1},"s_pumpcycle":{max:15,min:5,inc:1},"s_pumprest":{max:5,min:0,inc:1},"s_pumppremash":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpmash":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpmashout":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpboil":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpstop":{max:120,min:80,inc:1},"s_pipe":{max:1,min:0,inc:1,labels:["Passive","Active"]},"s_skipadd":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_skipremove":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_skipiodine":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_iodine":{max:120,min:0,inc:1},"s_whirlpool":{max:2,min:0,labels:["Off","Cold","Hot"]},"s_spenable":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_sptempctrl":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_spsensor":{max:5,min:0,inc:1},"s_sptemp":{max:80,min:75,inc:1},"s_spdiff":{max:2.0,min:0.5,inc:0.1,decode:function(v){return(v)/10},encode:function(v){return v*10}}};var BMSetting={values:{},editing:{},enabled:false,celius:true,singlesensor:true,disableSetting:function(a){$("#settings-p input").spinner({disabled:a})},disableButton:function(a){$("#settings-p button").button({disabled:a})},setEnabled:function(e){this.enabled=e;if(e){$("#esetting").button({disabled:false})}else{$("#esetting").button({disabled:true})}},display:function(){var t=this;var c=t.celius;$.each(this.values,function(k,v){var p=EEPROM[k];if(p){var a;if(typeof p["labels"]=="undefined"){if(typeof p["decode"]=="undefined")a=v;else a=p.decode(v)}else{a=p["labels"][v]}if(!c){if(k=="s_cal"||k=="s_spdiff")a=a*1.8;else if(k=="s_boil"||k=="s_pumpstop"||k=="s_sptemp")a=C2F(a)}$('#'+k).text(a)}else{if(k=="sensors")t.sensorAddr(v);else if(k=="primary")t.primarySensor(v);else if(k=="auxiliary")t.auxiliarySensor(v)}})},auxiliarySensor:function(l){for(var i=0;ithis.numsensor){for(var i=a;i<=n;i++){var e=b.clone();e.find("td.sensor_id").text(i);e.find("td.sensor_addr").attr("id","SA_"+i);e.insertAfter(b);b=e;var f=c.clone();var g="s_cal_"+i;f.find("td.TCAL_T").text(d+" #"+i);f.find("span.TCAL_V").attr("id",g);f.insertAfter(c);EEPROM[g]=EEPROM["s_cal"];c=f}}else{for(var i=n+1;i<=this.numsensor;i++){var h=$("#SA_"+i).closest("tr.sensor_row");h.remove();var j=$("#s_cal_"+i).closest("tr");j.remove()}}this.numsensor=n},setting:function(s){this.values=s;this.display();if($("#esetting").button("option","icons").primary!="ui-icon-pencil"){$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide()}},unitCelius:function(c){if(this.celius!=c){$(".tmp_unit").text((c)?"°C":"°F");this.celius=c}},valuechange:function(s){var n=$(s).attr("name");var v=$(s).spinner("value");var a=$(s).spinner("option","min");var b=$(s).spinner("option","max");if(vb)v=b;$(s).spinner("value",v);if(!this.celius){if(n=="s_cal"||n=="s_spdiff")v=v/1.8;else if(n=="s_boil"||n=="s_pumpstop"||n=="s_sptemp")v=F2C(v)}if(typeof EEPROM[n]["encode"]=="undefined")this.editing[n]=v;else this.editing[n]=EEPROM[n].encode(v)},switchchange:function(n,c){this.editing[n]=c},selectionchange:function(n,v){this.editing[n]=v},editsettings:function(){var f=this.values;var b=this;$.each(EEPROM,function(k,p){var s=$('#'+k).empty();var c=(typeof p["decode"]=="undefined")?f[k]:p.decode(f[k]);if(typeof p["labels"]=="undefined"){var d=p["min"];var e=p["max"];if(!b.celius){if(k=="s_cal"||k=="s_spdiff"){c=c*1.8;d=d*1.8;e=e*1.8}else{if(k=="s_boil"||k=="s_pumpstop"||k=="s_sptemp"){c=C2F(c);d=C2F(d);e=C2F(e)}}}$("").appendTo(s);s.find("input").spinner({min:d,max:e,step:p["inc"],change:function(){b.valuechange(this)}}).attr("name",k)}else if((p["labels"]).length==2){$("").appendTo(s);s.find("input[type=checkbox]").switchButton({on_label:p["labels"][1],off_label:p["labels"][0],name:k,on_callback:function(){b.switchchange(k,(this.options["checked"])?1:0)},off_callback:function(){b.switchchange(k,(this.options["checked"])?1:0)}})}else{var h="";$.each(p["labels"],function(i,a){var b=(c==i)?"checked":"";h=h+""+p["labels"][i]+"
"});$(h).appendTo(s);s.find("input").on("click",function(){b.selectionchange(k,s.find("input:checked").val())})}});if(this.singlesensor)this.editing={};else this.editing={scals:this.values["scals"]}},finishSaving:function(s){if(s){var b=this;$.each(b.editing,function(k,v){b.values[k]=v});b.display();$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide()}else{this.disableSetting(false)}this.disableButton(false)},init:function(a){var b=this;$("#esetting").button({disabled:false,text:false,icons:{primary:"ui-icon-pencil"}}).click(function(){if($("#esetting").button("option","icons").primary=="ui-icon-pencil"){$("#esetting").button("option","icons",{primary:"ui-icon-arrowreturnthick-1-w"});$("#savesetting").show();b.editsettings()}else{$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide();b.display()}});$("#savesetting").button({text:false,icons:{primary:"ui-icon-disk"}}).click(function(){if(!b.enabled){alert("BrewManiac is not in idle state");return}if(Object.keys(b.editing).length==0){$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide();b.display();return}b.disableSetting(true);b.disableButton(true);a.savesetting(b.editing)}).hide()}};var BMRecipe={auto:{},eauto:{},enabled:false,celius:true,disableInput:function(a){$("#automation-p input").spinner({disabled:a})},disableButton:function(a){$("#automation-p button").button({disabled:a})},setEnabled:function(e){this.enabled=e;if(e)$("#editauto").button({disabled:false});else $("#editauto").button({disabled:true})},updateRecipe:function(d){this.auto=d;this.display();if($("#editauto").button("option","icons").primary!="ui-icon-pencil"){this.stopEditRecipe()}},unitCelius:function(a){this.celius=a;if($("#editauto").button("option","icons").primary!="ui-icon-pencil"){this.stopEditRecipe()}if(typeof this.auto.rest_tp!=="undefined")this.display()},newrest:function(i){return $(''+STR.Mash+' '+i+' °'+((this.celius)?'C':'F')+' min')},dis_rest:function(d){var a=$("#s7_tp").closest("tr");$("#s0_tp").closest("tr").nextUntil(a).remove();for(var i=1;i<7;i++){var v=d.rest_tm[i];if(v==0){break}else{var b=this.newrest(i);a.before(b);$('#s'+i+'_tm').text(v);$('#s'+i+'_tp').text(this.TC(d.rest_tp[i]))}}},TC:function(t){return(this.celius)?t:C2F(t)},display:function(){var d=this.auto;$('#s0_tp').text(this.TC(d.rest_tp[0]));$('#s7_tm').text(d.rest_tm[7]);$('#s7_tp').text(this.TC(d.rest_tp[7]));this.dis_rest(this.auto);$("#boiltime").text(d.boil);$("#auto_table tr:gt("+$("#boiltime").closest("tr").index()+")").remove();var t=$("#auto_table");$.each(d.hops,function(i,h){$("Hop#"+(i+1)+""+h+" min").appendTo(t)})},minRT:[20,25,25,25,25,25,25,75],maxRT:[75,76,76,76,76,76,76,80],minRT_F:[68,77,77,77,77,77,77,167],maxRT_F:[167,169,169,169,169,169,176,176],rtmChange:function(s){var i=$(s).attr("name").substring(2);var v=$(s).spinner("value");if(v>140)v=140;var a=(i>5)?1:0;if(vb)v=b;$(s).spinner("value",v);this.eauto.rest_tp[i]=(this.celius)?v:F2C(v)},btChange:function(s){var v=$(s).spinner("value");if(v>140)v=140;if(v<1)v=1;$(s).spinner("value",v);this.eauto.boil=v;this.listhop()},hchange:function(s){var i=$(s).attr("name").substring(1);this.eauto.hops.splice(i,1);var v=$(s).spinner("value");if(v<1)v=1;if(v>this.eauto.boil)v=this.eauto.boil;this.eauto.hops.push(v);this.eauto.hops.sort(function(a,b){return b-a});this.listhop()},dhop:function(s){var i=$(s).attr("name").substring(2);this.eauto.hops.splice(i,1);$(s).closest("tr").remove()},ahop:function(){var v=this.eauto.hops[this.eauto.hops.length-1]-1;if(v<1)v=1;this.eauto.hops.push(v);this.listhop()},listhop:function(){$("#auto_table tr:gt("+$("#boiltime").closest("tr").index()+")").remove();var t=$("#auto_table");var b=this;$.each(b.eauto.hops,function(i,h){var e=$("Hop#"+(i+1)+"min ").appendTo(t);e.find("input").spinner({min:1,max:b.eauto.boil,change:function(){b.hchange(this)}});e.find("button").css("color","red").attr("name","dh"+i).button({text:false,icons:{primary:"ui-icon-trash"}}).click(function(){b.dhop(this)})})},drest:function(s){var b=this;var a=b.eauto.rest_tm;var c=b.eauto.rest_tp;var i=parseInt($(s).attr("name").substring(2));for(var r=i;r<6;r++){var n=r+1;a[r]=a[n];c[r]=c[n]}a[6]=0;c[6]=0;b.dis_rest(this.eauto);for(var i=0;i<7;i++){b.resteditable(i)}},arest:function(){var i;for(i=1;i<7;i++){if(this.eauto.rest_tm[i]==0){this.eauto.rest_tm[i]=10;this.eauto.rest_tp[i]=this.eauto.rest_tp[i-1]+1;var a=this.newrest(i);$("#s7_tp").closest("tr").before(a);this.resteditable(i);break}}},resteditable:function(i){var b=this;if(i!=0){var a=$('#s'+i+'_tm').empty();$("").appendTo(a);var c=1;a.find("input").spinner({min:c,max:140,change:function(){b.rtmChange(this)}}).attr("name",'tm'+i);if(i<7){$('').appendTo(a.closest("td")).css("color","red").attr("name","mr"+i).button({text:false,icons:{primary:"ui-icon-trash"}}).click(function(){b.drest(this)})}}var d=$('#s'+i+'_tp').empty();var v=(this.celius)?b.eauto.rest_tp[i]:C2F(b.eauto.rest_tp[i]);var c=(this.celius)?b.minRT[i]:b.minRT_F[i];var e=(this.celius)?b.maxRT[i]:b.maxRT_F[i];if(ve)v=e;b.eauto.rest_tp[i]=v;$("").appendTo(d);d.find("input").spinner({min:c,max:e,change:function(){b.rtpChange(this)}}).attr("name",'tp'+i)},edit:function(){$("#addhop").show();$("#addrest").show();$("#saveauto").show();var b=this;b.eauto=$.extend(true,{},this.auto);var a=$("").appendTo($('#boiltime').empty()).spinner({min:1,max:140,change:function(){b.btChange(this)}});b.listhop();for(var i=0;i<8;i++){if(i>0&&i<7&&b.eauto.rest_tm[i]==0){i=6;continue}this.resteditable(i)}},stopEditRecipe:function(){$("#editauto").button("option","icons",{primary:"ui-icon-pencil"});$("#saveauto").hide();$("#addhop").hide();$("#addrest").hide()},validate:function(){if(this.eauto.rest_tm[7]==0)return false;var a=this.eauto.boil;if(this.eauto.hops.length>0){var b=this.eauto.hops[0];if(b>a)return false;for(var i=1;i=b)return false;b=v}}return true},finishSaveRecipe:function(a){if(a){this.auto=this.eauto;this.display();this.stopEditRecipe()}else{this.disableInput(false)}this.disableButton(false)},init:function(a){var b=this;$("#editauto").button({disabled:false,text:false,icons:{primary:"ui-icon-pencil"}}).click(function(){if($("#editauto").button("option","icons").primary=="ui-icon-pencil"){b.edit();$("#editauto").button("option","icons",{primary:"ui-icon-arrowreturnthick-1-w"})}else{b.display();b.stopEditRecipe()}});$("#saveauto").button({disabled:false,text:false,icons:{primary:"ui-icon-disk"}}).click(function(){if(!b.enabled){alert("BrewManiac is not in idle state");return}if(b.validate()){b.disableButton(true);b.disableInput(true);a.saveRecipe(b.eauto)}else{alert("Invalid value!")}}).hide();$("#addhop").button({disabled:false,text:false,icons:{primary:"ui-icon-plusthick"}}).click(function(){b.ahop()}).hide();$("#addrest").button({disabled:false,text:false,icons:{primary:"ui-icon-plusthick"}}).click(function(){b.arest()}).hide()}};var BMScreen={ctemp:0,stemp:35,pwm:0,pwmOn:false,screen:"U",bm:null,celius:true,singlesensor:true,numsensor:0,htimer:null,h_animated:0,HC_active:"#FE1E1E",HC_inactive:"#5B0000",HC_pause:"#DE912F",PC_active:"#70FC57",PC_inactive:"#01290C",PC_pause:"#22C6AB",spargesensor:-1,autolist:function(){var a=this.bm.autoAllStages();var t=$("#auto-t").empty();var b=(this.celius)?"°C":"°F";b=""+b+"";var c={addmalt:STR.AddMalt,removemalt:STR.RemoveMalt,boilend:STR.BoilEnd,cooling:STR.Cooling};for(i=0;i"+STR.stageName[s.stage]+""+d+b+""+((s.stage)?(s.time+STR.min):"-")+">").appendTo(t)}else if(s.type=="event"){$(""+c[s.name]+"-->").appendTo(t)}else if(s.type=="boil"){$(""+STR.Boil+"-"+s.time+STR.min+">").appendTo(t)}else if(s.type=="hop"){$(""+STR.HopN+(s.index+1)+"-"+s.time+STR.min+">").appendTo(t)}}},inStage:function(i){$("#auto-t tr:eq("+i+")").removeClass("run").addClass("running");$("#auto-t tr:lt("+i+")").removeClass("running").addClass("run");$("#auto-t tr:gt("+i+")").removeClass("running").removeClass("run")},unitCelius:function(a){this.celius=a;if(this.singlesensor){this.currenttemp(this.ctemp)}else{this.alltemps(this.ctemps)}if(this.isRunning(this.screen))this.settingtemp(this.stemp)},isRunning:function(s){return(s=="A"||s=="M")},setScreen:function(s,a){var t=this;if(s=="S")$("#title").text(STR.Setup);else if(s=="I"){$("#title").text(STR.Idle);if(!t.singlesensor)t.setPrimarySensor(t.primary[0])}else if(s=="M"){$("#title").text(STR.ManualMode);if(!t.singlesensor)t.setPrimarySensor(t.primary[1])}else if(s=="A"){if(a==11)$("#title").text(STR.DelayStart);else $("#title").text(STR.Automation);if(!t.singlesensor){if(a==0)t.setPrimarySensor(t.primary[2]);else if(a>=1&&a<=7)t.setPrimarySensor(t.primary[3]);else if(a==8)t.setPrimarySensor(t.primary[4]);else if(a>8)t.setPrimarySensor(t.primary[5])}}else if(s=="U")$("#title").text(STR.Unknown);else if(s=="T")$("#title").text(STR.PIDAutoTune);if(s!="A"&&s!="M"&&s!="T"){t.clear_settingtemp();t.deacTime();BChart.stop()}else{t.settingtemp(t.stemp);t.displaytime(0);if(BChart.running){BChart.pull()}else{BChart.start();BChart.setCelius(this.celius)}}if(s=="A"){if(t.screen!="A"){t.autolist();$("#auto-p").css('display','inline-block')}}else{$("#auto-p").css('display','none')}t.screen=s},setLed:function(a,b){$(a).css("background",b)},heatStatus:function(s){if(s==0)this.setLed("#heatled",this.HC_inactive);else if(s==1)this.setLed("#heatled",this.HC_active);else this.setLed("#heatled",this.HC_pause)},pumpStatus:function(s){if(s==0)this.setLed("#pumpled",this.PC_inactive);else if(s==1)this.setLed("#pumpled",this.PC_active);else this.setLed("#pumpled",this.PC_pause)},currenttemp:function(t){this.ctemp=t;if(t>300||t<-1){$("#currenttemp").text('--')}else{var v=(this.celius)?t:C2F(t);$("#currenttemp").text(v.toFixed(2))}},setPrimarySensor:function(n){var a=n+1;for(var i=1;i<=this.numsensor;i++){if(i==a)$("#t_id_"+i).text("*#"+i+":");else{if(i!=(this.spargesensor+1))$("#t_id_"+i).text("#"+i+":")}}},multisensor:function(n,a,b){var t=this;t.primary=a;t.aux=b;if(n==0)return;t.singlesensor=false;if(t.numsensor!=n){if(t.numsensor300||t<-1){$("#currentTemp_"+(i+1)).text('--')}else{var v=(this.celius)?t:C2F(t);$("#currentTemp_"+(i+1)).text(v.toFixed(2))}}},clear_settingtemp:function(){$("#setpoint").css("color","#000033");$("#setpoint").text("0.00")},settingtemp:function(t){this.stemp=t;$("#setpoint").css("color","");var v=(this.celius)?t:C2F(t);$("#setpoint").text(v.toFixed(2))},showPwm:function(s){if(s)$("#pwm").css("color","");else{$("#pwm").css("color","#550000");$("#pwm").text("00")}},pwmValue:function(v){this.pwm=v;$("#pwm").text(v)},setPwmOn:function(o){this.pwmOn=o;this.showPwm(o)},displaytime:function(t){if(isNaN(t))return;var m=Math.floor(t/60);var s=t-m*60;var h=Math.floor(m/60);m=m-h*60;$("#timer").css("color","");$("#timer").text(""+((h>9)?h:("0"+h))+":"+((m>9)?m:("0"+m))+":"+((s>9)?s:("0"+s)))},deacTime:function(){$("#timer").css("color","#000033");$("#timer").text("00:00:00")},clearTime:function(){$("#timer").text("00:00:00")},openDiaTimer:null,initDialog:function(){$("div.dialog").hide();var b=this;$("div.dialog").dialog({autoOpen:false,modal:true,show:{effect:"bounce",duration:1000},hide:{effect:"fade",duration:1000},close:function(){Beep.pause()},buttons:{Ok:function(){$(this).dialog("close");if(b.openDiaTimer)clearTimeout(b.openDiaTimer)}}})},popDialog:function(a,c){$(a).dialog("open");var b=this;if((typeof c=="undefined")||c)b.openDiaTimer=setTimeout(function(){$(a).dialog("close");b.openDiaTimer=null},5000)},soundTimeout:null,sound:function(t){var b=this;if(b.soundTimeout)clearTimeout(b.soundTimeout);Beep.pause();Beep.loop=true;Beep.play();if(t>0)b.soundTimeout=setTimeout(function(){b.soundTimeout=null;Beep.pause()},t*1000)},setInfo:function(t,a){a=(typeof a==="undefined")?1:a;$("#info").text(t);if(a)setTimeout(function(){$("#info").text("")},5000)},brewevent:function(e){if(BChart.running)BChart.pull();if(e<=10){this.sound(2);this.setInfo(STR.event[e]);if(e==5)$("#title").text(STR.Pause);else if(e==6)$("#title").text(STR.Automation)}else if(e==11){this.setInfo(STR.PumpRest,0)}else if(e==12){this.setInfo("",0)}else if(e==99){this.sound(5);this.setInfo(STR.event[11])}},error:function(c){if(c=="disc"){this.sound(0);this.popDialog("#d_ConnectionError",false)}else if(c=="s_disc"){this.sound(0);this.popDialog("#d_SerialError",false)}this.setScreen("U")},toggleButton:function(){if($("#showbtn").button("option","icons").primary=="ui-icon-circle-triangle-s"){$("#showbtn").button("option","icons",{primary:"ui-icon-circle-triangle-n"})}else{$("#showbtn").button("option","icons",{primary:"ui-icon-circle-triangle-s"})}$("#bpannel").toggle("slide",{direction:"up"},500)},btnPressed:false,btnClick:function(k,l){var b=this;if(b.btnPressed)return;b.btnPressed=true;this.bm.sendButton(k,l,function(){b.btnPressed=false})},home:function(){this.btnClick("home",false)},hideButton:function(){var H=$("#btncover").height();var a=true;$("#btncover").on("click",function(){if(a){$("#btncover").animate({height:10},500)}else{$("#btncover").animate({height:H},500)}a=!a})},init:function(b){this.bm=b;this.showPwm(false);this.clear_settingtemp();this.initDialog();var b=this;var d=getCookie("warning");if(d!=1){$("#d_warning").dialog({resizable:false,dialogClass:"no-close",modal:true,buttons:{"Agree":function(){$(this).dialog("close")}}});$('#nshow').change(function(){setCookie("warning",($(this).is(':checked'))?1:0,365)})}else $("#d_warning").hide();this.hideButton();function sb(a){var c=$("#btn-"+a).css("background");$("#btn-"+a).bind("touchstart mousedown",function(e){e.preventDefault();this.dt=Date.now();$(this).css("background","#FF1111");return false}).bind("touchend mouseup",function(e){e.preventDefault();if(typeof this.dt!="undefined"){$(this).css("background",c);if(Date.now()-this.dt>1000)b.btnClick(a,true);else b.btnClick(a,false);return false}}).bind("mouseleave",function(e){if(typeof this.dt!="undefined"){$(this).css("background",c);this.dt=null}}).click(function(){return false})}sb("up");sb("down");sb("start");sb("enter");$("#btn-hint").hide()},btnIndex:-1,buttons:function(a){if(a==this.btnIndex)return;this.btnIndex=a;var b=(typeof ButtonLabels[a]=="undefined")?{u:"",d:"",s:"",e:"",i:""}:ButtonLabels[a];$("#btn-up").text(b.u);$("#btn-down").text(b.d);$("#btn-start").text(b.s);$("#btn-enter").text(b.e);$("#info").text(b.i)}};var BM={setting_url:"settings.php",automation_url:"automation.php",saveauto_url:"saveauto.php",ssavesetting_url:"savesettings.php",button_url:"button.php",status_url:"status.php",runningTime:0,timer:null,settings:{},s_settingS:{},auto:{},s_auto:{},celius:true,state:-1,hopN:0,updatingSetting:false,updatingRecipe:false,stageMap:[],conbroken:true,wdt:null,bc:{up:1,down:2,start:4,enter:8,home:3},sendButton:function(k,l,d){var e=this.bc[k]+((l)?16:0);$.ajax({url:this.button_url+"?code="+e,type:"GET",success:function(){d()},error:function(a,b,c){console.log(c)},})},getsetting:function(){var o=this;$.ajax({url:this.setting_url+"?time="+((new Date()).getTime()/1000),type:"GET",dataType:"json",success:function(a){if(a.code==0){o.proc_settings(a.data)}},error:function(a,b,c){console.log(c)},})},savesetting:function(d){this.s_settings=d;var b=this;this.updatingSetting=true;$.ajax({url:this.ssavesetting_url,type:"POST",data:{data:JSON.stringify(d)},success:function(){if(b.updatingSetting)b.startRecoveryTimer()},error:function(a,c,d){alert("error save setting, server response:"+d);b.finishSettingSave(false)}})},unitSetting:function(u){var c=(u==0);if(c!=this.celius){this.celius=c;BMSetting.unitCelius(c);BMRecipe.unitCelius(c);BMScreen.unitCelius(c)}},proc_settings:function(s){this.settings=s;if("s_unit"in s){this.unitSetting(s["s_unit"])}if("sensors"in s){BMScreen.multisensor(s["sensors"].length,s["primary"],s["auxiliary"]);BMSetting.multisensor(s["sensors"].length)}if(("s_spenable"in s)&&s["s_spenable"]!=0)BMScreen.swh(true,s.s_sptempctrl,s.s_spsensor);else BMScreen.swh(false);BMSetting.setting(s)},getauto:function(){var b=this;$.ajax({url:this.automation_url,type:"GET",dataType:"json",success:function(a){if(a.code==0){b.procRecipe(a.data)}},error:function(a,b,c){console.log(c)},})},procRecipe:function(d){this.auto=d;BMRecipe.updateRecipe(d)},saveRecipe:function(d){this.s_auto=d;var b=this;b.updatingRecipe=true;$.ajax({url:b.saveauto_url,type:"POST",data:{data:JSON.stringify(d)},success:function(){if(b.updatingRecipe)b.startRecoveryTimer()},error:function(a,c,d){b.finishSaveRecipe(false);alert("Error saving automation, server response:"+d)}})},bmstate:function(s){if(this.state==s)return;if(this.state==-1){if(typeof this.auto.boil=="undefined"){this.getsetting();this.getauto()}}if(s==101){if(!(this.updatingSetting||this.updatingRecipe)){BMRecipe.setEnabled(true);BMSetting.setEnabled(true)}}else{BMRecipe.setEnabled(false);BMSetting.setEnabled(false)}if(s>=0&&s<=11){BMScreen.setScreen("A",s);if(s==11)BMScreen.settingtemp(BM.auto.rest_tp[0]);else this.autostage(s)}else{if(s==100){BMScreen.setScreen("M")}else if(s==101){BMScreen.setScreen("I");this.stopRunningTime();BMScreen.clearTime()}else if(s==102){BMScreen.setScreen("S");this.stopRunningTime();BMScreen.clearTime()}else if(s==103){BMScreen.setScreen("T");BMScreen.clearTime()}else if(s<0){BMScreen.setScreen("U");this.stopRunningTime();BMScreen.clearTime()}}this.state=s},stopRunningTime:function(){if(this.timer)clearInterval(this.timer);this.timer=null},refTime:0,countDir:0,calTime:function(){var t=this.runningTime+this.countDir*Math.round((Date.now()-this.refTime)/1000);return(t<0)?0:t},startRunningTime:function(t){b=this;b.runningTime=t;if(isNaN(t))return;b.refTime=Date.now();b.timer=setInterval(function(){BMScreen.displaytime(b.calTime())},1000)},checkRunningTime:function(t){var a=this.calTime();if((a-t)>5||(a-t)<-5){this.stopRunningTime();this.startRunningTime(t)}},finishSaveRecipe:function(a){this.stopRecoveryTimer();this.updatingRecipe=false;BMRecipe.finishSaveRecipe(a)},finishSettingSave:function(a){this.stopRecoveryTimer();this.updatingSetting=false;BMSetting.finishSaving(a)},recoveryTimout:null,stopRecoveryTimer:function(){if(this.recoveryTimout){clearTimeout(this.recoveryTimout);this.recoveryTimout=null}},startRecoveryTimer:function(){var b=this;b.recoveryTimout=setTimeout(function(){b.recoveryTimout=null;alert("Update failed, check connections");if(b.updatingRecipe)b.finishSaveRecipe(false);if(b.updatingSetting)b.finishSettingSave(false)},10000)},init:function(){BMScreen.init(this);BMSetting.init(this);BMRecipe.init(this);this.getsetting();this.getauto();this.setupEvent()},timerControl:function(r,t,c,p){var b=this;b.countDir=(c==0)?-1:1;if(!p){if(b.timer==null){b.startRunningTime(t)}else{b.checkRunningTime(t)}}else{if(b.timer)b.stopRunningTime();if(r&&b.state<=8&&b.state>0){BMScreen.displaytime(t)}else if(b.state<8&&b.state>0){BMScreen.displaytime(b.auto.rest_tm[b.state]*60)}else if(b.state==8){BMScreen.displaytime(BM.auto.boil*60)}else{BMScreen.clearTime()}}},updateData:function(v){if(v=="recipe"){if(this.updatingRecipe){this.auto=this.s_auto;this.finishSaveRecipe(true)}else{this.getauto()}}else if(v=="setting"){var b=this;if(b.updatingSetting){$.each(b.s_settings,function(k,v){b.settings[k]=v;if(k=="s_unit")b.unitSetting(v)});b.finishSettingSave(true)}else{b.getsetting()}}},errorCode:function(a){this.bmstate(-1);BMScreen.error("s_disc")},watchdog:function(){var b=this;b.wdt=setTimeout(function(){location.reload()},20000)},kick_wdt:function(){if(this.wdt)clearTimeout(this.wdt);this.watchdog()},p_msg:function(e){var b=this;var a=JSON.parse(e);var c={pump:function(v){BMScreen.pumpStatus(v)},heat:function(v){BMScreen.heatStatus(v)},spgw:function(v){BMScreen.spargeStatus(v)},temp:function(v){BMScreen.currenttemp(v)},temps:function(v){BMScreen.alltemps(v)},stemp:function(v){BMScreen.settingtemp(v)},event:function(v){b.brewevent(v)},pwm:function(v){BMScreen.pwmValue(v)},pwmon:function(v){BMScreen.setPwmOn(v==1)},update:function(v){b.updateData(v)},code:function(v){b.errorCode(v)},btn:function(v){BMScreen.buttons(v)}};$.each(a,function(k,v){if(typeof(c[k])!="undefined"){c[k](v)}});if(typeof(a["tr"])!="undefined"&&typeof(a["timer"])!="undefined"&&typeof(a["state"])!="undefined"){b.timerControl(a["tr"],a["timer"],a["counting"],a["paused"]);b.bmstate(a["state"]);b.autoProgressBytime(a["tr"],a["state"],a["timer"])}},setupEvent:function(){var b=this;if(typeof EventSource==="undefined"){alert("Incompatible Browser!");return}var a=new EventSource(BM.status_url);a.onerror=function(){b.ssebroken=true;setTimeout(function(){if(b.ssebroken)BMScreen.error("disc")},5000)};a.onmessage=function(e){b.kick_wdt();b.ssebroken=false;b.p_msg(e.data)}},brewevent:function(e){var b=this;if(e==5&&b.timer)b.stopRunningTime();if(e==1){if(b.state>0&&b.state<8)b.startRunningTime(b.auto.rest_tm[b.state]*60);else if(b.state==8)b.startRunningTime(b.auto.boil*60)}b.autoProgressByevent(e);BMScreen.brewevent(e)},log:function(s){var d=new Date();$(""+d.toLocaleTimeString()+""+s+"").appendTo("#log-t")},autoAllStages:function(){var a=[];var b=0;for(i=0;i<8;i++){if(this.auto.rest_tm[i]>0||i==0){a.push({type:"mash",stage:i,temp:BM.auto.rest_tp[i],time:BM.auto.rest_tm[i]});this.stageMap[i]=b++}if(i==0){a.push({type:"event",name:"addmalt"});b++}}a.push({type:"event",name:"removemalt"});b++;a.push({type:"boil",time:BM.auto.boil});this.stageMap[8]=b++;$.each(BM.auto.hops,function(i,h){a.push({type:"hop",index:i,time:h});b++});a.push({type:"event",name:"boilend"});b++;a.push({type:"event",name:"cooling"});this.stageMap[9]=b++;this.hopN=0;return a},autostage:function(s){BMScreen.inStage(this.stageMap[s]);if(s<8){BMScreen.settingtemp(BM.auto.rest_tp[s]);if(s==0)BMScreen.clearTime();else BMScreen.displaytime(BM.auto.rest_tm[s]*60)}else if(s==8){BMScreen.settingtemp(BM.settings.s_boil);BMScreen.displaytime(BM.auto.boil*60)}else if(s==9){BMScreen.settingtemp(20)}},autoProgressByevent:function(e){if(e==2){BMScreen.inStage(1)}else if(e==3){BMScreen.inStage(BM.stageMap[7]+1)}else if(e==10){BMScreen.inStage(BM.stageMap[9])}},autoProgressBytime:function(a,b,c){if(!a||b!=8)return;if(c==0)c=this.auto.boil*60;var i=this.hopN;for(;ithis.auto.hops[i]*60){break}}if(i!=this.hopN){this.hopN=i;BMScreen.inStage(BM.stageMap[8]+i+1)}}};var NetworkConfig={url:"netcfg.php",host:"bm",secured:false,update:function(){var n=this;var u={};var h=$.trim($("#hostname").val());if(h!==n.host)u["host"]=h;var c=$("#protected").is(":checked");if(c!=n.secured)u["secured"]=c?1:0;var d=$.trim($("#newusername").val());if(d!=="")u["nuser"]=d;var e=$.trim($("#newpasswd").val());if(e!=="")u["npass"]=e;u["user"]=$.trim($("#username").val());u["pass"]=$("#password").val();console.log("update:"+JSON.stringify(u));$.ajax({url:n.url,type:"POST",data:{data:JSON.stringify(u)},success:function(){$("#saveok").show()},error:function(a,b,c){$("#savefail").show();console.log("Error saving automation, server response:"+c)}})},getcfg:function(){var n=this;$.ajax({url:n.url,type:"GET",dataType:"json",success:function(a){n.host=a.host;n.secured=(a.secured!=0);n.inputs()},error:function(a,b,c){n.inputs();console.log(c)}})},chkpass:function(){if($("#newpasswd").val()===$("#newpasswd2").val()){$("#passmatch").hide();$("#savecfg").button("option","disabled",false)}else{$("#passmatch").show();$("#savecfg").button("option","disabled",true)}},verify:function(){if($.trim($("#username").val())!==""&&$.trim($("#password").val())!=="")$("#savecfg").button("option","disabled",false);else $("#savecfg").button("option","disabled",true);$("#saveok").hide();$("#savefail").hide()},vchange:function(){$("#saveok").hide();$("#savefail").hide();$("#savecfg").show()},inputs:function(){var n=this;$("#passmatch").hide();$("#hostname").val(n.host).change(function(){n.vchange()});$("#protected").attr("checked",n.secured).change(function(){n.vchange()});$("#newusername").change(function(){n.vchange()});$("#newpasswd").change(function(){n.vchange();n.chkpass()});$("#newpasswd2").change(function(){n.chkpass()});$("#username").change(function(){n.verify()});$("#password").change(function(){n.verify()});$("#savecfg").button({disabled:true}).click(function(){n.update()}).hide();$("#saveok").hide();$("#savefail").hide()},init:function(){this.getcfg()},};var BChart={offset:0,url:'chart.php',reqdata:function(){var t=this;var b='offset='+t.offset;var c=new XMLHttpRequest();c.open('GET',t.url+'?'+b);c.responseType='arraybuffer';c.onload=function(e){var a=new Uint8Array(this.response);if(a.length==0){console.log("zero content");if(t.timer)clearInterval(t.timer);t.timer=null;setTimeout(function(){t.reqdata()},3000);return}t.chart.process(a);t.offset+=a.length;if(t.timer==null)t.settimer()};c.send()},settimer:function(){var t=this;t.timer=setInterval(function(){t.reqdata()},t.chart.interval*1000)},init:function(a){this.chart=new BrewChart(a)},timer:null,pull:function(){},setCelius:function(a){this.chart.setCelius(a)},setYLabel:function(a){this.chart.ylabel(a)},start:function(){if(this.running)return;this.running=true;this.offset=0;this.chart.clear();this.reqdata();$("#tchart").show()},stop:function(){if(!this.running)return;this.running=false;if(this.timer){clearInterval(this.timer);this.timer=null}$("#tchart").hide()}};var Logs={url:"logs.php",dl:"dl",init:function(){var t=this;this.row=$("#loglist").find("tr:nth-of-type(2)");this.row.remove();$("#listfile").button().button("option","icons",{primary:"ui-icon-arrowrefresh-1-e"}).click(function(){t.getlist()});$("#vchart").hide();t.chart=new BrewChart("vchart-canvas")},view:function(b,c){$("#vchart").show();$("#viewlogname").text(b+"@"+c.toLocaleString());var t=this;t.chart.clear();t.chart.setCelius(BM.celius);var d=new XMLHttpRequest();d.open('GET',t.url+"?"+t.dl+"="+b);d.responseType='arraybuffer';d.onload=function(e){var a=new Uint8Array(this.response);if(a.length==0){console.log("zero content");return}t.chart.realtime=true;t.chart.process(a)};d.oerror=function(e){console.log("error")};d.send()},process:function(e){var f=$("#loglist").find("tbody");var g=this.row;var t=this;$.each(e,function(i,a){var b=('000'+a.f).slice(-4);var c=new Date(a.t*1000);var d=g.clone();d.find(".logid").text(b);d.find(".logdate").text(c.toLocaleString());d.find(".dlbutton").button().button("option","icons",{primary:"ui-icon-disk"}).click(function(){window.open(t.url+"?"+t.dl+"="+b)});d.find(".viewbutton").button().button("option","icons",{primary:"ui-icon-circle-zoomout"}).click(function(){t.view(b,c)});f.append(d)})},getlist:function(){var t=this;$.ajax({url:t.url,type:"GET",dataType:"json",success:function(a){$("#loglist tr:gt(0)").remove();t.process(a)},error:function(a,b,c){console.log("Error:"+c)}})}};var BrewMath={plato2sg:function(a){return 1+a/(258.6-((a/258.2)*227.1))},sgTempCorrected:function(a,F,b){return a*((1.00130346-0.000134722124*F+0.00000204052596*F*F-0.00000000232820948*F*F*F)/(1.00130346-0.000134722124*b+0.00000204052596*b*b-0.00000000232820948*b*b*b))},brix2sg:function(a,b){b=(typeof b==="undefined")?1.0:b;var c=a/b;return(c/(258.6-((c/258.2)*227.1)))+1}};var BrewUtils={ciWeightUnit:"WEIGHT_U",ciVolumeUnit:"VOLUME_U",ciTempUnit:"TEMPERATURE_U",ciTC:"HydroCorrected",ciWC:"RefractoWortCorrect",u_vol:'L',u_weight:'M',u_temp:'C',did:null,VolFactor:{L:{L:1,G:0.264172052,Q:1.05668821},G:{L:3.78541178,G:1,Q:4},Q:{L:0.946352946,G:0.25,Q:1}},volume_unit:function(u){var a=(u=='L')?'L':((u=='G')?'gal':'qt');$(this.did).find(".vol_u").text(a);var b=this.VolFactor[this.u_vol][u];this.u_vol=u;setCookie(this.ciVolumeUnit,u,365);$(this.did).find(".volinput").each(function(){var v=$(this).val();if(v){v=(v*b);$(this).val(v.toFixed(2))}})},weight_unit:function(u){var a=(u=='M')?'kg':'lb';$(this.did).find(".weight_u").text(a);var b=(this.u_weight==u)?1:((u=='M')?0.45359237:2.20462262);this.u_weight=u;setCookie(this.ciWeightUnit,u,365);if(b==1)return;$(this.did).find(".weightinput").each(function(){var v=$(this).val();if(v){v=(v*b);$(this).val(v.toFixed(2))}})},temp_unit:function(u){if(this.u_temp==u)return;var a=(u=='C')?'°C':'°F';$(".tmp_u").text(a);this.u_temp=u;setCookie(this.ciTempUnit,u,365);function C2F(c){return c*1.8+32}function F2C(f){return(f-32)/1.8}var b=(u=='C')?F2C:C2F;$(this.did).find(".tempinput").each(function(){var v=$(this).val();if(v){v=b(v);$(this).val(v.toFixed(1))}})},init:function(f){var t=this;t.did=f;var v=getCookie(t.ciVolumeUnit);v=(v)?v:t.u_vol;$(f).find("[name=volume_unit]").val([v]);t.volume_unit(v);var w=getCookie(t.ciWeightUnit);w=(w)?w:t.u_weight;$(f).find("[name=weight_unit]").val([w]);t.weight_unit(w);var T=getCookie(t.ciTempUnit);T=(T)?T:t.u_temp;$(f).find("[name=temp_unit]").val([T]);t.temp_unit(T);var h=getCookie(t.ciWC);if(h)$(f).find(".REFRACTO .wortcorrection").val(h);var i=getCookie(t.ciTC);if(i){var j=i.split(',');var k=j[0];if(j[1]!=t.u_temp){k=(j[1]=='C')?(k*1.8+32):((k-32)/1.8)}$(f).find(".HYDROMETER .correctedTemp").val(k)}$(f).find('input[type="radio"]').change(function(){var a=$(this).attr('name');var b=$(this).val();if($(this).prop('checked')){t[a](b)}});$(f).find('.fwsg').change(function(){var a=$(f).find(".FWSG .grain").val();var b=$(f).find(".FWSG .water").val();if(a&&b){a=(t.u_weight=='M')?a:(a*0.45359237);b=t.VolFactor[t.u_vol].L*b;var c=(a*0.8)/(a*0.8+b);var d=BrewMath.plato2sg(c*100).toFixed(3);$(f).find(".FWSG .result").text(d)}});$(f).find('.hydroinput').change(function(){var a=$(f).find(".HYDROMETER .sgfraction").val();var b=$(f).find(".HYDROMETER .sgtemp").val();var c=$(f).find(".HYDROMETER .correctedTemp").val();if(c)setCookie(t.ciTC,c+","+t.u_temp,365);if(a&&b&&c){var F=(t.u_temp=='C')?(b*1.8+32):b;var d=(t.u_temp=='C')?(c*1.8+32):c;var e=BrewMath.sgTempCorrected(a,F,d);$(f).find(".HYDROMETER .result").text(e.toFixed(3));window.latestSG=e}});$(f).find('.brixinput').change(function(){var a=$(f).find(".REFRACTO .brixreading").val();var b=$(f).find(".REFRACTO .wortcorrection").val();if(b)setCookie(t.ciWC,b,365);if(a){b=(b)?b:1;var c=BrewMath.brix2sg(a,b);$(f).find(".REFRACTO .result").text(c.toFixed(3));window.latestSG=c}});$(f).find('.boiloffinput').change(function(){var a=$(f).find('.BOILOFF .sg').val();var b=$(f).find('.BOILOFF .vol').val();var c=$(f).find('.BOILOFF .newsg').val();var d=$(f).find('.BOILOFF .newvol').val();if(a&&b&&c){var v=(a-1)*b/(c-1);$(f).find(".BOILOFF .resultvol").text(v.toFixed(2))}if(a&&b&&d){var g=(a-1)*b/d+1;$(f).find(".BOILOFF .resultsg").text(g.toFixed(3))}})}}; \ No newline at end of file +function setCookie(a,b,c){var d=new Date();d.setTime(d.getTime()+(c*24*60*60*1000));var e="expires="+d.toUTCString();document.cookie=a+"="+b+"; "+e}function getCookie(a){var b=a+"=";var d=document.cookie.split(';');for(var i=0;i9)?c:"0"+c)+':'+((b>9)?b:"0"+b))};BrewChart.prototype.incTime=function(){this.config.data.labels.push(this.ftime(this.ctime));this.ctime+=this.interval};BrewChart.prototype.addData=function(i,a){if(!this.celius&&!isNaN(a))a=C2F(a);this.config.data.datasets[i].data.push(a)};BrewChart.prototype.chart=function(){var t=this;var a=document.getElementById(t.cid).getContext("2d");var b={label:t.spLabel,data:[],fill:false,borderColor:BrewChart.spcolor,backgroundColor:BrewChart.spcolor,pointBorderColor:BrewChart.spcolor,pointBackgroundColor:BrewChart.spcolor,borderDash:[8,4],pointBorderWidth:1,pointRadius:1,pointStyle:'dash',lineTension:0,cubicInterpolationMode:'linear'};t.config.data.datasets.push(b);for(i=0;i0&&a[a.length-1].value==b){if(a[a.length-1].dt=='e'){a.pop()}}var c=$.extend(true,{},BrewChart.stageAnno);if(s<=10){c.label.text=STR.stageName[s]}else if(s==100){c.label.text=STR.ManualMode}else if(s==103){c.label.text=STR.PIDAutoTune}else{return}c.value=b;this.config.options.annotation.annotations.push(c)};BrewChart.prototype.addEvent=function(s){if(s==1||s==10){var a=this.config.options.annotation.annotations;var b=this.ftime(this.ctime);if(a.length>0&&a[a.length-1].value==b){return}var c=$.extend(true,{},BrewChart.eventAnno);c.label.text=STR.event[s];c.value=b;this.config.options.annotation.annotations.push(c)}};BrewChart.prototype.addResume=function(s){this.incTime();for(i=0;i5)return false;return{sensor:s,f:a[1]&0x10}};BrewChart.prototype.process=function(a){var t=this;for(var i=0;i12000){t.addData(t.lidx+1,NaN)}else{t.addData(t.lidx+1,f/100)}if(++t.lidx>=t.numLine)t.lidx=0}}t.myLine.update()};var EEPROM={"s_kp":{max:100,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_ki":{max:155,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_kd":{max:100,min:-100,inc:1,decode:function(v){return v-100},encode:function(v){return v+100}},"s_sample_time":{max:3500,min:1500,inc:250,decode:function(v){return v*250},encode:function(v){return Math.round(v/250)}},"s_window":{max:7500,min:4000,inc:250,decode:function(v){return v*250},encode:function(v){return Math.round(v/250)}},"s_pwm":{max:100,min:0,inc:1},"s_cal":{max:5,min:-5,inc:0.1,decode:function(v){return(v-50)/10},encode:function(v){return v*10+50}},"s_pidstart":{max:3.5,min:1.0,inc:0.1,decode:function(v){return(v)/10},encode:function(v){return v*10}},"s_unit":{max:1,min:0,inc:1,labels:["°C","°F"],},"s_nodelay":{max:1,min:0,inc:1,labels:["No","Yes"]},"s_boil":{max:120,min:80,inc:1},"s_pumpcycle":{max:15,min:5,inc:1},"s_pumprest":{max:5,min:0,inc:1},"s_pumppremash":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpmash":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpmashout":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpboil":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_pumpstop":{max:120,min:80,inc:1},"s_pipe":{max:1,min:0,inc:1,labels:["Passive","Active"]},"s_skipadd":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_skipremove":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_skipiodine":{max:1,min:0,inc:1,labels:["NO","YES"]},"s_iodine":{max:120,min:0,inc:1},"s_whirlpool":{max:2,min:0,labels:["Off","Cold","Hot"]},"s_spenable":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_sptempctrl":{max:1,min:0,inc:1,labels:["Off","ON"]},"s_spsensor":{max:5,min:0,inc:1},"s_sptemp":{max:80,min:75,inc:1},"s_spdiff":{max:2.0,min:0.5,inc:0.1,decode:function(v){return(v)/10},encode:function(v){return v*10}}};var BMSetting={values:{},editing:{},enabled:false,celius:true,singlesensor:true,disableSetting:function(a){$("#settings-p input").spinner({disabled:a})},disableButton:function(a){$("#settings-p button").button({disabled:a})},setEnabled:function(e){this.enabled=e;if(e){$("#esetting").button({disabled:false})}else{$("#esetting").button({disabled:true})}},display:function(){var t=this;var c=t.celius;$.each(this.values,function(k,v){var p=EEPROM[k];if(p){var a;if(typeof p["labels"]=="undefined"){if(typeof p["decode"]=="undefined")a=v;else a=p.decode(v)}else{a=p["labels"][v]}if(!c){if(k=="s_cal"||k=="s_spdiff")a=a*1.8;else if(k=="s_boil"||k=="s_pumpstop"||k=="s_sptemp")a=C2F(a)}$('#'+k).text(a)}else{if(k=="sensors")t.sensorAddr(v);else if(k=="primary")t.primarySensor(v);else if(k=="auxiliary")t.auxiliarySensor(v)}})},auxiliarySensor:function(l){for(var i=0;ithis.numsensor){for(var i=a;i<=n;i++){var e=b.clone();e.find("td.sensor_id").text(i);e.find("td.sensor_addr").attr("id","SA_"+i);e.insertAfter(b);b=e;var f=c.clone();var g="s_cal_"+i;f.find("td.TCAL_T").text(d+" #"+i);f.find("span.TCAL_V").attr("id",g);f.insertAfter(c);EEPROM[g]=EEPROM["s_cal"];c=f}}else{for(var i=n+1;i<=this.numsensor;i++){var h=$("#SA_"+i).closest("tr.sensor_row");h.remove();var j=$("#s_cal_"+i).closest("tr");j.remove()}}this.numsensor=n},setting:function(s){this.values=s;this.display();if($("#esetting").button("option","icons").primary!="ui-icon-pencil"){$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide()}},unitCelius:function(c){if(this.celius!=c){$(".tmp_unit").text((c)?"°C":"°F");this.celius=c}},valuechange:function(s){var n=$(s).attr("name");var v=$(s).spinner("value");var a=$(s).spinner("option","min");var b=$(s).spinner("option","max");if(vb)v=b;$(s).spinner("value",v);if(!this.celius){if(n=="s_cal"||n=="s_spdiff")v=v/1.8;else if(n=="s_boil"||n=="s_pumpstop"||n=="s_sptemp")v=F2C(v)}if(typeof EEPROM[n]["encode"]=="undefined")this.editing[n]=v;else this.editing[n]=EEPROM[n].encode(v)},switchchange:function(n,c){this.editing[n]=c},selectionchange:function(n,v){this.editing[n]=v},editsettings:function(){var f=this.values;var b=this;$.each(EEPROM,function(k,p){var s=$('#'+k).empty();var c=(typeof p["decode"]=="undefined")?f[k]:p.decode(f[k]);if(typeof p["labels"]=="undefined"){var d=p["min"];var e=p["max"];if(!b.celius){if(k=="s_cal"||k=="s_spdiff"){c=c*1.8;d=d*1.8;e=e*1.8}else{if(k=="s_boil"||k=="s_pumpstop"||k=="s_sptemp"){c=C2F(c);d=C2F(d);e=C2F(e)}}}$("").appendTo(s);s.find("input").spinner({min:d,max:e,step:p["inc"],change:function(){b.valuechange(this)}}).attr("name",k)}else if((p["labels"]).length==2){$("").appendTo(s);s.find("input[type=checkbox]").switchButton({on_label:p["labels"][1],off_label:p["labels"][0],name:k,on_callback:function(){b.switchchange(k,(this.options["checked"])?1:0)},off_callback:function(){b.switchchange(k,(this.options["checked"])?1:0)}})}else{var h="";$.each(p["labels"],function(i,a){var b=(c==i)?"checked":"";h=h+""+p["labels"][i]+"
"});$(h).appendTo(s);s.find("input").on("click",function(){b.selectionchange(k,s.find("input:checked").val())})}});if(this.singlesensor)this.editing={};else this.editing={scals:this.values["scals"]}},finishSaving:function(s){if(s){var b=this;$.each(b.editing,function(k,v){b.values[k]=v});b.display();$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide()}else{this.disableSetting(false)}this.disableButton(false)},init:function(a){var b=this;$("#esetting").button({disabled:false,text:false,icons:{primary:"ui-icon-pencil"}}).click(function(){if($("#esetting").button("option","icons").primary=="ui-icon-pencil"){$("#esetting").button("option","icons",{primary:"ui-icon-arrowreturnthick-1-w"});$("#savesetting").show();b.editsettings()}else{$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide();b.display()}});$("#savesetting").button({text:false,icons:{primary:"ui-icon-disk"}}).click(function(){if(!b.enabled){alert("BrewManiac is not in idle state");return}if(Object.keys(b.editing).length==0){$("#esetting").button("option","icons",{primary:"ui-icon-pencil"});$("#savesetting").hide();b.display();return}b.disableSetting(true);b.disableButton(true);a.savesetting(b.editing)}).hide()}};var BMRecipe={auto:{},eauto:{},enabled:false,celius:true,disableInput:function(a){$("#automation-p input").spinner({disabled:a})},disableButton:function(a){$("#automation-p button").button({disabled:a})},setEnabled:function(e){this.enabled=e;if(e)$("#editauto").button({disabled:false});else $("#editauto").button({disabled:true})},updateRecipe:function(d){this.auto=d;this.display();if($("#editauto").button("option","icons").primary!="ui-icon-pencil"){this.stopEditRecipe()}},unitCelius:function(a){this.celius=a;if($("#editauto").button("option","icons").primary!="ui-icon-pencil"){this.stopEditRecipe()}if(typeof this.auto.rest_tp!=="undefined")this.display()},newrest:function(i){return $(''+STR.Mash+' '+i+' °'+((this.celius)?'C':'F')+' min')},dis_rest:function(d){var a=$("#s7_tp").closest("tr");$("#s0_tp").closest("tr").nextUntil(a).remove();for(var i=1;i<7;i++){var v=d.rest_tm[i];if(v==0){break}else{var b=this.newrest(i);a.before(b);$('#s'+i+'_tm').text(v);$('#s'+i+'_tp').text(this.TC(d.rest_tp[i]))}}},TC:function(t){return(this.celius)?t:C2F(t)},display:function(){var d=this.auto;$('#s0_tp').text(this.TC(d.rest_tp[0]));$('#s7_tm').text(d.rest_tm[7]);$('#s7_tp').text(this.TC(d.rest_tp[7]));this.dis_rest(this.auto);$("#boiltime").text(d.boil);$("#auto_table tr:gt("+$("#boiltime").closest("tr").index()+")").remove();var t=$("#auto_table");$.each(d.hops,function(i,h){$("Hop#"+(i+1)+""+h+" min").appendTo(t)})},minRT:[20,25,25,25,25,25,25,75],maxRT:[75,76,76,76,76,76,76,80],minRT_F:[68,77,77,77,77,77,77,167],maxRT_F:[167,169,169,169,169,169,176,176],rtmChange:function(s){var i=$(s).attr("name").substring(2);var v=$(s).spinner("value");if(v>140)v=140;var a=(i>5)?1:0;if(vb)v=b;$(s).spinner("value",v);this.eauto.rest_tp[i]=(this.celius)?v:F2C(v)},btChange:function(s){var v=$(s).spinner("value");if(v>140)v=140;if(v<1)v=1;$(s).spinner("value",v);this.eauto.boil=v;this.listhop()},hchange:function(s){var i=$(s).attr("name").substring(1);this.eauto.hops.splice(i,1);var v=$(s).spinner("value");if(v<1)v=1;if(v>this.eauto.boil)v=this.eauto.boil;this.eauto.hops.push(v);this.eauto.hops.sort(function(a,b){return b-a});this.listhop()},dhop:function(s){var i=$(s).attr("name").substring(2);this.eauto.hops.splice(i,1);$(s).closest("tr").remove()},ahop:function(){var v=this.eauto.hops[this.eauto.hops.length-1]-1;if(v<1)v=1;this.eauto.hops.push(v);this.listhop()},listhop:function(){$("#auto_table tr:gt("+$("#boiltime").closest("tr").index()+")").remove();var t=$("#auto_table");var b=this;$.each(b.eauto.hops,function(i,h){var e=$("Hop#"+(i+1)+"min ").appendTo(t);e.find("input").spinner({min:1,max:b.eauto.boil,change:function(){b.hchange(this)}});e.find("button").css("color","red").attr("name","dh"+i).button({text:false,icons:{primary:"ui-icon-trash"}}).click(function(){b.dhop(this)})})},drest:function(s){var b=this;var a=b.eauto.rest_tm;var c=b.eauto.rest_tp;var i=parseInt($(s).attr("name").substring(2));for(var r=i;r<6;r++){var n=r+1;a[r]=a[n];c[r]=c[n]}a[6]=0;c[6]=0;b.dis_rest(this.eauto);for(var i=0;i<7;i++){b.resteditable(i)}},arest:function(){var i;for(i=1;i<7;i++){if(this.eauto.rest_tm[i]==0){this.eauto.rest_tm[i]=10;this.eauto.rest_tp[i]=this.eauto.rest_tp[i-1]+1;var a=this.newrest(i);$("#s7_tp").closest("tr").before(a);this.resteditable(i);break}}},resteditable:function(i){var b=this;if(i!=0){var a=$('#s'+i+'_tm').empty();$("").appendTo(a);var c=1;a.find("input").spinner({min:c,max:140,change:function(){b.rtmChange(this)}}).attr("name",'tm'+i);if(i<7){$('').appendTo(a.closest("td")).css("color","red").attr("name","mr"+i).button({text:false,icons:{primary:"ui-icon-trash"}}).click(function(){b.drest(this)})}}var d=$('#s'+i+'_tp').empty();var v=(this.celius)?b.eauto.rest_tp[i]:C2F(b.eauto.rest_tp[i]);var c=(this.celius)?b.minRT[i]:b.minRT_F[i];var e=(this.celius)?b.maxRT[i]:b.maxRT_F[i];if(ve)v=e;b.eauto.rest_tp[i]=v;$("").appendTo(d);d.find("input").spinner({min:c,max:e,change:function(){b.rtpChange(this)}}).attr("name",'tp'+i)},edit:function(){$("#addhop").show();$("#addrest").show();$("#saveauto").show();var b=this;b.eauto=$.extend(true,{},this.auto);var a=$("").appendTo($('#boiltime').empty()).spinner({min:1,max:140,change:function(){b.btChange(this)}});b.listhop();for(var i=0;i<8;i++){if(i>0&&i<7&&b.eauto.rest_tm[i]==0){i=6;continue}this.resteditable(i)}},stopEditRecipe:function(){$("#editauto").button("option","icons",{primary:"ui-icon-pencil"});$("#saveauto").hide();$("#addhop").hide();$("#addrest").hide()},validate:function(){if(this.eauto.rest_tm[7]==0)return false;var a=this.eauto.boil;if(this.eauto.hops.length>0){var b=this.eauto.hops[0];if(b>a)return false;for(var i=1;i=b)return false;b=v}}return true},finishSaveRecipe:function(a){if(a){this.auto=this.eauto;this.display();this.stopEditRecipe()}else{this.disableInput(false)}this.disableButton(false)},init:function(a){var b=this;$("#editauto").button({disabled:false,text:false,icons:{primary:"ui-icon-pencil"}}).click(function(){if($("#editauto").button("option","icons").primary=="ui-icon-pencil"){b.edit();$("#editauto").button("option","icons",{primary:"ui-icon-arrowreturnthick-1-w"})}else{b.display();b.stopEditRecipe()}});$("#saveauto").button({disabled:false,text:false,icons:{primary:"ui-icon-disk"}}).click(function(){if(!b.enabled){alert("BrewManiac is not in idle state");return}if(b.validate()){b.disableButton(true);b.disableInput(true);a.saveRecipe(b.eauto)}else{alert("Invalid value!")}}).hide();$("#addhop").button({disabled:false,text:false,icons:{primary:"ui-icon-plusthick"}}).click(function(){b.ahop()}).hide();$("#addrest").button({disabled:false,text:false,icons:{primary:"ui-icon-plusthick"}}).click(function(){b.arest()}).hide()}};var BMScreen={ctemp:0,stemp:35,pwm:0,pwmOn:false,screen:"U",bm:null,celius:true,singlesensor:true,numsensor:0,htimer:null,h_animated:0,HC_active:"#FE1E1E",HC_inactive:"#5B0000",HC_pause:"#DE912F",PC_active:"#70FC57",PC_inactive:"#01290C",PC_pause:"#22C6AB",spargesensor:-1,autolist:function(){var a=this.bm.autoAllStages();var t=$("#auto-t").empty();var b=(this.celius)?"°C":"°F";b=""+b+"";var c={addmalt:STR.AddMalt,removemalt:STR.RemoveMalt,boilend:STR.BoilEnd,cooling:STR.Cooling};for(i=0;i"+STR.stageName[s.stage]+""+d+b+""+((s.stage)?(s.time+STR.min):"-")+">").appendTo(t)}else if(s.type=="event"){$(""+c[s.name]+"-->").appendTo(t)}else if(s.type=="boil"){$(""+STR.Boil+"-"+s.time+STR.min+">").appendTo(t)}else if(s.type=="hop"){$(""+STR.HopN+(s.index+1)+"-"+s.time+STR.min+">").appendTo(t)}}},inStage:function(i){$("#auto-t tr:eq("+i+")").removeClass("run").addClass("running");$("#auto-t tr:lt("+i+")").removeClass("running").addClass("run");$("#auto-t tr:gt("+i+")").removeClass("running").removeClass("run")},unitCelius:function(a){this.celius=a;if(this.singlesensor){this.currenttemp(this.ctemp)}else{this.alltemps(this.ctemps)}if(this.isRunning(this.screen))this.settingtemp(this.stemp)},isRunning:function(s){return(s=="A"||s=="M")},setScreen:function(s,a){var t=this;if(s=="S")$("#title").text(STR.Setup);else if(s=="I"){$("#title").text(STR.Idle);if(!t.singlesensor)t.setPrimarySensor(t.primary[0])}else if(s=="M"){$("#title").text(STR.ManualMode);if(!t.singlesensor)t.setPrimarySensor(t.primary[1])}else if(s=="A"){if(a==11)$("#title").text(STR.DelayStart);else $("#title").text(STR.Automation);if(!t.singlesensor){if(a==0)t.setPrimarySensor(t.primary[2]);else if(a>=1&&a<=7)t.setPrimarySensor(t.primary[3]);else if(a==8)t.setPrimarySensor(t.primary[4]);else if(a>8)t.setPrimarySensor(t.primary[5])}}else if(s=="U")$("#title").text(STR.Unknown);else if(s=="T")$("#title").text(STR.PIDAutoTune);if(s!="A"&&s!="M"&&s!="T"){t.clear_settingtemp();t.deacTime();BChart.stop()}else{t.settingtemp(t.stemp);t.displaytime(0);if(BChart.running){BChart.pull()}else{BChart.start();BChart.setCelius(this.celius)}}if(s=="A"){if(t.screen!="A"){t.autolist();$("#auto-p").css('display','inline-block')}}else{$("#auto-p").css('display','none')}t.screen=s},setLed:function(a,b){$(a).css("background",b)},heatStatus:function(s){if(s==0)this.setLed("#heatled",this.HC_inactive);else if(s==1)this.setLed("#heatled",this.HC_active);else this.setLed("#heatled",this.HC_pause)},pumpStatus:function(s){if(s==0)this.setLed("#pumpled",this.PC_inactive);else if(s==1)this.setLed("#pumpled",this.PC_active);else this.setLed("#pumpled",this.PC_pause)},currenttemp:function(t){this.ctemp=t;if(t>300||t<-1){$("#currenttemp").text('--')}else{var v=(this.celius)?t:C2F(t);$("#currenttemp").text(v.toFixed(2))}},setPrimarySensor:function(n){var a=n+1;for(var i=1;i<=this.numsensor;i++){if(i==a)$("#t_id_"+i).text("*#"+i+":");else{if(i!=(this.spargesensor+1))$("#t_id_"+i).text("#"+i+":")}}},multisensor:function(n,a,b){var t=this;t.primary=a;t.aux=b;if(n==0)return;t.singlesensor=false;if(t.numsensor!=n){if(t.numsensor300||t<-1){$("#currentTemp_"+(i+1)).text('--')}else{var v=(this.celius)?t:C2F(t);$("#currentTemp_"+(i+1)).text(v.toFixed(2))}}},clear_settingtemp:function(){$("#setpoint").css("color","#000033");$("#setpoint").text("0.00")},settingtemp:function(t){this.stemp=t;$("#setpoint").css("color","");var v=(this.celius)?t:C2F(t);$("#setpoint").text(v.toFixed(2))},showPwm:function(s){if(s)$("#pwm").css("color","");else{$("#pwm").css("color","#550000");$("#pwm").text("00")}},pwmValue:function(v){this.pwm=v;$("#pwm").text(v)},setPwmOn:function(o){this.pwmOn=o;this.showPwm(o)},displaytime:function(t){if(isNaN(t))return;var m=Math.floor(t/60);var s=t-m*60;var h=Math.floor(m/60);m=m-h*60;$("#timer").css("color","");$("#timer").text(""+((h>9)?h:("0"+h))+":"+((m>9)?m:("0"+m))+":"+((s>9)?s:("0"+s)))},deacTime:function(){$("#timer").css("color","#000033");$("#timer").text("00:00:00")},clearTime:function(){$("#timer").text("00:00:00")},openDiaTimer:null,initDialog:function(){$("div.dialog").hide();var b=this;$("div.dialog").dialog({autoOpen:false,modal:true,show:{effect:"bounce",duration:1000},hide:{effect:"fade",duration:1000},close:function(){Beep.pause()},buttons:{Ok:function(){$(this).dialog("close");if(b.openDiaTimer)clearTimeout(b.openDiaTimer)}}})},popDialog:function(a,c){$(a).dialog("open");var b=this;if((typeof c=="undefined")||c)b.openDiaTimer=setTimeout(function(){$(a).dialog("close");b.openDiaTimer=null},5000)},soundTimeout:null,sound:function(t){var b=this;if(b.soundTimeout)clearTimeout(b.soundTimeout);Beep.pause();Beep.loop=true;Beep.play();if(t>0)b.soundTimeout=setTimeout(function(){b.soundTimeout=null;Beep.pause()},t*1000)},setInfo:function(t,a){a=(typeof a==="undefined")?1:a;$("#info").text(t);if(a)setTimeout(function(){$("#info").text("")},5000)},brewevent:function(e){if(BChart.running)BChart.pull();if(e<=10){this.sound(2);this.setInfo(STR.event[e]);if(e==5)$("#title").text(STR.Pause);else if(e==6)$("#title").text(STR.Automation)}else if(e==11){this.setInfo(STR.PumpRest,0)}else if(e==12){this.setInfo("",0)}else if(e==99){this.sound(5);this.setInfo(STR.event[11])}},error:function(c){if(c=="disc"){this.sound(0);this.popDialog("#d_ConnectionError",false)}else if(c=="s_disc"){this.sound(0);this.popDialog("#d_SerialError",false)}this.setScreen("U")},toggleButton:function(){if($("#showbtn").button("option","icons").primary=="ui-icon-circle-triangle-s"){$("#showbtn").button("option","icons",{primary:"ui-icon-circle-triangle-n"})}else{$("#showbtn").button("option","icons",{primary:"ui-icon-circle-triangle-s"})}$("#bpannel").toggle("slide",{direction:"up"},500)},btnPressed:false,btnClick:function(k,l){var b=this;if(b.btnPressed)return;b.btnPressed=true;this.bm.sendButton(k,l,function(){b.btnPressed=false})},home:function(){this.btnClick("home",false)},hideButton:function(){var H=$("#btncover").height();var a=true;$("#btncover").on("click",function(){if(a){$("#btncover").animate({height:10},500)}else{$("#btncover").animate({height:H},500)}a=!a})},init:function(b){this.bm=b;this.showPwm(false);this.clear_settingtemp();this.initDialog();var b=this;var d=getCookie("warning");if(d!=1){$("#d_warning").dialog({resizable:false,dialogClass:"no-close",modal:true,buttons:{"Agree":function(){$(this).dialog("close")}}});$('#nshow').change(function(){setCookie("warning",($(this).is(':checked'))?1:0,365)})}else $("#d_warning").hide();this.hideButton();function sb(a){var c=$("#btn-"+a).css("background");$("#btn-"+a).bind("touchstart mousedown",function(e){e.preventDefault();this.dt=Date.now();$(this).css("background","#FF1111");return false}).bind("touchend mouseup",function(e){e.preventDefault();if(typeof this.dt!="undefined"){$(this).css("background",c);if(Date.now()-this.dt>1000)b.btnClick(a,true);else b.btnClick(a,false);return false}}).bind("mouseleave",function(e){if(typeof this.dt!="undefined"){$(this).css("background",c);this.dt=null}}).click(function(){return false})}sb("up");sb("down");sb("start");sb("enter");$("#btn-hint").hide()},btnIndex:-1,buttons:function(a){if(a==this.btnIndex)return;this.btnIndex=a;var b=(typeof ButtonLabels[a]=="undefined")?{u:"",d:"",s:"",e:"",i:""}:ButtonLabels[a];$("#btn-up").text(b.u);$("#btn-down").text(b.d);$("#btn-start").text(b.s);$("#btn-enter").text(b.e);$("#info").text(b.i)}};var BM={setting_url:"settings.php",automation_url:"automation.php",saveauto_url:"saveauto.php",ssavesetting_url:"savesettings.php",button_url:"button.php",status_url:"status.php",runningTime:0,timer:null,settings:{},s_settingS:{},auto:{},s_auto:{},celius:true,state:-1,hopN:0,updatingSetting:false,updatingRecipe:false,stageMap:[],conbroken:true,wdt:null,bc:{up:1,down:2,start:4,enter:8,home:3},sendButton:function(k,l,d){var e=this.bc[k]+((l)?16:0);$.ajax({url:this.button_url+"?code="+e,type:"GET",success:function(){d()},error:function(a,b,c){console.log(c)},})},getsetting:function(){var o=this;$.ajax({url:this.setting_url+"?time="+((new Date()).getTime()/1000),type:"GET",dataType:"json",success:function(a){if(a.code==0){o.proc_settings(a.data)}},error:function(a,b,c){console.log(c)},})},savesetting:function(d){this.s_settings=d;var b=this;this.updatingSetting=true;$.ajax({url:this.ssavesetting_url,type:"POST",data:{data:JSON.stringify(d)},success:function(){if(b.updatingSetting)b.startRecoveryTimer()},error:function(a,c,d){alert("error save setting, server response:"+d);b.finishSettingSave(false)}})},unitSetting:function(u){var c=(u==0);if(c!=this.celius){this.celius=c;BMSetting.unitCelius(c);BMRecipe.unitCelius(c);BMScreen.unitCelius(c)}},proc_settings:function(s){this.settings=s;if("s_unit"in s){this.unitSetting(s["s_unit"])}if("sensors"in s){BMScreen.multisensor(s["sensors"].length,s["primary"],s["auxiliary"]);BMSetting.multisensor(s["sensors"].length)}if(("s_spenable"in s)&&s["s_spenable"]!=0)BMScreen.swh(true,s.s_sptempctrl,s.s_spsensor);else BMScreen.swh(false);BMSetting.setting(s)},getauto:function(){var b=this;$.ajax({url:this.automation_url,type:"GET",dataType:"json",success:function(a){if(a.code==0){b.procRecipe(a.data)}},error:function(a,b,c){console.log(c)},})},procRecipe:function(d){this.auto=d;BMRecipe.updateRecipe(d)},saveRecipe:function(d){this.s_auto=d;var b=this;b.updatingRecipe=true;$.ajax({url:b.saveauto_url,type:"POST",data:{data:JSON.stringify(d)},success:function(){if(b.updatingRecipe)b.startRecoveryTimer()},error:function(a,c,d){b.finishSaveRecipe(false);alert("Error saving automation, server response:"+d)}})},bmstate:function(s){if(this.state==s)return;if(this.state==-1){if(typeof this.auto.boil=="undefined"){this.getsetting();this.getauto()}}if(s==101){if(!(this.updatingSetting||this.updatingRecipe)){BMRecipe.setEnabled(true);BMSetting.setEnabled(true)}}else{BMRecipe.setEnabled(false);BMSetting.setEnabled(false)}if(s>=0&&s<=11){BMScreen.setScreen("A",s);if(s==11)BMScreen.settingtemp(BM.auto.rest_tp[0]);else this.autostage(s)}else{if(s==100){BMScreen.setScreen("M")}else if(s==101){BMScreen.setScreen("I");this.stopRunningTime();BMScreen.clearTime()}else if(s==102){BMScreen.setScreen("S");this.stopRunningTime();BMScreen.clearTime()}else if(s==103){BMScreen.setScreen("T");BMScreen.clearTime()}else if(s<0){BMScreen.setScreen("U");this.stopRunningTime();BMScreen.clearTime()}}this.state=s},stopRunningTime:function(){if(this.timer)clearInterval(this.timer);this.timer=null},refTime:0,countDir:0,calTime:function(){var t=this.runningTime+this.countDir*Math.round((Date.now()-this.refTime)/1000);return(t<0)?0:t},startRunningTime:function(t){b=this;b.runningTime=t;if(isNaN(t))return;b.refTime=Date.now();b.timer=setInterval(function(){BMScreen.displaytime(b.calTime())},1000)},checkRunningTime:function(t){var a=this.calTime();if((a-t)>5||(a-t)<-5){this.stopRunningTime();this.startRunningTime(t)}},finishSaveRecipe:function(a){this.stopRecoveryTimer();this.updatingRecipe=false;BMRecipe.finishSaveRecipe(a)},finishSettingSave:function(a){this.stopRecoveryTimer();this.updatingSetting=false;BMSetting.finishSaving(a)},recoveryTimout:null,stopRecoveryTimer:function(){if(this.recoveryTimout){clearTimeout(this.recoveryTimout);this.recoveryTimout=null}},startRecoveryTimer:function(){var b=this;b.recoveryTimout=setTimeout(function(){b.recoveryTimout=null;alert("Update failed, check connections");if(b.updatingRecipe)b.finishSaveRecipe(false);if(b.updatingSetting)b.finishSettingSave(false)},10000)},init:function(){BMScreen.init(this);BMSetting.init(this);BMRecipe.init(this);this.getsetting();this.getauto();this.setupEvent()},timerControl:function(r,t,c,p){var b=this;b.countDir=(c==0)?-1:1;if(!p){if(b.timer==null){b.startRunningTime(t)}else{b.checkRunningTime(t)}}else{if(b.timer)b.stopRunningTime();if(r&&b.state<=8&&b.state>0){BMScreen.displaytime(t)}else if(b.state<8&&b.state>0){BMScreen.displaytime(b.auto.rest_tm[b.state]*60)}else if(b.state==8){BMScreen.displaytime(BM.auto.boil*60)}else{BMScreen.clearTime()}}},updateData:function(v){if(v=="recipe"){if(this.updatingRecipe){this.auto=this.s_auto;this.finishSaveRecipe(true)}else{this.getauto()}}else if(v=="setting"){var b=this;if(b.updatingSetting){$.each(b.s_settings,function(k,v){b.settings[k]=v;if(k=="s_unit")b.unitSetting(v)});b.finishSettingSave(true)}else{b.getsetting()}}},errorCode:function(a){this.bmstate(-1);BMScreen.error("s_disc")},watchdog:function(){var b=this;b.wdt=setTimeout(function(){location.reload()},20000)},kick_wdt:function(){if(this.wdt)clearTimeout(this.wdt);this.watchdog()},p_msg:function(e){var b=this;var a=JSON.parse(e);var c={pump:function(v){BMScreen.pumpStatus(v)},heat:function(v){BMScreen.heatStatus(v)},spgw:function(v){BMScreen.spargeStatus(v)},temp:function(v){BMScreen.currenttemp(v)},temps:function(v){BMScreen.alltemps(v)},stemp:function(v){BMScreen.settingtemp(v)},event:function(v){b.brewevent(v)},pwm:function(v){BMScreen.pwmValue(v)},pwmon:function(v){BMScreen.setPwmOn(v==1)},update:function(v){b.updateData(v)},code:function(v){b.errorCode(v)},btn:function(v){BMScreen.buttons(v)}};$.each(a,function(k,v){if(typeof(c[k])!="undefined"){c[k](v)}});if(typeof(a["tr"])!="undefined"&&typeof(a["timer"])!="undefined"&&typeof(a["state"])!="undefined"){b.timerControl(a["tr"],a["timer"],a["counting"],a["paused"]);b.bmstate(a["state"]);b.autoProgressBytime(a["tr"],a["state"],a["timer"])}},setupEvent:function(){var b=this;if(typeof EventSource==="undefined"){alert("Incompatible Browser!");return}var a=new EventSource(BM.status_url);a.onerror=function(){b.ssebroken=true;setTimeout(function(){if(b.ssebroken)BMScreen.error("disc")},5000)};a.onmessage=function(e){b.kick_wdt();b.ssebroken=false;b.p_msg(e.data)}},brewevent:function(e){var b=this;if(e==5&&b.timer)b.stopRunningTime();if(e==1){if(b.state>0&&b.state<8)b.startRunningTime(b.auto.rest_tm[b.state]*60);else if(b.state==8)b.startRunningTime(b.auto.boil*60)}b.autoProgressByevent(e);BMScreen.brewevent(e)},log:function(s){var d=new Date();$(""+d.toLocaleTimeString()+""+s+"").appendTo("#log-t")},autoAllStages:function(){var a=[];var b=0;for(i=0;i<8;i++){if(this.auto.rest_tm[i]>0||i==0){a.push({type:"mash",stage:i,temp:BM.auto.rest_tp[i],time:BM.auto.rest_tm[i]});this.stageMap[i]=b++}if(i==0){a.push({type:"event",name:"addmalt"});b++}}a.push({type:"event",name:"removemalt"});b++;a.push({type:"boil",time:BM.auto.boil});this.stageMap[8]=b++;$.each(BM.auto.hops,function(i,h){a.push({type:"hop",index:i,time:h});b++});a.push({type:"event",name:"boilend"});b++;a.push({type:"event",name:"cooling"});this.stageMap[9]=b++;this.hopN=0;return a},autostage:function(s){BMScreen.inStage(this.stageMap[s]);if(s<8){BMScreen.settingtemp(BM.auto.rest_tp[s]);if(s==0)BMScreen.clearTime();else BMScreen.displaytime(BM.auto.rest_tm[s]*60)}else if(s==8){BMScreen.settingtemp(BM.settings.s_boil);BMScreen.displaytime(BM.auto.boil*60)}else if(s==9){BMScreen.settingtemp(20)}},autoProgressByevent:function(e){if(e==2){BMScreen.inStage(1)}else if(e==3){BMScreen.inStage(BM.stageMap[7]+1)}else if(e==10){BMScreen.inStage(BM.stageMap[9])}},autoProgressBytime:function(a,b,c){if(!a||b!=8)return;if(c==0)c=this.auto.boil*60;var i=this.hopN;for(;ithis.auto.hops[i]*60){break}}if(i!=this.hopN){this.hopN=i;BMScreen.inStage(BM.stageMap[8]+i+1)}}};var NetworkConfig={url:"netcfg.php",host:"bm",secured:false,update:function(){var n=this;var u={};var h=$.trim($("#hostname").val());if(h!==n.host)u["host"]=h;var c=$("#protected").is(":checked");if(c!=n.secured)u["secured"]=c?1:0;var d=$.trim($("#newusername").val());if(d!=="")u["nuser"]=d;var e=$.trim($("#newpasswd").val());if(e!=="")u["npass"]=e;u["user"]=$.trim($("#username").val());u["pass"]=$("#password").val();console.log("update:"+JSON.stringify(u));$.ajax({url:n.url,type:"POST",data:{data:JSON.stringify(u)},success:function(){$("#saveok").show()},error:function(a,b,c){$("#savefail").show();console.log("Error saving automation, server response:"+c)}})},getcfg:function(){var n=this;$.ajax({url:n.url,type:"GET",dataType:"json",success:function(a){n.host=a.host;n.secured=(a.secured!=0);n.inputs()},error:function(a,b,c){n.inputs();console.log(c)}})},discnet:function(){var n=this;var u={};u["user"]=$.trim($("#username").val());u["pass"]=$("#password").val();u["disconnect"]=true;console.log("disconnect wifi:"+JSON.stringify(u));$.ajax({url:n.url,type:"POST",data:{data:JSON.stringify(u)},success:function(){alert("Network disconnect")},error:function(a,b,c){alert("error");console.log("Error saving automation, server response:"+c)}})},chkpass:function(){if($("#newpasswd").val()===$("#newpasswd2").val()){$("#passmatch").hide();$("#savecfg").button("option","disabled",false)}else{$("#passmatch").show();$("#savecfg").button("option","disabled",true)}},verify:function(){if($.trim($("#username").val())!==""&&$.trim($("#password").val())!==""){$("#savecfg").button("option","disabled",false);$("#wifidisc").show()}else{$("#savecfg").button("option","disabled",true);$("#wifidisc").hide()}$("#saveok").hide();$("#savefail").hide()},vchange:function(){$("#saveok").hide();$("#savefail").hide();$("#savecfg").show()},inputs:function(){var n=this;$("#passmatch").hide();$("#hostname").val(n.host).change(function(){n.vchange()});$("#protected").attr("checked",n.secured).change(function(){n.vchange()});$("#newusername").change(function(){n.vchange()});$("#newpasswd").change(function(){n.vchange();n.chkpass()});$("#newpasswd2").change(function(){n.chkpass()});$("#username").change(function(){n.verify()});$("#password").change(function(){n.verify()});$("#savecfg").button({disabled:true}).click(function(){n.update()}).hide();$("#wifidisc").button().click(function(){n.discnet()}).hide();$("#saveok").hide();$("#savefail").hide()},init:function(){this.getcfg()},};var BChart={offset:0,url:'chart.php',reqdata:function(){var t=this;var b='offset='+t.offset;var c=new XMLHttpRequest();c.open('GET',t.url+'?'+b);c.responseType='arraybuffer';c.onload=function(e){var a=new Uint8Array(this.response);if(a.length==0){console.log("zero content");if(t.timer)clearInterval(t.timer);t.timer=null;setTimeout(function(){t.reqdata()},3000);return}t.chart.process(a);t.offset+=a.length;if(t.timer==null)t.settimer()};c.send()},settimer:function(){var t=this;t.timer=setInterval(function(){t.reqdata()},t.chart.interval*1000)},init:function(a){this.chart=new BrewChart(a)},timer:null,pull:function(){},setCelius:function(a){this.chart.setCelius(a)},setYLabel:function(a){this.chart.ylabel(a)},start:function(){if(this.running)return;this.running=true;this.offset=0;this.chart.clear();this.reqdata();$("#tchart").show()},stop:function(){if(!this.running)return;this.running=false;if(this.timer){clearInterval(this.timer);this.timer=null}$("#tchart").hide()}};var Logs={url:"logs.php",dl:"dl",init:function(){var t=this;this.row=$("#loglist").find("tr:nth-of-type(2)");this.row.remove();$("#listfile").button().button("option","icons",{primary:"ui-icon-arrowrefresh-1-e"}).click(function(){t.getlist()});$("#vchart").hide();t.chart=new BrewChart("vchart-canvas")},view:function(b,c){$("#vchart").show();$("#viewlogname").text(b+"@"+c.toLocaleString());var t=this;t.chart.clear();t.chart.setCelius(BM.celius);var d=new XMLHttpRequest();d.open('GET',t.url+"?"+t.dl+"="+b);d.responseType='arraybuffer';d.onload=function(e){var a=new Uint8Array(this.response);if(a.length==0){console.log("zero content");return}t.chart.realtime=true;t.chart.process(a)};d.oerror=function(e){console.log("error")};d.send()},process:function(e){var f=$("#loglist").find("tbody");var g=this.row;var t=this;$.each(e,function(i,a){var b=('000'+a.f).slice(-4);var c=new Date(a.t*1000);var d=g.clone();d.find(".logid").text(b);d.find(".logdate").text(c.toLocaleString());d.find(".dlbutton").button().button("option","icons",{primary:"ui-icon-disk"}).click(function(){window.open(t.url+"?"+t.dl+"="+b)});d.find(".viewbutton").button().button("option","icons",{primary:"ui-icon-circle-zoomout"}).click(function(){t.view(b,c)});f.append(d)})},getlist:function(){var t=this;$.ajax({url:t.url,type:"GET",dataType:"json",success:function(a){$("#loglist tr:gt(0)").remove();t.process(a)},error:function(a,b,c){console.log("Error:"+c)}})}};var BrewMath={plato2sg:function(a){return 1+a/(258.6-((a/258.2)*227.1))},sgTempCorrected:function(a,F,b){return a*((1.00130346-0.000134722124*F+0.00000204052596*F*F-0.00000000232820948*F*F*F)/(1.00130346-0.000134722124*b+0.00000204052596*b*b-0.00000000232820948*b*b*b))},brix2sg:function(a,b){b=(typeof b==="undefined")?1.0:b;var c=a/b;return(c/(258.6-((c/258.2)*227.1)))+1}};var BrewUtils={ciWeightUnit:"WEIGHT_U",ciVolumeUnit:"VOLUME_U",ciTempUnit:"TEMPERATURE_U",ciTC:"HydroCorrected",ciWC:"RefractoWortCorrect",u_vol:'L',u_weight:'M',u_temp:'C',did:null,VolFactor:{L:{L:1,G:0.264172052,Q:1.05668821},G:{L:3.78541178,G:1,Q:4},Q:{L:0.946352946,G:0.25,Q:1}},volume_unit:function(u){var a=(u=='L')?'L':((u=='G')?'gal':'qt');$(this.did).find(".vol_u").text(a);var b=this.VolFactor[this.u_vol][u];this.u_vol=u;setCookie(this.ciVolumeUnit,u,365);$(this.did).find(".volinput").each(function(){var v=$(this).val();if(v){v=(v*b);$(this).val(v.toFixed(2))}})},weight_unit:function(u){var a=(u=='M')?'kg':'lb';$(this.did).find(".weight_u").text(a);var b=(this.u_weight==u)?1:((u=='M')?0.45359237:2.20462262);this.u_weight=u;setCookie(this.ciWeightUnit,u,365);if(b==1)return;$(this.did).find(".weightinput").each(function(){var v=$(this).val();if(v){v=(v*b);$(this).val(v.toFixed(2))}})},temp_unit:function(u){if(this.u_temp==u)return;var a=(u=='C')?'°C':'°F';$(".tmp_u").text(a);this.u_temp=u;setCookie(this.ciTempUnit,u,365);function C2F(c){return c*1.8+32}function F2C(f){return(f-32)/1.8}var b=(u=='C')?F2C:C2F;$(this.did).find(".tempinput").each(function(){var v=$(this).val();if(v){v=b(v);$(this).val(v.toFixed(1))}})},init:function(f){var t=this;t.did=f;var v=getCookie(t.ciVolumeUnit);v=(v)?v:t.u_vol;$(f).find("[name=volume_unit]").val([v]);t.volume_unit(v);var w=getCookie(t.ciWeightUnit);w=(w)?w:t.u_weight;$(f).find("[name=weight_unit]").val([w]);t.weight_unit(w);var T=getCookie(t.ciTempUnit);T=(T)?T:t.u_temp;$(f).find("[name=temp_unit]").val([T]);t.temp_unit(T);var h=getCookie(t.ciWC);if(h)$(f).find(".REFRACTO .wortcorrection").val(h);var i=getCookie(t.ciTC);if(i){var j=i.split(',');var k=j[0];if(j[1]!=t.u_temp){k=(j[1]=='C')?(k*1.8+32):((k-32)/1.8)}$(f).find(".HYDROMETER .correctedTemp").val(k)}$(f).find('input[type="radio"]').change(function(){var a=$(this).attr('name');var b=$(this).val();if($(this).prop('checked')){t[a](b)}});$(f).find('.fwsg').change(function(){var a=$(f).find(".FWSG .grain").val();var b=$(f).find(".FWSG .water").val();if(a&&b){a=(t.u_weight=='M')?a:(a*0.45359237);b=t.VolFactor[t.u_vol].L*b;var c=(a*0.8)/(a*0.8+b);var d=BrewMath.plato2sg(c*100).toFixed(3);$(f).find(".FWSG .result").text(d)}});$(f).find('.hydroinput').change(function(){var a=$(f).find(".HYDROMETER .sgfraction").val();var b=$(f).find(".HYDROMETER .sgtemp").val();var c=$(f).find(".HYDROMETER .correctedTemp").val();if(c)setCookie(t.ciTC,c+","+t.u_temp,365);if(a&&b&&c){var F=(t.u_temp=='C')?(b*1.8+32):b;var d=(t.u_temp=='C')?(c*1.8+32):c;var e=BrewMath.sgTempCorrected(a,F,d);$(f).find(".HYDROMETER .result").text(e.toFixed(3));window.latestSG=e}});$(f).find('.brixinput').change(function(){var a=$(f).find(".REFRACTO .brixreading").val();var b=$(f).find(".REFRACTO .wortcorrection").val();if(b)setCookie(t.ciWC,b,365);if(a){b=(b)?b:1;var c=BrewMath.brix2sg(a,b);$(f).find(".REFRACTO .result").text(c.toFixed(3));window.latestSG=c}});$(f).find('.boiloffinput').change(function(){var a=$(f).find('.BOILOFF .sg').val();var b=$(f).find('.BOILOFF .vol').val();var c=$(f).find('.BOILOFF .newsg').val();var d=$(f).find('.BOILOFF .newvol').val();if(a&&b&&c){var v=(a-1)*b/(c-1);$(f).find(".BOILOFF .resultvol").text(v.toFixed(2))}if(a&&b&&d){var g=(a-1)*b/d+1;$(f).find(".BOILOFF .resultsg").text(g.toFixed(3))}})}}; diff --git a/BrewManiacEx/data/index.htm b/BrewManiacEx/data/index.htm index 72aeb32..542d3b7 100644 --- a/BrewManiacEx/data/index.htm +++ b/BrewManiacEx/data/index.htm @@ -10,7 +10,7 @@ * Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:0;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px .4em;margin:.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.4em 2.1em .4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:0;background:0;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:0;border-bottom:0;border-right:0}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:0}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url("images/ubhs100e.png") 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url("images/ubggwv35.png") 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url("images/ubggf6.png") 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url("images/ubggl100f.png") 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#c77405;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url("images/ubgg65f.png") 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url("images/ubhs75.png") 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url("images/ubd-t40.png") 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui2.png")}.ui-widget-header .ui-icon{background-image:url("images/uifff.png")}.ui-state-default .ui-icon{background-image:url("images/uief8c.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/uief8c.png")}.ui-state-active .ui-icon{background-image:url("images/uief8c.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui228ef1.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/uiffd.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url("images/ubdt66.png") 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url("images/ubf10_.png") 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);border-radius:5px}#sb-site,.sb-site-container,.sb-slidebar,body,html{margin:0;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body,html{width:100%;overflow-x:hidden}html{height:100%}body{min-height:100%;height:auto;position:relative}html.sb-scroll-lock.sb-active:not(.sb-static){overflow:hidden}#sb-site,.sb-site-container{width:100%;min-height:100vh;position:relative;z-index:1;background-color:#fff}#sb-site:after,#sb-site:before,.sb-site-container:after,.sb-site-container:before{content:' ';display:table;clear:both}.sb-slidebar{height:100%;overflow-y:auto;position:fixed;top:0;z-index:0;display:none;background-color:#222}.sb-slidebar,.sb-slidebar *{-webkit-transform:translateZ(0px)}.sb-left{left:0}.sb-right{right:0}.sb-slidebar.sb-static,html.sb-static .sb-slidebar{position:absolute}.sb-slidebar.sb-active{display:block}.sb-style-overlay{z-index:9999}.sb-momentum-scrolling{-webkit-overflow-scrolling:touch}.sb-slidebar{width:30%}.sb-width-thin{width:15%}.sb-width-wide{width:45%}@media(max-width:480px){.sb-slidebar{width:70%}.sb-width-thin{width:55%}.sb-width-wide{width:85%}}@media(min-width:481px){.sb-slidebar{width:55%}.sb-width-thin{width:40%}.sb-width-wide{width:70%}}@media(min-width:768px){.sb-slidebar{width:40%}.sb-width-thin{width:25%}.sb-width-wide{width:55%}}@media(min-width:992px){.sb-slidebar{width:30%}.sb-width-thin{width:15%}.sb-width-wide{width:45%}}@media(min-width:1200px){.sb-slidebar{width:20%}.sb-width-thin{width:5%}.sb-width-wide{width:35%}}#sb-site,.sb-site-container,.sb-slide,.sb-slidebar{-webkit-transform:translate(0px);-moz-transform:translate(0px);-o-transform:translate(0px);transform:translate(0px);-webkit-transition:-webkit-transform 400ms ease;-moz-transition:-moz-transform 400ms ease;-o-transition:-o-transform 400ms ease;transition:transform 400ms ease;-webkit-transition-property:-webkit-transform,left,right;-webkit-backface-visibility:hidden}.sb-hide{display:none}.switch-button-label{float:left;font-size:10pt;cursor:pointer}.switch-button-label.off{color:#adadad}.switch-button-label.on{color:#08C}.switch-button-background{float:left;position:relative;background:#ccc;border:1px solid #aaa;margin:1px 10px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;cursor:pointer}.switch-button-button{position:absolute;left:-1px;top:-1px;background:#fafafa;border:1px solid #aaa;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}body{text-align:center}.ui-button,.ui-button-text .ui-button{font-size:10px!important}#sb-site{background-color:#e6e6e6}.navicon-line{width:24px;height:4px;border-radius:1px;margin-bottom:3px;background-color:#fff}.top-bar-block{display:inline-block;color:white;font-style:italic;font-family:Georgia,serif}#menubar{position:absolute;left:10px}#menu .ui-selecting{background:#feca40}#menu .ui-selected{background:#f39814;color:white}#menu{list-style-type:none;margin:0;padding:0;width:100%}#menu li{margin:3px;padding:.4em;font-size:1em;height:18px}#menupane{width:120px}#top-bar{background-color:#222}.setting-category{text-align:center;font-weight:bold;font-size:1.2em;background-color:yellow}#status-p,#settings-p,#automation-p,#sensors-p,#about-p,#top-bar{margin:auto;padding:10px;width:100%}#about-p{text-align:left}ul{text-align:left}.tmp_unit{font-family:Tahoma,Geneva,sans-serif}.editbtn{height:20px}.section{font-size:18px;font-weight:bold}table{border-collapse:collapse}table,tr,td,th{margin:auto;border:1px solid black}#auto-t tr,#auto-t td,#auto-t th{border:0;font-weight:bold}#auto-p td{text-align:left}.running{font-size:1.2em;color:red;background-color:yellow}.run{color:#bdbdbd;font-weight:normal}.panel{border-style:groove;text-align:right;padding:4px;margin-left:4px;margin-right:4px;margin-top:2px;margin-bottom:2px}.label{font-family:"Courier New",Courier,monospace;font-size:12px;color:white}.NUM{font-family:"Arial Black",Gadget,sans-serif;color:#c00;border-style:ridge;padding:2px;margin:2px;background-color:#212121}#timerPanel{height:46px;width:90px}#timer{height:24px;width:80px;font-size:12pt}.temperature{display:inline-block;font-size:12pt;width:64px;height:28px;white-space:nowrap;color:#c00}.tmp_unit{font-family:Tahoma,Geneva,sans-serif}#maintemp hr{margin:2px}#maintemp{width:120px}#setpoint{color:#c8f442}#auxT{display:none}#pwmPanel{width:90px}#pwm{font-size:10pt;width:26px;height:16px;display:inline-block}.ledreddim{background:#5b0000}.ledgreendim{background:#01290c}.round-led-circle{width:23px;height:0;padding-bottom:23px;border-radius:50%;border-style:outset;overflow:hidden;display:inline-block}span.round-led{width:12px;height:12px;display:table-cell;text-align:center;vertical-align:middle;font-weight:bold;text-decoration:none}a{-webkit-user-select:none;-webkit-touch-callout:none}#status-p table,#status-p tr,#status-p td{border:0;margin:0}#ctrlpanel{width:fit-content;margin-left:auto;margin-right:auto;display:inline-block;background-color:#c0c0c0}#btnpanel{width:fit-content;height:fit-content;position:relative}#btnpanel td{width:25%}#btngap{height:5px}#btncover{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1000;background-color:#FFF;border-radius:0 0 6px 6px;opacity:.6}.round-button-circle{width:52px;height:0;padding-bottom:52px;border-radius:50%;border-style:groove;overflow:hidden;background:#a22;margin:2px}a.round-button{width:52px;height:52px;display:table-cell;text-align:center;vertical-align:middle;color:#ccc;font-weight:bold;text-decoration:none;font-size:8pt}#info{text-align:center;color:white;font-family:"Courier New",Courier,monospace;background-color:black;height:16px}#title{text-align:center;color:white;font-family:"Courier New",Courier,monospace;height:1.1em}#tline{margin-top:0}#auto-p table,#auto-p tr{margin-top:10px;margin-left:auto;margin-right:auto;border:2px;border-style:groove}#sensors{display:none}#auxledcon{display:none}#network-p table,#network-p tr,#network-p td{border:0}#passmatch{color:red}#saveok{color:blue;font-style:italic}#savefail{color:red;font-weight:bold}fieldset.commonset{display:inline-block}fieldset{margin:10px;display:inline-block}fieldset th{text-align:right}fieldset td{text-align:left} - +
@@ -181,7 +181,7 @@

Network Settings

New passwords don't match!! User Name Password - + New setting will be effective after restart. Update failed!! @@ -287,4 +287,4 @@

Network Settings

Do you Really want to END current job and go back to Main screen?

- \ No newline at end of file + diff --git a/BrewManiacEx/data/version.txt b/BrewManiacEx/data/version.txt index ceab6e1..d917d3e 100644 --- a/BrewManiacEx/data/version.txt +++ b/BrewManiacEx/data/version.txt @@ -1 +1 @@ -0.1 \ No newline at end of file +0.1.2 diff --git a/BrewManiacEx/ui.h b/BrewManiacEx/ui.h index fd0bad3..fe9b40b 100644 --- a/BrewManiacEx/ui.h +++ b/BrewManiacEx/ui.h @@ -59,6 +59,7 @@ Constant definition #define WiStateNotConnected 0 #define WiStateConnected 1 +#define WiStateAccessPoint 2 #define PumpStatus_On 1 #define PumpStatus_On_PROGRAM_OFF 2 @@ -238,7 +239,10 @@ void uiLcdInitialize(void) ***********************************************************************/ -const byte WirelessSymbol[8] PROGMEM ={B00000,B01110,B10001,B00100,B01010,B00000,B00100,B00000}; +const byte WirelessSymbol[8] PROGMEM = {B00000,B01110,B10001,B00100,B01010,B00000,B00100,B00000}; +const byte WirelessAPSymbol[8] PROGMEM ={B00000,B10001,B01010,B10101,B00100,B00100,B00100,B01110}; + + const byte CelsiusSymbol[8] PROGMEM = {B01000, B10100, B01000, B00111, B01000, B01000, B01000, B00111}; // [0] degree c sybmol const byte FahrenheitSymbol[8] PROGMEM = {B01000, B10100, B01000, B00111, B00100, B00110, B00100, B00100}; // [0] degree f symbol @@ -415,10 +419,14 @@ void uiDisplayWirelessIcon(void) { uiLcdClear(19,0,1); } - else // ==WiStateConnected + else if(_wiStatus == WiStateConnected) { uiLcdDrawSymbolBmp(19,0,WirelessSymbol); } + else + { + uiLcdDrawSymbolBmp(19,0,WirelessAPSymbol); + } } @@ -427,7 +435,7 @@ void uiSetWirelessStatus(byte status) _wiStatus=status; uiDisplayWirelessIcon(); - if(_wiStatus !=WiStateConnected){ + if(_wiStatus == WiStateNotConnected){ ipSet = false; } @@ -453,6 +461,7 @@ void uiPrintIpAddress(void) } buffer[idx]='\0'; uiLcdPrint(1,2,buffer); + uiLcdClear(idx+1,2,17-idx); } } @@ -863,3 +872,32 @@ void uiInitialize(void) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BrewManiacEx/wi.h b/BrewManiacEx/wi.h index 788d365..c6bc243 100644 --- a/BrewManiacEx/wi.h +++ b/BrewManiacEx/wi.h @@ -147,11 +147,11 @@ void wiSettingChanged(int address,byte value) } -void wiSetDeviceAddress(byte ip[]) +void wiSetDeviceAddress(byte ip[], bool apmode) { // support only IPv4 for now if( ip[0] != 0 && ip[1] != 0 && ip[2] != 0 && ip[3] != 0){ - uiSetWirelessStatus(WiStateConnected); + uiSetWirelessStatus(apmode? WiStateAccessPoint:WiStateConnected); uiSetIp(ip); if(bmproxy.stage == StageIdleScreen) uiPrintIpAddress();