From cb7c38e6d4e14d152d5e00f1c48b0587e08b1d35 Mon Sep 17 00:00:00 2001 From: Martin Donnelly Date: Mon, 19 Sep 2016 16:45:04 +0100 Subject: [PATCH] =?UTF-8?q?=E2=80=9D2016-09-19=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mDotServer.censis/app.js | 4 +- .../mDotServer.censis/app/css/custom.css | 1956 +++++++++++++++++ .../mDotServer.censis/app/css/test.css | 20 + .../mDotServer.censis/app/js/mdot.js | 4 +- .../mDotServer.censis/app/js/websocket.js | 6 + .../mDotServer.censis/custom.scss | 16 + .../lib/server/db-connector.js | 10 +- .../mDotServer.censis/lib/sockethandler.js | 1 + .../mDotServer.censis/package.json | 2 +- .../mDotServer.censis/views/test.ejs | 11 +- .../mDotServer.censis/views/test2.ejs | 394 ++++ mdot/mqttArchiver/mqttArchiver/app.js | 16 +- mdot/mqttArchiver/mqttArchiver/lib/mailer.js | 44 + .../mqttArchiver/lib/mqtt/mqttClient.js | 137 +- .../mqttArchiver/lib/server/db-connector.js | 9 +- mdot/mqttArchiver/mqttArchiver/package.json | 6 +- 16 files changed, 2560 insertions(+), 76 deletions(-) create mode 100644 mdot/mDotServer.censis/mDotServer.censis/app/css/custom.css create mode 100644 mdot/mDotServer.censis/mDotServer.censis/custom.scss create mode 100644 mdot/mDotServer.censis/mDotServer.censis/views/test2.ejs create mode 100644 mdot/mqttArchiver/mqttArchiver/lib/mailer.js diff --git a/mdot/mDotServer.censis/mDotServer.censis/app.js b/mdot/mDotServer.censis/mDotServer.censis/app.js index f3cda2f..74553f3 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/app.js +++ b/mdot/mDotServer.censis/mDotServer.censis/app.js @@ -107,7 +107,9 @@ app.use(function(req, res, next) { // Run npm start --production to use dist var staticDir = isProduction ? 'dist' : 'app'; -var graphFile = isProduction ? 'graph-release' : 'test'; +//var graphFile = isProduction ? 'graph-release' : 'test2'; +staticDir = 'app'; +var graphFile = 'test2'; app.use(express.static(path.join(__dirname, staticDir))); app.use(errorhandler({dumpExceptions: true, showStack: true})); diff --git a/mdot/mDotServer.censis/mDotServer.censis/app/css/custom.css b/mdot/mDotServer.censis/mDotServer.censis/app/css/custom.css new file mode 100644 index 0000000..82f0a14 --- /dev/null +++ b/mdot/mDotServer.censis/mDotServer.censis/app/css/custom.css @@ -0,0 +1,1956 @@ +/** + * MUI Colors module + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ +html { + font-family: sans-serif; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } + +/** + * Remove default margin. + */ +body { + margin: 0; } + +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; } + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +audio, +canvas, +progress, +video { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ } + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; } + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; } + +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; } + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ +a:active, +a:hover { + outline: 0; } + +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; } + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b, +strong { + font-weight: bold; } + +/** + * Address styling not present in Safari and Chrome. + */ +dfn { + font-style: italic; } + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; } + +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; } + +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; } + +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +figure { + margin: 1em 40px; } + +/** + * Address differences between Firefox and other browsers. + */ +hr { + box-sizing: content-box; + height: 0; } + +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; } + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } + +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; + /* 1 */ + font: inherit; + /* 2 */ + margin: 0; + /* 3 */ } + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; } + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; } + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ } + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; } + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; } + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; } + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + box-sizing: content-box; + /* 2 */ } + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * Define consistent border, margin, and padding. + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; } + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +optgroup { + font-weight: bold; } + +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; } + +td, +th { + padding: 0; } + +/** + * MUI Colors module + */ +/** + * MUI Reboot + */ +* { + box-sizing: border-box; } + +*:before, +*:after { + box-sizing: border-box; } + +html { + font-size: 10px; + -webkit-tap-highlight-color: transparent; } + +body { + font-family: Ubuntu, Arial, Verdana, Tahoma; + font-size: 14px; + font-weight: 400; + line-height: 1.429; + color: rgba(0, 0, 0, 0.87); + background-color: #212121; } + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; } + +a { + color: #2196F3; + text-decoration: none; } + a:hover, a:focus { + color: #424242; + text-decoration: underline; } + a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +p { + margin: 0 0 10px; } + +ul, +ol { + margin-top: 0; + margin-bottom: 10px; } + +figure { + margin: 0; } + +img { + vertical-align: middle; } + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + height: 1px; + background-color: rgba(0, 0, 0, 0.12); } + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 10px; + font-size: 21px; + color: rgba(0, 0, 0, 0.87); + line-height: inherit; + border: 0; } + +input[type="search"] { + box-sizing: border-box; + -webkit-appearance: none; } + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +input[type="radio"]:disabled, +input[type="checkbox"]:disabled { + cursor: not-allowed; } + +strong { + font-weight: 700; } + +abbr[title] { + cursor: help; + border-bottom: 1px dotted #2196F3; } + +h1, h2, h3 { + margin-top: 20px; + margin-bottom: 10px; } + +h4, h5, h6 { + margin-top: 10px; + margin-bottom: 10px; } + +/** + * MUI Appbar + */ +.mui--appbar-height { + height: 56px; } + +.mui--appbar-min-height, .mui-appbar { + min-height: 56px; } + +.mui--appbar-line-height { + line-height: 56px; } + +.mui--appbar-top { + top: 56px; } + +@media (orientation: landscape) and (max-height: 480px) { + .mui--appbar-height { + height: 48px; } + .mui--appbar-min-height, .mui-appbar { + min-height: 48px; } + .mui--appbar-line-height { + line-height: 48px; } + .mui--appbar-top { + top: 48px; } } + +@media (min-width: 480px) { + .mui--appbar-height { + height: 64px; } + .mui--appbar-min-height, .mui-appbar { + min-height: 64px; } + .mui--appbar-line-height { + line-height: 64px; } + .mui--appbar-top { + top: 64px; } } + +.mui-appbar { + background-color: #2196F3; + color: #FFF; } + +/** + * MUI Buttons + */ +.mui-btn { + animation-duration: 0.0001s; + animation-name: mui-node-inserted; + font-weight: 500; + font-size: 14px; + line-height: 18px; + text-transform: uppercase; + color: rgba(0, 0, 0, 0.87); + background-color: #FFF; + transition: all 0.2s ease-in-out; + display: inline-block; + height: 36px; + padding: 0 26px; + margin-top: 6px; + margin-bottom: 6px; + border: none; + border-radius: 2px; + cursor: pointer; + touch-action: manipulation; + background-image: none; + text-align: center; + line-height: 36px; + vertical-align: middle; + white-space: nowrap; + user-select: none; + font-size: 14px; + letter-spacing: 0.03em; + position: relative; + overflow: hidden; } + .mui-btn:hover, .mui-btn:focus, .mui-btn:active { + color: rgba(0, 0, 0, 0.87); + background-color: white; } + .mui-btn[disabled]:hover, .mui-btn[disabled]:focus, .mui-btn[disabled]:active { + color: rgba(0, 0, 0, 0.87); + background-color: #FFF; } + .mui-btn.mui-btn--flat { + color: rgba(0, 0, 0, 0.87); + background-color: transparent; } + .mui-btn.mui-btn--flat:hover, .mui-btn.mui-btn--flat:focus, .mui-btn.mui-btn--flat:active { + color: rgba(0, 0, 0, 0.87); + background-color: #f2f2f2; } + .mui-btn.mui-btn--flat[disabled]:hover, .mui-btn.mui-btn--flat[disabled]:focus, .mui-btn.mui-btn--flat[disabled]:active { + color: rgba(0, 0, 0, 0.87); + background-color: transparent; } + .mui-btn:hover, .mui-btn:focus, .mui-btn:active { + outline: 0; + text-decoration: none; + color: rgba(0, 0, 0, 0.87); } + .mui-btn:hover, .mui-btn:focus { + box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2); } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-btn:hover, .mui-btn:focus { + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.12), -1px 0px 2px rgba(0, 0, 0, 0.12), 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2); } } + .mui-btn:active:hover { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-btn:active:hover { + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.12), -1px 0px 2px rgba(0, 0, 0, 0.12), 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } } + .mui-btn:disabled, .mui-btn.mui--is-disabled { + cursor: not-allowed; + pointer-events: none; + opacity: 0.60; + box-shadow: none; } + +.mui-btn + .mui-btn { + margin-left: 8px; } + +.mui-btn--flat { + background-color: transparent; } + .mui-btn--flat:hover, .mui-btn--flat:focus, .mui-btn--flat:active, .mui-btn--flat:active:hover { + box-shadow: none; + background-color: #f2f2f2; } + +.mui-btn--raised, .mui-btn--fab { + box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2); } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-btn--raised, .mui-btn--fab { + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.12), -1px 0px 2px rgba(0, 0, 0, 0.12), 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2); } } + .mui-btn--raised:active, .mui-btn--fab:active { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-btn--raised:active, .mui-btn--fab:active { + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.12), -1px 0px 2px rgba(0, 0, 0, 0.12), 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } } + +.mui-btn--fab { + position: relative; + padding: 0; + width: 55px; + height: 55px; + line-height: 55px; + border-radius: 50%; + z-index: 1; } + +.mui-btn--primary { + color: #FFF; + background-color: #2196F3; } + .mui-btn--primary:hover, .mui-btn--primary:focus, .mui-btn--primary:active { + color: #FFF; + background-color: #39a1f4; } + .mui-btn--primary[disabled]:hover, .mui-btn--primary[disabled]:focus, .mui-btn--primary[disabled]:active { + color: #FFF; + background-color: #2196F3; } + .mui-btn--primary.mui-btn--flat { + color: #2196F3; + background-color: transparent; } + .mui-btn--primary.mui-btn--flat:hover, .mui-btn--primary.mui-btn--flat:focus, .mui-btn--primary.mui-btn--flat:active { + color: #2196F3; + background-color: #f2f2f2; } + .mui-btn--primary.mui-btn--flat[disabled]:hover, .mui-btn--primary.mui-btn--flat[disabled]:focus, .mui-btn--primary.mui-btn--flat[disabled]:active { + color: #2196F3; + background-color: transparent; } + +.mui-btn--dark { + color: #FFF; + background-color: #424242; } + .mui-btn--dark:hover, .mui-btn--dark:focus, .mui-btn--dark:active { + color: #FFF; + background-color: #4f4f4f; } + .mui-btn--dark[disabled]:hover, .mui-btn--dark[disabled]:focus, .mui-btn--dark[disabled]:active { + color: #FFF; + background-color: #424242; } + .mui-btn--dark.mui-btn--flat { + color: #424242; + background-color: transparent; } + .mui-btn--dark.mui-btn--flat:hover, .mui-btn--dark.mui-btn--flat:focus, .mui-btn--dark.mui-btn--flat:active { + color: #424242; + background-color: #f2f2f2; } + .mui-btn--dark.mui-btn--flat[disabled]:hover, .mui-btn--dark.mui-btn--flat[disabled]:focus, .mui-btn--dark.mui-btn--flat[disabled]:active { + color: #424242; + background-color: transparent; } + +.mui-btn--danger { + color: #FFF; + background-color: #F44336; } + .mui-btn--danger:hover, .mui-btn--danger:focus, .mui-btn--danger:active { + color: #FFF; + background-color: #f55a4e; } + .mui-btn--danger[disabled]:hover, .mui-btn--danger[disabled]:focus, .mui-btn--danger[disabled]:active { + color: #FFF; + background-color: #F44336; } + .mui-btn--danger.mui-btn--flat { + color: #F44336; + background-color: transparent; } + .mui-btn--danger.mui-btn--flat:hover, .mui-btn--danger.mui-btn--flat:focus, .mui-btn--danger.mui-btn--flat:active { + color: #F44336; + background-color: #f2f2f2; } + .mui-btn--danger.mui-btn--flat[disabled]:hover, .mui-btn--danger.mui-btn--flat[disabled]:focus, .mui-btn--danger.mui-btn--flat[disabled]:active { + color: #F44336; + background-color: transparent; } + +.mui-btn--accent { + color: #004c6d; + background-color: #bad649; } + .mui-btn--accent:hover, .mui-btn--accent:focus, .mui-btn--accent:active { + color: #004c6d; + background-color: #c2db5e; } + .mui-btn--accent[disabled]:hover, .mui-btn--accent[disabled]:focus, .mui-btn--accent[disabled]:active { + color: #004c6d; + background-color: #bad649; } + .mui-btn--accent.mui-btn--flat { + color: #bad649; + background-color: transparent; } + .mui-btn--accent.mui-btn--flat:hover, .mui-btn--accent.mui-btn--flat:focus, .mui-btn--accent.mui-btn--flat:active { + color: #bad649; + background-color: #f2f2f2; } + .mui-btn--accent.mui-btn--flat[disabled]:hover, .mui-btn--accent.mui-btn--flat[disabled]:focus, .mui-btn--accent.mui-btn--flat[disabled]:active { + color: #bad649; + background-color: transparent; } + +.mui-btn--small { + height: 30.6px; + line-height: 30.6px; + padding: 0 16px; + font-size: 13px; } + +.mui-btn--large { + height: 54px; + line-height: 54px; + padding: 0 26px; + font-size: 14px; } + +.mui-btn--fab.mui-btn--small { + width: 44px; + height: 44px; + line-height: 44px; } + +.mui-btn--fab.mui-btn--large { + width: 75px; + height: 75px; + line-height: 75px; } + +/** + * MUI Checkboxe and Radio Components + */ +.mui-radio, +.mui-checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; } + .mui-radio > label, + .mui-checkbox > label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; } + +.mui-radio > label > input[type="radio"], +.mui-radio--inline > label > input[type="radio"], +.mui-checkbox > label > input[type="checkbox"], +.mui-checkbox--inline > label > input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px; } + +.mui-radio + .mui-radio, +.mui-checkbox + .mui-checkbox { + margin-top: -5px; } + +.mui-radio--inline, +.mui-checkbox--inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; } + .mui-radio--inline > input[type="radio"], + .mui-radio--inline > input[type="checkbox"], + .mui-radio--inline > label > input[type="radio"], + .mui-radio--inline > label > input[type="checkbox"], + .mui-checkbox--inline > input[type="radio"], + .mui-checkbox--inline > input[type="checkbox"], + .mui-checkbox--inline > label > input[type="radio"], + .mui-checkbox--inline > label > input[type="checkbox"] { + margin: 4px 0 0; + line-height: normal; } + +.mui-radio--inline + .mui-radio--inline, +.mui-checkbox--inline + .mui-checkbox--inline { + margin-top: 0; + margin-left: 10px; } + +/** + * MUI Container module + */ +.mui-container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } + .mui-container:before, .mui-container:after { + content: " "; + display: table; } + .mui-container:after { + clear: both; } + @media (min-width: 544px) { + .mui-container { + max-width: 570px; } } + @media (min-width: 768px) { + .mui-container { + max-width: 740px; } } + @media (min-width: 992px) { + .mui-container { + max-width: 960px; } } + @media (min-width: 1200px) { + .mui-container { + max-width: 1170px; } } + +.mui-container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } + .mui-container-fluid:before, .mui-container-fluid:after { + content: " "; + display: table; } + .mui-container-fluid:after { + clear: both; } + +/** + * MUI Divider Component and CSS Helpers + */ +.mui-divider { + display: block; + height: 1px; + background-color: rgba(0, 0, 0, 0.12); } + +.mui--divider-top { + border-top: 1px solid rgba(0, 0, 0, 0.12); } + +.mui--divider-bottom { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); } + +.mui--divider-left { + border-left: 1px solid rgba(0, 0, 0, 0.12); } + +.mui--divider-right { + border-right: 1px solid rgba(0, 0, 0, 0.12); } + +/** + * MUI Dropdown module + */ +.mui-dropdown { + display: inline-block; + position: relative; } + +[data-mui-toggle="dropdown"] { + animation-duration: 0.0001s; + animation-name: mui-node-inserted; + outline: 0; } + +.mui-dropdown__menu { + position: absolute; + top: 100%; + left: 0; + display: none; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #FFF; + border-radius: 2px; + z-index: 1; + background-clip: padding-box; } + .mui-dropdown__menu.mui--is-open { + display: block; } + .mui-dropdown__menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.429; + color: rgba(0, 0, 0, 0.87); + white-space: nowrap; } + .mui-dropdown__menu > li > a:hover, .mui-dropdown__menu > li > a:focus { + text-decoration: none; + color: rgba(0, 0, 0, 0.87); + background-color: #EEEEEE; } + .mui-dropdown__menu > .mui--is-disabled > a, .mui-dropdown__menu > .mui--is-disabled > a:hover, .mui-dropdown__menu > .mui--is-disabled > a:focus { + color: #EEEEEE; } + .mui-dropdown__menu > .mui--is-disabled > a:hover, .mui-dropdown__menu > .mui--is-disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + cursor: not-allowed; } + +.mui-dropdown__menu--right { + left: auto; + right: 0; } + +/** + * MUI Form Component + */ +@media (min-width: 544px) { + .mui-form--inline > .mui-textfield { + display: inline-block; + margin-bottom: 0; } + .mui-form--inline > .mui-radio, + .mui-form--inline > .mui-checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; } + .mui-form--inline > .mui-radio > label, + .mui-form--inline > .mui-checkbox > label { + padding-left: 0; } + .mui-form--inline > .mui-radio > label > input[type="radio"], + .mui-form--inline > .mui-checkbox > label > input[type="checkbox"] { + position: relative; + margin-left: 0; } + .mui-form--inline > .mui-select { + display: inline-block; } + .mui-form--inline > .mui-btn { + margin-bottom: 0; + margin-top: 0; + vertical-align: bottom; } } + +/** + * MUI Grid module + */ +.mui-row { + margin-left: -15px; + margin-right: -15px; } + .mui-row:before, .mui-row:after { + content: " "; + display: table; } + .mui-row:after { + clear: both; } + +.mui-col-xs-1, .mui-col-sm-1, .mui-col-md-1, .mui-col-lg-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-md-2, .mui-col-lg-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-md-3, .mui-col-lg-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-md-4, .mui-col-lg-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-md-5, .mui-col-lg-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-md-6, .mui-col-lg-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-md-7, .mui-col-lg-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-md-8, .mui-col-lg-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-md-9, .mui-col-lg-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-md-10, .mui-col-lg-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-md-11, .mui-col-lg-11, .mui-col-xs-12, .mui-col-sm-12, .mui-col-md-12, .mui-col-lg-12 { + min-height: 1px; + padding-left: 15px; + padding-right: 15px; } + +.mui-col-xs-1, .mui-col-xs-2, .mui-col-xs-3, .mui-col-xs-4, .mui-col-xs-5, .mui-col-xs-6, .mui-col-xs-7, .mui-col-xs-8, .mui-col-xs-9, .mui-col-xs-10, .mui-col-xs-11, .mui-col-xs-12 { + float: left; } + +.mui-col-xs-1 { + width: 8.33333%; } + +.mui-col-xs-2 { + width: 16.66667%; } + +.mui-col-xs-3 { + width: 25%; } + +.mui-col-xs-4 { + width: 33.33333%; } + +.mui-col-xs-5 { + width: 41.66667%; } + +.mui-col-xs-6 { + width: 50%; } + +.mui-col-xs-7 { + width: 58.33333%; } + +.mui-col-xs-8 { + width: 66.66667%; } + +.mui-col-xs-9 { + width: 75%; } + +.mui-col-xs-10 { + width: 83.33333%; } + +.mui-col-xs-11 { + width: 91.66667%; } + +.mui-col-xs-12 { + width: 100%; } + +.mui-col-xs-offset-0 { + margin-left: 0%; } + +.mui-col-xs-offset-1 { + margin-left: 8.33333%; } + +.mui-col-xs-offset-2 { + margin-left: 16.66667%; } + +.mui-col-xs-offset-3 { + margin-left: 25%; } + +.mui-col-xs-offset-4 { + margin-left: 33.33333%; } + +.mui-col-xs-offset-5 { + margin-left: 41.66667%; } + +.mui-col-xs-offset-6 { + margin-left: 50%; } + +.mui-col-xs-offset-7 { + margin-left: 58.33333%; } + +.mui-col-xs-offset-8 { + margin-left: 66.66667%; } + +.mui-col-xs-offset-9 { + margin-left: 75%; } + +.mui-col-xs-offset-10 { + margin-left: 83.33333%; } + +.mui-col-xs-offset-11 { + margin-left: 91.66667%; } + +.mui-col-xs-offset-12 { + margin-left: 100%; } + +@media (min-width: 544px) { + .mui-col-sm-1, .mui-col-sm-2, .mui-col-sm-3, .mui-col-sm-4, .mui-col-sm-5, .mui-col-sm-6, .mui-col-sm-7, .mui-col-sm-8, .mui-col-sm-9, .mui-col-sm-10, .mui-col-sm-11, .mui-col-sm-12 { + float: left; } + .mui-col-sm-1 { + width: 8.33333%; } + .mui-col-sm-2 { + width: 16.66667%; } + .mui-col-sm-3 { + width: 25%; } + .mui-col-sm-4 { + width: 33.33333%; } + .mui-col-sm-5 { + width: 41.66667%; } + .mui-col-sm-6 { + width: 50%; } + .mui-col-sm-7 { + width: 58.33333%; } + .mui-col-sm-8 { + width: 66.66667%; } + .mui-col-sm-9 { + width: 75%; } + .mui-col-sm-10 { + width: 83.33333%; } + .mui-col-sm-11 { + width: 91.66667%; } + .mui-col-sm-12 { + width: 100%; } + .mui-col-sm-offset-0 { + margin-left: 0%; } + .mui-col-sm-offset-1 { + margin-left: 8.33333%; } + .mui-col-sm-offset-2 { + margin-left: 16.66667%; } + .mui-col-sm-offset-3 { + margin-left: 25%; } + .mui-col-sm-offset-4 { + margin-left: 33.33333%; } + .mui-col-sm-offset-5 { + margin-left: 41.66667%; } + .mui-col-sm-offset-6 { + margin-left: 50%; } + .mui-col-sm-offset-7 { + margin-left: 58.33333%; } + .mui-col-sm-offset-8 { + margin-left: 66.66667%; } + .mui-col-sm-offset-9 { + margin-left: 75%; } + .mui-col-sm-offset-10 { + margin-left: 83.33333%; } + .mui-col-sm-offset-11 { + margin-left: 91.66667%; } + .mui-col-sm-offset-12 { + margin-left: 100%; } } + +@media (min-width: 768px) { + .mui-col-md-1, .mui-col-md-2, .mui-col-md-3, .mui-col-md-4, .mui-col-md-5, .mui-col-md-6, .mui-col-md-7, .mui-col-md-8, .mui-col-md-9, .mui-col-md-10, .mui-col-md-11, .mui-col-md-12 { + float: left; } + .mui-col-md-1 { + width: 8.33333%; } + .mui-col-md-2 { + width: 16.66667%; } + .mui-col-md-3 { + width: 25%; } + .mui-col-md-4 { + width: 33.33333%; } + .mui-col-md-5 { + width: 41.66667%; } + .mui-col-md-6 { + width: 50%; } + .mui-col-md-7 { + width: 58.33333%; } + .mui-col-md-8 { + width: 66.66667%; } + .mui-col-md-9 { + width: 75%; } + .mui-col-md-10 { + width: 83.33333%; } + .mui-col-md-11 { + width: 91.66667%; } + .mui-col-md-12 { + width: 100%; } + .mui-col-md-offset-0 { + margin-left: 0%; } + .mui-col-md-offset-1 { + margin-left: 8.33333%; } + .mui-col-md-offset-2 { + margin-left: 16.66667%; } + .mui-col-md-offset-3 { + margin-left: 25%; } + .mui-col-md-offset-4 { + margin-left: 33.33333%; } + .mui-col-md-offset-5 { + margin-left: 41.66667%; } + .mui-col-md-offset-6 { + margin-left: 50%; } + .mui-col-md-offset-7 { + margin-left: 58.33333%; } + .mui-col-md-offset-8 { + margin-left: 66.66667%; } + .mui-col-md-offset-9 { + margin-left: 75%; } + .mui-col-md-offset-10 { + margin-left: 83.33333%; } + .mui-col-md-offset-11 { + margin-left: 91.66667%; } + .mui-col-md-offset-12 { + margin-left: 100%; } } + +@media (min-width: 992px) { + .mui-col-lg-1, .mui-col-lg-2, .mui-col-lg-3, .mui-col-lg-4, .mui-col-lg-5, .mui-col-lg-6, .mui-col-lg-7, .mui-col-lg-8, .mui-col-lg-9, .mui-col-lg-10, .mui-col-lg-11, .mui-col-lg-12 { + float: left; } + .mui-col-lg-1 { + width: 8.33333%; } + .mui-col-lg-2 { + width: 16.66667%; } + .mui-col-lg-3 { + width: 25%; } + .mui-col-lg-4 { + width: 33.33333%; } + .mui-col-lg-5 { + width: 41.66667%; } + .mui-col-lg-6 { + width: 50%; } + .mui-col-lg-7 { + width: 58.33333%; } + .mui-col-lg-8 { + width: 66.66667%; } + .mui-col-lg-9 { + width: 75%; } + .mui-col-lg-10 { + width: 83.33333%; } + .mui-col-lg-11 { + width: 91.66667%; } + .mui-col-lg-12 { + width: 100%; } + .mui-col-lg-offset-0 { + margin-left: 0%; } + .mui-col-lg-offset-1 { + margin-left: 8.33333%; } + .mui-col-lg-offset-2 { + margin-left: 16.66667%; } + .mui-col-lg-offset-3 { + margin-left: 25%; } + .mui-col-lg-offset-4 { + margin-left: 33.33333%; } + .mui-col-lg-offset-5 { + margin-left: 41.66667%; } + .mui-col-lg-offset-6 { + margin-left: 50%; } + .mui-col-lg-offset-7 { + margin-left: 58.33333%; } + .mui-col-lg-offset-8 { + margin-left: 66.66667%; } + .mui-col-lg-offset-9 { + margin-left: 75%; } + .mui-col-lg-offset-10 { + margin-left: 83.33333%; } + .mui-col-lg-offset-11 { + margin-left: 91.66667%; } + .mui-col-lg-offset-12 { + margin-left: 100%; } } + +@media (min-width: 1200px) { + .mui-col-xl-1, .mui-col-xl-2, .mui-col-xl-3, .mui-col-xl-4, .mui-col-xl-5, .mui-col-xl-6, .mui-col-xl-7, .mui-col-xl-8, .mui-col-xl-9, .mui-col-xl-10, .mui-col-xl-11, .mui-col-xl-12 { + float: left; } + .mui-col-xl-1 { + width: 8.33333%; } + .mui-col-xl-2 { + width: 16.66667%; } + .mui-col-xl-3 { + width: 25%; } + .mui-col-xl-4 { + width: 33.33333%; } + .mui-col-xl-5 { + width: 41.66667%; } + .mui-col-xl-6 { + width: 50%; } + .mui-col-xl-7 { + width: 58.33333%; } + .mui-col-xl-8 { + width: 66.66667%; } + .mui-col-xl-9 { + width: 75%; } + .mui-col-xl-10 { + width: 83.33333%; } + .mui-col-xl-11 { + width: 91.66667%; } + .mui-col-xl-12 { + width: 100%; } + .mui-col-xl-offset-0 { + margin-left: 0%; } + .mui-col-xl-offset-1 { + margin-left: 8.33333%; } + .mui-col-xl-offset-2 { + margin-left: 16.66667%; } + .mui-col-xl-offset-3 { + margin-left: 25%; } + .mui-col-xl-offset-4 { + margin-left: 33.33333%; } + .mui-col-xl-offset-5 { + margin-left: 41.66667%; } + .mui-col-xl-offset-6 { + margin-left: 50%; } + .mui-col-xl-offset-7 { + margin-left: 58.33333%; } + .mui-col-xl-offset-8 { + margin-left: 66.66667%; } + .mui-col-xl-offset-9 { + margin-left: 75%; } + .mui-col-xl-offset-10 { + margin-left: 83.33333%; } + .mui-col-xl-offset-11 { + margin-left: 91.66667%; } + .mui-col-xl-offset-12 { + margin-left: 100%; } } + +/** + * MUI Panel module + */ +.mui-panel { + padding: 15px; + margin-bottom: 20px; + border-radius: 0; + background-color: #FFF; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0px 2px 0 rgba(0, 0, 0, 0.12); } + .mui-panel:before, .mui-panel:after { + content: " "; + display: table; } + .mui-panel:after { + clear: both; } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-panel { + box-shadow: 0 -1px 2px 0 rgba(0, 0, 0, 0.12), -1px 0px 2px 0 rgba(0, 0, 0, 0.12), 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0px 2px 0 rgba(0, 0, 0, 0.12); } } + +/** + * MUI Select Component + */ +.mui-select { + display: block; + padding-top: 15px; + margin-bottom: 20px; + position: relative; } + .mui-select:focus { + outline: 0; } + .mui-select:focus > select { + height: 33px; + margin-bottom: -1px; + border-color: #2196F3; + border-width: 2px; } + .mui-select > select { + animation-duration: 0.0001s; + animation-name: mui-node-inserted; + display: block; + height: 32px; + width: 100%; + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + outline: none; + border: none; + border-bottom: 1px solid rgba(0, 0, 0, 0.26); + border-radius: 0px; + box-shadow: none; + background-color: transparent; + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNiIgd2lkdGg9IjEwIj48cG9seWdvbiBwb2ludHM9IjAsMCAxMCwwIDUsNiIgc3R5bGU9ImZpbGw6cmdiYSgwLDAsMCwuMjQpOyIvPjwvc3ZnPg=="); + background-repeat: no-repeat; + background-position: right center; + cursor: pointer; + color: #FFF; + font-size: 16px; + padding: 0 25px 0 0; } + .mui-select > select::-ms-expand { + display: none; } + .mui-select > select:focus { + outline: 0; + height: 33px; + margin-bottom: -1px; + border-color: #2196F3; + border-width: 2px; } + .mui-select > select:disabled { + color: rgba(0, 0, 0, 0.38); + cursor: not-allowed; + background-color: transparent; + opacity: 1; } + .mui-select > label { + position: absolute; + top: 0; + display: block; + width: 100%; + color: rgba(0, 0, 0, 0.54); + font-size: 12px; + font-weight: 400; + line-height: 15px; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + +.mui-select:focus > label, +.mui-select > select:focus ~ label { + color: #2196F3; } + +.mui-select__menu { + position: absolute; + z-index: 2; + min-width: 100%; + overflow-y: auto; + padding: 8px 0; + background-color: #FFF; + font-size: 16px; } + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .mui-select__menu { + border-left: 1px solid rgba(0, 0, 0, 0.12); + border-top: 1px solid rgba(0, 0, 0, 0.12); } } + .mui-select__menu > div { + padding: 0 22px; + height: 42px; + line-height: 42px; + cursor: pointer; + white-space: nowrap; } + .mui-select__menu > div.mui--is-selected { + background-color: #EEEEEE; } + .mui-select__menu > div:not(.mui-optgroup__label):hover { + background-color: #E0E0E0; } + +.mui-optgroup__option { + text-indent: 1em; } + +.mui-optgroup__label { + color: rgba(0, 0, 0, 0.54); + font-size: 0.9em; } + +/** + * MUI Table Component + */ +th { + text-align: left; } + +.mui-table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; } + .mui-table > thead > tr > th, + .mui-table > thead > tr > td, + .mui-table > tbody > tr > th, + .mui-table > tbody > tr > td, + .mui-table > tfoot > tr > th, + .mui-table > tfoot > tr > td { + padding: 10px; + line-height: 1.429; } + .mui-table > thead > tr > th { + border-bottom: 2px solid rgba(0, 0, 0, 0.12); + font-weight: 700; } + .mui-table > tbody + tbody { + border-top: 2px solid rgba(0, 0, 0, 0.12); } + .mui-table.mui-table--bordered > tbody > tr > td { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); } + +/** + * MUI Tabs module + */ +.mui-tabs__bar { + list-style: none; + padding-left: 0; + margin-bottom: 0; + background-color: transparent; + white-space: nowrap; + overflow-x: auto; } + .mui-tabs__bar > li { + display: inline-block; } + .mui-tabs__bar > li > a { + display: block; + white-space: nowrap; + text-transform: uppercase; + font-weight: 500; + font-size: 14px; + color: rgba(255, 255, 255, 0.87); + cursor: default; + height: 48px; + line-height: 48px; + padding-left: 24px; + padding-right: 24px; + user-select: none; } + .mui-tabs__bar > li > a:hover { + text-decoration: none; } + .mui-tabs__bar > li.mui--is-active { + border-bottom: 2px solid #2196F3; } + .mui-tabs__bar > li.mui--is-active > a { + color: #2196F3; } + .mui-tabs__bar.mui-tabs__bar--justified { + display: table; + width: 100%; + table-layout: fixed; } + .mui-tabs__bar.mui-tabs__bar--justified > li { + display: table-cell; } + .mui-tabs__bar.mui-tabs__bar--justified > li > a { + text-align: center; + padding-left: 0px; + padding-right: 0px; } + +.mui-tabs__pane { + display: none; } + .mui-tabs__pane.mui--is-active { + display: block; } + +[data-mui-toggle="tab"] { + animation-duration: 0.0001s; + animation-name: mui-node-inserted; } + +/** + * MUI Textfield Component + */ +.mui-textfield { + display: block; + padding-top: 15px; + margin-bottom: 20px; + position: relative; } + .mui-textfield > label { + position: absolute; + top: 0; + display: block; + width: 100%; + color: rgba(0, 0, 0, 0.54); + font-size: 12px; + font-weight: 400; + line-height: 15px; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .mui-textfield > textarea { + padding-top: 5px; } + .mui-textfield > input, + .mui-textfield > textarea { + display: block; } + .mui-textfield > input:focus ~ label, + .mui-textfield > textarea:focus ~ label { + color: #2196F3; } + +.mui-textfield--float-label > label { + position: absolute; + transform: translate(0px, 15px); + font-size: 16px; + line-height: 32px; + color: rgba(0, 0, 0, 0.26); + text-overflow: clip; + cursor: text; + pointer-events: none; } + +.mui-textfield--float-label > input:focus ~ label, +.mui-textfield--float-label > textarea:focus ~ label { + transform: translate(0px, 0px); + font-size: 12px; + line-height: 15px; + text-overflow: ellipsis; } + +.mui-textfield--float-label > input:not(:focus).mui--is-not-empty ~ label, .mui-textfield--float-label > input:not(:focus)[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, .mui-textfield--float-label > input:not(:focus):not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield--float-label > textarea:not(:focus).mui--is-not-empty ~ label, +.mui-textfield--float-label > textarea:not(:focus)[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield--float-label > textarea:not(:focus):not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label { + color: rgba(0, 0, 0, 0.54); + font-size: 12px; + line-height: 15px; + transform: translate(0px, 0px); + text-overflow: ellipsis; } + +.mui-textfield--wrap-label { + display: table; + width: 100%; + padding-top: 0px; } + .mui-textfield--wrap-label:not(.mui-textfield--float-label) > label { + display: table-header-group; + position: static; + white-space: normal; + overflow-x: visible; } + +.mui-textfield > input, +.mui-textfield > textarea { + animation-duration: 0.0001s; + animation-name: mui-node-inserted; + display: block; + background-color: transparent; + color: #FFF; + border: none; + border-bottom: 1px solid rgba(0, 0, 0, 0.26); + outline: none; + width: 100%; + font-size: 16px; + padding: 0; + box-shadow: none; + border-radius: 0px; + background-image: none; } + .mui-textfield > input:focus, + .mui-textfield > textarea:focus { + border-color: #2196F3; + border-width: 2px; } + .mui-textfield > input:disabled, .mui-textfield > input:read-only, + .mui-textfield > textarea:disabled, + .mui-textfield > textarea:read-only { + cursor: not-allowed; + background-color: transparent; + opacity: 1; } + .mui-textfield > input::placeholder, + .mui-textfield > textarea::placeholder { + color: rgba(0, 0, 0, 0.26); + opacity: 1; } + +.mui-textfield > input { + height: 32px; } + .mui-textfield > input:focus { + height: 33px; + margin-bottom: -1px; } + +.mui-textfield > textarea { + min-height: 64px; } + .mui-textfield > textarea[rows]:not([rows="2"]):focus { + margin-bottom: -1px; } + +.mui-textfield > input:focus { + height: 33px; + margin-bottom: -1px; } + +.mui-textfield > input:invalid:not(:focus):not(:required), .mui-textfield > input:invalid:not(:focus):required.mui--is-not-empty, .mui-textfield > input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty, .mui-textfield > input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), .mui-textfield > input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > textarea:invalid:not(:focus):not(:required), +.mui-textfield > textarea:invalid:not(:focus):required.mui--is-not-empty, +.mui-textfield > textarea:invalid:not(:focus):required.mui--is-empty.mui--is-dirty, +.mui-textfield > textarea:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > textarea:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > input:not(:focus).mui--is-invalid:not(:required), +.mui-textfield > input:not(:focus).mui--is-invalid:required.mui--is-not-empty, +.mui-textfield > input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty, +.mui-textfield > input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > textarea:not(:focus).mui--is-invalid:not(:required), +.mui-textfield > textarea:not(:focus).mui--is-invalid:required.mui--is-not-empty, +.mui-textfield > textarea:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty, +.mui-textfield > textarea:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > textarea:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) { + border-color: #F44336; + border-width: 2px; } + +.mui-textfield > input:invalid:not(:focus):not(:required), .mui-textfield > input:invalid:not(:focus):required.mui--is-not-empty, .mui-textfield > input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty, .mui-textfield > input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), .mui-textfield > input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > input:not(:focus).mui--is-invalid:not(:required), +.mui-textfield > input:not(:focus).mui--is-invalid:required.mui--is-not-empty, +.mui-textfield > input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty, +.mui-textfield > input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty), +.mui-textfield > input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) { + height: 33px; + margin-bottom: -1px; } + +.mui-textfield > input:invalid:not(:focus):not(:required) ~ label, .mui-textfield > input:invalid:not(:focus):required.mui--is-not-empty ~ label, .mui-textfield > input:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, .mui-textfield > input:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > textarea:invalid:not(:focus):not(:required) ~ label, +.mui-textfield > textarea:invalid:not(:focus):required.mui--is-not-empty ~ label, +.mui-textfield > textarea:invalid:not(:focus):required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > textarea:invalid:not(:focus):required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > input:not(:focus).mui--is-invalid:not(:required) ~ label, +.mui-textfield > input:not(:focus).mui--is-invalid:required.mui--is-not-empty ~ label, +.mui-textfield > input:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > input:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > textarea:not(:focus).mui--is-invalid:not(:required) ~ label, +.mui-textfield > textarea:not(:focus).mui--is-invalid:required.mui--is-not-empty ~ label, +.mui-textfield > textarea:not(:focus).mui--is-invalid:required[value]:not([value=""]):not(.mui--is-empty):not(.mui--is-not-empty) ~ label, +.mui-textfield > textarea:not(:focus).mui--is-invalid:required:not(:empty):not(.mui--is-empty):not(.mui--is-not-empty) ~ label { + color: #F44336; } + +.mui-textfield:not(.mui-textfield--float-label) > input:invalid:not(:focus):required.mui--is-empty.mui--is-dirty ~ label, +.mui-textfield:not(.mui-textfield--float-label) > textarea:invalid:not(:focus):required.mui--is-empty.mui--is-dirty ~ label, +.mui-textfield:not(.mui-textfield--float-label) > input:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty ~ label, +.mui-textfield:not(.mui-textfield--float-label) > textarea:not(:focus).mui--is-invalid:required.mui--is-empty.mui--is-dirty ~ label { + color: #F44336; } + +/** + * MUI Helpers module + */ +@keyframes mui-node-inserted { + from { + opacity: 0.99; } + to { + opacity: 1; } } + +.mui--no-transition { + transition: none !important; } + +.mui--no-user-select { + user-select: none; } + +.mui-caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } + +.mui--text-left { + text-align: left !important; } + +.mui--text-right { + text-align: right !important; } + +.mui--text-center { + text-align: center !important; } + +.mui--text-justify { + text-align: justify !important; } + +.mui--text-nowrap { + white-space: nowrap !important; } + +.mui--align-baseline { + vertical-align: baseline !important; } + +.mui--align-top { + vertical-align: top !important; } + +.mui--align-middle { + vertical-align: middle !important; } + +.mui--align-bottom { + vertical-align: bottom !important; } + +.mui--text-dark { + color: rgba(0, 0, 0, 0.87); } + +.mui--text-dark-secondary { + color: rgba(0, 0, 0, 0.54); } + +.mui--text-dark-hint { + color: rgba(0, 0, 0, 0.38); } + +.mui--text-light { + color: #FFF; } + +.mui--text-light-secondary { + color: rgba(255, 255, 255, 0.7); } + +.mui--text-light-hint { + color: rgba(255, 255, 255, 0.3); } + +.mui--text-accent { + color: #F50057; } + +.mui--text-accent-secondary { + color: rgba(186, 214, 73, 0.54); } + +.mui--text-accent-hint { + color: rgba(186, 214, 73, 0.38); } + +.mui--text-black { + color: #000; } + +.mui--text-white { + color: #FFF; } + +.mui--text-danger { + color: #F44336; } + +.mui--bg-primary { + background-color: #2196F3; } + +.mui--bg-primary-dark { + background-color: #424242; } + +.mui--bg-primary-light { + background-color: #BBDEFB; } + +.mui--bg-accent { + background-color: #bad649; } + +.mui--bg-accent-dark { + background-color: #B9F6CA; } + +.mui--bg-accent-light { + background-color: #00E676; } + +.mui--bg-danger { + background-color: #F44336; } + +.mui-list--unstyled { + padding-left: 0; + list-style: none; } + +.mui-list--inline { + padding-left: 0; + list-style: none; + margin-left: -5px; } + .mui-list--inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; } + +.mui--z1, .mui-dropdown__menu, .mui-select__menu { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); } + +.mui--z2 { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); } + +.mui--z3 { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } + +.mui--z4 { + box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } + +.mui--z5 { + box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22); } + +.mui--clearfix:before, .mui--clearfix:after { + content: " "; + display: table; } + +.mui--clearfix:after { + clear: both; } + +.mui--pull-right { + float: right !important; } + +.mui--pull-left { + float: left !important; } + +.mui--hide { + display: none !important; } + +.mui--show { + display: block !important; } + +.mui--invisible { + visibility: hidden; } + +.mui--overflow-hidden { + overflow: hidden !important; } + +.mui--overflow-hidden-x { + overflow-x: hidden !important; } + +.mui--overflow-hidden-y { + overflow-y: hidden !important; } + +.mui--visible-xs-block, +.mui--visible-xs-inline, +.mui--visible-xs-inline-block, +.mui--visible-sm-block, +.mui--visible-sm-inline, +.mui--visible-sm-inline-block, +.mui--visible-md-block, +.mui--visible-md-inline, +.mui--visible-md-inline-block, +.mui--visible-lg-block, +.mui--visible-lg-inline, +.mui--visible-lg-inline-block, +.mui--visible-xl-block, +.mui--visible-xl-inline, +.mui--visible-xl-inline-block { + display: none !important; } + +@media (max-width: 543px) { + .mui-visible-xs { + display: block !important; } + table.mui-visible-xs { + display: table; } + tr.mui-visible-xs { + display: table-row !important; } + th.mui-visible-xs, + td.mui-visible-xs { + display: table-cell !important; } + .mui--visible-xs-block { + display: block !important; } + .mui--visible-xs-inline { + display: inline !important; } + .mui--visible-xs-inline-block { + display: inline-block !important; } } + +@media (min-width: 544px) and (max-width: 767px) { + .mui-visible-sm { + display: block !important; } + table.mui-visible-sm { + display: table; } + tr.mui-visible-sm { + display: table-row !important; } + th.mui-visible-sm, + td.mui-visible-sm { + display: table-cell !important; } + .mui--visible-sm-block { + display: block !important; } + .mui--visible-sm-inline { + display: inline !important; } + .mui--visible-sm-inline-block { + display: inline-block !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .mui-visible-md { + display: block !important; } + table.mui-visible-md { + display: table; } + tr.mui-visible-md { + display: table-row !important; } + th.mui-visible-md, + td.mui-visible-md { + display: table-cell !important; } + .mui--visible-md-block { + display: block !important; } + .mui--visible-md-inline { + display: inline !important; } + .mui--visible-md-inline-block { + display: inline-block !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .mui-visible-lg { + display: block !important; } + table.mui-visible-lg { + display: table; } + tr.mui-visible-lg { + display: table-row !important; } + th.mui-visible-lg, + td.mui-visible-lg { + display: table-cell !important; } + .mui--visible-lg-block { + display: block !important; } + .mui--visible-lg-inline { + display: inline !important; } + .mui--visible-lg-inline-block { + display: inline-block !important; } } + +@media (min-width: 1200px) { + .mui-visible-xl { + display: block !important; } + table.mui-visible-xl { + display: table; } + tr.mui-visible-xl { + display: table-row !important; } + th.mui-visible-xl, + td.mui-visible-xl { + display: table-cell !important; } + .mui--visible-xl-block { + display: block !important; } + .mui--visible-xl-inline { + display: inline !important; } + .mui--visible-xl-inline-block { + display: inline-block !important; } } + +@media (max-width: 543px) { + .mui--hidden-xs { + display: none !important; } } + +@media (min-width: 544px) and (max-width: 767px) { + .mui--hidden-sm { + display: none !important; } } + +@media (min-width: 768px) and (max-width: 991px) { + .mui--hidden-md { + display: none !important; } } + +@media (min-width: 992px) and (max-width: 1199px) { + .mui--hidden-lg { + display: none !important; } } + +@media (min-width: 1200px) { + .mui--hidden-xl { + display: none !important; } } + +body.mui-body--scroll-lock { + overflow: hidden !important; } + +/** + * MUI Overlay module + */ +#mui-overlay { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 99999999; + background-color: rgba(0, 0, 0, 0.2); + overflow: auto; } + +/** + * MUI Ripple module + */ +.mui-ripple-effect { + position: absolute; + border-radius: 50%; + pointer-events: none; + opacity: 0.4; + transform: scale(0.0001); } + .mui-ripple-effect.mui--animate-in { + opacity: 0; + transform: scale(1); + transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1), opacity 0.6s cubic-bezier(0, 0, 0.2, 1); } + .mui-ripple-effect.mui--active { + opacity: 0.3; } + .mui-ripple-effect.mui--animate-out { + opacity: 0; + transition: opacity 0.6s cubic-bezier(0, 0, 0.2, 1); } + +.mui-btn > .mui-ripple-effect { + background-color: #a6a6a6; } + +.mui-btn--primary > .mui-ripple-effect { + background-color: #FFF; } + +.mui-btn--dark > .mui-ripple-effect { + background-color: #FFF; } + +.mui-btn--danger > .mui-ripple-effect { + background-color: #FFF; } + +.mui-btn--accent > .mui-ripple-effect { + background-color: #FFF; } + +.mui-btn--flat > .mui-ripple-effect { + background-color: #a6a6a6; } + +/** + * MUI Typography module + */ +.mui--text-display4 { + font-weight: 300; + font-size: 112px; + line-height: 112px; } + +.mui--text-display3 { + font-weight: 400; + font-size: 56px; + line-height: 56px; } + +.mui--text-display2 { + font-weight: 400; + font-size: 45px; + line-height: 48px; } + +.mui--text-display1, h1 { + font-weight: 400; + font-size: 34px; + line-height: 40px; } + +.mui--text-headline, h2 { + font-weight: 400; + font-size: 24px; + line-height: 32px; } + +.mui--text-title, h3 { + font-weight: 400; + font-size: 20px; + line-height: 28px; } + +.mui--text-subhead, h4 { + font-weight: 400; + font-size: 16px; + line-height: 24px; } + +.mui--text-body2, h5 { + font-weight: 500; + font-size: 14px; + line-height: 24px; } + +.mui--text-body1 { + font-weight: 400; + font-size: 14px; + line-height: 20px; } + +.mui--text-caption { + font-weight: 400; + font-size: 12px; + line-height: 16px; } + +.mui--text-menu { + font-weight: 500; + font-size: 13px; + line-height: 17px; } + +.mui--text-button { + font-weight: 500; + font-size: 14px; + line-height: 18px; + text-transform: uppercase; } diff --git a/mdot/mDotServer.censis/mDotServer.censis/app/css/test.css b/mdot/mDotServer.censis/mDotServer.censis/app/css/test.css index eec97a3..c2d12f0 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/app/css/test.css +++ b/mdot/mDotServer.censis/mDotServer.censis/app/css/test.css @@ -3,3 +3,23 @@ color:rgba(255,0,99,1); } + + +[mui-row~="gutter--flush"],[data-mui-row~="gutter--flush"],[mui-row~="gutter"],[data-mui-row~="gutter"] { + padding-left: 1em +} + +[mui-row~="gutter--flush"]>[mui-col],[data-mui-row~="gutter--flush"]>[mui-col],[mui-row~="gutter--flush"]>[data-mui-col],[data-mui-row~="gutter--flush"]>[data-mui-col],[mui-row~="gutter"]>[mui-col],[mui-row~="gutter"]>[data-mui-col],[data-mui-row~="gutter"]>[mui-col],[data-mui-row~="gutter"]>[data-mui-col] { + padding-right: 1em +} + +[mui-row~="gutter--flush"],[data-mui-row~="gutter--flush"] { + margin-left: -1em; + margin-right: -1em +} + + +.spacer { + margin-top: 15px; + + } diff --git a/mdot/mDotServer.censis/mDotServer.censis/app/js/mdot.js b/mdot/mDotServer.censis/mDotServer.censis/app/js/mdot.js index ddb76d3..aa4efdd 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/app/js/mdot.js +++ b/mdot/mDotServer.censis/mDotServer.censis/app/js/mdot.js @@ -139,7 +139,7 @@ }; var minmaxesA = [ - {low:578,high:656, mp:617, count:1}, + {low:640,high:656, mp:617, count:1}, {low:657,high:709, mp:695, count:2}, {low:710,high:737, mp:723, count:3}, {low:738,high:778, mp:752, count:4}, @@ -160,6 +160,8 @@ skipOccupancy = true; } + skipOccupancy = true; + _(events.data).each(function(i) { var _occupancy = 0; diff --git a/mdot/mDotServer.censis/mDotServer.censis/app/js/websocket.js b/mdot/mDotServer.censis/mDotServer.censis/app/js/websocket.js index 84f9803..6121187 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/app/js/websocket.js +++ b/mdot/mDotServer.censis/mDotServer.censis/app/js/websocket.js @@ -2,6 +2,12 @@ var WEBSOCKET = function(model) { var wsUrl = 'ws://localhost:3001'; + if ('https:' === document.location.protocol) { + wsUrl = 'wss://mdotserver.bluemix.net:3001'; + } else { + wsUrl = 'ws://localhost:3001'; + } + this.socket = null; this.timer = 0; diff --git a/mdot/mDotServer.censis/mDotServer.censis/custom.scss b/mdot/mDotServer.censis/mDotServer.censis/custom.scss new file mode 100644 index 0000000..ce7618b --- /dev/null +++ b/mdot/mDotServer.censis/mDotServer.censis/custom.scss @@ -0,0 +1,16 @@ +@import "./src/bower_modules/mui/src/sass/mui/colors"; + +$mui-body-bg-color: mui-color('grey','900'); +$mui-input-font-color: mui-color('white'); +$mui-base-font-family: Ubuntu, Arial, Verdana, Tahoma !default; +$mui-primary-color-dark: mui-color('grey','800'); +$mui-accent-color: #bad649; +$mui-text-accent: mui-color('pink','A400'); +$mui-btn-accent-font-color: #004c6d; +$mui-accent-color-dark: mui-color('green', 'A100'); +$mui-accent-color-light: mui-color('green', 'A400'); +$mui-tab-font-color: rgba(255, 255, 255, 0.87); + + +// import MUI SASS +@import "./src/bower_modules/mui/src/sass/mui"; diff --git a/mdot/mDotServer.censis/mDotServer.censis/lib/server/db-connector.js b/mdot/mDotServer.censis/mDotServer.censis/lib/server/db-connector.js index e219a2e..e74c107 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/lib/server/db-connector.js +++ b/mdot/mDotServer.censis/mDotServer.censis/lib/server/db-connector.js @@ -9,7 +9,7 @@ var pgp = require('pg-promise')(); -var cn = { +var localCN = { host: 'localhost', port: 5432, database: 'mdot', @@ -19,13 +19,15 @@ var cn = { // ElephantSql settings -/*var cn = { +var remoteCN = { host: 'jumbo.db.elephantsql.com', port: 5432, database: 'amlrxqev', user: 'amlrxqev', password: 'K11cvCplk0--oNafsYj4ISN-rVQmVS3y' -};*/ +}; + +const cn = process.env.NODE_ENV === 'production' ? remoteCN : localCN; + exports.dbConnection = pgp(cn); - diff --git a/mdot/mDotServer.censis/mDotServer.censis/lib/sockethandler.js b/mdot/mDotServer.censis/mDotServer.censis/lib/sockethandler.js index 2f5c63d..b6d088d 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/lib/sockethandler.js +++ b/mdot/mDotServer.censis/mDotServer.censis/lib/sockethandler.js @@ -8,6 +8,7 @@ var WebSocketServer = require('websocket').server; var http = require('http'); +var https = require('https'); var logger = require('log4js').getLogger(); diff --git a/mdot/mDotServer.censis/mDotServer.censis/package.json b/mdot/mDotServer.censis/mDotServer.censis/package.json index c533233..a820bf4 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/package.json +++ b/mdot/mDotServer.censis/mDotServer.censis/package.json @@ -80,7 +80,7 @@ "scripts": { "test": "mocha --recursive --reporter spec --bail --check-leaks --timeout 3000", "start": "node app.js", - "prepublish": "gulp default" + "prepublish": "" }, "author": "Martin Donnelly", "license": "ISC", diff --git a/mdot/mDotServer.censis/mDotServer.censis/views/test.ejs b/mdot/mDotServer.censis/mDotServer.censis/views/test.ejs index 870d2dd..e395191 100644 --- a/mdot/mDotServer.censis/mDotServer.censis/views/test.ejs +++ b/mdot/mDotServer.censis/mDotServer.censis/views/test.ejs @@ -19,6 +19,7 @@ + + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mdot/mqttArchiver/mqttArchiver/app.js b/mdot/mqttArchiver/mqttArchiver/app.js index 41a6506..fbf5a7c 100644 --- a/mdot/mqttArchiver/mqttArchiver/app.js +++ b/mdot/mqttArchiver/mqttArchiver/app.js @@ -26,7 +26,6 @@ var mqtt = new mqttClient.mqttClient(busEmitter); var historianApi = require('./lib/historian/emulator.js'); - var app = express(); var port = (process.env.VCAP_APP_PORT || 3010); @@ -39,8 +38,23 @@ if (process.env.NODE_ENV === 'production') { isProduction = true; } +var restartTimer = 0; + logger.warn('isProduction:', isProduction); +var doRestart = () => { + mqtt = new mqttClient.mqttClient(busEmitter); +}; + +busEmitter.on('MAJORERROR', () => { + 'use strict'; + logger.warn('Major error discovered. Restarting MQTT Service in 10 seconds.'); + + clearTimeout(restartTimer); + restartTimer = setTimeout(doRestart, 10000); + +}); + var heartBeat = function() { console.log(this); diff --git a/mdot/mqttArchiver/mqttArchiver/lib/mailer.js b/mdot/mqttArchiver/mqttArchiver/lib/mailer.js new file mode 100644 index 0000000..b456f2a --- /dev/null +++ b/mdot/mqttArchiver/mqttArchiver/lib/mailer.js @@ -0,0 +1,44 @@ +/** + * + * User: Martin Donnelly + * Date: 2016-04-08 + * Time: 16:35 + * + */ +var UltraSES = require('ultrases'), dateFormat = require('dateformat'); + +var logger = require('log4js').getLogger(); + +var mailer = new UltraSES({ + aws: { + accessKeyId: 'AKIAJWJS75F7WNCGK64A', + secretAccessKey: '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', + region: 'eu-west-1' + }, defaults: { + from: 'Martin Donnelly ' + } +}); + +const prefix = process.env.NODE_ENV === 'production' ? 'Production' : 'Dev'; + +module.exports = { + + sendEmailV1: function(contents) { + var now = new Date(); + var email = { + to: 'martind2000@gmail.com', subject: 'MQTT ' + prefix + ' Archiver Alert' + }; + + var msg = '

MQTT ' + prefix + ' Archiver Alert

Alert logged at ' + dateFormat(now, "dddd, mmmm dS, yyyy, HH:MM:ss") + '

' + contents + '
'; + + mailer.sendHTML(email, msg, function(err){ + if(err) { + logger.error(err); + throw err; + } + logger.info('email sent!'); + }); + + + } +}; diff --git a/mdot/mqttArchiver/mqttArchiver/lib/mqtt/mqttClient.js b/mdot/mqttArchiver/mqttArchiver/lib/mqtt/mqttClient.js index b72c314..689e493 100644 --- a/mdot/mqttArchiver/mqttArchiver/lib/mqtt/mqttClient.js +++ b/mdot/mqttArchiver/mqttArchiver/lib/mqtt/mqttClient.js @@ -1,3 +1,4 @@ +'use strict'; var mqtt = require('mqtt'); var logger = require('log4js').getLogger(); @@ -10,17 +11,26 @@ var requestify = require('requestify'); var db = require('../server/db-connector').dbConnection; var dbSave = require('../server/db-save')(db); +var emailer = require('../mailer'); //var nano = require('nano')('http://martind2000:1V3D4m526i@localhost:5984'); +/* var nano = require('nano')('http://localhost:5984'); var db_name = 'mqttarchive'; var dbCouch = nano.use(db_name); +*/ +let remoteHost = process.env.NODE_ENV === 'production' ? 'http://mdotserver.mybluemix.net/apiv2/message' : 'http://localhost:3011/apiv2/message'; function dataBuilder(obj) { - 'use strict'; + var now = new Date(); - var newObj = {device_type: 'mDot', evt_type: 'update', timestamp: {}, evt: {}}; + var newObj = { + device_type: 'mDot', + evt_type: 'update', + timestamp: {}, + evt: {} + }; newObj.device_id = obj.topic.split('/')[4]; @@ -30,7 +40,6 @@ function dataBuilder(obj) { return newObj; } - function saveToDB(data) { // logger.debug('Inserting into couch...'); // Logger.info(util.inspect(obj)); @@ -45,28 +54,28 @@ function saveToDB(data) { var doSendMessage = (obj) => { 'use strict'; - requestify.post('http://localhost:3011/apiv2/message', obj) - //requestify.post('http://mdotserver.mybluemix.net/apiv2/message', obj) - .then(function(response) { - // Get the response body - // logger.debug(response.getBody()); - }) + + + requestify.post(remoteHost, obj) + .then(function(response) { + // Get the response body + // logger.debug(response.getBody()); + }) .catch(function(e) { - logger.error('doSendMessage',e); + logger.error('doSendMessage', e); }); }; - var doInsertEntry = (obj) => { // Logger.info('sendSocket: ' + JSON.stringify(obj)); - // insertEntry(obj); + // insertEntry(obj); dbSave.addNewEvent(obj) .then(function(d) { 'use strict'; - logger.info('Obj',obj.type); - saveToDB(obj); + // logger.info('Obj', obj.type); + // saveToDB(obj); if (obj.type === 'mDot') { busEmitter.emit('sendMessage', obj); } @@ -76,92 +85,106 @@ var doInsertEntry = (obj) => { logger.error(e); }); - +}; +var watchDog = 0; +var watchDogTimeout = () => { + 'use strict'; + logger.warn( + 'Watchdog timeout. Message has not been received for over 90 seconds.'); + emailer.sendEmailV1('Watchdog timeout. Message has not been received for over 90 seconds.'); }; - var mqttClient = function() { -var count=0; - var subscribeTopic; - var orgId = 'qz0da4'; - var userName = 'a-qz0da4-dfwwdkmkzr'; - var address = '.messaging.internetofthings.ibmcloud.com'; - var appKey = '9txJEf3Cjy7hkSOvkv'; - //Var subscribeTopic = prefix + deviceId + '/evt/+/fmt/json'; + var count = 0; + var subscribeTopic; + var orgId = 'qz0da4'; + var userName = 'a-qz0da4-dfwwdkmkzr'; + var address = '.messaging.internetofthings.ibmcloud.com'; + var appKey = '9txJEf3Cjy7hkSOvkv'; + var connection = 'mqtt://' + orgId + address; - this.connected = false; + this.connected = false; - var options = { - keepalive: 10, - clientId: 'a:' + orgId + ':' + Date.now(), - username: userName, - password: new Buffer(appKey), - reconnectPeriod:1000, - connectTimeout:30 * 1000 + var options = { + keepalive: 10, + clientId: 'a:' + orgId + ':' + Date.now(), + username: userName, + password: new Buffer(appKey), + reconnectPeriod: 1000, + connectTimeout: 30 * 1000 - }; + }; - this.client = mqtt.connect('mqtt://' + orgId + address, options); + logger.info('Connecting to ', connection); + //this.client = mqtt.connect(connection, options); + this.client = mqtt.connect('mqtt://' + orgId + address, options); - this.client.on('connect', function() { - connected = true; - logger.info('Connected to ', address); - }.bind(this)); + this.client.on('connect', function() { + // connected = true; + logger.info('Connected to ', address); + emailer.sendEmailV1('Connected to ' + address); + }.bind(this)); this.client.on('connected', function() { - logger.debug('mqttConnect - doConnection - Connected'); + logger.debug('mqttConnect - doConnection - Connected'); - }); + watchDog = setTimeout(watchDogTimeout, 90000); + console.log(watchDog); + + }); this.client.on('close', function() { logger.warn('mqttConnect - Connection closed'); + }); this.client.on('offline', function() { logger.warn('mqttConnect - OFFLINE!'); + emailer.sendEmailV1('mqttConnect - OFFLINE!'); }); - this.client.on('error', function(e) { logger.error('mqttConnect - error'); logger.error(e); }); this.client.on('reconnect', function() { - logger.warn('mqttConnect - Attempting to reconnect...'); + logger.warn('mqttConnect - Attempting to reconnect...'); - }); + }); subscribeTopic = 'iot-2/type/+/id/+/evt/+/fmt/json'; + //subscribeTopic = 'livingroomTemp'; logger.info('Subscribing:', subscribeTopic); + this.client.subscribe(subscribeTopic); - this.client.on('message', function(topic, message) { + this.client.on('message', function(topic, message) { - var json = JSON.parse(message.toString()); + var json = JSON.parse(message.toString()); - var topicArray = topic.split('/'); - json.topic = topic; - json.type = topicArray[2]; - json.device = topicArray[4]; - json.event = topicArray[6]; + var topicArray = topic.split('/'); + json.topic = topic; + json.type = topicArray[2]; + json.device = topicArray[4]; + json.event = topicArray[6]; - busEmitter.emit('saveData', json); - count++; + busEmitter.emit('saveData', json); + clearTimeout(watchDog); + watchDog = setTimeout(watchDogTimeout, 20000); + count++; - }.bind(this)); + }.bind(this)); - busEmitter.on('saveData', doInsertEntry); - busEmitter.on('sendMessage', doSendMessage); + busEmitter.on('saveData', doInsertEntry); + busEmitter.on('sendMessage', doSendMessage); this.getCount = function() { 'use strict'; return count; } - }; - - +}; module.exports.mqttClient = mqttClient; diff --git a/mdot/mqttArchiver/mqttArchiver/lib/server/db-connector.js b/mdot/mqttArchiver/mqttArchiver/lib/server/db-connector.js index 48207b0..8007530 100644 --- a/mdot/mqttArchiver/mqttArchiver/lib/server/db-connector.js +++ b/mdot/mqttArchiver/mqttArchiver/lib/server/db-connector.js @@ -9,7 +9,7 @@ var pgp = require('pg-promise')(); -var cn = { +var localCN = { host: 'localhost', port: 5432, database: 'mqttstore', @@ -19,15 +19,16 @@ var cn = { // ElephantSql settings -/* -var cn = { +var remoteCN = { host: 'jumbo.db.elephantsql.com', port: 5432, database: 'vmlcokon', user: 'vmlcokon', password: 'PQUYLiIW4M6r7SWyZevrES_rRAULYFkp' }; -*/ + + +const cn = process.env.NODE_ENV === 'production' ? remoteCN : localCN; exports.dbConnection = pgp(cn); diff --git a/mdot/mqttArchiver/mqttArchiver/package.json b/mdot/mqttArchiver/mqttArchiver/package.json index c70ab63..ca77843 100644 --- a/mdot/mqttArchiver/mqttArchiver/package.json +++ b/mdot/mqttArchiver/mqttArchiver/package.json @@ -1,5 +1,5 @@ { - "name": "mdot_mqtt", + "name": "mqttArchiver", "version": "1.0.0", "description": "", "main": "index.js", @@ -14,6 +14,7 @@ "body-parser": "^1.15.2", "cfenv": "1.0.x", "cookie-parser": "^1.4.3", + "dateformat": "^1.0.12", "ejs": "^2.5.1", "errorhandler": "^1.4.3", "events": "^1.1.1", @@ -35,6 +36,7 @@ "routes": "^2.1.0", "sugar": "^2.0.1", "sugar-date": "^2.0.0", + "ultrases": "^0.1.3", "websocket": "^1.0.22" }, "devDependencies": { @@ -81,6 +83,6 @@ "author": "Martin Donnelly ", "license": "ISC", "engines": { - "node": "5.7.0" + "node": "6.0.0" } }