Commit 4b6210dd authored by Administrator's avatar Administrator

历史记录采用influxdb

parent 707f3eb7
......@@ -49,3 +49,9 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MIX_BASE_API="${BASE_API}"
MIX_LARAVUE_PATH="${LARAVUE_PATH}"
INFLUX_USERNAME=admin
INFLUX_HOST=127.0.0.1
INFLUX_PASSWORD=null
INFLUX_PORT=8086
INFLUX_DB=zehongcloud
......@@ -8,6 +8,7 @@ use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
use App\Http\Controllers\DevicesController;
use Illuminate\Support\Facades\Config;
class SwooleCommandMeTcpController extends Controller
{
......@@ -25,6 +26,7 @@ class SwooleCommandMeTcpController extends Controller
Redis::set('sbjc:' . $datadevice[0], $data);
}
Redis::lpush('police',$data);
$this->saveInfluxDb($data);
$this->police();
}
$dalen = Redis::llen('Devicesdata');//返回队列长度
......@@ -138,4 +140,43 @@ class SwooleCommandMeTcpController extends Controller
->update(['devicepolice' => $davicedata[1], 'nd' => $davicedata[2]]);
}
}
}
\ No newline at end of file
/**
* 保存到时序数据库influxdb
* @param $data
* @throws \InfluxDB\Database\Exception
* @throws \InfluxDB\Exception
*/
private function saveInfluxDb($data)
{
$data_array = explode('/', $data);
$device_num = $data_array[0];
$device_status = $data_array[1];
$device_value = $data_array[2];
$influxDb = Config::get('database.influxdb');
$host = $influxDb['default']['host'];
$port = $influxDb['default']['port'];
$username = $influxDb['default']['username'];
$password = $influxDb['default']['password'];
$client = new \InfluxDB\Client($host, $port, $username, $password);
$database = $client->selectDB($influxDb['default']['database']);
$user_id = DB::table('device')->where('devicenum', $device_num)->value('uid');
if($user_id) {
$points = [
new \InfluxDB\Point(
'devices',
$device_value,
['device_num' => $device_num, 'device_status' => $device_status, 'user_id' => $user_id],
[],
time()
),
];
$database->writePoints($points, \InfluxDB\Database::PRECISION_SECONDS);
}
}
}
......@@ -11,6 +11,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
......@@ -353,8 +354,20 @@ class DevicesController extends Controller
//历史数据查询
public function detedevice(Request $request)
{
$dete = $request->input('dete');
$devicetime = $this->devicetime($dete);
$request = $request->input();
$time_start = $time_stop = false;
if(!is_null($request['timeRange'])) {
$time_start = strtotime($request['timeRange'][0]);
$time_stop = strtotime($request['timeRange'][1]);
}
$devicetime = $this->getDeviceData(
$time_start,
$time_stop,
$request['deviceNum'],
$request['deviceStatus'],
$request['pageSize'],
$request['currentPage']
);
if ($devicetime != 105) {
return $this->jsonSuccessData($devicetime);
} else {
......@@ -603,4 +616,70 @@ class DevicesController extends Controller
return 105;
}
}
/**
* 获取历史数据
* @param int $time_start
* @param int $time_stop
* @param string $device_num
* @param int $device_status
* @return array
* @throws \Exception
*/
private function getDeviceData($time_start = false, $time_stop = false, $device_num = '', $device_status = 0, $size=0, $page=0)
{
$influxDb = Config::get('database.influxdb');
$host = $influxDb['default']['host'];
$port = $influxDb['default']['port'];
$username = $influxDb['default']['username'];
$password = $influxDb['default']['password'];
$client = new \InfluxDB\Client($host, $port, $username, $password);
$database = $client->selectDB($influxDb['default']['database']);
$tdatabase = $client->selectDB($influxDb['default']['database']);
$builde = $database->getQueryBuilder();
$tbuilde = $tdatabase->getQueryBuilder();
$result = [];
if($time_start === false) {
$time_start = 0;
}
if($time_stop === false) {
$time_stop = time();
}
$time_start -= 8 * 3600;
$time_stop -= 8 * 3600;
$result = $builde->select('*')
->from('devices')
->setTimeRange($time_start, $time_stop);
$tresult = $tbuilde->select('*')
->from('devices')
->setTimeRange($time_start, $time_stop);
if(!empty($device_num)) {
$where = ["device_num='{$device_num}'"];
$result = $result->where($where);
$tresult = $tresult->where($where);
}
if($device_status != 0 && $device_status != null) {
$where = ["device_status='{$device_status}'"];
$result = $result->where($where);
$tresult = $tresult->where($where);
}
if($this->isadmin() != 1) {
$user_id = Auth::id();
$where = ["user_id='{$user_id}'"];
$result = $result->where($where);
$tresult = $tresult->where($where);
}
$total = $tresult->count('value')->getResultSet()->getPoints();
if(count($total) > 0) {
$result = $result->orderBy('time','DESC')
->limit($size)->offset(($page-1)*$size)
->getResultSet()->getPoints();
} else {
$result = [];
}
return ['list' => $result, 'total' => isset($total[0]) ? $total[0]['count'] : 0];
}
}
......@@ -22,6 +22,7 @@
"php": "^7.2",
"emadadly/laravel-uuid": "^1.3",
"fideloper/proxy": "^4.0",
"influxdb/influxdb-php": "^1.15",
"laravel/framework": "^7.0",
"laravel/passport": "^8.4",
"laravel/tinker": "^2.0",
......
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "2afb5db88798cc6ab2d4e8a7e00b3b73",
"content-hash": "3f4372197e40ba5bc91e08d835604a05",
"packages": [
{
"name": "aws/aws-sdk-php",
......@@ -831,6 +831,67 @@
],
"time": "2019-07-01T23:21:34+00:00"
},
{
"name": "influxdb/influxdb-php",
"version": "1.15.0",
"source": {
"type": "git",
"url": "https://github.com/influxdata/influxdb-php.git",
"reference": "bf3415f81962e1ab8c939bc1a08a85f500bead35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/bf3415f81962e1ab8c939bc1a08a85f500bead35",
"reference": "bf3415f81962e1ab8c939bc1a08a85f500bead35",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0",
"php": "^5.5 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"suggest": {
"ext-curl": "Curl extension, needed for Curl driver",
"stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP."
},
"type": "library",
"autoload": {
"psr-4": {
"InfluxDB\\": "src/InfluxDB"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gianluca Arbezzano",
"email": "gianarb92@gmail.com"
},
{
"name": "Daniel Martinez",
"email": "danimartcas@hotmail.com"
},
{
"name": "Stephen Hoogendijk",
"email": "stephen@tca0.nl"
}
],
"description": "InfluxDB client library for PHP",
"keywords": [
"client",
"influxdata",
"influxdb",
"influxdb class",
"influxdb client",
"influxdb library",
"time series"
],
"time": "2019-05-30T00:15:14+00:00"
},
{
"name": "laminas/laminas-diactoros",
"version": "2.2.3",
......
......@@ -156,4 +156,19 @@ return [
],
/**
* 时序数据库
*/
'influxdb' => [
'default' => [
'username' => env('INFLUX_USERNAME', 'admin'),
'host' => env('INFLUX_HOST', '127.0.0.1'),
'password' => env('INFLUX_PASSWORD', null),
'port' => env('INFLUX_PORT', 8086),
'database' => env('INFLUX_DB', 'influx_default'),
],
],
];
......@@ -78,10 +78,11 @@ export function equipment() {
});
}
export function detedevice(dete) {
export function detedevice(data) {
return request({
url: '/devices/detedevice?dete=' + dete,
method: 'get',
url: '/devices/detedevice',
method: 'post',
data,
});
}
......
<template>
<div class="app-container">
<div class="filter-container">
<el-date-picker v-model="value2" align="right" type="date" placeholder="选择日期" :picker-options="pickerOptions" value-format="yyyy-MM-dd" @change="dataSearch"></el-date-picker>
<el-form :inline="true" :model="formSearch" class="demo-form-inline">
<el-form-item label="设备编号">
<el-input v-model="formSearch.deviceNum" placeholder="输入完整设备编号"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-select
v-model="formSearch.deviceStatus"
style="margin-left: 20px;"
placeholder="请选择"
>
<el-option
v-for="item in optionStatus"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="时间">
<el-date-picker
v-model="formSearch.timeRange"
align="right"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
value-format="yyyy/MM/dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</div>
<el-pagination
:current-page="formSearch.currentPage"
:page-sizes="[20, 80, 150, 300]"
:page-size="formSearch.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="formSearch.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
<el-table :key="tableKey" :data="equipment" border fit highlight-current-rows>
<el-table-column label="设备编号" width="169">
<el-table-column label="设备编号" width="209">
<template slot-scope="scope">
<span @click="handleCopy(scope.row.devicenum,$event)">{{ scope.row.devicenum }}</span>
<span @click="handleCopy(scope.row.device_num,$event)">{{ scope.row.device_num }}</span>
</template>
</el-table-column>
<el-table-column label="设备名称" width="140">
<el-table-column label="用户ID" width="140">
<template slot-scope="scope">
<span>{{ scope.row.username }}</span>
<span>{{ scope.row.user_id }}</span>
</template>
</el-table-column>
<el-table-column label="设备备注" width="140">
<el-table-column label="" width="140">
<template slot-scope="scope">
<span>{{ scope.row.deviceremark }}</span>
<span>{{ scope.row.value }}</span>
</template>
</el-table-column>
<el-table-column label="设备联系人" width="140">
<el-table-column label="状态值" width="130">
<template slot-scope="scope">
<span>{{ scope.row.devicelinkman }}</span>
<span>{{ scope.row.device_status }}</span>
</template>
</el-table-column>
<el-table-column label="设备手机号" width="140">
<template slot-scope="scope">
<span @click="handleCopy(scope.row.devicephone,$event)">{{ scope.row.devicephone }}</span>
</template>
</el-table-column>
<el-table-column label="设备详情">
<template slot-scope="scope">
<span>{{ scope.row.deviceinfo }}</span>
</template>
</el-table-column>
<el-table-column label="设备分类" width="140">
<template slot-scope="scope">
<span>{{ scope.row.tname }}</span>
</template>
</el-table-column>
<el-table-column label="设备介质" width="130">
<template slot-scope="scope">
<span>{{ scope.row.gas }}</span>
</template>
</el-table-column>
<el-table-column label="设备单位" width="130">
<el-table-column label="设备状态" width="130">
<template slot-scope="scope">
<span>{{ scope.row.danwei }}</span>
<span>
<el-tag :type=" scope.row.device_status==1 ? 'success' : 'warning' " effect="dark">{{ scope.row.device_status==1 ? '正常' : '异常' }}</el-tag>
</span>
</template>
</el-table-column>
<el-table-column label="设备状态" width="130">
<el-table-column label="时间">
<template slot-scope="scope">
<span>{{ scope.row.status_name }}</span>
<span>{{ scope.row.time | parseTime('{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
</el-table>
......@@ -62,13 +88,73 @@
</template>
<script>
import { equipment, detedevice } from '@/api/device';
import { detedevice } from '@/api/device';
import clip from '@/utils/clipboard';
import BackToTop from '@/components/BackToTop';
export default {
components: { BackToTop },
data() {
return {
formSearch: {
deviceNum: '',
deviceStatus: 0,
timeRange: null,
pageSize: 20,
currentPage: 1,
total: 0,
},
optionStatus: [{
value: 0,
label: '全部',
}, {
value: 1,
label: '正常',
}, {
value: 2,
label: '错误',
}, {
value: 3,
label: '传感器故障',
}, {
value: 4,
label: '报警',
}, {
value: 5,
label: '低报',
}, {
value: 6,
label: '高报',
}, {
value: 7,
label: '通信故障',
}, {
value: 8,
label: '超量程',
}, {
value: 9,
label: '离线',
}, {
value: 10,
label: '电量低',
}, {
value: 11,
label: '主电故障',
}, {
value: 12,
label: '备电故障',
}, {
value: 13,
label: '无此节点',
}, {
value: 14,
label: '低电压',
}, {
value: 15,
label: '故障',
}, {
value: 16,
label: '报警联动',
}],
equipment: [],
timer: null,
tableKey: 0,
......@@ -78,25 +164,15 @@ export default {
return time.getTime() > Date.now();
},
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
},
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
},
}, {
text: '一周前',
text: '24小时内',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', [start, end]);
},
}],
},
],
},
myBackToTopStyle: {
right: '50px',
......@@ -110,40 +186,30 @@ export default {
};
},
created() {
this.equipmentlist(); // 列表
this.dataSearch();
},
methods: {
equipmentlist() {
equipment()
.then(response => {
if (response.code === 200) {
this.equipment = response.data;
this.timers();
} else if (response.code === 105) {
this.$message({
message: response.msg,
type: 'warning',
});
} else {
this.$notify({
title: '警告',
message: 'TCP链接失败',
type: 'warning',
});
}
})
.catch(err => {
console.log(err);
});
handleSizeChange(val) {
this.formSearch.pageSize = val;
this.dataSearch();
},
handleCurrentChange(val) {
this.formSearch.currentPage = val;
this.dataSearch();
},
handleCopy(text, event) {
clip(text, event);
},
onSubmit() {
this.formSearch.currentPage = 1;
this.dataSearch();
},
dataSearch() {
detedevice(this.value2)
detedevice(this.formSearch)
.then(response => {
if (response.code === 200) {
this.equipment = response.data;
this.equipment = response.data.list;
this.formSearch.total = response.data.total;
} else if (response.code === 105) {
this.$message({
message: response.msg,
......
......@@ -95,7 +95,7 @@ Route::group(['middleware'=>'auth:api'],function (){
Route::get('devices/deviceBasketList','DevicesController@deviceBasketList');//返回禁用设备和废纸篓设备
Route::get('devices/addClassify/{data}','DevicesController@addClassify');//添加分类
Route::get('devices/delteClassify/{id}','DevicesController@delteClassify');//删除分类
Route::get('devices/detedevice','DevicesController@detedevice');//查看历史数据
Route::post('devices/detedevice','DevicesController@detedevice');//查看历史数据
Route::get('devices/addUserDevice','DevicesController@addUserDevice');//返回正常用户
Route::get('devices/control','DevicesController@control');//返回消防监测
Route::get('devices/deviceLocation','DevicesController@deviceLocation');//返回设备安装位置
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment