您的位置:首页 > 其它

欢迎使用CSDN-markdown编辑器

2016-01-15 11:03 239 查看

欢迎使用JTT808解析服务器

简单介绍JTT808原理及使用方式:

配置要求

工作原理

使用教程

共同开发

代码托管

目录

欢迎使用JTT808解析服务器
目录

运行环境配置
创建虚拟运行环境

安装必要python库

建立开发目录

各个python包的简单概述

服务器配置
服务器监听IP及端口配置

解析的协议配置

简单使用教程

假设我们需要查询我们终端属性
详解所有名词

详解所有名词

怎样二次开发
基本数据流向图

结束语

运行环境配置

1 创建虚拟运行环境

pip install virtualenv
mkdir jtt808
cd jtt808
virtualenv .
source ./bin/activate


2 安装必要python库

pip install tongue
pip install sqlalchemy
pip install mysql-python


3 建立开发目录

用于存放开发源代码

mkdir src
cd src


4 各个python包的简单概述

app

这里是你可以扩展的部分,你需要做的通常只是继承父类,然后重载一些属性,即可以解析大部分协议。这里还是你编写ORM模型的地方,你可以选择保存那些数据到你的数据库里。

conf

这里只是简单配置,包含了协议配置。和服务器运行相关参数配置,例如数据库的名字及密码等。还有你需要监听的端口等~

core

这是整个框架解析的核心,包含了一个强大的基类,如果你没有理解透这里代码运行的原理。不推荐轻易修改!

docs

这个部分,目前尚未编写文档,目前只是预留。

process_signal

信号处理部分,为了与终端实时交换。我们可以在没有完全编写完整个终端设备管理系统的情景下,通过命令的方式与终端设备交换。例如,你可以按下CTRL+Z即可以进入交互模式。交互模式相对比较人性化,通常你只需输入选项前的数字即代表你的命令,系统内部会产生应答数据回复终端。你完全可以在这里查询终端的设备信息。不过,你需要记住一点,这个调试模式运行时会阻塞所有当前事务。

receiver

这里是数据的入口部分,也是决定服务器吞吐量的关口,目前设计了两种实现方案,一种是早期的suck_block_mode方式,这种方式主要是简单易于实现,不支持同时连接两个客户端,因此,其主要用于调试。第二种为suck_asyn_mode方式。这种方式能够同时支持多个连接,居然并发的能力!

shortcuts

这里包含了自动回复终端设备的模板机制,相当于打包数据。注意,其内部会调用tongue.Code对打包好的数据进行编码,然后发送产生的二进制数据到终端设备。

simulate

目前还未开发,主要用于模拟终端设备的运行。方便开发高并发的调试。

utils

提供了多种函数,用于计算数据的完整性,加密性以及产生鉴权码等等。

visual

终端视觉部分,主要提供各种不同颜色的提示方式,以区别不同数据以及错误提示等等。

服务器配置

1 服务器监听IP及端口配置

你可以在这里配置你接收数据的IP及端口号,还可以在这里配置你的数据库,等等!

cd jtt808/conf/
vim settings.py


配置好,就让咱们运行吧!

python suck_block_mode.py


2 解析的协议配置

这里是定义你需要解析的协议

vim /conf/protocols.py


例如,当我们使用的是JTT808-2013版的协议时,我们的协议定义如下表:



则我们在配置协议时可以这样配置,如下所示:

MSG_ID_ORIGINAL = pattern(
('0x0100', 'ter_reg_req'),
('0x8100', 'ser_reg_rsp'),
('0x0102', 'ter_aut_req'),
('0x8001', 'ser_com_rsp'),
('0x0200', 'position'),
('0x8104', 'get_ter_info'),
('0x0104', 'get_ter_info_rsp'),
('0x8107', 'get_ter_attr'),
('0x0107', 'get_ter_attr_rsp')
)


简单使用教程

假设我们需要查询我们终端属性

查表得知

消息ID: 0x8107

查询终端属性消息体为空

1 配置查询终端属性协议

vim /conf/protocols.py


添加如下

MSG_ID_ORIGINAL = pattern(
# Rest of Code ...
('0x8107', 'get_ter_attr'),
)


2 配置终端属性应答

我们下发终端查询属性的指令后,终端设备会回复我们,所以我们需要识别这个消息。因此我们接下来是配置这个终端属性应答。

MSG_ID_ORIGINAL = pattern(
# Rest of Code ...
('0x8107', 'get_ter_attr'),
('0x0107', 'get_ter_attr_rsp')
)


3 编写我们的视图函数

vim /app/views.py


添加代码如下:

def get_ter_attr(terminal_request):
template = 'get_ter_attr|sys_fixed_msg_attr2|client_dev_id|sys_product|'
return render(terminal_request, template)


详解所有名词

get_ter_attr

当然就是函数名了,你也可取其他名字,不过最好遵python命名规则。

terminal_request

是一个字典,它包含了终端的所有当前上传的信息。例如template里面的client_dev_id就是我们从客户上传上来的数据中获得的。

template

定义一个安装管道分割的字符串,你可以发现,它包含了 很容易理解的名字。这些都是为了让系统去查询相关的字典获取到数据后,组合起来。

get_ter_attr

还记得吧!我们自己定义的get_ter_attr消息id它对应的就是0x8107

sys_fixed_msg_attr2

这个是系统已经定义好的,其实你也可以自己定义。这个只是为了调试。它的意思是固定的系统消息属性。因为查询终端属性这条指令的消息体是空的,所以我们会看到(conf/protocols.py)里面定义的sys_fixed_msg_attr2为(0,0)所以协议中定义如下:

SYSTEM_CMD = pattern(
# Rest of Code ...
('sys_fixed_msg_attr2', (0, 0))  # Empty message content for check terminal setting
)


client_dev_id

就是客户端上传上来的数据中包含的内容,你只需要给定这个域的名字client_dev_id它会知道从客户上传上来的数据中找出来并且填充你的指令。

sys_product

也是系统定义的固定消息序列,真实运行的服务器应该是一个自增值

render

其实就是一个字典查询函数,它会查询你传人的terminal_request以及protocols.py里面定义的两个系统字典,然后拼接查询到的数据,通过tongue.Code编码发送出去。

4 编写第二个视图函数

这个函数用于响应设备终端上传上来的数据,我们这里只是简单的打印出来。

def terminal_attr(terminal_request):
print "terminal attribute", terminal_request


5 告诉系统我们有了一些新的视图

打开app/urls.py我们这里可以设置每条消息ID该映射到对应视图的地方。我们设置如下:

from app import views
urlpatterns = pattern(
('ser_reg_rsp', views.register),
('ter_aut_req', views.auth),
('position', views.position),
('get_ter_info_rsp', views.terminal_info),
('get_ter_attr_rsp', views.terminal_attr)
)


详解所有名词

views

就是前面我们写视图函数的地方,只不过导入时我们不需要写成views.py啦!

urlpatterns

出自Django的urls中,我们这里也使用这个名词。如果你使用过django那它的功能与django中使用的功能应该是一致的。

pattern

工作原理与django中得pattern也是几乎一样的,都是将元组转成字典,最终返回给urlpatterns

其实这部分就是给视图函数起个别名,只不过这个别名是与每条消息id对应的。

**6 让我们的终端调试知道我们的新功能

因为,终端设备发起请求的步骤大致有以下几步:

注册请求

鉴权请求

上传位置信息

它正常工作后会只发送位置信息给我们,所以如果我们需要打断它的话,我最简单的方式是使用信号,系统默认是捕捉SIG_TSTP暂停进程信号。然后进入到信号处理函数/process_signal.py文件里。

所以如何切换位置信息处理视图函数到发送查询终端属性函数的映射,我们将在这里实现,代码如下:

from visual.visual_decorator import display_color_two
from app.urls import urlpatterns
from app import views

@display_color_two('cyan')
def hello(a, b):
print ''
print '=' * 80
print '[1] Checking the terminal information'
print '[2] Checking the terminal attribute'
print '[3] Do something else!'
print '[0] Reset!'
print '=' * 80
cmd = raw_input('Please input cmd your :')
if int(cmd) == 1:
urlpatterns['position'] = views.get_ter_info
elif int(cmd) == 2:
urlpatterns['position'] = views.get_ter_attr
elif int(cmd) == 0:
urlpatterns['position'] = views.position
else:
print 'No match command!'


代码相对比较简单就不在介绍。

7 测试部分



再按下CTRL+Z你可以进行选择回退到原来的设置,这样就可以继续接收GPS数据啦!

8 如何保存我们的数据呢

那就去编写我们的ORM吧!你可以在app/models.py里面编写你的数据类!

9 如何改变数据的编码呢

注意,所有数据域都被转换成二进制编码对应的十进制数,你如果需要转换成自己需要的编码你需要到admin.py里面去编写你的数据域!如果系统提供的转换函数无法满足你的需求,你可以自己在utils里面增加你的函数,然后把它添加到core/covert.py里面增加你的转换函数映射表!

10 在哪调用你的model.py和admin.py

你应该在views.py里面调用这些处理存储类型,你可以参考我们的位置视图如何应用这些类型

怎样二次开发

二次开发是什么 —— [ 维基百科 ]

第一,你需要先学会使用这个服务哦!还需要一些简单的python支持你前进!你应该掌握python的继承以及字典。如果你了解Django的话,那就更棒啦!因为,它的设计思路依据的就是Django哈~

为了让服务器知道不同的消息id找到自己的对应的解析函数,我们需要定义协议哈!

vim /conf/protocols.py


这里已经定义好了一些常用的协议了,想帮助我们一起增加它的功能吗?那就动手试试吧~

可以使用冒号来定义对齐方式:

消息ID消息新名称备注
0x0100ter_reg_reqterminal register request
0x8100ser_reg_rspserver_register_response
0x0102ter_aut_reqterminal authentic request

基本数据流向图:

可以渲染序列图:

Created with Raphaël 2.1.0suck.pysuck.pydispatch.pydispatch.py嘿,我收到了一些二进制数据

Created with Raphaël 2.1.0dispatchdispatchreflectreflect我现在把收到数据传给你~

第三步咯!

Created with Raphaël 2.1.0reflectreflecturlpatternsurlpatterns我叫到谁的名字,谁就来处理这条数据~

我能够调用的函数有~:

函数名处理函数
registerviews.register
authviews.auth
positionviews.position
第四部

看来一切逻辑都在views.py文件里面编写啊!那谁帮存储数据啊!

Created with Raphaël 2.1.0views.pyviews.pymodule.pymodule.py我就把字典格式的数据交个你啦~

那么数据流程图会是怎样呢?来一起看看~

Created with Raphaël 2.1.0suck.py运行监听端口服务器解析,处理,存储数据还有数据吗?结束yesno

结束语

再说吧~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: