首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于web页面开发串口程序界面---代码实现

基于web页面开发串口程序界面---代码实现

原创
作者头像
MiaoGIS
修改于 2020-09-14 09:48:47
修改于 2020-09-14 09:48:47
1.4K02
代码可运行
举报
文章被收录于专栏:Python in AI-IOTPython in AI-IOT
运行总次数:2
代码可运行

对应的js代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$(function () {

    $('.dropdown-toggle').dropdown();
    $.get('com/ports', function (data) {
        var liTemplate = _.template('<li data-value="<%=device%>"><a href="#"><%=device%></a></li>');
        _(data['result']).each(x => {
            $('[data-role="ulPort"]').append($(liTemplate(x)));

        })

        $("[data-role=ulPort],[data-role=ulBaudrate],[data-role=ulBytesize],[data-role=ulParity],[data-role=ulStopbits]").find('li').click(function (e) {
            console.log($(this));
            $(this).addClass('active').siblings().removeClass('active');
        });
        $("[data-role=open]").click(function () {
            if (!$('[data-role=ulPort] li').hasClass('active')) {
                $('[data-role=info] p').text("请先选择一个串口!");
                return
            }

            var com = _.object($('#init').find('ul[data-role]').map(function (index, item) {
                return [[$(item).data('role').slice(2).toLowerCase(), $(item).find('li.active').data('value')]]
            }));
            console.log(com);
            $.post('com/open', {
                'com': JSON.stringify(com)
            }, function (data) {
                if (data['result']) {
                    $('[data-role=info] p').text("串口打开成功!");
                    $('[data-role="readwrite"]').removeClass('hide');
                }
            });
            console.log('open');
        });
        $("[data-role=close]").click(function () {
            if (!$('[data-role=ulPort] li').hasClass('active')) {
                $('[data-role=info] p').text("请先选择一个串口!");
                return
            }

            $.post('com/close', function (data) {
                if (!data['result']) {
                    $('[data-role=info] p').text("串口已经关闭!");
                    $('[data-role="readwrite"]').addClass('hide');
                }
            });
            console.log('close');
        });
        $("[data-role=clear]").click(function () {
            $('#result').val('');
        })

        $("[data-role=send]").click(function () {
            var cmdText = $("#cmdText").val();

            console.log(cmdText);
            $.post('com/read', {
                cmd: cmdText,

            }, function (data) {
                var hexes = data.result.hexes;
                var text = hexes.map(function (item) {
                    return item
                }).join(' ');


                $('#result').val(text);
                console.info(data);
            }).error(function () {
                alert("请先打开串口或重新发送!")
            });

            $('#result').val('');
        })

        console.log(data);
    });
    $('body').delegate('[data-role=read]', 'click', function () {
        var $panel = $(this).parents('[data-read]');
        var callback = $panel.data('callback');
        var cmdText = $panel.data('read');
        var params = $panel.find('[data-field]').map((x, y) => _.object(["field", "type", "size"], [$(y).data('field'), $(y).data('type'), $(y).data('size')])).toArray();
        console.log(cmdText);
        $.post('com/read', {
            cmd: cmdText,
            params: JSON.stringify(params)
        }, function (data) {
            if (data.result == 0) {
                alert("由于调试字节流突然涌入,本次命令失效,请重新发送命令!")
                return;
            }
            var hexes = data.result.hexes;

            var text = hexes.map(function (item) {
                return item
            }).join(' ');
            if (!!callback) {

                window[callback].apply(this, data.result.data);
            }

            data.result.data.forEach((x, y) => {
                $panel.siblings().find('[data-field]').eq(y).data('value', x).val(x)
            });
            $('#result').val(text);
            console.info(data);
        }).error(function () {
            alert("请先打开串口或重新发送!")
        });
    });


    $('body').delegate('[data-role=write]', 'click', function () {

        var $panel = $(this).parents('[data-write]');
        var cmdText = $panel.data('write');
        var params = $panel.siblings('[data-read]').find('[data-field]').map((x, y) => _.object(["field", "type", "size"], [$(y).data('field'), $(y).data('type'), $(y).data('size')])).toArray();
        console.log(cmdText);
        $.post('com/write', {
            cmd: cmdText,
            params: JSON.stringify(params)
        }, function (data) {
            var hexes = data.result.hexes;
            if (data.result == 0) {
                alert("由于调试字节流突然涌入,本次命令失效,请重新发送命令!")
                return;
            }
            var text = hexes.map(function (item) {
                return item
            }).join(' ');



            $('#result').val(text);
            console.info(data);
        }).error(function () {
            alert("请先打开串口或重新发送!")
        });


    });

    function initTabs(a, b, count) {
        var tabsTemplate = _.template($('#tabsTemplate').html());
        $("#tabsContainter").html(tabsTemplate({
            sensors: _.range(1, count + 1)
        }));
        $('#tabsContainter [data-toggle="tab"]').tab();

        var tableTemplate = _.template($('#tableTemplate').html());
        $("#tableContainter").html(tableTemplate({
            sensors: _.range(1, count + 1)
        }));


        var sensors = _.map(_.range(count), function (item, index) {
            return "0000";
        });
        initBordertablepanel(sensors);

        initStripedtable(_.range(1, count + 1));
    }

    function initStripedtable(sensors) {

        var stripedtableTemplate = _.template($('#stripedtableTemplate').html());
        $("#stripedtableContainter").html(stripedtableTemplate({
            sensors: sensors
        }));

    }

    function initBordertablepanel(sensors) {
        sensors = Object.values(arguments).flat();
        var bordertablepanelTemplate = _.template($('#bordertablepanelTemplate').html());
        $("#bordertablepanelContainter").html(bordertablepanelTemplate({
            sensors: sensors
        }));

    }

     function initBordertable(sensors) {
        sensors = Object.values(arguments).flat();
        var bordertableTemplate = _.template($('#bordertableTemplate').html());
        $("#bordertableContainter").html(bordertableTemplate({
            sensors: sensors
        }));

    }
    
    function refreshBordertable(sensors) {
        sensors = Object.values(arguments);
        console.log(sensors);
        $('#bordertableContainter tbody tr').find('td:first').each(function (index) {
            $(this).html(dictKey2Name[sensors[index]]);
        });

    }
    window.dictKey2Name = {
        '0010': '温度',
        '0030': '湿度',
        '0016': '气压',
        '0013': '风速',
        '0014': '风向',
        '0011': 'PM25',
        '0032': 'PM10',

        '0019': 'PM100',
        '0012': '噪声',

    }



    window.initTabs = initTabs;
    window.initBordertable = initBordertable;
    window.refreshBordertable = refreshBordertable;
})

后台web框架和串口操作采用的是Python语言,其中web框架使用的是tornado。

web网站代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import os
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tools
from tornado.options import define,options
import json
define('port',default=9001,type=int,help="input your port")

class indexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')
class readHandler(tornado.web.RequestHandler):
    def post(self):
        cmdText=self.get_argument('cmd')
        params=self.get_argument('params',None)
        hexes=tools.writeText(cmdText)
        if not params:
            self.write({'result':{'hexes':hexes}})
            return 
                   
        print(hexes[0]!='01')
        if(hexes[0]!='01'):
            self.write({'result':0})        
        data=tools.parseText(' '.join(hexes),json.loads(params))
        result={'hexes':hexes,'data':data}
        self.write({'result':result})
#未实现    
class writeHandler(tornado.web.RequestHandler):
    def post(self):
        pass
        

class portsHandler(tornado.web.RequestHandler):
    def get(self):
        result=tools.getPorts()
        self.write({'result':result})
class openHandler(tornado.web.RequestHandler):
    def post(self):
        print(dir(self))
        com=self.get_argument('com')
        com=json.loads(com)
        print(com)
        stopbits=com.get('stopbits',1)
        result=tools.begin(com.get('port',None),\
                           int(com.get('baudrate',115200)),\
                           int(com.get('bytesize',8)),\
                           com.get('parity',"N"),\
                           stopbits)
        self.write({'result':True})
        
class closeHandler(tornado.web.RequestHandler):
    def post(self):       
        result=tools.end()
        self.write({'result':result})

app=tornado.web.Application(
	handlers=[(r'/',indexHandler),
            (r'/index',indexHandler),
            (r'/com/open',openHandler),
            (r'/com/close',closeHandler),
            (r'/com/read',readHandler),
            (r'/com/write',writeHandler),
            (r'/com/ports',portsHandler)
		],static_path=os.path.join(os.curdir,'static'),
        template_path=os.path.join(os.curdir,'template'),debug=True
        )
if __name__=='__main__':
    tools.init()
    print(tools.s2)
    tornado.options.parse_command_line()
    httpserver=tornado.httpserver.HTTPServer(app)
    httpserver.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

串口操作tools.py代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import os
if os.name == 'nt':  # sys.platform == 'win32':
    import serial.tools.list_ports_windows as list_ports
    import list_ports_winreg as list_ports
elif os.name == 'posix':
    import serial.tools.list_ports_posix as list_ports

import serial
import time
import json
text='01 03 30 08 00 06 0A 4B'
#from serial.tools import list_ports
from datetime import datetime
import numpy as np
testSend1="01 03 10 00 01 7c 7b 41"
 
testReceive1="""
01 03 10 00 02 F8 23 03 33 30 42 30 37 31 38 31 32 30 33 30 31 32 00 00 39 32 36 30 00 32 31 38 32 31 38 2E 32 38 2E 37 31 2E 32 32 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 31 38 31 31 31 00 39 32 36 30 00 00 43 4D 4D 54 4D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 78 00 02 00 0A 00 50 00 78 00 3C 00 0A 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 09 00 01 00 10 00 54 45 4D 50 00 00 00 00 01 00 08 00 E8 03 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 00 00 00 00 00 00 02 00 30 00 48 55 4D 00 00 00 00 00 01 00 09 00 E7 03 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 00 00 02 00 00 00 12 00 16 00 50 52 45 53 53 00 00 00 01 00 0C 00 B0 04 00 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 00 00 00 00 00 00 03 00 13 00 57 53 00 00 00 00 00 00 01 00 0B 00 2C 01 00 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 00 00 00 00 00 00 04 00 14 00 57 44 00 00 00 00 00 00 00 00 0A 00 10 0E 00 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 00 00 00 00 00 00 05 00 11 00 50 4D 32 35 00 00 00 00 00 00 06 00 E8 03 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 06 00 00 00 00 00 06 00 32 00 50 4D 31 30 00 00 00 00 00 00 06 00 E8 03 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 06 00 02 00 00 00 14 00 19 00 50 4D 31 30 30 00 00 00 00 00 06 00 20 4E 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 06 00 00 00 00 00 18 00 12 00 4E 6F 69 73 65 00 00 00 01 00 0E 00 20 4E 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 80 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 24 13
"""

def calc_crc(string):
    data = bytearray.fromhex(string)
    crc = 0xFFFF
    for pos in data:
        crc ^= pos
        for i in range(8):
            if ((crc & 1) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return '{:04x}'.format(((crc & 0xff) << 8) + (crc >> 8))

 
def getPorts():
    ports=list_ports.comports()
    result=list(map(lambda x:{"device":x.device},ports))
    return result


def begin(port,baudrate,bytesize,parity,stopbits):
    if port is None:
        return False
    global s2
    if(s2.is_open):
        s2.close()
    s2=serial.Serial(port=port, baudrate=baudrate, bytesize=bytesize, 
                      parity=parity, stopbits=stopbits, timeout=5)
    return s2.is_open
    
def end():
    global s2
    if(s2.is_open):
        s2.close()
    return s2.is_open
    



def writeText(text):
    #print(text)
    hexs=map(lambda x:int(x,base=16),text.split())
    s2.write(bytes(hexs))
    time.sleep(5)
    text=s2.read_all()
    text=list(map(lambda x:'{0:02x}'.format(x),text))
    #print(text)
    return text

 
def checkText(text):
    hexstrs=text.split()
    length=int(hexstrs[4]+hexstrs[5],16)
    calccode=calc_crc(' '.join(hexstrs[:length+6]))
     
    #checkcode=''.join(hexstrs[length+6:length+8][::-1])
    checkcode=''.join(hexstrs[-2:][::-1])
    if(int(checkcode,16)==int(calccode,16)):
        return True


def getBody(text):
    hexstrs=text.split()
    length=int(hexstrs[4]+hexstrs[5],16)
    
    if not checkText(text):
        return (False,)
    body=hexstrs[6:length+6]
    return body



def parseText(text,formats):
    
    c=list(map(lambda x:x['size'],formats))

    a=text.split()[6:6+sum(c)*2] 
    b=enumerate(formats)
    d=np.cumsum(c)
    e=d-c
     
    result=map(lambda x:dictParse[x[1]['type']](a[e[x[0]]*2:x[1]['size']*2+e[x[0]]*2]),b)
    result=list(result)
    return result

def reverseRecord(record,formats):
    result=[]
    bytesArray=map(lambda x:dictReverse[x[1]['type']](record[x[0]]),enumerate(formats))
    for i in bytesArray:
        result=result+i
    return result

def parseTIME_HEX(xs):
    result=map(lambda x:parseNUMBER_HEX(x),xs)
    result= list(result)
    result[0]=result[0]+2000
    result=datetime(*result).strftime("%Y-%m-%d %H:%M:%S")
    return result

def reverseTIME_HEX(text):
    date=datetime.strptime(text,"%Y-%m-%d %H:%M:%S")
    result=[date.year-2000,date.month,date.day,date.hour,date.minute,date.second]
    result=list(map(lambda x:reverseNUMBER_HEX(x),result))
    return result

def parseREVERSE_STR(xs):
    xs.reverse()
    result=''.join(xs)
    return result


def parseSTR(xs):
    
    result=''.join(xs)
    return result
def reverseREVERSE_STR(text):
    result=zip(text[::2],text[1::2])
    result=list(map(lambda x:x[0]+x[1],result))
    result.reverse()
    
    return result

def reverseSTR(text):
    result=zip(text[::2],text[1::2])
    result=list(map(lambda x:x[0]+x[1],result))
     
    
    return result


def parseREVERSE_NUMBER(xs):
    xs.reverse()
    result=''.join(xs)
    result=int(result,16)
    return result

def reverseREVERSE_NUMBER(text):
    result=int(text)
    result='{:04x}'.format(result)
    result=reverseREVERSE_STR(result)
    return result
    
    
def parseBYTES(xs):
    #print(xs)
    result=bytes.fromhex(''.join(xs)).decode().strip('\x00')
    return result
    
def reverseBYTES(text,length):
    result=text.encode().hex()
    result='{0:0<{1}s}'.format(result,length)
    result=reverseREVERSE_STR(result)[::-1]
    return result

def parseNUMBER_HEX(xs):
    return int(xs,16)

def parseNUMBER_HEXS(xs):
    result=map(lambda x:str(parseNUMBER_HEX(x)),xs)
    result=''.join(result)
    return result
def reverseNUMBER_HEX(x):
    return '{:02x}'.format(int(x))

def parseNUMBERS_HEX(xs):
    return int(''.join(xs),16)

def reverseNUMBERS_HEX(text):
    result='{:04x}'.format(int(text))
    result=reverseREVERSE_STR(result)[::-1]
    return result

def reverseNUMBER_HEXS(text):
    result=map(lambda x:'{:02d}'.format(int(x)),text)
    return ''.join(result)

def parseNUMBER_BITS(xs):
    result=int(''.join(xs),16)
    result='{:016b}'.format(result)
    return result

def reverseNUMBER_BITS(text):
    result=int(text,2)
    result='{:04x}'.format(result)
    return result
    
def init():

 
    global s2
    s2=serial.SerialBase()
    global dictParse
    dictParse={"STR":parseSTR,"NUMBER_BITS":parseNUMBER_BITS,
               "NUMBER_HEXS":parseNUMBER_HEXS,"REVERSE_NUMBER":parseREVERSE_NUMBER,
               "TIME_HEX":parseTIME_HEX,"NUMBERS_HEX":parseNUMBERS_HEX,
               'REVERSE_STR':parseREVERSE_STR,'BYTES':parseBYTES}
    global dictReverse
    dictReverse={"STR":reverseSTR,"NUMBER_BITS":reverseNUMBER_BITS,
                 "NUMBER_HEXS":reverseNUMBER_HEXS,"REVERSE_NUMBER":reverseREVERSE_NUMBER,
                 "TIME_HEX":reverseTIME_HEX,"NUMBERS_HEX":reverseNUMBERS_HEX,
                 'REVERSE_STR':reverseREVERSE_STR,'BYTES':reverseBYTES}

list_ports_winreg.py用于识别通过软件虚拟的串口,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#! python
#
# Enumerate serial ports on Windows including a human readable description
# and hardware information using winreg.
#
# Using winreg helps find virtual comports

try:
    # Python 3.X
    import winreg
except ImportError:
    # Python 2.7 compatibility
    try:
        import _winreg as winreg
    except ImportError:
        winreg = None

from serial.tools import list_ports_common
from serial.tools import list_ports_windows


SERIAL_REGISTRY_PATH = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'


def regval_to_listport(winport):
    """Convert a windows port from registry key to pyserial's ListPortInfo.
    Args:
        winport (tuple): Windows registry value (description, device, value).
    Returns:
        listport (ListPortInfo): comport device details.
    """
    # Create the ListPortInfo
    description, device, _ = winport
    listport = list_ports_common.ListPortInfo(device)

    # Format the description like other ListPortInfo
    description = description.replace('\\Device\\', '')
    listport.description = "{} ({})".format(description, device)

    return listport
# end regval_to_listport


def winreg_comports():
    """Return windows comports found in the registry.
    See Also:
        list_ports_winreg.comports(), list_ports_winreg.comports_list(),
        list_ports_windows.comports()
    Note:
        This should include virtual comports, and it is significantly faster
        than list_ports_windows.comports(). However, list_ports_windows has far
        more information. comports() contains all list_ports_windows.comports()
        and winreg_comports() that were not found from list_ports_windows.
    Returns:
        comports (list): Sorted list of ListPortInfo.
    """
    try:
        # Get the Serial Coms registry
        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, SERIAL_REGISTRY_PATH)

        # Get key info - number of values (subkeys, num_vals, last_modified)
        num_values = winreg.QueryInfoKey(key)[1]

        # Make a generator of comports
        for i in range(num_values):        
            # get registry value for the comport
            value = winreg.EnumValue(key, i)
            yield regval_to_listport(value)

        # Close the registry key
        winreg.CloseKey(key)
    except (AttributeError, WindowsError, EnvironmentError):
        # winreg is None or there was a key error
        pass
# end winreg_comports


def comports_list():
    """Return a list of comports found from list_ports_windows and comports
    found in the window registry.
    
    See Also:
        list_ports_winreg.comports(), list_ports_winreg.winreg_comports(),
        list_ports_windows.comports()
    Note:
        This should include virtual comports. This method contains all
        list_ports_windows.comports() and winreg_comports() that were not found
        from list_ports_windows.
    Returns:
        comports (list): List of ListPortInfo comport details.
    """
    comports = list(list_ports_windows.comports())

    comports[len(comports): ] = [li for li in winreg_comports()
                                 if li not in comports]

    return comports
 


def comports():
    """Generator for comports found from list ports windows and comports found
    in the windows registry.
    See Also:
        list_ports_winreg.comports_list(), list_ports_winreg.winreg_comports(),
        list_ports_windows.comports()
    Note:
        This should include virtual comports. This method contains all
        list_ports_windows.comports() and winreg_comports() that were not found
        from list_ports_windows.
    Yields:
        comport (ListPortInfo): Comport details.
    Returns:
        comports (generator): Generator of ListPortInfo comports.
    """
    existing = []
    for comport in list_ports_windows.comports():
        existing.append(comport)
        yield comport

    for li in winreg_comports():
        if li not in existing:
            existing.append(li)
            yield li
 
if __name__ == '__main__':
    
    for port, desc, hwid in sorted(comports()):
        
        print("%s: %s [%s]" % (port, desc, hwid))

上面便是这个程序的全部代码了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于web页面开发串口程序界面---html代码
代码实现只展示读取设备参数的功能,写入即设置设备参数目前没有开发需求。 首先是html代码如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <
MiaoGIS
2020/09/14
4.1K0
基于web页面开发串口程序界面---html代码
基于web页面开发串口程序界面---后台实现
经测试,当使用软件创建的虚拟串口时,系统自带的serial库查询不到,所以这里同时引用了在网上找的一段代码list_ports_winreg.py,经测试可以查询到虚拟串口。
MiaoGIS
2020/09/14
9560
基于web页面开发串口程序界面---后台实现
python的pyserial模块
pyserial是python提供用于进行串口通信的库 源文档:https://pythonhosted.org/pyserial/ 1、安装pyserial pip install pyserial 2、查看电脑现连串口设备 import serial.tools.list_ports #检测设备的端口数 # plist = list(serial.tools.list_ports.comports()) # if len(plist) <= 0: # print("没有发现端口!") # e
py3study
2020/01/06
2.2K0
Web开发---单页面应用(签到日报--技术实现)
疫情前期,员工分布在各个地区,需要上报个人的健康状态和位置信息,于是做了一个单页面应用(当时钉钉和微信上的健康上报模板还没出现)
MiaoGIS
2020/03/16
8930
Web开发---单页面应用(签到日报--技术实现)
Python开发---单选题考试H5页面
调查问卷通常采用选择题来方便问卷对象更简单快速完成调查。而且为了统计分析更加有针对性和明确性,调查问卷题目设计成单选题更合理有效。即使是现实情况下涉及多条选项更合理的题目,也可以用“最喜欢”,答案“都有”,或者答案组合(1)(3)(6)设计为单个选项等还用单选题的形式来收集答案。下面介绍类似调查问卷的单选题考试的H5微应用。
MiaoGIS
2022/03/03
8020
Python开发---单选题考试H5页面
前端开发---异步上传文件
有一个名为ajaxFileUpload的JQuery插件可以利用iframe来实现前端页面中异步上传文件。
MiaoGIS
2020/11/25
1.6K0
前端开发---异步上传文件
高质量编码--Python开发串口读取程序
下图是一款多功能声级计,是采用数字信号处理技术的新一代噪声测量仪器,它支持将实时测量的数据通过串口输出。
MiaoGIS
2023/03/06
1.3K0
高质量编码--Python开发串口读取程序
【开源】PyQT+Pyserial开发的串口调试工具
串口调试工具是我们做嵌入式开发常用的工具,市面上已经有很多串口调试工具了,博主写这款串口调试工具一方面是为了学习Python PyQT Pyserial 相关的知识,另一方面是也是可以为后续基于此设计更多的串口自动化工具。所以本文会详细介绍如何使用PyQT+Pyserial实现一款串口调试工具。
物联网布道师
2023/02/28
2.3K0
【开源】PyQT+Pyserial开发的串口调试工具
我的小工具-nodejs串口转TCP调试通信
工作上,每次都怕让联调采集前置服务调试通信业务,上传记录,下载参数。去哪找流量卡?而且,有的机器型号是cdma,有的是gprs,有的机器通信模块还坏了。想到搞个串口通信方式吧,与电脑连接,在电脑上做个工具中专转tcp与采集通信。 提高下工作效率。且如果现场的机器,通信模块坏了,利用此工具,把车载机通过串口接到电脑上,主要电脑能联网,可以通过电脑网络把记录上传上去。且,通信日志,一目了然,便于分析
杨永贞
2020/08/04
1.7K0
基于Appium实现UI遍历工具(五)代码实现篇(中)
主要封装了一些常用的方法,方便后续的调用,增加了隐形等待,让元素定位更加不受外在的影响。
雷子
2022/09/29
1K0
高质量编码-事件图层前端交互设计
当滑块位置变化时,将滑块位置对应的数值保存在$('[data-role=realPay]')对应的DOM上。滑块事件代码如下:
MiaoGIS
2019/05/23
7270
高质量编码-事件图层前端交互设计
高质量编码-克里金插值地图可视化(后台缓存优化)
实际在web页面中根据真实数据即时运行上面三个步骤的计算,因为模型训练涉及到的数学计算量很大,可能需要很长时间才能得到结果,前端javascript耗时统计如下:
MiaoGIS
2021/08/20
1.9K0
高质量编码-克里金插值地图可视化(后台缓存优化)
Python Qt GUI设计:做一款串口调试助手(实战篇—1)
Python Qt GUI设计系列博文终于到了实战篇,本篇博文将贯穿之前的基础知识点实现一款串口调试助手。
不脱发的程序猿
2022/01/13
6.9K0
Python Qt GUI设计:做一款串口调试助手(实战篇—1)
Python解决小需求-歌词同步代码实现
无论是哪个在线音乐网站,当我们看歌词时,歌词都会有滚动显示歌词的功能,而且当前正播放的那句歌词样式和别的行歌词样式不同,通常是颜色加重字体加大。所以我们可以在前端控制台里利用jQuery样式选择器来获得当前歌词。
MiaoGIS
2020/07/07
1.2K0
Python解决小需求-歌词同步代码实现
hitcon2016 web writeup
当大家在为祖国母亲庆生的时候,我在打lctf,当大家正为休息而搁置的事情忙碌的时候,我在打hitcon,不过虽然有点儿辛苦,但是一场国内的优质比赛加上顶级的国外比赛,还是让我打开了新世界的大门,orange菊苣大法叼…
LoRexxar
2023/02/21
3500
hitcon2016 web writeup
HC小区管理系统项目前端页面开发流程梳理
在我之前写的文章你一定没见过这样高度适配的接口,HC小区管理系统后端项目源码难点梳理 中我们一起梳理了后端项目MicroCommunity的开发流程和难点,当时前端项目MicroCommunityWeb尚未梳理,而前端项目MicroCommunityWeb对于
用户3587585
2024/06/13
6560
HC小区管理系统项目前端页面开发流程梳理
【python】【Djang】GPS/北斗串口数据实时定位百度地图
本项目为从串口读取GPS/北斗设备接收数据,进行处理后使用百度地图api实时显示定位。
一点儿也不潇洒
2018/12/13
7.1K2
【python】【Djang】GPS/北斗串口数据实时定位百度地图
人生苦短,我用Python-手把手教你如何使用python写串口调试助手
  笔者这里使用的是QTCreator和Python来实现一个简单的串口上位机的开发的简单过程,使用到Python,之前记录的Qt 使用C++ 写上位机也记录一篇文章,大家感兴趣的话可以看看。从零开始编写一个上位机(串口助手)QT Creator + C++
用户8913398
2023/03/05
6.8K0
人生苦短,我用Python-手把手教你如何使用python写串口调试助手
Web Spider XHR断点 千千XX 歌曲下载(三)
首先声明: 此次案例只为学习交流使用,切勿用于其他非法用途 注:网站url、接口url请使用base64.b64decode自行解码
EXI-小洲
2023/01/13
3960
Web Spider XHR断点 千千XX 歌曲下载(三)
Python开发物联网数据分析平台---web框架
前端使用Bootstrap主题框架AdminLTE,后台使用python语言的tornado作为web框架。利用tornado的模板作为主要的动态页面生成方式,以及巧妙使用模板将json数据渲染到页面hidden元素的值,然后在js中直接用eval函数计算隐藏域的值来生成图表JavaScript插件所需的json数据来生成页面中相应的可视化图表。
MiaoGIS
2019/11/01
3.3K0
Python开发物联网数据分析平台---web框架
推荐阅读
相关推荐
基于web页面开发串口程序界面---html代码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档