├── .gitignore ├── LICENSE ├── README.md ├── dashboard ├── .gitignore ├── app │ ├── app.js │ ├── controllers.js │ ├── css │ │ └── iotdemo.css │ ├── directives │ │ ├── exec │ │ │ ├── biz-state.js │ │ │ ├── biz-trends.js │ │ │ ├── facility-utilization.js │ │ │ ├── maintain-events.js │ │ │ ├── summary.js │ │ │ └── top-facilities.js │ │ ├── header.js │ │ ├── mapchart.js │ │ ├── pkgtelemetry.js │ │ ├── shiplist.js │ │ ├── vehiclepanel.js │ │ └── vehicleslist.js │ ├── imgs │ │ ├── logo.png │ │ ├── plan.jpg │ │ ├── rhpower.png │ │ ├── truck-Engine Temp.png │ │ ├── truck-Oil Pressure.png │ │ ├── truck-RPM.png │ │ ├── truck-plain.png │ │ └── vandelay.png │ ├── routes.js │ └── services │ │ ├── reports.js │ │ ├── sensor.js │ │ ├── shipments.js │ │ └── vehicles.js ├── bower.json ├── config.js ├── package.json ├── server.js └── views │ ├── index.html │ ├── kurapayload.proto │ └── partials │ ├── exec │ ├── biz-state.html │ ├── biz-trends.html │ ├── facility-utilization.html │ ├── home.html │ ├── maintain-events.html │ ├── summary.html │ └── top-facilities.html │ ├── facility.html │ ├── header.html │ ├── history.html │ ├── home.html │ ├── mapchart.html │ ├── pkgtelemetry.html │ ├── shiplist.html │ ├── vehiclepanel.html │ └── vehicleslist.html ├── dgproxy ├── pom.xml └── src │ └── main │ ├── java │ ├── com │ │ └── redhat │ │ │ └── iot │ │ │ └── cargodemo │ │ │ ├── model │ │ │ ├── Alert.java │ │ │ ├── Customer.java │ │ │ ├── Facility.java │ │ │ ├── LatLng.java │ │ │ ├── Operator.java │ │ │ ├── Shipment.java │ │ │ ├── Summary.java │ │ │ ├── Telemetry.java │ │ │ └── Vehicle.java │ │ │ ├── rest │ │ │ ├── CORSFilter.java │ │ │ ├── CustomerEndpoint.java │ │ │ ├── FacilitiesEndpoint.java │ │ │ ├── RestApplication.java │ │ │ ├── ShipmentsEndpoint.java │ │ │ ├── UtilsEndpoint.java │ │ │ └── VehiclesEndpoint.java │ │ │ └── service │ │ │ ├── AlertsService.java │ │ │ └── DGService.java │ └── org │ │ └── eclipse │ │ └── kura │ │ └── core │ │ └── message │ │ └── protobuf │ │ └── KuraPayloadProto.java │ ├── resources │ └── kurapayload.proto │ └── webapp │ └── WEB-INF │ ├── beans.xml │ └── web.xml ├── docs ├── qr │ ├── README.md │ ├── go.sh │ ├── pkg-1.png │ ├── pkg-10.png │ ├── pkg-11.png │ ├── pkg-12.png │ ├── pkg-13.png │ ├── pkg-14.png │ ├── pkg-15.png │ ├── pkg-16.png │ ├── pkg-17.png │ ├── pkg-18.png │ ├── pkg-19.png │ ├── pkg-2.png │ ├── pkg-20.png │ ├── pkg-3.png │ ├── pkg-4.png │ ├── pkg-5.png │ ├── pkg-6.png │ ├── pkg-7.png │ ├── pkg-8.png │ ├── pkg-9.png │ ├── truck-1.png │ ├── truck-10.png │ ├── truck-2.png │ ├── truck-3.png │ ├── truck-4.png │ ├── truck-5.png │ ├── truck-6.png │ ├── truck-7.png │ ├── truck-8.png │ └── truck-9.png └── screenshots │ ├── exec.png │ └── fleet.png ├── iot-demo.yml ├── iot-sim-deploy.sh ├── iot-simulator.yml ├── openshift-common.sh ├── openshift-deploy.sh ├── openshift-iot.sh └── simulator └── generators.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | target/ 3 | out/ 4 | .DS_Store 5 | *.classpath 6 | *.project 7 | *.settings 8 | .security/ 9 | *.jar 10 | *.war 11 | *.iml 12 | .idea 13 | workspace 14 | data 15 | logs/ 16 | tmp/ 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and documentation 12 | distributed under this Agreement, and 13 | b) in the case of each subsequent Contributor: 14 | i) changes to the Program, and 15 | ii) additions to the Program; 16 | 17 | where such changes and/or additions to the Program originate from and are 18 | distributed by that particular Contributor. A Contribution 'originates' 19 | from a Contributor if it was added to the Program by such Contributor 20 | itself or anyone acting on such Contributor's behalf. Contributions do not 21 | include additions to the Program which: (i) are separate modules of 22 | software distributed in conjunction with the Program under their own 23 | license agreement, and (ii) are not derivative works of the Program. 24 | 25 | "Contributor" means any person or entity that distributes the Program. 26 | 27 | "Licensed Patents" mean patent claims licensable by a Contributor which are 28 | necessarily infringed by the use or sale of its Contribution alone or when 29 | combined with the Program. 30 | 31 | "Program" means the Contributions distributed in accordance with this 32 | Agreement. 33 | 34 | "Recipient" means anyone who receives the Program under this Agreement, 35 | including all Contributors. 36 | 37 | 2. GRANT OF RIGHTS 38 | a) Subject to the terms of this Agreement, each Contributor hereby grants 39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 40 | reproduce, prepare derivative works of, publicly display, publicly 41 | perform, distribute and sublicense the Contribution of such Contributor, 42 | if any, and such derivative works, in source code and object code form. 43 | b) Subject to the terms of this Agreement, each Contributor hereby grants 44 | Recipient a non-exclusive, worldwide, royalty-free patent license under 45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 46 | transfer the Contribution of such Contributor, if any, in source code and 47 | object code form. This patent license shall apply to the combination of 48 | the Contribution and the Program if, at the time the Contribution is 49 | added by the Contributor, such addition of the Contribution causes such 50 | combination to be covered by the Licensed Patents. The patent license 51 | shall not apply to any other combinations which include the Contribution. 52 | No hardware per se is licensed hereunder. 53 | c) Recipient understands that although each Contributor grants the licenses 54 | to its Contributions set forth herein, no assurances are provided by any 55 | Contributor that the Program does not infringe the patent or other 56 | intellectual property rights of any other entity. Each Contributor 57 | disclaims any liability to Recipient for claims brought by any other 58 | entity based on infringement of intellectual property rights or 59 | otherwise. As a condition to exercising the rights and licenses granted 60 | hereunder, each Recipient hereby assumes sole responsibility to secure 61 | any other intellectual property rights needed, if any. For example, if a 62 | third party patent license is required to allow Recipient to distribute 63 | the Program, it is Recipient's responsibility to acquire that license 64 | before distributing the Program. 65 | d) Each Contributor represents that to its knowledge it has sufficient 66 | copyright rights in its Contribution, if any, to grant the copyright 67 | license set forth in this Agreement. 68 | 69 | 3. REQUIREMENTS 70 | 71 | A Contributor may choose to distribute the Program in object code form under 72 | its own license agreement, provided that: 73 | 74 | a) it complies with the terms and conditions of this Agreement; and 75 | b) its license agreement: 76 | i) effectively disclaims on behalf of all Contributors all warranties 77 | and conditions, express and implied, including warranties or 78 | conditions of title and non-infringement, and implied warranties or 79 | conditions of merchantability and fitness for a particular purpose; 80 | ii) effectively excludes on behalf of all Contributors all liability for 81 | damages, including direct, indirect, special, incidental and 82 | consequential damages, such as lost profits; 83 | iii) states that any provisions which differ from this Agreement are 84 | offered by that Contributor alone and not by any other party; and 85 | iv) states that source code for the Program is available from such 86 | Contributor, and informs licensees how to obtain it in a reasonable 87 | manner on or through a medium customarily used for software exchange. 88 | 89 | When the Program is made available in source code form: 90 | 91 | a) it must be made available under this Agreement; and 92 | b) a copy of this Agreement must be included with each copy of the Program. 93 | Contributors may not remove or alter any copyright notices contained 94 | within the Program. 95 | 96 | Each Contributor must identify itself as the originator of its Contribution, 97 | if 98 | any, in a manner that reasonably allows subsequent Recipients to identify the 99 | originator of the Contribution. 100 | 101 | 4. COMMERCIAL DISTRIBUTION 102 | 103 | Commercial distributors of software may accept certain responsibilities with 104 | respect to end users, business partners and the like. While this license is 105 | intended to facilitate the commercial use of the Program, the Contributor who 106 | includes the Program in a commercial product offering should do so in a manner 107 | which does not create potential liability for other Contributors. Therefore, 108 | if a Contributor includes the Program in a commercial product offering, such 109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify 110 | every other Contributor ("Indemnified Contributor") against any losses, 111 | damages and costs (collectively "Losses") arising from claims, lawsuits and 112 | other legal actions brought by a third party against the Indemnified 113 | Contributor to the extent caused by the acts or omissions of such Commercial 114 | Contributor in connection with its distribution of the Program in a commercial 115 | product offering. The obligations in this section do not apply to any claims 116 | or Losses relating to any actual or alleged intellectual property 117 | infringement. In order to qualify, an Indemnified Contributor must: 118 | a) promptly notify the Commercial Contributor in writing of such claim, and 119 | b) allow the Commercial Contributor to control, and cooperate with the 120 | Commercial Contributor in, the defense and any related settlement 121 | negotiations. The Indemnified Contributor may participate in any such claim at 122 | its own expense. 123 | 124 | For example, a Contributor might include the Program in a commercial product 125 | offering, Product X. That Contributor is then a Commercial Contributor. If 126 | that Commercial Contributor then makes performance claims, or offers 127 | warranties related to Product X, those performance claims and warranties are 128 | such Commercial Contributor's responsibility alone. Under this section, the 129 | Commercial Contributor would have to defend claims against the other 130 | Contributors related to those performance claims and warranties, and if a 131 | court requires any other Contributor to pay any damages as a result, the 132 | Commercial Contributor must pay those damages. 133 | 134 | 5. NO WARRANTY 135 | 136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN 137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each 140 | Recipient is solely responsible for determining the appropriateness of using 141 | and distributing the Program and assumes all risks associated with its 142 | exercise of rights under this Agreement , including but not limited to the 143 | risks and costs of program errors, compliance with applicable laws, damage to 144 | or loss of data, programs or equipment, and unavailability or interruption of 145 | operations. 146 | 147 | 6. DISCLAIMER OF LIABILITY 148 | 149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 156 | OF SUCH DAMAGES. 157 | 158 | 7. GENERAL 159 | 160 | If any provision of this Agreement is invalid or unenforceable under 161 | applicable law, it shall not affect the validity or enforceability of the 162 | remainder of the terms of this Agreement, and without further action by the 163 | parties hereto, such provision shall be reformed to the minimum extent 164 | necessary to make such provision valid and enforceable. 165 | 166 | If Recipient institutes patent litigation against any entity (including a 167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 168 | (excluding combinations of the Program with other software or hardware) 169 | infringes such Recipient's patent(s), then such Recipient's rights granted 170 | under Section 2(b) shall terminate as of the date such litigation is filed. 171 | 172 | All Recipient's rights under this Agreement shall terminate if it fails to 173 | comply with any of the material terms or conditions of this Agreement and does 174 | not cure such failure in a reasonable period of time after becoming aware of 175 | such noncompliance. If all Recipient's rights under this Agreement terminate, 176 | Recipient agrees to cease use and distribution of the Program as soon as 177 | reasonably practicable. However, Recipient's obligations under this Agreement 178 | and any licenses granted by Recipient relating to the Program shall continue 179 | and survive. 180 | 181 | Everyone is permitted to copy and distribute copies of this Agreement, but in 182 | order to avoid inconsistency the Agreement is copyrighted and may only be 183 | modified in the following manner. The Agreement Steward reserves the right to 184 | publish new versions (including revisions) of this Agreement from time to 185 | time. No one other than the Agreement Steward has the right to modify this 186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 187 | Eclipse Foundation may assign the responsibility to serve as the Agreement 188 | Steward to a suitable separate entity. Each new version of the Agreement will 189 | be given a distinguishing version number. The Program (including 190 | Contributions) may always be distributed subject to the version of the 191 | Agreement under which it was received. In addition, after a new version of the 192 | Agreement is published, Contributor may elect to distribute the Program 193 | (including its Contributions) under the new version. Except as expressly 194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 195 | licenses to the intellectual property of any Contributor under this Agreement, 196 | whether expressly, by implication, estoppel or otherwise. All rights in the 197 | Program not expressly granted under this Agreement are reserved. 198 | 199 | This Agreement is governed by the laws of the State of New York and the 200 | intellectual property laws of the United States of America. No party to this 201 | Agreement will bring a legal action under this Agreement more than one year 202 | after the cause of action arose. Each party waives its rights to a jury trial in 203 | any resulting litigation. 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Red Hat Fleet Telematics & Asset Tracking IoT Demo 2 | ================================================== 3 | This is an example IoT demo showing a realtime updating dashboard of data streaming from an 4 | IoT gateway device (based on Eclipse Kura) through an Eclipse Kapua-based instance. 5 | 6 | It demonstrates realtime fleet telematics, package tracking, alerting, and a telemetry dashboard showing critical measurements of packages in transit, 7 | including temperature, humidity, displacement, light levels, etc. 8 | 9 | ![Dashboard Screenshot](docs/screenshots/fleet.png "Dashboard Screenshot") 10 | ![Dashboard Screenshot](docs/screenshots/exec.png "Exec Dashboard Screenshot") 11 | 12 | Technologies used: 13 | 14 | - [Eclipse Kapua](http://www.eclipse.org/kapua/) 15 | - [AngularJS](http://angularjs.org) 16 | - [Patternfly](http://patternfly.org) 17 | - [JBoss Middleware](https://www.redhat.com/en/technologies/jboss-middleware) (EAP, JDG, and more to come) 18 | 19 | Running on OpenShift 20 | -------------------- 21 | 22 | The demo deploys as an Angular.js app running on a Node.js runtime, along with JBoss Data Grid and a Data Grid 23 | proxy component that properly handles browser-based REST requests and relays to JBoss Data Grid via the Hotrod 24 | protocol. 25 | 26 | Eclipse Kapua is also deployed and acts as the IoT cloud management layer. 27 | 28 | Follow these steps to build and run the demo: 29 | 30 | 1. Install and have access to an [OpenShift Container Platform](https://www.openshift.com/container-platform/) 3.4 or later or [OpenShift Origin](https://www.openshift.org/) 1.4 or later. You must be able to use the `oc` command line tool. 31 | 32 | 2. Clone this repo 33 | ``` 34 | git clone https://github.com/redhat-iot/summit2017 35 | cd summit2017 36 | ``` 37 | 38 | 3. Issue the following commands to create a new OpenShift project and deploy the demo components: 39 | ``` 40 | oc new-project redhat-iot --display-name="Red Hat IoT Demo" 41 | oc policy add-role-to-user view system:serviceaccount:$(oc project -q):default -n $(oc project -q) 42 | ./openshift-deploy.sh 43 | ``` 44 | 45 | You can monitor the build with `oc status` or watch the deployments using the OpenShift web console. 46 | 47 | If you see some components with "No Deployments" or are not building, you may need to add imagestream 48 | definitions for ``wildfly`` and ``jboss-datagrid``. To do so, run these commands: 49 | 50 | ``` 51 | oc login -u system:admin (Or login with any userid that has cluster-admin privileges, TODO: Explain all options here) 52 | oc create -n openshift -f https://raw.githubusercontent.com/jboss-openshift/application-templates/master/jboss-image-streams.json 53 | oc create -n openshift -f https://raw.githubusercontent.com/openshift/origin/master/examples/image-streams/image-streams-centos7.json 54 | ``` 55 | 56 | Once everything is up and running, you can access the demo using the URL of the `dashboard` route, 57 | for example `http://dashboard-redhat-iot.domain` 58 | 59 | Confirm that all the components are running successfully: 60 | 61 | ``` 62 | oc get pods --show-all=false 63 | ``` 64 | You should see the following pods and their status: 65 | 66 | |NAME | READY | STATUS | 67 | |---------------------|:-----------:|:-------:| 68 | |dashboard-1-xxx | 1/1 | Running | 69 | |datastore-1-xxx | 1/1 | Running | 70 | |datastore-proxy-1-xxx| 1/1 | Running | 71 | |elasticsearch-1-xxx | 1/1 | Running | 72 | |kapua-api-1-wc1l7 | 1/1 | Running | 73 | |kapua-broker-1-xxx | 1/1 | Running | 74 | |kapua-console-1-xxx | 1/1 | Running | 75 | |simulator-1-xxx | 1/1 | Running | 76 | |sql-1-xxx | 1/1 | Running | 77 | 78 | Eclipse Kapua API Documentation 79 | ------------------------------- 80 | Eclipse Kapua exposes a REST API which can be used to access Kapua data and invoke Kapua operations. The REST API application is running as a dedicated Java process. 81 | 82 | For example, to use the `curl` command login to Eclipse Kapua and retrieve an authentication token: 83 | 84 | ``` 85 | curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{"password": ["your_password"], "username": "your_username"}' 'http://api-redhat-iot.domain/v1/authentication/user' 86 | ``` 87 | 88 | Once logged in, the retrieved token can be passed for future API calls, e.g. 89 | 90 | ``` 91 | curl -X GET --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer ' http://api-redhat-iot.domain/v1/my_scope/devices 92 | ``` 93 | 94 | The complete API documentation can accessed using the URL of the `api` route, for example `http://api-redhat-iot.domain/doc`. More information on the REST API can be found in the [Eclipse Kapua user guide](http://download.eclipse.org/kapua/docs/develop/user-manual/en/rest.html). 95 | 96 | 97 | Add template to "Add to project" 98 | -------------------------------- 99 | The following command will add the template and the options to the "Add to project" screen in the 100 | "Other" section. The template will deploy with defaults the same as it does using the scripts above. 101 | ``` 102 | oc create -f iot-demo.yml 103 | ``` 104 | 105 | Options 106 | ------- 107 | The template contains various optional parameters that can be specified when deploying the components: 108 | 109 | ``` 110 | oc process -f openshift-template.yaml OPTION1=value OPTION2=value | oc create -f - 111 | ``` 112 | 113 | * `MAVEN_MIRROR_URL` - To speed up Maven-based builds 114 | * `GOOGLE_MAPS_API_KEY` - for your personal Google Maps API key 115 | * `GIT_URI` and `GIT_REF` - overrides where source code is pulled (e.g. using your own personal fork) 116 | * `IMAGE_VERSION` - Docker image tag to use when pulling Kapua (default `latest`) 117 | * `DOCKER_ACCOUNT` - Name of docker account to use when pulling Kapua (default: `redhatiot`) 118 | 119 | There are other options in the template that can be overridden if you know what you are doing! 120 | 121 | Uninstalling and cleaning up project 122 | ------------------------------------ 123 | ``` 124 | oc delete all --all -n redhat-iot && oc delete configmap hawkular-openshift-agent-kapua data-simulator-config -n redhat-iot 125 | ``` 126 | This will delete everything but the project "Red Hat IoT". This is suitable for testing new scripts, template, 127 | etc. 128 | -------------------------------------------------------------------------------- /dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .DS_Store 3 | *.classpath 4 | *.settings 5 | *.tern* 6 | .idea 7 | *.iml 8 | .security/ 9 | *.jar 10 | src/main/webapp/vendor 11 | app.properties -------------------------------------------------------------------------------- /dashboard/app/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | var module = angular.module('app', ['ngRoute', 'ui.bootstrap', 'patternfly', 19 | 'angular-websocket', 'ngMap', 'angularMoment', 'n3-line-chart','scrollable-table', 20 | 'frapontillo.bootstrap-switch']); 21 | 22 | angular.element(document).ready(function () { 23 | 24 | // get config 25 | var initInjector = angular.injector(["ng"]); 26 | var $http = initInjector.get("$http"); 27 | 28 | $http.get("config.json").then(function (response) { 29 | module.constant("APP_CONFIG", response.data); 30 | console.log("Bootstrapping system"); 31 | angular.bootstrap(document, ["app"], { 32 | strictDi: true 33 | }); 34 | }); 35 | }); 36 | 37 | -------------------------------------------------------------------------------- /dashboard/app/css/iotdemo.css: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | #chart_container { 17 | position: relative; 18 | font-family: Arial, Helvetica, sans-serif; 19 | margin: 10px; 20 | } 21 | 22 | #historylink { 23 | position: absolute; 24 | right: 0; 25 | bottom: 0; 26 | width: 25%; 27 | text-align: center; 28 | } 29 | 30 | #chart { 31 | position: relative; 32 | left: 10%; 33 | width: 60%; 34 | } 35 | 36 | #y_axis { 37 | position: absolute; 38 | top: 0; 39 | bottom: 0; 40 | width: 10%; 41 | } 42 | 43 | .detail_swatch { 44 | float: right; 45 | display: inline-block; 46 | width: 10px; 47 | height: 10px; 48 | margin: 0 4px 0 0 49 | } 50 | 51 | #datalabeldiv { 52 | position: absolute; 53 | top: 0; 54 | left: 75%; 55 | width: 25%; 56 | } 57 | 58 | #datalabel { 59 | font-size: 3em; 60 | } 61 | 62 | .line { 63 | fill: none; 64 | stroke: url(#line-gradient); 65 | stroke-width: 2px; 66 | } 67 | 68 | .custom-marker { 69 | /*font-size: 1.5em;*/ 70 | padding: 10px; 71 | background: #fff; 72 | -webkit-border-radius: 4px; 73 | -moz-border-radius: 4px; 74 | border-radius: 4px; 75 | border: #7F7F7F solid 1px; 76 | } 77 | 78 | .p-a-3 { 79 | padding: 3px; 80 | } 81 | 82 | .p-t-10 { 83 | padding-top: 10px; 84 | } 85 | 86 | .panel-body { 87 | padding: 15px; 88 | } 89 | 90 | .modal-body { 91 | max-height: calc(100vh - 210px); 92 | overflow-y: auto; 93 | } 94 | 95 | .row-eq-height { 96 | display: -webkit-box; 97 | display: -webkit-flex; 98 | display: -ms-flexbox; 99 | display: flex; 100 | } 101 | 102 | /* For telemetry charts */ 103 | 104 | .chart-legend { 105 | display: none; 106 | } 107 | 108 | .chart .axis { 109 | display: none; 110 | } 111 | 112 | .scrollArea table th .box { 113 | background-clip: padding-box; 114 | background-image: linear-gradient(to bottom,#fafafa 0,#ededed 100%); 115 | background-repeat: repeat-x; 116 | } 117 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/biz-state.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execBizState', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | scope: true, 25 | replace: true, 26 | templateUrl: 'partials/exec/biz-state.html', 27 | controller: 'ExecBizStateController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/biz-trends.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execBizTrends', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/exec/biz-trends.html', 27 | controller: 'ExecBizTrendsController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/facility-utilization.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execFacilityUtilization', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/exec/facility-utilization.html', 27 | controller: 'ExecFacilityUtilizationController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/maintain-events.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execMaintainEvents', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/exec/maintain-events.html', 27 | controller: 'ExecMaintainEventsController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/summary.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execSummary', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/exec/summary.html', 27 | controller: 'ExecSummaryController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/exec/top-facilities.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('execTopFacilities', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/exec/top-facilities.html', 27 | controller: 'ExecTopFacilitiesController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/header.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('header', function() { 20 | return { 21 | restrict: 'A', 22 | replace: true, 23 | scope: true, 24 | templateUrl: 'partials/header.html', 25 | controller: 'HeaderController' 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /dashboard/app/directives/mapchart.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('mapChart', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/mapchart.html', 27 | controller: 'MapController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/pkgtelemetry.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('pkgTelemetry', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/pkgtelemetry.html', 27 | controller: 'PkgTelemetryController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/shiplist.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('shipList', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/shiplist.html', 27 | controller: 'ShipListController', 28 | link: function postLink(scope, element, attrs) { 29 | element.find('[data-toggle="tooltip"]').tooltip() 30 | 31 | } 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /dashboard/app/directives/vehiclepanel.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('vehiclePanel', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | replace: true, 25 | scope: true, 26 | templateUrl: 'partials/vehiclepanel.html', 27 | controller: 'VehiclePanelController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/directives/vehicleslist.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | 19 | angular.module('app').directive('vehiclesList', function () { 20 | 21 | 22 | return { 23 | restrict: 'E', 24 | scope: true, 25 | replace: true, 26 | templateUrl: 'partials/vehicleslist.html', 27 | controller: 'VehiclesListController' 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /dashboard/app/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/logo.png -------------------------------------------------------------------------------- /dashboard/app/imgs/plan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/plan.jpg -------------------------------------------------------------------------------- /dashboard/app/imgs/rhpower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/rhpower.png -------------------------------------------------------------------------------- /dashboard/app/imgs/truck-Engine Temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/truck-Engine Temp.png -------------------------------------------------------------------------------- /dashboard/app/imgs/truck-Oil Pressure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/truck-Oil Pressure.png -------------------------------------------------------------------------------- /dashboard/app/imgs/truck-RPM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/truck-RPM.png -------------------------------------------------------------------------------- /dashboard/app/imgs/truck-plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/truck-plain.png -------------------------------------------------------------------------------- /dashboard/app/imgs/vandelay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/dashboard/app/imgs/vandelay.png -------------------------------------------------------------------------------- /dashboard/app/routes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | angular.module('app').config([ '$routeProvider', function($routeProvider) { 19 | $routeProvider.when('/', { 20 | templateUrl : 'partials/home.html', 21 | controller : 'HomeController' 22 | }).when('/exec', { 23 | templateUrl : 'partials/exec/home.html', 24 | controller : 'ExecHomeController' 25 | }).otherwise({ 26 | redirectTo : '/' 27 | }); 28 | } ]); 29 | -------------------------------------------------------------------------------- /dashboard/app/services/reports.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | angular.module('app') 19 | 20 | .factory('Reports', ['$rootScope', '$location', '$http', '$q', 'APP_CONFIG', 'Notifications', 21 | function($rootScope, $location, $http, $q, APP_CONFIG, Notifications) { 22 | 23 | var factory = {}, 24 | summaries = [], 25 | facilities = [], 26 | 27 | configRestEndpoint = "http://" + APP_CONFIG.DATASTORE_REST_HOSTNAME + '.' + $location.host().replace(/^.*?\.(.*)/g,"$1") + '/api'; 28 | 29 | 30 | factory.getSummaries = function() { 31 | return summaries; 32 | }; 33 | 34 | factory.getShipCount = function() { 35 | var shipCount = 0; 36 | summaries.forEach(function(summary) { 37 | if (summary.name == 'packages') { 38 | shipCount = summary.count; 39 | } 40 | }); 41 | return shipCount; 42 | }; 43 | factory.getFacilities = function() { 44 | return facilities; 45 | }; 46 | 47 | factory.refresh = function() { 48 | 49 | // get summaries 50 | $http({ 51 | method: 'GET', 52 | url: configRestEndpoint + '/utils/summaries' 53 | }).then(function (response) { 54 | summaries = response.data; 55 | if ((summaries == undefined) || (summaries.constructor !== Array)) { 56 | Notifications.error("Error fetching Summaries (invalid data). Reload to retry"); 57 | return; 58 | } 59 | 60 | $rootScope.$broadcast('summaries:updated', summaries); 61 | 62 | }, function err(response) { 63 | console.log(JSON.stringify(response)); 64 | Notifications.error("Error fetching Summaries Configuration from [" + response.config.url + "]. Reload to retry"); 65 | }); 66 | 67 | // get facilities 68 | $http({ 69 | method: 'GET', 70 | url: configRestEndpoint + '/facilities' 71 | }).then(function (response) { 72 | facilities = response.data; 73 | if ((facilities == undefined) || (facilities.constructor !== Array)) { 74 | Notifications.error("Error fetching Facilities (invalid data). Reload to retry"); 75 | return; 76 | } 77 | 78 | $rootScope.$broadcast('facilities:updated', facilities); 79 | 80 | }, function err(response) { 81 | console.log(JSON.stringify(response)); 82 | Notifications.error("Error fetching Facilities from [" + response.config.url + "]. Reload to retry"); 83 | }); 84 | 85 | }; 86 | 87 | factory.refresh(); 88 | 89 | return factory; 90 | }]); 91 | -------------------------------------------------------------------------------- /dashboard/app/services/sensor.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * Benjamin Cabé (Eclipse Foundation) - #1 ES histogram should be showing history for the selected package only 13 | * 14 | * ****************************************************************************** 15 | */ 16 | 17 | 'use strict'; 18 | 19 | angular.module('app') 20 | 21 | .factory('SensorData', ['$http', '$filter', '$timeout', '$interval', '$rootScope', '$location', '$q', 'APP_CONFIG', 'Notifications', 'Reports', 'Shipments', 'Vehicles', 22 | function ($http, $filter, $timeout, $interval, $rootScope, $location, $q, APP_CONFIG, Notifications, Reports, Shipments, Vehicles) { 23 | var factory = {}, 24 | client = null, 25 | msgproto = null, 26 | listeners = [], 27 | topicRegex = /Red-Hat\/([^\/]*)\/iot-demo\/([^\/]*)\/([^\/]*)$/, 28 | alertRegex = /Red-Hat\/([^\/]*)\/iot-demo\/([^\/]*)\/([^\/]*)\/alerts$/, 29 | metricOverrides = {}; 30 | 31 | // Set the name of the hidden property and the change event for visibility 32 | var hidden, visibilityChange; 33 | if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 34 | hidden = "hidden"; 35 | visibilityChange = "visibilitychange"; 36 | } else if (typeof document.msHidden !== "undefined") { 37 | hidden = "msHidden"; 38 | visibilityChange = "msvisibilitychange"; 39 | } else if (typeof document.webkitHidden !== "undefined") { 40 | hidden = "webkitHidden"; 41 | visibilityChange = "webkitvisibilitychange"; 42 | } 43 | 44 | // If the page/tab is hidden, pause the data stream; 45 | // if the page/tab is shown, restart the stream 46 | function handleVisibilityChange() { 47 | if (document[hidden]) { 48 | listeners.forEach(function(listener) { 49 | client.unsubscribe(listener.topic); 50 | }); 51 | } else { 52 | // doc played 53 | listeners.forEach(function(listener) { 54 | client.subscribe(listener.topic); 55 | }); 56 | } 57 | } 58 | 59 | // Warn if the browser doesn't support addEventListener or the Page Visibility API 60 | if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") { 61 | console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API."); 62 | } else { 63 | // Handle page visibility change 64 | document.addEventListener(visibilityChange, handleVisibilityChange, false); 65 | } 66 | 67 | function onConnectionLost(responseObject) { 68 | if (responseObject.errorCode !== 0) { 69 | console.log("onConnectionLost:"+responseObject.errorMessage); 70 | Notifications.warn("Lost connection to broker, attempting to reconnect (" + responseObject.errorMessage); 71 | connectClient(1); 72 | 73 | } 74 | } 75 | 76 | function handleAlert(destination, alertObj) { 77 | 78 | if (alertObj.type == 'VEHICLE') { 79 | $rootScope.$broadcast('vehicle:alert', { 80 | vin: alertObj.truckid, 81 | message: $filter('date')(alertObj.date, 'medium') + ": " + 82 | alertObj.desc + ": " + alertObj.message 83 | }); 84 | } else if (alertObj.type == 'PACKAGE') { 85 | $rootScope.$broadcast('package:alert', { 86 | vin: alertObj.truckid, 87 | sensor_id: alertObj.sensorid, 88 | message: $filter('date')(alertObj.date, 'medium') + ": " + 89 | alertObj.desc + ": " + alertObj.message 90 | }); 91 | } 92 | 93 | Reports.refresh(); 94 | 95 | } 96 | 97 | function onMessageArrived(message) { 98 | var destination = message.destinationName; 99 | 100 | if (alertRegex.test(destination)) { 101 | handleAlert(destination, JSON.parse(message.payloadString)); 102 | } else { 103 | var payload = message.payloadBytes; 104 | var decoded = msgproto.decode(payload); 105 | var matches = topicRegex.exec(destination); 106 | var objType = matches[2]; 107 | var objId = matches[3]; 108 | 109 | listeners.filter(function(listener) { 110 | return (listener.objType == objType && listener.objId == objId); 111 | }).forEach(function(listener) { 112 | var targetObj = listener.pkg || listener.vehicle; 113 | var cb = listener.listener; 114 | 115 | var data = []; 116 | 117 | decoded.metric.forEach(function(decodedMetric) { 118 | targetObj.telemetry.forEach(function(objTel) { 119 | var telName = objTel.name; 120 | var telMetricName = objTel.metricName; 121 | var value = (metricOverrides[listener.objId] && metricOverrides[listener.objId][telMetricName]) ? 122 | (metricOverrides[listener.objId][telMetricName] * (.95 + 0.05 * Math.random())).toFixed(1) : 123 | decodedMetric.doubleValue.toFixed(1); 124 | if (telMetricName == decodedMetric.name) { 125 | data.push({ 126 | name: telName, 127 | value: value, 128 | timestamp: new Date() 129 | }); 130 | } 131 | }); 132 | }); 133 | cb(data); 134 | }); 135 | } 136 | } 137 | 138 | function onConnect() { 139 | console.log("Connected to server"); 140 | var topicName = "Red-Hat/+/iot-demo/+/+/alerts"; 141 | client.subscribe(topicName); 142 | 143 | } 144 | 145 | function connectClient(attempt) { 146 | 147 | var MAX_ATTEMPTS = 100; 148 | 149 | if (attempt > MAX_ATTEMPTS) { 150 | Notifications.error("Cannot connect to broker after " + MAX_ATTEMPTS +" attempts, reload to retry"); 151 | return; 152 | } 153 | 154 | if (attempt > 1) { 155 | Notifications.warn("Trouble connecting to broker, will keep trying (reload to re-start the count)"); 156 | } 157 | var brokerHostname = APP_CONFIG.BROKER_WEBSOCKET_HOSTNAME + '.' + $location.host().replace(/^.*?\.(.*)/g,"$1"); 158 | client = new Paho.MQTT.Client(brokerHostname, Number(APP_CONFIG.BROKER_WEBSOCKET_PORT), "demo-client-" + guid()); 159 | 160 | client.onConnectionLost = onConnectionLost; 161 | client.onMessageArrived = onMessageArrived; 162 | 163 | protobuf.load("kurapayload.proto", function(err, root) { 164 | if (err) throw err; 165 | 166 | msgproto = root.lookup("kuradatatypes.KuraPayload"); 167 | // connect the client 168 | client.connect({ 169 | onSuccess: function() { 170 | console.log("Connected to broker"); 171 | if (attempt > 1) { 172 | Notifications.success("Connected to the IoT cloud!"); 173 | } 174 | var topicName = "Red-Hat/+/iot-demo/+/+/alerts"; 175 | client.subscribe(topicName); 176 | }, 177 | userName: APP_CONFIG.BROKER_USERNAME, 178 | password: APP_CONFIG.BROKER_PASSWORD, 179 | onFailure: function(err) { 180 | console.log("Failed to connect to broker (attempt " + attempt + "), retrying. Error code:" + err.errorCode + " message:" + err.errorMessage); 181 | $timeout(function() { 182 | connectClient(attempt+1); 183 | }, 10000); 184 | } 185 | }); 186 | }); 187 | } 188 | 189 | function guid() { 190 | function s4() { 191 | return Math.floor((1 + Math.random()) * 0x10000) 192 | .toString(16) 193 | .substring(1); 194 | } 195 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 196 | s4() + '-' + s4() + s4() + s4(); 197 | } 198 | 199 | factory.subscribePkg = function (pkg, listener) { 200 | 201 | var topicName = "Red-Hat/+/iot-demo/packages/" + pkg.sensor_id; 202 | client.subscribe(topicName); 203 | console.log("subscribed to " + topicName); 204 | listeners.push({ 205 | pkg: pkg, 206 | topic: topicName, 207 | objType: 'packages', 208 | objId: pkg.sensor_id, 209 | listener: listener 210 | }); 211 | }; 212 | 213 | factory.subscribeVehicle = function (vehicle, listener) { 214 | 215 | var topicName = "Red-Hat/+/iot-demo/trucks/" + vehicle.vin; 216 | client.subscribe(topicName); 217 | console.log("subscribed to " + topicName); 218 | listeners.push({ 219 | vehicle: vehicle, 220 | topic: topicName, 221 | objType: 'trucks', 222 | objId: vehicle.vin, 223 | listener: listener 224 | }); 225 | }; 226 | 227 | factory.unsubscribeVehicle = function (vehicle) { 228 | var topicName = "Red-Hat/+/iot-demo/trucks/" + vehicle.vin; 229 | client.unsubscribe(topicName); 230 | console.log("UNsubscribed to " + topicName); 231 | listeners = listeners.filter(function(listener) { 232 | return ((!listener.vehicle) || (listener.vehicle.vin != vehicle.vin)); 233 | }); 234 | }; 235 | 236 | factory.unsubscribePackage = function (pkg) { 237 | var topicName = "Red-Hat/+/iot-demo/packages/" + pkg.sensor_id; 238 | client.unsubscribe(topicName); 239 | console.log("UNsubscribed to " + topicName); 240 | listeners = listeners.filter(function(listener) { 241 | return ((!listener.pkg) || (listener.pkg.sensor_id != pkg.sensor_id)); 242 | }); 243 | }; 244 | 245 | 246 | factory.unsubscribeAll = function () { 247 | listeners.forEach(function(listener) { 248 | client.unsubscribe(listener.topic); 249 | }); 250 | 251 | listeners = []; 252 | }; 253 | 254 | factory.getRecentData = function (pkg, telemetry, cb) { 255 | 256 | var esUrl = "http://" + APP_CONFIG.ES_HOSTNAME + '.' + 257 | $location.host().replace(/^.*?\.(.*)/g,"$1") + ':' + APP_CONFIG.ES_PORT + '/_search'; 258 | 259 | $http({ 260 | method: 'POST', 261 | url: esUrl, 262 | headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 263 | data: { 264 | "size": 0, 265 | "query": { 266 | "bool": { 267 | "must": [ 268 | { 269 | "term": { 270 | "channel": "iot-demo/packages/" + pkg.sensor_id 271 | } 272 | } 273 | ] 274 | } 275 | }, 276 | "aggs": { 277 | "my_date_histo": { 278 | "date_histogram": { 279 | "field": "timestamp", 280 | "interval": "5m" 281 | }, 282 | "aggs": { 283 | "the_avg": { 284 | "avg": { 285 | "field": "metrics." + telemetry.metricName + ".dbl" 286 | } 287 | }, 288 | "the_movavg": { 289 | "moving_avg": { 290 | "buckets_path": "the_avg" 291 | } 292 | } 293 | } 294 | } 295 | } 296 | } 297 | }).then(function successCallback(response) { 298 | 299 | if (!response.data) { 300 | cb([]); 301 | return; 302 | } 303 | 304 | var recentData = []; 305 | response.data.aggregations.my_date_histo.buckets.forEach(function (bucket) { 306 | if (bucket.the_movavg) { 307 | recentData.push({ 308 | timestamp: bucket.key, 309 | value: bucket.the_movavg.value 310 | }); 311 | } 312 | }); 313 | cb(recentData); 314 | }, function errorCallback(response) { 315 | Notifications.error("error fetching recent data: " + response.statusText); 316 | }); 317 | 318 | 319 | }; 320 | 321 | function sendJSONObjectMsg(jsonObj, topic) { 322 | var message = new Paho.MQTT.Message(JSON.stringify(jsonObj)); 323 | message.destinationName = topic; 324 | client.send(message); 325 | 326 | } 327 | 328 | function sendKuraMsg(kuraObj, topic) { 329 | var payload = msgproto.encode(kuraObj).finish(); 330 | var message = new Paho.MQTT.Message(payload); 331 | message.destinationName = topic; 332 | client.send(message); 333 | 334 | } 335 | 336 | factory.cascadingAlert = function(vehicle) { 337 | 338 | var intervals = []; 339 | 340 | function stopAll() { 341 | intervals.forEach(function(i) { 342 | $interval.cancel(i); 343 | i = undefined; 344 | }); 345 | intervals = []; 346 | } 347 | 348 | var hitemp = 349 | { 350 | timestamp: new Date().getTime(), 351 | metric: [ 352 | { 353 | name: 'temp', 354 | type: 'DOUBLE', 355 | doubleValue: 265 356 | } 357 | ] 358 | }; 359 | 360 | var hipress = 361 | { 362 | timestamp: new Date().getTime(), 363 | metric: [ 364 | { 365 | name: 'oilpress', 366 | type: 'DOUBLE', 367 | doubleValue: 95 368 | } 369 | ] 370 | }; 371 | 372 | metricOverrides[vehicle.vin] = {}; 373 | 374 | intervals.push($interval(function() { 375 | metricOverrides[vehicle.vin]['temp'] = 265; 376 | sendKuraMsg(hitemp, 'Red-Hat/sim-truck/iot-demo/trucks/' + vehicle.vin) 377 | }, 5000)); 378 | 379 | $timeout(function() { 380 | intervals.push($interval(function() { 381 | metricOverrides[vehicle.vin]['oilpress'] = 95; 382 | sendKuraMsg(hipress, 'Red-Hat/sim-truck/iot-demo/trucks/' + vehicle.vin); 383 | }, 5000)); 384 | var hitempalert = { 385 | date: new Date().getTime(), 386 | from: "Operations", 387 | desc: "Truck Maintenance Required", 388 | message: "Your vehicle is in need of maintenance. A maintenance crew has been dispatched to the " + vehicle.destination.name + " facility (bay 4), please arrive no later than 10:0am EDT", 389 | type: 'VEHICLE', 390 | truckid: vehicle.vin, 391 | sensorid: null 392 | }; 393 | 394 | sendJSONObjectMsg(hitempalert, 'Red-Hat/sim-truck/iot-demo/trucks/' + vehicle.vin + '/alerts'); 395 | }, 10000); 396 | 397 | // stop everything after 2 minutes 398 | $timeout(function() { 399 | stopAll(); 400 | }, 120000); 401 | 402 | }; 403 | 404 | factory.cascadingPkgAlert = function(vehicle, pkg) { 405 | 406 | var intervals = []; 407 | 408 | function stopAll() { 409 | intervals.forEach(function(i) { 410 | $interval.cancel(i); 411 | i = undefined; 412 | }); 413 | intervals = []; 414 | } 415 | 416 | var hipkgtemp = 417 | { 418 | timestamp: new Date().getTime(), 419 | metric: [ 420 | { 421 | name: 'Ambient', 422 | type: 'DOUBLE', 423 | doubleValue: 42.2 424 | } 425 | ] 426 | }; 427 | 428 | $timeout(function() { 429 | intervals.push($interval(function() { 430 | sendKuraMsg(hipkgtemp, 'Red-Hat/sim-truck/iot-demo/packages/' + pkg.sensor_id); 431 | metricOverrides[pkg.sensor_id] = {}; 432 | metricOverrides[pkg.sensor_id]['Ambient'] = 42.2; 433 | }, 5000)); 434 | }, 5000); 435 | 436 | 437 | $timeout(function() { 438 | var hitempalert = { 439 | date: new Date().getTime(), 440 | from: "Operations", 441 | desc: "Client Package Alert", 442 | message: 'Temperature on package ' + pkg.sensor_id + ' (' + pkg.desc + ' for client ' + pkg.customer.name + ') on shelf 12 is out of spec (42.2°C), please verify condition', 443 | type: 'PACKAGE', 444 | truckid: vehicle.vin, 445 | sensorid: pkg.sensor_id 446 | }; 447 | 448 | sendJSONObjectMsg(hitempalert, 'Red-Hat/sim-truck/iot-demo/packages/' + pkg.sensor_id + '/alerts'); 449 | 450 | }, 8000); 451 | 452 | // start looking to clear alerts after 20s 453 | $timeout(function() { 454 | intervals.push($interval(function() { 455 | Vehicles.reset(); 456 | Shipments.getCurrentShipments().filter(function(s) { return s.sensor_id == pkg.sensor_id }).forEach(function(s) { 457 | if (s.status == 'ok') { 458 | stopAll(); 459 | metricOverrides[s.sensor_id] = null; 460 | } 461 | }); 462 | }, 5000)); 463 | }, 20000); 464 | 465 | // stop everything after a 2 minutes 466 | $timeout(function() { 467 | stopAll(); 468 | }, 120000); 469 | }; 470 | 471 | connectClient(1); 472 | 473 | return factory; 474 | }]); 475 | -------------------------------------------------------------------------------- /dashboard/app/services/shipments.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | angular.module('app') 19 | 20 | .factory('Shipments', ['$rootScope', '$location', '$http', '$q', 'APP_CONFIG', 'Notifications', 21 | function($rootScope, $location, $http, $q, APP_CONFIG, Notifications) { 22 | 23 | var factory = {}, 24 | shipments = [], 25 | allShipments = [], 26 | configRestEndpoint = "http://" + APP_CONFIG.DATASTORE_REST_HOSTNAME + '.' + $location.host().replace(/^.*?\.(.*)/g,"$1") + '/api/shipments'; 27 | 28 | factory.getCurrentShipments = function() { 29 | return shipments; 30 | }; 31 | 32 | factory.getShipments = function(vehicle, cb) { 33 | // get config 34 | $http({ 35 | method: 'GET', 36 | url: configRestEndpoint + '/' + vehicle.vin 37 | }).then(function (response) { 38 | shipments = response.data; 39 | if ((shipments == undefined) || (shipments.constructor !== Array)) { 40 | Notifications.error("Error fetching Shipments for vehicle:" + vehicle.vin + " (invalid data). Reload to retry"); 41 | return; 42 | } 43 | 44 | cb(shipments); 45 | 46 | }, function err(response) { 47 | console.log(JSON.stringify(response)); 48 | Notifications.error("Error fetching Shipments for vehicle: " + vehicle.vin + ". Reload to retry"); 49 | }); 50 | 51 | }; 52 | 53 | factory.getAllShipments = function(cb) { 54 | // get config 55 | $http({ 56 | method: 'GET', 57 | url: configRestEndpoint 58 | }).then(function (response) { 59 | allShipments = response.data; 60 | if ((allShipments == undefined) || (allShipments.constructor !== Array)) { 61 | Notifications.error("Error fetching ALL Shipments (invalid data). Reload to retry"); 62 | return; 63 | } 64 | 65 | cb(allShipments); 66 | 67 | }, function err(response) { 68 | console.log(JSON.stringify(response)); 69 | Notifications.error("Error fetching ALL Shipments. Reload to retry"); 70 | }); 71 | 72 | }; 73 | 74 | return factory; 75 | }]); 76 | -------------------------------------------------------------------------------- /dashboard/app/services/vehicles.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | 16 | 'use strict'; 17 | 18 | angular.module('app') 19 | 20 | .factory('Vehicles', ['$rootScope', '$location', '$http', '$q', 'APP_CONFIG', 'Notifications', function($rootScope, $location, $http, $q, APP_CONFIG, Notifications) { 21 | 22 | var factory = {}, 23 | vehicles = [], 24 | configRestEndpoint = "http://" + APP_CONFIG.DATASTORE_REST_HOSTNAME + '.' + $location.host().replace(/^.*?\.(.*)/g,"$1") + '/api/vehicles'; 25 | 26 | 27 | factory.getVehicles = function() { 28 | return vehicles; 29 | }; 30 | 31 | 32 | // this.getIconName = function(type) { 33 | // if (type == 'danger') { 34 | // return 'pficon-error-circle-o'; 35 | // } else if (type == 'warning') { 36 | // return 'pficon-warning-triangle-o'; 37 | // } else if (type == 'info') { 38 | // return 'pficon-info'; 39 | // } else if (type == 'success') { 40 | // return 'pficon-ok' 41 | // } 42 | // } 43 | 44 | factory.reset = function() { 45 | 46 | // get config 47 | $http({ 48 | method: 'GET', 49 | url: configRestEndpoint + "/" 50 | }).then(function (response) { 51 | vehicles = response.data; 52 | if ((vehicles == undefined) || (vehicles.constructor !== Array)) { 53 | Notifications.error("Error fetching Vehicle Configuration (invalid data). Reload to retry"); 54 | return; 55 | } 56 | 57 | $rootScope.$broadcast('vehicles:updated'); 58 | 59 | // currentShipments = currentShipments.filter(function(shipment) { 60 | // return shipment.pkgId; 61 | // }); 62 | 63 | }, function err(response) { 64 | console.log(JSON.stringify(response)); 65 | Notifications.error("Error fetching Vehicle Configuration from [" + response.config.url + "]. Reload to retry"); 66 | }); 67 | 68 | }; 69 | 70 | factory.reset(); 71 | 72 | return factory; 73 | }]); 74 | -------------------------------------------------------------------------------- /dashboard/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iot-cargo-demo", 3 | "description": "Red Hat IoT Dashboard Demo", 4 | "authors": [ 5 | "Red Hat" 6 | ], 7 | "license": "EPL-1.0", 8 | "private": true, 9 | "devDependencies": { 10 | "patternfly": "3.18.1", 11 | "angular-patternfly": "3.18.1", 12 | "angular-websocket": "2.0.0", 13 | "ngmap": "1.18.4", 14 | "angular-bootstrap-switch": "0.5.1", 15 | "async": "1.5.2", 16 | "protobuf": "6.6.3", 17 | "paho-mqtt-js": "1.0.1", 18 | "angular-route": "1.5.11", 19 | "angular-sanitize": "1.5.11", 20 | "angular-scrollable-table": "1.1.2", 21 | "angular-moment": "1.0.0", 22 | "c3": "0.4.11" 23 | }, 24 | "resolutions": { 25 | "jquery": "~2.1.4", 26 | "angular": "1.5.11" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dashboard/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | var config = 16 | { 17 | // hostname/port/name/password for Kapua broker 18 | BROKER_WEBSOCKET_HOSTNAME: process.env.BROKER_WS_NAME + '-' + process.env.OPENSHIFT_BUILD_NAMESPACE, 19 | BROKER_WEBSOCKET_PORT: process.env.BROKER_WEBSOCKET_PORT || 80, 20 | BROKER_USERNAME: process.env.BROKER_USERNAME || "demo_username", 21 | BROKER_PASSWORD: process.env.BROKER_PASSWORD || "demo_password", 22 | 23 | ES_HOSTNAME: (process.env.ES_NAME || 'search') + '-' + process.env.OPENSHIFT_BUILD_NAMESPACE, 24 | ES_PORT: process.env.ES_PORT || 80, 25 | 26 | // hostname/port for DG proxy (no username/password required for demo) 27 | DATASTORE_REST_HOSTNAME: process.env.DATASTORE_PROXY_SERVICE + '-' + process.env.OPENSHIFT_BUILD_NAMESPACE, 28 | DATASTORE_REST_PORT: process.env.DATASTORE_REST_PORT || 80, 29 | 30 | // Google API Key (can be blank, resulting in throttling for high usage) 31 | GOOGLE_MAPS_API_KEY: process.env.GOOGLE_MAPS_API_KEY || "", 32 | 33 | STATIC_TELEMETRY_GRAPHS: process.env.STATIC_TELEMETRY_GRAPHS || 'Humidity,Pressure', 34 | DASHBOARD_WEB_TITLE: process.env.DASHBOARD_WEB_TITLE || '' 35 | }; 36 | 37 | module.exports = config; 38 | -------------------------------------------------------------------------------- /dashboard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Red Hat", 3 | "name": "iot-cargo-demo", 4 | "repository": "redhat-iot/iot-cargo-demo", 5 | "version": "2.0.0", 6 | "license": "EPL-1.0", 7 | "private": true, 8 | "description": "Red Hat IoT Dashboard Demo", 9 | "homepage": "https://github.com/redhat-iot", 10 | "dependencies": { 11 | "express": "^4.13.4", 12 | "request": "^2.74.0", 13 | "n3-charts": "2.0.18" 14 | }, 15 | "devDependencies": { 16 | "bower": ">=1.7.9" 17 | }, 18 | "engines": { 19 | "node": ">=0.10.10" 20 | }, 21 | "scripts": { 22 | "postinstall": "node_modules/.bin/bower install" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dashboard/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | var express = require('express'), 16 | http = require('http'), 17 | request = require('request'), 18 | fs = require('fs'), 19 | app = express(), 20 | path = require("path"), 21 | appConfig = require('./config.js'), 22 | port = process.env.OPENSHIFT_NODEJS_PORT || 8080, 23 | ip = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0'; 24 | 25 | // error handling 26 | app.use(function (err, req, res, next) { 27 | console.error(err.stack); 28 | res.status(500).send('Something bad happened!'); 29 | }); 30 | 31 | // keycloak config server 32 | app.get('/config.json', function (req, res, next) { 33 | res.json(appConfig); 34 | }); 35 | 36 | app.use(express.static(path.join(__dirname, '/views'))); 37 | app.use('/app', express.static(path.join(__dirname, '/app'))); 38 | app.use('/bower_components', express.static(path.join(__dirname, '/bower_components'))); 39 | app.use('/node_modules', express.static(path.join(__dirname, '/node_modules'))); 40 | 41 | console.log("app config: " + JSON.stringify(appConfig)); 42 | 43 | http.createServer(app).listen(port); 44 | 45 | console.log('HTTP Server running on http://%s:%s', ip, port); 46 | 47 | module.exports = app; 48 | -------------------------------------------------------------------------------- /dashboard/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | Red Hat IoT Dashboard Demo 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
97 | 98 |
99 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /dashboard/views/kurapayload.proto: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2016, 2017 Eurotech and/or its affiliates and others 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-v10.html 8 | * 9 | * Contributors: 10 | * Eurotech 11 | * 12 | *******************************************************************************/ 13 | 14 | /* 15 | * This file originates from the Eclipse Kura™ project 16 | */ 17 | 18 | // 19 | // To compile: 20 | // protoc --proto_path=src/main/protobuf --java_out=src/main/java src/main/protobuf/kurapayload.proto 21 | // 22 | package kuradatatypes; 23 | 24 | option java_package = "org.eclipse.kura.core.message.protobuf"; 25 | option java_outer_classname = "KuraPayloadProto"; 26 | 27 | message KuraPayload { 28 | 29 | message KuraMetric { 30 | enum ValueType { 31 | DOUBLE = 0; 32 | FLOAT = 1; 33 | INT64 = 2; 34 | INT32 = 3; 35 | BOOL = 4; 36 | STRING = 5; 37 | BYTES = 6; 38 | } 39 | 40 | required string name = 1; 41 | required ValueType type = 2; 42 | 43 | optional double double_value = 3; 44 | optional float float_value = 4; 45 | optional int64 long_value = 5; 46 | optional int32 int_value = 6; 47 | optional bool bool_value = 7; 48 | optional string string_value = 8; 49 | optional bytes bytes_value = 9; 50 | } 51 | 52 | message KuraPosition { 53 | required double latitude = 1; 54 | required double longitude = 2; 55 | optional double altitude = 3; 56 | optional double precision = 4; // dilution of precision of the current satellite fix. 57 | optional double heading = 5; // heading in degrees 58 | optional double speed = 6; // meters per second 59 | optional int64 timestamp = 7; 60 | optional int32 satellites = 8; // number satellites locked by the GPS device 61 | optional int32 status = 9; // status indicator for the GPS data: 1 = no GPS response; 2 = error in response; 4 = valid. 62 | } 63 | 64 | optional int64 timestamp = 1; 65 | optional KuraPosition position = 2; 66 | 67 | extensions 3 to 4999; 68 | repeated KuraMetric metric = 5000; // can be zero, so optional 69 | optional bytes body = 5001; 70 | } 71 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/biz-state.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 25 | 26 |

State of the Business

27 | 28 | 29 |
31 | 32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/biz-trends.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 | 16 | 27 | 28 |

Business Trends

29 | 30 | 36 | 37 |
38 | 39 | 40 |
41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/facility-utilization.html: -------------------------------------------------------------------------------- 1 | 13 |
14 |

Facility Utilization

15 | 16 |
22 | 23 |
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/home.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 | 26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 |
34 | 35 | 36 | 37 |
38 | 39 |
40 | 41 | 42 |
43 | 44 |
45 | 46 |
47 | 48 |
49 | 50 |
51 | 52 | 53 |
54 | 55 | 56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/maintain-events.html: -------------------------------------------------------------------------------- 1 | 13 |
14 |

Fleet Maintenance Events

15 | 16 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/summary.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /dashboard/views/partials/exec/top-facilities.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 | 26 | 27 |

Top Facilities

28 | 29 |
30 |
32 | 33 |
34 |
35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /dashboard/views/partials/facility.html: -------------------------------------------------------------------------------- 1 | 13 | 19 | 62 | -------------------------------------------------------------------------------- /dashboard/views/partials/header.html: -------------------------------------------------------------------------------- 1 | 13 | 67 | -------------------------------------------------------------------------------- /dashboard/views/partials/history.html: -------------------------------------------------------------------------------- 1 | 13 | 18 | 24 | -------------------------------------------------------------------------------- /dashboard/views/partials/home.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |
16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 |
36 | 37 |
38 |
39 | 40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /dashboard/views/partials/mapchart.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |

Vehicle Tracking

16 |
17 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | -------------------------------------------------------------------------------- /dashboard/views/partials/pkgtelemetry.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |

Package Telemetry

16 |
17 |
{{selectedPkg.desc}} (Client: {{selectedPkg.customer.name}})
18 | 19 | 20 | 21 | 22 |
23 |  Choose a shipment to view its telemetry 24 |
25 | 26 |
27 | 28 | 29 |
30 |  Current {{telemetry.name}} unavailable (History) 31 |
32 | 33 |
34 | {{telemetry.name}} 35 |   36 |
37 | History 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 |

{{n3data[telemetry.name].value}}{{telemetry.units}}

47 |
48 |
49 | 50 |
51 | 52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 |
60 | 61 | -------------------------------------------------------------------------------- /dashboard/views/partials/shiplist.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |

Client Shipments

16 |
17 | 18 |
19 | 20 |  Choose a vehicle to view its packages 21 |
22 | 23 |
24 | No Shipments found for vehicle {{selectedVehicle.desc}}. Try picking a different Vehicle. 25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 59 | 60 | 61 | 66 | 67 | 68 | 69 | 73 | 74 | 75 | 76 |
Client PackageRouteETAStatus
57 | {{shipment.customer.name}} ({{shipment.desc}}) 58 |  {{shipment.route[0].address}}
63 |  {{shipment.route[shipment.route.length-1].address}} 65 |
{{shipment.eta | amCalendar:referenceTime:formats}}
70 | 71 | 72 |
77 |
78 | 79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /dashboard/views/partials/vehiclepanel.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |

Vehicle Telemetry 

16 |
17 |
18 |
19 | Truck 20 |
21 |
22 | 23 | 24 |
25 |
26 |
27 |

{{telemetry.name}}

28 |
29 |
30 |
31 |
32 |
33 |
34 | 35 |
36 | -------------------------------------------------------------------------------- /dashboard/views/partials/vehicleslist.html: -------------------------------------------------------------------------------- 1 | 13 |
14 | 15 |

Vehicles

16 |
17 |
18 | No vehicles found. Perhaps you need to initialize the system? 19 |
20 | 21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 54 | 55 | 59 | 60 | 61 | 62 |
Vehicle IDRouteETAStatus
{{vehicle.vin}} {{vehicle.origin.address}}
51 |  {{vehicle.destination.address}} 53 |
{{vehicle.eta | date:'medium'}}
56 | 57 | 58 |
63 |
64 | 65 | 66 |
67 | 68 | -------------------------------------------------------------------------------- /dgproxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 4.0.0 15 | com.redhat.iot 16 | dgproxy 17 | 1.0.0-SNAPSHOT 18 | war 19 | Simple DG Proxy 20 | Simple DG Proxy using hotrod 21 | 22 | 23 | 24 | Apache License, Version 2.0 25 | repo 26 | http://www.apache.org/licenses/LICENSE-2.0.html 27 | 28 | 29 | 30 | 31 | redhat-ga 32 | Red Hat GA Repo 33 | https://maven.repository.redhat.com/ga/ 34 | 35 | 36 | Eclipse Paho Repo 37 | https://repo.eclipse.org/content/repositories/paho-releases/ 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | UTF-8 47 | 48 | 49 | 50 | 1.0.2.Final 51 | 52 | 6.4.1.Final-redhat-1 53 | 54 | 1.0.3.Final 55 | 56 | 57 | 2.1.1 58 | 59 | 60 | 1.8 61 | 1.8 62 | 63 | 64 | 65 | 66 | 69 | 75 | 76 | org.jboss.spec 77 | jboss-javaee-7.0 78 | ${version.jboss.spec.javaee.7.0} 79 | pom 80 | import 81 | 82 | 83 | 84 | org.infinispan 85 | infinispan-bom 86 | ${version.org.infinispan} 87 | pom 88 | import 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | org.eclipse.paho 100 | org.eclipse.paho.client.mqttv3 101 | 1.0.2 102 | 103 | 104 | 105 | com.google.protobuf 106 | protobuf-java 107 | 3.2.0 108 | 109 | 110 | 111 | org.infinispan 112 | infinispan-remote 113 | 114 | 115 | 116 | org.infinispan 117 | infinispan-client-hotrod 118 | 119 | 120 | 121 | org.infinispan 122 | infinispan-query-dsl 123 | 124 | 125 | 126 | org.infinispan 127 | infinispan-remote-query-client 128 | 129 | 130 | 131 | javax.cache 132 | cache-api 133 | 1.0.0.redhat-1 134 | 135 | 136 | 137 | org.json 138 | json 139 | 20160212 140 | 141 | 142 | 143 | 144 | javax.enterprise 145 | cdi-api 146 | provided 147 | 148 | 149 | 151 | 152 | org.jboss.spec.javax.annotation 153 | jboss-annotations-api_1.2_spec 154 | provided 155 | 156 | 157 | 158 | 159 | org.jboss.spec.javax.ws.rs 160 | jboss-jaxrs-api_2.0_spec 161 | provided 162 | 163 | 164 | 165 | 166 | 168 | ${project.artifactId} 169 | 170 | 171 | maven-war-plugin 172 | ${version.war.plugin} 173 | 174 | 175 | false 176 | ROOT 177 | 178 | 179 | 180 | 181 | org.wildfly.plugins 182 | wildfly-maven-plugin 183 | ${version.wildfly.maven.plugin} 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Alert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.util.Date; 19 | 20 | @XmlRootElement(name="alert") 21 | public class Alert { 22 | private Date date; 23 | private String from; 24 | private String desc; 25 | private String message; 26 | private String type; 27 | private String truckid; 28 | private String sensorid; 29 | 30 | public Alert(Date date, String from, String desc, String message, String type, String truckid, String sensorid) { 31 | this.date = date; 32 | this.from = from; 33 | this.desc = desc; 34 | this.message = message; 35 | this.type = type; 36 | this.truckid = truckid; 37 | this.sensorid = sensorid; 38 | } 39 | 40 | public Date getDate() { 41 | return date; 42 | } 43 | 44 | public void setDate(Date date) { 45 | this.date = date; 46 | } 47 | 48 | public String getFrom() { 49 | return from; 50 | } 51 | 52 | public void setFrom(String from) { 53 | this.from = from; 54 | } 55 | 56 | public String getDesc() { 57 | return desc; 58 | } 59 | 60 | public void setDesc(String desc) { 61 | this.desc = desc; 62 | } 63 | 64 | public String getMessage() { 65 | return message; 66 | } 67 | 68 | public void setMessage(String message) { 69 | this.message = message; 70 | } 71 | 72 | public String getType() { 73 | return type; 74 | } 75 | 76 | public void setType(String type) { 77 | this.type = type; 78 | } 79 | 80 | public String getTruckid() { 81 | return truckid; 82 | } 83 | 84 | public void setTruckid(String truckid) { 85 | this.truckid = truckid; 86 | } 87 | 88 | public String getSensorid() { 89 | return sensorid; 90 | } 91 | 92 | public void setSensorid(String sensorid) { 93 | this.sensorid = sensorid; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Customer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement(name="customer") 21 | public class Customer implements Serializable { 22 | private String name; 23 | private String login; 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getLogin() { 34 | return login; 35 | } 36 | 37 | public void setLogin(String login) { 38 | this.login = login; 39 | } 40 | 41 | public Customer(String name, String login) { 42 | this.name = name; 43 | this.login = login; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Facility.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement(name="facility") 21 | public class Facility implements Serializable { 22 | private String name; 23 | private String address; 24 | private LatLng location; 25 | private double utilization; 26 | private double size; 27 | 28 | public double getSize() { 29 | return size; 30 | } 31 | 32 | public void setSize(double size) { 33 | this.size = size; 34 | } 35 | 36 | public double getUtilization() { 37 | return utilization; 38 | } 39 | 40 | public void setUtilization(double utilization) { 41 | this.utilization = utilization; 42 | } 43 | 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | public String getAddress() { 53 | return address; 54 | } 55 | 56 | public void setAddress(String address) { 57 | this.address = address; 58 | } 59 | 60 | public LatLng getLocation() { 61 | return location; 62 | } 63 | 64 | public void setLocation(LatLng location) { 65 | this.location = location; 66 | } 67 | 68 | public Facility(String name, String address, LatLng location, double size) { 69 | this.name = name; 70 | this.address = address; 71 | this.location = location; 72 | this.size = size; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/LatLng.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement() 21 | public class LatLng implements Serializable { 22 | 23 | private double latitude; 24 | private double longitude; 25 | 26 | public double getLatitude() { 27 | return latitude; 28 | } 29 | 30 | public void setLatitude(double latitude) { 31 | this.latitude = latitude; 32 | } 33 | 34 | public double getLongitude() { 35 | return longitude; 36 | } 37 | 38 | public void setLongitude(double longitude) { 39 | this.longitude = longitude; 40 | } 41 | 42 | public LatLng(double latitude, double longitude) { 43 | this.latitude = latitude; 44 | this.longitude = longitude; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Operator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement(name="operator") 21 | public class Operator implements Serializable { 22 | private String name; 23 | private String login; 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getLogin() { 34 | return login; 35 | } 36 | 37 | public void setLogin(String login) { 38 | this.login = login; 39 | } 40 | 41 | public Operator(String name, String login) { 42 | this.name = name; 43 | this.login = login; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Shipment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | @XmlRootElement(name="shipment") 23 | public class Shipment implements Serializable { 24 | 25 | private List telemetry; 26 | private Customer customer; 27 | private String desc; 28 | private String name; 29 | private String sensor_id; 30 | private List route; 31 | private Date etd; 32 | private Date eta; 33 | private double amount_paid; 34 | // realtime data 35 | private Vehicle cur_vehicle; 36 | private String status; 37 | 38 | public String getStatus() { 39 | return status; 40 | } 41 | 42 | public void setStatus(String status) { 43 | this.status = status; 44 | } 45 | 46 | public String getName() { 47 | return name; 48 | } 49 | 50 | public void setName(String name) { 51 | this.name = name; 52 | } 53 | 54 | public List getTelemetry() { 55 | return telemetry; 56 | } 57 | 58 | public void setTelemetry(List telemetry) { 59 | this.telemetry = telemetry; 60 | } 61 | 62 | public String getDesc() { 63 | return desc; 64 | } 65 | 66 | public void setDesc(String desc) { 67 | this.desc = desc; 68 | } 69 | 70 | public String getSensor_id() { 71 | return sensor_id; 72 | } 73 | 74 | public void setSensor_id(String sensor_id) { 75 | this.sensor_id = sensor_id; 76 | } 77 | 78 | public List getRoute() { 79 | return route; 80 | } 81 | 82 | public void setRoute(List route) { 83 | this.route = route; 84 | } 85 | 86 | public Date getEtd() { 87 | return etd; 88 | } 89 | 90 | public void setEtd(Date etd) { 91 | this.etd = etd; 92 | } 93 | 94 | public Date getEta() { 95 | return eta; 96 | } 97 | 98 | public void setEta(Date eta) { 99 | this.eta = eta; 100 | } 101 | 102 | public double getAmount_paid() { 103 | return amount_paid; 104 | } 105 | 106 | public void setAmount_paid(double amount_paid) { 107 | this.amount_paid = amount_paid; 108 | } 109 | 110 | public Vehicle getCur_vehicle() { 111 | return cur_vehicle; 112 | } 113 | 114 | public void setCur_vehicle(Vehicle cur_vehicle) { 115 | this.cur_vehicle = cur_vehicle; 116 | } 117 | 118 | public Customer getCustomer() { 119 | return customer; 120 | } 121 | 122 | public void setCustomer(Customer customer) { 123 | this.customer = customer; 124 | } 125 | 126 | public Shipment() { 127 | this.status = "ok"; 128 | } 129 | public Shipment(Customer customer, String name, String desc, String sensor_id, List route, Date etd, Date eta, double amount_paid, Vehicle cur_vehicle) { 130 | super(); 131 | this.status = "ok"; 132 | this.customer = customer; 133 | this.name = name; 134 | this.desc = desc; 135 | this.sensor_id = sensor_id; 136 | this.route = route; 137 | this.etd = etd; 138 | this.eta = eta; 139 | this.amount_paid = amount_paid; 140 | this.cur_vehicle = cur_vehicle; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Summary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement(name="summary") 21 | public class Summary implements Serializable { 22 | public String name; 23 | public String title; 24 | public long count; 25 | public long warningCount; 26 | public long errorCount; 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public String getTitle() { 37 | return title; 38 | } 39 | 40 | public void setTitle(String title) { 41 | this.title = title; 42 | } 43 | 44 | public long getCount() { 45 | return count; 46 | } 47 | 48 | public void setCount(int count) { 49 | this.count = count; 50 | } 51 | 52 | public long getWarningCount() { 53 | return warningCount; 54 | } 55 | 56 | public void setWarningCount(long warningCount) { 57 | this.warningCount = warningCount; 58 | } 59 | 60 | public long getErrorCount() { 61 | return errorCount; 62 | } 63 | 64 | public void setErrorCount(long errorCount) { 65 | this.errorCount = errorCount; 66 | } 67 | 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Telemetry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | 20 | @XmlRootElement(name="shipment") 21 | public class Telemetry implements Serializable { 22 | 23 | private String units; 24 | private double max; 25 | private double min; 26 | private String name; 27 | private String metricName; 28 | 29 | public String getMetricName() { 30 | return metricName; 31 | } 32 | 33 | public void setMetricName(String metricName) { 34 | this.metricName = metricName; 35 | } 36 | 37 | public String getUnits() { 38 | return units; 39 | } 40 | 41 | public void setUnits(String units) { 42 | this.units = units; 43 | } 44 | 45 | public double getMax() { 46 | return max; 47 | } 48 | 49 | public void setMax(double max) { 50 | this.max = max; 51 | } 52 | 53 | public double getMin() { 54 | return min; 55 | } 56 | 57 | public void setMin(double min) { 58 | this.min = min; 59 | } 60 | 61 | public String getName() { 62 | return name; 63 | } 64 | 65 | public void setName(String name) { 66 | this.name = name; 67 | } 68 | 69 | public Telemetry(String units, double max, double min, String name, String metricName) { 70 | this.units = units; 71 | this.metricName = metricName; 72 | this.max = max; 73 | this.min = min; 74 | this.name = name; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/model/Vehicle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.model; 16 | 17 | import javax.xml.bind.annotation.XmlRootElement; 18 | import java.io.Serializable; 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | @XmlRootElement(name="vehicle") 23 | public class Vehicle implements Serializable { 24 | 25 | private String vin; 26 | private String desc; 27 | private List telemetry; 28 | private Facility origin; 29 | private Facility destination; 30 | private Date eta; 31 | private String status; 32 | 33 | public Date getEta() { 34 | return eta; 35 | } 36 | 37 | public void setEta(Date eta) { 38 | this.eta = eta; 39 | } 40 | 41 | public String getStatus() { 42 | return status; 43 | } 44 | 45 | public void setStatus(String status) { 46 | this.status = status; 47 | } 48 | 49 | 50 | public List getTelemetry() { 51 | return telemetry; 52 | } 53 | 54 | public void setTelemetry(List telemetry) { 55 | this.telemetry = telemetry; 56 | } 57 | 58 | 59 | public String getVin() { 60 | return vin; 61 | } 62 | 63 | public void setVin(String vin) { 64 | this.vin = vin; 65 | } 66 | 67 | public String getDesc() { 68 | return desc; 69 | } 70 | 71 | public void setDesc(String desc) { 72 | this.desc = desc; 73 | } 74 | 75 | public Vehicle() { 76 | this.status = "ok"; 77 | 78 | } 79 | public Facility getOrigin() { 80 | return origin; 81 | } 82 | 83 | public void setOrigin(Facility origin) { 84 | this.origin = origin; 85 | } 86 | 87 | public Facility getDestination() { 88 | return destination; 89 | } 90 | 91 | public void setDestination(Facility destination) { 92 | this.destination = destination; 93 | } 94 | 95 | public Vehicle(String vin, String desc) { 96 | super(); 97 | this.status = "ok"; 98 | this.vin = vin; 99 | this.desc = desc; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/CORSFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import java.io.IOException; 18 | 19 | import javax.ws.rs.container.ContainerRequestContext; 20 | import javax.ws.rs.container.ContainerResponseContext; 21 | import javax.ws.rs.container.ContainerResponseFilter; 22 | import javax.ws.rs.ext.Provider; 23 | 24 | @Provider 25 | public class CORSFilter implements ContainerResponseFilter { 26 | 27 | @Override 28 | public void filter(final ContainerRequestContext requestContext, 29 | final ContainerResponseContext responseContext) throws IOException { 30 | responseContext.getHeaders().add("Access-Control-Allow-Origin", "*"); 31 | responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); 32 | responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true"); 33 | responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); 34 | responseContext.getHeaders().add("Access-Control-Max-Age", "1209600"); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/CustomerEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import com.redhat.iot.cargodemo.model.Customer; 18 | import com.redhat.iot.cargodemo.service.DGService; 19 | 20 | import javax.inject.Inject; 21 | import javax.inject.Singleton; 22 | import javax.ws.rs.*; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.stream.Collectors; 27 | 28 | /** 29 | * A simple REST service which proxies requests to a local datagrid. 30 | */ 31 | 32 | @Path("/customer") 33 | @Singleton 34 | public class CustomerEndpoint { 35 | 36 | @Inject 37 | DGService dgService; 38 | 39 | @GET 40 | @Path("/{id}") 41 | @Produces({"application/json"}) 42 | public Customer getCustomer(@PathParam("id") String id) { 43 | return dgService.getCustomers().get(id); 44 | } 45 | 46 | @PUT 47 | @Path("/{id}") 48 | public void putCustomer(@PathParam("id") String id, Customer value) { 49 | dgService.getCustomers().put(id, value); 50 | } 51 | 52 | @GET 53 | @Path("/") 54 | @Produces({"application/json"}) 55 | public List getAllCustomers() { 56 | 57 | Map cache = dgService.getCustomers(); 58 | 59 | return cache.keySet().stream() 60 | .map(cache::get) 61 | .collect(Collectors.toList()); 62 | 63 | } 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/FacilitiesEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import com.redhat.iot.cargodemo.model.Facility; 18 | import com.redhat.iot.cargodemo.model.Vehicle; 19 | import com.redhat.iot.cargodemo.service.DGService; 20 | 21 | import javax.inject.Inject; 22 | import javax.inject.Singleton; 23 | import javax.ws.rs.*; 24 | import java.util.*; 25 | import java.util.stream.Collectors; 26 | 27 | /** 28 | * A simple REST service which proxies requests to a local datagrid. 29 | */ 30 | 31 | @Path("/facilities") 32 | @Singleton 33 | public class FacilitiesEndpoint { 34 | 35 | @Inject 36 | DGService dgService; 37 | 38 | @GET 39 | @Path("/top/{count}") 40 | @Produces({"application/json"}) 41 | public List topFacilities(@PathParam("count") int count) { 42 | 43 | Map cache = dgService.getFacilities(); 44 | 45 | 46 | return cache.keySet().stream() 47 | .map(cache::get).sorted(Comparator.comparingDouble(Facility::getUtilization)) 48 | .limit(count) 49 | .collect(Collectors.toList()); 50 | 51 | } 52 | 53 | @GET 54 | @Path("/") 55 | @Produces({"application/json"}) 56 | public List getAll() { 57 | 58 | Map cache = dgService.getFacilities(); 59 | 60 | return cache.keySet().stream() 61 | .map(cache::get) 62 | .collect(Collectors.toList()); 63 | 64 | } 65 | 66 | 67 | } 68 | 69 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/RestApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import javax.ws.rs.ApplicationPath; 18 | import javax.ws.rs.core.Application; 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | 22 | @ApplicationPath("/api") 23 | public class RestApplication extends Application { 24 | 25 | 26 | } -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/ShipmentsEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import com.redhat.iot.cargodemo.model.Shipment; 18 | import com.redhat.iot.cargodemo.model.Vehicle; 19 | import com.redhat.iot.cargodemo.service.AlertsService; 20 | import com.redhat.iot.cargodemo.service.DGService; 21 | 22 | import javax.inject.Inject; 23 | import javax.inject.Singleton; 24 | import javax.ws.rs.*; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.stream.Collectors; 28 | 29 | /** 30 | * A simple REST service which proxies requests to a local datagrid. 31 | */ 32 | 33 | @Path("/shipments") 34 | @Singleton 35 | public class ShipmentsEndpoint { 36 | 37 | @Inject 38 | DGService dgService; 39 | 40 | @GET 41 | @Path("/") 42 | @Produces({"application/json"}) 43 | public List getAll() { 44 | Map cache = dgService.getShipments(); 45 | return cache.keySet().stream() 46 | .map(cache::get) 47 | .collect(Collectors.toList()); 48 | 49 | } 50 | @GET 51 | @Path("/{vin}") 52 | @Produces({"application/json"}) 53 | public List get(@PathParam("vin") String vin) { 54 | 55 | Map cache = dgService.getShipments(); 56 | 57 | // TODO: use DG queries properly 58 | return cache.keySet().stream() 59 | .map(cache::get) 60 | .filter(shipment -> vin.equals(shipment.getCur_vehicle().getVin())) 61 | .collect(Collectors.toList()); 62 | } 63 | 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/UtilsEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import com.redhat.iot.cargodemo.model.*; 18 | import com.redhat.iot.cargodemo.service.DGService; 19 | 20 | import javax.inject.Inject; 21 | import javax.inject.Singleton; 22 | import javax.ws.rs.*; 23 | import java.util.*; 24 | 25 | /** 26 | * A simple REST service which proxies requests to a local datagrid. 27 | */ 28 | 29 | @Path("/utils") 30 | @Singleton 31 | public class UtilsEndpoint { 32 | 33 | public static final int MAX_VEHICLES = 10; 34 | public static final int MAX_PACKAGES_PER_VEHICLE = 20; 35 | public static final long DAY_IN_MS = 24*60*60*1000; 36 | 37 | @Inject 38 | DGService dgService; 39 | 40 | @GET 41 | @Path("/health") 42 | public String health() { 43 | return "ok"; 44 | } 45 | 46 | @POST 47 | @Path("/resetAll") 48 | public void resetAll() { 49 | 50 | Map vehiclesCache = dgService.getVehicles(); 51 | Map customerCache = dgService.getCustomers(); 52 | Map facilitiesCache = dgService.getFacilities(); 53 | Map operatorCache = dgService.getOperators(); 54 | Map shipmentCache = dgService.getShipments(); 55 | 56 | 57 | facilitiesCache.clear(); 58 | vehiclesCache.clear(); 59 | customerCache.clear(); 60 | operatorCache.clear(); 61 | shipmentCache.clear(); 62 | 63 | for (String COMPANY : COMPANIES) { 64 | customerCache.put(COMPANY, 65 | new Customer(COMPANY, "password")); 66 | } 67 | 68 | for (String oper : OPERATOR_NAMES){ 69 | operatorCache.put(oper, new Operator(oper, "password")); 70 | } 71 | 72 | List facs = new ArrayList(); 73 | facs.addAll(Arrays.asList(ORIGINS)); 74 | facs.addAll(Arrays.asList(DESTS)); 75 | 76 | for (String facName : facs) { 77 | 78 | facilitiesCache.put(facName, 79 | new Facility(facName, facName, 80 | new LatLng(-80, 20), 81 | Math.random() * 1000.0)); 82 | 83 | } 84 | 85 | 86 | for (int i = 1; i <= MAX_VEHICLES; i++) { 87 | 88 | String vin = "truck-" + i; 89 | 90 | Vehicle newVehicle = new Vehicle(vin, rand(VEHICLE_TYPES)); 91 | 92 | Facility v_origin = facilitiesCache.get(rand(ORIGINS)); 93 | Facility v_dest = facilitiesCache.get(rand(DESTS)); 94 | 95 | newVehicle.setOrigin(v_origin); 96 | newVehicle.setDestination(v_dest); 97 | 98 | List vehicleTelemetry = new ArrayList<>(); 99 | vehicleTelemetry.add(new Telemetry("°C", 250.0, 150.0, "Engine Temp", "temp")); 100 | vehicleTelemetry.add(new Telemetry("rpm", 2200.0, 500.0, "RPM", "rpm")); 101 | vehicleTelemetry.add(new Telemetry("psi", 80.0, 30.0, "Oil Pressure", "oilpress")); 102 | newVehicle.setTelemetry(vehicleTelemetry); 103 | 104 | Date v_eta = new Date(new Date().getTime() + DAY_IN_MS + (long)(Math.random() * DAY_IN_MS * 2)); 105 | 106 | newVehicle.setEta(v_eta); 107 | vehiclesCache.put(vin, newVehicle); 108 | 109 | for (int j = 1; j <= MAX_PACKAGES_PER_VEHICLE; j++) { 110 | 111 | addShipment(customerCache, facilitiesCache, shipmentCache, vin, newVehicle, v_dest, "pkg-" + j, 112 | rand(PKG_DESCS)); 113 | } 114 | 115 | // Add additional sensor ids if present 116 | String addl = System.getenv("ADDITIONAL_SENSOR_IDS"); 117 | if (addl != null) { 118 | String[] ids = addl.split(","); 119 | for (String id: ids) { 120 | addShipment(customerCache, facilitiesCache, shipmentCache, vin, newVehicle, v_dest, id.trim(), 121 | rand(PKG_DESCS) + " [" + id.trim() + "]"); 122 | } 123 | } 124 | 125 | } 126 | calcUtilization(); 127 | 128 | } 129 | 130 | private void addShipment(Map customerCache, Map facilitiesCache, 131 | Map shipmentCache, String vin, Vehicle v, Facility v_dest, String sensor_id, 132 | String pkgDesc) { 133 | List route = new ArrayList(); 134 | 135 | Facility p_origin = facilitiesCache.get(rand(ORIGINS)); 136 | Facility p_dest = facilitiesCache.get(rand(DESTS)); 137 | 138 | route.add(p_origin); 139 | route.add(v_dest); 140 | route.add(p_dest); 141 | 142 | List telemetry = new ArrayList<>(); 143 | telemetry.add(new Telemetry("°C", 40.0, 0.0, "Temperature", "Ambient")); 144 | telemetry.add(new Telemetry("%", 100.0, 0.0, "Humidity", "Humidity")); 145 | telemetry.add(new Telemetry("lm", 400.0, 100.0, "Light", "Light")); 146 | telemetry.add(new Telemetry("inHg", 31, 29, "Pressure", "Pressure")); 147 | 148 | Customer cust = customerCache.get(rand(COMPANIES)); 149 | 150 | // left ~3 days, ago eta ~5 days from now 151 | Date etd = new Date(new Date().getTime() - DAY_IN_MS - (long)(Math.random() * DAY_IN_MS * 3)); 152 | Date eta = new Date(new Date().getTime() + DAY_IN_MS + (long)(Math.random() * DAY_IN_MS * 4)); 153 | 154 | Shipment s = new Shipment(customerCache.get(rand(COMPANIES)), 155 | "Package " + sensor_id + "/" + vin, pkgDesc, 156 | sensor_id, route, etd, eta, Math.random() * 2000, v); 157 | 158 | s.setTelemetry(telemetry); 159 | shipmentCache.put(sensor_id + "/" + vin, s); 160 | } 161 | 162 | private String rand(String[] strs) { 163 | return strs[(int)Math.floor(Math.random() * strs.length)]; 164 | } 165 | 166 | private void calcUtilization() { 167 | Map facCache = dgService.getFacilities(); 168 | Map shipCache = dgService.getShipments(); 169 | 170 | Map facCount = new HashMap<>(); 171 | 172 | int total = 0; 173 | 174 | for (String s1 : shipCache.keySet()) { 175 | Shipment s = shipCache.get(s1); 176 | for (Facility f : s.getRoute()) { 177 | total++; 178 | if (facCount.containsKey(f.getName())) { 179 | facCount.put(f.getName(), facCount.get(f.getName()) + 1); 180 | } else { 181 | facCount.put(f.getName(), 1); 182 | } 183 | } 184 | } 185 | 186 | for (String s1 : facCache.keySet()) { 187 | Facility f = facCache.get(s1); 188 | if (!facCount.containsKey(f.getName())) { 189 | f.setUtilization(0); 190 | } else { 191 | f.setUtilization(2.5 * ((double) facCount.get(f.getName()) / (double) total)); 192 | } 193 | facCache.put(f.getName(), f); 194 | } 195 | } 196 | 197 | @PUT 198 | @Path("/{id}") 199 | public void put(@PathParam("id") String id, Vehicle value) { 200 | dgService.getVehicles().put(id, value); 201 | } 202 | 203 | @GET 204 | @Path("/summaries") 205 | @Produces({"application/json"}) 206 | public List getSummaries() { 207 | 208 | List result = new ArrayList<>(); 209 | 210 | Summary vehicleSummary = getVehicleSummary(); 211 | Summary clientSummary = getClientSUmmary(); 212 | Summary packageSummary = getPackageSummary(); 213 | Summary facilitySummary = getFacilitySummary(); 214 | Summary operatorSummary = getOperatorSummary(); 215 | 216 | result.add(clientSummary); 217 | result.add(packageSummary); 218 | result.add(vehicleSummary); 219 | result.add(operatorSummary); 220 | result.add(facilitySummary); 221 | 222 | Summary mgrs = new Summary(); 223 | mgrs.setName("fake"); 224 | mgrs.setTitle("Managers"); 225 | mgrs.setCount(23); 226 | mgrs.setWarningCount(4); 227 | mgrs.setErrorCount(1); 228 | result.add(mgrs); 229 | return result; 230 | } 231 | 232 | private Summary getOperatorSummary() { 233 | Map cache = dgService.getOperators(); 234 | 235 | Summary summary = new Summary(); 236 | summary.setName("operators"); 237 | summary.setTitle("Operators"); 238 | summary.setCount(cache.keySet().size()); 239 | 240 | return summary; 241 | 242 | } 243 | 244 | private Summary getFacilitySummary() { 245 | Map cache = dgService.getFacilities(); 246 | 247 | Summary summary = new Summary(); 248 | summary.setName("facilities"); 249 | summary.setTitle("Facilities"); 250 | summary.setCount(cache.keySet().size()); 251 | 252 | long warningCount = cache.keySet().stream() 253 | .map(cache::get) 254 | .filter(v -> v.getUtilization() < .7 && v.getUtilization() > .5) 255 | .count(); 256 | 257 | long errorCount = cache.keySet().stream() 258 | .map(cache::get) 259 | .filter(v -> v.getUtilization() < .5) 260 | .count(); 261 | 262 | summary.setWarningCount(warningCount); 263 | summary.setErrorCount(errorCount); 264 | 265 | return summary; 266 | } 267 | 268 | private Summary getPackageSummary() { 269 | Map cache = dgService.getShipments(); 270 | 271 | Summary summary = new Summary(); 272 | summary.setName("packages"); 273 | summary.setTitle("Packages"); 274 | summary.setCount(cache.keySet().size()); 275 | 276 | 277 | long warningCount = cache.keySet().stream() 278 | .map(cache::get) 279 | .filter(v -> "warning".equalsIgnoreCase(v.getStatus())) 280 | .count(); 281 | 282 | long errorCount = cache.keySet().stream() 283 | .map(cache::get) 284 | .filter(v -> "error".equalsIgnoreCase(v.getStatus())) 285 | .count(); 286 | 287 | summary.setWarningCount(warningCount); 288 | summary.setErrorCount(errorCount); 289 | return summary; 290 | 291 | } 292 | 293 | private Summary getClientSUmmary() { 294 | Map cache = dgService.getCustomers(); 295 | 296 | Summary summary = new Summary(); 297 | summary.setName("clients"); 298 | summary.setTitle("Clients"); 299 | summary.setCount(cache.keySet().size()); 300 | return summary; 301 | 302 | } 303 | 304 | private Summary getVehicleSummary() { 305 | Map cache = dgService.getVehicles(); 306 | 307 | Summary summary = new Summary(); 308 | summary.setName("vehicles"); 309 | summary.setTitle("Vehicles"); 310 | summary.setCount(cache.keySet().size()); 311 | 312 | 313 | long warningCount = cache.keySet().stream() 314 | .map(cache::get) 315 | .filter(v -> "warning".equalsIgnoreCase(v.getStatus())) 316 | .count(); 317 | 318 | long errorCount = cache.keySet().stream() 319 | .map(cache::get) 320 | .filter(v -> "error".equalsIgnoreCase(v.getStatus())) 321 | .count(); 322 | 323 | summary.setWarningCount(warningCount); 324 | summary.setErrorCount(errorCount); 325 | return summary; 326 | } 327 | 328 | 329 | public static final String[] COMPANIES = new String[]{ 330 | "Wonka Industries", 331 | "Acme Corp", 332 | "Stark Industries", 333 | "Ollivander's Wand Shop", 334 | "Gekko & Co", 335 | "Wayne Enterprises", 336 | "Cyberdyne Systems", 337 | "Cheers", 338 | "Genco Pura", 339 | "NY Enquirer", 340 | "Duff Beer", 341 | "Bubba Gump Shrimp Co", 342 | "Olivia Pope & Associates", 343 | "Sterling Cooper", 344 | "Soylent", 345 | "Hooli", 346 | "Good Burger" 347 | }; 348 | 349 | public static final String[] ORIGINS = new String[]{ 350 | "Winter Springs, FL", 351 | "Raleigh, NC", 352 | "Westford, MA", 353 | "Atlanta, GA", 354 | "Charleston, SC", 355 | "Tarboro, NC", 356 | "Huntsville, AL", 357 | "Knoxville, TN", 358 | "Showshoe, WV", 359 | "Washington, D.C.", 360 | "Virginia Beach, VA", 361 | "New York, NY", 362 | "Jacksonville, FL" 363 | }; 364 | 365 | public static final String[] DESTS = new String[]{ 366 | "Chatanooga, TN", 367 | "Louisville, KY", 368 | "Omaha, NE", 369 | "Chicago, IL", 370 | "Des Moines, IA", 371 | "Lexington, KY", 372 | "New Orleans, LA", 373 | "Mobile, AL" 374 | }; 375 | 376 | public static final String[] VEHICLE_TYPES = new String[] { 377 | 378 | "Box truck", 379 | "Van", 380 | "Cutaway van chassis", 381 | "Medium Duty Truck such as Ford F-650 in North America", 382 | "Medium Standard Truck", 383 | "Platform truck", 384 | "Flatbed truck (may also be light duty trucks)", 385 | "Firetruck (may also be a heavy truck)", 386 | "Recreational Vehicle or Motorhome", 387 | "Concrete transport truck (cement mixer)", 388 | "Mobile crane", 389 | "Dump truck", 390 | "Garbage truck", 391 | "Log carrier", 392 | "Refrigerator truck", 393 | "Tractor unit", 394 | "Tank truck", 395 | "Heavy Hauler", 396 | "F-35" 397 | }; 398 | 399 | public static final String[] PKG_DESCS = new String[] { 400 | "Spare F-22 Parts", 401 | "Violins", 402 | "Antique Baseballs", 403 | "Frozen Cells", 404 | "Machined Parts", 405 | "Misc. Assembly Fasteners", 406 | "Fresh Fruit", 407 | "Frozen Steaks", 408 | "Precious Jewels", 409 | "Optical Hard Drives", 410 | "Polyjuice Potion", 411 | "Live Bait" 412 | }; 413 | 414 | public static final String[] OPERATOR_NAMES = new String[]{ 415 | "R. Kint", 416 | "H. Potter", 417 | "A. Ventura", 418 | "H. Lime", 419 | "S. Kowalski", 420 | "D. Vader", 421 | "S. Spade", 422 | "D. Strangelove", 423 | "T. Montana", 424 | "N. Rae", 425 | "J. Benjamin", 426 | "A. DeLarge", 427 | "J. Cousteau", 428 | "E. Scissorhands", 429 | "G. Bailey", 430 | "Lt. Kilgore", 431 | "T. Dude", 432 | "F. Booth", 433 | "F. Kreuger" 434 | }; 435 | 436 | } 437 | 438 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/rest/VehiclesEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.rest; 16 | 17 | import com.redhat.iot.cargodemo.model.Alert; 18 | import com.redhat.iot.cargodemo.model.Shipment; 19 | import com.redhat.iot.cargodemo.model.Vehicle; 20 | import com.redhat.iot.cargodemo.service.AlertsService; 21 | import com.redhat.iot.cargodemo.service.DGService; 22 | 23 | import javax.inject.Inject; 24 | import javax.inject.Singleton; 25 | import javax.ws.rs.*; 26 | import java.util.List; 27 | import java.util.Map; 28 | import java.util.stream.Collectors; 29 | 30 | /** 31 | * A simple REST service which proxies requests to a local datagrid. 32 | */ 33 | @Path("/vehicles") 34 | @Singleton 35 | public class VehiclesEndpoint { 36 | 37 | @Inject 38 | DGService dgService; 39 | 40 | @Inject 41 | AlertsService alertsService; 42 | 43 | @GET 44 | @Path("/{id}") 45 | @Produces({"application/json"}) 46 | public Vehicle get(@PathParam("id") String id) { 47 | return dgService.getVehicles().get(id); 48 | } 49 | 50 | @PUT 51 | @Path("/{id}") 52 | public void put(@PathParam("id") String id, Vehicle value) { 53 | dgService.getVehicles().put(id, value); 54 | } 55 | 56 | @GET 57 | @Path("/") 58 | @Produces({"application/json"}) 59 | public List getAll() { 60 | 61 | Map cache = dgService.getVehicles(); 62 | 63 | return cache.keySet().stream() 64 | .map(cache::get) 65 | .collect(Collectors.toList()); 66 | 67 | } 68 | 69 | @GET 70 | @Path("/{vin}/alerts") 71 | @Produces({"application/json"}) 72 | public List getAlerts(@PathParam("vin") String vin) { 73 | 74 | Map cache = dgService.getVehicles(); 75 | List alerts = alertsService.getAlerts(); 76 | 77 | Vehicle v = cache.get(vin); 78 | 79 | List finalAlerts = alerts.stream() 80 | .filter(a -> vin.equals(a.getTruckid())) 81 | .collect(Collectors.toList()); 82 | 83 | alertsService.clearAlertsForVehicle(v); 84 | 85 | return finalAlerts; 86 | } 87 | 88 | @POST 89 | @Path("/{vin}/resetStatus") 90 | public void clearAll(@PathParam("vin") String vin) { 91 | Map cache = dgService.getVehicles(); 92 | Vehicle v = cache.get(vin); 93 | v.setStatus("ok"); 94 | cache.put(v.getVin(), v); 95 | 96 | } 97 | 98 | @POST 99 | @Path("/{vin}/{pkgid}/resetStatus") 100 | public void clearPkg(@PathParam("vin") String vin, @PathParam("pkgid") String pkgid) { 101 | Map cache = dgService.getVehicles(); 102 | 103 | Map shipCache = dgService.getShipments(); 104 | 105 | // TODO: use DG queries properly 106 | List vehiclePackages = shipCache.keySet().stream() 107 | .map(shipCache::get) 108 | .filter(shipment -> vin.equals(shipment.getCur_vehicle().getVin())) 109 | .collect(Collectors.toList()); 110 | 111 | for (Shipment pkg : vehiclePackages) { 112 | pkg.setStatus("ok"); 113 | shipCache.put(pkg.getSensor_id() + "/" + pkg.getCur_vehicle().getVin(), pkg); 114 | } 115 | } 116 | 117 | } 118 | 119 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/service/AlertsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.service; 16 | 17 | import com.redhat.iot.cargodemo.model.*; 18 | import org.eclipse.paho.client.mqttv3.*; 19 | import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; 20 | import org.json.JSONObject; 21 | 22 | import javax.enterprise.context.ApplicationScoped; 23 | import javax.enterprise.context.Initialized; 24 | import javax.enterprise.event.Observes; 25 | import javax.inject.Inject; 26 | import java.util.*; 27 | 28 | @ApplicationScoped 29 | public class AlertsService implements MqttCallback { 30 | 31 | final private List alerts = Collections.synchronizedList(new ArrayList<>()); 32 | 33 | public static final int MAX_RECONNECT_ATTEMPTS = 100; 34 | 35 | @Inject 36 | DGService dgService; 37 | 38 | public AlertsService() { 39 | 40 | } 41 | 42 | public void addAlert(Alert alert) { 43 | alerts.add(alert); 44 | } 45 | 46 | public List getAlerts() { 47 | return alerts; 48 | } 49 | 50 | public void clearAlerts() { 51 | alerts.clear(); 52 | } 53 | 54 | public void clearAlertsForVehicle(Vehicle v) { 55 | synchronized (alerts) { 56 | List toRemove = new ArrayList<>(); 57 | for (Alert alert : alerts) { 58 | if (alert.getTruckid().equals(v.getVin())) { 59 | toRemove.add(alert); 60 | } 61 | } 62 | for (Alert toRemoveAlert: toRemove) { 63 | alerts.remove(toRemoveAlert); 64 | } 65 | } 66 | } 67 | 68 | public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { 69 | 70 | subscribeToAlerts(); 71 | 72 | } 73 | 74 | 75 | private void subscribeToAlerts() { 76 | MemoryPersistence persistence = new MemoryPersistence(); 77 | String broker = "tcp://kapua-broker:1883"; 78 | 79 | for (int i = 0; i < MAX_RECONNECT_ATTEMPTS; i++) { 80 | try { 81 | 82 | MqttClient sampleClient = new MqttClient(broker, "dgproxy", persistence); 83 | 84 | MqttConnectOptions connOpts = new MqttConnectOptions(); 85 | connOpts.setUserName(System.getenv("BROKER_USERNAME")); 86 | connOpts.setPassword(System.getenv("BROKER_PASSWORD").toCharArray()); 87 | 88 | connOpts.setCleanSession(true); 89 | System.out.println("Attempt " + (i+1) + " of " + MAX_RECONNECT_ATTEMPTS + ": Connecting to broker: " + broker); 90 | sampleClient.connect(connOpts); 91 | System.out.println("Connected"); 92 | 93 | sampleClient.setCallback(this); 94 | sampleClient.subscribe("Red-Hat/+/iot-demo/+/+/alerts"); 95 | 96 | System.out.println("Subscribed"); 97 | break; 98 | } catch (Exception me) { 99 | System.out.println("Could not connect to " + broker); 100 | System.out.println("msg " + me.getMessage()); 101 | System.out.println("loc " + me.getLocalizedMessage()); 102 | System.out.println("cause " + me.getCause()); 103 | System.out.println("excep " + me); 104 | me.printStackTrace(); 105 | } 106 | try { 107 | System.out.println("Waiting for 10s to retry"); 108 | Thread.sleep(10000); 109 | } catch (InterruptedException e) { 110 | e.printStackTrace(); 111 | } 112 | } 113 | } 114 | 115 | @Override 116 | public void connectionLost(Throwable throwable) { 117 | System.out.println("CONNECTION LOST"); 118 | throwable.printStackTrace(); 119 | System.out.println("Attempting to reconnect"); 120 | subscribeToAlerts(); 121 | } 122 | 123 | private boolean isNull(String s) { 124 | return ((s == null) || (s.trim().isEmpty()) || s.trim().equalsIgnoreCase("null")); 125 | } 126 | 127 | private Long getLongObj(JSONObject dic, String key) { 128 | if (!dic.has(key) || dic.isNull(key)) { 129 | return null; 130 | } else { 131 | return dic.getLong(key); 132 | } 133 | } 134 | 135 | private String getStringObj(JSONObject dic, String key) { 136 | if (!dic.has(key) || dic.isNull(key)) { 137 | return null; 138 | } else { 139 | return dic.getString(key).trim(); 140 | } 141 | } 142 | 143 | @Override 144 | public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { 145 | 146 | String payload = mqttMessage.toString(); 147 | 148 | System.out.println("ALERT ARRIVED FOR TOPIC " + topic + " payload: " + payload); 149 | 150 | JSONObject j = new JSONObject(payload); 151 | 152 | Long dateObj = getLongObj(j, "date"); 153 | if (dateObj == null) { 154 | dateObj = new Date().getTime(); 155 | } 156 | 157 | Date date = new Date(dateObj); 158 | 159 | String from = getStringObj(j, "from"); 160 | String desc = getStringObj(j, "desc"); 161 | String message = getStringObj(j, "message"); 162 | String type = getStringObj(j, "type"); 163 | String truck_id = getStringObj(j, "truckid"); 164 | String sensor_id = getStringObj(j, "sensorid"); 165 | 166 | if ("VEHICLE".equalsIgnoreCase(type)) { 167 | 168 | Vehicle v = dgService.getVehicles().get(truck_id.trim()); 169 | if (v == null) { 170 | System.out.println("Cannot find vehicle " + truck_id + ", ignoring alert"); 171 | return; 172 | } 173 | v.setStatus("warning"); 174 | dgService.getVehicles().put(v.getVin(), v); 175 | addAlert(new Alert(date, from, desc, message, type, truck_id, null)); 176 | } else if ("PACKAGE".equalsIgnoreCase(type)) { 177 | 178 | Map shipCache = dgService.getShipments(); 179 | 180 | Shipment s = shipCache.get(sensor_id + "/" + truck_id); 181 | 182 | if (s == null) { 183 | System.out.println("Cannot find shipment for sensor_id=" + sensor_id + " truck_id=" + truck_id + ", ignoring alert"); 184 | return; 185 | } 186 | 187 | s.setStatus("warning"); 188 | dgService.getShipments().put(sensor_id + "/" + truck_id, s); 189 | addAlert(new Alert(date, from, desc, message, type, truck_id, sensor_id)); 190 | } else { 191 | System.out.println("Unknown alert type (" + type + "), ignoring"); 192 | } 193 | } 194 | 195 | @Override 196 | public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { 197 | System.out.println("DELIVERY COMPLETE?"); 198 | 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /dgproxy/src/main/java/com/redhat/iot/cargodemo/service/DGService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2017 Red Hat, Inc. and others 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * which accompanies this distribution, and is available at 8 | * http://www.eclipse.org/legal/epl-v10.html 9 | * 10 | * Contributors: 11 | * Red Hat Inc. - initial API and implementation 12 | * 13 | * ****************************************************************************** 14 | */ 15 | package com.redhat.iot.cargodemo.service; 16 | 17 | import com.redhat.iot.cargodemo.model.*; 18 | import org.infinispan.client.hotrod.RemoteCacheManager; 19 | import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; 20 | 21 | import javax.enterprise.context.ApplicationScoped; 22 | import java.util.Map; 23 | import java.util.Properties; 24 | 25 | @ApplicationScoped 26 | public class DGService { 27 | 28 | private RemoteCacheManager cacheManager; 29 | 30 | public Map getCustomers() { 31 | return cacheManager.getCache("customer"); 32 | } 33 | public Map getFacilities() { 34 | return cacheManager.getCache("facility"); 35 | } 36 | public Map getOperators() { 37 | return cacheManager.getCache("operator"); 38 | } 39 | public Map getShipments() { 40 | return cacheManager.getCache("shipment"); 41 | } 42 | public Map getVehicles() { 43 | return cacheManager.getCache("vehicle"); 44 | } 45 | 46 | public DGService() { 47 | 48 | 49 | String host = System.getenv("DATASTORE_HOST"); 50 | if (host == null) { 51 | host = "localhost"; 52 | } 53 | 54 | int port = 11333; 55 | String portStr = System.getenv("DATASTORE_PORT"); 56 | if (portStr != null) { 57 | port = Integer.parseInt(portStr); 58 | } 59 | 60 | String cacheNames = System.getenv("DATASTORE_CACHE"); 61 | if (cacheNames == null) { 62 | cacheNames = "customer,facility,operator,shipment,vehicle"; 63 | } 64 | 65 | System.out.println("DG Proxy initializing to " + host + ":" + port + " cache:" + cacheNames); 66 | 67 | Properties props = new Properties(); 68 | props.setProperty("infinispan.client.hotrod.protocol_version", "1.0"); 69 | 70 | ConfigurationBuilder builder = new ConfigurationBuilder(); 71 | builder.withProperties(props).addServer() 72 | .host(host) 73 | .port(port); 74 | cacheManager = new RemoteCacheManager(builder.build()); 75 | 76 | System.out.println("DG Proxy connected to " + host + ":" + port + " preconfigured caches: " + cacheNames); 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /dgproxy/src/main/resources/kurapayload.proto: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2016, 2017 Eurotech and/or its affiliates and others 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * which accompanies this distribution, and is available at 7 | * http://www.eclipse.org/legal/epl-v10.html 8 | * 9 | * Contributors: 10 | * Eurotech 11 | * 12 | *******************************************************************************/ 13 | 14 | /* 15 | * This file originates from the Eclipse Kura™ project 16 | */ 17 | 18 | // 19 | // To compile: 20 | // protoc --proto_path=src/main/protobuf --java_out=src/main/java src/main/protobuf/kurapayload.proto 21 | // 22 | package kuradatatypes; 23 | 24 | option java_package = "org.eclipse.kura.core.message.protobuf"; 25 | option java_outer_classname = "KuraPayloadProto"; 26 | 27 | message KuraPayload { 28 | 29 | message KuraMetric { 30 | enum ValueType { 31 | DOUBLE = 0; 32 | FLOAT = 1; 33 | INT64 = 2; 34 | INT32 = 3; 35 | BOOL = 4; 36 | STRING = 5; 37 | BYTES = 6; 38 | } 39 | 40 | required string name = 1; 41 | required ValueType type = 2; 42 | 43 | optional double double_value = 3; 44 | optional float float_value = 4; 45 | optional int64 long_value = 5; 46 | optional int32 int_value = 6; 47 | optional bool bool_value = 7; 48 | optional string string_value = 8; 49 | optional bytes bytes_value = 9; 50 | } 51 | 52 | message KuraPosition { 53 | required double latitude = 1; 54 | required double longitude = 2; 55 | optional double altitude = 3; 56 | optional double precision = 4; // dilution of precision of the current satellite fix. 57 | optional double heading = 5; // heading in degrees 58 | optional double speed = 6; // meters per second 59 | optional int64 timestamp = 7; 60 | optional int32 satellites = 8; // number satellites locked by the GPS device 61 | optional int32 status = 9; // status indicator for the GPS data: 1 = no GPS response; 2 = error in response; 4 = valid. 62 | } 63 | 64 | optional int64 timestamp = 1; 65 | optional KuraPosition position = 2; 66 | 67 | extensions 3 to 4999; 68 | repeated KuraMetric metric = 5000; // can be zero, so optional 69 | optional bytes body = 5001; 70 | } -------------------------------------------------------------------------------- /dgproxy/src/main/webapp/WEB-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /dgproxy/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /docs/qr/README.md: -------------------------------------------------------------------------------- 1 | Sample QR codes for summit demo use with mobile app 2 | =================================================== 3 | To re-generate QR codes, use the `go.sh` script. The script requires two packages: 4 | * [Imagemagick](https://www.imagemagick.org/script/index.php) 5 | * [qrencode](https://fukuchi.org/works/qrencode/index.html.en) 6 | -------------------------------------------------------------------------------- /docs/qr/go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #******************************************************************************* 3 | # Copyright (c) 2017 Red Hat, Inc and others 4 | # 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Eclipse Public License v1.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.eclipse.org/legal/epl-v10.html 9 | # 10 | # Contributors: 11 | # Red Hat, Inc. - initial API and implementation 12 | # 13 | #****************************************************************************** 14 | 15 | # 16 | # script to generate qr codes 17 | # requires imagemagick and qrencode 18 | # 19 | for i in 1 2 3 4 5 6 7 8 9 10 ; do 20 | qrencode -s 50 -o truck-${i}.png "truck-${i}" 21 | convert truck-${i}.png -font Overpass -fill Black -pointsize 250 -gravity center label:truck-${i} -append truck-${i}.png 22 | echo "done with truck-$i" 23 | done 24 | 25 | for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do 26 | qrencode -s 50 -o pkg-${i}.png "pkg-${i}" 27 | convert pkg-${i}.png -font Overpass -fill Black -pointsize 250 -gravity center label:pkg-${i} -append pkg-${i}.png 28 | echo "done with pkg-$i" 29 | done 30 | -------------------------------------------------------------------------------- /docs/qr/pkg-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-1.png -------------------------------------------------------------------------------- /docs/qr/pkg-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-10.png -------------------------------------------------------------------------------- /docs/qr/pkg-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-11.png -------------------------------------------------------------------------------- /docs/qr/pkg-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-12.png -------------------------------------------------------------------------------- /docs/qr/pkg-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-13.png -------------------------------------------------------------------------------- /docs/qr/pkg-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-14.png -------------------------------------------------------------------------------- /docs/qr/pkg-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-15.png -------------------------------------------------------------------------------- /docs/qr/pkg-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-16.png -------------------------------------------------------------------------------- /docs/qr/pkg-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-17.png -------------------------------------------------------------------------------- /docs/qr/pkg-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-18.png -------------------------------------------------------------------------------- /docs/qr/pkg-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-19.png -------------------------------------------------------------------------------- /docs/qr/pkg-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-2.png -------------------------------------------------------------------------------- /docs/qr/pkg-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-20.png -------------------------------------------------------------------------------- /docs/qr/pkg-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-3.png -------------------------------------------------------------------------------- /docs/qr/pkg-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-4.png -------------------------------------------------------------------------------- /docs/qr/pkg-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-5.png -------------------------------------------------------------------------------- /docs/qr/pkg-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-6.png -------------------------------------------------------------------------------- /docs/qr/pkg-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-7.png -------------------------------------------------------------------------------- /docs/qr/pkg-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-8.png -------------------------------------------------------------------------------- /docs/qr/pkg-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/pkg-9.png -------------------------------------------------------------------------------- /docs/qr/truck-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-1.png -------------------------------------------------------------------------------- /docs/qr/truck-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-10.png -------------------------------------------------------------------------------- /docs/qr/truck-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-2.png -------------------------------------------------------------------------------- /docs/qr/truck-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-3.png -------------------------------------------------------------------------------- /docs/qr/truck-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-4.png -------------------------------------------------------------------------------- /docs/qr/truck-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-5.png -------------------------------------------------------------------------------- /docs/qr/truck-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-6.png -------------------------------------------------------------------------------- /docs/qr/truck-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-7.png -------------------------------------------------------------------------------- /docs/qr/truck-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-8.png -------------------------------------------------------------------------------- /docs/qr/truck-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/qr/truck-9.png -------------------------------------------------------------------------------- /docs/screenshots/exec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/screenshots/exec.png -------------------------------------------------------------------------------- /docs/screenshots/fleet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-iot/iot-assettracking-demo/f07468c84325454b538f854962285c2e04c6a3fa/docs/screenshots/fleet.png -------------------------------------------------------------------------------- /iot-sim-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #******************************************************************************* 3 | # Copyright (c) 2017 Red Hat, Inc and others 4 | # 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Eclipse Public License v1.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.eclipse.org/legal/epl-v10.html 9 | # 10 | # Contributors: 11 | # Red Hat, Inc. - initial API and implementation 12 | # 13 | #****************************************************************************** 14 | 15 | . openshift-common.sh 16 | 17 | : ${OPENSHIFT_PROJECT_NAME:=redhat-iot} 18 | : ${DOCKER_ACCOUNT:=redhatiot} 19 | 20 | 21 | # Set up new simulator instance 22 | $OC delete dc/simulator 23 | $OC delete configmap data-simulator-config 24 | $OC create configmap data-simulator-config --from-file=ksim.simulator.configuration=simulator/generators.json -n "$OPENSHIFT_PROJECT_NAME" 25 | $OC new-app -n "$OPENSHIFT_PROJECT_NAME" -f iot-simulator.yml 26 | -------------------------------------------------------------------------------- /iot-simulator.yml: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Copyright (c) 2017 Red Hat, Eurotech, Inc and others 3 | # 4 | # All rights reserved. This program and the accompanying materials 5 | # are made available under the terms of the Eclipse Public License v1.0 6 | # which accompanies this distribution, and is available at 7 | # http://www.eclipse.org/legal/epl-v10.html 8 | # 9 | # Contributors: 10 | # Red Hat, Inc. - initial implementation 11 | # Eurotech - initial implementation of Kapua components 12 | # 13 | #****************************************************************************** 14 | apiVersion: v1 15 | kind: Template 16 | metadata: 17 | name: kura-simulator 18 | annotations: 19 | openshift.io/display-name: "Eclipse Kura™ simulator" 20 | description: "An IoT gateway simulator, simulating Eclipse Kura™ instances" 21 | labels: 22 | kapua: simulator 23 | parameters: 24 | - name: IMAGE_VERSION 25 | description: The version of the image to use 26 | value: latest 27 | - name: DOCKER_ACCOUNT 28 | description: The docker hub account name to pull from 29 | value: redhatiot 30 | - description: MQ Broker username 31 | name: BROKER_USERNAME 32 | value: "demo-gw2" 33 | required: true 34 | - description: MQ Broker password 35 | name: BROKER_PASSWORD 36 | value: "RedHat123" 37 | required: true 38 | - description: Number of Kura Simulators to run 39 | name: KSIM_NUM_GATEWAYS 40 | value: "2" 41 | required: true 42 | - description: Kapua Account Name 43 | name: KSIM_ACCOUNT_NAME 44 | value: "Red-Hat" 45 | required: true 46 | - description: Simulator Name Factory 47 | name: KSIM_NAME_FACTORY 48 | # value: "host:addr" 49 | - description: Simulator Name Custom Prefix 50 | name: KSIM_BASE_NAME 51 | value: "truck-" 52 | 53 | objects: 54 | 55 | # Image streams 56 | 57 | # - apiVersion: v1 58 | # kind: ImageStream 59 | # metadata: 60 | # name: kura-simulator 61 | # spec: 62 | # tags: 63 | # - from: 64 | # kind: DockerImage 65 | # name: kura-simulator:${IMAGE_VERSION} 66 | # name: ${IMAGE_VERSION} 67 | # importPolicy: 68 | # scheduled: true 69 | 70 | # Deployment configs 71 | 72 | - apiVersion: v1 73 | kind: DeploymentConfig 74 | metadata: 75 | name: simulator 76 | spec: 77 | replicas: 1 78 | selector: 79 | app: simulator 80 | deploymentconfig: simulator 81 | strategy: 82 | type: Recreate 83 | template: 84 | metadata: 85 | labels: 86 | app: simulator 87 | deploymentconfig: simulator 88 | spec: 89 | containers: 90 | - name: simulator 91 | image: ${DOCKER_ACCOUNT}/kura-simulator:${IMAGE_VERSION} 92 | imagePullPolicy: Always 93 | restartPolicy: Always 94 | dnsPolicy: ClusterFirst 95 | env: 96 | - name: KSIM_BROKER_PROTO 97 | value: $(KAPUA_BROKER_PORT_1883_TCP_PROTO) 98 | - name: KSIM_BROKER_HOST 99 | value: $(KAPUA_BROKER_SERVICE_HOST) 100 | - name: KSIM_BROKER_PORT 101 | value: $(KAPUA_BROKER_PORT_1883_TCP_PORT) 102 | - name: KSIM_BROKER_USER 103 | value: ${BROKER_USERNAME} 104 | - name: KSIM_BROKER_PASSWORD 105 | value: ${BROKER_PASSWORD} 106 | - name: KSIM_BASE_NAME 107 | value: ${KSIM_BASE_NAME} 108 | - name: KSIM_NAME_FACTORY 109 | value: ${KSIM_NAME_FACTORY} 110 | - name: KSIM_NUM_GATEWAYS 111 | value: ${KSIM_NUM_GATEWAYS} 112 | - name: KSIM_ACCOUNT_NAME 113 | value: ${KSIM_ACCOUNT_NAME} 114 | - name: KSIM_SIMULATION_CONFIGURATION 115 | valueFrom: 116 | configMapKeyRef: 117 | name: data-simulator-config 118 | key: ksim.simulator.configuration 119 | # triggers: 120 | # - type: ConfigChange 121 | # - type: ImageChange 122 | # imageChangeParams: 123 | # automatic: true 124 | # containerNames: 125 | # - simulator 126 | # from: 127 | # kind: ImageStreamTag 128 | # name: kura-simulator:${IMAGE_VERSION} 129 | # paused: false 130 | # revisionHistoryLimit: 2 131 | # minReadySeconds: 0 132 | -------------------------------------------------------------------------------- /openshift-common.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #******************************************************************************* 3 | # Copyright (c) 2017 Red Hat, Inc and others 4 | # 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Eclipse Public License v1.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.eclipse.org/legal/epl-v10.html 9 | # 10 | # Contributors: 11 | # Red Hat, Inc. - initial API and implementation 12 | # 13 | #****************************************************************************** 14 | 15 | export OPENSHIFT_PROJECT_NAME=${OPENSHIFT_PROJECT_NAME:=redhat-iot} 16 | 17 | if which oc &>/dev/null; then 18 | echo Using "oc" from path 19 | export OC=oc 20 | else 21 | export OPENSHIFT_DIR=/tmp/openshift 22 | export OC=${OPENSHIFT_DIR}/openshift-origin-server-v1.4.1+3f9807a-linux-64bit/oc 23 | fi 24 | -------------------------------------------------------------------------------- /openshift-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #******************************************************************************* 3 | # Copyright (c) 2017 Red Hat, Inc and others 4 | # 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Eclipse Public License v1.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.eclipse.org/legal/epl-v10.html 9 | # 10 | # Contributors: 11 | # Red Hat, Inc. - initial API and implementation 12 | # 13 | #****************************************************************************** 14 | 15 | set -e 16 | 17 | . openshift-common.sh 18 | 19 | OPENSHIFT_PROJECT_NAME=${OPENSHIFT_PROJECT_NAME:=redhat-iot} 20 | IMAGE_VERSION=${IMAGE_VERSION:=2017-04-08} 21 | 22 | # print error and exit when necessary 23 | 24 | die() { printf "$@" "\n" 1>&2 ; exit 1; } 25 | 26 | # test if the project is already created ... fail otherwise 27 | 28 | $OC describe "project/$OPENSHIFT_PROJECT_NAME" &>/dev/null || die "Project '$OPENSHIFT_PROJECT_NAME' not created or OpenShift is unreachable. Try with:\n\n\toc new-project eclipse-kapua\n\n" 29 | 30 | ### Create Kapua from template 31 | 32 | echo Creating Kapua from template ... 33 | $OC create configmap data-simulator-config --from-file=ksim.simulator.configuration=simulator/generators.json -n "$OPENSHIFT_PROJECT_NAME" 34 | $OC new-app -n "$OPENSHIFT_PROJECT_NAME" -f iot-demo.yml -p IMAGE_VERSION=${IMAGE_VERSION} ${DASHBOARD_WEB_TITLE:+-p DASHBOARD_WEB_TITLE="$DASHBOARD_WEB_TITLE"} ${ADDITIONAL_SENSOR_IDS:+-p ADDITIONAL_SENSOR_IDS="$ADDITIONAL_SENSOR_IDS"} 35 | echo Creating Kapua from template ... done! 36 | -------------------------------------------------------------------------------- /openshift-iot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #******************************************************************************* 3 | # Copyright (c) 2017 Red Hat, Inc and others 4 | # 5 | # All rights reserved. This program and the accompanying materials 6 | # are made available under the terms of the Eclipse Public License v1.0 7 | # which accompanies this distribution, and is available at 8 | # http://www.eclipse.org/legal/epl-v10.html 9 | # 10 | # Contributors: 11 | # Red Hat, Inc. - initial API and implementation 12 | # 13 | #****************************************************************************** 14 | 15 | . openshift-common.sh 16 | 17 | # Expose the MQTT broker on 1883 and 61614 18 | $OC expose dc kapua-broker --type=LoadBalancer --name=mqtt-ingress 19 | 20 | # Export the nodePorts assigned to those services, enter these into Kura, MQTT clients, etc. 21 | # This is temporary until we work out a better way 22 | $OC export svc mqtt-ingress 23 | 24 | -------------------------------------------------------------------------------- /simulator/generators.json: -------------------------------------------------------------------------------- 1 | { 2 | "applications": { 3 | "iot-demo": { 4 | "scheduler": { "period": 1000 }, 5 | "topics": { 6 | "trucks/truck-1": { 7 | "metrics": { 8 | "rpm" : { "generator": "rpm", "name": "value" }, 9 | "temp" : { "generator": "temp", "name": "value" }, 10 | "oilpress" : { "generator": "oilpress", "name": "value" } 11 | } 12 | }, 13 | "trucks/truck-2": { 14 | "metrics": { 15 | "rpm" : { "generator": "rpm", "name": "value" }, 16 | "temp" : { "generator": "temp", "name": "value" }, 17 | "oilpress" : { "generator": "oilpress", "name": "value" } 18 | } 19 | }, 20 | "trucks/truck-3": { 21 | "metrics": { 22 | "rpm" : { "generator": "rpm", "name": "value" }, 23 | "temp" : { "generator": "temp", "name": "value" }, 24 | "oilpress" : { "generator": "oilpress", "name": "value" } 25 | } 26 | }, 27 | "trucks/truck-4": { 28 | "metrics": { 29 | "rpm" : { "generator": "rpm", "name": "value" }, 30 | "temp" : { "generator": "temp", "name": "value" }, 31 | "oilpress" : { "generator": "oilpress", "name": "value" } 32 | } 33 | }, 34 | "trucks/truck-5": { 35 | "metrics": { 36 | "rpm" : { "generator": "rpm", "name": "value" }, 37 | "temp" : { "generator": "temp", "name": "value" }, 38 | "oilpress" : { "generator": "oilpress", "name": "value" } 39 | } 40 | }, 41 | "trucks/truck-6": { 42 | "metrics": { 43 | "rpm" : { "generator": "rpm", "name": "value" }, 44 | "temp" : { "generator": "temp", "name": "value" }, 45 | "oilpress" : { "generator": "oilpress", "name": "value" } 46 | } 47 | }, 48 | "trucks/truck-7": { 49 | "metrics": { 50 | "rpm" : { "generator": "rpm", "name": "value" }, 51 | "temp" : { "generator": "temp", "name": "value" }, 52 | "oilpress" : { "generator": "oilpress", "name": "value" } 53 | } 54 | }, 55 | "trucks/truck-8": { 56 | "metrics": { 57 | "rpm" : { "generator": "rpm", "name": "value" }, 58 | "temp" : { "generator": "temp", "name": "value" }, 59 | "oilpress" : { "generator": "oilpress", "name": "value" } 60 | } 61 | }, 62 | "trucks/truck-9": { 63 | "metrics": { 64 | "rpm" : { "generator": "rpm", "name": "value" }, 65 | "temp" : { "generator": "temp", "name": "value" }, 66 | "oilpress" : { "generator": "oilpress", "name": "value" } 67 | } 68 | }, 69 | "trucks/truck-10": { 70 | "metrics": { 71 | "rpm" : { "generator": "rpm", "name": "value" }, 72 | "temp" : { "generator": "temp", "name": "value" }, 73 | "oilpress" : { "generator": "oilpress", "name": "value" } 74 | } 75 | }, 76 | "packages/pkg-1": { 77 | "metrics": { 78 | "Ambient" : { "generator": "ambient_temp" }, 79 | "Light" : { "generator": "lux" }, 80 | "Humidity" : { "generator": "humidity" }, 81 | "Pressure" : { "generator": "barometer" } 82 | } 83 | }, 84 | "packages/pkg-2": { 85 | "metrics": { 86 | "Ambient" : { "generator": "ambient_temp" }, 87 | "Light" : { "generator": "lux" }, 88 | "Humidity" : { "generator": "humidity" }, 89 | "Pressure" : { "generator": "barometer" } 90 | } 91 | }, 92 | "packages/pkg-3": { 93 | "metrics": { 94 | "Ambient" : { "generator": "ambient_temp" }, 95 | "Light" : { "generator": "lux" }, 96 | "Humidity" : { "generator": "humidity" }, 97 | "Pressure" : { "generator": "barometer" } 98 | } 99 | }, 100 | "packages/pkg-4": { 101 | "metrics": { 102 | "Ambient" : { "generator": "ambient_temp" }, 103 | "Light" : { "generator": "lux" }, 104 | "Humidity" : { "generator": "humidity" }, 105 | "Pressure" : { "generator": "barometer" } 106 | } 107 | }, 108 | "packages/pkg-5": { 109 | "metrics": { 110 | "Ambient" : { "generator": "ambient_temp" }, 111 | "Light" : { "generator": "lux" }, 112 | "Humidity" : { "generator": "humidity" }, 113 | "Pressure" : { "generator": "barometer" } 114 | } 115 | }, 116 | "packages/pkg-6": { 117 | "metrics": { 118 | "Ambient" : { "generator": "ambient_temp" }, 119 | "Light" : { "generator": "lux" }, 120 | "Humidity" : { "generator": "humidity" }, 121 | "Pressure" : { "generator": "barometer" } 122 | } 123 | }, 124 | "packages/pkg-7": { 125 | "metrics": { 126 | "Ambient" : { "generator": "ambient_temp" }, 127 | "Light" : { "generator": "lux" }, 128 | "Humidity" : { "generator": "humidity" }, 129 | "Pressure" : { "generator": "barometer" } 130 | } 131 | }, 132 | "packages/pkg-8": { 133 | "metrics": { 134 | "Ambient" : { "generator": "ambient_temp" }, 135 | "Light" : { "generator": "lux" }, 136 | "Humidity" : { "generator": "humidity" }, 137 | "Pressure" : { "generator": "barometer" } 138 | } 139 | }, 140 | "packages/pkg-9": { 141 | "metrics": { 142 | "Ambient" : { "generator": "ambient_temp" }, 143 | "Light" : { "generator": "lux" }, 144 | "Humidity" : { "generator": "humidity" }, 145 | "Pressure" : { "generator": "barometer" } 146 | } 147 | }, 148 | "packages/pkg-10": { 149 | "metrics": { 150 | "Ambient" : { "generator": "ambient_temp" }, 151 | "Light" : { "generator": "lux" }, 152 | "Humidity" : { "generator": "humidity" }, 153 | "Pressure" : { "generator": "barometer" } 154 | } 155 | }, 156 | "packages/pkg-11": { 157 | "metrics": { 158 | "Ambient" : { "generator": "ambient_temp" }, 159 | "Light" : { "generator": "lux" }, 160 | "Humidity" : { "generator": "humidity" }, 161 | "Pressure" : { "generator": "barometer" } 162 | } 163 | }, 164 | "packages/pkg-12": { 165 | "metrics": { 166 | "Ambient" : { "generator": "ambient_temp" }, 167 | "Light" : { "generator": "lux" }, 168 | "Humidity" : { "generator": "humidity" }, 169 | "Pressure" : { "generator": "barometer" } 170 | } 171 | }, 172 | "packages/pkg-13": { 173 | "metrics": { 174 | "Ambient" : { "generator": "ambient_temp" }, 175 | "Light" : { "generator": "lux" }, 176 | "Humidity" : { "generator": "humidity" }, 177 | "Pressure" : { "generator": "barometer" } 178 | } 179 | }, 180 | "packages/pkg-14": { 181 | "metrics": { 182 | "Ambient" : { "generator": "ambient_temp" }, 183 | "Light" : { "generator": "lux" }, 184 | "Humidity" : { "generator": "humidity" }, 185 | "Pressure" : { "generator": "barometer" } 186 | } 187 | }, 188 | "packages/pkg-15": { 189 | "metrics": { 190 | "Ambient" : { "generator": "ambient_temp" }, 191 | "Light" : { "generator": "lux" }, 192 | "Humidity" : { "generator": "humidity" }, 193 | "Pressure" : { "generator": "barometer" } 194 | } 195 | }, 196 | "packages/pkg-16": { 197 | "metrics": { 198 | "Ambient" : { "generator": "ambient_temp" }, 199 | "Light" : { "generator": "lux" }, 200 | "Humidity" : { "generator": "humidity" }, 201 | "Pressure" : { "generator": "barometer" } 202 | } 203 | }, 204 | "packages/pkg-17": { 205 | "metrics": { 206 | "Ambient" : { "generator": "ambient_temp" }, 207 | "Light" : { "generator": "lux" }, 208 | "Humidity" : { "generator": "humidity" }, 209 | "Pressure" : { "generator": "barometer" } 210 | } 211 | }, 212 | "packages/pkg-18": { 213 | "metrics": { 214 | "Ambient" : { "generator": "ambient_temp" }, 215 | "Light" : { "generator": "lux" }, 216 | "Humidity" : { "generator": "humidity" }, 217 | "Pressure" : { "generator": "barometer" } 218 | } 219 | }, 220 | "packages/pkg-19": { 221 | "metrics": { 222 | "Ambient" : { "generator": "ambient_temp" }, 223 | "Light" : { "generator": "lux" }, 224 | "Humidity" : { "generator": "humidity" }, 225 | "Pressure" : { "generator": "barometer" } 226 | } 227 | }, 228 | "packages/pkg-20": { 229 | "metrics": { 230 | "Ambient" : { "generator": "ambient_temp" }, 231 | "Light" : { "generator": "lux" }, 232 | "Humidity" : { "generator": "humidity" }, 233 | "Pressure" : { "generator": "barometer" } 234 | } 235 | } 236 | }, 237 | "generators": { 238 | "rpm": { 239 | "type": "sine", "period": 30000, "offset": 1200, "amplitude": 600 240 | }, 241 | "temp": { 242 | "type": "sine", "period": 60000, "shift": 100, "offset": 190, "amplitude": 40 243 | }, 244 | "oilpress": { 245 | "type": "sine", "period": 30000, "shift": 400, "offset": 50, "amplitude": 20 246 | }, 247 | "ambient_temp": { 248 | "type": "sine", "period": 100000, "offset": 25, "amplitude": 4 249 | }, 250 | "lux": { 251 | "type": "sine", "period": 100000, "shift": 45.5, "offset": 220, "amplitude": 90 252 | }, 253 | "humidity": { 254 | "type": "sine", "period": 432000, "offset": 70, "amplitude": 20 255 | }, 256 | "barometer": { 257 | "type": "sine", "period": 432000, "offset": 29.92, "amplitude": 0.5 258 | } 259 | } 260 | } 261 | } 262 | } 263 | --------------------------------------------------------------------------------