打开终端切换到 cd /var/client目录,
运行sudo ./client start
运行sudo ./cmd 选择2
打开另一个终端
关闭网卡 sudo service NetworkManager stop 或sudo service network-manager stop
开启网卡 sudo service NetworkManager start 或 sudo service network-manager start
切回原来终端,输入accountlist
切回另一个终端,输入sudu dhclient _
打开编译工具,找到tools
复制这些路径,找到这个路径
打开目录后,鼠标右键在终端打开,
输入以下命令:.\hdc_std.exe shell
查询ip地址输入:ifconfig
重置网络地址:ifconfig eth1 192.168.1.107 netmask 255.255.255.0
重置网络地址加域名:ifconfig eth1 192.168.1.107 netmask 255.255.255.0 broadcast 192.168.1.255
再次查询就可以发现定义在了上述的ip地址了
查看系统的串口名称
输入 ls -l /dev/ttyS*
关闭防火墙命令
setenforce 0
添加指定串口号的权限:
chmod 666 /dev/ttyS3
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-socket-0000001281361026
1.配置权限
在以下目录下找到module.json5文件
主要添加internet权限,wifi的权限需要用可以开启,不想加其他限制可以简写
{
“name” : “ohos.permission.INTERNET”,
},
2.引入socket,绑定连接
import socket from ‘@ohos.net.socket’;
创建socket—tcp通信(udp同样的)
let plcTcp=socket.constructTCPSocketInstance()
在与另一个地址进行建立连接前需要绑定设备的ip
plcTcp.bind({address: '192.168.1.107',family: 1})
.then(() => {console.log('bind success');})
.catch(err => {console.log('bind fail');});
address必须是字符串,可以是写设备连的网线地址,也可以获取当前wifi
获取wifi步骤
定义把wifi地址解析成字符串是函数
function resolveIP(ip){
if(ip < 0 || ip > 0xFFFFFFFF){
throw(“The number is normal!”)}
return (ip >>> 24) + “.” + (ip >> 16 & 0xFF) + “.” + (ip >> 8 & 0xFF) + “.” + (ip & 0xFF);
}
使用
plcTcp.bind({address: resolveIP(wifi.getIpInfo().ipAddress),family: 1})
.then(() => {console.log(‘bind success’);})
.catch(err => {console.log(‘bind fail’);});
3.创建连接
这里连接的就是目标的ip地址和端口号
首先要保证在终端可以ping通这个地址,例如这个就是可以连接的
与目标地址建立连接
plcTcp.connect({ address: {address: ‘192.168.1.120’, port: 102, family: 1}})
.then(() => {console.log(‘连接plc成功’)
}).catch(err => {console.log(‘connect fail’)});
4.与目标地址发信息通信(tcp)
发送信息到目标ip,注意这里plcTcp.send({ data:firstShakeHands }),data目前只支持发送string或者arraybuffer这两类型,如果你是发送个buffer必须进行buffer转换arraybuffer
错误演示:发送buffer报文使用 订阅message事件xx.on(‘message’,value=>{})接受消息是没有任何反应的,因为发送的是一个buffer缓冲区
let firstShakeHands =buffer.from('0300001611E00000000500C1020101C2020101C0010A', 'hex')
plcTcp.send({ data:firstShakeHands }).then(() => {console.log('第一次握手-->success');})
//如果添加一个buffer转arraybuffer函数做转换是可以的,这样是可以发送成功的
function toArrayBuffer(buf) {
var ab = new ArrayBuffer(buf.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
}
let firstShakeHands =buffer.from('0300001611E00000000500C1020101C2020101C0010A', 'hex')
plcTcp.send({ data:toArrayBuffer(firstShakeHands) }).then(() => {console.log('第一次握手-->success');})
或者使用 OpenHarmony自带的.buffer也是可以转换的,这样也是可以发送成功的
plcTcp.send({ data:firstShakeHands.buffer }).then(() => {console.log('第一次握手-->success');})
5.收到目标返回的数据通信
plcTcp.on('message', value => {
let plcBack = toBuffer(value.message)
console.log(plcBack )
})
返回的value.message是个arraybuffer类型,如需要转换buffer进行操作可以进行函数转换
function toBuffer(arrBuf) {
var buf = buffer.allocUninitializedFromPool(arrBuf.byteLength);
var view = new Uint8Array(arrBuf);
for (var i = 0; i < buf.length; ++i) {
buf[i] = view[i];
}
return buf
}
let plcBack = toBuffer(value.message)
console.log(plcBack )
这样打印的就是个buffer缓冲区
udp的收发也是一样的,发送的只能是arraybuffer或string
udp.send({
// @ts-ignore
data:sendMessage.buffer,
address: { address:targetAdd.ip, port: targetAdd.port, family: 1 }
})
npm install iconv-lite
安装完成前者后还需要安装这个npm i buffer
import iconv from 'iconv-lite'
iconv.encode(str, 'gbk')
buffer
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-buffer.md
api和开发板需要达到9以上才能使用
import buffer from ‘@ohos.buffer’;
//根据指定编码格式的字符串,创建新的Buffer实例。buffer不支持slice方法,转换成ArrayBuffer可以执行slice方法
let buf = buffer.from('21210000','hex')
// @ts-ignore
console.log(buf)
// @ts-ignore
console.log(buf.buffer)//转换arraybuffer
let buf2 = buffer.allocUninitialized(4)//创建一个4位都是0的buffer,buffer填充
buf2.fill(0)
// @ts-ignore
console.log(buf2)
//从3起到4结束填充一个5
buf2.fill(5,3,4)
// @ts-ignore
console.log(buf2)
var context: Context = getContext(this) as Context
创建数据库或者获取数据库实例
export function CreateDb(){
dataRdb.getRdbStore(context,{ name: "softDb.db" }, 1, function (err, rdbStore) {
if (err) {
console.log('获取失败' + err)
} else {
const SQL_CREATE_TABLE_RJ_NET = "CREATE TABLE IF NOT EXISTS sfd1 (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, IP TEXT, PORT TEXT, START TEXT,AUTO INTEGER)"
const SQL_CREATE_TABLE1_YJ = "CREATE TABLE IF NOT EXISTS hsn (ID INTEGER PRIMARY KEY AUTOINCREMENT, rcNAME TEXT, ledNAME TEXT, lpiNAME TEXT)"
rdbStore.executeSql(SQL_CREATE_TABLE_RJ_NET, null)
rdbStore.executeSql(SQL_CREATE_TABLE1_YJ, null)
console.log('fun CreateDb-->本地数据库创建或初始化成功')
//数据库插入,向sfd1表的字段里插入对象
//对象参考
// 'readCard': {
// 'rs': {
// 'rs1': {
// 'NAME': 'rs1',
// 'IP': '192.168.1.120',
// 'PORT': '102',
// 'START': '无',
// 'AUTO':1
// },
// 'rs2': {
// 'NAME': 'rs2',
// 'IP': '192.168.2.52',
// 'PORT': '6000',
// 'START': '无',
// 'AUTO':1
// }
// },
// }
rdbStore.insert("sfd1", softDataAll.readCard.rs.rs1)
rdbStore.insert("sfd1", softDataAll.readCard.rs.rs2)
db=rdbStore
}
})
}
查询数据库
无论查询数据库还是其他操作数据库的行为,都需要在数据库实例产生的情况下才能执行
export function Select_sfd1(tabName:string,charName:string,charValue:string){
//查询前调用下获取数据库实例的函数,或者再某个ets页面需要获取查询的生命周期上调用也行
CreateDb()
let predicates = new dataRdb.RdbPredicates(tabName)//查询表名
predicates.equalTo(charName, charValue)//查询条件限制
//predicates这里其实可以使用数据库语句
//['NAME', 'IP', 'PORT', 'START', 'AUTO']需要查询的字段
return db.query(predicates, ['NAME', 'IP', 'PORT', 'START', 'AUTO']).then((resultSet) => {
let obj ={}
resultSet.goToFirstRow()
obj = {
//getString一般获取字符串类型,getLong获取数字类型
'name': resultSet.getString(resultSet.getColumnIndex('NAME')),
'ip': resultSet.getString(resultSet.getColumnIndex('IP')),
'port': resultSet.getString(resultSet.getColumnIndex('PORT')),
'start': resultSet.getString(resultSet.getColumnIndex('START')),
'autoOpen': resultSet.getLong(resultSet.getColumnIndex('AUTO'))
}
console.log('db=》:本地数据库获取数据成功' )
return obj
})
}
//修改数据库
export function updateData(tabName:string,charName:string,charValue:string,obj?:any){
var that=this;
dataRdb.getRdbStore(context,{name: "softDb.db"}, 1, function (err, rdbStore:any) {
if (err) {
console.log('获取失败' + err)
} else {
let predicates = new dataRdb.RdbPredicates(tabName)
predicates.equalTo(charName, charValue)
rdbStore.update(obj, predicates, function (err, ret) {
console.log("修改成功==>>updated row count: " + ret)
})
}
})
}
这个数据存储当应用关闭或者退出时也会随之清除
import data_preferences from ‘@ohos.data.preferences’;
数据的存,需要获取上下文
插入一个key,value
数据的查询,根据键值查询,这里直接查询了所以键值
一般stage模型下静态文件会放在entry/src/main/resource/rawfile里面
文件的读取
现在需要读取文件test.txt里面的内容,文件读取路径也需要获取上下文
import fileIo from '@ohos.fileio';
let context:Context = getContext(this) as Context
let path = context.bundleCodeDir+'/entry/resources/rawfile/config.json'
//读取文件
export function readConfig(){
let pp= `${context.bundleCodeDir}/entry/resources/rawfile/test.txt`
//let read = fileIo.readTextSync(path);
let str = fileIo.readTextSync(pp);
console.log('文件读取结果↓↓↓↓↓↓↓↓↓↓')
console.log(str)
//return JSON.parse(read)
}
文件写入暂时遇到了问题,无法写入
export function writeConfig(){
let pp= `${context.bundleCodeDir}/entry/resources/rawfile/test.txt`
fileIo.open(pp, 0o2 | 0o100, 0o666)
.then(function(number){
fileIo.writeSync(number, 'hello world');
console.info("open file succeed");
}).catch(function(err){
console.info("open file failed with error:"+ err);
});
}
首先是项目文件目录,主线程test123.ets文件与子线程worker.js文件进行通信。
分别同位于page文件夹下面的view和worker文件夹
首先在主进程test123.ets和worker.js文件里面引入
import worker from ‘@ohos.worker’;
主进程接收发送信息,发送完注意销毁进程,如果不销毁存在9个会让应用卡死
子进程接收与发送
测试结果
public p2(){
switch (this.step) {
case 0:
console.log(‘0—led:车牌识别仪’)
console.log(‘0—语音:车牌识别仪’)
this.step=1
break;
case 1:
if(this.carNumber===‘闽D9999U’||this.carNumber==‘粤A68688’){
console.log(“1-(正向)led显示车牌—记牌:”+this.carNumber)
console.log(“1-(正向)语音车牌—记牌:”+this.carNumber)
this.processCarNumber = this.carNumber
this.direc = ‘z’
this.step=2
break;
}
if(this.carNumber2===‘闽D9999U’||this.carNumber2==‘粤A68688’){
console.log(“1-(反向)led显示车牌—记牌:”+this.carNumber2)
console.log(“1-(反向)语音车牌—记牌:”+this.carNumber2)
this.processCarNumber = this.carNumber2
this.direc = ‘f’
this.step=2
break;
}
case 2:
if(this.direc==‘z’){
console.log(‘-》2-开1#道闸、亮12#红灯’)
control_plc(‘51’)
console.log(‘2-(正向)led:’+this.processCarNumber+‘请上衡’)
console.log(‘2-(正向)语音:’+this.processCarNumber+‘请上衡’)
this.direc='z'
this.step=3
}else if(this.direc=='f'){
console.log('-》2-开2#道闸、亮12#红灯')
control_plc('54')
console.log('2-(反向)led:'+this.processCarNumber+'请上衡')
console.log('2-(反向)语音:'+this.processCarNumber+'请上衡')
this.direc='f'
this.step=3
}
break;
case 3:
console.log('3体重保存---暂时这样-----------')
console.log(this.processCarNumber)
setTimeout(()=>{
this.step=4
},5000)
break;
case 4:
//外层还需嵌入一段判断保存结果,目前默认为保存成功
if(this.saveDataResult){
if(this.direc=='z'){
console.log('-》4-开2#道闸、关1#道闸---质量<正>向上传')
control_plc('06')
}else if(this.direc=='f'){
console.log('-》4-开1#道闸、关2#道闸----质量反向上传')
control_plc('09')
}
console.log('打印')
}
this.step=5
break;
case 5:
if(this.direc=='z') {
console.log('5-正向-信号检测')
// if (this.plcStatic.raster1 || this.plcStatic.raster2) {
// return
// }
// //20是回零重量
// if (this.carWeight > 20) {
// return
// }
// if (this.plcStatic.protectSignal2) {
// return
// }
this.step = 6
} else if(this.direc==‘f’){
console.log(‘5-反向-信号检测’)
// if (this.plcStatic.raster1 || this.plcStatic.raster2) {
// return
// }
// if (this.carWeight > 20) {
// return
// }
// if (this.plcStatic.protectSignal1) {
// return
// }
this.step = 6
}
break;
case 6:
if(this.direc==‘z’) {
// setTimeout(() => {
console.log(‘-》6-2#落闸,红绿灯绿灯’)
control_plc(‘A8’)
// },4000)
} else if(this.direc==‘f’){
// setTimeout(() => {
console.log(‘-》6-1#落闸,红绿灯绿灯’)
control_plc(‘A2’)
// },4000)
}
console.log(‘6-上传图片’)
this.step = 7
break;
case 7:
console.log(‘7-车辆下横’)
this.direc=‘e’
setTimeout(()=>{
this.step=0
},3000)
break;
}
}