Compare commits

...

2 Commits

Author SHA1 Message Date
7f1a85d430 Added Device services for back and frontend 2020-11-07 14:19:29 +01:00
05a8d7f090 Added logout button functionality 2020-11-04 12:34:37 +01:00
27 changed files with 4443 additions and 46 deletions

View File

@ -1733,6 +1733,11 @@
"@types/node": "*"
}
},
"@types/googlemaps": {
"version": "3.40.3",
"resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.40.3.tgz",
"integrity": "sha512-ivlG5S0LlnQgpgPnQCUNAs7kjBtO367ZwDmuK+ggsQfW+w4N0RyWbxWZ6vPwegDe50Du3Xbb5+QVwJuB/U1XpA=="
},
"@types/history": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.3.tgz",
@ -6321,6 +6326,19 @@
}
}
},
"google-maps": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/google-maps/-/google-maps-4.3.3.tgz",
"integrity": "sha512-MQbEgBNQbGyV7mfS2tlFgW4EoGKLia24BvAl4a+kgsYWt4283kyPpaay/yKIsScQLr7nSUONaLNfOdMsCuJDEw==",
"requires": {
"@types/googlemaps": "^3.39.1"
}
},
"google-maps-react": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/google-maps-react/-/google-maps-react-2.0.6.tgz",
"integrity": "sha512-M8Eo9WndfQEfxcmm6yRq03qdJgw1x6rQmJ9DN+a+xPQ3K7yNDGkVDbinrf4/8vcox7nELbeopbm4bpefKewWfQ=="
},
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",

View File

@ -8,11 +8,13 @@
"@material-ui/lab": "^4.0.0-alpha.56",
"bootstrap": "^4.3.1",
"connected-react-router": "6.5.2",
"google-maps": "^4.3.3",
"google-maps-react": "^2.0.6",
"history": "4.10.1",
"jquery": "^3.5.1",
"merge": "1.2.1",
"popper.js": "^1.16.0",
"react": "16.11.0",
"react": "^16.11.0",
"react-dom": "16.11.0",
"react-redux": "7.1.1",
"react-router": "5.1.2",

View File

@ -1,4 +1,4 @@
import { Box, Container, IconButton, Menu, MenuItem } from '@material-ui/core';
import { Box, Container, IconButton, Menu, MenuItem, MenuList, Paper, Grow, Popper } from '@material-ui/core';
import AccountCircle from '@material-ui/icons/AccountCircle';
import AppBar from '@material-ui/core/AppBar';
import blue from '@material-ui/core/colors/blue';
@ -7,11 +7,12 @@ import { createMuiTheme, createStyles, makeStyles, Theme } from '@material-ui/co
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import { ThemeProvider } from '@material-ui/styles';
import React, { useState } from 'react';
import { BrowserRouter, NavLink, Redirect, Route, Switch } from 'react-router-dom';
import React, { useState, } from 'react';
import { BrowserRouter, NavLink, Redirect, Route, Switch, Link } from 'react-router-dom';
import BirdmapTitle from './common/components/BirdmapTitle';
import Auth from './components/auth/Auth';
import AuthService from './components/auth/AuthService';
import { ClickAwayListener } from '@material-ui/core';
const theme = createMuiTheme({
@ -87,17 +88,47 @@ const PrivateRoute = ({ component: Component, authenticated: Authenticated, ...r
const DefaultLayout = ({ component: Component, authenticated: Authenticated, ...rest }: { [x: string]: any, component: any, authenticated: any }) => {
const classes = useDefaultLayoutStyles();
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const [open, setOpen] = React.useState(false);
const anchorRef = React.useRef<HTMLButtonElement>(null);
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = () => {
setAnchorEl(null);
const handleClose = (event: React.MouseEvent<EventTarget>) => {
if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) {
return;
}
setOpen(false);
};
const handleLogout = (event: React.MouseEvent<EventTarget>) => {
if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) {
return;
}
AuthService.logout();
setOpen(false);
};
function handleListKeyDown(event: React.KeyboardEvent) {
if (event.key === 'Tab') {
event.preventDefault();
setOpen(false);
}
}
const prevOpen = React.useRef(open);
React.useEffect(() => {
if (prevOpen.current === true && open === false) {
anchorRef.current!.focus();
}
prevOpen.current = open;
}, [open]);
const renderNavLinks = () => {
return Authenticated
? <Container className={classes.nav_menu}>
@ -105,28 +136,28 @@ const DefaultLayout = ({ component: Component, authenticated: Authenticated, ...
<NavLink exact to="/devices" className={classes.nav_menu_item} activeClassName={classes.nav_menu_item_active}>Devices</NavLink>
<NavLink exact to="/heatmap" className={classes.nav_menu_item} activeClassName={classes.nav_menu_item_active}>Heatmap</NavLink>
<IconButton className={classes.nav_menu_icon}
ref={anchorRef}
aria-haspopup="true"
aria-controls="menu-appbar"
aria-controls={open ? 'menu-list-grow' : undefined}
aria-label="account of current user"
onClick={handleMenu}>
onClick={handleToggle}>
<AccountCircle/>
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={open}
onClose={handleClose}>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} transition disablePortal>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{ transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom' }}>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList autoFocusItem={open} id="menu-list-grow" onKeyDown={handleListKeyDown}>
<MenuItem onClick={handleLogout} component={Link} {...{ to: '/login' }}>Logout</MenuItem>
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</Container>
: null;
};

View File

@ -5,6 +5,7 @@ import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import AuthService from './AuthService';
export default function Auth(props: any) {
props.onAuthenticated();
const history = useHistory();
const classes = useStyles();
@ -36,7 +37,6 @@ export default function Auth(props: any) {
};
const onLoginClicked = () => {
setIsLoggingIn(true);
if (!username) {
setShowError(true);
@ -52,6 +52,7 @@ export default function Auth(props: any) {
return;
}
setIsLoggingIn(true);
AuthService.login(username, password)
.then(() => {
props.onAuthenticated();
@ -86,7 +87,7 @@ export default function Auth(props: any) {
</Typography>
</Grid>
<Grid item xs={12} >
<TextField label="Username" type="text" onChange={onUsernameChanged} />
<TextField autoFocus label="Username" type="text" onChange={onUsernameChanged} />
</Grid>
<Grid item xs={12} >
<TextField label="Password" type="password" onChange={onPasswordChanged} onKeyPress={onPasswordKeyPress} />

View File

@ -9,6 +9,10 @@ exports.default = {
isAdmin: function () {
return sessionStorage.getItem('role') === 'Admin';
},
logout: function () {
sessionStorage.removeItem('user');
sessionStorage.removeItem('role');
},
login: function (username, password) {
var body = {
username: username,

View File

@ -1 +1 @@
{"version":3,"file":"AuthService.js","sourceRoot":"","sources":["AuthService.ts"],"names":[],"mappings":";;AAAA,wDAAmD;AAEnD,IAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,kBAAe;IACX,eAAe;QACX,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACnD,CAAC;IAED,OAAO;QACH,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC;IACtD,CAAC;IAED,KAAK,EAAL,UAAM,QAAgB,EAAE,QAAgB;QACpC,IAAI,IAAI,GAAG;YACP,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;SACrB,CAAC;QACF,IAAI,OAAO,GAAG;YACV,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC;QAEF,OAAO,qBAAW,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC;aAC7C,IAAI,CAAC,UAAA,QAAQ;YACV,cAAc,CAAC,OAAO,CAAC,MAAM,EAAK,QAAQ,CAAC,UAAU,SAAI,QAAQ,CAAC,YAAc,CAAC,CAAC;YAClF,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACX,CAAC;CACJ,CAAA"}
{"version":3,"file":"AuthService.js","sourceRoot":"","sources":["AuthService.ts"],"names":[],"mappings":";;AAAA,wDAAmD;AAEnD,IAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,kBAAe;IACX,eAAe;QACX,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACnD,CAAC;IAED,OAAO;QACH,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC;IACtD,CAAC;IAED,MAAM;QACF,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAClC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,EAAL,UAAM,QAAgB,EAAE,QAAgB;QACpC,IAAI,IAAI,GAAG;YACP,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;SACrB,CAAC;QACF,IAAI,OAAO,GAAG;YACV,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC;QAEF,OAAO,qBAAW,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC;aAC7C,IAAI,CAAC,UAAA,QAAQ;YACV,cAAc,CAAC,OAAO,CAAC,MAAM,EAAK,QAAQ,CAAC,UAAU,SAAI,QAAQ,CAAC,YAAc,CAAC,CAAC;YAClF,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACX,CAAC;CACJ,CAAA"}

View File

@ -11,6 +11,11 @@ export default {
return sessionStorage.getItem('role') === 'Admin';
},
logout() {
sessionStorage.removeItem('user');
sessionStorage.removeItem('role');
},
login(username: string, password: string) {
let body = {
username: username,

View File

@ -0,0 +1,601 @@
"use strict";
/* tslint:disable */
/* eslint-disable */
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
// ReSharper disable InconsistentNaming
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiException = exports.SensorStatus = exports.Coordinates = exports.DeviceStatus = exports.Sensor = exports.Device = exports.DeviceService = void 0;
var DeviceService = /** @class */ (function () {
function DeviceService(baseUrl, http) {
this.jsonParseReviver = undefined;
this.http = http ? http : window;
this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "api/devices";
}
/**
* Get all device info
* @return Array of devices
*/
DeviceService.prototype.getall = function () {
var _this = this;
var url_ = this.baseUrl;
var options_ = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processGetall(_response);
});
};
DeviceService.prototype.processGetall = function (response) {
var _this = this;
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
var result200 = null;
var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver);
if (Array.isArray(resultData200)) {
result200 = [];
for (var _i = 0, resultData200_1 = resultData200; _i < resultData200_1.length; _i++) {
var item = resultData200_1[_i];
result200.push(Device.fromJS(item));
}
}
return result200;
});
}
else if (status === 404) {
return response.text().then(function (_responseText) {
return throwException("No device found", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Shut down all devices
* @return Message sent
*/
DeviceService.prototype.offlineall = function () {
var _this = this;
var url_ = this.baseUrl + "/offline";
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOfflineall(_response);
});
};
DeviceService.prototype.processOfflineall = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Bring all devices online
* @return Message sent
*/
DeviceService.prototype.onlineall = function () {
var _this = this;
var url_ = this.baseUrl + "/online";
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOnlineall(_response);
});
};
DeviceService.prototype.processOnlineall = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Get all device info
* @param deviceID ID of device to query
* @return Information about a particular device
*/
DeviceService.prototype.getdevice = function (deviceID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processGetdevice(_response);
});
};
DeviceService.prototype.processGetdevice = function (response) {
var _this = this;
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
var result200 = null;
var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver);
result200 = Device.fromJS(resultData200);
return result200;
});
}
else if (status === 404) {
return response.text().then(function (_responseText) {
return throwException("Device not found", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Shut down device
* @param deviceID ID of device to shut down
* @return Message sent
*/
DeviceService.prototype.offlinedevice = function (deviceID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}/offline";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOfflinedevice(_response);
});
};
DeviceService.prototype.processOfflinedevice = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Bring device online
* @param deviceID ID of device to bring online
* @return Message sent
*/
DeviceService.prototype.onlinedevice = function (deviceID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}/online";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOnlinedevice(_response);
});
};
DeviceService.prototype.processOnlinedevice = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Get info about a particular device's sensor
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Information about a sensor
*/
DeviceService.prototype.getsensor = function (deviceID, sensorID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}/{sensorID}";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processGetsensor(_response);
});
};
DeviceService.prototype.processGetsensor = function (response) {
var _this = this;
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
var result200 = null;
var resultData200 = _responseText === "" ? null : JSON.parse(_responseText, _this.jsonParseReviver);
result200 = Sensor.fromJS(resultData200);
return result200;
});
}
else if (status === 404) {
return response.text().then(function (_responseText) {
return throwException("Device or sensor not found", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Shut down sensor
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Message sent
*/
DeviceService.prototype.offlinesensor = function (deviceID, sensorID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}/{sensorID}/offline";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOfflinesensor(_response);
});
};
DeviceService.prototype.processOfflinesensor = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
/**
* Bring sensor online
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Message sent
*/
DeviceService.prototype.onlinesensor = function (deviceID, sensorID) {
var _this = this;
var url_ = this.baseUrl + "/{deviceID}/{sensorID}/online";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
var options_ = {
method: "POST",
headers: {}
};
return this.http.fetch(url_, options_).then(function (_response) {
return _this.processOnlinesensor(_response);
});
};
DeviceService.prototype.processOnlinesensor = function (response) {
var status = response.status;
var _headers = {};
if (response.headers && response.headers.forEach) {
response.headers.forEach(function (v, k) { return _headers[k] = v; });
}
;
if (status === 200) {
return response.text().then(function (_responseText) {
return;
});
}
else if (status === 500) {
return response.text().then(function (_responseText) {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
}
else if (status !== 200 && status !== 204) {
return response.text().then(function (_responseText) {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve(null);
};
return DeviceService;
}());
exports.DeviceService = DeviceService;
var Device = /** @class */ (function () {
function Device(data) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
this[property] = data[property];
}
}
if (!data) {
this.coordinates = new Coordinates();
this.sensors = [];
}
}
Device.prototype.init = function (_data) {
if (_data) {
this.id = _data["id"];
this.status = _data["status"];
this.url = _data["url"];
this.coordinates = _data["coordinates"] ? Coordinates.fromJS(_data["coordinates"]) : new Coordinates();
if (Array.isArray(_data["sensors"])) {
this.sensors = [];
for (var _i = 0, _a = _data["sensors"]; _i < _a.length; _i++) {
var item = _a[_i];
this.sensors.push(Sensor.fromJS(item));
}
}
}
};
Device.fromJS = function (data) {
data = typeof data === 'object' ? data : {};
var result = new Device();
result.init(data);
return result;
};
Device.prototype.toJSON = function (data) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["status"] = this.status;
data["url"] = this.url;
data["coordinates"] = this.coordinates ? this.coordinates.toJSON() : undefined;
if (Array.isArray(this.sensors)) {
data["sensors"] = [];
for (var _i = 0, _a = this.sensors; _i < _a.length; _i++) {
var item = _a[_i];
data["sensors"].push(item.toJSON());
}
}
return data;
};
return Device;
}());
exports.Device = Device;
var Sensor = /** @class */ (function () {
function Sensor(data) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
this[property] = data[property];
}
}
}
Sensor.prototype.init = function (_data) {
if (_data) {
this.id = _data["id"];
this.status = _data["status"];
}
};
Sensor.fromJS = function (data) {
data = typeof data === 'object' ? data : {};
var result = new Sensor();
result.init(data);
return result;
};
Sensor.prototype.toJSON = function (data) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["status"] = this.status;
return data;
};
return Sensor;
}());
exports.Sensor = Sensor;
var DeviceStatus;
(function (DeviceStatus) {
DeviceStatus["Online"] = "online";
DeviceStatus["Error"] = "error";
DeviceStatus["Offline"] = "offline";
})(DeviceStatus = exports.DeviceStatus || (exports.DeviceStatus = {}));
var Coordinates = /** @class */ (function () {
function Coordinates(data) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
this[property] = data[property];
}
}
}
Coordinates.prototype.init = function (_data) {
if (_data) {
this.latitude = _data["latitude"];
this.longitude = _data["longitude"];
}
};
Coordinates.fromJS = function (data) {
data = typeof data === 'object' ? data : {};
var result = new Coordinates();
result.init(data);
return result;
};
Coordinates.prototype.toJSON = function (data) {
data = typeof data === 'object' ? data : {};
data["latitude"] = this.latitude;
data["longitude"] = this.longitude;
return data;
};
return Coordinates;
}());
exports.Coordinates = Coordinates;
var SensorStatus;
(function (SensorStatus) {
SensorStatus["Online"] = "online";
SensorStatus["Unknown"] = "unknown";
SensorStatus["Offline"] = "offline";
})(SensorStatus = exports.SensorStatus || (exports.SensorStatus = {}));
var ApiException = /** @class */ (function (_super) {
__extends(ApiException, _super);
function ApiException(message, status, response, headers, result) {
var _this = _super.call(this) || this;
_this.isApiException = true;
_this.message = message;
_this.status = status;
_this.response = response;
_this.headers = headers;
_this.result = result;
return _this;
}
ApiException.isApiException = function (obj) {
return obj.isApiException === true;
};
return ApiException;
}(Error));
exports.ApiException = ApiException;
function throwException(message, status, response, headers, result) {
if (result !== null && result !== undefined)
throw result;
else
throw new ApiException(message, status, response, headers, null);
}
//# sourceMappingURL=DeviceService.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,599 @@
/* tslint:disable */
/* eslint-disable */
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
// ReSharper disable InconsistentNaming
export class DeviceService {
private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
private baseUrl: string;
protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
this.http = http ? http : <any>window;
this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "api/devices";
}
/**
* Get all device info
* @return Array of devices
*/
getall(): Promise<Device[]> {
let url_ = this.baseUrl;
let options_ = <RequestInit>{
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetall(_response);
});
}
protected processGetall(response: Response): Promise<Device[]> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
if (Array.isArray(resultData200)) {
result200 = [] as any;
for (let item of resultData200)
result200!.push(Device.fromJS(item));
}
return result200;
});
} else if (status === 404) {
return response.text().then((_responseText) => {
return throwException("No device found", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<Device[]>(<any>null);
}
/**
* Shut down all devices
* @return Message sent
*/
offlineall(): Promise<void> {
let url_ = this.baseUrl + "/offline";
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOfflineall(_response);
});
}
protected processOfflineall(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
/**
* Bring all devices online
* @return Message sent
*/
onlineall(): Promise<void> {
let url_ = this.baseUrl + "/online";
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOnlineall(_response);
});
}
protected processOnlineall(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
/**
* Get all device info
* @param deviceID ID of device to query
* @return Information about a particular device
*/
getdevice(deviceID: string): Promise<Device> {
let url_ = this.baseUrl + "/{deviceID}";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetdevice(_response);
});
}
protected processGetdevice(response: Response): Promise<Device> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = Device.fromJS(resultData200);
return result200;
});
} else if (status === 404) {
return response.text().then((_responseText) => {
return throwException("Device not found", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<Device>(<any>null);
}
/**
* Shut down device
* @param deviceID ID of device to shut down
* @return Message sent
*/
offlinedevice(deviceID: string): Promise<void> {
let url_ = this.baseUrl + "/{deviceID}/offline";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOfflinedevice(_response);
});
}
protected processOfflinedevice(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
/**
* Bring device online
* @param deviceID ID of device to bring online
* @return Message sent
*/
onlinedevice(deviceID: string): Promise<void> {
let url_ = this.baseUrl + "/{deviceID}/online";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOnlinedevice(_response);
});
}
protected processOnlinedevice(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
/**
* Get info about a particular device's sensor
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Information about a sensor
*/
getsensor(deviceID: string, sensorID: string): Promise<Sensor> {
let url_ = this.baseUrl + "/{deviceID}/{sensorID}";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "GET",
headers: {
"Accept": "application/json"
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processGetsensor(_response);
});
}
protected processGetsensor(response: Response): Promise<Sensor> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = Sensor.fromJS(resultData200);
return result200;
});
} else if (status === 404) {
return response.text().then((_responseText) => {
return throwException("Device or sensor not found", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<Sensor>(<any>null);
}
/**
* Shut down sensor
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Message sent
*/
offlinesensor(deviceID: string, sensorID: string): Promise<void> {
let url_ = this.baseUrl + "/{deviceID}/{sensorID}/offline";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOfflinesensor(_response);
});
}
protected processOfflinesensor(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
/**
* Bring sensor online
* @param deviceID ID of device to query
* @param sensorID ID of sensor to query
* @return Message sent
*/
onlinesensor(deviceID: string, sensorID: string): Promise<void> {
let url_ = this.baseUrl + "/{deviceID}/{sensorID}/online";
if (deviceID === undefined || deviceID === null)
throw new Error("The parameter 'deviceID' must be defined.");
url_ = url_.replace("{deviceID}", encodeURIComponent("" + deviceID));
if (sensorID === undefined || sensorID === null)
throw new Error("The parameter 'sensorID' must be defined.");
url_ = url_.replace("{sensorID}", encodeURIComponent("" + sensorID));
url_ = url_.replace(/[?&]$/, "");
let options_ = <RequestInit>{
method: "POST",
headers: {
}
};
return this.http.fetch(url_, options_).then((_response: Response) => {
return this.processOnlinesensor(_response);
});
}
protected processOnlinesensor(response: Response): Promise<void> {
const status = response.status;
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
if (status === 200) {
return response.text().then((_responseText) => {
return;
});
} else if (status === 500) {
return response.text().then((_responseText) => {
return throwException("Message sending unsuccessful", status, _responseText, _headers);
});
} else if (status !== 200 && status !== 204) {
return response.text().then((_responseText) => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
});
}
return Promise.resolve<void>(<any>null);
}
}
export class Device implements IDevice {
id!: string;
status!: DeviceStatus;
url!: string;
coordinates!: Coordinates;
sensors!: Sensor[];
constructor(data?: IDevice) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
if (!data) {
this.coordinates = new Coordinates();
this.sensors = [];
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.status = _data["status"];
this.url = _data["url"];
this.coordinates = _data["coordinates"] ? Coordinates.fromJS(_data["coordinates"]) : new Coordinates();
if (Array.isArray(_data["sensors"])) {
this.sensors = [] as any;
for (let item of _data["sensors"])
this.sensors!.push(Sensor.fromJS(item));
}
}
}
static fromJS(data: any): Device {
data = typeof data === 'object' ? data : {};
let result = new Device();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["status"] = this.status;
data["url"] = this.url;
data["coordinates"] = this.coordinates ? this.coordinates.toJSON() : <any>undefined;
if (Array.isArray(this.sensors)) {
data["sensors"] = [];
for (let item of this.sensors)
data["sensors"].push(item.toJSON());
}
return data;
}
}
export interface IDevice {
id: string;
status: DeviceStatus;
url: string;
coordinates: Coordinates;
sensors: Sensor[];
}
export class Sensor implements ISensor {
id!: string;
status!: SensorStatus;
constructor(data?: ISensor) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.status = _data["status"];
}
}
static fromJS(data: any): Sensor {
data = typeof data === 'object' ? data : {};
let result = new Sensor();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["status"] = this.status;
return data;
}
}
export interface ISensor {
id: string;
status: SensorStatus;
}
export enum DeviceStatus {
Online = "online",
Error = "error",
Offline = "offline",
}
export class Coordinates implements ICoordinates {
latitude!: number;
longitude!: number;
constructor(data?: ICoordinates) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.latitude = _data["latitude"];
this.longitude = _data["longitude"];
}
}
static fromJS(data: any): Coordinates {
data = typeof data === 'object' ? data : {};
let result = new Coordinates();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["latitude"] = this.latitude;
data["longitude"] = this.longitude;
return data;
}
}
export interface ICoordinates {
latitude: number;
longitude: number;
}
export enum SensorStatus {
Online = "online",
Unknown = "unknown",
Offline = "offline",
}
export class ApiException extends Error {
message: string;
status: number;
response: string;
headers: { [key: string]: any; };
result: any;
constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
super();
this.message = message;
this.status = status;
this.response = response;
this.headers = headers;
this.result = result;
}
protected isApiException = true;
static isApiException(obj: any): obj is ApiException {
return obj.isApiException === true;
}
}
function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {
if (result !== null && result !== undefined)
throw result;
else
throw new ApiException(message, status, response, headers, null);
}

View File

@ -0,0 +1,555 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initMap = void 0;
var google_maps_1 = require("google-maps");
var map, heatmap;
function initMap() {
var options = { /* todo */};
var loader = new google_maps_1.Loader('AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY', options);
loader.load().then(function (google) {
map = new google.maps.Map(document.getElementById("map"), {
zoom: 13,
center: { lat: 37.775, lng: -122.434 },
mapTypeId: "satellite",
});
heatmap = new google.maps.visualization.HeatmapLayer({
data: getPoints(),
map: map,
});
});
}
exports.initMap = initMap;
function toggleHeatmap() {
heatmap.setMap(heatmap.getMap() ? null : map);
}
function changeGradient() {
var gradient = [
"rgba(0, 255, 255, 0)",
"rgba(0, 255, 255, 1)",
"rgba(0, 191, 255, 1)",
"rgba(0, 127, 255, 1)",
"rgba(0, 63, 255, 1)",
"rgba(0, 0, 255, 1)",
"rgba(0, 0, 223, 1)",
"rgba(0, 0, 191, 1)",
"rgba(0, 0, 159, 1)",
"rgba(0, 0, 127, 1)",
"rgba(63, 0, 91, 1)",
"rgba(127, 0, 63, 1)",
"rgba(191, 0, 31, 1)",
"rgba(255, 0, 0, 1)",
];
heatmap.set("gradient", heatmap.get("gradient") ? null : gradient);
}
function changeRadius() {
heatmap.set("radius", heatmap.get("radius") ? null : 20);
}
function changeOpacity() {
heatmap.set("opacity", heatmap.get("opacity") ? null : 0.2);
}
// Heatmap data: 500 Points
function getPoints() {
return [
new google.maps.LatLng(37.782551, -122.445368),
new google.maps.LatLng(37.782745, -122.444586),
new google.maps.LatLng(37.782842, -122.443688),
new google.maps.LatLng(37.782919, -122.442815),
new google.maps.LatLng(37.782992, -122.442112),
new google.maps.LatLng(37.7831, -122.441461),
new google.maps.LatLng(37.783206, -122.440829),
new google.maps.LatLng(37.783273, -122.440324),
new google.maps.LatLng(37.783316, -122.440023),
new google.maps.LatLng(37.783357, -122.439794),
new google.maps.LatLng(37.783371, -122.439687),
new google.maps.LatLng(37.783368, -122.439666),
new google.maps.LatLng(37.783383, -122.439594),
new google.maps.LatLng(37.783508, -122.439525),
new google.maps.LatLng(37.783842, -122.439591),
new google.maps.LatLng(37.784147, -122.439668),
new google.maps.LatLng(37.784206, -122.439686),
new google.maps.LatLng(37.784386, -122.43979),
new google.maps.LatLng(37.784701, -122.439902),
new google.maps.LatLng(37.784965, -122.439938),
new google.maps.LatLng(37.78501, -122.439947),
new google.maps.LatLng(37.78536, -122.439952),
new google.maps.LatLng(37.785715, -122.44003),
new google.maps.LatLng(37.786117, -122.440119),
new google.maps.LatLng(37.786564, -122.440209),
new google.maps.LatLng(37.786905, -122.44027),
new google.maps.LatLng(37.786956, -122.440279),
new google.maps.LatLng(37.800224, -122.43352),
new google.maps.LatLng(37.800155, -122.434101),
new google.maps.LatLng(37.80016, -122.43443),
new google.maps.LatLng(37.800378, -122.434527),
new google.maps.LatLng(37.800738, -122.434598),
new google.maps.LatLng(37.800938, -122.43465),
new google.maps.LatLng(37.801024, -122.434889),
new google.maps.LatLng(37.800955, -122.435392),
new google.maps.LatLng(37.800886, -122.435959),
new google.maps.LatLng(37.800811, -122.436275),
new google.maps.LatLng(37.800788, -122.436299),
new google.maps.LatLng(37.800719, -122.436302),
new google.maps.LatLng(37.800702, -122.436298),
new google.maps.LatLng(37.800661, -122.436273),
new google.maps.LatLng(37.800395, -122.436172),
new google.maps.LatLng(37.800228, -122.436116),
new google.maps.LatLng(37.800169, -122.43613),
new google.maps.LatLng(37.800066, -122.436167),
new google.maps.LatLng(37.784345, -122.422922),
new google.maps.LatLng(37.784389, -122.422926),
new google.maps.LatLng(37.784437, -122.422924),
new google.maps.LatLng(37.784746, -122.422818),
new google.maps.LatLng(37.785436, -122.422959),
new google.maps.LatLng(37.78612, -122.423112),
new google.maps.LatLng(37.786433, -122.423029),
new google.maps.LatLng(37.786631, -122.421213),
new google.maps.LatLng(37.78666, -122.421033),
new google.maps.LatLng(37.786801, -122.420141),
new google.maps.LatLng(37.786823, -122.420034),
new google.maps.LatLng(37.786831, -122.419916),
new google.maps.LatLng(37.787034, -122.418208),
new google.maps.LatLng(37.787056, -122.418034),
new google.maps.LatLng(37.787169, -122.417145),
new google.maps.LatLng(37.787217, -122.416715),
new google.maps.LatLng(37.786144, -122.416403),
new google.maps.LatLng(37.785292, -122.416257),
new google.maps.LatLng(37.780666, -122.390374),
new google.maps.LatLng(37.780501, -122.391281),
new google.maps.LatLng(37.780148, -122.392052),
new google.maps.LatLng(37.780173, -122.391148),
new google.maps.LatLng(37.780693, -122.390592),
new google.maps.LatLng(37.781261, -122.391142),
new google.maps.LatLng(37.781808, -122.39173),
new google.maps.LatLng(37.78234, -122.392341),
new google.maps.LatLng(37.782812, -122.393022),
new google.maps.LatLng(37.7833, -122.393672),
new google.maps.LatLng(37.783809, -122.394275),
new google.maps.LatLng(37.784246, -122.394979),
new google.maps.LatLng(37.784791, -122.395958),
new google.maps.LatLng(37.785675, -122.396746),
new google.maps.LatLng(37.786262, -122.39578),
new google.maps.LatLng(37.786776, -122.395093),
new google.maps.LatLng(37.787282, -122.394426),
new google.maps.LatLng(37.787783, -122.393767),
new google.maps.LatLng(37.788343, -122.393184),
new google.maps.LatLng(37.788895, -122.392506),
new google.maps.LatLng(37.789371, -122.391701),
new google.maps.LatLng(37.789722, -122.390952),
new google.maps.LatLng(37.790315, -122.390305),
new google.maps.LatLng(37.790738, -122.389616),
new google.maps.LatLng(37.779448, -122.438702),
new google.maps.LatLng(37.779023, -122.438585),
new google.maps.LatLng(37.778542, -122.438492),
new google.maps.LatLng(37.7781, -122.438411),
new google.maps.LatLng(37.777986, -122.438376),
new google.maps.LatLng(37.77768, -122.438313),
new google.maps.LatLng(37.777316, -122.438273),
new google.maps.LatLng(37.777135, -122.438254),
new google.maps.LatLng(37.776987, -122.438303),
new google.maps.LatLng(37.776946, -122.438404),
new google.maps.LatLng(37.776944, -122.438467),
new google.maps.LatLng(37.776892, -122.438459),
new google.maps.LatLng(37.776842, -122.438442),
new google.maps.LatLng(37.776822, -122.438391),
new google.maps.LatLng(37.776814, -122.438412),
new google.maps.LatLng(37.776787, -122.438628),
new google.maps.LatLng(37.776729, -122.43865),
new google.maps.LatLng(37.776759, -122.438677),
new google.maps.LatLng(37.776772, -122.438498),
new google.maps.LatLng(37.776787, -122.438389),
new google.maps.LatLng(37.776848, -122.438283),
new google.maps.LatLng(37.77687, -122.438239),
new google.maps.LatLng(37.777015, -122.438198),
new google.maps.LatLng(37.777333, -122.438256),
new google.maps.LatLng(37.777595, -122.438308),
new google.maps.LatLng(37.777797, -122.438344),
new google.maps.LatLng(37.77816, -122.438442),
new google.maps.LatLng(37.778414, -122.438508),
new google.maps.LatLng(37.778445, -122.438516),
new google.maps.LatLng(37.778503, -122.438529),
new google.maps.LatLng(37.778607, -122.438549),
new google.maps.LatLng(37.77867, -122.438644),
new google.maps.LatLng(37.778847, -122.438706),
new google.maps.LatLng(37.77924, -122.438744),
new google.maps.LatLng(37.779738, -122.438822),
new google.maps.LatLng(37.780201, -122.438882),
new google.maps.LatLng(37.7804, -122.438905),
new google.maps.LatLng(37.780501, -122.438921),
new google.maps.LatLng(37.780892, -122.438986),
new google.maps.LatLng(37.781446, -122.439087),
new google.maps.LatLng(37.781985, -122.439199),
new google.maps.LatLng(37.782239, -122.439249),
new google.maps.LatLng(37.782286, -122.439266),
new google.maps.LatLng(37.797847, -122.429388),
new google.maps.LatLng(37.797874, -122.42918),
new google.maps.LatLng(37.797885, -122.429069),
new google.maps.LatLng(37.797887, -122.42905),
new google.maps.LatLng(37.797933, -122.428954),
new google.maps.LatLng(37.798242, -122.42899),
new google.maps.LatLng(37.798617, -122.429075),
new google.maps.LatLng(37.798719, -122.429092),
new google.maps.LatLng(37.798944, -122.429145),
new google.maps.LatLng(37.79932, -122.429251),
new google.maps.LatLng(37.79959, -122.429309),
new google.maps.LatLng(37.799677, -122.429324),
new google.maps.LatLng(37.799966, -122.42936),
new google.maps.LatLng(37.800288, -122.42943),
new google.maps.LatLng(37.800443, -122.429461),
new google.maps.LatLng(37.800465, -122.429474),
new google.maps.LatLng(37.800644, -122.42954),
new google.maps.LatLng(37.800948, -122.42962),
new google.maps.LatLng(37.801242, -122.429685),
new google.maps.LatLng(37.801375, -122.429702),
new google.maps.LatLng(37.8014, -122.429703),
new google.maps.LatLng(37.801453, -122.429707),
new google.maps.LatLng(37.801473, -122.429709),
new google.maps.LatLng(37.801532, -122.429707),
new google.maps.LatLng(37.801852, -122.429729),
new google.maps.LatLng(37.802173, -122.429789),
new google.maps.LatLng(37.802459, -122.429847),
new google.maps.LatLng(37.802554, -122.429825),
new google.maps.LatLng(37.802647, -122.429549),
new google.maps.LatLng(37.802693, -122.429179),
new google.maps.LatLng(37.802729, -122.428751),
new google.maps.LatLng(37.766104, -122.409291),
new google.maps.LatLng(37.766103, -122.409268),
new google.maps.LatLng(37.766138, -122.409229),
new google.maps.LatLng(37.766183, -122.409231),
new google.maps.LatLng(37.766153, -122.409276),
new google.maps.LatLng(37.766005, -122.409365),
new google.maps.LatLng(37.765897, -122.40957),
new google.maps.LatLng(37.765767, -122.409739),
new google.maps.LatLng(37.765693, -122.410389),
new google.maps.LatLng(37.765615, -122.411201),
new google.maps.LatLng(37.765533, -122.412121),
new google.maps.LatLng(37.765467, -122.412939),
new google.maps.LatLng(37.765444, -122.414821),
new google.maps.LatLng(37.765444, -122.414964),
new google.maps.LatLng(37.765318, -122.415424),
new google.maps.LatLng(37.763961, -122.415296),
new google.maps.LatLng(37.763115, -122.415196),
new google.maps.LatLng(37.762967, -122.415183),
new google.maps.LatLng(37.762278, -122.415127),
new google.maps.LatLng(37.761675, -122.415055),
new google.maps.LatLng(37.760932, -122.414988),
new google.maps.LatLng(37.759337, -122.414862),
new google.maps.LatLng(37.773187, -122.421922),
new google.maps.LatLng(37.773043, -122.422118),
new google.maps.LatLng(37.773007, -122.422165),
new google.maps.LatLng(37.772979, -122.422219),
new google.maps.LatLng(37.772865, -122.422394),
new google.maps.LatLng(37.772779, -122.422503),
new google.maps.LatLng(37.772676, -122.422701),
new google.maps.LatLng(37.772606, -122.422806),
new google.maps.LatLng(37.772566, -122.42284),
new google.maps.LatLng(37.772508, -122.422852),
new google.maps.LatLng(37.772387, -122.423011),
new google.maps.LatLng(37.772099, -122.423328),
new google.maps.LatLng(37.771704, -122.423783),
new google.maps.LatLng(37.771481, -122.424081),
new google.maps.LatLng(37.7714, -122.424179),
new google.maps.LatLng(37.771352, -122.42422),
new google.maps.LatLng(37.771248, -122.424327),
new google.maps.LatLng(37.770904, -122.424781),
new google.maps.LatLng(37.77052, -122.425283),
new google.maps.LatLng(37.770337, -122.425553),
new google.maps.LatLng(37.770128, -122.425832),
new google.maps.LatLng(37.769756, -122.426331),
new google.maps.LatLng(37.7693, -122.426902),
new google.maps.LatLng(37.769132, -122.427065),
new google.maps.LatLng(37.769092, -122.427103),
new google.maps.LatLng(37.768979, -122.427172),
new google.maps.LatLng(37.768595, -122.427634),
new google.maps.LatLng(37.768372, -122.427913),
new google.maps.LatLng(37.768337, -122.427961),
new google.maps.LatLng(37.768244, -122.428138),
new google.maps.LatLng(37.767942, -122.428581),
new google.maps.LatLng(37.767482, -122.429094),
new google.maps.LatLng(37.767031, -122.429606),
new google.maps.LatLng(37.766732, -122.429986),
new google.maps.LatLng(37.76668, -122.430058),
new google.maps.LatLng(37.766633, -122.430109),
new google.maps.LatLng(37.76658, -122.430211),
new google.maps.LatLng(37.766367, -122.430594),
new google.maps.LatLng(37.76591, -122.431137),
new google.maps.LatLng(37.765353, -122.431806),
new google.maps.LatLng(37.764962, -122.432298),
new google.maps.LatLng(37.764868, -122.432486),
new google.maps.LatLng(37.764518, -122.432913),
new google.maps.LatLng(37.763435, -122.434173),
new google.maps.LatLng(37.762847, -122.434953),
new google.maps.LatLng(37.762291, -122.435935),
new google.maps.LatLng(37.762224, -122.436074),
new google.maps.LatLng(37.761957, -122.436892),
new google.maps.LatLng(37.761652, -122.438886),
new google.maps.LatLng(37.761284, -122.439955),
new google.maps.LatLng(37.76121, -122.440068),
new google.maps.LatLng(37.761064, -122.44072),
new google.maps.LatLng(37.76104, -122.441411),
new google.maps.LatLng(37.761048, -122.442324),
new google.maps.LatLng(37.760851, -122.443118),
new google.maps.LatLng(37.759977, -122.444591),
new google.maps.LatLng(37.759913, -122.444698),
new google.maps.LatLng(37.759623, -122.445065),
new google.maps.LatLng(37.758902, -122.445158),
new google.maps.LatLng(37.758428, -122.44457),
new google.maps.LatLng(37.757687, -122.44334),
new google.maps.LatLng(37.757583, -122.44324),
new google.maps.LatLng(37.757019, -122.442787),
new google.maps.LatLng(37.756603, -122.442322),
new google.maps.LatLng(37.75638, -122.441602),
new google.maps.LatLng(37.75579, -122.441382),
new google.maps.LatLng(37.754493, -122.442133),
new google.maps.LatLng(37.754361, -122.442206),
new google.maps.LatLng(37.753719, -122.44265),
new google.maps.LatLng(37.753096, -122.442915),
new google.maps.LatLng(37.751617, -122.443211),
new google.maps.LatLng(37.751496, -122.443246),
new google.maps.LatLng(37.750733, -122.443428),
new google.maps.LatLng(37.750126, -122.443536),
new google.maps.LatLng(37.750103, -122.443784),
new google.maps.LatLng(37.75039, -122.44401),
new google.maps.LatLng(37.750448, -122.444013),
new google.maps.LatLng(37.750536, -122.44404),
new google.maps.LatLng(37.750493, -122.444141),
new google.maps.LatLng(37.790859, -122.402808),
new google.maps.LatLng(37.790864, -122.402768),
new google.maps.LatLng(37.790995, -122.402539),
new google.maps.LatLng(37.791148, -122.402172),
new google.maps.LatLng(37.791385, -122.401312),
new google.maps.LatLng(37.791405, -122.400776),
new google.maps.LatLng(37.791288, -122.400528),
new google.maps.LatLng(37.791113, -122.400441),
new google.maps.LatLng(37.791027, -122.400395),
new google.maps.LatLng(37.791094, -122.400311),
new google.maps.LatLng(37.791211, -122.400183),
new google.maps.LatLng(37.79106, -122.399334),
new google.maps.LatLng(37.790538, -122.398718),
new google.maps.LatLng(37.790095, -122.398086),
new google.maps.LatLng(37.789644, -122.39736),
new google.maps.LatLng(37.789254, -122.396844),
new google.maps.LatLng(37.788855, -122.396397),
new google.maps.LatLng(37.788483, -122.395963),
new google.maps.LatLng(37.788015, -122.395365),
new google.maps.LatLng(37.787558, -122.394735),
new google.maps.LatLng(37.787472, -122.394323),
new google.maps.LatLng(37.78763, -122.394025),
new google.maps.LatLng(37.787767, -122.393987),
new google.maps.LatLng(37.787486, -122.394452),
new google.maps.LatLng(37.786977, -122.395043),
new google.maps.LatLng(37.786583, -122.395552),
new google.maps.LatLng(37.78654, -122.39561),
new google.maps.LatLng(37.786516, -122.395659),
new google.maps.LatLng(37.786378, -122.395707),
new google.maps.LatLng(37.786044, -122.395362),
new google.maps.LatLng(37.785598, -122.394715),
new google.maps.LatLng(37.785321, -122.394361),
new google.maps.LatLng(37.785207, -122.394236),
new google.maps.LatLng(37.785751, -122.394062),
new google.maps.LatLng(37.785996, -122.393881),
new google.maps.LatLng(37.786092, -122.39383),
new google.maps.LatLng(37.785998, -122.393899),
new google.maps.LatLng(37.785114, -122.394365),
new google.maps.LatLng(37.785022, -122.394441),
new google.maps.LatLng(37.784823, -122.394635),
new google.maps.LatLng(37.784719, -122.394629),
new google.maps.LatLng(37.785069, -122.394176),
new google.maps.LatLng(37.7855, -122.39365),
new google.maps.LatLng(37.78577, -122.393291),
new google.maps.LatLng(37.785839, -122.393159),
new google.maps.LatLng(37.782651, -122.400628),
new google.maps.LatLng(37.782616, -122.400599),
new google.maps.LatLng(37.782702, -122.40047),
new google.maps.LatLng(37.782915, -122.400192),
new google.maps.LatLng(37.783137, -122.399887),
new google.maps.LatLng(37.783414, -122.399519),
new google.maps.LatLng(37.783629, -122.399237),
new google.maps.LatLng(37.783688, -122.399157),
new google.maps.LatLng(37.783716, -122.399106),
new google.maps.LatLng(37.783798, -122.399072),
new google.maps.LatLng(37.783997, -122.399186),
new google.maps.LatLng(37.784271, -122.399538),
new google.maps.LatLng(37.784577, -122.399948),
new google.maps.LatLng(37.784828, -122.40026),
new google.maps.LatLng(37.784999, -122.400477),
new google.maps.LatLng(37.785113, -122.400651),
new google.maps.LatLng(37.785155, -122.400703),
new google.maps.LatLng(37.785192, -122.400749),
new google.maps.LatLng(37.785278, -122.400839),
new google.maps.LatLng(37.785387, -122.400857),
new google.maps.LatLng(37.785478, -122.40089),
new google.maps.LatLng(37.785526, -122.401022),
new google.maps.LatLng(37.785598, -122.401148),
new google.maps.LatLng(37.785631, -122.401202),
new google.maps.LatLng(37.78566, -122.401267),
new google.maps.LatLng(37.803986, -122.426035),
new google.maps.LatLng(37.804102, -122.425089),
new google.maps.LatLng(37.804211, -122.424156),
new google.maps.LatLng(37.803861, -122.423385),
new google.maps.LatLng(37.803151, -122.423214),
new google.maps.LatLng(37.802439, -122.423077),
new google.maps.LatLng(37.80174, -122.422905),
new google.maps.LatLng(37.801069, -122.422785),
new google.maps.LatLng(37.800345, -122.422649),
new google.maps.LatLng(37.799633, -122.422603),
new google.maps.LatLng(37.79975, -122.4217),
new google.maps.LatLng(37.799885, -122.420854),
new google.maps.LatLng(37.799209, -122.420607),
new google.maps.LatLng(37.795656, -122.400395),
new google.maps.LatLng(37.795203, -122.400304),
new google.maps.LatLng(37.778738, -122.415584),
new google.maps.LatLng(37.778812, -122.415189),
new google.maps.LatLng(37.778824, -122.415092),
new google.maps.LatLng(37.778833, -122.414932),
new google.maps.LatLng(37.778834, -122.414898),
new google.maps.LatLng(37.77874, -122.414757),
new google.maps.LatLng(37.778501, -122.414433),
new google.maps.LatLng(37.778182, -122.414026),
new google.maps.LatLng(37.777851, -122.413623),
new google.maps.LatLng(37.777486, -122.413166),
new google.maps.LatLng(37.777109, -122.412674),
new google.maps.LatLng(37.776743, -122.412186),
new google.maps.LatLng(37.77644, -122.4118),
new google.maps.LatLng(37.776295, -122.411614),
new google.maps.LatLng(37.776158, -122.41144),
new google.maps.LatLng(37.775806, -122.410997),
new google.maps.LatLng(37.775422, -122.410484),
new google.maps.LatLng(37.775126, -122.410087),
new google.maps.LatLng(37.775012, -122.409854),
new google.maps.LatLng(37.775164, -122.409573),
new google.maps.LatLng(37.775498, -122.40918),
new google.maps.LatLng(37.775868, -122.40873),
new google.maps.LatLng(37.776256, -122.40824),
new google.maps.LatLng(37.776519, -122.407928),
new google.maps.LatLng(37.776539, -122.407904),
new google.maps.LatLng(37.776595, -122.407854),
new google.maps.LatLng(37.776853, -122.407547),
new google.maps.LatLng(37.777234, -122.407087),
new google.maps.LatLng(37.777644, -122.406558),
new google.maps.LatLng(37.778066, -122.406017),
new google.maps.LatLng(37.778468, -122.405499),
new google.maps.LatLng(37.778866, -122.404995),
new google.maps.LatLng(37.779295, -122.404455),
new google.maps.LatLng(37.779695, -122.40395),
new google.maps.LatLng(37.779982, -122.403584),
new google.maps.LatLng(37.780295, -122.403223),
new google.maps.LatLng(37.780664, -122.402766),
new google.maps.LatLng(37.781043, -122.402288),
new google.maps.LatLng(37.781399, -122.401823),
new google.maps.LatLng(37.781727, -122.401407),
new google.maps.LatLng(37.781853, -122.401247),
new google.maps.LatLng(37.781894, -122.401195),
new google.maps.LatLng(37.782076, -122.400977),
new google.maps.LatLng(37.782338, -122.400603),
new google.maps.LatLng(37.782666, -122.400133),
new google.maps.LatLng(37.783048, -122.399634),
new google.maps.LatLng(37.78345, -122.399198),
new google.maps.LatLng(37.783791, -122.398998),
new google.maps.LatLng(37.784177, -122.398959),
new google.maps.LatLng(37.784388, -122.398971),
new google.maps.LatLng(37.784404, -122.399128),
new google.maps.LatLng(37.784586, -122.399524),
new google.maps.LatLng(37.784835, -122.399927),
new google.maps.LatLng(37.785116, -122.400307),
new google.maps.LatLng(37.785282, -122.400539),
new google.maps.LatLng(37.785346, -122.400692),
new google.maps.LatLng(37.765769, -122.407201),
new google.maps.LatLng(37.76579, -122.407414),
new google.maps.LatLng(37.765802, -122.407755),
new google.maps.LatLng(37.765791, -122.408219),
new google.maps.LatLng(37.765763, -122.408759),
new google.maps.LatLng(37.765726, -122.409348),
new google.maps.LatLng(37.765716, -122.409882),
new google.maps.LatLng(37.765708, -122.410202),
new google.maps.LatLng(37.765705, -122.410253),
new google.maps.LatLng(37.765707, -122.410369),
new google.maps.LatLng(37.765692, -122.41072),
new google.maps.LatLng(37.765699, -122.411215),
new google.maps.LatLng(37.765687, -122.411789),
new google.maps.LatLng(37.765666, -122.412373),
new google.maps.LatLng(37.765598, -122.412883),
new google.maps.LatLng(37.765543, -122.413039),
new google.maps.LatLng(37.765532, -122.413125),
new google.maps.LatLng(37.7655, -122.413553),
new google.maps.LatLng(37.765448, -122.414053),
new google.maps.LatLng(37.765388, -122.414645),
new google.maps.LatLng(37.765323, -122.41525),
new google.maps.LatLng(37.765303, -122.415847),
new google.maps.LatLng(37.765251, -122.416439),
new google.maps.LatLng(37.765204, -122.41702),
new google.maps.LatLng(37.765172, -122.417556),
new google.maps.LatLng(37.765164, -122.418075),
new google.maps.LatLng(37.765153, -122.418618),
new google.maps.LatLng(37.765136, -122.419112),
new google.maps.LatLng(37.765129, -122.419378),
new google.maps.LatLng(37.765119, -122.419481),
new google.maps.LatLng(37.7651, -122.419852),
new google.maps.LatLng(37.765083, -122.420349),
new google.maps.LatLng(37.765045, -122.42093),
new google.maps.LatLng(37.764992, -122.421481),
new google.maps.LatLng(37.76498, -122.421695),
new google.maps.LatLng(37.764993, -122.421843),
new google.maps.LatLng(37.764986, -122.422255),
new google.maps.LatLng(37.764975, -122.422823),
new google.maps.LatLng(37.764939, -122.423411),
new google.maps.LatLng(37.764902, -122.424014),
new google.maps.LatLng(37.764853, -122.424576),
new google.maps.LatLng(37.764826, -122.424922),
new google.maps.LatLng(37.764796, -122.425375),
new google.maps.LatLng(37.764782, -122.425869),
new google.maps.LatLng(37.764768, -122.426089),
new google.maps.LatLng(37.764766, -122.426117),
new google.maps.LatLng(37.764723, -122.426276),
new google.maps.LatLng(37.764681, -122.426649),
new google.maps.LatLng(37.782012, -122.4042),
new google.maps.LatLng(37.781574, -122.404911),
new google.maps.LatLng(37.781055, -122.405597),
new google.maps.LatLng(37.780479, -122.406341),
new google.maps.LatLng(37.779996, -122.406939),
new google.maps.LatLng(37.779459, -122.407613),
new google.maps.LatLng(37.778953, -122.408228),
new google.maps.LatLng(37.778409, -122.408839),
new google.maps.LatLng(37.777842, -122.409501),
new google.maps.LatLng(37.777334, -122.410181),
new google.maps.LatLng(37.776809, -122.410836),
new google.maps.LatLng(37.77624, -122.411514),
new google.maps.LatLng(37.775725, -122.412145),
new google.maps.LatLng(37.77519, -122.412805),
new google.maps.LatLng(37.774672, -122.413464),
new google.maps.LatLng(37.774084, -122.414186),
new google.maps.LatLng(37.773533, -122.413636),
new google.maps.LatLng(37.773021, -122.413009),
new google.maps.LatLng(37.772501, -122.412371),
new google.maps.LatLng(37.771964, -122.411681),
new google.maps.LatLng(37.771479, -122.411078),
new google.maps.LatLng(37.770992, -122.410477),
new google.maps.LatLng(37.770467, -122.409801),
new google.maps.LatLng(37.77009, -122.408904),
new google.maps.LatLng(37.769657, -122.408103),
new google.maps.LatLng(37.769132, -122.407276),
new google.maps.LatLng(37.768564, -122.406469),
new google.maps.LatLng(37.76798, -122.405745),
new google.maps.LatLng(37.76738, -122.405299),
new google.maps.LatLng(37.766604, -122.405297),
new google.maps.LatLng(37.765838, -122.4052),
new google.maps.LatLng(37.765139, -122.405139),
new google.maps.LatLng(37.764457, -122.405094),
new google.maps.LatLng(37.763716, -122.405142),
new google.maps.LatLng(37.762932, -122.405398),
new google.maps.LatLng(37.762126, -122.405813),
new google.maps.LatLng(37.761344, -122.406215),
new google.maps.LatLng(37.760556, -122.406495),
new google.maps.LatLng(37.759732, -122.406484),
new google.maps.LatLng(37.75891, -122.406228),
new google.maps.LatLng(37.758182, -122.405695),
new google.maps.LatLng(37.757676, -122.405118),
new google.maps.LatLng(37.757039, -122.404346),
new google.maps.LatLng(37.756335, -122.403719),
new google.maps.LatLng(37.755503, -122.403406),
new google.maps.LatLng(37.754665, -122.403242),
new google.maps.LatLng(37.753837, -122.403172),
new google.maps.LatLng(37.752986, -122.403112),
new google.maps.LatLng(37.751266, -122.403355),
];
}
//# sourceMappingURL=heatmap.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,561 @@
import { Loader, LoaderOptions } from 'google-maps';
let map: google.maps.Map, heatmap: google.maps.visualization.HeatmapLayer;
function initMap(): void {
const options: LoaderOptions = {/* todo */ };
const loader = new Loader('AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY', options);
loader.load().then(function (google) {
map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
zoom: 13,
center: { lat: 37.775, lng: -122.434 },
mapTypeId: "satellite",
});
heatmap = new google.maps.visualization.HeatmapLayer({
data: getPoints(),
map: map,
});
});
}
function toggleHeatmap() {
heatmap.setMap(heatmap.getMap() ? null : map);
}
function changeGradient() {
const gradient = [
"rgba(0, 255, 255, 0)",
"rgba(0, 255, 255, 1)",
"rgba(0, 191, 255, 1)",
"rgba(0, 127, 255, 1)",
"rgba(0, 63, 255, 1)",
"rgba(0, 0, 255, 1)",
"rgba(0, 0, 223, 1)",
"rgba(0, 0, 191, 1)",
"rgba(0, 0, 159, 1)",
"rgba(0, 0, 127, 1)",
"rgba(63, 0, 91, 1)",
"rgba(127, 0, 63, 1)",
"rgba(191, 0, 31, 1)",
"rgba(255, 0, 0, 1)",
];
heatmap.set("gradient", heatmap.get("gradient") ? null : gradient);
}
function changeRadius() {
heatmap.set("radius", heatmap.get("radius") ? null : 20);
}
function changeOpacity() {
heatmap.set("opacity", heatmap.get("opacity") ? null : 0.2);
}
// Heatmap data: 500 Points
function getPoints() {
return [
new google.maps.LatLng(37.782551, -122.445368),
new google.maps.LatLng(37.782745, -122.444586),
new google.maps.LatLng(37.782842, -122.443688),
new google.maps.LatLng(37.782919, -122.442815),
new google.maps.LatLng(37.782992, -122.442112),
new google.maps.LatLng(37.7831, -122.441461),
new google.maps.LatLng(37.783206, -122.440829),
new google.maps.LatLng(37.783273, -122.440324),
new google.maps.LatLng(37.783316, -122.440023),
new google.maps.LatLng(37.783357, -122.439794),
new google.maps.LatLng(37.783371, -122.439687),
new google.maps.LatLng(37.783368, -122.439666),
new google.maps.LatLng(37.783383, -122.439594),
new google.maps.LatLng(37.783508, -122.439525),
new google.maps.LatLng(37.783842, -122.439591),
new google.maps.LatLng(37.784147, -122.439668),
new google.maps.LatLng(37.784206, -122.439686),
new google.maps.LatLng(37.784386, -122.43979),
new google.maps.LatLng(37.784701, -122.439902),
new google.maps.LatLng(37.784965, -122.439938),
new google.maps.LatLng(37.78501, -122.439947),
new google.maps.LatLng(37.78536, -122.439952),
new google.maps.LatLng(37.785715, -122.44003),
new google.maps.LatLng(37.786117, -122.440119),
new google.maps.LatLng(37.786564, -122.440209),
new google.maps.LatLng(37.786905, -122.44027),
new google.maps.LatLng(37.786956, -122.440279),
new google.maps.LatLng(37.800224, -122.43352),
new google.maps.LatLng(37.800155, -122.434101),
new google.maps.LatLng(37.80016, -122.43443),
new google.maps.LatLng(37.800378, -122.434527),
new google.maps.LatLng(37.800738, -122.434598),
new google.maps.LatLng(37.800938, -122.43465),
new google.maps.LatLng(37.801024, -122.434889),
new google.maps.LatLng(37.800955, -122.435392),
new google.maps.LatLng(37.800886, -122.435959),
new google.maps.LatLng(37.800811, -122.436275),
new google.maps.LatLng(37.800788, -122.436299),
new google.maps.LatLng(37.800719, -122.436302),
new google.maps.LatLng(37.800702, -122.436298),
new google.maps.LatLng(37.800661, -122.436273),
new google.maps.LatLng(37.800395, -122.436172),
new google.maps.LatLng(37.800228, -122.436116),
new google.maps.LatLng(37.800169, -122.43613),
new google.maps.LatLng(37.800066, -122.436167),
new google.maps.LatLng(37.784345, -122.422922),
new google.maps.LatLng(37.784389, -122.422926),
new google.maps.LatLng(37.784437, -122.422924),
new google.maps.LatLng(37.784746, -122.422818),
new google.maps.LatLng(37.785436, -122.422959),
new google.maps.LatLng(37.78612, -122.423112),
new google.maps.LatLng(37.786433, -122.423029),
new google.maps.LatLng(37.786631, -122.421213),
new google.maps.LatLng(37.78666, -122.421033),
new google.maps.LatLng(37.786801, -122.420141),
new google.maps.LatLng(37.786823, -122.420034),
new google.maps.LatLng(37.786831, -122.419916),
new google.maps.LatLng(37.787034, -122.418208),
new google.maps.LatLng(37.787056, -122.418034),
new google.maps.LatLng(37.787169, -122.417145),
new google.maps.LatLng(37.787217, -122.416715),
new google.maps.LatLng(37.786144, -122.416403),
new google.maps.LatLng(37.785292, -122.416257),
new google.maps.LatLng(37.780666, -122.390374),
new google.maps.LatLng(37.780501, -122.391281),
new google.maps.LatLng(37.780148, -122.392052),
new google.maps.LatLng(37.780173, -122.391148),
new google.maps.LatLng(37.780693, -122.390592),
new google.maps.LatLng(37.781261, -122.391142),
new google.maps.LatLng(37.781808, -122.39173),
new google.maps.LatLng(37.78234, -122.392341),
new google.maps.LatLng(37.782812, -122.393022),
new google.maps.LatLng(37.7833, -122.393672),
new google.maps.LatLng(37.783809, -122.394275),
new google.maps.LatLng(37.784246, -122.394979),
new google.maps.LatLng(37.784791, -122.395958),
new google.maps.LatLng(37.785675, -122.396746),
new google.maps.LatLng(37.786262, -122.39578),
new google.maps.LatLng(37.786776, -122.395093),
new google.maps.LatLng(37.787282, -122.394426),
new google.maps.LatLng(37.787783, -122.393767),
new google.maps.LatLng(37.788343, -122.393184),
new google.maps.LatLng(37.788895, -122.392506),
new google.maps.LatLng(37.789371, -122.391701),
new google.maps.LatLng(37.789722, -122.390952),
new google.maps.LatLng(37.790315, -122.390305),
new google.maps.LatLng(37.790738, -122.389616),
new google.maps.LatLng(37.779448, -122.438702),
new google.maps.LatLng(37.779023, -122.438585),
new google.maps.LatLng(37.778542, -122.438492),
new google.maps.LatLng(37.7781, -122.438411),
new google.maps.LatLng(37.777986, -122.438376),
new google.maps.LatLng(37.77768, -122.438313),
new google.maps.LatLng(37.777316, -122.438273),
new google.maps.LatLng(37.777135, -122.438254),
new google.maps.LatLng(37.776987, -122.438303),
new google.maps.LatLng(37.776946, -122.438404),
new google.maps.LatLng(37.776944, -122.438467),
new google.maps.LatLng(37.776892, -122.438459),
new google.maps.LatLng(37.776842, -122.438442),
new google.maps.LatLng(37.776822, -122.438391),
new google.maps.LatLng(37.776814, -122.438412),
new google.maps.LatLng(37.776787, -122.438628),
new google.maps.LatLng(37.776729, -122.43865),
new google.maps.LatLng(37.776759, -122.438677),
new google.maps.LatLng(37.776772, -122.438498),
new google.maps.LatLng(37.776787, -122.438389),
new google.maps.LatLng(37.776848, -122.438283),
new google.maps.LatLng(37.77687, -122.438239),
new google.maps.LatLng(37.777015, -122.438198),
new google.maps.LatLng(37.777333, -122.438256),
new google.maps.LatLng(37.777595, -122.438308),
new google.maps.LatLng(37.777797, -122.438344),
new google.maps.LatLng(37.77816, -122.438442),
new google.maps.LatLng(37.778414, -122.438508),
new google.maps.LatLng(37.778445, -122.438516),
new google.maps.LatLng(37.778503, -122.438529),
new google.maps.LatLng(37.778607, -122.438549),
new google.maps.LatLng(37.77867, -122.438644),
new google.maps.LatLng(37.778847, -122.438706),
new google.maps.LatLng(37.77924, -122.438744),
new google.maps.LatLng(37.779738, -122.438822),
new google.maps.LatLng(37.780201, -122.438882),
new google.maps.LatLng(37.7804, -122.438905),
new google.maps.LatLng(37.780501, -122.438921),
new google.maps.LatLng(37.780892, -122.438986),
new google.maps.LatLng(37.781446, -122.439087),
new google.maps.LatLng(37.781985, -122.439199),
new google.maps.LatLng(37.782239, -122.439249),
new google.maps.LatLng(37.782286, -122.439266),
new google.maps.LatLng(37.797847, -122.429388),
new google.maps.LatLng(37.797874, -122.42918),
new google.maps.LatLng(37.797885, -122.429069),
new google.maps.LatLng(37.797887, -122.42905),
new google.maps.LatLng(37.797933, -122.428954),
new google.maps.LatLng(37.798242, -122.42899),
new google.maps.LatLng(37.798617, -122.429075),
new google.maps.LatLng(37.798719, -122.429092),
new google.maps.LatLng(37.798944, -122.429145),
new google.maps.LatLng(37.79932, -122.429251),
new google.maps.LatLng(37.79959, -122.429309),
new google.maps.LatLng(37.799677, -122.429324),
new google.maps.LatLng(37.799966, -122.42936),
new google.maps.LatLng(37.800288, -122.42943),
new google.maps.LatLng(37.800443, -122.429461),
new google.maps.LatLng(37.800465, -122.429474),
new google.maps.LatLng(37.800644, -122.42954),
new google.maps.LatLng(37.800948, -122.42962),
new google.maps.LatLng(37.801242, -122.429685),
new google.maps.LatLng(37.801375, -122.429702),
new google.maps.LatLng(37.8014, -122.429703),
new google.maps.LatLng(37.801453, -122.429707),
new google.maps.LatLng(37.801473, -122.429709),
new google.maps.LatLng(37.801532, -122.429707),
new google.maps.LatLng(37.801852, -122.429729),
new google.maps.LatLng(37.802173, -122.429789),
new google.maps.LatLng(37.802459, -122.429847),
new google.maps.LatLng(37.802554, -122.429825),
new google.maps.LatLng(37.802647, -122.429549),
new google.maps.LatLng(37.802693, -122.429179),
new google.maps.LatLng(37.802729, -122.428751),
new google.maps.LatLng(37.766104, -122.409291),
new google.maps.LatLng(37.766103, -122.409268),
new google.maps.LatLng(37.766138, -122.409229),
new google.maps.LatLng(37.766183, -122.409231),
new google.maps.LatLng(37.766153, -122.409276),
new google.maps.LatLng(37.766005, -122.409365),
new google.maps.LatLng(37.765897, -122.40957),
new google.maps.LatLng(37.765767, -122.409739),
new google.maps.LatLng(37.765693, -122.410389),
new google.maps.LatLng(37.765615, -122.411201),
new google.maps.LatLng(37.765533, -122.412121),
new google.maps.LatLng(37.765467, -122.412939),
new google.maps.LatLng(37.765444, -122.414821),
new google.maps.LatLng(37.765444, -122.414964),
new google.maps.LatLng(37.765318, -122.415424),
new google.maps.LatLng(37.763961, -122.415296),
new google.maps.LatLng(37.763115, -122.415196),
new google.maps.LatLng(37.762967, -122.415183),
new google.maps.LatLng(37.762278, -122.415127),
new google.maps.LatLng(37.761675, -122.415055),
new google.maps.LatLng(37.760932, -122.414988),
new google.maps.LatLng(37.759337, -122.414862),
new google.maps.LatLng(37.773187, -122.421922),
new google.maps.LatLng(37.773043, -122.422118),
new google.maps.LatLng(37.773007, -122.422165),
new google.maps.LatLng(37.772979, -122.422219),
new google.maps.LatLng(37.772865, -122.422394),
new google.maps.LatLng(37.772779, -122.422503),
new google.maps.LatLng(37.772676, -122.422701),
new google.maps.LatLng(37.772606, -122.422806),
new google.maps.LatLng(37.772566, -122.42284),
new google.maps.LatLng(37.772508, -122.422852),
new google.maps.LatLng(37.772387, -122.423011),
new google.maps.LatLng(37.772099, -122.423328),
new google.maps.LatLng(37.771704, -122.423783),
new google.maps.LatLng(37.771481, -122.424081),
new google.maps.LatLng(37.7714, -122.424179),
new google.maps.LatLng(37.771352, -122.42422),
new google.maps.LatLng(37.771248, -122.424327),
new google.maps.LatLng(37.770904, -122.424781),
new google.maps.LatLng(37.77052, -122.425283),
new google.maps.LatLng(37.770337, -122.425553),
new google.maps.LatLng(37.770128, -122.425832),
new google.maps.LatLng(37.769756, -122.426331),
new google.maps.LatLng(37.7693, -122.426902),
new google.maps.LatLng(37.769132, -122.427065),
new google.maps.LatLng(37.769092, -122.427103),
new google.maps.LatLng(37.768979, -122.427172),
new google.maps.LatLng(37.768595, -122.427634),
new google.maps.LatLng(37.768372, -122.427913),
new google.maps.LatLng(37.768337, -122.427961),
new google.maps.LatLng(37.768244, -122.428138),
new google.maps.LatLng(37.767942, -122.428581),
new google.maps.LatLng(37.767482, -122.429094),
new google.maps.LatLng(37.767031, -122.429606),
new google.maps.LatLng(37.766732, -122.429986),
new google.maps.LatLng(37.76668, -122.430058),
new google.maps.LatLng(37.766633, -122.430109),
new google.maps.LatLng(37.76658, -122.430211),
new google.maps.LatLng(37.766367, -122.430594),
new google.maps.LatLng(37.76591, -122.431137),
new google.maps.LatLng(37.765353, -122.431806),
new google.maps.LatLng(37.764962, -122.432298),
new google.maps.LatLng(37.764868, -122.432486),
new google.maps.LatLng(37.764518, -122.432913),
new google.maps.LatLng(37.763435, -122.434173),
new google.maps.LatLng(37.762847, -122.434953),
new google.maps.LatLng(37.762291, -122.435935),
new google.maps.LatLng(37.762224, -122.436074),
new google.maps.LatLng(37.761957, -122.436892),
new google.maps.LatLng(37.761652, -122.438886),
new google.maps.LatLng(37.761284, -122.439955),
new google.maps.LatLng(37.76121, -122.440068),
new google.maps.LatLng(37.761064, -122.44072),
new google.maps.LatLng(37.76104, -122.441411),
new google.maps.LatLng(37.761048, -122.442324),
new google.maps.LatLng(37.760851, -122.443118),
new google.maps.LatLng(37.759977, -122.444591),
new google.maps.LatLng(37.759913, -122.444698),
new google.maps.LatLng(37.759623, -122.445065),
new google.maps.LatLng(37.758902, -122.445158),
new google.maps.LatLng(37.758428, -122.44457),
new google.maps.LatLng(37.757687, -122.44334),
new google.maps.LatLng(37.757583, -122.44324),
new google.maps.LatLng(37.757019, -122.442787),
new google.maps.LatLng(37.756603, -122.442322),
new google.maps.LatLng(37.75638, -122.441602),
new google.maps.LatLng(37.75579, -122.441382),
new google.maps.LatLng(37.754493, -122.442133),
new google.maps.LatLng(37.754361, -122.442206),
new google.maps.LatLng(37.753719, -122.44265),
new google.maps.LatLng(37.753096, -122.442915),
new google.maps.LatLng(37.751617, -122.443211),
new google.maps.LatLng(37.751496, -122.443246),
new google.maps.LatLng(37.750733, -122.443428),
new google.maps.LatLng(37.750126, -122.443536),
new google.maps.LatLng(37.750103, -122.443784),
new google.maps.LatLng(37.75039, -122.44401),
new google.maps.LatLng(37.750448, -122.444013),
new google.maps.LatLng(37.750536, -122.44404),
new google.maps.LatLng(37.750493, -122.444141),
new google.maps.LatLng(37.790859, -122.402808),
new google.maps.LatLng(37.790864, -122.402768),
new google.maps.LatLng(37.790995, -122.402539),
new google.maps.LatLng(37.791148, -122.402172),
new google.maps.LatLng(37.791385, -122.401312),
new google.maps.LatLng(37.791405, -122.400776),
new google.maps.LatLng(37.791288, -122.400528),
new google.maps.LatLng(37.791113, -122.400441),
new google.maps.LatLng(37.791027, -122.400395),
new google.maps.LatLng(37.791094, -122.400311),
new google.maps.LatLng(37.791211, -122.400183),
new google.maps.LatLng(37.79106, -122.399334),
new google.maps.LatLng(37.790538, -122.398718),
new google.maps.LatLng(37.790095, -122.398086),
new google.maps.LatLng(37.789644, -122.39736),
new google.maps.LatLng(37.789254, -122.396844),
new google.maps.LatLng(37.788855, -122.396397),
new google.maps.LatLng(37.788483, -122.395963),
new google.maps.LatLng(37.788015, -122.395365),
new google.maps.LatLng(37.787558, -122.394735),
new google.maps.LatLng(37.787472, -122.394323),
new google.maps.LatLng(37.78763, -122.394025),
new google.maps.LatLng(37.787767, -122.393987),
new google.maps.LatLng(37.787486, -122.394452),
new google.maps.LatLng(37.786977, -122.395043),
new google.maps.LatLng(37.786583, -122.395552),
new google.maps.LatLng(37.78654, -122.39561),
new google.maps.LatLng(37.786516, -122.395659),
new google.maps.LatLng(37.786378, -122.395707),
new google.maps.LatLng(37.786044, -122.395362),
new google.maps.LatLng(37.785598, -122.394715),
new google.maps.LatLng(37.785321, -122.394361),
new google.maps.LatLng(37.785207, -122.394236),
new google.maps.LatLng(37.785751, -122.394062),
new google.maps.LatLng(37.785996, -122.393881),
new google.maps.LatLng(37.786092, -122.39383),
new google.maps.LatLng(37.785998, -122.393899),
new google.maps.LatLng(37.785114, -122.394365),
new google.maps.LatLng(37.785022, -122.394441),
new google.maps.LatLng(37.784823, -122.394635),
new google.maps.LatLng(37.784719, -122.394629),
new google.maps.LatLng(37.785069, -122.394176),
new google.maps.LatLng(37.7855, -122.39365),
new google.maps.LatLng(37.78577, -122.393291),
new google.maps.LatLng(37.785839, -122.393159),
new google.maps.LatLng(37.782651, -122.400628),
new google.maps.LatLng(37.782616, -122.400599),
new google.maps.LatLng(37.782702, -122.40047),
new google.maps.LatLng(37.782915, -122.400192),
new google.maps.LatLng(37.783137, -122.399887),
new google.maps.LatLng(37.783414, -122.399519),
new google.maps.LatLng(37.783629, -122.399237),
new google.maps.LatLng(37.783688, -122.399157),
new google.maps.LatLng(37.783716, -122.399106),
new google.maps.LatLng(37.783798, -122.399072),
new google.maps.LatLng(37.783997, -122.399186),
new google.maps.LatLng(37.784271, -122.399538),
new google.maps.LatLng(37.784577, -122.399948),
new google.maps.LatLng(37.784828, -122.40026),
new google.maps.LatLng(37.784999, -122.400477),
new google.maps.LatLng(37.785113, -122.400651),
new google.maps.LatLng(37.785155, -122.400703),
new google.maps.LatLng(37.785192, -122.400749),
new google.maps.LatLng(37.785278, -122.400839),
new google.maps.LatLng(37.785387, -122.400857),
new google.maps.LatLng(37.785478, -122.40089),
new google.maps.LatLng(37.785526, -122.401022),
new google.maps.LatLng(37.785598, -122.401148),
new google.maps.LatLng(37.785631, -122.401202),
new google.maps.LatLng(37.78566, -122.401267),
new google.maps.LatLng(37.803986, -122.426035),
new google.maps.LatLng(37.804102, -122.425089),
new google.maps.LatLng(37.804211, -122.424156),
new google.maps.LatLng(37.803861, -122.423385),
new google.maps.LatLng(37.803151, -122.423214),
new google.maps.LatLng(37.802439, -122.423077),
new google.maps.LatLng(37.80174, -122.422905),
new google.maps.LatLng(37.801069, -122.422785),
new google.maps.LatLng(37.800345, -122.422649),
new google.maps.LatLng(37.799633, -122.422603),
new google.maps.LatLng(37.79975, -122.4217),
new google.maps.LatLng(37.799885, -122.420854),
new google.maps.LatLng(37.799209, -122.420607),
new google.maps.LatLng(37.795656, -122.400395),
new google.maps.LatLng(37.795203, -122.400304),
new google.maps.LatLng(37.778738, -122.415584),
new google.maps.LatLng(37.778812, -122.415189),
new google.maps.LatLng(37.778824, -122.415092),
new google.maps.LatLng(37.778833, -122.414932),
new google.maps.LatLng(37.778834, -122.414898),
new google.maps.LatLng(37.77874, -122.414757),
new google.maps.LatLng(37.778501, -122.414433),
new google.maps.LatLng(37.778182, -122.414026),
new google.maps.LatLng(37.777851, -122.413623),
new google.maps.LatLng(37.777486, -122.413166),
new google.maps.LatLng(37.777109, -122.412674),
new google.maps.LatLng(37.776743, -122.412186),
new google.maps.LatLng(37.77644, -122.4118),
new google.maps.LatLng(37.776295, -122.411614),
new google.maps.LatLng(37.776158, -122.41144),
new google.maps.LatLng(37.775806, -122.410997),
new google.maps.LatLng(37.775422, -122.410484),
new google.maps.LatLng(37.775126, -122.410087),
new google.maps.LatLng(37.775012, -122.409854),
new google.maps.LatLng(37.775164, -122.409573),
new google.maps.LatLng(37.775498, -122.40918),
new google.maps.LatLng(37.775868, -122.40873),
new google.maps.LatLng(37.776256, -122.40824),
new google.maps.LatLng(37.776519, -122.407928),
new google.maps.LatLng(37.776539, -122.407904),
new google.maps.LatLng(37.776595, -122.407854),
new google.maps.LatLng(37.776853, -122.407547),
new google.maps.LatLng(37.777234, -122.407087),
new google.maps.LatLng(37.777644, -122.406558),
new google.maps.LatLng(37.778066, -122.406017),
new google.maps.LatLng(37.778468, -122.405499),
new google.maps.LatLng(37.778866, -122.404995),
new google.maps.LatLng(37.779295, -122.404455),
new google.maps.LatLng(37.779695, -122.40395),
new google.maps.LatLng(37.779982, -122.403584),
new google.maps.LatLng(37.780295, -122.403223),
new google.maps.LatLng(37.780664, -122.402766),
new google.maps.LatLng(37.781043, -122.402288),
new google.maps.LatLng(37.781399, -122.401823),
new google.maps.LatLng(37.781727, -122.401407),
new google.maps.LatLng(37.781853, -122.401247),
new google.maps.LatLng(37.781894, -122.401195),
new google.maps.LatLng(37.782076, -122.400977),
new google.maps.LatLng(37.782338, -122.400603),
new google.maps.LatLng(37.782666, -122.400133),
new google.maps.LatLng(37.783048, -122.399634),
new google.maps.LatLng(37.78345, -122.399198),
new google.maps.LatLng(37.783791, -122.398998),
new google.maps.LatLng(37.784177, -122.398959),
new google.maps.LatLng(37.784388, -122.398971),
new google.maps.LatLng(37.784404, -122.399128),
new google.maps.LatLng(37.784586, -122.399524),
new google.maps.LatLng(37.784835, -122.399927),
new google.maps.LatLng(37.785116, -122.400307),
new google.maps.LatLng(37.785282, -122.400539),
new google.maps.LatLng(37.785346, -122.400692),
new google.maps.LatLng(37.765769, -122.407201),
new google.maps.LatLng(37.76579, -122.407414),
new google.maps.LatLng(37.765802, -122.407755),
new google.maps.LatLng(37.765791, -122.408219),
new google.maps.LatLng(37.765763, -122.408759),
new google.maps.LatLng(37.765726, -122.409348),
new google.maps.LatLng(37.765716, -122.409882),
new google.maps.LatLng(37.765708, -122.410202),
new google.maps.LatLng(37.765705, -122.410253),
new google.maps.LatLng(37.765707, -122.410369),
new google.maps.LatLng(37.765692, -122.41072),
new google.maps.LatLng(37.765699, -122.411215),
new google.maps.LatLng(37.765687, -122.411789),
new google.maps.LatLng(37.765666, -122.412373),
new google.maps.LatLng(37.765598, -122.412883),
new google.maps.LatLng(37.765543, -122.413039),
new google.maps.LatLng(37.765532, -122.413125),
new google.maps.LatLng(37.7655, -122.413553),
new google.maps.LatLng(37.765448, -122.414053),
new google.maps.LatLng(37.765388, -122.414645),
new google.maps.LatLng(37.765323, -122.41525),
new google.maps.LatLng(37.765303, -122.415847),
new google.maps.LatLng(37.765251, -122.416439),
new google.maps.LatLng(37.765204, -122.41702),
new google.maps.LatLng(37.765172, -122.417556),
new google.maps.LatLng(37.765164, -122.418075),
new google.maps.LatLng(37.765153, -122.418618),
new google.maps.LatLng(37.765136, -122.419112),
new google.maps.LatLng(37.765129, -122.419378),
new google.maps.LatLng(37.765119, -122.419481),
new google.maps.LatLng(37.7651, -122.419852),
new google.maps.LatLng(37.765083, -122.420349),
new google.maps.LatLng(37.765045, -122.42093),
new google.maps.LatLng(37.764992, -122.421481),
new google.maps.LatLng(37.76498, -122.421695),
new google.maps.LatLng(37.764993, -122.421843),
new google.maps.LatLng(37.764986, -122.422255),
new google.maps.LatLng(37.764975, -122.422823),
new google.maps.LatLng(37.764939, -122.423411),
new google.maps.LatLng(37.764902, -122.424014),
new google.maps.LatLng(37.764853, -122.424576),
new google.maps.LatLng(37.764826, -122.424922),
new google.maps.LatLng(37.764796, -122.425375),
new google.maps.LatLng(37.764782, -122.425869),
new google.maps.LatLng(37.764768, -122.426089),
new google.maps.LatLng(37.764766, -122.426117),
new google.maps.LatLng(37.764723, -122.426276),
new google.maps.LatLng(37.764681, -122.426649),
new google.maps.LatLng(37.782012, -122.4042),
new google.maps.LatLng(37.781574, -122.404911),
new google.maps.LatLng(37.781055, -122.405597),
new google.maps.LatLng(37.780479, -122.406341),
new google.maps.LatLng(37.779996, -122.406939),
new google.maps.LatLng(37.779459, -122.407613),
new google.maps.LatLng(37.778953, -122.408228),
new google.maps.LatLng(37.778409, -122.408839),
new google.maps.LatLng(37.777842, -122.409501),
new google.maps.LatLng(37.777334, -122.410181),
new google.maps.LatLng(37.776809, -122.410836),
new google.maps.LatLng(37.77624, -122.411514),
new google.maps.LatLng(37.775725, -122.412145),
new google.maps.LatLng(37.77519, -122.412805),
new google.maps.LatLng(37.774672, -122.413464),
new google.maps.LatLng(37.774084, -122.414186),
new google.maps.LatLng(37.773533, -122.413636),
new google.maps.LatLng(37.773021, -122.413009),
new google.maps.LatLng(37.772501, -122.412371),
new google.maps.LatLng(37.771964, -122.411681),
new google.maps.LatLng(37.771479, -122.411078),
new google.maps.LatLng(37.770992, -122.410477),
new google.maps.LatLng(37.770467, -122.409801),
new google.maps.LatLng(37.77009, -122.408904),
new google.maps.LatLng(37.769657, -122.408103),
new google.maps.LatLng(37.769132, -122.407276),
new google.maps.LatLng(37.768564, -122.406469),
new google.maps.LatLng(37.76798, -122.405745),
new google.maps.LatLng(37.76738, -122.405299),
new google.maps.LatLng(37.766604, -122.405297),
new google.maps.LatLng(37.765838, -122.4052),
new google.maps.LatLng(37.765139, -122.405139),
new google.maps.LatLng(37.764457, -122.405094),
new google.maps.LatLng(37.763716, -122.405142),
new google.maps.LatLng(37.762932, -122.405398),
new google.maps.LatLng(37.762126, -122.405813),
new google.maps.LatLng(37.761344, -122.406215),
new google.maps.LatLng(37.760556, -122.406495),
new google.maps.LatLng(37.759732, -122.406484),
new google.maps.LatLng(37.75891, -122.406228),
new google.maps.LatLng(37.758182, -122.405695),
new google.maps.LatLng(37.757676, -122.405118),
new google.maps.LatLng(37.757039, -122.404346),
new google.maps.LatLng(37.756335, -122.403719),
new google.maps.LatLng(37.755503, -122.403406),
new google.maps.LatLng(37.754665, -122.403242),
new google.maps.LatLng(37.753837, -122.403172),
new google.maps.LatLng(37.752986, -122.403112),
new google.maps.LatLng(37.751266, -122.403355),
];
}
// [END maps_layer_heatmap]
export { initMap };

View File

@ -0,0 +1,21 @@
import { Map, GoogleApiWrapper } from 'google-maps-react';
export function Heatmap() {
const mapStyles = {
width: '100%',
height: '100%',
};
return (
<Map
google={this.props.google}
zoom={8}
style={mapStyles}
initialCenter={{ lat: 47.444, lng: -122.176 }}
/>
);
}
export default GoogleApiWrapper({
apiKey: 'AIzaSyCZ51VFfxqZ2GkCmVrcNZdUKsM0fuBQUCY'
});

View File

@ -35,8 +35,7 @@ namespace Birdmap.Controllers
}
[AllowAnonymous]
[HttpPost("authenticate")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[HttpPost("authenticate"), ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
public async Task<IActionResult> AuthenticateAsync([FromBody] AuthenticateRequest model)
{
_logger.LogInformation($"Authenticating user [{model.Username}] with password [*******]...");
@ -70,8 +69,7 @@ namespace Birdmap.Controllers
}
[AllowAnonymous]
[HttpPost("register")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[HttpPost("register"), ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> RegisterAsync([FromBody] RegisterRequest model)
{
_logger.LogInformation($"Registering user [{model.Username}]...");

View File

@ -0,0 +1,144 @@
using Birdmap.BLL.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
namespace Birdmap.API.Controllers
{
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class DevicesController : ControllerBase
{
private readonly IDeviceService _service;
private readonly ILogger<ServicesController> _logger;
public DevicesController(IDeviceService service, ILogger<ServicesController> logger)
{
_service = service;
_logger = logger;
}
/// <summary>Get all device info</summary>
/// <returns>Array of devices</returns>
[HttpGet]
public async Task<ActionResult<List<Device>>> Getall()
{
_logger.LogInformation("Getting all devices...");
return (await _service.GetallAsync()).ToList();
}
/// <summary>Shut down all devices</summary>
/// <returns>Message sent</returns>
[HttpPost, Route("offline")]
public async Task<IActionResult> Offlineall()
{
_logger.LogInformation("Turning off all devices and sensors...");
await _service.OfflineallAsync();
return Ok();
}
/// <summary>Bring all devices online</summary>
/// <returns>Message sent</returns>
[HttpPost, Route("online")]
public async Task<IActionResult> Onlineall()
{
_logger.LogInformation("Turning on all devices and sensors...");
await _service.OnlineallAsync();
return Ok();
}
/// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns>
[HttpGet, Route("{deviceID}")]
public async Task<ActionResult<Device>> Getdevice([BindRequired] Guid deviceID)
{
_logger.LogInformation($"Getting device [{deviceID}]...");
return await _service.GetdeviceAsync(deviceID);
}
/// <summary>Shut down device</summary>
/// <param name="deviceID">ID of device to shut down</param>
/// <returns>Message sent</returns>
[HttpPost, Route("{deviceID}/offline")]
public async Task<IActionResult> Offlinedevice([BindRequired] Guid deviceID)
{
_logger.LogInformation($"Turning off device [{deviceID}]...");
await _service.OfflinedeviceAsync(deviceID);
return Ok();
}
/// <summary>Bring device online</summary>
/// <param name="deviceID">ID of device to bring online</param>
/// <returns>Message sent</returns>
[HttpPost, Route("{deviceID}/online")]
public async Task<IActionResult> Onlinedevice([BindRequired] Guid deviceID)
{
_logger.LogInformation($"Turning on device [{deviceID}]...");
await _service.OnlinedeviceAsync(deviceID);
return Ok();
}
/// <summary>Get info about a particular device's sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns>
[HttpGet, Route("{deviceID}/{sensorID}")]
public async Task<ActionResult<Sensor>> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
{
_logger.LogInformation($"Getting sensor [{sensorID}] of device [{deviceID}]...");
return await _service.GetsensorAsync(deviceID, sensorID);
}
/// <summary>Shut down sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
[HttpPost, Route("{deviceID}/{sensorID}/offline")]
public async Task<IActionResult> Offlinesensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
{
_logger.LogInformation($"Turning off sensor [{sensorID}] of device [{deviceID}]...");
await _service.OfflinesensorAsync(deviceID, sensorID);
return Ok();
}
/// <summary>Bring sensor online</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
[HttpPost, Route("{deviceID}/{sensorID}/online")]
public async Task<IActionResult> Onlinesensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
{
_logger.LogInformation($"Turning on sensor [{sensorID}] of device [{deviceID}]...");
await _service.OnlinesensorAsync(deviceID, sensorID);
return Ok();
}
}
}
#pragma warning restore 1591
#pragma warning restore 1573
#pragma warning restore 472
#pragma warning restore 114
#pragma warning restore 108

View File

@ -30,8 +30,7 @@ namespace Birdmap.API.Controllers
_logger = logger;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpGet, ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<ServiceInfo>>> GetAsync()
{
_logger.LogInformation($"Getting all services from db...");
@ -59,8 +58,7 @@ namespace Birdmap.API.Controllers
return serviceInfos.ToList();
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[HttpPost, ProducesResponseType(StatusCodes.Status201Created)]
public async Task<ActionResult<ServiceRequest>> PostAsync(ServiceRequest request)
{
_logger.LogInformation($"Creating service [{request.Name}]...");
@ -74,8 +72,7 @@ namespace Birdmap.API.Controllers
_mapper.Map<ServiceRequest>(created));
}
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[HttpPut, ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> PutAsync(ServiceRequest request)
{
_logger.LogInformation($"Updating service [{request.Name}]...");
@ -87,8 +84,7 @@ namespace Birdmap.API.Controllers
return NoContent();
}
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[HttpDelete("{id}"), ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> DeleteAsync(int id)
{
_logger.LogInformation($"Deleting service [{id}]...");

View File

@ -8,7 +8,8 @@
},
"AllowedHosts": "*",
"Secret": "7vj.3KW.hYE!}4u6",
"LocalDbConnectionString": "Data Source=DESKTOP-A6JQ6B5\\SQLEXPRESS;Initial Catalog=Birdmap;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
// "LocalDbConnectionString": "Data Source=DESKTOP-3600\\SQLEXPRESS;Initial Catalog=birdmap;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
"LocalDbConnectionString": "Data Source=DESKTOP-3600;Initial Catalog=birdmap;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
"Defaults": {
"Services": {
"Local Database": "https://localhost:44331/health",
@ -18,7 +19,7 @@
{
"Name": "admin",
"Password": "pass",
"Role": "Admin"
"Role": "Admin"
},
{
"Name": "user",
@ -26,5 +27,6 @@
"Role": "User"
}
]
}
},
"UseDummyServices": true
}

View File

@ -0,0 +1,279 @@
namespace Birdmap.BLL.Interfaces
{
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class ListOfDevices : System.Collections.ObjectModel.Collection<Device>
{
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class Device
{
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public System.Guid Id { get; set; }
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public DeviceStatus Status { get; set; }
[Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Url { get; set; }
[Newtonsoft.Json.JsonProperty("coordinates", Required = Newtonsoft.Json.Required.AllowNull)]
[System.ComponentModel.DataAnnotations.Required]
public Coordinates Coordinates { get; set; } = new Coordinates();
[Newtonsoft.Json.JsonProperty("sensors", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public ArrayofSensors Sensors { get; set; } = new ArrayofSensors();
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class ArrayofSensors : System.Collections.ObjectModel.Collection<Sensor>
{
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class Sensor
{
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public System.Guid Id { get; set; }
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public SensorStatus Status { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class Coordinates
{
[Newtonsoft.Json.JsonProperty("latitude", Required = Newtonsoft.Json.Required.Always)]
public double Latitude { get; set; }
[Newtonsoft.Json.JsonProperty("longitude", Required = Newtonsoft.Json.Required.Always)]
public double Longitude { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public enum DeviceStatus
{
[System.Runtime.Serialization.EnumMember(Value = @"online")]
Online = 0,
[System.Runtime.Serialization.EnumMember(Value = @"error")]
Error = 1,
[System.Runtime.Serialization.EnumMember(Value = @"offline")]
Offline = 2,
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
public enum SensorStatus
{
[System.Runtime.Serialization.EnumMember(Value = @"online")]
Online = 0,
[System.Runtime.Serialization.EnumMember(Value = @"unknown")]
Unknown = 1,
[System.Runtime.Serialization.EnumMember(Value = @"offline")]
Offline = 2,
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial class ApiException : System.Exception
{
public int StatusCode { get; private set; }
public string Response { get; private set; }
public System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> Headers { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, System.Exception innerException)
: base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException)
{
StatusCode = statusCode;
Response = response;
Headers = headers;
}
public override string ToString()
{
return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial class ApiException<TResult> : ApiException
{
public TResult Result { get; private set; }
public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers, TResult result, System.Exception innerException)
: base(message, statusCode, response, headers, innerException)
{
Result = result;
}
}
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial interface IDeviceService
{
/// <summary>Get all device info</summary>
/// <returns>Array of devices</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Device>> GetallAsync();
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get all device info</summary>
/// <returns>Array of devices</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Device>> GetallAsync(System.Threading.CancellationToken cancellationToken);
/// <summary>Shut down all devices</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflineallAsync();
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down all devices</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflineallAsync(System.Threading.CancellationToken cancellationToken);
/// <summary>Bring all devices online</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlineallAsync();
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring all devices online</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlineallAsync(System.Threading.CancellationToken cancellationToken);
/// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<Device> GetdeviceAsync(System.Guid deviceID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<Device> GetdeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken);
/// <summary>Shut down device</summary>
/// <param name="deviceID">ID of device to shut down</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down device</summary>
/// <param name="deviceID">ID of device to shut down</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken);
/// <summary>Bring device online</summary>
/// <param name="deviceID">ID of device to bring online</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring device online</summary>
/// <param name="deviceID">ID of device to bring online</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken);
/// <summary>Get info about a particular device's sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<Sensor> GetsensorAsync(System.Guid deviceID, System.Guid sensorID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get info about a particular device's sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<Sensor> GetsensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken);
/// <summary>Shut down sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken);
/// <summary>Bring sensor online</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID);
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring sensor online</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,39 @@
using Birdmap.BLL.Interfaces;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Birdmap.BLL.Services
{
public abstract class DeviceServiceBase : IDeviceService
{
public virtual Task<ICollection<Device>> GetallAsync()
=> GetallAsync(CancellationToken.None);
public abstract Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken);
public virtual Task<Device> GetdeviceAsync(Guid deviceID)
=> GetdeviceAsync(deviceID, CancellationToken.None);
public abstract Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken);
public virtual Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID)
=> GetsensorAsync(deviceID, sensorID, CancellationToken.None);
public abstract Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken);
public virtual Task OfflineallAsync()
=> OfflineallAsync(CancellationToken.None);
public abstract Task OfflineallAsync(CancellationToken cancellationToken);
public virtual Task OfflinedeviceAsync(Guid deviceID)
=> OfflinedeviceAsync(deviceID, CancellationToken.None);
public abstract Task OfflinedeviceAsync(Guid deviceID, CancellationToken cancellationToken);
public virtual Task OfflinesensorAsync(Guid deviceID, Guid sensorID)
=> OfflinesensorAsync(deviceID, sensorID, CancellationToken.None);
public abstract Task OfflinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken);
public virtual Task OnlineallAsync()
=> OnlineallAsync(CancellationToken.None);
public abstract Task OnlineallAsync(CancellationToken cancellationToken);
public virtual Task OnlinedeviceAsync(Guid deviceID)
=> OnlinedeviceAsync(deviceID, CancellationToken.None);
public abstract Task OnlinedeviceAsync(Guid deviceID, CancellationToken cancellationToken);
public virtual Task OnlinesensorAsync(Guid deviceID, Guid sensorID)
=> OnlinesensorAsync(deviceID, sensorID, CancellationToken.None);
public abstract Task OnlinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,139 @@
using Birdmap.BLL.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Birdmap.BLL.Services
{
public class DummyDeviceService : DeviceServiceBase
{
private const double centerLong = 21.469640;
private const double centerLat = 48.275939;
private const double radius = 0.000200;
private readonly Lazy<ICollection<Device>> _devices = new Lazy<ICollection<Device>>(GenerateDevices);
private static ListOfDevices GenerateDevices()
{
var devices = new ListOfDevices();
var rand = new Random();
T GetRandomEnum<T>()
{
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(rand.Next(values.Length));
}
double GetPlusMinus(double center, double radius)
{
return center - radius + rand.NextDouble() * radius * 2;
}
for (int d = 0; d < 15; d++)
{
var sensors = new ArrayofSensors();
for (int s = 0; s < rand.Next(1, 5); s++)
{
sensors.Add(new Sensor
{
Id = Guid.NewGuid(),
Status = GetRandomEnum<SensorStatus>(),
});
}
devices.Add(new Device
{
Id = Guid.NewGuid(),
Sensors = sensors,
Status = GetRandomEnum<DeviceStatus>(),
Url = "dummyservice.device.url",
Coordinates = new Coordinates
{
Latitude = GetPlusMinus(centerLat, radius),
Longitude = GetPlusMinus(centerLong, radius),
}
});
}
return devices;
}
public override Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken)
{
return Task.FromResult(_devices.Value);
}
public override Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken)
{
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID));
}
public override Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
{
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID));
}
public override Task OfflineallAsync(CancellationToken cancellationToken)
{
SetStatus(DeviceStatus.Offline, SensorStatus.Offline);
return Task.CompletedTask;
}
public override Task OfflinedeviceAsync(Guid deviceID, CancellationToken cancellationToken)
{
SetDeviceStatus(deviceID, DeviceStatus.Offline);
return Task.CompletedTask;
}
public override Task OfflinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
{
SetSensorStatus(deviceID, sensorID, SensorStatus.Offline);
return Task.CompletedTask;
}
public override Task OnlineallAsync(CancellationToken cancellationToken)
{
SetStatus(DeviceStatus.Online, SensorStatus.Online);
return Task.CompletedTask;
}
public override Task OnlinedeviceAsync(Guid deviceID, CancellationToken cancellationToken)
{
SetDeviceStatus(deviceID, DeviceStatus.Online);
return Task.CompletedTask;
}
public override Task OnlinesensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
{
SetSensorStatus(deviceID, sensorID, SensorStatus.Online);
return Task.CompletedTask;
}
private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus)
{
foreach (var device in _devices.Value)
{
device.Status = deviceStatus;
foreach (var sensor in device.Sensors)
{
sensor.Status = sensorStatus;
}
}
}
private void SetDeviceStatus(Guid deviceID, DeviceStatus status)
{
var device = GetdeviceAsync(deviceID).Result;
device.Status = status;
}
private void SetSensorStatus(Guid deviceId, Guid sensorID, SensorStatus status)
{
var sensor = GetsensorAsync(deviceId, sensorID).Result;
sensor.Status = status;
}
}
}

View File

@ -0,0 +1,902 @@
//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------
#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
namespace Birdmap.BLL.Services
{
using Birdmap.BLL.Interfaces;
using System = global::System;
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
public partial class LiveDummyService : IDeviceService
{
private string _baseUrl = "https://birb.k8s.kmlabz.com";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public LiveDummyService(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
{
var settings = new Newtonsoft.Json.JsonSerializerSettings();
UpdateJsonSerializerSettings(settings);
return settings;
}
public string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
/// <summary>Get all device info</summary>
/// <returns>Array of devices</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Device>> GetallAsync()
{
return GetallAsync(System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get all device info</summary>
/// <returns>Array of devices</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Device>> GetallAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<Device>>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("No device found", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Shut down all devices</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OfflineallAsync()
{
return OfflineallAsync(System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down all devices</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OfflineallAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/offline");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Bring all devices online</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OnlineallAsync()
{
return OnlineallAsync(System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring all devices online</summary>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OnlineallAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/online");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<Device> GetdeviceAsync(System.Guid deviceID)
{
return GetdeviceAsync(deviceID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get all device info</summary>
/// <param name="deviceID">ID of device to query</param>
/// <returns>Information about a particular device</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<Device> GetdeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<Device>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Device not found", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Shut down device</summary>
/// <param name="deviceID">ID of device to shut down</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID)
{
return OfflinedeviceAsync(deviceID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down device</summary>
/// <param name="deviceID">ID of device to shut down</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OfflinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/offline");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Bring device online</summary>
/// <param name="deviceID">ID of device to bring online</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID)
{
return OnlinedeviceAsync(deviceID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring device online</summary>
/// <param name="deviceID">ID of device to bring online</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OnlinedeviceAsync(System.Guid deviceID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/online");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Get info about a particular device's sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task<Sensor> GetsensorAsync(System.Guid deviceID, System.Guid sensorID)
{
return GetsensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Get info about a particular device's sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Information about a sensor</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task<Sensor> GetsensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
if (sensorID == null)
throw new System.ArgumentNullException("sensorID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<Sensor>(response_, headers_).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Device or sensor not found", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Shut down sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID)
{
return OfflinesensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Shut down sensor</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OfflinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
if (sensorID == null)
throw new System.ArgumentNullException("sensorID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}/offline");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
/// <summary>Bring sensor online</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID)
{
return OnlinesensorAsync(deviceID, sensorID, System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>Bring sensor online</summary>
/// <param name="deviceID">ID of device to query</param>
/// <param name="sensorID">ID of sensor to query</param>
/// <returns>Message sent</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task OnlinesensorAsync(System.Guid deviceID, System.Guid sensorID, System.Threading.CancellationToken cancellationToken)
{
if (deviceID == null)
throw new System.ArgumentNullException("deviceID");
if (sensorID == null)
throw new System.ArgumentNullException("sensorID");
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/devices/{deviceID}/{sensorID}/online");
urlBuilder_.Replace("{deviceID}", System.Uri.EscapeDataString(ConvertToString(deviceID, System.Globalization.CultureInfo.InvariantCulture)));
urlBuilder_.Replace("{sensorID}", System.Uri.EscapeDataString(ConvertToString(sensorID, System.Globalization.CultureInfo.InvariantCulture)));
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json");
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 500)
{
string responseText_ = (response_.Content == null) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("Message sending unsuccessful", status_, responseText_, headers_, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
this.Object = responseObject;
this.Text = responseText;
}
public T Object { get; }
public string Text { get; }
}
public bool ReadResponseAsString { get; set; }
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
{
if (response == null || response.Content == null)
{
return new ObjectResponseResult<T>(default(T), string.Empty);
}
if (ReadResponseAsString)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
}
}
else
{
try
{
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var streamReader = new System.IO.StreamReader(responseStream))
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
{
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
var typedBody = serializer.Deserialize<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, string.Empty);
}
}
catch (Newtonsoft.Json.JsonException exception)
{
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
}
}
}
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return null;
}
if (value is System.Enum)
{
var name = System.Enum.GetName(value.GetType(), value);
if (name != null)
{
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
if (field != null)
{
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
as System.Runtime.Serialization.EnumMemberAttribute;
if (attribute != null)
{
return attribute.Value != null ? attribute.Value : name;
}
}
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
}
}
else if (value is bool)
{
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return System.Convert.ToBase64String((byte[])value);
}
else if (value.GetType().IsArray)
{
var array = System.Linq.Enumerable.OfType<object>((System.Array)value);
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
}
var result = System.Convert.ToString(value, cultureInfo);
return (result is null) ? string.Empty : result;
}
}
}
#pragma warning restore 1591
#pragma warning restore 1573
#pragma warning restore 472
#pragma warning restore 114
#pragma warning restore 108

View File

@ -13,6 +13,11 @@ namespace Birdmap.BLL
services.AddTransient<IUserService, UserService>();
services.AddTransient<IServiceService, ServiceService>();
if (configuration.GetValue<bool>("UseDummyServices"))
services.AddTransient<IDeviceService, DummyDeviceService>();
else
services.AddTransient<IDeviceService, LiveDummyService>();
return services;
}
}

221
c-n-c-nswag.nswag Normal file

File diff suppressed because one or more lines are too long

272
c-n-c.yml Normal file
View File

@ -0,0 +1,272 @@
openapi: 3.0.3
info:
title: Command and Control Service
description: This service s responsible for controlling and handling information
about IoT devices in the Birbnetes system.
contact:
email: tormakristof@tormakristof.eu
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
servers:
- url: https://birb.k8s.kmlabz.com
tags:
- name: cnc
description: Command and Control Service interaction
paths:
/devices:
get:
tags:
- cnc
summary: Get all device info
operationId: getall
responses:
200:
description: Array of devices
content:
application/json:
schema:
$ref: '#/components/schemas/ListOfDevices'
404:
description: No device found
content: {}
/devices/offline:
post:
tags:
- cnc
summary: Shut down all devices
operationId: offlineall
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
/devices/online:
post:
tags:
- cnc
summary: Bring all devices online
operationId: onlineall
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
/devices/{deviceID}:
get:
tags:
- cnc
summary: Get all device info
operationId: getdevice
parameters:
- name: deviceID
in: path
description: ID of device to query
required: true
schema:
type: string
format: uuid
responses:
200:
description: Information about a particular device
content:
application/json:
schema:
$ref: '#/components/schemas/Device'
404:
description: Device not found
content: {}
/devices/{deviceID}/offline:
post:
tags:
- cnc
summary: Shut down device
operationId: offlinedevice
parameters:
- name: deviceID
in: path
description: ID of device to shut down
required: true
schema:
type: string
format: uuid
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
/devices/{deviceID}/online:
post:
tags:
- cnc
summary: Bring device online
operationId: onlinedevice
parameters:
- name: deviceID
in: path
description: ID of device to bring online
required: true
schema:
type: string
format: uuid
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
/devices/{deviceID}/{sensorID}:
get:
tags:
- cnc
summary: Get info about a particular device's sensor
operationId: getsensor
parameters:
- name: deviceID
in: path
description: ID of device to query
required: true
schema:
type: string
format: uuid
- name: sensorID
in: path
description: ID of sensor to query
required: true
schema:
type: string
format: uuid
responses:
200:
description: Information about a sensor
content:
application/json:
schema:
$ref: '#/components/schemas/Sensor'
404:
description: Device or sensor not found
content: {}
/devices/{deviceID}/{sensorID}/offline:
post:
tags:
- cnc
summary: Shut down sensor
operationId: offlinesensor
parameters:
- name: deviceID
in: path
description: ID of device to query
required: true
schema:
type: string
format: uuid
- name: sensorID
in: path
description: ID of sensor to query
required: true
schema:
type: string
format: uuid
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
/devices/{deviceID}/{sensorID}/online:
post:
tags:
- cnc
summary: Bring sensor online
operationId: onlinesensor
parameters:
- name: deviceID
in: path
description: ID of device to query
required: true
schema:
type: string
format: uuid
- name: sensorID
in: path
description: ID of sensor to query
required: true
schema:
type: string
format: uuid
responses:
200:
description: Message sent
content: {}
500:
description: Message sending unsuccessful
content: {}
components:
schemas:
ListOfDevices:
type: array
items:
$ref: '#/components/schemas/Device'
Device:
required:
- id
- sensors
- status
- url
- coordinates
type: object
properties:
id:
type: string
format: uuid
status:
type: string
enum:
- online
- error
- offline
url:
type: string
format: url
coordinates:
required:
- latitude
- longitude
type: object
properties:
latitude:
type: number
format: double
longitude:
type: number
format: double
sensors:
$ref: '#/components/schemas/ArrayofSensors'
ArrayofSensors:
type: array
items:
$ref: '#/components/schemas/Sensor'
Sensor:
required:
- id
- status
type: object
properties:
id:
type: string
format: uuid
status:
type: string
enum:
- online
- unknown
- offline

BIN
docs/Dashboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/Login.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB