简体   繁体   中英

How to trigger Raspberry Pi 3 to take action from Server

I am currently developing a system where I need to send notification to Raspberry to run a Python file. It is much like a observer pattern design where my server is publisher and Raspberry is the observer. Worth to note that, I actually need to interact with one Raspberry at the time (even I have dozens of them). Specifically, on a specific event, I need to warn a single Raspberry that it has to take an action.

I searched for it literally for all the night but I could not find anything coming handy. Nothing really give me a clue how to implement this.

The most close answer I could find is this technology firm's product called PubNub which can actually work. However, as I need is a one-to-one interaction, this might be unnecessary because it is designed to publish a data to multiple clients.

Long story short, I need to trigger Raspberry to take some action in accordance to the some data coming from the server, whenever it receives the data.

Server is running on Amazon and implemented with Python 2.7.

Please do not hesitate to ask me for further detail, if I am missing any.

Thanks for all the supports,


EDIT

Just a recent update with an improvement to my answer. As far as I understand, sockets are able to manage this process. Such as from client (Raspberry in my case) listening for the server and server sending some data. Taken from this site , I managed to make a sample run on my computer, from my local. I used Port 5000 as their 'meeting point'.

Below is the code:

client.py

#!/usr/bin/env python

import socket


TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print("received data:", data)

server.py

#!/usr/bin/env python

import socket


TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
print('Connection address:', addr)
while 1:
    data = conn.recv(BUFFER_SIZE)
    if not data: break
    print("received data:", data)
    conn.send(data)  # echo
conn.close()

However, I still have some questions.

Firstly, I want to learn whether the same thing work when I deploy the project and how. If that will work - lets say I have an url for the server like 'www.thisisanexampleurl.com' - simply assignign a port for it, will work?

Secondly, assuming first question is done, what is the way of making it continous so that it does not stop after receiving and sending data once. Because currently, when it makes the data transfer, it stops working.

Thanks again for the all support and again please do not hesitate to ask me for the further details i am missing any.

You should be able to do something this simple:

Run something like this on your pi:

import socket

s = socket.socket()
host = ""
port = 12345
s.bind((host, port))
s.listen(5)

while True:
    try:
        clientsock, addr = s.accept()
    except OSError:
        continue
    message = clientsock.recv(20)

    #the code you want to run
    print("doing %s" % message)

    clientsock.close()

And this on your server every time you want the pi to take action:

import socket

s = socket.socket()
host = "0.0.0.0"
port = 12345
s.connect((host, port))
s.send("foo")
s.close()

Have a look at Pyro4 . It lets you avoid having to write network code at all and just write code that calls remote Python objects as if they were running on the same machine. In your case, the server could call a normal Python method on your Raspberry Pi to do something. It has many features but you can start with something extremely simple.

raspberry pi code:

import Pyro4

@Pyro4.expose
class Raspberry:
    def something(self, arg):
        print("called with:", arg)
        return "hi from pi"

Pyro4.Daemon.serveSimple({Raspberry: "raspberry"})

server code to make the pi do something:

import Pyro4
rasp = Pyro4.Proxy("PYRONAME:raspberry")
print(rasp.something(42))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM