I'm having a really weird issue on my Raspberry. I need to play sounds with it and I need to do it inside a script which requires sudo to work. However, for some reason, when I try to play sounds with sudo, it doesn't work.
No errors, it just doesn't make any sound (I tried with several libraries, none worked). It does work if I'm using omxplayer.
If I don't use sudo, everything works fine.
Anybody had a similar issue?
Edit: I added one of the code I used (this works just fine on another Raspberry)
import pygame
import time
pygame.mixer.init()
pygame.mixer.music.stop()
pygame.mixer.music.load("music.mp3")
pygame.mixer.music.play()
print("Going forward")
while True:
time.sleep(1)
Are you using the 3.5mm jack or HDMI?
One thing I have noticed in the past is that if I run alsamixer as user=pi the default device is the 3.5mm aux jack. However if I run sudo alsamixer the default device is now HDMI. Never looked in to why, just know that's a thing.
Spent nearly a day trying to enable the analog out when using the root user.
First make sure the default user (pi) has audio:
aplay sound.wav
If that works then copy the audio configuration to the root user home, try this:
sudo su
cd
cp /home/pi/.asoundrc .asoundrc
reboot
Related
I made this code to open the pi camera and to close it. When i run the code it makes .h264 videos but i can't play these on windows. Heres the code
import picamera
from time import *
from subprocess import call
with picamera.PiCamera() as camera:
camera.start_recording("beepvid.h264")
sleep(5)
camera.stop_recording()
Another simpler way is to simply make it record to beepvid.mp4
This is really a question for the rasberry pi stack but its ok!
If you type in cd (where ever the file is stored) and type ‘omxplayer (yourvid).h264, it will show you the video. The best thing for you to do is to use a command called ‘MP4Box’.
You can do this with the CMD but ill tell you how to do it in Python. Below your current code add the following.
command = "MP4Box -add beepvid.h264 beepvid.mp4"
call([command], shell=True)
print("vid conv")
This will convert the ‘beepvid.h264’ to mp4 and you can install VLC player if you want to play it. The way to install VLC player is the following: sudo apt-get install vlc. I suggest you type in ‘ sudo apt-get update’ and ‘sudo apt-get upgrade’ before hand
I hope this has answered your question.
I'm writing a Python script that will run on a Raspberry that will read the temperature from a sensor and log to Thingspeak. I have this working with a bash script but wan't to do it with Python since it will be easier to manipulate and check the read values. The sensor reading is done with a library called loldht. I was trying to do it like this:
from subprocess import STDOUT, check_output
output = check_output("/home/pi/bin/lol_dht22/loldht", timeout=10)
The problem is that I have to run the library with sudo to be able to access the pins. I will run the script as a cron. Is it possible to run this with sudo?
Or could I create a bash script that executes 'sudo loldht' and then run the bash script from python?
I will run the script as a cron. Is it possible to run this with sudo?
You can put python script.py in the cron of a user with sufficient privileges (e.g. root or a user with permissions to files and devices in question)
I don't know which OS you're using, but if Raspbian is close to Debian, there is no need for sudo or root, just use a user with sufficient permissions.
It seems I can also do this check_output check_output(["sudo", "/home/pi/bin/lol_dht22/loldht", "7"], timeout=10)
Sure but the unix user that's going to invoke that Python script will need the sudo privilege (Otherwise can't call the sudo from subprocess). In which case you might as well do as above, run the cron from a user with the required permissions.
You can run sudo commands with cron. Just use sudo crontab -e to set the cron and it should work fine.
You should very careful with running things as root. Since root has access to everything, a simple error can potentially render the system unusable.
The proper way to have access to the hardware as a normal user is to change the permissions on the required device files.
It seems that the utility you mention uses the WiringPi library. Some digging in the source code indicates that it uses the /dev/gpiomem (or /dev/mem) devices.
On raspbian, device permissions are set with udev. See here and also here.
You could give every user access to /dev/gpiomem and other gpio devices by creating a file e.g. /etc/udev/rules.d/local.rules and putting the following text in it:
ACTION=="add", KERNEL=="gpio*", MODE="0666"
ACTION=="add", KERNEL=="i2c-[0-9]*", MODE="0666"
The first line makes the gpio devices available, the second one I2C devices.
I am trying to write a script that will shut down the computer if a few requirements are filled with the command
os.system("poweroff")
also tried
os.system("shutdown now -h")
and a few others. but nothing happens when I run it, the computer goes through the code without crashing or producing any error messages and terminates the script normally, without shutting down the computer.
How does one shutdown the computer in python?
edit:
Seems that the commands I have tried requires root access. Is there any way to shut down the machine from the script without elevated privileges?
import os
os.system("shutdown now -h")
execute your script with root privileges.
Many of the linux distributions out there require super user privileges to execute shutdown or halt, but then, how come that if you're sitting on your computer you can power it off without being root? You open a menu, hit Shutdown and it shutdowns without you becoming root, right?
Well... the rationale behind this is that if you have physical access to the computer, you could pretty much pull the power cord and power it off anyways, so nowadays, many distributions allow power-off though access to the local System Bus accessible through dbus. Problem with dbus (or the services exposed through it, rather)? It's constantly changing. I'd recommend installing a dbus viewer tool such as D-feet (be advised: it's still pretty hard to visualize, but it may help)
Take a look to these Dbus shutdown scripts.
If you still have HAL in your distrubution (is on the way to being deprecated) try this:
import dbus
sys_bus = dbus.SystemBus()
hal_srvc = sys_bus.get_object('org.freedesktop.Hal',
'/org/freedesktop/Hal/devices/computer')
pwr_mgmt = dbus.Interface(hal_srvc,
'org.freedesktop.Hal.Device.SystemPowerManagement')
shutdown_method = pwr_mgmt.get_dbus_method("Shutdown")
shutdown_method()
This works on a Ubuntu 12.04 (I just powered off my computer to make sure it worked). If you have something newer... well, it may not work. It's the downside of this method: it is very distribution specific.
You might have to install the dbus-python package for this to work (http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html)
UPDATE 1:
I've been doing a little bit of research and it looks like this is done in newer Ubuntu versions through ConsoleKit. I've tested the code below in my Ubuntu 12.04 (which has the deprecated HAL and the newer ConsoleKit) and it did shut my computer off:
>>> import dbus
>>> sys_bus = dbus.SystemBus()
>>> ck_srv = sys_bus.get_object('org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager')
>>> ck_iface = dbus.Interface(ck_srv, 'org.freedesktop.ConsoleKit.Manager')
>>> stop_method = ck_iface.get_dbus_method("Stop")
>>> stop_method()
UPDATE 2:
Probably why can you do this without being root deserves a bit of a wider explanation. Let's focus on the newer ConsoleKit (HAL is way more complicated and messy, IMHO).
The ConsoleKit is a service running as root in your system:
borrajax#borrajax:/tmp$ ps aux|grep console-kit
root 1590 0.0 0.0 1043056 3876 ? Sl Dec05 0:00 /usr/sbin/console-kit-daemon --no-daemon
Now, d-bus is just a message passing system. You have a service, such as ConsoleKit that exposes an interface to d-bus. One of the methods exposed is the Stop (shown above). ConsoleKit's permissions are controlled with PolKit, which (despite on being based on regular Linux permissions) offers a bit of a finer grain of control for "who can do what". For instance, PolKit can say things like "If the user is logged into the computer, then allow him to do something. If it's remotely connected, then don't.". If PolKit determines that your user is allowed to call ConsoleKit's Stop method, that request will be passed by (or through) d-bus to ConsoleKit (which will subsequently shutdown your computer because it can... because it worth's it... because it's root)
Further reading:
What are ConsoleKit and PolicyKit? How do they work?
ArchWiki PolKit
To summarize: You can't switch a computer off without being root. But you can tell a service that is running as root to shutdown the system for you.
UPDATE 3:
On December 2021, seven years after the original answer was written I had to do this again. This time, in a Ubuntu 18.04.
Unsurprisingly, things seem to have changed a bit:
The PowerOff functionality seems to be handled via a new org.freedesktop.login1 service, which is part of the """new""" (cough! cough!) SystemD machinery.
The dbus Python package seems to have been deprecated and/or considered "legacy". There is, however, a new PyDbus library to be used instead.
So we can still power off machines with an unprivileged script:
#! /usr/bin/python3
from pydbus import SystemBus
bus = SystemBus()
proxy = bus.get('org.freedesktop.login1', '/org/freedesktop/login1')
if proxy.CanPowerOff() == 'yes':
proxy.PowerOff(False) # False for 'NOT interactive'
Update 3.1:
It looks like it's not as new as I thought X-D
There's already an answer by #Roeften in this very same thread.
BONUS:
I read in one of your comments that you wanna switch the computer off after a time consuming task to prevent it from overheating... Did you know that you can probably power it on at a given time using RTC? (See this and this) Pretty cool, uh? (I got so excited when I found out I could do this... ) :-D
The best way to shutdown a system is to use the following codes
import os
os.system('systemctl poweroff')
any way to shut down...without elevated privileges?
No, there isn't (fortunately!).
Keep in mind that you can use several system features to make privilege escalation for normal users easier:
sudo
setuid
setcap
Just to add to #BorrajaX 's answer for those using logind (newer fedora systems):
import dbus
sys_bus = dbus.SystemBus()
lg = sys_bus.get_object('org.freedesktop.login1','/org/freedesktop/login1')
pwr_mgmt = dbus.Interface(lg,'org.freedesktop.login1.Manager')
shutdown_method = pwr_mgmt.get_dbus_method("PowerOff")
shutdown_method(True)
linux:
import subprocess
cmdCommand = "shutdown -h now"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)
Windows:
import subprocess
cmdCommand = "shutdown -s"
process = subprocess.Popen(cmdCommand.split(), stdout=subprocess.PIPE)
In case you want to execute it from root, #Rahul R Dhobi answer works great:
import os
os.system("shutdown now -h")
Execution: sudo python_script.py
In case you need to execute it without root privileges:
import subprocess
import shlex
cmd = shlex.split("sudo shutdown -h now")
subprocess.call(cmd)
Execution: $ python_script.py # no sudo required
try this
import os
os.system("sudo shutdown now -h")
this worked for me
I'am using Fedora and it works with me. all what i need to do is Writing this line in terminal :
$ sudo python yourScript.py
There is a way to shut down the computer without using elevated permissions.
import os
subprocess.call(['osascript', '-e', 'tell app "system events" to shut down'])
I've been playing around with Motion on my Rapsberry Pi running Raspbian and came across this post that sounded like fun to do.
I've been trying to tweak the steps he lists to have it work with Raspbian, and as far as I know I should be good. I installed GData using "sudo apt-get install python-gdata" And then I put the uploader.py and uploader.cfg files in /etc/motion and changed the motion.confg file to have the line
on_movie_end /etc/motion/uploader.py /etc/motion/uploader.cfg %f
Am I missing something? Theoretically this should work on Raspbian right? What else has to be done?
Thanks
I have been following the guides you have referred to get this working on Raspbian and I had the same problem; Motion seems to work but the script never executes.
However, when i tried to run the script directly I got a permission error.
I ran the following to make the script executable.
chmod a+x /etc/motion/uploader.py
now it uploads the videos to Google drive (no emails though?)
hope this helps,
This isn't a direct answer to your question, but it might be a away of getting files uploaded to google drive in an easier way.
Have you had a look at grive, its a linux utility which can be used to sync a folder on your raspberry pi with a folder on google drive.
See this link for more info on how to setup and use grive on a raspberry pi.
http://www.stuffaboutcode.com/2013/03/raspberry-pi-google-drive-grive.html
I also struggled with it quite a bit and this is what helped. First try to run this from terminal:
/etc/motion/uploader.py /etc/motion/uploader.cfg /
Here you put the absolute path to your file you want to upload.
Try to run it, and if it asks you for a password you know you have a permission problem and need to change permissions so that it does not require the password to execute.
Try again. If it works then it will also work if you use this in uploader.cfg:
on_movie_end /etc/motion/uploader.py /etc/motion/uploader.cfg %f
Do not forget to uncomment this line! This sounds silly but it took me some time to realize it, i.e. delete ; that is in front of on_movie_end.
Another issue I had was the movie encoding. Only mpeg4 really worked for me.
I have written a very simple script for my raspberry pi that loads an uncompressed WAV and plays it - however when I run the script as root (to be able to use GPIO and ServoBlaster), there is no sound output.
I have set the default audio device to a USB sound card, and this works - I have tested this using aplay fx.wav.
Running the pygame script without sudo, the sound plays fine.
What is going on here?
The issue was the sudo command changing the directory in which the script was being run - so running python with sudo -s or simply using an absolute path for the sound fixed it.