I am working on a program where connecting over SSH to a raspberry pi is necessary to run the program through my GUI app window in python, here is what I have right now to "test" ssh connections on all devices but i have to type in the actual IP of the pi itself. I need to make this where it just tests connection of everything on the network and connects to the available device.
Any help?
def raspi_connecter():
for n in range(1, 255):
server_ip= "10.0.0.153".format(n)
subprocess.Popen('ssh' + ' ' + 'dev#' + server_ip, shell= True)
Here's python2 program (I've never reworked it for python3) that finds your Raspberries. It runs nmap to create XML output then crudely parses that.
It needs the iproute module sudo apt install python{,3}-pyroute
#!/usr/bin/python2
from pyroute2 import IPRoute
import socket
import subprocess
import xml.etree.ElementTree as ET
ip = IPRoute()
for x in ip.get_addr(label='eth0',family=socket.AF_INET):
ipa =x.get_attr('IFA_ADDRESS')+"/"+str(x['prefixlen'])
print ipa
process = subprocess.Popen(['sudo','nmap','-oX', '/tmp/nmap.xml','-sn',ipa],stdout=subprocess.PIPE)
process.wait()
tree = ET.parse('/tmp/nmap.xml')
for node in tree.iter('address'):
try:
if node.attrib['addrtype'] == "ipv4":
ip = node.attrib['addr']
except:
pass
try:
if node.attrib['vendor'] == "Raspberry Pi Foundation":
print "IP:", ip
except:
pass
Once you have an IP address for a Raspberry then you can run ssh with subprocess (or ping or netcat). It will need additional testing for Raspberry Pi 4 and Pi400 devices (as I don't have either of those (which use the new MAC OUI).
I am working on a automation of my home using a raspberry pi 3B+
I bought a electronic energy meter MEMO4-M-MOD.
https://docs-emea.rs-online.com/webdocs/152f/0900766b8152f22b.pdf
To connect it to raspberry pi i bought a cable RS485/USB.
I am interested to read some values from the energy meter
( exemple in the datasheet of the energy meter it says that the register adress of voltage is on the adress 2000(hexa) )
i wrote this code
#!/usr/bin/env python3
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('/dev/ttyUSB0',0)
instrument.serial.port
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity =serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.05
instrument.mode = minimalmodbus.MODE_RTU
try:
valeur= instrument.read_register(2000,1,3,False)
print(valeur)
except IOError:
print("no connection")
Problem I am facing here is it print no connection, so that make me think i use correctly the library.
Have you used this library?can you give me some advice to make that work?
thank you so much
#!/usr/bin/env python3
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('/dev/ttyUSB0',1)
instrument.serial.baudrate = 9600
instrument.close_port_after_each_call = True
valeur = instrument.read_float(2000, functioncode=3, number_of_registers=2, byteorder=0)
print(valeur)
Connect your RS485 USB device to your pi and make sure that your pi can see it... check by running "dmesg | grep ttyUSB" you will get an output of most likely ttyUSB0, use whatever this is as your device address.
You also need to set modbus address of power meter, I set it to 1 above...
Your register is big endian, I checked official documentation here on returning a big endian double register value (classed as read_float): https://minimalmodbus.readthedocs.io/en/stable/internalminimalmodbus.html
Quick summary to what I want to achieve:
I’m making a python script that communicates with firebase-Realtime
database running on Raspberry Pi 3 B and depending on the values
stored in the database, the script will light up a LED or shut it
down. The script will also always start on bootup.
Background to what I’m using (software/hardware/configuration):
Raspberry Pi 3 B - Raspbian installed with NOOBS version 3.0.0
Using Python 3.5.3 with Pyrebase libraries
I've enabled SSH and remote
desktop on Raspberry PI 3 B, so I only work with Raspberry PI using
remote desktop.
What I have achieved so far and what works:
Python script does everything that I want it to do when started from
terminal or Python IDLE (it connects to firebase, then reads the data
via stream and updates LED status whenever the data changes in the
database).
I managed also to launch the script as service using
systemd.
What is wrong:
This part of the code is supposed to react in two ways depending on if there is
or isn’t internet connection (NOTE that this works as intended when
running script from terminal/idle):
..
#Test of connection ...
GPIO.output(LED1_adr, GPIO.HIGH)
while have_internet() == False:
GPIO.output(LED1_adr, GPIO.LOW)
print("No connection ...")
sleep(1)
GPIO.output(LED1_adr, GPIO.HIGH)
If there ISN’T an internet connection, the LED stays on for
approx. 5 seconds, and then the while loop gets stuck and turns off
the LED. Then it waits until there is internet connection - turns on
the LED back and continues. This works - and I’ve checked it by
rebooting the PI and unplugging WLAN from my home router, the LED
turns off and waits … then when I plug the WLAN back into my router,
LED turns on again.
If there IS an internet connection the code continues with
LED TURNED ON.
But when I run the script from reboot as service using systemd this happens:
The LED turns on as it should in the start.
The while loop does what
it is supposed to do: waits until there is an internet connection and
then turns on the LED.
And then the LED stays ON the whole time. I
change the data in the firebase-Realtime database, and it doesn’t
respond to it! The LED stays on no matter how I change the data in
the database.
I’m so confused here because there is 100% internet connection and still it can’t connect to the firebase.
NOTE that the connection to firebase is happening AFTER the “Test of connection” is completed (my whole code is down below).
Also, as I said before: the script works when running from terminal/idle as intended. So I don’t even know how to troubleshoot and debug this code.
What I think is happening is that the code can’t establish a connection to the firebase when running as service, but I don’t know why …
I have four main questions:
Why the code can’t establish a connection to firebase when running
as service using systemd? Even if there is 100% internet connection
established.
Is there something that I need to add to the code so
it can run as service?
I’m new to python (3 weeks of
experience), so if there is something wrong that I’m doing, even tho
it doesn’t affect the functionality, I’m open to any suggestions.
Is there a way to troubleshoot/debug this kind of stuff? Because I
have no idea how to do so ...
Here is the systemd service:
[Unit]
Description=My Script Service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
User=pi
ExecStart=/usr/bin/python3 /home/pi/Desktop/FirebaseTest/firebaseTest.py
[Install]
WantedBy=multi-user.target
I was following these two tutorials:
Tutorial 1 and Tutorial 2
And this is my code (I’m sorry that I'm adding the whole code but I didn't think of a way to how to split it into meaningful parts):
#!/usr/bin/env python
#Libraries:
import RPi.GPIO as GPIO
import pyrebase
from time import sleep
try:
import httplib
except:
import http.client as httplib
#My functions:
def updateLED(status_LED, adr_LED): #Function that just update status of LED based on address and data
if status_LED == "ON":
GPIO.output(adr_LED, GPIO.HIGH)
if status_LED == "OFF":
GPIO.output(adr_LED, GPIO.LOW)
return
def have_internet(): #Function that returns true if there is internet connection, false if theres not
conn = httplib.HTTPConnection("www.google.com", timeout=5)
try:
conn.request("HEAD", "/")
conn.close()
return True
except:
conn.close()
return False
#Cleanup of pins + turn off warnings + GPIO pins will be mapped as BCM
GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode (GPIO.BCM)
#Set pins to OUTputs or INputs
LED1_adr = 18 #Adress of LED
GPIO.setup(LED1_adr, GPIO.OUT)
#Variables:
LED1 = "NULL"
#Test of connection ...
GPIO.output(LED1_adr, GPIO.HIGH)
while have_internet() == False:
GPIO.output(LED1_adr, GPIO.LOW)
print("No connection ...")
sleep(1)
GPIO.output(LED1_adr, GPIO.HIGH)
#Main references to firebase and its config:
config = {
"apiKey": "my apiKey",
"authDomain": "my authDomain",
"databaseURL": "my databseURL",
"storageBucket": "my storageBucket",
}
firebase = pyrebase.initialize_app(config)
database = firebase.database()
#Stream handler for reading realtime changes
def stream_handler(message):
global LED1
LED1 = message["data"]
my_stream = database.child("/led1/status").stream(stream_handler)
#Main functions:
while True:
sleep(0.25)
updateLED(LED1, LED1_adr)
Environment: Python v2.x in Windows OS.
Question: I am using COM4 to communicate with a robot. I notice that I cannot get complete return in my Python code when I send "getver(ion)" cmd to robot.
To be specific, my current code is:
########## open COM4
ser = serial.Serial(3)
########## send cmd 'getver'
ser.write ("testmode on \n")
ser.write ("getver \n")
print ser.read()
########### return
Component,Major,Minor,Build,Aux
APPassword,956FC721
BaseID,1.2,1.0,18000,2000,
BatteryType,4,LIION_4CELL_SMART,
Beehive URL, beehive.cloud.com
BlowerType,1,BLOWER_ORIG,
Bootloader Version,27828,,
BrushMotorType,1,BRUSH_MOTOR_ORIG,
BrushSpeed,1400,,
BrushSpeedEco,800,,
ChassisRev,1,,
Cloud Selector, 2
However, the right return is this:
Component,Major,Minor,Build,Aux
APPassword,956FC721
BaseID,1.2,1.0,18000,2000,
BatteryType,4,LIION_4CELL_SMART,
Beehive URL, beehive.cloud.com
BlowerType,1,BLOWER_ORIG,
Bootloader Version,27828,,
BrushMotorType,1,BRUSH_MOTOR_ORIG,
BrushSpeed,1400,,
BrushSpeedEco,800,,
ChassisRev,1,,
Cloud Selector, 2
DropSensorType,1,DROP_SENSOR_ORIG,
LCD Panel,137,240,124,
LDS CPU,F2802x/c001,,
LDS Serial,KSH13315AA-0000153,,
LDS Software,V2.6.15295,0000000001,
LDSMotorType,2,LDS_MOTOR_MABUCHI,
Locale,1,LOCALE_USA,
MagSensorType,1,MAG_SENSOR_ORIG,
MainBoard Serial Number,OPS13115,544a1696de32,
MainBoard Version,1,,
Model,BotVacConnected,905-0143,
QAState,QA_STATE_APPROVED
Serial Number,KSH13715,544a1696de32,P
SideBrushPower,1500,,
SideBrushType,2,SIDE_BRUSH_VORWERK_REV1,
SmartBatt Data Version,2048
SmartBatt Device Chemistry,LION
SmartBatt Device Name,F164A1028
SmartBatt Manufacturer Name,Panasonic
SmartBatt Mfg Year/Month/Day,2095,10,6
SmartBatt Serial Number,14592
SmartBatt Software Version,1280
Software,2,0,0,46,28146
UI Board Hardware,0,0,
UI Board Software,1,3,
UI Name,Davinci
UI Version,1.0.0
VacuumPwr,80,,
VacuumPwrEco,65,,
WallSensorType,1,WALL_SENSOR_ORIG,
WheelPodType,1,WHEEL_POD_ORIG,
As you can see, the return from python is not complete, um...then how to display the full info? Thanks in advance.
I know some electronics and robotics, but I cannot predict what exact could happen, so I have some ideas to check only ;)
1) I wonder to know what did you get when call recieve again. I think it could help.
2) set exact bytes to recieve in read() method.
it is described here,
TL;DR below:
While True:
bytesToRead = ser.inWaiting()
ser.read(bytesToRead)
3) Try to initialize Serial object with timeout = None - maybe it just waits, or default is too small ;)
I will edit that when you check that sth not working, and if I will have new idea.
Regards and sorry for my English.
I'm currently trying to do something simple with a Telit CC864 Cellular module. The module is controlled with AT-Commands through serial ports. So with a modem control software such as minicom, I can input the following sequence of commands:
Input: AT
Output: OK
Input: AT#SGACT=1,1
Output: OK
Input: AT#SD=1,0,54321,"30.19.24.10",0,0,1
Output: CONNECTED
Input: AT#SSEND=1
> Hello world!
>
Output: OK
What this does is it connects to a server I have set up and sends a packet "Hello world!". Everything is working in minicom. However, what I am trying to do is convert this to a python script. Here's what I have so far:
import serial
import time
# Modem config
modem_port = serial.Serial()
modem_port.baudrate = 115200
modem_port.port = "/dev/tty.usbserial-00002114B"
modem_port.parity = "N"
modem_port.stopbits = 1
modem_port.xonxoff = 0
modem_port.timeout = 3
modem_port.open()
def send_at_command(command):
modem_port.write(bytes(command+"\r", encoding='ascii'))
def read_command_response():
print(modem_port.read(100).decode('ascii').strip())
print("\n")
if modem_port.isOpen():
# Check network status
send_at_command("AT+CREG=1")
read_command_response()
# Configure Socket
send_at_command("AT#SCFG=1,1,0,0,1200,0")
read_command_response()
# Obtain IP from network
send_at_command("AT#SGACT=1,1")
read_command_response()
# Connect to AWS server
send_at_command("AT#SD=1,0,54321,\"30.19.24.10\",0,0,1")
read_command_response()
# Send packet to AWS server
send_at_command("AT#SSEND=1")
read_command_response()
send_at_command("This is sent from Python Script.")
read_command_response()
modem_port.close()
However, this script fails to send the packet. I'm thinking that the reason is because in minicom, I have to press enter after Hello world! in order to send the packet. I'm at a loss at how to simulate this in the python script. Any suggestions would be much appreciated.
EDIT:
So I was reading the module documentation some more, and it seems that what I need to do is send Ctrl-Z char (0x1A hex) through the serial port. Do you know how I would do this in python?
Note that the documentation indicated that the execute command was ctrl-z so this answer has been edited to remove references to \n and \r
EDIT:
Based on your comments, try
def send_at_command(command): modem_port.write(bytes(command+"\1a", encoding='ascii'))