1*cf78ab8cSAndroid Build Coastguard Workerimport {css, html, LitElement} from 'lit'; 2*cf78ab8cSAndroid Build Coastguard Workerimport {customElement, property} from 'lit/decorators.js'; 3*cf78ab8cSAndroid Build Coastguard Workerimport {styleMap} from 'lit/directives/style-map.js'; 4*cf78ab8cSAndroid Build Coastguard Worker 5*cf78ab8cSAndroid Build Coastguard Workerimport {Device, Notifiable, SimulationInfo, simulationState,} from './device-observer.js'; 6*cf78ab8cSAndroid Build Coastguard Worker 7*cf78ab8cSAndroid Build Coastguard Worker@customElement('ns-device-map') 8*cf78ab8cSAndroid Build Coastguard Workerexport class DeviceMap extends LitElement implements Notifiable { 9*cf78ab8cSAndroid Build Coastguard Worker /** 10*cf78ab8cSAndroid Build Coastguard Worker * List of devices currently on the netsim. 11*cf78ab8cSAndroid Build Coastguard Worker */ 12*cf78ab8cSAndroid Build Coastguard Worker @property() deviceData: Device[] = []; 13*cf78ab8cSAndroid Build Coastguard Worker 14*cf78ab8cSAndroid Build Coastguard Worker /** 15*cf78ab8cSAndroid Build Coastguard Worker * Index of the background image displayed. 16*cf78ab8cSAndroid Build Coastguard Worker */ 17*cf78ab8cSAndroid Build Coastguard Worker @property() imageIdx = 0; 18*cf78ab8cSAndroid Build Coastguard Worker 19*cf78ab8cSAndroid Build Coastguard Worker /** 20*cf78ab8cSAndroid Build Coastguard Worker * Number of images available for the background. 21*cf78ab8cSAndroid Build Coastguard Worker */ 22*cf78ab8cSAndroid Build Coastguard Worker @property() numImages = 3; 23*cf78ab8cSAndroid Build Coastguard Worker 24*cf78ab8cSAndroid Build Coastguard Worker @property({type: Boolean, reflect: true}) isometric: boolean = false; 25*cf78ab8cSAndroid Build Coastguard Worker 26*cf78ab8cSAndroid Build Coastguard Worker connectedCallback() { 27*cf78ab8cSAndroid Build Coastguard Worker super.connectedCallback(); // eslint-disable-line 28*cf78ab8cSAndroid Build Coastguard Worker simulationState.registerObserver(this); 29*cf78ab8cSAndroid Build Coastguard Worker window.addEventListener('map-button-clicked', this.onChangeMap); 30*cf78ab8cSAndroid Build Coastguard Worker window.addEventListener( 31*cf78ab8cSAndroid Build Coastguard Worker 'isometric-button-clicked', this.handleIsometricView); 32*cf78ab8cSAndroid Build Coastguard Worker } 33*cf78ab8cSAndroid Build Coastguard Worker 34*cf78ab8cSAndroid Build Coastguard Worker disconnectedCallback() { 35*cf78ab8cSAndroid Build Coastguard Worker window.removeEventListener( 36*cf78ab8cSAndroid Build Coastguard Worker 'isometric-button-clicked', this.handleIsometricView); 37*cf78ab8cSAndroid Build Coastguard Worker window.removeEventListener('map-button-clicked', this.onChangeMap); 38*cf78ab8cSAndroid Build Coastguard Worker simulationState.removeObserver(this); 39*cf78ab8cSAndroid Build Coastguard Worker super.disconnectedCallback(); // eslint-disable-line 40*cf78ab8cSAndroid Build Coastguard Worker } 41*cf78ab8cSAndroid Build Coastguard Worker 42*cf78ab8cSAndroid Build Coastguard Worker static styles = css` 43*cf78ab8cSAndroid Build Coastguard Worker #dropzone { 44*cf78ab8cSAndroid Build Coastguard Worker margin-left: 200px; 45*cf78ab8cSAndroid Build Coastguard Worker margin-right: 200px; 46*cf78ab8cSAndroid Build Coastguard Worker transition: transform 2s, top 2s; 47*cf78ab8cSAndroid Build Coastguard Worker transform-style: preserve-3d; 48*cf78ab8cSAndroid Build Coastguard Worker } 49*cf78ab8cSAndroid Build Coastguard Worker 50*cf78ab8cSAndroid Build Coastguard Worker .box { 51*cf78ab8cSAndroid Build Coastguard Worker position: relative; 52*cf78ab8cSAndroid Build Coastguard Worker width: 1000px; //40vw; 53*cf78ab8cSAndroid Build Coastguard Worker height: 1000px; //40vh; 54*cf78ab8cSAndroid Build Coastguard Worker border: solid 1px rgb(198, 210, 255); 55*cf78ab8cSAndroid Build Coastguard Worker margin: 2.5em auto; 56*cf78ab8cSAndroid Build Coastguard Worker } 57*cf78ab8cSAndroid Build Coastguard Worker 58*cf78ab8cSAndroid Build Coastguard Worker .pattern0 { 59*cf78ab8cSAndroid Build Coastguard Worker background-image: url(./assets/grid-background.svg); 60*cf78ab8cSAndroid Build Coastguard Worker } 61*cf78ab8cSAndroid Build Coastguard Worker 62*cf78ab8cSAndroid Build Coastguard Worker .pattern1 { 63*cf78ab8cSAndroid Build Coastguard Worker background-image: url(./assets/polar-background.svg); 64*cf78ab8cSAndroid Build Coastguard Worker background-size: 1150px 1150px; 65*cf78ab8cSAndroid Build Coastguard Worker background-position: center; 66*cf78ab8cSAndroid Build Coastguard Worker } 67*cf78ab8cSAndroid Build Coastguard Worker 68*cf78ab8cSAndroid Build Coastguard Worker .pattern2 { 69*cf78ab8cSAndroid Build Coastguard Worker background-image: url(./assets/hexagonal-background.png); 70*cf78ab8cSAndroid Build Coastguard Worker background-size: 1175px 1175px; 71*cf78ab8cSAndroid Build Coastguard Worker background-position: center; 72*cf78ab8cSAndroid Build Coastguard Worker } 73*cf78ab8cSAndroid Build Coastguard Worker 74*cf78ab8cSAndroid Build Coastguard Worker .container { 75*cf78ab8cSAndroid Build Coastguard Worker display: flex; 76*cf78ab8cSAndroid Build Coastguard Worker width: 100%; 77*cf78ab8cSAndroid Build Coastguard Worker } 78*cf78ab8cSAndroid Build Coastguard Worker 79*cf78ab8cSAndroid Build Coastguard Worker .contentA { 80*cf78ab8cSAndroid Build Coastguard Worker flex: 2; 81*cf78ab8cSAndroid Build Coastguard Worker } 82*cf78ab8cSAndroid Build Coastguard Worker 83*cf78ab8cSAndroid Build Coastguard Worker .contentB { 84*cf78ab8cSAndroid Build Coastguard Worker flex: 2; 85*cf78ab8cSAndroid Build Coastguard Worker } 86*cf78ab8cSAndroid Build Coastguard Worker 87*cf78ab8cSAndroid Build Coastguard Worker ns-device-dragzone { 88*cf78ab8cSAndroid Build Coastguard Worker transform-style: inherit; 89*cf78ab8cSAndroid Build Coastguard Worker } 90*cf78ab8cSAndroid Build Coastguard Worker `; 91*cf78ab8cSAndroid Build Coastguard Worker 92*cf78ab8cSAndroid Build Coastguard Worker onNotify(data: SimulationInfo): void { 93*cf78ab8cSAndroid Build Coastguard Worker this.deviceData = data.devices; 94*cf78ab8cSAndroid Build Coastguard Worker this.requestUpdate(); 95*cf78ab8cSAndroid Build Coastguard Worker } 96*cf78ab8cSAndroid Build Coastguard Worker 97*cf78ab8cSAndroid Build Coastguard Worker private onChangeMap = () => { 98*cf78ab8cSAndroid Build Coastguard Worker this.imageIdx = (this.imageIdx + 1) % this.numImages; 99*cf78ab8cSAndroid Build Coastguard Worker }; 100*cf78ab8cSAndroid Build Coastguard Worker 101*cf78ab8cSAndroid Build Coastguard Worker private handleIsometricView = () => { 102*cf78ab8cSAndroid Build Coastguard Worker this.isometric = !this.isometric; 103*cf78ab8cSAndroid Build Coastguard Worker }; 104*cf78ab8cSAndroid Build Coastguard Worker 105*cf78ab8cSAndroid Build Coastguard Worker checkBle(device: Device): 106*cf78ab8cSAndroid Build Coastguard Worker boolean{return device.chips.at(0)?.bleBeacon !== undefined} 107*cf78ab8cSAndroid Build Coastguard Worker 108*cf78ab8cSAndroid Build Coastguard Worker render() { 109*cf78ab8cSAndroid Build Coastguard Worker const rainbow = [ 110*cf78ab8cSAndroid Build Coastguard Worker 'red', 111*cf78ab8cSAndroid Build Coastguard Worker 'orange', 112*cf78ab8cSAndroid Build Coastguard Worker 'yellow', 113*cf78ab8cSAndroid Build Coastguard Worker 'green', 114*cf78ab8cSAndroid Build Coastguard Worker 'blue', 115*cf78ab8cSAndroid Build Coastguard Worker 'indigo', 116*cf78ab8cSAndroid Build Coastguard Worker 'purple', 117*cf78ab8cSAndroid Build Coastguard Worker ]; 118*cf78ab8cSAndroid Build Coastguard Worker const viewStyle = this.isometric ? 119*cf78ab8cSAndroid Build Coastguard Worker `perspective(200rem) rotateX(60deg) rotateY(0deg) rotateZ(0deg) scale3d(0.8,0.8,0.8); top: 250px` : 120*cf78ab8cSAndroid Build Coastguard Worker 'none; top: 0px;'; 121*cf78ab8cSAndroid Build Coastguard Worker 122*cf78ab8cSAndroid Build Coastguard Worker return html` 123*cf78ab8cSAndroid Build Coastguard Worker <ns-device-dropzone role="widget" tabindex="0" aria-label="Device map"> 124*cf78ab8cSAndroid Build Coastguard Worker <div id="dropzone" class="box pattern${this.imageIdx}"> 125*cf78ab8cSAndroid Build Coastguard Worker ${ 126*cf78ab8cSAndroid Build Coastguard Worker this.deviceData.map( 127*cf78ab8cSAndroid Build Coastguard Worker (device, idx) => html` 128*cf78ab8cSAndroid Build Coastguard Worker ${ 129*cf78ab8cSAndroid Build Coastguard Worker true ? // TODO manage device.visible in Web UI 130*cf78ab8cSAndroid Build Coastguard Worker this.checkBle(device) ? 131*cf78ab8cSAndroid Build Coastguard Worker html` 132*cf78ab8cSAndroid Build Coastguard Worker <ns-device-dragzone 133*cf78ab8cSAndroid Build Coastguard Worker .action=${'move'} 134*cf78ab8cSAndroid Build Coastguard Worker style=${styleMap({ 135*cf78ab8cSAndroid Build Coastguard Worker position: 'absolute', 136*cf78ab8cSAndroid Build Coastguard Worker left: `${device.position.x * 100}px`, 137*cf78ab8cSAndroid Build Coastguard Worker top: `${device.position.y * 100}px`, 138*cf78ab8cSAndroid Build Coastguard Worker })} 139*cf78ab8cSAndroid Build Coastguard Worker > 140*cf78ab8cSAndroid Build Coastguard Worker <ns-pyramid-sprite 141*cf78ab8cSAndroid Build Coastguard Worker id=${device.name} 142*cf78ab8cSAndroid Build Coastguard Worker .color=${rainbow[idx % rainbow.length]} 143*cf78ab8cSAndroid Build Coastguard Worker .size=${'30px'} 144*cf78ab8cSAndroid Build Coastguard Worker .controls=${true} 145*cf78ab8cSAndroid Build Coastguard Worker yaw=${device.orientation.yaw} 146*cf78ab8cSAndroid Build Coastguard Worker pitch=${device.orientation.pitch} 147*cf78ab8cSAndroid Build Coastguard Worker roll=${device.orientation.roll} 148*cf78ab8cSAndroid Build Coastguard Worker posZ=${device.position.z * 100} 149*cf78ab8cSAndroid Build Coastguard Worker role="widget" 150*cf78ab8cSAndroid Build Coastguard Worker tabindex="1" 151*cf78ab8cSAndroid Build Coastguard Worker aria-label="${device.name} on Device Map, Position: ${ 152*cf78ab8cSAndroid Build Coastguard Worker Math.round(device.position.x * 100)}, ${ 153*cf78ab8cSAndroid Build Coastguard Worker Math.round(device.position.y * 100)}, ${ 154*cf78ab8cSAndroid Build Coastguard Worker Math.round( 155*cf78ab8cSAndroid Build Coastguard Worker device.position.z * 100)}, Orientation: yaw: ${ 156*cf78ab8cSAndroid Build Coastguard Worker device.orientation.yaw}, pitch: ${ 157*cf78ab8cSAndroid Build Coastguard Worker device.orientation.pitch}, roll: ${ 158*cf78ab8cSAndroid Build Coastguard Worker device.orientation.roll}" 159*cf78ab8cSAndroid Build Coastguard Worker aria-live="polite" 160*cf78ab8cSAndroid Build Coastguard Worker ></ns-pyramid-sprite> 161*cf78ab8cSAndroid Build Coastguard Worker </ns-device-dragzone> 162*cf78ab8cSAndroid Build Coastguard Worker ` : 163*cf78ab8cSAndroid Build Coastguard Worker html` 164*cf78ab8cSAndroid Build Coastguard Worker <ns-device-dragzone 165*cf78ab8cSAndroid Build Coastguard Worker .action=${'move'} 166*cf78ab8cSAndroid Build Coastguard Worker style=${styleMap({ 167*cf78ab8cSAndroid Build Coastguard Worker position: 'absolute', 168*cf78ab8cSAndroid Build Coastguard Worker left: `${device.position.x * 100}px`, 169*cf78ab8cSAndroid Build Coastguard Worker top: `${device.position.y * 100}px`, 170*cf78ab8cSAndroid Build Coastguard Worker })} 171*cf78ab8cSAndroid Build Coastguard Worker > 172*cf78ab8cSAndroid Build Coastguard Worker <ns-cube-sprite 173*cf78ab8cSAndroid Build Coastguard Worker id=${device.name} 174*cf78ab8cSAndroid Build Coastguard Worker .color=${rainbow[idx % rainbow.length]} 175*cf78ab8cSAndroid Build Coastguard Worker .size=${'30px'} 176*cf78ab8cSAndroid Build Coastguard Worker .controls=${true} 177*cf78ab8cSAndroid Build Coastguard Worker yaw=${device.orientation.yaw} 178*cf78ab8cSAndroid Build Coastguard Worker pitch=${device.orientation.pitch} 179*cf78ab8cSAndroid Build Coastguard Worker roll=${device.orientation.roll} 180*cf78ab8cSAndroid Build Coastguard Worker posZ=${device.position.z * 100} 181*cf78ab8cSAndroid Build Coastguard Worker role="widget" 182*cf78ab8cSAndroid Build Coastguard Worker tabindex="1" 183*cf78ab8cSAndroid Build Coastguard Worker aria-label="${device.name} on Device Map, Position: ${ 184*cf78ab8cSAndroid Build Coastguard Worker Math.round(device.position.x * 100)}, ${ 185*cf78ab8cSAndroid Build Coastguard Worker Math.round(device.position.y * 100)}, ${ 186*cf78ab8cSAndroid Build Coastguard Worker Math.round( 187*cf78ab8cSAndroid Build Coastguard Worker device.position.z * 100)}, Orientation: yaw: ${ 188*cf78ab8cSAndroid Build Coastguard Worker device.orientation.yaw}, pitch: ${ 189*cf78ab8cSAndroid Build Coastguard Worker device.orientation.pitch}, roll: ${ 190*cf78ab8cSAndroid Build Coastguard Worker device.orientation.roll}" 191*cf78ab8cSAndroid Build Coastguard Worker aria-live="polite" 192*cf78ab8cSAndroid Build Coastguard Worker ></ns-cube-sprite> 193*cf78ab8cSAndroid Build Coastguard Worker </ns-device-dragzone> 194*cf78ab8cSAndroid Build Coastguard Worker ` : 195*cf78ab8cSAndroid Build Coastguard Worker html``} 196*cf78ab8cSAndroid Build Coastguard Worker `)} 197*cf78ab8cSAndroid Build Coastguard Worker </div> 198*cf78ab8cSAndroid Build Coastguard Worker <style> 199*cf78ab8cSAndroid Build Coastguard Worker #dropzone { 200*cf78ab8cSAndroid Build Coastguard Worker transform: ${viewStyle}; 201*cf78ab8cSAndroid Build Coastguard Worker } 202*cf78ab8cSAndroid Build Coastguard Worker </style> 203*cf78ab8cSAndroid Build Coastguard Worker </ns-device-dropzone> 204*cf78ab8cSAndroid Build Coastguard Worker `; 205*cf78ab8cSAndroid Build Coastguard Worker } 206*cf78ab8cSAndroid Build Coastguard Worker} 207