mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
Coy Cobra
This commit is contained in:
parent
157bf6feb0
commit
c8b67c57b4
45 changed files with 3076 additions and 144 deletions
5
plugins/python-yolo/.gitignore
vendored
Normal file
5
plugins/python-yolo/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
conf.json
|
||||
cascades
|
||||
cfg
|
||||
weights
|
||||
data
|
109
plugins/python-yolo/INSTALL.sh
Normal file
109
plugins/python-yolo/INSTALL.sh
Normal file
|
@ -0,0 +1,109 @@
|
|||
#!/bin/bash
|
||||
echo "-----------------------------------------------"
|
||||
echo "-- Installing Python Yolo Plugin for Shinobi --"
|
||||
echo "-----------------------------------------------"
|
||||
echo "-----------------------------------"
|
||||
if [ ! -d "weights" ]; then
|
||||
echo "Downloading yolov3 weights..."
|
||||
mkdir weights
|
||||
wget -O weights/yolov3.weights https://pjreddie.com/media/files/yolov3.weights
|
||||
else
|
||||
echo "yolov3 weights found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if [ ! -d "cfg" ]; then
|
||||
echo "Downloading yolov3 cfg"
|
||||
mkdir cfg
|
||||
wget -O cfg/coco.data https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/coco.data
|
||||
wget -O cfg/yolov3.cfg https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg
|
||||
else
|
||||
echo "yolov3 cfg found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if [ ! -d "data" ]; then
|
||||
echo "Downloading yolov3 data"
|
||||
mkdir data
|
||||
wget -O data/coco.names https://raw.githubusercontent.com/pjreddie/darknet/master/data/coco.names
|
||||
else
|
||||
echo "yolov3 data found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if [ ! -e "./conf.json" ]; then
|
||||
echo "Creating conf.json"
|
||||
sudo cp conf.sample.json conf.json
|
||||
else
|
||||
echo "conf.json already exists..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
sudo apt update -y
|
||||
sudo apt-get install libxml2-dev libxslt-dev libxslt1-dev zlib1g-dev -y
|
||||
echo "Installing python3"
|
||||
sudo apt install python3 python3-dev python3-pip -y
|
||||
sudo apt install python3-lxml libxml2-dev -y
|
||||
echo "-----------------------------------"
|
||||
if ! [ -x "$(command -v gcc-6)" ]; then
|
||||
echo "Installing gcc-6 and g++-6"
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
sudo apt-get install gcc-6 g++-6 -y && sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6
|
||||
else
|
||||
echo "gcc-6 and g++-6 found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if ! [ -x "$(command -v nvidia-smi)" ]; then
|
||||
echo "You need to install NVIDIA Drivers to use this."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/cuda9-part1.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "NVIDIA Drivers found..."
|
||||
echo "$(nvidia-smi |grep 'Driver Version')"
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if [ ! -d "/usr/local/cuda" ]; then
|
||||
echo "You need to install CUDA Toolkit to use this."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/cuda9-part2-after-reboot.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "CUDA Toolkit found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if ! [ -x "$(command -v opencv_version)" ]; then
|
||||
echo "You need to install OpenCV with CUDA first."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/opencv-cuda.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "OpenCV found... : $(opencv_version)"
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
echo "Getting new pip..."
|
||||
pip3 install --upgrade pip
|
||||
pip install --user --upgrade pip
|
||||
echo "Smoking pips..."
|
||||
pip3 install flask_socketio
|
||||
pip3 install flask
|
||||
pip3 install numpy
|
||||
pip3 install gevent gevent-websocket
|
||||
export PATH=/usr/local/cuda/bin:$PATH
|
||||
pip3 install lxml
|
||||
pip3 install numpy
|
||||
pip3 install cython
|
||||
echo "Installing Darknet..."
|
||||
cd /opt
|
||||
git clone https://github.com/pjreddie/darknet.git darknet
|
||||
cd darknet
|
||||
make
|
||||
cd ..
|
||||
echo "Installing YOLO3-4-Py"
|
||||
echo "Learn more about this wrapper here : https://github.com/madhawav/YOLO3-4-Py"
|
||||
git clone https://github.com/madhawav/YOLO3-4-Py.git YOLO3-4-Py
|
||||
cd YOLO3-4-Py
|
||||
export GPU=1
|
||||
export OPENCV=1
|
||||
pip3 install .
|
||||
apt remove libpython-all-dev python-all python-all-dev python-asn1crypto python-cffi-backend python-crypto python-cryptography python-dbus python-enum34 python-gi python-idna python-ipaddress python-keyring python-keyrings.alt python-pkg-resources python-secretstorage python-setuptools python-six python-wheel python-xdg -y
|
||||
echo "Done Installing Darknet..."
|
||||
export PATH=/opt/darknet:$PATH
|
||||
echo "Start the plugin with pm2 like so :"
|
||||
echo "pm2 start shinobi-python-yolo.js"
|
72
plugins/python-yolo/README.md
Normal file
72
plugins/python-yolo/README.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Python Yolo
|
||||
|
||||
> This plugin requires the use of port `7990` by default. You can specify a different port by adding `pythonPort` to your plugin's conf.json.
|
||||
|
||||
**Ubuntu and Debian only**
|
||||
|
||||
Go to the Shinobi directory. **/home/Shinobi** is the default directory.
|
||||
|
||||
```
|
||||
cd /home/Shinobi/plugins/python-yolo
|
||||
```
|
||||
|
||||
Copy the config file.
|
||||
|
||||
```
|
||||
sh INSTALL.sh
|
||||
```
|
||||
|
||||
Start the plugin.
|
||||
|
||||
```
|
||||
pm2 start shinobi-python-yolo.js
|
||||
```
|
||||
|
||||
Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped.
|
||||
|
||||
## Run the plugin as a Host
|
||||
> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes.
|
||||
|
||||
Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`.
|
||||
|
||||
```
|
||||
nano conf.json
|
||||
```
|
||||
|
||||
Here is a sample of a Host configuration for the plugin.
|
||||
- `plug` is the name of the plugin corresponding in the main configuration file.
|
||||
- `https` choose if you want to use SSL or not. Default is `false`.
|
||||
- `hostPort` can be any available port number. **Don't make this the same port number as Shinobi.** Default is `8082`.
|
||||
- `type` tells the main application (Shinobi) what kind of plugin it is. In this case it is a detector.
|
||||
|
||||
```
|
||||
{
|
||||
"plug":"PythonYolo",
|
||||
"hostPort":8082,
|
||||
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode":"host",
|
||||
"type":"detector"
|
||||
}
|
||||
```
|
||||
|
||||
Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.*
|
||||
|
||||
```
|
||||
nano conf.json
|
||||
```
|
||||
|
||||
Add the `plugins` array if you don't already have it. Add the following *object inside the array*.
|
||||
|
||||
```
|
||||
"plugins":[
|
||||
{
|
||||
"id" : "PythonYolo",
|
||||
"https" : false,
|
||||
"host" : "localhost",
|
||||
"port" : 8082,
|
||||
"key" : "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode" : "host",
|
||||
"type" : "detector"
|
||||
}
|
||||
],
|
||||
```
|
1
plugins/python-yolo/bootPy.sh
Normal file
1
plugins/python-yolo/bootPy.sh
Normal file
|
@ -0,0 +1 @@
|
|||
python3 -u $@
|
10
plugins/python-yolo/conf.sample.json
Normal file
10
plugins/python-yolo/conf.sample.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plug":"PythonYolo",
|
||||
"host":"localhost",
|
||||
"port":8080,
|
||||
"pythonPort":7990,
|
||||
"hostPort":8082,
|
||||
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode":"client",
|
||||
"type":"detector"
|
||||
}
|
14
plugins/python-yolo/download-weights.sh
Normal file
14
plugins/python-yolo/download-weights.sh
Normal file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading config files..."
|
||||
|
||||
mkdir cfg
|
||||
wget -O cfg/coco.data https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/coco.data
|
||||
wget -O cfg/yolov3.cfg https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg
|
||||
|
||||
mkdir data
|
||||
wget -O data/coco.names https://raw.githubusercontent.com/pjreddie/darknet/master/data/coco.names
|
||||
|
||||
echo "Downloading yolov3 weights"
|
||||
mkdir weights
|
||||
wget -O weights/yolov3.weights https://pjreddie.com/media/files/yolov3.weights
|
18
plugins/python-yolo/package.json
Normal file
18
plugins/python-yolo/package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "shinobi-python-yolo",
|
||||
"version": "1.0.0",
|
||||
"description": "YOLOv3 plugin for Shinobi that uses Python functions for detection.",
|
||||
"main": "shinobi-python-yolo.js",
|
||||
"dependencies": {
|
||||
"socket.io-client": "^1.7.4",
|
||||
"express": "^4.16.2",
|
||||
"moment": "^2.19.2",
|
||||
"socket.io": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Moe Alam",
|
||||
"license": "ISC"
|
||||
}
|
103
plugins/python-yolo/pumpkin.py
Normal file
103
plugins/python-yolo/pumpkin.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
from flask import Flask, request, jsonify, render_template
|
||||
from flask_socketio import SocketIO, emit
|
||||
from pydarknet import Detector, Image
|
||||
import cv2
|
||||
import os
|
||||
import json
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
dirname = sys.argv[1]
|
||||
|
||||
try:
|
||||
with open("{}/conf.json".format(dirname)) as json_file:
|
||||
config = json.load(json_file)
|
||||
httpPort = config['pythonPort']
|
||||
try:
|
||||
httpPort
|
||||
except NameError:
|
||||
httpPort = 7990
|
||||
except Exception as e:
|
||||
print("conf.json not found.")
|
||||
httpPort = 7990
|
||||
|
||||
# Load Flask
|
||||
app = Flask("YOLOv3 for Shinobi (Pumpkin Pie)")
|
||||
socketio = SocketIO(app)
|
||||
# Silence Flask
|
||||
import logging
|
||||
log = logging.getLogger('werkzeug')
|
||||
log.setLevel(logging.ERROR)
|
||||
|
||||
# Load Darknet
|
||||
net = Detector(bytes("{}/cfg/yolov3.cfg".format(dirname), encoding="utf-8"), bytes("{}/weights/yolov3.weights".format(dirname), encoding="utf-8"), 0, bytes("{}/cfg/coco.data".format(dirname),encoding="utf-8"))
|
||||
|
||||
def spark(filepath):
|
||||
try:
|
||||
filepath
|
||||
except NameError:
|
||||
return "File path not found."
|
||||
img = cv2.imread(filepath)
|
||||
|
||||
img2 = Image(img)
|
||||
|
||||
# r = net.classify(img2)
|
||||
results = net.detect(img2)
|
||||
returnData = '[]'
|
||||
try:
|
||||
new_list = []
|
||||
for item in results:
|
||||
sub_list = {}
|
||||
i = 0
|
||||
for sub_item in item:
|
||||
if i == 0:
|
||||
key = 'tag'
|
||||
sub_list[key] = sub_item.decode('utf-8')
|
||||
if i == 1:
|
||||
key = 'confidence'
|
||||
sub_list[key] = sub_item
|
||||
if i == 2:
|
||||
key = 'points'
|
||||
points_list = []
|
||||
for points_item in sub_item:
|
||||
points_list.append(points_item)
|
||||
sub_list[key] = points_list
|
||||
i += 1
|
||||
new_list.append(sub_list)
|
||||
returnData = new_list
|
||||
# returnData = json.dumps(results)
|
||||
except Exception as e:
|
||||
returnData = ',\n'.join(map(str, results))
|
||||
|
||||
return returnData
|
||||
|
||||
# bake the image data by a file path
|
||||
# POST body contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/', methods=['GET'])
|
||||
def index():
|
||||
return "Pumpkin.py is running. This web interface should NEVER be accessible remotely. The Node.js plugin that runs this script should only be allowed accessible remotely."
|
||||
|
||||
# bake the image data by a file path
|
||||
# POST body contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/post', methods=['POST'])
|
||||
def post():
|
||||
filepath = request.form['img']
|
||||
return jsonify(spark(filepath))
|
||||
|
||||
# bake the image data by a file path
|
||||
# GET string contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/get', methods=['GET'])
|
||||
def get():
|
||||
filepath = request.args.get('img')
|
||||
return jsonify(spark(filepath))
|
||||
|
||||
@socketio.on('f')
|
||||
def receiveMessage(message):
|
||||
emit('f',{'id':message.get("id"),'data':spark(message.get("path"))})
|
||||
|
||||
# quick-and-dirty start
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, port=httpPort)
|
296
plugins/python-yolo/shinobi-python-yolo.js
Normal file
296
plugins/python-yolo/shinobi-python-yolo.js
Normal file
|
@ -0,0 +1,296 @@
|
|||
//
|
||||
// Shinobi - Python YOLOv3 Plugin
|
||||
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||
//
|
||||
// # Donate
|
||||
//
|
||||
// If you like what I am doing here and want me to continue please consider donating :)
|
||||
// PayPal : paypal@m03.ca
|
||||
//
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
//main vars
|
||||
var fs=require('fs');
|
||||
var exec = require('child_process').exec;
|
||||
var spawn = require('child_process').spawn;
|
||||
var moment = require('moment');
|
||||
var http = require('http');
|
||||
var express = require('express');
|
||||
var socketIoClient = require('socket.io-client');
|
||||
var config = require('./conf.json');
|
||||
var http = require('http'),
|
||||
app = express(),
|
||||
server = http.createServer(app);
|
||||
s={
|
||||
group:{},
|
||||
dir:{},
|
||||
isWin:(process.platform==='win32'),
|
||||
s:function(json){return JSON.stringify(json,null,3)}
|
||||
}
|
||||
s.checkCorrectPathEnding=function(x){
|
||||
var length=x.length
|
||||
if(x.charAt(length-1)!=='/'){
|
||||
x=x+'/'
|
||||
}
|
||||
return x.replace('__DIR__',__dirname)
|
||||
}
|
||||
s.debugLog = function(){
|
||||
if(config.debugLog === true){
|
||||
console.log(new Date(),arguments)
|
||||
if(config.debugLogVerbose === true){
|
||||
console.log(new Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!config.port){config.port=8080}
|
||||
if(!config.pythonScript){config.pythonScript=__dirname+'/pumpkin.py'}
|
||||
if(!config.pythonPort){config.pythonPort=7990}
|
||||
if(!config.hostPort){config.hostPort=8082}
|
||||
if(config.systemLog===undefined){config.systemLog=true}
|
||||
if(config.alprConfig===undefined){config.alprConfig=__dirname+'/openalpr.conf'}
|
||||
//default stream folder check
|
||||
if(!config.streamDir){
|
||||
if(s.isWin===false){
|
||||
config.streamDir='/dev/shm'
|
||||
}else{
|
||||
config.streamDir=config.windowsTempDir
|
||||
}
|
||||
if(!fs.existsSync(config.streamDir)){
|
||||
config.streamDir=__dirname+'/streams/'
|
||||
}else{
|
||||
config.streamDir+='/streams/'
|
||||
}
|
||||
}
|
||||
s.dir.streams=config.streamDir;
|
||||
//streams dir
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.getRequest = function(url,callback){
|
||||
return http.get(url, function(res){
|
||||
var body = '';
|
||||
res.on('data', function(chunk){
|
||||
body += chunk;
|
||||
});
|
||||
res.on('end',function(){
|
||||
try{body = JSON.parse(body)}catch(err){}
|
||||
callback(body)
|
||||
});
|
||||
}).on('error', function(e){
|
||||
// s.systemLog("Get Snapshot Error", e);
|
||||
});
|
||||
}
|
||||
s.multiplerHeight = 0.75
|
||||
s.multiplerWidth = 0.96
|
||||
s.detectObject=function(buffer,d,tx){
|
||||
d.tmpFile=s.gid(5)+'.jpg'
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||
if(err) return s.systemLog(err);
|
||||
if(s.isPythonRunning === false){
|
||||
return console.log('Python Script is not Running.')
|
||||
}
|
||||
var callbackId = s.gid(10)
|
||||
s.group[d.ke][d.id].sendToPython({path:d.dir+d.tmpFile,id:callbackId},function(data){
|
||||
if(data.length > 0){
|
||||
var mats=[]
|
||||
data.forEach(function(v){
|
||||
mats.push({
|
||||
x:v.points[0] * s.multiplerWidth,
|
||||
y:v.points[1] * s.multiplerHeight,
|
||||
width:v.points[2],
|
||||
height:v.points[3],
|
||||
confidence:v.confidence,
|
||||
tag:v.tag
|
||||
})
|
||||
})
|
||||
tx({
|
||||
f:'trigger',
|
||||
id:d.id,
|
||||
ke:d.ke,
|
||||
details:{
|
||||
plug:config.plug,
|
||||
name:'yolo',
|
||||
reason:'object',
|
||||
matrices:mats,
|
||||
imgHeight:d.mon.detector_scale_y,
|
||||
imgWidth:d.mon.detector_scale_x
|
||||
}
|
||||
})
|
||||
}
|
||||
delete(s.callbacks[callbackId])
|
||||
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||
})
|
||||
})
|
||||
}
|
||||
s.systemLog=function(q,w,e){
|
||||
if(w===undefined){return}
|
||||
if(!w){w=''}
|
||||
if(!e){e=''}
|
||||
if(config.systemLog===true){
|
||||
return console.log(moment().format(),q,w,e)
|
||||
}
|
||||
}
|
||||
s.MainEventController=function(d,cn,tx){
|
||||
switch(d.f){
|
||||
case'init_plugin_as_host':
|
||||
if(!cn){
|
||||
console.log('No CN',d)
|
||||
return
|
||||
}
|
||||
if(d.key!==config.key){
|
||||
console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d)
|
||||
cn.emit('init',{ok:false})
|
||||
cn.disconnect()
|
||||
}else{
|
||||
console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress)
|
||||
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||
}
|
||||
break;
|
||||
case'init_monitor':
|
||||
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
break;
|
||||
case'frame':
|
||||
try{
|
||||
if(!s.group[d.ke]){
|
||||
s.group[d.ke]={}
|
||||
}
|
||||
if(!s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id]={
|
||||
sendToPython : s.createCameraBridgeToPython(d.ke+d.id)
|
||||
}
|
||||
}
|
||||
if(!s.group[d.ke][d.id].buffer){
|
||||
s.group[d.ke][d.id].buffer=[d.frame];
|
||||
}else{
|
||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||
}
|
||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||
s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d,tx)
|
||||
s.group[d.ke][d.id].buffer=null;
|
||||
}
|
||||
}catch(err){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
server.listen(config.hostPort);
|
||||
//web pages and plugin api
|
||||
app.get('/', function (req, res) {
|
||||
res.end('<b>'+config.plug+'</b> for Shinobi is running')
|
||||
});
|
||||
//Conector to Shinobi
|
||||
if(config.mode==='host'){
|
||||
//start plugin as host
|
||||
var io = require('socket.io')(server);
|
||||
io.attach(server);
|
||||
s.connectedClients={};
|
||||
io.on('connection', function (cn) {
|
||||
s.connectedClients[cn.id]={id:cn.id}
|
||||
s.connectedClients[cn.id].tx = function(data){
|
||||
data.pluginKey=config.key;data.plug=config.plug;
|
||||
return io.to(cn.id).emit('ocv',data);
|
||||
}
|
||||
cn.on('f',function(d){
|
||||
s.MainEventController(d,cn,s.connectedClients[cn.id].tx)
|
||||
});
|
||||
cn.on('disconnect',function(d){
|
||||
delete(s.connectedClients[cn.id])
|
||||
})
|
||||
});
|
||||
}else{
|
||||
//start plugin as client
|
||||
if(!config.host){config.host='localhost'}
|
||||
var io = socketIoClient('ws://'+config.host+':'+config.port);//connect to master
|
||||
s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)}
|
||||
io.on('connect',function(d){
|
||||
s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type});
|
||||
})
|
||||
io.on('disconnect',function(d){
|
||||
io.connect();
|
||||
})
|
||||
io.on('f',function(d){
|
||||
s.MainEventController(d,null,s.cx)
|
||||
})
|
||||
}
|
||||
|
||||
//Start Python Controller
|
||||
s.callbacks = {}
|
||||
s.createCameraBridgeToPython = function(uniqueId){
|
||||
var pythonIo = socketIoClient('ws://localhost:'+config.pythonPort,{transports : ['websocket']});
|
||||
var sendToPython = function(data,callback){
|
||||
s.callbacks[data.id] = callback
|
||||
pythonIo.emit('f',data)
|
||||
}
|
||||
pythonIo.on('connect',function(d){
|
||||
s.debugLog(uniqueId+' is Connected from Python')
|
||||
})
|
||||
pythonIo.on('disconnect',function(d){
|
||||
s.debugLog(uniqueId+' is Disconnected from Python')
|
||||
setTimeout(function(){
|
||||
pythonIo.connect();
|
||||
s.debugLog(uniqueId+' is Attempting to Reconect to Python')
|
||||
},3000)
|
||||
})
|
||||
pythonIo.on('f',function(d){
|
||||
if(s.callbacks[d.id]){
|
||||
s.callbacks[d.id](d.data)
|
||||
delete(s.callbacks[d.id])
|
||||
}
|
||||
})
|
||||
return sendToPython
|
||||
}
|
||||
|
||||
|
||||
//Start Python Daemon
|
||||
process.env.PYTHONUNBUFFERED = 1;
|
||||
s.createPythonProcess = function(){
|
||||
s.isPythonRunning = false
|
||||
s.pythonScript = spawn('sh',[__dirname+'/bootPy.sh',config.pythonScript,__dirname]);
|
||||
var onStdErr = function (data) {
|
||||
s.debugLog('Python ERR')
|
||||
data = data.toString()
|
||||
s.debugLog(data)
|
||||
if(data.indexOf('Done!') > -1){
|
||||
console.log('PYTHON READY')
|
||||
s.isPythonRunning = true
|
||||
onStdErr = function(data){
|
||||
s.debugLog(data.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
s.pythonScript.stderr.on('data',onStdErr);
|
||||
|
||||
s.pythonScript.stdout.on('data', function (data) {
|
||||
s.debugLog('Python OUT')
|
||||
s.debugLog(data.toString())
|
||||
});
|
||||
|
||||
s.pythonScript.on('close', function () {
|
||||
s.debugLog('Python CLOSED')
|
||||
});
|
||||
}
|
||||
s.createPythonProcess()
|
Loading…
Add table
Add a link
Reference in a new issue