Home Assistant release with the issue: 0.88.1
Last working Home Assistant release (if known): Unknown
Operating environment (Hass.io/Docker/Windows/etc.): Python Virtual Environment - Centos 7
Component/platform: https://www.home-assistant.io/components/camera.local_file/
Description of problem:
Same issue as https://github.com/home-assistant/home-assistant/issues/14532
Node-RED calls to camera.local_file_update_file_path appears to only update the first camera updated.
Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):
camera:
- platform: local_file
name: "Carport"
file_path: /srv/homeassistant/.homeassistant/Blank.jpg
- platform: local_file
name: "Master Bath Door"
file_path: /srv/homeassistant/.homeassistant/Blank.jpg
- platform: local_file
name: "Drive Gate"
file_path: /srv/homeassistant/.homeassistant/Blank.jpg
- platform: local_file
name: "Front Door"
file_path: /srv/homeassistant/.homeassistant/Blank.jpg
Traceback (if applicable):
Additional information:
Here is the Node-RED flow making the call:
[
{
"id": "5bb78d64.9c6cc4",
"type": "change",
"z": "149e5773.99ecf9",
"name": "Set Filename",
"rules": [
{
"t": "set",
"p": "filename",
"pt": "msg",
"to": "topic",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 510,
"y": 140,
"wires": [
[
"11c03854.6c2e38",
"371f061e.7c91ba"
]
]
},
{
"id": "11c03854.6c2e38",
"type": "string",
"z": "149e5773.99ecf9",
"name": "Generate Image Filename",
"methods": [
{
"name": "getRightMost",
"params": [
{
"type": "str",
"value": "/"
}
]
},
{
"name": "replaceAll",
"params": [
{
"type": "str",
"value": " "
},
{
"type": "str",
"value": "_"
}
]
},
{
"name": "ensureLeft",
"params": [
{
"type": "str",
"value": "/srv/homeassistant/.homeassistant/www/"
}
]
}
],
"prop": "filename",
"propout": "filename",
"object": "msg",
"objectout": "msg",
"x": 730,
"y": 140,
"wires": [
[
"18c00627.ec3f2a"
]
]
},
{
"id": "18c00627.ec3f2a",
"type": "file",
"z": "149e5773.99ecf9",
"name": "Save Image",
"filename": "",
"appendNewline": false,
"createDir": false,
"overwriteFile": "true",
"x": 950,
"y": 140,
"wires": [
[]
]
},
{
"id": "cf763c92.0d785",
"type": "string",
"z": "149e5773.99ecf9",
"name": "Determine Camera",
"methods": [
{
"name": "getRightMost",
"params": [
{
"type": "str",
"value": "/"
}
]
},
{
"name": "delRightMost",
"params": [
{
"type": "str",
"value": "_01"
}
]
},
{
"name": "replaceAll",
"params": [
{
"type": "str",
"value": " "
},
{
"type": "str",
"value": "_"
}
]
}
],
"prop": "topic",
"propout": "camera",
"object": "msg",
"objectout": "msg",
"x": 310,
"y": 140,
"wires": [
[
"5bb78d64.9c6cc4"
]
]
},
{
"id": "e9ca92a.32b557",
"type": "api-call-service",
"z": "149e5773.99ecf9",
"name": "Update Camera Filename",
"server": "bd0ac36a.ed0df",
"service_domain": "camera",
"service": "local_file_update_file_path",
"data": "{\"entity_id\":\"camera.{{camera}}\",\"file_path\":\"/srv/homeassistant/.homeassistant/www/{{filename}}\"}",
"render_data": true,
"mergecontext": "",
"output_location": "",
"output_location_type": "none",
"x": 990,
"y": 200,
"wires": [
[]
]
},
{
"id": "371f061e.7c91ba",
"type": "string",
"z": "149e5773.99ecf9",
"name": "Generate Image Filename",
"methods": [
{
"name": "getRightMost",
"params": [
{
"type": "str",
"value": "/"
}
]
},
{
"name": "replaceAll",
"params": [
{
"type": "str",
"value": " "
},
{
"type": "str",
"value": "_"
}
]
}
],
"prop": "filename",
"propout": "filename",
"object": "msg",
"objectout": "msg",
"x": 730,
"y": 200,
"wires": [
[
"e9ca92a.32b557",
"e7d2eab8.a7d658"
]
]
},
{
"id": "e7d2eab8.a7d658",
"type": "debug",
"z": "149e5773.99ecf9",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 930,
"y": 260,
"wires": []
},
{
"id": "bd0ac36a.ed0df",
"type": "server",
"z": "",
"name": "Home Assistant",
"legacy": false,
"hassio": false,
"rejectUnauthorizedCerts": true,
"ha_boolean": "y|yes|true|on|home|open"
}
]
One example of a payload (truncated):
{
"topic":"/2019/02/23/Drive Gate_01_20190223220623.jpg",
"payload":[ ],
"_msgid":"e0ce20cf.465a2",
"camera":"Drive_Gate",
"filename":"Drive_Gate_01_20190223220623.jpg"
}
Second example with a different camera (truncated):
{
"topic":"/2019/02/23/Carport_01_20190223220626.jpg",
"payload":[ ],
"_msgid":"5f2eb03b.04e01",
"camera":"Carport",
"filename":"Carport_01_20190223220626.jpg"
}
Both examples updated the camera.drive_gate.file_path
@Landrash Something you can help with?
The component was rewritten after my contribution so I'm not of any help.
Just viewing the example I would try to replicate it on a simpler basis to do some further testing without Node Red since this isn't a setup I even imagined .
I did a bit more debugging; it's pretty simple to reproduce.
local_filecameras, each with a unique pathCAMERA.LOCAL_FILE_UPDATE_FILE_PATH, specifying the first camera and a new file path--it will be updated as expected.CAMERA.LOCAL_FILE_UPDATE_FILE_PATH, specifying the second camera and a secondary file path--the first camera path is updated with the file path in the second call.The problem seems to be related to the following code:
def update_file_path_service(call):
"""Update the file path."""
file_path = call.data.get(CONF_FILE_PATH)
camera.update_file_path(file_path)
return True
In the context, the camera object is not related in any way to the entity_id in the call. I know almost nothing about coding in HASS but I did do a fair amount of debugging and once the first call came through to update a file path, that was the camera that was updated each time thereafter, no matter which entity_idwas specified.
Blame @robmarkcole
Hello,
I reproduct this bug.
i'm Update file_path by API.
curl -X POST -H "Authorization: Bearer xxxxx " -H "Content-Type: application/json" -d '{"entity_id": "camera.2cam", "file_path": "/home/homeassistant/.homeassistant/www/cameras/cam1/01_20190308090536.jpg"}' https://xxxx:8123/api/services/camera/local_file_update_file_path
Result :
[{"attributes": {"access_token": "xxxx", "entity_picture": "/api/camera_proxy/camera.1cam?token=xxxx", "file_path": "/home/homeassistant/.homeassistant/www/cameras/cam1/01_20190308090536.jpg", "friendly_name": "1cam", "supported_features": 0}, "context": {"id": "da1d219fa63d4ccbbd7ebf6d9208fcd5", "parent_id": null, "user_id": null}, "entity_id": "camera.1cam", "last_changed": "2019-03-27T22:21:12.353680+00:00", "last_updated": "2019-03-27T22:22:23.731442+00:00", "state": "idle"}]
In result entity_id is camera.1cam and not camera.2cam send in POST
Regards
@robmarkcole Are there any plans to look into this issue? It's simple to reproduce at this point. Obviously, I have no idea how complex it is to fix outside knowing it's beyond my capabilities.
If not, I get it; however, having this work would make dealing with multiple camera feeds and Tensorflow much easier when motion is handled externally and just a static JPEG is being handed off.
Thanks for your attention.
@ratsputin I had a quick look, and don't see anything obvious. I could easily spend half to a full day chasing and fixing this and I just don't have the bandwidth at the moment.
@robmarkcole Thanks so much for taking a quick look at this. You saved me beating my head against the wall trying to track down the issue with my limited knowledge. I'll work around this with a more brute-force method.
Cheers!
Proposed solution: check camera.entity_id before update.
UPDATE: done this and discovered that the camera.entity_id attr is NOT CORRECT when I have multiple cameras. Below I call the service with data for camera.local_file, _2, _3 but the camera.entity_id is ALWAYS camera.local_file_3
2019-04-27 16:21:48 WARNING (SyncWorker_18) [homeassistant.components.local_file.camera] XXX UPDATE ENTITY: ['camera.local_file']
2019-04-27 16:21:48 WARNING (SyncWorker_18) [homeassistant.components.local_file.camera] XXX camera.entity_id : camera.local_file_3
2019-04-27 16:25:53 WARNING (SyncWorker_19) [homeassistant.components.local_file.camera] XXX UPDATE ENTITY: ['camera.local_file_2']
2019-04-27 16:25:53 WARNING (SyncWorker_19) [homeassistant.components.local_file.camera] XXX camera.entity_id : camera.local_file_3
2019-04-27 16:26:04 WARNING (SyncWorker_6) [homeassistant.components.local_file.camera] XXX UPDATE ENTITY: ['camera.local_file_3']
2019-04-27 16:26:04 WARNING (SyncWorker_6) [homeassistant.components.local_file.camera] XXX camera.entity_id : camera.local_file_3
2019-04-27 16:26:04 WARNING (SyncWorker_6) [homeassistant.components.local_file.camera] updating entity XXX
The service should get the correct camera object like here, can reuse facebox approach
OK the following appears to resolve this issue:
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Camera that works with local files."""
if DATA_LOCAL_FILE not in hass.data:
hass.data[DATA_LOCAL_FILE] = []
file_path = config[CONF_FILE_PATH]
camera = LocalFile(config[CONF_NAME], file_path)
hass.data[DATA_LOCAL_FILE].append(camera)
def update_file_path_service(call):
"""Update the file path."""
file_path = call.data.get(CONF_FILE_PATH)
entity_ids = call.data.get(ATTR_ENTITY_ID)
cameras = hass.data[DATA_LOCAL_FILE]
for camera in cameras:
if camera.entity_id in entity_ids:
camera.update_file_path(file_path)
return True
All changes here @ratsputin can you try this modified file?
@robmarkcole Yes, this is brilliant! It absolutely fixed the issue; thanks so much!
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 馃憤
This issue now has been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.