Commit acc1df8e authored by liyuanhong's avatar liyuanhong

首次提交

parents
Pipeline #279 canceled 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下双击即可启动)
#### (二)、运行机制
0
\ 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
{"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
{"time": {"dateTime": "2020-08-05 18:21:01", "date": "2020-08-05", "time": "18:21:01"}, "curDayTravel": {"todayTotalMilleage": 132, "todayTotalOil": 12, "todayTotalTime": 6, "theMilleage": 41052, "theOil": 3732, "theTime": 1866}, "travelData": {"totalMilleage": 41052, "totalOil": 3732, "totalTime": 1866}}
\ No newline at end of file
#coding:utf-8
'''
定义基类,供所有协议类继承
'''
class Base():
def __init__(self):
pass
#####################################################
# 生成协议头
#####################################################
def getProtocalHeader(self):
# print("生成协议头方法")
pass
#coding:utf-8
import datetime
from lib.protocol.report.ProtocolBase import ProtocolBase
from lib.protocol.report.GPSReport_protocol import GPSReport_protocol
from lib.protocol.report.SecurityStatusReport_protocol import SecurityStatusReport_protocol
class EventClass(ProtocolBase):
def __init__(self):
self.GPSPkg = "1401091213260265b86206ed8c70026103280000752f03030405af017102610bb800003200000186a0001ed2a25e16fe3a"
self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"
self.securityData = ""
def setGPSpkg(self,data):
self.GPSPkg = data
def setSecurityData(self,data):
self.securityData = data
# 3 点火事件附带信息
def fireExtraInfo(self):
allRapidlyAccelerateCount = self.int2hexStringByBytes(15, 2) # 急加速总次数
allSharpSlowdownCount = self.int2hexStringByBytes(15, 2) # 急减速总次数
allSharpTurn = self.int2hexStringByBytes(15, 2) # 急转弯总次数
securityObj = SecurityStatusReport_protocol()
securityObj.setGPSPkg(self.GPSPkg)
securityData = ""
if self.securityData == "":
securityData = securityObj.generateSecurityStatusData() # 安防数据
else:
securityData = self.securityData
data = allRapidlyAccelerateCount + allSharpSlowdownCount + allSharpTurn + securityData
return data
#4 熄火事件附带信息
def misFireExtraInfo(self):
allRapidlyAccelerateCount = self.int2hexStringByBytes(100,2) #急加速总次数
allSharpSlowdownCount = self.int2hexStringByBytes(101,2) #急减速总次数
allSharpTurn = self.int2hexStringByBytes(35,2) #急转弯总次数
securityObj = SecurityStatusReport_protocol()
securityObj.setGPSPkg(self.GPSPkg)
securityData = ""
if self.securityData == "":
securityData = securityObj.generateSecurityStatusData() # 安防数据
else:
securityData = self.securityData
data = allRapidlyAccelerateCount + allSharpSlowdownCount + allSharpTurn + securityData
return data
#5 设防事件附带信息
def setUpDefencesExtraInfo(self):
securityObj = SecurityStatusReport_protocol()
securityObj.setGPSPkg(self.GPSPkg)
securityData = ""
if self.securityData == "":
securityData = securityObj.generateSecurityStatusData() # 安防数据
else:
securityData = self.securityData
return securityData
#6 撤防事件附带信息
def setDownDefencesExtraInfo(self):
securityObj = SecurityStatusReport_protocol()
securityObj.setGPSPkg(self.GPSPkg)
securityData = ""
if self.securityData == "":
securityData = securityObj.generateSecurityStatusData() # 安防数据
else:
securityData = self.securityData
return securityData
return securityData
#7 锁车未成功事件附带信息
def lockCarFaillExtraInfo(self):
securityData = SecurityStatusReport_protocol.generateSecurityStatusData() # 安防数据
return securityData
#8 超时未设防事件附带信息
def noDefencesWithTimeoutExtraInfo(self):
securityData = SecurityStatusReport_protocol.generateSecurityStatusData() # 安防数据
return securityData
#9 设防玻璃未关事件附带信息
def defencesGlassNoCloseExtraInfo(self):
securityData = SecurityStatusReport_protocol.generateSecurityStatusData() # 安防数据
return securityData
#10 设防非法开门事件附带信息
def defencesIllegalCloseDoorExtraInfo(self):
securityData = SecurityStatusReport_protocol.generateSecurityStatusData() # 安防数据
return securityData
#11 设防非法点火事件附带信息
def defencesIllegalFireExtraInfo(self):
securityData = SecurityStatusReport_protocol.generateSecurityStatusData() # 安防数据
return securityData
#12 急加速报警附带信息
def rapidlyAccelerateExtraInfo(self):
totalRapidlyAccelerateCount = 100 #急加速总次数
totalSharpSlowdown = 200 #急减速总次数
totalSharpTurn = 50 #急转弯总次数
dataProperty = 2 #事件属性,1:表示事件发生时刻,前10秒的事件采样数据;2:表示事件发生时刻,后10秒的事件采样数据;
GPSSampleData = self.GPSDataFromSeconds(10) #GPS 采样点 ,N秒内的GPS采样数据,170个字节
CANSampleData = self.CANDataFromSeconds(10) #CAN采样点 ,N秒内的CAN采样数据,90个字节
SENSORSampleData = self.SENSORDataFromSeconds(20) #SENSOR采样点 ,N秒内的SENSOR采样数据
totalRapidlyAccelerateCount = self.int2hexStringByBytes(totalRapidlyAccelerateCount,2)
totalSharpSlowdown = self.int2hexStringByBytes(totalSharpSlowdown,2)
totalSharpTurn = self.int2hexStringByBytes(totalSharpTurn,2)
dataProperty = self.int2hexStringByBytes(dataProperty,1)
data = totalRapidlyAccelerateCount + totalSharpSlowdown + totalSharpTurn + dataProperty + GPSSampleData + CANSampleData + SENSORSampleData
return data
#13 急减速报警附带信息
def sharpSlowdownExtraInfo(self):
totalRapidlyAccelerateCount = 100 #急加速总次数
totalSharpSlowdown = 200 #急减速总次数
totalSharpTurn = 50 #急转弯总次数
dataProperty = 2 #事件属性,1:表示事件发生时刻,前10秒的事件采样数据;2:表示事件发生时刻,后10秒的事件采样数据;
GPSSampleData = self.GPSDataFromSeconds(10) #GPS 采样点 ,N秒内的GPS采样数据,170个字节
CANSampleData = self.CANDataFromSeconds(10) #CAN采样点 ,N秒内的CAN采样数据,90个字节
SENSORSampleData = self.SENSORDataFromSeconds(20) #SENSOR采样点 ,N秒内的SENSOR采样数据
totalRapidlyAccelerateCount = self.int2hexStringByBytes(totalRapidlyAccelerateCount,2)
totalSharpSlowdown = self.int2hexStringByBytes(totalSharpSlowdown,2)
totalSharpTurn = self.int2hexStringByBytes(totalSharpTurn,2)
dataProperty = self.int2hexStringByBytes(dataProperty,1)
data = totalRapidlyAccelerateCount + totalSharpSlowdown + totalSharpTurn + dataProperty + GPSSampleData + CANSampleData + SENSORSampleData
return data
#14 急转弯报警附带信息
def sharpTurnExtraInfo(self):
totalRapidlyAccelerateCount = 100 #急加速总次数
totalSharpSlowdown = 200 #急减速总次数
totalSharpTurn = 50 #急转弯总次数
dataProperty = 2 #事件属性,1:表示事件发生时刻,前10秒的事件采样数据;2:表示事件发生时刻,后10秒的事件采样数据;
GPSSampleData = self.GPSDataFromSeconds(10) #GPS 采样点 ,N秒内的GPS采样数据,170个字节
CANSampleData = self.CANDataFromSeconds(10) #CAN采样点 ,N秒内的CAN采样数据,90个字节
SENSORSampleData = self.SENSORDataFromSeconds(20) #SENSOR采样点 ,N秒内的SENSOR采样数据
totalRapidlyAccelerateCount = self.int2hexStringByBytes(totalRapidlyAccelerateCount,2)
totalSharpSlowdown = self.int2hexStringByBytes(totalSharpSlowdown,2)
totalSharpTurn = self.int2hexStringByBytes(totalSharpTurn,2)
dataProperty = self.int2hexStringByBytes(dataProperty,1)
data = totalRapidlyAccelerateCount + totalSharpSlowdown + totalSharpTurn + dataProperty + GPSSampleData + CANSampleData + SENSORSampleData
return data
#15 碰撞报警附带信息
def collisionAlarmExtraInfo(self):
totalCount = self.int2hexStringByBytes(7,2) #历史碰撞总次数
# 1:表示事件发生时刻,前10秒的事件采样数据;
# [碰撞报警前后10秒采样数据附带信息]
# 2:表示事件发生时刻,后10秒的事件采样数据;
# [碰撞报警前后10秒采样数据附带信息]
# 3:表示事件发生时刻,后120秒的事件采样数据;
# [碰撞报警后120秒采样数据附带信息]
dataProperty = self.int2hexString(1)
extraInfo = self.collisionSamplingData() #附带信息
data = totalCount + dataProperty + extraInfo
return data
#16 碰撞报警前后10秒采样数据附带信息
def collisionSamplingData(self):
GPSSampleData = self.GPSDataFromSeconds(10) #GPS 采样点 ,N秒内的GPS采样数据,170个字节
CANSampleData = self.CANDataFromSeconds(10) #CAN采样点 ,N秒内的CAN采样数据,90个字节
SENSORSampleData1 = self.SENSORDataFromSeconds(20) #SENSOR采样点 ,N秒内的SENSOR采样数据
SENSORSampleData2 = self.SENSORDataFromSeconds(40) #S碰撞时刻前后100毫秒内的SENSOR采样数据;50ms滑动窗车平面加速度;(2.5ms采样周期)碰撞前后100毫秒内的滑动窗SENSOR采样数据
SENSORStatus = self.int2hexString(1) #SENSOR状态,0:初始状态,1:学习状态,2:工作状态,其他:保留
# 角度范围: [0, 360);
# 学习状态时,相对车平面内的x正半轴方向逆时针旋转角度;
# 工作状态时,相对车头方向逆时针旋转角度。
collisionAngle = self.int2hexStringByBytes(60,2)
SENSORSampleData3 = self.SENSORDataFromSeconds(40) #碰撞时刻前后100毫秒内的SENSOR采样数据;50ms滑动窗垂直车平面加速度;(2.5ms采样周期),碰撞前后100毫秒内的滑动窗SENSOR采样数据
SENSORCheckFlag = self.int2hexString(1) #0:未初始化或者中心点偏离大于148mg,1:完成初始化或者中心点偏离小于100mg
carSlopeAngle = self.carSlopeAngleFromSeconds(10) #车辆倾斜角
data = GPSSampleData + CANSampleData + SENSORSampleData1 + SENSORSampleData2 + SENSORStatus + collisionAngle + SENSORSampleData3 + SENSORCheckFlag + carSlopeAngle
return data
#23 GPS采样数据项
def GPSSamplingData(self):
latitude = 40.22077 #纬度
longitude = 116.23128 #经度
speed = 60.9 #速度
directionAngle = 80.8 #方向角
elevation = 2999.9 #海拔
statusBit = 1 #状态位,Bit7:当前定位是否有效,0-无效,1-有效,其它Bit位预留
latitude = GPSReport_protocol().getLatitude(latitude)
longitude = GPSReport_protocol().getLongitude(longitude)
speed = GPSReport_protocol().getSpeed(speed)
directionAngle = GPSReport_protocol().getDirectionAngle(directionAngle)
elevation = GPSReport_protocol().geteElevation(elevation)
statusBit = GPSReport_protocol().getStatusBit(statusBit)
data = latitude + longitude + speed + directionAngle + elevation + statusBit
return data
#24 N秒内的GPS采样数据
def GPSDataFromSeconds(self,counts):
data = ""
for i in range(0,counts):
data += self.GPSSamplingData()
return data
#25 加速度CAN数据项
def CANSamplingData(self):
speed = 65 #车速
enginSpeed = 1000 #发动机转速
brakingStatus = 0 #刹车状态:1-刹车,0-未刹车,2-不支持;
acceleratorLocation = 50 #油门踏板位置
airDamper = 17 #节气门开度
troubleCount = 2 #故障码个数
speed = self.int2hexStringByBytes(speed,1)
enginSpeed = self.int2hexStringByBytes(enginSpeed,2)
brakingStatus = self.int2hexStringByBytes(brakingStatus,1)
acceleratorLocation = self.int2hexStringByBytes(acceleratorLocation,2)
airDamper = self.int2hexStringByBytes(airDamper,2)
troubleCount = self.int2hexStringByBytes(troubleCount,1)
data = speed + enginSpeed + brakingStatus + acceleratorLocation + airDamper + troubleCount
return data
#26 N秒内的CAN采样数据
def CANDataFromSeconds(self,counts):
data = ""
for i in range(0,counts):
data += self.CANSamplingData()
return data
#27 N秒内的SENSOR采样数据
def SENSORDataFromSeconds(self,counts):
data = ""
for i in range(0,counts):
data += self.int2hexStringByBytes(30,2) #第1秒内的第1个0.5秒内的平均加速度值
return data
#30 终端插入报警附带信息
def terminalInsertionAlarmExtraInfo(self,theTime=""):
if theTime != "":
return self.getUTCTimeHex(theTime)
else:
return self.getUTCTimeHex(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
#36 预点火事件附带信息
def preFiringExtraInfo(self):
bit0 = 1 #1:有点火电压波形,0:无点火电压波形
bit1 = 2 #2:有电压和噪声点火,0:无电压和噪声点火
bit2 = 4 #3:有gps车速和噪声点火,0:无gps车速和噪声点火
data = bit0 + bit1 + bit2
return self.int2hexString(data)
#39 SOS报警事件附加信息
def SOSAlarmEtraInfo(self,theTime):
if theTime != "":
return self.getUTCTimeHex(theTime)
else:
return self.getUTCTimeHex(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
#41 充电事件附带信息
def chargeEtraInfo(self):
SOC = self.int2hexString(0.3 * 100) #乘以100上传,平台除以100处理(显示小于1的小数值)
SOH = self.int2hexString(4 * 100) #乘以100上传,平台除以100处理
voltage = self.int2hexStringByBytes(3.6 * 10,2) #乘以10上传,平台除以10处理
chargeEventCode = self.int2hexString(3) #充电开始报警,和后续的充电结束报警为同一编号
data = SOC + SOH + voltage + chargeEventCode
return data
#45 终端拔出报警附带信息
def terminalPulloutAlarmExtraInfo(self,theTime=""):
if theTime != "":
return self.getUTCTimeHex(theTime)
else:
return self.getUTCTimeHex(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
#50 低档高速报警附
def lowGearHighSpeedAlarm(self,alarmType=1,durationTime=10):
alarmTypeHex = self.int2hexStringByBytes(alarmType)
durationTimeHex = self.int2hexStringByBytes(durationTime,2)
data = alarmTypeHex + durationTimeHex
return data
#51 高档低速报警附带信息
def highGearLowSpeedAlarm(self,alarmType=1,durationTime=10):
alarmTypeHex = self.int2hexStringByBytes(alarmType)
durationTimeHex = self.int2hexStringByBytes(durationTime,2)
data = alarmTypeHex + durationTimeHex
return data
def carSlopeAngleFromSeconds(self,counts):
data = ""
for i in range(0,counts):
data += self.int2hexStringByBytes(60,2) #第1秒内倾斜角[0,180)
data += self.int2hexStringByBytes(self.num2signedNum(-50),2) #第1秒内侧倾角[-90, 90],大于0右倾,小于0左倾
return data
#69 剩余油量异常告警附带信息
def surplusOilAlarm(self,surplusOilType=0,value=30):
surplusOilTypeHex = self.int2hexStringByBytes(surplusOilType)
valueHex = self.int2hexStringByBytes(value,2)
data = surplusOilTypeHex + valueHex
return data
if __name__ == "__main__":
# print(EventClass().GPSDataFromSeconds(10))
# print(EventClass().CANSamplingData())
# print(EventClass().rapidlyAccelerateEtraInfo())
# print(EventClass().carSlopeAngleFromSeconds(10))
# print(EventClass().SENSORDataFromSeconds(40))
# print(EventClass().carSlopeAngleFromSeconds(10))
print(EventClass().collisionSamplingData())
\ No newline at end of file
#coding:utf-8
'''
定义一个终端上报基站定位数据包协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class BaseStationReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = "0002",DEV_ID = "M121501010001",infoTime="2020-01-20 10:12:05",operators=2,serverLAC=2020,serverCellID=2022,N1LAC=2024,N1CellID=2026,N2LAC=2028,N2CellID=20202,N3LAC=20204,N3CellID=20206,N4LAC=20208,N4CellID=20220,N5LAC=20222,N5CellID=20224,N6LAC=20226,N6CellID=20228,voltage=3.6,speed=60.6,engineSpeed=2000,totalMileage=500005,totalOilExpend=600006,totalRunTime=60001,statusBit=1):
super().__init__()
self.msgCount = int(msgCount) # 要发送的数据包个数
self.WATER_CODE = int(WATER_CODE); # 消息流水号
self.DEV_ID = DEV_ID # 设备id
self.infoTime = infoTime #基站时间信息
self.operators = int(operators) #运营商
self.serverLAC = int(serverLAC) #服务器 LAC
self.serverCellID = int(serverCellID) #服务器CellID
self.N1LAC = int(N1LAC) #N1 LAC
self.N1CellID = int(N1CellID) #N1 CellID
self.N2LAC = int(N2LAC) # N2 LAC
self.N2CellID = int(N2CellID) # N2 CellID
self.N3LAC = int(N3LAC) # N3 LAC
self.N3CellID = int(N3CellID) # N3 CellID
self.N4LAC = int(N4LAC) # N4 LAC
self.N4CellID = int(N4CellID) # N4 CellID
self.N5LAC = int(N5LAC) # N5 LAC
self.N5CellID = int(N5CellID) # N5 CellID
self.N6LAC = int(N6LAC) # N6 LAC
self.N6CellID = int(N6CellID) # N6 CellID
self.voltage = float(voltage) #电瓶电压
self.speed = float(speed) #车速
self.engineSpeed = int(engineSpeed) #发动机转速
self.totalMileage = int(totalMileage) #累计里程
self.totalOilExpend = int(totalOilExpend) #累计油耗
self.totalRunTime = int(totalRunTime) #累计行驶时间
self.statusBit = int(statusBit) #状态位
#####################################################
# 生成基站定位数据消息
#####################################################
def generateBaseStationMsg(self):
self.getProtocalHeader()
info = ""
# 消息头
HEADER = "4040"
# 消息流水号
WATER_CODE = self.getWaterCode(self.WATER_CODE)
# 设备id
DEV_ID = self.devid2hexString(self.DEV_ID)
# 功能id(GPS功能id)
FUN_ID = "0011"
# 数据段
data = ""
for i in range(0, self.msgCount):
data += self.generateBaseStationPkg(self.generateBaseStationData())
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
# 校验字段
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE
return info
#####################################################
# 创建基站定位数据包,包含包个数
# data:传入数据包的多条数据段
#####################################################
def generateBaseStationPkg(self, data):
pkgLen = len(data)
pkgNum = (pkgLen / 2) / 55
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + data
return pkg
#####################################################
# 创建基站定位数据段
#####################################################
def generateBaseStationData(self):
data = ""
baseData = self.generateBaseStationBaseData() #基站基本数据
voltage = self.getVoltageHex(self.voltage) #电瓶电压
speed = self.getSpeedHex(self.speed) #车速
engineSpeed = self.getEngineSpeedHex(self.engineSpeed) #发动机转速
totalMileage = self.getTotalMileageHex(self.totalMileage) #累计里程
totalOilExpend = self.getTotalOilExpendHex(self.totalOilExpend) #累计油耗
totalRunTime = self.getTotalRunTimeHex(self.totalRunTime) #累计行驶时间
statusBit = self.getStatusBitHex(self.statusBit) #状态位
retain = "00" # 预留字节
data = baseData + voltage + speed + engineSpeed + totalMileage + totalOilExpend + totalRunTime + statusBit + retain
return data
#####################################################
# 创建基站定位基本数据段
#####################################################
def generateBaseStationBaseData(self):
data = ""
infoTime = self.getUTCTimeHex(self.infoTime) #基站时间信息
operators = self.getOperatorsHex(self.operators) #运营商
serverLAC = self.getServerLACHex(self.serverLAC) #服务器 LAC
serverCellID = self.getServerCellIDHex(self.serverCellID) #服务器CellID
N1LAC = self.getN1LACHex(self.N1LAC) #N1 LAC
N1CellID = self.getN1CellIDHex(self.N1CellID) #N1 CellID
N2LAC = self.getN2LACHex(self.N2LAC) # N2 LAC
N2CellID = self.getN2CellIDHex(self.N2CellID) # N2 CellID
N3LAC = self.getN3LACHex(self.N3LAC) # N3 LAC
N3CellID = self.getN3CellIDHex(self.N3CellID) # N3 CellID
N4LAC = self.getN4LACHex(self.N4LAC) # N4 LAC
N4CellID = self.getN4CellIDHex(self.N4CellID) # N4 CellID
N5LAC = self.getN5LACHex(self.N5LAC) # N5 LAC
N5CellID = self.getN5CellIDHex(self.N5CellID) # N5 CellID
N6LAC = self.getN6LACHex(self.N6LAC) # N6 LAC
N6CellID = self.getN6CellIDHex(self.N6CellID) # N6 CellID
data = infoTime + operators + serverLAC + serverCellID + N1LAC + N1CellID + N2LAC + N2CellID + N3LAC + N3CellID + N4LAC + N4CellID + N5LAC + N5CellID + N6LAC + N6CellID
return data
#####################################################
# 获取运营商 16进制数据
#####################################################
def getOperatorsHex(self,data):
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取服务器LAC 16进制数据
#####################################################
def getServerLACHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取服务器CellID 16进制数据
#####################################################
def getServerCellIDHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N1LAC 16进制数据
#####################################################
def getN1LACHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N1 CellID 16进制数据
#####################################################
def getN1CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N2LAC 16进制数据
#####################################################
def getN2LACHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N2 CellID 16进制数据
#####################################################
def getN2CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N3LAC 16进制数据
#####################################################
def getN3LACHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N3 CellID 16进制数据
#####################################################
def getN3CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N4LAC 16进制数据
#####################################################
def getN4LACHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N4 CellID 16进制数据
#####################################################
def getN4CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N5LAC 16进制数据
#####################################################
def getN5LACHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N5 CellID 16进制数据
#####################################################
def getN5CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N6LAC 16进制数据
#####################################################
def getN6LACHex(self, data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取N6 CellID 16进制数据
#####################################################
def getN6CellIDHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取电瓶电压的16进制数据
# 单位:0.01V
###################################################
def getVoltageHex(self,data):
dataStr = str(data)
dataStr = dataStr.replace(".", "")
hexData = self.int2hexString(int(dataStr))
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取车速度的16进制数据
# 单位:0.1km/h
###################################################
def getSpeedHex(self,data):
dataStr = str(data)
dataStr = dataStr.replace(".", "")
hexData = self.int2hexString(int(dataStr))
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取发送机转速的16进制数据
###################################################
def getEngineSpeedHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取累计里程的16进制数据
###################################################
def getTotalMileageHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
####################################################
# 获取累计油耗的16进制数据
###################################################
def getTotalOilExpendHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
####################################################
# 获取累计行驶时间的16进制数据
###################################################
def getTotalRunTimeHex(self,data):
hexData = self.int2hexString(data)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
def getStatusBitHex(self,data):
isFire = 1 #指示当前车辆点熄火状态:0-熄火,1-点火
hexData = self.int2hexString(data)
return hexData
#coding:utf-8
'''
定义一个通用应答数据包
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class CommonReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",resId="8205",status="00"):
super().__init__()
self.msgCount = int(msgCount)
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.resId = resId #应答的功能ID
self.status = status #应答状态
def setResId(self,data):
self.resId = data
def setStatus(self,data):
self.status = data
#####################################################
# 生成 通用应答 消息
#####################################################
def generateCommonMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" #消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) #消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) #设备id
FUN_ID = "0000" # 功能id
data = "" #数据段
for i in range(0,self.msgCount):
data += self.generateCommonPkg(self.generateCommonData())
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建 版本信息 数据包,包含包个数
#####################################################
def generateCommonPkg(self,data):
return data
#####################################################
# 创建 版本信息 数据段
#####################################################
def generateCommonData(self):
data = ""
resId = self.resId
status = self.status
data = resId + status
return data
if __name__ == "__main__":
print(CommonReport_protocol().generateCommonMsg())
\ No newline at end of file
#coding:utf-8
import time
from lib.protocol.report.GPSReport_protocol import GPSReport_protocol
from lib.protocol.report.ProtocolBase import ProtocolBase
from lib.protocol.appendix.EventClass import EventClass
from lib.protocol.report.SecurityStatusReport_protocol import SecurityStatusReport_protocol
'''
终端上事件数据包
'''
class EventReport_protocol(ProtocolBase):
#data = {"WATER_CODE":"0003","DEV_ID":"M121501010001","gpsInfo":{"UTCTime":"2020-04-14 11:03:20","latitude":"40.22077","longitude":"116.23128","speed":"80.8","directionAngle":"80.8","elevation":"2999.9","positionStar":"3","Pdop":"0.3","Hdop":"0.4","Vdop":"0.5","statusBit":162,"valtage":"36.9","OBDSpeed":"60.9","engineSpeed":"3000","GPSTotalMileage":"12800","totalOil":"100000","totalTime":"2020002","GPSTimestamp":"1586833400"},"securityData":{"securityStatus":107,"doorStatus":0,"lockStatus":0,"windowStatus":0,"lightStatus":0,"onoffStatusA":0,"onoffStatusB":112,"dataByte":249},"event":{}}
data = {}
def __init__(self,msgCount = 1,WATER_CODE = 26,DEV_ID = "M121501010001",locationType=1,eventType="0036",data={}):
super().__init__()
self.data = data
if len(data) == 0:
self.msgCount = msgCount #数据包个数
self.WATER_CODE = int(WATER_CODE) #消息流水号
self.DEV_ID = DEV_ID #设备id
self.locationType = int(locationType) # 定位类型
#self.GPSPkg = GPSpkg & BaseStationPkg # GPS包或者基站包
self.GPSPkg = "1401091213260265b86206ed8c70026103280000752f03030405af017102610bb800003200000186a0001ed2a25e16fe3a"
self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"
self.eventType = eventType #事件类别
else:
self.msgCount = 1 # 数据包个数
self.WATER_CODE = int(data["WATER_CODE"]) # 消息流水号
self.DEV_ID = data["DEV_ID"] # 设备id
self.locationType = 1 # 定位类型
gpsInfo = data["gpsInfo"]
self.gpsInfo = gpsInfo
securityData = data["securityData"]
self.securityData = securityData
event = data["event"]
self.event = event
self.GPSPkg = GPSReport_protocol(1,self.WATER_CODE,self.DEV_ID,gpsInfo["UTCTime"],gpsInfo["latitude"],gpsInfo["longitude"] \
,gpsInfo["speed"],gpsInfo["directionAngle"],gpsInfo["elevation"],gpsInfo["positionStar"],gpsInfo["Pdop"] \
,gpsInfo["Hdop"],gpsInfo["Vdop"],gpsInfo["statusBit"],gpsInfo["valtage"],gpsInfo["OBDSpeed"],gpsInfo["engineSpeed"] \
,gpsInfo["GPSTotalMileage"],gpsInfo["totalOil"],gpsInfo["totalTime"],gpsInfo["GPSTimestamp"]).generateGpsData()
self.securityPkg = SecurityStatusReport_protocol(1,self.WATER_CODE,self.DEV_ID,1,self.GPSPkg,"ffffffffffffffffffff" \
,securityData["securityStatus"],securityData["doorStatus"],securityData["lockStatus"] \
,securityData["windowStatus"],securityData["lightStatus"],securityData["onoffStatusA"] \
,securityData["onoffStatusB"],securityData["dataByte"]).generateSecurityStatusData()
self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"
def setLatitude(self,data):
self.latitude = data
def setLongtitude(self,data):
self.longitude = data
def setEventType(self,data):
self.eventType = data
def setLocationType(self,data):
self.locationType = data
def setGPSPkg(self,data):
self.GPSPkg = data
def setBaseStationPkg(self,data):
self.BaseStationPkg = data
#####################################################
# 生成事件信息消息
#####################################################
def generateEventMsg(self):
self.getProtocalHeader()
info = ""
#消息头
HEADER = "4040"
#消息流水号
WATER_CODE = self.getWaterCode(self.WATER_CODE)
#设备id
DEV_ID = self.devid2hexString(self.DEV_ID)
# 功能id(GPS功能id)
FUN_ID = "0021"
#数据段
data = ""
if len(self.data) == 0:
for i in range(0,self.msgCount):
data += self.generateEventPkg(self.msgCount,self.generateEventData())
else:
data += self.generateEventData_GUI()
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
# 校验字段
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE
return info
#####################################################
# 创建GPS数据包,包含包个数
# data:传入GPS数据包的多条数据段
#####################################################
def generateEventPkg(self,pkgNum,data):
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + data
return pkg
#####################################################
# 创建事件信息数据段
#####################################################
def generateEventData(self):
data = ""
locationType = self.int2hexString(self.locationType) #定位类型
locationData = "" #GPS包或基站包
if self.locationType == 1:
locationData = self.GPSPkg
elif self.locationType == 2:
locationData = self.BaseStationPkg
eventType = self.eventType
extraInfo = self.getExtraData(eventType) #附带信息
extraInfoLen = self.int2hexStringByBytes(int((len(extraInfo) / 2)),2) #附带信息长度
data = locationType + locationData + eventType + extraInfoLen + extraInfo
return data
def generateEventData_GUI(self):
data = ""
locationType = self.int2hexString(self.locationType) #定位类型
locationData = "" #GPS包或基站包
if self.locationType == 1:
locationData = self.GPSPkg
elif self.locationType == 2:
locationData = self.BaseStationPkg
eventData = self.getExtraData_GUI(self.event)
data = locationType + locationData + eventData
return data
#####################################################
# 获取附带信息
#####################################################
def getExtraData(self,eventType):
if eventType == "0001": #终端插入报警
return EventClass().terminalInsertionAlarmExtraInfo()
elif eventType == "0002": #终端拔出报警
return EventClass().terminalPulloutAlarmExtraInfo()
elif eventType == "0003": #汽车电瓶低电压报警
return ""
elif eventType == "0004": #终端主电断电报警
return ""
elif eventType == "0005": #GPS模块故障报
return ""
elif eventType == "0006": #GPS天线开路报警
return ""
elif eventType == "0007": #GPS天线短路报警
return ""
elif eventType == "0008": #GPS定位时间过长报警
return ""
elif eventType == "0009": #FLASH故障报警
return ""
elif eventType == "000A": #CAN模块故障报警
return ""
elif eventType == "000B": #3D传感器故障报警
return ""
elif eventType == "000C": #RTC模块故障报警
return ""
elif eventType == "000D": #TF卡故障报警
return ""
elif eventType == "000E": #刷卡器故障报警
return ""
elif eventType == "000F": #汽车预点火上报
return EventClass().preFiringExtraInfo()
elif eventType == "0010": #汽车点火上报
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
return eventObj.fireExtraInfo()
elif eventType == "0011": #汽车熄火上报
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
return eventObj.misFireExtraInfo()
elif eventType == "0012": #汽车设防上报
return EventClass().setUpDefencesExtraInfo()
elif eventType == "0013": #汽车撤防上报
return EventClass().setDownDefencesExtraInfo()
elif eventType == "0014": #锁车未成功提醒
return EventClass().lockCarFaillExtraInfo()
elif eventType == "0015": #超时未设防提醒
return EventClass().noDefencesWithTimeoutExtraInfo()
elif eventType == "0016": #设防玻璃未关提醒
return EventClass().defencesGlassNoCloseExtraInfo()
elif eventType == "0017": #设防非法开门报警
return EventClass().defencesIllegalCloseDoorExtraInfo()
elif eventType == "0036": #低档高速报警
return EventClass().lowGearHighSpeedAlarm()
elif eventType == "0037": #高档低速报警
return EventClass().highGearLowSpeedAlarm()
elif eventType == "004A": #剩余油量异常告警
return EventClass().surplusOilAlarm()
#####################################################
# 获取附带信息(针对图形界面)
#####################################################
def getExtraData_GUI(self,eventData):
data = ""
dataNums = 0
if("0003" in eventData.keys()): #汽车电瓶低电压报警
dataNums = dataNums + 1
theData = ""
data = data + "0003" + self.int2hexStringByBytes(int((len(theData) / 2)),2) + theData
if ("0004" in eventData.keys()): #终端主电断电报警
dataNums = dataNums + 1
theData = ""
data = data + "0004" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0010" in eventData.keys()): #汽车点火上报
dataNums = dataNums + 1
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
eventObj.setSecurityData(self.securityPkg)
theData = eventObj.fireExtraInfo()
data = data + "0010" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0011" in eventData.keys()): #汽车熄火上报
dataNums = dataNums + 1
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
eventObj.setSecurityData(self.securityPkg)
theData = eventObj.fireExtraInfo()
data = data + "0011" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0012" in eventData.keys()): #汽车设防上报
dataNums = dataNums + 1
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
eventObj.setSecurityData(self.securityPkg)
theData = eventObj.setUpDefencesExtraInfo()
data = data + "0012" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0013" in eventData.keys()): #汽车撤防上报
dataNums = dataNums + 1
eventObj = EventClass()
eventObj.setGPSpkg(self.GPSPkg)
eventObj.setSecurityData(self.securityPkg)
theData = eventObj.setDownDefencesExtraInfo()
data = data + "0013" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0036" in eventData.keys()): #低档高速报警
dataNums = dataNums + 1
eventObj = EventClass()
theData = eventObj.lowGearHighSpeedAlarm(int(eventData["0036"]["alarmType"]),int(eventData["0036"]["durationTime"]))
data = data + "0036" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("0037" in eventData.keys()): #高档低速报警
dataNums = dataNums + 1
eventObj = EventClass()
theData = eventObj.lowGearHighSpeedAlarm(int(eventData["0036"]["alarmType"]),int(eventData["0036"]["durationTime"]))
data = data + "0037" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
if ("004A" in eventData.keys()): #高档低速报警
dataNums = dataNums + 1
eventObj = EventClass()
theData = eventObj.surplusOilAlarm(int(eventData["004A"]["surplusOilType"]),int(eventData["004A"]["value"]))
data = data + "004A" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
dataNumsHex = self.int2hexString(int(dataNums))
data = dataNumsHex +data
return data
if __name__ == "__main__":
data = {"a":1,"b":2,"c":{"d":3}}
data = {}
print(len(data))
\ No newline at end of file
#coding:utf-8
'''
定义一个GPS协议的类
'''
import datetime
from lib.util import dataUtil
from lib.protocol.report.ProtocolBase import ProtocolBase
'''
终端上报GPS定位数据包
'''
class GPSReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",UTCTime="2020-01-09 18:19:38",latitude=40.22077,longitude=116.23128,speed=60,directionAngle=80.8,elevation=2999.9,positionStar=3,Pdop=0.3,Hdop=0.4,Vdop=0.5,statusBit=175,valtage=36.9,OBDSpeed=60.9,engineSpeed=3000,GPSTotalMileage=12800,totalOil=100000,totalTime=2020002,GPSTimestamp=1578565178):
super().__init__()
self.msgCount = int(msgCount) # 设置默认要发送的GPS数据包个数
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.UTCTime = UTCTime # 设置默认UTC时间
self.latitude = float(latitude) # 设置默认纬度
self.longitude = float(longitude) # 设置默认经度
self.speed = float(speed) # 设置默认速度
self.directionAngle = float(directionAngle) # 设置默认方向角
self.elevation = float(elevation) # 设置默认海拔
self.positionStar = int(positionStar) # 设置默认定位星数
self.Pdop = float(Pdop)
self.Hdop = float(Hdop)
self.Vdop = float(Vdop)
self.statusBit = int(statusBit) # 设置默认状态字节
self.valtage = float(valtage) # 设置默认电压值
self.OBDSpeed = float(OBDSpeed) # 设置默认OBD车速
self.engineSpeed = int(engineSpeed) # 设置默认发动机转速
self.GPSTotalMileage = int(GPSTotalMileage) # 设置默认GPS累计里程
self.totalOil = int(totalOil) # 设置默认累计油耗
self.totalTime = int(totalTime) # 设置默认累计行驶时间
self.GPSTimestamp = int(GPSTimestamp) # 设置默认GPS信息时间戳
# self.msgCount = 1 #设置默认要发送的GPS数据包个数
#
# self.WATER_CODE = 1000; #设置默认消息流水号
# self.DEV_ID = "M121501010001" #设置默认设备id
#
# self.UTCTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') #设置默认UTC时间
# self.latitude = 40.22077 #设置默认纬度
# self.longitude = 116.23128 #设置默认经度
# self.speed = 60.9 #设置默认速度
# self.directionAngle = 80.8 #设置默认方向角
# self.elevation = 2999.9 #设置默认海拔
# self.positionStar = 3 #设置默认定位星数
# self.Pdop = 0.3
# self.Hdop = 0.4
# self.Vdop = 0.5
# self.statusBit = 175 #设置默认状态字节
# self.valtage = 36.9 #设置默认电压值
# self.OBDSpeed = 60.9 #设置默认OBD车速
# self.engineSpeed = 3000 #设置默认发动机转速
# self.GPSTotalMileage = 12800 #设置默认GPS累计里程
# self.totalOil = 100000 #设置默认累计油耗
# self.totalTime = 2020002 #设置默认累计行驶时间
# self.GPSTimestamp = int(time.time()) #设置默认GPS信息时间戳
#####################################################
# 生成GPS消息
#####################################################
def generateGpsMsg(self):
self.getProtocalHeader()
info = ""
#消息头
HEADER = "4040"
#消息流水号
WATER_CODE = self.getWaterCode(self.WATER_CODE)
#设备id
DEV_ID = self.devid2hexString(self.DEV_ID)
# 功能id(GPS功能id)
FUN_ID = "0010"
#数据段
data = ""
for i in range(0,self.msgCount):
data += self.generateGpsPkg(self.generateGpsData())
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
# 校验字段
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE
# print("header:" +HEADER)
# print("length:" + LENGTH)
# print("water:" + WATER_CODE)
# print("devid:" + DEV_ID)
# print("funid:" + FUN_ID)
# print("msg:" + info)
return info
#####################################################
# 创建GPS数据包,包含包个数
# data:传入GPS数据包的多条数据段
#####################################################
def generateGpsPkg(self,data):
pkgLen = len(data)
pkgNum = (pkgLen / 2)/49
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + data
return pkg
#####################################################
# 创建GPS数据段
#####################################################
def generateGpsData(self):
data = ""
#UTC时间
# UTCTime = self.getUTCTime("2020-01-03 13:05:13")
UTCTime = self.getUTCTime(self.UTCTime)
#纬度
latitude = self.getLatitude(self.latitude)
#经度
longitude = self.getLongitude(self.longitude)
#速度
speed = self.getSpeed(self.speed)
#方向角
directionAngle = self.getDirectionAngle(self.directionAngle)
#海拔
elevation = self.geteElevation(self.elevation)
#定字节星数
positionStar = self.getPositionStar(self.positionStar)
Pdop = self.getPdop(self.Pdop)
Hdop = self.getHdop(self.Hdop)
Vdop = self.getVdop(self.Vdop)
#状态字节
statusBit = self.getStatusBit(self.statusBit)
#电压
valtage = self.getValtage(self.valtage)
#OBD车速
OBDSpeed = self.getOBDSpeed(self.OBDSpeed)
#发动机转速
engineSpeed = self.getEngineSpeed(self.engineSpeed)
#GPS累计里程
GPSTotalMileage = self.getGPSTotalMileage(self.GPSTotalMileage)
#累计油耗
totalOil = self.getTotalOil(self.totalOil)
#累计行驶时间
totalTime = self.getTotalTime(self.totalTime)
#GPS信息时间戳
GPSTimestamp = self.getGPSTimestamp(self.GPSTimestamp)
data = UTCTime + latitude + longitude + speed + directionAngle
data = data + elevation + positionStar + Pdop + Hdop + Vdop
data = data + statusBit + valtage + OBDSpeed + engineSpeed +GPSTotalMileage
data = data + totalOil + totalTime + GPSTimestamp
return data
#####################################################
# 数字转换为16进制字符串
#####################################################
def int2hexString(self,num):
hexStr = hex(num)[2:]
if (len(hexStr) % 2) == 1:
hexStr = "0" + hexStr
return hexStr
#####################################################
# 获取消息体长度
#####################################################
def getMsgLength(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取功能id
#####################################################
def getFunId(self,num):
hexData = "0010"
return hexData
#####################################################
# 获取校验码
#####################################################
def getCheckCode(self,data):
return dataUtil.crc16(data)
#####################################################
# 将UTC时间转换为16进制,
# 例如:2020-01-02 20:30:00 (年取后面2字节)则将20,01,02,20,30,00 转换为对应的6个字节
# theTime:传入一个类似:2020-01-03 13:05:13的一个字符串
#####################################################
def getUTCTime(self,theTime):
# 获取当前时间,时间格式为:2020-01-03 13:05:13
# now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 将2020-01-03 13:05:13时间格式转换为一个数组
# timeStr = "2020-01-03 13:05:13"
timeStr = theTime
timeArr = []
timeArr.append(timeStr[2:4])
timeArr.append(timeStr[5:7])
timeArr.append(timeStr[8:11])
timeArr.append(timeStr[11:13])
timeArr.append(timeStr[14:16])
timeArr.append(timeStr[17:19])
UTCTime = ""
for i in range(0, len(timeArr)):
UTCTime += self.int2hexString(int(timeArr[i]))
return UTCTime
#####################################################
# 获取一个纬度,并转换为4个字节的16进制,例如(40.22077)
# latitude: float 类型的纬度数据
#####################################################
def getLatitude(self,latitude):
latitudeStr = str(latitude)
latitudeStr = latitudeStr.replace(".", "") # 去掉纬度小数点
#纬度去掉小数点后可能之后7位,所以在后面补了一个0到8位
while(len(latitudeStr) < 8):
latitudeStr += "0"
latitudeHex = hex(int(latitudeStr))
latitudeHex = self.leftPad(str(latitudeHex)[2:], 8)
return latitudeHex
#####################################################
# 获取一个经度,并转换为4个字节的16进制,例如(40.22077)
# latitude: float 类型的纬度数据
#####################################################
def getLongitude(self, num):
longitudeStr = str(num)
longitudeArr = longitudeStr.replace(".", "") # 去掉经度小数点
# 经度要求要有9位数,所以少于9位数的时候,在后面补0
while (len(longitudeArr) < 9):
longitudeArr += "0"
longitudeHex = hex(int(longitudeArr))
longitudeHex = self.leftPad(str(longitudeHex)[2:], 8)
return longitudeHex
#####################################################
# 获取速度,并转换为2个字节的16进制
#####################################################
def getSpeed(self,num):
speedStr = str(num)
speedStr = speedStr.replace(".", "") # 去掉经度小数点
speedHex = hex(int(speedStr))
speedHex = self.leftPad(str(speedHex)[2:], 4)
return speedHex
#####################################################
# 获取方向角度(角度精确到0.1度)
# 方向角的的传入值应该为x.x
# 方向角2个字节表示
#####################################################
def getDirectionAngle(self,num):
angleStr = str(num)
angleStr = angleStr.replace(".", "") # 去掉经度小数点
angleHex = hex(int(angleStr))
angleHex = self.leftPad(str(angleHex)[2:], 4)
return angleHex
#####################################################
# 获取海拔(精确到0.1米)
# 方向角的的传入值应该为x.x
# 4个字节表示
#####################################################
def geteElevation(self,num):
elevationStr = str(num)
elevationStr = elevationStr.replace(".", "") # 去掉经度小数点
while (len(elevationStr) < 8):
elevationStr = "0" + elevationStr
elevationHex = hex(int(elevationStr))
elevationHex = self.leftPad(str(elevationHex)[2:], 8)
return elevationHex
#####################################################
# 获取定字节星数,1字节表示
#####################################################
def getPositionStar(self,num):
# positionStarHex = self.int2hexString(num) #该方法同下
positionStarHex = hex(num)
positionStarHex = self.leftPad(str(positionStarHex)[2:], 2)
return positionStarHex
#####################################################
# Pdop:传输数值为原始值乘以10(即放大10倍,精度0.1),1字节表示
#####################################################
def getPdop(self,num):
pdopHex = self.int2hexString(int(num * 10))
return pdopHex
#####################################################
# Hdop:传输数值为原始值乘以10(即放大10倍,精度0.1),1字节表示
#####################################################
def getHdop(self, num):
hdopHex = self.int2hexString(int(num * 10))
return hdopHex
#####################################################
# Hdop:传输数值为原始值乘以10(即放大10倍,精度0.1),1字节表示
#####################################################
def getVdop(self, num):
vdopHex = self.int2hexString(int(num * 10))
return vdopHex
#####################################################
# 获取状态字节16进制,状态字节1字节表示
# Bit7:GPS当前定位是否有效,0-无效,1-有效;
# Bit6-4:指示当前定位模式:
# 0:自动模式;1:单GPS模式;2:单BDS模式;
# 3:GPS+BDS双模式;其它预留;
# Bit3-2:定位类型;
# 0~1:预留;2:2D定位;3:3D定位;
# Bit1:当前统计里程模式:
# 0-GPS统计里程;1-OBD统计里程;
# Bit0:指示当前车辆点熄火状态:0-熄火,1-点火
# (按照低位在前高位在后的方式去计算)
#####################################################
def getStatusBit(self,num):
fireStatus = 0 #点火状态,128表示点火,0表示熄火
mileageWay = 64 #0里程统计模式,表示GPS里程,64表示OBD里程
locationWay = 32 #定位类型,32表示2D定位,48表示3D定位
locationMode = 0 #定位模式,0表示自动模式,2表示单GPS模式,4表示单BDS模式,6表示GPS+BDS双模式
isLocationValid = 1 #当前定位是否有效,1表示有效,0表示无效
statusbitHex = self.int2hexString(num)
return statusbitHex
#####################################################
# 获取电压16进制值,2字节表示
#####################################################
def getValtage(self,num):
valtageStr = str(num)
valtageStr = valtageStr.replace(".", "")
while (len(valtageStr) < 4):
valtageStr = "0" + valtageStr
valtageHex = hex(int(valtageStr))
valtageHex = self.leftPad(str(valtageHex)[2:], 4)
return valtageHex
#####################################################
# 获取OBD车速,2字节表示
#####################################################
def getOBDSpeed(self,num):
OBDSpeedStr = str(num)
OBDSpeedStr = OBDSpeedStr.replace(".", "")
while (len(OBDSpeedStr) < 4):
OBDSpeedStr = "0" + OBDSpeedStr
OBDSpeedHex = hex(int(OBDSpeedStr))
OBDSpeedHex = self.leftPad(str(OBDSpeedHex)[2:], 4)
return OBDSpeedHex
#####################################################
# 获取发动机转速,2字节表示
#####################################################
def getEngineSpeed(self,num):
engineSpeedStr = str(num)
# engineSpeedStr = engineSpeedStr.replace(".", "")
while (len(engineSpeedStr) < 4):
engineSpeedStr = "0" + engineSpeedStr
engineSpeedHex = hex(int(engineSpeedStr))
engineSpeedHex = self.leftPad(str(engineSpeedHex)[2:], 4)
return engineSpeedHex
#####################################################
# 获取GPS累计里程,4字节表示
#####################################################
def getGPSTotalMileage(self,num):
GPSTotalMileageStr = str(num)
# GPSTotalMileageStr = GPSTotalMileageStr.replace(".", "")
while (len(GPSTotalMileageStr) < 8):
GPSTotalMileageStr = "0" + GPSTotalMileageStr
GPSTotalMileageHex = hex(int(GPSTotalMileageStr))
GPSTotalMileageHex = self.leftPad(str(GPSTotalMileageHex)[2:], 8)
return GPSTotalMileageHex
#####################################################
# 获取总油耗,4字节表示
#####################################################
def getTotalOil(self,num):
totalOilStr = str(num)
totalOilHex = hex(int(totalOilStr))
totalOilHex = self.leftPad(str(totalOilHex)[2:], 8)
return totalOilHex
#以下算法同上面的算法值一样
# hexData = self.int2hexString(num)
# while len(hexData) < 8:
# hexData = "0" + hexData
# return hexData
#####################################################
# 获取总行驶时间(秒),4字节表示
#####################################################
def getTotalTime(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
#####################################################
# 获取GPS信息时间戳,4字节表示
#####################################################
def getGPSTimestamp(self,num):
GPSTimestampHex = self.int2hexString(num)
while len(GPSTimestampHex) < 8:
GPSTimestampHex = "0" + GPSTimestampHex
return GPSTimestampHex
# 设置要发送的GPS数据包个数
def setMsgCount(self,msgCount):
self.msgCount = int(msgCount)
# 设置消息流水号
def setWATER_CODE(self,WATER_CODE ):
self.WATER_CODE = int(WATER_CODE)
# 设置设备id
def setDEV_ID(self,DEV_ID):
self.DEV_ID = DEV_ID
# 设置UTC时间
def setUTCTime(self,UTCTime):
self.UTCTime = UTCTime
# 设置纬度
def setLatitude(self,latitude):
self.latitude = float(latitude)
# 设置经度
def setLongitude(self,longitude):
self.longitude = float(longitude)
# 设置速度
def setSpeed(self,speed):
self.speed = float(speed)
# 设置方向角
def setDirectionAngle(self,directionAngle):
self.directionAngle = float(directionAngle)
# 设置海拔
def setElevation(self,elevation):
self.elevation = float(elevation)
# 设置定位星数
def setPositionStar(self,positionStar):
self.positionStar = int(positionStar)
def setPdop(self,Pdop):
self.Pdop = float(Pdop)
def setHdop(self,Hdop):
self.Hdop = float(Hdop)
def setVdop(self,Vdop):
self.Vdop = float(Vdop)
# 设置状态字节
def setStatusBit(self,statusBit):
self.statusBit = int(statusBit)
# 设置电压值
def setValtage(self,valtage):
self.valtage = float(valtage)
# 设置OBD车速
def setOBDSpeed(self,OBDSpeed):
self.OBDSpeed = float(OBDSpeed)
# 设置发动机转速
def setEngineSpeed(self,engineSpeed):
self.engineSpeed = int(engineSpeed)
# 设置GPS累计里程
def setGPSTotalMileage(self,GPSTotalMileage):
self.GPSTotalMileage = int(GPSTotalMileage)
#设置累计油耗
def setTotalOil(self,totalOil):
self.totalOil = int(totalOil)
# 设置累计行驶时间
def setTotalTime(self,totalTime):
self.totalTime = int(totalTime)
# 设置GPS信息时间戳
def setGPSTimestamp(self,GPSTimestamp):
self.GPSTimestamp = int(GPSTimestamp)
if __name__ == "__main__":
GPSReport_protocol().generateGpsMsg()
# Gps_protocol().getLatitude(40.22077)
# print(Gps_protocol().getHexTime())
print(GPSReport_protocol().getUTCTime(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
print(datetime.datetime.now())
# Gps_protocol().generateGpsData()
# Gps_protocol().getLatitude(40.22077)
# Gps_protocol().getLongitude(116.23128)
# Gps_protocol().getDirectionAngle(0.5)
# Gps_protocol().geteElevation(2999.9)
# Gps_protocol().getOBDSpeed(10.1)
\ No newline at end of file
#coding:utf-8
'''
定义一个心跳协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
'''
终端心跳协议数据包
'''
class HeartBeatReport_protocol(ProtocolBase):
def __init__(self,WATER_CODE = "0003",DEV_ID = "M121501010001"):
super().__init__()
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
#####################################################
# 生成心跳消息
#####################################################
def generateHeartBeatMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" # 消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) # 消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) # 设备id
FUN_ID = "0003" # 功能id(心跳功能id)
data = "" # 数据段
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
if __name__ == "__main__":
pass
\ No newline at end of file
#coding:utf-8
'''
定义一个终端登录协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class LoginReport_protocol(ProtocolBase):
def __init__(self,WATER_CODE = "0002",DEV_ID = "M121501010001",cpuId="CPU-ID001122334455667788",imsi="IMSI13145678902",ccid="CCID1122334455667788",imei="IMEI12233445566"):
super().__init__()
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.cpuId = cpuId #设置默认cupId值
self.imsi = imsi #设置默认imsi值
self.ccid = ccid #设置默认ccid值
self.imei = imei #设置默认imei值
#####################################################
# 生成终端登录消息
#####################################################
def generateLoginMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" # 消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) # 消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) # 设备id
FUN_ID = "0002" # 功能id(终端登录功能id)
data = self.generateLoginData() # 数据段
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建终端登录数据段
#####################################################
def generateLoginData(self):
data = ""
CPU_ID = self.getCPU_IDHex(self.cpuId) #CPU-ID
IMSI = self.getIMSIHex(self.imsi) #IMSI
CCID = self.getCCIDHex(self.ccid) #CCID
IMEI = self.getIMEIHex(self.imei) #IMEI
data = data + CPU_ID + IMSI +CCID +IMEI
return data
#####################################################
# 获取CPU_ID对应的16进制数据
#####################################################
def getCPU_IDHex(self,data):
return self.str2Hex(data)
#####################################################
# 获取IMSI对应的16进制数据
#####################################################
def getIMSIHex(self,data):
return self.str2Hex(data)
#####################################################
# 获取CCID对应的16进制数据
#####################################################
def getCCIDHex(self,data):
return self.str2Hex(data)
#####################################################
# 获取IMDE对应的16进制数据
#####################################################
def getIMEIHex(self,data):
return self.str2Hex(data)
if __name__ == "__main__":
print(LoginReport_protocol().generateLoginData())
\ No newline at end of file
#coding:utf-8
'''
定义一个OBD终端上报CAN静态数据类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class OBDReport_CAN_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",infoTime="2020-01-10 16:29:19",dataFlowCode="ffffffffff",protocolType="0101",fireStatus=1,ACCStatus=1,voltage=12,troubleLightStatus=0,toubleCodeCount=0,engineSpeed=4000,speed=60,meterMileage=128500,mileageStatisticsStyle="01",totalMileage=4129040,troubleMileage=500,totalOilExpend=3500,surplusOil=505,totalRunTime=50000000,totalEngineTime=5000,airIntoAisleTemperture=42,coolingLiquidTemperture=38,envTemperture=68,ariIntoPress=20,oilPressure=550,atmosphericPressure=120,airFlow=3600,valveLocationSensor=4000,acceleratorLocation=50,engineLoad=55,fuelTrim=34,fireAngle=800,B1S1oxygenSensorVoltage=18,B1S2oxygenSensorVoltage=20,B1S1oxygenSensorElectricity=13000,B1S2oxygenSensorElectricity=13200,momentOilExpend=15,meterOilExpend=20000,engineAbsoluteLoad=32,steeringWheelAngle=10,torquePercentage=31,gearsLocation=1,GPSSpeed=72.4,GPSMileage=380000):
pass
self.msgCount = int(msgCount) # 设置默认要发送的数据包个数
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.infoTime = infoTime # 设置时间
self.dataFlowCode = dataFlowCode # 设置数据流掩码
self.protocolType = protocolType # 设置协议类型
self.fireStatus = int(fireStatus) # 设置点火状态
self.ACCStatus = int(ACCStatus) # 设置ACC状态
self.voltage = float(voltage) # 设置电瓶电压
self.troubleLightStatus = int(troubleLightStatus) # 设置故障灯状态(MIL)
self.toubleCodeCount = int(toubleCodeCount) # 设置故障码个数
self.engineSpeed = int(engineSpeed) # 设置发动机转速
self.speed = int(speed) # 设置车辆速度
self.meterMileage = int(meterMileage) # 设置仪表里程值
self.mileageStatisticsStyle = mileageStatisticsStyle # 设置里程统计方式
self.totalMileage = int(totalMileage) # 设置总里程值
self.troubleMileage = int(troubleMileage) # 设置故障行驶里程
self.totalOilExpend = int(totalOilExpend) # 设置总耗油量
self.surplusOil = int(surplusOil) # 设置剩余油量
self.totalRunTime = int(totalRunTime) # 设置车辆运行时间
self.totalEngineTime = int(totalEngineTime) # 设置发动机运行时间
self.airIntoAisleTemperture = int(airIntoAisleTemperture) # 设置进气口温度
self.coolingLiquidTemperture = int(coolingLiquidTemperture) # 设置冷却液温度
self.envTemperture = int(envTemperture) # 设置车辆环境温度
self.ariIntoPress = int(ariIntoPress) # 设置进气管压力
self.oilPressure = int(oilPressure) # 设置燃油压力
self.atmosphericPressure = int(atmosphericPressure) # 设置大气压力
self.airFlow = int(airFlow) # 设置空气流量
self.valveLocationSensor = int(valveLocationSensor) # 设置气门位置传感器
self.acceleratorLocation = int(acceleratorLocation) # 设置油门位置
self.engineLoad = int(engineLoad) # 设置发动机负荷
self.fuelTrim = int(fuelTrim) # 设置长期燃油修正
self.fireAngle = int(fireAngle) # 设置点火提前角
self.B1S1oxygenSensorVoltage = int(B1S1oxygenSensorVoltage) # 设置B1-S1氧传感器输出电压
self.B1S2oxygenSensorVoltage = int(B1S2oxygenSensorVoltage) # 设置B1-S2氧传感器输出电压
self.B1S1oxygenSensorElectricity = int(B1S1oxygenSensorElectricity) # 设置B1-S1氧传感器输出电流
self.B1S2oxygenSensorElectricity = int(B1S2oxygenSensorElectricity) # 设置B1-S2氧传感器输出电流
self.momentOilExpend = int(momentOilExpend) # 设置瞬时油耗
self.meterOilExpend = int(meterOilExpend) # 设置仪表油耗
self.engineAbsoluteLoad = int(engineAbsoluteLoad) # 设置发动机绝对负荷
self.steeringWheelAngle = int(steeringWheelAngle) # 设置方向盘转向角
self.torquePercentage = int(torquePercentage) # 设置扭矩百分比
self.gearsLocation = int(gearsLocation) # 设置档位(仅商用车)
self.GPSSpeed = float(GPSSpeed) # 设置GPS车速
self.GPSMileage = int(GPSMileage) # 设置GPS里程
def setInfoTime(self,data):
self.infoTime = data
def setFireStatus(self,data): #点火状态
self.fireStatus = data
def setACCStatus(self,data): #ACC状态
self.ACCStatus = data
def setEngineSpeed(self,data): #发动机转速
self.engineSpeed = data
def setSpeed(self,data): #车辆速度
self.speed = data
def setMeterMileage(self,data): #汽车仪表里程值
self.meterMileage = data
def setTotalMileage(self,data): #总里程
self.totalMileage = data
def setTroubleMileage(self,data): #故障行驶里程
self.troubleMileage = data
def setTotalOilExpend(self,data): #总油耗
self.totalOilExpend = data
def setSurplusOil(self,data): #剩余油量
self.surplusOil = data
def setTotalRunTime(self,data): #车辆总运行时间
self.totalRunTime = data
#####################################################
# 生成OBD终端上报CAN配置信息
#####################################################
def generateOBDReportCANMsg(self):
self.getProtocalHeader()
info = ""
#消息头
HEADER = "4040"
#消息流水号
# WATER_CODE = self.getWaterCode(1000)
WATER_CODE = self.getWaterCode(self.WATER_CODE)
#设备id
# DEV_ID = self.devid2hexString("M121501010001")
DEV_ID = self.devid2hexString(self.DEV_ID)
# 功能id(OBD_CAN功能id)
FUN_ID = "0012"
#数据段
data = ""
for i in range(0,self.msgCount):
data += self.generateBD_CAN_Pkg(self.generateOBD_CAN_Data())
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
# 校验字段
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE
return info
#####################################################
# 创建OBD的CAN数据包,包含包个数
# data:传入OBD的CAN数据包的多条数据段
#####################################################
def generateBD_CAN_Pkg(self, data):
pkgLen = len(data)
pkgNum = (pkgLen / 2) / 100
# print("------------------------" + str(pkgNum))
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + data
return pkg
####################################################
# 生成OBD终端上报CAN数据包
#####################################################
def generateOBD_CAN_Data(self):
data = ""
#时间
# infoTime = self.getTimeHex(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
infoTime = self.getTimeHex(self.infoTime)
#数据流掩码
# dataFlowCode = self.getDataFlowCodeHex()
dataFlowCode = self.dataFlowCode
#协议类型
# protocolType = self.getProtocolTypeHex()
protocolType = self.protocolType
#点火状态
fireStatus = self.getFireStatusHex(self.fireStatus)
#ACC状态
ACCStatus = self.getACCStatusHex(self.ACCStatus)
#电瓶电压
voltage = self.getVoltageHex(self.voltage)
#故障灯状态(MIL)
troubleLightStatus = self.getTroubleLightStatusHex(self.troubleLightStatus)
#故障码个数
toubleCodeCount = self.getToubleCodeCountHex(self.toubleCodeCount)
#发动机转速
engineSpeed = self.getEngineSpeedHex(self.engineSpeed)
#车辆速度
speed = self.getSpeedHex(self.speed)
#仪表里程值
meterMileage = self.getMeterMileageHex(self.meterMileage)
#里程统计方式
# mileageStatisticsStyle = self.getMileageStatisticsStyleHex()
mileageStatisticsStyle = self.mileageStatisticsStyle
#总里程值
totalMileage = self.getTotalMileageHex(self.totalMileage)
#故障行驶里程
troubleMileage = self.getTroubleMileageHex(self.troubleMileage)
#总耗油量
totalOilExpend = self.getTotalOilExpendHex(self.totalOilExpend)
#剩余油量
surplusOil = self.getSurplusOilHex(self.surplusOil)
#车辆总运行时间
totalRunTime = self.getTotalRunTimeHex(self.totalRunTime)
#发动机运行时间
totalEngineTime = self.getTotalEngineTimeHex(self.totalEngineTime)
#进气口温度
airIntoAisleTemperture = self.getAirIntoAisleTempertureHex(self.airIntoAisleTemperture)
#冷却液温度
coolingLiquidTemperture = self.getCoolingLiquidTempertureHex(self.coolingLiquidTemperture)
#车辆环境温度
envTemperture = self.getEnvTempertureHex(self.envTemperture)
#进气管压力
ariIntoPress = self.getAriIntoPressHex(self.ariIntoPress)
#燃油压力
oilPressure = self.getOilPressureHex(self.oilPressure)
#大气压力
atmosphericPressure = self.getAtmosphericPressureHex(self.atmosphericPressure)
#空气流量
airFlow = self.getAirFlowHex(self.airFlow)
#气门位置传感器
valveLocationSensor = self.getValveLocationSensorHex(self.valveLocationSensor)
#油门位置
acceleratorLocation = self.getAcceleratorLocationHex(self.acceleratorLocation)
#发动机负荷
engineLoad = self.getEngineLoadHex(self.engineLoad)
#长期燃油修正
fuelTrim = self.getFuelTrimHex(self.fuelTrim)
#点火提前角
fireAngle = self.getFireAngleHex(self.fireAngle)
#B1-S1氧传感器输出电压
B1S1oxygenSensorVoltage = self.getB1S1OxygenSensorVoltageHex(self.B1S1oxygenSensorVoltage)
# B1-S2氧传感器输出电压
B1S2oxygenSensorVoltage = self.getB1S2OxygenSensorVoltageHex(self.B1S2oxygenSensorVoltage)
#B1-S1氧传感器输出电流
B1S1oxygenSensorElectricity = self.B1S1oxygenSensorElectricityHex(self.B1S1oxygenSensorElectricity)
# B1-S2氧传感器输出电流
B1S2oxygenSensorElectricity = self.B1S2oxygenSensorElectricityHex(self.B1S2oxygenSensorElectricity)
#瞬时油耗
momentOilExpend = self.getMomentOilExpendHex(self.momentOilExpend)
#仪表油耗
meterOilExpend = self.getMeterOilExpendHex(self.meterOilExpend)
#发动机绝对负荷
engineAbsoluteLoad = self.getEngineAbsoluteLoadHex(self.engineAbsoluteLoad)
#方向盘转向角
steeringWheelAngle = self.getSteeringWheelAngleHex(self.steeringWheelAngle)
#扭矩百分比
torquePercentage = self.getTorquePercentageHex(self.torquePercentage)
#档位(仅商用车)
gearsLocation = self.getGearsLocationHex(self.gearsLocation)
#GPS车速
GPSSpeed = self.getGPSSpeedHex(self.GPSSpeed)
#GPS里程
GPSMileage = self.getGPSMileageHex(self.GPSMileage)
#预留字段
retain = self.getRetainHex()
data = data + infoTime + dataFlowCode + protocolType + fireStatus + ACCStatus + voltage + troubleLightStatus
data = data + toubleCodeCount + engineSpeed + speed + meterMileage + mileageStatisticsStyle + totalMileage
data = data + troubleMileage + totalOilExpend + surplusOil + totalRunTime + totalEngineTime + airIntoAisleTemperture
data = data + coolingLiquidTemperture + envTemperture + ariIntoPress + oilPressure + atmosphericPressure + airFlow
data = data + valveLocationSensor + acceleratorLocation + engineLoad + fuelTrim + fireAngle
data = data + B1S1oxygenSensorVoltage + B1S2oxygenSensorVoltage + B1S1oxygenSensorElectricity + B1S2oxygenSensorElectricity
data = data + momentOilExpend + meterOilExpend + engineAbsoluteLoad + steeringWheelAngle + torquePercentage
data = data + gearsLocation + GPSSpeed + GPSMileage + retain
return data
####################################################
# 将U时间转换为16进制,
# 例如:2020-01-02 20:30:00 (年取后面2字节)则将20,01,02,20,30,00 转换为对应的6个字节
# theTime:传入一个类似:2020-01-03 13:05:13的一个字符串
#####################################################
def getTimeHex(self, theTime):
# 获取当前时间,时间格式为:2020-01-03 13:05:13
# now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 将2020-01-03 13:05:13时间格式转换为一个数组
# timeStr = "2020-01-03 13:05:13"
timeStr = theTime
timeArr = []
timeArr.append(timeStr[2:4])
timeArr.append(timeStr[5:7])
timeArr.append(timeStr[8:11])
timeArr.append(timeStr[11:13])
timeArr.append(timeStr[14:16])
timeArr.append(timeStr[17:19])
time = ""
for i in range(0, len(timeArr)):
time += self.int2hexString(int(timeArr[i]))
return time
####################################################
# 获取数据流掩码的16进制数据
# 数据流掩码,标识以下可支持的各数据流字段,每个BIT位表示一个数据流字段;
#####################################################
def getDataFlowCodeHex(self):
return "0102030405"
####################################################
# 获取协议类型的16进制数据
#####################################################
def getProtocolTypeHex(self):
OBD_ST_HCAN = "0101"
OBD_ST_MCAN = "0102"
OBD_EX_HCAN = "0103"
OBD_EX_MCAN = "0104"
OBD_FK = "0105"
OBD_K_ADDR = "0106"
OBD_ISO = "0107"
OBD_VPW = "0108"
OBD_PWM = "0109"
VW_ST_HCAN = "0201"
VW_BOSCH = "0202"
VW_TP_CAN = "0203"
VW_K_ADDR = "0204"
VW_UDS = "VW_UDS"
return OBD_ST_HCAN
####################################################
# 获取点火状态的16进制数据
# 0:熄火 1:点火
#####################################################
def getFireStatusHex(self,num=1):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取ACC状态的16进制数据
# 0:OFF 1:ON
#####################################################
def getACCStatusHex(self,num = 1):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取电瓶电压的16进制数据
# 单位:0.01V
###################################################
def getVoltageHex(self,num):
valtageStr = str(num)
valtageStr = valtageStr.replace(".", "")
while (len(valtageStr) < 4):
valtageStr = "0" + valtageStr
valtageHex = hex(int(valtageStr))
valtageHex = self.leftPad(str(valtageHex)[2:], 4)
return valtageHex
####################################################
# 获取故障灯状态的16进制数据
# if(Bit0) ON else OFF
#####################################################
def getTroubleLightStatusHex(self,num = 0):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取故障个数的16进制数据
#####################################################
def getToubleCodeCountHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取发动机转速的16进制数据
#####################################################
def getEngineSpeedHex(self,num):
engineSpeedStr = str(num)
while (len(engineSpeedStr) < 4):
engineSpeedStr = "0" + engineSpeedStr
engineSpeedHex = hex(int(engineSpeedStr))
engineSpeedHex = self.leftPad(str(engineSpeedHex)[2:], 4)
return engineSpeedHex
####################################################
# 获取车辆速度的16进制数据
#####################################################
def getSpeedHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取仪表里程值的16进制数据
#####################################################
def getMeterMileageHex(self,num):
totalMeterStrHex = self.int2hexStringByBytes(num,4)
return totalMeterStrHex
####################################################
# 获取里程统计方式的16进制数据
# 总里程类型:
# 00:GPS里程统计方式
# 01:OBD里程统计方式
#####################################################
def getMileageStatisticsStyleHex(self):
GPS = "00"
OBD = "01"
return GPS
####################################################
# 获取总里程值的16进制数据
# 行驶里程,上报值单位为m(米)
#####################################################
def getTotalMileageHex(self,num):
totalMileageStr = str(num)
totalMileageStrHex = hex(int(totalMileageStr))
totalMileageStrHex = self.leftPad(str(totalMileageStrHex)[2:], 8)
return totalMileageStrHex
####################################################
# 获取故障行驶里程的16进制数据(km)
#####################################################
def getTroubleMileageHex(self,num):
dataStr = str(num)
dataHex = hex(int(dataStr))
dataHex = self.leftPad(str(dataHex)[2:], 8)
return dataHex
####################################################
# 获取总油耗量的16进制数据(ml 毫升)
#####################################################
def getTotalOilExpendHex(self,num):
dataStr = str(num)
dataHex = hex(int(dataStr))
dataHex = self.leftPad(str(dataHex)[2:], 8)
return dataHex
####################################################
# 获取剩余油量的16进制数据
# 剩余油量,单位L或 %
# bit15 == 0 百分比 % OBD都为百分比
# bit15 == 1 单位L
# 显示值为上报值 / 10
#####################################################
def getSurplusOilHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取车辆总运行时间的16进制数据(单位秒)
#####################################################
def getTotalRunTimeHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
####################################################
# 获取发动机总运行时间的16进制数据(单位秒)
#####################################################
def getTotalEngineTimeHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取进气口温度的16进制数据
# 进气口温度(上报范围0~255)
# 显示值为上报值 - 40(实际范围 - 40~215)
#####################################################
def getAirIntoAisleTempertureHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取l冷却液温度的16进制数据
# 进气口温度(上报范围0~255)
# 显示值为上报值 - 40(实际范围 - 40~215)
#####################################################
def getCoolingLiquidTempertureHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取车辆环境温度的16进制数据
# 进气口温度(上报范围0~255)
# 显示值为上报值 - 40(实际范围 - 40~215)
#####################################################
def getEnvTempertureHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取进气管压力的16进制数据
# 进气歧管压力 (10~105kpa)
#####################################################
def getAriIntoPressHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取燃油压力的16进制数据
#####################################################
def getOilPressureHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取大气压力的16进制数据
#####################################################
def getAtmosphericPressureHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取空气流量的16进制数据
#####################################################
def getAirFlowHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取气门位置传感器的16进制数据
#####################################################
def getValveLocationSensorHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取油门位置的16进制数据
# 显示值为上报值/10 ( 0~100)
#####################################################
def getAcceleratorLocationHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取发动机负荷的16进制数据
# 发动机负荷, 0~100
#####################################################
def getEngineLoadHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取长期燃油修正的16进制数据
# 显示值为(上报值/10)-100
##################################################
def getFuelTrimHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取点火提前角的16进制数据
# 显示值为(上报值/10)-64
##################################################
def getFireAngleHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取B1-S1氧传感器输出电压的16进制数据
# 显示值为上传值/10,单位0.1V
####################################################
def getB1S1OxygenSensorVoltageHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取B1-S2氧传感器输出电压的16进制数据
# 显示值为上传值/10,单位0.1V
####################################################
def getB1S2OxygenSensorVoltageHex(self, num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取B1-S1氧传感器输出电流的16进制数据
# 显示值为(上传值/100)-128,单位0.01mA
####################################################
def B1S1oxygenSensorElectricityHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取B1-S2氧传感器输出电流的16进制数据
# 显示值为(上传值/100)-128,单位0.01mA
####################################################
def B1S2oxygenSensorElectricityHex(self, num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取瞬时油耗的16进制数据
# 显示值为(上传值/100),单位L/h
####################################################
def getMomentOilExpendHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取仪表油耗的16进制数据
# 总的燃油消耗量,上报值单位为ml(毫升)
####################################################
def getMeterOilExpendHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
####################################################
# 获取发动机绝对负荷的16进制数据
# 显示值为(上传值/100),单位%
####################################################
def getEngineAbsoluteLoadHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取方向盘转向角的16进制数据
# 显示值为(上传值/10)-3276.7
####################################################
def getSteeringWheelAngleHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
####################################################
# 获取方扭矩百分比的16进制数据
# 显示值为0~100,单位%
####################################################
def getTorquePercentageHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取档位(仅商用车)的16进制数据
# 商用车:0为空档,1-16为前进档,17-20为后退档,21为P档
####################################################
def getGearsLocationHex(self,num):
hexData = self.int2hexString(num)
return hexData
####################################################
# 获取GPS车速的16进制数据
# 车辆速度,单位0.1Km/h
####################################################
def getGPSSpeedHex(self,num):
dataStr = str(num)
dataStr = dataStr.replace(".", "") # 去掉经度小数点
dataHex = hex(int(dataStr))
dataHex = self.leftPad(str(dataHex)[2:], 4)
return dataHex
####################################################
# 获取GPS里程的16进制数据
# GPS里程,单位M
####################################################
def getGPSMileageHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 8:
hexData = "0" + hexData
return hexData
####################################################
# 获取预留字段的16进制数据
####################################################
def getRetainHex(self):
return "0000000000000000000000"
if __name__ == "__main__":
# print(OBDReport_CAN_protocol().getTotalMileageHex(128500))
OBDReport_CAN_protocol().generateOBD_CAN_Data()
#coding:utf-8
'''
定义一个终端上报OBD适配信息
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class OBDReport_protocol(ProtocolBase):
def __init__(self):
pass
#####################################################
# 生成OBD终端上报配置信息
#####################################################
def generateOBDReportMsg(self):
self.getProtocalHeader()
info = ""
#消息头
HEADER = "4040"
#消息流水号
WATER_CODE = self.getWaterCode(1000)
#设备id
DEV_ID = self.devid2hexString("M121501010001")
# 功能id(GPS功能id)
FUN_ID = "0008"
#数据段
data = self.generateOBDData()
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
# 校验字段
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE
return info
#####################################################
# 生成OBD终端上报数据包
#####################################################
def generateOBDData(self):
data = ""
#每条信息默认带两个字节
default = "0000"
#获取协议类型
protocolType = self.getProtocolTypeHex()
#读码方式
readType = self.getReadTypeHex()
#防盗协议
securityProtocal = self.getSecurityProtocalHex()
#车型ID
carId = self.getCarIdHex()
#帧与帧间隔
frameInterval = self.getFrameIntervalHex(100)
#ECU地址
ECU = self.getECUHex()
#油耗系数
oilExpend = self.getOilExpendHex(999)
#里程系数
mileageCoefficient = self.getMileageCoefficientHex(888)
#排量
displacement = self.getDisplacementHex(80)
#油品密度
oilDensity = self.getOilDensityHex()
#油耗计算方法
oilCalculateMode = self.getOilCalculateModeHex()
#数据流读取时间
dataFlowTime = self.getDataFlowTimeHex(60)
#换车标志
carSign = self.getCarSignHex()
#车辆动力类型
carPowerMode = self.getCarPowerModeHex()
#最大扭矩
maxTorque = self.getMaxTorqueHex(1000)
#发动机缸数
engineJar = self.getEngineJarHex(8)
#满载电量
fullElec = self.getFullElecHex(400)
#里程协议编号
mileageNum = self.getMileageNumHex()
#OBD扫描方式
OBDScanWay = self.getOBDScanWayHex(2)
#保留数据
retainData = self.getRetainDataHex()
# data = data + default + protocolType + readType + securityProtocal + carId + frameInterval
# data = data + ECU + oilExpend + mileageCoefficient + displacement + oilDensity + oilCalculateMode
# data = data + dataFlowTime + carSign + carPowerMode + maxTorque + engineJar + fullElec
# data = data + mileageNum + OBDScanWay + retainData
data = data + default + "01" + protocolType + "02" + readType + "03" + securityProtocal + "04" + carId + "05" + frameInterval
data = data + "06" + ECU + "07" + oilExpend + "08" + mileageCoefficient + "09" + displacement + "0A" + oilDensity + "0B" + oilCalculateMode
data = data + "0C" + dataFlowTime + "0D" + carSign + "0E" + carPowerMode + "0F" + maxTorque + "10" + engineJar + "11" + fullElec
data = data + "12" + mileageNum + "13" + OBDScanWay + "14" + retainData
return data
#####################################################
# 获取协议类型的16进制数据
#####################################################
def getProtocolTypeHex(self):
#非以下数据,其他数据为无效或错误数据,0x0000为无效数据
OBD_ST_HCAN = "0101"
OBD_ST_MCAN = "0102"
OBD_EX_HCAN = "0103"
OBD_EX_MCAN = "0104"
OBD_FK = "0105"
OBD_K_ADDR = "0106"
OBD_ISO = "0107"
OBD_VPW = "0108"
OBD_PWM = "0109"
VW_ST_HCAN = "0201"
VW_BOSCH = "0202"
VW_TP_CAN = "0203"
VW_K_ADDR = "0204"
VW_UDS = "0205"
#禁止 / 不支持OBD功能[车机禁止访问ECU]
FORBID = "FFFE"
#车机自动扫描
AUTO = "FFFF"
return OBD_ST_HCAN
#####################################################
# 获取读码方式的16进制数据
#####################################################
def getReadTypeHex(self):
#无效数据:0x00
#不读取故障码
NO_READ = "01"
#15s读取故障码
READ = "02"
return READ
#####################################################
# 获取防盗协议的16进制数据
#####################################################
def getSecurityProtocalHex(self):
#无效数据:0x00000000
#有效数据: 0x00000001~0X000000FE:
return "00000001"
#####################################################
# 获取车型id的16进制数据
####################################################
def getCarIdHex(self):
#无效数据:0x00000000 , 错误数据:其他值为错误数据
FENG_TIAN = "00001E00" #丰田
BEND_TIAN = "00000900" #本田
RI_CHAN = "00004900" #日产
TONG_YONG = "00000C00" #通用
FU_TE = "00001F00" #福特
DA_ZHONG = "00001500" #大众、奥迪、西雅特、斯柯达
ZHONG_HUA = "00005E00" #中华
BI_YA_DI = "00000A00" #比亚迪
JIANG_HUAI = "00002C00" #江淮
BIAO_ZHI = "00000B00" #标致(3008)
DEFAULT = "0000FF00" #出场默认车型
return BI_YA_DI
#####################################################
# 获取帧与帧间隔的16进制数据
# 无效数据:0
# 有效数据:50~5000(单位MS)
# 错误数据:其他值为错误数据
####################################################
def getFrameIntervalHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取ECU地址的16进制数据
# 无效数据:0x00000000
# 有效数据:0x00000001~0xFFFFFFFF
# 错误数据:其他
####################################################
def getECUHex(self):
return "00000001"
#####################################################
# 获取油耗系数的16进制数据
# 无效数据: 0
# 有效数据: 1~1000
# 错误数据:其他
##################################################
def getOilExpendHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取里程系数的16进制数据
# 无效数据:0
# 有效数据:1~1000
# 错误数据:其他
##################################################
def getMileageCoefficientHex(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取排量的16进制数据
# 排量:实际值=设置值/10
# 无效数据:0
# 有效数据:5~100
# 错误数据:其他
#####################################################
def getDisplacementHex(self,num):
hexData = self.int2hexString(num)
return hexData
#####################################################
# 获取油耗密度的16进制数据
#####################################################
def getOilDensityHex(self):
CAI_YOU_0 = 835 #柴油0#
CAI_YOU_10 = 840 #柴油10#
CAI_YOU_20 = 830 #柴油20#
CAI_YOU_5 = 840 #柴油5#
CAI_YOU_35 = 820 #柴油35
CAI_YOU_50 = 816 #柴油50#
QI_YOU_90 = 722 #汽油90#
QI_YOU_93 = 725 #汽油93#
QI_YOU_97 = 737 #汽油97#
QI_YOU_98 = 753 #汽油98#
num = QI_YOU_93
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取油耗计算方式16进制数据
# 无效数据:0x00;
# 错误数据:其他
#####################################################
def getOilCalculateModeHex(self):
MOMENT_OIL = "01" #瞬时油耗算法
AIR_FLOW = "02" #空气流量算法
INTO_STRESS = "03" #进气歧管压力算法
ENGINE_LOAD = "04" #发动机绝对负荷算法
GAS_DOOR = "05" #节气门算法
CAR_SPEED = "06" #车速模拟算法
ROTATE_SPEED = "07" #车速转速模拟算法
METER_OIL = "08" #仪表油耗算累计油耗
GUSH_OIL = "09" #喷油量算累计油耗
ENGINE_TORQUE = "0A" #发动机实际扭矩
ENGINE_TORQUE_PERSENT = "0B" #发动机扭矩百分比
return AIR_FLOW
#####################################################
# 获取数据流读取时间的16进制数据
# 无读取数据流时间,单位秒;
# 无效数据:0
# 有效数据:30~200(默认30)
# 错误数据:其他
#####################################################
def getDataFlowTimeHex(self,num=30):
hexData = self.int2hexString(num)
return hexData
#####################################################
# 获取换车标志16进制数据
# 用于平台下发OBD适配信息时,标识当前车机是否已换车:
# 无效数据:0x00
# 错误数据:其他
#####################################################
def getCarSignHex(self):
INDETERMINATION = "01" #未确定
NO_CHANGE = "02" #未换车
CHANGED = "03" #已换车
return NO_CHANGE
#####################################################
# 获取车辆动力类型16进制数据
# 用于平台下发OBD适配信息时,标识车辆动力类型:
# 无效数据:0x00
# 错误数据:其他
#####################################################
def getCarPowerModeHex(self):
FIRE_ENGINE = "01" #内燃机
FIRE_ELEC = "02" #油电混合
ONlY_ELEC = "03" #纯电动车
return FIRE_ELEC
#####################################################
# 发动机最大扭矩
# 无效数据:0
# 有效数据:100~5000(默认800)
# 错误数据:其他;
#####################################################
def getMaxTorqueHex(self,num = 800):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 发动机气缸数
# 无效数据:0
# 有效数据:3~12(默认6)
# 错误数据:其他;
#####################################################
def getEngineJarHex(self,num = 6):
hexData = self.int2hexString(num)
return hexData
#####################################################
# 电动车满载电量
# 无效数据:0
# 有效数据:10~1000(默认200)
# 错误数据:其他;
#####################################################
def getFullElecHex(self,num = 200):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 里程协议编号
# 无效数据:0
# 有效数据:
# 1~0xfe:具体的某个里程协议
# 0xff:自动扫描里程协议
# 有效数据:1-0xff(默认0xff:自动扫描里程协议)
# 错误数据:无;;
#####################################################
def getMileageNumHex(self):
return "ff"
#####################################################
# OBD扫描优先方式
# 有效数据:0~4(默认0)
# 错误数据: 其他
#####################################################
def getOBDScanWayHex(self,num=0):
hexData = self.int2hexString(num)
return hexData
#####################################################
# 保留数据字节:0x00000000
#####################################################
def getRetainDataHex(self):
return "00000000"
if __name__ == "__main__":
# print(OBDReport_protocol().getDisplacementHex(2))
print(OBDReport_protocol().generateOBDData())
print(OBDReport_protocol().generateOBDReportMsg())
#encoding:utf-8
from lib.protocol.Base import Base
'''
定义协议类的基类
'''
class ProtocolBase(Base):
def __init__(self):
pass
#####################################################
# 数字转换为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
####################################################
# 获取消息体长度
#####################################################
def getMsgLength(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取流水号
#####################################################
def getWaterCode(self,num):
hexData = self.int2hexString(num)
while len(hexData) < 4:
hexData = "0" + hexData
return hexData
#####################################################
# 获取校验码
#####################################################
def getCheckCode(self,data):
return self.crc16(data)
#####################################################
# 定义生成校验字段的函数(自己翻译的函数,简化了很多步骤)
# 通过我实现的方式
#####################################################
def myCrc16(self,msg):
msg = self.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
#####################################################
# 将字符串转换为对应的ascii值数组
#####################################################
def str2Ascsii(self,s):
asciiArr = []
for i in range(0, len(s)):
asciiValue = ord(s[i])
asciiArr.append(asciiValue)
return asciiArr
#####################################################
# 将字符串转换为对应的ascii字母对应的16进制字符串
#####################################################
def str2Hex(self,s):
sHex = ""
tem = ""
for i in s:
tem = ord(i)
sHex += hex(tem)[2:]
return sHex
####################################################
# 定义生成校验字段的函数
# 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
#####################################################
# 将UTC时间转换为16进制,
# 例如:2020-01-02 20:30:00 (年取后面2字节)则将20,01,02,20,30,00 转换为对应的6个字节
# theTime:传入一个类似:2020-01-03 13:05:13的一个字符串
#####################################################
def getUTCTimeHex(self, theTime):
# 获取当前时间,时间格式为:2020-01-03 13:05:13
# now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 将2020-01-03 13:05:13时间格式转换为一个数组
# timeStr = "2020-01-03 13:05:13"
timeStr = theTime
timeArr = []
timeArr.append(timeStr[2:4])
timeArr.append(timeStr[5:7])
timeArr.append(timeStr[8:10])
timeArr.append(timeStr[11:13])
timeArr.append(timeStr[14:16])
timeArr.append(timeStr[17:19])
UTCTime = ""
for i in range(0, len(timeArr)):
UTCTime += self.int2hexString(int(timeArr[i]))
return UTCTime
#####################################################
#16进制转换为UTC时间格式
#####################################################
def hex2UTCTime(self,dataHex):
theTime = "20"
theTime = theTime + str(int(dataHex[:2],16))
theTime = theTime + "-" + str(int(dataHex[2:4],16))
theTime = theTime + "-" + str(int(dataHex[4:6],16))
theTime = theTime + " " + str(int(dataHex[6:8],16))
theTime = theTime + ":" + str(int(dataHex[8:10],16))
theTime = theTime + ":" + str(int(dataHex[10:],16))
return theTime
####################################################
# 将整数转换为有符号的整数
#####################################################
def num2signedNum(self,num):
return num & 0xff
if __name__ == "__main__":
# print(ProtocolBase().str2Hex("a"))
# print(ProtocolBase().int2hexStringByBytes(1,6))
# print(ProtocolBase().num2signedNum(-5))
print(ProtocolBase().getUTCTimeHex("2020-01-03 13:05:13"))
# print(ProtocolBase().hex2UTCTime("1401030d050d"))
# print(ProtocolBase().hex2UTCTime("14020a07122b"))
# print(ProtocolBase().crc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
# print(ProtocolBase().myCrc16("4040007000064d20191201000200120114030503202d26d7fffff0000000000505000000143c00000bb80100000fa00000000a0000000000005e60723b723b39331e100055320000001312001007d0001e0000000000000096000000280096ffff3e0001f40000003e0000000000000000000000"))
#coding:utf-8
'''
定义一个终端安防状态上报协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class SecurityStatusReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 14,DEV_ID = "M121501010001",locationType=1,GPSpkg="",statusCode="ffffffffffffffffffff",securityStatus=32,doorStatus=0,lockStatus=0,windowStatus=0,lightStatus=0,onoffStatusA=0,onoffStatusB=0,dataByte=0):
super().__init__()
self.msgCount = int(msgCount)
self.WATER_CODE = int(WATER_CODE)
self.DEV_ID = DEV_ID
self.locationType = int(locationType) #定位类型
#self.GPSPkg = GPSpkg & BaseStationPkg #GPS包或者基站包
self.GPSPkg = "1401091213260265b86206ed8c70026103280000752f03030405af017102610bb800003200000186a0001ed2a25e16fe3a"
self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"
self.statusCode = statusCode #状态掩码
self.securityStatus = int(securityStatus) #安全状态
self.doorStatus = int(doorStatus) #门状态
self.lockStatus = int(lockStatus) #锁状态
self.windowStatus = int(windowStatus) #窗户状态
self.lightStatus = int(lightStatus) #灯光状态
self.onoffStatusA = int(onoffStatusA) #开关状态A
self.onoffStatusB = int(onoffStatusB) #开关状态B
self.dataByte = int(dataByte) #数据字节
def setLocationType(self,data):
self.locationType = data
def setGPSPkg(self,data):
self.GPSPkg = data
def setBaseStationPkg(self,data):
self.BaseStationPkg = data
#####################################################
# 生成安全状态消息
#####################################################
def generateSecurityStatusMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" # 消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) # 消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) # 设备id
FUN_ID = "0014" # 功能id(安全状态功能id)
# 数据段
data = ""
for i in range(0, self.msgCount):
data += self.generateSecurityStatusPkg(self.locationType,self.GPSPkg,self.generateSecurityStatusData()) # 数据段
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建安防状态数据包,包含包个数
# data:传入安防状态数据包的多条数据段
#####################################################
def generateSecurityStatusPkg(self,locationType,thePkg,data):
nData = ""
pkg = ""
if locationType == 1: #GPS定位
locationTypeHex = self.int2hexString(locationType)
nData = nData + locationTypeHex + thePkg + data
pkgLen = len(nData)
pkgNum = (pkgLen / 2) / 70
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + nData
elif locationType == 2: #基站定位
locationTypeHex = self.int2hexString(locationType)
nData = nData + locationTypeHex + thePkg + data
pkgLen = len(nData)
pkgNum = (pkgLen / 2) / 76
pkgNumHex = self.int2hexString(int(pkgNum))
pkg = pkgNumHex + nData
return pkg
#####################################################
# 创建安防状态数据段
#####################################################
def generateSecurityStatusData(self):
data = ""
# statusCode = self.getStatusCodeHex() #状态掩码
statusCode = self.statusCode # 状态掩码
securityStatus = self.getSecurityStatusHex(self.securityStatus) #安全状态
doorStatus = self.getDoorStatusHex(self.doorStatus) #门状态
lockStatus = self.getLockStatusHex(self.lockStatus) #锁状态
windowStatus = self.getWindowStatusHex(self.windowStatus) #窗户状态
lightStatus = self.getLightStatusHex(self.lightStatus) #灯光状态
onoffStatusA = self.getOnoffStatusAHex(self.onoffStatusA) #开关状态A
onoffStatusB = self.getOnoffStatusBHex(self.onoffStatusB) #开关状态B
dataByte = self.getDataByteHex(self.dataByte) #数据字节
retain1 = "00" #预留
retain2 = "00" #预留
data = data + statusCode + securityStatus + doorStatus + lockStatus + windowStatus + lightStatus + onoffStatusA + onoffStatusB + dataByte + retain1 + retain2
return data
#####################################################
# 获取安全状态16进制数据
# 按照高位在前,低位在后的规则
#####################################################
def getSecurityStatusHex(self,data):
accStatus = 0 #acc状态,1:开 0:关
defenseStatus = 0 #设防撤防状态,2:设防 0:撤防
brakeStatus = 0 #脚刹状态,4:踩下 0:松开
acceleratorStatus = 0 #是否踩油门,8:踩下 0:松开
handBrakeStatus = 0 #手刹状态,16:拉起手刹 0:松开手刹
mainSafetyBelt = 32 #主驾驶安全带,32:插入安全带 0:松开安全带
subSafetyBelt = 64 #副驾驶安全带,64:插入安全带 0:松开安全带
retain = 0 #预留字段
# val = accStatus +defenseStatus +brakeStatus +acceleratorStatus + handBrakeStatus + mainSafetyBelt + subSafetyBelt + retain
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取门状态16进制数据
#####################################################
def getDoorStatusHex(self,data):
lfDoorStatus = 0 #左前门,1,:开 0:关
rfDoorStatus = 0 #右前门,2:开 0:关
lbDoorStatus = 0 #左后门,4:开 0:关
rbDoorStatus = 0 #右后门,8:开 0:关
trunk = 0 #后备箱,32:开 0:关
enginCover = 0 #发送机盖:64:开 0:关
retain1 = 0 #预留字段
retain2 = 0 #预留字段
# val = lfDoorStatus + rfDoorStatus + lbDoorStatus +rbDoorStatus + trunk + enginCover + retain1 +retain2
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取锁状态16进制数据
#####################################################
def getLockStatusHex(self,data):
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.int2hexString(data)
return hexData
#####################################################
# 获取窗户状态16进制数据
#####################################################
def getWindowStatusHex(self,data):
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.int2hexString(data)
return hexData
#####################################################
# 获取灯光状态16进制数据
#####################################################
def getLightStatusHex(self,data):
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.int2hexString(data)
return hexData
#####################################################
# 获取开关状态A16进制数据
#####################################################
def getOnoffStatusAHex(self,data):
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.int2hexString(data)
return hexData
#####################################################
# 获取开关状态B16进制数据
#####################################################
def getOnoffStatusBHex(self,data):
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:16挡 160:M挡 176:S挡
gears = 0
# val = retain1 + retain2 + retain3 + retain4 + gears
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取数据字节16进制数据
#####################################################
def getDataByteHex(self,data):
V1N1 = 0 #V1N1,1:存在 0:不存在
retain1 = 0
retain2 = 0
busTotalMileage = 0 #总线总里程,8:存在 0,:不存在
meterData = 0 #仪表数据,16:存在 0,:不存在
engineSpeed = 0 #发送机转速,32:存在 0:不存在
speed = 0 #车辆速度,64:存在 0:不存在
surplusOil = 0 #剩余油量,128:存在 0:不存在
# val = V1N1 + retain1 + retain2 + busTotalMileage +meterData + engineSpeed + speed +surplusOil
hexData = self.int2hexString(data)
return hexData
#coding:utf-8
'''
定义一个终端休眠协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class SleepReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",verInfo="M100AB01010.0000",compileDate="2020-03-23",GSM="GSM_123456",sleepType="01",sleepStatus=0):
super().__init__()
self.msgCount = int(msgCount) # 设置默认要发送的GPS数据包个数
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.sleepType = sleepType #休眠类型
self.sleepStatus = sleepStatus #休眠状态
#####################################################
# 生成 版本上报 消息
#####################################################
def generateSleepMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" #消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) #消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) #设备id
FUN_ID = "00FF" # 功能id
data = "" #数据段
for i in range(0,self.msgCount):
data += self.generateSleepPkg(self.generateSleepData())
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建 版本信息 数据包,包含包个数
#####################################################
def generateSleepPkg(self,data):
return data
#####################################################
# 创建 版本信息 数据段
#####################################################
def generateSleepData(self):
sleepTypeHex = self.sleepType
sleepStatusHex = self.int2hexString(self.sleepStatus)
data = sleepTypeHex + sleepStatusHex
return data
if __name__ == "__main__":
print(SleepReport_protocol().generateSleepMsg())
\ No newline at end of file
#coding:utf-8
from lib.protocol.report.ProtocolBase import ProtocolBase
'''
终端上报故障码数据包
'''
class TroubleReport_protocol(ProtocolBase):
def __init__(self,WATER_CODE = 26,DEV_ID = "M121501010001",infoTime="2020-01-20 11:55:58",troubleCount=1,byte0="02",byte1=2,byte2=3,byte3=1,MILStatus=1):
super().__init__()
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.infoTime = infoTime #时间信息
self.troubleCount = int(troubleCount) #故障码个数
self.byte0 = byte0 #系统id
self.byte1 = int(byte1) #故障码内容
self.byte2 = int(byte2) #故障码内容
self.byte3 = int(byte3) #故障码状态
self.MILStatus = int(MILStatus) #MIL状态
#####################################################
# 生成故障码消息
#####################################################
def generateTroubleMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" # 消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) # 消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) # 设备id
FUN_ID = "001A" # 功能id(GPS功能id)
data = self.generateTroubleData(self.troubleCount) # 数据段
# 消息长度
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2))
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info)
info += CHECK_CODE # 校验字段
return info
#####################################################
# 创建故障码数据段
#####################################################
def generateTroubleData(self,troubleCount):
data = ""
infoTime = self.getUTCTimeHex(self.infoTime) #时间信息
data += infoTime
data += self.int2hexString(troubleCount)
for i in range(0,troubleCount):
data = data + self.generateTroubleCode()
data = data + self.int2hexString(self.MILStatus)
return data
#####################################################
# 生成一个故障码数据
#####################################################
def generateTroubleCode(self):
byte0 = self.byte0 #系统ID
byte1 = self.getByte1Hex(self.byte1) #故障码内容
byte2 = self.getByte2Hex(self.byte2) #故障码内容
byte3 = self.getByte3Hex(self.byte3) #故障码状态
data = byte0 + byte1 +byte2 + byte3
return data
#####################################################
# 获取系统ID的16进制数据
# 0x00: 发动机故障码
# 0x01: 变速箱故障码
# 0x02: ABS故障码
# 0x03: 安全气囊故障码
# 其它预留
#####################################################
def getByte0Hex(self, data):
return "02"
#####################################################
# 获取故障码内容的16进制数据
#####################################################
def getByte1Hex(self,data):
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取故障码内容的16进制数据
#####################################################
def getByte2Hex(self, data):
hexData = self.int2hexString(data)
return hexData
#####################################################
# 获取故障码状态的16进制数据
#####################################################
def getByte3Hex(self, data):
hexData = self.int2hexString(data)
return hexData
#coding:utf-8
'''
定义一个终端版本协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class VersionReport_protocol(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",verInfo="M100AB01010.0000",compileDate="2020-03-23",GSM="GSM_123456"):
super().__init__()
self.msgCount = int(msgCount) # 设置默认要发送的GPS数据包个数
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.verInfo = verInfo # 设置默认UTC时间度戳
self.compileDate = compileDate #编译日期
self.GSM = GSM #GSM模块型号
#####################################################
# 生成 版本上报 消息
#####################################################
def generateVersionMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" #消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) #消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) #设备id
FUN_ID = "0005" # 功能id
data = "" #数据段
for i in range(0,self.msgCount):
data += self.generateVersionPkg(self.generateVersionData())
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建 版本信息 数据包,包含包个数
#####################################################
def generateVersionPkg(self,data):
return data
#####################################################
# 创建 版本信息 数据段
#####################################################
def generateVersionData(self):
data = ""
verInfoHex = self.str2Hex(self.verInfo) # 设置默认UTC时间度戳
compileDateHex = self.str2Hex(self.compileDate) #编译日期
GSMHex = self.str2Hex(self.GSM) #GSM模块型号
data = verInfoHex + compileDateHex + GSMHex
return data
if __name__ == "__main__":
print(VersionReport_protocol().generateVersionMsg())
\ No newline at end of file
#coding:utf-8
'''
定义一个上报电瓶采样协议的类
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class VoltageDataReport_protocol(ProtocolBase):
def __init__(self,WATER_CODE = "0002",DEV_ID = "M121501010001",sampleNums=1,sampleData=[{"sampleTime":"2020-04-09 16:20:22","voltage":12}]):
super().__init__()
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.sampleNums = sampleNums #采样个数
self.sampleData = sampleData #采样数据
#####################################################
# 生成终端登录消息
#####################################################
def generateMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" # 消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) # 消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) # 设备id
FUN_ID = "000A" # 功能id(终端登录功能id)
data = self.generateData() # 数据段
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data) / 2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建终端登录数据段
#####################################################
def generateData(self):
data = ""
sampleNums = self.int2hexStringByBytes(self.sampleNums)
data = data + sampleNums
for i in range(0,self.sampleNums):
sampleData = self.getUTCTimeHex(self.sampleData[i]["sampleTime"]) + self.int2hexStringByBytes(int(self.sampleData[i]["voltage"]),2)
data = data + sampleData
return data
if __name__ == "__main__":
print(VoltageDataReport_protocol().generateMsg())
\ No newline at end of file
#coding:utf-8
'''
定义一个通用应答数据包
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class Common_response(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",resId="8205",status="00"):
super().__init__()
self.msgCount = int(msgCount)
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.resId = resId #应答的功能ID
self.status = status #应答状态
def setResId(self,data):
self.resId = data
def setStatus(self,data):
self.status = data
#####################################################
# 生成 通用应答 消息
#####################################################
def generateCommonMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" #消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) #消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) #设备id
FUN_ID = "0000" # 功能id
data = "" #数据段
for i in range(0,self.msgCount):
data += self.generateCommonPkg(self.generateCommonData())
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建 通用应答 数据包,包含包个数
#####################################################
def generateCommonPkg(self,data):
return data
#####################################################
# 创建 通用应答 数据段
#####################################################
def generateCommonData(self):
data = ""
resId = self.resId
status = self.status
data = resId + status
return data
if __name__ == "__main__":
print(Common_response().generateCommonMsg())
\ No newline at end of file
#coding:utf-8
'''
定义一个升级应答数据包
'''
from lib.protocol.report.ProtocolBase import ProtocolBase
class Update_response(ProtocolBase):
def __init__(self,msgCount = 1,WATER_CODE = 1000,DEV_ID = "M121501010001",status="00"):
super().__init__()
self.msgCount = int(msgCount)
self.WATER_CODE = int(WATER_CODE); # 设置默认消息流水号
self.DEV_ID = DEV_ID # 设置默认设备id
self.status = status #应答状态
def setStatus(self,data):
self.status = data
#####################################################
# 生成 升级应答 消息
#####################################################
def generateUpdateMsg(self):
self.getProtocalHeader()
info = ""
HEADER = "4040" #消息头
WATER_CODE = self.getWaterCode(self.WATER_CODE) #消息流水号
DEV_ID = self.devid2hexString(self.DEV_ID) #设备id
FUN_ID = "0300" # 功能id
data = "" #数据段
for i in range(0,self.msgCount):
data += self.generateUpdatePkg(self.generateUpdateData())
LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2)) # 消息长度
info += HEADER
info += LENGTH
info += WATER_CODE
info += DEV_ID
info += FUN_ID
info += data
CHECK_CODE = self.getCheckCode(info) # 校验字段
info += CHECK_CODE
return info
#####################################################
# 创建 升级应答 数据包,包含包个数
#####################################################
def generateUpdatePkg(self,data):
return data
#####################################################
# 创建 升级应答 数据段
#####################################################
def generateUpdateData(self):
data = ""
status = self.status
data = status
return data
if __name__ == "__main__":
print(Update_response().generateUpdateMsg())
\ No newline at end of file
#encoding:utf-8
'''
定义通用应答消息解码类
'''
import json
from lib.protocol.reportPlateform.ResponseBase import ResponseBase
class Common_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.msg[0:4]
json_msg["msgLen"] = self.getMsgLen()
json_msg["waterCode"] = self.hexString2int(self.msg[8:12])
json_msg["devId"] = self.hex2string(self.msg[12:14]) + self.msg[14:26]
json_msg["funcId"] = self.msg[26:30]
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.msg[-4:]
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() #自己计算消息后得到的校验码
json_msg = json.dumps(json_msg)
return json_msg
#######################################################
# 获取消息长度
#######################################################
def getMsgLen(self):
msgLenHex = self.msg[4:8]
msgLen = self.hexString2int(msgLenHex)
return msgLen
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
data = {}
msgbody = self.msg[30:][:-4]
data["funcId"] = msgbody[:4]
data["status"] = msgbody[4:]
return data
#######################################################
# 获取自己计算得到的校验码
#######################################################
def getCalculateCheckCode(self):
checkCode = self.crc16(self.msg[:-4])
return checkCode
if __name__ == "__main__":
print(Common_res("4040000e000a4d12150101000180000010001550").getMsg())
#encoding:utf-8
'''
定义终端登录应答消息解码类
'''
import json
from lib.protocol.reportPlateform.ResponseBase import ResponseBase
class Login_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.msg[0:4]
json_msg["msgLen"] = self.getMsgLen()
json_msg["waterCode"] = self.hexString2int(self.msg[8:12])
json_msg["devId"] = self.hex2string(self.msg[12:14]) + self.msg[14:26]
json_msg["funcId"] = self.msg[26:30]
json_msg["body"] = self.getMsgBody()
json_msg["checkCode"] = self.msg[-4:]
json_msg["calculateCheckCode"] = self.getCalculateCheckCode() # 自己计算消息后得到的校验码
json_msg = json.dumps(json_msg)
return json_msg
#######################################################
# 获取消息长度
#######################################################
def getMsgLen(self):
msgLenHex = self.msg[4:8]
msgLen = self.hexString2int(msgLenHex)
return msgLen
#######################################################
# 获取消息体
#######################################################
def getMsgBody(self):
data = {}
msgbody = self.msg[30:][:-4]
data["data"] = msgbody
return data
#######################################################
# 获取自己计算得到的校验码
#######################################################
def getCalculateCheckCode(self):
checkCode = self.crc16(self.msg[:-4])
return checkCode
if __name__ == "__main__":
print(Login_res("4040000e00024d1215010100018000000300482a").getMsg())
#encoding:utf-8
import binascii
import time
from lib.protocol.Base import Base
class ResponseBase(Base):
def __init__(self):
pass
#####################################################
# 数字转换为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
#######################################################
# 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
####################################################
# 定义生成校验字段的函数
# 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
#######################################################
# utc 时间格式的16进制字符串转时间
######################################################
def hexDate2date(self,hexData):
UTCTime = "20"
UTCTime = UTCTime + str(self.hexString2int(hexData[:2]))
UTCTime = UTCTime + "-" + str(self.hexString2int(hexData[2:4]))
UTCTime = UTCTime + "-" + str(self.hexString2int(hexData[4:6]))
UTCTime = UTCTime + " " + str(self.hexString2int(hexData[6:8]))
UTCTime = UTCTime + ":" + str(self.hexString2int(hexData[8:10]))
UTCTime = UTCTime + ":" + str(self.hexString2int(hexData[10:12]))
return UTCTime
#######################################################
# 时间戳的16进制字符串转时间
######################################################
def hexTimestamp2date(self,hexData):
timeStamp = self.hexString2int(hexData)
timeArray = time.localtime(timeStamp)
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
return otherStyleTime
if __name__ == "__main__":
print(ResponseBase().hexDate2date("01c329ed065"))
print(ResponseBase().hexTimestamp2date("5e60723b"))
#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.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
#encoding:utf-8
#########################################################
#
# 定义socket的基类
#
#########################################################
from lib.socket.Base import Base
class SocketBase(Base):
def __init__(self):
pass
#coding:utf-8
##################################################
# 汽车自动驾驶模拟程序(可定时执行)
##################################################
import binascii
import datetime
import json
import math
import os
import random
import threading
import time
import traceback
from lib.protocol.report.EventReport_protocol import EventReport_protocol
from lib.protocol.report.GPSReport_protocol import GPSReport_protocol
from lib.protocol.report.LoginReport_protocol import LoginReport_protocol
from lib.protocol.report.OBDReport_CAN_protocol import OBDReport_CAN_protocol
from lib.protocol.report.VersionReport_protocol import VersionReport_protocol
from lib.protocol.report.response.Common_response import Common_response
from lib.protocol.report.response.Update_response import Update_response
from lib.socket.ClientSocket import ClientSocket
from lib.socket.service.ProtocolSimulaterDataService import ProtocolSimulaterDataService
class AutoCarWhichTimesService():
def __init__(self):
self.host = "10.100.12.32" #模拟器发送消息的主机地址
self.port = 9008 #模拟器发送消息的端口号
self.socket = None
self.timeout = 360 #socket的超时时间
self.sendDur = 5 #设置默认多久发一条消息
self.serviceStatus = 0 #服务状态,0表示未启动,1表示启动
self.gpsLine = [] #GPS 轨迹
self.gpsLineIndex = 0 #GPS 轨迹索引
self.travelStatus = 0 #0,表示未行驶,1表示开始行驶
self.carId = "M202003060520" #车机号
self.sn = 1 #消息流水号
self.oilExpend = 10 #设置汽车每升能跑多少公里
self.carSpeed = 60 #设置车速度
self.directAngle = 59 #设置默认方向角
self.isLogOut = 0 #是否输入日志文件,0代表不输出,1代表输出
# 定义要发送的obd数据
self.OBDdata = {"fireStatus":1,"ACCStatus":0,"engineSpeed":300,"speed":0,"meterMileage":6000,"totailMileage":600,"totalOilExpen":30,"totalRunTime":10}
# 定义初始的obd数据,与上面的OBD数据保持一致,主要用于汽车行驶过程中数据变化量的计算
self.OBDdataOri = {"fireStatus": 1, "ACCStatus": 0, "engineSpeed": 300, "speed": 0, "meterMileage": 6000,"totailMileage": 600, "totalOilExpen": 30, "totalRunTime": 10}
def setHost(self,data):
self.host = data
def setPort(self,data):
self.port = data
def setTimeout(self,data):
self.timeout = data
def setSendDur(self,data):
self.sendDur = data
def setCarId(self,data):
self.carId = data
def setOilExpend(self,data):
self.oilExpend = data
def setSpeed(self,data):
self.carSpeed = data
######################################################
#启动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 sendLoginMsg(self):
loginObj = LoginReport_protocol(WATER_CODE=self.sn,DEV_ID=self.carId)
loginMsg = loginObj.generateLoginMsg()
self.sendMsg(loginMsg)
self.sn = self.sn +1
info = self.getCurTime() + " 进行了登录操作"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
######################################################
#发送版本消息
######################################################
def sendVersionMsg(self):
versionObj = VersionReport_protocol(msgCount=1,WATER_CODE=self.sn,DEV_ID=self.carId)
versionMsg = versionObj.generateVersionMsg()
self.sendMsg(versionMsg)
self.sn = self.sn + 1
info = self.getCurTime() + " 发送了版本信息"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
######################################################
# 汽车开始行驶的服务方法
######################################################
def serviceTravel(self):
while self.serviceStatus == 1:
self.isLogOut = int(self.getFileContent("config/log.conf"))
gpsMsg = ""
OBDMsg = ""
if self.travelStatus == 0:
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
gpsMsg = self.genGPSMsg(latitude,longitude)
return
elif self.travelStatus == 1:
if self.gpsLineIndex < len(self.gpsLine):
OBDMsg = self.genOBDMsg(self.OBDdata["fireStatus"],self.OBDdata["ACCStatus"],self.OBDdata["engineSpeed"], \
self.OBDdata["speed"],self.OBDdata["meterMileage"],self.OBDdata["totailMileage"], \
self.OBDdata["totalOilExpen"],self.OBDdata["totalRunTime"])
self.OBDdata["engineSpeed"] = 3000
self.OBDdata["speed"] = self.carSpeed
self.OBDdata["meterMileage"] = self.OBDdata["meterMileage"] + int(self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
self.OBDdata["totailMileage"] = self.OBDdata["totailMileage"] + int(self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
oilExpend = self.oilExpend
self.OBDdata["totalOilExpen"] = self.OBDdata["totalOilExpen"] + int((self.sendDur * (self.OBDdata["speed"] * 1000 / 3600)) * (1000 / (oilExpend *1000)))
self.OBDdata["totalRunTime"] = self.OBDdata["totalRunTime"] + self.sendDur
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
gpsMsg = self.genGPSMsg(latitude, longitude)
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):
self.gpsLineIndex = self.gpsLineIndex - 1
# self.fireOff()
self.stopTravelService()
info = self.getCurTime() + " gps轨迹跑完,自动停止行驶!"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
info = "------------------------------------------------------------------------\n"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
self.serviceStatus = 0
self.carDataObj.setTodayTotalMilleage(self.carData["curDayTravel"]["todayTotalMilleage"] + self.OBDdata["totailMileage"] - self.OBDdataOri["totailMileage"])
self.carDataObj.setTheMilleage(self.carData["curDayTravel"]["theMilleage"] + self.OBDdata["totailMileage"] -self.OBDdataOri["totailMileage"])
self.carDataObj.setTotalMilleage(self.carData["travelData"]["totalMilleage"] + self.OBDdata["totailMileage"] -self.OBDdataOri["totailMileage"])
temp = self.OBDdata["totailMileage"]
self.OBDdataOri["totailMileage"] = temp
self.carDataObj.setTodayTodayTotalOil(self.carData["curDayTravel"]["todayTotalOil"] + self.OBDdata["totalOilExpen"] - self.OBDdataOri["totalOilExpen"])
self.carDataObj.setTheOil(self.carData["curDayTravel"]["theOil"] + self.OBDdata["totalOilExpen"] - self.OBDdataOri["totalOilExpen"])
self.carDataObj.setTotalOil(self.carData["travelData"]["totalOil"] + self.OBDdata["totalOilExpen"] - self.OBDdataOri["totalOilExpen"])
self.OBDdataOri["totalOilExpen"] = self.OBDdata["totalOilExpen"]
self.carDataObj.setTodayTodayTotalTime(self.carData["curDayTravel"]["todayTotalTime"] + self.OBDdata["totalRunTime"] - self.OBDdataOri["totalRunTime"])
self.carDataObj.setTheTime(self.carData["curDayTravel"]["theTime"] + self.OBDdata["totalRunTime"] - self.OBDdataOri["totalRunTime"])
self.carDataObj.setTotalTime(self.carData["travelData"]["totalTime"] + self.OBDdata["totalRunTime"] - self.OBDdataOri["totalRunTime"])
self.OBDdataOri["totalRunTime"] = self.OBDdata["totalRunTime"]
if self.serviceStatus == 1:
if OBDMsg != "":
self.sendMsg(OBDMsg)
self.sn = self.sn + 1
if gpsMsg != "":
time.sleep(0.1)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
if self.isLogOut == 1:
timeS = int(time.time())
timeArray = time.localtime(timeS)
datetime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
self.writeToFile("data/log.txt","[" + datetime + "]gps msg:" + gpsMsg + "\n", type=1)
self.writeToFile("data/log.txt","[" + datetime + "]obd msg:" + OBDMsg + "\n", type=1)
time.sleep(self.sendDur)
######################################################
#点火,发送点火事件
######################################################
def fireOn(self):
if not os.path.exists("data/protocolTools/carData/" + self.carId + ".json"):
psdsObj = ProtocolSimulaterDataService()
data = psdsObj.genDataTemplate()
psdsObj.writeToFile("data/protocolTools/carData/" + self.carId + ".json",data)
#读取车机行驶数据
with open("data/protocolTools/carData/" + self.carId + ".json", "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)
dataFile = self.carId + ".json"
self.carDataObj = ProtocolSimulaterDataService("data/protocolTools/carData/", dataFile)
self.carDataObj.setData(conJson)
if dateM == conJson["time"]["date"]:
self.OBDdata["totailMileage"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["totailMileage"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["totalOilExpen"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["totalOilExpen"] = conJson["travelData"]["totalOil"]
self.OBDdata["totalRunTime"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["totalRunTime"] = 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.setData2file(dateM)
self.carDataObj.setTime2file(timeM)
self.OBDdata["totailMileage"] = conJson["travelData"]["totalMilleage"]
self.OBDdataOri["totailMileage"] = conJson["travelData"]["totalMilleage"]
self.OBDdata["totalOilExpen"] = conJson["travelData"]["totalOil"]
self.OBDdataOri["totalOilExpen"] = conJson["travelData"]["totalOil"]
self.OBDdata["totalRunTime"] = conJson["travelData"]["totalTime"]
self.OBDdataOri["totalRunTime"] = conJson["travelData"]["totalTime"]
self.carData = conJson
fireOnEventObj = EventReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsData = self.genGPSData(self.gpsLine[0]["lat"], self.gpsLine[0]["lng"])
fireOnEventObj.setGPSPkg(gpsData)
fireOnEventObj.setEventType("0010")
firOnEventMsg = fireOnEventObj.generateEventMsg()
self.sendMsg(firOnEventMsg)
self.sn = self.sn + 1
time.sleep(0.1)
gpsMsg = self.genGPSMsg(self.gpsLine[0]["lat"],self.gpsLine[0]["lng"])
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
time.sleep(0.1)
OBDMsg = self.genOBDMsg(self.OBDdata["fireStatus"],1,self.OBDdata["engineSpeed"], \
self.OBDdata["speed"],self.OBDdata["meterMileage"],self.OBDdata["totailMileage"], \
self.OBDdata["totalOilExpen"],self.OBDdata["totalRunTime"])
self.sendMsg(OBDMsg)
self.sn = self.sn + 1
info = self.getCurTime() + " 发送了点火事件"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
######################################################
# 熄火,发送熄火事件
######################################################
def fireOff(self):
gpsLineIndex = self.gpsLineIndex
if gpsLineIndex >= len(self.gpsLine):
gpsLineIndex = gpsLineIndex - 1
fireOffEventObj = EventReport_protocol(DEV_ID=self.carId)
gpsData = self.genGPSData(self.gpsLine[gpsLineIndex]["lat"],self.gpsLine[gpsLineIndex]["lng"])
fireOffEventObj.setGPSPkg(gpsData)
fireOffEventObj.setEventType("0011")
fireOffEventMsg = fireOffEventObj.generateEventMsg()
self.sendMsg(fireOffEventMsg)
time.sleep(0.1)
gpsMsg = self.genGPSMsg(self.gpsLine[gpsLineIndex]["lat"], self.gpsLine[gpsLineIndex]["lng"])
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
info = self.getCurTime() + " 发送了熄火事件:"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
#发送消息
def sendMsg(self,msg):
self.socket.setTimeOut(self.timeout)
self.socket.send(msg)
#接收消息
def revMsg(self):
self.socket.setTimeOut(3000)
return self.socket.receive()
#设置GPS轨迹
def setGpsLine(self,gpsline):
fileName = gpsline
with open("data/protocolTools/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)
#读取文件内容
def getFileContent(self,file):
with open(file, "r", encoding="utf-8") as fi:
content = fi.read()
return content
#根据特定参数,生成GPS消息
def genGPSMsg(self,latitude,longtitude):
gpsObj = GPSReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsObj.setLatitude(latitude)
gpsObj.setLongitude(longtitude)
gpsObj.setDirectionAngle(self.getDirAngle())
gpsObj.setSpeed(self.carSpeed)
gpsObj.setOBDSpeed(self.carSpeed)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsObj.setUTCTime(UTCTime)
gpsObj.setGPSTimestamp(timeS)
msg = gpsObj.generateGpsMsg()
return msg
#根据特定参数,生成GPS消息体,不包含消息头
def genGPSData(self,latitude,longtitude):
gpsObj = GPSReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsObj.setLatitude(latitude)
gpsObj.setLongitude(longtitude)
gpsObj.setDirectionAngle(self.getDirAngle())
gpsObj.setSpeed(self.carSpeed)
gpsObj.setOBDSpeed(self.carSpeed)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsObj.setUTCTime(UTCTime)
gpsObj.setGPSTimestamp(timeS)
data = gpsObj.generateGpsData()
return data
# 根据特定参数,生成OBD CAN消息
def genOBDMsg(self,fireStatus=1,ACCStatus=0,engineSpeed=300,speed=0,meterMileage=6000, \
totailMileage=600,totalOilExpend=30,totalRunTime=10):
try:
OBDObj = OBDReport_CAN_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
OBDObj.setInfoTime(UTCTime)
OBDObj.setFireStatus(fireStatus)
OBDObj.setACCStatus(ACCStatus)
OBDObj.setEngineSpeed(engineSpeed) # 设置发动机转速
OBDObj.setSpeed(speed) # 设置车辆速度
OBDObj.setMeterMileage(meterMileage) # 设置仪表里程值
OBDObj.setTotalMileage(totailMileage) # 设置总里程值
OBDObj.setTotalOilExpend(totalOilExpend) # 设置总耗油量
OBDObj.setTotalRunTime(totalRunTime) # 设置车辆运行时间
msg = OBDObj.generateOBDReportCANMsg()
return msg
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()
if self.isLogOut == 1:
self.writeToFile("data/log.txt", "[" + datetime + "]", type=1)
self.writeToFile("data/log.txt",err,type=1)
#收到 某些类型的消息后执行回复操作
def doResponse(self,msg):
msgFunId = self.getMsgFunId(msg)
if msgFunId == "8205":
msg = Common_response(resId="8205").generateCommonMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
elif msgFunId == "8206":
msg = Common_response(resId="8206").generateCommonMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
elif msgFunId == "8300":
msg = Update_response().generateUpdateMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
########################################################
#启动行驶的服务
########################################################
def startTravelService(self):
self.serviceStatus = 1
self.travelStatus = 1
self.serviceTravel()
# t1 = threading.Thread(target=self.serviceTravel,args=())
# t1.start()
########################################################
# 停止行驶的服务
########################################################
def stopTravelService(self):
self.fireOff()
self.serviceStatus = 0
self.gpsLine = []
self.gpsLineIndex = 0
self.travelStatus = 0
self.socket.close()
info = self.getCurTime() + " 执行了停止行驶服务"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
########################################################
#接收消息方法
########################################################
def serviceRev(self):
self.serviceStatus = 2 #2代表只启动了接收消息的进程,1代表了接收和发送都启动了
while self.serviceStatus != 0:
d = self.revMsg()
d = str(binascii.b2a_hex(d))[2:][:-1]
########################################################
#启动接收消息服务
########################################################
def startRevService(self):
if self.socket != None:
t2 = threading.Thread(target=self.serviceRev, args=())
t2.start()
info = self.getCurTime() + " 启动了接收消息服务"
print(info)
self.writeToFile("result.txt", info + "\n", 1)
def getCurTime(self):
curTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
return "[" + curTime + "]"
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 isTimesStart(self,travelConf):
times = travelConf["times"]
for item in times:
year = int(time.strftime("%Y", item))
month = int(time.strftime("%m", item))
day = int(time.strftime("%d", item))
hour = int(time.strftime("%H", item))
minute = int(time.strftime("%M", item))
second = int(time.strftime("%S", item))
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:
resu = {}
resu["line"] = travelConf["line"]
resu["time"] = item
return resu
else:
return {}
else:
return {}
else:
return {}
else:
return {}
else:
return {}
else:
return {}
###########################################################
# 获取方向角
###########################################################
def getDirAngle(self):
dire = self.directAngle
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
return int(dire)
########################################################
# 启动模拟程序服务
########################################################
def startService(self,travelConf):
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(travelConf):
try:
self.sn = 1
self.connectService()
self.setGpsLine(travelConf["line"])
# self.startRevService() #启动接收消息服务
self.sendLoginMsg()
time.sleep(0.5)
self.sendVersionMsg()
time.sleep(0.5)
self.fireOn()
time.sleep(2)
self.startTravelService()
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__":
temp = True
while True:
temp = AutoCarWhichTimesService().isTimerStart(year=0,month=0,day=0,hour=0,minute=50,second=0)
if temp:
timeS = int(time.time())
timeArray = time.localtime(timeS)
datetime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
print(datetime)
time.sleep(5)
#coding:utf-8
##################################################
# 定义M500 车机行驶过程中产生的数据类
##################################################
import datetime
import json
import time
class ProtocolSimulaterDataService():
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 setData2file(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.setData2file(dateM)
self.setTime2file(timeM)
self.data = conJson
if __name__ == "__main__":
print(ProtocolSimulaterDataService().genDataTemplate())
data = ProtocolSimulaterDataService().genDataTemplate()
ProtocolSimulaterDataService().writeToFile("../../../data/protocolTools/carData/M202003060520.json",data)
\ No newline at end of file
#coding:utf-8
'''
M500车机模拟服务类
'''
import binascii
import json
import os
import threading
import time
import traceback
from time import sleep
from lib.protocol.report.EventReport_protocol import EventReport_protocol
from lib.protocol.report.GPSReport_protocol import GPSReport_protocol
from lib.protocol.report.OBDReport_CAN_protocol import OBDReport_CAN_protocol
from lib.protocol.report.response.Common_response import Common_response
from lib.protocol.report.response.Update_response import Update_response
from lib.socket.service.ProtocolSimulaterDataService import ProtocolSimulaterDataService
from lib.socket.service.websocket_service import Websocket_service
class ProtocolSimulaterService():
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.timeout = 1 #socket的超时时间
self.gpsLine = [] #GPS 轨迹
self.gpsLineIndex = 0 #GPS 轨迹索引
self.travelStatus = 0 #0,表示为行驶,1表示开始行驶
self.carId = "" #车机号
self.sn = 0 #消息流水号
self.travelDirection = 0 #行驶方向,0表示正向行驶,1表示反向行驶
# 定义要发送的obd数据
self.OBDdata = {"fireStatus":1,"ACCStatus":0,"engineSpeed":300,"speed":0,"meterMileage":6000,"totailMileage":600,"totalOilExpen":30,"totalRunTime":10}
# 定义初始的obd数据,与上面的OBD数据保持一致,主要用于汽车行驶过程中数据变化量的计算
self.OBDdataOri = {"fireStatus": 1, "ACCStatus": 0, "engineSpeed": 300, "speed": 0, "meterMileage": 6000,"totailMileage": 600, "totalOilExpen": 30, "totalRunTime": 10}
#设置套接字
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 getWebsocket(self):
return self.websocket
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()
#发送消息,可指定消息的描述类型
def serviceSendMsg(self,msg,type): #type字段目前废掉没有实际意义
self.sendMsg(msg)
type = self.getMsgFunId(msg)
self.websocket.send(">>>>" + type + ":" + msg)
def serviceSend(self):
while self.serviceStatus == 1:
gpsMsg = ""
OBDMsg = ""
if self.travelStatus == 0:
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
gpsMsg = self.genGPSMsg(latitude,longitude)
elif self.travelStatus == 1:
if self.gpsLineIndex < len(self.gpsLine) and self.gpsLineIndex != -1:
OBDMsg = self.genOBDMsg(self.OBDdata["fireStatus"],self.OBDdata["ACCStatus"],self.OBDdata["engineSpeed"], \
self.OBDdata["speed"],self.OBDdata["meterMileage"],self.OBDdata["totailMileage"], \
self.OBDdata["totalOilExpen"],self.OBDdata["totalRunTime"])
self.OBDdata["engineSpeed"] = 3000
self.OBDdata["speed"] = int(self.data["travelData"]["carSpeed"])
self.OBDdata["meterMileage"] = self.OBDdata["meterMileage"] + int(self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
self.OBDdata["totailMileage"] = self.OBDdata["totailMileage"] + int(self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["totalOilExpen"] = self.OBDdata["totalOilExpen"] + int((self.sendDur * (self.OBDdata["speed"] * 1000 / 3600)) * (1000 / (oilExpend *1000)))
self.OBDdata["totalRunTime"] = self.OBDdata["totalRunTime"] + self.sendDur
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
gpsMsg = self.genGPSMsg(latitude, longitude)
if self.travelDirection == 0:
self.gpsLineIndex = self.gpsLineIndex + 1 #正向行驶
else:
self.gpsLineIndex = self.gpsLineIndex - 1 #反向行驶
elif self.gpsLineIndex == len(self.gpsLine) or self.gpsLineIndex == -1:
if int(self.data["travelData"]["travelLoop"]) == 0:
self.stopTravel()
self.websocket.send("gps轨迹跑完,自动停止行驶!")
else:
if self.travelDirection == 0:
self.gpsLineIndex = self.gpsLineIndex - 1
self.travelDirection = 1
self.websocket.send("gps轨迹正向行驶跑完,变换行驶方向......")
else:
self.gpsLineIndex = self.gpsLineIndex + 1
self.travelDirection = 0
self.websocket.send("gps轨迹反向行驶跑完,变换行驶方向......")
OBDMsg = self.genOBDMsg(self.OBDdata["fireStatus"], self.OBDdata["ACCStatus"],self.OBDdata["engineSpeed"], \
self.OBDdata["speed"], self.OBDdata["meterMileage"],self.OBDdata["totailMileage"], \
self.OBDdata["totalOilExpen"], self.OBDdata["totalRunTime"])
self.OBDdata["engineSpeed"] = 3000
self.OBDdata["speed"] = int(self.data["travelData"]["carSpeed"])
self.OBDdata["meterMileage"] = self.OBDdata["meterMileage"] + int(
self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
self.OBDdata["totailMileage"] = self.OBDdata["totailMileage"] + int(
self.sendDur * (self.OBDdata["speed"] * 1000 / 3600))
oilExpend = int(self.data["travelData"]["oilExpend"])
self.OBDdata["totalOilExpen"] = self.OBDdata["totalOilExpen"] + int(
(self.sendDur * (self.OBDdata["speed"] * 1000 / 3600)) * (1000 / (oilExpend * 1000)))
self.OBDdata["totalRunTime"] = self.OBDdata["totalRunTime"] + self.sendDur
latitude = self.gpsLine[self.gpsLineIndex]["lat"]
longitude = self.gpsLine[self.gpsLineIndex]["lng"]
gpsMsg = self.genGPSMsg(latitude, longitude)
self.carDataObj.setTodayTotalMilleage(self.carData["curDayTravel"]["todayTotalMilleage"] + self.OBDdata["totailMileage"] - self.OBDdataOri["totailMileage"])
self.carDataObj.setTheMilleage(self.carData["curDayTravel"]["theMilleage"] + self.OBDdata["totailMileage"] -self.OBDdataOri["totailMileage"])
self.OBDdataOri["totailMileage"] = self.OBDdata["totailMileage"]
self.carDataObj.setTodayTodayTotalOil(self.carData["curDayTravel"]["todayTotalOil"] + self.OBDdata["totalOilExpen"] - self.OBDdataOri["totalOilExpen"])
self.carDataObj.setTheOil(self.carData["curDayTravel"]["theOil"] + self.OBDdata["totalOilExpen"] - self.OBDdataOri["totalOilExpen"])
self.OBDdataOri["totalOilExpen"] = self.OBDdata["totalOilExpen"]
self.carDataObj.setTodayTodayTotalTime(self.carData["curDayTravel"]["todayTotalTime"] + self.OBDdata["totalRunTime"] - self.OBDdataOri["totalRunTime"])
self.carDataObj.setTheTime(self.carData["curDayTravel"]["theTime"] + self.OBDdata["totalRunTime"] - self.OBDdataOri["totalRunTime"])
self.OBDdataOri["totalRunTime"] = self.OBDdata["totalRunTime"]
if OBDMsg != "":
self.sendMsg(OBDMsg)
self.sn = self.sn + 1
type = self.getMsgFunId(OBDMsg)
info = type + ">>>>:" + OBDMsg
self.websocket.send(info)
if gpsMsg != "":
sleep(0.1)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
type = self.getMsgFunId(gpsMsg)
info = type + ">>>>:" + gpsMsg
self.websocket.send(info)
sleep(self.sendDur)
def serviceRev(self):
self.serviceStatus = 2 #2代表只启动了接收消息的进程,1代表了接收和发送都启动了
while self.serviceStatus != 0:
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.send(info)
self.doResponse(d)
#启动与页面交互的websockt服务
def websocketService(self):
self.websocket = Websocket_service()
self.websocket.setHost("0.0.0.0")
self.websocket.setPort(5005)
self.websocket.startWebsocketServer()
#启动定时发送消息和接收消息的服务
def startService(self):
self.serviceStatus = 1
t1 = threading.Thread(target=self.serviceSend,args=())
t1.start()
#启动与页面交互的websocket服务
def startWebsocketService(self):
if self.websocket == None:
t = threading.Thread(target=self.websocketService, args=())
t.start()
t2 = threading.Thread(target=self.serviceRev, args=())
t2.start()
#停止定时发送消息的服务
def stopService(self):
self.serviceStatus = 0
self.gpsLine = []
self.gpsLineIndex = 0
self.travelStatus = 0
def closeSocket(self):
try:
self.socket.close()
except BaseException as e:
# 打印异常信息
traceback.print_exc()
#停止websocket服务
def stopWebsocketService(self):
try:
self.websocket.close()
self.websocket = None
except BaseException as e:
# 打印异常信息
traceback.print_exc()
########################################################
# 开始行驶
########################################################
def startTravel(self):
self.travelStatus = 1
########################################################
# 停止行驶
########################################################
def stopTravel(self):
self.travelStatus = 0
self.serviceStatus = 0
#获取收到消息的功能id
def getMsgFunId(self,msg):
funId = msg[26:30]
return funId
#收到 某些类型的消息后执行回复操作
def doResponse(self,msg):
msgFunId = self.getMsgFunId(msg)
if msgFunId == "8205":
msg = Common_response(resId="8205").generateCommonMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
type = self.getMsgFunId(msg)
self.websocket.send(type + ">>>>设置GPSR通信参数应答:" + msg)
elif msgFunId == "8206":
msg = Common_response(resId="8206").generateCommonMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
type = self.getMsgFunId(msg)
self.websocket.send(type + ">>>>设置车辆OBD适配信息应答:" + msg)
elif msgFunId == "8300":
msg = Update_response().generateUpdateMsg()
self.sendMsg(msg)
self.sn = self.sn + 1
type = self.getMsgFunId(msg)
self.websocket.send(type + ">>>>升级_平台通知终端远程升级应答:" + msg)
#设置GPS轨迹
def setGpsLine(self,fileName):
with open("data/protocolTools/GPSLines/" + fileName,"r",encoding="utf-8") as fi:
content = fi.read()
conJson = json.loads(content)
self.gpsLine = conJson["GPSLine"]
#点火,发送点火事件
def fireOn(self):
if not os.path.exists("data/protocolTools/carData/" + self.carId + ".json"):
psdsObj = ProtocolSimulaterDataService()
data = psdsObj.genDataTemplate()
psdsObj.writeToFile("data/protocolTools/carData/" + self.carId + ".json",data)
#读取车机行驶数据
with open("data/protocolTools/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 = ProtocolSimulaterDataService("data/protocolTools/carData/", dataFile)
self.carDataObj.setData(conJson)
if dateM == conJson["time"]["date"]:
pass
else: #如果不是当天日期,则将日期设置为当天,并写入车辆数据文件
conJson["time"]["dateTime"] = dateTimeM
conJson["time"]["date"] = dateM
conJson["time"]["time"] = timeM
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.setData2file(dateM)
self.carDataObj.setTime2file(timeM)
self.carData = conJson
fireOnEventObj = EventReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsData = self.genGPSData(self.gpsLine[0]["lat"], self.gpsLine[0]["lng"])
fireOnEventObj.setGPSPkg(gpsData)
fireOnEventObj.setEventType("0010")
firOnEventMsg = fireOnEventObj.generateEventMsg()
type = self.getMsgFunId(firOnEventMsg)
self.sendMsg(firOnEventMsg)
self.sn = self.sn + 1
self.websocket.send(type + ">>>>:" + firOnEventMsg)
sleep(0.1)
gpsMsg = self.genGPSMsg(self.gpsLine[0]["lat"],self.gpsLine[0]["lng"])
type = self.getMsgFunId(gpsMsg)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
self.websocket.send(type + ">>>>:" + gpsMsg)
sleep(0.1)
OBDMsg = self.genOBDMsg()
type = self.getMsgFunId(OBDMsg)
self.sendMsg(OBDMsg)
self.sn = self.sn + 1
self.websocket.send(type + ">>>>:" + OBDMsg)
# 熄火,发送熄火事件
def fireOff(self):
gpsLineIndex = self.gpsLineIndex
if gpsLineIndex >= len(self.gpsLine):
gpsLineIndex = gpsLineIndex - 1
fireOffEventObj = EventReport_protocol(DEV_ID=self.carId)
gpsData = self.genGPSData(self.gpsLine[gpsLineIndex]["lat"],self.gpsLine[gpsLineIndex]["lng"])
fireOffEventObj.setGPSPkg(gpsData)
fireOffEventObj.setEventType("0011")
fireOffEventMsg = fireOffEventObj.generateEventMsg()
type = self.getMsgFunId(fireOffEventMsg)
self.sendMsg(fireOffEventMsg)
self.websocket.send(type + ">>>>:" + fireOffEventMsg)
sleep(0.1)
gpsMsg = self.genGPSMsg(self.gpsLine[gpsLineIndex]["lat"], self.gpsLine[gpsLineIndex]["lng"])
type = self.getMsgFunId(gpsMsg)
self.sendMsg(gpsMsg)
self.sn = self.sn + 1
self.websocket.send(type + ">>>>:" + gpsMsg)
#根据特定参数,生成GPS消息
def genGPSMsg(self,latitude,longtitude):
gpsObj = GPSReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsObj.setLatitude(latitude)
gpsObj.setLongitude(longtitude)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsObj.setUTCTime(UTCTime)
gpsObj.setGPSTimestamp(timeS)
msg = gpsObj.generateGpsMsg()
return msg
#根据特定参数,生成GPS消息体,不包含消息头
def genGPSData(self,latitude,longtitude):
gpsObj = GPSReport_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
gpsObj.setLatitude(latitude)
gpsObj.setLongitude(longtitude)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
gpsObj.setUTCTime(UTCTime)
gpsObj.setGPSTimestamp(timeS)
data = gpsObj.generateGpsData()
return data
# 根据特定参数,生成OBD CAN消息
def genOBDMsg(self,fireStatus=1,ACCStatus=0,engineSpeed=300,speed=0,meterMileage=6000, \
totailMileage=600,totalOilExpend=30,totalRunTime=10):
OBDObj = OBDReport_CAN_protocol(DEV_ID=self.carId,WATER_CODE=self.sn)
timeS = int(time.time()) - 8 * 3600
timeArray = time.localtime(timeS)
UTCTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
OBDObj.setInfoTime(UTCTime)
OBDObj.setFireStatus(fireStatus)
OBDObj.setACCStatus(ACCStatus)
OBDObj.setEngineSpeed(engineSpeed) # 设置发动机转速
OBDObj.setSpeed(speed) # 设置车辆速度
OBDObj.setMeterMileage(meterMileage) # 设置仪表里程值
OBDObj.setTotalMileage(totailMileage) # 设置总里程值
OBDObj.setTotalOilExpend(totalOilExpend) # 设置总耗油量
OBDObj.setTotalRunTime(totalRunTime) # 设置车辆运行时间
msg = OBDObj.generateOBDReportCANMsg()
return msg
# utf-8
#GPS轨迹转换,将数据库导入的gps轨迹转换为程序可使用的GPs
import json
with open('gps.txt', "r", encoding="utf-8") as f:
con = f.readlines()
data = {}
data["name"] = "gpsLine"
data["GPSLine"] = []
for i in range(0, len(con)):
location = con[i].split(",")
location[0] = location[0].replace("\n", "")
location[0] = location[0].replace("\r", "")
location[0] = location[0].replace(" ", "")
location[1] = location[1].replace("\n", "")
location[1] = location[1].replace("\r", "")
location[1] = location[1].replace(" ", "")
jLocation = {}
jLocation["lng"] = location[0]
jLocation["lat"] = location[1]
data["GPSLine"].append(jLocation)
with open('gpsLine1111.txt', "w", encoding="utf-8") as f2:
data = json.dumps(data)
f2.write(data)
#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")))
[2020-08-05 18:23:34] 启动了模拟程序
[2020-08-05 18:24:00] 建立了连接
[2020-08-05 18:24:00] 进行了登录操作
[2020-08-05 18:24:00] 发送了版本信息
[2020-08-05 18:24:01] 当前设置了GPS轨迹:gpsLine2.txt
[2020-08-05 18:24:01] 发送了点火事件
#utf-8
import time
import traceback
from lib.socket.service.AutoCarWhichTimesService import AutoCarWhichTimesService
#写入文件
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 = AutoCarWhichTimesService()
autoCarObj.setHost("10.100.12.32") # 设置主机地址
autoCarObj.setPort(9008) # 设置端口号
autoCarObj.setCarId("M202003060520") #设置车机号
autoCarObj.setSendDur(3) # 设置发送消息的间隔时间
autoCarObj.setTimeout(30) # 设置socket超时时间
autoCarObj.setOilExpend(10) # 设置1L 油跑多少公里
autoCarObj.setSpeed(80) #设置车速,每小时多少公里
'''
type:0表示正向行驶,1表示反向行驶
日期全为0,表示每天
注意:时间尽量不要精确到秒,有很小概率导致时间跳过无法执行
'''
travelConf = {
"line": "gpsLine1.txt",
"times": [
{"time": "0000-00-00 09:10:00", "type": "0"},
{"time": "0000-00-00 18:30:00", "type": "1"},
]
}
autoCarObj.startService(travelConf)
if __name__ == "__main__":
try:
startSimulaterService()
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()
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