令狐鸣 发表于 2019-5-6 14:13:48

百度/高德逆地理-获取位置信息同步HA

本帖最后由 令狐鸣 于 2019-5-8 20:31 编辑

# 逆地理## 2019/05/08

> 加入一个判断在固定位置的节点

​      如果位置在家或者固定的zone地址,直接显示"在家"或者"固定位置",其他位置走逆地理;导入节点,照图连线即可.

![](http://img.sonicming.top/201905082032_292.png)
![](http://img.sonicming.top/201905082035_375.png)

```
[{"id":"eb240d88.cb2f9","type":"function","z":"dc61884c.5c1728","name":"固定位置判断","func":"var loc = msg.payload;\n//不在固定位置走逆地里\nif( loc === 'not_home'){\n    return ;\n}else{\n//在固定位置\n    //获取位置人信息\n    let who = msg.topic.split(\".\");\n    //转换\n    if(msg.payload ==='home'){\n      msg.payload = '在家';\n      //如果有车可以加入车的id判断在家显示停车场\n      //msg.payload = who == 'carId'?'停车场':'在家'; \n    }\n    //拼接MQTT地址\n    let topic = `gaode/location/${who}`;\n      msg.topic = topic;\n    //显示位置    \n    node.status({\n      text:who+\":\"+msg.payload\n    })\n    return ;\n}\n\n","outputs":2,"noerr":0,"x":220,"y":780,"wires":[["339b14ac.d635dc"],["20489eee.4a6302"]],"outputLabels":["逆地理","固定位置"]}]
```

## 2019/05/08 更新高德位置纠偏

​      之前只是按照api做了逆地理,没考虑到还有不同地图坐标不一致的问题,导致直接使用偏移很严重.      多谢(https://bbs.hassbian.com/home.php?mod=space&uid=2861)提醒.
      同时坛友(https://bbs.hassbian.com/home.php?mod=space&uid=4355)给提供了解决方案,
      高德的纠偏api和node-red高德节点,都可以很好的解决问题.之后做了高德节点调整(百度没改,感觉直接用高德就行了.)

​      节点做了修改,高德**重新导入node即可,Ha配置不变**(node-red转ha就是这点方便,ha完全不用动)

高德现在做了三条线,按需连线删除其他不需要的即可:

1. 高德Node-Red节点(推荐)
   需要先添加`node-red-contrib-gaode`节点
   ![](http://img.sonicming.top/201905081848_847.png)
2. 高德API位置纠偏
   ![](http://img.sonicming.top/201905081836_500.png)
3. 手动纠偏
   如果纠偏还是不准,可以自己手动计算修改
   ![](http://img.sonicming.top/201905081900_198.png)

高德新的JSON节点:

```json
[{"id":"cdff9762.12a898","type":"comment","z":"dc61884c.5c1728","name":"高德逆地理","info":"(https://lbs.amap.com/api/webservice/guide/api/georegeo/)\n\n必填参数\n- key : \n- location","x":100,"y":600,"wires":[]},{"id":"4ae149a0.0eb568","type":"api-current-state","z":"dc61884c.5c1728","name":"获取当前位置","server":"5d5b63f8.ca1c8c","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"device_tracker.xxx","x":260,"y":640,"wires":[["339b14ac.d635dc"]]},{"id":"127df421.4b592c","type":"inject","z":"dc61884c.5c1728","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":640,"wires":[["4ae149a0.0eb568"]]},{"id":"8e4d751e.3f0498","type":"comment","z":"dc61884c.5c1728","name":"HA配置","info":"```yaml\n# https://www.home-assistant.io/components/sensor.mqtt/\n# 高德逆地理\n# 根据高德API,NODE获取用户坐标信息转换地址\n# group.gaode_node\n\nsensor:\n- platform: mqtt\n    name: \"x_loc\"\n    state_topic: \"gaode/location/设备名\"\n    value_template: \"{{ value}}\"\n\n#自定义名称\nhomeassistant:\ncustomize_glob:\n    sensor.*_loc:\n      icon: mdi:google-maps\ncustomize:\n    sensor.x_loc:\n      friendly_name: 位置\n\n#分组\ngroup:\ngaode_node:\n    name: 逆地理\n    view: no\n    entities:\n      - sensor.x_loc\n\n\n\n\n\n```","x":230,"y":600,"wires":[]},{"id":"92c70793.85ae98","type":"http request","z":"dc61884c.5c1728","name":"GET请求逆地里","method":"GET","ret":"txt","url":"","tls":"","x":620,"y":840,"wires":[["8b7cf37b.2e40e"]]},{"id":"c90e428b.9f327","type":"function","z":"dc61884c.5c1728","name":"拼接参数(未纠偏地址)","func":"//API地址\nlet url = 'https://restapi.amap.com/v3/geocode/regeo';\n//key\nlet key = \"高德key\"\n//经纬度\nlet location = \"\";\nif(msg.data.attributes===undefined){\n//events\nlet loc = msg.data.new_state.attributes;\nlocation = loc.longitude+','+loc.latitude;    \n}else{\n//current\nlocation = msg.data.attributes.longitude+','+msg.data.attributes.latitude;\n}\n//拼接GET地址\nmsg.url = `${url}?key=${key}&location=${location}`\nreturn msg;","outputs":1,"noerr":0,"x":380,"y":840,"wires":[["92c70793.85ae98"]]},{"id":"8b7cf37b.2e40e","type":"function","z":"dc61884c.5c1728","name":"转换位置","func":"//获取位置人信息\nlet who = msg.topic.split(\".\");\n//拼接MQTT地址\nlet topic = `gaode/location/${who}`;\n//转换JSON\nlet res = JSON.parse(msg.payload);\n//成功返回\nif(res.status === '1'){\n    msg.topic = topic;\n    msg.payload = res.regeocode.formatted_address;\n    //显示位置    \n    node.status({\n      text:who+\":\"+msg.payload\n    })\n    //输出值\n    return msg;\n}\n","outputs":1,"noerr":0,"x":780,"y":840,"wires":[["20489eee.4a6302"]]},{"id":"20489eee.4a6302","type":"mqtt out","z":"dc61884c.5c1728","name":"高德逆地里","topic":"","qos":"0","retain":"true","broker":"fe3c94f2.6bfd58","x":890,"y":780,"wires":[]},{"id":"2d4fa3bf.01f00c","type":"function","z":"dc61884c.5c1728","name":"获取坐标","func":"//API地址\nlet url = 'http://restapi.amap.com/v3/assistant/coordinate/convert?coordsys=gps&output=json';\n//key\nlet key = \"高德key\"\nmsg.key = key;\n//经纬度\nlet location = \"\";\nif(msg.data.attributes===undefined){\n//events\nlet loc = msg.data.new_state.attributes;\nlocation = loc.longitude+','+loc.latitude;    \n}else{\n//current\nlocation = msg.data.attributes.longitude+','+msg.data.attributes.latitude;\n}\n//拼接GET地址\nmsg.url = `${url}&key=${key}&locations=${location}`\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":780,"wires":[["a512a238.9d413"]]},{"id":"a512a238.9d413","type":"http request","z":"dc61884c.5c1728","name":"高德纠偏","method":"GET","ret":"txt","url":"","tls":"","x":480,"y":780,"wires":[["420fc795.62f458"]]},{"id":"420fc795.62f458","type":"function","z":"dc61884c.5c1728","name":"地址拼接","func":"let correct = JSON.parse(msg.payload);\nlet newLoc = correct.locations;\n\nlet url = 'https://restapi.amap.com/v3/geocode/regeo';\n//拼接GET地址\nmsg.url = `${url}?key=${msg.key}&location=${newLoc}`\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":780,"wires":[["92c70793.85ae98"]]},{"id":"339b14ac.d635dc","type":"function","z":"dc61884c.5c1728","name":"获取坐标","func":"//经纬度\nlet loc = \"\";\nlet longitude = \"\";\nlet latitude = \"\";\nif(msg.data.attributes===undefined){\n//events\nloc = msg.data.new_state.attributes;\nlongitude = loc.longitude;\nlatitude = loc.latitude;    \n}else{\n//current\nloc = msg.data.attributes;\nlongitude = loc.longitude;\nlatitude = loc.latitude;\n}\n//拼接GET地址\nmsg.payload = {\n    longitude,\n    latitude\n}\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":720,"wires":[["27900981.f2af56"]]},{"id":"a50f4b62.63a938","type":"function","z":"dc61884c.5c1728","name":"转换位置","func":"//获取位置人信息\nlet who = msg.topic.split(\".\");\n//拼接MQTT地址\nlet topic = `gaode/location/${who}`;\n//转换JSON\nlet res = msg.payload;\n//成功返回\nif(res.status === 1){\n    msg.topic = topic;\n    msg.payload = res.location;\n    //显示位置    \n    node.status({\n      text:who+\":\"+msg.payload\n    })\n    //输出值\n    return msg;\n}\n","outputs":1,"noerr":0,"x":680,"y":720,"wires":[["20489eee.4a6302"]]},{"id":"a7681b0c.3688c8","type":"function","z":"dc61884c.5c1728","name":"拼接参数(手动纠偏)","func":"//API地址\nlet url = 'https://restapi.amap.com/v3/geocode/regeo';\n//key\nlet key = \"高德key\"\n//手动纠偏参数\nconst longitude_offset = 0.00459;\nconst latitude_offset = -0.00318;\n//经纬度\nlet loc = \"\"\nlet location = \"\";\n//events or current\nloc = msg.data.attributes===undefined?msg.data.new_state.attributes:msg.data.attributes\n//拼接坐标\nlocation = `${parseInt(loc.longitude)+longitude_offset},${parseInt(loc.latitude)+latitude_offset}`;   \n//拼接GET地址\nmsg.url = `${url}?key=${key}&location=${location}`\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":900,"wires":[["92c70793.85ae98"]]},{"id":"27900981.f2af56","type":"gaode","z":"dc61884c.5c1728","server":"","name":"获取位置","longitude":"","latitude":"","x":520,"y":720,"wires":[["a50f4b62.63a938"]]},{"id":"6a7fabdf.f0fc04","type":"server-state-changed","z":"dc61884c.5c1728","name":"我的位置","server":"5d5b63f8.ca1c8c","entityidfilter":"device_tracker.xxx","entityidfiltertype":"substring","haltifstate":"","outputinitially":true,"x":120,"y":800,"wires":[["339b14ac.d635dc"]]},{"id":"5d5b63f8.ca1c8c","type":"server","z":"","name":"8123","legacy":true},{"id":"fe3c94f2.6bfd58","type":"mqtt-broker","z":"","name":"88-MQTT","broker":"10.0.0.88","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
```





其他配置相同,参考下文**需要修改的配置****和**HA配置**

最后,忘记百度吧,哈哈

### 前言

​      这个可能也没有多大用,就是把人员坐标通过逆地里转换为详细文字位置,看个人所需吧,比地图直观一点.

​      之前一直用的L大的插件修改获取[百度路况V3修复bug【通勤时间】【回家时间】](http://t.cn/EoGBY5z),有空弄了下node-red感觉更灵活一点吧.两个版本,同一个坐标位置获取都不太一样.

**效果**

![](http://img.sonicming.top/201905061337_152.png)

### 前提条件

1. ha
2. node-red
3. 百度or高德注册开发者获取key



#### 百度开发者申请

[申请地址](http://t.cn/R1bnpp8)

1. 注册
2. 创建应用
   ![](http://img.sonicming.top/201905061151_169.png)
3. 复制AK
   ![](http://img.sonicming.top/201905061152_405.png)

#### 高德开发者申请

[高德地图API](https://lbs.amap.com/)

1. 注册

2. 控制台-创建应用

   ![](http://img.sonicming.top/201905061346_56.png)

3. 获取key
   ![](http://img.sonicming.top/201905061346_702.png)

### node-red截图

![](http://img.sonicming.top/201905061140_493.png)

### Node-Red配置

```json
[{"id":"f240c33c.baf28","type":"comment","z":"dc61884c.5c1728","name":"百度逆地理","info":"[说明](http://t.cn/RmeNq8X)\n\n# API\n`\nhttp://api.map.baidu.com/geocode ... put=json&pois=0&ak=\n`\n\n# 必填参数\n- ak : \n- location : 32.24506727,107.94106806\n- \n\n# 返回json\n```json\n{\n    \"status\": 0,\n    \"result\": {\n      \"location\": {\n            \"lng\": 108.94106805999995,\n            \"lat\": 34.24506730328651\n      },\n      \"formatted_address\": \"返回地址\",\n      \"business\": \"\",\n      \"addressComponent\": {\n            \"country\": \"中国\",\n            \"country_code\": 0,\n            \"country_code_iso\": \"CHN\",\n            \"country_code_iso2\": \"CN\",\n            \"province\": \"陕西省\",\n            \"city\": \"\",\n            \"city_level\": ,\n            \"district\": \"\",\n            \"town\": \"\",\n            \"adcode\": \"\",\n            \"street\": \"\",\n            \"street_number\": \"\",\n            \"direction\": \"\",\n            \"distance\": \"\"\n      },\n      \"pois\": [],\n      \"roads\": [],\n      \"poiRegions\": [\n            {\n                \"direction_desc\": \"\",\n                \"name\": \"\",\n                \"tag\": \"\",\n                \"uid\": \"\",\n                \"distance\": \"0\"\n            }\n      ],\n      \"sematic_description\": \"\",\n      \"cityCode\": \n    }\n}\n```","x":120,"y":80,"wires":[]},{"id":"807ac13d.1552b","type":"http request","z":"dc61884c.5c1728","name":"GET请求逆地理","method":"GET","ret":"txt","url":"","tls":"","x":480,"y":240,"wires":[["9b3d850b.8f2a18"]]},{"id":"9498874f.bec988","type":"api-current-state","z":"dc61884c.5c1728","name":"获取当前位置","server":"5d5b63f8.ca1c8c","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"device_tracker.xxx","x":280,"y":120,"wires":[["4e8ebb15.122a74"]]},{"id":"5026028a.38774c","type":"inject","z":"dc61884c.5c1728","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":120,"wires":[["9498874f.bec988"]]},{"id":"4e8ebb15.122a74","type":"function","z":"dc61884c.5c1728","name":"拼接参数","func":"//API地址\nlet url = 'http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&output=json';\n//ak\nlet ak = '百度AK';\n//经纬度\nlet location = \"\";\nlet loc = \"\";\nif(msg.data.attributes===undefined){\n//events\nloc = msg.data.new_state.attributes;\n    \n}else{\n//current\nloc = msg.data.attributes;\n}\nlocation = loc.latitude +','+ loc.longitude;\n//拼接GET地址\nmsg.url = `${url}&ak=${ak}&location=${location}`\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":240,"wires":[["807ac13d.1552b"]]},{"id":"9b3d850b.8f2a18","type":"function","z":"dc61884c.5c1728","name":"转换位置","func":"//获取位置人信息\nlet who = msg.topic.split(\".\");\n//拼接MQTT地址\nlet topic = `baidu/location/${who}`;\n//转换JSON\nlet json = msg.payload.replace(/renderReverse&&renderReverse\\((.*)\\)/,\"$1\");\nlet res = JSON.parse(json);\n//成功返回\nif(res.status === 0){\n    msg.topic = topic;\n    msg.payload = res.result.formatted_address;\n    //显示位置    \n    node.status({\n      text:who+\":\"+msg.payload\n    })\n    //输出值\n    return msg;\n}\n","outputs":1,"noerr":0,"x":640,"y":240,"wires":[["d7723f6d.680ec"]]},{"id":"d7723f6d.680ec","type":"mqtt out","z":"dc61884c.5c1728","name":"百度逆地理","topic":"","qos":"0","retain":"true","broker":"","x":790,"y":240,"wires":[]},{"id":"f160bfd9.fc7f3","type":"comment","z":"dc61884c.5c1728","name":"HA配置","info":"```yaml\n# https://www.home-assistant.io/components/sensor.mqtt/\n# 百度逆地理\n# 根据百度API,NODE获取用户坐标信息转换地址\n# group.baidu_node\n\nsensor:\n- platform: mqtt\n    name: \"x_loc\"\n    state_topic: \"baidu/location/设备名\"\n    value_template: \"{{ value}}\"\n\n\n#自定义名称\nhomeassistant:\ncustomize_glob:\n    sensor.*_loc:\n      icon: mdi:google-maps\ncustomize:\n    sensor.m_loc:\n      friendly_name: 位置\n\n\n#分组\ngroup:\nbaidu_node:\n    name: 逆地理\n    view: no\n    entities:\n      - sensor.x_loc\n\n\n\n\n\n```","x":250,"y":80,"wires":[]},{"id":"cdff9762.12a898","type":"comment","z":"dc61884c.5c1728","name":"高德逆地理","info":"(https://lbs.amap.com/api/webservice/guide/api/georegeo/)\n\n必填参数\n- key : \n- location","x":120,"y":440,"wires":[]},{"id":"48b25712.df9678","type":"http request","z":"dc61884c.5c1728","name":"GET请求逆地里","method":"GET","ret":"txt","url":"","tls":"","x":480,"y":600,"wires":[["1eb2f664.cb1b4a"]]},{"id":"4ae149a0.0eb568","type":"api-current-state","z":"dc61884c.5c1728","name":"获取当前位置","server":"5d5b63f8.ca1c8c","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"device_tracker.xxx","x":280,"y":480,"wires":[["3d3bf2cc.118a7e"]]},{"id":"127df421.4b592c","type":"inject","z":"dc61884c.5c1728","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":480,"wires":[["4ae149a0.0eb568"]]},{"id":"3d3bf2cc.118a7e","type":"function","z":"dc61884c.5c1728","name":"拼接参数","func":"//API地址\nlet url = 'https://restapi.amap.com/v3/geocode/regeo';\n//key\nlet key = \"高德key\"\n//经纬度\nlet location = \"\";\nif(msg.data.attributes===undefined){\n//events\nlet loc = msg.data.new_state.attributes;\nlocation = loc.longitude+','+loc.latitude;    \n}else{\n//current\nlocation = msg.data.attributes.longitude+','+msg.data.attributes.latitude;\n}\n//拼接GET地址\nmsg.url = `${url}?key=${key}&location=${location}`\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":600,"wires":[["48b25712.df9678"]]},{"id":"1eb2f664.cb1b4a","type":"function","z":"dc61884c.5c1728","name":"转换位置","func":"//获取位置人信息\nlet who = msg.topic.split(\".\");\n//拼接MQTT地址\nlet topic = `gaode/location/${who}`;\n//转换JSON\nlet res = JSON.parse(msg.payload);\n//成功返回\nif(res.status === '1'){\n    msg.topic = topic;\n    msg.payload = res.regeocode.formatted_address;\n    //显示位置    \n    node.status({\n      text:who+\":\"+msg.payload\n    })\n    //输出值\n    return msg;\n}\n","outputs":1,"noerr":0,"x":640,"y":600,"wires":[["abe4dbb6.712078"]]},{"id":"ceadceba.e29ae","type":"server-state-changed","z":"dc61884c.5c1728","name":"我的位置","server":"5d5b63f8.ca1c8c","entityidfilter":"device_tracker.xxx","entityidfiltertype":"substring","haltifstate":"","outputinitially":true,"x":140,"y":600,"wires":[["3d3bf2cc.118a7e"]]},{"id":"abe4dbb6.712078","type":"mqtt out","z":"dc61884c.5c1728","name":"高德逆地理","topic":"","qos":"0","retain":"true","broker":"","x":790,"y":600,"wires":[]},{"id":"8e4d751e.3f0498","type":"comment","z":"dc61884c.5c1728","name":"HA配置","info":"```yaml\n# https://www.home-assistant.io/components/sensor.mqtt/\n# 高德逆地理\n# 根据高德API,NODE获取用户坐标信息转换地址\n# group.gaode_node\n\nsensor:\n- platform: mqtt\n    name: \"x_loc\"\n    state_topic: \"gaode/location/设备名\"\n    value_template: \"{{ value}}\"\n\n#自定义名称\nhomeassistant:\ncustomize_glob:\n    sensor.*_loc:\n      icon: mdi:google-maps\ncustomize:\n    sensor.x_loc:\n      friendly_name: 位置\n\n#分组\ngroup:\ngaode_node:\n    name: 逆地理\n    view: no\n    entities:\n      - sensor.x_loc\n\n\n\n\n\n```","x":250,"y":440,"wires":[]},{"id":"776a7172.13d7","type":"server-state-changed","z":"dc61884c.5c1728","name":"我的位置","server":"5d5b63f8.ca1c8c","entityidfilter":"device_tracker.xxx","entityidfiltertype":"substring","haltifstate":"","outputinitially":true,"x":140,"y":240,"wires":[["4e8ebb15.122a74"]]},{"id":"5d5b63f8.ca1c8c","type":"server","z":"","name":"8123","legacy":true}]
```



### 需要修改的配置

- 填写设备id(可同时连接多设备)
![](http://img.sonicming.top/201905061348_325.png)

- 填写ak&key

- 百度
    ![](http://img.sonicming.top/201905061349_233.png)
- 高德
    ![](http://img.sonicming.top/201905061350_211.png)

- MQTT地址(可不修改)
![](http://img.sonicming.top/201905061352_623.png)

- 如不修改MQTT订阅地址为
    - `baidu/location/设备名`
      如:device_tracker.xxx -> `baidu/location/xxx`
    - `gaode/location/设备名`


### Ha配置

- 百度

```yaml
sensor:
    - platform: mqtt
      name: "x_loc"
      state_topic: "baidu/location/设备名"
      value_template: "{{ value }}"
```

- 高德

```yaml
sensor:
    - platform: mqtt
      name: "x_loc"
      state_topic: "gaode/location/设备名"
      value_template: "{{ value }}"
```


### 配置附件



### 存在问题

​      可能存在偏移,也不知道什么情况.







咸味土豆 发表于 2019-5-6 14:42:24

大侠出手了,nodered好评,标记备用。

令狐鸣 发表于 2019-5-6 14:47:11

咸味土豆 发表于 2019-5-6 14:42
大侠出手了,nodered好评,标记备用。

nodered还是方便:lol

xieahui 发表于 2019-5-6 14:49:27

先顶后看

咸味土豆 发表于 2019-5-6 15:10:26

令狐鸣 发表于 2019-5-6 14:47
nodered还是方便

我也要玩,感觉是时候了。

xieahui 发表于 2019-5-6 15:25:11

我感觉我可以尝试下! 做到喊天猫精灵……
你好天猫:老婆在哪里
如果在家就报 在家
如果在公司就报 在公司
如果不在这两个地方就报 逆地理位置……

令狐鸣 发表于 2019-5-6 15:35:48

xieahui 发表于 2019-5-6 15:25
我感觉我可以尝试下! 做到喊天猫精灵……
你好天猫:老婆在哪里
如果在家就报 在家


这个可以,哈哈.
可以直接加个节点判断payload是否等于home,
不等于再走逆地理,
等于直接返回"在家"

a439771597 发表于 2019-5-6 19:33:17

nodered好,标记备用,感谢分享

houhd 发表于 2019-5-7 00:43:36

请让我仰视一下。今天太晚了,明天好好来看。

sasukebinbin 发表于 2019-5-7 23:29:19

楼主好厉害,多多学习
页: [1] 2 3 4 5
查看完整版本: 百度/高德逆地理-获取位置信息同步HA