『瀚思彼岸』» 智能家居技术论坛

标题: 新坑:air780eg定位器diy [打印本页]

作者: ryanh7    时间: 2024-10-24 03:59
标题: 新坑:air780eg定位器diy
本帖最后由 ryanh7 于 2025-2-6 12:42 编辑

电动自行车的定位器之前发掘过2款了,都是十几块的款。2款都是在原硬件的基础上重新编写固件,以支持gt06接入traccar。买过的两款优点都是价格便宜,该有的硬件都有,缺点是芯片资料稀缺,二次开发成本比较大,而且供货不稳定。其中第2款编写了主要的功能接入了traccar。但是后来感觉硬件不太稳定,有莫名其妙需要重新刷固件的情况。所以有了开发第三款定位器固件的想法。根据之前的经验,觉得新的方案要有几个特点:1,芯片供货量大,容易买到;2,sdk成熟并且公开,3,能支持4g和ipv6。于是留意到合宙的air780eg这个模组
air780eg
1, 支持4g网络(只测试过中国移动的)
2, sdk比较开放,提供了lua脚本编写的sdk,体验下来确实减少了很多开发者需要关系的细节(很多简单繁琐的底层不用写c实现,虽然不大信任脚本语言,但是考虑到大大提高了开发效率还是可以的)
3, 内置gps(这里有个坑,23年以前的出货版本没法在维持gps供电的情况下让cpu睡眠,功耗没法做到极致。不过考虑到开车时的耗电量比定位器工作耗电大多了,也不是不能忽略,大不了车不动的时候就让芯片睡死过去)
4, 可以扫描wifi(这是个大大的优点也是个大大的坑,优点是可以使用wifi定位,有望解决gps定位在不动的时候飘得离谱得问题,缺点是这个wifi扫描功能用的是连接基站的相关芯片,在tcp处于连接状态时无法扫描wifi,废了大半)
5, 这个芯片目前还是比较容易买到的

于是搜着搜着,我发现某宝有家银尔达公司出了一个电动自行车版本的基于air780eg的定位器,价格也公道
[attach]65067[/attach]

于是买了一个用于验证开发,到手后发现还给了一张用于测试的物联卡(有坑的地方是这张卡无法分配ipv6,在网上另外买的一张物联卡就可以)。
[attach]65068[/attach]



店家给了文档,罗列了一些外部原件的引脚信息,这点就比买其他成品商品进行逆向好,至少引脚不用花时间猜了。实际打开之后发现还是有一些离谱的地方
1, 用于刷机的usb引脚测试点做得很小,对于不常用电烙铁的人不太友好,虽然明明采用的外壳上都留了usb的开口,直接做个usb的焊盘哪怕是让我自己吹一个usb口上去都挺好,实在不行做大点触点也好啊
2, 没有几乎标配的加速度传感器,无法检测翻车状态,也没法做碰撞(不过碰撞这个不好做,一个是要调教算法,另一个是要考虑功耗,cpu睡眠的时候这个传感器就没法用了,除非加芯片),不过给了震动电阻(这点挺好的,实测下来电阻很灵敏,轻轻碰一下都能反应),震动电阻可用于定位器休眠的时候唤醒(以前研究其他成品商品时我就觉得该有这个电阻,可能是因为引脚不明没在其他商品上测出来),应该说做震动报警什么的也可以
3, 没有电池,不能做断电报警,不过这个可以原谅,毕竟成本和售价摆在这。
4, 这个外壳换sim卡不好换,可能设计上就没打算换,毕竟是给开发商用的
5, 有一路输入(检测电动车钥匙开没开),一路输出继电器,但是这个输出的设计好像有点离谱,好像是拉流,继电器还得单独供电?

经过几天痛苦的加班开发研制,验证了几个功能:
1, 联网正常,sim卡支持并且当地网络支持的话可以获得ipv6,和traccar通讯也正常
2, 基本实现了gt06,sdk提供的lua库还是比较丰富的,写起来也比较舒服(补充一句,调试工具也挺好用的),虽然感觉合宙的社区还没做起来,但是路子是对的
3, 可以正常休眠和轻碰唤醒
4, 定位基本正常,验证了agnss(还是官方demo的功劳),定位速度也基本在10秒内。但还是和之前开发过的定位器一样,定位器长时间不动的时候飘得厉害(大多在20米内飘,离谱的时候二三百米地飘),这个应该是和gps的原理有关,高楼的多径效应让定位器“产生了幻觉”。考虑结合震动传感器和wifi判断,长时间不动的时候就不上传定位了,或者结合wifi定位(这个要在服务端做,LBS数据库不好整,考虑做自学习)

有几个还在做的想法
1, 去掉traccar,直接在home assistant写插件接收定位,这样比较好做定位器的远程设置功能(改traccar太繁琐了,不合并到上游还要时不时解决更新的问题),不过缺点的话,ha上的历史轨迹这些就要自己做了(之前正愁写的百度高德无偏地图能有什么用)
2, 抛弃gt06重新设计基于udp的协议,这样可能可以在上传定位的间隔里扫描wifi(不确定,但是官方demo看着像udp和wifi扫描能共存),反正重新设计协议了就可以更好地和第一条结合。吐槽一下gt06的协议设计还是有点问题
3, 验证好这个平台以后,可以做OBD车载设备和直接把air780g集成到电动车仪表盘的版本,电动车版本的也可以改进(加加速度传感器和usb刷机口,电池),同一套程序不用大改(通讯协议的设计难度又上升了,还要考虑扩展性,obd设备有行车数据,电池还有电池信息和告警)
4, 在ha侧做开发,可以远程修改参数(上报间隔,报警功能什么的),基于定位信息做一些实体和功能,还有做lbs和历史轨迹什么的(麻烦啊,看心情吧)


一些备忘信息:
lua开发文档 https://wiki.luatos.com/api
固件地址 LuatOS 发行版 - Gitee.com
demo https://gitee.com/openLuat/LuatOS.git

-----
慢慢更

好消息是经过测试确实是wifi扫描和udp通信可以共存,坏消息是思来想去tcp还是比udp更合适一些,用udp的话还是得想办法实现tcp就有的一些会话特性。

29日:新进度是初步拟定了一个比较灵活的协议,还在慢慢补充细节。已经根据新协议基本跑通了流程,验证了wifi和udp可以共存。基本功能还差定位器的配置项同步流程。然后再完善一下细节,测试和代码安全审查。这样就算基本完成了定位器的功能,写ha插件就要轻松得多了。

31日:1、优化定位发送逻辑:正常情况下发送卫星定位,慢速的时候发送wifi信息辅助定位,开机没有定位信号及定位信号中途丢失的时候发送wifi信息和基站信息辅助定位 2、优化agnss辅助定位逻辑,缓存4小时内的星历,以减少流量消耗。实测在冷启动的情况下,辅助定位可以将卫星首次定位时间从几分钟减少到十几秒。3、指示灯可用,震动检测及唤醒可用,卫星定位及辅助定位可用,wifi扫描可用,基站扫描可用,ipv6可用,休眠功能可用。待完成:远程设置功能,钥匙检测及继电器控制逻辑。

17日:插件写得七七八八了。之前用wifi和基站定位都需要使用第三方数据库,需要收费不说,还有可能数据库不全或者更新不及时,特别是像wifi定位的这种数据库。这次想到可以自建数据库,让定位器在路上跑的时候就顺便采集wifi和基站数据。这部分逻辑写成代码之后感觉是可行的,具体还需要写完之后上路实测一下。可能需要根据具体效果优化定位算法和定位器的上报逻辑。

19日:增加了一些插件细节。还需要打磨
[attach]65066[/attach]


21日:其实要考虑的细节挺多的。这两天在一个字节一个比特地优化协议节省流量。尽量控制在30m/月以下。前提是不进行ota,ota要消耗一些流量。硬件层要考虑的有够不够稳定,脚本是不是有没测到的bug,业务逻辑和功能齐不齐全,代码清不清晰,不同网络网络下使用什么发送策略,ota失败怎么办,更新后循环重启怎么办。协议层要考虑字段是不是合理,通用性和效率怎么取舍,节省流量和实时性怎么取舍,向后兼容和扩展性怎么平衡,会话逻辑要考虑网络干扰等意外情况。ha插件侧除了要实现基本功能,重载重启各方面没有bug,还要尽可能优化性能和细节体验,想方设法实现远程配置功能(设备不在线时怎么办),ota怎么更新,wifi和gps融合定位的逻辑和算法怎么设计。相关代码还要简洁,还要进行合理抽象和重构,有必要的文档。算下来确实挺花时间。
这个插件叫U27,为啥叫U27呢其实是拍脑袋想的,因为协议是UDP,写第一行代码的那天是27日 : )
29日:插件侧新增远程配置(未完成)
[attach]65516[/attach]
2月6日:经过几天测试,发现震动传感器不太可靠,有误触和漏检情况,或许应该换一个安装位置





作者: jjss520    时间: 2024-10-24 09:03
大佬牛批,现在途强EV49,traccar感觉还可以
作者: DDDear    时间: 2024-10-24 10:03
大佬牛批,持续关注
作者: xlsj519    时间: 2024-10-24 10:15
支持,万物在线节点废了后,弄了2个银尔达的780模块替代,通过MQTT上传数据,目前有两个问题,一是静止状态位置飘的有点大,二是从地下车库出来后,定位很慢,有时7、8分钟定不上。期待大神的成果
作者: ryanh7    时间: 2024-10-24 10:35
xlsj519 发表于 2024-10-24 10:15
支持,万物在线节点废了后,弄了2个银尔达的780模块替代,通过MQTT上传数据,目前有两个问题,一是静止状态 ...

静止位置是会漂,空旷地方定位慢可能是agnss 网络辅助定位没开
作者: xlsj519    时间: 2024-10-24 11:08
本帖最后由 xlsj519 于 2024-10-29 11:29 编辑
  1. function
  2.         --系统等待15s
  3.         sys.wait(15000)
  4.         --相关变量赋值
  5.         local taskname="userTask"
  6.         log.info(taskname,"start")
  7.         --赋值nid网络通道序号,后面获取网络通道状态api PronetGetNetSta(id)用
  8.         local nid=1
  9.         --赋值uid,后面没用到?
  10.         local uid=1
  11.         --将获取网络通道状态返回值赋予netsta
  12.         local netsta =0
  13.         --需要上传数据信息时,needup变为1
  14.         local needup =1
  15.         --计数器,用来计算发送数据间隔,每秒加1
  16.         local count =0
  17.         local count2 =0
  18.         --local lastlnglat = 0
  19.         --初始化GPS
  20.         GpsInit()
  21.         --执行AGNSS辅助定位,下载星历成功返回1
  22.         GpsExecAgnss()
  23.         --执纪一个while循环,因为直接检测true的值,所以一直循环
  24.         while true do
  25.         --声明局部变量d为一个表         
  26.                 local d ={}
  27.                 --获取系统日期,并赋值给d.datetime
  28.                 d.datetime=os.date("%Y-%m-%d %H:%M:%S")
  29.                 --获取sim卡信号强度
  30.                 d.xinhao=mobile.csq()
  31.                 --获取sim卡imei
  32.                 d.imei=mobile.imei()
  33.                 --获取sim卡用户识别码(ICCID)
  34.                 d.iccid = PerGetIccid()
  35.                 --获取外部供电电压,通道为1
  36.                 d.adc = PerGetAdcGatherValByAdcId(1)
  37.                 --获取外部高低电平输入端状态
  38.                 d.input=PerGetDiById(1)
  39.                 --获取GPS震动情况
  40.                 d.shake=PerGetGpsZdSta()
  41.                 --赋值d.gps为空表
  42.                 d.gps={}
  43.                 --用libgnss.isfix获取gps是否定位成功并赋值给d.gps.isFix
  44.                 d.gps.isFix=libgnss.isFix()
  45.                 --如果gps定位成功,则通过libgnss.getRmc(2)api获取相关数据并赋值给d.gps
  46.                 if libgnss.isFix() then
  47.                         local tg =libgnss.getRmc(2)
  48.                         d.gps.lat=tg.lat
  49.                         d.gps.lng=tg.lng
  50.                         --gps返回速度为海里(节),转换为公里
  51.                         d.gps.speed=tg.speed * 1.85
  52.                         --variation地面航向,单位度,从正北顺时针算;year\moth\day\hour\min\sec时间
  53.                         --local lnglat = tg.lng + tg.lat
  54.                         --local deltalnglat = math.abs(lnglat - lastlnglat)
  55.                         --lastlnglat = lnglat
  56.                 end
  57.                 --将Lua的数据结构(如表、数组、字符串、数字等)转换为 JSON 格式的字符串并赋值给updata
  58.                 local updata = json.encode(d)
  59.                 --获取网络通道状态,并赋值给netsta
  60.                 local netsta = PronetGetNetSta(nid)
  61.                 log.info(taskname,"updata",updata,"netsta",netsta)
  62.                 --如果needup为1,且updata不为空,网络通道状态正常,就调用网络通道发送数据PronetSetSendCh(id,s)上报数据,并将needup和count归零
  63.                 if needup ==1 and updata and netsta ==1 then
  64.                         needup =0
  65.                         count =0
  66.                         PronetSetSendCh(nid,updata)
  67.                 end
  68.                 --计数器加1
  69.                 count = count+1
  70.                 count2 = count2+1
  71.                 -- CX4 电压大于13700,A4L 电压大于13500视为车辆启动,10秒将needup设为1,上传一次数据
  72.                 if PerGetAdcGatherValByAdcId(1) > 13700 and count > 10 then
  73.                         needup =1
  74.                         count =0
  75.                 end
  76.                 --如果电压高于13.7视为车辆启动,且gps未获取成功,每300秒GpsExecAgnss获取下辅助定位数据
  77.                 if PerGetAdcGatherValByAdcId(1) > 13700 and libgnss.isFix() == false  and count2 > 300 then
  78.                         GpsExecAgnss()
  79.                         count2 =0
  80.                 end
  81.                 --平常600秒上传次数据
  82.                 if count > 600 then
  83.                         needup =1
  84.                         count =0
  85.                 end
  86.                 sys.wait(1000)
  87.         end
  88. end
复制代码
使用任务模块加了电压检测和定时上报数据
作者: xlsj519    时间: 2024-10-24 11:17
ryanh7 发表于 2024-10-24 10:35
静止位置是会漂,空旷地方定位慢可能是agnss 网络辅助定位没开

不会重写固件,原来的DTu固件下,请教下如何打开agnss功能
作者: jjcs    时间: 2024-10-24 11:23
https://bbs.hassbian.com/thread-25273-1-1.html
作者: ryanh7    时间: 2024-10-24 11:32
GpsExecAgnss这个函数就是,想办法在失去定位后2到4个小时后重新执行就可以了(比如离开地库的时候)
作者: jjcs    时间: 2024-10-24 11:33
本帖最后由 jjcs 于 2024-10-24 11:34 编辑

还是别用traccar,用mqtt,第三方的云,方便稳定,毕竟云平台比自己搭的稳
作者: jjcs    时间: 2024-10-24 11:34
xlsj519 发表于 2024-10-24 11:08
使用任务模块加了电压检测和定时上报数据

原来dtu固件,海拔,速度,和方向角应该咋写
作者: jjcs    时间: 2024-10-24 11:39
xlsj519 发表于 2024-10-24 10:15
支持,万物在线节点废了后,弄了2个银尔达的780模块替代,通过MQTT上传数据,目前有两个问题,一是静止状态 ...

静止飘是因为,一直是常电把,我只有设备启动才会定位
作者: ryanh7    时间: 2024-10-24 11:40
jjcs 发表于 2024-10-24 11:33
还是别用traccar,用mqtt,第三方的云,方便稳定,毕竟云平台比自己搭的稳

正是想完全本地化才从头开发
作者: ghostist    时间: 2024-10-24 11:40
我好像有两个780e
虽然现在用的拆车哈啰 免年费,但是这种自研的才是永久方案啊
看能跟着上车不
作者: jjcs    时间: 2024-10-24 11:42
ghostist 发表于 2024-10-24 11:40
我好像有两个780e
虽然现在用的拆车哈啰 免年费,但是这种自研的才是永久方案啊
看能跟着上车不 ...

taobao就有
作者: Jarvis    时间: 2024-10-25 01:37
这个不错,持续关注一下
作者: Hermit    时间: 2024-10-27 00:58
ryanh7大佬出品必属精品!!!
作者: xlsj519    时间: 2024-10-29 09:29
jjcs 发表于 2024-10-24 11:34
原来dtu固件,海拔,速度,和方向角应该咋写

我用的任务上报相关数据
  1. local tg =libgnss.getRmc(2)
  2.                         d.gps.lat=tg.lat
  3.                         d.gps.lng=tg.lng
  4.                         d.gps.speed=tg.speed * 1.85
  5. 光获取了经、纬度,还有速度,速度是海里,*1.85转换为公里
复制代码

作者: linlongnan    时间: 2024-11-14 22:31
ryanh7 发表于 2024-10-24 10:35
静止位置是会漂,空旷地方定位慢可能是agnss 网络辅助定位没开

我也买了780,还没时间研究,期待你们弄好,蹭一下
作者: C哩C哩    时间: 2024-11-19 15:53
部署就卡住了
作者: ryanh7    时间: 2024-11-19 18:40
C哩C哩 发表于 2024-11-19 15:53
部署就卡住了

usb下载,boot引脚要拉一下
作者: wbdownn    时间: 2024-11-25 17:00
ryanh7 大佬开发过很多东西,也有不少“烂尾”(随着ha的升级,无法兼容了),也删掉了项目

1、http Bluetooth proxy,无法使用了,这个东西还是有使用环境的,,,现在采用esp32代替了。
2、hacs proxy,好像有bug,停用插件会导致ha崩掉。
作者: ryanh7    时间: 2024-11-25 18:18
本帖最后由 ryanh7 于 2024-11-25 18:25 编辑
wbdownn 发表于 2024-11-25 17:00
ryanh7 大佬开发过很多东西,也有不少“烂尾”(随着ha的升级,无法兼容了),也删掉了项目

1、http Bluet ...

1、这个从一开始就基本没人用吧,很早就停止维护了。不过都是开源的,可以自己修修补补。某些项目删掉了是因为对中文社区开源环境不乐观,部分原因参考上一个帖子。论坛很多讨论的东西其实放商业项目里那都不是事,程序员能直接搞定,都不需要用户操心。但…一言难尽

2、没收到这方面的错误报告(再次对中文开源环境表示担忧,真正有问题的不提issue,提issue的都是hacs怎么用…),这个小插件从诞生起就没有怎么更新过,没有什么工作量也没什么技术含量,但居然是我写的插件中收藏量最活跃的,只是hacs不愿添加代理设置的一个投机取巧的副产物罢了,唉
作者: lovelyelfpop    时间: 2025-1-6 17:15
自制AirTag,支持安卓和HA,无需iphone
https://bbs.hassbian.com/thread-27928-1-1.html

需要一定动手能力,包含硬件DIY和软件部署。

和AirTag一样,依靠附近的苹果设备,不建议农村或人少的地方用。位置不是实时的,有10-30分钟延迟。但是不耗电啊,一个CR2032纽扣电池可以用至少一年
作者: ryanh7    时间: 2025-1-6 17:57
lovelyelfpop 发表于 2025-1-6 17:15
自制AirTag,支持安卓和HA,无需iphone
https://bbs.hassbian.com/thread-27928-1-1.html

可以写一个新的插件直接接入,简化流程
另外可以考虑做带蜂鸣器的版本,以及近距离直接通过蓝牙触发蜂鸣器和定位
作者: lovelyelfpop    时间: 2025-1-7 08:22
ryanh7 发表于 2025-1-6 17:57
可以写一个新的插件直接接入,简化流程
另外可以考虑做带蜂鸣器的版本,以及近距离直接通过蓝牙触发蜂鸣 ...

我只搬运。ha做插件不会,给蓝牙芯片编程也不会。
另外有蜂鸣器的蓝牙防丢iTag(ST17H66B)可以刷成定位标签,但是只支持单MAC地址,定位不太准确不太实时。
其它可刷的蓝牙芯片都没有蜂鸣器
作者: laofanren    时间: 2025-1-7 16:44
看到你的帖子,我也买了这款设备,可是要怎样设置才能发到traccar呢,请指导一下。谢谢。
作者: laofanren    时间: 2025-1-7 17:16
看了这个帖子,我也买了一个这个设备。请问呢怎样设置才能把数据发送到traccar呢,能详细点好吗,谢谢了。
作者: ryanh7    时间: 2025-1-7 17:54
laofanren 发表于 2025-1-7 17:16
看了这个帖子,我也买了一个这个设备。请问呢怎样设置才能把数据发送到traccar呢,能详细点好吗,谢谢了。 ...

我这个方法需要开发固件和插件,评论区有人用mqtt的方式会简单一点,你可以问问他
作者: jjcs    时间: 2025-1-7 19:25
银尔达的4g默认流量是30mb/一个月,如何做到4g流量保持一个月是4g开发的难点
作者: ryanh7    时间: 2025-1-7 20:09
本帖最后由 ryanh7 于 2025-1-8 04:24 编辑
jjcs 发表于 2025-1-7 19:25
银尔达的4g默认流量是30mb/一个月,如何做到4g流量保持一个月是4g开发的难点 ...

按24小时不停发送定位算,每分钟只能发送700个字节,每秒11个字节,对于频率最高的定位消息来说勉勉强强了,如果定位器平均只有一半的时间在工作,那足够了。如果工作时间更少或者2秒以上发送一次定位,甚至能做agps和wifi扫描。设计通讯协议的时候就要尽可能地减少损耗了。当然ota多了还是不行的。
作者: jjcs    时间: 2025-1-7 20:39
本帖最后由 jjcs 于 2025-1-7 20:40 编辑
ryanh7 发表于 2025-1-7 20:09
按24小时不停发送定位算,每分钟只能发送700个字节,每秒11个字节,对于频率最高的定位消息来说勉勉强强了 ...

怪不得,更新配置是消耗流量,我现在在尝试使用Haversine函数计算两个经纬度的距离,距离大于多少上报,目前还在测试中,还有基站定位也消耗流量,另外如果mqtt重新连接和和心跳包,这样的操作消耗流量应该不大把。
作者: jjcs    时间: 2025-1-7 20:42
目前我部署的定位器消耗流量最少的是在汽车上的,只有汽车启动才会定位,平时就断电
作者: ryanh7    时间: 2025-1-7 21:26
jjcs 发表于 2025-1-7 20:39
怪不得,更新配置是消耗流量,我现在在尝试使用Haversine函数计算两个经纬度的距离,距离大于多少上报,目 ...

重连不频繁不大,如果用字符串发送定位,消耗相对偶尔重连时候的报文大得多
作者: xiaomi2024    时间: 2025-1-10 05:22
大佬666,持续关注
作者: ywjvip    时间: 2025-1-10 17:24
大佬,我能买两个吗?
作者: dscao    时间: 2025-1-22 13:08
本帖最后由 dscao 于 2025-1-26 15:36 编辑

近期2G网络很多地方没信号了,导致之前的优驾很久没更新,开到有些地方能上传,之后定位总是停在行程中间不动了。准备换个4G版,结果价格贵不说还给我发了一个用过的,外壳松动,没有皮盖,原包装还是撕破了的。客服意思爱买不买,发货的都是新的,现在工厂出来就是这样都没有皮盖,都会有缝隙。退货重新下单,拖了几天也不发货。真是气死了,只好放弃优驾了。

还有2个电动车上的2G定位器,也是一个半个月没刷新数据了,一个偶偶刷新一下,但定位点很少。 经过不少天的测试。车智汇加密的搞不定接入ha,退货。最后用了途强在线。 途强的先给了个途强智能,那个根本抓不到包。不知道采用了什么高科技,怕同时加密。准备退货了,客服说可以帮我换到途强在线平台。

另外买了这个银尔达的,主要就是研究学习了。官方的参数配置用任务加入6楼的代码,可以按自己的稍微修改一点,官方文档也比较详细。 最简单的就是用mqtt方式上报到ha的mqtt中。阿里云的mqtt试了半天没搞定,有点复杂,移动电信等其它的还要注册认证懒得试了。
最后用mqtt端口内网穿透出去,虽然是外网的怕网络不好,测试下来还算很稳定。

nodered将mqtt格式做一下转化直接生成实体,效果目测还不错。控制方面还没研究。
[attach]67675[/attach]


[attach]67554[/attach]

今天出去放车上试了一下,很长时间不能定位,空旷地方拿出车外有时很久突然定位上了,变绿灯。只要不断电,放车内也一直可以定位,较准确。但断电后再上电,又是几十分钟都没能定位。不知哪里的问题。看代码中也有gps初始化还有下载星历的部分。问题就是通电后第一次定位超级慢啊。

  1. if e.s ==1 and libgnss.isFix() == false  and count2 > 300 then
  2.                         GpsSetPower(0)
  3.                         sys.wait(1000)
  4.                         GpsSetPower(1)
  5.                         sys.wait(1000)
  6.                         GpsExecAgnss()
  7.                         count2 =0
  8.                 end
复制代码


加了一段5分钟以上没定位成功,检测到震动时就关开一次gps,再下载星历。发现定位速度好像好此,有时从室内拿着出去就定位上了,有时又很慢。



另外为了减少流量消耗,任务中加入:判断正常静止状态每10分钟上报一次完整消息,当20秒以上震动状态改变立即上报、ACC状态改变立即上报、Gps定位状态下距离超过20米时最快5秒上报,位移超过20米后20秒后定位数据上报一次。
其它上报时未上报的数据使用服务器或nodere中的缓存数据。nodered处理是否停车状态及停车时长等计算,超过50米以上并控制频率调用逆地理信息。




作者: ryanh7    时间: 2025-1-23 09:31
本帖最后由 ryanh7 于 2025-1-23 09:39 编辑
dscao 发表于 2025-1-22 13:08
近期2G网络很多地方没信号了,导致之前的优驾很久没更新,开到有些地方能上传,之后定位总是停在行程中间不 ...

冷启动定位时间长,需要agps加速搜星。联网获取星历注入定位芯片,再注入一个最后一次定位的坐标,就能加速定位。昨天也在调定位器,快能上路实测了。我这里用星历的情况下快的话一分钟内,慢的话几分钟,不过是在相对开阔的位置测试的。还做了星历缓存。
作者: jjcs    时间: 2025-2-19 19:34
dscao 发表于 2025-1-22 13:08
近期2G网络很多地方没信号了,导致之前的优驾很久没更新,开到有些地方能上传,之后定位总是停在行程中间不 ...

大佬发下你的代码,我学习学习
作者: jjcs    时间: 2025-2-19 19:37
ryanh7 发表于 2025-1-23 09:31
冷启动定位时间长,需要agps加速搜星。联网获取星历注入定位芯片,再注入一个最后一次定位的坐标,就能加 ...

期待大佬最后的代码
作者: dscao    时间: 2025-2-20 09:52
本帖最后由 dscao 于 2025-3-19 10:06 编辑

参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了):
  1. function
  2.     sys.wait(15000)
  3.     local taskname="userTask"
  4.     log.info(taskname,"start")
  5.     local nid=1
  6.     local uid=1
  7.     local netsta =0
  8.     local needup =1
  9.     local needdw =0
  10.     local needupall =1
  11.     local count =0
  12.     local count2 =0
  13.     local count3 =0
  14.     local shake=0
  15.     local thisshake=0
  16.     local lastshake=0
  17.     local acc=1
  18.     local run=0
  19.     local adc =0
  20.     local e ={}
  21.     local lbslng =0
  22.     local lbslat =0
  23.     local gpslng =0
  24.     local gpslat =0
  25.     local gpsisfix =0
  26.     GpsInit()
  27.     GpsExecAgnss()
  28.     e.adc=0
  29.     PronetStopProRecCh(1)
  30. UartStopProRecCh(1) --如果串口数据还需要透传,需要删除
  31.     local EARTH_RADIUS = 6378.137
  32.     local function getDistance(lat1,lng1,lat2,lng2)
  33.             local radLat1 = lat1 * math.pi / 180.0
  34.             local radLat2 = lat2 * math.pi / 180.0
  35.             local a = radLat1 - radLat2
  36.             local b = lng1 * math.pi / 180.0 - lng2  * math.pi / 180.0
  37.             local s = 2 * math.asin(math.sqrt(math.pow(math.sin(a/2),2) + math.cos(radLat1)*math.cos(radLat2)*math.pow(math.sin(b/2),2)))
  38.             s = s * EARTH_RADIUS
  39.             return s*1000
  40.     end
  41.     local function calculateBearing(lat1, lng1, lat2, lng2)
  42.             local deltaLng = math.rad(lng2 - lng1)
  43.             lat1 = math.rad(lat1)
  44.             lat2 = math.rad(lat2)
  45.             local y = math.sin(deltaLng) * math.cos(lat2)
  46.             local x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(deltaLng)
  47.             local bearing = math.deg(math.atan2(y, x))
  48.             return (bearing + 360) % 360
  49.     end
  50.     while true do
  51.              --解析网络数据
  52.             netr = PronetGetRecChAndDel(nid)
  53.             if netr then
  54.                 log.info(taskname,"netr data",netr)
  55.                 local j =json.decode(netr)
  56.                 if j and type(j)=="table" and j.cmd then
  57.                     if j.cmd =="on1" then
  58.                         PerSetDo(1,1)
  59.                     elseif j.cmd =="off1" then
  60.                         PerSetDo(1,0)
  61.                     elseif j.cmd =="on2" then
  62.                         PerSetDo(2,1)
  63.                     elseif j.cmd =="off2" then
  64.                         PerSetDo(2,0)
  65.                     elseif j.cmd =="onoff2" then
  66.                         PerSetDo(2,1)
  67.                         sys.wait(1000)
  68.                         PerSetDo(2,0)
  69.                     elseif j.cmd =="dw" then  --立即定位
  70.                         needupall =1
  71.                         needupdw =1
  72.                     elseif j.cmd =="reboot" then  --重启
  73.                         pm.reboot()
  74.                     end
  75.                     local jb={}
  76.                     jb.cmd =j.cmd
  77.                     jb.res =1
  78.                     jb.In1=PerGetDoSta(1)
  79.                     jb.In2=PerGetDoSta(2)
  80.                     jb.csq=mobile.csq()
  81.                     local bck = json.encode(jb)
  82.                     if j.cmd ~="dw" and j.cmd ~="reboot" and bck and 1==PronetGetNetSta(nid) then
  83.                         PronetSetSendCh(nid,bck)
  84.                     end
  85.                     local jb={}
  86.                 end
  87.             end       

  88.             local d ={}
  89.             if needupall ==1 then
  90.                     d.t=os.date("%Y-%m-%d %H:%M:%S")
  91.                     d.csq=mobile.csq()
  92.                     d.In1=PerGetDoSta(1)
  93.                     d.In2=PerGetDoSta(2)
  94.             end
  95.             adc =tonumber(PerGetAdcGatherValByAdcId(1))
  96.             if math.abs(e.adc-adc) >1000 or needupall ==1 then
  97.                     d.adc = adc
  98.                     e.adc = d.adc
  99.                     needup =1
  100.             end
  101.             acc=PerGetDiById(1)
  102.             if needupall ==1 or e.acc~=acc then
  103.                     d.acc=acc
  104.                     e.acc=acc
  105.                     needup =1
  106.             end
  107.             thisshake = PerGetGpsZdSta()
  108.             if thisshake == lastshake then
  109.                     count3 = count3+1
  110.             else
  111.                     count3 = 0
  112.             end
  113.             lastshake = thisshake
  114.             if thisshake == 1  and count3>2  then
  115.                     shake = 1
  116.             end
  117.             if thisshake == 0 and count3>30 then
  118.                     shake = 0
  119.             end
  120.             if  needupall ==1 or e.s ~= shake then
  121.                     d.s = shake
  122.                     e.s = shake
  123.                     needup =1
  124.             end
  125.             if libgnss.isFix() then
  126.                     gpsisfix = 1
  127.             else
  128.                     gpsisfix = 0
  129.             end
  130.             if  needupall ==1 or e.f~=gpsisfix then
  131.                     d.f=gpsisfix
  132.                     e.f=d.f
  133.                     needup =1
  134.             end
  135.             if  (acc ==0 or e.s ==1 or needupdw ==1) and libgnss.isFix()==true then
  136.                     local tg =libgnss.getRmc(2)
  137.                     local m = getDistance(tg.lat,tg.lng,gpslat,gpslng)
  138.                     d.m = m
  139.                     d.gps={}
  140.                     d.gps.lat,d.gps.lng=tg.lat,tg.lng
  141.                     d.gps.speed=tg.speed * 1.85
  142.                     d.gps.course = calculateBearing(tg.lat,tg.lng,gpslat,gpslng)
  143.                     if needup ==1 then
  144.                             gpslat,gpslng = d.gps.lat,d.gps.lng
  145.                     end
  146.             end
  147.             lbslng,lbslat = GetLbs()
  148.             if  needupall ==1 or e.lbslng ~= lbslng then
  149.                     d.lbs={}
  150.                     d.lbs.lng,d.lbs.lat=lbslng,lbslat
  151.                     e.lbslng,e.lbslat=lbslng,lbslat
  152.                     needup =1
  153.             end
  154.             local updata = json.encode(d)
  155.             local netsta = PronetGetNetSta(nid)
  156.             log.info(taskname,"updata",updata,"netsta",netsta)
  157.             if needup ==1 and updata and next(d)~=nil and netsta ==1 then
  158.                     needup =0
  159.                     needupall =0
  160.                     count =0
  161.                     PronetSetSendCh(nid,updata)
  162.             end
  163.             count = count+1
  164.             count2 = count2+1
  165.             if (acc ==0 or e.s ==1) and count > 15 then
  166.                     needup =1
  167.             end
  168.             if e.s ==1 and libgnss.isFix() == false  and count2 > 300 then
  169.                     GpsSetPower(0)
  170.                     sys.wait(1000)
  171.                     GpsSetPower(1)
  172.                     sys.wait(1000)
  173.                     GpsExecAgnss()
  174.                     count2 =0
  175.             end
  176.             if count > 3600 then
  177.                     needup =1
  178.                     needupall =1
  179.             end
  180.             sys.wait(1000)
  181.     end
  182. end
复制代码


Nodered端需要做缓存及转化,上报时没有的数据使用缓存,有新的数据更新缓存对应值,最后输出实体。最好再做一下空值过滤,避免特殊情况下实体状态间接性出现短暂unknown导致墨澜地图无法显示轨迹。

[attach]68301[/attach]

之前想用计算运动状态或移动距离来控制上报频率,实际体验非常不好,最后还是改为震动状态或ACC状态控制,ACC接线不太方便,实际使用中还是以震动来判断的,这里震动传感器持续震动2秒后将shake=1,持续静止30秒后shake=0 ,因为实测中发现行驶过程中震动传感器也会偶偶触发静止,所以加入了ha中自动化中状态持续时间的思路。

我也在关注楼主的固件和集成的进展情况,暂时mqtt方式先用着。
为解决定位漂移,后来改成 当静止30t秒以上且未接ACC时,定时上传消息中不包括gps坐标,这样服务端记录的就不会有漂移了。只在ACC接通或动的状态时才发送定位数据。
[attach]69216[/attach]

电动车用得少,一天两次,每次约1公里。每天平均0.3M流量。
mqtt方式的话mqtt服务器一定要稳定,之前家里在网络坏了,停了几天,那几天流量差不多一天流量消耗10M多,还好当时是测试期流量没计算。后来将mqtt改到vps上了,nodered转发相关主题消息到ha中。命令也是由nodered转发到服务器上的mqtt。

[attach]69217[/attach]




作者: ryanh7    时间: 2025-2-20 14:26
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,应该还有很多可以优化的):

震动电阻确实不太靠谱,容易在行驶过程中识别为静止(影响严重),或者在静止时识别为运动(影响较小)。有ACC的情况下还是使用ACC判断比较靠谱。没有ACC的情况下才用震动判断(主要用于判断长时间没有震动后休眠,可能会延长定位器开机)。其余逻辑还是放到服务端处理比较好。现在主要问题还是定位漂移
作者: zhuzhuzhu    时间: 2025-2-25 13:57
666大佬们牛逼,期待固件和集成
作者: jjcs    时间: 2025-7-6 23:18
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了 ...

请问一下,楼主的acc没有接,纯靠震动判断吗,也就是说定位器一直在运行状态,流量消耗怎么样
作者: jjcs    时间: 2025-7-6 23:19
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了 ...

求大佬nodered代码
作者: dscao    时间: 2025-7-7 10:23
本帖最后由 dscao 于 2025-7-7 10:25 编辑
jjcs 发表于 2025-7-6 23:19
求大佬nodered代码

nodered已经迁移到这里了:https://bbs.hassbian.com/thread-23386-1-1.html
可以试一下

教程:
https://bbs.hassbian.com/forum.p ... 9464&pid=681521

作者: jjcs    时间: 2025-7-7 22:09
dscao 发表于 2025-7-7 10:23
nodered已经迁移到这里了:https://bbs.hassbian.com/thread-23386-1-1.html
可以试一下

有一个疑问,使用集成接入,是不是需要使用nodered转发一下,我使用本地mqtt,
作者: jjcs    时间: 2025-7-7 22:10
dscao 发表于 2025-7-7 10:23
nodered已经迁移到这里了:https://bbs.hassbian.com/thread-23386-1-1.html
可以试一下

Nodered端需要做缓存及转化,上报时没有的数据使用缓存,有新的数据更新缓存对应值,最后输出实体。最好再做一下空值过滤,避免特殊情况下实体状态间接性出现短暂unknown导致墨澜地图无法显示轨迹,貌似没看见,nodered已经迁移到这里了:https://bbs.hassbian.com/thread-23386-1-1.html
作者: dscao    时间: 2025-7-7 23:07
本帖最后由 dscao 于 2025-7-7 23:08 编辑
jjcs 发表于 2025-7-7 22:09
有一个疑问,使用集成接入,是不是需要使用nodered转发一下,我使用本地mqtt, ...

gps接入到哪个mqtt服务器,这个集成就连接那个mqtt服务器。如果gps的mqtt消息已经发送到本地了,这个就填写本地的mqtt服务器就行了。

我说的迁移是指用nodered实现的原理及流程已经改成了集成的方式,现在不需要nodered了。

作者: jjcs    时间: 2025-7-8 11:51
dscao 发表于 2025-7-7 23:07
gps接入到哪个mqtt服务器,这个集成就连接那个mqtt服务器。如果gps的mqtt消息已经发送到本地了,这个就填 ...

使用集成连接mqtt服务器有bug,直接成功连接在删除设备,在连接就不行了,而且有写mqtt端口不是非标,是不是可以直接加端口xxxxxx:1883||xxxx||xxxx,对于有些需要固定客户端id的权鉴,是不是没办法添加
作者: jjcs    时间: 2025-7-8 12:54
jjcs 发表于 2025-7-8 11:51
使用集成连接mqtt服务器有bug,直接成功连接在删除设备,在连接就不行了,而且有写mqtt端口不是非标,是 ...

又可以了奇怪
作者: jjcs    时间: 2025-7-8 13:36
dscao 发表于 2025-7-7 23:07
gps接入到哪个mqtt服务器,这个集成就连接那个mqtt服务器。如果gps的mqtt消息已经发送到本地了,这个就填 ...

集成在点击定位按钮,会让ha卡死,版本2025.7.1,安装方式
Home Assistant Container
Core
2025.7.1
Frontend
20250702.1
作者: dscao    时间: 2025-7-8 13:51
jjcs 发表于 2025-7-8 13:36
集成在点击定位按钮,会让ha卡死,版本2025.7.1,安装方式
Home Assistant Container
Core

卡死就搞不清楚什么原因了,日志也看不到。
我这边三个ha系统,一个银尔达gps设备,没出现过这种情况。早期的版本是时间长了mqtt连接就假死了,收不到消息了,但也没有让ha卡死。改过多次,现在我自己用得感觉已经很稳定了。
作者: jjcs    时间: 2025-7-8 16:35
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了 ...

终于测试成功了,楼主的代码可谓是完成的之前设想的全部功能,调试gps很烦老是需要户外跑来跑去,mqtt使用巴法云,稳定性比自建好,话说对于电动车适用,那我用在汽车上,是不是也可以用,{主要是是启动定位逻辑}我汽车逻辑是只有点火定位器才上电
作者: yangrusen    时间: 2025-7-8 17:57
大神卖不卖设备
作者: jjcs    时间: 2025-7-9 20:34
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了 ...

这个代码是不是这行有问题97行 if math.abs(e.adc-adc) >1000 or needupall ==1 then,如果PerGetAdcGatherValByAdcId(1)返回nil,感觉有概率,空值运算报错,
debug日志
[string " ..."]:97: in main chunk
[2025-07-09 20:04:50.564][000000021.286] E/main Luat:
[2025-07-09 20:04:50.571][000000021.287] E/main [string " ..."]:97: attempt to perform arithmetic on a nil value (local 'adc')
stack traceback:
        [string " ..."]:97: in main chunk
作者: feiniao7168    时间: 昨天 00:20
有加速度传感器就绝了




欢迎光临 『瀚思彼岸』» 智能家居技术论坛 (https://bbs.hassbian.com/) Powered by Discuz! X3.5