You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1376 lines
77 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="#2196f3">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<title>首页</title>
<link rel="stylesheet" href="lib/framework7/css/framework7.bundle.min.css">
<link rel="stylesheet" href="css/framework7-icons.css">
<link rel="stylesheet" href="css/app.css">
<style>
form i {
color: deepskyblue;
}
</style>
</head>
<body>
<div id="app">
<f7-app :params="f7params">
<f7-statusbar></f7-statusbar>
<f7-view id="main-view" url="/home/" main class="safe-areas">
</f7-view>
</f7-app>
</div>
<!--login-->
<template id="page-login">
<f7-page>
<f7-navbar>
<f7-nav-title>登录2</f7-nav-title>
<f7-nav-right>
<f7-link external panel-open="right" icon-f7="add" v-on:click="FaceLogin(vm.Login.Host)"></f7-link>
</f7-nav-right>
</f7-navbar>
<form v-bind:action="'http://'+vm.Login.Host+'/UserCenter/Account/AppLogin'" v-on:submit.prevent="OnSubmit" class="login">
<div class="list no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">link</i>
</div>
<div class="item-inner">
<div class="item-title item-label">服务器</div>
<div class="item-input-wrap">
<input type="text" name="Host" v-model="vm.Login.Host" data-val="true" data-val-required="请输入服务器地址">
<span class="input-clear-button"></span>
</div>
<span class="field-validation-valid text-danger" data-valmsg-for="Host" data-valmsg-replace="true"></span>
</div>
</li>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">person</i>
</div>
<div class="item-inner">
<div class="item-title item-label">用户名</div>
<div class="item-input-wrap">
<input type="text" name="UserName" v-model="vm.Login.UserName" data-val="true" data-val-required="请输入用户名">
<span class="input-clear-button"></span>
</div>
<span class="field-validation-valid text-danger" data-valmsg-for="UserName" data-valmsg-replace="true"></span>
</div>
</li>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">lock</i>
</div>
<div class="item-inner">
<div class="item-title item-label">密码</div>
<div class="item-input-wrap">
<input type="password" name="Password" data-val="true" data-val-required="请输入密码">
<span class="input-clear-button"></span>
</div>
<span class="field-validation-valid text-danger" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
</li>
<li>
<div class="item-content">
<div class="item-inner">
<button type="submit" class="button button-large button-large button-raised button-fill color-blue submit">确定</button>
</div>
</div>
</li>
</ul>
</div>
</form>
</f7-page>
</template>
<!--home-->
<template id="page-home">
<f7-page :page-content="false">
<f7-navbar>
<f7-nav-title>{{vm.Home.Name}}</f7-nav-title>
</f7-navbar>
<f7-toolbar tabbar labels bottom>
<f7-link tab-link="#tab-message" icon-ios="f7:chat" icon-md="f7:chat" text="消息"></f7-link>
<f7-link tab-link="#tab-nodes" icon-ios="f7:data" icon-md="f7:data" text="智慧教室" tab-link-active></f7-link>
<f7-link tab-link="#tab-user" icon-ios="f7:person" icon-md="f7:person" text="我的"></f7-link>
</f7-toolbar>
<f7-tabs>
<!--message-->
<f7-tab id="tab-message" class="page-content">
<template v-for="message in vm.MessageList">
<template v-if="message&&message.Data.length">
<div class="block-title">{{message.DisplayName||message.Name}}</div>
<div class="list">
<ul v-if="message.Data.length">
<template v-for="p in message.Data">
<li v-if="p.Name!=='hidden'">
<div class="item-content">
<div class="item-media"><i class="f7-icons">info</i></div>
<div class="item-inner">
<div class="item-title">{{p.Name}}</div>
<div class="item-after">
<span class="badge color-blue">
{{p.Value}}
</span>
<span>&nbsp;</span>
<span class="badge color-blue" v-if="p.Unit">
{{p.Unit}}
</span>
<span>&nbsp;</span>
<span class="badge color-blue" v-if="p.Description">
{{p.Description}}
</span>
</div>
</div>
</div>
</li>
</template>
</ul>
</div>
</template>
</template>
</f7-tab>
<!--nodes-->
<f7-tab id="tab-nodes" class="page-content" tab-active>
<div class="list">
<ul>
<li v-for="node in vm.NodeList">
<a class="item-link" :href="'/node/'+node.Number+'/name/'+node.Name">
<div class="item-content">
<div class="item-media"><img :src="'images/'+node.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{node.Name}}</div>
<div class="item-after">{{node.Count}}</div>
</div>
</div>
</a>
</li>
</ul>
</div>
</f7-tab>
<!--user-->
<f7-tab id="tab-user" class="page-content">
<f7-list>
<f7-list-item title="用户名" :after="vm.Home.UserName"></f7-list-item>
<f7-list-item title="昵称" :after="vm.Home.NickName"></f7-list-item>
<f7-list-item link="/login/" title="注销"></f7-list-item>
</f7-list>
</f7-tab>
</f7-tabs>
</f7-page>
</template>
<!--node-->
<template id="page-node">
<f7-page>
<f7-navbar>
<f7-navbar v-if="vm.Node" :title="vm.Node.Name" back-link="Back"></f7-navbar>
</f7-navbar>
<template v-if="getDevices('光强检测器').length">
<div class="block-title">光强检测器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('光强检测器')">
<div class="list links-list">
<ul>
<li>
<a class="item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="getData(device,'光照度')" class="badge color-green">{{getData(device,'光照度')}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('粉尘检测器').length">
<div class="block-title">粉尘检测器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('粉尘检测器')">
<div class="list links-list">
<ul>
<li>
<a class="item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="getData(device,'温度')" class="badge color-green">{{getData(device,'温度')}}</span>
<span v-if="getData(device,'湿度')" class="badge color-green">{{getData(device,'湿度')}}</span>
<span v-if="getData(device,'PM1.0')" class="badge color-green">{{getData(device,'PM1.0')}}</span>
<span v-if="getData(device,'PM2.5')" class="badge color-green">{{getData(device,'PM2.5')}}</span>
<span v-if="getData(device,'PM10')" class="badge color-green">{{getData(device,'PM10')}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('温湿度传感器').length">
<div class="block-title">温湿度传感器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('温湿度传感器')">
<div class="list links-list">
<ul>
<li>
<a class="item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="getData(device,'温度')" class="badge color-green">{{getData(device,'温度')}}</span>
<span v-if="getData(device,'湿度')" class="badge color-green">{{getData(device,'湿度')}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('烟雾传感器').length">
<div class="block-title">烟雾传感器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('烟雾传感器')">
<div class="list links-list">
<ul>
<li>
<a class="item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="getData(device,'状态')" class="badge color-green">{{getData(device,'状态')}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('红外感应器').length">
<div class="block-title">红外感应器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('红外感应器')">
<div class="list links-list">
<ul>
<li>
<a class="item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="getData(device,'状态')" class="badge color-green">{{getData(device,'状态')}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('窗帘').length">
<div class="block-title">窗帘</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('窗帘')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after"><span class="badge color-green">{{getData(device,"状态")}}</span></div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Curtain/On')"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Curtain/Stop')"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Curtain/Off')"></a>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('插座').length">
<div class="block-title">插座</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('插座')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span v-if="device.Name=='智能插座'" class="badge color-green" v-if="getData(device,'电量')">{{getData(device,"电量")}}</span>
<span class="badge color-green">{{getData(device,"状态")}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Socket/On')" v-if="getData(device,'状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Socket/Off')" v-else></a>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('一路开关').length">
<div class="block-title">一路开关</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('一路开关')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span class="badge color-green">{{getData(device,"状态")}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch/On')" v-if="getData(device,'状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch/Off')" v-else></a>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('二路开关').length">
<div class="block-title">二路开关</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('二路开关')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span class="badge color-green">{{getData(device,"L1状态")}}</span>
<span class="badge color-green">{{getData(device,"L2状态")}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/On')">全开</a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/Off')">全关</a>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/L1On')" v-if="getData(device,'L1状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/L1Off')" v-else></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/L2On')" v-if="getData(device,'L2状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch2/L2Off')" v-else></a>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('三路开关').length">
<div class="block-title">三路开关</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('三路开关')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after">
<span class="badge color-green">{{getData(device,"L1状态")}}</span>
<span class="badge color-green">{{getData(device,"L2状态")}}</span>
<span class="badge color-green">{{getData(device,"L3状态")}}</span>
</div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/On')">全开</a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/Off')">全关</a>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L1On')" v-if="getData(device,'L1状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L1Off')" v-else></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L2On')" v-if="getData(device,'L2状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L2Off')" v-else></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L3On')" v-if="getData(device,'L3状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Switch3/L3Off')" v-else></a>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('调色灯').length">
<div class="block-title">调色灯</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('调色灯')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after"><span class="badge color-green">{{getData(device,"状态")}}</span></div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/ColorLight/On')" v-if="getData(device,'状态')==='关'"></a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/ColorLight/Off')" v-else></a>
</div>
<div class="row">
<form class="ajax" method="get" :action="'http://'+vm.Login.Host+'/IoTCenter/App/Exec'">
<input type="hidden" name="ConnectionId" :value="vm.ConnectionId" />
<input type="hidden" name="Gateway" :value="device.GatewayNumber" />
<input type="hidden" name="Number" :value="device.Number" />
<input type="hidden" name="Method" value="/ColorLight/SetBrightness" />
<div class="list inline-labels no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">info</i>
</div>
<div class="item-inner">
<div class="item-title item-label">亮度</div>
<div class="item-input-wrap">
<input class="ajax" type="range" min="0" step="1" max="255" name="Brightness" :value="getValue(device,'亮度')" />
</div>
</div>
</li>
</ul>
</div>
</form>
</div>
<div class="row">
<form class="ajax" method="get" :action="'http://'+vm.Login.Host+'/IoTCenter/App/Exec'">
<input type="hidden" name="ConnectionId" :value="vm.ConnectionId" />
<input type="hidden" name="Gateway" :value="device.GatewayNumber" />
<input type="hidden" name="Number" :value="device.Number" />
<input type="hidden" name="Method" value="/ColorLight/SetColor" />
<div class="list inline-labels no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">info</i>
</div>
<div class="item-inner">
<div class="item-title item-label">色调</div>
<div class="item-input-wrap">
<input class="ajax" type="range" min="0" step="1" max="255" name="Hue" :value="getValue(device,'色调')" />
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">info</i>
</div>
<div class="item-inner">
<div class="item-title item-label">饱和度</div>
<div class="item-input-wrap">
<input class="ajax" type="range" min="0" step="1" max="255" name="Saturation" :value="getValue(device,'饱和度')" />
</div>
</div>
</li>
</ul>
</div>
</form>
</div>
<div class="row">
<form class="ajax" method="get" :action="'http://'+vm.Login.Host+'/IoTCenter/App/Exec'">
<input type="hidden" name="ConnectionId" :value="vm.ConnectionId" />
<input type="hidden" name="Gateway" :value="device.GatewayNumber" />
<input type="hidden" name="Number" :value="device.Number" />
<input type="hidden" name="Method" value="/ColorLight/SetColorTemperature" />
<div class="list inline-labels no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="f7-icons">info</i>
</div>
<div class="item-inner">
<div class="item-title item-label">色温</div>
<div class="item-input-wrap">
<input class="ajax" type="range" min="2700" step="1" max="6500" name="ColorTemperature" :value="getValue(device,'色温')" />
</div>
</div>
</li>
</ul>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('红外转发器').length">
<div class="block-title">红外转发器</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('红外转发器')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after"></div>
</div>
</a>
</li>
</ul>
</div>
<div class="row">
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Ir/KeyCodeType1On')" v-if="getData(device,'空调')==='关'">启用空调</a>
<a class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.GatewayNumber,device.Number,'/Ir/KeyCodeType1Off')" v-else>禁用空调</a>
</div>
<div class="row" v-if="getData(device,'空调')==='开'">
<form class="device KeyCodeType1" method="get" :action="'http://'+vm.Login.Host+'/IoTCenter/App/Exec'">
<input type="hidden" name="ConnectionId" :value="vm.ConnectionId" />
<input type="hidden" name="Gateway" :value="device.GatewayNumber" />
<input type="hidden" name="Number" :value="device.Number" />
<input type="hidden" name="Method" value="/Ir/Send" />
<input type="hidden" name="Type" value="1" />
<input type="hidden" name="Code" :value="getValue(device,'按键')" />
<div class="row">
<div class="col-20">
<label>电源:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="power" type="radio" value="2" v-model="getCode1(getValue(device,'按键')).power" /></label>
<label class="button button-raised button-round"><input class="ajax" name="power" type="radio" value="1" v-model="getCode1(getValue(device,'按键')).power" /></label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>模式:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="0" />制冷</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="120" />自动</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="240" />制热</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="360" />抽湿</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="480" />送风</label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>温度:</label>
</div>
<div class="col-80">
<input class="ajax" name="temperature" type="range" step="1" min="1" max="15" :value="getCode1(getValue(device,'按键')).temperature" />
</div>
</div>
<div class="row">
<div class="col-20">
<label>风向:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="0" class="ajax" />任意</label>
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="60" class="ajax" />手动</label>
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="75" class="ajax" />自动</label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>风量:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="0" />自动</label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="15" /></label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="30" /></label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="45" /></label>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('串口').length">
<div class="block-title">串口</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('串口')">
<div class="list">
<ul>
<li>
<a class="item-link item-content"
:href="'/device/'+device.Number+'/name/'+device.Name">
<div class="item-media"> <img :src="'images/'+device.Icon+'.png'" /></div>
<div class="item-inner">
<div class="item-title">{{device.DisplayName||device.Name}}</div>
<div class="item-after"></div>
</div>
</a>
</li>
</ul>
</div>
<div class="row" v-if="getData(device,'空调')==='开'">
<form class="device KeyCodeType1" method="get" :action="'http://'+vm.Login.Host+'/IoTCenter/App/Exec'">
<input type="hidden" name="ConnectionId" :value="vm.ConnectionId" />
<input type="hidden" name="Gateway" :value="device.GatewayNumber" />
<input type="hidden" name="Number" :value="device.Number" />
<input type="hidden" name="Method" value="/Ir/Send" />
<input type="hidden" name="Type" value="1" />
<input type="hidden" name="Code" :value="getValue(device,'按键')" />
<div class="row">
<div class="col-20">
<label>电源:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="power" type="radio" value="2" v-model="getCode1(getValue(device,'按键')).power" /></label>
<label class="button button-raised button-round"><input class="ajax" name="power" type="radio" value="1" v-model="getCode1(getValue(device,'按键')).power" /></label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>模式:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="0" />制冷</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="120" />自动</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="240" />制热</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="360" />抽湿</label>
<label class="button button-raised button-round"><input class="ajax" name="pattern" type="radio" v-model="getCode1(getValue(device,'按键')).pattern" value="480" />送风</label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>温度:</label>
</div>
<div class="col-80">
<input class="ajax" name="temperature" type="range" step="1" min="1" max="15" :value="getCode1(getValue(device,'按键')).temperature" />
</div>
</div>
<div class="row">
<div class="col-20">
<label>风向:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="0" class="ajax" />任意</label>
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="60" class="ajax" />手动</label>
<label class="button button-raised button-round"><input name="direction" type="radio" v-model="getCode1(getValue(device,'按键')).direction" value="75" class="ajax" />自动</label>
</div>
</div>
<div class="row">
<div class="col-20">
<label>风量:</label>
</div>
<div class="col-80 row">
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="0" />自动</label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="15" /></label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="30" /></label>
<label class="button button-raised button-round"><input class="ajax" name="wind" type="radio" v-model="getCode1(getValue(device,'按键')).wind" value="45" /></label>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<template v-if="getDevices('摄像头').length">
<div class="block-title">摄像头</div>
<div class="block block-strong">
<div class="row">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('摄像头')">
<img :src="'data:image/jpeg;base64,'+getValue(device,'截图')" alt="截图" style="width:100%;" />
</div>
</div>
</div>
</template>
</f7-page>
</template>
<!--device-->
<template id="page-device">
<f7-page>
<f7-navbar>
<f7-navbar v-if="vm.Device" :title="vm.Device.DisplayName||vm.Device.Name" back-link="Back"></f7-navbar>
</f7-navbar>
</f7-page>
</template>
<template id="page-not-found">
<f7-page>
<f7-navbar title="Not found" back-link="Back"></f7-navbar>
<f7-block strong>
<p>Sorry</p>
<p>Requested content not found.</p>
</f7-block>
</f7-page>
</template>
<div id="callback" class="popup popup-tablet-fullscreen">
<div class="page">
<div class="navbar">
<div class="navbar-inner">
<div class="left">
</div>
<div class="title">API调用结果</div>
<div class="right"><a href="#" class="link popup-close">关闭</a></div>
</div>
</div>
<div class="page-content">
</div>
</div>
</div>
<script src="lib/mobile.detect/mobile-detect.min.js"></script>
<script src="lib/lodash/lodash.min.js"></script>
<script src="lib/jquery/jquery.min.js"></script>
<script src="lib/jquery.validation/jquery.validate.min.js"></script>
<script src="lib/jquery.validation.unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="lib/jquery.ajax.unobtrusive/jquery.unobtrusive-ajax.min.js"></script>
<script src="lib/framework7/js/framework7.bundle.min.js"></script>
<script src="lib/vue/vue.min.js"></script>
<script src="lib/framework7/js/framework7-vue.bundle.min.js"></script>
<script src="lib/signalr/signalr.min.js"></script>
<script src="lib/dayjs/dayjs.min.js"></script>
<script src="lib/URI.js/URI.min.js"></script>
<script src="lib/flv.js/flv.min.js"></script>
<script src="lib/Chart.js/Chart.bundle.min.js"></script>
<script>
var app;
var connection;
$.ajaxSetup({
cache: false,
timeout: 5000
});
function connect() {
if (connection && connection.connection.connectionState === 1) {
console.log('has connected');
}
else {
console.log('start connect to server:' + Date());
connection.start().then(function () {
console.log('signalR>start');
}).catch(function (err) {
console.error(err.toString());
setTimeout(connect, 10 * 1000);
});
}
}
function onMessage() {
connection.on('Connected', function (id) {
vm.ConnectionId = id;
});
connection.on('ApiResult', function (result) {
result = JSON.parse(result);
if (result.code === 0) {
if (result.type === 0) {
if (result.format === 1) {
console.log('format/1/base64 jpeg image');
$('#callback .page-content').html('<img class="shot" src="' + result.data + '">');
}
else {
console.log('format/0/json object');
$('#callback .page-content').html(result.data);
}
app.popup.open('#callback');
}
}
});
connection.on("UpdateNode", (message) => {
var newNode = JSON.parse(message);
var oldNode = _.chain(vm.Nodes).filter(o => o.Number === newNode.Number).first().value();
oldNode.Name = newNode.Name;
if (node && node.Node.Number === newNode.Number) {
node.Node.Name = newNode.Name;
}
console.log('update:' + newNode.Name);
});
connection.on("UpdateDevice", (message) => {
var newDevice = JSON.parse(message);
while (vm.MessageList.length >= 1) {
vm.MessageList.pop();
}
vm.MessageList.push(newDevice);
if (vm.Node && vm.Node.Id == newDevice.NodeId) {
var update = false;
for (var i = 0; i < vm.Node.Devices.length; i++) {
if (vm.Node.Devices[i].Number == newDevice.Number) {
update = true;
break;
}
}
if (update) {
vm.Node.Devices.splice(i, 1, newDevice);
}
else {
vm.Node.Devices.push(newDevice);
}
}
if (vm.Device && vm.Device.Number == newDevice.Number) {
vm.Device.Name = newDevice.Name;
vm.Device.DisplayName = newDevice.DisplayName;
vm.Device.Data = newDevice.Data;
//updateChart();
}
});
connection.on("DeleteDevice", (message) => {
var number = message;
if (node && node.Node.Id === newDevice.NodeId) {
for (var i = 0; i < node.Node.Devices.length; i++) {
if (node.Node.Devices[i].Number == number) {
node.Node.Devices.splice(i, 1);
break;
}
}
console.log('delete:' + newDevice.Number);
}
});
connection.on("UpdateSence", function (message) {
var sence = JSON.parse(message);
if (node && node.Node.Id === sence.NodeId) {
var update = false;
for (var i = 0; i < node.Node.Sences.length; i++) {
if (node.Node.Sences[i].Id == sence.Id) {
update = true;
break;
}
}
if (update) {
node.Node.Sences.splice(i, 1, sence);
}
else {
node.Node.Sences.push(sence);
}
console.log('update:' + sence.DisplayName);
}
});
connection.on("DeleteSence", function (message) {
var sence = JSON.parse(message);
if (node && node.Node.Id === sence.NodeId) {
for (var i = 0; i < node.Node.Sences.length; i++) {
if (node.Node.Sences[i].Id == sence.Id) {
node.Node.Sences.splice(i, 1);
break;
}
}
console.log('delete:' + sence.Name);
}
});
connection.onclose(function () {
setTimeout(connect, 10 * 1000);
});
}
function ajax(url) {
console.log(url);
app.dialog.progress();
$.get(url, function (response) {
var result = response;
if (result.code === 0) {
if (result.type === 0) {
if (result.format === 1) {
console.log('format/1/base64 jpeg image');
$('#callback .page-content').html('<img class="shot" src="' + result.data + '">');
}
else {
console.log('format/0/json object');
$('#callback .page-content').html(result.data);
}
app.popup.open('#callback');
}
}
}).fail(function (result) {
console.log('error');
console.log(result);
}).always(function () {
app.dialog.close();
});;
}
</script>
<script>
var isiOS = new MobileDetect(window.navigator.userAgent).os() === 'iOS';
Framework7.use(Framework7Vue);
function faceLoginCallback(token) {
localStorage.setItem("Token", token);
setTimeout(function () { app.view.current.router.navigate('/home/'); }, 1);
}
Vue.component('page-home', {
template: '#page-home',
data() {
return {
};
},
mounted() {
if (vm.Token) {
var url = 'http://' + vm.Login.Host + '/UserCenter/Account/GetUserInfo?token=' + vm.Token;
$.get(url, function (response) {
vm.Home = response;
});
url = 'http://' + vm.Login.Host + '/IoTCenter/App/GetNodeList?token=' + vm.Token;
$.get(url, function (response) {
vm.NodeList = response;
});
}
},
methods: {
}
});
Vue.component('page-login', {
template: '#page-login',
data() {
return {
};
},
mounted() {
localStorage.removeItem('Token');
if ((window.navigator.userAgent.indexOf("app") > -1)) {
window.location.href = "uniwebview://getToken";
}
},
methods: {
FaceLogin: function (host) {
window.location.href = "uniwebview://facelogin?host=" + encodeURIComponent(host);
},
OnSubmit: function (e) {
if (!$(e.target).valid()) {
return;
}
var url = e.target.action;
var data = $(e.target).serialize();
$.post(url, data, function (response) {
localStorage.setItem("Host", vm.Login.Host);
if (response.Code === 0) {
vm.Token = response.Token;
localStorage.setItem('Token', vm.Token);
setTimeout(function () { app.view.current.router.navigate('/home/'); }, 1);
}
else {
app.dialog.alert(response.Message, "消息");
}
}).fail(function (e) {
var message;
if (e.status === 0) {
message = "不是有效的服务器地址";
}
else {
message = e.status + ":" + e.statusText;
}
vm.$f7.dialog.alert(message, "消息");
});
}
}
});
Vue.component('page-node', {
template: '#page-node',
data() {
return {
};
},
mounted() {
var url = 'http://' + vm.Login.Host + '/IoTCenter/App/GetNode?number=' + this.$f7route.params.number + '&token=' + vm.Token;
$.get(url, function (response) {
vm.Node = response;
});
},
methods: {
getDevices: function () {
var args = arguments;
if (vm.Node) {
return _.chain(vm.Node.Devices).filter(function (device) {
return _.chain(args).filter(function (name) { return device.Name.indexOf(name) != -1; }).value().length > 0;
}).orderBy(['DisplayOrder', 'Name']).value();
}
return [];
},
getData(device, dataName) {
if (device != null) {
var data = _.first(_.filter(device.Data, function (o) { return o.Name === dataName }));
if (data != null) {
if (data.Value) {
var value = data.Value;
if (data.Unit) {
value += " " + data.Unit;
}
if (data.Description) {
value += " " + data.Description;
}
return value;
}
else {
console.log('值为空:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + dataName);
}
return "";
},
getValue(device, dataName) {
if (device != null) {
var data = _.first(_.filter(device.Data, function (o) { return o.Name === dataName }));
if (data != null) {
if (data.Value) {
var value = data.Value;
return value;
}
else {
console.log('值为空:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + dataName);
}
return "";
},
getCode1(code) {
var pattern = 0;
var direction = 0;
var wind = 0;
var power = 2;
var temperature = 1;
if (code > 480 + 2) {
pattern = 480;
}
else if (code > 360 + 2) {
pattern = 360;
}
else if (code > 240 + 2) {
pattern = 240;
}
else if (code > 120 + 2) {
pattern = 120;
}
else {
pattern = 0;
}
code -= pattern;
if (code > 75 + 2) {
direction = 75;
}
else if (code > 60 + 2) {
direction = 60;
}
else {
direction = 0;
}
code -= direction;
if (code > 45 + 2) {
wind = 45;
}
else if (code > 30 + 2) {
wind = 30;
}
else if (code > 15 + 2) {
wind = 15;
}
else {
wind = 0;
}
code -= wind;
if (code === 1) {
power = 1;
}
else {
power = 2;
temperature = code - power;
}
return {
pattern: pattern,
direction: direction,
wind: wind,
power: power,
temperature: temperature
};
},
call: function (gateway, number, cmd, query) {
query = query || '';
var url = 'http://' + vm.Host + '/IoTCenter/App/Exec/?connectionId=' + vm.ConnectionId + '&gateway=' + gateway + '&number=' + number + '&method=' + cmd + query;
if (query != '') {
url += "&" + query;
}
ajax(url);
}
}
});
Vue.component('page-device', {
template: '#page-device',
data() {
return {
Device: {
Number: null,
Name: null,
Data: [],
Apis: []
}
}
},
mounted() {
var number = this.$f7route.params.number;
vm.Device = _.first(_.filter(vm.Node.Devices, function (o) { return o.Number == number; }));
},
methods: {
isSelect: function (device, key) {
return _.filter(device.Data, function (o) { return o.Key == key + '[]' }).length > 0;
},
getSelect: function (device, key) {
var data = _.first(_.filter(device.Data, function (o) { return o.Key == key + '[]' })).Value;
var result = JSON.parse(data);
return result;
},
getParameter: function (name) {
console.log(name);
var prop = _.chain(this.Device.Data).filter(function (o) { return o.Key == name; }).first().value();
return prop ? prop.Value : '';
},
call: function (e) {
if (!$(e.target).valid()) {
return;
}
var url = vm.IoTServer + '/App/Exec/?connectionId=' + vm.ConnectionId + '&node=' + this.getNodeNumber(this.Device.NodeId) + '&' + $(e.target).serialize();
ajax(url);
},
getNodeNumber(nodeId) {
return _.chain(vm.Nodes).filter(function (o) {
return o.Id === nodeId;
}).first().value().Number;
},
showData(name) {
if (name === 'hidden' || name.indexOf('rtsp') != -1 || name.indexOf('rtmp') != -1 || name.indexOf('flv') != -1 || name.indexOf('hls') != -1) {
return false;
}
return true;
},
showApi(api) {
if (this.Device.Name === '摄像头') {
if (this.getParameter('Ptz3DZoomSupport') === '否') {
if (api.Name !== '截屏') {
return false;
}
}
}
return true;
},
getUrl(type) {
var url = _.chain(this.Device.Data).filter(function (o) { return o.Name === (type + '2'); }).first().value().Value;
url += '?id=' + this.Device.Id;
url += '&host=' + encodeURIComponent(vm.IoTServer);
url += '&node=' + _.chain(vm.Nodes).filter(function (o) { return o.Id === device.Device.NodeId; }).first().value().Number;
if (this.getParameter('Ptz3DZoomSupport') !== '否') {
url += '&ptz=true';
}
return url;
},
flv() {
this.$f7router.navigate('/camera/', {
props: {
name: this.Device.DisplayName || this.Device.Name,
url: this.getParameter('flv2'),
ptz: this.getParameter('Ptz3DZoomSupport') !== '否',
node: this.getNodeNumber(this.Device.NodeId),
id: this.Device.Id,
hls: this.getParameter('hls2')
}
});
}
},
destroyed() {
device = null;
},
});
Vue.component('page-not-found', {
template: '#page-not-found'
});
vm = new Vue({
el: '#app',
data() {
return {
f7params: {
root: '#app',
id: 'io.framework7.testapp',
name: 'Framework7',
theme: 'ios',
routes: [
{
path: '/home/',
component: 'page-home'
},
{
path: '/login/',
component: 'page-login'
},
{
path: '/node/:number/name/:name',
component: 'page-node'
},
{
path: '/device/:number/name/:name',
component: 'page-device'
},
{
path: '(.*)',
component: 'page-not-found',
},
],
},
ConnectionId: null,
Host: localStorage.getItem('Host'),
Token: localStorage.getItem('Token'),
Login: {
Host: localStorage.getItem('Host') || '192.168.3.124',
UserName: localStorage.getItem('UserName')
},
Home: {
Title: '',
NickName: '',
},
NodeList: [],
Node: null,
Device: null,
MessageList: []
}
},
mounted() {
this.$f7ready((f7) => {
app = this.$f7;
if (this.Token) {
//var wsUrl = 'http://' + this.Host + ":8001/hub?group=page";
var wsUrl = 'http://' + this.Host + "/IoTCenter/hub?group=page";
connection = new signalR.HubConnectionBuilder().withUrl(wsUrl).build();
onMessage();
connect();
}
else {
setTimeout(function () { app.view.current.router.navigate('/login/'); }, 1);
}
});
},
methods: {
}
});
</script>
<script>
$('body').on('change', 'input.ajax', function (e) {
var form = $(this).parents('form');
var url = form.attr('action') + '?' + form.serialize();
if (form.hasClass('KeyCodeType1')) {
if (e.target.name == "power" && e.target.value == "1") {
url = new URI(url).setQuery('Code', '1').toString();
}
else {
var list = {};
list['power'] = form.find("[name = 'power']:checked").val();
list['pattern'] = form.find("[name = 'pattern']:checked").val();
list['direction'] = form.find("[name = 'direction']:checked").val();
list['wind'] = form.find("[name = 'wind']:checked").val();
list['temperature'] = form.find("[name = 'temperature']").val();
list[e.target.name] = e.target.value;
var code = 0;
for (var name in list) {
code += parseInt(list[name]);
}
url = new URI(url).setQuery('Code', code).toString();
}
}
ajax(url);
return false;
});
</script>
</body>
</html>