Commit 0505f1f7 authored by liyuanhong's avatar liyuanhong

首次提交

parents
Pipeline #301 failed with stages
.idea/*
venv/*
\ No newline at end of file
# 模拟程序说明文档
### (一)、模拟车机程序部署方法
1、安装了python3 和 pip 包管理工具
2、使用 :pip install -r requirements.txt 安装依赖库
3、编辑start.py 设置为自己想要的参数
4、python3 start.py即可启动模拟服务(window下双击即可启动)
### (二)、运行机制
1、启动程序后,模拟车机会在:data/GSPLines 目录下面随机选择一条轨迹行驶
2、行驶完成后会自动熄火停止,并在设定的某个时间后开始下一次随机轨迹的选择行驶
3、一直重复此步骤,除非手动停止该程序
\ No newline at end of file
0
\ No newline at end of file
[2020-10-12 16:31:32]Traceback (most recent call last):
File "C:\Users\lyh\Desktop\autoCarTimer-Vandyo\lib\socket\service\AutoCarTimerService.py", line 690, in startTravelService
except BaseException as e:
File "C:\Users\lyh\Desktop\autoCarTimer-Vandyo\lib\socket\service\AutoCarTimerService.py", line 538, in startService
# t1 = threading.Thread(target=self.serviceTrave,args=())
File "C:\Users\lyh\Desktop\autoCarTimer-Vandyo\lib\socket\service\AutoCarTimerService.py", line 388, in serviceTrave
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
IndexError: list index out of range
{"name": "gpsLine", "GPSLine": [{"lng": "106.484708", "lat": "29.541383\n"}, {"lng": "106.484708", "lat": "29.541383\n"}, {"lng": "106.48525", "lat": "29.54261\n"}, {"lng": "106.485416", "lat": "29.542851\n"}, {"lng": "106.485576", "lat": "29.543066\n"}, {"lng": "106.485718", "lat": "29.543145\n"}, {"lng": "106.486151", "lat": "29.543361\n"}, {"lng": "106.486681", "lat": "29.543641\n"}, {"lng": "106.487396", "lat": "29.5442\n"}, {"lng": "106.489105", "lat": "29.54584\n"}, {"lng": "106.489171", "lat": "29.54596\n"}, {"lng": "106.48921", "lat": "29.546175\n"}, {"lng": "106.489215", "lat": "29.546413\n"}, {"lng": "106.489138", "lat": "29.546638\n"}, {"lng": "106.48901", "lat": "29.546963\n"}, {"lng": "106.488645", "lat": "29.548548\n"}, {"lng": "106.488666", "lat": "29.548698\n"}, {"lng": "106.488726", "lat": "29.548755\n"}, {"lng": "106.48877", "lat": "29.548778\n"}, {"lng": "106.48883", "lat": "29.54879\n"}, {"lng": "106.488978", "lat": "29.548846\n"}, {"lng": "106.48901", "lat": "29.54884\n"}, {"lng": "106.489726", "lat": "29.548905\n"}, {"lng": "106.48973", "lat": "29.548903\n"}, {"lng": "106.489768", "lat": "29.54894\n"}, {"lng": "106.489768", "lat": "29.54894\n"}, {"lng": "106.489768", "lat": "29.54894\n"}, {"lng": "106.49035", "lat": "29.549128\n"}, {"lng": "106.49035", "lat": "29.549115\n"}, {"lng": "106.490346", "lat": "29.549095\n"}, {"lng": "106.490343", "lat": "29.549085\n"}, {"lng": "106.490343", "lat": "29.549085\n"}, {"lng": "106.490343", "lat": "29.549085\n"}, {"lng": "106.490343", "lat": "29.549085\n"}, {"lng": "106.49037", "lat": "29.549171\n"}, {"lng": "106.490538", "lat": "29.549168\n"}, {"lng": "106.490695", "lat": "29.549196\n"}, {"lng": "106.491661", "lat": "29.549308\n"}, {"lng": "106.491828", "lat": "29.549321\n"}, {"lng": "106.492118", "lat": "29.549441\n"}, {"lng": "106.492333", "lat": "29.549435\n"}, {"lng": "106.492373", "lat": "29.549403\n"}, {"lng": "106.492396", "lat": "29.549403\n"}, {"lng": "106.492396", "lat": "29.549403\n"}, {"lng": "106.492396", "lat": "29.549403\n"}, {"lng": "106.492396", "lat": "29.549403\n"}, {"lng": "106.492846", "lat": "29.549358\n"}, {"lng": "106.492846", "lat": "29.549358\n"}]}
\ No newline at end of file
{"name": "gpsLine", "GPSLine": [{"lng": "106.489936", "lat": "29.571413\n"}, {"lng": "106.489936", "lat": "29.571413\n"}, {"lng": "106.489936", "lat": "29.571413\n"}, {"lng": "106.489936", "lat": "29.571413\n"}, {"lng": "106.489228", "lat": "29.572476\n"}, {"lng": "106.489278", "lat": "29.57247\n"}, {"lng": "106.48928", "lat": "29.572478\n"}, {"lng": "106.489308", "lat": "29.572493\n"}, {"lng": "106.489336", "lat": "29.572491\n"}, {"lng": "106.489401", "lat": "29.572516\n"}, {"lng": "106.489463", "lat": "29.572516\n"}, {"lng": "106.489526", "lat": "29.572513\n"}, {"lng": "106.489551", "lat": "29.572516\n"}, {"lng": "106.48958", "lat": "29.572516\n"}, {"lng": "106.489673", "lat": "29.572513\n"}, {"lng": "106.489723", "lat": "29.572528\n"}, {"lng": "106.48976", "lat": "29.57255\n"}, {"lng": "106.489806", "lat": "29.572548\n"}, {"lng": "106.489945", "lat": "29.572588\n"}, {"lng": "106.490688", "lat": "29.573006\n"}, {"lng": "106.493176", "lat": "29.574358\n"}, {"lng": "106.494316", "lat": "29.575038\n"}, {"lng": "106.494641", "lat": "29.575311\n"}, {"lng": "106.495465", "lat": "29.575978\n"}, {"lng": "106.49554", "lat": "29.576051\n"}, {"lng": "106.495676", "lat": "29.576178\n"}, {"lng": "106.495676", "lat": "29.576178\n"}, {"lng": "106.49603", "lat": "29.576513\n"}, {"lng": "106.497765", "lat": "29.578031\n"}, {"lng": "106.498773", "lat": "29.57854\n"}, {"lng": "106.499798", "lat": "29.578868\n"}, {"lng": "106.501658", "lat": "29.579578\n"}, {"lng": "106.50237", "lat": "29.580096\n"}, {"lng": "106.503121", "lat": "29.580836\n"}, {"lng": "106.50395", "lat": "29.581896\n"}, {"lng": "106.504175", "lat": "29.582433\n"}, {"lng": "106.505063", "lat": "29.584653\n"}, {"lng": "106.50554", "lat": "29.585078\n"}, {"lng": "106.50609", "lat": "29.585436\n"}, {"lng": "106.506691", "lat": "29.585701\n"}, {"lng": "106.507366", "lat": "29.585848\n"}, {"lng": "106.50825", "lat": "29.585931\n"}, {"lng": "106.51094", "lat": "29.586\n"}, {"lng": "106.513358", "lat": "29.586065\n"}, {"lng": "106.516028", "lat": "29.586071\n"}, {"lng": "106.519216", "lat": "29.586091\n"}, {"lng": "106.522845", "lat": "29.586266\n"}, {"lng": "106.523246", "lat": "29.586368\n"}, {"lng": "106.525301", "lat": "29.586976\n"}, {"lng": "106.527695", "lat": "29.587878\n"}, {"lng": "106.528158", "lat": "29.588231\n"}, {"lng": "106.52835", "lat": "29.58837\n"}, {"lng": "106.528901", "lat": "29.588898\n"}, {"lng": "106.530315", "lat": "29.590686\n"}, {"lng": "106.530693", "lat": "29.590921\n"}, {"lng": "106.531298", "lat": "29.591176\n"}, {"lng": "106.531461", "lat": "29.591223\n"}, {"lng": "106.531958", "lat": "29.591311\n"}, {"lng": "106.532708", "lat": "29.591331\n"}, {"lng": "106.53456", "lat": "29.59121\n"}, {"lng": "106.536136", "lat": "29.591001\n"}, {"lng": "106.536763", "lat": "29.590758\n"}, {"lng": "106.537365", "lat": "29.590386\n"}, {"lng": "106.537816", "lat": "29.590071\n"}, {"lng": "106.53997", "lat": "29.588791\n"}, {"lng": "106.54105", "lat": "29.58838\n"}, {"lng": "106.544393", "lat": "29.58736\n"}, {"lng": "106.546295", "lat": "29.586875\n"}, {"lng": "106.54707", "lat": "29.586838\n"}, {"lng": "106.547906", "lat": "29.586898\n"}, {"lng": "106.550141", "lat": "29.58728\n"}, {"lng": "106.550928", "lat": "29.587341\n"}, {"lng": "106.554313", "lat": "29.587185\n"}, {"lng": "106.558706", "lat": "29.587231\n"}, {"lng": "106.564148", "lat": "29.587476\n"}, {"lng": "106.568888", "lat": "29.587811\n"}, {"lng": "106.57465", "lat": "29.588195\n"}, {"lng": "106.581358", "lat": "29.58863\n"}, {"lng": "106.58715", "lat": "29.588625\n"}, {"lng": "106.587683", "lat": "29.588548\n"}, {"lng": "106.588408", "lat": "29.588351\n"}, {"lng": "106.589363", "lat": "29.587905\n"}, {"lng": "106.58993", "lat": "29.587518\n"}, {"lng": "106.590306", "lat": "29.587135\n"}, {"lng": "106.590373", "lat": "29.587008\n"}, {"lng": "106.590413", "lat": "29.58687\n"}, {"lng": "106.59044", "lat": "29.586643\n"}, {"lng": "106.590418", "lat": "29.586578\n"}, {"lng": "106.590366", "lat": "29.586528\n"}, {"lng": "106.590295", "lat": "29.586491\n"}, {"lng": "106.590121", "lat": "29.586416\n"}, {"lng": "106.58978", "lat": "29.586376\n"}, {"lng": "106.589298", "lat": "29.586303\n"}, {"lng": "106.58896", "lat": "29.586151\n"}, {"lng": "106.587671", "lat": "29.585425\n"}, {"lng": "106.587248", "lat": "29.585178\n"}, {"lng": "106.587193", "lat": "29.585103\n"}, {"lng": "106.586845", "lat": "29.584518\n"}, {"lng": "106.586873", "lat": "29.584393\n"}, {"lng": "106.586908", "lat": "29.584336\n"}, {"lng": "106.586978", "lat": "29.584295\n"}, {"lng": "106.587063", "lat": "29.584245\n"}, {"lng": "106.587728", "lat": "29.583933\n"}, {"lng": "106.58852", "lat": "29.583666\n"}, {"lng": "106.588616", "lat": "29.583636\n"}, {"lng": "106.59062", "lat": "29.583203\n"}, {"lng": "106.5909", "lat": "29.583028\n"}, {"lng": "106.590946", "lat": "29.583026\n"}, {"lng": "106.591038", "lat": "29.583023\n"}, {"lng": "106.591191", "lat": "29.582983\n"}, {"lng": "106.591945", "lat": "29.582805\n"}, {"lng": "106.593713", "lat": "29.5825\n"}, {"lng": "106.594765", "lat": "29.582348\n"}, {"lng": "106.595623", "lat": "29.582066\n"}, {"lng": "106.59581", "lat": "29.58191\n"}, {"lng": "106.59589", "lat": "29.581818\n"}, {"lng": "106.596008", "lat": "29.58164\n"}, {"lng": "106.596105", "lat": "29.581355\n"}, {"lng": "106.596305", "lat": "29.5805\n"}, {"lng": "106.596385", "lat": "29.579981\n"}, {"lng": "106.596376", "lat": "29.579921\n"}, {"lng": "106.5964", "lat": "29.57966\n"}, {"lng": "106.596518", "lat": "29.579361\n"}, {"lng": "106.596688", "lat": "29.579113\n"}, {"lng": "106.597758", "lat": "29.577621\n"}, {"lng": "106.597786", "lat": "29.577493\n"}, {"lng": "106.597826", "lat": "29.577223\n"}, {"lng": "106.597873", "lat": "29.577126\n"}, {"lng": "106.597888", "lat": "29.576851\n"}, {"lng": "106.597788", "lat": "29.576398\n"}, {"lng": "106.597645", "lat": "29.57626\n"}, {"lng": "106.59744", "lat": "29.576173\n"}, {"lng": "106.597366", "lat": "29.576155\n"}, {"lng": "106.597295", "lat": "29.576161\n"}, {"lng": "106.597103", "lat": "29.576156\n"}, {"lng": "106.597018", "lat": "29.576163\n"}, {"lng": "106.596796", "lat": "29.576183\n"}, {"lng": "106.596551", "lat": "29.57617\n"}, {"lng": "106.59605", "lat": "29.576128\n"}, {"lng": "106.595771", "lat": "29.576055\n"}, {"lng": "106.595018", "lat": "29.575778\n"}, {"lng": "106.594866", "lat": "29.57571\n"}, {"lng": "106.594543", "lat": "29.575561\n"}, {"lng": "106.594506", "lat": "29.575486\n"}, {"lng": "106.594505", "lat": "29.575436\n"}, {"lng": "106.594511", "lat": "29.575385\n"}, {"lng": "106.594491", "lat": "29.575216\n"}, {"lng": "106.594468", "lat": "29.575196\n"}, {"lng": "106.594391", "lat": "29.575178\n"}, {"lng": "106.594345", "lat": "29.575181\n"}, {"lng": "106.594196", "lat": "29.575205\n"}, {"lng": "106.593868", "lat": "29.575305\n"}, {"lng": "106.59372", "lat": "29.57537\n"}, {"lng": "106.59363", "lat": "29.575435\n"}, {"lng": "106.593523", "lat": "29.575543\n"}, {"lng": "106.5933", "lat": "29.575731\n"}, {"lng": "106.593236", "lat": "29.575753\n"}, {"lng": "106.593095", "lat": "29.575788\n"}, {"lng": "106.59263", "lat": "29.575965\n"}, {"lng": "106.59258", "lat": "29.576035\n"}, {"lng": "106.592545", "lat": "29.576106\n"}, {"lng": "106.592495", "lat": "29.576258\n"}, {"lng": "106.592303", "lat": "29.576691\n"}, {"lng": "106.592215", "lat": "29.576761\n"}, {"lng": "106.592118", "lat": "29.57682\n"}, {"lng": "106.59181", "lat": "29.57696\n"}, {"lng": "106.591708", "lat": "29.576963\n"}, {"lng": "106.59155", "lat": "29.576893\n"}, {"lng": "106.591506", "lat": "29.576825\n"}, {"lng": "106.591498", "lat": "29.576743\n"}, {"lng": "106.591511", "lat": "29.576651\n"}, {"lng": "106.591545", "lat": "29.576583\n"}, {"lng": "106.591563", "lat": "29.57627\n"}, {"lng": "106.591503", "lat": "29.576076\n"}, {"lng": "106.591426", "lat": "29.575991\n"}, {"lng": "106.59105", "lat": "29.575535\n"}, {"lng": "106.590888", "lat": "29.575535\n"}, {"lng": "106.590741", "lat": "29.575553\n"}, {"lng": "106.590668", "lat": "29.575568\n"}, {"lng": "106.590585", "lat": "29.575606\n"}, {"lng": "106.589545", "lat": "29.575728\n"}, {"lng": "106.589331", "lat": "29.575686\n"}, {"lng": "106.588915", "lat": "29.575568\n"}, {"lng": "106.588903", "lat": "29.575546\n"}, {"lng": "106.588861", "lat": "29.575505\n"}, {"lng": "106.588415", "lat": "29.575126\n"}, {"lng": "106.588343", "lat": "29.575101\n"}, {"lng": "106.588276", "lat": "29.575088\n"}, {"lng": "106.588216", "lat": "29.575088\n"}, {"lng": "106.58816", "lat": "29.575098\n"}, {"lng": "106.588105", "lat": "29.575121\n"}, {"lng": "106.588058", "lat": "29.575151\n"}, {"lng": "106.587973", "lat": "29.575213\n"}, {"lng": "106.58742", "lat": "29.57571\n"}, {"lng": "106.587413", "lat": "29.575743\n"}, {"lng": "106.587418", "lat": "29.575771\n"}, {"lng": "106.587436", "lat": "29.575788\n"}, {"lng": "106.587461", "lat": "29.5758\n"}, {"lng": "106.58749", "lat": "29.57581\n"}, {"lng": "106.587545", "lat": "29.575818\n"}, {"lng": "106.587605", "lat": "29.575815\n"}, {"lng": "106.587781", "lat": "29.575788\n"}, {"lng": "106.587861", "lat": "29.57577\n"}, {"lng": "106.587883", "lat": "29.5758\n"}, {"lng": "106.587883", "lat": "29.5758\n"}, {"lng": "106.587883", "lat": "29.5758\n"}, {"lng": "106.587883", "lat": "29.5758"}]}
\ No newline at end of file
{
"name":"GPS轨迹1",
"GPSLine":[
{
"lng":106.586571,
"lat":29.569133
},
{
"lng":106.586935,
"lat":29.569215
},
{
"lng":106.587114,
"lat":29.569215
},
{
"lng":106.587424,
"lat":29.569231
},
{
"lng":106.587685,
"lat":29.569278
},
{
"lng":106.587981,
"lat":29.569298
},
{
"lng":106.588098,
"lat":29.569341
},
{
"lng":106.588287,
"lat":29.569392
},
{
"lng":106.588435,
"lat":29.569439
},
{
"lng":106.588565,
"lat":29.569506
},
{
"lng":106.588646,
"lat":29.569565
},
{
"lng":106.588763,
"lat":29.569651
},
{
"lng":106.588884,
"lat":29.569745
},
{
"lng":106.589073,
"lat":29.569832
},
{
"lng":106.589374,
"lat":29.569977
},
{
"lng":106.589688,
"lat":29.570114
},
{
"lng":106.589993,
"lat":29.570228
},
{
"lng":106.590146,
"lat":29.570271
},
{
"lng":106.590357,
"lat":29.570291
},
{
"lng":106.590573,
"lat":29.570264
},
{
"lng":106.590802,
"lat":29.570248
},
{
"lng":106.59095,
"lat":29.570205
},
{
"lng":106.59108,
"lat":29.570256
},
{
"lng":106.591273,
"lat":29.570421
},
{
"lng":106.591507,
"lat":29.570578
},
{
"lng":106.591673,
"lat":29.570703
},
{
"lng":106.591772,
"lat":29.570774
},
{
"lng":106.591974,
"lat":29.570943
},
{
"lng":106.592145,
"lat":29.57108
},
{
"lng":106.592342,
"lat":29.571261
},
{
"lng":106.592383,
"lat":29.571332
},
{
"lng":106.592527,
"lat":29.571493
},
{
"lng":106.592679,
"lat":29.571642
},
{
"lng":106.592765,
"lat":29.571748
},
{
"lng":106.592877,
"lat":29.571834
},
{
"lng":106.593007,
"lat":29.571901
},
{
"lng":106.593182,
"lat":29.571936
},
{
"lng":106.593308,
"lat":29.571936
},
{
"lng":106.593407,
"lat":29.571874
},
{
"lng":106.593591,
"lat":29.571815
},
{
"lng":106.593784,
"lat":29.571795
},
{
"lng":106.593847,
"lat":29.571862
},
{
"lng":106.593865,
"lat":29.571983
},
{
"lng":106.59391,
"lat":29.572105
},
{
"lng":106.594054,
"lat":29.572144
},
{
"lng":106.594453,
"lat":29.572121
},
{
"lng":106.594665,
"lat":29.57205
},
{
"lng":106.594799,
"lat":29.571968
},
{
"lng":106.594925,
"lat":29.571862
},
{
"lng":106.595078,
"lat":29.57172
},
{
"lng":106.595145,
"lat":29.571607
},
{
"lng":106.595226,
"lat":29.571449
},
{
"lng":106.595239,
"lat":29.571324
},
{
"lng":106.59528,
"lat":29.571124
},
{
"lng":106.59528,
"lat":29.570982
},
{
"lng":106.595289,
"lat":29.570821
},
{
"lng":106.59532,
"lat":29.57066
},
{
"lng":106.59532,
"lat":29.570515
},
{
"lng":106.595325,
"lat":29.570413
},
{
"lng":106.595374,
"lat":29.570158
},
{
"lng":106.595374,
"lat":29.570024
},
{
"lng":106.595406,
"lat":29.56984
},
{
"lng":106.59541,
"lat":29.569631
},
{
"lng":106.59541,
"lat":29.569439
},
{
"lng":106.595451,
"lat":29.569199
},
{
"lng":106.595451,
"lat":29.569074
},
{
"lng":106.595473,
"lat":29.568932
},
{
"lng":106.595495,
"lat":29.568787
},
{
"lng":106.595469,
"lat":29.568563
},
{
"lng":106.595464,
"lat":29.568422
},
{
"lng":106.595401,
"lat":29.568151
},
{
"lng":106.595406,
"lat":29.567947
},
{
"lng":106.595352,
"lat":29.567739
},
{
"lng":106.595334,
"lat":29.567593
},
{
"lng":106.595316,
"lat":29.567397
},
{
"lng":106.595298,
"lat":29.567209
},
{
"lng":106.595266,
"lat":29.567016
},
{
"lng":106.595239,
"lat":29.566777
},
{
"lng":106.595217,
"lat":29.566592
},
{
"lng":106.595186,
"lat":29.566384
},
{
"lng":106.595141,
"lat":29.566188
},
{
"lng":106.595091,
"lat":29.565976
},
{
"lng":106.594997,
"lat":29.565732
},
{
"lng":106.594934,
"lat":29.565544
},
{
"lng":106.594795,
"lat":29.565178
},
{
"lng":106.594678,
"lat":29.564951
},
{
"lng":106.594629,
"lat":29.564758
},
{
"lng":106.594566,
"lat":29.564605
},
{
"lng":106.594691,
"lat":29.564554
},
{
"lng":106.594898,
"lat":29.564507
},
{
"lng":106.595212,
"lat":29.564409
},
{
"lng":106.595626,
"lat":29.564291
},
{
"lng":106.596165,
"lat":29.564134
},
{
"lng":106.596421,
"lat":29.564063
},
{
"lng":106.596704,
"lat":29.563985
},
{
"lng":106.596928,
"lat":29.56391
},
{
"lng":106.59744,
"lat":29.563761
},
{
"lng":106.597867,
"lat":29.563635
},
{
"lng":106.598105,
"lat":29.563553
},
{
"lng":106.598294,
"lat":29.563517
},
{
"lng":106.598572,
"lat":29.563415
},
{
"lng":106.598909,
"lat":29.563317
},
{
"lng":106.599165,
"lat":29.56325
},
{
"lng":106.599673,
"lat":29.563109
},
{
"lng":106.600104,
"lat":29.562975
},
{
"lng":106.600369,
"lat":29.562921
},
{
"lng":106.600571,
"lat":29.562854
},
{
"lng":106.600786,
"lat":29.562807
},
{
"lng":106.600791,
"lat":29.562807
},
{
"lng":106.600804,
"lat":29.562913
},
{
"lng":106.600836,
"lat":29.563082
},
{
"lng":106.600849,
"lat":29.563164
},
{
"lng":106.60089,
"lat":29.56336
},
{
"lng":106.600957,
"lat":29.563623
},
{
"lng":106.600966,
"lat":29.563733
},
{
"lng":106.600966,
"lat":29.563922
},
{
"lng":106.600984,
"lat":29.564216
},
{
"lng":106.601002,
"lat":29.56444
},
{
"lng":106.601011,
"lat":29.564692
},
{
"lng":106.601025,
"lat":29.564978
},
{
"lng":106.601025,
"lat":29.565182
},
{
"lng":106.601047,
"lat":29.565367
},
{
"lng":106.601038,
"lat":29.565508
},
{
"lng":106.601056,
"lat":29.56563
},
{
"lng":106.601051,
"lat":29.565932
},
{
"lng":106.60106,
"lat":29.566129
},
{
"lng":106.601074,
"lat":29.566388
},
{
"lng":106.601096,
"lat":29.566569
},
{
"lng":106.601083,
"lat":29.566706
},
{
"lng":106.601096,
"lat":29.566985
},
{
"lng":106.601083,
"lat":29.567122
},
{
"lng":106.601105,
"lat":29.567271
},
{
"lng":106.601105,
"lat":29.567432
},
{
"lng":106.601114,
"lat":29.567625
},
{
"lng":106.601105,
"lat":29.567723
},
{
"lng":106.601114,
"lat":29.567786
},
{
"lng":106.601132,
"lat":29.568006
},
{
"lng":106.601128,
"lat":29.568112
},
{
"lng":106.601114,
"lat":29.568257
},
{
"lng":106.601119,
"lat":29.568379
},
{
"lng":106.601119,
"lat":29.568646
},
{
"lng":106.601101,
"lat":29.568779
},
{
"lng":106.60111,
"lat":29.568913
},
{
"lng":106.601101,
"lat":29.569031
},
{
"lng":106.601101,
"lat":29.569196
},
{
"lng":106.601083,
"lat":29.569302
},
{
"lng":106.601083,
"lat":29.569435
},
{
"lng":106.601051,
"lat":29.56958
},
{
"lng":106.601029,
"lat":29.569722
},
{
"lng":106.601034,
"lat":29.56984
},
{
"lng":106.600998,
"lat":29.570001
},
{
"lng":106.60098,
"lat":29.570193
},
{
"lng":106.600944,
"lat":29.570354
},
{
"lng":106.600926,
"lat":29.57048
},
{
"lng":106.600885,
"lat":29.570668
},
{
"lng":106.600867,
"lat":29.570825
},
{
"lng":106.600854,
"lat":29.570966
},
{
"lng":106.600849,
"lat":29.571065
},
{
"lng":106.600804,
"lat":29.571186
},
{
"lng":106.600755,
"lat":29.571351
},
{
"lng":106.600769,
"lat":29.57141
},
{
"lng":106.600751,
"lat":29.571512
},
{
"lng":106.600737,
"lat":29.571622
},
{
"lng":106.600697,
"lat":29.571779
},
{
"lng":106.600697,
"lat":29.571901
},
{
"lng":106.600661,
"lat":29.572035
},
{
"lng":106.600638,
"lat":29.572172
},
{
"lng":106.60062,
"lat":29.572357
},
{
"lng":106.600593,
"lat":29.572514
},
{
"lng":106.600571,
"lat":29.572655
},
{
"lng":106.600548,
"lat":29.572828
},
{
"lng":106.60053,
"lat":29.572981
},
{
"lng":106.600499,
"lat":29.573142
},
{
"lng":106.600495,
"lat":29.573267
},
{
"lng":106.600441,
"lat":29.573401
},
{
"lng":106.600423,
"lat":29.573523
},
{
"lng":106.600391,
"lat":29.573754
},
{
"lng":106.600364,
"lat":29.57399
},
{
"lng":106.600328,
"lat":29.574186
},
{
"lng":106.600283,
"lat":29.574379
},
{
"lng":106.600261,
"lat":29.574548
},
{
"lng":106.600234,
"lat":29.574693
},
{
"lng":106.600207,
"lat":29.574846
},
{
"lng":106.600189,
"lat":29.574956
},
{
"lng":106.600162,
"lat":29.575093
},
{
"lng":106.600122,
"lat":29.57525
},
{
"lng":106.600077,
"lat":29.575474
},
{
"lng":106.600009,
"lat":29.575631
},
{
"lng":106.599933,
"lat":29.575831
},
{
"lng":106.599866,
"lat":29.576008
},
{
"lng":106.599758,
"lat":29.576204
},
{
"lng":106.5997,
"lat":29.576326
},
{
"lng":106.599583,
"lat":29.576487
},
{
"lng":106.599479,
"lat":29.576636
},
{
"lng":106.599399,
"lat":29.57677
},
{
"lng":106.5993,
"lat":29.576947
},
{
"lng":106.59921,
"lat":29.577053
},
{
"lng":106.599093,
"lat":29.577182
},
{
"lng":106.59899,
"lat":29.5773
},
{
"lng":106.598909,
"lat":29.577437
},
{
"lng":106.598797,
"lat":29.577512
},
{
"lng":106.598666,
"lat":29.577693
},
{
"lng":106.5985,
"lat":29.57785
},
{
"lng":106.598401,
"lat":29.57796
},
{
"lng":106.598262,
"lat":29.578054
},
{
"lng":106.598168,
"lat":29.578195
},
{
"lng":106.598038,
"lat":29.578297
},
{
"lng":106.598015,
"lat":29.578364
},
{
"lng":106.598015,
"lat":29.578364
}
]
}
{ "name":"GPS轨迹1", "GPSLine":[ { "lng":106.586571, "lat":29.569133 }, { "lng":106.586935, "lat":29.569215 }, { "lng":106.587114, "lat":29.569215 }, { "lng":106.587424, "lat":29.569231 }, { "lng":106.587685, "lat":29.569278 }, { "lng":106.587981, "lat":29.569298 }, { "lng":106.588098, "lat":29.569341 }, { "lng":106.588287, "lat":29.569392 }, { "lng":106.588435, "lat":29.569439 }, { "lng":106.588565, "lat":29.569506 }, { "lng":106.588646, "lat":29.569565 }, { "lng":106.588763, "lat":29.569651 }, { "lng":106.588884, "lat":29.569745 }, { "lng":106.589073, "lat":29.569832 }, { "lng":106.589374, "lat":29.569977 }, { "lng":106.589688, "lat":29.570114 }, { "lng":106.589993, "lat":29.570228 }, { "lng":106.590146, "lat":29.570271 }, { "lng":106.590357, "lat":29.570291 }, { "lng":106.590573, "lat":29.570264 }, { "lng":106.590802, "lat":29.570248 }, { "lng":106.59095, "lat":29.570205 }, { "lng":106.59108, "lat":29.570256 }, { "lng":106.591273, "lat":29.570421 }, { "lng":106.591507, "lat":29.570578 }, { "lng":106.591673, "lat":29.570703 }, { "lng":106.591772, "lat":29.570774 }, { "lng":106.591974, "lat":29.570943 }, { "lng":106.592145, "lat":29.57108 }, { "lng":106.592342, "lat":29.571261 }, { "lng":106.592383, "lat":29.571332 }, { "lng":106.592527, "lat":29.571493 }, { "lng":106.592679, "lat":29.571642 }, { "lng":106.592765, "lat":29.571748 }, { "lng":106.592877, "lat":29.571834 }, { "lng":106.593007, "lat":29.571901 }, { "lng":106.593182, "lat":29.571936 }, { "lng":106.593308, "lat":29.571936 }, { "lng":106.593407, "lat":29.571874 }, { "lng":106.593591, "lat":29.571815 }, { "lng":106.593784, "lat":29.571795 }, { "lng":106.593847, "lat":29.571862 }, { "lng":106.593865, "lat":29.571983 }, { "lng":106.59391, "lat":29.572105 }, { "lng":106.594054, "lat":29.572144 }, { "lng":106.594453, "lat":29.572121 }, { "lng":106.594665, "lat":29.57205 }, { "lng":106.594799, "lat":29.571968 }, { "lng":106.594925, "lat":29.571862 }, { "lng":106.595078, "lat":29.57172 }, { "lng":106.595145, "lat":29.571607 }, { "lng":106.595226, "lat":29.571449 }, { "lng":106.595239, "lat":29.571324 }, { "lng":106.59528, "lat":29.571124 }, { "lng":106.59528, "lat":29.570982 }, { "lng":106.595289, "lat":29.570821 }, { "lng":106.59532, "lat":29.57066 }, { "lng":106.59532, "lat":29.570515 }, { "lng":106.595325, "lat":29.570413 }, { "lng":106.595374, "lat":29.570158 }, { "lng":106.595374, "lat":29.570024 }, { "lng":106.595406, "lat":29.56984 }, { "lng":106.59541, "lat":29.569631 }, { "lng":106.59541, "lat":29.569439 }, { "lng":106.595451, "lat":29.569199 }, { "lng":106.595451, "lat":29.569074 }, { "lng":106.595473, "lat":29.568932 }, { "lng":106.595495, "lat":29.568787 }, { "lng":106.595469, "lat":29.568563 }, { "lng":106.595464, "lat":29.568422 }, { "lng":106.595401, "lat":29.568151 }, { "lng":106.595406, "lat":29.567947 }, { "lng":106.595352, "lat":29.567739 }, { "lng":106.595334, "lat":29.567593 }, { "lng":106.595316, "lat":29.567397 }, { "lng":106.595298, "lat":29.567209 }, { "lng":106.595266, "lat":29.567016 }, { "lng":106.595239, "lat":29.566777 }, { "lng":106.595217, "lat":29.566592 }, { "lng":106.595186, "lat":29.566384 }, { "lng":106.595141, "lat":29.566188 }, { "lng":106.595091, "lat":29.565976 }, { "lng":106.594997, "lat":29.565732 }, { "lng":106.594934, "lat":29.565544 }, { "lng":106.594795, "lat":29.565178 }, { "lng":106.594678, "lat":29.564951 }, { "lng":106.594629, "lat":29.564758 }, { "lng":106.594566, "lat":29.564605 }, { "lng":106.594691, "lat":29.564554 }, { "lng":106.594898, "lat":29.564507 }, { "lng":106.595212, "lat":29.564409 }, { "lng":106.595626, "lat":29.564291 }, { "lng":106.596165, "lat":29.564134 }, { "lng":106.596421, "lat":29.564063 }, { "lng":106.596704, "lat":29.563985 }, { "lng":106.596928, "lat":29.56391 }, { "lng":106.59744, "lat":29.563761 }, { "lng":106.597867, "lat":29.563635 }, { "lng":106.598105, "lat":29.563553 }, { "lng":106.598294, "lat":29.563517 }, { "lng":106.598572, "lat":29.563415 }, { "lng":106.598909, "lat":29.563317 }, { "lng":106.599165, "lat":29.56325 }, { "lng":106.599673, "lat":29.563109 }, { "lng":106.600104, "lat":29.562975 }, { "lng":106.600369, "lat":29.562921 }, { "lng":106.600571, "lat":29.562854 }, { "lng":106.600786, "lat":29.562807 }, { "lng":106.600791, "lat":29.562807 }, { "lng":106.600804, "lat":29.562913 }, { "lng":106.600836, "lat":29.563082 }, { "lng":106.600849, "lat":29.563164 }, { "lng":106.60089, "lat":29.56336 }, { "lng":106.600957, "lat":29.563623 }, { "lng":106.600966, "lat":29.563733 }, { "lng":106.600966, "lat":29.563922 }, { "lng":106.600984, "lat":29.564216 }, { "lng":106.601002, "lat":29.56444 }, { "lng":106.601011, "lat":29.564692 }, { "lng":106.601025, "lat":29.564978 }, { "lng":106.601025, "lat":29.565182 }, { "lng":106.601047, "lat":29.565367 }, { "lng":106.601038, "lat":29.565508 }, { "lng":106.601056, "lat":29.56563 }, { "lng":106.601051, "lat":29.565932 }, { "lng":106.60106, "lat":29.566129 }, { "lng":106.601074, "lat":29.566388 }, { "lng":106.601096, "lat":29.566569 }, { "lng":106.601083, "lat":29.566706 }, { "lng":106.601096, "lat":29.566985 }, { "lng":106.601083, "lat":29.567122 }, { "lng":106.601105, "lat":29.567271 }, { "lng":106.601105, "lat":29.567432 }, { "lng":106.601114, "lat":29.567625 }, { "lng":106.601105, "lat":29.567723 }, { "lng":106.601114, "lat":29.567786 }, { "lng":106.601132, "lat":29.568006 }, { "lng":106.601128, "lat":29.568112 }, { "lng":106.601114, "lat":29.568257 }, { "lng":106.601119, "lat":29.568379 }, { "lng":106.601119, "lat":29.568646 }, { "lng":106.601101, "lat":29.568779 }, { "lng":106.60111, "lat":29.568913 }, { "lng":106.601101, "lat":29.569031 }, { "lng":106.601101, "lat":29.569196 }, { "lng":106.601083, "lat":29.569302 }, { "lng":106.601083, "lat":29.569435 }, { "lng":106.601051, "lat":29.56958 }, { "lng":106.601029, "lat":29.569722 }, { "lng":106.601034, "lat":29.56984 }, { "lng":106.600998, "lat":29.570001 }, { "lng":106.60098, "lat":29.570193 }, { "lng":106.600944, "lat":29.570354 }, { "lng":106.600926, "lat":29.57048 }, { "lng":106.600885, "lat":29.570668 }, { "lng":106.600867, "lat":29.570825 }, { "lng":106.600854, "lat":29.570966 }, { "lng":106.600849, "lat":29.571065 }, { "lng":106.600804, "lat":29.571186 }, { "lng":106.600755, "lat":29.571351 }, { "lng":106.600769, "lat":29.57141 }, { "lng":106.600751, "lat":29.571512 }, { "lng":106.600737, "lat":29.571622 }, { "lng":106.600697, "lat":29.571779 }, { "lng":106.600697, "lat":29.571901 }, { "lng":106.600661, "lat":29.572035 }, { "lng":106.600638, "lat":29.572172 }, { "lng":106.60062, "lat":29.572357 }, { "lng":106.600593, "lat":29.572514 }, { "lng":106.600571, "lat":29.572655 }, { "lng":106.600548, "lat":29.572828 }, { "lng":106.60053, "lat":29.572981 }, { "lng":106.600499, "lat":29.573142 }, { "lng":106.600495, "lat":29.573267 }, { "lng":106.600441, "lat":29.573401 }, { "lng":106.600423, "lat":29.573523 }, { "lng":106.600391, "lat":29.573754 }, { "lng":106.600364, "lat":29.57399 }, { "lng":106.600328, "lat":29.574186 }, { "lng":106.600283, "lat":29.574379 }, { "lng":106.600261, "lat":29.574548 }, { "lng":106.600234, "lat":29.574693 }, { "lng":106.600207, "lat":29.574846 }, { "lng":106.600189, "lat":29.574956 }, { "lng":106.600162, "lat":29.575093 }, { "lng":106.600122, "lat":29.57525 }, { "lng":106.600077, "lat":29.575474 }, { "lng":106.600009, "lat":29.575631 }, { "lng":106.599933, "lat":29.575831 }, { "lng":106.599866, "lat":29.576008 }, { "lng":106.599758, "lat":29.576204 }, { "lng":106.5997, "lat":29.576326 }, { "lng":106.599583, "lat":29.576487 }, { "lng":106.599479, "lat":29.576636 }, { "lng":106.599399, "lat":29.57677 }, { "lng":106.5993, "lat":29.576947 }, { "lng":106.59921, "lat":29.577053 }, { "lng":106.599093, "lat":29.577182 }, { "lng":106.59899, "lat":29.5773 }, { "lng":106.598909, "lat":29.577437 }, { "lng":106.598797, "lat":29.577512 }, { "lng":106.598666, "lat":29.577693 }, { "lng":106.5985, "lat":29.57785 }, { "lng":106.598401, "lat":29.57796 }, { "lng":106.598262, "lat":29.578054 }, { "lng":106.598168, "lat":29.578195 }, { "lng":106.598038, "lat":29.578297 }, { "lng":106.598015, "lat":29.578364 }, { "lng":106.598015, "lat":29.578364 } ] }
\ No newline at end of file
{ "name":"GPS轨迹1", "GPSLine":[ { "lng":106.591507, "lat":29.570578 }, { "lng":106.591673, "lat":29.570703 }, { "lng":106.591772, "lat":29.570774 }, { "lng":106.591974, "lat":29.570943 }, { "lng":106.592145, "lat":29.57108 }, { "lng":106.592342, "lat":29.571261 }, { "lng":106.592383, "lat":29.571332 }, { "lng":106.592527, "lat":29.571493 }, { "lng":106.592679, "lat":29.571642 }, { "lng":106.592765, "lat":29.571748 }, { "lng":106.592877, "lat":29.571834 }, { "lng":106.593007, "lat":29.571901 }, { "lng":106.593182, "lat":29.571936 }, { "lng":106.593308, "lat":29.571936 }, { "lng":106.593407, "lat":29.571874 }, { "lng":106.593591, "lat":29.571815 }, { "lng":106.593784, "lat":29.571795 }, { "lng":106.593847, "lat":29.571862 }, { "lng":106.593865, "lat":29.571983 }, { "lng":106.59391, "lat":29.572105 }, { "lng":106.594054, "lat":29.572144 }, { "lng":106.594453, "lat":29.572121 }, { "lng":106.594665, "lat":29.57205 }, { "lng":106.594799, "lat":29.571968 }, { "lng":106.594925, "lat":29.571862 }, { "lng":106.595078, "lat":29.57172 }, { "lng":106.595145, "lat":29.571607 }, { "lng":106.595226, "lat":29.571449 }, { "lng":106.595239, "lat":29.571324 }, { "lng":106.59528, "lat":29.571124 }, { "lng":106.59528, "lat":29.570982 }, { "lng":106.595289, "lat":29.570821 }, { "lng":106.59532, "lat":29.57066 }, { "lng":106.59532, "lat":29.570515 }, { "lng":106.595325, "lat":29.570413 }, { "lng":106.595374, "lat":29.570158 }, { "lng":106.595374, "lat":29.570024 }, { "lng":106.595406, "lat":29.56984 }, { "lng":106.59541, "lat":29.569631 }, { "lng":106.59541, "lat":29.569439 }, { "lng":106.595451, "lat":29.569199 }, { "lng":106.595451, "lat":29.569074 }, { "lng":106.595473, "lat":29.568932 }, { "lng":106.595495, "lat":29.568787 }, { "lng":106.595469, "lat":29.568563 }, { "lng":106.595464, "lat":29.568422 }, { "lng":106.595401, "lat":29.568151 }, { "lng":106.595406, "lat":29.567947 }, { "lng":106.595352, "lat":29.567739 }, { "lng":106.595334, "lat":29.567593 }, { "lng":106.595316, "lat":29.567397 }, { "lng":106.595298, "lat":29.567209 }, { "lng":106.595266, "lat":29.567016 }, { "lng":106.595239, "lat":29.566777 }, { "lng":106.595217, "lat":29.566592 }, { "lng":106.595186, "lat":29.566384 }, { "lng":106.595141, "lat":29.566188 }, { "lng":106.595091, "lat":29.565976 }, { "lng":106.594997, "lat":29.565732 }, { "lng":106.594934, "lat":29.565544 }, { "lng":106.594795, "lat":29.565178 }, { "lng":106.594678, "lat":29.564951 }, { "lng":106.594629, "lat":29.564758 }, { "lng":106.594566, "lat":29.564605 }, { "lng":106.594691, "lat":29.564554 }, { "lng":106.594898, "lat":29.564507 }, { "lng":106.595212, "lat":29.564409 }, { "lng":106.595626, "lat":29.564291 }, { "lng":106.596165, "lat":29.564134 }, { "lng":106.596421, "lat":29.564063 }, { "lng":106.596704, "lat":29.563985 }, { "lng":106.596928, "lat":29.56391 }, { "lng":106.59744, "lat":29.563761 }, { "lng":106.597867, "lat":29.563635 }, { "lng":106.598105, "lat":29.563553 }, { "lng":106.598294, "lat":29.563517 }, { "lng":106.598572, "lat":29.563415 }, { "lng":106.598909, "lat":29.563317 }, { "lng":106.599165, "lat":29.56325 }, { "lng":106.599673, "lat":29.563109 }, { "lng":106.600104, "lat":29.562975 }, { "lng":106.600369, "lat":29.562921 }, { "lng":106.600571, "lat":29.562854 }, { "lng":106.600786, "lat":29.562807 }, { "lng":106.600791, "lat":29.562807 }, { "lng":106.600804, "lat":29.562913 }, { "lng":106.600836, "lat":29.563082 }, { "lng":106.600849, "lat":29.563164 }, { "lng":106.60089, "lat":29.56336 }, { "lng":106.600957, "lat":29.563623 }, { "lng":106.600966, "lat":29.563733 }, { "lng":106.600966, "lat":29.563922 }, { "lng":106.600984, "lat":29.564216 }, { "lng":106.601002, "lat":29.56444 }, { "lng":106.601011, "lat":29.564692 }, { "lng":106.601025, "lat":29.564978 }, { "lng":106.601025, "lat":29.565182 }, { "lng":106.601047, "lat":29.565367 }, { "lng":106.601038, "lat":29.565508 }, { "lng":106.601056, "lat":29.56563 }, { "lng":106.601051, "lat":29.565932 }, { "lng":106.60106, "lat":29.566129 }, { "lng":106.601074, "lat":29.566388 }, { "lng":106.601096, "lat":29.566569 }, { "lng":106.601083, "lat":29.566706 }, { "lng":106.601096, "lat":29.566985 }, { "lng":106.601083, "lat":29.567122 }, { "lng":106.601105, "lat":29.567271 }, { "lng":106.601105, "lat":29.567432 }, { "lng":106.601114, "lat":29.567625 }, { "lng":106.601105, "lat":29.567723 }, { "lng":106.601114, "lat":29.567786 }, { "lng":106.601132, "lat":29.568006 }, { "lng":106.601128, "lat":29.568112 }, { "lng":106.601114, "lat":29.568257 }, { "lng":106.601119, "lat":29.568379 }, { "lng":106.601119, "lat":29.568646 }, { "lng":106.601101, "lat":29.568779 }, { "lng":106.60111, "lat":29.568913 }, { "lng":106.601101, "lat":29.569031 }, { "lng":106.601101, "lat":29.569196 }, { "lng":106.601083, "lat":29.569302 }, { "lng":106.601083, "lat":29.569435 }, { "lng":106.601051, "lat":29.56958 }, { "lng":106.601029, "lat":29.569722 }, { "lng":106.601034, "lat":29.56984 }, { "lng":106.600998, "lat":29.570001 }, { "lng":106.60098, "lat":29.570193 }, { "lng":106.600944, "lat":29.570354 }, { "lng":106.600926, "lat":29.57048 }, { "lng":106.600885, "lat":29.570668 }, { "lng":106.600867, "lat":29.570825 }, { "lng":106.600854, "lat":29.570966 }, { "lng":106.600849, "lat":29.571065 }, { "lng":106.600804, "lat":29.571186 }, { "lng":106.600755, "lat":29.571351 }, { "lng":106.600769, "lat":29.57141 }, { "lng":106.600751, "lat":29.571512 }, { "lng":106.600737, "lat":29.571622 }, { "lng":106.600697, "lat":29.571779 }, { "lng":106.600697, "lat":29.571901 }, { "lng":106.600661, "lat":29.572035 }, { "lng":106.600638, "lat":29.572172 }, { "lng":106.60062, "lat":29.572357 }, { "lng":106.600593, "lat":29.572514 }, { "lng":106.600571, "lat":29.572655 }, { "lng":106.600548, "lat":29.572828 }, { "lng":106.60053, "lat":29.572981 }, { "lng":106.600499, "lat":29.573142 }, { "lng":106.600495, "lat":29.573267 }, { "lng":106.600441, "lat":29.573401 }, { "lng":106.600423, "lat":29.573523 }, { "lng":106.600391, "lat":29.573754 }, { "lng":106.600364, "lat":29.57399 }, { "lng":106.600328, "lat":29.574186 }, { "lng":106.600283, "lat":29.574379 }, { "lng":106.600261, "lat":29.574548 }, { "lng":106.600234, "lat":29.574693 }, { "lng":106.600207, "lat":29.574846 }, { "lng":106.600189, "lat":29.574956 }, { "lng":106.600162, "lat":29.575093 }, { "lng":106.600122, "lat":29.57525 }, { "lng":106.600077, "lat":29.575474 }, { "lng":106.600009, "lat":29.575631 }, { "lng":106.599933, "lat":29.575831 }, { "lng":106.599866, "lat":29.576008 }, { "lng":106.599758, "lat":29.576204 }, { "lng":106.5997, "lat":29.576326 }, { "lng":106.599583, "lat":29.576487 } ] }
\ No newline at end of file
{"name": "gpsLine", "GPSLine": [{"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.279711", "lat": "29.585448\n"}, {"lng": "106.287903", "lat": "29.586623\n"}, {"lng": "106.289041", "lat": "29.586608\n"}, {"lng": "106.293958", "lat": "29.586631\n"}, {"lng": "106.296643", "lat": "29.586603\n"}, {"lng": "106.29702", "lat": "29.586588\n"}, {"lng": "106.297076", "lat": "29.586625\n"}, {"lng": "106.297116", "lat": "29.586675\n"}, {"lng": "106.297148", "lat": "29.58674\n"}, {"lng": "106.297161", "lat": "29.586818\n"}, {"lng": "106.297168", "lat": "29.586906\n"}, {"lng": "106.297275", "lat": "29.58793\n"}, {"lng": "106.297461", "lat": "29.588408\n"}, {"lng": "106.297783", "lat": "29.588835\n"}, {"lng": "106.298863", "lat": "29.589848\n"}, {"lng": "106.299571", "lat": "29.59043\n"}, {"lng": "106.30007", "lat": "29.590666\n"}, {"lng": "106.300655", "lat": "29.59083\n"}, {"lng": "106.301408", "lat": "29.59091\n"}, {"lng": "106.301695", "lat": "29.590925\n"}, {"lng": "106.303111", "lat": "29.590928\n"}, {"lng": "106.30319", "lat": "29.590958\n"}, {"lng": "106.30325", "lat": "29.591001\n"}, {"lng": "106.303288", "lat": "29.59106\n"}, {"lng": "106.303306", "lat": "29.591125\n"}, {"lng": "106.303311", "lat": "29.591196\n"}, {"lng": "106.303321", "lat": "29.59202\n"}, {"lng": "106.303418", "lat": "29.594665\n"}, {"lng": "106.303493", "lat": "29.596323\n"}, {"lng": "106.30351", "lat": "29.597693\n"}, {"lng": "106.303563", "lat": "29.598776\n"}, {"lng": "106.303651", "lat": "29.600776\n"}, {"lng": "106.303651", "lat": "29.600776\n"}, {"lng": "106.303735", "lat": "29.6027\n"}, {"lng": "106.303841", "lat": "29.605561\n"}, {"lng": "106.30389", "lat": "29.605611\n"}, {"lng": "106.303936", "lat": "29.605648\n"}, {"lng": "106.303988", "lat": "29.605683\n"}, {"lng": "106.30405", "lat": "29.605698\n"}, {"lng": "106.304203", "lat": "29.605718\n"}, {"lng": "106.307615", "lat": "29.605741\n"}, {"lng": "106.309696", "lat": "29.605716\n"}, {"lng": "106.309731", "lat": "29.605715\n"}, {"lng": "106.313746", "lat": "29.605721\n"}, {"lng": "106.31563", "lat": "29.605693\n"}, {"lng": "106.320446", "lat": "29.605731\n"}, {"lng": "106.325616", "lat": "29.605701\n"}, {"lng": "106.3258", "lat": "29.605626\n"}, {"lng": "106.326526", "lat": "29.605285\n"}, {"lng": "106.326736", "lat": "29.605265\n"}, {"lng": "106.326958", "lat": "29.605301\n"}, {"lng": "106.327066", "lat": "29.605343\n"}, {"lng": "106.327813", "lat": "29.605686\n"}, {"lng": "106.328125", "lat": "29.605711\n"}, {"lng": "106.328805", "lat": "29.605706\n"}, {"lng": "106.335046", "lat": "29.605946\n"}, {"lng": "106.339763", "lat": "29.606455\n"}, {"lng": "106.342376", "lat": "29.606618\n"}, {"lng": "106.346018", "lat": "29.606541\n"}, {"lng": "106.34853", "lat": "29.606423\n"}, {"lng": "106.352298", "lat": "29.606235\n"}, {"lng": "106.357856", "lat": "29.606015\n"}, {"lng": "106.359951", "lat": "29.605968\n"}, {"lng": "106.360195", "lat": "29.605978\n"}, {"lng": "106.360195", "lat": "29.605978\n"}, {"lng": "106.360341", "lat": "29.60598\n"}, {"lng": "106.360453", "lat": "29.605988\n"}, {"lng": "106.360515", "lat": "29.606005\n"}, {"lng": "106.360578", "lat": "29.606036\n"}, {"lng": "106.360638", "lat": "29.606081\n"}, {"lng": "106.360686", "lat": "29.606136\n"}, {"lng": "106.360756", "lat": "29.606266\n"}, {"lng": "106.360791", "lat": "29.60645\n"}, {"lng": "106.361096", "lat": "29.608673\n"}, {"lng": "106.361216", "lat": "29.611228\n"}, {"lng": "106.36123", "lat": "29.611825\n"}, {"lng": "106.36123", "lat": "29.611825\n"}, {"lng": "106.361245", "lat": "29.612025\n"}, {"lng": "106.361295", "lat": "29.612065\n"}, {"lng": "106.36137", "lat": "29.612091\n"}, {"lng": "106.361458", "lat": "29.612105\n"}, {"lng": "106.362618", "lat": "29.612145\n"}, {"lng": "106.36646", "lat": "29.61203\n"}, {"lng": "106.366696", "lat": "29.612051\n"}, {"lng": "106.37035", "lat": "29.612156\n"}, {"lng": "106.374651", "lat": "29.61214\n"}, {"lng": "106.378093", "lat": "29.612096\n"}, {"lng": "106.378153", "lat": "29.612078\n"}, {"lng": "106.378198", "lat": "29.612083\n"}, {"lng": "106.37833", "lat": "29.612105\n"}, {"lng": "106.37846", "lat": "29.61212\n"}, {"lng": "106.379693", "lat": "29.612105\n"}, {"lng": "106.380753", "lat": "29.61197\n"}, {"lng": "106.381605", "lat": "29.611756\n"}, {"lng": "106.383603", "lat": "29.611061\n"}, {"lng": "106.384098", "lat": "29.610913\n"}, {"lng": "106.384285", "lat": "29.610855\n"}, {"lng": "106.385345", "lat": "29.610528\n"}, {"lng": "106.38565", "lat": "29.610451\n"}, {"lng": "106.38565", "lat": "29.610451\n"}, {"lng": "106.385915", "lat": "29.610401\n"}, {"lng": "106.386206", "lat": "29.610345\n"}, {"lng": "106.386226", "lat": "29.610335\n"}, {"lng": "106.386403", "lat": "29.6103\n"}, {"lng": "106.38658", "lat": "29.61027\n"}, {"lng": "106.386611", "lat": "29.610255\n"}, {"lng": "106.386675", "lat": "29.610243\n"}, {"lng": "106.386825", "lat": "29.610236\n"}, {"lng": "106.386991", "lat": "29.610215\n"}, {"lng": "106.387395", "lat": "29.610166\n"}, {"lng": "106.387485", "lat": "29.610156\n"}, {"lng": "106.387591", "lat": "29.610146\n"}, {"lng": "106.387591", "lat": "29.610146\n"}, {"lng": "106.387638", "lat": "29.610136\n"}, {"lng": "106.38778", "lat": "29.610118\n"}, {"lng": "106.387863", "lat": "29.610113\n"}, {"lng": "106.388031", "lat": "29.610101\n"}, {"lng": "106.388351", "lat": "29.610085\n"}, {"lng": "106.389061", "lat": "29.610033\n"}, {"lng": "106.389386", "lat": "29.609993\n"}, {"lng": "106.389428", "lat": "29.609978\n"}, {"lng": "106.389523", "lat": "29.609993\n"}, {"lng": "106.389571", "lat": "29.61\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.389993", "lat": "29.610195\n"}, {"lng": "106.435588", "lat": "29.605548\n"}, {"lng": "106.438256", "lat": "29.605048\n"}, {"lng": "106.439735", "lat": "29.604535\n"}, {"lng": "106.443626", "lat": "29.603025\n"}, {"lng": "106.4472", "lat": "29.601625\n"}, {"lng": "106.451066", "lat": "29.600068\n"}, {"lng": "106.454213", "lat": "29.598905\n"}, {"lng": "106.45434", "lat": "29.59888\n"}, {"lng": "106.454888", "lat": "29.598818\n"}, {"lng": "106.456268", "lat": "29.59885\n"}, {"lng": "106.457346", "lat": "29.598828\n"}, {"lng": "106.457583", "lat": "29.5988\n"}, {"lng": "106.458478", "lat": "29.598606\n"}, {"lng": "106.459485", "lat": "29.598228\n"}, {"lng": "106.461946", "lat": "29.596961\n"}, {"lng": "106.463806", "lat": "29.595875\n"}, {"lng": "106.46479", "lat": "29.595176\n"}, {"lng": "106.465008", "lat": "29.595086\n"}, {"lng": "106.465338", "lat": "29.59501\n"}, {"lng": "106.465613", "lat": "29.594993\n"}, {"lng": "106.466701", "lat": "29.59499\n"}, {"lng": "106.467031", "lat": "29.59493\n"}, {"lng": "106.4674", "lat": "29.594861\n"}, {"lng": "106.467635", "lat": "29.594811\n"}, {"lng": "106.468015", "lat": "29.594733\n"}, {"lng": "106.468356", "lat": "29.594663\n"}, {"lng": "106.468688", "lat": "29.594606\n"}, {"lng": "106.469243", "lat": "29.594496\n"}, {"lng": "106.4697", "lat": "29.594405\n"}, {"lng": "106.470393", "lat": "29.594256\n"}, {"lng": "106.470938", "lat": "29.594128\n"}, {"lng": "106.471188", "lat": "29.594086\n"}, {"lng": "106.471315", "lat": "29.59407\n"}, {"lng": "106.471315", "lat": "29.59407\n"}, {"lng": "106.471381", "lat": "29.593996\n"}, {"lng": "106.471381", "lat": "29.593996\n"}, {"lng": "106.471381", "lat": "29.593996\n"}, {"lng": "106.471381", "lat": "29.593996\n"}, {"lng": "106.471381", "lat": "29.593996\n"}, {"lng": "106.471016", "lat": "29.59573\n"}, {"lng": "106.471043", "lat": "29.59598\n"}, {"lng": "106.471066", "lat": "29.596046\n"}, {"lng": "106.471141", "lat": "29.596221\n"}, {"lng": "106.47149", "lat": "29.596728\n"}, {"lng": "106.471711", "lat": "29.597083\n"}, {"lng": "106.471793", "lat": "29.597168\n"}, {"lng": "106.471921", "lat": "29.597321\n"}, {"lng": "106.472008", "lat": "29.59745\n"}, {"lng": "106.473231", "lat": "29.599268\n"}, {"lng": "106.474456", "lat": "29.600981\n"}, {"lng": "106.476253", "lat": "29.603555\n"}, {"lng": "106.478031", "lat": "29.605808\n"}, {"lng": "106.478705", "lat": "29.606413\n"}, {"lng": "106.479531", "lat": "29.606973\n"}, {"lng": "106.479635", "lat": "29.607038\n"}, {"lng": "106.48009", "lat": "29.607296\n"}, {"lng": "106.4814", "lat": "29.607835\n"}, {"lng": "106.483045", "lat": "29.608393\n"}, {"lng": "106.484661", "lat": "29.608958\n"}, {"lng": "106.486753", "lat": "29.609663\n"}, {"lng": "106.488121", "lat": "29.610041\n"}, {"lng": "106.488623", "lat": "29.610021\n"}, {"lng": "106.488958", "lat": "29.609928\n"}, {"lng": "106.489265", "lat": "29.609778\n"}, {"lng": "106.489535", "lat": "29.609585\n"}, {"lng": "106.489755", "lat": "29.609358\n"}, {"lng": "106.489908", "lat": "29.609111\n"}, {"lng": "106.490006", "lat": "29.608851\n"}, {"lng": "106.49004", "lat": "29.608458\n"}, {"lng": "106.490031", "lat": "29.60833\n"}, {"lng": "106.489563", "lat": "29.606326\n"}, {"lng": "106.489528", "lat": "29.606178\n"}, {"lng": "106.489513", "lat": "29.606031\n"}, {"lng": "106.48948", "lat": "29.604848\n"}, {"lng": "106.48942", "lat": "29.604678\n"}, {"lng": "106.489378", "lat": "29.604641\n"}, {"lng": "106.489325", "lat": "29.604611\n"}, {"lng": "106.489313", "lat": "29.604593\n"}, {"lng": "106.48927", "lat": "29.60456\n"}, {"lng": "106.489196", "lat": "29.604556\n"}, {"lng": "106.489078", "lat": "29.60457\n"}, {"lng": "106.48942", "lat": "29.60452\n"}, {"lng": "106.489513", "lat": "29.604593\n"}, {"lng": "106.489671", "lat": "29.604805\n"}, {"lng": "106.489826", "lat": "29.605506\n"}, {"lng": "106.489901", "lat": "29.605845\n"}, {"lng": "106.489911", "lat": "29.605966\n"}, {"lng": "106.489981", "lat": "29.606478\n"}, {"lng": "106.490048", "lat": "29.606725\n"}, {"lng": "106.490123", "lat": "29.607035\n"}, {"lng": "106.490426", "lat": "29.608278\n"}, {"lng": "106.49082", "lat": "29.60894\n"}, {"lng": "106.492993", "lat": "29.611308\n"}, {"lng": "106.493921", "lat": "29.611998\n"}, {"lng": "106.49428", "lat": "29.612191\n"}, {"lng": "106.496546", "lat": "29.613038\n"}, {"lng": "106.499858", "lat": "29.614171\n"}, {"lng": "106.501808", "lat": "29.614551\n"}, {"lng": "106.506008", "lat": "29.614793\n"}, {"lng": "106.511356", "lat": "29.615113\n"}, {"lng": "106.51573", "lat": "29.615883\n"}, {"lng": "106.52062", "lat": "29.6174\n"}, {"lng": "106.521103", "lat": "29.61761\n"}, {"lng": "106.523751", "lat": "29.618693\n"}, {"lng": "106.524405", "lat": "29.6188\n"}, {"lng": "106.525161", "lat": "29.61881\n"}, {"lng": "106.525318", "lat": "29.618796\n"}, {"lng": "106.526193", "lat": "29.618633\n"}, {"lng": "106.528783", "lat": "29.617955\n"}, {"lng": "106.5296", "lat": "29.617983\n"}, {"lng": "106.530508", "lat": "29.618173\n"}, {"lng": "106.530946", "lat": "29.618333\n"}, {"lng": "106.536373", "lat": "29.621093\n"}, {"lng": "106.538231", "lat": "29.621951\n"}, {"lng": "106.539586", "lat": "29.622285\n"}, {"lng": "106.541451", "lat": "29.622491\n"}, {"lng": "106.547163", "lat": "29.62288\n"}, {"lng": "106.551135", "lat": "29.62318\n"}, {"lng": "106.551746", "lat": "29.623071\n"}, {"lng": "106.552366", "lat": "29.622858\n"}, {"lng": "106.552928", "lat": "29.622525\n"}, {"lng": "106.553408", "lat": "29.622078\n"}, {"lng": "106.553761", "lat": "29.621568\n"}, {"lng": "106.553971", "lat": "29.621085\n"}, {"lng": "106.55433", "lat": "29.619071\n"}, {"lng": "106.554345", "lat": "29.61893\n"}, {"lng": "106.55461", "lat": "29.617645\n"}, {"lng": "106.555123", "lat": "29.616488\n"}, {"lng": "106.555801", "lat": "29.615525\n"}, {"lng": "106.556685", "lat": "29.614673\n"}, {"lng": "106.557566", "lat": "29.614041\n"}, {"lng": "106.558643", "lat": "29.613508\n"}, {"lng": "106.559913", "lat": "29.613148\n"}, {"lng": "106.565655", "lat": "29.611973\n"}, {"lng": "106.574231", "lat": "29.609888\n"}, {"lng": "106.581846", "lat": "29.606735\n"}, {"lng": "106.589951", "lat": "29.603261\n"}, {"lng": "106.594541", "lat": "29.6011\n"}, {"lng": "106.5959", "lat": "29.60005\n"}, {"lng": "106.596643", "lat": "29.599225\n"}, {"lng": "106.597645", "lat": "29.597795\n"}, {"lng": "106.598491", "lat": "29.595783\n"}, {"lng": "106.599025", "lat": "29.593788\n"}, {"lng": "106.599518", "lat": "29.591826\n"}, {"lng": "106.599483", "lat": "29.591545\n"}, {"lng": "106.599243", "lat": "29.590313\n"}, {"lng": "106.599315", "lat": "29.589813\n"}, {"lng": "106.599588", "lat": "29.588765\n"}, {"lng": "106.600148", "lat": "29.586796\n"}, {"lng": "106.600188", "lat": "29.586675\n"}, {"lng": "106.600201", "lat": "29.58652\n"}, {"lng": "106.600196", "lat": "29.586075\n"}, {"lng": "106.60011", "lat": "29.584358\n"}, {"lng": "106.600033", "lat": "29.584201\n"}, {"lng": "106.599591", "lat": "29.583591\n"}, {"lng": "106.59953", "lat": "29.583356\n"}, {"lng": "106.599535", "lat": "29.58319\n"}, {"lng": "106.599583", "lat": "29.582196\n"}, {"lng": "106.59954", "lat": "29.582101\n"}, {"lng": "106.599541", "lat": "29.58202\n"}, {"lng": "106.599566", "lat": "29.58186\n"}, {"lng": "106.599556", "lat": "29.58143\n"}, {"lng": "106.599531", "lat": "29.581238\n"}, {"lng": "106.59942", "lat": "29.580988\n"}, {"lng": "106.599075", "lat": "29.580548\n"}, {"lng": "106.598998", "lat": "29.580371\n"}, {"lng": "106.598826", "lat": "29.580243\n"}, {"lng": "106.598598", "lat": "29.580171\n"}, {"lng": "106.598381", "lat": "29.580156\n"}, {"lng": "106.598215", "lat": "29.580195\n"}, {"lng": "106.598066", "lat": "29.580266\n"}, {"lng": "106.597168", "lat": "29.580861\n"}, {"lng": "106.5971", "lat": "29.580881\n"}, {"lng": "106.596883", "lat": "29.580918\n"}, {"lng": "106.596485", "lat": "29.58094\n"}, {"lng": "106.596395", "lat": "29.580918\n"}, {"lng": "106.596351", "lat": "29.580896\n"}, {"lng": "106.596285", "lat": "29.580825\n"}, {"lng": "106.596246", "lat": "29.580695\n"}, {"lng": "106.596253", "lat": "29.580378\n"}, {"lng": "106.596355", "lat": "29.579646\n"}, {"lng": "106.596563", "lat": "29.579251\n"}, {"lng": "106.597333", "lat": "29.578206\n"}, {"lng": "106.597531", "lat": "29.578023\n"}, {"lng": "106.597761", "lat": "29.577653\n"}, {"lng": "106.597776", "lat": "29.5775\n"}, {"lng": "106.597778", "lat": "29.577413\n"}, {"lng": "106.597756", "lat": "29.577235\n"}, {"lng": "106.597618", "lat": "29.5769\n"}, {"lng": "106.597361", "lat": "29.576315\n"}, {"lng": "106.597266", "lat": "29.57608\n"}, {"lng": "106.597143", "lat": "29.576006\n"}, {"lng": "106.597116", "lat": "29.575966\n"}, {"lng": "106.597083", "lat": "29.57593\n"}, {"lng": "106.597056", "lat": "29.575915\n"}, {"lng": "106.596976", "lat": "29.575886\n"}, {"lng": "106.596916", "lat": "29.575878\n"}, {"lng": "106.596776", "lat": "29.575915\n"}, {"lng": "106.596406", "lat": "29.576011\n"}, {"lng": "106.596253", "lat": "29.576018\n"}, {"lng": "106.59586", "lat": "29.575971\n"}, {"lng": "106.595778", "lat": "29.575956\n"}, {"lng": "106.595226", "lat": "29.575818\n"}, {"lng": "106.595013", "lat": "29.575741\n"}, {"lng": "106.594976", "lat": "29.575726\n"}, {"lng": "106.594956", "lat": "29.575711\n"}, {"lng": "106.594896", "lat": "29.575681\n"}, {"lng": "106.594661", "lat": "29.575591\n"}, {"lng": "106.59453", "lat": "29.575545\n"}, {"lng": "106.594498", "lat": "29.575518\n"}, {"lng": "106.594478", "lat": "29.575486\n"}, {"lng": "106.59447", "lat": "29.575451\n"}, {"lng": "106.59447", "lat": "29.57541\n"}, {"lng": "106.594483", "lat": "29.575275\n"}, {"lng": "106.594473", "lat": "29.575185\n"}, {"lng": "106.594428", "lat": "29.57513\n"}, {"lng": "106.594391", "lat": "29.575121\n"}, {"lng": "106.59435", "lat": "29.575125\n"}, {"lng": "106.594305", "lat": "29.575135\n"}, {"lng": "106.594198", "lat": "29.575166\n"}, {"lng": "106.593661", "lat": "29.575371\n"}, {"lng": "106.593606", "lat": "29.575411\n"}, {"lng": "106.593476", "lat": "29.575548\n"}, {"lng": "106.593363", "lat": "29.575676\n"}, {"lng": "106.59325", "lat": "29.575738\n"}, {"lng": "106.593176", "lat": "29.57576\n"}, {"lng": "106.592536", "lat": "29.57602\n"}, {"lng": "106.592505", "lat": "29.576071\n"}, {"lng": "106.592468", "lat": "29.576196\n"}, {"lng": "106.592301", "lat": "29.576678\n"}, {"lng": "106.592231", "lat": "29.576746\n"}, {"lng": "106.592063", "lat": "29.576848\n"}, {"lng": "106.591801", "lat": "29.576965\n"}, {"lng": "106.591715", "lat": "29.57698\n"}, {"lng": "106.591633", "lat": "29.57697\n"}, {"lng": "106.591563", "lat": "29.57694\n"}, {"lng": "106.591481", "lat": "29.576833\n"}, {"lng": "106.591441", "lat": "29.576718\n"}, {"lng": "106.591441", "lat": "29.57665\n"}, {"lng": "106.59147", "lat": "29.576533\n"}, {"lng": "106.591456", "lat": "29.576468\n"}, {"lng": "106.591225", "lat": "29.575853\n"}, {"lng": "106.591078", "lat": "29.575711\n"}, {"lng": "106.590995", "lat": "29.575673\n"}, {"lng": "106.590653", "lat": "29.575616\n"}, {"lng": "106.590346", "lat": "29.575651\n"}, {"lng": "106.589585", "lat": "29.575773\n"}, {"lng": "106.58941", "lat": "29.57574\n"}, {"lng": "106.588855", "lat": "29.575533\n"}, {"lng": "106.58867", "lat": "29.575393\n"}, {"lng": "106.588263", "lat": "29.57508\n"}, {"lng": "106.58818", "lat": "29.575058\n"}, {"lng": "106.588093", "lat": "29.575065\n"}, {"lng": "106.588011", "lat": "29.575108\n"}, {"lng": "106.587836", "lat": "29.575231\n"}, {"lng": "106.587395", "lat": "29.575621\n"}, {"lng": "106.587358", "lat": "29.575683\n"}, {"lng": "106.587353", "lat": "29.575735\n"}, {"lng": "106.58738", "lat": "29.575775\n"}, {"lng": "106.587416", "lat": "29.575803\n"}, {"lng": "106.587458", "lat": "29.575811\n"}, {"lng": "106.587495", "lat": "29.575813\n"}, {"lng": "106.587595", "lat": "29.575806\n"}, {"lng": "106.587818", "lat": "29.575816\n"}, {"lng": "106.587845", "lat": "29.575825\n"}, {"lng": "106.587845", "lat": "29.575825\n"}, {"lng": "106.587845", "lat": "29.575825"}]}
\ No newline at end of file
{"name": "gpsLine", "GPSLine": [{"lng": "106.597495", "lat": "29.715498\n"}, {"lng": "106.597495", "lat": "29.715498\n"}, {"lng": "106.597495", "lat": "29.715498\n"}, {"lng": "106.597495", "lat": "29.715498\n"}, {"lng": "106.597258", "lat": "29.715191\n"}, {"lng": "106.597231", "lat": "29.715181\n"}, {"lng": "106.597195", "lat": "29.715178\n"}, {"lng": "106.597143", "lat": "29.71518\n"}, {"lng": "106.597008", "lat": "29.715185\n"}, {"lng": "106.596721", "lat": "29.715243\n"}, {"lng": "106.596056", "lat": "29.71545\n"}, {"lng": "106.595986", "lat": "29.715498\n"}, {"lng": "106.595931", "lat": "29.715558\n"}, {"lng": "106.5959", "lat": "29.715636\n"}, {"lng": "106.595863", "lat": "29.715915\n"}, {"lng": "106.59576", "lat": "29.71727\n"}, {"lng": "106.595735", "lat": "29.71755\n"}, {"lng": "106.595878", "lat": "29.719105\n"}, {"lng": "106.596391", "lat": "29.720531\n"}, {"lng": "106.596681", "lat": "29.721093\n"}, {"lng": "106.598001", "lat": "29.723316\n"}, {"lng": "106.598043", "lat": "29.723341\n"}, {"lng": "106.598103", "lat": "29.723356\n"}, {"lng": "106.59817", "lat": "29.723376\n"}, {"lng": "106.59835", "lat": "29.723391\n"}, {"lng": "106.59857", "lat": "29.723391\n"}, {"lng": "106.602948", "lat": "29.72335\n"}, {"lng": "106.604158", "lat": "29.723346\n"}, {"lng": "106.606105", "lat": "29.723356\n"}, {"lng": "106.608568", "lat": "29.723358\n"}, {"lng": "106.6087", "lat": "29.723363\n"}, {"lng": "106.6087", "lat": "29.723363\n"}, {"lng": "106.609365", "lat": "29.723346\n"}, {"lng": "106.609385", "lat": "29.723343\n"}, {"lng": "106.609385", "lat": "29.723343\n"}, {"lng": "106.609868", "lat": "29.723355\n"}, {"lng": "106.613723", "lat": "29.723353\n"}, {"lng": "106.614495", "lat": "29.723273\n"}, {"lng": "106.615505", "lat": "29.723008\n"}, {"lng": "106.615505", "lat": "29.723008\n"}, {"lng": "106.62447", "lat": "29.72212\n"}, {"lng": "106.625515", "lat": "29.722123\n"}, {"lng": "106.625515", "lat": "29.722123\n"}, {"lng": "106.632141", "lat": "29.721476\n"}, {"lng": "106.632235", "lat": "29.721426\n"}, {"lng": "106.632291", "lat": "29.721336\n"}, {"lng": "106.632326", "lat": "29.721255\n"}, {"lng": "106.632323", "lat": "29.721166\n"}, {"lng": "106.632263", "lat": "29.720966\n"}, {"lng": "106.631975", "lat": "29.719906\n"}, {"lng": "106.630851", "lat": "29.716403\n"}, {"lng": "106.631013", "lat": "29.716293\n"}, {"lng": "106.631165", "lat": "29.716255\n"}, {"lng": "106.631915", "lat": "29.715973\n"}, {"lng": "106.632115", "lat": "29.71581\n"}, {"lng": "106.63227", "lat": "29.715611\n"}, {"lng": "106.632333", "lat": "29.715418\n"}, {"lng": "106.632333", "lat": "29.715213\n"}, {"lng": "106.632271", "lat": "29.715005\n"}, {"lng": "106.631836", "lat": "29.713595\n"}, {"lng": "106.631435", "lat": "29.712523\n"}, {"lng": "106.631308", "lat": "29.712408\n"}, {"lng": "106.631201", "lat": "29.712295\n"}, {"lng": "106.631171", "lat": "29.712231\n"}, {"lng": "106.63116", "lat": "29.712165\n"}, {"lng": "106.631158", "lat": "29.712096\n"}, {"lng": "106.631136", "lat": "29.711848\n"}, {"lng": "106.630786", "lat": "29.710756\n"}, {"lng": "106.629801", "lat": "29.707925\n"}, {"lng": "106.629801", "lat": "29.707925\n"}, {"lng": "106.629801", "lat": "29.707925\n"}, {"lng": "106.628816", "lat": "29.704841\n"}, {"lng": "106.628831", "lat": "29.70477\n"}, {"lng": "106.628873", "lat": "29.704711\n"}, {"lng": "106.628938", "lat": "29.704668\n"}, {"lng": "106.629025", "lat": "29.704651\n"}, {"lng": "106.629123", "lat": "29.704651\n"}, {"lng": "106.630831", "lat": "29.70468\n"}, {"lng": "106.632243", "lat": "29.704356\n"}, {"lng": "106.633906", "lat": "29.703646\n"}, {"lng": "106.635908", "lat": "29.702735\n"}, {"lng": "106.639518", "lat": "29.701456\n"}, {"lng": "106.640381", "lat": "29.701475\n"}, {"lng": "106.640603", "lat": "29.70151\n"}, {"lng": "106.641648", "lat": "29.701748\n"}, {"lng": "106.644295", "lat": "29.702938\n"}, {"lng": "106.644538", "lat": "29.703033\n"}, {"lng": "106.64464", "lat": "29.703038\n"}, {"lng": "106.644741", "lat": "29.703023\n"}, {"lng": "106.647585", "lat": "29.702196\n"}, {"lng": "106.647681", "lat": "29.702121\n"}, {"lng": "106.647763", "lat": "29.702031\n"}, {"lng": "106.647898", "lat": "29.701816\n"}, {"lng": "106.647966", "lat": "29.70157\n"}, {"lng": "106.647958", "lat": "29.701445\n"}, {"lng": "106.646828", "lat": "29.697065\n"}, {"lng": "106.644126", "lat": "29.689963\n"}, {"lng": "106.64176", "lat": "29.686225\n"}, {"lng": "106.638655", "lat": "29.682431\n"}, {"lng": "106.632641", "lat": "29.675176\n"}, {"lng": "106.628875", "lat": "29.669918\n"}, {"lng": "106.628273", "lat": "29.66877\n"}, {"lng": "106.624655", "lat": "29.661561\n"}, {"lng": "106.62259", "lat": "29.658756\n"}, {"lng": "106.618748", "lat": "29.65431\n"}, {"lng": "106.613693", "lat": "29.647371\n"}, {"lng": "106.608845", "lat": "29.640648\n"}, {"lng": "106.607166", "lat": "29.637853\n"}, {"lng": "106.606445", "lat": "29.63572\n"}, {"lng": "106.606165", "lat": "29.634108\n"}, {"lng": "106.60618", "lat": "29.631573\n"}, {"lng": "106.606673", "lat": "29.627206\n"}, {"lng": "106.60695", "lat": "29.61928\n"}, {"lng": "106.607138", "lat": "29.610996\n"}, {"lng": "106.606578", "lat": "29.604418\n"}, {"lng": "106.605823", "lat": "29.598575\n"}, {"lng": "106.604053", "lat": "29.593738\n"}, {"lng": "106.60236", "lat": "29.58983\n"}, {"lng": "106.602068", "lat": "29.589403\n"}, {"lng": "106.601778", "lat": "29.589135\n"}, {"lng": "106.601461", "lat": "29.588945\n"}, {"lng": "106.60107", "lat": "29.588793\n"}, {"lng": "106.600653", "lat": "29.58872\n"}, {"lng": "106.600198", "lat": "29.588718\n"}, {"lng": "106.599111", "lat": "29.588773\n"}, {"lng": "106.593851", "lat": "29.588923\n"}, {"lng": "106.591751", "lat": "29.588931\n"}, {"lng": "106.591641", "lat": "29.588973\n"}, {"lng": "106.591555", "lat": "29.589033\n"}, {"lng": "106.591486", "lat": "29.589106\n"}, {"lng": "106.591436", "lat": "29.589191\n"}, {"lng": "106.591405", "lat": "29.589286\n"}, {"lng": "106.591231", "lat": "29.590408\n"}, {"lng": "106.591223", "lat": "29.590531\n"}, {"lng": "106.591208", "lat": "29.592293\n"}, {"lng": "106.591495", "lat": "29.593398\n"}, {"lng": "106.591518", "lat": "29.593476\n"}, {"lng": "106.591518", "lat": "29.593476\n"}, {"lng": "106.591546", "lat": "29.593823\n"}, {"lng": "106.591515", "lat": "29.593871\n"}, {"lng": "106.59147", "lat": "29.593911\n"}, {"lng": "106.591413", "lat": "29.593945\n"}, {"lng": "106.591348", "lat": "29.593963\n"}, {"lng": "106.591273", "lat": "29.593976\n"}, {"lng": "106.590715", "lat": "29.59408\n"}, {"lng": "106.590285", "lat": "29.594135\n"}, {"lng": "106.590176", "lat": "29.594151\n"}, {"lng": "106.587883", "lat": "29.594633\n"}, {"lng": "106.587883", "lat": "29.594641\n"}, {"lng": "106.58583", "lat": "29.595106\n"}, {"lng": "106.585778", "lat": "29.59519\n"}, {"lng": "106.585751", "lat": "29.595281\n"}, {"lng": "106.585756", "lat": "29.595496\n"}, {"lng": "106.58588", "lat": "29.596118\n"}, {"lng": "106.585941", "lat": "29.596226\n"}, {"lng": "106.586123", "lat": "29.596411\n"}, {"lng": "106.586503", "lat": "29.596635\n"}, {"lng": "106.586975", "lat": "29.59696\n"}, {"lng": "106.587038", "lat": "29.597063\n"}, {"lng": "106.58711", "lat": "29.597273\n"}, {"lng": "106.587143", "lat": "29.59769\n"}, {"lng": "106.587171", "lat": "29.599486\n"}, {"lng": "106.587098", "lat": "29.599621\n"}, {"lng": "106.58692", "lat": "29.599823\n"}, {"lng": "106.586703", "lat": "29.599965\n"}, {"lng": "106.586316", "lat": "29.600108\n"}, {"lng": "106.583935", "lat": "29.600895\n"}, {"lng": "106.583715", "lat": "29.600953\n"}, {"lng": "106.583641", "lat": "29.600951\n"}, {"lng": "106.583568", "lat": "29.600925\n"}, {"lng": "106.583503", "lat": "29.600876\n"}, {"lng": "106.583451", "lat": "29.600808\n"}, {"lng": "106.58342", "lat": "29.600708\n"}, {"lng": "106.582803", "lat": "29.598305\n"}, {"lng": "106.582431", "lat": "29.596901\n"}, {"lng": "106.580938", "lat": "29.592926\n"}, {"lng": "106.580518", "lat": "29.590686\n"}, {"lng": "106.580463", "lat": "29.59025\n"}, {"lng": "106.580446", "lat": "29.58901\n"}, {"lng": "106.580448", "lat": "29.58523\n"}, {"lng": "106.580383", "lat": "29.58225\n"}, {"lng": "106.580535", "lat": "29.58181\n"}, {"lng": "106.580938", "lat": "29.581141\n"}, {"lng": "106.581355", "lat": "29.580713\n"}, {"lng": "106.581948", "lat": "29.580281\n"}, {"lng": "106.58283", "lat": "29.579855\n"}, {"lng": "106.583291", "lat": "29.57967\n"}, {"lng": "106.583413", "lat": "29.579613\n"}, {"lng": "106.583413", "lat": "29.579613\n"}, {"lng": "106.585158", "lat": "29.577626\n"}, {"lng": "106.586611", "lat": "29.576251\n"}, {"lng": "106.587248", "lat": "29.575718\n"}, {"lng": "106.587286", "lat": "29.575708\n"}, {"lng": "106.587328", "lat": "29.575711\n"}, {"lng": "106.587368", "lat": "29.575726\n"}, {"lng": "106.587458", "lat": "29.575771\n"}, {"lng": "106.587538", "lat": "29.575788\n"}, {"lng": "106.587618", "lat": "29.575786\n"}, {"lng": "106.587833", "lat": "29.575755\n"}, {"lng": "106.587853", "lat": "29.57572\n"}, {"lng": "106.587885", "lat": "29.575676\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621\n"}, {"lng": "106.58792", "lat": "29.575621"}]}
\ No newline at end of file
{"name": "gpsLine", "GPSLine": [{"lng": "106.599021", "lat": "29.58118\n"}, {"lng": "106.599021", "lat": "29.58118\n"}, {"lng": "106.598375", "lat": "29.580248\n"}, {"lng": "106.598233", "lat": "29.580251\n"}, {"lng": "106.598086", "lat": "29.580311\n"}, {"lng": "106.598025", "lat": "29.580328\n"}, {"lng": "106.597785", "lat": "29.580461\n"}, {"lng": "106.597433", "lat": "29.580715\n"}, {"lng": "106.59717", "lat": "29.580863\n"}, {"lng": "106.596965", "lat": "29.580923\n"}, {"lng": "106.596686", "lat": "29.580965\n"}, {"lng": "106.596516", "lat": "29.580965\n"}, {"lng": "106.596516", "lat": "29.580965\n"}, {"lng": "106.596293", "lat": "29.580956\n"}, {"lng": "106.59627", "lat": "29.58092\n"}, {"lng": "106.59626", "lat": "29.580863\n"}, {"lng": "106.596256", "lat": "29.580786\n"}, {"lng": "106.596293", "lat": "29.58042\n"}, {"lng": "106.59639", "lat": "29.579695\n"}, {"lng": "106.59648", "lat": "29.579493\n"}, {"lng": "106.596866", "lat": "29.57891\n"}, {"lng": "106.5976", "lat": "29.577858\n"}, {"lng": "106.597736", "lat": "29.577583\n"}, {"lng": "106.597738", "lat": "29.577518\n"}, {"lng": "106.597733", "lat": "29.57715\n"}, {"lng": "106.597666", "lat": "29.576971\n"}, {"lng": "106.597101", "lat": "29.575966\n"}, {"lng": "106.597026", "lat": "29.575928\n"}, {"lng": "106.596896", "lat": "29.575918\n"}, {"lng": "106.596751", "lat": "29.575935\n"}, {"lng": "106.596655", "lat": "29.575958\n"}, {"lng": "106.596513", "lat": "29.575993\n"}, {"lng": "106.596305", "lat": "29.576015\n"}, {"lng": "106.59592", "lat": "29.576016\n"}, {"lng": "106.595193", "lat": "29.575835\n"}, {"lng": "106.594995", "lat": "29.575755\n"}, {"lng": "106.594668", "lat": "29.5756\n"}, {"lng": "106.594515", "lat": "29.575545\n"}, {"lng": "106.594465", "lat": "29.575485\n"}, {"lng": "106.59446", "lat": "29.575448\n"}, {"lng": "106.59446", "lat": "29.575385\n"}, {"lng": "106.594466", "lat": "29.575341\n"}, {"lng": "106.594483", "lat": "29.575148\n"}, {"lng": "106.594466", "lat": "29.575131\n"}, {"lng": "106.594435", "lat": "29.575125\n"}, {"lng": "106.594396", "lat": "29.575126\n"}, {"lng": "106.59435", "lat": "29.575135\n"}, {"lng": "106.594291", "lat": "29.57515\n"}, {"lng": "106.593961", "lat": "29.575268\n"}, {"lng": "106.593655", "lat": "29.57541\n"}, {"lng": "106.593603", "lat": "29.57545\n"}, {"lng": "106.593445", "lat": "29.575618\n"}, {"lng": "106.593338", "lat": "29.57573\n"}, {"lng": "106.593236", "lat": "29.57578\n"}, {"lng": "106.592581", "lat": "29.576023\n"}, {"lng": "106.592536", "lat": "29.576076\n"}, {"lng": "106.592508", "lat": "29.576135\n"}, {"lng": "106.592493", "lat": "29.576208\n"}, {"lng": "106.592476", "lat": "29.576285\n"}, {"lng": "106.592346", "lat": "29.57666\n"}, {"lng": "106.59228", "lat": "29.576743\n"}, {"lng": "106.59219", "lat": "29.576816\n"}, {"lng": "106.591973", "lat": "29.576921\n"}, {"lng": "106.591771", "lat": "29.576991\n"}, {"lng": "106.591618", "lat": "29.576983\n"}, {"lng": "106.591565", "lat": "29.576953\n"}, {"lng": "106.591531", "lat": "29.576908\n"}, {"lng": "106.591508", "lat": "29.576856\n"}, {"lng": "106.59149", "lat": "29.57673\n"}, {"lng": "106.591485", "lat": "29.576293\n"}, {"lng": "106.59144", "lat": "29.576208\n"}, {"lng": "106.591411", "lat": "29.576081\n"}, {"lng": "106.59126", "lat": "29.575768\n"}, {"lng": "106.591028", "lat": "29.575528\n"}, {"lng": "106.590843", "lat": "29.57537\n"}, {"lng": "106.590715", "lat": "29.575391\n"}, {"lng": "106.59059", "lat": "29.575416\n"}, {"lng": "106.590465", "lat": "29.575441\n"}, {"lng": "106.590355", "lat": "29.575483\n"}, {"lng": "106.589895", "lat": "29.575628\n"}, {"lng": "106.589628", "lat": "29.575645\n"}, {"lng": "106.589491", "lat": "29.575616\n"}, {"lng": "106.589208", "lat": "29.575585\n"}, {"lng": "106.588721", "lat": "29.575371\n"}, {"lng": "106.588195", "lat": "29.575006\n"}, {"lng": "106.588145", "lat": "29.575001\n"}, {"lng": "106.58803", "lat": "29.57503\n"}, {"lng": "106.587971", "lat": "29.575073\n"}, {"lng": "106.587826", "lat": "29.575193\n"}, {"lng": "106.58736", "lat": "29.575653\n"}, {"lng": "106.58735", "lat": "29.575705\n"}, {"lng": "106.587358", "lat": "29.575745\n"}, {"lng": "106.58738", "lat": "29.575771\n"}, {"lng": "106.587411", "lat": "29.575786\n"}, {"lng": "106.587455", "lat": "29.575795\n"}, {"lng": "106.587495", "lat": "29.575796\n"}, {"lng": "106.587571", "lat": "29.575791\n"}, {"lng": "106.587713", "lat": "29.575773\n"}, {"lng": "106.58799", "lat": "29.575745\n"}, {"lng": "106.58799", "lat": "29.575745\n"}, {"lng": "106.58799", "lat": "29.575745\n"}]}
\ No newline at end of file
{"name": "gpsLine", "GPSLine": [{"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.484645", "lat": "29.519863\n"}, {"lng": "106.498255", "lat": "29.51929\n"}, {"lng": "106.49839", "lat": "29.519245\n"}, {"lng": "106.498496", "lat": "29.519196\n"}, {"lng": "106.498686", "lat": "29.519095\n"}, {"lng": "106.498731", "lat": "29.519106\n"}, {"lng": "106.49879", "lat": "29.519121\n"}, {"lng": "106.498851", "lat": "29.519141\n"}, {"lng": "106.499026", "lat": "29.519215\n"}, {"lng": "106.499136", "lat": "29.519258\n"}, {"lng": "106.49923", "lat": "29.519415\n"}, {"lng": "106.499251", "lat": "29.519476\n"}, {"lng": "106.49952", "lat": "29.519686\n"}, {"lng": "106.500043", "lat": "29.520288\n"}, {"lng": "106.500173", "lat": "29.52039\n"}, {"lng": "106.500246", "lat": "29.520403\n"}, {"lng": "106.501561", "lat": "29.521333\n"}, {"lng": "106.502366", "lat": "29.52206\n"}, {"lng": "106.502606", "lat": "29.522266\n"}, {"lng": "106.502881", "lat": "29.522416\n"}, {"lng": "106.503096", "lat": "29.52248\n"}, {"lng": "106.50344", "lat": "29.522505\n"}, {"lng": "106.503656", "lat": "29.522483\n"}, {"lng": "106.50396", "lat": "29.52239\n"}, {"lng": "106.50414", "lat": "29.52232\n"}, {"lng": "106.504521", "lat": "29.522191\n"}, {"lng": "106.504866", "lat": "29.522156\n"}, {"lng": "106.506228", "lat": "29.52215\n"}, {"lng": "106.506621", "lat": "29.522256\n"}, {"lng": "106.507173", "lat": "29.522475\n"}, {"lng": "106.507423", "lat": "29.52261\n"}, {"lng": "106.507683", "lat": "29.522835\n"}, {"lng": "106.50822", "lat": "29.523151\n"}, {"lng": "106.509468", "lat": "29.52365\n"}, {"lng": "106.5102", "lat": "29.523761\n"}, {"lng": "106.511401", "lat": "29.523706\n"}, {"lng": "106.516661", "lat": "29.523321\n"}, {"lng": "106.520538", "lat": "29.523081\n"}, {"lng": "106.525145", "lat": "29.523038\n"}, {"lng": "106.530208", "lat": "29.52304\n"}, {"lng": "106.534585", "lat": "29.523023\n"}, {"lng": "106.536085", "lat": "29.522871\n"}, {"lng": "106.53838", "lat": "29.522366\n"}, {"lng": "106.538986", "lat": "29.522248\n"}, {"lng": "106.53921", "lat": "29.52228\n"}, {"lng": "106.539255", "lat": "29.522316\n"}, {"lng": "106.539286", "lat": "29.522361\n"}, {"lng": "106.539286", "lat": "29.52241\n"}, {"lng": "106.539268", "lat": "29.52246\n"}, {"lng": "106.539235", "lat": "29.522498\n"}, {"lng": "106.539196", "lat": "29.522511\n"}, {"lng": "106.539136", "lat": "29.522541\n"}, {"lng": "106.538613", "lat": "29.522701\n"}, {"lng": "106.537718", "lat": "29.522915\n"}, {"lng": "106.536041", "lat": "29.523331\n"}, {"lng": "106.535086", "lat": "29.523863\n"}, {"lng": "106.535016", "lat": "29.52399\n"}, {"lng": "106.535003", "lat": "29.524065\n"}, {"lng": "106.535001", "lat": "29.52414\n"}, {"lng": "106.535031", "lat": "29.524296\n"}, {"lng": "106.53507", "lat": "29.524366\n"}, {"lng": "106.535133", "lat": "29.524436\n"}, {"lng": "106.535296", "lat": "29.52455\n"}, {"lng": "106.535813", "lat": "29.524886\n"}, {"lng": "106.53595", "lat": "29.525051\n"}, {"lng": "106.535985", "lat": "29.525153\n"}, {"lng": "106.53598", "lat": "29.525195\n"}, {"lng": "106.53596", "lat": "29.525226\n"}, {"lng": "106.535921", "lat": "29.525256\n"}, {"lng": "106.535871", "lat": "29.52527\n"}, {"lng": "106.53581", "lat": "29.52526\n"}, {"lng": "106.535745", "lat": "29.525235\n"}, {"lng": "106.535548", "lat": "29.525113\n"}, {"lng": "106.535295", "lat": "29.52499\n"}, {"lng": "106.534181", "lat": "29.524505\n"}, {"lng": "106.534015", "lat": "29.524511\n"}, {"lng": "106.533921", "lat": "29.524543\n"}, {"lng": "106.533768", "lat": "29.524628\n"}, {"lng": "106.533665", "lat": "29.524743\n"}, {"lng": "106.53361", "lat": "29.524888\n"}, {"lng": "106.533585", "lat": "29.525051\n"}, {"lng": "106.533611", "lat": "29.525138\n"}, {"lng": "106.533673", "lat": "29.525208\n"}, {"lng": "106.533736", "lat": "29.525261\n"}, {"lng": "106.533976", "lat": "29.525435\n"}, {"lng": "106.534098", "lat": "29.525563\n"}, {"lng": "106.5341", "lat": "29.525606\n"}, {"lng": "106.534081", "lat": "29.525646\n"}, {"lng": "106.534018", "lat": "29.525793\n"}, {"lng": "106.534031", "lat": "29.525828\n"}, {"lng": "106.534056", "lat": "29.525858\n"}, {"lng": "106.534106", "lat": "29.525928\n"}, {"lng": "106.534096", "lat": "29.525956\n"}, {"lng": "106.534076", "lat": "29.525965\n"}, {"lng": "106.53405", "lat": "29.525968\n"}, {"lng": "106.53402", "lat": "29.525961\n"}, {"lng": "106.533986", "lat": "29.525936\n"}, {"lng": "106.533455", "lat": "29.525546\n"}, {"lng": "106.5332", "lat": "29.525413\n"}, {"lng": "106.532426", "lat": "29.525155\n"}, {"lng": "106.532353", "lat": "29.525163\n"}, {"lng": "106.53229", "lat": "29.5252\n"}, {"lng": "106.532241", "lat": "29.525253\n"}, {"lng": "106.532198", "lat": "29.525315\n"}, {"lng": "106.531586", "lat": "29.5269\n"}, {"lng": "106.531363", "lat": "29.52778\n"}, {"lng": "106.531326", "lat": "29.528746\n"}, {"lng": "106.531458", "lat": "29.529691\n"}, {"lng": "106.532046", "lat": "29.53156\n"}, {"lng": "106.53357", "lat": "29.535643\n"}, {"lng": "106.53374", "lat": "29.535928\n"}, {"lng": "106.534836", "lat": "29.5374\n"}, {"lng": "106.536893", "lat": "29.539351\n"}, {"lng": "106.538446", "lat": "29.540533\n"}, {"lng": "106.539238", "lat": "29.540896\n"}, {"lng": "106.540116", "lat": "29.541156\n"}, {"lng": "106.540788", "lat": "29.541235\n"}, {"lng": "106.541853", "lat": "29.541261\n"}, {"lng": "106.54615", "lat": "29.540981\n"}, {"lng": "106.549441", "lat": "29.540926\n"}, {"lng": "106.550593", "lat": "29.54118\n"}, {"lng": "106.551516", "lat": "29.541558\n"}, {"lng": "106.554295", "lat": "29.542755\n"}, {"lng": "106.555916", "lat": "29.543063\n"}, {"lng": "106.556861", "lat": "29.543186\n"}, {"lng": "106.560363", "lat": "29.54361\n"}, {"lng": "106.561361", "lat": "29.543498\n"}, {"lng": "106.562058", "lat": "29.543373\n"}, {"lng": "106.563295", "lat": "29.543205\n"}, {"lng": "106.564865", "lat": "29.543231\n"}, {"lng": "106.567205", "lat": "29.543681\n"}, {"lng": "106.571403", "lat": "29.544415\n"}, {"lng": "106.574481", "lat": "29.544786\n"}, {"lng": "106.574908", "lat": "29.544871\n"}, {"lng": "106.574951", "lat": "29.544865\n"}, {"lng": "106.574981", "lat": "29.54487\n"}, {"lng": "106.575065", "lat": "29.544883\n"}, {"lng": "106.575368", "lat": "29.544971\n"}, {"lng": "106.575446", "lat": "29.545\n"}, {"lng": "106.57792", "lat": "29.545733\n"}, {"lng": "106.57879", "lat": "29.545958\n"}, {"lng": "106.5819", "lat": "29.546685\n"}, {"lng": "106.582638", "lat": "29.546916\n"}, {"lng": "106.583336", "lat": "29.547221\n"}, {"lng": "106.584188", "lat": "29.5478\n"}, {"lng": "106.584356", "lat": "29.547933\n"}, {"lng": "106.584933", "lat": "29.548418\n"}, {"lng": "106.585056", "lat": "29.548348\n"}, {"lng": "106.585081", "lat": "29.548358\n"}, {"lng": "106.585181", "lat": "29.548448\n"}, {"lng": "106.58525", "lat": "29.54856\n"}, {"lng": "106.58583", "lat": "29.549613\n"}, {"lng": "106.586525", "lat": "29.551088\n"}, {"lng": "106.588258", "lat": "29.554658\n"}, {"lng": "106.589325", "lat": "29.556971\n"}, {"lng": "106.590013", "lat": "29.558385\n"}, {"lng": "106.590681", "lat": "29.560546\n"}, {"lng": "106.59077", "lat": "29.561608\n"}, {"lng": "106.590806", "lat": "29.563003\n"}, {"lng": "106.590851", "lat": "29.563895\n"}, {"lng": "106.590766", "lat": "29.566858\n"}, {"lng": "106.590591", "lat": "29.568281\n"}, {"lng": "106.589873", "lat": "29.572468\n"}, {"lng": "106.589526", "lat": "29.573176\n"}, {"lng": "106.588891", "lat": "29.574146\n"}, {"lng": "106.588333", "lat": "29.574741\n"}, {"lng": "106.587363", "lat": "29.575703\n"}, {"lng": "106.587371", "lat": "29.575726\n"}, {"lng": "106.58739", "lat": "29.575745\n"}, {"lng": "106.587408", "lat": "29.575756\n"}, {"lng": "106.587425", "lat": "29.575766\n"}, {"lng": "106.587478", "lat": "29.575786\n"}, {"lng": "106.587505", "lat": "29.575788\n"}, {"lng": "106.587645", "lat": "29.57578\n"}, {"lng": "106.58777", "lat": "29.575776\n"}, {"lng": "106.587808", "lat": "29.575805\n"}, {"lng": "106.587808", "lat": "29.575805\n"}, {"lng": "106.587808", "lat": "29.575805\n"}, {"lng": "106.587808", "lat": "29.575805\n"}]}
\ No newline at end of file
{"time": {"dateTime": "2020-08-17 11:31:47", "date": "2020-08-17", "time": "11:31:47"}, "curDayTravel": {"todayTotalMilleage": 7609, "todayTotalOil": 484, "todayTotalTime": 475, "theMilleage": 3091, "theOil": 196, "theTime": 193}, "travelData": {"totalMilleage": 138555, "totalOil": 11893, "totalTime": 8515}}
\ No newline at end of file
{"time": {"dateTime": "2020-10-12 15:03:02", "date": "2020-10-12", "time": "15:03:02"}, "curDayTravel": {"todayTotalMilleage": 7942, "todayTotalOil": 722, "todayTotalTime": 361, "theMilleage": 132, "theOil": 12, "theTime": 6}, "travelData": {"totalMilleage": 18162, "totalOil": 1417, "totalTime": 7296}}
\ No newline at end of file
#coding:utf-8
'''
定义基类,供所有协议类继承
'''
class Base():
def __init__(self):
pass
#####################################################
# 生成协议头
#####################################################
def getProtocalHeader(self):
# print("生成协议头方法")
pass
#encoding:utf-8
'''
定义数据上行透传消息
'''
import datetime
from lib.protocol.message.MessageBase import MessageBase
class DataUpstreamTransport_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="0100",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0,msgType="F3",data={"infoTime":"2020-02-06 11:31:56"}):
msg = ""
msgBody = self.getMsgBody_GUI(msgType,data)
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
#透传消息类型
#0xF1 驾驶行程数据(熄火发送)
# 0xF2 故障码数据(状态改变发送)
# 0xF3 休眠进入(进入休眠模式发送)
# 0xF4 休眠唤醒(退出休眠模式发送)
msgType = "F2"
msgContent = ""
if msgType == "F1":
msgContent = self.getDrivingData() #驾驶行程数据(熄火发送)
elif msgType == "F2":
msgContent = self.getTroubleCodeData() #故障码数据(状态改变发送)
elif msgType == "F3":
msgContent = self.getIntoSleepData() #休眠进入(进入休眠模式发送)
elif msgType == "F4":
msgContent = self.getOutSleepData() #休眠唤醒(退出休眠模式发送)
msg = msgType + msgContent
return msg
# 获取消息体,针对图形界面,可传递参数
def getMsgBody_GUI(self,msgType="F3",data={"infoTime":"2020-02-06 11:31:56"}):
msg = ""
# 透传消息类型
# 0xF1 驾驶行程数据(熄火发送)
# 0xF2 故障码数据(状态改变发送)
# 0xF3 休眠进入(进入休眠模式发送)
# 0xF4 休眠唤醒(退出休眠模式发送)
msgType = msgType
msgContent = ""
if msgType == "F1":
# 驾驶行程数据(熄火发送)
msgContent = self.getDrivingData_GUI(data["time_1"],data["time_2"],data["fireLatitude"],data["fireLongitude"],data["unFireLatitude"], \
data["unFireLongitude"],data["drivingCircleLabel"],data["drivingCircleTotalMileageType"],data["drivingCircleTotalMileage"], \
data["drivingCircleTotalOil"],data["drivingCircleTotalTime"],data["drivingCircleOverSpeedTotalTime"], \
data["drivingCircleOverSpeedTotalTimes"],data["drivingCircleAverageSpeed"],data["drivingCircleMaxSpeed"], \
data["drivingCircleIdlingTime"],data["drivingCircleFootBrakeIsSupport"],data["drivingCircleFootBrakeTatalTimes"], \
data["drivingCircleRapidlyAccelerateTimes"],data["drivingCircleSharpSlowdownTimes"],data["drivingCircleSharpCurveTimes"], \
data["speedIn20"],data["speedIn20_40"],data["speedIn40_60"],data["speedIn60_80"],data["speedIn80_100"],data["speedIn100_120"], \
data["speedOut120"],data["rapidlyAccelerateTimes"],data["rapidlySharpSlowdownTimes"],data["sharpCurveTimes"])
elif msgType == "F2":
# 故障码数据(状态改变发送)
msgContent = self.getTroubleCodeData_GUI(data["infoTime"],data["latitude"],data["longitude"],data["troubleCodeNums"],data["systemId"])
elif msgType == "F3":
# 休眠进入(进入休眠模式发送)
msgContent = self.getIntoSleepData_GUI(data["infoTime"])
elif msgType == "F4":
# 休眠唤醒(退出休眠模式发送)
msgContent = self.getOutSleepData_GUI(data["infoTime"],data["outSleepType"],data["carVoltage"],data["vibrateOutSleepSpeedUpVal"])
msg = msgType + msgContent
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0900"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取驾驶行程数据
#######################################################
def getDrivingData(self):
time_1 = "0001" + self.int2hexStringByBytes(6) + self.getBCDTime("2020-02-05 22:07:30")
time_2 = "0002" + self.int2hexStringByBytes(6) + self.getBCDTime(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
fireLatitude = "0003" + self.int2hexStringByBytes(4) + self.getFireLatitude(29.40268) #点火纬度
fireLongitude = "0004" + self.int2hexStringByBytes(4) + self.getFireLongitude(106.54041) #点火经度
unFireLatitude = "0005" + self.int2hexStringByBytes(4) + self.getUnFireLatitude(29.40268) #熄火纬度
unFireLongitude = "0006" + self.int2hexStringByBytes(4) + self.getUnFireLongitude(106.54041) # 熄火经度
drivingCircleLabel = "0007" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(123,2) #驾驶循环标签
#一个驾驶循环总里程类型:
# 0x01:GPS 总里程(累计)
# 0x02:J1939 里程算法 1
# 0x03:J1939 里程算法 2
# 0x04:J1939 里程算法 3
# 0x05:J1939 里程算法 4
# 0x06:J1939 里程算法 5
# 0x07:OBD 仪表里程
# 0x08:OBD 速度里程
# 0x09:J1939 里程算法 6
# 0x0A:J1939 里程算法 7
# 0x0B:J1939 里程算法 8
# 0x0C:J1939 里程算法 9
drivingCircleTotalMileageType = "0008" + self.int2hexStringByBytes(1) + "01"
#一个驾驶循环总里程,单位米
drivingCircleTotalMileage = "0009" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(38090,4)
#一个驾驶循环总耗油,单位毫升(ml)
drivingCircleTotalOil = "000A" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(75400,4)
#一个驾驶循环总时长,单位秒
drivingCircleTotalTime = "000B" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(726000,4)
#一个驾驶循环超速累计时长,单位秒
drivingCircleOverSpeedTotalTime = "000C" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(54000,2)
#一个驾驶循环超速次数,单位次
drivingCircleOverSpeedTotalTimes = "000D" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(101,2)
#一个驾驶循环平均车速,单位 KM/H
drivingCircleAverageSpeed = "000E" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(65)
#一个驾驶循环最大车速,单位 KM/H
drivingCircleMaxSpeed = "000F" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(123)
#一个驾驶循环怠速时长,单位秒
drivingCircleIdlingTime = "0010" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(12600000,4)
#一个驾驶循环脚刹次数支持与否,1 为支持
drivingCircleFootBrakeIsSupport = "0011" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(1)
#一个驾驶循环脚刹总次数,单位次
drivingCircleFootBrakeTatalTimes = "0012" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(32,2)
#一个驾驶循环急加速次数
drivingCircleRapidlyAccelerateTimes = "0013" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(79,4)
#一个驾驶循环急减速次数
drivingCircleSharpSlowdownTimes = "0014" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(10,4)
#一个驾驶循环急转弯次数
drivingCircleSharpCurveTimes = "0015" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(33,4)
#速度为-20Km/H 的里程,单位:m
speedIn20 = "0016" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(1068,4)
#速度为 20-40Km/H 的里程,单位:m
speedIn20_40 = "0017" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(2020,4)
#速度为 40-60Km/H 的里程,单位:m
speedIn40_60 = "0018" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(30400,4)
#速度为 60-80Km/H 的里程,单位:m
speedIn60_80 = "0019" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(37000,4)
#速度为 80-100Km/H 的里程,单位:m
speedIn80_100 = "001A" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(10400,4)
#速度为 100-120Km/H 的里程,单位:m
speedIn100_120 = "001B" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(5000,4)
#速度为 120Km/H 以上的里程,单位:m
speedOut120 = "001C" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3200,4)
#急加速总次数
rapidlyAccelerateTimes = "001D" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3000,4)
#急减速总次数
rapidlySharpSlowdownTimes = "001E" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3507,4)
#急转弯总次数
sharpCurveTimes = "001F" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(580,4)
data = time_1 + time_2 + fireLatitude + fireLongitude + unFireLatitude
data = data + unFireLongitude + drivingCircleLabel + drivingCircleTotalMileageType + drivingCircleTotalMileage + drivingCircleTotalOil
data = data + drivingCircleTotalTime + drivingCircleOverSpeedTotalTime + drivingCircleOverSpeedTotalTimes + drivingCircleAverageSpeed + drivingCircleMaxSpeed
data = data + drivingCircleIdlingTime + drivingCircleFootBrakeIsSupport + drivingCircleFootBrakeTatalTimes + drivingCircleRapidlyAccelerateTimes + drivingCircleSharpSlowdownTimes
data = data + drivingCircleSharpCurveTimes + speedIn20 + speedIn20_40 + speedIn40_60 + speedIn60_80
data = data + speedIn80_100 + speedIn100_120 + speedOut120 + rapidlyAccelerateTimes + rapidlySharpSlowdownTimes
data = data + sharpCurveTimes
return data
# 获取驾驶行程数据,针对图形界面,可传递参数
def getDrivingData_GUI(self,time_1="2020-02-05 22:07:30",time_2="2020-02-08 22:07:30",fireLatitude=29.40268,fireLongitude=106.54041, \
unFireLatitude=29.40268,unFireLongitude=106.54041,drivingCircleLabel=123,drivingCircleTotalMileageType="01", \
drivingCircleTotalMileage=38090,drivingCircleTotalOil=75400,drivingCircleTotalTime=726000, \
drivingCircleOverSpeedTotalTime=54000,drivingCircleOverSpeedTotalTimes=101,drivingCircleAverageSpeed=65, \
drivingCircleMaxSpeed=123,drivingCircleIdlingTime=12600000,drivingCircleFootBrakeIsSupport=1, \
drivingCircleFootBrakeTatalTimes=32,drivingCircleRapidlyAccelerateTimes=79,drivingCircleSharpSlowdownTimes=10, \
drivingCircleSharpCurveTimes=33,speedIn20=1068,speedIn20_40=2020,speedIn40_60=30400,speedIn60_80=37000, \
speedIn80_100=10400,speedIn100_120=5000,speedOut120=3200,rapidlyAccelerateTimes=3000, \
rapidlySharpSlowdownTimes=3507,sharpCurveTimes=580):
time_1 = "0001" + self.int2hexStringByBytes(6) + self.getBCDTime(time_1)
time_2 = "0002" + self.int2hexStringByBytes(6) + self.getBCDTime(time_2)
fireLatitude = "0003" + self.int2hexStringByBytes(4) + self.getFireLatitude(fireLatitude) #点火纬度
fireLongitude = "0004" + self.int2hexStringByBytes(4) + self.getFireLongitude(fireLongitude) #点火经度
unFireLatitude = "0005" + self.int2hexStringByBytes(4) + self.getUnFireLatitude(unFireLatitude) #熄火纬度
unFireLongitude = "0006" + self.int2hexStringByBytes(4) + self.getUnFireLongitude(unFireLongitude) # 熄火经度
drivingCircleLabel = "0007" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(drivingCircleLabel,2) #驾驶循环标签
#一个驾驶循环总里程类型:
drivingCircleTotalMileageType = "0008" + self.int2hexStringByBytes(1) + drivingCircleTotalMileageType
#一个驾驶循环总里程,单位米
drivingCircleTotalMileage = "0009" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleTotalMileage,4)
#一个驾驶循环总耗油,单位毫升(ml)
drivingCircleTotalOil = "000A" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleTotalOil,4)
#一个驾驶循环总时长,单位秒
drivingCircleTotalTime = "000B" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleTotalTime,4)
#一个驾驶循环超速累计时长,单位秒
drivingCircleOverSpeedTotalTime = "000C" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(drivingCircleOverSpeedTotalTime,2)
#一个驾驶循环超速次数,单位次
drivingCircleOverSpeedTotalTimes = "000D" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(drivingCircleOverSpeedTotalTimes,2)
#一个驾驶循环平均车速,单位 KM/H
drivingCircleAverageSpeed = "000E" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(drivingCircleAverageSpeed)
#一个驾驶循环最大车速,单位 KM/H
drivingCircleMaxSpeed = "000F" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(drivingCircleMaxSpeed)
#一个驾驶循环怠速时长,单位秒
drivingCircleIdlingTime = "0010" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleIdlingTime,4)
#一个驾驶循环脚刹次数支持与否,1 为支持
drivingCircleFootBrakeIsSupport = "0011" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(drivingCircleFootBrakeIsSupport)
#一个驾驶循环脚刹总次数,单位次
drivingCircleFootBrakeTatalTimes = "0012" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(drivingCircleFootBrakeTatalTimes,2)
#一个驾驶循环急加速次数
drivingCircleRapidlyAccelerateTimes = "0013" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleRapidlyAccelerateTimes,4)
#一个驾驶循环急减速次数
drivingCircleSharpSlowdownTimes = "0014" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleSharpSlowdownTimes,4)
#一个驾驶循环急转弯次数
drivingCircleSharpCurveTimes = "0015" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(drivingCircleSharpCurveTimes,4)
#速度为-20Km/H 的里程,单位:m
speedIn20 = "0016" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn20,4)
#速度为 20-40Km/H 的里程,单位:m
speedIn20_40 = "0017" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn20_40,4)
#速度为 40-60Km/H 的里程,单位:m
speedIn40_60 = "0018" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn40_60,4)
#速度为 60-80Km/H 的里程,单位:m
speedIn60_80 = "0019" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn60_80,4)
#速度为 80-100Km/H 的里程,单位:m
speedIn80_100 = "001A" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn80_100,4)
#速度为 100-120Km/H 的里程,单位:m
speedIn100_120 = "001B" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedIn100_120,4)
#速度为 120Km/H 以上的里程,单位:m
speedOut120 = "001C" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(speedOut120,4)
#急加速总次数
rapidlyAccelerateTimes = "001D" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(rapidlyAccelerateTimes,4)
#急减速总次数
rapidlySharpSlowdownTimes = "001E" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(rapidlySharpSlowdownTimes,4)
#急转弯总次数
sharpCurveTimes = "001F" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(sharpCurveTimes,4)
data = time_1 + time_2 + fireLatitude + fireLongitude + unFireLatitude
data = data + unFireLongitude + drivingCircleLabel + drivingCircleTotalMileageType + drivingCircleTotalMileage + drivingCircleTotalOil
data = data + drivingCircleTotalTime + drivingCircleOverSpeedTotalTime + drivingCircleOverSpeedTotalTimes + drivingCircleAverageSpeed + drivingCircleMaxSpeed
data = data + drivingCircleIdlingTime + drivingCircleFootBrakeIsSupport + drivingCircleFootBrakeTatalTimes + drivingCircleRapidlyAccelerateTimes + drivingCircleSharpSlowdownTimes
data = data + drivingCircleSharpCurveTimes + speedIn20 + speedIn20_40 + speedIn40_60 + speedIn60_80
data = data + speedIn80_100 + speedIn100_120 + speedOut120 + rapidlyAccelerateTimes + rapidlySharpSlowdownTimes
data = data + sharpCurveTimes
return data
#######################################################
# 获取点火纬度,单位:0.000001 度,Bit31=0/1 北纬/南纬
#######################################################
def getFireLatitude(self,data=29.40268):
orientation = 0 #0:北纬 1:南纬 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 点火经度,单位:0.000001 度,Bit31=0/1 东经/西经
#######################################################
def getFireLongitude(self,data=106.54041):
orientation = 0 #0:东经 1:西经 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 获取熄火纬度,单位:0.000001 度,Bit31=0/1 北纬/南纬
#######################################################
def getUnFireLatitude(self,data=29.40268):
orientation = 0 #0:北纬 1:南纬 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 熄火经度,单位:0.000001 度,Bit31=0/1 东经/西经
#######################################################
def getUnFireLongitude(self,data=106.54041):
orientation = 0 #0:东经 1:西经 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 获取故障码数据
#######################################################
def getTroubleCodeData(self):
infoTime = self.getBCDTime("2020-02-06 11:31:56")
#单位:0.000001 度,Bit31=0/1 北纬/南纬
latitude = self.getLatitude(29.40268)
#单位:0.000001 度,Bit31=0/1 东经/西经
longitude = self.getLongitude(106.54041)
#为 0 表示无故障码,非 0 为故障码个数
troubleCodeNums = 6
troubleCodeNumsHex = self.int2hexStringByBytes(troubleCodeNums)
#故障码
troubleCode = ""
for i in range(0,troubleCodeNums):
# tbc0 = self.int2hexStringByBytes(i)
tbc0 = "00"
# tbc1 = self.int2hexStringByBytes(1)
tbc1 = self.int2hexStringByBytes(0)
# tbc2 = self.int2hexStringByBytes(2)
tbc2 = self.int2hexStringByBytes(i)
# tbc3 = self.int2hexStringByBytes(3)
tbc3 = self.int2hexStringByBytes(0)
troubleCode = troubleCode + tbc0 + tbc1 + tbc2 + tbc3
data = infoTime + latitude + longitude + troubleCodeNumsHex + troubleCode
return data
# 获取故障码数据,针对图形界面,可传递参数
def getTroubleCodeData_GUI(self,infoTime="2020-02-06 11:31:56",latitude=29.40268,longitude=106.54041,troubleCodeNums=3,systemId="00"):
infoTime = self.getBCDTime(infoTime)
#单位:0.000001 度,Bit31=0/1 北纬/南纬
latitude = self.getLatitude(latitude)
#单位:0.000001 度,Bit31=0/1 东经/西经
longitude = self.getLongitude(longitude)
#为 0 表示无故障码,非 0 为故障码个数
troubleCodeNums = troubleCodeNums
troubleCodeNumsHex = self.int2hexStringByBytes(troubleCodeNums)
#故障码
troubleCode = ""
for i in range(0,troubleCodeNums):
# troubleCode = troubleCode + self.int2hexStringByBytes(i,4)
tbc0 = systemId
tbc1 = self.int2hexStringByBytes(0)
tbc2 = self.int2hexStringByBytes(i)
tbc3 = self.int2hexStringByBytes(0)
troubleCode = troubleCode + tbc0 + tbc1 + tbc2 + tbc3
data = infoTime + latitude + longitude + troubleCodeNumsHex + troubleCode
return data
#获取维度
def getLatitude(self,data=29.40268):
orientation = 0 #0:北纬 1:南纬 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#获取经度
def getLongitude(self,data=106.54041):
orientation = 0 #0:东经 1:西经 (2147483648)
data = int(data * 1000000)
data = data + orientation
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 获取进入休眠数据包
#######################################################
def getIntoSleepData(self):
infoTime = self.getBCDTime("2020-02-06 11:31:56")
msg = infoTime
return msg
# 获取进入休眠数据包,针对图形界面,可传递参数
def getIntoSleepData_GUI(self,infoTime="2020-02-06 11:31:56"):
infoTime = self.getBCDTime(infoTime)
msg = infoTime
return msg
#######################################################
# 获取休眠唤醒数据包
#######################################################
def getOutSleepData(self):
infoTime = self.getBCDTime("2020-02-06 11:31:56")
#休眠唤醒类型
# 0x01:休眠定时唤醒
# 0x02:CAN1
# 0x04:CAN2
# 0x08:gSensor 0x10:电压变
outSleepType = "01"
#车辆电压,单位 0.1V
carVoltage = self.int2hexStringByBytes(360,2)
#振动唤醒加速度值,单位 mg
vibrateOutSleepSpeedUpVal = self.int2hexStringByBytes(3700,2)
data = infoTime + outSleepType + carVoltage + vibrateOutSleepSpeedUpVal
return data
#获取休眠唤醒数据包,针对图形界面,可传递参数
def getOutSleepData_GUI(self,infoTime="2020-02-06 11:31:56",outSleepType="01",carVoltage=360,vibrateOutSleepSpeedUpVal=3700):
infoTime = self.getBCDTime(infoTime)
#休眠唤醒类型
# 0x01:休眠定时唤醒
# 0x02:CAN1
# 0x04:CAN2
# 0x08:gSensor 0x10:电压变
outSleepType = outSleepType
#车辆电压,单位 0.1V
carVoltage = self.int2hexStringByBytes(carVoltage,2)
#振动唤醒加速度值,单位 mg
vibrateOutSleepSpeedUpVal = self.int2hexStringByBytes(vibrateOutSleepSpeedUpVal,2)
data = infoTime + outSleepType + carVoltage + vibrateOutSleepSpeedUpVal
return data
if __name__ == "__main__":
print(DataUpstreamTransport_msg().generateMsg())
#encoding:utf-8
'''
定义定位数据批量上传
'''
import datetime
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.message.data.AlarmEvent_data import AlarmEvent_data
from lib.protocol.message.data.CarSafeStatusInfo import CarSafeStatusInfo
from lib.protocol.message.data.Circum_data import Circum_data
from lib.protocol.message.data.NewEnergyCar_data import NewEnergyCar_data
from lib.protocol.message.data.SaloonCarOBD_data import SaloonCarOBD_data
from lib.protocol.message.data.TruckCarOBD_data import TruckCarOBD_data
class LocationDataBatchUpdate_msg(MessageBase):
def __init__(self):
super().__init__()
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
dataItemCounts = self.getDataItemCounts() #数据项个数
#位置数据类型 ,0:正常位置批量汇报,1:盲区补报
locationDataType = self.int2hexStringByBytes(0)
#位置汇报数据项
locationData = self.getLocationData()
msg = dataItemCounts + locationDataType + locationData
return msg
#######################################################
# 位置信息汇报数据项
#######################################################
def getLocationData(self):
dataBody = "" #位置汇报数据体
for i in range(0,12):
dataBody = dataBody + self.getLocationBaseInfo()
dataLen = self.int2hexStringByBytes(int(len(dataBody)/2),2) #位置汇报数据体长度
data = dataLen + dataBody
return data
#######################################################
# 获取数据项个数
#######################################################
def getDataItemCounts(self):
# 起始字节 标志
# 0 1:紧急(备注:主要用于设备厂商私有协议 ASCII 文本控制指令下发) (1)
# 1 保留
# 2 1:终端显示器显示 (4)
# 3 1:终端 TTS 播读 (8)
# 4 1:广告屏显示 (16)
# 5 0:中心导航信息,1:CAN 故障码信息 (32)
# 6-7 保留
bit0 = 1
bit2 = 4
bit3 = 8
bit4 = 16
bit5 = 32
data = bit0 + bit2 + bit2 + bit4 + bit5
dataHex = self.int2hexStringByBytes(data)
return dataHex
#######################################################
# 获取位置基本信息
#######################################################
def getLocationBaseInfo(self):
msg = ""
alarmFlag = self.getAlarmFlag() #报警标志
status = self.getStatus() #状态
latitude = self.getLatitude() #纬度
longtitude = self.getLongtitude() #经度
elevation = self.getElevation() #海拔高度
speed = self.getSpeed() #速度
directionAngle = self.getDirectionAngle() #获取方向角度
infoTime = self.getInfoTime() #获取时间
msg = alarmFlag + status + latitude + longtitude + elevation + speed + directionAngle + infoTime
return msg
#######################################################
# 获取位置附加信息
#######################################################
def getLocationExtraInfo(self):
data = ""
extraInfoId = self.int2hexStringByBytes(1)
# 里程,DWORD,1 / 10km,对应车上里程表读数;不支持OBD时,为基于GPS车速统计的车辆累计行驶总里程。
extra_01 = "01" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(20202020,4)
#油量,WORD,1/10L,对应车上油量表读数
extra_02 = "02" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(5200,2)
#超速报警附加信息
extra_11 = "11" + self.int2hexStringByBytes(int(len(self.getOverSpeedAlarmExtraInfo()) / 2)) + self.getOverSpeedAlarmExtraInfo()
#进出区域/路线报警附加信息见
extra_12 = "12" + self.int2hexStringByBytes(6) + self.getInOutAreaAlarmExtraInfo()
#路段行驶时间不足/过长报警附加信息见
extra_13 = "13" + self.int2hexStringByBytes(7) + self.getDrivingLongOrShortAlarmExtraInfo()
#IO 状态位
extra_2A = "2A" + self.int2hexStringByBytes(2) + self.getStatusBit()
#BYTE,无线通信网络信号强度
extra_30 = "30" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(33)
#BYTE,GNSS 定位卫星数
extra_31 = "31" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(2)
#基础数据项列表
extra_EA = "EA" + self.int2hexStringByBytes(int(len(self.getBaseDataList()) / 2)) + self.getBaseDataList()
#轿车 OBD 数据流
extra_EB = "EB" + self.int2hexStringByBytes(int(len(SaloonCarOBD_data().generateSaloonCarOBDData()) / 2)) + SaloonCarOBD_data().generateSaloonCarOBDData()
#货车 OBD 数据流
extra_EC = "EC" + self.int2hexStringByBytes(int(len(TruckCarOBD_data().generateTruckCarOBD_data()) / 2)) + TruckCarOBD_data().generateTruckCarOBD_data()
#新能源 OBD 数据流
extra_ED = "ED" + self.int2hexStringByBytes(int(len(NewEnergyCar_data().generateNewEnergyCar_data()) / 2)) + NewEnergyCar_data().generateNewEnergyCar_data()
#外设数据项列表
extra_EE = "EE" + self.int2hexStringByBytes(int(len(Circum_data().generateCircum_data()) / 2)) + Circum_data().generateCircum_data()
#报警事件 ID 数据项列表
extra_FA = "FA" + self.int2hexStringByBytes(int(len(AlarmEvent_data().generateAlarmEvent_data()) / 2)) + AlarmEvent_data().generateAlarmEvent_data()
data = extra_01 + extra_02 + extra_11 + extra_12 + extra_13 + extra_FA
# data = extra_01 + extra_02 + extra_11 + extra_12 + extra_13
# data = data + extra_2A + extra_30 + extra_31 + extra_EA + extra_EB
# data = data + extra_EC
extraInfoLen = self.int2hexStringByBytes(int(len(data) / 2))
data = extraInfoId + extraInfoLen + data
return data
#获取超速报警附加信息
def getOverSpeedAlarmExtraInfo(self):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = 1
areaId = "" #若位置类型为 0,无该字段
if locationType == 0:
pass
else:
areaId = self.int2hexStringByBytes(2020,4)
msg = self.int2hexStringByBytes(locationType) + areaId
return msg
#获取进出区域/路线报警附加信息
def getInOutAreaAlarmExtraInfo(self):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = 1
areaId = ""
if locationType == 0:
areaId = "00000000"
else:
areaId = self.int2hexStringByBytes(2020, 4)
direction = 0 #0-进,1-出
msg = self.int2hexStringByBytes(locationType) + areaId + self.int2hexStringByBytes(direction)
return msg
#路线行驶时间不足/过长报警附加信息消息
def getDrivingLongOrShortAlarmExtraInfo(self):
areaId = self.int2hexStringByBytes(2020, 4) #路段Id
drivingTime = self.int2hexStringByBytes(36000,2) #路段行驶时间(单位:秒)
result = self.int2hexStringByBytes(0) #结果,0-不足,1-过长
msg = areaId + drivingTime + result
return msg
#获取状态位
def getStatusBit(self):
deepSleepStatus = 1 #1:深度休眠状态
sleepStatus = 2 #1:休眠状态
retain = 0
data = deepSleepStatus + sleepStatus + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#基础数据项列表
def getBaseDataList(self):
dataId_0001 = "0001" + self.int2hexStringByBytes(4) + self.getExpandStatusBit()
dataId_0002 = "0002" + self.int2hexStringByBytes(4) + self.getExpandAlarmBit()
dataId_0003 = "0003" + self.int2hexStringByBytes(5) + self.getTotalMileage()
dataId_0004 = "0004" + self.int2hexStringByBytes(5) + self.getTotalOil()
dataId_0005 = "0005" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(360000,4)
dataId_0006 = "0006" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(72000,4)
dataId_0007 = "0007" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(480000,4)
dataId_0010 = "0010" + self.int2hexStringByBytes(int(len(self.getSpeedupInOneSeconds()) / 2)) + self.getSpeedupInOneSeconds()
dataId_0011 = "0011" + self.int2hexStringByBytes(int(len(CarSafeStatusInfo().generateSecurityStatusData()) / 2)) + CarSafeStatusInfo().generateSecurityStatusData()
dataId_0012 = "0012" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(36,2)
dataId_0013 = "0013" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
#TODO 由于被置灰,所以没有实现
# dataId_0015 = "0015" + self.int2hexStringByBytes(2)
# dataId_0016 = "0016"
#TODO 暂不支持
# dataId_0017 = "0017" + self.int2hexStringByBytes(2)
dataId_001D = "001D" + self.int2hexStringByBytes(1) + "01"
data = dataId_0001 + dataId_0002 + dataId_0003 + dataId_0004 + dataId_0005
data = data + dataId_0006 + dataId_0007 + dataId_0010 + dataId_0011 + dataId_0012
data = data + dataId_0013 + dataId_001D
return data
'''扩展状态标志位,见 表 C1EXT1'''
def getExpandStatusBit(self):
defenseUndefenseRep = 0 #0:撤防上报;1:设防上报 (1)
retain = 0
data = defenseUndefenseRep + retain
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
'''扩展报警标志位,见 表 C1EXT2'''
def getExpandAlarmBit(self):
waterTemperatureAlarm = 1 #1:水温报警 (1)
idlingOverlongAlarm = 2 #1:怠速过长报警 (2)
rapidlyAccelerateAlarm = 4 #1:急加速报警 (4)
sharpSlowsownAlarm = 8 #1:急减速报警 (8)
sharpCurve = 16 #1:急转弯报警 (16)
retain5_9 = 0
insertAlarm = 1024 #1:插入报警 (1024)
oilExpenseNotSupportAlarm = 2048 #1:油耗不支持报警 (2048)
OBDNotSupportAlarm = 4096 #1:OBD 不支持报警 (4096)
buslineNotSleepAlarm = 8192 #1:总线不睡眠报警 (8192)
illegalOpenDoor = 16384 #1:非法开门 (16384)
retain15_16 = 0
FLASHTroubleAlarm = 131072 #1: FLASH 故障报警 (131072)
CANTroubleAlarm = 262144 #1: CAN 模块故障报警 (262144)
D3SensorTroubleAlarm = 524288 #1:3D 传感器故障报警 (524288)
RTCTroubleAlarm = 1048576 #1:RTC 模块故障报警
retain21_31 = 0
data = waterTemperatureAlarm + idlingOverlongAlarm + rapidlyAccelerateAlarm + sharpSlowsownAlarm + sharpCurve
data = data + retain5_9 + insertAlarm + oilExpenseNotSupportAlarm + OBDNotSupportAlarm + buslineNotSleepAlarm
data = data + illegalOpenDoor + retain15_16 + FLASHTroubleAlarm + CANTroubleAlarm + D3SensorTroubleAlarm
data = data + RTCTroubleAlarm + retain21_31
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
'''行驶总里程'''
def getTotalMileage(self):
caculateType = "01"
totalMileage = self.int2hexStringByBytes(128000,4) #行驶总里程(单位米)
data = caculateType + totalMileage
return data
'''行驶总油耗'''
def getTotalOil(self):
caculateType = "01"
totalOil = self.int2hexStringByBytes(120000,4) #总油耗(单位 mL)
data = caculateType + totalOil
return data
'''此刻 1 秒内的加速度数据,见 表 C1EXT3'''
def getSpeedupInOneSeconds(self):
data = ""
pointCount = 4 #采集的点个数 N
collectIntercal = 100 #采集间隔(单位 ms),上传值为该采集间隔时间内的加速度均值
data = data + self.int2hexStringByBytes(pointCount,2)
data = data + self.int2hexStringByBytes(collectIntercal,2)
speedupVal = 1000 #采集点加速度均值
for i in range(0,pointCount):
data = data + self.int2hexStringByBytes(speedupVal + 10,2)
return data
#######################################################
# 获取精度信息
#######################################################
def getLatitude(self,data=29.40268):
data = int(data * 1000000)
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
#######################################################
# 获取纬度信息
#######################################################
def getLongtitude(self,data=106.54041):
data = int(data * 1000000)
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 获取海拔高度
#######################################################
def getElevation(self,data=520):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取海拔高度
#######################################################
def getSpeed(self,data=66):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取方向角度
#######################################################
def getDirectionAngle(self,data=59):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取时间
#######################################################
def getInfoTime(self,data="2020-02-04 18:57:04"):
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data = data
data = data.replace("-","")
data = data.replace(" ","")
data = data.replace(":","")
data = data[2:]
data = self.int2BCD(int(data))
return data
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0200"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2BCD(1) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取报警标志
#######################################################
def getAlarmFlag(self):
emergencyAlarm = 1 #紧急报警,触动报警开关后触发
overspeedAlarm = 2 #超速报警
fatigueDriving = 4 #疲劳驾驶
dangerAlarm = 8 #危险预警
GNSSTrouble = 16 #GNSS 模块发生故障
GNSSAntennaeLost = 32 #GNSS 天线未接或被剪断
GNSSAntennaeShortOut = 64 #GNSS 天线短路
TerminalMainPowerLackVoltage = 128 #终端主电源欠压
TerminalMainPowerLostConnect = 256 #终端主电源掉电(设备拔出告警)
TerMinalLCDTrouble = 512 #终端 LCD 或显示器故障
TTSTrouble = 1024 #TTS 模块故障
cameraTrouble = 2048 #摄像头故障
ICTrouble = 4096 #道路运输证 IC 卡模块故障
speedEarlyWarning = 8192 #超速预警
fatigueDrivingearlyWarning = 16384 #疲劳驾驶预警
retain1 = 0
retain2 = 0
retain3 = 0
drivingOverTime = 262144 #当天累计驾驶超时
stoppingOverTime = 524288 #超时停车
InOutArea = 1048576 #进出区域
InOutRouting = 2097152 #进出路线
drivingLongOrShort = 4194304 #路段行驶时间不足/过长
routingDivergeAlarm = 8388608 #路线偏离报警
VSSTrouble = 16777216 #车辆 VSS 故障
oilException = 33554432 #车辆油量异常
carLost = 67108864 #车辆被盗(通过车辆防盗器)
illegalFire = 134217728 #车辆非法点火
illegalMoving = 268435456 #车辆非法位移(拖车告警)
collisionAlarm = 536870912 #碰撞预警
rollOverAlarm = 1073741824 #侧翻预警
illegalOpenDoor = 2147483648 #非法开门报警(终端未设置区域时, 不判断非法开门)
data = emergencyAlarm + overspeedAlarm + fatigueDriving + dangerAlarm + GNSSTrouble + GNSSAntennaeLost
data = data + GNSSAntennaeShortOut + TerminalMainPowerLackVoltage + TerminalMainPowerLostConnect + TerMinalLCDTrouble
data = data + TTSTrouble + cameraTrouble + ICTrouble + speedEarlyWarning + fatigueDrivingearlyWarning
data = data + retain1 + retain2 + retain3 + drivingOverTime + stoppingOverTime
data = data + InOutArea + InOutRouting + drivingLongOrShort + routingDivergeAlarm + VSSTrouble
data = data + oilException + carLost + illegalFire + illegalMoving + collisionAlarm
data = data + rollOverAlarm + illegalOpenDoor
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
#######################################################
# 获取状态
#######################################################
def getStatus(self):
ACCStatus = 1 #0:ACC 关;1: ACC 开 (1)
locationStatus = 2 #0:未定位;1:定位 (2)
latitudeStatus = 0 #0:北纬;1:南纬 (4)
longitudeStatus = 0 #0:东经;1:西经 (8)
runStatus = 0 #0:运营状态;1:停运状态 (16)
isLocationEncrypt = 0 #0:经纬度未经保密插件加密;1:经纬度已经保密插件加密 (32)
retain6_7 = 0
# 00:空车;01:半载;10:保留;11:满载(0 , 256 ,512 , 768)
#(可用于客车的空、重车及货车的空载、满载状态表示,人工输入或传感器 获取)
isFull = 256
oilRouteStatus = 0 #0:车辆油路正常;1:车辆油路断开 (1024)
powerStatus = 0 #0:车辆电路正常;1:车辆电路断开 (2048)
doorLockStatus = 0 #0:车门解锁;1:车门加锁 (4096)
frontDoor = 0 #0:门 1 关;1:门 1 开(前门) (8192)
middleDoor = 0 #0:门 2 关;1:门 2 开(中门) (16384)
backDoor = 0 #0:门 3 关;1:门 3 开(后门) (32768)
drivingDoor = 0 #0:门 4 关;1:门 4 开(驾驶席门) (65536)
otherDoor = 0 #0:门 5 关;1:门 5 开(自定义) (131072)
GPSStatus = 262144 #0:未使用 GPS 卫星进行定位;1:使用 GPS 卫星进行定位 (262144)
beidouStatus = 524288 #0:未使用北斗卫星进行定位;1:使用北斗卫星进行定位 (524288)
GLONSSStatus = 1048576 #0:未使用 GLONASS 卫星进行定位;1:使用 GLONASS 卫星进行定位 (1048576)
GalileoStatus = 0 #0:未使用 Galileo 卫星进行定位;1:使用 Galileo 卫星进行定位 (2097152)
retain22_31 = 0
data = ACCStatus + locationStatus + latitudeStatus + longitudeStatus + runStatus
data = data + isLocationEncrypt + retain6_7 + isFull + oilRouteStatus + powerStatus
data = data + doorLockStatus + frontDoor + middleDoor + backDoor + drivingDoor
data = data + otherDoor + GPSStatus + beidouStatus + GLONSSStatus + GalileoStatus
data = data + retain22_31
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
if __name__ == "__main__":
print(LocationDataBatchUpdate_msg().getLocationBaseInfo())
print(LocationDataBatchUpdate_msg().generateMsg())
#encoding:utf-8
'''
定义位置信息汇报消息
'''
import datetime
from random import random
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.message.data.AlarmEvent_data import AlarmEvent_data
from lib.protocol.message.data.CarSafeStatusInfo import CarSafeStatusInfo
from lib.protocol.message.data.Circum_data import Circum_data
from lib.protocol.message.data.NewEnergyCar_data import NewEnergyCar_data
from lib.protocol.message.data.SaloonCarOBD_data import SaloonCarOBD_data
from lib.protocol.message.data.TruckCarOBD_data import TruckCarOBD_data
class Location_msg(MessageBase):
def __init__(self):
super().__init__()
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,params):
msg = ""
msgBody = self.getMsgBody_GUI(params)
msgHeader = self.getMsgHeader_GUI(params["msgID"], int(params["phoneNum"]), int(params["msgWaterCode"]),
int(params["encryptionType"]), int(params["subPkg"]),msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,数据随机产生
def generateMsg_random(self):
msg = ""
msgID = "0200"
phoneNum = self.getRandomStr(11, "0123456789")
msgWaterCode = self.getRandomNum(1, 65535)
encryptionType = 0
# subPkg = self.getRandomNum(intArr=[0, 8192])
subPkg = 0
msgHeader = self.getMsgHeader_GUI(msgID,phoneNum,msgWaterCode,encryptionType,subPkg)
msgBody = self.getMsgBody_random()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
locationBaseInfo = self.getLocationBaseInfo() #位置基本信息
locationExtraInfo = self.getLocationExtraInfo() #位置附加信息
msg = locationBaseInfo + locationExtraInfo
return msg
# 获取消息体,针对图形界面,可传递参数
def getMsgBody_GUI(self,params):
msg = ""
locationBaseInfo = self.getLocationBaseInfo_GUI(params["baseInfo"]) #位置基本信息
locationExtraInfo = ""
if params["extraInfo"] == {}:
pass
else:
locationExtraInfo = self.getLocationExtraInfo_GUI(params["extraInfo"]) #位置附加信息
msg = locationBaseInfo + locationExtraInfo
return msg
# 获取消息体,数据随机产生
def getMsgBody_random(self):
msg = ""
locationBaseInfo = self.getLocationBaseInfo_random() #位置基本信息
locationExtraInfo = self.getLocationExtraInfo_random() #位置附加信息
msg = locationBaseInfo + locationExtraInfo
return msg
#######################################################
# 获取位置基本信息
#######################################################
def getLocationBaseInfo(self):
msg = ""
alarmFlag = self.getAlarmFlag() #报警标志
status = self.getStatus() #状态
latitude = self.getLatitude() #纬度
longtitude = self.getLongtitude() #经度
elevation = self.getElevation() #海拔高度
speed = self.getSpeed() #速度
directionAngle = self.getDirectionAngle() #获取方向角度
infoTime = self.getInfoTime() #获取时间
msg = alarmFlag + status + latitude + longtitude + elevation + speed + directionAngle + infoTime
return msg
# 获取位置基本信息,针对图形界面,可传递参数
def getLocationBaseInfo_GUI(self,baseInfo):
msg = ""
alarmFlag = self.int2hexStringByBytes(int(baseInfo["alarmFlag"]),4) #报警标志
status = self.int2hexStringByBytes(int(baseInfo["status"]),4) #状态
latitude = self.getLatitude(float(baseInfo["latitude"])) #纬度
longtitude = self.getLongtitude(float(baseInfo["longtitude"])) #经度
elevation = self.getElevation(int(baseInfo["elevation"])) #海拔高度
speed = self.getSpeed(int(baseInfo["speed"])) #速度
directionAngle = self.getDirectionAngle(int(baseInfo["directionAngle"])) #获取方向角度
infoTime = self.getInfoTime(baseInfo["infoTime"]) #获取时间
msg = alarmFlag + status + latitude + longtitude + elevation + speed + directionAngle + infoTime
return msg
# 获取位置基本信息,数据随机产生
def getLocationBaseInfo_random(self):
msg = ""
alarmFlag = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1,2,4,8,16,32,64, \
128,256,512,1024,2048,4096,8192,16384,262144,524288,1048576,2097152,4194304, \
8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648],mult=29),4) #报警标志
status = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1,2,4,8,16,32,256, \
512,768,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152],mult=21),4) #状态
latitude = self.getLatitude(self.getRandomNum(s=0,e=90000000) / 1000000) #纬度
longtitude = self.getLongtitude(self.getRandomNum(s=0,e=180000000) / 1000000) #经度
elevation = self.getElevation(self.getRandomNum(s=0,e=6000)) #海拔高度
speed = self.getSpeed(self.getRandomNum(s=0,e=150)) #速度
directionAngle = self.getDirectionAngle(self.getRandomNum(s=0,e=359)) #获取方向角度
infoTime = self.getInfoTime(self.getRandomDate()) #获取时间
msg = alarmFlag + status + latitude + longtitude + elevation + speed + directionAngle + infoTime
return msg
#######################################################
# 获取位置附加信息
#######################################################
def getLocationExtraInfo(self):
data = ""
# 里程,DWORD,1 / 10km,对应车上里程表读数;不支持OBD时,为基于GPS车速统计的车辆累计行驶总里程。
extra_01 = "01" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(20202020,4)
#油量,WORD,1/10L,对应车上油量表读数
extra_02 = "02" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(5200,2)
#超速报警附加信息
extra_11 = "11" + self.int2hexStringByBytes(int(len(self.getOverSpeedAlarmExtraInfo()) / 2)) + self.getOverSpeedAlarmExtraInfo()
#进出区域/路线报警附加信息见
extra_12 = "12" + self.int2hexStringByBytes(6) + self.getInOutAreaAlarmExtraInfo()
#路段行驶时间不足/过长报警附加信息见
extra_13 = "13" + self.int2hexStringByBytes(7) + self.getDrivingLongOrShortAlarmExtraInfo()
#IO 状态位
extra_2A = "2A" + self.int2hexStringByBytes(2) + self.getStatusBit()
#BYTE,无线通信网络信号强度
extra_30 = "30" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(33)
#BYTE,GNSS 定位卫星数
extra_31 = "31" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(2)
#基础数据项列表
extra_EA = "EA" + self.int2hexStringByBytes(int(len(self.getBaseDataList()) / 2)) + self.getBaseDataList()
#轿车 OBD 数据流
extra_EB = "EB" + self.int2hexStringByBytes(int(len(SaloonCarOBD_data().generateSaloonCarOBDData()) / 2)) + SaloonCarOBD_data().generateSaloonCarOBDData()
#货车 OBD 数据流
extra_EC = "EC" + self.int2hexStringByBytes(int(len(TruckCarOBD_data().generateTruckCarOBD_data()) / 2)) + TruckCarOBD_data().generateTruckCarOBD_data()
#新能源 OBD 数据流
extra_ED = "ED" + self.int2hexStringByBytes(int(len(NewEnergyCar_data().generateNewEnergyCar_data()) / 2)) + NewEnergyCar_data().generateNewEnergyCar_data()
#外设数据项列表
extra_EE = "EE" + self.int2hexStringByBytes(int(len(Circum_data().generateCircum_data()) / 2)) + Circum_data().generateCircum_data()
#报警事件 ID 数据项列表
extra_FA = "FA" + self.int2hexStringByBytes(int(len(AlarmEvent_data().generateAlarmEvent_data()) / 2)) + AlarmEvent_data().generateAlarmEvent_data()
data = extra_01 + extra_02 + extra_11 + extra_31 + extra_EA + extra_EB
# data = extra_11 + extra_31 + extra_EA + extra_EB + extra_FA
# data = extra_11 + extra_31 + extra_EA + extra_FA
# data = extra_EB + extra_FA
# data = extra_01 + extra_02 + extra_11 + extra_12 + extra_13
# data = data + extra_2A + extra_30 + extra_31 + extra_EA + extra_EB
# data = data +extra_FA
return data
def getLocationExtraInfo_GUI(self,extraInfo):
data = ""
if("01" in extraInfo.keys()):
# 里程,DWORD,1 / 10km,对应车上里程表读数;不支持OBD时,为基于GPS车速统计的车辆累计行驶总里程。
extra_01 = "01" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(extraInfo["01"]["extra_01"]),4)
data = data + extra_01
if ("02" in extraInfo.keys()):
#油量,WORD,1/10L,对应车上油量表读数
extra_02 = "02" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(extraInfo["02"]["extra_02"]),2)
data = data + extra_02
if ("11" in extraInfo.keys()):
#超速报警附加信息
overSpeedAlarmExtraInfo = self.getOverSpeedAlarmExtraInfo_GUI(extraInfo["11"])
extra_11 = "11" + self.int2hexStringByBytes(int(len(overSpeedAlarmExtraInfo) / 2))
data = data + extra_11
if ("12" in extraInfo.keys()):
#进出区域/路线报警附加信息见
extra_12 = "12" + self.int2hexStringByBytes(6) + self.getInOutAreaAlarmExtraInfo_GUI(extraInfo["12"])
data = data +extra_12
if ("13" in extraInfo.keys()):
#路段行驶时间不足/过长报警附加信息见
extra_13 = "13" + self.int2hexStringByBytes(7) + self.getDrivingLongOrShortAlarmExtraInfo_GUI(extraInfo["13"])
data = data + extra_13
if ("2A" in extraInfo.keys()):
#IO 状态位
extra_2A = "2A" + self.int2hexStringByBytes(2) + self.getStatusBit_GUI(extraInfo["2A"])
data = data + extra_2A
if ("30" in extraInfo.keys()):
#BYTE,无线通信网络信号强度
extra_30 = "30" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(extraInfo["30"]["extra_30"]))
data = data + extra_30
if ("31" in extraInfo.keys()):
#BYTE,GNSS 定位卫星数
extra_31 = "31" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(extraInfo["31"]["extra_31"]))
data = data + extra_31
if ("EA" in extraInfo.keys()):
#基础数据项列表
baseDataList = self.getBaseDataList_GUI(extraInfo["EA"])
extra_EA = "EA" + self.int2hexStringByBytes(int(len(baseDataList) / 2)) + baseDataList
data = data + extra_EA
if ("EB" in extraInfo.keys()):
#轿车 OBD 数据流
saloonCarOBD_data = SaloonCarOBD_data().generateSaloonCarOBDData_GUI(extraInfo["EB"])
extra_EB = "EB" + self.int2hexStringByBytes(int(len(saloonCarOBD_data) / 2)) + saloonCarOBD_data
data = data + extra_EB
if ("EC" in extraInfo.keys()):
#货车 OBD 数据流
truckCarOBD_data = TruckCarOBD_data().generateTruckCarOBD_data()
extra_EC = "EC" + self.int2hexStringByBytes(int(len(truckCarOBD_data) / 2)) + truckCarOBD_data
data = data + extra_EC
if ("ED" in extraInfo.keys()):
#新能源 OBD 数据流
newEnergyCar_data = NewEnergyCar_data().generateNewEnergyCar_data()
extra_ED = "ED" + self.int2hexStringByBytes(int(len(newEnergyCar_data) / 2)) + newEnergyCar_data
data = data + extra_ED
if ("EE" in extraInfo.keys()):
#外设数据项列表
circum_data = Circum_data().generateCircum_data()
extra_EE = "EE" + self.int2hexStringByBytes(int(len(circum_data) / 2)) + circum_data
data = data + extra_EE
if ("FA" in extraInfo.keys()):
#报警事件 ID 数据项列表
alarmEvent_data = AlarmEvent_data().generateAlarmEvent_data_GUI(extraInfo["FA"])
extra_FA = "FA" + self.int2hexStringByBytes(int(len(alarmEvent_data) / 2)) + alarmEvent_data
data = data + extra_FA
return data
# 获取位置附加信息,数据随机产生
def getLocationExtraInfo_random(self):
data = ""
# 里程,DWORD,1 / 10km,对应车上里程表读数;不支持OBD时,为基于GPS车速统计的车辆累计行驶总里程。
extra_01 = "01" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4)
#油量,WORD,1/10L,对应车上油量表读数
extra_02 = "02" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#超速报警附加信息
data_11 = self.getOverSpeedAlarmExtraInfo_random()
extra_11 = "11" + self.int2hexStringByBytes(int(len(data_11) / 2)) + data_11
#进出区域/路线报警附加信息见
extra_12 = "12" + self.int2hexStringByBytes(6) + self.getInOutAreaAlarmExtraInfo_random()
#路段行驶时间不足/过长报警附加信息见
extra_13 = "13" + self.int2hexStringByBytes(7) + self.getDrivingLongOrShortAlarmExtraInfo_ramdom()
#IO 状态位
extra_2A = "2A" + self.int2hexStringByBytes(2) + self.getStatusBit_random()
#BYTE,无线通信网络信号强度
extra_30 = "30" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
#BYTE,GNSS 定位卫星数
extra_31 = "31" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
data_EA = self.getBaseDataList_random()
#基础数据项列表
extra_EA = "EA" + self.int2hexStringByBytes(int(len(data_EA) / 2)) + data_EA
#轿车 OBD 数据流
data_EB = SaloonCarOBD_data().generateSaloonCarOBDData_random()
extra_EB = "EB" + self.int2hexStringByBytes(int(len(data_EB) / 2)) + data_EB
#货车 OBD 数据流
# extra_EC = "EC" + self.int2hexStringByBytes(int(len(TruckCarOBD_data().generateTruckCarOBD_data()) / 2)) + TruckCarOBD_data().generateTruckCarOBD_data()
#新能源 OBD 数据流
# extra_ED = "ED" + self.int2hexStringByBytes(int(len(NewEnergyCar_data().generateNewEnergyCar_data()) / 2)) + NewEnergyCar_data().generateNewEnergyCar_data()
#外设数据项列表
# extra_EE = "EE" + self.int2hexStringByBytes(int(len(Circum_data().generateCircum_data()) / 2)) + Circum_data().generateCircum_data()
#报警事件 ID 数据项列表
data_FA = AlarmEvent_data().generateAlarmEvent_data_random()
extra_FA = "FA" + self.int2hexStringByBytes(int(len(data_FA) / 2)) + data_FA
arr = []
arr.append(extra_01)
arr.append(extra_02)
arr.append(extra_11)
arr.append(extra_12)
arr.append(extra_13)
arr.append(extra_2A)
arr.append(extra_30)
arr.append(extra_31)
arr.append(extra_EA)
arr.append(extra_EB)
arr.append(extra_FA)
mult = self.getRandomNum(0,11)
temp = []
for i in range(0, mult):
con = self.getRandomNum(intArr=arr,mult=1)
if con in temp:
con = ""
temp.append(con)
data = data + con
return data
#获取超速报警附加信息
def getOverSpeedAlarmExtraInfo(self):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = 1
areaId = "" #若位置类型为 0,无该字段
if locationType == 0:
pass
else:
areaId = self.int2hexStringByBytes(2020,4)
msg = self.int2hexStringByBytes(locationType) + areaId
return msg
def getOverSpeedAlarmExtraInfo_GUI(self,data):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = int(data["locationType_OverSpeed"])
areaId = "" #若位置类型为 0,无该字段
if locationType == 0:
pass
else:
areaId = self.int2hexStringByBytes(int(data["areaId_OverSpeed"]),4)
msg = self.int2hexStringByBytes(locationType) + areaId
return msg
#获取超速报警附加信息,数据随机产生
def getOverSpeedAlarmExtraInfo_random(self):
locationType = self.getRandomNum(intArr=[0,1,2,3,4])
areaId = "" #若位置类型为 0,无该字段
if locationType == 0:
pass
else:
areaId = self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4)
msg = self.int2hexStringByBytes(locationType) + areaId
return msg
#获取进出区域/路线报警附加信息
def getInOutAreaAlarmExtraInfo(self):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = 1
areaId = ""
if locationType == 0:
areaId = "00000000"
else:
areaId = self.int2hexStringByBytes(2020, 4)
direction = 0 #0-进,1-出
msg = self.int2hexStringByBytes(locationType) + areaId + self.int2hexStringByBytes(direction)
return msg
def getInOutAreaAlarmExtraInfo_GUI(self,data):
# 0:无特定位置;
# 1:圆形区域;
# 2:矩形区域;
# 3:多边形区域;
# 4:路段
locationType = int(data["locationType_inOut"])
areaId = ""
if locationType == 0:
areaId = "00000000"
else:
areaId = self.int2hexStringByBytes(int(data["areaId_inOut"]), 4)
direction = int(data["direction"]) #0-进,1-出
msg = self.int2hexStringByBytes(locationType) + areaId + self.int2hexStringByBytes(direction)
return msg
#获取进出区域/路线报警附加信息,数据随机参数
def getInOutAreaAlarmExtraInfo_random(self):
locationType = self.getRandomNum(intArr=[0,1,2,3,4])
areaId = ""
if locationType == 0:
areaId = "00000000"
else:
areaId = self.int2hexStringByBytes(self.getRandomNum(1,4294967295), 4)
direction = self.getRandomNum(intArr=[0,1]) #0-进,1-出
msg = self.int2hexStringByBytes(locationType) + areaId + self.int2hexStringByBytes(direction)
return msg
#路线行驶时间不足/过长报警附加信息消息
def getDrivingLongOrShortAlarmExtraInfo(self):
areaId = self.int2hexStringByBytes(2020, 4) #路段Id
drivingTime = self.int2hexStringByBytes(36000,2) #路段行驶时间(单位:秒)
result = self.int2hexStringByBytes(0) #结果,0-不足,1-过长
msg = areaId + drivingTime + result
return msg
def getDrivingLongOrShortAlarmExtraInfo_GUI(self,data):
areaId = self.int2hexStringByBytes(int(data["areaId_road"]), 4) #路段Id
drivingTime = self.int2hexStringByBytes(int(data["drivingTime"]),2) #路段行驶时间(单位:秒)
result = self.int2hexStringByBytes(int(data["result"])) #结果,0-不足,1-过长
msg = areaId + drivingTime + result
return msg
#路线行驶时间不足/过长报警附加信息消息,数据随机产生
def getDrivingLongOrShortAlarmExtraInfo_ramdom(self):
areaId = self.int2hexStringByBytes(self.getRandomNum(0,4294967295), 4) #路段Id
drivingTime = self.int2hexStringByBytes(self.getRandomNum(0,65535),2) #路段行驶时间(单位:秒)
result = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1])) #结果,0-不足,1-过长
msg = areaId + drivingTime + result
return msg
#获取状态位
def getStatusBit(self):
deepSleepStatus = 1 #1:深度休眠状态
sleepStatus = 2 #1:休眠状态
retain = 0
data = deepSleepStatus + sleepStatus + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
def getStatusBit_GUI(self,data):
deepSleepStatus = int(data["deepSleepStatus"]) #1:深度休眠状态
sleepStatus = int(data["sleepStatus"]) #1:休眠状态
retain = 0
data = deepSleepStatus + sleepStatus + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取状态位,数据随机产生
def getStatusBit_random(self):
dataHex = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1,2],mult=2),2)
return dataHex
#基础数据项列表
def getBaseDataList(self):
dataId_0001 = "0001" + self.int2hexStringByBytes(4) + self.getExpandStatusBit()
dataId_0002 = "0002" + self.int2hexStringByBytes(4) + self.getExpandAlarmBit()
dataId_0003 = "0003" + self.int2hexStringByBytes(5) + self.getTotalMileage()
dataId_0004 = "0004" + self.int2hexStringByBytes(5) + self.getTotalOil()
dataId_0005 = "0005" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(360000,4)
dataId_0006 = "0006" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(72000,4)
dataId_0007 = "0007" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(480000,4)
dataId_0010 = "0010" + self.int2hexStringByBytes(int(len(self.getSpeedupInOneSeconds()) / 2)) + self.getSpeedupInOneSeconds()
dataId_0011 = "0011" + self.int2hexStringByBytes(int(len(CarSafeStatusInfo().generateSecurityStatusData()) / 2)) + CarSafeStatusInfo().generateSecurityStatusData()
dataId_0012 = "0012" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(36,2)
dataId_0013 = "0013" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
#TODO 由于被置灰,所以没有实现
# dataId_0015 = "0015" + self.int2hexStringByBytes(2)
# dataId_0016 = "0016"
#TODO 暂不支持
# dataId_0017 = "0017" + self.int2hexStringByBytes(2)
dataId_001D = "001D" + self.int2hexStringByBytes(1) + "01"
data = dataId_0001 + dataId_0002 + dataId_0003 + dataId_0004 + dataId_0005
data = data + dataId_0006 + dataId_0007 + dataId_0010 + dataId_0011 + dataId_0012
data = data + dataId_0013 + dataId_001D
return data
def getBaseDataList_GUI(self,data):
dataHex = ""
if ("0001" in data.keys()):
dataId_0001 = "0001" + self.int2hexStringByBytes(4) + self.getExpandStatusBit_GUI(data["0001"])
dataHex = dataHex + dataId_0001
if ("0002" in data.keys()):
dataId_0002 = "0002" + self.int2hexStringByBytes(4) + self.getExpandAlarmBit_GUI(data["0002"])
dataHex = dataHex + dataId_0002
if ("0003" in data.keys()):
dataId_0003 = "0003" + self.int2hexStringByBytes(5) + self.getTotalMileage_GUI(data["0003"])
dataHex = dataHex + dataId_0003
if ("0004" in data.keys()):
dataId_0004 = "0004" + self.int2hexStringByBytes(5) + self.getTotalOil_GUI(data["0004"])
dataHex = dataHex + dataId_0004
if ("0005" in data.keys()):
dataId_0005 = "0005" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["0005"]["dataId_0005"]),4)
dataHex = dataHex + dataId_0005
if ("0006" in data.keys()):
dataId_0006 = "0006" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["0006"]["dataId_0006"]),4)
dataHex = dataHex + dataId_0006
if ("0007" in data.keys()):
dataId_0007 = "0007" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["0007"]["dataId_0007"]),4)
dataHex = dataHex + dataId_0007
if ("0010" in data.keys()):
speedupInOneSeconds = self.getSpeedupInOneSeconds_GUI(data["0010"])
dataId_0010 = "0010" + self.int2hexStringByBytes(int(len(speedupInOneSeconds) / 2)) + speedupInOneSeconds
dataHex = dataHex + dataId_0010
if ("0011" in data.keys()):
securityStatusData = CarSafeStatusInfo().generateSecurityStatusData_GUI(data["0011"])
dataId_0011 = "0011" + self.int2hexStringByBytes(int(len(securityStatusData) / 2)) + securityStatusData
dataHex = dataHex + dataId_0011
if ("0012" in data.keys()):
dataId_0012 = "0012" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["0012"]["dataId_0012"]),2)
dataHex = dataHex + dataId_0012
if ("0013" in data.keys()):
dataId_0013 = "0013" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["0013"]["dataId_0013"]))
dataHex = dataHex + dataId_0013
if ("001D" in data.keys()):
dataId_001D = "001D" + self.int2hexStringByBytes(1) + data["001D"]["dataId_001D"]
dataHex = dataHex + dataId_001D
return dataHex
#基础数据项列表,数据随机产生
def getBaseDataList_random(self):
dataId_0001 = "0001" + self.int2hexStringByBytes(4) + self.getExpandStatusBit_random()
dataId_0002 = "0002" + self.int2hexStringByBytes(4) + self.getExpandAlarmBit_random()
dataId_0003 = "0003" + self.int2hexStringByBytes(5) + self.getTotalMileage_random()
dataId_0004 = "0004" + self.int2hexStringByBytes(5) + self.getTotalOil_random()
dataId_0005 = "0005" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4)
dataId_0006 = "0006" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4)
dataId_0007 = "0007" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4)
dataId_0010 = "0010" + self.int2hexStringByBytes(int(len(self.getSpeedupInOneSeconds_random()) / 2)) + self.getSpeedupInOneSeconds_random()
dataId_0011 = "0011" + self.int2hexStringByBytes(int(len(CarSafeStatusInfo().generateSecurityStatusData_random()) / 2)) + CarSafeStatusInfo().generateSecurityStatusData_random()
dataId_0012 = "0012" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
dataId_0013 = "0013" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
dataId_001D = "001D" + self.int2hexStringByBytes(1) + self.getRandomNum(intArr=["00","01","02"])
arr = []
arr.append(dataId_0001)
arr.append(dataId_0002)
arr.append(dataId_0003)
arr.append(dataId_0004)
arr.append(dataId_0005)
arr.append(dataId_0006)
arr.append(dataId_0007)
arr.append(dataId_0010)
arr.append(dataId_0011)
arr.append(dataId_0012)
arr.append(dataId_0013)
arr.append(dataId_001D)
mult = self.getRandomNum(0,12)
temp = []
data = ""
for i in range(0, mult):
con = self.getRandomNum(intArr=arr)
if con in temp:
con = ""
temp.append(con)
data = data + con
return data
'''扩展状态标志位,见 表 C1EXT1'''
def getExpandStatusBit(self):
defenseUndefenseRep = 0 #0:撤防上报;1:设防上报 (1)
retain = 0
data = defenseUndefenseRep + retain
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
def getExpandStatusBit_GUI(self,data):
defenseUndefenseRep = int(data["dataId_0001"]) #0:撤防上报;1:设防上报 (1)
retain = 0
data = defenseUndefenseRep + retain
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
def getExpandStatusBit_random(self):
dataHex = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]),4)
return dataHex
'''扩展报警标志位,见 表 C1EXT2'''
def getExpandAlarmBit(self):
waterTemperatureAlarm = 1 #1:水温报警 (1)
idlingOverlongAlarm = 2 #1:怠速过长报警 (2)
rapidlyAccelerateAlarm = 4 #1:急加速报警 (4)
sharpSlowsownAlarm = 8 #1:急减速报警 (8)
sharpCurve = 16 #1:急转弯报警 (16)
retain5_9 = 0
insertAlarm = 1024 #1:插入报警 (1024)
oilExpenseNotSupportAlarm = 2048 #1:油耗不支持报警 (2048)
OBDNotSupportAlarm = 4096 #1:OBD 不支持报警 (4096)
buslineNotSleepAlarm = 8192 #1:总线不睡眠报警 (8192)
illegalOpenDoor = 16384 #1:非法开门 (16384)
retain15_16 = 0
FLASHTroubleAlarm = 131072 #1: FLASH 故障报警 (131072)
CANTroubleAlarm = 262144 #1: CAN 模块故障报警 (262144)
D3SensorTroubleAlarm = 524288 #1:3D 传感器故障报警 (524288)
RTCTroubleAlarm = 1048576 #1:RTC 模块故障报警
retain21_31 = 0
data = waterTemperatureAlarm + idlingOverlongAlarm + rapidlyAccelerateAlarm + sharpSlowsownAlarm + sharpCurve
data = data + retain5_9 + insertAlarm + oilExpenseNotSupportAlarm + OBDNotSupportAlarm + buslineNotSleepAlarm
data = data + illegalOpenDoor + retain15_16 + FLASHTroubleAlarm + CANTroubleAlarm + D3SensorTroubleAlarm
data = data + RTCTroubleAlarm + retain21_31
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
def getExpandAlarmBit_GUI(self,data):
dataHex = self.int2hexStringByBytes(data["dataId_0002"], 4)
return dataHex
def getExpandAlarmBit_random(self):
data = self.getRandomNum(intArr=[0,1,2,4,8,16,1024,2048, \
4096,8192,16384,131072,262144,524288,1048576],mult=14)
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
'''行驶总里程'''
def getTotalMileage(self):
caculateType = "0A"
totalMileage = self.int2hexStringByBytes(128000,4) #行驶总里程(单位米)
data = caculateType + totalMileage
return data
def getTotalMileage_GUI(self,data):
caculateType = data["caculateType"]
totalMileage = self.int2hexStringByBytes(int(data["totalMileage"]),4) #行驶总里程(单位米)
data = caculateType + totalMileage
return data
def getTotalMileage_random(self):
caculateType = self.getRandomNum(intArr=["01","02","03","04","05","06","07","09","0A","0B","0C"],)
totalMileage = self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4) #行驶总里程(单位米)
data = caculateType + totalMileage
return data
'''行驶总油耗'''
def getTotalOil(self):
caculateType = "02"
totalOil = self.int2hexStringByBytes(120000,4) #总油耗(单位 mL)
data = caculateType + totalOil
return data
def getTotalOil_GUI(self,data):
caculateType = data["caculateType"]
totalOil = self.int2hexStringByBytes(int(data["totalOil"]),4) #总油耗(单位 mL)
data = caculateType + totalOil
return data
def getTotalOil_random(self):
caculateType = self.getRandomNum(intArr=["01","02","03","04","05","0B","0C"],)
totalOil = self.int2hexStringByBytes(self.getRandomNum(0,4294967295),4) #总油耗(单位 mL)
data = caculateType + totalOil
return data
'''此刻 1 秒内的加速度数据,见 表 C1EXT3'''
def getSpeedupInOneSeconds(self):
data = ""
pointCount = 4 #采集的点个数 N
collectIntercal = 100 #采集间隔(单位 ms),上传值为该采集间隔时间内的加速度均值
data = data + self.int2hexStringByBytes(pointCount,2)
data = data + self.int2hexStringByBytes(collectIntercal,2)
speedupVal = 1000 #采集点加速度均值
for i in range(0,pointCount):
data = data + self.int2hexStringByBytes(speedupVal + 10,2)
return data
def getSpeedupInOneSeconds_GUI(self,data):
pointCount = int(data["pointCount"]) #采集的点个数 N
collectIntercal = int(data["collectIntercal"]) #采集间隔(单位 ms),上传值为该采集间隔时间内的加速度均值
data = ""
data = data + self.int2hexStringByBytes(pointCount,2)
data = data + self.int2hexStringByBytes(collectIntercal,2)
speedupVal = 1000 #采集点加速度均值
for i in range(0,pointCount):
data = data + self.int2hexStringByBytes(speedupVal + 10,2)
return data
def getSpeedupInOneSeconds_random(self):
data = ""
pointCount = self.getRandomNum(0,50) #采集的点个数 N
collectIntercal = self.getRandomNum(0,10000) #采集间隔(单位 ms),上传值为该采集间隔时间内的加速度均值
data = data + self.int2hexStringByBytes(pointCount,2)
data = data + self.int2hexStringByBytes(collectIntercal,2) #采集点加速度均值
for i in range(0,pointCount):
speedupVal = self.getRandomNum(0,65535)
data = data + self.int2hexStringByBytes(speedupVal,2)
return data
#######################################################
# 获取纬度信息
#######################################################
def getLatitude(self,data=29.40268):
data = int(data * 1000000)
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
#######################################################
# 获取经度信息
#######################################################
def getLongtitude(self,data=106.54041):
data = int(data * 1000000)
dataHex = self.int2hexStringByBytes(data, 4)
return dataHex
#######################################################
# 获取海拔高度
#######################################################
def getElevation(self,data=521):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取速度
#######################################################
def getSpeed(self,data=66):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取方向角度
#######################################################
def getDirectionAngle(self,data=59):
dataHex = self.int2hexStringByBytes(data, 2)
return dataHex
#######################################################
# 获取时间
#######################################################
def getInfoTime(self,data="2020-02-04 18:57:04"):
#now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data = data
data = data.replace("-","")
data = data.replace(" ","")
data = data.replace(":","")
data = data[2:]
data = self.int2BCD(int(data))
return data
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0200"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201110) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取报警标志
#######################################################
def getAlarmFlag(self):
emergencyAlarm = 1 #紧急报警,触动报警开关后触发
overspeedAlarm = 2 #超速报警
fatigueDriving = 4 #疲劳驾驶
dangerAlarm = 8 #危险预警
GNSSTrouble = 16 #GNSS 模块发生故障
GNSSAntennaeLost = 32 #GNSS 天线未接或被剪断
GNSSAntennaeShortOut = 64 #GNSS 天线短路
TerminalMainPowerLackVoltage = 128 #终端主电源欠压
TerminalMainPowerLostConnect = 256 #终端主电源掉电(设备拔出告警)
TerMinalLCDTrouble = 512 #终端 LCD 或显示器故障
TTSTrouble = 1024 #TTS 模块故障
cameraTrouble = 2048 #摄像头故障
ICTrouble = 4096 #道路运输证 IC 卡模块故障
speedEarlyWarning = 8192 #超速预警
fatigueDrivingearlyWarning = 16384 #疲劳驾驶预警
retain1 = 0
retain2 = 0
retain3 = 0
drivingOverTime = 262144 #当天累计驾驶超时
stoppingOverTime = 524288 #超时停车
InOutArea = 1048576 #进出区域
InOutRouting = 2097152 #进出路线
drivingLongOrShort = 4194304 #路段行驶时间不足/过长
routingDivergeAlarm = 8388608 #路线偏离报警
VSSTrouble = 16777216 #车辆 VSS 故障
oilException = 33554432 #车辆油量异常
carLost = 67108864 #车辆被盗(通过车辆防盗器)
illegalFire = 134217728 #车辆非法点火
illegalMoving = 268435456 #车辆非法位移(拖车告警)
collisionAlarm = 536870912 #碰撞预警
rollOverAlarm = 1073741824 #侧翻预警
illegalOpenDoor = 2147483648 #非法开门报警(终端未设置区域时, 不判断非法开门)
# emergencyAlarm = 0 #紧急报警,触动报警开关后触发
# overspeedAlarm = 0 #超速报警
# fatigueDriving = 0 #疲劳驾驶
# dangerAlarm = 0 #危险预警
# GNSSTrouble = 0 #GNSS 模块发生故障
# GNSSAntennaeLost = 0 #GNSS 天线未接或被剪断
# GNSSAntennaeShortOut = 0 #GNSS 天线短路
# TerminalMainPowerLackVoltage = 0 #终端主电源欠压
# TerminalMainPowerLostConnect = 0 #终端主电源掉电(设备拔出告警)
# TerMinalLCDTrouble = 0 #终端 LCD 或显示器故障
# TTSTrouble = 0 #TTS 模块故障
# cameraTrouble = 0 #摄像头故障
# ICTrouble = 0 #道路运输证 IC 卡模块故障
# speedEarlyWarning = 0 #超速预警
# fatigueDrivingearlyWarning = 0 #疲劳驾驶预警
# retain1 = 0
# retain2 = 0
# retain3 = 0
# drivingOverTime = 0 #当天累计驾驶超时
# stoppingOverTime = 0 #超时停车
# InOutArea = 0 #进出区域
# InOutRouting = 0 #进出路线
# drivingLongOrShort = 0 #路段行驶时间不足/过长
# routingDivergeAlarm = 0 #路线偏离报警
# VSSTrouble = 0 #车辆 VSS 故障
# oilException = 0 #车辆油量异常
# carLost = 0 #车辆被盗(通过车辆防盗器)
# illegalFire = 0 #车辆非法点火
# illegalMoving = 0 #车辆非法位移(拖车告警)
# collisionAlarm = 0 #碰撞预警
# rollOverAlarm = 0 #侧翻预警
# illegalOpenDoor = 0 #非法开门报警(终端未设置区域时, 不判断非法开门)
data = emergencyAlarm + overspeedAlarm + fatigueDriving + dangerAlarm + GNSSTrouble + GNSSAntennaeLost
data = data + GNSSAntennaeShortOut + TerminalMainPowerLackVoltage + TerminalMainPowerLostConnect + TerMinalLCDTrouble
data = data + TTSTrouble + cameraTrouble + ICTrouble + speedEarlyWarning + fatigueDrivingearlyWarning
data = data + retain1 + retain2 + retain3 + drivingOverTime + stoppingOverTime
data = data + InOutArea + InOutRouting + drivingLongOrShort + routingDivergeAlarm + VSSTrouble
data = data + oilException + carLost + illegalFire + illegalMoving + collisionAlarm
data = data + rollOverAlarm + illegalOpenDoor
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
#######################################################
# 获取状态
#######################################################
def getStatus(self):
ACCStatus = 1 #0:ACC 关;1: ACC 开 (1)
locationStatus = 2 #0:未定位;1:定位 (2)
latitudeStatus = 4 #0:北纬;1:南纬 (4)
longitudeStatus = 0 #0:东经;1:西经 (8)
runStatus = 0 #0:运营状态;1:停运状态 (16)
isLocationEncrypt = 0 #0:经纬度未经保密插件加密;1:经纬度已经保密插件加密 (32)
retain6_7 = 0
# 00:空车;01:半载;10:保留;11:满载(0 , 256 ,512 , 768)
#(可用于客车的空、重车及货车的空载、满载状态表示,人工输入或传感器 获取)
isFull = 256
oilRouteStatus = 0 #0:车辆油路正常;1:车辆油路断开 (1024)
powerStatus = 0 #0:车辆电路正常;1:车辆电路断开 (2048)
doorLockStatus = 0 #0:车门解锁;1:车门加锁 (4096)
frontDoor = 0 #0:门 1 关;1:门 1 开(前门) (8192)
middleDoor = 0 #0:门 2 关;1:门 2 开(中门) (16384)
backDoor = 0 #0:门 3 关;1:门 3 开(后门) (32768)
drivingDoor = 0 #0:门 4 关;1:门 4 开(驾驶席门) (65536)
otherDoor = 0 #0:门 5 关;1:门 5 开(自定义) (131072)
GPSStatus = 262144 #0:未使用 GPS 卫星进行定位;1:使用 GPS 卫星进行定位 (262144)
beidouStatus = 524288 #0:未使用北斗卫星进行定位;1:使用北斗卫星进行定位 (524288)
GLONSSStatus = 1048576 #0:未使用 GLONASS 卫星进行定位;1:使用 GLONASS 卫星进行定位 (1048576)
GalileoStatus = 0 #0:未使用 Galileo 卫星进行定位;1:使用 Galileo 卫星进行定位 (2097152)
retain22_31 = 0
data = ACCStatus + locationStatus + latitudeStatus + longitudeStatus + runStatus
data = data + isLocationEncrypt + retain6_7 + isFull + oilRouteStatus + powerStatus
data = data + doorLockStatus + frontDoor + middleDoor + backDoor + drivingDoor
data = data + otherDoor + GPSStatus + beidouStatus + GLONSSStatus + GalileoStatus
data = data + retain22_31
dataHex = self.int2hexStringByBytes(data,4)
return dataHex
if __name__ == "__main__":
# print(Location_msg().getAlarmFlag())
# print(Location_msg().getInfoTime())
# print(Location_msg().generateMsg())
# lati = Location_msg().getLatitude(29.40268)
# print(lati)
# print(int("01c329ed",16) / 1000000)
# print(int("0659dec5", 16) / 1000000)
print(Location_msg().getLocationBaseInfo_random())
#encoding:utf-8
import datetime
import random
import re
import time
from lib.protocol.Base import Base
'''
定义消息协议类的基类
'''
class MessageBase(Base):
def __init__(self):
self.IDENTIFY = "7e" #标识位
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
msgID = self.int2hexStringByBytes(102,2) #消息id
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201118) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息头,针对图形界面,可传递参数
def getMsgHeader_GUI(self,msgID,phoneNum,msgWaterCode,encryptionType,subPkg,msgBody=""): #消息id
msgID = msgID
subPkg = subPkg
msgBodyProperty = self.getMsgBodyProperty_GUI(msgBodyLen=int(len(msgBody) / 2),encryptionType=encryptionType,subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(phoneNum) #终端手机号
msgWaterCode = self.int2hexStringByBytes(msgWaterCode,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息封装项
def getMsgPackage(self):
pkgCounts = 2 #消息报包总数
pkgCountsHex = self.int2hexStringByBytes(2,2)
pkgNumsHex = ""
for i in range(0,pkgCounts):
pkgNum = i
dataHex = self.int2hexStringByBytes(pkgNum,2)
pkgNumsHex = pkgNumsHex + dataHex
msgPackage = pkgCountsHex + pkgNumsHex
return msgPackage
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
return ""
#######################################################
# 获取校验码
#######################################################
def getCheckCode(self,data="aa"):
if len(data) % 2 == 1:
raise RuntimeError('数据段错误!')
start = data[0:2]
tmp = int(start,16)
for i in range(2,len(data),2):
tmp = tmp ^ int(data[i:i + 2],16)
dataHex = self.int2hexStringByBytes(tmp)
return dataHex
#######################################################
# 替换消息中的7e7d字符
#######################################################
def replace7e7d(self,data):
# data = data.replace("7d","7d01")
# data = data.replace("7e","7d02")
tmpR = data
tmp = tmpR[0:2]
tmpA = tmpR[0:2]
tmpR = tmpR[2:]
data = ""
while tmpA != "":
if tmp == "7d":
tmp = "7d01"
elif tmp == "7e":
tmp = "7d02"
data = data + tmp
tmp = tmpR[0:2]
tmpA = tmpR[0:2]
tmpR = tmpR[2:]
return data
#######################################################
# 字符串转16进制
#######################################################
def str2Hex(self,data):
dataHex = ""
tem = ""
for i in data:
tem = ord(i)
dataHex += hex(tem)[2:]
return dataHex
#######################################################
# 16进制转字符串
#######################################################
def hex2Str(self,data):
theStr = ""
while data != "":
tmp = data[:2]
data = data[2:]
theStr = theStr + chr(int(tmp,16))
return theStr
#####################################################
# 将字符串转换为对应的ascii值数组
#####################################################
def str2Ascsii(self,data):
asciiArr = []
for i in range(0, len(data)):
asciiValue = ord(data[i])
asciiArr.append(asciiValue)
return asciiArr
####################################################
# 将整数转换为有符号的整数
#####################################################
def num2signedNum(self,num):
return num & 0xff
#####################################################
# 数字转换为16进制字符串,通过传入字节数可自动补0
# 传入数据格式所占字节数
#####################################################
def int2hexStringByBytes(self, num,bytescount=1):
hexStr = hex(num)[2:]
while len(hexStr) < (bytescount * 2):
hexStr = "0" + hexStr
return hexStr
####################################################
# 将10进制转换位8421码
#####################################################
def int2BCD(self,data,bytescount=6):
data = str(data)
while len(data) < bytescount * 2:
data = "0" + data
return data
#######################################################
# 获取UTC时间转换位BCD格式
#######################################################
def getBCDTime(self,data="2020-02-04 18:57:04"):
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data = data
data = data.replace("-","")
data = data.replace(" ","")
data = data.replace(":","")
data = data[2:]
data = self.int2BCD(int(data))
return data
#######################################################
# 字符串转换为GBK的16进制
#######################################################
def GBKString2Hex(self,data):
'''
data = str(data.encode("gbk"))
dataHex = self.str2Hex(data[2:len(data) - 1])
return dataHex
'''
dataHex = ""
strLen = len(data)
for i in range(0,strLen):
if re.search("[0-9a-zA-Z-_]",data[i]) != None:
dataHex = dataHex + self.str2Hex(data[i])
else:
temp = str(data[i].encode("gbk")).replace("\\x","")
dataHex = dataHex + temp[2:len(temp) - 1]
return dataHex
#######################################################
# 16进制转换为GBK字符串
#######################################################
def hex2GBKString(self,dataHex):
dataStr = self.hex2Str(dataHex)
data = bytes(map(ord,str(dataStr)))
data = data.decode("gbk")
return data
#######################################################
# 获取一个随机数,也可以指定获取数组中的随机字符串
#######################################################
def getRandomNum(self,s=1,e=1,intArr=[],mult=0):
if intArr == []:
data = random.randint(s, e)
else:
if mult == 0:
if type(intArr[0]) == int:
data = int(random.choice(intArr))
elif type(intArr[0]) == str:
data = random.choice(intArr)
else:
if type(intArr[0]) == int:
if len(intArr) < mult:
raise RuntimeError('个数超过数组长度!')
temp = []
data = 0
for i in range(0,mult):
num = int(random.choice(intArr))
if num in temp:
# num = int(random.choice(intArr))
num = 0
temp.append(num)
data = data + num
elif type(intArr[0]) == str:
if len(intArr) < mult:
raise RuntimeError('个数超过数组长度!')
temp = []
data = ""
for i in range(0,mult):
num = random.choice(intArr)
if num in temp:
# num = int(random.choice(intArr))
num = "0"
temp.append(num)
data = data + num
return data
#######################################################
# 获取一个随机字符串
#######################################################
def getRandomStr(self,counts,strs=""):
if strs == "":
data = random.sample("0123456789abcdefghijkmlnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-", counts)
else:
data = []
for s in range(0,counts):
data.append(random.choice(strs))
temp = ""
for ch in data:
temp = temp +ch
return temp
#######################################################
# 获取随机时间
# type:0、获取年月日时分秒 1、获取年月日 2、获取时分秒
#######################################################
def getRandomDate(self,s=631123200,e=1577808000,type=0):
timeStamp = random.randint(s, e)
timeArray = time.localtime(timeStamp)
if type == 0:
theTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
elif type == 1:
theTime = time.strftime("%Y-%m-%d", timeArray)
elif type == 2:
theTime = time.strftime("%H:%M:%S", timeArray)
return theTime
if __name__ == "__main__":
# print(MessageBase().str2Hex("uvwxyz"))
# print(MessageBase().str2Ascsii("uvwxyz"))
# print(MessageBase().int2hexStringByBytes(220400566542345564784802,20))
# print(MessageBase().str2Hex("a865h643gfdj64fd7432"))
# print(MessageBase().hex2Str("d4c1423939383838"))
# print(MessageBase().GBKString2Hex("KZP200_V201001"))
# print(MessageBase().hex2GBKString("4b5a503230305f56323031303031"))
# print(MessageBase().str2Hex("\xd3\xe5B23CX"))
# print(MessageBase().getMsgBodyProperty())
# print(MessageBase().int2BCD(13146201117))
# print(MessageBase().getCheckCode("8001000501314620111800000000000200"))
# print(MessageBase().getMsgHeader())
# print(MessageBase().generateMsg())
print(MessageBase().GBKString2Hex("渝B23CX"))
print(MessageBase().hex2GBKString("d3e54232334358"))
print(MessageBase().hex2GBKString("4c323030414230313032303030312c737a6c696e6779692e716963702e7669702c383838392c537a4c696e6759692c7a373254713246742c4c3230304142303130322e303030312e42494e2c2f2c"))
# print(MessageBase().int2BCD(123456789012345,10))
# print(MessageBase().getRandomNum(3000,5000,[2,4,6,8,10,12],4))
# print(MessageBase().getRandomStr(10))
print(MessageBase().replace7e7d("807d007e01314620111800000000000200"))
print(MessageBase().replace7e7d("87d107e501314620111800000000000200"))
#encoding:utf-8
'''
定义平台升级数据包应答消息
'''
from lib.protocol.message.MessageBase import MessageBase
class PlateformUpdateRes_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="8FF1",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0):
msg = ""
msgBody = self.getMsgBody()
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
firmwareVersionLen = self.int2hexStringByBytes(12) #固件版本号长度
firmwareVersion = self.str2Hex("ver_12.34.10") #固件版本号
upgradeFileSize = self.int2hexStringByBytes(2048000,4) #升级文件总大小
upgradeFileCheck = self.int2hexStringByBytes(205000,4) #升级文件总校验
offsetAddress = self.int2hexStringByBytes(48000,4) #偏移量地址
upgradePkgContent = self.str2Hex("upgrade_content_11.22.33") #升级数据包内容
msg = msg + firmwareVersionLen + firmwareVersion + upgradeFileSize + upgradeFileCheck + offsetAddress + upgradePkgContent
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "8FF1"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
pass
\ No newline at end of file
#encoding:utf-8
'''
定义设置终端参数消息
'''
import datetime
from lib.protocol.message.MessageBase import MessageBase
class SetTerminalParam_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
paramTotalNums = self.int2hexStringByBytes(1) #参数总数
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "8103"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#encoding:utf-8
'''
定义终端鉴权消息
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalAuthenticate_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
#鉴权码
authenticateCode = str("asuyx7".encode("gbk"))
authenticateCode = authenticateCode[2:len(authenticateCode) - 1]
authenticateCode = self.str2Hex(authenticateCode)
msg = authenticateCode
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0102"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
\ No newline at end of file
#encoding:utf-8
'''
定义终端通用应答
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalCommonMsgRes_msg(MessageBase):
def __init__(self,resId="0002",phoneNum=13146201119,resWaterCode="0001",sn=1):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
self.resId = resId
self.phoneNum = phoneNum
self.resWaterCode = resWaterCode
self.sn = sn
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
resWaterCode = self.resWaterCode #对应的平台消息的流水号
msgId = self.resId #消息id,对应的平台消息的 ID
reslult = self.int2hexStringByBytes(0) #0:成功/确认;1:失败;2:消息有误;3:不支持
data = ""
msg = data + resWaterCode + msgId + reslult
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0001" #消息id
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(int(self.phoneNum)) #终端手机号
msgWaterCode = self.int2hexStringByBytes(self.sn,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
if __name__ == "__main__":
print(TerminalCommonMsgRes_msg().generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义终端心跳消息
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalHeartbeat_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="0002",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0):
msg = ""
msgBody = self.getMsgBody()
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,数据随机产生
def generateMsg_random(self):
msgID="0002"
phoneNum=self.getRandomStr(11,"0123456789")
msgWaterCode=self.getRandomNum(1,65535)
encryptionType=0
subPkg=self.getRandomNum(intArr=[0,8192],mult=1)
msg = ""
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg)
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0002"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201118) #终端手机号
msgWaterCode = self.int2hexStringByBytes(6,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType << 10 #加密方式
subPkg = subPkg << 13 #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(TerminalHeartbeat_msg().generateMsg())
print(TerminalHeartbeat_msg().getMsgBodyProperty())
\ No newline at end of file
#encoding:utf-8
'''
定义终端注册消息
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalRegister_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="0100",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0,provinceId=50,\
countyId=103,manufacturerId="11010",terminalType="a865h643gfdj64fd7432",terminalId="H6uyt08", \
licencePlateColor=1,carSign="渝B23CX"):
msg = ""
msgBody = self.getMsgBody_GUI(provinceId,countyId,manufacturerId,terminalType,terminalId,licencePlateColor,carSign)
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,数据随机产生
def generateMsg_random(self):
msgID = "0100"
phoneNum = self.getRandomStr(11, "0123456789")
msgWaterCode = self.getRandomNum(1, 65535)
encryptionType = 0
subPkg = self.getRandomNum(intArr=[0, 8192])
provinceId = self.getRandomNum(10,99)
countyId = self.getRandomNum(100,990)
manufacturerId = self.getRandomStr(5,"0123456789")
terminalType = self.getRandomStr(20)
terminalId = self.getRandomStr(7)
licencePlateColor = self.getRandomNum(intArr=[1,2,3,4,9])
carSign = self.getRandomStr(5)
msg = ""
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg)
msgBody = self.getMsgBody_GUI(provinceId, countyId, manufacturerId, terminalType, terminalId, licencePlateColor,
carSign)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
# msgNums = self.int2hexStringByBytes(1,2)
# msgNumber = self.int2hexStringByBytes(1,2)
#省域 ID (标示终端安装车辆所在的省域,0 保留,由平台取默认值。省 域 ID 采用 GB/T 2260 中规定的行政区划代 码六位中前两)
provinceId = self.int2hexStringByBytes(50,2)
#市县域 ID
countyId = self.int2hexStringByBytes(103,2)
#制造商 ID (5 个字节,终端制造商编码)
manufacturerId = self.str2Hex("man03")
#终端型号 (20 个字节,此终端型号由制造商自行定义,位数不足时,后 补“0X00”。)
terminalType = self.str2Hex("a865h643gfdj64fd7432")
#终端 ID (7 个字节,由大写字母和数字组成,此终端 ID 由制造商自行 定义,位数不足时,后补“0X00”)
terminalId = self.str2Hex("H6uyt08")
#车牌颜色 (车牌颜色,按照 JT/T415-2006 的 5.4.12。未上牌时,取值 为 0) 1:蓝色 2:黄色 3:黑色 4:白色 9:其他
licencePlateColor = self.int2hexStringByBytes(2)
#车辆标识 (车牌颜色为 0 时,表示车辆 VIN;否则,表示公安交通管理 部门颁发的机动车号牌)
carSign = self.GBKString2Hex("渝B23CX")
# msg = msg + msgNums + msgNumber
msg = msg + provinceId + countyId + manufacturerId + terminalType + terminalId + licencePlateColor + carSign
return msg
# 获取消息体,针对图形界面,可传递参数
def getMsgBody_GUI(self,provinceId=50,countyId=103,manufacturerId="11010",terminalType="a865h643gfdj64fd7432",terminalId="H6uyt08", \
licencePlateColor=1,carSign="渝B23CX"):
msg = ""
# msgNums = self.int2hexStringByBytes(1,2)
# msgNumber = self.int2hexStringByBytes(1,2)
#省域 ID (标示终端安装车辆所在的省域,0 保留,由平台取默认值。省 域 ID 采用 GB/T 2260 中规定的行政区划代 码六位中前两)
provinceId = self.int2hexStringByBytes(provinceId,2)
# 市县域 ID
countyId = self.int2hexStringByBytes(countyId, 2)
#制造商 ID (5 个字节,终端制造商编码)
manufacturerId = self.str2Hex(manufacturerId)
#终端型号 (20 个字节,此终端型号由制造商自行定义,位数不足时,后 补“0X00”。)
terminalType = self.str2Hex(terminalType)
#终端 ID (7 个字节,由大写字母和数字组成,此终端 ID 由制造商自行 定义,位数不足时,后补“0X00”)
terminalId = self.str2Hex(terminalId)
#车牌颜色 (车牌颜色,按照 JT/T415-2006 的 5.4.12。未上牌时,取值 为 0) 1:蓝色 2:黄色 3:黑色 4:白色 9:其他
licencePlateColor = self.int2hexStringByBytes(licencePlateColor)
#车辆标识 (车牌颜色为 0 时,表示车辆 VIN;否则,表示公安交通管理 部门颁发的机动车号牌)
carSign = self.GBKString2Hex(carSign)
# msg = msg + msgNums + msgNumber
msg = msg + provinceId + countyId + manufacturerId + terminalType + terminalId + licencePlateColor + carSign
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0100"
msgBodyProperty = self.getMsgBodyProperty(int(len(self.getMsgBody()) / 2)) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(TerminalRegister_msg().generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义终端请求OBD适配信息
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalRequestOBDInfo_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="0206",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0):
msg = ""
msgBody = self.getMsgBody()
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,数据随机产生
def generateMsg_random(self):
msgID="0206"
phoneNum=self.getRandomStr(11,"0123456789")
msgWaterCode=self.getRandomNum(1,65535)
encryptionType=0
subPkg=self.getRandomNum(intArr=[0,8192],mult=1)
msg = ""
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg)
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0206"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201118) #终端手机号
msgWaterCode = self.int2hexStringByBytes(6,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType << 10 #加密方式
subPkg = subPkg << 13 #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(TerminalRequestOBDInfo_msg().generateMsg())
print(TerminalRequestOBDInfo_msg().getMsgBodyProperty())
\ No newline at end of file
#encoding:utf-8
'''
定义终端升级结果通知
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalUpdataResult_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
#升级类型
#00:终端
# 12:道路运输证 IC 卡读卡器
# 52:北斗
updateType = "00"
#升级结果
#0x00:成功
# 0x01:失败(升级超时,放弃当前升级)
# 0x02:取消
# 0xF0:升级相同版本,不升级(扩展)
# 0xF1:升级版本属性错误(扩展)
# 0xF2:升级文件校验错误(扩展)
# 0xF3:升级文件不存在(扩展)
updataResult = "00"
msg = updateType + updataResult
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0108"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(TerminalUpdataResult_msg().generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义终端版本信息主动上报
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalVersionInfo_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="0205",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0, \
softwareVersion="L200AB01020002", softwareVersionDate="2020-02-10", CPUId="CPU-12345678",GMSType="GMS-TYPE-123456", \
GMS_IMEI="GMS_IMEI_123456", SIM_IMSI="SIM_13146201119", SIM_ICCID="SIM_ICCID13146201119",carType=22, VIN="VIN_1234567891234", \
totalMileage=389000, totalOilExpend=420000,displacement=1500,oilDensity=80,OBDSerial=257,oilCalculateType="01"):
msg = ""
msgBody = self.getMsgBody_GUI(softwareVersion,softwareVersionDate,CPUId,GMSType,GMS_IMEI,SIM_IMSI,SIM_ICCID,carType,VIN,\
totalMileage,totalOilExpend,displacement,oilDensity,OBDSerial,oilCalculateType)
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,数据随机产生
def generateMsg_random(self):
msgID = "0205"
phoneNum = self.getRandomStr(11, "0123456789")
msgWaterCode = self.getRandomNum(1, 65535)
encryptionType = 0
subPkg = self.getRandomNum(intArr=[0, 8192])
softwareVersion = "KZP200_" + self.getRandomStr(7)
softwareVersionDate = self.getRandomDate(type=1)
CPUId = "CPU-" + self.getRandomStr(8,"0123456789")
GMSType = "GMS-TYPE-" + self.getRandomStr(6,"0123456789")
GMS_IMEI = "GMS_IMEI_" + self.getRandomStr(6,"0123456789")
SIM_IMSI = "SIM_" + self.getRandomStr(11,"0123456789")
SIM_ICCID = "SIM_ICCID" + self.getRandomStr(11,"0123456789")
carType = self.getRandomNum(0,65535)
VIN = "VIN_" + self.getRandomStr(13,"0123456789")
totalMileage = self.getRandomNum(30000,6000000)
totalOilExpend = self.getRandomNum(30000,6000000)
displacement = self.getRandomNum(500,3000)
oilDensity = self.getRandomNum(80,500)
msg = ""
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg)
msgBody = self.getMsgBody_GUI(softwareVersion, softwareVersionDate, CPUId, GMSType, GMS_IMEI, SIM_IMSI,
SIM_ICCID, carType, VIN, \
totalMileage, totalOilExpend,displacement,oilDensity)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
softwareVersion = self.GBKString2Hex("L200AB01020002") #软件版本号
softwareVersionDate = self.GBKString2Hex("2020-02-10") #终端版本日期
CPUId = self.str2Hex("CPU-12345678") #cpuId
GSMType = self.GBKString2Hex("GSM-TYPE-123456") #GSM型号
GSM_IMEI = self.GBKString2Hex("GSM_IMEI_123456") #GSM IMEI 号
SIM_IMSI = self.GBKString2Hex("SIM_13146201119") #终端 SIM 卡 IMSI 号
SIM_ICCID = self.GBKString2Hex("SIM_ICCID13146201119") #终端 SIM 卡 ICCID 号
carType = self.int2hexStringByBytes(22,2) #车系车型 ID
VIN = self.GBKString2Hex("VIN_1234567891234") #汽车 VIN 码
totalMileage = self.int2hexStringByBytes(389000,4) #装上终端后车辆累计总里程或车辆仪表里程(单位米)
totalOilExpend = self.int2hexStringByBytes(420000,4) #装上终端后车辆累计总耗油量(ml)
displacement = self.int2hexStringByBytes(1500,2) #排量
oilDensity = self.int2hexStringByBytes(92,2) #油品密度
OBDSerial = "0101" #OBD协议编号
oilCalculateType = "01" #油耗计算方式
msg = msg + softwareVersion + softwareVersionDate + CPUId + GSMType + GSM_IMEI
msg = msg + SIM_IMSI + SIM_ICCID + carType + VIN + totalMileage
msg = msg + totalOilExpend + displacement + oilDensity + OBDSerial + oilCalculateType
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def getMsgBody_GUI(self,softwareVersion="L200AB01020002",softwareVersionDate="2020-02-10",CPUId="CPU-12345678",GMSType="GMS-TYPE-123456",\
GMS_IMEI="GMS_IMEI_123456",SIM_IMSI="SIM_13146201119",SIM_ICCID="SIM_ICCID13146201119",carType=22,VIN="VIN_1234567891234",\
totalMileage=389000,totalOilExpend=420000,displacement=1500,oilDensity=92,OBDSerial=257,oilCalculateType="01"):
msg = ""
softwareVersion = self.GBKString2Hex(softwareVersion) #软件版本号
softwareVersionDate = self.GBKString2Hex(softwareVersionDate) #终端版本日期
CPUId = self.str2Hex(CPUId) #cpuId
GMSType = self.GBKString2Hex(GMSType) #GMS型号
GMS_IMEI = self.GBKString2Hex(GMS_IMEI) #GSM IMEI 号
SIM_IMSI = self.GBKString2Hex(SIM_IMSI) #终端 SIM 卡 IMSI 号
SIM_ICCID = self.GBKString2Hex(SIM_ICCID) #终端 SIM 卡 ICCID 号
carType = self.int2hexStringByBytes(carType,2) #车系车型 ID
VIN = self.GBKString2Hex(VIN) #汽车 VIN 码
totalMileage = self.int2hexStringByBytes(totalMileage,4) #装上终端后车辆累计总里程或车辆仪表里程(单位米)
totalOilExpend = self.int2hexStringByBytes(totalOilExpend,4) #装上终端后车辆累计总耗油量(ml)
displacement = self.int2hexStringByBytes(displacement,2) #排量
oilDensity = self.int2hexStringByBytes(oilDensity,2) #油密度
OBDSerial = self.int2hexStringByBytes(OBDSerial,2) #OBD协议编号
oilCalculateType = oilCalculateType #油耗计算方式
msg = msg + softwareVersion + softwareVersionDate + CPUId + GMSType + GMS_IMEI
msg = msg + SIM_IMSI + SIM_ICCID + carType + VIN + totalMileage
msg = msg + totalOilExpend + displacement + oilDensity + OBDSerial + oilCalculateType
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0205"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
pass
\ No newline at end of file
#encoding:utf-8
'''
定义文本信息上传消息
'''
from lib.protocol.message.MessageBase import MessageBase
class TextInfoUpload_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
# 生成一条完整的消息,针对图形界面,可传递参数
def generateMsg_GUI(self,msgID="8300",phoneNum="13146201119",msgWaterCode=1,encryptionType=0,subPkg=0):
msg = ""
msgBody = self.getMsgBody()
msgHeader = self.getMsgHeader_GUI(msgID, phoneNum, msgWaterCode, encryptionType, subPkg,msgBody)
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
flag = self.getFlag() #标志
textInfo = self.GBKString2Hex("textInfo_123456") #文本信息
msg = flag + textInfo
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "8300"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#获取消息体属性,针对图形界面,可传递参数
def getMsgBodyProperty_GUI(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取文本信息标志
#######################################################
def getFlag(self):
#0 1:紧急(备注:主要用于设备厂商私有协议 ASCII 文本控制指令下发)
# 1 保留
# 2 1:终端显示器显示
# 3 1:终端 TTS 播读
# 4 1:广告屏显示
# 5 0:中心导航信息,1:CAN 故障码信息
# 6-7 保留
bit0 = 0
bit2 = 4
bit3 = 8
bit4 = 16
bit5 = 32
data = bit0 + bit2 + bit3 + bit4 + bit5
dataHex = self.int2hexStringByBytes(data)
return dataHex
if __name__ == "__main__":
pass
\ No newline at end of file
#encoding:utf-8
'''
定义外设数据项
'''
from lib.protocol.message.MessageBase import MessageBase
class AlarmEvent_data(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建报警事件数据
#####################################################
def generateAlarmEvent_data(self):
data = ""
ignition = "0001" + self.int2hexStringByBytes(0) #点火上报
flameout = "0002" + self.int2hexStringByBytes(0) #熄火上报
setUpDefences = "0003" + self.int2hexStringByBytes(0) #设防上报
withdrawGarrision = "0004" + self.int2hexStringByBytes(0) #撤防上报
doorOpen = "0005" + self.int2hexStringByBytes(0) #车门打开
doorClose = "0006" + self.int2hexStringByBytes(0) #车门关闭
systemStart = "0007" + self.int2hexStringByBytes(0) #系统启动
trailCarAlarm = "0101" + self.int2hexStringByBytes(0) #拖车报警
locationTooLong = "0102" + self.int2hexStringByBytes(0) #定位过长报警
terminalPullOut = "0103" + self.int2hexStringByBytes(0) #终端拔出报警
terminalInsert = "0104" + self.int2hexStringByBytes(0) #终端插入报警
lowVoltage = "0105" + self.int2hexStringByBytes(0) #低电压报警
#怠速过长报警 附带信息见 表 C6EXT1
idlingSpeedOver = "0106" + self.int2hexStringByBytes(9) + self.getIdlingSpeedOver()
#超速报警 附带信息见 表 C6EXT2
overspeedAlarm = "0107" + self.int2hexStringByBytes(9) + self.getOverspeedAlarm()
#疲劳驾驶报警 附带信息见 表 C6EXT3
fatigueDriving = "0108" + self.int2hexStringByBytes(5) + self.getFatigueDriving()
#水温报警 附带信息见 表 C6EXT4
waterTemperatureAlarm = "0109" + self.int2hexStringByBytes(9) + self.getWaterTemperatureAlarm()
highSpeedNeutralGear = "010A" + self.int2hexStringByBytes(0) #高速空档滑行报警
oilExpendNotSurport = "010B" +self.int2hexStringByBytes(0) #油耗不支持报警
OBDNotSurport = "010C" + self.int2hexStringByBytes(0) #OBD 不支持报警
lowWaterTemperatureHighSpeed = "010D" +self.int2hexStringByBytes(0) #低水温高转速
buslineNotSleep = "010E" + self.int2hexStringByBytes(0) #总线不睡眠报警
illegalOpenDoor = "010f" + self.int2hexStringByBytes(0) #非法开门
illegalFire = "0110" + self.int2hexStringByBytes(0) #非法点火
rapidAccelerateAlarm = "0111" + self.int2hexStringByBytes(0) #急加速报警
sharpSlowdownAlarm = "0112" + self.int2hexStringByBytes(0) #急减速报警
sharpBendAlarm = "0113" + self.int2hexStringByBytes(0) #急左拐弯报警
crashAlarm = "0114" + self.int2hexStringByBytes(0) #碰撞报警
rapidChangeLines = "0115" + self.int2hexStringByBytes(0) #急变道报警
sharpRightBendAlarm = "0117" + self.int2hexStringByBytes(0) #急右拐弯报警
data = ignition
# data = data + ignition + flameout + setUpDefences + withdrawGarrision + doorOpen
# data = data + doorClose + systemStart + trailCarAlarm + locationTooLong + terminalPullOut
# data = data + terminalInsert + lowVoltage + idlingSpeedOver + overspeedAlarm + fatigueDriving
# data = data + waterTemperatureAlarm + highSpeedNeutralGear + oilExpendNotSurport + OBDNotSurport + lowWaterTemperatureHighSpeed
# data = data + buslineNotSleep + illegalOpenDoor + illegalFire + rapidAccelerateAlarm + sharpSlowdownAlarm
# data = data + sharpBendAlarm + crashAlarm + rapidChangeLines
return data
def generateAlarmEvent_data_GUI(self,data):
dataHex = ""
if ("ignition" in data.keys()):
ignition = "0001" + self.int2hexStringByBytes(0) #点火上报
dataHex = dataHex + ignition
if ("flameout" in data.keys()):
flameout = "0002" + self.int2hexStringByBytes(0) #熄火上报
dataHex = dataHex + flameout
if ("setUpDefences" in data.keys()):
setUpDefences = "0003" + self.int2hexStringByBytes(0) #设防上报
dataHex = dataHex + setUpDefences
if ("withdrawGarrision" in data.keys()):
withdrawGarrision = "0004" + self.int2hexStringByBytes(0) #撤防上报
dataHex = dataHex + withdrawGarrision
if ("doorOpen" in data.keys()):
doorOpen = "0005" + self.int2hexStringByBytes(0) #车门打开
dataHex = dataHex + doorOpen
if ("doorClose" in data.keys()):
doorClose = "0006" + self.int2hexStringByBytes(0) #车门关闭
dataHex = dataHex + doorClose
if ("systemStart" in data.keys()):
systemStart = "0007" + self.int2hexStringByBytes(0) #系统启动
dataHex = dataHex + systemStart
if ("trailCarAlarm" in data.keys()):
trailCarAlarm = "0101" + self.int2hexStringByBytes(0) #拖车报警
dataHex = dataHex + trailCarAlarm
if ("locationTooLong" in data.keys()):
locationTooLong = "0102" + self.int2hexStringByBytes(0) #定位过长报警
dataHex = dataHex + locationTooLong
if ("terminalPullOut" in data.keys()):
terminalPullOut = "0103" + self.int2hexStringByBytes(0) #终端拔出报警
dataHex = dataHex + terminalPullOut
if ("terminalInsert" in data.keys()):
terminalInsert = "0104" + self.int2hexStringByBytes(0) #终端插入报警
dataHex = dataHex + terminalInsert
if ("lowVoltage" in data.keys()):
lowVoltage = "0105" + self.int2hexStringByBytes(0) #低电压报警
dataHex = dataHex + lowVoltage
if ("idlingSpeedOver" in data.keys()):
#怠速过长报警 附带信息见 表 C6EXT1
idlingSpeedOver = "0106" + self.int2hexStringByBytes(9) + self.getIdlingSpeedOver_GUI(data["idlingSpeedOver"])
dataHex = dataHex + idlingSpeedOver
if ("overspeedAlarm" in data.keys()):
#超速报警 附带信息见 表 C6EXT2
overspeedAlarm = "0107" + self.int2hexStringByBytes(9) + self.getOverspeedAlarm_GUI(data["overspeedAlarm"])
dataHex = dataHex + overspeedAlarm
if ("fatigueDriving" in data.keys()):
#疲劳驾驶报警 附带信息见 表 C6EXT3
fatigueDriving = "0108" + self.int2hexStringByBytes(5) + self.getFatigueDriving_GUI(data["fatigueDriving"])
dataHex = dataHex + fatigueDriving
if ("waterTemperatureAlarm" in data.keys()):
#水温报警 附带信息见 表 C6EXT4
waterTemperatureAlarm = "0109" + self.int2hexStringByBytes(9) + self.getWaterTemperatureAlarm_GUI(data["waterTemperatureAlarm"])
dataHex = dataHex + waterTemperatureAlarm
if ("highSpeedNeutralGear" in data.keys()):
highSpeedNeutralGear = "010A" + self.int2hexStringByBytes(0) #高速空档滑行报警
dataHex = dataHex + highSpeedNeutralGear
if ("oilExpendNotSurport" in data.keys()):
oilExpendNotSurport = "010B" +self.int2hexStringByBytes(0) #油耗不支持报警
dataHex = dataHex + oilExpendNotSurport
if ("OBDNotSurport" in data.keys()):
OBDNotSurport = "010C" + self.int2hexStringByBytes(0) #OBD 不支持报警
dataHex = dataHex + OBDNotSurport
if ("lowWaterTemperatureHighSpeed" in data.keys()):
lowWaterTemperatureHighSpeed = "010D" +self.int2hexStringByBytes(0) #低水温高转速
dataHex = dataHex + lowWaterTemperatureHighSpeed
if ("buslineNotSleep" in data.keys()):
buslineNotSleep = "010E" + self.int2hexStringByBytes(0) #总线不睡眠报警
dataHex = dataHex + buslineNotSleep
if ("illegalOpenDoor" in data.keys()):
illegalOpenDoor = "010f" + self.int2hexStringByBytes(0) #非法开门
dataHex = dataHex + illegalOpenDoor
if ("illegalFire" in data.keys()):
illegalFire = "0110" + self.int2hexStringByBytes(0) #非法点火
dataHex = dataHex + illegalFire
if ("rapidAccelerateAlarm" in data.keys()):
rapidAccelerateAlarm = "0111" + self.int2hexStringByBytes(0) #急加速报警
dataHex = dataHex + rapidAccelerateAlarm
if ("sharpSlowdownAlarm" in data.keys()):
sharpSlowdownAlarm = "0112" + self.int2hexStringByBytes(0) #急减速报警
dataHex = dataHex + sharpSlowdownAlarm
if ("sharpBendAlarm" in data.keys()):
sharpBendAlarm = "0113" + self.int2hexStringByBytes(0) #急左拐弯报警
dataHex = dataHex + sharpBendAlarm
if ("crashAlarm" in data.keys()):
crashAlarm = "0114" + self.int2hexStringByBytes(0) #碰撞报警
dataHex = dataHex + crashAlarm
if ("rapidChangeLines" in data.keys()):
rapidChangeLines = "0115" + self.int2hexStringByBytes(0) #急变道报警
dataHex = dataHex + rapidChangeLines
if ("sharpRightBendAlarm" in data.keys()):
sharpBendAlarm = "0117" + self.int2hexStringByBytes(0) #急右拐弯报警
dataHex = dataHex + sharpBendAlarm
return dataHex
# 创建报警事件数据,数据随机产生
def generateAlarmEvent_data_random(self):
data = ""
ignition = "0001" + self.int2hexStringByBytes(0) #点火上报
flameout = "0002" + self.int2hexStringByBytes(0) #熄火上报
setUpDefences = "0003" + self.int2hexStringByBytes(0) #设防上报
withdrawGarrision = "0004" + self.int2hexStringByBytes(0) #撤防上报
doorOpen = "0005" + self.int2hexStringByBytes(0) #车门打开
doorClose = "0006" + self.int2hexStringByBytes(0) #车门关闭
systemStart = "0007" + self.int2hexStringByBytes(0) #系统启动
trailCarAlarm = "0101" + self.int2hexStringByBytes(0) #拖车报警
locationTooLong = "0102" + self.int2hexStringByBytes(0) #定位过长报警
terminalPullOut = "0103" + self.int2hexStringByBytes(0) #终端拔出报警
terminalInsert = "0104" + self.int2hexStringByBytes(0) #终端插入报警
lowVoltage = "0105" + self.int2hexStringByBytes(0) #低电压报警
#怠速过长报警 附带信息见 表 C6EXT1
idlingSpeedOver = "0106" + self.int2hexStringByBytes(9) + self.getIdlingSpeedOver_random()
#超速报警 附带信息见 表 C6EXT2
overspeedAlarm = "0107" + self.int2hexStringByBytes(9) + self.getOverspeedAlarm_random()
#疲劳驾驶报警 附带信息见 表 C6EXT3
fatigueDriving = "0108" + self.int2hexStringByBytes(5) + self.getFatigueDriving_random()
#水温报警 附带信息见 表 C6EXT4
waterTemperatureAlarm = "0109" + self.int2hexStringByBytes(9) + self.getWaterTemperatureAlarm_random()
highSpeedNeutralGear = "010A" + self.int2hexStringByBytes(0) #高速空档滑行报警
oilExpendNotSurport = "010B" +self.int2hexStringByBytes(0) #油耗不支持报警
OBDNotSurport = "010C" + self.int2hexStringByBytes(0) #OBD 不支持报警
lowWaterTemperatureHighSpeed = "010D" +self.int2hexStringByBytes(0) #低水温高转速
buslineNotSleep = "010E" + self.int2hexStringByBytes(0) #总线不睡眠报警
illegalOpenDoor = "010f" + self.int2hexStringByBytes(0) #非法开门
illegalFire = "0110" + self.int2hexStringByBytes(0) #非法点火
rapidAccelerateAlarm = "0111" + self.int2hexStringByBytes(0) #急加速报警
sharpSlowdownAlarm = "0112" + self.int2hexStringByBytes(0) #急减速报警
sharpBendAlarm = "0113" + self.int2hexStringByBytes(0) #急左拐弯报警
crashAlarm = "0114" + self.int2hexStringByBytes(0) #碰撞报警
rapidChangeLines = "0115" + self.int2hexStringByBytes(0) #急变道报警
sharpRightBendAlarm = "0117" + self.int2hexStringByBytes(0) #急右拐弯报警
arr = []
arr.append(ignition)
arr.append(flameout)
arr.append(setUpDefences)
arr.append(withdrawGarrision)
arr.append(doorOpen)
arr.append(doorClose)
arr.append(systemStart)
arr.append(trailCarAlarm)
arr.append(locationTooLong)
arr.append(terminalPullOut)
arr.append(terminalInsert)
arr.append(lowVoltage)
arr.append(idlingSpeedOver)
arr.append(overspeedAlarm)
arr.append(fatigueDriving)
arr.append(waterTemperatureAlarm)
arr.append(highSpeedNeutralGear)
arr.append(oilExpendNotSurport)
arr.append(OBDNotSurport)
arr.append(lowWaterTemperatureHighSpeed)
arr.append(buslineNotSleep)
arr.append(illegalOpenDoor)
arr.append(illegalFire)
arr.append(rapidAccelerateAlarm)
arr.append(sharpSlowdownAlarm)
arr.append(sharpBendAlarm)
arr.append(crashAlarm)
arr.append(rapidChangeLines)
arr.append(sharpRightBendAlarm)
mult = self.getRandomNum(0, 29)
temp = []
for i in range(0, mult):
con = self.getRandomNum(intArr=arr, mult=1)
if con in temp:
con = ""
temp.append(con)
data = data + con
return data
#####################################################
# 获取怠速过长附带信息
#####################################################
def getIdlingSpeedOver(self):
#报警属性 1:报警触发(无下面的数据内容项)0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(1)
#怠速持续时间 怠速持续的时间(含报警前的预判时间),单位为秒
idlingTimeOfDuration = self.int2hexStringByBytes(600,2)
#怠速耗油量 单位 mL
idlingOilExpend = self.int2hexStringByBytes(1200,2)
#怠速最高转速 单位 RPM
idlingEngineMaxSpeed = self.int2hexStringByBytes(5000,2)
#怠速最低转速 单位 RPM
idlingEngineMinSpeed = self.int2hexStringByBytes(500,2)
data = alarmType + idlingTimeOfDuration + idlingOilExpend + idlingEngineMaxSpeed + idlingEngineMinSpeed
return data
def getIdlingSpeedOver_GUI(self,data):
#报警属性 1:报警触发(无下面的数据内容项)0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(int(data["alarmType"]))
#怠速持续时间 怠速持续的时间(含报警前的预判时间),单位为秒
idlingTimeOfDuration = self.int2hexStringByBytes(int(data["idlingTimeOfDuration"]),2)
#怠速耗油量 单位 mL
idlingOilExpend = self.int2hexStringByBytes(int(data["idlingOilExpend"]),2)
#怠速最高转速 单位 RPM
idlingEngineMaxSpeed = self.int2hexStringByBytes(int(data["idlingEngineMaxSpeed"]),2)
#怠速最低转速 单位 RPM
idlingEngineMinSpeed = self.int2hexStringByBytes(int(data["idlingEngineMinSpeed"]),2)
data = alarmType + idlingTimeOfDuration + idlingOilExpend + idlingEngineMaxSpeed + idlingEngineMinSpeed
return data
def getIdlingSpeedOver_random(self):
#报警属性 1:报警触发(无下面的数据内容项)0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
#怠速持续时间 怠速持续的时间(含报警前的预判时间),单位为秒
idlingTimeOfDuration = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#怠速耗油量 单位 mL
idlingOilExpend = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#怠速最高转速 单位 RPM
idlingEngineMaxSpeed = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#怠速最低转速 单位 RPM
idlingEngineMinSpeed = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
data = alarmType + idlingTimeOfDuration + idlingOilExpend + idlingEngineMaxSpeed + idlingEngineMinSpeed
return data
#####################################################
# 获取超速报警信息
#####################################################
def getOverspeedAlarm(self):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(0)
#超速持续时间 2 WORD 怠速持续的时间(含报警前的预判时间),单位为秒
overspeedTimeOfDuration = self.int2hexStringByBytes(700,2)
#最高车速 2 WORD 单位 0.1KM/H
maxSpeed = self.int2hexStringByBytes(145,2)
#平均车速 2 WORD 单位 0.1KM/H
averageSpeed = self.int2hexStringByBytes(70,2)
#超速行驶距离 2 WORD 单位米
overspeedDistance = self.int2hexStringByBytes(10000,2)
data = alarmType + overspeedTimeOfDuration + maxSpeed + averageSpeed + overspeedDistance
return data
def getOverspeedAlarm_GUI(self,data):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(int(data["alarmType"]))
#超速持续时间 2 WORD 怠速持续的时间(含报警前的预判时间),单位为秒
overspeedTimeOfDuration = self.int2hexStringByBytes(int(data["overspeedTimeOfDuration"]),2)
#最高车速 2 WORD 单位 0.1KM/H
maxSpeed = self.int2hexStringByBytes(int(data["maxSpeed"]),2)
#平均车速 2 WORD 单位 0.1KM/H
averageSpeed = self.int2hexStringByBytes(int(data["averageSpeed"]),2)
#超速行驶距离 2 WORD 单位米
overspeedDistance = self.int2hexStringByBytes(int(data["overspeedDistance"]),2)
data = alarmType + overspeedTimeOfDuration + maxSpeed + averageSpeed + overspeedDistance
return data
def getOverspeedAlarm_random(self):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
#超速持续时间 2 WORD 怠速持续的时间(含报警前的预判时间),单位为秒
overspeedTimeOfDuration = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#最高车速 2 WORD 单位 0.1KM/H
maxSpeed = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#平均车速 2 WORD 单位 0.1KM/H
averageSpeed = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#超速行驶距离 2 WORD 单位米
overspeedDistance = self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
data = alarmType + overspeedTimeOfDuration + maxSpeed + averageSpeed + overspeedDistance
return data
#####################################################
# 获取疲劳驾驶报警附带信息
#####################################################
def getFatigueDriving(self):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(0)
#累计持续驾驶时间 4 DWORD 车辆点火行驶到报警解除的累计行驶时间,单位为秒
totalContinueDrivingTime = self.int2hexStringByBytes(21000,4)
data = alarmType + totalContinueDrivingTime
return data
def getFatigueDriving_GUI(self,data):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(int(data["alarmType"]))
#累计持续驾驶时间 4 DWORD 车辆点火行驶到报警解除的累计行驶时间,单位为秒
totalContinueDrivingTime = self.int2hexStringByBytes(int(data["totalContinueDrivingTime"]),4)
data = alarmType + totalContinueDrivingTime
return data
def getFatigueDriving_random(self):
#报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
#累计持续驾驶时间 4 DWORD 车辆点火行驶到报警解除的累计行驶时间,单位为秒
totalContinueDrivingTime = self.int2hexStringByBytes(self.getRandomNum(0,2147483648),4)
data = alarmType + totalContinueDrivingTime
return data
#####################################################
# 获取水温报警附带信息
#####################################################
def getWaterTemperatureAlarm(self):
# 报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(1)
# 持续时长 4 DWORD 单位秒
timeOfDuration = self.int2hexStringByBytes(11000,4)
# 最高温度 2 WORD 单位 0.1 度
maxTemperature = self.int2hexStringByBytes(700,2)
# 平均温度 2 WORD 单位 0.1 度
averageTemperature = self.int2hexStringByBytes(55,2)
data = alarmType + timeOfDuration + maxTemperature + averageTemperature
return data
def getWaterTemperatureAlarm_GUI(self,data):
# 报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(int(data["alarmType"]))
# 持续时长 4 DWORD 单位秒
timeOfDuration = self.int2hexStringByBytes(int(data["timeOfDuration"]),4)
# 最高温度 2 WORD 单位 0.1 度
maxTemperature = self.int2hexStringByBytes(int(data["maxTemperature"]),2)
# 平均温度 2 WORD 单位 0.1 度
averageTemperature = self.int2hexStringByBytes(int(data["averageTemperature"]),2)
data = alarmType + timeOfDuration + maxTemperature + averageTemperature
return data
def getWaterTemperatureAlarm_random(self):
# 报警属性 1 BYTE 1:报警触发(无下面的数据内容项) 0:报警解除(有下面的数据内容项)
alarmType = self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
# 持续时长 4 DWORD 单位秒
timeOfDuration = self.int2hexStringByBytes(self.getRandomNum(0,2147483648),4)
# 最高温度 2 WORD 单位 0.1 度
maxTemperature = self.int2hexStringByBytes(self.getRandomNum(0,2500),2)
# 平均温度 2 WORD 单位 0.1 度
averageTemperature = self.int2hexStringByBytes(self.getRandomNum(0,1500),2)
data = alarmType + timeOfDuration + maxTemperature + averageTemperature
return data
if __name__ == "__main__":
print(AlarmEvent_data().generateAlarmEvent_data())
#encoding:utf-8
'''
定义安防状态信息
'''
from lib.protocol.message.MessageBase import MessageBase
class CarSafeStatusInfo(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建安防状态数据
#####################################################
def generateSecurityStatusData(self):
data = ""
statusCode = "ffffffffffffffffffff" #状态掩码
securityStatus = self.getSecurityStatusHex() #安全状态
doorStatus = self.getDoorStatusHex() #门状态
lockStatus = self.getLockStatusHex() #锁状态
windowStatus = self.getWindowStatusHex() #窗户状态
lightStatus = self.getLightStatusHex() #灯光状态
onoffStatusA = self.getOnoffStatusAHex() #开关状态A
onoffStatusB = self.getOnoffStatusBHex() #开关状态B
retain1 = "00" #预留
retain2 = "00" #预留
retain3 = "00" # 预留
data = data + statusCode + securityStatus + doorStatus + lockStatus + windowStatus + lightStatus + onoffStatusA + onoffStatusB + retain1 + retain2 + retain3
return data
def generateSecurityStatusData_GUI(self,data):
dataHex = ""
statusCode = data["statusCode"] #状态掩码
securityStatus = self.int2hexStringByBytes(int(data["securityStatus"])) #安全状态
doorStatus = self.int2hexStringByBytes(int(data["doorStatus"])) #门状态
lockStatus = self.int2hexStringByBytes(int(data["lockStatus"])) #锁状态
windowStatus = self.int2hexStringByBytes(int(data["windowStatus"])) #窗户状态
lightStatus = self.int2hexStringByBytes(int(data["lightStatus"])) #灯光状态
onoffStatusA = self.int2hexStringByBytes(int(data["onoffStatusA"])) #开关状态A
onoffStatusB = self.int2hexStringByBytes(int(data["onoffStatusB"])) #开关状态B
retain1 = "00" #预留
retain2 = "00" #预留
retain3 = "00" # 预留
dataHex = dataHex + statusCode + securityStatus + doorStatus + lockStatus + windowStatus + lightStatus + onoffStatusA + onoffStatusB + retain1 + retain2 + retain3
return dataHex
#创建安防状态数据,数据随机产生
def generateSecurityStatusData_random(self):
data = ""
statusCode = "ffffffffffffffffffff" #状态掩码
securityStatus = self.getSecurityStatusHex_random() #安全状态
doorStatus = self.getDoorStatusHex_random() #门状态
lockStatus = self.getLockStatusHex_random() #锁状态
windowStatus = self.getWindowStatusHex_random() #窗户状态
lightStatus = self.getLightStatusHex_random() #灯光状态
onoffStatusA = self.getOnoffStatusAHex_random() #开关状态A
onoffStatusB = self.getOnoffStatusBHex_random() #开关状态B
retain1 = "00" #预留
retain2 = "00" #预留
retain3 = "00" # 预留
data = data + statusCode + securityStatus + doorStatus + lockStatus + windowStatus + lightStatus + onoffStatusA + onoffStatusB + retain1 + retain2 + retain3
return data
#####################################################
# 获取安全状态16进制数据
# 按照高位在前,低位在后的规则
#####################################################
def getSecurityStatusHex(self):
accStatus = 0 #acc状态,1:开 0:关
defenseStatus = 0 #设防撤防状态,2:设防 0:撤防
brakeStatus = 0 #脚刹状态,4:踩下 0:松开
acceleratorStatus = 0 #是否踩油门,8:踩下 0:松开
handBrakeStatus = 0 #手刹状态,16:拉起手刹 0:松开手刹
mainSafetyBelt = 0 #主驾驶安全带,32:插入安全带 0:松开安全带
subSafetyBelt = 0 #副驾驶安全带,64:插入安全带 0:松开安全带
retain = 0 #预留字段
val = accStatus +defenseStatus +brakeStatus +acceleratorStatus + handBrakeStatus + mainSafetyBelt + subSafetyBelt + retain
hexData = self.int2hexStringByBytes(val)
return hexData
def getSecurityStatusHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8,16,32,64],mult=7)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取门状态16进制数据
#####################################################
def getDoorStatusHex(self):
lfDoorStatus = 0 #左前门,1,:开 0:关
rfDoorStatus = 0 #右前门,2:开 0:关
lbDoorStatus = 0 #左后门,4:开 0:关
rbDoorStatus = 0 #右后门,8:开 0:关
trunk = 0 #后备箱,16:开 0:关
enginCover = 0 #发动机盖:32:开 0:关
retain1 = 0 #预留字段
retain2 = 0 #预留字段
val = lfDoorStatus + rfDoorStatus + lbDoorStatus +rbDoorStatus + trunk + enginCover + retain1 +retain2
hexData = self.int2hexStringByBytes(val)
return hexData
def getDoorStatusHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8,16,32],mult=6)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取锁状态16进制数据
#####################################################
def getLockStatusHex(self):
lfDoorLockStatus = 0 #左前门锁状态,1:开 0:关
rfDoorLockStatus = 0 #右前门锁状态,2:开 0:关
lbDoorLockStatus = 0 #左后门锁状态,4:开 0:关
rbDoorLockStatus = 0 #右后门锁状态,8:开 0:关
retain1 = 0
retain2 = 0
retain3 = 0
retain4 = 0
val = lfDoorLockStatus + rfDoorLockStatus + lbDoorLockStatus + rbDoorLockStatus + retain1 +retain2 + retain3 +retain4
hexData = self.int2hexStringByBytes(val)
return hexData
def getLockStatusHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8],mult=4)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取窗户状态16进制数据
#####################################################
def getWindowStatusHex(self):
lfWindowStatus = 0 #左前窗,1:开 0:关
rfWindowStatus = 0 #右前窗,2:开 0:关
lbWindowStatus = 0 # 左后窗,4:开 0:关
rbWindowStatus = 0 # 右后窗,8:开 0:关
topWindowStatus = 0 #天窗开关,16:开 0:关
lTurnLight = 0 #左转向灯,32:开 0:关
rTurnLight = 0 #右转向灯,64:开 0:关
readLight = 0 #阅读灯,128:开 0:关
val = lfWindowStatus + rfWindowStatus + lbWindowStatus + rbWindowStatus + topWindowStatus + lTurnLight + rTurnLight + readLight
hexData = self.int2hexStringByBytes(val)
return hexData
def getWindowStatusHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8,16,32,64,128],mult=8)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取灯光状态16进制数据
#####################################################
def getLightStatusHex(self):
lowHeadlight = 0 #近光灯,1:开 0:关
highHeadlight = 0 #远光灯,2:开 0:关
ffogLight = 0 #前雾灯,4:开 0:关
bfogLight = 0 #后雾灯,8:开 0:关
dangerLight = 0 #危险灯,16:开 0:关
backCarLight = 0 #倒车灯,32:开 0:关
autoLight = 0 #auto灯,64:开 0:关
widthLight = 0 #示宽灯,128:开 0:关
val = lowHeadlight + highHeadlight + ffogLight + bfogLight + dangerLight + backCarLight + autoLight + widthLight
hexData = self.int2hexStringByBytes(val)
return hexData
def getLightStatusHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8,16,32,64,128],mult=8)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取开关状态A16进制数据
#####################################################
def getOnoffStatusAHex(self):
machineOilWarning = 0 #机油报警,1:开 0:关
oilWarning = 0 #燃油报警,2:开 0:关
wiperWarning = 0 #雨刷报警,4:开 0:关
loudsspeakerWaring = 0 #喇叭报警,8:开 0:关
airConditionerWaring = 0 #空调,16:开 0:关
backMirrorWaring = 0 #后视镜状态:32开 0:关
retain1 = 0
retain2 = 0
val = machineOilWarning + oilWarning + wiperWarning + loudsspeakerWaring + airConditionerWaring + backMirrorWaring + retain1 + retain2
hexData = self.int2hexStringByBytes(val)
return hexData
def getOnoffStatusAHex_random(self):
val = self.getRandomNum(intArr=[0,1,2,4,8,16,32],mult=6)
hexData = self.int2hexStringByBytes(val)
return hexData
#####################################################
# 获取开关状态B16进制数据
#####################################################
def getOnoffStatusBHex(self):
retain1 = 0
retain2 = 0
retain3 = 0
retain4 = 0
#档位,0:p 16:R 32:N 48:D 64:1挡 80:2挡 96:3挡 112:4挡 128:5挡 144:6挡 160:M挡 176:S挡
gears = 0
val = retain1 + retain2 + retain3 + retain4 + gears
hexData = self.int2hexStringByBytes(val)
return hexData
def getOnoffStatusBHex_random(self):
val = self.getRandomNum(intArr=[0,16,32,48,64,80,96,112,128,144,160,176])
hexData = self.int2hexStringByBytes(val)
return hexData
\ No newline at end of file
#encoding:utf-8
'''
定义外设数据项
'''
from lib.protocol.message.MessageBase import MessageBase
class Circum_data(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建轿车OBD数据
#####################################################
def generateCircum_data(self):
data = ""
data_1 = "3001" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(20)
data_2 = "3002" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(21)
data = data_1 + data_2
return data
\ No newline at end of file
#encoding:utf-8
'''
定义新能源车 OBD 数据
'''
from lib.protocol.message.MessageBase import MessageBase
class NewEnergyCar_data(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建轿车OBD数据
#####################################################
def generateNewEnergyCar_data(self):
data = ""
#续航里程 , 0.1km 显示值为上传值/10
enduranceMileage = "7001" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(22000,4)
#剩余电量 , 0% - 100%
surplusPower = "7002" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(55)
#车速 , Km/h 0 - 240
speed = "7003" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(74)
#充电状态
#0x0: 初始值
# 0x1: 未充电
# 0x2: 交流充电中
# 0x3: 直流充电中
# 0x4: 充电完成 0x5: Void 0x6: Void 0x7: 无效值
chargeStatus = "7004" + self.int2hexStringByBytes(1) + "01"
#充电桩状态 , 0x01:插入 0x00:未插入
chargingPileStatus = "7005" + self.int2hexStringByBytes(1) + "00"
#动力电池充放电电流 0.01A 0x0-0xFFFF
batteryStream = "7006" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(30,2)
#单体电芯最高电压 0.001V 0x0-0xFFFF
batteryMaxVoltage_1 = "7007" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(7000,2)
# 单体电芯最高电压 0.001V 0x0-0xFFFF
batteryMaxVoltage_2 = "7008" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(7000, 2)
#驱动电机当前转速 Rpm
electromotorSpeed = "7009" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(5000,2)
#驱动电机当前转矩 Nm
electromotorTorque = "700a" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(2000,2)
#驱动电机当前温度 C 上传值减去 40
electromotorTemperature = "700b" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(90)
#直流母线电压 0.001V 0x0-0xFFFF
DCBusVotage = "700c" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(3000,2)
#直流母线电流 0.01A 0x0-0xFFFF
DCBusStream = "700d" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(36,2)
#动力电池可用能量 0.01Kwh 0x0-0xFFFF
batteryAvailablePower = "700e" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(30000,2)
#1 号单体电池电压 V
batteryVotage_1 = "7021" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_2 = "7022" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_3 = "7023" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_4 = "7024" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_5 = "7025" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_6 = "7026" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_7 = "7027" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_8 = "7028" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_9 = "7029" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
batteryVotage_10 = "702A" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(6)
data = data + enduranceMileage + surplusPower + speed + chargeStatus + chargingPileStatus
data = data + batteryStream + batteryMaxVoltage_1 + batteryMaxVoltage_2 + electromotorSpeed + electromotorTorque
data = data + electromotorTemperature + DCBusVotage + DCBusStream + batteryAvailablePower + batteryVotage_1
data = data + batteryVotage_2 + batteryVotage_3 + batteryVotage_4 + batteryVotage_5 + batteryVotage_6
data = data + batteryVotage_7 + batteryVotage_8 + batteryVotage_9 + batteryVotage_10
return data
if __name__ == "__main__":
print(NewEnergyCar_data().generateNewEnergyCar_data())
\ No newline at end of file
#encoding:utf-8
'''
定义轿车OBD数据
'''
from lib.protocol.message.MessageBase import MessageBase
class SaloonCarOBD_data(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建轿车OBD数据
#####################################################
def generateSaloonCarOBDData(self):
data = ""
#发动机转速 , 0 - 8000 rpm
engineSpeed = "60C0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(3000,2)
#车速 , 0 - 240 Km/h
carSpeed = "60D0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(60)
#剩余油量 ,剩余油量,单位 L 或%Bit15=0 百分比%,OBD 都为百分比Bit15=1 单位 L,显示值为上传值/10
surplusOil = "62f0" + self.int2hexStringByBytes(2) + self.getSurplusOil()
#冷却液温度 ,-40.0℃ 到 +210℃,上传值减去 40
coolingLiquidTemperature = "6050" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(76)
#进气口温度 ,-40.0℃ 到 +210℃,上传值减去 40
airInletTemperature = "60F0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(88)
#进气(岐管绝对)压力 , 0 - 250kpa
intakeManifoldPressure = "60B0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(20)
#大气压力 , 0 - 125kpa
atmosphericPressure = "6330" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(28)
#环境温度 , -40.0℃ 到 +210℃,上传值减去 40
envTemperature = "6460" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(65)
#加速踏板位置 , 0% - 100%
acceleratorLocation = "6490" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(32)
#燃油压力 , 0 - 500kpa
oilPressure = "60A0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(276,2)
#故障码状态 , 发动机故障码状态
troubleCodeStatus = "6014" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(0)
#故障码个数
troubleCodeNum = "6010" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(2)
#空气流量 , 0.1 实际值为上传值/10 0.1g/s
airFlow = "6100" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(550,2)
#绝对气门位置
valveLocation = "6110" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(51,2)
#自发动机启动运行时间 sec
engineRunTime = "61F0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(3700,2)
#故障行驶里程 , Km
troubleMileage = "6210" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(4508,4)
#计算负荷值
calculateLoadValue = "6040" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(44)
#长期燃油修正(气缸列 1 和 3)
fuelTrim = "6070" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(89,2)
#第一缸点火正时提前角 ,显示值为上传值-64
fireAngle = "60E0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(154,2)
#前刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
frontBrakeBlockAbrasion = "6701" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(0)
#后刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
backBrakeBlockAbrasion = "6702" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(0)
#制动液液位 , 0:不正 1:正常 其他:无法使用
brakeFluidLocation = "6703" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(1)
#机油液位 , 显示值为上传值/1000 单位 毫米
engineOilLocation = "6704" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(20000,2)
#胎压报警 0:当前无警告 1:存在胎压失压 其他:不可用
tirePressureAlarm = "6705" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(0,2)
#冷却液液位 , 显示值为上传值-48
coolingLiquidLocation = "6706" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(65,2)
#续航里程 0.1 km ; 显示值为上传值/10
enduranceMileage = "6707" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(382,4)
#仪表里程
dashboardMileage = "6708" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3500,4)
#车辆总运行时间
runTotalTime = "6709" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(7200000,4)
#总耗油量
totalOilExpend = "670a" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3700000,4)
#OBD 累计里程,不支持 OBD 时,为基于 GPS 车速统计的车辆累计行驶总里程
OBDTotalMileage = "670b" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(123000,4)
data = data + engineSpeed + carSpeed + surplusOil + coolingLiquidTemperature + airInletTemperature
data = data + intakeManifoldPressure + atmosphericPressure + envTemperature + acceleratorLocation + oilPressure
data = data + troubleCodeStatus + troubleCodeNum + airFlow + valveLocation + engineRunTime
data = data + troubleMileage + calculateLoadValue + fuelTrim + fireAngle + frontBrakeBlockAbrasion
data = data + backBrakeBlockAbrasion + brakeFluidLocation + engineOilLocation + tirePressureAlarm + coolingLiquidLocation
data = data + enduranceMileage + dashboardMileage + runTotalTime + totalOilExpend + OBDTotalMileage
return data
def generateSaloonCarOBDData_GUI(self,data):
dataHex = ""
if ("60C0" in data.keys()):
#发动机转速 , 0 - 8000 rpm
engineSpeed = "60C0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["60C0"]),2)
dataHex = dataHex + engineSpeed
if ("60D0" in data.keys()):
#车速 , 0 - 240 Km/h
carSpeed = "60D0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["60D0"]))
dataHex = dataHex + carSpeed
if ("62f0" in data.keys()):
#剩余油量 ,剩余油量,单位 L 或%Bit15=0 百分比%,OBD 都为百分比Bit15=1 单位 L,显示值为上传值/10
surplusOil = "62f0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["62f0"]),2)
dataHex = dataHex + surplusOil
if ("6050" in data.keys()):
#冷却液温度 ,-40.0℃ 到 +210℃,上传值减去 40
coolingLiquidTemperature = "6050" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6050"]))
dataHex = dataHex + coolingLiquidTemperature
if ("60F0" in data.keys()):
#进气口温度 ,-40.0℃ 到 +210℃,上传值减去 40
airInletTemperature = "60F0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["60F0"]))
dataHex = dataHex + airInletTemperature
if ("60B0" in data.keys()):
#进气(岐管绝对)压力 , 0 - 250kpa
intakeManifoldPressure = "60B0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["60B0"]))
dataHex = dataHex + intakeManifoldPressure
if ("6330" in data.keys()):
#大气压力 , 0 - 125kpa
atmosphericPressure = "6330" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6330"]))
dataHex = dataHex + atmosphericPressure
if ("6460" in data.keys()):
#环境温度 , -40.0℃ 到 +210℃,上传值减去 40
envTemperature = "6460" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6460"]))
dataHex = dataHex + envTemperature
if ("6490" in data.keys()):
#加速踏板位置 , 0% - 100%
acceleratorLocation = "6490" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6490"]))
dataHex = dataHex + acceleratorLocation
if ("60A0" in data.keys()):
#燃油压力 , 0 - 500kpa
oilPressure = "60A0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["60A0"]),2)
dataHex = dataHex + oilPressure
if ("6014" in data.keys()):
#故障码状态 , 发动机故障码状态
troubleCodeStatus = "6014" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6014"]))
dataHex = dataHex + troubleCodeStatus
if ("6010" in data.keys()):
#故障码个数
troubleCodeNum = "6010" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6010"]))
dataHex = dataHex + troubleCodeNum
if ("6100" in data.keys()):
#空气流量 , 0.1 实际值为上传值/10 0.1g/s
airFlow = "6100" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6100"]),2)
dataHex = dataHex + airFlow
if ("6110" in data.keys()):
#绝对气门位置
valveLocation = "6110" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6110"]),2)
dataHex = dataHex + valveLocation
if ("61F0" in data.keys()):
#自发动机启动运行时间 sec
engineRunTime = "61F0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["61F0"]),2)
dataHex = dataHex + engineRunTime
if ("6210" in data.keys()):
#故障行驶里程 , Km
troubleMileage = "6210" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["6210"]),4)
dataHex = dataHex + troubleMileage
if ("6040" in data.keys()):
#计算负荷值
calculateLoadValue = "6040" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6040"]))
dataHex = dataHex + calculateLoadValue
if ("6070" in data.keys()):
#长期燃油修正(气缸列 1 和 3)
fuelTrim = "6070" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6070"]),2)
dataHex = dataHex + fuelTrim
if ("60E0" in data.keys()):
#第一缸点火正时提前角 ,显示值为上传值-64
fireAngle = "60E0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["60E0"]),2)
dataHex = dataHex + fireAngle
if ("6701" in data.keys()):
#前刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
frontBrakeBlockAbrasion = "6701" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6701"]))
dataHex = dataHex + frontBrakeBlockAbrasion
if ("6702" in data.keys()):
#后刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
backBrakeBlockAbrasion = "6702" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6702"]))
dataHex = dataHex + backBrakeBlockAbrasion
if ("6703" in data.keys()):
#制动液液位 , 0:不正 1:正常 其他:无法使用
brakeFluidLocation = "6703" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(int(data["6703"]))
dataHex = dataHex + brakeFluidLocation
if ("6704" in data.keys()):
#机油液位 , 显示值为上传值/1000 单位 毫米
engineOilLocation = "6704" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6704"]),2)
dataHex = dataHex + engineOilLocation
if ("6705" in data.keys()):
#胎压报警 0:当前无警告 1:存在胎压失压 其他:不可用
tirePressureAlarm = "6705" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6705"]),2)
dataHex = dataHex + tirePressureAlarm
if ("6706" in data.keys()):
#冷却液液位 , 显示值为上传值-48
coolingLiquidLocation = "6706" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(int(data["6706"]),2)
dataHex = dataHex + coolingLiquidLocation
if ("6707" in data.keys()):
#续航里程 0.1 km ; 显示值为上传值/10
enduranceMileage = "6707" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["6707"]),4)
dataHex = dataHex + enduranceMileage
if ("6708" in data.keys()):
#仪表里程
dashboardMileage = "6708" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["6708"]),4)
dataHex = dataHex + dashboardMileage
if ("6709" in data.keys()):
#车辆总运行时间
runTotalTime = "6709" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["6709"]),4)
dataHex = dataHex + runTotalTime
if ("670a" in data.keys()):
#总耗油量
totalOilExpend = "670a" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["670a"]),4)
dataHex = dataHex + totalOilExpend
if ("670b" in data.keys()):
#OBD 累计里程
OBDTotalMileage = "670b" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(int(data["670b"]),4)
dataHex = dataHex + OBDTotalMileage
return dataHex
def generateSaloonCarOBDData_random(self):
data = ""
#发动机转速 , 0 - 8000 rpm
engineSpeed = "60C0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,8000),2)
#车速 , 0 - 240 Km/h
carSpeed = "60D0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,240))
#剩余油量 ,剩余油量,单位 L 或%Bit15=0 百分比%,OBD 都为百分比Bit15=1 单位 L,显示值为上传值/10
surplusOil = "62f0" + self.int2hexStringByBytes(2) + self.getSurplusOil_random()
#冷却液温度 ,-40.0℃ 到 +210℃,上传值减去 40
coolingLiquidTemperature = "6050" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,250))
#进气口温度 ,-40.0℃ 到 +210℃,上传值减去 40
airInletTemperature = "60F0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,250))
#进气(岐管绝对)压力 , 0 - 250kpa
intakeManifoldPressure = "60B0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,250))
#大气压力 , 0 - 125kpa
atmosphericPressure = "6330" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,125))
#环境温度 , -40.0℃ 到 +210℃,上传值减去 40
envTemperature = "6460" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,250))
#加速踏板位置 , 0% - 100%
acceleratorLocation = "6490" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,100))
#燃油压力 , 0 - 500kpa
oilPressure = "60A0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,500),2)
#故障码状态 , 发动机故障码状态
troubleCodeStatus = "6014" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
#故障码个数
troubleCodeNum = "6010" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
#空气流量 , 0.1 实际值为上传值/10 0.1g/s
airFlow = "6100" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#绝对气门位置
valveLocation = "6110" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#自发动机启动运行时间 sec
engineRunTime = "61F0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#故障行驶里程 , Km
troubleMileage = "6210" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,2147483648),4)
#计算负荷值
calculateLoadValue = "6040" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
#长期燃油修正(气缸列 1 和 3)
fuelTrim = "6070" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#第一缸点火正时提前角 ,显示值为上传值-64
fireAngle = "60E0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65435),2)
#前刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
frontBrakeBlockAbrasion = "6701" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
#后刹车片磨损 , 0 正常/否则,显示对应数据,单位:级
backBrakeBlockAbrasion = "6702" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(0,255))
#制动液液位 , 0:不正 1:正常 其他:无法使用
brakeFluidLocation = "6703" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]))
#机油液位 , 显示值为上传值/1000 单位 毫米
engineOilLocation = "6704" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65535),2)
#胎压报警 0:当前无警告 1:存在胎压失压 其他:不可用
tirePressureAlarm = "6705" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(intArr=[0,1]),2)
#冷却液液位 , 显示值为上传值-48
coolingLiquidLocation = "6706" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(self.getRandomNum(0,65435),2)
#续航里程 0.1 km ; 显示值为上传值/10
enduranceMileage = "6707" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,2147483648),4)
#仪表里程
dashboardMileage = "6708" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,3500),4)
#车辆总运行时间
runTotalTime = "6709" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,7200000),4)
#总耗油量
totalOilExpend = "670a" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0,3700000),4)
#OBD 累计里程
OBDTotalMileage = "670b" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(self.getRandomNum(0, 3700000), 4)
data = data + engineSpeed + carSpeed + surplusOil + coolingLiquidTemperature + airInletTemperature
data = data + intakeManifoldPressure + atmosphericPressure + envTemperature + acceleratorLocation + oilPressure
data = data + troubleCodeStatus + troubleCodeNum + airFlow + valveLocation + engineRunTime
data = data + troubleMileage + calculateLoadValue + fuelTrim + fireAngle + frontBrakeBlockAbrasion
data = data + backBrakeBlockAbrasion + brakeFluidLocation + engineOilLocation + tirePressureAlarm + coolingLiquidLocation
data = data + enduranceMileage + dashboardMileage + runTotalTime + totalOilExpend + OBDTotalMileage
return data
#####################################################
# 获取剩余油量
#####################################################
def getSurplusOil(self):
# 剩余油量 ,剩余油量,单位L或% ; Bit15=0 百分比%,OBD都为百分比 ;Bit15=1 单位 L,显示值为上传值/10 (32768)
units = 0
surplusOil = 801
data = units + surplusOil
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
def getSurplusOil_random(self):
# 剩余油量 ,剩余油量,单位L或% ; Bit15=0 百分比%,OBD都为百分比 ;Bit15=1 单位 L,显示值为上传值/10 (32768)
units = self.getRandomNum(intArr=[0,32768])
surplusOil = self.getRandomNum(0,16384)
data = units + surplusOil
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(SaloonCarOBD_data().generateSaloonCarOBDData())
\ No newline at end of file
#encoding:utf-8
'''
定义终端注销消息
'''
from lib.protocol.message.MessageBase import MessageBase
class TerminalCancle_msg(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0003"
msgBodyProperty = self.getMsgBodyProperty(len(self.getMsgBody())) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
subPkgContent = "" #消息包封装项
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
\ No newline at end of file
#encoding:utf-8
'''
定义轿车OBD数据
'''
from lib.protocol.message.MessageBase import MessageBase
class TruckCarOBD_data(MessageBase):
def __init__(self):
super().__init__()
pass
#####################################################
# 创建轿车OBD数据
#####################################################
def generateTruckCarOBD_data(self):
data = ""
#发动机转速 , 0 - 8000 rpm
engineSpeed = "60C0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(3000,2)
#车速 , 0 - 240 Km/h
carSpeed = "60D0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(60)
#剩余油量 ,剩余油量,单位 L 或%Bit15=0 百分比%,OBD 都为百分比Bit15=1 单位 L,显示值为上传值/10
surplusOil = "62f0" + self.int2hexStringByBytes(2) + self.getSurplusOil()
#冷却液温度 ,-40.0℃ 到 +210℃,上传值减去 40
coolingLiquidTemperature = "6050" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(76)
#进气口温度 ,-40.0℃ 到 +210℃,上传值减去 40
airInletTemperature = "60F0" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(88)
#进气(岐管绝对)压力 , 0 - 250kpa
intakeManifoldPressure = "60B0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(20)
#大气压力 , 0 - 125kpa
atmosphericPressure = "6330" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(28)
#环境温度 , -40.0℃ 到 +210℃,上传值减去 40
envTemperature = "6460" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(65)
#加速踏板位置 , 0% - 100%
acceleratorLocation = "6490" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(32)
#燃油压力 , 0 - 500kpa
oilPressure = "60A0" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(276,2)
#故障码个数
troubleCodeNum = "6010" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(2)
#OBD 离合器开关 ,0x00/0x01 关/开
clutchSwitch = "5001" + self.int2hexStringByBytes(1) + "01"
#OBD 制动刹车开关 , 0x00/0x01 关/开
brakeSwich = "5002" + self.int2hexStringByBytes(1) + "01"
#OBD 驻车刹车开关 , 0x00/0x01 关/开
parkingBrakeSwitch = "5003" + self.int2hexStringByBytes(1) + "01"
#OBD 节流阀位置 , 0% - 100%
throttleLocation = "5004" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(33)
#OBD 油料使用率 , 0 - 3212.75L/h
oilUsageRate = "5005" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(1000,2)
#OBD 燃油温度 , 起始值-273℃ 范围(-273 到+1735)
oilTemperature = "5006" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(299,2)
#OBD 机油温度 , 起始值-273℃ 范围(-273 到+1735)
engineOilTemperature = "5007" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(300,2)
#OBD 发动机润滑油压力 , 0 - 1000kpa
engineOilPresure = "5008" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(120)
#OBD 制动器踏板位置 , 0% - 100%
brekeLocation = "5009" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(31)
#OBD 空气流量 , 0.1 G/S
airFlow = "500A" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(800,2)
data = data + engineSpeed + carSpeed + surplusOil + coolingLiquidTemperature + airInletTemperature
data = data + intakeManifoldPressure + atmosphericPressure + envTemperature + acceleratorLocation + oilPressure
data = data + troubleCodeNum + clutchSwitch + brakeSwich + parkingBrakeSwitch + throttleLocation
data = data + oilUsageRate + oilTemperature + engineOilTemperature + engineOilPresure + brekeLocation
data = data + airFlow
return data
#####################################################
# 获取剩余油量
#####################################################
def getSurplusOil(self):
# 剩余油量 ,剩余油量,单位 L 或%Bit15=0 百分比%,OBD 都为百分比Bit15=1 单位 L,显示值为上传值/10 (32768)
units = 32768
surplusOil = 800
data = units + surplusOil
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
if __name__ == "__main__":
print(TruckCarOBD_data().generateTruckCarOBD_data())
\ No newline at end of file
#encoding:utf-8
'''
定义查询终端参数应答消息
'''
from lib.protocol.message.MessageBase import MessageBase
class QueryTerminalParam_res(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
resWaterCode = self.int2hexStringByBytes(1004,2) #应答流水号,对应的终端参数查询消息的流水号
resParamCounts = self.int2hexStringByBytes(10) #应答参数个数
paramList = self.getParamList() #参数项列表
msg = resWaterCode + paramList
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0104"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取参数项列表
#######################################################
def getParamList(self):
#终端心跳发送间隔,单位为秒(s)
param_0001 = "0001" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(10,4)
#TCP 消息应答超时时间,单位为秒(s)
param_0002 = "0002" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(10,4)
#TCP 消息重传次数
param_0003 = "0003" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(5,4)
#主服务器 APN,无线通信拨号访问点。若网络制式为 CDMA,则该处为 PPP 拨号号码
param_0010 = "0010" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("CDMA_0123")) / 2)) + self.GBKString2Hex("CDMA_0123")
#主服务器无线通信拨号用户名
param_0011 = "0011" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("user007")) / 2)) + self.GBKString2Hex("user007")
#主服务器无线通信拨号密码
param_0012 = "0012" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("password_123")) / 2)) + self.GBKString2Hex("password_123")
#主服务器地址,IP 或域名
param_0013 = "0013" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("www.test.com")) / 2)) + self.GBKString2Hex("www.test.com")
#备份服务器 APN,无线通信拨号访问点
param_0014 = "0014" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("192.168.1.3")) / 2)) + self.GBKString2Hex("192.168.1.3")
#备份服务器无线通信拨号用户名
param_0015 = "0015" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("user123")) / 2)) + self.GBKString2Hex("user123")
#备份服务器无线通信拨号密码
param_0016 = "0016" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("pass1234")) / 2)) + self.GBKString2Hex("pass1234")
#备份服务器地址,IP 或域名
param_0017 = "0017" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("www.test2.com")) / 2)) + self.GBKString2Hex("www.test2.com")
#服务器 TCP 端口/主服务器端口
param_0018 = "0018" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(53762,4)
#服务器 UDP 端口/备份服务器端口
param_0019 = "0019" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(53673,4)
#位置汇报策略,0:定时汇报;1:定距汇报;2:定时和定距汇报
param_0020 = "0020" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(0,4)
#休眠时汇报时间间隔,单位为秒(s),>0
param_0027 = "0027" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(20,4)
#缺省时间汇报间隔,单位为秒(s),>0
param_0029 = "0029" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(30,4)
#缺省距离汇报间隔,单位为米(m),>0
param_002C = "002C" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(1000,4)
#拐点补传角度,<180
param_0030 = "0030" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(60,4)
#电子围栏半径(非法位移阈值),单位为米
param_0031 = "0031" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(100,2)
#报警屏蔽字,与位置信息汇报消息中的报警标志相对应,相应位为 1 则相应报警被屏蔽
param_0050 = "0050" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(1,4)
#最高速度,单位为公里每小时(km/h)
param_0055 = "0055" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(240000,4)
#超速持续时间,单位为秒(s)
param_0056 = "0056" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(1200,4)
#连续驾驶时间门限,单位为秒(s)
param_0057 = "0057" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(18000,4)
#当天累计驾驶时间门限,单位为秒(s)
param_0058 = "0058" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(19000,4)
#最小休息时间,单位为秒(s)
param_0059 = "0059" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3600,4)
#最长停车时间,单位为秒(s)
param_005A = "005A" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(4800,4)
#超速报警预警差值,单位为 1/10Km/h
param_005B = "005B" + self.int2hexStringByBytes(2) +self.int2hexStringByBytes(50,2)
#疲劳驾驶预警差值,单位为秒(s),>0
param_005C = "005C" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(10,2)
#碰撞报警参数设置:
# b7-b0:碰撞时间,单位 4ms;
# b15-b8:碰撞加速度,单位 0.1g,设置范围在:0-79 之间,默认为 10
param_005D = "005D" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(10 + (30 + 255),2)
#侧翻报警参数设置:
# 侧翻角度,单位 1 度,默认为 30 度。
param_005E = "005E" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(30,2)
#车辆里程表读数,1/10km
param_0080 = "0080" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(320000,4)
#车辆所在的省域 ID
param_0081 = "0081" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(50,2)
#车辆所在的市域 ID
param_0082 = "0082" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(100,2)
#公安交通管理部门颁发的机动车号牌
param_0083 = "0083" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("CX3B")) / 2)) + self.GBKString2Hex("CX3B")
#车牌颜色,按照 JT/T415-2006 的 5.4.12 未上牌时,取值 为 0) 1:蓝色 2:黄色 3:黑色 4:白色 9:其他
param_0084 = "0084" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(1)
#GNSS 定位模式,定义如下:
#bit0,0:禁用 GPS 定位, 1:启用 GPS 定位;
# bit1,0:禁用北斗定位, 1:启用北斗定位;
# bit2,0:禁用 GLONASS 定位, 1:启用 GLONASS 定位;
# bit3,0:禁用 Galileo 定位, 1:启用 Galileo 定位。
param_0085 = "0085" + self.int2hexStringByBytes(1) + self.getGNSSMode()
#清零故障码,0x01:清空
param_2001 = "2001" + self.int2hexStringByBytes(1) + "01"
#清空设备车辆数据,0x01:清空
param_2002 = "2002" + self.int2hexStringByBytes(1) + "01"
#清空驾驶行程数据,0x01:清空
param_2003 = "2003" + self.int2hexStringByBytes(1) + "01"
#总油耗(单位 ml)
param_2004 = "2004" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(5000000,4)
#水温报警参数(单位℃)
param_2006 = "2006" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(70,4)
#急加速参数附表(无):0-关闭;1-低灵敏;2-中灵敏;3-高灵敏;
param_2007 = "2007" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(3)
#急减速参数附表(无):0-关闭;1-低灵敏;2-中灵敏;3-高灵敏;
param_2008 = "2008" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(3)
#急转弯参数附表(无):0-关闭;1-低灵敏;2-中灵敏;3-高灵敏;
param_2009 = "2009" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(3)
#车辆类型,详细见厂家车型表
param_200A = "200A" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(30,2)
#车辆电瓶低电压报警阈值(单位 0.1V)
param_200B = "200B" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(3,4)
#怠速时间过长报警(单位 S)
param_200C = "200C" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(6000,4)
#定位时间过长报警(单位 S)
param_200D = "200D" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(60,4)
#拖车报警参数附表(无)
param_200E = "200E" + self.int2hexStringByBytes(int(len(self.GBKString2Hex("Alarm003")) / 2)) + self.GBKString2Hex("Alarm003")
#碰撞报警参数附表(无):0-关闭;1-低灵敏;2-中灵敏;3-高灵敏;
param_200F = "200F" + self.int2hexStringByBytes(1) + self.int2hexStringByBytes(1)
#点火门限电压,单位 0.1V
param_200F = "200F" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(2200,4)
#里程类型(高位字节),油耗类型(低位字节)
# 里程类型:
# 0x00: 取消强制设置
# 0x01: GPS
# 0x02: J19391; 0x03: J19392; 0x04: J19393;
# 0x05: J19394; 0x06: J19395; 0x07: OBD 仪表;
# 0x08: OBD/私有协议;
# 0x09: J1939A; 0x0A: J1939B; 0x0B: J1939C;0x0C: J1939D
# …
# 0xFF: 不改变强制类型
#
# 油耗类型:
# 0x00: 取消强制设置
# 0x01: J19391; 0x02: J19392; 0x03: J19393; 0x04: J19394
# 0x05: J19395; 0x06: OBD1; 0x07: OBD2
# …
# 0xFF: 不改变强制类型
param_2012 = "2012" + self.int2hexStringByBytes(2) + "0001"
#里程系数:设置值/1000,例如:1020 -> 1.02
param_2013 = "2013" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(2000,2)
#油耗系数:设置值/1000,例如:1020 -> 1.02
param_2014 = "2014" + self.int2hexStringByBytes(2) + self.int2hexStringByBytes(2000,2)
#00:关闭 OBD 功能(禁止终端设备访问汽车 ECU)
# 01:开启 OBD 功能(允许终端设备访问汽车 ECU)
param_2017 = "2017" + self.int2hexStringByBytes(1) + "01"
#发送位置数据方式,设备默认采用先进先出
# 0x00:先进先出(默认)
# 0x01:实时优先
param_2018 = "2018" + self.int2hexStringByBytes(1) + "00"
#三急报警需要增加前后几秒的数据包(增加的数据主要是针对 0200) 0x00-0x0A,最大是 10 秒,默认是 0 秒,即是关闭该功能。
param_2019 = "2019" + self.int2hexStringByBytes(1) + "02"
#读取故障码指令:
# 0x01:读取 OBD 故障码,通过 0900 上报 F2 上报。
# 0x00:不读取故障码。
param_201A = "201A" + self.int2hexStringByBytes(1) + "01"
#单位秒,休眠唤醒时长最低 5 分钟,即是 300 秒
param_201C = "201C" + self.int2hexStringByBytes(4) + self.int2hexStringByBytes(300,4)
#数据加密使能
# 00:不加密
# 01:加密算法 1
# 02:加密算法 2
param_FF01 = "FF01" + self.int2hexStringByBytes(1) + "00"
data = param_0001 + param_0002 + param_0003 + param_0010 + param_0011
data = data + param_0012 + param_0013 + param_0014 + param_0015 + param_0016
data = data + param_0017 + param_0018 + param_0019 + param_0020 + param_0027
data = data + param_0029 + param_002C + param_0030 + param_0031 + param_0050
data = data + param_0055 + param_0056 + param_0057 + param_0058 + param_0059
data = data + param_005A + param_005B + param_005C + param_005D + param_005E
data = data + param_0080 + param_0081 + param_0082 + param_0083 + param_0084
data = data + param_0085 + param_2001 + param_2002 + param_2003 + param_2004
data = data + param_2006 + param_2007 + param_2008 + param_2009 + param_200A
data = data + param_200B + param_200C + param_200D + param_200E + param_200F
data = data + param_2012 + param_2013 + param_2014 + param_2017 + param_2018
data = data + param_2019 + param_201A + param_201C + param_FF01
return data
#获取GNSS 定位模式
# bit0,0:禁用 GPS 定位, 1:启用 GPS 定位;
# bit1,0:禁用北斗定位, 1:启用北斗定位;
# bit2,0:禁用 GLONASS 定位, 1:启用 GLONASS 定位;
# bit3,0:禁用 Galileo 定位, 1:启用 Galileo 定位
def getGNSSMode(self):
bit0 = 1
bit1 = 2
bit2 = 0
bit3 = 0
data = bit0 + bit1 + bit2 + bit3
dataHex = self.int2hexStringByBytes(data)
return dataHex
if __name__ == "__main__":
print(QueryTerminalParam_res().generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义查询终端属性应答消息
'''
from lib.protocol.message.MessageBase import MessageBase
class QueryTerminalProperty_res(MessageBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
pass
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
# 终端类型
terminalType = self.getTerminalType()
# 制造商 ID,5 个字节,终端制造商编码
manufacturerId = self.str2Hex("id123")
#终端型号,20 个字节,此终端型号由制造商自行定义,位数不足时 后补“0X00”。
terminalMode = self.str2Hex("mode_123456789012345")
#终端 ID,7 个字节,由大写字母和数字组成,此终端 ID 由制造商 自行定义,位数不足时,后补“0X00”。
terminalId = self.str2Hex("id121345")
#终端 SIM 卡 ICCID
ICCID = self.int2BCD(6238964579643234,10)
#终端硬件版本号长度
hardwareVersionNumLen = self.int2hexStringByBytes(10)
#终端硬件版本号
hardwareVersion = self.GBKString2Hex("version1.2")
#终端固件版本号长度
firmwareVersionLen = self.int2hexStringByBytes(11)
#终端固件版本号
firmwareVersion = self.GBKString2Hex("firmware1.2")
#GNSS 模块属性
GNSSProperty = self.getGNSSProperty()
#通信模块属性
communicationProperty = self.getCommunicationProperty()
data = terminalType + manufacturerId + terminalMode + terminalId + ICCID
data = data + hardwareVersionNumLen + hardwareVersion + firmwareVersionLen + firmwareVersion + GNSSProperty
data = data + communicationProperty
msg = data
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
# msgID = self.int2hexStringByBytes(102,2) #消息id
msgID = "0107"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(13146201119) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取终端类型
#######################################################
def getTerminalType(self):
#bit0,0:不适用客运车辆,1:适用客运车辆; (1)
# bit1,0:不适用危险品车辆,1:适用危险品车辆; (2)
# bit2,0:不适用普通货运车辆,1:适用普通货运车辆 (4)
# bit3,0:不适用出租车辆,1:适用出租车辆; (8)
# bit6,0:不支持硬盘录像,1:支持硬盘录像; (64)
# bit7,0:一体机,1:分体机。 (128)
bit0 = 1
bit1 = 2
bit2 = 4
bit3 = 8
bit6 = 64
bit7 = 128
data = bit0 + bit1 + bit2 + bit3 + bit6 + bit7
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取GNSS 模块属性
#######################################################
def getGNSSProperty(self):
#bit0,0:不支持 GPS 定位, 1:支持 GPS 定位; (1)
# bit1,0:不支持北斗定位, 1:支持北斗定位; (2)
# bit2,0:不支持 GLONASS 定位, 1:支持 GLONASS 定位 (4)
# bit3,0:不支持 Galileo 定位, 1:支持 Galileo 定位 (8)
bit0 = 1
bit1 = 2
bit2 = 4
bit3 = 8
data = bit0 +bit1 +bit2 + bit3
dataHex = self.int2hexStringByBytes(data)
return dataHex
#######################################################
# 获取通信模块属性
#######################################################
def getCommunicationProperty(self):
#bit0,0:不支持 GPRS 通信, 1:支持 GPRS 通信; (1)
# bit1,0:不支持 CDMA 通信, 1:支持 CDMA 通信; (2)
# bit2,0:不支持 TD-SCDMA 通信, 1:支持 TD-SCDMA 通信 (4)
# bit3,0:不支持 WCDMA 通信, 1:支持 WCDMA 通信; (8)
# bit4,0:不支持 CDMA2000 通信, 1:支持 CDMA2000 通信 (16)
# bit5,0:不支持 TD-LTE 通信, 1:支持 TD-LTE 通信; (32)
# bit7,0:不支持其他通信方式, 1:支持其他通信方式 (128)
bit0 = 1
bit1 = 2
bit2 = 4
bit3 = 8
bit4 = 16
bit5 = 32
bit7 = 128
data = bit0 + bit1 + bit2 + bit3 + bit4 + bit5 +bit7
dataHex = self.int2hexStringByBytes(data)
return dataHex
if __name__ == "__main__":
print(QueryTerminalProperty_res().generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义查询指定终端参数应答消息
'''
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.messagePlateform.ResponseBase import ResponseBase
class QueryTheTerminalParam_res(MessageBase,ResponseBase):
def __init__(self):
super().__init__() #不执行该方法,无法使用父类里面定义的属性
self.msgRes = "" #需要回复的消息的16进制报文
pass
#######################################################
# 设置需要回复的消息
#######################################################
def setMsgRes(self,data):
self.msgRes = data
#######################################################
# 获取需要回复消息的消息体
#######################################################
def getMsgResBody(self):
data = self.msgRes[28:][:-4]
data = self.restore_7e7d(data)
return data
#######################################################
# 获取需要回复消息的消息流水号
#######################################################
def getQueryWaterCode(self):
wc = self.msgRes[22:26]
return wc
#######################################################
# 获取需要回复消息的消息手机号
#######################################################
def getQueryPhoneNum(self):
phoneNum = self.msgRes[10:22]
return phoneNum
#######################################################
# 将消息体转换为需要查询的终端参数
#######################################################
def getQueryParams(self):
body = self.getMsgResBody()
params = []
param = body[0:8]
body = body[8:]
while param != "":
params.append(param)
param = body[0:8]
body = body[8:]
return params
#######################################################
# 生成一条完整的消息
#######################################################
def generateMsg(self):
msg = ""
msgHeader = self.getMsgHeader()
msgBody = self.getMsgBody()
checkCode = self.getCheckCode(msgHeader + msgBody)
msg = msg + self.IDENTIFY
info = msgHeader + msgBody + checkCode
info = self.replace7e7d(info)
msg = msg + info
msg = msg + self.IDENTIFY
return msg
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
msg = ""
resWaterCode = self.getQueryWaterCode() #应答流水号,对应的终端参数查询消息的流水号
resParamCounts = self.int2hexStringByBytes(len(self.getQueryParams())) #应答参数个数
paramList = self.getParamList() #参数项列表
msg = resWaterCode + resParamCounts + paramList
return msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
msgID = "0104"
subPkg = 0
msgBodyProperty = self.getMsgBodyProperty(msgBodyLen=int(len(self.getMsgBody()) / 2),subPkg=subPkg) #消息体属性
phoneNum = self.int2BCD(self.getQueryPhoneNum()) #终端手机号
msgWaterCode = self.int2hexStringByBytes(1,2) #消息流水号
if subPkg != 8192:
subPkgContent = "" #消息包封装项
else:
subPkgContent = self.getMsgPackage()
data = msgID + msgBodyProperty + phoneNum + msgWaterCode + subPkgContent
return data
#获取消息体属性
def getMsgBodyProperty(self,msgBodyLen=128,encryptionType=0,subPkg=0):
if msgBodyLen >= 512:
raise RuntimeError('消息体长度超长!')
msgBodyLen = msgBodyLen #消息体长度
encryptionType = encryptionType #加密方式
subPkg = subPkg #分包
retain = 0 #保留位
data = msgBodyLen + encryptionType + subPkg + retain
dataHex = self.int2hexStringByBytes(data,2)
return dataHex
#######################################################
# 获取参数项列表
#######################################################
def getParamList(self):
queryParams = self.getQueryParams()
paramNums = 0 #参数总数
data = ""
if "00000010" in queryParams:
content = self.str2Hex("tnet")
data = data + "00000010" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000011" in queryParams:
content = self.str2Hex("yuanhong")
data = data + "00000011" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000012" in queryParams:
content = self.str2Hex("123456")
data = data + "00000012" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000013" in queryParams:
content = self.str2Hex("10.100.12.30")
data = data + "00000013" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000014" in queryParams:
content = self.str2Hex("CDMA")
data = data + "00000014" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000015" in queryParams:
content = self.str2Hex("yuanhong2")
data = data + "00000015" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000016" in queryParams:
content = self.str2Hex("1234567")
data = data + "00000016" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000017" in queryParams:
content = self.str2Hex("10.100.12.31")
data = data + "00000017" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000018" in queryParams:
content = self.int2hexStringByBytes(9001,4)
data = data + "00000018" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
if "00000019" in queryParams:
content = self.int2hexStringByBytes(9002,4)
data = data + "00000019" + self.int2hexStringByBytes(int(len(content) / 2)) + content
paramNums = paramNums + 1
paramNums = self.int2hexStringByBytes(paramNums)
data = paramNums + data
return data
if __name__ == "__main__":
obj = QueryTheTerminalParam_res()
obj.setMsgRes("7e8106002901220150001000060a00000010000000110000001200000013000000180000001400000015000000160000001700000019c17e")
body = obj.getMsgResBody()
print(obj.getQueryParams())
print(obj.getQueryWaterCode())
print(obj.generateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义平台通用应答消息解码类
'''
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.messagePlateform.ResponseBase import ResponseBase
class DataDownStreamTransport_res(ResponseBase):
def __init__(self,msg):
super().__init__()
if type(msg) == bytes:
self.msg = self.binary2ascii(msg)
else:
self.msg = msg
pass
#######################################################
# 获取消息
#######################################################
def getMsg(self):
json_msg = {}
json_msg["header"] = self.getMsgHeader()
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.getCheckCode()
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() #自己计算消息后得到的校验码
return json_msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
json_header = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
header = data[:24]
msgId = header[:4] #消息id
msgBodyProperty = header[4:8] #消息体属性
phoneNum = header[8:20] #终端手机号
msgWaterCode = header[20:24] #消息流水号
json_header["msgId"] = msgId
json_header["msgBodyProperty"] = self.getMsgBodyProperty(msgBodyProperty)
json_header["phoneNum"] = phoneNum[1:]
json_header["msgWaterCode"] = int(msgWaterCode,16)
return json_header
#获取消息体属性
def getMsgBodyProperty(self,data):
data = self.int2binStr(int(data,16),2)
data = self.restore_7e7d(data)
json_data = {}
subPkg = data[2:3] #分包
encryptionType = data[3:6] #加密方式
msgBodyLen = data[6:] #消息体长度
json_data["subPkg"] = int(subPkg,2)
json_data["encryptionType"] = int(encryptionType,2)
json_data["msgBodyLen"] = int(msgBodyLen,2)
return json_data
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
json_body = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
body = data[24:dataLen - 2]
#透传消息类型
#0xF1 驾驶行程数据(熄火发送)
# 0xF2 故障码数据(状态改变发送)
# 0xF3 休眠进入(进入休眠模式发送)
# 0xF4 休眠唤醒(退出休眠模式发送)
msgType = body[:2] #消息类型
msgContent = body[2:] #消息内容
if msgType == "F1":
msgContent = self.getDrivingJsonData(msgContent) #驾驶行程数据(熄火发送)
elif msgType == "F2":
msgContent = self.getTroubleCodeJsonData(msgContent) #故障码数据(状态改变发送)
elif msgType == "F3":
msgContent = self.getIntoSleepJsonData(msgContent) #休眠进入(进入休眠模式发送)
elif msgType == "F4":
msgContent = self.getOutSleepJsonData(msgContent) #休眠唤醒(退出休眠模式发送)
json_body["msgType"] = msgType
json_body["msgContent"] = msgContent
return json_body
#######################################################
# 获取校验码
#######################################################
def getCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
checkCode = data[dataLen - 2:]
return checkCode
#######################################################
# 计算消息得到校验码
#######################################################
def getCalculateCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
data = data[:dataLen - 2]
calculateCheckCode = MessageBase().getCheckCode(data)
return calculateCheckCode
#######################################################
# 获取最原始的消息数据(没有替换7e,7d之前的状态)
#######################################################
def getOriginalMsg(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
data = "7e" + data + "7e"
return data
#######################################################
# 驾驶行程数据(熄火发送)
#######################################################
def getDrivingJsonData(self,msgContent):
json_content = []
#time_1
item_0 = {}
item_0["msgId"] = msgContent[:4]
item_0["length"] = self.hexString2int(msgContent[4:6])
item_0["time_1"] = self.getBCD2GMTTime(msgContent[6:18])
json_content.append(item_0)
msgContent = msgContent[18:]
# time_2
item_1 = {}
item_1["msgId"] = msgContent[:4]
item_1["length"] = self.hexString2int(msgContent[4:6])
item_1["time_2"] = self.getBCD2GMTTime(msgContent[6:18])
json_content.append(item_1)
msgContent = msgContent[18:]
#获取点火纬度,单位:0.000001 度,Bit31=0/1 北纬/南纬 ; :北纬 1:南纬 (2147483648)
item_2 = {}
item_2["msgId"] = msgContent[:4]
item_2["length"] = self.hexString2int(msgContent[4:6])
item_2["fireLatitude"] = - self.hexString2int(msgContent[6:14])
json_content.append(item_2)
msgContent = msgContent[14:]
#点火经度,单位:0.000001 度,Bit31=0/1 东经/西经 ; 0:东经 1:西经 (2147483648)
item_3 = {}
item_3["msgId"] = msgContent[:4]
item_3["length"] = self.hexString2int(msgContent[4:6])
item_3["fireLongitude"] = self.hexString2int(msgContent[6:14])
json_content.append(item_3)
msgContent = msgContent[14:]
#获取熄火纬度,单位:0.000001 度,Bit31=0/1 北纬/南纬 ; 0:北纬 1:南纬 (2147483648)
item_4 = {}
item_4["msgId"] = msgContent[:4]
item_4["length"] = self.hexString2int(msgContent[4:6])
item_4["unFireLatitude"] = self.hexString2int(msgContent[6:14])
json_content.append(item_4)
msgContent = msgContent[14:]
#熄火经度,单位:0.000001 度,Bit31=0/1 东经/西经 ; 0:东经 1:西经 (2147483648)
item_5 = {}
item_5["msgId"] = msgContent[:4]
item_5["length"] = self.hexString2int(msgContent[4:6])
item_5["unFireLongitude"] = self.hexString2int(msgContent[6:14])
json_content.append(item_5)
msgContent = msgContent[14:]
#驾驶循环标签
item_6 = {}
item_6["msgId"] = msgContent[:4]
item_6["length"] = self.hexString2int(msgContent[4:6])
item_6["drivingCircleLabel"] = self.hexString2int(msgContent[6:10])
json_content.append(item_6)
msgContent = msgContent[10:]
#一个驾驶循环总里程类型
item_7 = {}
item_7["msgId"] = msgContent[:4]
item_7["length"] = self.hexString2int(msgContent[4:6])
item_7["drivingCircleTotalMileageType"] = msgContent[6:8]
json_content.append(item_7)
msgContent = msgContent[8:]
#一个驾驶循环总里程,单位米
item_8 = {}
item_8["msgId"] = msgContent[:4]
item_8["length"] = self.hexString2int(msgContent[4:6])
item_8["drivingCircleTotalMileage"] = self.hexString2int(msgContent[6:14])
json_content.append(item_8)
msgContent = msgContent[14:]
#一个驾驶循环总耗油,单位毫升(ml)
item_9 = {}
item_9["msgId"] = msgContent[:4]
item_9["length"] = self.hexString2int(msgContent[4:6])
item_9["drivingCircleTotalOil"] = self.hexString2int(msgContent[6:14])
json_content.append(item_9)
msgContent = msgContent[14:]
#一个驾驶循环总时长,单位秒
item_10 = {}
item_10["msgId"] = msgContent[:4]
item_10["length"] = self.hexString2int(msgContent[4:6])
item_10["drivingCircleTotalTime"] = self.hexString2int(msgContent[6:14])
json_content.append(item_10)
msgContent = msgContent[14:]
#一个驾驶循环超速累计时长,单位秒
item_11 = {}
item_11["msgId"] = msgContent[:4]
item_11["length"] = self.hexString2int(msgContent[4:6])
item_11["drivingCircleOverSpeedTotalTime"] = self.hexString2int(msgContent[6:10])
json_content.append(item_11)
msgContent = msgContent[10:]
#一个驾驶循环超速次数,单位次
item_12 = {}
item_12["msgId"] = msgContent[:4]
item_12["length"] = self.hexString2int(msgContent[4:6])
item_12["drivingCircleOverSpeedTotalTimes"] = self.hexString2int(msgContent[6:10])
json_content.append(item_12)
msgContent = msgContent[10:]
#一个驾驶循环平均车速,单位 KM/H
item_13 = {}
item_13["msgId"] = msgContent[:4]
item_13["length"] = self.hexString2int(msgContent[4:6])
item_13["drivingCircleAverageSpeed"] = self.hexString2int(msgContent[6:8])
json_content.append(item_13)
msgContent = msgContent[8:]
# 一个驾驶循环最大车速,单位 KM/H
item_14 = {}
item_14["msgId"] = msgContent[:4]
item_14["length"] = self.hexString2int(msgContent[4:6])
item_14["drivingCircleMaxSpeed"] = self.hexString2int(msgContent[6:8])
json_content.append(item_14)
msgContent = msgContent[8:]
# 一个驾驶循环怠速时长,单位秒
item_15 = {}
item_15["msgId"] = msgContent[:4]
item_15["length"] = self.hexString2int(msgContent[4:6])
item_15["drivingCircleIdlingTime"] = self.hexString2int(msgContent[6:14])
json_content.append(item_15)
msgContent = msgContent[14:]
# 一个驾驶循环脚刹次数支持与否,1 为支持
item_16 = {}
item_16["msgId"] = msgContent[:4]
item_16["length"] = self.hexString2int(msgContent[4:6])
item_16["drivingCircleFootBrakeIsSupport"] = self.hexString2int(msgContent[6:8])
json_content.append(item_16)
msgContent = msgContent[8:]
# 一个驾驶循环脚刹总次数,单位次
item_17 = {}
item_17["msgId"] = msgContent[:4]
item_17["length"] = self.hexString2int(msgContent[4:6])
item_17["drivingCircleFootBrakeTatalTimes"] = self.hexString2int(msgContent[6:10])
json_content.append(item_17)
msgContent = msgContent[10:]
# 一个驾驶循环急加速次数
item_18 = {}
item_18["msgId"] = msgContent[:4]
item_18["length"] = self.hexString2int(msgContent[4:6])
item_18["drivingCircleRapidlyAccelerateTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_18)
msgContent = msgContent[14:]
# 一个驾驶循环急减速次数
item_19 = {}
item_19["msgId"] = msgContent[:4]
item_19["length"] = self.hexString2int(msgContent[4:6])
item_19["drivingCircleSharpSlowdownTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_19)
msgContent = msgContent[14:]
# 一个驾驶循环急转弯次数
item_20 = {}
item_20["msgId"] = msgContent[:4]
item_20["length"] = self.hexString2int(msgContent[4:6])
item_20["drivingCircleSharpCurveTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_20)
msgContent = msgContent[14:]
# 速度为-20Km/H 的里程,单位:m
item_21 = {}
item_21["msgId"] = msgContent[:4]
item_21["length"] = self.hexString2int(msgContent[4:6])
item_21["speedIn20"] = self.hexString2int(msgContent[6:14])
json_content.append(item_21)
msgContent = msgContent[14:]
# 速度为 20-40Km/H 的里程,单位:m
item_22 = {}
item_22["msgId"] = msgContent[:4]
item_22["length"] = self.hexString2int(msgContent[4:6])
item_22["speedIn20_40"] = self.hexString2int(msgContent[6:14])
json_content.append(item_22)
msgContent = msgContent[14:]
# 速度为 40-60Km/H 的里程,单位:m
item_23 = {}
item_23["msgId"] = msgContent[:4]
item_23["length"] = self.hexString2int(msgContent[4:6])
item_23["speedIn40_60"] = self.hexString2int(msgContent[6:14])
json_content.append(item_23)
msgContent = msgContent[14:]
# 速度为 60-80Km/H 的里程,单位:m
item_24 = {}
item_24["msgId"] = msgContent[:4]
item_24["length"] = self.hexString2int(msgContent[4:6])
item_24["speedIn60_80"] = self.hexString2int(msgContent[6:14])
json_content.append(item_24)
msgContent = msgContent[14:]
# 速度为 80-100Km/H 的里程,单位:m
item_25 = {}
item_25["msgId"] = msgContent[:4]
item_25["length"] = self.hexString2int(msgContent[4:6])
item_25["speedIn80_100"] = self.hexString2int(msgContent[6:14])
json_content.append(item_25)
msgContent = msgContent[14:]
# 速度为 100-120Km/H 的里程,单位:m
item_26 = {}
item_26["msgId"] = msgContent[:4]
item_26["length"] = self.hexString2int(msgContent[4:6])
item_26["speedIn100_120"] = self.hexString2int(msgContent[6:14])
json_content.append(item_26)
msgContent = msgContent[14:]
# 速度为 120Km/H 以上的里程,单位:m
item_27 = {}
item_27["msgId"] = msgContent[:4]
item_27["length"] = self.hexString2int(msgContent[4:6])
item_27["speedOut120"] = self.hexString2int(msgContent[6:14])
json_content.append(item_27)
msgContent = msgContent[14:]
# 急加速总次数
item_28 = {}
item_28["msgId"] = msgContent[:4]
item_28["length"] = self.hexString2int(msgContent[4:6])
item_28["rapidlyAccelerateTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_28)
msgContent = msgContent[14:]
# 急减速总次数
item_29 = {}
item_29["msgId"] = msgContent[:4]
item_29["length"] = self.hexString2int(msgContent[4:6])
item_29["rapidlySharpSlowdownTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_29)
msgContent = msgContent[14:]
# 急转弯总次数
item_30 = {}
item_30["msgId"] = msgContent[:4]
item_30["length"] = self.hexString2int(msgContent[4:6])
item_30["sharpCurveTimes"] = self.hexString2int(msgContent[6:14])
json_content.append(item_30)
msgContent = msgContent[14:]
if msgContent != "":
raise RuntimeError('还有数据未解析!')
return json_content
#######################################################
# 获取故障码数据
#######################################################
def getTroubleCodeJsonData(self,msgContent):
json_content = {}
# time
json_content["infoTime"] = self.getBCD2GMTTime(msgContent[:12])
msgContent = msgContent[12:]
# 单位:0.000001 度,Bit31=0/1 北纬/南纬
json_content["latitude"] = self.hexString2int(msgContent[:8])
msgContent = msgContent[8:]
# 单位:0.000001 度,Bit31=0/1 东经/西经
json_content["longitude"] = self.hexString2int(msgContent[:8])
msgContent = msgContent[8:]
# 为 0 表示无故障码,非 0 为故障码个数
json_content["troubleCodeNums"] = self.hexString2int(msgContent[:2])
msgContent = msgContent[2:]
troubleCodeCounts = json_content["troubleCodeNums"]
troubleCode = []
for i in range(0,troubleCodeCounts):
item = {}
item["systemId"] = self.hexString2int(msgContent[:2])
item["code1"] = self.hexString2int(msgContent[2:4])
item["code2"] = self.hexString2int(msgContent[4:6])
item["code3"] = self.hexString2int(msgContent[6:8])
troubleCode.append(item)
msgContent = msgContent[8:]
json_content["troubleCode"] = troubleCode
return json_content
#######################################################
# 获取进入休眠数据包
#######################################################
def getIntoSleepJsonData(self,msgContent):
json_content = {}
# time
json_content["infoTime"] = self.getBCD2GMTTime(msgContent[:12])
return json_content
#######################################################
# 获取休眠唤醒数据包
#######################################################
def getOutSleepJsonData(self,msgContent):
json_content = {}
# time
json_content["infoTime"] = self.getBCD2GMTTime(msgContent[:12])
msgContent = msgContent[12:]
# 休眠唤醒类型
# 0x01:休眠定时唤醒
# 0x02:CAN1
# 0x04:CAN2
# 0x08:gSensor 0x10:电压变
json_content["outSleepType"] = msgContent[:2]
msgContent = msgContent[2:]
# 车辆电压,单位 0.1V
json_content["carVoltage"] = self.hexString2int(msgContent[:4])
msgContent = msgContent[4:]
# 振动唤醒加速度值,单位 mg
json_content["vibrateOutSleepSpeedUpVal"] = self.hexString2int(msgContent[:4])
return json_content
if __name__ == "__main__":
# print(DataDownStreamTransport_res("7e090000ca0131462011190001F100010620020522073000020620020715175600030401c0a6380004040659ad7a00050401c0a6380006040659ad7a000702007b00080101000904000094ca000A0400012688000B04000b13f0000C02d2f0000D020065000E0141000F017b00100400c042c00011010100120100200013040000004f0014040000000a001504000000210016040000042c001704000007d024001804000076c000190400009088001A04000028a0001B0400001388001C0400000c80001D0400000bb8001E0400000db3001F0400000244817e").getMsg())
# print(DataDownStreamTransport_res("7e0900001c0131462011190001F220020611315601c0a6380659ad7a03010a141e010a141e010a141e3f7e").getMsg())
# print(DataDownStreamTransport_res("7e090000070131462011190001F3200206113156f07e").getMsg())
print(DataDownStreamTransport_res("7e0900000c0131462011190001F42002061131560101680e74ee7e").getMsg())
#encoding:utf-8
'''
定义平台版本信息包上传应答解码类
'''
import json
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.messagePlateform.ResponseBase import ResponseBase
class PlatefromVersionInfo_res(ResponseBase):
def __init__(self,msg):
super().__init__()
if type(msg) == bytes:
self.msg = self.binary2ascii(msg)
else:
self.msg = msg
pass
#######################################################
# 获取消息
#######################################################
def getMsg(self):
json_msg = {}
json_msg["header"] = self.getMsgHeader()
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.getCheckCode()
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() #自己计算消息后得到的校验码
json_msg = json.dumps(json_msg)
return json_msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
json_header = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
header = data[:24]
msgId = header[:4] #消息id
msgBodyProperty = header[4:8] #消息体属性
phoneNum = header[8:20] #终端手机号
msgWaterCode = header[20:24] #消息流水号
json_header["msgId"] = msgId
json_header["msgBodyProperty"] = self.getMsgBodyProperty(msgBodyProperty)
json_header["phoneNum"] = phoneNum[1:]
json_header["msgWaterCode"] = int(msgWaterCode,16)
return json_header
#获取消息体属性
def getMsgBodyProperty(self,data):
data = self.int2binStr(int(data,16),2)
data = self.restore_7e7d(data)
json_data = {}
subPkg = data[2:3] #分包
encryptionType = data[3:6] #加密方式
msgBodyLen = data[6:] #消息体长度
json_data["subPkg"] = int(subPkg,2)
json_data["encryptionType"] = int(encryptionType,2)
json_data["msgBodyLen"] = int(msgBodyLen,2)
return json_data
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
json_body = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
body = data[24:dataLen - 2]
plateformCurrentTime = self.getBCD2GMTTime(body[:12]) #平台当前时间
carId = self.hexString2int(body[12:16]) #车型id
displacement = self.hexString2int(body[16:20]) #排量
isUpdate = body[20:22] #是否升级,0x55 升级,其他不升级
oilDensity = self.hexString2int(body[22:26]) #油密度
OBDCtrType = self.hexString2int(body[26:]) >> 7
json_body["plateformCurrentTime"] = plateformCurrentTime
json_body["carId"] = carId
json_body["displacement"] = displacement
json_body["isUpdate"] = isUpdate
json_body["oilDensity"] = oilDensity
json_body["OBDCtrType"] = OBDCtrType
return json_body
#######################################################
# 获取校验码
#######################################################
def getCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
checkCode = data[dataLen - 2:]
return checkCode
#######################################################
# 计算消息得到校验码
#######################################################
def getCalculateCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
data = data[:dataLen - 2]
calculateCheckCode = MessageBase().getCheckCode(data)
return calculateCheckCode
#######################################################
# 获取最原始的消息数据(没有替换7e,7d之前的状态)
#######################################################
def getOriginalMsg(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
data = "7e" + data + "7e"
return data
#encoding:utf-8
'''
定义平台通用应答消息解码类
'''
import json
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.messagePlateform.ResponseBase import ResponseBase
class PlatformCommon_res(ResponseBase):
def __init__(self,msg):
super().__init__()
if type(msg) == bytes:
self.msg = self.binary2ascii(msg)
else:
self.msg = msg
pass
#######################################################
# 获取消息
#######################################################
def getMsg(self):
json_msg = {}
json_msg["header"] = self.getMsgHeader()
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.getCheckCode()
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() #自己计算消息后得到的校验码
json_msg = json.dumps(json_msg)
return json_msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
json_header = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
header = data[:24]
msgId = header[:4] #消息id
msgBodyProperty = header[4:8] #消息体属性
phoneNum = header[8:20] #终端手机号
msgWaterCode = header[20:24] #消息流水号
json_header["msgId"] = msgId
json_header["msgBodyProperty"] = self.getMsgBodyProperty(msgBodyProperty)
json_header["phoneNum"] = phoneNum[1:]
json_header["msgWaterCode"] = int(msgWaterCode,16)
return json_header
#获取消息体属性
def getMsgBodyProperty(self,data):
data = self.int2binStr(int(data,16),2)
data = self.restore_7e7d(data)
json_data = {}
subPkg = data[2:3] #分包
encryptionType = data[3:6] #加密方式
msgBodyLen = data[6:] #消息体长度
json_data["subPkg"] = int(subPkg,2)
json_data["encryptionType"] = int(encryptionType,2)
json_data["msgBodyLen"] = int(msgBodyLen,2)
return json_data
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
json_body = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
body = data[24:dataLen - 2]
resWaterCode = body[:4] #应答流水号
resId = body[4:8] #应答id
result = body[8:] #结果
json_body["resWaterCode"] = int(resWaterCode,16)
json_body["resId"] = int(resId,16)
json_body["result"] = int(result,16)
return json_body
#######################################################
# 获取校验码
#######################################################
def getCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
checkCode = data[dataLen - 2:]
return checkCode
#######################################################
# 计算消息得到校验码
#######################################################
def getCalculateCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
data = data[:dataLen - 2]
calculateCheckCode = MessageBase().getCheckCode(data)
return calculateCheckCode
#######################################################
# 获取最原始的消息数据(没有替换7e,7d之前的状态)
#######################################################
def getOriginalMsg(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
data = "7e" + data + "7e"
return data
#encoding:utf-8
import binascii
from lib.protocol.Base import Base
class ResponseBase(Base):
def __init__(self):
pass
#######################################################
# 二进制转换为ascii码
#######################################################
def binary2ascii(self,binData):
strs = binascii.b2a_hex(binData)
strsLen = len(str(strs))
data = str(strs)[2:strsLen - 1]
return data
#######################################################
# 还原消息中被转换过的7e和7d
#######################################################
def restore_7e7d(self,data):
data = data.replace("7d02", "7e")
data = data.replace("7d01", "7d")
return data
#######################################################
# 去除标识位
#######################################################
def removeIdentify(self,data):
dataLen = len(data)
data = data[2:dataLen - 2]
return data
#######################################################
# 10进制转换为2进制字符串
#######################################################
def int2binStr(self,data,bytescount=1):
binStr = bin(data)
binStr = binStr[2:]
bytesLen = bytescount * 8
while len(binStr) < bytesLen:
binStr = "0" + binStr
return binStr
#######################################################
# 16进制字符串转换为整数
#######################################################
def hexString2int(self, data):
val = int(data,16)
return val
#######################################################
# 16进制字符串转换为ascii字符串
#######################################################
def hex2string(self,data):
theStr = ""
while data != "":
tmp = data[:2]
data = data[2:]
theStr = theStr + chr(int(tmp, 16))
return theStr
#######################################################
# BCD时间格式转换为GMD时间格式
#######################################################
def getBCD2GMTTime(self,data):
theTime = "20"
theTime = theTime + data[:2]
theTime = theTime + "-" + data[2:4]
theTime = theTime + "-" + data[4:6]
theTime = theTime + " " + data[6:8]
theTime = theTime + ":" + data[8:10]
theTime = theTime + ":" + data[10:]
return theTime
#######################################################
# 通过原始数据,获取消息id
#######################################################
def getMsgId(self, data):
data = self.removeIdentify(data)
data = self.restore_7e7d(data)
header = data[:24]
msgId = header[:4] # 消息id
return msgId
#######################################################
# 16进制转换为GBK字符串
#######################################################
def hex2GBKString_res(self,dataHex):
dataStr = self.hex2Str(dataHex)
data = bytes(map(ord,str(dataStr)))
data = data.decode("gbk")
return data
if __name__ == "__main__":
# print(ResponseBase().int2binStr(7,2))
# print(ResponseBase().getMsgId("7e0002000001314620111800065b7e"))
# print(ResponseBase().getMsgId("7e80010005013146201118e1480006000200767e"))
print(ResponseBase().hex2string("014c3230304142303030302c737a6c696e6779692e716963702e7669702c383838392c537a4c696e6759692c7a373254713246742c4c3230304142303130322e303030342e42494e2c2f2c"))
print(ResponseBase().hexString2int("00001f43 "))
\ No newline at end of file
#encoding:utf-8
'''
定义平台通用应答消息解码类
'''
import json
from lib.protocol.message.MessageBase import MessageBase
from lib.protocol.messagePlateform.ResponseBase import ResponseBase
class TerminalRegister_res(ResponseBase):
def __init__(self,msg):
super().__init__()
if type(msg) == bytes:
self.msg = self.binary2ascii(msg)
else:
self.msg = msg
pass
#######################################################
# 获取消息
#######################################################
def getMsg(self):
json_msg = {}
json_msg["header"] = self.getMsgHeader()
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.getCheckCode()
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() #自己计算消息后得到的校验码
json_msg = json.dumps(json_msg)
return json_msg
#######################################################
# 获取消息头
#######################################################
def getMsgHeader(self):
json_header = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
header = data[:24]
msgId = header[:4] #消息id
msgBodyProperty = header[4:8] #消息体属性
phoneNum = header[8:20] #终端手机号
msgWaterCode = header[20:24] #消息流水号
json_header["msgId"] = msgId
json_header["msgBodyProperty"] = self.getMsgBodyProperty(msgBodyProperty)
json_header["phoneNum"] = phoneNum[1:]
json_header["msgWaterCode"] = int(msgWaterCode,16)
return json_header
#获取消息体属性
def getMsgBodyProperty(self,data):
data = self.int2binStr(int(data,16),2)
data = self.restore_7e7d(data)
json_data = {}
subPkg = data[2:3] #分包
encryptionType = data[3:6] #加密方式
msgBodyLen = data[6:] #消息体长度
json_data["subPkg"] = int(subPkg,2)
json_data["encryptionType"] = int(encryptionType,2)
json_data["msgBodyLen"] = int(msgBodyLen,2)
return json_data
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
json_body = {}
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
body = data[24:dataLen - 2]
resWaterCode = body[:4] #应答流水号
result = body[4:6] #结果
authenticationCode = body[6:] #鉴权码
json_body["resWaterCode"] = int(resWaterCode,16)
json_body["result"] = int(result,16)
json_body["authenticationCode"] = self.hex2string(authenticationCode)
return json_body
#######################################################
# 获取校验码
#######################################################
def getCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
checkCode = data[dataLen - 2:]
return checkCode
#######################################################
# 计算消息得到校验码
#######################################################
def getCalculateCheckCode(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
dataLen = len(data)
data = data[:dataLen - 2]
calculateCheckCode = MessageBase().getCheckCode(data)
return calculateCheckCode
#######################################################
# 获取最原始的消息数据(没有替换7e,7d之前的状态)
#######################################################
def getOriginalMsg(self):
data = self.removeIdentify(self.msg)
data = self.restore_7e7d(data)
data = "7e" + data + "7e"
return data
\ No newline at end of file
#coding:utf-8
#########################################################
#
# 定义基类,供所有类继承
#
#########################################################
class Base():
def __init__(self):
pass
#coding:utf-8
import socket
from time import sleep
from lib.socket.SocketBase import SocketBase
import binascii
import random
import string
import traceback
'''
定义客户端socket类
'''
class ClientSocket(SocketBase):
def __init__(self, host="127.0.0.1", port=5000):
#socke连接的标识,生成一个长度为8的随机字符串
self.socketId = ''.join(random.sample(string.ascii_letters + string.digits, 8))
self.port = port
self.host = host
self.timeOut = 1 #设置连接超时时间
# 0代表未连接 , 1代表socket处于连接状态
self.status = 0
self.BUF_SIZE = 1024
#####################################################
# 连接服务器
#####################################################
def connect(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳
# 设置连接socket的超时时间
self.client.settimeout(self.timeOut)
self.client.connect((self.host, self.port))
self.status = 1
#####################################################
# 发送消息
#####################################################
def send(self, msg):
# 设置发送消息的超时时间
self.client.settimeout(self.timeOut)
self.client.send(binascii.a2b_hex(msg))
def receive(self):
data = ""
try:
# 设置接收消息的超时时间
self.client.settimeout(self.timeOut)
data = self.client.recv(self.BUF_SIZE)
except BaseException as e:
# traceback.print_exc()
self.client.close()
self.status = 0
raise RuntimeError('socket 接收消息超时!')
return data
#####################################################
# 断开socket
#####################################################
def close(self):
# self.client.send("_end".encode()) //发送一个socket断开的命令
self.client.shutdown(socket.SHUT_RDWR)
self.client.close()
self.status = 0
#设置服务器域名
def setHost(self,host):
self.host = host
#设置要连接的服务器端口
def setPort(self,port):
self.port = port
#获取该连接的socket ID号
def getSocketId(self):
return self.socketId
def getSocketStatus(self):
return self.status
def setTimeOut(self,data):
self.timeOut = data
if __name__ == "__main__":
client = ClientSocket()
client.connect()
for i in range(0,10):
client.send("world" + str(i))
sleep(1)
print(i)
client.close()
\ No newline at end of file
#coding:utf-8
#########################################################
#
# 定义服务端socket类
#
#########################################################
import socket
from time import sleep
from lib.socket.SocketBase import SocketBase
class ServerSocket(SocketBase):
def __init__(self,host="127.0.0.1",port=5000):
self.host = host
self.port = port
self.status = 0 #0代表socket停止服务,1代表socket服务运行
self.BUF_SIZE = 1024
#####################################################
# 创建一个服务端套接字
#####################################################
def createServerSocket(self):
serverSocket = socket.socket() #默认为ipv4,tcp连接
#下面创建socketyu8上面创建的没有区别(AF_INET:ipv4,SOCK_STREAM代表使用TCP连接)
# serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind((self.host,self.port))
return serverSocket
#####################################################
# 启动socket服务
#####################################################
def startServer(self):
self.status = 1
server = self.createServerSocket()
# 设置接收的连接数为1
server.listen(1)
server.settimeout(10)
client, address = server.accept()
while self.status == 1: # 循环收发数据包,长连接
data = client.recv(self.BUF_SIZE)
text = data.decode()
sleep(1)
if text != "":
print(text) # python3 要使用decode
client.send("world".encode())
# client.close() #连接不断开,长连接
#接收到断开连接的信息后,关闭socket;应为python的socket没有提供获取服务端自身socket的状态或者客户端是否断开了连接
if text == "_end":
self.close()
def close(self):
self.status = 0
def getHost(self):
return self.host
def getPort(self):
return self.port
def setHost(self,host):
self.host = host
def setPort(self,port):
self.port = port
if __name__ == "__main__":
server = ServerSocket("localhost", 5000)
server.createServerSocket()
server.startServer()
\ No newline at end of file
#encoding:utf-8
#########################################################
#
# 定义socket的基类
#
#########################################################
from lib.socket.Base import Base
class SocketBase(Base):
def __init__(self):
pass
#coding:utf-8
import binascii
import socket
import traceback
from lib.protocol.message.DataUpstreamTransport_msg import DataUpstreamTransport_msg
from lib.protocol.message.LocationDataBatchUpdate_msg import LocationDataBatchUpdate_msg
from lib.protocol.message.Location_msg import Location_msg
from lib.protocol.message.PlateformUpdateRes_msg import PlateformUpdateRes_msg
from lib.protocol.message.TerminalAuthenticate_msg import TerminalAuthenticate_msg
from lib.protocol.message.TerminalCommonMsgRes_msg import TerminalCommonMsgRes_msg
from lib.protocol.message.TerminalHeartbeat_msg import TerminalHeartbeat_msg
from lib.protocol.message.TerminalRegister_msg import TerminalRegister_msg
from lib.protocol.message.TerminalVersionInfo_msg import TerminalVersionInfo_msg
from lib.protocol.message.TextInfoUpload_msg import TextInfoUpload_msg
from lib.protocol.messagePlateform.PlateformVersionInfo_res import PlatefromVersionInfo_res
from lib.protocol.messagePlateform.PlatformCommon_res import PlatformCommon_res
from lib.protocol.messagePlateform.TerminalRegister_res import TerminalRegister_res
# host = "10.100.11.20"
# port = 9001
host = "10.100.12.32"
port = 9001
# msg = MessageBase().generateMsg()
# msg = TerminalCommonMsgRes_msg().generateMsg() #终端通用应答
# msg = TerminalHeartbeat_msg().generateMsg() #终端心跳
# msg = TerminalRegister_msg().generateMsg() #终端注册
# msg = TerminalCancle_msg().generateMsg() #终端注销
# msg = TerminalAuthenticate_msg().generateMsg() #终端鉴权
# msg = TerminalVersionInfo_msg().generateMsg() #终端版本信息上报
# msg = QueryTerminalParam_res().generateMsg() #查询终端参数应答
# msg = QueryTerminalProperty_res().generateMsg() #查询终端属性应答消息
# msg = Location_msg().generateMsg() #位置信息汇报
msg = DataUpstreamTransport_msg().generateMsg() #数据上行透传消息
# msg = TerminalUpdataResult_msg().generateMsg() #终端升级结果通知
# msg = LocationDataBatchUpdate_msg().generateMsg() #定位数据批量上传
# msg = TextInfoUpload_msg().generateMsg() #文本信息上传
# msg = PlateformUpdateRes_msg().generateMsg() #平台升级数据包应答
#发送单条消息
def sendSingleMsg(msg):
print(msg)
BUF_SIZE = 1024
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳
client.settimeout(1)
try:
client.connect((host, port))
client.send(binascii.a2b_hex(msg))
# client.send(bytes.fromhex(msg))
except BaseException as e:
traceback.print_exc()
client.close()
print("连接超时,socket断开")
return
try:
data = client.recv(BUF_SIZE)
# print(data)
except BaseException as e:
traceback.print_exc()
client.close()
# raise RuntimeError('socket 接收消息超时!')
print('socket 接收消息超时!')
return
print(data)
print(PlatformCommon_res(data).getOriginalMsg())
# print(PlatformCommon_res(data).getMsg()) #解析平台通用应答消息
# print(TerminalRegister_res(data).getMsg()) #解析终端注册应答消息
# print(PlatefromVersionInfo_res(data).getMsg()) #解析平台版本信息包上传应答
client.close()
def closeSocket(soc):
soc.close
def connectSock():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳
client.connect((host, port))
return client
def sendMsg(client,msg):
print("发送的消息为:" + msg)
BUF_SIZE = 1024
client.send(binascii.a2b_hex(msg))
data = client.recv(BUF_SIZE)
if PlatformCommon_res(data).getMsg()["header"]["msgId"] == "0100": #终端注册应答
print("收到的消息:" + str(TerminalRegister_res(data).getMsg()))
else:
print("收到的消息:" + str(PlatformCommon_res(data).getMsg())) #平台通用应答
return client
def sendMultMsg():
pass
if __name__ == "__main__":
sendSingleMsg(msg)
'''
print("发送终端注册消息")
client = connectSock()
msg = TerminalRegister_msg().generateMsg() #终端注册
sendMsg(client,msg)
sleep(2)
print("发送终端心跳消息")
msg = TerminalHeartbeat_msg().generateMsg() # 终端心跳
sendMsg(client,msg)
sleep(2)
print("发送终端鉴权消息")
msg = TerminalAuthenticate_msg().generateMsg() # 终端鉴权
sendMsg(client,msg)
sleep(2)
closeSocket(client)
print("断开连接")
'''
#coding:utf-8
'''
新硬件车机模拟服务类
'''
import binascii
import datetime
import json
import math
import os
import random
import threading
import time
import traceback
from time import sleep
from lib.protocol.message.Location_msg import Location_msg
from lib.protocol.message.TerminalRegister_msg import TerminalRegister_msg
from lib.protocol.message.TerminalVersionInfo_msg import TerminalVersionInfo_msg
from lib.socket.ClientSocket import ClientSocket
from lib.socket.service.MessageSimulaterDataService import MessageSimulaterDataService
from lib.util.util import strAddSpace
class AutoCarTimerService():
def __init__(self):
self.host = "10.100.12.32"
self.port = 9008
self.carId = "012201800001" # 车机号
self.data = {"phoneNum": "012201500010", "durTime": "5", "timeout": "3600", "gpsLine": "10_gpsLine4.txt",
"session": {"sessionId": "UqnnCYUt_190660"},
"login": {"provinceId": "50", "countyId": "103", "manufacturerId": "11010",
"terminalType": "a865h643gfdj64fd7432", "terminalId": "H6uyt08",
"licencePlateColor": "1", "carSign": "渝B23CX"},
"version": {"softwareVersion": "L200AB01020002", "softwareVersionDate": "2020-02-10",
"CPUId": "CPU-12345678", "GMSType": "GMS-TYPE-123456", "GMS_IMEI": "GMS_IMEI_123456",
"SIM_IMSI": "SIM_13146201119", "SIM_ICCID": "SIM_ICCID13146201119", "carType": "22",
"VIN": "VIN_1234567891234", "totalMileage": "389000", "totalOilExpend": "420000",
"displacement": "1500", "oilDensity": "92"},
"travelData": {"carSpeed": "60", "oilExpend": "10", "travelLoop": "0", "votage": 120,
"surplusOil": 505, "engineSpeed": 3000}} #用来接收模拟器传过来的参数
self.carData = {} #保存车辆行驶数据
self.carDataObj = None #管理车辆行驶数据对象
self.socket = None
self.sendDur = 5 #设置默认多久发一条消息
self.serviceStatus = 0 #服务状态,0表示未启动,1表示启动
self.timeout = 60 #socket的超时时间
self.gpsLine = [] #GPS 轨迹
self.gpsLineIndex = 0 #GPS 轨迹索引
self.travelStatus = 0 #0,表示未行驶,1表示开始行驶同时开启了接收消息服务,2表示值开启了接收消息的服务
self.sn = 0 #消息流水号
self.travelDirection = 0 #行驶方向,0表示正向行驶,1表示反向行驶
self.directAngle = 59 #定义默认方向角
self.fixCurPosition = 0 #是否固定当前GPS点,0:不固定 1:固定
# 定义要发送的obd数据
self.OBDdata = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "66", "directionAngle": "59",
"infoTime": "2020-04-23 13:15:37"}, "extraInfo": {"01": {"extra_01": "20202020"},
"EA": {"0012": {"dataId_0012": "36"}},
"EB": {"6010": "2", "6014": "0", "6040": "44", "6050": "76", "6070": "89", "6100": "505", "6110": "51",
"6210": "4508", "6330": "28", "6460": "65", "6490": "32", "6701": "0", "6702": "0", "6703": "1",
"6704": "505", "6705": "1", "6706": "505", "6707": "505", "6708": "3500", "6709": "7200000",
"60C0": "3000", "60D0": "60", "62f0": "801", "60F0": "88", "60B0": "20", "60A0": "276",
"61F0": "3700", "60E0": "154", "670a": "3700000", "670b": "123000"}}}
# 定义初始的obd数据,与上面的OBD数据保持一致,主要用于汽车行驶过程中数据变化量的计算
self.OBDdataOri = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "66", "directionAngle": "59",
"infoTime": "2020-04-23 13:15:37"}, "extraInfo": {"01": {"extra_01": "20202020"},
"EA": {"0012": {"dataId_0012": "36"}},
"EB": {"6010": "2", "6014": "0", "6040": "44", "6050": "76", "6070": "89", "6100": "505", "6110": "51",
"6210": "4508", "6330": "28", "6460": "65", "6490": "32", "6701": "0", "6702": "0", "6703": "1",
"6704": "505", "6705": "1", "6706": "505", "6707": "505", "6708": "3500", "6709": "7200000",
"60C0": "3000", "60D0": "60", "62f0": "801", "60F0": "88", "60B0": "20", "60A0": "276",
"61F0": "3700", "60E0": "154", "670a": "3700000", "670b": "123000"}}}
def getSn(self):
return self.sn
def getTravelStatus(self):
return self.travelStatus
def getCurLatitude(self):
return self.gpsLine[self.gpsLineIndex]["lat"]
def getCurLongtitude(self):
return self.gpsLine[self.gpsLineIndex]["lng"]
def getTravelDirection(self):
return self.travelDirection
def getGpsLine(self):
return self.gpsLine
def getGpsLineIndex(self):
return self.gpsLineIndex
def setHost(self,data):
self.host = data
def setPort(self,data):
self.port = data
#设置套接字
def setSocket(self,data):
self.socket = data
def setSendDur(self,data):
self.sendDur = data
def setTimeout(self,data):
self.timeout = data
def setCarId(self,data):
self.carId = data
self.data["phoneNum"] = data
def setData(self,data):
self.data = data
def setSn(self,data):
self.sn = data
def setCarSpeed(self,data):
self.data["travelData"]["carSpeed"] = data
def setOilExpend(self,data):
self.data["travelData"]["oilExpend"] = data
def setSendDur(self,data):
self.sendDur = data
def setTravelDirection(self,data):
self.travelDirection = data
def setFixCurPosition(self,data):
self.fixCurPosition = data
def setVotage(self,data):
self.data["travelData"]["votage"] = data
def setEngineSpeed(self,data):
self.data["travelData"]["engineSpeed"] = data
def setSurplusOil(self,data):
self.data["travelData"]["surplusOil"] = data
def sendMsg(self,msg):
self.socket.setTimeOut(self.timeout)
self.socket.send(msg)
def revMsg(self):
self.socket.setTimeOut(self.timeout)
return self.socket.receive()
######################################################
#启动socket连接
######################################################
def connectService(self):
cliSocket = ClientSocket(self.host, self.port)
cliSocket.setTimeOut(self.timeout)
cliSocket.connect()
self.socket = cliSocket
info = self.getCurTime() + " 建立了连接"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
########################################################
#车机登录
########################################################
def carLogin(self):
loginObj = TerminalRegister_msg()
self.data["login"]["manufacturerId"] = strAddSpace(self.data["login"]["manufacturerId"],5)
self.data["login"]["terminalType"] = strAddSpace(self.data["login"]["terminalType"], 20)
self.data["login"]["terminalId"] = strAddSpace(self.data["login"]["terminalId"], 7)
msg = loginObj.generateMsg_GUI(msgID="0100",phoneNum=int(self.data["phoneNum"]),msgWaterCode=self.sn,encryptionType=0,subPkg=0,provinceId=int(self.data["login"]["provinceId"]),\
countyId=int(self.data["login"]["countyId"]),manufacturerId=self.data["login"]["manufacturerId"],terminalType=self.data["login"]["terminalType"], \
terminalId=self.data["login"]["terminalId"],licencePlateColor=int(self.data["login"]["licencePlateColor"]),carSign=self.data["login"]["carSign"])
self.sendMsg(msg)
self.sn = self.sn + 1
verObj = TerminalVersionInfo_msg()
time.sleep(0.5)
self.data["version"]["softwareVersion"] = strAddSpace(self.data["version"]["softwareVersion"], 14)
self.data["version"]["CPUId"] = strAddSpace(self.data["version"]["CPUId"], 12)
self.data["version"]["GMSType"] = strAddSpace(self.data["version"]["GMSType"], 15)
self.data["version"]["GMS_IMEI"] = strAddSpace(self.data["version"]["GMS_IMEI"], 15)
self.data["version"]["SIM_IMSI"] = strAddSpace(self.data["version"]["SIM_IMSI"], 15)
self.data["version"]["SIM_ICCID"] = strAddSpace(self.data["version"]["SIM_ICCID"], 20)
self.data["version"]["VIN"] = strAddSpace(self.data["version"]["VIN"], 17)
msg = verObj.generateMsg_GUI(msgID="0205",phoneNum=int(self.data["phoneNum"]),msgWaterCode=self.sn,encryptionType=0,subPkg=0, \
softwareVersion=self.data["version"]["softwareVersion"], softwareVersionDate=self.data["version"]["softwareVersionDate"], CPUId=self.data["version"]["CPUId"], \
GMSType=self.data["version"]["GMSType"], GMS_IMEI=self.data["version"]["GMS_IMEI"], SIM_IMSI=self.data["version"]["SIM_IMSI"], \
SIM_ICCID=self.data["version"]["SIM_ICCID"],carType=int(self.data["version"]["carType"]), VIN=self.data["version"]["VIN"], \
totalMileage=int(self.data["version"]["totalMileage"]), totalOilExpend=int(self.data["version"]["totalOilExpend"]), \
displacement=int(self.data["version"]["displacement"]),oilDensity=int(self.data["version"]["oilDensity"]))
self.sendMsg(msg)
self.sn = self.sn + 1
info = self.getCurTime() + " 进行了登录操作"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
########################################################
#车机点火
########################################################
def fireOn(self):
if not os.path.exists("data/messageTools/carData/" + self.carId + ".json"):
psdsObj = MessageSimulaterDataService()
data = psdsObj.genDataTemplate()
psdsObj.writeToFile("data/messageTools/carData/" + self.carId + ".json",data)
#读取车机行驶数据
with open("data/messageTools/carData/" + self.carId + ".json", "r", encoding="utf-8") as fi:
############################# 读取车机的数据 ############################
content = fi.read()
conJson = json.loads(content)
conJson["curDayTravel"]["theMilleage"] = 0 # 本次行驶总里程
conJson["curDayTravel"]["theOil"] = 0 # 本次行驶总油耗
conJson["curDayTravel"]["theTime"] = 0 # 本次行驶总时间
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
dateTimeM = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
dateM = time.strftime("%Y-%m-%d", timeArray)
timeM = time.strftime("%H:%M:%S", timeArray)
dataFile = self.carId + ".json"
self.carDataObj = MessageSimulaterDataService("data/messageTools/carData/", dataFile)
self.carDataObj.setData(conJson)
if dateM == conJson["time"]["date"]:
self.OBDdata["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdata["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
else: #如果不是当天日期,则将日期设置为当天,并写入车辆数据文件
conJson["curDayTravel"]["todayTotalMilleage"] = 0 # 今日行驶总里程
conJson["curDayTravel"]["todayTotalOil"] = 0 # 今日行驶总油耗
conJson["curDayTravel"]["todayTotalTime"] = 0 # 今日行驶总时间
self.carDataObj.setTodayTotalMilleage(0)
self.carDataObj.setTodayTodayTotalOil(0)
self.carDataObj.setTodayTodayTotalTime(0)
self.carDataObj.setDateTime2file(dateTimeM)
self.carDataObj.setDate2file(dateM)
self.carDataObj.setTime2file(timeM)
self.OBDdata["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdata["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.carData = conJson
############################# 发送点火数据 ############################
self.setGpsLine()
fireOnParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "0", "directionAngle": "59",
"infoTime": "2020-04-21 18:03:49"}, "extraInfo": {"FA": {"ignition": "on"}}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
fireOnParams["phoneNum"] = self.data["phoneNum"]
fireOnParams["msgWaterCode"] = self.sn
fireOnParams["baseInfo"]["infoTime"] = curTime
fireOnParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
fireOnParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
fireOnParams["baseInfo"]["directionAngle"] = self.getDirAngle()
msgObj = Location_msg()
msg = msgObj.generateMsg_GUI(fireOnParams)
self.sendMsg(msg)
self.sn = self.sn + 1
time.sleep(0.1)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
self.OBDdata["extraInfo"]["EB"]["60C0"] = 0 # 发动机转速
self.OBDdata["extraInfo"]["EB"]["60D0"] = 0 # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.carData["travelData"]["totalOil"] # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.carData["travelData"]["totalTime"] # 总运行时间
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.carData["travelData"]["totalMilleage"] # 总里程
self.OBDdata["extraInfo"]["EB"]["670b"] = self.carData["travelData"]["totalMilleage"] # OBD 累计里程
obdMsg = msgObj.generateMsg_GUI(self.OBDdata)
self.sendMsg(obdMsg)
self.sn = self.sn + 1
info = self.getCurTime() + " 发送了点火事件"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
########################################################
#车机行驶服务
########################################################
def serviceTrave(self):
plusMilleage = 0 #每次增加的里程数,上报的时候要除以100,因为原始文档总里程的单位是0.1km
plusMilleage2 = 0 #每次增加的里程数,用于写入文件 用,写入后置为0
while self.serviceStatus == 1:
gpsMsg = ""
obdMsg = "" #对比比上一次上报,所增加的里程
if self.travelStatus == 0: #行驶服务未启动
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0","pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571,"elevation": "521", "speed": "0",
"directionAngle": "59","infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
elif self.travelStatus == 1: #行驶服务启动
if self.gpsLineIndex < len(self.gpsLine) and self.gpsLineIndex != -1: #如果正向行驶和反向行驶的轨迹点都没有跑完
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0", "pkgCounts": "0",
"baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571, "elevation": "521", "speed": "0",
"directionAngle": "59", "infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
self.OBDdata["extraInfo"]["EA"]["0012"]["dataId_0012"] = int(self.data["travelData"]["votage"]) # 电瓶电压
self.OBDdata["extraInfo"]["EB"]["60C0"] = int(self.data["travelData"]["engineSpeed"]) # 发动机转速
self.OBDdata["extraInfo"]["EB"]["62f0"] = int(self.data["travelData"]["surplusOil"]) # 剩余油量
speed = int(self.data["travelData"]["carSpeed"])
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["extraInfo"]["EB"]["60D0"] = speed # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"] + int((self.sendDur * (speed * 1000 / 3600)) * (1000 / (oilExpend * 1000))) # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"] + self.sendDur # 总运行时间
plusMilleage = plusMilleage + int(self.sendDur * (speed * 1000 / 3600))
plusMilleage2 = int(self.sendDur * (speed * 1000 / 3600))
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.OBDdata["extraInfo"]["01"]["extra_01"] + int(plusMilleage / 100) # 总里程(附加信息)
# OBD 累计里程,如果有该字段,则里程的计算方式使用该字段,如果没有,里程计算方式使用的是附加信息里得到总里程字段
self.OBDdata["extraInfo"]["EB"]["670b"] = self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2) # 总里程(OBD信息,默认使用)
self.OBDdata["extraInfo"]["EB"]["6708"] = int((self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2)) / 1000) # 仪表里程
plusMilleage = plusMilleage - int(plusMilleage / 100) * 100
obdObj = Location_msg()
obdMsg = obdObj.generateMsg_GUI(self.OBDdata)
if self.fixCurPosition == 0:
if self.travelDirection == 0:
if self.gpsLineIndex < len(self.gpsLine):
self.gpsLineIndex = self.gpsLineIndex + 1 # 正向行驶
info = self.getCurTime() + " 纬度:" + str(latitude).replace("\n", "") + " 经度:" + str(longitude).replace("\n", "")
info.replace("\n", "")
print(info)
self.writeToFile("result.txt", info + "\n", 1)
else:
if self.gpsLineIndex > 0:
self.gpsLineIndex = self.gpsLineIndex - 1 # 反向行驶
info = self.getCurTime() + " 纬度:" + str(latitude).replace("\n", "") + " 经度:" + str(longitude).replace("\n", "")
info.replace("\n", "")
print(info)
self.writeToFile("result.txt", info + "\n", 1)
elif self.gpsLineIndex == len(self.gpsLine) or self.gpsLineIndex == -1: #如果反向行驶和反向行驶刚好跑完
if int(self.data["travelData"]["travelLoop"]) == 0: #没有设置循环行驶
self.gpsLineIndex = self.gpsLineIndex - 1
self.stopTravel()
else: #设置了循环行驶
if self.travelDirection == 0:
self.gpsLineIndex = self.gpsLineIndex - 1
self.travelDirection = 1
else:
self.gpsLineIndex = self.gpsLineIndex + 1
self.travelDirection = 0
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0", "pkgCounts": "0",
"baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571, "elevation": "521", "speed": "0",
"directionAngle": "59", "infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
# self.OBDdata["extraInfo"]["EB"]["60C0"] = 3000 # 发动机转速
self.OBDdata["extraInfo"]["EA"]["0012"]["dataId_0012"] = int(self.data["travelData"]["votage"]) # 电瓶电压
self.OBDdata["extraInfo"]["EB"]["60C0"] = int(self.data["travelData"]["engineSpeed"]) # 发动机转速
self.OBDdata["extraInfo"]["EB"]["62f0"] = int(self.data["travelData"]["surplusOil"]) # 剩余油量
speed = int(self.data["travelData"]["carSpeed"])
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["extraInfo"]["EB"]["60D0"] = speed # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"] + int((self.sendDur * (speed * 1000 / 3600)) * (1000 / (oilExpend * 1000))) # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"] + self.sendDur # 总运行时间
plusMilleage = plusMilleage + int(self.sendDur * (speed * 1000 / 3600))
plusMilleage2 = int(self.sendDur * (speed * 1000 / 3600))
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.OBDdata["extraInfo"]["01"]["extra_01"] + int(plusMilleage / 100) # 总里程
# OBD 累计里程,如果有该字段,则里程的计算方式使用该字段,如果没有,里程计算方式使用的是附加信息里得到总里程字段
self.OBDdata["extraInfo"]["EB"]["670b"] = self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2) # 总里程(OBD信息,默认使用)
self.OBDdata["extraInfo"]["EB"]["6708"] = int((self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2)) / 1000) # 仪表里程
plusMilleage = plusMilleage - int(plusMilleage / 100) * 100
obdObj = Location_msg()
obdMsg = obdObj.generateMsg_GUI(self.OBDdata)
self.carDataObj.setTodayTotalMilleage(self.carData["curDayTravel"]["todayTotalMilleage"] + plusMilleage2)
self.carDataObj.setTheMilleage(self.carData["curDayTravel"]["theMilleage"] + plusMilleage2)
self.carDataObj.setTotalMilleage(self.carData["travelData"]["totalMilleage"] + plusMilleage2)
temp = self.OBDdata["extraInfo"]["01"]["extra_01"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = temp
self.carDataObj.setTodayTodayTotalOil(self.carData["curDayTravel"]["todayTotalOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.carDataObj.setTheOil(self.carData["curDayTravel"]["theOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.carDataObj.setTotalOil(self.carData["travelData"]["totalOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.OBDdataOri["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"]
self.carDataObj.setTodayTodayTotalTime(self.carData["curDayTravel"]["todayTotalTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.carDataObj.setTheTime(self.carData["curDayTravel"]["theTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.carDataObj.setTotalTime(self.carData["travelData"]["totalTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.OBDdataOri["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"]
if obdMsg != "":
self.sendMsg(obdMsg)
self.sn = self.sn + 1
if gpsMsg != "":
time.sleep(0.1)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
sleep(self.sendDur)
########################################################
#车机熄火
########################################################
def fireOff(self):
gpsLineIndex = self.gpsLineIndex
if gpsLineIndex >= len(self.gpsLine):
gpsLineIndex = gpsLineIndex - 1
fireOffParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "0", "directionAngle": "59",
"infoTime": "2020-04-21 18:09:34"}, "extraInfo": {"FA": {"flameout": "on"}}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
fireOffParams["phoneNum"] = self.data["phoneNum"]
fireOffParams["msgWaterCode"] = self.sn
fireOffParams["baseInfo"]["infoTime"] = curTime
fireOffParams["baseInfo"]["latitude"] = self.gpsLine[gpsLineIndex]["lat"]
fireOffParams["baseInfo"]["longtitude"] = self.gpsLine[gpsLineIndex]["lng"]
fireOffParams["baseInfo"]["directionAngle"] = self.getDirAngle()
msgObj = Location_msg()
msg = msgObj.generateMsg_GUI(fireOffParams)
self.sendMsg(msg)
self.sn = self.sn + 1
info = self.getCurTime() + " 发送了熄火事件:"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
########################################################
# 接收消息的服务
########################################################
def serviceRev(self):
self.serviceStatus = 2 #2代表只启动了接收消息的进程,1代表了接收和发送都启动了
while self.serviceStatus != 0:
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
self.socket.setTimeOut(self.timeout)
d = self.revMsg()
d = str(binascii.b2a_hex(d))[2:][:-1]
########################################################
#关闭车机的连接
########################################################
def closeSocket(self):
try:
self.socket.close()
except BaseException as e:
# 打印异常信息
traceback.print_exc
########################################################
#获取收到消息的功能id
########################################################
def getMsgFunId(self,msg):
funId = msg[2:6]
return funId
#设置GPS轨迹
def setGpsLine(self):
fileName = self.getRandomGpsLine()
with open("data/messageTools/GPSLines/" + fileName,"r",encoding="utf-8") as fi:
content = fi.read()
conJson = json.loads(content)
self.gpsLine = conJson["GPSLine"]
self.gpsLineIndex = 0
info = self.getCurTime() + " 当前设置了GPS轨迹:" + fileName
print(info)
self.writeToFile("result.txt", info + "\n", 1)
# #设置GPS轨迹
# def setGpsLine(self,fileName):
# with open("data/messageTools/GPSLines/" + fileName,"r",encoding="utf-8") as fi:
# content = fi.read()
# conJson = json.loads(content)
# self.gpsLine = conJson["GPSLine"]
#随机获取一条GPS 轨迹
def getRandomGpsLine(self):
files = os.listdir("data/messageTools/GPSLines/")
filesLen = len(files)
whichF = random.randint(0,filesLen - 1)
return files[whichF]
########################################################
#启动接收消息的服务
########################################################
def startReciveService(self):
t2 = threading.Thread(target=self.serviceRev, args=())
t2.start()
########################################################
# 开启发送消息的服务
########################################################
def startService(self):
self.serviceStatus = 1
self.travelStatus = 1
self.serviceTrave()
# t1 = threading.Thread(target=self.serviceTrave,args=())
# t1.start()
########################################################
#停止发送消息的服务
########################################################
def stopService(self):
self.serviceStatus = 0
self.gpsLine = []
self.gpsLineIndex = 0
self.travelStatus = 0
########################################################
# 开始行驶
########################################################
def startTravel(self):
self.travelStatus = 1
########################################################
# 停止行驶
########################################################
def stopTravel(self):
self.fireOff()
self.travelStatus = 0
self.serviceStatus = 0
self.gpsLine = []
self.gpsLineIndex = 0
self.socket.close()
info = self.getCurTime() + " 执行了停止行驶服务"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
###########################################################
#获取方向角
###########################################################
def getDirAngle(self):
dire = self.directAngle
if self.travelDirection == 0:
if self.gpsLineIndex == 0:
return int(self.directAngle)
lngCut = (float(self.gpsLine[self.gpsLineIndex]["lng"]) - float(self.gpsLine[self.gpsLineIndex - 1]["lng"])) * 1000000
latCut = (float(self.gpsLine[self.gpsLineIndex]["lat"]) - float(self.gpsLine[self.gpsLineIndex - 1]["lat"])) * 1000000
if latCut == 0: #除数维度不能为0
latCut = 1
if lngCut == 0 or latCut == 0:
return int(self.directAngle)
val = lngCut / latCut
dire = math.atan2(1, val) * 180 / math.pi
if lngCut > 0 and latCut > 0:
dire = 90 - dire
if lngCut < 0 and latCut > 0:
dire = 270 + 180 - dire
elif latCut < 0 and lngCut > 0:
dire = 270 - dire
elif lngCut < 0 and latCut < 0:
dire = 180 + 90 - dire
self.directAngle = dire
elif self.travelDirection == 1:
if self.gpsLineIndex == (len(self.gpsLine) - 1):
return int(self.directAngle)
lngCut = (float(self.gpsLine[self.gpsLineIndex]["lng"]) - float(self.gpsLine[self.gpsLineIndex + 1]["lng"])) * 1000000
latCut = (float(self.gpsLine[self.gpsLineIndex]["lat"]) - float(self.gpsLine[self.gpsLineIndex + 1]["lat"])) * 1000000
if latCut == 0: #除数维度不能为0
latCut = 1
if lngCut == 0 or latCut == 0:
return int(self.directAngle)
val = lngCut / latCut
dire = math.atan2(1, val) * 180 / math.pi
if lngCut > 0 and latCut > 0:
dire = 90 - dire
if lngCut < 0 and latCut > 0:
dire = 270 + 180 - dire
elif latCut < 0 and lngCut > 0:
dire = 270 - dire
elif lngCut < 0 and latCut < 0:
dire = 180 + 90 - dire
self.directAngle = dire
return int(dire)
########################################################
# 判断是否满足定时器条件(用来启动模拟程序服务)
########################################################
def isTimerStart(self,year=0,month=0,day=0,hour=0,minute=0,second=0):
if year == 0 and month == 0 and hour == 0 and minute == 0 and second == 0:
raise Exception("所传值不可都为0 !")
if type(year) == str or type(month) == str or type(day) == str or type(hour) == str or type(minute) == str or type(second) == str:
raise Exception("请传入数字 !")
timeS = int(time.time())
timeArray = time.localtime(timeS)
time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
theYear = int(time.strftime("%Y", timeArray))
theMonth = int(time.strftime("%m", timeArray))
theDay = int(time.strftime("%d", timeArray))
theHour = int(time.strftime("%H", timeArray))
theMinute = int(time.strftime("%M", timeArray))
theSecond = int(time.strftime("%S", timeArray))
if year == 0 or year == theYear:
if month == 0 or month == theMonth:
if day == 0 or day == theDay:
if hour == 0 or hour == theHour:
if minute == 0 or minute == theMinute:
if second == 0 or second == theSecond:
return True
else:
return False
else:
return False
else:
return False
else:
return False
else:
return False
else:
return False
def writeToFile(self,path,data,type=1): #:代表追加 0:代表覆盖
if(type == 1):
with open(path, "a", encoding='utf-8') as fi:
fi.write(data)
else:
with open(path, "w", encoding='utf-8') as fi:
fi.write(data)
def getCurTime(self):
curTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
return "[" + curTime + "]"
########################################################
# 启动模拟程序服务
########################################################
def startTravelService(self,year=0,month=0,day=0,hour=0,minute=0,second=2):
timeS = int(time.time())
timeArray = time.localtime(timeS)
datetime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
info = "[" + datetime + "]" + " 启动了模拟程序\n"
print(info)
self.writeToFile("result.txt", info, 0)
while True:
if self.isTimerStart(year,month,day,hour,minute,second):
try:
self.sn = 1
self.connectService()
# self.startReciveService() #启动接收消息服务
self.carLogin()
time.sleep(0.5)
self.fireOn()
time.sleep(2)
self.startService()
except BaseException as e:
timeS = int(time.time())
timeArray = time.localtime(timeS)
datetime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
err = traceback.format_exc()
self.writeToFile("data/log1.txt", "[" + datetime + "]", type=1)
self.writeToFile("data/log1.txt", err, type=1)
else:
time.sleep(0.5)
if __name__ == "__main__":
pass
#coding:utf-8
##################################################
# 定义车安优 车机行驶过程中产生的数据类
##################################################
import datetime
import json
import time
class MessageSimulaterDataService():
def __init__(self,path="/data/protocolTools/carData/",fileName="default.json"):
self.data = {}
self.path = path #保存车机数据文件地址
self.fileName = fileName #保存车机数据文件
def setPath(self,data):
self.path = data
def setFileName(self,data):
self.fileName = data
def setData(self,data):
self.data = data
####################################################
# 生成一个默认数据模板
####################################################
def genDataTemplate(self):
data = {}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
data["time"] = {} #定义时间数据项
data["time"]["dateTime"] = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
data["time"]["date"] = time.strftime("%Y-%m-%d", timeArray)
data["time"]["time"] = time.strftime("%H:%M:%S", timeArray)
data["curDayTravel"] = {} #定义当天行驶数据项
data["curDayTravel"]["todayTotalMilleage"] = 0 #今日行驶总里程
data["curDayTravel"]["todayTotalOil"] = 0 #今日行驶总油耗
data["curDayTravel"]["todayTotalTime"] = 0 #今日行驶总时间
data["curDayTravel"]["theMilleage"] = 0 #本次行驶总里程
data["curDayTravel"]["theOil"] = 0 #本次行驶总油耗
data["curDayTravel"]["theTime"] = 0 #本次行驶总时间
data["travelData"] = {} #定义所有行驶数据
data["travelData"]["totalMilleage"] = 0 #行驶总里程
data["travelData"]["totalOil"] = 0 #行驶总油耗
data["travelData"]["totalTime"] = 0 #行驶总时间
return data
#设今日行驶总里程,同时写入文件
def setTodayTotalMilleage(self,data):
self.data["curDayTravel"]["todayTotalMilleage"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设今日行驶总油耗,同时写入文件
def setTodayTodayTotalOil(self,data):
self.data["curDayTravel"]["todayTotalOil"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设今日行驶总时间,同时写入文件
def setTodayTodayTotalTime(self,data):
self.data["curDayTravel"]["todayTotalTime"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设本次行驶总里程,同时写入文件
def setTheMilleage(self,data):
self.data["curDayTravel"]["theMilleage"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设本次行驶总油耗,同时写入文件
def setTheOil(self,data):
self.data["curDayTravel"]["theOil"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设本次行驶总时间,同时写入文件
def setTheTime(self,data):
self.data["curDayTravel"]["theTime"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设总里程,同时写入文件
def setTotalMilleage(self,data):
self.data["travelData"]["totalMilleage"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设总油耗,同时写入文件
def setTotalOil(self,data):
self.data["travelData"]["totalOil"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设总时间,同时写入文件
def setTotalTime(self,data):
self.data["travelData"]["totalTime"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设今日日期时间
def setDateTime2file(self,data):
self.data["time"]["dateTime"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设今日日期
def setDate2file(self,data):
self.data["time"]["date"] = data
self.writeToFile(self.path + self.fileName,self.data)
#设今日时间
def setTime2file(self,data):
self.data["time"]["time"] = data
self.writeToFile(self.path + self.fileName,self.data)
####################################################
# 将数据写入文件
####################################################
def writeToFile(self,path,data):
with open(path,"w",encoding="utf-8") as fi:
data = json.dumps(data)
fi.write(data)
####################################################
# 从文件读取数据
####################################################
def readFromFile(self,path):
with open(path, "r", encoding="utf-8") as fi:
content = fi.read()
conJson = json.loads(content)
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
dateTimeM = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
dateM = time.strftime("%Y-%m-%d", timeArray)
timeM = time.strftime("%H:%M:%S", timeArray)
if dateM == conJson["time"]["date"]:
pass
else: #如果不是当天日期,则将日期设置为当天
conJson["time"]["dateTime"] = dateTimeM
conJson["time"]["date"] = dateM
conJson["time"]["time"] = timeM
data["curDayTravel"]["todayTotalMilleage"] = 0 # 今日行驶总里程
data["curDayTravel"]["todayTotalOil"] = 0 # 今日行驶总油耗
data["curDayTravel"]["todayTotalTime"] = 0 # 今日行驶总时间
self.setTodayTotalMilleage(0)
self.setTodayTodayTotalOil(0)
self.setTodayTodayTotalTime(0)
self.setDateTime2file(dateTimeM)
self.setDate2file(dateM)
self.setTime2file(timeM)
self.data = conJson
if __name__ == "__main__":
print(MessageSimulaterDataService().genDataTemplate())
data = MessageSimulaterDataService().genDataTemplate()
MessageSimulaterDataService().writeToFile("../../../data/protocolTools/carData/M202003060520.json",data)
\ No newline at end of file
#coding:utf-8
'''
新硬件车机模拟服务类
'''
import binascii
import json
import math
import os
import threading
import time
import traceback
from time import sleep
from lib.protocol.message.Location_msg import Location_msg
from lib.protocol.message.TerminalRegister_msg import TerminalRegister_msg
from lib.protocol.message.TerminalRequestOBDInfo_msg import TerminalRequestOBDInfo_msg
from lib.protocol.message.TerminalVersionInfo_msg import TerminalVersionInfo_msg
from lib.protocol.message.response.QueryTheTerminalParam_res import QueryTheTerminalParam_res
from lib.protocol.messagePlateform.PlateformVersionInfo_res import PlatefromVersionInfo_res
from lib.socket.service.MessageSimulaterDataService import MessageSimulaterDataService
from lib.socket.service.websocket_service import Websocket_service
from lib.util.util import strAddSpace
class MessageSimulaterService():
def __init__(self):
self.data = {} #用来接收模拟器传过来的参数
self.carData = {} #保存车辆行驶数据
self.carDataObj = None #管理车辆行驶数据对象
self.socket = None
self.sendDur = 5 #设置默认多久发一条消息
self.serviceStatus = 0 #服务状态,0表示未启动,1表示启动
self.websocket = None #网页与服务的通信socket
self.websocketId = "" # 当前连接的webSocketId
self.timeout = 1 #socket的超时时间
self.gpsLine = [] #GPS 轨迹
self.gpsLineIndex = 0 #GPS 轨迹索引
self.travelStatus = 0 #0,表示未行驶,1表示开始行驶同时开启了接收消息服务,2表示值开启了接收消息的服务
self.carId = "" #车机号
self.sn = 0 #消息流水号
self.travelDirection = 0 #行驶方向,0表示正向行驶,1表示反向行驶
self.directAngle = 59 #定义默认方向角
self.fixCurPosition = 0 #是否固定当前GPS点,0:不固定 1:固定
# 定义要发送的obd数据
self.OBDdata = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "66", "directionAngle": "59",
"infoTime": "2020-04-23 13:15:37"}, "extraInfo": {"01": {"extra_01": "20202020"},
"EA": {"0012": {"dataId_0012": "36"}},
"EB": {"6010": "2", "6014": "0", "6040": "44", "6050": "76", "6070": "89", "6100": "505", "6110": "51",
"6210": "4508", "6330": "28", "6460": "65", "6490": "32", "6701": "0", "6702": "0", "6703": "1",
"6704": "505", "6705": "1", "6706": "505", "6707": "505", "6708": "3500", "6709": "7200000",
"60C0": "3000", "60D0": "60", "62f0": "801", "60F0": "88", "60B0": "20", "60A0": "276",
"61F0": "3700", "60E0": "154", "670a": "3700000", "670b": "123000"}}}
# 定义初始的obd数据,与上面的OBD数据保持一致,主要用于汽车行驶过程中数据变化量的计算
self.OBDdataOri = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "66", "directionAngle": "59",
"infoTime": "2020-04-23 13:15:37"}, "extraInfo": {"01": {"extra_01": "20202020"},
"EA": {"0012": {"dataId_0012": "36"}},
"EB": {"6010": "2", "6014": "0", "6040": "44", "6050": "76", "6070": "89", "6100": "505", "6110": "51",
"6210": "4508", "6330": "28", "6460": "65", "6490": "32", "6701": "0", "6702": "0", "6703": "1",
"6704": "505", "6705": "1", "6706": "505", "6707": "505", "6708": "3500", "6709": "7200000",
"60C0": "3000", "60D0": "60", "62f0": "801", "60F0": "88", "60B0": "20", "60A0": "276",
"61F0": "3700", "60E0": "154", "670a": "3700000", "670b": "123000"}}}
def getSn(self):
return self.sn
def getWebsocket(self):
return self.websocket
def getTravelStatus(self):
return self.travelStatus
def getCurLatitude(self):
return self.gpsLine[self.gpsLineIndex]["lat"]
def getCurLongtitude(self):
return self.gpsLine[self.gpsLineIndex]["lng"]
def getTravelDirection(self):
return self.travelDirection
def getGpsLine(self):
return self.gpsLine
def getGpsLineIndex(self):
return self.gpsLineIndex
#设置套接字
def setSocket(self,data):
self.socket = data
def setSendDur(self,data):
self.sendDur = data
def setTimeout(self,data):
self.timeout = data
def setCarId(self,data):
self.carId = data
def setData(self,data):
self.data = data
def setWebsocketId(self):
sleep(1)
self.websocketId = self.websocket.getCurrentClientId()
def setWebsocket(self,data):
self.websocket = data
def setSn(self,data):
self.sn = data
def setCarSpeed(self,data):
self.data["travelData"]["carSpeed"] = data
def setOilExpend(self,data):
self.data["travelData"]["oilExpend"] = data
def setSendDur(self,data):
self.sendDur = data
def setTravelDirection(self,data):
self.travelDirection = data
def setFixCurPosition(self,data):
self.fixCurPosition = data
def setVotage(self,data):
self.data["travelData"]["votage"] = data
def setEngineSpeed(self,data):
self.data["travelData"]["engineSpeed"] = data
def setSurplusOil(self,data):
self.data["travelData"]["surplusOil"] = data
def sendMsg(self,msg):
self.socket.setTimeOut(self.timeout)
self.socket.send(msg)
def revMsg(self):
self.socket.setTimeOut(self.timeout)
return self.socket.receive()
#websocket向网页发送消息
def serviceSendMsg(self,msg):
self.sendMsg(msg)
type = self.getMsgFunId(msg)
self.websocket.sendMsgToClient(">>>>" + type + ":" + msg,self.websocketId)
########################################################
#车机登录
########################################################
def carLogin(self):
loginObj = TerminalRegister_msg()
self.data["login"]["manufacturerId"] = strAddSpace(self.data["login"]["manufacturerId"],5)
self.data["login"]["terminalType"] = strAddSpace(self.data["login"]["terminalType"], 20)
self.data["login"]["terminalId"] = strAddSpace(self.data["login"]["terminalId"], 7)
msg = loginObj.generateMsg_GUI(msgID="0100",phoneNum=int(self.data["phoneNum"]),msgWaterCode=self.sn,encryptionType=0,subPkg=0,provinceId=int(self.data["login"]["provinceId"]),\
countyId=int(self.data["login"]["countyId"]),manufacturerId=self.data["login"]["manufacturerId"],terminalType=self.data["login"]["terminalType"], \
terminalId=self.data["login"]["terminalId"],licencePlateColor=int(self.data["login"]["licencePlateColor"]),carSign=self.data["login"]["carSign"])
self.sendMsg(msg)
type = self.getMsgFunId(msg)
info = type + ">>>>:" + msg
self.websocket.sendMsgToClient(info,self.websocketId)
self.sn = self.sn + 1
verObj = TerminalVersionInfo_msg()
time.sleep(0.5)
self.data["version"]["softwareVersion"] = strAddSpace(self.data["version"]["softwareVersion"], 14)
self.data["version"]["CPUId"] = strAddSpace(self.data["version"]["CPUId"], 12)
self.data["version"]["GMSType"] = strAddSpace(self.data["version"]["GMSType"], 15)
self.data["version"]["GMS_IMEI"] = strAddSpace(self.data["version"]["GMS_IMEI"], 15)
self.data["version"]["SIM_IMSI"] = strAddSpace(self.data["version"]["SIM_IMSI"], 15)
self.data["version"]["SIM_ICCID"] = strAddSpace(self.data["version"]["SIM_ICCID"], 20)
self.data["version"]["VIN"] = strAddSpace(self.data["version"]["VIN"], 17)
msg = verObj.generateMsg_GUI(msgID="0205",phoneNum=int(self.data["phoneNum"]),msgWaterCode=self.sn,encryptionType=0,subPkg=0, \
softwareVersion=self.data["version"]["softwareVersion"], softwareVersionDate=self.data["version"]["softwareVersionDate"], CPUId=self.data["version"]["CPUId"], \
GMSType=self.data["version"]["GMSType"], GMS_IMEI=self.data["version"]["GMS_IMEI"], SIM_IMSI=self.data["version"]["SIM_IMSI"], \
SIM_ICCID=self.data["version"]["SIM_ICCID"],carType=int(self.data["version"]["carType"]), VIN=self.data["version"]["VIN"], \
totalMileage=int(self.data["version"]["totalMileage"]), totalOilExpend=int(self.data["version"]["totalOilExpend"]), \
displacement=int(self.data["version"]["displacement"]),oilDensity=int(self.data["version"]["oilDensity"]))
self.sendMsg(msg)
type = self.getMsgFunId(msg)
info = type + ">>>>:" + msg
self.websocket.sendMsgToClient(info,self.websocketId)
self.sn = self.sn + 1
########################################################
#车机点火
########################################################
def fireOn(self):
if not os.path.exists("data/messageTools/carData/" + self.carId + ".json"):
psdsObj = MessageSimulaterDataService()
data = psdsObj.genDataTemplate()
psdsObj.writeToFile("data/messageTools/carData/" + self.carId + ".json",data)
#读取车机行驶数据
with open("data/messageTools/carData/" + self.carId + ".json", "r", encoding="utf-8") as fi:
############################# 读取车机的数据 ############################
content = fi.read()
conJson = json.loads(content)
conJson["curDayTravel"]["theMilleage"] = 0 # 本次行驶总里程
conJson["curDayTravel"]["theOil"] = 0 # 本次行驶总油耗
conJson["curDayTravel"]["theTime"] = 0 # 本次行驶总时间
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
dateTimeM = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
dateM = time.strftime("%Y-%m-%d", timeArray)
timeM = time.strftime("%H:%M:%S", timeArray)
dataFile = self.carId + ".json"
self.carDataObj = MessageSimulaterDataService("data/messageTools/carData/", dataFile)
self.carDataObj.setData(conJson)
if dateM == conJson["time"]["date"]:
self.OBDdata["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdata["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
else: #如果不是当天日期,则将日期设置为当天,并写入车辆数据文件
conJson["curDayTravel"]["todayTotalMilleage"] = 0 # 今日行驶总里程
conJson["curDayTravel"]["todayTotalOil"] = 0 # 今日行驶总油耗
conJson["curDayTravel"]["todayTotalTime"] = 0 # 今日行驶总时间
self.carDataObj.setTodayTotalMilleage(0)
self.carDataObj.setTodayTodayTotalOil(0)
self.carDataObj.setTodayTodayTotalTime(0)
self.carDataObj.setDateTime2file(dateTimeM)
self.carDataObj.setDate2file(dateM)
self.carDataObj.setTime2file(timeM)
self.OBDdata["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["extraInfo"]["EB"]["670a"] = conJson["travelData"]["totalOil"]
self.OBDdata["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["extraInfo"]["EB"]["6709"] = conJson["travelData"]["totalTime"]
self.carData = conJson
############################# 发送点火数据 ############################
self.setGpsLine(self.data["gpsLine"])
fireOnParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "0", "directionAngle": "59",
"infoTime": "2020-04-21 18:03:49"}, "extraInfo": {"FA": {"ignition": "on"}}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
fireOnParams["phoneNum"] = self.data["phoneNum"]
fireOnParams["msgWaterCode"] = self.sn
fireOnParams["baseInfo"]["infoTime"] = curTime
fireOnParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
fireOnParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
fireOnParams["baseInfo"]["directionAngle"] = self.getDirAngle()
msgObj = Location_msg()
msg = msgObj.generateMsg_GUI(fireOnParams)
self.sendMsg(msg)
type = self.getMsgFunId(msg)
info = type + ">>>>:" + msg
self.websocket.sendMsgToClient(info,self.websocketId)
self.sn = self.sn + 1
time.sleep(0.1)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
self.OBDdata["extraInfo"]["EB"]["60C0"] = 0 # 发动机转速
self.OBDdata["extraInfo"]["EB"]["60D0"] = 0 # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.carData["travelData"]["totalOil"] # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.carData["travelData"]["totalTime"] # 总运行时间
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.carData["travelData"]["totalMilleage"] # 总里程
self.OBDdata["extraInfo"]["EB"]["670b"] = self.carData["travelData"]["totalMilleage"] # OBD 累计里程
obdMsg = msgObj.generateMsg_GUI(self.OBDdata)
self.sendMsg(obdMsg)
type = self.getMsgFunId(obdMsg)
info = type + ">>>>:" + obdMsg
self.websocket.sendMsgToClient(info,self.websocketId)
self.sn = self.sn + 1
########################################################
#车机行驶服务
########################################################
def serviceTrave(self):
plusMilleage = 0 #每次增加的里程数,上报的时候要除以100,因为原始文档总里程的单位是0.1km
plusMilleage2 = 0 #每次增加的里程数,用于写入文件 用,写入后置为0
while self.serviceStatus == 1:
gpsMsg = ""
obdMsg = "" #对比比上一次上报,所增加的里程
if self.travelStatus == 0: #行驶服务未启动
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0","pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571,"elevation": "521", "speed": "0",
"directionAngle": "59","infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
elif self.travelStatus == 1: #行驶服务启动
if self.gpsLineIndex < len(self.gpsLine) and self.gpsLineIndex != -1: #如果正向行驶和反向行驶的轨迹点都没有跑完
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0", "pkgCounts": "0",
"baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571, "elevation": "521", "speed": "0",
"directionAngle": "59", "infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
self.OBDdata["extraInfo"]["EA"]["0012"]["dataId_0012"] = int(self.data["travelData"]["votage"]) # 电瓶电压
self.OBDdata["extraInfo"]["EB"]["60C0"] = int(self.data["travelData"]["engineSpeed"]) # 发动机转速
self.OBDdata["extraInfo"]["EB"]["62f0"] = int(self.data["travelData"]["surplusOil"]) # 剩余油量
speed = int(self.data["travelData"]["carSpeed"])
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["extraInfo"]["EB"]["60D0"] = speed # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"] + int((self.sendDur * (speed * 1000 / 3600)) * (1000 / (oilExpend * 1000))) # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"] + self.sendDur # 总运行时间
plusMilleage = plusMilleage + int(self.sendDur * (speed * 1000 / 3600))
plusMilleage2 = int(self.sendDur * (speed * 1000 / 3600))
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.OBDdata["extraInfo"]["01"]["extra_01"] + int(plusMilleage / 100) # 总里程(附加信息)
# OBD 累计里程,如果有该字段,则里程的计算方式使用该字段,如果没有,里程计算方式使用的是附加信息里得到总里程字段
self.OBDdata["extraInfo"]["EB"]["670b"] = self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2) # 总里程(OBD信息,默认使用)
self.OBDdata["extraInfo"]["EB"]["6708"] = int((self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2)) / 1000) # 仪表里程
plusMilleage = plusMilleage - int(plusMilleage / 100) * 100
obdObj = Location_msg()
obdMsg = obdObj.generateMsg_GUI(self.OBDdata)
if self.fixCurPosition == 0:
if self.travelDirection == 0:
if self.gpsLineIndex < len(self.gpsLine):
self.gpsLineIndex = self.gpsLineIndex + 1 # 正向行驶
else:
if self.gpsLineIndex > 0:
self.gpsLineIndex = self.gpsLineIndex - 1 # 反向行驶
elif self.gpsLineIndex == len(self.gpsLine) or self.gpsLineIndex == -1: #如果反向行驶和反向行驶刚好跑完
if int(self.data["travelData"]["travelLoop"]) == 0: #没有设置循环行驶
self.gpsLineIndex = self.gpsLineIndex - 1
self.stopTravel()
self.websocket.sendMsgToClient("gps轨迹跑完,自动停止行驶!",self.websocketId)
else: #设置了循环行驶
if self.travelDirection == 0:
self.gpsLineIndex = self.gpsLineIndex - 1
self.travelDirection = 1
self.websocket.sendMsgToClient("gps轨迹正向行驶跑完,变换行驶方向......",self.websocketId)
else:
self.gpsLineIndex = self.gpsLineIndex + 1
self.travelDirection = 0
self.websocket.sendMsgToClient("gps轨迹反向行驶跑完,变换行驶方向......",self.websocketId)
gpsParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0",
"subPkg": "0", "pkgCounts": "0",
"baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133,
"longtitude": 106.586571, "elevation": "521", "speed": "0",
"directionAngle": "59", "infoTime": "2020-04-21 18:09:34"},
"extraInfo": {}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsParams["phoneNum"] = self.data["phoneNum"]
gpsParams["msgWaterCode"] = self.sn
gpsParams["baseInfo"]["infoTime"] = curTime
gpsParams["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
gpsParams["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
gpsParams["baseInfo"]["speed"] = int(self.data["travelData"]["carSpeed"]) * 10
gpsParams["baseInfo"]["directionAngle"] = self.getDirAngle()
gpsObj = Location_msg()
gpsMsg = gpsObj.generateMsg_GUI(gpsParams)
self.OBDdata["phoneNum"] = self.data["phoneNum"]
self.OBDdata["msgWaterCode"] = self.sn
self.OBDdata["baseInfo"]["infoTime"] = curTime
self.OBDdata["baseInfo"]["latitude"] = self.gpsLine[self.gpsLineIndex]["lat"]
self.OBDdata["baseInfo"]["longtitude"] = self.gpsLine[self.gpsLineIndex]["lng"]
self.OBDdata["baseInfo"]["directionAngle"] = self.getDirAngle()
# self.OBDdata["extraInfo"]["EB"]["60C0"] = 3000 # 发动机转速
self.OBDdata["extraInfo"]["EA"]["0012"]["dataId_0012"] = int(self.data["travelData"]["votage"]) # 电瓶电压
self.OBDdata["extraInfo"]["EB"]["60C0"] = int(self.data["travelData"]["engineSpeed"]) # 发动机转速
self.OBDdata["extraInfo"]["EB"]["62f0"] = int(self.data["travelData"]["surplusOil"]) # 剩余油量
speed = int(self.data["travelData"]["carSpeed"])
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["extraInfo"]["EB"]["60D0"] = speed # 车速
self.OBDdata["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"] + int((self.sendDur * (speed * 1000 / 3600)) * (1000 / (oilExpend * 1000))) # 总油耗
self.OBDdata["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"] + self.sendDur # 总运行时间
plusMilleage = plusMilleage + int(self.sendDur * (speed * 1000 / 3600))
plusMilleage2 = int(self.sendDur * (speed * 1000 / 3600))
self.OBDdata["extraInfo"]["01"]["extra_01"] = self.OBDdata["extraInfo"]["01"]["extra_01"] + int(plusMilleage / 100) # 总里程
# OBD 累计里程,如果有该字段,则里程的计算方式使用该字段,如果没有,里程计算方式使用的是附加信息里得到总里程字段
self.OBDdata["extraInfo"]["EB"]["670b"] = self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2) # 总里程(OBD信息,默认使用)
self.OBDdata["extraInfo"]["EB"]["6708"] = int((self.OBDdata["extraInfo"]["EB"]["670b"] + int(plusMilleage2)) / 1000) # 仪表里程
plusMilleage = plusMilleage - int(plusMilleage / 100) * 100
obdObj = Location_msg()
obdMsg = obdObj.generateMsg_GUI(self.OBDdata)
self.carDataObj.setTodayTotalMilleage(self.carData["curDayTravel"]["todayTotalMilleage"] + plusMilleage2)
self.carDataObj.setTheMilleage(self.carData["curDayTravel"]["theMilleage"] + plusMilleage2)
self.carDataObj.setTotalMilleage(self.carData["travelData"]["totalMilleage"] + plusMilleage2)
temp = self.OBDdata["extraInfo"]["01"]["extra_01"]
self.OBDdataOri["extraInfo"]["01"]["extra_01"] = temp
self.carDataObj.setTodayTodayTotalOil(self.carData["curDayTravel"]["todayTotalOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.carDataObj.setTheOil(self.carData["curDayTravel"]["theOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.carDataObj.setTotalOil(self.carData["travelData"]["totalOil"] + self.OBDdata["extraInfo"]["EB"]["670a"] - self.OBDdataOri["extraInfo"]["EB"]["670a"])
self.OBDdataOri["extraInfo"]["EB"]["670a"] = self.OBDdata["extraInfo"]["EB"]["670a"]
self.carDataObj.setTodayTodayTotalTime(self.carData["curDayTravel"]["todayTotalTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.carDataObj.setTheTime(self.carData["curDayTravel"]["theTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.carDataObj.setTotalTime(self.carData["travelData"]["totalTime"] + self.OBDdata["extraInfo"]["EB"]["6709"] - self.OBDdataOri["extraInfo"]["EB"]["6709"])
self.OBDdataOri["extraInfo"]["EB"]["6709"] = self.OBDdata["extraInfo"]["EB"]["6709"]
if obdMsg != "":
self.sendMsg(obdMsg)
self.sn = self.sn + 1
type = self.getMsgFunId(obdMsg)
info = type + ">>>>:" + obdMsg
self.websocket.sendMsgToClient(info,self.websocketId)
if gpsMsg != "":
time.sleep(0.1)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
type = self.getMsgFunId(gpsMsg)
info = type + ">>>>:" + gpsMsg
self.websocket.sendMsgToClient(info,self.websocketId)
sleep(self.sendDur)
########################################################
#车机熄火
########################################################
def fireOff(self):
gpsLineIndex = self.gpsLineIndex
if gpsLineIndex >= len(self.gpsLine):
gpsLineIndex = gpsLineIndex - 1
fireOffParams = {"msgID": "0200", "phoneNum": "13146201119", "msgWaterCode": "1", "encryptionType": "0", "subPkg": "0",
"pkgCounts": "0", "baseInfo": {"alarmFlag": 0, "status": 262402, "latitude": 29.569133, "longtitude": 106.586571,
"elevation": "521", "speed": "0", "directionAngle": "59",
"infoTime": "2020-04-21 18:09:34"}, "extraInfo": {"FA": {"flameout": "on"}}}
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
fireOffParams["phoneNum"] = self.data["phoneNum"]
fireOffParams["msgWaterCode"] = self.sn
fireOffParams["baseInfo"]["infoTime"] = curTime
fireOffParams["baseInfo"]["latitude"] = self.gpsLine[gpsLineIndex]["lat"]
fireOffParams["baseInfo"]["longtitude"] = self.gpsLine[gpsLineIndex]["lng"]
fireOffParams["baseInfo"]["directionAngle"] = self.getDirAngle()
msgObj = Location_msg()
msg = msgObj.generateMsg_GUI(fireOffParams)
self.sendMsg(msg)
type = self.getMsgFunId(msg)
info = type + ">>>>:" + msg
self.websocket.sendMsgToClient(info,self.websocketId)
self.sn = self.sn + 1
########################################################
#启动与页面交互的websockt服务
########################################################
def websocketService(self):
self.websocket = Websocket_service()
self.websocket.setHost("0.0.0.0")
self.websocket.setPort(5007)
self.websocket.startWebsocketServer()
########################################################
# 接收消息的服务
########################################################
def serviceRev(self):
self.serviceStatus = 2 #2代表只启动了接收消息的进程,1代表了接收和发送都启动了
while self.serviceStatus != 0:
timeStamp = time.time()
timeArray = time.localtime(timeStamp)
curTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
self.socket.setTimeOut(self.timeout)
d = self.revMsg()
d = str(binascii.b2a_hex(d))[2:][:-1]
type = self.getMsgFunId(d)
info = type + "<<<<:" + d
self.websocket.sendMsgToClient(info,self.websocketId)
self.doResponse(d)
########################################################
#启动与页面交互的websocket服务
########################################################
def startWebsocketService(self):
if self.websocket == None:
t = threading.Thread(target=self.websocketService, args=())
t.start()
t3 = threading.Thread(target=self.setWebsocketId, args=())
t3.start()
# 为websocket服务添加一个新的客户端连接
def addNewWebsocket(self):
t3 = threading.Thread(target=self.setWebsocketId, args=())
t3.start()
########################################################
#停止websocket服务
########################################################
def stopWebsocketService(self):
try:
self.websocket.close()
self.websocket = None
except BaseException as e:
# 打印异常信息
traceback.print_exc()
########################################################
#关闭车机的连接
########################################################
def closeSocket(self):
try:
self.socket.close()
except BaseException as e:
# 打印异常信息
traceback.print_exc
########################################################
#获取收到消息的功能id
########################################################
def getMsgFunId(self,msg):
funId = msg[2:6]
return funId
########################################################
#收到 某些类型的消息后执行回复操作
########################################################
def doResponse(self,msg):
msgFunId = self.getMsgFunId(msg)
if msgFunId == "8106":
obj = QueryTheTerminalParam_res()
obj.setMsgRes(msg)
msg = obj.generateMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
type = self.getMsgFunId(msg)
self.websocket.send(type + ">>>>查询终端参数消息应答:" + msg)
elif msgFunId == "8205":
dic = PlatefromVersionInfo_res(msg).getMsg()
OBDCtrType = int(json.loads(dic)["body"]["OBDCtrType"])
if OBDCtrType == 0:
obj = TerminalRequestOBDInfo_msg()
msg = obj.generateMsg_GUI(phoneNum=self.carId,msgWaterCode=self.sn)
self.sendMsg(msg)
self.sn = self.sn + 1
type = self.getMsgFunId(msg)
self.websocket.send(type + ">>>>终端请求OBD适配信息:" + msg)
elif msgFunId == "8206":
pass
#设置GPS轨迹
def setGpsLine(self,fileName):
with open("data/messageTools/GPSLines/" + fileName,"r",encoding="utf-8") as fi:
content = fi.read()
conJson = json.loads(content)
self.gpsLine = conJson["GPSLine"]
########################################################
#启动接收消息的服务
########################################################
def startReciveService(self):
t2 = threading.Thread(target=self.serviceRev, args=())
t2.start()
########################################################
# 开启发送消息的服务
########################################################
def startService(self):
self.serviceStatus = 1
t1 = threading.Thread(target=self.serviceTrave,args=())
t1.start()
########################################################
#停止发送消息的服务
########################################################
def stopService(self):
self.serviceStatus = 0
self.gpsLine = []
self.gpsLineIndex = 0
self.travelStatus = 0
########################################################
# 开始行驶
########################################################
def startTravel(self):
self.travelStatus = 1
########################################################
# 停止行驶
########################################################
def stopTravel(self):
self.travelStatus = 0
self.serviceStatus = 0
###########################################################
#获取方向角
###########################################################
def getDirAngle(self):
dire = self.directAngle
if self.travelDirection == 0:
if self.gpsLineIndex == 0:
return int(self.directAngle)
lngCut = (float(self.gpsLine[self.gpsLineIndex]["lng"]) - float(self.gpsLine[self.gpsLineIndex - 1]["lng"])) * 1000000
latCut = (float(self.gpsLine[self.gpsLineIndex]["lat"]) - float(self.gpsLine[self.gpsLineIndex - 1]["lat"])) * 1000000
if latCut == 0: #除数维度不能为0
latCut = 1
if lngCut == 0 or latCut == 0:
return int(self.directAngle)
val = lngCut / latCut
dire = math.atan2(1, val) * 180 / math.pi
if lngCut > 0 and latCut > 0:
dire = 90 - dire
if lngCut < 0 and latCut > 0:
dire = 270 + 180 - dire
elif latCut < 0 and lngCut > 0:
dire = 270 - dire
elif lngCut < 0 and latCut < 0:
dire = 180 + 90 - dire
self.directAngle = dire
elif self.travelDirection == 1:
if self.gpsLineIndex == (len(self.gpsLine) - 1):
return int(self.directAngle)
lngCut = (float(self.gpsLine[self.gpsLineIndex]["lng"]) - float(self.gpsLine[self.gpsLineIndex + 1]["lng"])) * 1000000
latCut = (float(self.gpsLine[self.gpsLineIndex]["lat"]) - float(self.gpsLine[self.gpsLineIndex + 1]["lat"])) * 1000000
if latCut == 0: #除数维度不能为0
latCut = 1
if lngCut == 0 or latCut == 0:
return int(self.directAngle)
val = lngCut / latCut
dire = math.atan2(1, val) * 180 / math.pi
if lngCut > 0 and latCut > 0:
dire = 90 - dire
if lngCut < 0 and latCut > 0:
dire = 270 + 180 - dire
elif latCut < 0 and lngCut > 0:
dire = 270 - dire
elif lngCut < 0 and latCut < 0:
dire = 180 + 90 - dire
self.directAngle = dire
return int(dire)
#coding:utf-8
#########################################################
#
# 定义图形界面基类,供所有类继承
#
#########################################################
class Base():
def __init__(self):
pass
\ No newline at end of file
#encoding:utf-8
#########################################################
#
# 定义图形界面的基类
#
#########################################################
from lib.ui.Base import Base
class InterfaceBase(Base):
def __init__(self):
pass
\ No newline at end of file
#coding:utf-8
import wx
from lib.ui.InterfaceBase import InterfaceBase
from lib.ui.MyMenubar import MyMenubar
from lib.ui.MyToolsbar import MyToolsbar
'''
定义主窗体
'''
class MainWindow(InterfaceBase):
def __init__(self):
self.app = None
self.frame = None
self.main()
def main(self):
self.app = wx.App()
self.frame = wx.Frame(None,-1, title='socketTools',size = wx.Size(800,700))
#添加设置菜单栏
self.frame.SetMenuBar(MyMenubar(self.frame).createMenuBar())
#添加设置工具栏
self.toolsBar = MyToolsbar(self.frame).createToolsBar()
#创建主窗体布局面板,将主窗体分为几大块
self.createPanel()
#####################################################
# 显示窗体
#####################################################
def show(self):
self.frame.Show()
self.app.MainLoop()
#####################################################
# 创建主窗体的布局面板
#####################################################
def createPanel(self):
# 创建面板
splitter = wx.SplitterWindow(self.frame, wx.ID_ANY)
panel1 = wx.Panel(splitter, wx.ID_ANY)
treeList = wx.TreeCtrl(panel1, wx.ID_ANY, size=(wx.EXPAND, wx.EXPAND))
item1 = treeList.AddRoot("工具汇总")
item11 = treeList.AppendItem(item1, "终端上报报文")
treeList.AppendItem(item1, "远程查询报文")
treeList.AppendItem(item1, "车辆行为模拟")
treeList.AppendItem(item1, "系统设置")
treeList.AppendItem(item11, "GPS上报报文")
treeList.AppendItem(item11, "OBD_CAN上报报文")
treeList.AppendItem(item11, "其他报文")
panel2 = wx.Panel(splitter, wx.ID_ANY)
panel2.SetBackgroundColour("pink")
splitter.SplitVertically(panel1, panel2)
splitter.SetSashPosition(200) #设置水平分割的位置
if __name__ == "__main__":
MainWindow().show()
\ No newline at end of file
#coding:utf-8
import wx
from lib.ui.InterfaceBase import InterfaceBase
'''
定义菜单栏
'''
class MyMenubar(InterfaceBase):
def __init__(self,frame):
self.frame = frame
#####################################################
# wxpython定义菜单栏
#####################################################
def createMenuBar(self):
menuBar = wx.MenuBar()
#《------------------ 开始菜单编码start ---------------------》
#first_ 代表一级菜单,即menubar上显示的菜单
first_menuStart = wx.Menu()
menuItemOpen = first_menuStart.Append(wx.ID_ANY, u"打开 ")
menuItemExit = first_menuStart.Append(wx.ID_ANY, u"退出 ")
self.frame.Bind(wx.EVT_MENU, self.myExit, menuItemExit)
# 《------------------ 开始菜单编码end ---------------------》
menuBar.Append(first_menuStart, u"文件")
return menuBar
def myExit(self,evt):
print(evt)
wx.Exit()
\ No newline at end of file
#coding:utf-8
import wx
from lib.ui.InterfaceBase import InterfaceBase
'''
定义工具条
'''
class MyToolsbar(InterfaceBase):
def __init__(self,frame):
self.frame = frame
#####################################################
# 创建一个工具栏,并返回该对象
#####################################################
# @property
def createToolsBar(self):
toolBar = self.frame.CreateToolBar()
openTool = toolBar.AddTool(wx.ID_ANY, "open",
wx.Bitmap(wx.Image("../../img/folder.png", "image/png").Scale(25, 25),
wx.BITMAP_SCREEN_DEPTH))
startTool = toolBar.AddTool(wx.ID_ANY, "start",
wx.Bitmap(wx.Image("../../img/start.png", "image/png").Scale(25, 25),
wx.BITMAP_SCREEN_DEPTH))
stopTool = toolBar.AddTool(wx.ID_ANY, "stop",
wx.Bitmap(wx.Image("../../img/stop.png", "image/png").Scale(25, 25),
wx.BITMAP_SCREEN_DEPTH))
toolBar.AddSeparator()
infoTool = toolBar.AddTool(wx.ID_ANY, "info",
wx.Bitmap(wx.Image("../../img/info.png", "image/png").Scale(25, 25),
wx.BITMAP_SCREEN_DEPTH))
helpTool = toolBar.AddTool(wx.ID_ANY, "help",
wx.Bitmap(wx.Image("../../img/help.png", "image/png").Scale(25, 25),
wx.BITMAP_SCREEN_DEPTH))
toolBar.Realize()
return toolBar
\ No newline at end of file
#coding: utf-8
import binascii
import os
import socket
import time
class DelaySend():
def __init__(self,din = "M202003060520",service = None):
self.baseUrl = "data/protocolTools/sendMsg/"
self.din = din
self.service = service
def setDin(self,din):
self.din = din
def setServer(self,data):
self.service = data
#####################################################
# 数字转换为16进制字符串
#####################################################
def int2hexString(self,num):
hexStr = hex(num)[2:]
if (len(hexStr) % 2) == 1:
hexStr = "0" + hexStr
return hexStr
#####################################################
# 数字转换为16进制字符串,通过传入字节数可自动补0
# 传入数据格式所占字节数
#####################################################
def int2hexStringByBytes(self,num, bytescount=1):
hexStr = hex(num)[2:]
while len(hexStr) < (bytescount * 2):
hexStr = "0" + hexStr
return hexStr
#####################################################
# 设备id转换为16进制字符串
#####################################################
def devid2hexString(self,id):
# 获取第一个字符的ASCII值
ascii = ord(id[0:1])
# 将10进制的ASCII值转换为16进制
ascii = self.int2hexString(int(ascii))
devid = str(ascii) + id[1:]
return devid
#####################################################
# 定义生成校验字段的函数
# inputStr:需要传入一个已经转换为16进制的字符串
#####################################################
# add crc 16 check at the end of the string
def crc16(self,inputStr):
inputStrByte = bytes.fromhex(inputStr)
crc = 0xFFFF
for i in range(0, len(inputStrByte)):
for j in range(0, 8):
c15 = (crc >> 15) == 1
bit = ((inputStrByte[i] >> (7 - j)) & 1) == 1
crc <<= 1
crc &= 0xFFFF
if c15 ^ bit:
crc ^= 0x1021
crc = str(hex(crc))
crc = self.leftPad(crc[2:], 4)
# outputStr = inputStr + crc
outputStr = crc
return outputStr
# pad zero to the left of the string if not long enough
def leftPad(self,inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = "0000000000000000000000000000000000000000" + inputStr
outputStr = outputStr[len(outputStr) - strLen:]
return outputStr
else:
return inputStr
# pad zero to the right of the string if not long enough
def rightPad(self,inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = inputStr + "0000000000000000000000000000000000000000"
outputStr = outputStr[: strLen]
return outputStr
else:
return inputStr
##############################################################################
def getEventPkg(self):
if os.path.exists(self.baseUrl + self.din + '/event.txt'):
with open(self.baseUrl + self.din + "/event.txt", "r", encoding="utf-8") as fi:
content = fi.readlines()
pkg = ""
msgs = []
pkgCounts = 0
for i in content:
onePkg = i[21:].replace("\n", "")
onePkg = onePkg[30:][:-4]
onePkg = onePkg[2:]
pkg = pkg + onePkg
pkgCounts = pkgCounts + 1
if len(pkg) > 2000:
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0021"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
pkg = ""
pkgCounts = 0
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0021"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
with open(self.baseUrl + self.din + "/event_big.txt", "w", encoding="utf-8") as fi2:
for txt in msgs:
fi2.write(txt + "\n")
return msgs
else:
print("event.txt is not exist")
return ["4040000b00034d1215010100010003f50b"]
def getGpsPkg(self):
if os.path.exists(self.baseUrl + self.din + '/gps.txt'):
with open(self.baseUrl + self.din + "/gps.txt", "r", encoding="utf-8") as fi:
content = fi.readlines()
pkg = ""
msgs = []
pkgCounts = 0
for i in content:
onePkg = i[21:].replace("\n", "")
onePkg = onePkg[30:][:-4]
onePkg = onePkg[2:]
pkg = pkg + onePkg
pkgCounts = pkgCounts + 1
if len(pkg) > 2000:
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0010"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
pkg = ""
pkgCounts = 0
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0010"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
with open(self.baseUrl + self.din + "/gps_big.txt", "w", encoding="utf-8") as fi2:
for txt in msgs:
fi2.write(txt + "\n")
return msgs
else:
print("gps.txt is not exist")
return ["4040000b00034d1215010100010003f50b"]
def getObdPkg(self):
if os.path.exists(self.baseUrl + self.din + '/obd.txt'):
with open(self.baseUrl + self.din + "/obd.txt", "r", encoding="utf-8") as fi:
content = fi.readlines()
pkg = ""
msgs = []
pkgCounts = 0
for i in content:
onePkg = i[21:].replace("\n", "")
onePkg = onePkg[30:][:-4]
onePkg = onePkg[2:]
pkg = pkg + onePkg
pkgCounts = pkgCounts + 1
if len(pkg) > 2000:
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0012"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
pkg = ""
pkgCounts = 0
pkgCounts = self.int2hexStringByBytes(pkgCounts)
HEADER = "4040"
WATER_CODE = self.int2hexStringByBytes(1, 2)
DEV_ID = self.devid2hexString(self.din)
FUN_ID = "0012"
LENGTH = self.int2hexStringByBytes(int(len(WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg) / 2), 2)
CHECK_CODE = self.crc16(HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg)
msg = HEADER + LENGTH + WATER_CODE + DEV_ID + FUN_ID + pkgCounts + pkg + CHECK_CODE
msgs.append(msg)
with open(self.baseUrl + self.din + "/obd_big.txt", "w", encoding="utf-8") as fi2:
for txt in msgs:
fi2.write(txt + "\n")
return msgs
else:
print("obd.txt is not exist")
return ["4040000b00034d1215010100010003f50b"]
def getLenOfFile(self):
with open(self.baseUrl + "event_big.txt", "r", encoding="utf-8") as fi:
data = fi.readline()
print(len(data))
def sendMsg(self,msgs):
for msg in msgs:
msg = msg.replace("\n", "")
self.service.serviceSendMsg(msg,"0")
time.sleep(0.05)
def sendDelayMsgs(self):
time.sleep(0.1)
self.service.websocket.sendMsgToClient("-----------------------发送补报消息【开始】--------------------------",self.service.websocketId)
msg = self.getEventPkg()
self.sendMsg(msg)
time.sleep(0.1)
msg = self.getGpsPkg()
self.sendMsg(msg)
time.sleep(0.1)
msg = self.getObdPkg()
self.sendMsg(msg)
self.service.websocket.sendMsgToClient("-----------------------发送补报消息【结束】--------------------------",self.service.websocketId)
for fi in os.listdir(self.baseUrl + self.din):
os.remove(self.baseUrl + self.din + "/" + fi)
os.rmdir(self.baseUrl + self.din)
#encoding:utf-8
'''
定义平台消息解码辅助类
'''
class MessageDecode():
def __init__(self):
pass
\ No newline at end of file
#coding:utf-8
'''
定义一个处理数据包的辅助方法集合
'''
from binascii import *
from crcmod import *
import struct
#####################################################
# 定义生成校验字段的函数(自己翻译的函数,简化了很多步骤)
#####################################################
def myCrc16(msg):
msg = str2Ascsii(msg)
crc = 0xFFFF
for i in range(0, len(msg)):
for j in range(0, 8):
cl5 = ((crc >> 15 & 1) == 1)
bit = ((msg[i] >> (7 - j) & 1) == 1)
crc <<= 1
# 通过与0xFFFF(即二进制:1111111111111111)做了一个或运算,将其转换为一个有符号的数
crc &= 0xFFFF
if (cl5 ^ bit):
crc ^= 0x1021;
crc = hex(crc) # 将10进制的crc转换为16进制
crc = str(crc)[2:] # 将16进制转换为字符串,并去掉前面的0x
return crc
#####################################################
# 定义生成校验字段的函数
# inputStr:需要传入一个已经转换为16进制的字符串
#####################################################
# add crc 16 check at the end of the string
def crc16(inputStr):
inputStrByte = bytes.fromhex(inputStr)
crc = 0xFFFF
for i in range(0, len(inputStrByte)):
for j in range(0, 8):
c15 = (crc >> 15) == 1
bit = ((inputStrByte[i] >> (7 - j)) & 1) == 1
crc <<= 1
crc &= 0xFFFF
if c15 ^ bit:
crc ^= 0x1021
crc = str(hex(crc))
crc = leftPad(crc[2:], 4)
# outputStr = inputStr + crc
outputStr = crc
return outputStr
# pad zero to the left of the string if not long enough
def leftPad(inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = "0000000000000000000000000000000000000000" + inputStr
outputStr = outputStr[len(outputStr) - strLen:]
return outputStr
else:
return inputStr
# pad zero to the right of the string if not long enough
def rightPad(inputStr, strLen):
if (strLen > len(inputStr)):
outputStr = inputStr + "0000000000000000000000000000000000000000"
outputStr = outputStr[: strLen]
return outputStr
else:
return inputStr
#####################################################
# 将字符串转换为16进制的数字字符串
#####################################################
def str2Hex(s):
s_hex=""
for i in range(len(s)):
s_hex=s_hex+hex(ord(s[i]))[2:]+" "
return s_hex
#####################################################
# 将字符串转换为16进制的数字字符串,并去掉空格
#####################################################
def str2HexStrip(s):
s = str2Hex(s)
s2 = s.replace(" ","")
return s2
#####################################################
# 将字符串转换为对应的ascii值数组
#####################################################
def str2Ascsii(s):
asciiArr = []
for i in range(0,len(s)):
asciiValue = ord(s[i])
asciiArr.append(asciiValue)
return asciiArr
if __name__ == "__main__":
# print(crc16(str2Hex("aa")))
# print(str2Hex("aa"))
# print(str2HexStrip("aa"))
# print(str2Ascsii("aa"))
print(myCrc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
# print(crc16(str2HexStrip("aa")))
#coding:utf-8
'''
文件操作辅助类
'''
import os
###############################################
# 获取目录下的所有文件名
###############################################
def getDirFiles(filePath):
files = os.listdir(filePath)
return files
###############################################
# 获取目录下的所有文件名,去掉前缀
###############################################
def getDirFilesNoPrefix(filePath):
files = os.listdir(filePath)
for i in range(0,len(files)):
files[i] = removeFilePrefix(files[i])
return files
###############################################
# 获取目录下的所有文件名,以map形式
###############################################
def getDirFilesListMap(filePath):
files = os.listdir(filePath)
filesMap = {}
for i in range(len(files) - 1,-1,-1):
filesMap[files[i]] = removeSuffix(removeFilePrefix(files[i]))
return filesMap
###############################################
# 文件名去掉前缀
###############################################
def removeFilePrefix(fileName):
noPrefixFileName = fileName.split("_")[1]
return noPrefixFileName
###############################################
# 获取当前目录前缀最大的文件
###############################################
def getMaxPrefixFile(filePath):
theFileName = getDirFiles(filePath)[-1]
return theFileName
###############################################
# 获取当前目录前缀最大的文件的前缀
###############################################
def getMaxPrefixFilePre(filePath):
fileList = getDirFiles(filePath)
thePrefix = 0
for temp in fileList:
curPrefix = int(temp.split("_")[0])
if thePrefix < curPrefix:
thePrefix = curPrefix
return thePrefix
###############################################
# 去掉文件后缀
###############################################
def removeSuffix(fileName):
theFileName = fileName.split(".")[0]
return theFileName
###############################################
# 删除文件
###############################################
def delFile(path,fileName):
# fi = fileName + ".txt"
fi = fileName
theFile = path + fi
if os.path.exists(theFile):
os.remove(theFile)
# fi = fileName + ".json"
# theFile = path + fi
# if os.path.exists(theFile):
# os.remove(theFile)
if __name__ == "__main__":
# print(getDirFiles("../../data/protocolTools/GPSLines"))
# print(getMaxPrefixFile("../../data/protocolTools/GPSLines"))
# print(getMaxPrefixFilePre("../../data/protocolTools/GPSLines"))
# print(getDirFilesNoPrefix("../../data/protocolTools/GPSLines"))
# print(getDirFilesListMap("../../data/protocolTools/GPSLines"))
delFile("../../data/protocolTools/GPSLines/","11_testLine")
#coding:utf-8
'''
处理json辅助类
'''
#####################################################
# 判断json中是否有值为空的项
#####################################################
def hasJsonDataIsNone(data):
for key,value in data.items():
if value == None or value == "":
return True
return False
if __name__ == "__main__":
data = {"a":1,"b":"bb","c":"s","d":123}
print(hasJsonDataIsNone(data))
\ No newline at end of file
#coding:utf-8
'''
定义一个获取经纬度的辅助方法集合
'''
import json
#####################################################
# 获取文件的金纬度数据,返回一个经纬度数组
# path:传入文件路径
#####################################################
def getLocationInfo(path):
with open(path,"r",encoding='utf-8') as fi:
loc_data = fi.readlines()
strData = ""
for lineD in loc_data:
strData += lineD
json_data = json.loads(strData)
return json_data["locationInfo"]
if __name__ == "__main__":
print(getLocationInfo("../../data/protocolTools/GPSLine_1.json"))
\ No newline at end of file
#coding:utf-8
#########################################
# 字符串自动补空格函数
# num 字符串期望的长度
#########################################
def strAddSpace(str,num):
data = str
if len(str) < num:
for i in range(0,num - len(str)):
data = data + " "
return data
\ No newline at end of file
这是一个测试日志文件
\ No newline at end of file
#wxPython==4.0.7.post2
#crcmod==1.7
[2020-10-12 16:27:50] 启动了模拟程序
[2020-10-12 16:28:01] 建立了连接
[2020-10-12 16:28:01] 进行了登录操作
[2020-10-12 16:28:02] 当前设置了GPS轨迹:9_gpsLine3.txt
[2020-10-12 16:28:02] 发送了点火事件
[2020-10-12 16:28:04] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:05] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:06] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:07] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:08] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:09] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:11] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:12] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:13] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:14] 纬度:29.519863 经度:106.484645
[2020-10-12 16:28:15] 纬度:29.51929 经度:106.498255
[2020-10-12 16:28:16] 纬度:29.519245 经度:106.49839
[2020-10-12 16:28:17] 纬度:29.519196 经度:106.498496
[2020-10-12 16:28:18] 纬度:29.519095 经度:106.498686
[2020-10-12 16:28:19] 纬度:29.519106 经度:106.498731
[2020-10-12 16:28:20] 纬度:29.519121 经度:106.49879
[2020-10-12 16:28:22] 纬度:29.519141 经度:106.498851
[2020-10-12 16:28:23] 纬度:29.519215 经度:106.499026
[2020-10-12 16:28:24] 纬度:29.519258 经度:106.499136
[2020-10-12 16:28:25] 纬度:29.519415 经度:106.49923
[2020-10-12 16:28:26] 纬度:29.519476 经度:106.499251
[2020-10-12 16:28:27] 纬度:29.519686 经度:106.49952
[2020-10-12 16:28:28] 纬度:29.520288 经度:106.500043
[2020-10-12 16:28:29] 纬度:29.52039 经度:106.500173
[2020-10-12 16:28:30] 纬度:29.520403 经度:106.500246
[2020-10-12 16:28:32] 纬度:29.521333 经度:106.501561
[2020-10-12 16:28:33] 纬度:29.52206 经度:106.502366
[2020-10-12 16:28:34] 纬度:29.522266 经度:106.502606
[2020-10-12 16:28:35] 纬度:29.522416 经度:106.502881
[2020-10-12 16:28:36] 纬度:29.52248 经度:106.503096
[2020-10-12 16:28:37] 纬度:29.522505 经度:106.50344
[2020-10-12 16:28:38] 纬度:29.522483 经度:106.503656
[2020-10-12 16:28:39] 纬度:29.52239 经度:106.50396
[2020-10-12 16:28:40] 纬度:29.52232 经度:106.50414
[2020-10-12 16:28:41] 纬度:29.522191 经度:106.504521
[2020-10-12 16:28:43] 纬度:29.522156 经度:106.504866
[2020-10-12 16:28:44] 纬度:29.52215 经度:106.506228
[2020-10-12 16:28:45] 纬度:29.522256 经度:106.506621
[2020-10-12 16:28:46] 纬度:29.522475 经度:106.507173
[2020-10-12 16:28:47] 纬度:29.52261 经度:106.507423
[2020-10-12 16:28:48] 纬度:29.522835 经度:106.507683
[2020-10-12 16:28:49] 纬度:29.523151 经度:106.50822
[2020-10-12 16:28:50] 纬度:29.52365 经度:106.509468
[2020-10-12 16:28:51] 纬度:29.523761 经度:106.5102
[2020-10-12 16:28:53] 纬度:29.523706 经度:106.511401
[2020-10-12 16:28:54] 纬度:29.523321 经度:106.516661
[2020-10-12 16:28:55] 纬度:29.523081 经度:106.520538
[2020-10-12 16:28:56] 纬度:29.523038 经度:106.525145
[2020-10-12 16:28:57] 纬度:29.52304 经度:106.530208
[2020-10-12 16:28:58] 纬度:29.523023 经度:106.534585
[2020-10-12 16:28:59] 纬度:29.522871 经度:106.536085
[2020-10-12 16:29:01] 纬度:29.522366 经度:106.53838
[2020-10-12 16:29:02] 纬度:29.522248 经度:106.538986
[2020-10-12 16:29:03] 纬度:29.52228 经度:106.53921
[2020-10-12 16:29:04] 纬度:29.522316 经度:106.539255
[2020-10-12 16:29:05] 纬度:29.522361 经度:106.539286
[2020-10-12 16:29:06] 纬度:29.52241 经度:106.539286
[2020-10-12 16:29:08] 纬度:29.52246 经度:106.539268
[2020-10-12 16:29:09] 纬度:29.522498 经度:106.539235
[2020-10-12 16:29:10] 纬度:29.522511 经度:106.539196
[2020-10-12 16:29:11] 纬度:29.522541 经度:106.539136
[2020-10-12 16:29:12] 纬度:29.522701 经度:106.538613
[2020-10-12 16:29:13] 纬度:29.522915 经度:106.537718
[2020-10-12 16:29:14] 纬度:29.523331 经度:106.536041
[2020-10-12 16:29:15] 纬度:29.523863 经度:106.535086
[2020-10-12 16:29:16] 纬度:29.52399 经度:106.535016
[2020-10-12 16:29:17] 纬度:29.524065 经度:106.535003
[2020-10-12 16:29:19] 纬度:29.52414 经度:106.535001
[2020-10-12 16:29:20] 纬度:29.524296 经度:106.535031
[2020-10-12 16:29:21] 纬度:29.524366 经度:106.53507
[2020-10-12 16:29:22] 纬度:29.524436 经度:106.535133
[2020-10-12 16:29:23] 纬度:29.52455 经度:106.535296
[2020-10-12 16:29:24] 纬度:29.524886 经度:106.535813
[2020-10-12 16:29:25] 纬度:29.525051 经度:106.53595
[2020-10-12 16:29:26] 纬度:29.525153 经度:106.535985
[2020-10-12 16:29:27] 纬度:29.525195 经度:106.53598
[2020-10-12 16:29:29] 纬度:29.525226 经度:106.53596
[2020-10-12 16:29:30] 纬度:29.525256 经度:106.535921
[2020-10-12 16:29:31] 纬度:29.52527 经度:106.535871
[2020-10-12 16:29:32] 纬度:29.52526 经度:106.53581
[2020-10-12 16:29:33] 纬度:29.525235 经度:106.535745
[2020-10-12 16:29:34] 纬度:29.525113 经度:106.535548
[2020-10-12 16:29:35] 纬度:29.52499 经度:106.535295
[2020-10-12 16:29:36] 纬度:29.524505 经度:106.534181
[2020-10-12 16:29:37] 纬度:29.524511 经度:106.534015
[2020-10-12 16:29:38] 纬度:29.524543 经度:106.533921
[2020-10-12 16:29:40] 纬度:29.524628 经度:106.533768
[2020-10-12 16:29:41] 纬度:29.524743 经度:106.533665
[2020-10-12 16:29:42] 纬度:29.524888 经度:106.53361
[2020-10-12 16:29:43] 纬度:29.525051 经度:106.533585
[2020-10-12 16:29:44] 纬度:29.525138 经度:106.533611
[2020-10-12 16:29:45] 纬度:29.525208 经度:106.533673
[2020-10-12 16:29:46] 纬度:29.525261 经度:106.533736
[2020-10-12 16:29:47] 纬度:29.525435 经度:106.533976
[2020-10-12 16:29:48] 纬度:29.525563 经度:106.534098
[2020-10-12 16:29:50] 纬度:29.525606 经度:106.5341
[2020-10-12 16:29:51] 纬度:29.525646 经度:106.534081
[2020-10-12 16:29:52] 纬度:29.525793 经度:106.534018
[2020-10-12 16:29:53] 纬度:29.525828 经度:106.534031
[2020-10-12 16:29:54] 纬度:29.525858 经度:106.534056
[2020-10-12 16:29:55] 纬度:29.525928 经度:106.534106
[2020-10-12 16:29:56] 纬度:29.525956 经度:106.534096
[2020-10-12 16:29:57] 纬度:29.525965 经度:106.534076
[2020-10-12 16:29:58] 纬度:29.525968 经度:106.53405
[2020-10-12 16:30:00] 纬度:29.525961 经度:106.53402
[2020-10-12 16:30:01] 纬度:29.525936 经度:106.533986
[2020-10-12 16:30:02] 纬度:29.525546 经度:106.533455
[2020-10-12 16:30:03] 纬度:29.525413 经度:106.5332
[2020-10-12 16:30:04] 纬度:29.525155 经度:106.532426
[2020-10-12 16:30:05] 纬度:29.525163 经度:106.532353
[2020-10-12 16:30:06] 纬度:29.5252 经度:106.53229
[2020-10-12 16:30:07] 纬度:29.525253 经度:106.532241
[2020-10-12 16:30:08] 纬度:29.525315 经度:106.532198
[2020-10-12 16:30:09] 纬度:29.5269 经度:106.531586
[2020-10-12 16:30:11] 纬度:29.52778 经度:106.531363
[2020-10-12 16:30:12] 纬度:29.528746 经度:106.531326
[2020-10-12 16:30:13] 纬度:29.529691 经度:106.531458
[2020-10-12 16:30:14] 纬度:29.53156 经度:106.532046
[2020-10-12 16:30:15] 纬度:29.535643 经度:106.53357
[2020-10-12 16:30:16] 纬度:29.535928 经度:106.53374
[2020-10-12 16:30:17] 纬度:29.5374 经度:106.534836
[2020-10-12 16:30:18] 纬度:29.539351 经度:106.536893
[2020-10-12 16:30:19] 纬度:29.540533 经度:106.538446
[2020-10-12 16:30:21] 纬度:29.540896 经度:106.539238
[2020-10-12 16:30:22] 纬度:29.541156 经度:106.540116
[2020-10-12 16:30:23] 纬度:29.541235 经度:106.540788
[2020-10-12 16:30:24] 纬度:29.541261 经度:106.541853
[2020-10-12 16:30:25] 纬度:29.540981 经度:106.54615
[2020-10-12 16:30:26] 纬度:29.540926 经度:106.549441
[2020-10-12 16:30:27] 纬度:29.54118 经度:106.550593
[2020-10-12 16:30:28] 纬度:29.541558 经度:106.551516
[2020-10-12 16:30:29] 纬度:29.542755 经度:106.554295
[2020-10-12 16:30:31] 纬度:29.543063 经度:106.555916
[2020-10-12 16:30:32] 纬度:29.543186 经度:106.556861
[2020-10-12 16:30:33] 纬度:29.54361 经度:106.560363
[2020-10-12 16:30:34] 纬度:29.543498 经度:106.561361
[2020-10-12 16:30:35] 纬度:29.543373 经度:106.562058
[2020-10-12 16:30:36] 纬度:29.543205 经度:106.563295
[2020-10-12 16:30:37] 纬度:29.543231 经度:106.564865
[2020-10-12 16:30:38] 纬度:29.543681 经度:106.567205
[2020-10-12 16:30:39] 纬度:29.544415 经度:106.571403
[2020-10-12 16:30:40] 纬度:29.544786 经度:106.574481
[2020-10-12 16:30:42] 纬度:29.544871 经度:106.574908
[2020-10-12 16:30:43] 纬度:29.544865 经度:106.574951
[2020-10-12 16:30:44] 纬度:29.54487 经度:106.574981
[2020-10-12 16:30:45] 纬度:29.544883 经度:106.575065
[2020-10-12 16:30:46] 纬度:29.544971 经度:106.575368
[2020-10-12 16:30:47] 纬度:29.545 经度:106.575446
[2020-10-12 16:30:48] 纬度:29.545733 经度:106.57792
[2020-10-12 16:30:49] 纬度:29.545958 经度:106.57879
[2020-10-12 16:30:50] 纬度:29.546685 经度:106.5819
[2020-10-12 16:30:52] 纬度:29.546916 经度:106.582638
[2020-10-12 16:30:53] 纬度:29.547221 经度:106.583336
[2020-10-12 16:30:54] 纬度:29.5478 经度:106.584188
[2020-10-12 16:30:55] 纬度:29.547933 经度:106.584356
[2020-10-12 16:30:56] 纬度:29.548418 经度:106.584933
[2020-10-12 16:30:57] 纬度:29.548348 经度:106.585056
[2020-10-12 16:30:58] 纬度:29.548358 经度:106.585081
[2020-10-12 16:30:59] 纬度:29.548448 经度:106.585181
[2020-10-12 16:31:00] 纬度:29.54856 经度:106.58525
[2020-10-12 16:31:01] 纬度:29.549613 经度:106.58583
[2020-10-12 16:31:03] 纬度:29.551088 经度:106.586525
[2020-10-12 16:31:04] 纬度:29.554658 经度:106.588258
[2020-10-12 16:31:05] 纬度:29.556971 经度:106.589325
[2020-10-12 16:31:06] 纬度:29.558385 经度:106.590013
[2020-10-12 16:31:07] 纬度:29.560546 经度:106.590681
[2020-10-12 16:31:08] 纬度:29.561608 经度:106.59077
[2020-10-12 16:31:09] 纬度:29.563003 经度:106.590806
[2020-10-12 16:31:10] 纬度:29.563895 经度:106.590851
[2020-10-12 16:31:11] 纬度:29.566858 经度:106.590766
[2020-10-12 16:31:13] 纬度:29.568281 经度:106.590591
[2020-10-12 16:31:14] 纬度:29.572468 经度:106.589873
[2020-10-12 16:31:15] 纬度:29.573176 经度:106.589526
[2020-10-12 16:31:16] 纬度:29.574146 经度:106.588891
[2020-10-12 16:31:17] 纬度:29.574741 经度:106.588333
[2020-10-12 16:31:18] 纬度:29.575703 经度:106.587363
[2020-10-12 16:31:19] 纬度:29.575726 经度:106.587371
[2020-10-12 16:31:20] 纬度:29.575745 经度:106.58739
[2020-10-12 16:31:21] 纬度:29.575756 经度:106.587408
[2020-10-12 16:31:22] 纬度:29.575766 经度:106.587425
[2020-10-12 16:31:24] 纬度:29.575786 经度:106.587478
[2020-10-12 16:31:25] 纬度:29.575788 经度:106.587505
[2020-10-12 16:31:26] 纬度:29.57578 经度:106.587645
[2020-10-12 16:31:27] 纬度:29.575776 经度:106.58777
[2020-10-12 16:31:28] 纬度:29.575805 经度:106.587808
[2020-10-12 16:31:29] 纬度:29.575805 经度:106.587808
[2020-10-12 16:31:30] 纬度:29.575805 经度:106.587808
[2020-10-12 16:31:31] 纬度:29.575805 经度:106.587808
[2020-10-12 16:31:32] 发送了熄火事件:
[2020-10-12 16:31:32] 执行了停止行驶服务
[2020-10-12 16:32:01] 建立了连接
[2020-10-12 16:32:01] 进行了登录操作
[2020-10-12 16:32:02] 当前设置了GPS轨迹:10_gpsLine5.txt
[2020-10-12 16:32:02] 发送了点火事件
[2020-10-12 16:32:04] 纬度:29.571413 经度:106.489936
[2020-10-12 16:32:05] 纬度:29.571413 经度:106.489936
[2020-10-12 16:32:06] 纬度:29.571413 经度:106.489936
[2020-10-12 16:32:07] 纬度:29.571413 经度:106.489936
[2020-10-12 16:32:08] 纬度:29.572476 经度:106.489228
[2020-10-12 16:32:10] 纬度:29.57247 经度:106.489278
#utf-8
import time
import traceback
from lib.socket.service.AutoCarTimerService import AutoCarTimerService
#写入文件
def writeToFile(path,data,type=1): #:代表追加 0:代表覆盖
if(type == 1):
with open(path, "a", encoding='utf-8') as fi:
fi.write(data)
else:
with open(path, "w", encoding='utf-8') as fi:
fi.write(data)
def startSimulaterService():
autoCarObj = AutoCarTimerService()
autoCarObj.setHost("172.19.7.13") # 设置主机地址
autoCarObj.setPort(49007) # 设置端口号
autoCarObj.setCarId("012201800001") #设置车机号
autoCarObj.setSendDur(1) # 设置发送消息的间隔时间
autoCarObj.setTimeout(30) # 设置socket超时时间
autoCarObj.setOilExpend(10) # 设置1L 油跑多少公里
autoCarObj.setCarSpeed(80) #设置车速,每小时多少公里
'''
如果年、月、日、时、分、秒都设置为0,则代表永远不会有模拟汽车行驶
如果想要每小时的25分自动执行一次轨迹行驶,则设置:year=0,month=0,day=0,hour=0,minute=25,second=0
如果想要每天的9点自动执行一次轨迹行驶,则设置:year=0,month=0,day=0,hour=9,minute=0,second=0
如果想要每天的9点30自动执行一次轨迹行驶,则设置:year=0,month=0,day=0,hour=9,minute=30,second=0
'''
autoCarObj.startTravelService(year=0,month=0,day=0,hour=0,minute=0,second=1)
if __name__ == "__main__":
try:
startSimulaterService()
except BaseException as e:
traceback.print_exc()
timeS = int(time.time())
timeArray = time.localtime(timeS)
datetime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
err = traceback.format_exc()
writeToFile("data/log1.txt", "[" + datetime + "]", type=1)
writeToFile("data/log1.txt", err, type=1)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment