Commit 053b7a7f 董杰

init

0 个父辈
正在显示 131 个修改的文件 包含 2226 行增加0 行删除
from flask import Flask
from config import Config
import logging
from logging.handlers import RotatingFileHandler,TimedRotatingFileHandler
# from flask_socketio import SocketIO
def setup_log():
# 设置日志的记录等级
logging.basicConfig(level=Config.LOG_LEVEL) # 调试debug级
# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler(Config.LOG_FOLDER, maxBytes=1024 * 1024 * 100, backupCount=10)
# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
# log_file_handler = TimedRotatingFileHandler(filename='logs/smartshelf.log', when="D", interval=1, backupCount=3)
formatter = logging.Formatter('%(asctime)s : %(message)s')
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局的日志工具对象(flask app使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)
setup_log()
app = Flask(__name__)
app.config.from_object(Config)
from app import routes,post,led_strip,driver_gpio,autoback
# return app
\ No newline at end of file \ No newline at end of file
# codinf:utf-8
import os
import time
from flask import render_template, Response, request,redirect,url_for
from werkzeug.utils import secure_filename
from app import app
import logging
import pexpect
import json
import zipfile
import shutil
import csv
import requests
import re
from config import Config
basepath = os.path.dirname(__file__)
def backup():
try:
source_dir = '/prog/backup/'
today = source_dir + time.strftime('%Y%m%d')
if not os.path.exists(today):
os.mkdir(today)
cmd = "cp -rf /prog/smartshelf/* /prog/backup/{}/".format(time.strftime('%Y%m%d'))
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(2)
run.sendline('xxx')
logging.warning("备份成功")
except Exception as e:
logging.warning("备份失败:{}".format(e))
def read_ip():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + 'ipconfig.csv','r') as f:
reader = csv.reader(f)
current = [row for row in reader]
ip = current[0][0]
return ip
def read_version():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","r") as f:
s_version=f.readline()
return s_version
def confirm_version(version):
logging.warning("写入最新版本号:{}".format(version))
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","w") as f:
f.write(str(version))
f.close()
@app.route('/upgrade',methods=['POST'])
def upgrade():
ip = read_ip()
ip = ip.replace('/myproject', '')
# ip = 'http://192.168.1.99'
download_url = '{}/download/version.txt'.format(ip)
logging.warning("服务器最新版本信息:{}".format(download_url))
try:
response = requests.get(download_url)
if response.status_code == 200:
version = response.json()
s_version = read_version()
logging.warning("当前版本:{},最新版本:{}".format(s_version,version))
if str(s_version) == str(version):
info = {'operation':'当前版本已是最新版本!'}
else:
download_zip(ip,version)
backup()
time.sleep(2)
process_file()
time.sleep(2)
confirm_version(version)
reboot()
info = {'operation':'已升级到最新版本'}
else:
info = {'operation':'服务器地址错误'}
except Exception as e:
logging.warning("发生错误:{}".format(e))
info = {'operation':'发生错误'}
return json.dumps(info)
def download_zip(ip,version):
zip_url = '{}/download/{}.zip'.format(ip,version)
logging.warning("服务器最新文件:{}".format(zip_url))
target_path = '/prog/upgrade_cach/smartshelf.zip'
File=requests.get(zip_url, stream=True)
with open(target_path,'wb+') as f:
for chunk in File.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.close()
def process_file():
zfile = zipfile.ZipFile('/prog/upgrade_cach/smartshelf.zip','r')
path2 = '/prog/update/smartshelf/'
n_train = 0
for filename in zfile.namelist():
if filename.endswith('/'):
n_train += 1
os.makedirs(os.path.join(path2, filename))
else:
data = zfile.read(filename)
file = open(os.path.join(path2, filename), 'w+b')
file.write(data)
file.close()
time.sleep(5)
py_source = '/prog/update/smartshelf/app/'
templates_source = '/prog/update/smartshelf/app/templates/'
py_target = '/prog/smartshelf/app/'
template_target = '/prog/smartshelf/app/templates/'
templates_lis = os.listdir(path=templates_source)
py_lis = os.listdir(path=py_source)
logging.warning("待更新文件:{},{}".format(py_lis,templates_lis))
for t_file in templates_lis:
t_filename = os.path.join(templates_source,t_file)
if os.path.isfile(t_filename):
try:
shutil.copy(t_filename, template_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
# print("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
for p_file in py_lis:
p_filename = os.path.join(py_source,p_file)
if os.path.isfile(p_filename):
try:
shutil.copy(p_filename, py_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
shutil.rmtree(path2)
os.remove('/prog/upgrade_cach/smartshelf.zip')
# shutil.rmtree('/prog/upgrade_cach/')
logging.warning("templates upgrade success")
def reboot():
os.system('/prog/./restart.sh')
import RPi.GPIO as GPIO
import time
def init(gpiox):
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpiox,GPIO.OUT)
def gpio_high(gpiox):
GPIO.output(gpiox, GPIO.HIGH)
def gpio_low(gpiox):
GPIO.output(gpiox, GPIO.LOW)
def clean():
GPIO.cleanup()
\ No newline at end of file \ No newline at end of file
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
config and init 24-LEDs-stripe
"""
from neopixel import *
# import logger
from rpi_ws281x import Adafruit_NeoPixel, Color,PixelStrip
LED_COUNT = 750 # 要控制LED的数量.
# LED_PIN = 18 # GPIO接口 (PWM编码).
LED_BRIGHTNESS = 100 # 设置LED亮度 (0-255)
#以下LED配置无需修改
LED_FREQ_HZ = 800000 # LED信号频率(以赫兹为单位)(通常为800khz)
LED_DMA = 10 # 用于生成信号的DMA通道(尝试5)
LED_INVERT = False # 反转信号(使用NPN晶体管电平移位时)
LED_CHANNEL = 0
stop_flag = None
def get_strip(pin=12):
LED_PIN = pin
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS,LED_CHANNEL)
# Initialize the library (must be called once before other functions).
# log.debug("Initialize: " + str(strip))
strip.begin()
return strip
def color_wipe_full(strip, color, wait_ms=50):
"""Wipe color across display a pixel at a time."""
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()
# time.sleep(wait_ms/1000.0)
def reset_strip(strip):
strip.setBrightness(LED_BRIGHTNESS)
color_wipe_full(strip, Color(0,0,0), 20)
# log.debug('LED stripe cleared.')
return
# noinspection PyProtectedMember
def _cleanup_strip(strip: Adafruit_NeoPixel):
strip._cleanup()
\ No newline at end of file \ No newline at end of file
http://192.168.101.193/myproject/service/store/communication@suzhou
\ No newline at end of file \ No newline at end of file
http://192.168.1.245:8080,491
off
\ No newline at end of file \ No newline at end of file
1.4
\ No newline at end of file \ No newline at end of file
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
/*
* Globals
*/
/* Links */
a,
a:focus,
a:hover {
color: #fff;
}
/* Custom default button */
.btn-default,
.btn-default:hover,
.btn-default:focus {
color: #333;
text-shadow: none; /* Prevent inheritance from `body` */
background-color: #fff;
border: 1px solid #fff;
}
/*
* Base structure
*/
html,
body {
height: 100%;
background-color: #333;
}
body {
color: #fff;
text-align: center;
text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* Extra markup and styles for table-esque vertical and horizontal centering */
.site-wrapper {
display: table;
width: 100%;
height: 100%; /* For at least Firefox */
min-height: 100%;
-webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
box-shadow: inset 0 0 100px rgba(0,0,0,.5);
}
.site-wrapper-inner {
display: table-cell;
vertical-align: top;
}
.cover-container {
margin-right: auto;
margin-left: auto;
}
/* Padding for spacing */
.inner {
padding: 30px;
}
/*
* Header
*/
.masthead-brand {
margin-top: 10px;
margin-bottom: 10px;
}
.masthead-nav > li {
display: inline-block;
}
.masthead-nav > li + li {
margin-left: 20px;
}
.masthead-nav > li > a {
padding-right: 0;
padding-left: 0;
font-size: 16px;
font-weight: bold;
color: #fff; /* IE8 proofing */
color: rgba(255,255,255,.75);
border-bottom: 2px solid transparent;
}
.masthead-nav > li > a:hover,
.masthead-nav > li > a:focus {
background-color: transparent;
border-bottom-color: #a9a9a9;
border-bottom-color: rgba(255,255,255,.25);
}
.masthead-nav > .active > a,
.masthead-nav > .active > a:hover,
.masthead-nav > .active > a:focus {
color: #fff;
border-bottom-color: #fff;
}
@media (min-width: 768px) {
.masthead-brand {
float: left;
}
.masthead-nav {
float: right;
}
}
/*
* Cover
*/
.cover {
padding: 0 20px;
}
.cover .btn-lg {
padding: 10px 20px;
font-weight: bold;
}
/*
* Footer
*/
.mastfoot {
color: #999; /* IE8 proofing */
color: rgba(255,255,255,.5);
}
/*
* Affix and center
*/
@media (min-width: 768px) {
/* Pull out the header and footer */
.masthead {
position: fixed;
top: 0;
}
.mastfoot {
position: fixed;
bottom: 0;
}
/* Start the vertical centering */
.site-wrapper-inner {
vertical-align: middle;
}
/* Handle the widths */
.masthead,
.mastfoot,
.cover-container {
width: 100%; /* Must be percentage or pixels for horizontal alignment */
}
}
@media (min-width: 992px) {
.masthead,
.mastfoot,
.cover-container {
width: 700px;
}
}
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*
* See the Getting Started docs for more information:
* http://getbootstrap.com/getting-started/#support-ie10-width
*/
@-ms-viewport { width: device-width; }
@-o-viewport { width: device-width; }
@viewport { width: device-width; }
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
// See the Getting Started docs for more information:
// http://getbootstrap.com/getting-started/#support-ie10-width
(function () {
'use strict';
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement('style')
msViewportStyle.appendChild(
document.createTextNode(
'@-ms-viewport{width:auto!important}'
)
)
document.querySelector('head').appendChild(msViewportStyle)
}
})();
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
require('../../js/transition.js')
require('../../js/alert.js')
require('../../js/button.js')
require('../../js/carousel.js')
require('../../js/collapse.js')
require('../../js/dropdown.js')
require('../../js/modal.js')
require('../../js/tooltip.js')
require('../../js/popover.js')
require('../../js/scrollspy.js')
require('../../js/tab.js')
require('../../js/affix.js')
\ No newline at end of file \ No newline at end of file
位置,优先级,高度,宽度,料仓ID,设备IP,区域ID,灯索引
1_1_1,10,12,15,1,,1,0
1_1_2,10,12,15,1,,1,1
1_1_3,10,12,15,1,,1,2
1_1_4,10,12,15,1,,1,3
1_1_5,10,12,15,1,,1,4
1_1_6,10,12,15,1,,1,5
1_1_7,10,12,15,1,,1,6
1_1_8,10,12,15,1,,1,7
1_1_9,10,12,15,1,,1,8
1_1_10,10,12,15,1,,1,9
1_1_11,10,12,15,1,,1,10
1_1_12,10,12,15,1,,1,11
1_1_13,10,12,15,1,,1,12
1_1_14,10,12,15,1,,1,13
1_1_15,10,12,15,1,,1,14
1_1_16,10,12,15,1,,1,15
1_1_17,10,12,15,1,,1,16
1_1_18,10,12,15,1,,1,17
1_1_19,10,12,15,1,,1,18
2_1_1,10,12,15,1,,2,0
2_1_2,10,12,15,1,,2,1
2_1_3,10,12,15,1,,2,2
2_1_4,10,12,15,1,,2,3
2_1_5,10,12,15,1,,2,4
2_1_6,10,12,15,1,,2,5
2_1_7,10,12,15,1,,2,6
2_1_8,10,12,15,1,,2,7
2_1_9,10,12,15,1,,2,8
2_1_10,10,12,15,1,,2,9
2_1_11,10,12,15,1,,2,10
2_1_12,10,12,15,1,,2,11
2_1_13,10,12,15,1,,2,12
2_1_14,10,12,15,1,,2,13
2_1_15,10,12,15,1,,2,14
2_1_16,10,12,15,1,,2,15
2_1_17,10,12,15,1,,2,16
2_1_18,10,12,15,1,,2,17
2_1_19,10,12,15,1,,2,18
status,,,,,,1,19
<span style="font-size:18px;"><!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>smartshelf系统</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">亮灯料架</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">控制</a></li>
<li><a href="{{ url_for('ledtest') }}">测试</a> </li>
<li><a href="{{ url_for('shelfconfig') }}">料架配置</a> </li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<h2>料架系统</h2>
<hr class="divider">
<!-- 料架启动关闭 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">开关</h3>
</div>
<div class="panel-body">
<input type="button" value="启动" class="btn btn-info" onclick="startpost()"/>
<input type="button" value="停止" class="btn btn-warning" onclick="stoppost()"/>
</div>
</div>
<div id="panel-group">
<!-- 1 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">提醒消息</h3>
</div>
<div class="panel-body">
<div class="alert alert-info" role="alert">
<p>
运行状态:<span id="shelfstate"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
配置文件加载状态:<span id="testinfo">{{ config_state }}</span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
服务器地址:<span id="ipconfig"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
料架编号:<span id="ccid"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
服务器连接状态:<span id="poststate"></span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<h2>运行日志&状态信息</h2>
<hr class="divider">
<!-- 日志下载 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日志下载</h3>
</div>
<div class="panel-body">
<a type="button" class="btn btn-warning" href="{{ url_for('download') }}">下载日志</a>
</div>
</div>
<!-- 日志显示 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日志</h3>
</div>
<div class="panel-body">
<div id="logmsg" style="overflow:auto;height: 400px;background:#000; color:green"></div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
getstate();
taillog();
console.log('success');
});
function startpost(){
$.ajax({
url:"/startpost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
// console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("启动失败");
}
})
}
function stoppost(){
// var form= new FormData(document.getElementById("test_form"));
var shelfstate = document.getElementById("shelfstate").value
console.log(shelfstate)
$.ajax({
url:"/stoppost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("停止失败");
}
})
}
// 获取开机关机状态
function getstate(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/getstate",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
console.log(data)
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
// $("#gpioconfig").html(data[0].gpio)
$("#ipconfig").html(data[0].ipconfig['ip'])
$("#ccid").html(data[0].ipconfig['cid'])
},
error:function(e){
alert("未获取到状态信息");
}
})
}
// 获取开机关机状态
function taillog(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/taillog",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
$("#logmsg").html(data.msg)
$("#poststate").html(data.poststate)
},
error:function(e){
}
})
}
setInterval(function(){
taillog();
}, 3000);
</script>
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</body>
</html>
\ No newline at end of file \ No newline at end of file
import os
import logging
# from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
# load_dotenv(os.path.join(basedir, '.env'))
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
URL = 'http://192.168.1.100:8080/service/store/communication'
UPLOAD_FOLDER = '/static/uploads'
STATE_PATH = '/state/'
ALLOWED_EXTENSIONS = set(['csv']) #限制上传文件格式
LOG_LEVEL = logging.WARNING
LOG_FOLDER = 'logs/smart.log'
DEFAULT_COLOR = 'red'
\ No newline at end of file \ No newline at end of file
此文件类型无法预览
此文件的差异太大,无法显示。
from app import app,db
from app.models import State
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'State': State}
\ No newline at end of file \ No newline at end of file
from flask import Flask
from config import Config
import logging
from logging.handlers import RotatingFileHandler,TimedRotatingFileHandler
# from flask_socketio import SocketIO
def setup_log():
# 设置日志的记录等级
logging.basicConfig(level=Config.LOG_LEVEL) # 调试debug级
# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler(Config.LOG_FOLDER, maxBytes=1024 * 1024 * 100, backupCount=10)
# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
# log_file_handler = TimedRotatingFileHandler(filename='logs/smartshelf.log', when="D", interval=1, backupCount=3)
formatter = logging.Formatter('%(asctime)s : %(message)s')
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局的日志工具对象(flask app使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)
setup_log()
app = Flask(__name__)
app.config.from_object(Config)
from app import routes,post,led_strip,driver_gpio,autoback
# return app
\ No newline at end of file \ No newline at end of file
# codinf:utf-8
import os
import time
from flask import render_template, Response, request,redirect,url_for
from werkzeug.utils import secure_filename
from app import app
import logging
import pexpect
import json
import zipfile
import shutil
import csv
import requests
import re
from config import Config
basepath = os.path.dirname(__file__)
def backup():
try:
source_dir = '/prog/backup/'
today = source_dir + time.strftime('%Y%m%d')
if not os.path.exists(today):
os.mkdir(today)
cmd = "cp -rf /prog/smartshelf/* /prog/backup/{}/".format(time.strftime('%Y%m%d'))
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(2)
run.sendline('xxx')
logging.warning("备份成功")
except Exception as e:
logging.warning("备份失败:{}".format(e))
def read_ip():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + 'ipconfig.csv','r') as f:
reader = csv.reader(f)
current = [row for row in reader]
ip = current[0][0]
return ip
def read_version():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","r") as f:
s_version=f.readline()
return s_version
def confirm_version(version):
logging.warning("写入最新版本号:{}".format(version))
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","w") as f:
f.write(str(version))
f.close()
@app.route('/upgrade',methods=['POST'])
def upgrade():
ip = read_ip()
ip = ip.replace('/myproject', '')
# ip = 'http://192.168.1.99'
download_url = '{}/download/version.txt'.format(ip)
logging.warning("服务器最新版本信息:{}".format(download_url))
try:
response = requests.get(download_url)
if response.status_code == 200:
version = response.json()
s_version = read_version()
logging.warning("当前版本:{},最新版本:{}".format(s_version,version))
if str(s_version) == str(version):
info = {'operation':'当前版本已是最新版本!'}
else:
download_zip(ip,version)
backup()
time.sleep(2)
process_file()
time.sleep(2)
confirm_version(version)
reboot()
info = {'operation':'已升级到最新版本'}
else:
info = {'operation':'服务器地址错误'}
except Exception as e:
logging.warning("发生错误:{}".format(e))
info = {'operation':'发生错误'}
return json.dumps(info)
def download_zip(ip,version):
zip_url = '{}/download/{}.zip'.format(ip,version)
logging.warning("服务器最新文件:{}".format(zip_url))
target_path = '/prog/upgrade_cach/smartshelf.zip'
File=requests.get(zip_url, stream=True)
with open(target_path,'wb+') as f:
for chunk in File.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.close()
def process_file():
zfile = zipfile.ZipFile('/prog/upgrade_cach/smartshelf.zip','r')
path2 = '/prog/update/smartshelf/'
n_train = 0
for filename in zfile.namelist():
if filename.endswith('/'):
n_train += 1
os.makedirs(os.path.join(path2, filename))
else:
data = zfile.read(filename)
file = open(os.path.join(path2, filename), 'w+b')
file.write(data)
file.close()
time.sleep(5)
py_source = '/prog/update/smartshelf/app/'
templates_source = '/prog/update/smartshelf/app/templates/'
py_target = '/prog/smartshelf/app/'
template_target = '/prog/smartshelf/app/templates/'
templates_lis = os.listdir(path=templates_source)
py_lis = os.listdir(path=py_source)
logging.warning("待更新文件:{},{}".format(py_lis,templates_lis))
for t_file in templates_lis:
t_filename = os.path.join(templates_source,t_file)
if os.path.isfile(t_filename):
try:
shutil.copy(t_filename, template_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
# print("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
for p_file in py_lis:
p_filename = os.path.join(py_source,p_file)
if os.path.isfile(p_filename):
try:
shutil.copy(p_filename, py_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
shutil.rmtree(path2)
os.remove('/prog/upgrade_cach/smartshelf.zip')
# shutil.rmtree('/prog/upgrade_cach/')
logging.warning("templates upgrade success")
def reboot():
os.system('/prog/./restart.sh')
import RPi.GPIO as GPIO
import time
def init(gpiox):
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpiox,GPIO.OUT)
def gpio_high(gpiox):
GPIO.output(gpiox, GPIO.HIGH)
def gpio_low(gpiox):
GPIO.output(gpiox, GPIO.LOW)
def clean():
GPIO.cleanup()
\ No newline at end of file \ No newline at end of file
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
config and init 24-LEDs-stripe
"""
from neopixel import *
# import logger
from rpi_ws281x import Adafruit_NeoPixel, Color,PixelStrip
LED_COUNT = 750 # 要控制LED的数量.
# LED_PIN = 18 # GPIO接口 (PWM编码).
LED_BRIGHTNESS = 100 # 设置LED亮度 (0-255)
#以下LED配置无需修改
LED_FREQ_HZ = 800000 # LED信号频率(以赫兹为单位)(通常为800khz)
LED_DMA = 10 # 用于生成信号的DMA通道(尝试5)
LED_INVERT = False # 反转信号(使用NPN晶体管电平移位时)
LED_CHANNEL = 0
stop_flag = None
def get_strip(pin=12):
LED_PIN = pin
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS,LED_CHANNEL)
# Initialize the library (must be called once before other functions).
# log.debug("Initialize: " + str(strip))
strip.begin()
return strip
def color_wipe_full(strip, color, wait_ms=50):
"""Wipe color across display a pixel at a time."""
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()
# time.sleep(wait_ms/1000.0)
def reset_strip(strip):
strip.setBrightness(LED_BRIGHTNESS)
color_wipe_full(strip, Color(0,0,0), 20)
# log.debug('LED stripe cleared.')
return
# noinspection PyProtectedMember
def _cleanup_strip(strip: Adafruit_NeoPixel):
strip._cleanup()
\ No newline at end of file \ No newline at end of file
http://192.168.101.193/myproject/service/store/communication@suzhou
\ No newline at end of file \ No newline at end of file
http://192.168.1.245:8080/myproject,491
off
\ No newline at end of file \ No newline at end of file
1.0
\ No newline at end of file \ No newline at end of file
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
/*
* Globals
*/
/* Links */
a,
a:focus,
a:hover {
color: #fff;
}
/* Custom default button */
.btn-default,
.btn-default:hover,
.btn-default:focus {
color: #333;
text-shadow: none; /* Prevent inheritance from `body` */
background-color: #fff;
border: 1px solid #fff;
}
/*
* Base structure
*/
html,
body {
height: 100%;
background-color: #333;
}
body {
color: #fff;
text-align: center;
text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* Extra markup and styles for table-esque vertical and horizontal centering */
.site-wrapper {
display: table;
width: 100%;
height: 100%; /* For at least Firefox */
min-height: 100%;
-webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
box-shadow: inset 0 0 100px rgba(0,0,0,.5);
}
.site-wrapper-inner {
display: table-cell;
vertical-align: top;
}
.cover-container {
margin-right: auto;
margin-left: auto;
}
/* Padding for spacing */
.inner {
padding: 30px;
}
/*
* Header
*/
.masthead-brand {
margin-top: 10px;
margin-bottom: 10px;
}
.masthead-nav > li {
display: inline-block;
}
.masthead-nav > li + li {
margin-left: 20px;
}
.masthead-nav > li > a {
padding-right: 0;
padding-left: 0;
font-size: 16px;
font-weight: bold;
color: #fff; /* IE8 proofing */
color: rgba(255,255,255,.75);
border-bottom: 2px solid transparent;
}
.masthead-nav > li > a:hover,
.masthead-nav > li > a:focus {
background-color: transparent;
border-bottom-color: #a9a9a9;
border-bottom-color: rgba(255,255,255,.25);
}
.masthead-nav > .active > a,
.masthead-nav > .active > a:hover,
.masthead-nav > .active > a:focus {
color: #fff;
border-bottom-color: #fff;
}
@media (min-width: 768px) {
.masthead-brand {
float: left;
}
.masthead-nav {
float: right;
}
}
/*
* Cover
*/
.cover {
padding: 0 20px;
}
.cover .btn-lg {
padding: 10px 20px;
font-weight: bold;
}
/*
* Footer
*/
.mastfoot {
color: #999; /* IE8 proofing */
color: rgba(255,255,255,.5);
}
/*
* Affix and center
*/
@media (min-width: 768px) {
/* Pull out the header and footer */
.masthead {
position: fixed;
top: 0;
}
.mastfoot {
position: fixed;
bottom: 0;
}
/* Start the vertical centering */
.site-wrapper-inner {
vertical-align: middle;
}
/* Handle the widths */
.masthead,
.mastfoot,
.cover-container {
width: 100%; /* Must be percentage or pixels for horizontal alignment */
}
}
@media (min-width: 992px) {
.masthead,
.mastfoot,
.cover-container {
width: 700px;
}
}
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*
* See the Getting Started docs for more information:
* http://getbootstrap.com/getting-started/#support-ie10-width
*/
@-ms-viewport { width: device-width; }
@-o-viewport { width: device-width; }
@viewport { width: device-width; }
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
// See the Getting Started docs for more information:
// http://getbootstrap.com/getting-started/#support-ie10-width
(function () {
'use strict';
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement('style')
msViewportStyle.appendChild(
document.createTextNode(
'@-ms-viewport{width:auto!important}'
)
)
document.querySelector('head').appendChild(msViewportStyle)
}
})();
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
require('../../js/transition.js')
require('../../js/alert.js')
require('../../js/button.js')
require('../../js/carousel.js')
require('../../js/collapse.js')
require('../../js/dropdown.js')
require('../../js/modal.js')
require('../../js/tooltip.js')
require('../../js/popover.js')
require('../../js/scrollspy.js')
require('../../js/tab.js')
require('../../js/affix.js')
\ No newline at end of file \ No newline at end of file
位置,优先级,高度,宽度,料仓ID,设备IP,区域ID,灯索引
1_1_1,10,12,15,1,,1,0
1_1_2,10,12,15,1,,1,1
1_1_3,10,12,15,1,,1,2
1_1_4,10,12,15,1,,1,3
1_1_5,10,12,15,1,,1,4
1_1_6,10,12,15,1,,1,5
1_1_7,10,12,15,1,,1,6
1_1_8,10,12,15,1,,1,7
1_1_9,10,12,15,1,,1,8
1_1_10,10,12,15,1,,1,9
1_1_11,10,12,15,1,,1,10
1_1_12,10,12,15,1,,1,11
1_1_13,10,12,15,1,,1,12
1_1_14,10,12,15,1,,1,13
1_1_15,10,12,15,1,,1,14
1_1_16,10,12,15,1,,1,15
1_1_17,10,12,15,1,,1,16
1_1_18,10,12,15,1,,1,17
1_1_19,10,12,15,1,,1,18
2_1_1,10,12,15,1,,2,0
2_1_2,10,12,15,1,,2,1
2_1_3,10,12,15,1,,2,2
2_1_4,10,12,15,1,,2,3
2_1_5,10,12,15,1,,2,4
2_1_6,10,12,15,1,,2,5
2_1_7,10,12,15,1,,2,6
2_1_8,10,12,15,1,,2,7
2_1_9,10,12,15,1,,2,8
2_1_10,10,12,15,1,,2,9
2_1_11,10,12,15,1,,2,10
2_1_12,10,12,15,1,,2,11
2_1_13,10,12,15,1,,2,12
2_1_14,10,12,15,1,,2,13
2_1_15,10,12,15,1,,2,14
2_1_16,10,12,15,1,,2,15
2_1_17,10,12,15,1,,2,16
2_1_18,10,12,15,1,,2,17
2_1_19,10,12,15,1,,2,18
status,,,,,,1,19
1_1_20,,,,,,1,20
1_1_21,,,,,,1,21
1_1_22,,,,,,1,22
1_1_23,,,,,,1,23
1_1_24,,,,,,1,24
1_1_25,,,,,,1,25
1_1_26,,,,,,1,26
1_1_27,,,,,,1,27
1_1_28,,,,,,1,28
1_1_29,,,,,,1,29
1_1_30,,,,,,1,30
1_1_31,,,,,,1,31
1_1_32,,,,,,1,32
1_1_33,,,,,,1,33
1_1_34,,,,,,1,34
1_1_35,,,,,,1,35
1_1_36,,,,,,1,36
1_1_37,,,,,,1,37
1_1_38,,,,,,1,38
1_1_39,,,,,,1,39
1_1_40,,,,,,1,40
1_1_41,,,,,,1,41
1_1_42,,,,,,1,42
1_1_43,,,,,,1,43
1_1_44,,,,,,1,44
1_1_45,,,,,,1,45
1_1_46,,,,,,1,46
1_1_47,,,,,,1,47
1_1_48,,,,,,1,48
1_1_49,,,,,,1,49
1_1_50,,,,,,1,50
1_1_51,,,,,,1,51
1_1_52,,,,,,1,52
1_1_53,,,,,,1,53
1_1_54,,,,,,1,54
1_1_55,,,,,,1,55
1_1_56,,,,,,1,56
1_1_57,,,,,,1,57
1_1_58,,,,,,1,58
1_1_59,,,,,,1,59
1_1_60,,,,,,1,60
1_1_61,,,,,,1,61
1_1_62,,,,,,1,62
1_1_63,,,,,,1,63
1_1_64,,,,,,1,64
1_1_65,,,,,,1,65
1_1_66,,,,,,1,66
1_1_67,,,,,,1,67
1_1_68,,,,,,1,68
1_1_69,,,,,,1,69
1_1_70,,,,,,1,70
1_1_71,,,,,,1,71
1_1_72,,,,,,1,72
1_1_73,,,,,,1,73
1_1_74,,,,,,1,74
1_1_75,,,,,,1,75
1_1_76,,,,,,1,76
1_1_77,,,,,,1,77
1_1_78,,,,,,1,78
1_1_79,,,,,,1,79
1_1_80,,,,,,1,80
1_1_81,,,,,,1,81
1_1_82,,,,,,1,82
1_1_83,,,,,,1,83
1_1_84,,,,,,1,84
1_1_85,,,,,,1,85
1_1_86,,,,,,1,86
1_1_87,,,,,,1,87
1_1_88,,,,,,1,88
1_1_89,,,,,,1,89
1_1_90,,,,,,1,90
1_1_91,,,,,,1,91
1_1_92,,,,,,1,92
1_1_93,,,,,,1,93
1_1_94,,,,,,1,94
1_1_95,,,,,,1,95
1_1_96,,,,,,1,96
1_1_97,,,,,,1,97
1_1_98,,,,,,1,98
1_1_99,,,,,,1,99
1_1_100,,,,,,1,100
1_1_101,,,,,,1,101
1_1_102,,,,,,1,102
1_1_103,,,,,,1,103
1_1_104,,,,,,1,104
1_1_105,,,,,,1,105
1_1_106,,,,,,1,106
1_1_107,,,,,,1,107
1_1_108,,,,,,1,108
1_1_109,,,,,,1,109
1_1_110,,,,,,1,110
1_1_111,,,,,,1,111
1_1_112,,,,,,1,112
1_1_113,,,,,,1,113
1_1_114,,,,,,1,114
1_1_115,,,,,,1,115
1_1_116,,,,,,1,116
1_1_117,,,,,,1,117
1_1_118,,,,,,1,118
1_1_119,,,,,,1,119
1_1_120,,,,,,1,120
1_1_121,,,,,,1,121
1_1_122,,,,,,1,122
1_1_123,,,,,,1,123
1_1_124,,,,,,1,124
1_1_125,,,,,,1,125
1_1_126,,,,,,1,126
1_1_127,,,,,,1,127
1_1_128,,,,,,1,128
1_1_129,,,,,,1,129
1_1_130,,,,,,1,130
1_1_131,,,,,,1,131
1_1_132,,,,,,1,132
1_1_133,,,,,,1,133
1_1_134,,,,,,1,134
1_1_135,,,,,,1,135
1_1_136,,,,,,1,136
1_1_137,,,,,,1,137
1_1_138,,,,,,1,138
1_1_139,,,,,,1,139
1_1_140,,,,,,1,140
1_1_141,,,,,,1,141
1_1_142,,,,,,1,142
1_1_143,,,,,,1,143
1_1_144,,,,,,1,144
1_1_145,,,,,,1,145
1_1_146,,,,,,1,146
1_1_147,,,,,,1,147
1_1_148,,,,,,1,148
1_1_149,,,,,,1,149
1_1_150,,,,,,1,150
1_1_151,,,,,,1,151
1_1_152,,,,,,1,152
1_1_153,,,,,,1,153
1_1_154,,,,,,1,154
1_1_155,,,,,,1,155
1_1_156,,,,,,1,156
1_1_157,,,,,,1,157
1_1_158,,,,,,1,158
1_1_159,,,,,,1,159
1_1_160,,,,,,1,160
1_1_161,,,,,,1,161
1_1_162,,,,,,1,162
1_1_163,,,,,,1,163
1_1_164,,,,,,1,164
1_1_165,,,,,,1,165
1_1_166,,,,,,1,166
1_1_167,,,,,,1,167
1_1_168,,,,,,1,168
1_1_169,,,,,,1,169
1_1_170,,,,,,1,170
1_1_171,,,,,,1,171
1_1_172,,,,,,1,172
1_1_173,,,,,,1,173
1_1_174,,,,,,1,174
1_1_175,,,,,,1,175
1_1_176,,,,,,1,176
1_1_177,,,,,,1,177
1_1_178,,,,,,1,178
1_1_179,,,,,,1,179
1_1_180,,,,,,1,180
1_1_181,,,,,,1,181
1_1_182,,,,,,1,182
1_1_183,,,,,,1,183
1_1_184,,,,,,1,184
1_1_185,,,,,,1,185
1_1_186,,,,,,1,186
1_1_187,,,,,,1,187
1_1_188,,,,,,1,188
1_1_189,,,,,,1,189
1_1_190,,,,,,1,190
1_1_191,,,,,,1,191
1_1_192,,,,,,1,192
1_1_193,,,,,,1,193
1_1_194,,,,,,1,194
1_1_195,,,,,,1,195
1_1_196,,,,,,1,196
1_1_197,,,,,,1,197
1_1_198,,,,,,1,198
1_1_199,,,,,,1,199
1_1_200,,,,,,1,200
1_1_201,,,,,,1,201
1_1_202,,,,,,1,202
1_1_203,,,,,,1,203
1_1_204,,,,,,1,204
1_1_205,,,,,,1,205
1_1_206,,,,,,1,206
1_1_207,,,,,,1,207
1_1_208,,,,,,1,208
1_1_209,,,,,,1,209
1_1_210,,,,,,1,210
1_1_211,,,,,,1,211
1_1_212,,,,,,1,212
1_1_213,,,,,,1,213
1_1_214,,,,,,1,214
1_1_215,,,,,,1,215
1_1_216,,,,,,1,216
1_1_217,,,,,,1,217
1_1_218,,,,,,1,218
1_1_219,,,,,,1,219
1_1_220,,,,,,1,220
1_1_221,,,,,,1,221
1_1_222,,,,,,1,222
1_1_223,,,,,,1,223
1_1_224,,,,,,1,224
1_1_225,,,,,,1,225
1_1_226,,,,,,1,226
1_1_227,,,,,,1,227
1_1_228,,,,,,1,228
1_1_229,,,,,,1,229
1_1_230,,,,,,1,230
1_1_231,,,,,,1,231
1_1_232,,,,,,1,232
1_1_233,,,,,,1,233
1_1_234,,,,,,1,234
1_1_235,,,,,,1,235
1_1_236,,,,,,1,236
1_1_237,,,,,,1,237
1_1_238,,,,,,1,238
1_1_239,,,,,,1,239
1_1_240,,,,,,1,240
1_1_241,,,,,,1,241
1_1_242,,,,,,1,242
1_1_243,,,,,,1,243
1_1_244,,,,,,1,244
1_1_245,,,,,,1,245
1_1_246,,,,,,1,246
1_1_247,,,,,,1,247
1_1_248,,,,,,1,248
1_1_249,,,,,,1,249
1_1_250,,,,,,1,250
1_1_251,,,,,,1,251
1_1_252,,,,,,1,252
1_1_253,,,,,,1,253
1_1_254,,,,,,1,254
1_1_255,,,,,,1,255
1_1_256,,,,,,1,256
1_1_257,,,,,,1,257
1_1_258,,,,,,1,258
1_1_259,,,,,,1,259
1_1_260,,,,,,1,260
1_1_261,,,,,,1,261
1_1_262,,,,,,1,262
1_1_263,,,,,,1,263
1_1_264,,,,,,1,264
1_1_265,,,,,,1,265
1_1_266,,,,,,1,266
1_1_267,,,,,,1,267
1_1_268,,,,,,1,268
1_1_269,,,,,,1,269
1_1_270,,,,,,1,270
1_1_271,,,,,,1,271
1_1_272,,,,,,1,272
1_1_273,,,,,,1,273
1_1_274,,,,,,1,274
1_1_275,,,,,,1,275
1_1_276,,,,,,1,276
1_1_277,,,,,,1,277
1_1_278,,,,,,1,278
1_1_279,,,,,,1,279
1_1_280,,,,,,1,280
1_1_281,,,,,,1,281
1_1_282,,,,,,1,282
1_1_283,,,,,,1,283
1_1_284,,,,,,1,284
1_1_285,,,,,,1,285
1_1_286,,,,,,1,286
1_1_287,,,,,,1,287
1_1_288,,,,,,1,288
1_1_289,,,,,,1,289
1_1_290,,,,,,1,290
1_1_291,,,,,,1,291
1_1_292,,,,,,1,292
1_1_293,,,,,,1,293
1_1_294,,,,,,1,294
1_1_295,,,,,,1,295
1_1_296,,,,,,1,296
1_1_297,,,,,,1,297
1_1_298,,,,,,1,298
1_1_299,,,,,,1,299
1_1_300,,,,,,1,300
1_1_301,,,,,,1,301
1_1_302,,,,,,1,302
1_1_303,,,,,,1,303
1_1_304,,,,,,1,304
1_1_305,,,,,,1,305
1_1_306,,,,,,1,306
1_1_307,,,,,,1,307
1_1_308,,,,,,1,308
1_1_309,,,,,,1,309
1_1_310,,,,,,1,310
1_1_311,,,,,,1,311
1_1_312,,,,,,1,312
1_1_313,,,,,,1,313
1_1_314,,,,,,1,314
1_1_315,,,,,,1,315
1_1_316,,,,,,1,316
1_1_317,,,,,,1,317
1_1_318,,,,,,1,318
1_1_319,,,,,,1,319
1_1_320,,,,,,1,320
<span style="font-size:18px;"><!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>smartshelf系统</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">亮灯料架</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">控制</a></li>
<li><a href="{{ url_for('ledtest') }}">测试</a> </li>
<li><a href="{{ url_for('shelfconfig') }}">料架配置</a> </li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<h2>料架系统</h2>
<hr class="divider">
<!-- 料架启动关闭 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">开关</h3>
</div>
<div class="panel-body">
<input type="button" value="启动" class="btn btn-info" onclick="startpost()"/>
<input type="button" value="停止" class="btn btn-warning" onclick="stoppost()"/>
</div>
</div>
<div id="panel-group">
<!-- 1 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">提醒消息</h3>
</div>
<div class="panel-body">
<div class="alert alert-info" role="alert">
<p>
运行状态:<span id="shelfstate"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
配置文件加载状态:<span id="testinfo">{{ config_state }}</span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
服务器地址:<span id="ipconfig"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
料架编号:<span id="ccid"></span>
</p>
</div>
<div class="alert alert-info" role="alert">
<p>
服务器连接状态:<span id="poststate"></span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<h2>运行日志&状态信息</h2>
<hr class="divider">
<!-- 日志下载 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日志下载</h3>
</div>
<div class="panel-body">
<a type="button" class="btn btn-warning" href="{{ url_for('download') }}">下载日志</a>
</div>
</div>
<!-- 日志显示 -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">日志</h3>
</div>
<div class="panel-body">
<div id="logmsg" style="overflow:auto;height: 400px;background:#000; color:green"></div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
getstate();
taillog();
console.log('success');
});
function startpost(){
$.ajax({
url:"/startpost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
// console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("启动失败");
}
})
}
function stoppost(){
// var form= new FormData(document.getElementById("test_form"));
var shelfstate = document.getElementById("shelfstate").value
console.log(shelfstate)
$.ajax({
url:"/stoppost",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
console.log(data)
alert (data[0].msg)
},
error:function(e){
alert("停止失败");
}
})
}
// 获取开机关机状态
function getstate(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/getstate",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
console.log(data)
if (data[0].state == 'on') {$("#shelfstate").html("运行中");}
else if (data[0].state == 'off') {$("#shelfstate").html("已关闭");}
else {$("#shelfstate").html("未初始化");}
// $("#gpioconfig").html(data[0].gpio)
$("#ipconfig").html(data[0].ipconfig['ip'])
$("#ccid").html(data[0].ipconfig['cid'])
},
error:function(e){
alert("未获取到状态信息");
}
})
}
// 获取开机关机状态
function taillog(){
// var form= new FormData(document.getElementById("test_form"));
$.ajax({
url:"/taillog",
type:"post",
// data:form,
dataType: 'json',
processData:false,
contentType:false,
success:function(data){
$("#logmsg").html(data.msg)
$("#poststate").html(data.poststate)
},
error:function(e){
}
})
}
setInterval(function(){
taillog();
}, 3000);
</script>
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</body>
</html>
\ No newline at end of file \ No newline at end of file
import os
import logging
# from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
# load_dotenv(os.path.join(basedir, '.env'))
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
URL = 'http://192.168.1.100:8080/service/store/communication'
UPLOAD_FOLDER = '/static/uploads'
STATE_PATH = '/state/'
ALLOWED_EXTENSIONS = set(['csv']) #限制上传文件格式
LOG_LEVEL = logging.WARNING
LOG_FOLDER = 'logs/smart.log'
DEFAULT_COLOR = 'red'
\ No newline at end of file \ No newline at end of file
此文件类型无法预览
此文件的差异太大,无法显示。
from app import app,db
from app.models import State
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'State': State}
\ No newline at end of file \ No newline at end of file
#!/usr/bin/env bash
workdir=/prog/smartshelf/logs
cd $workdir
: > smart.log &
echo "log clear"
#!/usr/bin/env bash
workdir=/prog/smartshelf
cd $workdir
flask run -p 5000 -h 0.0.0.0 &
echo "server started"
#!/usr/bin/env bash
workdir=/prog/smartshelf
cd $workdir
pid=$(ps -ef | grep "flask" | grep -v grep | awk '{print $2}')
echo $pid
sleep 2
kill $pid
echo "server stop"
sleep 1
flask run -p 5000 -h 0.0.0.0 &
echo "server restart"
from flask import Flask
from flask_babel import Babel
from config import Config
import logging
from logging.handlers import RotatingFileHandler,TimedRotatingFileHandler
# from flask_socketio import SocketIO
def setup_log():
# 设置日志的记录等级
logging.basicConfig(level=Config.LOG_LEVEL) # 调试debug级
# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler(Config.LOG_FOLDER, maxBytes=1024 * 1024 * 100, backupCount=10)
# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
# log_file_handler = TimedRotatingFileHandler(filename='logs/smartshelf.log', when="D", interval=1, backupCount=3)
formatter = logging.Formatter('%(asctime)s : %(message)s')
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局的日志工具对象(flask app使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)
setup_log()
app = Flask(__name__)
babel = Babel(app)
app.config.from_object(Config)
LANGUAGES = {
"zh": "Chinese",
"en": "English",
"ja": "Japanese"
}
@babel.localeselector
def get_locale():
return request.accept_languages.best_match(LANGUAGES.keys())
from app import routes,post,led_strip,driver_gpio,autoback
# return app
\ No newline at end of file \ No newline at end of file
# codinf:utf-8
import os
import time
from flask import render_template, Response, request,redirect,url_for
from werkzeug.utils import secure_filename
from app import app
import logging
import pexpect
import json
import zipfile
import shutil
import csv
import requests
import re
from config import Config
basepath = os.path.dirname(__file__)
def backup():
try:
source_dir = '/prog/backup/'
today = source_dir + time.strftime('%Y%m%d')
if not os.path.exists(today):
os.mkdir(today)
cmd = "cp -rf /prog/smartshelf/* /prog/backup/{}/".format(time.strftime('%Y%m%d'))
run = pexpect.spawn('su -c "%s" root' %cmd)
time.sleep(2)
run.sendline('xxx')
logging.warning("备份成功")
except Exception as e:
logging.warning("备份失败:{}".format(e))
def read_ip():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + 'ipconfig.csv','r') as f:
reader = csv.reader(f)
current = [row for row in reader]
ip = current[0][0]
return ip
def read_version():
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","r") as f:
s_version=f.readline()
return s_version
def confirm_version(version):
logging.warning("写入最新版本号:{}".format(version))
uploads_path = basepath + Config.STATE_PATH
with open(uploads_path + "version.txt","w") as f:
f.write(str(version))
f.close()
@app.route('/upgrade',methods=['POST'])
def upgrade():
ip = read_ip()
ip = ip.replace('/myproject', '')
# ip = 'http://192.168.1.99'
download_url = '{}/download/version.txt'.format(ip)
logging.warning("服务器最新版本信息:{}".format(download_url))
try:
response = requests.get(download_url)
if response.status_code == 200:
version = response.json()
s_version = read_version()
logging.warning("当前版本:{},最新版本:{}".format(s_version,version))
if str(s_version) == str(version):
info = {'operation':'当前版本已是最新版本!'}
else:
download_zip(ip,version)
backup()
time.sleep(2)
process_file()
time.sleep(2)
confirm_version(version)
reboot()
info = {'operation':'已升级到最新版本'}
else:
info = {'operation':'服务器地址错误'}
except Exception as e:
logging.warning("发生错误:{}".format(e))
info = {'operation':'发生错误'}
return json.dumps(info)
def download_zip(ip,version):
zip_url = '{}/download/{}.zip'.format(ip,version)
logging.warning("服务器最新文件:{}".format(zip_url))
target_path = '/prog/upgrade_cach/smartshelf.zip'
File=requests.get(zip_url, stream=True)
with open(target_path,'wb+') as f:
for chunk in File.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.close()
def process_file():
zfile = zipfile.ZipFile('/prog/upgrade_cach/smartshelf.zip','r')
path2 = '/prog/update/smartshelf/'
n_train = 0
for filename in zfile.namelist():
if filename.endswith('/'):
n_train += 1
os.makedirs(os.path.join(path2, filename))
else:
data = zfile.read(filename)
file = open(os.path.join(path2, filename), 'w+b')
file.write(data)
file.close()
time.sleep(5)
py_source = '/prog/update/smartshelf/app/'
templates_source = '/prog/update/smartshelf/app/templates/'
py_target = '/prog/smartshelf/app/'
template_target = '/prog/smartshelf/app/templates/'
templates_lis = os.listdir(path=templates_source)
py_lis = os.listdir(path=py_source)
logging.warning("待更新文件:{},{}".format(py_lis,templates_lis))
for t_file in templates_lis:
t_filename = os.path.join(templates_source,t_file)
if os.path.isfile(t_filename):
try:
shutil.copy(t_filename, template_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
# print("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
for p_file in py_lis:
p_filename = os.path.join(py_source,p_file)
if os.path.isfile(p_filename):
try:
shutil.copy(p_filename, py_target)
except IOError as e:
logging.warning("Unable to copy file. %s" % e)
except Exception as e:
logging.warning("Unexpected error: %s" % e)
shutil.rmtree(path2)
os.remove('/prog/upgrade_cach/smartshelf.zip')
# shutil.rmtree('/prog/upgrade_cach/')
logging.warning("templates upgrade success")
def reboot():
os.system('/prog/./restart.sh')
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
\ No newline at end of file \ No newline at end of file
import RPi.GPIO as GPIO
import time
def init(gpiox):
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpiox,GPIO.OUT)
def gpio_high(gpiox):
GPIO.output(gpiox, GPIO.HIGH)
def gpio_low(gpiox):
GPIO.output(gpiox, GPIO.LOW)
def clean():
GPIO.cleanup()
\ No newline at end of file \ No newline at end of file
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
config and init 24-LEDs-stripe
"""
from neopixel import *
# import logger
from rpi_ws281x import Adafruit_NeoPixel, Color,PixelStrip
LED_COUNT = 750 # 要控制LED的数量.
# LED_PIN = 18 # GPIO接口 (PWM编码).
LED_BRIGHTNESS = 100 # 设置LED亮度 (0-255)
#以下LED配置无需修改
LED_FREQ_HZ = 800000 # LED信号频率(以赫兹为单位)(通常为800khz)
LED_DMA = 10 # 用于生成信号的DMA通道(尝试5)
LED_INVERT = False # 反转信号(使用NPN晶体管电平移位时)
LED_CHANNEL = 0
stop_flag = None
def get_strip(pin=12):
LED_PIN = pin
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS,LED_CHANNEL)
# Initialize the library (must be called once before other functions).
# log.debug("Initialize: " + str(strip))
strip.begin()
return strip
def color_wipe_full(strip, color, wait_ms=50):
"""Wipe color across display a pixel at a time."""
for i in range(strip.numPixels()):
strip.setPixelColor(i, color)
strip.show()
# time.sleep(wait_ms/1000.0)
def reset_strip(strip):
strip.setBrightness(LED_BRIGHTNESS)
color_wipe_full(strip, Color(0,0,0), 20)
# log.debug('LED stripe cleared.')
return
# noinspection PyProtectedMember
def _cleanup_strip(strip: Adafruit_NeoPixel):
strip._cleanup()
\ No newline at end of file \ No newline at end of file
# Translations template for PROJECT.
# Copyright (C) 2021 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-04-08 16:38+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n"
#: templates/base.html:6 templates/ledtest.html:6 templates/shelfconfig.html:6
msgid "智能料架系统"
msgstr ""
#: templates/base.html:23 templates/ledtest.html:23
#: templates/shelfconfig.html:79
msgid "亮灯料架"
msgstr ""
#: templates/base.html:27 templates/ledtest.html:27
#: templates/shelfconfig.html:83
msgid "控制"
msgstr ""
#: templates/base.html:28 templates/ledtest.html:28
#: templates/shelfconfig.html:84
msgid "测试"
msgstr ""
#: templates/base.html:29 templates/ledtest.html:29
#: templates/shelfconfig.html:85
msgid "料架配置"
msgstr ""
#: templates/base.html:45 templates/ledtest.html:45
#: templates/shelfconfig.html:101
msgid "料架系统"
msgstr ""
#: templates/base.html:50
msgid "开关"
msgstr ""
#: templates/base.html:53
msgid "启动"
msgstr ""
#: templates/base.html:54
msgid "停止"
msgstr ""
#: templates/base.html:62 templates/ledtest.html:137
#: templates/shelfconfig.html:154
msgid "提醒消息"
msgstr ""
#: templates/base.html:67 templates/ledtest.html:142
#: templates/shelfconfig.html:159
msgid "运行状态"
msgstr ""
#: templates/base.html:72 templates/ledtest.html:152
#: templates/shelfconfig.html:164
msgid "配置文件加载状态"
msgstr ""
#: templates/base.html:77 templates/shelfconfig.html:124
#: templates/shelfconfig.html:169
msgid "服务器地址"
msgstr ""
#: templates/base.html:82 templates/shelfconfig.html:130
#: templates/shelfconfig.html:174
msgid "料架编号"
msgstr ""
#: templates/base.html:87
msgid "服务器连接状态"
msgstr ""
#: templates/base.html:96 templates/ledtest.html:131
#: templates/shelfconfig.html:148
msgid "运行日志&状态信息"
msgstr ""
#: templates/base.html:101
msgid "日志下载"
msgstr ""
#: templates/base.html:104
msgid "下载日志"
msgstr ""
#: templates/base.html:111
msgid "日志"
msgstr ""
#: templates/ledtest.html:50
msgid "灯条测试"
msgstr ""
#: templates/ledtest.html:53 templates/ledtest.html:109
msgid "通道"
msgstr ""
#: templates/ledtest.html:60 templates/ledtest.html:88
#: templates/ledtest.html:116
msgid "颜色"
msgstr ""
#: templates/ledtest.html:70
msgid "灯条全开"
msgstr ""
#: templates/ledtest.html:71
msgid "灯条关闭"
msgstr ""
#: templates/ledtest.html:77
msgid "库位操作测试"
msgstr ""
#: templates/ledtest.html:80
msgid "库位"
msgstr ""
#: templates/ledtest.html:98 templates/ledtest.html:124
msgid "亮灯"
msgstr ""
#: templates/ledtest.html:99 templates/ledtest.html:125
msgid "灭灯"
msgstr ""
#: templates/ledtest.html:100
msgid "重置"
msgstr ""
#: templates/ledtest.html:106
msgid "状态灯测试"
msgstr ""
#: templates/ledtest.html:147
msgid "测试消息"
msgstr ""
#: templates/shelfconfig.html:106
msgid "配置文件"
msgstr ""
#: templates/shelfconfig.html:110
msgid "选择文件"
msgstr ""
#: templates/shelfconfig.html:113
msgid "上传"
msgstr ""
#: templates/shelfconfig.html:119
msgid "服务器配置"
msgstr ""
#: templates/shelfconfig.html:134
msgid "保存"
msgstr ""
#: templates/shelfconfig.html:139
msgid "控制器备份&升级"
msgstr ""
#: templates/shelfconfig.html:143
msgid "料架升级"
msgstr ""
#: templates/shelfconfig.html:179
msgid "操作提醒"
msgstr ""
#: templates/shelfconfig.html:184
msgid "软件版本"
msgstr ""
此文件的差异被折叠, 点击展开。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件类型无法预览
此文件的差异被折叠, 点击展开。
此文件类型无法预览
此文件的差异太大,无法显示。
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!