-
-
Save okets/b2bdf3ba2ab96c27ad58274372298261 to your computer and use it in GitHub Desktop.
const mapData = msg.payload; | |
const _pixelSize = mapData.pixelSize; | |
let _robotXY = null; | |
for (let i = 0; i < mapData.entities.length; i++) { | |
if (mapData.entities[i].type == "robot_position") { | |
_robotXY = { | |
x: Math.floor(mapData.entities[i].points[0] / _pixelSize), | |
y: Math.floor(mapData.entities[i].points[1] / _pixelSize) | |
}; | |
break; | |
} | |
} | |
// Test Data | |
// _robotXY = { | |
// x: 1000, | |
// y: 1000 | |
// }; | |
const _nearestPoint = { | |
x: mapData.size.x, | |
y: mapData.size.y, | |
distance: Math.pow(mapData.size.x,2) + Math.pow(mapData.size.y,2), //Just a placeholder with the biggest distance possible | |
foundRoom:{ | |
segmentId: null, | |
name: null | |
} | |
} | |
if (mapData.metaData?.version === 2 && Array.isArray(mapData.layers)) { | |
mapData.layers.forEach(layer => { | |
if (layer.pixels.length === 0 && layer.compressedPixels.length !== 0 && layer.type == "segment") { | |
for (let i = 0; i < layer.compressedPixels.length; i = i + 3) { | |
const xStart = layer.compressedPixels[i]; | |
const y = layer.compressedPixels[i + 1] | |
const count = layer.compressedPixels[i + 2] | |
for (let j = 0; j < count; j++) { | |
let x = xStart + j; | |
let _distanceX = x - _robotXY.x; | |
let _distanceY = y - _robotXY.y; | |
//const _pointToRobotDistance = Math.sqrt(Math.pow(_distanceX, 2) + Math.pow(_distanceY, 2)); | |
const _pointToRobotDistance = Math.pow(_distanceX, 2) + Math.pow(_distanceY, 2);//sqrt is the "correct" trig function, but I only need to compare relative to other points, not exact distance, so I dropped the "sqrt" function for efficiancy | |
if (_nearestPoint.distance > _pointToRobotDistance){ | |
_nearestPoint.distance = _pointToRobotDistance; | |
_nearestPoint.x = x; | |
_nearestPoint.y = y; | |
_nearestPoint.foundRoom= { | |
segmentId: layer.metaData.segmentId, | |
name: layer.metaData.name | |
}; | |
} | |
if (_nearestPoint.distance==0) { | |
return; | |
} | |
} | |
} | |
} | |
}) | |
} | |
return _nearestPoint.foundRoom; |
@killone78, I wouldn't know where to start.
Your request sounds simple but it has some complexities.
My code isn't monitoring the robot's activity, it only tells you where it is at the moment you run it.
I can help you with guidelines:
- you should monitor the state of your robot.
- on any state change publish mqtt message with the location of the robot.
2.1) if the robot is in a moving state (not "docked"/"error"/"paused") publish the position in a regular interval (5 sec. Seems fine)
2.2) if its not moving, stop the interval.
In my opinion, it would be easier to just write whatever automation you are trying to write in homeassistant directly in NodeRed.
It is a much better automation engine and it can work alongside homeassistant's automation engine, you don't have to transfer existing automations.
@carefulcomputer sorry for the delayed response. home with the flu... I uploaded my complete flow to this repo: https://github.com/okets/Valetudo-NodeRed-Extensions Feel free to add/change whatever you want.
This is so simple and brilliant thank you so much for this!
Thanks for the script! With the help of NodeRed I made a small automation to disable obstacle recognition in a certain segment, that the robot can't pass with it enabled.
@okets Thanks for info, but I find it really difficult to understand how to do it, I'm really a node-red noob...^_^; in the end what I would like to do is simply publish via mqtt "currentLocation" with "segmentId": and "name":
Even if it has nothing to do with the purpose of this topic, could you help me? Thank you so much :)