├── README.md ├── arch.png ├── backend └── kakapo │ ├── .classpath │ ├── .project │ ├── .settings │ ├── org.eclipse.core.resources.prefs │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs │ ├── dataPump │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── kakapo │ │ │ │ │ └── dataPump │ │ │ │ │ ├── DataWaveProducer.java │ │ │ │ │ ├── kafkaCon │ │ │ │ │ └── KafkaDataPumbOut.java │ │ │ │ │ └── mqttClient │ │ │ │ │ └── MqttDataSubscribe.java │ │ │ └── resources │ │ │ │ └── log4j.properties │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── kakapo │ │ │ └── dataPump │ │ │ └── AppTest.java │ └── target │ │ ├── classes │ │ ├── META-INF │ │ │ ├── MANIFEST.MF │ │ │ └── maven │ │ │ │ └── com.zlata.kakapo │ │ │ │ └── dataPump │ │ │ │ ├── pom.properties │ │ │ │ └── pom.xml │ │ ├── com │ │ │ └── kakapo │ │ │ │ └── dataPump │ │ │ │ ├── DataWaveProducer.class │ │ │ │ ├── kafkaCon │ │ │ │ └── KafkaDataPumbOut.class │ │ │ │ └── mqttClient │ │ │ │ └── MqttDataSubscribe.class │ │ └── log4j.properties │ │ └── test-classes │ │ └── com │ │ └── kakapo │ │ └── dataPump │ │ └── AppTest.class │ ├── dataSpoonDrift │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── kakapo │ │ │ │ └── dataSpoonDrift │ │ │ │ ├── DataProcessor.java │ │ │ │ ├── dataModel │ │ │ │ └── TrackingData.java │ │ │ │ └── storm │ │ │ │ ├── DataKafkaSpout.java │ │ │ │ ├── DataNormalizerBlot.java │ │ │ │ └── DataStorageBlot.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── kakapo │ │ │ └── dataSpoonDrift │ │ │ └── AppTest.java │ └── target │ │ ├── classes │ │ ├── META-INF │ │ │ ├── MANIFEST.MF │ │ │ └── maven │ │ │ │ └── com.zlata.kakapo │ │ │ │ └── dataSpoonDrift │ │ │ │ ├── pom.properties │ │ │ │ └── pom.xml │ │ └── com │ │ │ └── kakapo │ │ │ └── dataSpoonDrift │ │ │ ├── DataProcessor.class │ │ │ ├── dataModel │ │ │ └── TrackingData.class │ │ │ └── storm │ │ │ ├── DataKafkaSpout.class │ │ │ ├── DataNormalizerBlot.class │ │ │ └── DataStorageBlot.class │ │ ├── dataSpoonDrift-0.0.1-SNAPSHOT-jar-with-dependencies.jar │ │ ├── dataSpoonDrift-0.0.1-SNAPSHOT.jar │ │ ├── maven-archiver │ │ └── pom.properties │ │ ├── maven-status │ │ └── maven-compiler-plugin │ │ │ ├── compile │ │ │ └── default-compile │ │ │ │ ├── createdFiles.lst │ │ │ │ └── inputFiles.lst │ │ │ └── testCompile │ │ │ └── default-testCompile │ │ │ ├── createdFiles.lst │ │ │ └── inputFiles.lst │ │ ├── surefire-reports │ │ ├── TEST-com.kakapo.dataSpoonDrift.AppTest.xml │ │ └── com.kakapo.dataSpoonDrift.AppTest.txt │ │ └── test-classes │ │ └── com │ │ └── kakapo │ │ └── dataSpoonDrift │ │ └── AppTest.class │ ├── pom.xml │ ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── zlata │ │ │ └── kakapo │ │ │ └── App.java │ └── test │ │ └── java │ │ └── com │ │ └── zlata │ │ └── kakapo │ │ └── AppTest.java │ └── target │ ├── classes │ └── com │ │ └── zlata │ │ └── kakapo │ │ └── App.class │ └── test-classes │ └── com │ └── zlata │ └── kakapo │ └── AppTest.class ├── frontend ├── LICENSE ├── README.md ├── appveyor.yml ├── backers.md ├── build │ ├── build.js │ ├── dev-client.js │ ├── dev-server.js │ ├── server.js │ ├── utils.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── client │ ├── App.vue │ ├── app.js │ ├── assets │ │ ├── Honeywell_logo.png │ │ ├── kakapo.png │ │ ├── logo.png │ │ ├── logo@2x.png │ │ ├── top_logo.png │ │ └── truck.png │ ├── components │ │ └── layout │ │ │ ├── AppMain.vue │ │ │ ├── FooterBar.vue │ │ │ ├── Levelbar.vue │ │ │ ├── Navbar.vue │ │ │ ├── Sidebar.vue │ │ │ └── index.js │ ├── filters │ │ └── index.js │ ├── index.js │ ├── router │ │ ├── index.js │ │ └── menu.js │ ├── store │ │ ├── config.js │ │ └── index.js │ └── views │ │ ├── Home.vue │ │ ├── charts │ │ ├── CanvasGauges.vue │ │ ├── Chartist.vue │ │ ├── Chartjs.vue │ │ ├── Peity.vue │ │ ├── Plotly.vue │ │ └── index.vue │ │ ├── components │ │ ├── BMapComponent.vue │ │ ├── BackToTop.vue │ │ ├── Collapse.vue │ │ ├── Datepicker.vue │ │ ├── Default.vue │ │ ├── Emoji.vue │ │ ├── Lory.vue │ │ ├── Message.vue │ │ ├── Modal.vue │ │ ├── Notification.vue │ │ ├── ProgressBar.vue │ │ ├── ProgressTracker.vue │ │ ├── Quill.vue │ │ ├── Rating.vue │ │ ├── Slider.vue │ │ ├── Switch.vue │ │ ├── Tabs.vue │ │ ├── Tooltip.vue │ │ ├── index.vue │ │ └── modals │ │ │ ├── CardModal.vue │ │ │ ├── ImageModal.vue │ │ │ └── Modal.vue │ │ ├── dashboard │ │ └── index.vue │ │ ├── monitor │ │ └── index.vue │ │ ├── tables │ │ ├── Basic.vue │ │ └── Handsontable.vue │ │ └── ui │ │ ├── Buttons.vue │ │ ├── Form.vue │ │ ├── Icons.vue │ │ └── Typography.vue ├── config │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── doc │ ├── charts.md │ ├── components.md │ ├── dependencies.md │ └── development.md ├── electron.js ├── index.html ├── package.json └── screenshots │ └── app.png ├── kakapo_monitor.png └── kakapo_overview.png /README.md: -------------------------------------------------------------------------------- 1 | Please visit https://brucezlata.github.io/ 2 | 3 | Title: sensor数据的实时采集,传输和显示 4 | 5 | Author: Bruce Sun (zlata.bruce@qq.com) 6 | 7 | Date: Dec, 25, 2016 8 | 9 | ![webportal](/kakapo_overview.png) 10 | 11 | ![webportal](/kakapo_monitor.png) 12 | 13 | 原计划基于一些传感器数据,针对冷链行业,做一个可以追溯冷链运输车辆的解决方案,包括硬件和软件,及云服务系统。最后完成了一个原型系统,可以实时显示温度和湿度的数据,在百度地图上显示运输车辆的GPS轨迹。当然后续如果在货柜上加个开关门的传感器,然后接上一个摄像头,传输一些图像数据到PDA上,也是没有问题的。 14 | 15 | 这篇文章只是为了记录这个原型系统用到的技术,请大牛们看看我们的设计,是不是符合实时,高并发的要求,还请大家吐槽,指正。 16 | 17 | # 0. 环境搭建 18 | 19 | 这个原型用到的技术比较多,罗列一下有mosquitto,kafka,storm,redis等,还有nodejs,socketIO,前端开发webpack,vuejs等。 20 | 21 | 环境搭建遇到最困难的storm,当然还算比较顺利。遇到一些问题都是前人踩过的坑,一步一步都能找到解决的方法。另外我会在写一些文章总结总结。 22 | 23 | # 1. 架构 24 | 25 | 传感器数据采集依赖硬件平台的MQTT Publish,数据通过3G传输到mosquitto,mqtt broker。云端的kafka和storm配合做数据的传输和清洗。最后Redis存储一个月的数据,另外mongodb存储所有数据,当然关系数据库mysql可以存储结构化数据,例如车辆信息,配送任务等。 26 | 27 | ![架构图](/arch.png) 28 | 29 | 这个设计是否合理,能否扛住几千台设备发传感器数据,原型也没有测试。不过mqtt servre和云端的kafka,storm等均可以负载均衡,增加机器来获得性能提升。具体还是要深入下去考虑。有大牛不吝赐教。 30 | 31 | 软件系统搭建在Ubuntu 16.04 Desktop上面,后来移到微软Azure Ubuntu Server 16.04 32 | 33 | # 2. 硬件系统 34 | 35 | MTK的无线路由解决平台,MT7620A,MTK single SOC solution for smart phone, AR9331,3G/GPS: Quectel UC20,温度和湿度传感器是德州仪器 TI Sensor Tag。Sensor Tag是依靠BLE和MTK平台数据交互的。MTK平台安装了openwrt,完全是一个路由器。 36 | 37 | # 3. 云端软件服务 38 | 39 | ## MQTT(mosquitto) 40 | 41 | 原来的计划是使用HTTP RESTFul。云端完成RESTFul的API,提供给硬件来调用。在仔细研究Restful和mqtt后,觉得mqtt更适合。HTTP协议是短连接,消耗更多的资源,对于移动设备来说,电能始终是个缺陷,相反mqtt的TCP长连接能够节省一点电能。当然云端部署一个mosquitto,消息的传输大大方便。更多看 [这篇文章](http://stephendnicholas.com/posts/power-profiling-mqtt-vs-https)。 42 | - MQTT Publish 43 | 44 | 用Eclipse paho的C语言客户端,采集sensor的数据,然后send出来。自行脑补。 45 | 46 | - MQTT Subsrible 47 | 48 | 用paho的Java客户端,不打算贴长段的代码了。后面可以下载整个工程。 49 | 50 | ``` java 51 | private static final String TOPIC = "topic_cctt_mqtt"; 52 | 53 | MqttClient subClient; 54 | 55 | String broker = "tcp://localhost:1883"; 56 | 57 | String clientId = "cdata_sub"; 58 | 59 | MemoryPersistence persistence = new MemoryPersistence(); 60 | 61 | myKafkaDataPumbOut = new KafkaDataPumbOut(); 62 | 63 | subClient = new MqttClient(broker,clientId,persistence); 64 | 65 | subClient.connect(); 66 | 67 | subClient.subscribe(TOPIC); 68 | 69 | subClient.setCallback(this); 70 | ``` 71 | 72 | 原型刚开始还使用了Javascript的mqtt sub,获得硬件上传来的数据,然后调用百度地图的绘制功能,做了一个汽车轨迹的应用。具体的代码在“frontend/client/views/components/BMapComponent.vue”里面,startMQTTClient方法。 73 | 74 | 在实际使用中,web应用是直接使用mqtt sub获取数据,还是使用socketio从redis里面或者ajax http请求到其他db里面拿,优缺点是什么,此处也没有深究。 75 | 76 | 77 | ## kafka 78 | 79 | mqtt sub接受到数据后,直接把数据发送到kafka的queue中,交给kafka处理。 80 | 81 | ``` java 82 | public void messageArrived(String topic, MqttMessage message) throws Exception { 83 | 84 | myKafkaDataPumbOut.publish("topic_cctt_kafka", message.toString()); 85 | 86 | System.out.println("Publish to Kafka:" + message.toString()); 87 | 88 | } 89 | ``` 90 | 91 | ## storm 92 | 93 | storm直接使用KafkaSpout,从kafka的queue拿到对应的topic数据。这里做了两个blot,一个做数据的标准化,从字符串中分割出各个传感器的数据,第二是做存储,直接想前面的数据,JSON后存入Redis中。 94 | 95 | 96 | 97 | ``` java 98 | String zkConnString= "localhost:2181"; 99 | 100 | String topicName = "topic_cctt_kafka"; //this is kafka topic 101 | 102 | BrokerHosts hosts = new ZkHosts(zkConnString); 103 | 104 | SpoutConfig spoutConfig = new SpoutConfig(hosts, 105 | topicName, "" , "spout_bruce"); 106 | 107 | spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme()); 108 | 109 | spoutConfig.startOffsetTime = kafka.api.OffsetRequest.LatestTime(); 110 | 111 | TopologyBuilder builder = new TopologyBuilder(); 112 | 113 | DataKafkaSpout dataKafkaOut = new DataKafkaSpout(spoutConfig); 114 | 115 | builder.setSpout("data-kafka-spout", dataKafkaOut); 116 | 117 | builder.setBolt("data-normalizer-blot", new DataNormalizerBlot()) 118 | .shuffleGrouping("data-kafka-spout"); 119 | 120 | builder.setBolt("data-storage-blot", new DataStorageBlot()) 121 | .shuffleGrouping("data-normalizer-blot"); 122 | 123 | ``` 124 | 125 | ## Redis 126 | 127 | 如何存储数据也是思考了很久,对于关系数据库而言,很难达到目的,在纠结很久后,觉得redis的Sorted sets,基于评分(score)的有序列表比较适合存储这类数据。 128 | 129 | 这类数据的特点是和基于时间轴的数据集,查询的时候也是根据时间的范围来查询。我将timestamp转化成long类型,作为有序列表的score,每条数据java object to Json后存储。 130 | 131 | ``` java 132 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", 133 | 134 | Locale.ENGLISH); 135 | 136 | long score = format.parse(strTime).getTime(); 137 | 138 | jedis.zadd(redis_date_key, score,strDataObject); 139 | 140 | ``` 141 | 142 | ## Web protal 143 | 144 | - vuejs & vue admin 145 | 146 | 之前对jquery和bootstrap还算熟悉,前端这几年的巨大变化,有太多有意思的东西出现,vuejs就是其中之一。这次做原型,看看这个js的前端框架,优势不必多说。对于我个人而言,玩的还不是很溜。其中觉得,优秀的和它配合的css/UI框架很缺少。远远没有之前随便花个几美金买一个优秀的UI来的爽。vue admin是vuejs的一个免费的UI主题,我拿来读代码学习vuejs用的。 147 | 148 | 学习vuejs一个痛苦的地方,vue admin用到的一些语法,vuejs官方文档很难找到,也是困惑的,估计是我的前端基础比较差,看的比较少。 149 | 150 | - baidu echarts和map 151 | 152 | 不容质疑百度这两个应用,非常的厉害,echarts非常强大。有人已经写了echarts和map的veujs接口。在npm上面搜索即可。 153 | 154 | 不过百度地图目前还没有,我搜索了一片如何在vuejs中使用高德地图的文章,将百度地图加进去了。 155 | 156 | - gps运行轨迹的实现 157 | 158 | 首先轨迹实际上是在地图上根据轨迹点,绘制折线。类似与滴滴打车的车头,会在地图上转换方向,其实实现的原理就是根据目前的点和下一个要绘制的点的计算出方向向量,然后旋转地图over layer,也就是marker。 159 | 160 | 161 | 162 | ``` Javascript 163 | 164 | function setRotation (marker,curPos,targetPos){ 165 | 166 | var me = this; 167 | 168 | var deg = 0; 169 | 170 | //start! 171 | 172 | curPos = baiduMap.pointToPixel(curPos); 173 | 174 | targetPos = baiduMap.pointToPixel(targetPos); 175 | 176 | if(targetPos.x != curPos.x){ 177 | 178 | var tan = (targetPos.y - curPos.y)/(targetPos.x - curPos.x), 179 | 180 | atan = Math.atan(tan); 181 | 182 | deg = atan*360/(2*Math.PI); 183 | 184 | //degree correction; 185 | 186 | if(targetPos.x < curPos.x){ 187 | 188 | deg = -deg + 90 + 90; 189 | 190 | } else { 191 | 192 | deg = -deg; 193 | 194 | } 195 | 196 | marker.setRotation(-deg); 197 | 198 | 199 | 200 | }else { 201 | 202 | var disy = targetPos.y- curPos.y ; 203 | 204 | var bias = 0; 205 | 206 | if(disy > 0) 207 | 208 | bias=-1 209 | 210 | else 211 | 212 | bias = 1 213 | 214 | marker.setRotation(-bias * 90); 215 | 216 | } 217 | 218 | return; 219 | 220 | } 221 | 222 | ``` 223 | 224 | 225 | 226 | 227 | 228 | # 4. 后续的工作 229 | 230 | * 硬件集成 231 | 232 | * 数据安全和身份验证 233 | 234 | 原型没有考虑数据安全,没有任何身份验证。后续要考虑mqtt broker的身份验证,kafka和storm的auth方法。 235 | 236 | 237 | 238 | # 5. 开源链接 239 | 240 | https://coding.net/u/zlata/p/kakapo/git 241 | 242 | https://github.com/brucezlata/kakapo.git 243 | -------------------------------------------------------------------------------- /arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/arch.png -------------------------------------------------------------------------------- /backend/kakapo/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /backend/kakapo/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kakapo 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /backend/kakapo/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /backend/kakapo/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /backend/kakapo/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | dataPump 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.compliance=1.5 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.5 9 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.zlata 7 | kakapo 8 | 0.0.1-SNAPSHOT 9 | 10 | com.zlata.kakapo 11 | dataPump 12 | 0.0.1-SNAPSHOT 13 | dataPump 14 | http://maven.apache.org 15 | 16 | UTF-8 17 | 18 | 19 | 20 | org.eclipse.paho 21 | org.eclipse.paho.client.mqttv3 22 | 1.0.2 23 | 24 | 25 | org.slf4j 26 | slf4j-log4j12 27 | 1.7.21 28 | 29 | 30 | org.apache.kafka 31 | kafka-clients 32 | 0.10.0.0 33 | 34 | 35 | junit 36 | junit 37 | 3.8.1 38 | test 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/src/main/java/com/kakapo/dataPump/DataWaveProducer.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataPump; 2 | 3 | import com.kakapo.dataPump.mqttClient.*; 4 | 5 | public class DataWaveProducer { 6 | 7 | public static void main(String[] args) { 8 | // TODO Auto-generated method stub 9 | 10 | new MqttDataSubscribe().listen(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/src/main/java/com/kakapo/dataPump/kafkaCon/KafkaDataPumbOut.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataPump.kafkaCon; 2 | 3 | import java.util.*; 4 | import org.apache.kafka.clients.producer.*; 5 | 6 | public class KafkaDataPumbOut { 7 | 8 | public Producer kafkaSpoondriftOut = null; 9 | public KafkaDataPumbOut() 10 | { 11 | Properties props = new Properties(); 12 | props.put("bootstrap.servers", "localhost:9092"); 13 | props.put("acks", "all"); 14 | props.put("retries", 0); 15 | props.put("batch.size", 16384); 16 | props.put("linger.ms", 1); 17 | props.put("buffer.memory", 33554432); 18 | props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); 19 | props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); 20 | 21 | kafkaSpoondriftOut = new KafkaProducer(props); 22 | } 23 | public void publish(String topic, String content) 24 | { 25 | if(kafkaSpoondriftOut == null) 26 | { 27 | System.out.println("kafkaSpoondriftOut is NULL!"); 28 | return; 29 | } 30 | kafkaSpoondriftOut.send(new ProducerRecord(topic, content)); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/src/main/java/com/kakapo/dataPump/mqttClient/MqttDataSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataPump.mqttClient; 2 | 3 | import org.eclipse.paho.client.mqttv3.MqttClient; 4 | import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 5 | import org.eclipse.paho.client.mqttv3.MqttCallback; 6 | import org.eclipse.paho.client.mqttv3.MqttException; 7 | import org.eclipse.paho.client.mqttv3.MqttMessage; 8 | import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; 9 | 10 | import com.kakapo.dataPump.kafkaCon.*; 11 | 12 | public class MqttDataSubscribe implements MqttCallback { 13 | 14 | private static final String TOPIC = "topic_cctt_mqtt"; 15 | MqttClient subClient; 16 | String broker = "tcp://localhost:1883"; 17 | String clientId = "cdata_sub"; 18 | MemoryPersistence persistence = new MemoryPersistence(); 19 | 20 | KafkaDataPumbOut myKafkaDataPumbOut = null; 21 | 22 | public void listen() { 23 | try { 24 | 25 | myKafkaDataPumbOut = new KafkaDataPumbOut(); 26 | subClient = new MqttClient(broker,clientId,persistence); 27 | subClient.connect(); 28 | subClient.subscribe(TOPIC); 29 | subClient.setCallback(this); 30 | 31 | 32 | } catch (MqttException e) { 33 | e.printStackTrace(); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | public void close() 40 | { 41 | try{ 42 | subClient.disconnect(); 43 | } 44 | catch (MqttException e) { 45 | e.printStackTrace(); 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | public void connectionLost(Throwable t) { 52 | t.printStackTrace(); 53 | } 54 | 55 | public void deliveryComplete(IMqttDeliveryToken arg0) { 56 | 57 | } 58 | 59 | public void messageArrived(String topic, MqttMessage message) throws Exception { 60 | 61 | if(!message.toString().contains("debugmsg")){ 62 | System.out.println("Received Message from broker"); 63 | myKafkaDataPumbOut.publish("topic_cctt_kafka", message.toString()); 64 | System.out.println("Publish to Kafka:" + message.toString()); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=DEBUG, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -------------------------------------------------------------------------------- /backend/kakapo/dataPump/src/test/java/com/kakapo/dataPump/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataPump; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: bruce 3 | Build-Jdk: 1.8.0_91 4 | Created-By: Maven Integration for Eclipse 5 | 6 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/META-INF/maven/com.zlata.kakapo/dataPump/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Mon Dec 05 17:31:45 CST 2016 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.zlata.kakapo 5 | m2e.projectName=dataPump 6 | m2e.projectLocation=/home/bruce/jWorks/kakapo/dataPump 7 | artifactId=dataPump 8 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/META-INF/maven/com.zlata.kakapo/dataPump/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.zlata 7 | kakapo 8 | 0.0.1-SNAPSHOT 9 | 10 | com.zlata.kakapo 11 | dataPump 12 | 0.0.1-SNAPSHOT 13 | dataPump 14 | http://maven.apache.org 15 | 16 | UTF-8 17 | 18 | 19 | 20 | org.eclipse.paho 21 | org.eclipse.paho.client.mqttv3 22 | 1.0.2 23 | 24 | 25 | org.slf4j 26 | slf4j-log4j12 27 | 1.7.21 28 | 29 | 30 | org.apache.kafka 31 | kafka-clients 32 | 0.10.0.0 33 | 34 | 35 | junit 36 | junit 37 | 3.8.1 38 | test 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/DataWaveProducer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/DataWaveProducer.class -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/kafkaCon/KafkaDataPumbOut.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/kafkaCon/KafkaDataPumbOut.class -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/mqttClient/MqttDataSubscribe.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataPump/target/classes/com/kakapo/dataPump/mqttClient/MqttDataSubscribe.class -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/classes/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=DEBUG, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n -------------------------------------------------------------------------------- /backend/kakapo/dataPump/target/test-classes/com/kakapo/dataPump/AppTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataPump/target/test-classes/com/kakapo/dataPump/AppTest.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | dataSpoonDrift 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.zlata 7 | kakapo 8 | 0.0.1-SNAPSHOT 9 | 10 | com.zlata.kakapo 11 | dataSpoonDrift 12 | 0.0.1-SNAPSHOT 13 | dataSpoonDrift 14 | http://maven.apache.org 15 | 16 | UTF-8 17 | 18 | 19 | 20 | org.apache.kafka 21 | kafka_2.11 22 | 0.10.0.1 23 | 24 | 25 | org.slf4j 26 | slf4j-log4j12 27 | 28 | 29 | log4j 30 | log4j 31 | 32 | 33 | 34 | 35 | 36 | org.apache.storm 37 | storm-core 38 | 1.0.2 39 | provided 40 | 41 | 42 | org.apache.storm 43 | storm-kafka 44 | 1.0.2 45 | 46 | 47 | redis.clients 48 | jedis 49 | 2.9.0 50 | jar 51 | compile 52 | 53 | 54 | com.google.code.gson 55 | gson 56 | 2.8.0 57 | 58 | 59 | junit 60 | junit 61 | 3.8.1 62 | test 63 | 64 | 65 | 66 | 67 | 68 | maven-assembly-plugin 69 | 70 | 71 | jar-with-dependencies 72 | 73 | 74 | 75 | com.kakapo.dataSpoonDrift.DataProcessor 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/DataProcessor.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift; 2 | 3 | import org.apache.storm.Config; 4 | import org.apache.storm.LocalCluster; 5 | import org.apache.storm.StormSubmitter; 6 | import org.apache.storm.generated.AlreadyAliveException; 7 | import org.apache.storm.generated.AuthorizationException; 8 | import org.apache.storm.generated.InvalidTopologyException; 9 | import org.apache.storm.kafka.BrokerHosts; 10 | import org.apache.storm.kafka.SpoutConfig; 11 | import org.apache.storm.kafka.StringScheme; 12 | import org.apache.storm.kafka.ZkHosts; 13 | import org.apache.storm.spout.SchemeAsMultiScheme; 14 | import org.apache.storm.topology.TopologyBuilder; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import com.kakapo.dataSpoonDrift.storm.*; 19 | 20 | 21 | /** 22 | * Hello world! 23 | * 24 | */ 25 | public class DataProcessor 26 | { 27 | private static final String TOPOLOGY_NAME = "data-spoondrift"; 28 | 29 | private static final Logger LOG = LoggerFactory.getLogger(DataProcessor.class); 30 | 31 | public static void main( String[] args ) throws InterruptedException, AlreadyAliveException, InvalidTopologyException, AuthorizationException 32 | { 33 | 34 | LOG.debug("Start DataProcessor Topology"); 35 | //System.out.println( "Hello World!" ); 36 | //config kafka spout 37 | // String zkConnString= "199.63.154.198:2181"; //this is zkeeper connection string 38 | String zkConnString= "localhost:2181"; 39 | String topicName = "topic_cctt_kafka"; //this is kafka topic 40 | 41 | BrokerHosts hosts = new ZkHosts(zkConnString); 42 | SpoutConfig spoutConfig = new SpoutConfig(hosts, topicName, "" , "spout_bruce"); 43 | spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme()); 44 | spoutConfig.startOffsetTime = kafka.api.OffsetRequest.LatestTime(); 45 | 46 | TopologyBuilder builder = new TopologyBuilder(); 47 | DataKafkaSpout dataKafkaOut = new DataKafkaSpout(spoutConfig); 48 | builder.setSpout("data-kafka-spout", dataKafkaOut); 49 | 50 | builder.setBolt("data-normalizer-blot", new DataNormalizerBlot()) 51 | .shuffleGrouping("data-kafka-spout"); 52 | 53 | builder.setBolt("data-storage-blot", new DataStorageBlot()) 54 | .shuffleGrouping("data-normalizer-blot"); 55 | 56 | Config conf = new Config(); 57 | //conf.setNumWorkers(2); 58 | if(args.length == 0){ 59 | LocalCluster cluster = new LocalCluster(); 60 | cluster.submitTopology(TOPOLOGY_NAME, conf,builder.createTopology()); 61 | Thread.sleep(3000*1000); 62 | cluster.killTopology(TOPOLOGY_NAME); 63 | cluster.shutdown(); 64 | }else{ 65 | StormSubmitter.submitTopology(args[0], conf, builder.createTopology()); 66 | } 67 | 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/dataModel/TrackingData.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift.dataModel; 2 | 3 | public class TrackingData { 4 | public String deviceSN = null; 5 | public String timestamp = null; 6 | public String latitude = null; 7 | public String longitude = null; 8 | public String temperature = null; 9 | public String humidity = null; 10 | } 11 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataKafkaSpout.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift.storm; 2 | 3 | import org.apache.storm.kafka.KafkaSpout; 4 | import org.apache.storm.kafka.SpoutConfig; 5 | import org.apache.storm.topology.OutputFieldsDeclarer; 6 | import org.apache.storm.tuple.Fields; 7 | 8 | public class DataKafkaSpout extends KafkaSpout{ 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = 1L; 13 | public DataKafkaSpout(SpoutConfig spoutConf) { 14 | super(spoutConf); 15 | // TODO Auto-generated constructor stub 16 | } 17 | public void declareOutputFields(OutputFieldsDeclarer declarer) { 18 | declarer.declare(new Fields("datawave")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataNormalizerBlot.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift.storm; 2 | 3 | import java.text.DateFormat; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.ArrayList; 7 | import java.util.Date; 8 | import java.util.List; 9 | import java.util.Locale; 10 | import java.util.Map; 11 | 12 | import org.apache.storm.task.OutputCollector; 13 | import org.apache.storm.task.TopologyContext; 14 | import org.apache.storm.topology.IRichBolt; 15 | import org.apache.storm.topology.OutputFieldsDeclarer; 16 | import org.apache.storm.tuple.Fields; 17 | import org.apache.storm.tuple.Tuple; 18 | import org.apache.storm.tuple.Values; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | import com.kakapo.dataSpoonDrift.dataModel.TrackingData; 23 | 24 | import com.google.gson.Gson; 25 | 26 | public class DataNormalizerBlot implements IRichBolt{ 27 | /** 28 | * 29 | */ 30 | private static final long serialVersionUID = 1L; 31 | private OutputCollector collector; 32 | private static final Logger LOG = LoggerFactory.getLogger(DataNormalizerBlot.class); 33 | public void cleanup(){ 34 | } 35 | public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { 36 | this.collector=collector; 37 | } 38 | public void execute(Tuple input){ 39 | 40 | //System.out.println("Data from Kafka:" + input.toString()); 41 | String rawData = input.getStringByField("datawave"); 42 | System.out.println("burce Recived:" + rawData); 43 | LOG.debug("From Kafka Spout Recived:" + rawData); 44 | String[] trackDataArray = rawData.split(","); 45 | 46 | TrackingData tDataObj = new TrackingData(); 47 | 48 | for(String trackData : trackDataArray){ 49 | trackData = trackData.trim(); 50 | if(!trackData.isEmpty()){ 51 | //here get key:value 52 | String[] pairs = trackData.split(":"); 53 | if(pairs.length == 2){ 54 | String key = pairs[0].trim(); 55 | String value = pairs[1].trim(); 56 | if(key.equals("sn")){ 57 | tDataObj.deviceSN = value; 58 | }else if(key.equals("dt")){ 59 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.ENGLISH); 60 | try { 61 | Date newdate= format.parse(value); 62 | //2011-10-05T14:48:00.000Z 63 | format.applyPattern("yyyy-MM-dd'T'HH:mm:ss"); 64 | tDataObj.timestamp = format.format(newdate); 65 | 66 | } catch (ParseException e) { 67 | // TODO Auto-generated catch block 68 | e.printStackTrace(); 69 | } 70 | }else if(key.equals("la")){ 71 | tDataObj.latitude = value; 72 | }else if(key.equals("lg")){ 73 | tDataObj.longitude = value; 74 | }else if(key.equals("t")){ 75 | tDataObj.temperature = value; 76 | }else if(key.equals("h")){ 77 | tDataObj.humidity = value; 78 | }else{ 79 | //nothing 80 | } 81 | } 82 | } 83 | } 84 | 85 | //convert data to json 86 | Gson gson = new Gson(); 87 | String json = gson.toJson(tDataObj); 88 | //emit json string and teimstamp 89 | // System.out.println("***---*** json:" + json); 90 | // System.out.println("***---*** timestamp:" + tDataObj.timestamp); 91 | this.collector.emit(new Values(json,tDataObj.timestamp)); 92 | 93 | //answer the tuple 94 | collector.ack(input); 95 | } 96 | /** 97 | * blot publish fields 98 | */ 99 | public void declareOutputFields(OutputFieldsDeclarer declarer) { 100 | declarer.declare(new Fields("trackjsondata","timestamp")); 101 | } 102 | public Map getComponentConfiguration() { 103 | // TODO Auto-generated method stub 104 | return null; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataStorageBlot.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift.storm; 2 | import java.text.DateFormat; 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Locale; 6 | import java.util.Map; 7 | 8 | import org.apache.storm.task.OutputCollector; 9 | import org.apache.storm.task.TopologyContext; 10 | import org.apache.storm.topology.IRichBolt; 11 | import org.apache.storm.topology.OutputFieldsDeclarer; 12 | import org.apache.storm.tuple.Tuple; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import redis.clients.jedis.Jedis; 17 | import redis.clients.jedis.JedisPool; 18 | import redis.clients.jedis.JedisPoolConfig; 19 | 20 | public class DataStorageBlot implements IRichBolt{ 21 | 22 | private static final long serialVersionUID = 1L; 23 | private static final int redisPort = 6379; 24 | private static final String redisURL = "localhost"; 25 | private static final String redis_date_key = "track_store"; 26 | private static final Logger LOG = LoggerFactory.getLogger(DataStorageBlot.class); 27 | private OutputCollector collector; 28 | 29 | private JedisPool pool = null; 30 | public void cleanup(){ 31 | if(pool != null) 32 | pool.destroy(); 33 | } 34 | 35 | /** 36 | * 为每个单词计数 37 | */ 38 | 39 | public void execute(Tuple input) { 40 | String strMember = input.getStringByField("trackjsondata"); 41 | String strTime = input.getStringByField("timestamp"); 42 | Jedis jedis = null; 43 | try { 44 | jedis = pool.getResource(); 45 | if (jedis != null){ 46 | //get score using timestamp 47 | // System.out.println("***---*** strMember:" + strMember); 48 | // System.out.println("***---*** strTime:" + strTime); 49 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); 50 | long score = format.parse(strTime).getTime(); 51 | //add data to redis database 52 | 53 | jedis.zadd(redis_date_key, score,strMember); 54 | System.out.println("add date to redis:" + strMember); 55 | jedis.publish("trackchannel", strMember); 56 | LOG.debug("Publish data to" + " trackchannel:" + strMember); 57 | } 58 | } catch (ParseException e) { 59 | // TODO Auto-generated catch block 60 | //e.printStackTrace(); 61 | System.out.println("***---***" + "ParseException"); 62 | } finally { 63 | if (jedis != null) { 64 | jedis.close(); 65 | } 66 | } 67 | collector.ack(input); 68 | } 69 | 70 | public void prepare(Map stormConf, TopologyContext context, OutputCollector collector){ 71 | this.collector = collector; 72 | pool = new JedisPool(new JedisPoolConfig(), redisURL,redisPort); 73 | LOG.debug("Create Jedis Connection."); 74 | } 75 | 76 | public void declareOutputFields(OutputFieldsDeclarer declarer) {} 77 | 78 | public Map getComponentConfiguration() { 79 | // TODO Auto-generated method stub 80 | return null; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/src/test/java/com/kakapo/dataSpoonDrift/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.kakapo.dataSpoonDrift; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: bruce 3 | Build-Jdk: 1.8.0_91 4 | Created-By: Maven Integration for Eclipse 5 | 6 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/META-INF/maven/com.zlata.kakapo/dataSpoonDrift/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Mon Dec 05 17:31:48 CST 2016 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.zlata.kakapo 5 | m2e.projectName=dataSpoonDrift 6 | m2e.projectLocation=/home/bruce/jWorks/kakapo/dataSpoonDrift 7 | artifactId=dataSpoonDrift 8 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/META-INF/maven/com.zlata.kakapo/dataSpoonDrift/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.zlata 7 | kakapo 8 | 0.0.1-SNAPSHOT 9 | 10 | com.zlata.kakapo 11 | dataSpoonDrift 12 | 0.0.1-SNAPSHOT 13 | dataSpoonDrift 14 | http://maven.apache.org 15 | 16 | UTF-8 17 | 18 | 19 | 20 | org.apache.kafka 21 | kafka_2.11 22 | 0.10.0.1 23 | 24 | 25 | org.slf4j 26 | slf4j-log4j12 27 | 28 | 29 | log4j 30 | log4j 31 | 32 | 33 | 34 | 35 | 36 | org.apache.storm 37 | storm-core 38 | 1.0.2 39 | provided 40 | 41 | 42 | org.apache.storm 43 | storm-kafka 44 | 1.0.2 45 | 46 | 47 | redis.clients 48 | jedis 49 | 2.9.0 50 | jar 51 | compile 52 | 53 | 54 | com.google.code.gson 55 | gson 56 | 2.8.0 57 | 58 | 59 | junit 60 | junit 61 | 3.8.1 62 | test 63 | 64 | 65 | 66 | 67 | 68 | maven-assembly-plugin 69 | 70 | 71 | jar-with-dependencies 72 | 73 | 74 | 75 | com.kakapo.dataSpoonDrift.DataProcessor 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/DataProcessor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/DataProcessor.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/dataModel/TrackingData.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/dataModel/TrackingData.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataKafkaSpout.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataKafkaSpout.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataNormalizerBlot.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataNormalizerBlot.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataStorageBlot.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/classes/com/kakapo/dataSpoonDrift/storm/DataStorageBlot.class -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/dataSpoonDrift-0.0.1-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/dataSpoonDrift-0.0.1-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/dataSpoonDrift-0.0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/dataSpoonDrift-0.0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven 2 | #Wed Nov 23 16:10:41 CST 2016 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.zlata.kakapo 5 | artifactId=dataSpoonDrift 6 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/dataModel/TrackingData.java 2 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataKafkaSpout.java 3 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataNormalizerBlot.java 4 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/storm/DataStorageBlot.java 5 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/main/java/com/kakapo/dataSpoonDrift/DataProcessor.java 6 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /home/bruce/jWorks/kakapo/dataSpoonDrift/src/test/java/com/kakapo/dataSpoonDrift/AppTest.java 2 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/surefire-reports/TEST-com.kakapo.dataSpoonDrift.AppTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 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 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/surefire-reports/com.kakapo.dataSpoonDrift.AppTest.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.kakapo.dataSpoonDrift.AppTest 3 | ------------------------------------------------------------------------------- 4 | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec - in com.kakapo.dataSpoonDrift.AppTest 5 | -------------------------------------------------------------------------------- /backend/kakapo/dataSpoonDrift/target/test-classes/com/kakapo/dataSpoonDrift/AppTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/dataSpoonDrift/target/test-classes/com/kakapo/dataSpoonDrift/AppTest.class -------------------------------------------------------------------------------- /backend/kakapo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.zlata 6 | kakapo 7 | 0.0.1-SNAPSHOT 8 | pom 9 | 10 | kakapo 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | dataPump 27 | dataSpoonDrift 28 | 29 | -------------------------------------------------------------------------------- /backend/kakapo/src/main/java/com/zlata/kakapo/App.java: -------------------------------------------------------------------------------- 1 | package com.zlata.kakapo; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | */ 7 | public class App 8 | { 9 | public static void main( String[] args ) 10 | { 11 | System.out.println( "Hello World!" ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /backend/kakapo/src/test/java/com/zlata/kakapo/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.zlata.kakapo; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/kakapo/target/classes/com/zlata/kakapo/App.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/target/classes/com/zlata/kakapo/App.class -------------------------------------------------------------------------------- /backend/kakapo/target/test-classes/com/zlata/kakapo/AppTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/backend/kakapo/target/test-classes/com/zlata/kakapo/AppTest.class -------------------------------------------------------------------------------- /frontend/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Fangdun Cai (fundon.me) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 |

Vue Admin

5 | 6 |

7 | Vue Admin Panel Framework, 8 | Live Demo 9 |

10 | 11 |

12 | Made with ❤︎ by 13 | Fangdun Cai and 14 | contributors 15 | 16 |

17 | 18 |

19 | NPM version 20 | MIT License 21 | Linux Build 22 | Window Build 23 | Gitter 24 |

25 | 26 |
27 | 28 | ![](screenshots/app.png) 29 | 30 | 31 | ## Features 32 | 33 | * Powered by [Vue][] **2.0** & [Bulma][] **0.2** 34 | * Responsive and Flexible Box Layout 35 | * [Variety of Charts](doc/charts.md) 36 | * [Rich Components](doc/components.md) or See [vue-bulma][] 37 | * Based on the awesome third-party [libraries](doc/dependencies.md) 38 | 39 | 40 | ## [Backers](backers.md) 41 | 42 | Its ongoing development is made possible thanks to the support by these awesome backers. If you'd like to join them, check out [Vue Admin & Vue Bulma](https://www.patreon.com/_fundon)'s Patreon campaign. 43 | 44 | 45 | ## [Development](doc/development.md) 46 | 47 | 48 | ### Requirements 49 | 50 | * NPM v3 51 | 52 | * Webpack v2 53 | 54 | 55 | ## Notes 56 | 57 | If you want to use Vue Admin with Vue 1.0 version, please checkout the [vue-v1](https://github.com/fundon/vue-admin/tree/vue-v1) branch. 58 | 59 | 60 | --- 61 | 62 | > [fundon.me](https://fundon.me)  ·  63 | > GitHub [@fundon](https://github.com/fundon)  ·  64 | > Twitter [@_fundon](https://twitter.com/_fundon) 65 | 66 | 67 | [Live Demo]: https://vue-admin.fundon.me/ 68 | [Fangdun Cai]: https://twitter.com/_fundon 69 | [Vue]: http://vuejs.org 70 | [Bulma]: http://bulma.io 71 | [Vue-bulma]: https://github.com/vue-bulma 72 | -------------------------------------------------------------------------------- /frontend/appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: '4' 4 | - nodejs_version: '5' 5 | - nodejs_version: '6' 6 | 7 | install: 8 | - ps: Install-Product node $env:nodejs_version 9 | - npm install npm@latest -g 10 | - npm install 11 | 12 | test_script: 13 | - node --version 14 | - npm --version 15 | - npm run build 16 | 17 | build: off 18 | 19 | version: "{build}" 20 | -------------------------------------------------------------------------------- /frontend/backers.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/backers.md -------------------------------------------------------------------------------- /frontend/build/build.js: -------------------------------------------------------------------------------- 1 | // https://github.com/shelljs/shelljs 2 | 'use strict' 3 | 4 | require('shelljs/global') 5 | env.NODE_ENV = 'production' 6 | 7 | const path = require('path') 8 | const config = require('../config') 9 | const ora = require('ora') 10 | const webpack = require('webpack') 11 | const webpackConfig = require('./webpack.prod.conf') 12 | 13 | const spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | const assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) 17 | rm('-rf', assetsPath) 18 | mkdir('-p', assetsPath) 19 | cp('-R', 'assets/', assetsPath) 20 | 21 | const compiler = webpack(webpackConfig) 22 | const ProgressPlugin = require('webpack/lib/ProgressPlugin') 23 | compiler.apply(new ProgressPlugin()) 24 | 25 | compiler.run((err, stats) => { 26 | spinner.stop() 27 | if (err) throw err 28 | process.stdout.write(stats.toString({ 29 | colors: true, 30 | modules: false, 31 | children: false, 32 | chunks: false, 33 | chunkModules: false 34 | }) + '\n') 35 | }) 36 | -------------------------------------------------------------------------------- /frontend/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe((event) => { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /frontend/build/dev-server.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var express = require('express') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var proxyMiddleware = require('http-proxy-middleware') 6 | var webpackConfig = process.env.NODE_ENV === 'testing' 7 | ? require('./webpack.prod.conf') 8 | : require('./webpack.dev.conf') 9 | 10 | // default port where dev server listens for incoming traffic 11 | var port = process.env.PORT || config.dev.port 12 | // Define HTTP proxies to your custom API backend 13 | // https://github.com/chimurai/http-proxy-middleware 14 | var proxyTable = config.dev.proxyTable 15 | 16 | var app = express() 17 | var compiler = webpack(webpackConfig) 18 | 19 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 20 | publicPath: webpackConfig.output.publicPath, 21 | stats: { 22 | colors: true, 23 | chunks: false 24 | } 25 | }) 26 | 27 | var hotMiddleware = require('webpack-hot-middleware')(compiler) 28 | // force page reload when html-webpack-plugin template changes 29 | compiler.plugin('compilation', function (compilation) { 30 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 31 | hotMiddleware.publish({ action: 'reload' }) 32 | cb() 33 | }) 34 | }) 35 | 36 | // proxy api requests 37 | Object.keys(proxyTable).forEach(function (context) { 38 | var options = proxyTable[context] 39 | if (typeof options === 'string') { 40 | options = { target: options } 41 | } 42 | app.use(proxyMiddleware(context, options)) 43 | }) 44 | 45 | // handle fallback for HTML5 history API 46 | app.use(require('connect-history-api-fallback')()) 47 | 48 | // serve webpack bundle output 49 | app.use(devMiddleware) 50 | 51 | // enable hot-reload and state-preserving 52 | // compilation error display 53 | app.use(hotMiddleware) 54 | 55 | // serve pure static assets 56 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 57 | app.use(staticPath, express.static('./assets')) 58 | 59 | module.exports = app.listen(port, function (err) { 60 | if (err) { 61 | console.log(err) 62 | return 63 | } 64 | console.log('Listening at http://localhost:' + port + '\n') 65 | }) 66 | 67 | var app1 = require('express')(); 68 | var server = require('http').Server(app1); 69 | var io = require('socket.io')(server); 70 | 71 | server.listen(3000); 72 | // const socket = io.listen(server); 73 | var redis = require("redis"); 74 | io.on('connection', function (socket) { 75 | const subscribe = redis.createClient("redis://199.63.154.198:6379"); 76 | var initDataObj = []; 77 | 78 | subscribe.zrange('track_store',0,-1,function(err,results){ 79 | 80 | // console.log("initgps30 - results:" + results.length); 81 | initDataObj = results; 82 | }); 83 | 84 | // socket.emit('news', { hello: 'world' }); 85 | socket.on('initgps30', function (data) { 86 | var parser = require('json-parser'); 87 | for(var i=0 ;i 2 |
3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 50 | 51 | 88 | -------------------------------------------------------------------------------- /frontend/client/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Resource from 'vue-resource' 3 | import NProgress from 'vue-nprogress' 4 | import { sync } from 'vuex-router-sync' 5 | import App from './App.vue' 6 | import router from './router' 7 | import store from './store' 8 | import * as filters from './filters' 9 | 10 | Vue.use(Resource) 11 | Vue.use(NProgress) 12 | 13 | sync(store, router) 14 | 15 | const nprogress = new NProgress({ parent: '.nprogress-container' }) 16 | 17 | const { state } = store 18 | const { config } = state 19 | 20 | router.beforeEach((route, redirect, next) => { 21 | if (config.mobile && config.sidebar) { 22 | config.sidebar = false 23 | } 24 | next() 25 | }) 26 | 27 | Object.keys(filters).forEach(key => { 28 | Vue.filter(key, filters[key]) 29 | }) 30 | 31 | const app = new Vue({ 32 | router, 33 | store, 34 | nprogress, 35 | ...App 36 | }) 37 | 38 | export { app, router, store } 39 | -------------------------------------------------------------------------------- /frontend/client/assets/Honeywell_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/Honeywell_logo.png -------------------------------------------------------------------------------- /frontend/client/assets/kakapo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/kakapo.png -------------------------------------------------------------------------------- /frontend/client/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/logo.png -------------------------------------------------------------------------------- /frontend/client/assets/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/logo@2x.png -------------------------------------------------------------------------------- /frontend/client/assets/top_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/top_logo.png -------------------------------------------------------------------------------- /frontend/client/assets/truck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/assets/truck.png -------------------------------------------------------------------------------- /frontend/client/components/layout/AppMain.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 45 | -------------------------------------------------------------------------------- /frontend/client/components/layout/FooterBar.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 37 | -------------------------------------------------------------------------------- /frontend/client/components/layout/Levelbar.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 59 | -------------------------------------------------------------------------------- /frontend/client/components/layout/Navbar.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 57 | 58 | 92 | -------------------------------------------------------------------------------- /frontend/client/components/layout/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 125 | 126 | 179 | -------------------------------------------------------------------------------- /frontend/client/components/layout/index.js: -------------------------------------------------------------------------------- 1 | export Navbar from './Navbar' 2 | 3 | export Sidebar from './Sidebar' 4 | 5 | export AppMain from './AppMain' 6 | 7 | export FooterBar from './FooterBar' 8 | -------------------------------------------------------------------------------- /frontend/client/filters/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/client/filters/index.js -------------------------------------------------------------------------------- /frontend/client/index.js: -------------------------------------------------------------------------------- 1 | import { app } from './app' 2 | 3 | app.$mount('#app') 4 | -------------------------------------------------------------------------------- /frontend/client/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | import menu from './menu' 5 | 6 | Vue.use(Router) 7 | 8 | export default new Router({ 9 | mode: 'hash', // Demo is living in GitHub.io, so required! 10 | linkActiveClass: 'is-active', 11 | scrollBehavior: () => ({ y: 0 }), 12 | routes: [ 13 | { 14 | name: 'Home', 15 | path: '/', 16 | component: require('../views/Home') 17 | }, 18 | ...generateRoutesFromMenu(menu), 19 | { 20 | path: '*', 21 | redirect: '/' 22 | } 23 | ] 24 | }) 25 | 26 | // Menu should have 2 levels. 27 | function generateRoutesFromMenu (menu = [], routes = []) { 28 | for (let i = 0, l = menu.length; i < l; i++) { 29 | let item = menu[i] 30 | if (item.path) { 31 | routes.push(item) 32 | } 33 | if (!item.component) { 34 | generateRoutesFromMenu(item.children, routes) 35 | } 36 | } 37 | return routes 38 | } 39 | -------------------------------------------------------------------------------- /frontend/client/store/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | mobile: false, 3 | sidebar: true 4 | } 5 | -------------------------------------------------------------------------------- /frontend/client/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import pkg from 'package' 5 | import config from './config' 6 | import menu from '../router/menu' 7 | 8 | Vue.use(Vuex) 9 | 10 | const state = { 11 | pkg, 12 | config, 13 | menu, 14 | count: 0 15 | } 16 | 17 | const mutations = { 18 | INCREMENT (state) { 19 | state.count++ 20 | }, 21 | SIDEBAR (state, status = true) { 22 | state.config.sidebar = status 23 | } 24 | } 25 | 26 | const actions = { 27 | INCREMENT ({ commit }) { 28 | commit('INCREMENT') 29 | }, 30 | INCREMENT_ASYNC ({ commit }) { 31 | setTimeout(() => { 32 | commit('INCREMENT') 33 | }, 1000) 34 | }, 35 | 36 | // Sidebar: show, hide, toggle 37 | SHOW_SIDEBAR ({ commit }) { 38 | commit('SIDEBAR', true) 39 | }, 40 | HIDE_SIDEBAR ({ commit }) { 41 | commit('SIDEBAR', false) 42 | }, 43 | TOGGLE_SIDEBAR ({ commit, state }) { 44 | commit('SIDEBAR', !state.config.sidebar) 45 | } 46 | } 47 | 48 | const store = new Vuex.Store({ 49 | state, 50 | mutations, 51 | actions 52 | }) 53 | 54 | export default store 55 | -------------------------------------------------------------------------------- /frontend/client/views/Home.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 26 | 27 | 32 | -------------------------------------------------------------------------------- /frontend/client/views/charts/CanvasGauges.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 52 | 53 | 55 | -------------------------------------------------------------------------------- /frontend/client/views/charts/Chartist.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 182 | 183 | 188 | -------------------------------------------------------------------------------- /frontend/client/views/charts/Chartjs.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 154 | 155 | 157 | -------------------------------------------------------------------------------- /frontend/client/views/charts/Peity.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 99 | -------------------------------------------------------------------------------- /frontend/client/views/charts/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /frontend/client/views/components/BackToTop.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 58 | -------------------------------------------------------------------------------- /frontend/client/views/components/Collapse.vue: -------------------------------------------------------------------------------- 1 | 75 | 76 | 86 | 87 | 92 | -------------------------------------------------------------------------------- /frontend/client/views/components/Default.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 67 | -------------------------------------------------------------------------------- /frontend/client/views/components/Emoji.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 62 | 63 | 80 | -------------------------------------------------------------------------------- /frontend/client/views/components/Lory.vue: -------------------------------------------------------------------------------- 1 | 142 | 143 | 155 | 156 | 170 | -------------------------------------------------------------------------------- /frontend/client/views/components/Message.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 88 | 89 | 98 | -------------------------------------------------------------------------------- /frontend/client/views/components/Modal.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 83 | 84 | 86 | -------------------------------------------------------------------------------- /frontend/client/views/components/Notification.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 87 | 88 | 97 | -------------------------------------------------------------------------------- /frontend/client/views/components/ProgressBar.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 82 | 83 | 88 | -------------------------------------------------------------------------------- /frontend/client/views/components/ProgressTracker.vue: -------------------------------------------------------------------------------- 1 | 74 | 75 | 108 | 109 | 114 | -------------------------------------------------------------------------------- /frontend/client/views/components/Quill.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 33 | 34 | 37 | -------------------------------------------------------------------------------- /frontend/client/views/components/Rating.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 92 | 93 | 101 | -------------------------------------------------------------------------------- /frontend/client/views/components/Slider.vue: -------------------------------------------------------------------------------- 1 | 69 | 70 | 100 | 101 | 112 | -------------------------------------------------------------------------------- /frontend/client/views/components/Switch.vue: -------------------------------------------------------------------------------- 1 | 66 | 67 | 90 | 91 | 102 | -------------------------------------------------------------------------------- /frontend/client/views/components/Tabs.vue: -------------------------------------------------------------------------------- 1 | 123 | 124 | 174 | 175 | 183 | -------------------------------------------------------------------------------- /frontend/client/views/components/Tooltip.vue: -------------------------------------------------------------------------------- 1 | 151 | 152 | 161 | 162 | 175 | -------------------------------------------------------------------------------- /frontend/client/views/components/index.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /frontend/client/views/components/modals/CardModal.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 34 | -------------------------------------------------------------------------------- /frontend/client/views/components/modals/ImageModal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /frontend/client/views/components/modals/Modal.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 46 | -------------------------------------------------------------------------------- /frontend/client/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 107 | 108 | 153 | 154 | 156 | -------------------------------------------------------------------------------- /frontend/client/views/monitor/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 187 | 188 | 193 | -------------------------------------------------------------------------------- /frontend/client/views/tables/Handsontable.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 34 | -------------------------------------------------------------------------------- /frontend/client/views/ui/Buttons.vue: -------------------------------------------------------------------------------- 1 | 180 | 181 | 183 | 184 | 189 | -------------------------------------------------------------------------------- /frontend/client/views/ui/Icons.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 64 | -------------------------------------------------------------------------------- /frontend/client/views/ui/Typography.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 53 | -------------------------------------------------------------------------------- /frontend/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /frontend/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'assets', 10 | assetsPublicPath: '/', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'] 18 | }, 19 | dev: { 20 | env: require('./dev.env'), 21 | port: 8080, 22 | assetsSubDirectory: 'assets', 23 | assetsPublicPath: '/', 24 | proxyTable: {}, 25 | // CSS Sourcemaps off by default because relative paths are "buggy" 26 | // with this option, according to the CSS-Loader README 27 | // (https://github.com/webpack/css-loader#sourcemaps) 28 | // In our experience, they generally work as expected, 29 | // just be aware of this issue when enabling this option. 30 | cssSourceMap: false 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /frontend/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /frontend/config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /frontend/doc/charts.md: -------------------------------------------------------------------------------- 1 | # Charts 2 | 3 | * Chart 4 | 5 | * Chartist 6 | 7 | * Peity 8 | 9 | * Plotly 10 | 11 | * ... 12 | -------------------------------------------------------------------------------- /frontend/doc/components.md: -------------------------------------------------------------------------------- 1 | # Components 2 | 3 | [Vue Bulma UI Components](https://github.com/vue-bulma) 4 | 5 | | Component | Demo | Source | 6 | | --- | --- | --- | 7 | | BackToTop | http://vue-admin.fundon.me/#!/components/backtotop | https://github.com/vue-bulma/jump | 8 | | Breadcrumb | http://vue-admin.fundon.me/#!/components/breadcrumb | https://github.com/vue-bulma/breadcrumb | 9 | | Cleave | http://vue-admin.fundon.me/#!/ui/form | https://github.com/vue-bulma/cleave | 10 | | Collapse | http://vue-admin.fundon.me/#!/components/collapse | https://github.com/vue-bulma/collapse | 11 | | Datepicker | http://vue-admin.fundon.me/#!/components/datepicker | https://github.com/vue-bulma/datepicker | 12 | | Message | http://vue-admin.fundon.me/#!/components/message | https://github.com/vue-bulma/message | 13 | | Modal | http://vue-admin.fundon.me/#!/components/modal | https://github.com/vue-bulma/modal | 14 | | Notification | http://vue-admin.fundon.me/#!/components/notification | https://github.com/vue-bulma/notification | 15 | | ProgressBar | http://vue-admin.fundon.me/#!/components/progress | https://github.com/vue-bulma/progress-bar | 16 | | ProgressTracker | http://vue-admin.fundon.me/#!/components/progress | https://github.com/vue-bulma/progress-tracker | 17 | | Rating | http://vue-admin.fundon.me/#!/components/rating | https://github.com/vue-bulma/rating | 18 | | Slider | http://vue-admin.fundon.me/#!/components/slider | https://github.com/vue-bulma/slider | 19 | | Switch | http://vue-admin.fundon.me/#!/components/switch | https://github.com/vue-bulma/switch | 20 | | Tabs | http://vue-admin.fundon.me/#!/components/tabs | https://github.com/vue-bulma/tabs | 21 | | Tooltip | http://vue-admin.fundon.me/#!/components/tooltip | https://github.com/vue-bulma/tooltip | 22 | | ... | ... | 23 | -------------------------------------------------------------------------------- /frontend/doc/dependencies.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | 4 | ## System Components 5 | 6 | * [vue-resource][] 7 | * [vue-router][] 8 | * [vuex][] 9 | 10 | 11 | ## UI Components 12 | 13 | | Component | Library | 14 | | --- | --- | --- | 15 | | Animations & Transitions | [animate.css][] & [animejs][] | 16 | | BackToTop | [jump.js][] | 17 | | Cleave | [cleave.js][] | 18 | | Charts | [chart.js][], [chartist.js][], [peity][], [plotly.js][] | 19 | | Datepicker | [flatpickr][] | 20 | | Fonts | [font-awesome][], [Material Design icons][] | 21 | | Progress | [progress-tracker][] | 22 | | Rating | [Starability.css][] | 23 | | Tables | [Handsontable][] | 24 | | Tooltip | [hint.css][] | 25 | | ... | ... | 26 | 27 | 28 | ## Development Tools 29 | 30 | * [ESLint][] 31 | * [Babel][] 32 | * [Webpack][] 33 | * [vue-devtools][] 34 | 35 | 36 | [animate.css]: http://daneden.github.io/animate.css/ 37 | [animejs]: http://anime-js.com/ 38 | 39 | [vue-resource]: https://github.com/vuejs/vue-resource 40 | [vue-router]: https://github.com/vuejs/vue-router 41 | [vuex]: https://github.com/vuejs/vuex 42 | 43 | [jump.js]: http://callmecavs.com/jump.js/ 44 | 45 | [progress-tracker]: http://nigelotoole.github.io/progress-tracker/ 46 | 47 | [Starability.css]: http://lunarlogic.github.io/starability/ 48 | 49 | [hint.css]: http://kushagragour.in/lab/hint/ 50 | 51 | [flatpickr]: https://chmln.github.io/flatpickr/ 52 | 53 | [cleave.js]: http://nosir.github.io/cleave.js 54 | 55 | [chart.js]: http://www.chartjs.org 56 | [chartist.js]: https://gionkunz.github.io/chartist-js/index.html 57 | [peity]: https://github.com/benpickles/peity 58 | [plotly.js]: https://github.com/plotly/plotly.js 59 | 60 | [Handsontable]: https://handsontable.com 61 | 62 | [font-awesome]: http://fontawesome.io 63 | [Material Design icons]: http://google.github.io/material-design-icons/ 64 | 65 | [Babel]: http://babeljs.io/ 66 | [ESLint]: http://eslint.org 67 | [Webpack]: https://webpack.github.io 68 | [vue-devtools]: https://github.com/vuejs/vue-devtools 69 | -------------------------------------------------------------------------------- /frontend/doc/development.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | ## Build Setup 4 | 5 | ``` bash 6 | # install dependencies 7 | npm install 8 | 9 | # serve with hot reload at localhost:8080 10 | npm run dev 11 | 12 | # build for production with minification 13 | npm run build 14 | 15 | # run unit tests 16 | npm run unit 17 | 18 | # run e2e tests 19 | npm run e2e 20 | 21 | # run all tests 22 | npm test 23 | ``` 24 | 25 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 26 | -------------------------------------------------------------------------------- /frontend/electron.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const { app, BrowserWindow } = require('electron') 4 | 5 | // Keep a global reference of the window object, if you don't, the window will 6 | // be closed automatically when the JavaScript object is garbage collected. 7 | let mainWindow 8 | 9 | const isDev = process.env.NODE_ENV === 'development' 10 | 11 | function createWindow () { 12 | // Create the browser window. 13 | mainWindow = new BrowserWindow({ 14 | width: 800, 15 | height: 600 16 | }) 17 | 18 | // and load the index.html of the app. 19 | mainWindow.loadURL(`file://${__dirname}/dist/index.html`) 20 | 21 | // Open the DevTools. 22 | if (isDev) { 23 | mainWindow.webContents.openDevTools() 24 | 25 | const installExtension = require('electron-devtools-installer') 26 | installExtension.default(installExtension.VUEJS_DEVTOOLS) 27 | .then(name => console.log(`Added Extension: ${name}`)) 28 | .catch(err => console.log('An error occurred: ', err)) 29 | } 30 | 31 | // Emitted when the window is closed. 32 | mainWindow.on('closed', () => { 33 | // Dereference the window object, usually you would store windows 34 | // in an array if your app supports multi windows, this is the time 35 | // when you should delete the corresponding element. 36 | mainWindow = null 37 | }) 38 | } 39 | 40 | // This method will be called when Electron has finished 41 | // initialization and is ready to create browser windows. 42 | // Some APIs can only be used after this event occurs. 43 | app.on('ready', createWindow) 44 | 45 | // Quit when all windows are closed. 46 | app.on('window-all-closed', () => { 47 | // On OS X it is common for applications and their menu bar 48 | // to stay active until the user quits explicitly with Cmd + Q 49 | if (process.platform !== 'darwin') { 50 | app.quit() 51 | } 52 | }) 53 | 54 | app.on('activate', () => { 55 | // On OS X it's common to re-create a window in the app when the 56 | // dock icon is clicked and there are no other windows open. 57 | if (mainWindow === null) { 58 | createWindow() 59 | } 60 | }) 61 | 62 | // In this file you can include the rest of your app's specific main process 63 | // code. You can also put them in separate files and require them here. 64 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 48 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Kakapo", 3 | "version": "0.0.1", 4 | "description": "Kakapo is a Cold Chain Track&Trace Platform", 5 | "repository": "", 6 | "homepage": "", 7 | "license": "MIT", 8 | "author": { 9 | "name": "Bruce Sun", 10 | "email": "zlata.bruce@qq.com", 11 | "url": "kakapo.com" 12 | }, 13 | "keywords": [ 14 | "kakapo", 15 | "Gateway" 16 | ], 17 | "engines": { 18 | "node": ">=4", 19 | "npm": ">=3" 20 | }, 21 | "scripts": { 22 | "build": "cross-env NODE_ENV=production node build/build.js", 23 | "clean": "rm -rf dist", 24 | "dev": "cross-env NODE_ENV=development node build/dev-server.js", 25 | "electron": "cross-env NODE_ELECTRON=true npm run build && electron electron.js", 26 | "gh": "npm run build && gh-pages -d dist", 27 | "lint": "eslint --ext .js .vue client/*", 28 | "lint:fix": "eslint --fix --ext .js .vue electron.js client/* build/* config/*", 29 | "test": "echo lol" 30 | }, 31 | "dependencies": { 32 | "animate.css": "3.5.2", 33 | "animejs": "1.1.1", 34 | "bulma": "0.2.3", 35 | "font-awesome": "4.7.0", 36 | "hiredis": "^0.5.0", 37 | "json-parser": "^1.1.5", 38 | "mdi": "1.7.22", 39 | "paho-mqtt": "^1.0.3", 40 | "plotly": "1.0.6", 41 | "plotly.js": "1.18.1", 42 | "redis": "^2.6.3", 43 | "socket.io": "^1.6.0", 44 | "socket.io-client": "^1.6.0", 45 | "vue": "2.0.5", 46 | "vue-bulma-breadcrumb": "github:vue-bulma/breadcrumb", 47 | "vue-bulma-chartist": "github:vue-bulma/chartist", 48 | "vue-bulma-chartjs": "github:vue-bulma/chartjs", 49 | "vue-bulma-collapse": "1.0.3", 50 | "vue-bulma-datepicker": "github:vue-bulma/datepicker", 51 | "vue-bulma-emoji": "github:vue-bulma/emoji", 52 | "vue-bulma-expanding": "github:vue-bulma/expanding", 53 | "vue-bulma-jump": "github:vue-bulma/jump", 54 | "vue-bulma-message": "1.1.0", 55 | "vue-bulma-modal": "github:vue-bulma/modal", 56 | "vue-bulma-notification": "1.1.0", 57 | "vue-bulma-progress-bar": "github:vue-bulma/progress-bar", 58 | "vue-bulma-progress-tracker": "0.0.4", 59 | "vue-bulma-quill": "0.0.1", 60 | "vue-bulma-rating": "github:vue-bulma/rating", 61 | "vue-bulma-slider": "github:vue-bulma/slider", 62 | "vue-bulma-switch": "github:vue-bulma/switch", 63 | "vue-bulma-tabs": "github:vue-bulma/tabs", 64 | "vue-bulma-tooltip": "github:vue-bulma/tooltip", 65 | "vue-canvas-gauges": "github:vue-bulma/canvas-gauges", 66 | "vue-cleave": "1.1.0", 67 | "vue-handsontable": "github:vue-bulma/handsontable", 68 | "vue-lory": "0.0.4", 69 | "vue-nprogress": "0.1.2", 70 | "vue-peity": "0.4.0", 71 | "vue-resource": "1.0.3", 72 | "vue-router": "2.0.1", 73 | "vue2-echarts": "^1.0.1", 74 | "vuex": "2.0.0", 75 | "vuex-router-sync": "3.0.0", 76 | "wysiwyg.css": "0.0.2" 77 | }, 78 | "devDependencies": { 79 | "autoprefixer": "^6.5.1", 80 | "babel-core": "^6.17.0", 81 | "babel-eslint": "^7.0.0", 82 | "babel-loader": "^6.2.4", 83 | "babel-plugin-transform-export-extensions": "^6.8.0", 84 | "babel-preset-es2015": "^6.14.0", 85 | "babel-preset-stage-2": "^6.17.0", 86 | "connect-history-api-fallback": "^1.3.0", 87 | "cross-env": "^3.1.3", 88 | "css-loader": "^0.25.0", 89 | "electron": "^1.4.4", 90 | "electron-devtools-installer": "^2.0.1", 91 | "eslint": "^3.8.1", 92 | "eslint-config-standard": "^6.1.0", 93 | "eslint-loader": "^1.6.0", 94 | "eslint-plugin-html": "^1.5.5", 95 | "eslint-plugin-promise": "^3.0.0", 96 | "eslint-plugin-standard": "^2.0.1", 97 | "eventsource-polyfill": "^0.9.6", 98 | "express": "^4.14.0", 99 | "extract-text-webpack-plugin": "^2.0.0-beta.4", 100 | "file-loader": "^0.9.0", 101 | "html-webpack-plugin": "^2.24.0", 102 | "http-proxy-middleware": "^0.17.1", 103 | "imports-loader": "^0.6.5", 104 | "json-loader": "^0.5.4", 105 | "node-sass": "^3.10.0", 106 | "ora": "^0.3.0", 107 | "postcss-loader": "^1.0.0", 108 | "progress-bar-webpack-plugin": "^1.9.0", 109 | "sass-loader": "^4.0.2", 110 | "serve-favicon": "^2.3.0", 111 | "style-loader": "^0.13.1", 112 | "stylus": "^0.54.5", 113 | "stylus-loader": "^2.3.1", 114 | "url-loader": "^0.5.7", 115 | "vue-html-loader": "^1.2.3", 116 | "vue-loader": "^9.7.0", 117 | "vue-template-compiler": "^2.0.5", 118 | "webpack": "^2.1.0-beta.25", 119 | "webpack-dev-middleware": "^1.8.4", 120 | "webpack-hot-middleware": "^2.13.0", 121 | "webpack-merge": "^0.15.0" 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /frontend/screenshots/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/frontend/screenshots/app.png -------------------------------------------------------------------------------- /kakapo_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/kakapo_monitor.png -------------------------------------------------------------------------------- /kakapo_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brucezlata/kakapo/7bbbd5c0142a0df800b9cfe0a41f4b43dcb3c93c/kakapo_overview.png --------------------------------------------------------------------------------