Skip to content

Commit

Permalink
Merge branch 'v2_latest'
Browse files Browse the repository at this point in the history
  • Loading branch information
SvenVD committed Dec 27, 2020
2 parents 9292ef5 + 7c18766 commit 7d448e1
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 23 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ If you like this software please consider donating:
See [RELEASE_NOTES](https://github.com/SvenVD/rpisurv/blob/master/RELEASE_NOTES.md)

## Goal
Rpisurv is designed to be simple to use (no need to fiddle with coordinates or detailed layout configs) and to be able to run unattended for long periods of time. Therefore watchdogs and autohealing logic have been implemented.
Rpisurv is designed to be simple to use (no need to fiddle with coordinates or detailed layout configs, although you [can](https://gist.github.com/SvenVD/0cb1a40261b7c7f2d4cffac24dc9181d) if you really want) and to be able to run unattended for long periods of time. Therefore watchdogs and autohealing logic have been implemented.
Version 2 adds functionality to define multiple screens which can be cycled between.

## Description
Expand Down Expand Up @@ -61,6 +61,13 @@ Keys F1 to F12 (or keypad 0 to 9), will force the equal numbered screen to be sh

Disable rotation (as in pause rotation, as in fix the current displayed screen) dynamically during runtime. By pressing "p" (or keypad "*") to pause or "r" (or "," or keypad ".")' to resume/rotate. This overrides the disable_autorotation option if this has been set in the config file.

Touchscreen control:
The width of the screen is divided in four sections,
- Touching on the first section trigger a pause event.
- Touching In the two sections in the middle trigger a resume event.
- Touching In the last section, a next screen event.
Note that a mouse can be used, however mouse cursor is hidden by default.


## Troubleshooting

Expand Down
8 changes: 8 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# rpisurv 2 release notes
## Changes in 2.1.9
A long requested feature [link](https://www.tapatalk.com/groups/rpisurv/grid-lay-out-show-one-stream-bigger-then-others-t5.html) has now finally made it to rpisurv.
Instead of letting rpisurv calculate the layout for you, you can now create complex custom layouts yourself. [Examples click here](https://gist.github.com/SvenVD/0cb1a40261b7c7f2d4cffac24dc9181d)

## Changes in 2.1.8
[nicolake](https://github.com/SvenVD/rpisurv/pull/100) provided some code to be able for touch screens to control rpisurv with basic commands.
This has been incorporated into rpisurv.

## Changes in 2.1.7
Http probe did not handle all exceptions which could crash rpisurv on rare occasions like described in the [link](https://www.tapatalk.com/groups/rpisurv/viewtopic.php?p=339#p339).
Fixed by inserting a fallback exception handler in the http probe logic.
Expand Down
37 changes: 27 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,37 @@ BACKUPCONFFILE=/tmp/surveillance.yml.$(date +%Y%m%d_%s)
DESTPATH="/usr/local/bin/rpisurv"
sudo mkdir -p "$DESTPATH"

if [ -f "$DESTPATH/$CONFFILE" ]; then sudo cp -v "$DESTPATH/$CONFFILE" "${BACKUPCONFFILE}";fi
echo
echo "Existing config file will be backed up to "${BACKUPCONFFILE}""
if [ -f "$DESTPATH/$CONFFILE" ];then
echo
echo "Existing config file will be backed up to "${BACKUPCONFFILE}""
sudo cp -v "$DESTPATH/$CONFFILE" "${BACKUPCONFFILE}"

echo
echo "Do you want to overwrite your current config file with the example config file?"
echo "Newer major versions of rpisurv are not backwards compatible with old format of config file"
echo "Type yes/no"
read USEEXAMPLECONFIG
else
USEEXAMPLECONFIG="yes"
fi

if [ -d /usr/local/bin/rpisurv/images/ ];then
echo
echo "Do you want to overwrite you current images directory (/usr/local/bin/rpisurv/images/) with the images from the installer?"
echo "Type yes/no"
read OVERWRITESIMAGES
else
OVERWRITESIMAGES="yes"
fi


echo
echo "Do you want to overwrite you current config file with the example config file?"
echo "Newer major versions of rpisurv are not backwards compatible with old format of config file"
echo "Type yes/no"
read ANSWER
if [ x"$OVERWRITESIMAGES" == x"no" ]; then
RSYNCOPTIONS="--exclude /images"
fi

sudo rsync -av "$SOURCEDIR/" "$DESTPATH/"
sudo rsync -av $RSYNCOPTIONS "$SOURCEDIR/" "$DESTPATH/"

if [ x"$ANSWER" == x"no" ]; then
if [ x"$USEEXAMPLECONFIG" == x"no" ]; then
#Putting back old config file
if [ -f "${BACKUPCONFFILE}" ]; then sudo cp -v "${BACKUPCONFFILE}" "$DESTPATH/$CONFFILE" ; fi
fi
Expand Down
18 changes: 16 additions & 2 deletions surveillance/conf/surveillance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,27 @@ essentials:
#Optional: aidx: this is a one to one mapping with the omxplayer aidx (Audio stream index) option, the default for rpisurv is the value -1 (audio disabled).
#To enable audio for this stream try setting this to 1. You do not have to set this option if you do not want audio, the default is -1
aidx: -1
#Optional and advanced option: force_coordinates: If you are not happy with the pre-calculated position on the screen of a particular stream then you can override it with this option
#Note: Once you do this, the layout of this particular screen becomes the responsability of the user
#Note2: rpisurv will continue to draw other streams with the pre-calculated values if they do not have force_coordinates set.
#Remember that rpisurv autocalculation can be influenced by nr_of_columns option
#This can cause overlap with other streams but the user can correct this by manually calculating and setting the position of the other camera streams with force_coordinates
#Note2: You can also put camera streams on top of each other if you use this option and a combination of freeform_advanced_omxplayer_options: "--layer 1000"
#Note3: This works transparently with rotation of screens, every screen can have a different layout
#force_coordinates: [upperleft corner x position, upperleft corner y position, downright corner x position, downright corner y position]
#Minimal example see here: https://gist.github.com/SvenVD/0cb1a40261b7c7f2d4cffac24dc9181d
force_coordinates: [0, 800, 600, 1080]

#Foscam-fi9821w example
- url: "rtsp://<user>:<password>@<ip or dnsname>:<port>/videoMain"
#Dahua IPC-HDW4200S example or IPC-HDW4300S
- url: "rtsp://<user>:<password>@<ip or dnsname>:<port>/cam/realmonitor?channel=1&subtype=1"

#OPTIONAL AND ADVANCED PER SCREEN OPTIONS, YOU CAN CONFIGURE THIS PER SCREEN, IF NOT CONFIGURED A DEFAULT VALUE WILL BE USED
#NOT recommendeded to enable disable_probing_for_all_streams, it disables some autohealing functions of rpisurv
#NOT recommendeded to enable disable_probing_for_all_streams, it disables the removal of dead feeds which also disables auto-rearranging the screen layout.
#Also if using multiple screens, enabling this will slow down rotation of one screen to the next if there are unconnectable screens
#This also disabled rpisurv only drawing the connectable screens using up all pixels. In other words, you will get a placeholder for an unconnectable stream instead of not showing at all
#This also disables rpisurv only drawing the connectable screens using up all pixels.
#In other words, you will get a placeholder for an unconnectable stream instead of not showing at all
#Roughly the same as the obsoleted keep_first_screen_layout in rpisurv v1.0
#Defaults to False
disable_probing_for_all_streams: False
Expand Down Expand Up @@ -110,11 +122,13 @@ advanced:
##Enable this option if you want to have a fixed width of all your camera streams,
##By default rpisurv autocalculates this value, this can cause streams to get "stretched",
##if this value exceeds the available width, rpisurv will fallback to autocalculation
##Note, this value will be ignored for a stream that uses force_coordinates
#fixed_width: 500

##Enable this option if you want to have a fixed height for all your camera streams,
##By default rpisurv autocalculates this value, this can cause streams to get "stretched",
##if this value exceeds the available height, rpisurv will fallback to autocalculation
##Note, this value will be ignored for a stream that uses force_coordinates
#fixed_height: 500

#Rpisurv sends usage stats to it's statistics server to give the rpisurv community an idea how widespread this software is being used
Expand Down
8 changes: 7 additions & 1 deletion surveillance/core/CameraStream.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def __init__(self, name, camera_stream):
self.name = name
self.worker = None
self.omxplayer_extra_options = ""
#This option overrides any other coordinates passed to this stream
self.force_coordinates=camera_stream.setdefault("force_coordinates", False)
self.freeform_advanced_omxplayer_options = camera_stream.setdefault("freeform_advanced_omxplayer_options","")
self.probe_timeout = camera_stream.setdefault("probe_timeout",3)
self.imageurl = camera_stream.setdefault("imageurl", False)
Expand Down Expand Up @@ -212,7 +214,11 @@ def refresh_image_from_url(self):
logger.debug("CameraStream: This stream " + self.name + " is not an imageurl, skip refreshing imageurl")

def start_stream(self, coordinates, pygamescreen, cached):
self.coordinates=coordinates
if self.force_coordinates and not cached:
logger.debug("CameraStream: This stream " + self.name + " uses force_coordinates " + str(self.force_coordinates) + " which will override pre-calculated coordinates of " + str(coordinates) )
self.coordinates = self.force_coordinates
else:
self.coordinates=coordinates
self.pygamescreen=pygamescreen
logger.debug("CameraStream: Start stream " + self.name)

Expand Down
32 changes: 30 additions & 2 deletions surveillance/core/util/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def placeholder(absposx,absposy,width,height,background_img_path,surface):
refresh()
return background_img

def check_keypress():
def check_input():
try:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
Expand All @@ -53,8 +53,36 @@ def check_keypress():
return numeric_key_counter
else:
return None


# Touch screen handling
# the width of the screen is divided in four sections,
# touching or clicking on the first section trigger a pause event,
# in the two sections in the middle trigger a resume event
# and in the last section, a next screen event.
elif event.type == pygame.MOUSEBUTTONUP:
#For debug set_visible(True)
#pygame.mouse.set_visible(True)
logger.debug("draw: pygame.MOUSEBUTTONUP detected")
pos = pygame.mouse.get_pos()
display_w = pygame.display.Info().current_w
logger.debug("draw touch/mouse handling: pygame detected display width of " + str(display_w))
quarter = display_w / 4
firstQuarter = quarter
lastQuarter = display_w - quarter
logger.debug("draw touch/mouse handling: firstQuarter " + str(firstQuarter) + " and lastquarter " + str(lastQuarter))
if pos[0] > lastQuarter:
logger.debug("draw touch/mouse handling: detected touch/mouse in lastquarter")
touchResult = "next_event"
elif pos[0] > firstQuarter and pos[0] < lastQuarter:
logger.debug("draw touch/mouse handling: detected touch/mouse in middle")
touchResult = "resume_rotation"
else:
logger.debug("draw touch/mouse handling: detected touch/mouse in first quarter")
touchResult = "pause_rotation"
return touchResult
except pygame.error as e:
logger.debug("Exception " + repr(e))
logger.debug("draw: Exception " + repr(e))
exit(0)

def refresh():
Expand Down
14 changes: 7 additions & 7 deletions surveillance/surveillance.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ def sigterm_handler(_signo, _stack_frame):
sys.exit(0)


def handle_keypresses():
def handle_input():
global disable_autorotation
event = draw.check_keypress()
event = draw.check_input()
if event == "next_event":
logger.debug("Main: force next screen keyboard event detected, start rotate_next event")
logger.debug("Main: force next screen input event detected, start rotate_next event")
screen_manager_main.rotate_next()
# This can do not harm, but is not really needed in this case, since the screen was already updated in cache and we merely swap it on screen as is.
# We do not check update_connectable_cameras this time as this is to slow for the user to wait for and we live with the fact if there is one unavailable or one became available since cache time,
# it is not updated until next regular update of the screen
# logger.debug("MAIN: after keyboard next_event start update_active_screen with skip_update_connectable_camera true")
# screen_manager_main.update_active_screen(skip_update_connectable_camera = True)
if event == "end_event":
logger.debug("Main: quit_on_keyboard event detected")
logger.debug("Main: quit input event detected")
screen_manager_main.destroy()
if event == "resume_rotation":
logger.debug("Main: resume_rotation event detected")
Expand All @@ -112,7 +112,7 @@ def handle_keypresses():
#Setup logger
logger = setup_logging()

fullversion_for_installer = "2.1.7"
fullversion_for_installer = "2.1.9"

version = fullversion_for_installer
logger.info("Starting rpisurv " + version)
Expand Down Expand Up @@ -159,7 +159,7 @@ def handle_keypresses():
loop_counter += 1

#Handle keypresses
handle_keypresses()
handle_input()

#Check free mem and log warning
if memory_usage_check:
Expand All @@ -174,7 +174,7 @@ def handle_keypresses():
screen_manager_main.update_active_screen()

else:
logger.debug("MAIN: disable_autorotation is True, use keyboard only to rotate between screens")
logger.debug("MAIN: disable_autorotation is True, use input keyboard/mouse/touch only to rotate between screens")

#Only update the screen/check connectable cameras every interval_check_status seconds
if loop_counter % int(interval_check_status) == 0:
Expand Down

0 comments on commit 7d448e1

Please sign in to comment.