neilenns / node-deepstackai-trigger

Detects motion using Deepstack AI and calls registered triggers based on trigger rules.
MIT License
167 stars 28 forks source link

Feature Request: Use MQTT to Trigger BlueIris #151

Closed rohankapoorcom closed 4 years ago

rohankapoorcom commented 4 years ago

Due to how I've partitioned my network, my blueiris web interface is not locally accessible without going through a reverse proxy that enforces SSO (single sign on).

BlueIris can however take the same web request commands over MQTT. See https://www.reddit.com/r/BlueIris/comments/eaemq1/mqtt_commands_recognize_by_blueiris/

Would you be open to adding support for them / open to a PR that adds support for sending the trigger commands via MQTT?

neilenns commented 4 years ago

MQTT events can already get sent, see https://github.com/danecreekphotography/node-deepstackai-trigger/wiki/Defining-triggers#defining-mqtt-handlers

What additional properties would need to go in the event to trigger the camera? The camera name?

neilenns commented 4 years ago

Ah, I see on their release notes. Yeah, sure, this should be pretty easy. The system already supports registering multiple MQTT topics for a single trigger so you can put a dedicated topic on each camera for the MQTT event.

I'm going to add mustache template support to handle #148 so it'd be easy enough to just use that. I'll probably get this done tonight, thanks for the idea!

rohankapoorcom commented 4 years ago

Fantastic! Thanks @danecreekphotography

neilenns commented 4 years ago

And I lied, it doesn't support multiple topics on a single trigger. Guess I'll have to fix that!

rohankapoorcom commented 4 years ago

Hah! Let me know if you want me to review or try it out before you release.

neilenns commented 4 years ago

Yeah I will, I'll make a Docker image on hub.docker.com that points to the branch. Should have something for you to try later today!

neilenns commented 4 years ago

Ok this is ready for you to test out @rohankapoorcom. The docker image tag is danecreekphotography/node-deepstackai-trigger:issue151. I assume you know how to pull that down but if not let me know.

Add this to your trigger.conf for each trigger that should send MQTT that BlueIris understands:

        "mqtt": {
          "topic": "BlueIris/admin",
          "payload": "camera=FrontDoorSD&trigger",
          "offDelay": 0
        },

You can replace the camera name with whatever your camera name is. Note that offDelay is there to prevent a status off message getting sent on that topic since BlueIris won't understand it.

If you really want I did get mustache templates wired in although it turns out not to be necessary for this feature request. For example you could use this for the payload and it would work as well:

          "payload": "camera={{name}}&trigger",

{{name}} gets replaced with the trigger's name property.

Please let me know how it works out!

rohankapoorcom commented 4 years ago

Hmm - I have been trying to test it but I'm not getting anything from the detector. There is nothing getting published to mqtt. Is there a way to check what Deepstack AI is detecting?

MQTT is connecting

2020-06-09T17:11:46-07:00 [MQTT manager] Loaded configuration from /config/mqtt.json,
2020-06-09T17:11:46-07:00 [MQTT Manager] Connected to MQTT server mqtt://REDACTED

Sample log line: 2020-06-09T17:12:15-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_171214566.jpg: Analyzing

triggers.json snippet:

{
      "name": "Front Door Detector",
      "watchPattern": "/aiinput/FrontDoor*.jpg",
      "enabled": true,
      "handlers": {
        "mqtt": {
          "topic": "BlueIris/admin",
          "payload": "camera=FrontDoorHD&trigger",
          "offDelay": 0
        },
      },
      "watchObjects": ["person", "dog"]
    },
neilenns commented 4 years ago

You can look at the logs for the deepstack ai docker container and see what it says. Was this working for you before this change?

rohankapoorcom commented 4 years ago

I'm not sure if it was working before since I had no triggers setup yet. Yesterday I was working on getting data in to it and today I was working on getting the results out.

The logs in deepstack-ai seem rather empty:

/v1/vision/detection,
---------------------------------------,
v1/vision/addmodel,
---------------------------------------,
v1/vision/listmodels,
---------------------------------------,
v1/vision/deletemodel,
---------------------------------------,
---------------------------------------,,
p,
---------------------------------------,
v1/restore,

I'm fairly sure that this container is able to communicate with the deepstack-ai container over it's docker bridge network. When it wasn't, it clearly failed to start up.

Any ideas where to look next?

neilenns commented 4 years ago

You'll know the AI detection is getting called when you see logs like this in its log output:

[GIN] 2020/06/10 - 01:19:06 | 200 | 884.0362ms | 172.25.0.3 | POST /v1/vision/detection

From your comment on #144 I assume you've set up each image (deepstackai and node-deepstackai-trigger) independently? My guess is the port isn't exposed properly for the deepstackai container, although I'm surprised an error for that isn't showing in the trigger container's logs.

Is it possible to try running things using docker-compose instead of Portainer? It's a pretty much guaranteed way of spinning up the two images in a way that communication can flow between them without issue.

neilenns commented 4 years ago

@rohankapoorcom I installed Portainer and I have to admit it's rather overcomplicated 😂 I can't figure out how to properly mount volumes but what I can suggest is make sure that you have a Stack configured that has both the deepstackai container and the container image in it. As best I can figure out Portainer's Stack concept maps exactly to docker compose, and gets the two images containers running together with guaranteed ability to communicate with each other.

I created a stack using a modified version of the docker-compose.yaml file, setting the version to 2 and removing all of the secrets stuff (not supported in v2 of docker compose). The only issue I had at that point is I couldn't figure out how to tell Portainer to use my local folders for aiinput (mounts to /aiinput) and the config file directory (must mount to /config).

rohankapoorcom commented 4 years ago

@danecreekphotography - Can you provide a copy of your test docker-compose.yaml.

I did not end up creating a stack in portainer yet. I did manually create my volumes (they're backed by a samba share) and then manually created a custom bridge network for communication between the containers and then created the containers.

My guess is the port isn't exposed properly for the deepstackai container, although I'm surprised an error for that isn't showing in the trigger container's logs.

When I had the the network between the two containers misconfigured, I was getting an error. Once I switched to using my own bridge network between them, the error went away.

neilenns commented 4 years ago

I got this up and running in Portainer. You need to create a Stack that has both containers in it otherwise the network communication will be a royal pain in the ass.

The sample config I provide for docker-compose.yaml is available here: https://github.com/danecreekphotography/node-blueiris-deepstack-ai/blob/master/sampleConfiguration/docker-compose.yml. My whole goal behind providing a docker-compose.yaml file and recommending the docker-compose command line is it guarantees both containers run together and can see each other with no networking heartache.

Here's the file I pasted into the Portainer new stack UI, which is essentially the same as the sample above except modified to be version 2 and use mount points instead of secrets.

version: "2"
services:
  trigger:
    volumes:
      # Change ./path_to_local_ai_images_folder to point to the folder that
      # will have the images to analyze
      - ./path_to_local_ai_images_folder:/aiinput
      - ./config:/config

    environment:
      # Change this to match the timezone the images are produced in,
      # Typically this will be the timezone of the machine running
      # the Docker container. For a list of valid timezone values
      # see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
      # The value to use is in the "TZ database name" column.
      - TZ=America/Los_Angeles
      # This is pre-configured for service-to-service connectivity in
      # Docker. Don't change this unless there is a need to talk to an
      # external DeepStack server somewhere and you know what you are doing.
      - DEEPSTACK_URI=http://deepstack-ai:5000/
      # Comment this line out to disable verbose logging. Once the system is
      # running well the extra logging information really isn't necessary
      # and is nice to turn off.
      - VERBOSE=true

    # ------------------------------------------------------------------------
    # Don't change anything below this line unless you know what you are doing
    image: danecreekphotography/node-deepstackai-trigger:latest
    restart: always
    depends_on:
      - deepstack-ai

  deepstack-ai:
    image: deepquestai/deepstack:latest
    restart: always
    volumes:
      - localstorage:/datastore
    environment:
      - VISION-DETECTION=True

volumes:
  localstorage:

Once the stack was created I went in to the trigger container and manually modified it to have the proper volume mounts from my local machine to Portainer. This too was a pain since there's basically no documentation of what the local path should be for Windows. I wound up with this: /run/desktop/mnt/host/d/git/node-deepstackai-trigger/sampleConfiguration.

Then it just worked... just like running docker-compose from a command line but with a whole lot more effort 😂

2020-06-09T18:57:11-07:00 [Trigger Cat detector] /aiinput/Cat_20200523-074700 - Copy.jpg: Analyzing
2020-06-09T18:57:13-07:00 [Trigger Cat detector] /aiinput/Cat_20200523-074700 - Copy.jpg: Found at least one object in the photo
2020-06-09T18:57:13-07:00 [Trigger Cat detector] /aiinput/Cat_20200523-074700 - Copy.jpg: Matched triggering object cat
2020-06-09T18:57:13-07:00 [Trigger Cat detector] /aiinput/Cat_20200523-074700 - Copy.jpg: Confidence 98.341376 wasn't between threshold 10 and 90
2020-06-09T18:57:13-07:00 [Trigger Cat detector] /aiinput/Cat_20200523-074700 - Copy.jpg: Not triggered by cat (98.341376)
neilenns commented 4 years ago

Note that the above uses the latest tag from Docker Hub. If you want to try the MQTT changes you'll need to point it to the issue151 tag.

rohankapoorcom commented 4 years ago

Hmmm - I was playing with this while waiting for your response and came up with the following docker-compose file. It looks basically the same except I've pointed my volumes for aiinput and config to their actual sources of data.

I get the same behavior as I was getting with the individually managed containers.

2020-06-09T19:04:28-07:00 [Main] Starting up version 1.7.0,
2020-06-09T19:04:28-07:00 [Main] Timezone offset is 420,
2020-06-09T19:04:28-07:00 [Main] Current time is Tue Jun 09 2020 19:04:28 GMT-0700 (Pacific Daylight Time),
2020-06-09T19:04:28-07:00 [Trigger Manager] Unable to read the configuration file: ENOENT: no such file or directory, open '/run/secrets/triggers'.,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration from /config/triggers.json,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Upper Driveway Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Driveway Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Lower Entrance Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Front Door Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Doorbell Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Patio Left Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Patio Right Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Balcony Left Detector,
2020-06-09T19:04:28-07:00 [Trigger manager] Loaded configuration for Balcony Center Detector,
2020-06-09T19:04:28-07:00 [MQTT Manager] Unable to read the configuration file: ENOENT: no such file or directory, open '/run/secrets/mqtt'.,
2020-06-09T19:04:28-07:00 [MQTT manager] Loaded configuration from /config/mqtt.json,
2020-06-09T19:04:28-07:00 [MQTT Manager] Connected to MQTT server mqtt://REDACTED,
2020-06-09T19:04:28-07:00 [Telegram Manager] Unable to read the Telegram configuration file: ENOENT: no such file or directory, open '/run/secrets/telegram'.,
2020-06-09T19:04:28-07:00 [Telegram Manager] Unable to read the Telegram configuration file: ENOENT: no such file or directory, open '/config/telegram.json'.,
2020-06-09T19:04:28-07:00 [Telegram Manager] Unable to find an Telegram configuration file. If Telegram was disabled in the Docker configuration then this warning can be safely ignored. Otherwise it means something is wrong with how the container is configured. Verify the telegram secret points to a file called telegram.json or that the /config mount point contains a file called telegram.json.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] Listening for new images in /aiinput/UpperDriveway*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] Listening for new images in /aiinput/Driveway*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Lower Entrance Detector] Listening for new images in /aiinput/LowerEntrance*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Front Door Detector] Listening for new images in /aiinput/FrontDoor*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Doorbell Detector] Listening for new images in /aiinput/Doorbell*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Patio Left Detector] Listening for new images in /aiinput/PatioLeft*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Patio Right Detector] Listening for new images in /aiinput/PatioRight*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Balcony Left Detector] Listening for new images in /aiinput/BalconyLeft*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] Listening for new images in /aiinput/BalconyCenter*.jpg,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_113801649.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_181138669.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_181625340.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_181630375.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_182036876.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_182041876.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_182046876.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_182051876.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_182056876.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_184814591.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_184819598.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_185435223.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_190544023.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Lower Entrance Detector] /aiinput/LowerEntranceSD.20200609_182039566.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Lower Entrance Detector] /aiinput/LowerEntranceSD.20200609_182044584.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_190306713.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_190311713.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Patio Left Detector] /aiinput/PatioLeftSD.20200609_184359920.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Patio Left Detector] /aiinput/PatioLeftSD.20200609_184404930.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Patio Right Detector] /aiinput/PatioRightSD.20200609_184141456.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Patio Right Detector] /aiinput/PatioRightSD.20200609_184146482.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Patio Right Detector] /aiinput/PatioRightSD.20200609_184356057.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_182038042.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_182043042.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_182048042.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_182053042.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_185436742.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_113845795.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184056253.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184101253.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184107253.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184112253.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184406453.jpg: Skipping as it was created before the service started.,
2020-06-09T19:04:28-07:00 [Trigger Balcony Center Detector] /aiinput/BalconyCenterSD.20200609_184411453.jpg: Skipping as it was created before the service started.,
2020-06-09T19:08:53-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_190852800.jpg: Analyzing,
2020-06-09T19:08:54-07:00 [Trigger Driveway Detector] /aiinput/DrivewaySD.20200609_190853742.jpg: Analyzing,
2020-06-09T19:08:58-07:00 [Trigger Upper Driveway Detector] /aiinput/UpperDrivewaySD.20200609_190857800.jpg: Analyzing,
2020-06-09T19:16:51-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_191651373.jpg: Analyzing,
2020-06-09T19:16:57-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_191656373.jpg: Analyzing,
2020-06-09T19:17:02-07:00 [Trigger Front Door Detector] /aiinput/FrontDoorSD.20200609_191701373.jpg: Analyzing,
version: "2"
services:
  trigger:
    volumes:
      - /var/lib/docker/volumes/blueiris-aiinput/_data:/aiinput
      - /var/lib/docker/volumes/deepstack-ai-blueiris-trigger-config/_data:/config

    environment:
      - TZ=America/Los_Angeles
      - DEEPSTACK_URI=http://deepstack-ai-testing:5000/
      - VERBOSE=true

    # ------------------------------------------------------------------------
    # Don't change anything below this line unless you know what you are doing
    image: danecreekphotography/node-deepstackai-trigger:latest
    restart: always
    depends_on:
      - deepstack-ai-testing

  deepstack-ai-testing:
    image: deepquestai/deepstack:latest
    restart: always
    volumes:
      - localstorage:/datastore
    environment:
      - VISION-DETECTION=True

volumes:
  localstorage:

I'm reasonably sure at this point that the problem isn't coming from how I'm using portainer, but rather something else.

rohankapoorcom commented 4 years ago

I thought maybe the problem was that I renamed the deepstack-ai services in the stack editor, so I tried again with this config and got exactly the same behavior. It says analyzing and then nothing further.

version: "2"
services:
  trigger:
    volumes:
      - blueiris-aiinput:/aiinput
      - deepstack-ai-blueiris-trigger-config:/config

    environment:
      - TZ=America/Los_Angeles
      - DEEPSTACK_URI=http://deepstack-ai:5000/
      # Comment this line out to disable verbose logging. Once the system is
      # running well the extra logging information really isn't necessary
      # and is nice to turn off.
      - VERBOSE=true

    # ------------------------------------------------------------------------
    # Don't change anything below this line unless you know what you are doing
    image: danecreekphotography/node-deepstackai-trigger:latest
    restart: always
    depends_on:
      - deepstack-ai

  deepstack-ai:
    image: deepquestai/deepstack:latest
    restart: always
    volumes:
      - localstorage:/datastore
    environment:
      - VISION-DETECTION=True

volumes:
  localstorage:
    external: true
neilenns commented 4 years ago

I think you're hitting the same issue others have faced using the AI Tool: your CPU doesn't support AVX. What computer and OS are you running this on?

Try changing the deepstack container to use the deepquestai/deepstack:noavx image and see if that works better.

Oooooh also, have you activated Deepstack with an activation key? You might have to do that too, see https://deepstack.cc/support/installation/docker. I may have done that so long ago I forgot about it and might have to add it to install instructions.

rohankapoorcom commented 4 years ago

Thanks @danecreekphotography!!!!! That was it. I had recently gotten rid of my Dell R710 (replaced with an R720) and had not bumped up my VMware EVC level to account for that. Bumping it up to "Intel Ivy Bridge" and rebooting the docker vm and rebuilding the stack with portainer seems to have sorted it out.

Amazingly, both instances are now working correctly (the stack version and the non stack version). I've switched to the stack version (which is the one I actually want to be using in the long run).

I've confirmed that the tag issue151 is working as expected.

Thanks for building out the new feature so quickly and for working with me to make sure everything works :) I really appreciate the help!

neilenns commented 4 years ago

Excellent! I'll get this out under the "latest" image tag in a day or so, I have a bunch of other changes I want to bundle into that release because they'll wind up being breaking config file changes.

Until then if you want you can point to the "dev" tag to stay current with everything in the main branch.