找回密码
 立即注册

微信扫码登录

搜索
楼主: ryanh7

[技术探讨] 新坑:air780eg定位器diy

  [复制链接]

81

主题

1436

回帖

3万

积分

元老级技术达人

积分
30382
金钱
28825
HASS币
290
发表于 2025-2-20 09:52:06 | 显示全部楼层
本帖最后由 dscao 于 2025-3-19 10:06 编辑

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

参数配置中的任务(目前最后的代码,20250319更新,平台上参数版本179了):
function 
    sys.wait(15000) 
    local taskname="userTask" 
    log.info(taskname,"start")
    local nid=1
    local uid=1
    local netsta =0
    local needup =1
    local needdw =0
    local needupall =1
    local count =0
    local count2 =0
    local count3 =0
    local shake=0
    local thisshake=0
    local lastshake=0
    local acc=1
    local run=0
    local adc =0
    local e ={}
    local lbslng =0
    local lbslat =0
    local gpslng =0
    local gpslat =0
    local gpsisfix =0
    GpsInit()
    GpsExecAgnss()
    e.adc=0
    PronetStopProRecCh(1)
UartStopProRecCh(1) --如果串口数据还需要透传,需要删除
    local EARTH_RADIUS = 6378.137
    local function getDistance(lat1,lng1,lat2,lng2)
            local radLat1 = lat1 * math.pi / 180.0
            local radLat2 = lat2 * math.pi / 180.0
            local a = radLat1 - radLat2
            local b = lng1 * math.pi / 180.0 - lng2  * math.pi / 180.0
            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)))
            s = s * EARTH_RADIUS
            return s*1000
    end
    local function calculateBearing(lat1, lng1, lat2, lng2)
            local deltaLng = math.rad(lng2 - lng1)
            lat1 = math.rad(lat1)
            lat2 = math.rad(lat2)
            local y = math.sin(deltaLng) * math.cos(lat2)
            local x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(deltaLng)
            local bearing = math.deg(math.atan2(y, x))
            return (bearing + 360) % 360
    end
    while true do
             --解析网络数据
            netr = PronetGetRecChAndDel(nid)
            if netr then 
                log.info(taskname,"netr data",netr)
                local j =json.decode(netr)
                if j and type(j)=="table" and j.cmd then 
                    if j.cmd =="on1" then 
                        PerSetDo(1,1)
                    elseif j.cmd =="off1" then 
                        PerSetDo(1,0)
                    elseif j.cmd =="on2" then 
                        PerSetDo(2,1)
                    elseif j.cmd =="off2" then 
                        PerSetDo(2,0)
                    elseif j.cmd =="onoff2" then 
                        PerSetDo(2,1)
                        sys.wait(1000)
                        PerSetDo(2,0)
                    elseif j.cmd =="dw" then  --立即定位
                        needupall =1
                        needupdw =1
                    elseif j.cmd =="reboot" then  --重启
                        pm.reboot()
                    end 
                    local jb={}
                    jb.cmd =j.cmd
                    jb.res =1
                    jb.In1=PerGetDoSta(1)
                    jb.In2=PerGetDoSta(2)
                    jb.csq=mobile.csq()
                    local bck = json.encode(jb)
                    if j.cmd ~="dw" and j.cmd ~="reboot" and bck and 1==PronetGetNetSta(nid) then 
                        PronetSetSendCh(nid,bck)
                    end 
                    local jb={}
                end 
            end        

            local d ={}
            if needupall ==1 then
                    d.t=os.date("%Y-%m-%d %H:%M:%S")
                    d.csq=mobile.csq()
                    d.In1=PerGetDoSta(1)
                    d.In2=PerGetDoSta(2)
            end
            adc =tonumber(PerGetAdcGatherValByAdcId(1)) 
            if math.abs(e.adc-adc) >1000 or needupall ==1 then
                    d.adc = adc
                    e.adc = d.adc
                    needup =1
            end
            acc=PerGetDiById(1)
            if needupall ==1 or e.acc~=acc then
                    d.acc=acc
                    e.acc=acc
                    needup =1
            end
            thisshake = PerGetGpsZdSta()
            if thisshake == lastshake then
                    count3 = count3+1
            else
                    count3 = 0
            end
            lastshake = thisshake
            if thisshake == 1  and count3>2  then
                    shake = 1
            end
            if thisshake == 0 and count3>30 then
                    shake = 0
            end
            if  needupall ==1 or e.s ~= shake then
                    d.s = shake
                    e.s = shake
                    needup =1
            end
            if libgnss.isFix() then
                    gpsisfix = 1
            else
                    gpsisfix = 0
            end
            if  needupall ==1 or e.f~=gpsisfix then
                    d.f=gpsisfix
                    e.f=d.f
                    needup =1
            end
            if  (acc ==0 or e.s ==1 or needupdw ==1) and libgnss.isFix()==true then 
                    local tg =libgnss.getRmc(2)
                    local m = getDistance(tg.lat,tg.lng,gpslat,gpslng)
                    d.m = m
                    d.gps={}
                    d.gps.lat,d.gps.lng=tg.lat,tg.lng
                    d.gps.speed=tg.speed * 1.85
                    d.gps.course = calculateBearing(tg.lat,tg.lng,gpslat,gpslng)
                    if needup ==1 then
                            gpslat,gpslng = d.gps.lat,d.gps.lng
                    end
            end
            lbslng,lbslat = GetLbs()
            if  needupall ==1 or e.lbslng ~= lbslng then
                    d.lbs={}
                    d.lbs.lng,d.lbs.lat=lbslng,lbslat
                    e.lbslng,e.lbslat=lbslng,lbslat
                    needup =1
            end
            local updata = json.encode(d)
            local netsta = PronetGetNetSta(nid)
            log.info(taskname,"updata",updata,"netsta",netsta)
            if needup ==1 and updata and next(d)~=nil and netsta ==1 then 
                    needup =0
                    needupall =0
                    count =0
                    PronetSetSendCh(nid,updata)
            end
            count = count+1
            count2 = count2+1
            if (acc ==0 or e.s ==1) and count > 15 then
                    needup =1
            end
            if e.s ==1 and libgnss.isFix() == false  and count2 > 300 then
                    GpsSetPower(0)
                    sys.wait(1000)
                    GpsSetPower(1)
                    sys.wait(1000)
                    GpsExecAgnss()
                    count2 =0
            end
            if count > 3600 then 
                    needup =1
                    needupall =1
            end 
            sys.wait(1000)
    end 
end


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

20250220094954.jpg

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

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

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

PixPin_2025-03-19_09-55-45.png



评分

参与人数 3金钱 +24 收起 理由
jjcs + 12 高手,这是高手!
s2233 + 10 看到tb店里你那配图买了个,今天看到论坛里 ...
ahu + 2 GPS 定位一直不行,只到我用了这段代码!.

查看全部评分

回复

使用道具 举报

66

主题

309

回帖

6168

积分

元老级技术达人

积分
6168
金钱
5778
HASS币
100
 楼主| 发表于 2025-2-20 14:26:22 | 显示全部楼层
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

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

震动电阻确实不太靠谱,容易在行驶过程中识别为静止(影响严重),或者在静止时识别为运动(影响较小)。有ACC的情况下还是使用ACC判断比较靠谱。没有ACC的情况下才用震动判断(主要用于判断长时间没有震动后休眠,可能会延长定位器开机)。其余逻辑还是放到服务端处理比较好。现在主要问题还是定位漂移
回复

使用道具 举报

0

主题

147

回帖

1234

积分

金牌会员

积分
1234
金钱
1087
HASS币
0
发表于 2025-2-25 13:57:45 | 显示全部楼层
666大佬们牛逼,期待固件和集成
回复

使用道具 举报

jjcs 手机认证

57

主题

2033

回帖

8260

积分

论坛元老

积分
8260
金钱
6160
HASS币
50
发表于 2025-7-6 23:18:07 | 显示全部楼层
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

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

请问一下,楼主的acc没有接,纯靠震动判断吗,也就是说定位器一直在运行状态,流量消耗怎么样
折腾精神永存,感恩感谢论坛每一位愿意分享和帮助过我的大佬,论坛有你更精彩
回复

使用道具 举报

jjcs 手机认证

57

主题

2033

回帖

8260

积分

论坛元老

积分
8260
金钱
6160
HASS币
50
发表于 2025-7-6 23:19:44 | 显示全部楼层
dscao 发表于 2025-2-20 09:52
参数中的定位: 全部启用但不上报

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

求大佬nodered代码
折腾精神永存,感恩感谢论坛每一位愿意分享和帮助过我的大佬,论坛有你更精彩
回复

使用道具 举报

81

主题

1436

回帖

3万

积分

元老级技术达人

积分
30382
金钱
28825
HASS币
290
发表于 2025-7-7 10:23:28 | 显示全部楼层
本帖最后由 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 手机认证

57

主题

2033

回帖

8260

积分

论坛元老

积分
8260
金钱
6160
HASS币
50
发表于 2025-7-7 22:09:36 | 显示全部楼层
dscao 发表于 2025-7-7 10:23
nodered已经迁移到这里了:https://bbs.hassbian.com/thread-23386-1-1.html
可以试一下

有一个疑问,使用集成接入,是不是需要使用nodered转发一下,我使用本地mqtt,
折腾精神永存,感恩感谢论坛每一位愿意分享和帮助过我的大佬,论坛有你更精彩
回复

使用道具 举报

jjcs 手机认证

57

主题

2033

回帖

8260

积分

论坛元老

积分
8260
金钱
6160
HASS币
50
发表于 2025-7-7 22:10:44 | 显示全部楼层
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
折腾精神永存,感恩感谢论坛每一位愿意分享和帮助过我的大佬,论坛有你更精彩
回复

使用道具 举报

81

主题

1436

回帖

3万

积分

元老级技术达人

积分
30382
金钱
28825
HASS币
290
发表于 2025-7-7 23:07:05 | 显示全部楼层
本帖最后由 dscao 于 2025-7-7 23:08 编辑
jjcs 发表于 2025-7-7 22:09
有一个疑问,使用集成接入,是不是需要使用nodered转发一下,我使用本地mqtt, ...

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

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

使用道具 举报

jjcs 手机认证

57

主题

2033

回帖

8260

积分

论坛元老

积分
8260
金钱
6160
HASS币
50
发表于 2025-7-8 11:51:05 | 显示全部楼层
dscao 发表于 2025-7-7 23:07
gps接入到哪个mqtt服务器,这个集成就连接那个mqtt服务器。如果gps的mqtt消息已经发送到本地了,这个就填 ...

使用集成连接mqtt服务器有bug,直接成功连接在删除设备,在连接就不行了,而且有写mqtt端口不是非标,是不是可以直接加端口xxxxxx:1883||xxxx||xxxx,对于有些需要固定客户端id的权鉴,是不是没办法添加
折腾精神永存,感恩感谢论坛每一位愿意分享和帮助过我的大佬,论坛有你更精彩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-8-31 09:18 , Processed in 0.110235 second(s), 12 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表