Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 17 additions & 30 deletions PyExpLabSys/common/sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@
# Queue was renamed to queue in Python 3
import queue as Queue
import logging
import six
from .utilities import call_spec_string
from .system_status import SystemStatus
from ..settings import Settings
from .supported_versions import python2_and_3

# Instantiate module logger
LOGGER = logging.getLogger(__name__)
Expand All @@ -71,9 +69,6 @@
# Instantiate a global system status object
SYSTEM_STATUS = SystemStatus()

# Indicate Python 2/3
python2_and_3(__file__)

# Instantiate settings object
SETTINGS = Settings()
LOGGER.debug("Settings loaded with the following values: %s", SETTINGS.settings)
Expand Down Expand Up @@ -200,9 +195,9 @@ def _single_value(self, command):

elif command == 'json' and name in DATA[self.port]['data']:
if self._old_data(name):
out = six.text_type(json.dumps(OLD_DATA))
out = json.dumps(OLD_DATA)
else:
out = six.text_type(json.dumps(DATA[self.port]['data'][name]))
out = json.dumps(DATA[self.port]['data'][name])
# The command is unknown
else:
out = UNKNOWN_COMMAND
Expand Down Expand Up @@ -239,7 +234,7 @@ def _all_values(self, command):
else:
data = DATA[self.port]['data'][codename]
points.append(data)
out = six.text_type(json.dumps(points))
out = json.dumps(points)
# Return a raw string with all measurements in codenames order including names
elif command == 'raw_wn':
strings = []
Expand All @@ -258,25 +253,23 @@ def _all_values(self, command):
for codename in DATA[self.port]['codenames']:
if self._old_data(codename):
datacopy[codename] = OLD_DATA
out = six.text_type(json.dumps(datacopy))
out = json.dumps(datacopy)
# Return all codesnames in a raw string
elif command == 'codenames_raw':
out = ','.join(DATA[self.port]['codenames'])
# Return a list with all codenames encoded as a json string
elif command == 'codenames_json':
out = six.text_type(json.dumps(DATA[self.port]['codenames']))
out = json.dumps(DATA[self.port]['codenames'])
# Return the socket server name
elif command == 'name':
out = DATA[self.port]['name']
# Return status of system and all socket servers
elif command == 'status':
out = six.text_type(
json.dumps(
{
'system_status': SYSTEM_STATUS.complete_status(),
'socket_server_status': socket_server_status(),
}
)
out = json.dumps(
{
'system_status': SYSTEM_STATUS.complete_status(),
'socket_server_status': socket_server_status(),
}
)
# The command is not known
else:
Expand Down Expand Up @@ -686,13 +679,11 @@ def handle(self):
commands = ['json_wn#', 'raw_wn#', 'name', 'status', 'commands']
return_value = '{}#{}'.format(PUSH_RET, json.dumps(commands))
elif request == 'status':
return_value = six.text_type(
json.dumps(
{
'system_status': SYSTEM_STATUS.complete_status(),
'socket_server_status': socket_server_status(),
}
)
return_value = json.dumps(
{
'system_status': SYSTEM_STATUS.complete_status(),
'socket_server_status': socket_server_status(),
}
)
elif request.count('#') != 1:
return_value = '{}#{}'.format(PUSH_ERROR, UNKNOWN_COMMAND)
Expand Down Expand Up @@ -939,7 +930,7 @@ def _format_return_raw_dict(argument):
# Check all values in list are of same type
types = [type(element) for element in value]
element_type = types[0]
element_type_name = six.text_type(element_type.__name__)
element_type_name = element_type.__name__
if types != len(types) * [element_type]:
message = (
'With return format raw, value in list must have same type'
Expand All @@ -953,13 +944,9 @@ def _format_return_raw_dict(argument):
value_string = ''
else:
# Single element conversion
element_type_name = six.text_type(type(value).__name__)
element_type_name = type(value).__name__
value_string = '{}'.format(str(value))

# We always call it str
if sys.version_info[0] == 2 and element_type_name == 'unicode':
element_type_name = 'str'

# Check that the element type makes sense for raw conversion
if element_type_name not in ['int', 'float', 'bool', 'str']:
message = (
Expand Down
3 changes: 0 additions & 3 deletions bin/autostart.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ def main():
args = parse_args()
config_file_path = find_config(args)

# Change current working directory to config dir
pathlib.os.chdir(config_file_path.parent)

# Parse XML config file
etree_object = XML.parse(config_file_path)
xml = etree_object.getroot()
Expand Down
105 changes: 55 additions & 50 deletions bootstrap/bootstrap_linux.bash
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,26 @@
# EDIT POINT START: Edit here to change what the script does #
##############################################################

# Install virtual python environment in ~/$PELS_ENV
PELS_ENV=.pels

# apt install packages line 1, general packages
#
apt1="openssh-server emacs graphviz screen i2c-tools vim-nox"
apt1="emacs-nox graphviz screen i2c-tools vim-nox"

# apt install packages line 2, python extensions
#
# NOTE: This line used to contain colorama, but it is a dependency of
# pip, so it will be installed anyway
apt2="python3-pip python3-numpy black"
# NOTE: This line used to contain colorama, but it was a dependency of
# pip, so it will be installed anyway. Only used on Windows systems?
apt2="python3-pip python3-venv black"

# apt install packages that has possibly changed name, written in list form and installed one at at time
declare -a apt3=("libpython3-dev" "python3-dev")
# https://pypi.org/project/mysqlclient/
declare -a apt3=("libpython3-dev" "python3-dev default-libmysqlclient-dev build-essential pkg-config")
# for rhel, you need python3-devel mysql-devel pkgconfig instead to be able to pip mysqlclient

# packages to be installed by pip
pip3packages="minimalmodbus pyusb python-usbtmc pyserial pyyaml mysqlclient"
pip3packages="minimalmodbus pyusb python-usbtmc pyserial pyyaml mysqlclient numpy"
# Put packages into this array, whose installation sometimes fail
declare -a pip3problempackages=("pylint")

Expand All @@ -37,16 +42,13 @@ if [ -d $machine_dir ]; then
cd $machine_dir
fi
pistatus.py
if [ -f ~/'$PELS_ENV'/bin/activate ]; then
source ~/'$PELS_ENV'/bin/activate
fi
'

# These lines will be added to ~/.bash_aliases
bash_aliases="
alias sagi=\"sudo apt-get install\"
alias sagr=\"sudo apt-get remove\"
alias acs=\"apt-cache search\"
alias sagu=\"sudo apt-get update\"
alias sagup=\"sudo apt-get upgrade\"
alias sagdu=\"sudo apt-get dist-upgrade\"
alias ll=\"ls -lh\"
alias df=\"df -h\"
alias emacs-nolint=\"emacs -q --load ~/PyExpLabSys/bootstrap/.emacs-simple\"
Expand Down Expand Up @@ -87,6 +89,7 @@ abelec Setup device to use daq-modules from AB Electronics (NOT part of all
dash Install packages for dash
qt Setup GUI environment: Qt and Qwt (for plots)
"

##################
# EDIT POINT END #
##################
Expand Down Expand Up @@ -200,69 +203,66 @@ fi

# Install packages
if [ $1 == "install" ] || [ $1 == "all" ];then
# Verified for Debian 13 - Trixie
echo
echobold "===> INSTALLING PACKAGES"
echoblue "---> Updating package archive information"

# Update, but only if it has not just been done (within the last
# 10 hours), since it actually takes a while on a RPi.
#
# NOTE. The method is based on checking the last modification of
# the apt cache file, which may not the perfect method, we will
# test it and see
last_update=`stat /var/cache/apt/pkgcache.bin --format="%Y"`
now=`date +%s`
since_last_update=$((now-last_update))
if [ $since_last_update -gt 36000 ];then
sudo apt-get update
else
echoblue "Skipping, since it was done" $(($since_last_update/3600)) "hours ago"
fi
# Update - it does not take that long on newer hardware and the old
# method seemingly did not work when run on a fresh minimal installation.
sudo apt update

aptgetprefix='sudo apt-get -y'
aptprefix='sudo apt -y'

echoblue "---> Upgrade all existing packages"
$aptgetprefix dist-upgrade
$aptprefix full-upgrade
echoblue "---> Installing packages"
echoblue "----> Install: $apt1"
$aptgetprefix install $apt1
$aptprefix install $apt1
echoblue "----> Install: $apt2"
$aptgetprefix install $apt2
$aptprefix install $apt2

# Install package individually, that may have changed name
for package in "${apt3[@]}";do
echoblue "----> Attempting to install \"$package\" as an individual package"
$aptgetprefix install $package
$aptprefix install $package
done

echoblue "---> Remove un-needed packages, if any"
$aptgetprefix autoremove
$aptprefix autoremove
echoblue "---> Clear apt cache"
$aptgetprefix clean
sudo apt -y clean

echoblue "---> Enable ssh by creating /boot/ssh"
sudo touch /boot/ssh
echogood "+++++> DONE"
fi

# Install extra packages with pip
if [ $1 == "pip" ] || [ $1 == "all" ];then
# Verified for Debian 13 - Trixie
echo
# Test if pip3 is there
PIPEXECUTABLE=`which pip3`

if [ $? -eq 0 ];then
echobold "===> INSTALLING EXTRA PYTHON PACKAGES WITH PIP3"
echoblue "---> Installing: $pip3packages"
sudo $PIPEXECUTABLE install -U $pip3packages
# Individual packages
for package in "${pip3problempackages[@]}";do
echoblue "---> Installing \"$package\" as an invididual package"
sudo $PIPEXECUTABLE install -U $package
done
echogood "+++++> DONE"
# Create virtual Python environment if not existing
if [ ! -d ~/$PELS_ENV ];then
echoblue "Creating virtual environment for PyExpLabSys as $PELS_ENV"
python3 -m venv ~/$PELS_ENV
fi
# Activate virtual environment
if [ -f ~/$PELS_ENV/bin/activate ];then
source ~/$PELS_ENV/bin/activate

# Install packages
echobold "===> INSTALLING EXTRA PYTHON PACKAGES WITH PIP3"
echoblue "---> Installing: $pip3packages"
python -m pip install -U $pip3packages
# Individual packages
for package in "${pip3problempackages[@]}";do
echoblue "---> Installing \"$package\" as an invididual package"
python -m pip install -U $package
done
echogood "+++++> DONE"
else
echobad "pip3 not installed, run install step and then re-try pip step"
echobad "~/$PELS_ENV already exists, but is not a virtual environment for Python"
echobad "Skipping pip installs"
fi
fi

Expand Down Expand Up @@ -309,7 +309,7 @@ $cronline"
fi


# Setup autostart cronjob
# Setup settings
if [ $1 == "settings" ] || [ $1 == "all" ];then
echobold "===> LINKING PYEXPLABSYS SETTINGS FILE IN PLACE"
if [ -f ~/.config/PyExpLabSys/user_settings.yaml ];then
Expand Down Expand Up @@ -349,6 +349,7 @@ fi

# Install extra packages needed for writing docs
if [ $1 == "docs" ];then
# FIXME: Should be updated/removed or is working?
# TODO add sphinx and extra package needed to dependency graph
echobold "===> INSTALLING EXTRA PACKAGES FOR WRITING DOCS"
echo
Expand All @@ -370,6 +371,7 @@ if [ $1 == "docs" ];then
fi

if [ $1 == "wiringpi" ];then
# FIXME: Should be updated/removed or is working?
echobold "===> INSTALLING WIRINGPI"
echoblue "---> Installing wiringpi with apt-get"
sudo apt-get install wiringpi
Expand All @@ -383,9 +385,10 @@ if [ $1 == "wiringpi" ];then
fi

if [ $1 == "abelec" ];then
# FIXME: Should be updated/removed or is working?
# TODO: Improve script to allow multiple executions
echobold "===> INSTALLING EXTRA PACKAGES FOR AB ELECTRONICS"
sudo apt-get install i2c-tools python-smbus
sudo apt install i2c-tools python-smbus
echo

sudo touch /etc/modprobe.d/raspi-blacklist.conf # Make sure file is there before removing
Expand Down Expand Up @@ -439,6 +442,7 @@ fi


if [ $1 == "dash" ];then
# FIXME: Should be updated/removed or is working?
# TODO: Improve script to allow multiple executions
echobold "===> INSTALLING EXTRA PACKAGES FOR DASH"
pip3 install dash==0.28.5 # The core dash backend
Expand All @@ -450,6 +454,7 @@ fi

# GUI section (Qt and Qwt)
if [ $1 == "qt" ];then
# FIXME: Should be updated/removed or is working?
echobold "===> INSTALLING EXTRA PACKAGES FOR GUIS"
echo

Expand Down