
php+mysql+workerman+uni-app开发一套新能源汽车充电桩管理平台
我们使用了php+mysql+workerman+uni-app开发一套 新能源汽车充电桩管理平台,
前言
充电桩管理系统按理用springboot技术架构去解决,但因为客户的开发周期短,预算低原因,我们使用了我们最熟悉的php+workerman技术栈解决了,经过2个月的开发,一年的使用,目前整套系统运行稳定,没有发现明显的问题,所以在这里记录下我们开发的过程。
充电桩运营管理系统,提供全套的定制化充电解决方案。一个管理平台对接多家硬件协议。
自建私有服务器,数据安全、数据隐私得到保障。
功能模块有:电站查询、导航、充值、退款,消费明细、数据大 屏、发票自动开具等功能。
支持多级子运营商管理,可进行统一或单独的财务结算。
客户端包含安卓APP、 苹果APP、微信小程序。
协议参照GBT-27930在这里插入图片描述
希望大家一起来讨论:150-5606-9927
提示:以下是本篇文章正文内容,下面案例可供参考
一、技术开发需求
充电桩主要包括:
1 服务器获取充电桩硬件的数据
2 充电桩发送数据给服务器
3 充电桩数据映射成api接口
4 客户端APP 跟服务器数据交互
二、技术解决
硬件厂商发来的应用层报文桢格式
应用层数据结构
起始标志 数据长度 序列号域 加密标志 桢类型标志 消息体 桢校验域
1字节 1字节 2字节 1字节 1字节 N字节 2字节
数据结构定义说明:
起始标识符代表一帧数据的开始,固定为0x68。
数据域字节数,数据域长度不超过200字节。不加密时为原数据长度,加密时,为加密后数据长度。其值为“序列号域+加密标志+桢类型标志+消息体”字节数之和。
序列号域即为数据包的发送顺序号,从 0 开始顺序增加,如是应答数据包,则与询问数据包序号保持一致,当桩与平台网络断开重新建立连接或者溢出后归0。
加密标志只针对消息体(数据单元)。0x00:不加密,0x01:3DES
桢类型标志定义了上下行数据桢。
桢校验域:从序列号域到数据域的 CRC 校验,校验多项式为 0x180D,低字节在前,高字节在后
我们根据发来的报文帧格式
先用workerman的Text协议格式 文本+换行符进行服务器余硬件通讯
global $worker;
$db = new \Workerman\MySQL\Connection(DB_HOST, '3306', DB_USER, DB_PASS,DB_NAME);
$worker = new Worker('tcp://0.0.0.0:8877');
$worker->count = 1;
$worker->uidConnections = array();
$redis = new redisdrive();
$redis->dbindex(1);//选择数据库
// worker进程启动后建立一个内部通讯端口
function handle_start($worker)
{
// 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
$inner_text_worker = new Worker('Text://0.0.0.0:1234');
$inner_text_worker->onMessage = function($connection, $buffer)
{
global $worker;
// $data数组格式,里面有uid,表示向那个uid的页面推送数据
$data = json_decode($buffer, true);
$uid = $data['uid'];
echo '--s-->>>>' . @$data['zhen'] . "\n" . @$data['cons'] . "\n";
// 通过workerman,向uid的页面推送数据
$ret = sendMessageByUid($uid,$data['cons']);
// 返回推送结果
$connection->send($ret ? 'ok' : 'fail');
// 关闭
// $ret=closeMessageByUid($uid);
// $connection->send($ret ? 'ok' : 'fail');
};
$inner_text_worker->listen();
};
function handle_connection($connection)
{
echo $uid=$connection->id;
};
function handle_message($connection, $data){
global $worker;
$alldata='';
// 转成16进制
$data = bin2hex($data);
//多报文分拆
$data=doublestr($data);
// print_r($data);
foreach ($data as $value) {
@$newdata=xy($value);
$zhuangnum= $newdata['zhuangnum'];
$alldata.= $newdata['dataok'];
}
if(!isset($connection->uid)) {//如果没有隐射,就增加隐射
$connection->uid = @$zhuangnum;
$worker->uidConnections[$connection->uid] = $connection;
}
return $connection->send(@hex2bin($alldata));
};
function handle_onclose($connection)
{
global $worker;
if(isset($connection->uid))
{
//关闭链接
$worker->uidConnections[$connection->uid]->close();
// 连接断开时删除映射
unset($worker->uidConnections[$connection->uid]);
}
};
$worker->onClose = 'handle_onclose';
$worker->onConnect = 'handle_connection';
$worker->onMessage = 'handle_message';
$worker->onWorkerStart = 'handle_start';
// 运行worker
Worker::runAll();
用php的的正则获取需要的数据
如获取帧的类型:
$newdata['zhen'] = substr($data, 10, 2);
获取帧的检验码:
```php
$newdata['hash'] = substr($data, -4);
获取到全部帧的有效数据,在封装到数组里面。
如果数据需要保存到数据库,那就调用数据库插入:
$db->query("INSERT INTO `" . DB_PREFIX . "pile` ( `num`)VALUES ('" . $newdata['zhuangnum'] . "')");
如果数据需要写入到redis里面:
$redis->set('icojoo-' . $newdata['zhuangnum'] . '-' . $newdata['gunnum'] . '-05', json_encode($newdata));
如果数据需要组装新的发送报文给硬件:
先组合好需要发送的报文格式
$newdata['dataok'] = $newdata['start'] . $newdata['len'] . $newdata['allcons'] . $newdata['xy'];
在通过workerman TCP协议发送给硬件
$client = stream_socket_client('tcp://127.0.0.1:1234', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
$data = array('uid'=>$zhuangnum,'zhen'=>$newdata['zhen'], 'cons'=>$newdata['dataok']);
// print_r($data);
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($data)."\n");
// 读取推送结果
return trimall(fread($client, 8192));
这样就完成了服务器接受硬件发送数据,服务器发送数据给硬件的数据,
发送跟获取数据是核心开发,这个完成后,服务器跟app通讯就是常规的web开发了,不在赘述。
三、客户端
客户端我们使用了uni-app开发,安卓+苹果都上架到官方各大商城,
四、页面展示
更多推荐
所有评论(0)