yaqwsx / SensorStreamer

Stream sensor values from your Android device
MIT License
51 stars 7 forks source link

Better SensorStreamer server mode #1

Open FedeDP opened 6 years ago

FedeDP commented 6 years ago

Hi! Very nice and useful project, thanks!

It would be great if, in Server mode, users could force a "passive" mode, ie: server would only anwer back to http GET calls with desired sensors current data, instead of continuously streaming data.

Moreover, i notice that in server mode, testing with: curl phoneIp:port whenever i close data stream (with ctrl-c), an error pops up on Android app:

Communication Error - Broken pipe

By the way, again really thank you for this app :)

yaqwsx commented 5 years ago

Hi, I am sorry for really late reply. I was thinking about implementing such a feature. However, it hasn't got high enough on my priority list, and I am not sure if it will appear in the future.

Of course, I am glad to accept a pull request with the feature.

engrinak commented 4 years ago

Hi, Do you have any example python script to read the streaming json data? I am having difficulty reading from the url, I think because the file keeps growing. Thanks!

yaqwsx commented 4 years ago

What URL are you referring to? What file? There are no files nor URLs with SensorStreamer. SensorStreamer uses plain old TCP sockets. Could you give me at least a hint of what do you do?

engrinak commented 4 years ago

What URL are you referring to? What file? There are no files nor URLs with SensorStreamer. SensorStreamer uses plain old TCP sockets. Could you give me at least a hint of what do you do?

Hi, thank you for taking the time to write. My main goal is to read my magnetometer data into Python using Pandas, if possible. I am having some luck using sockets. While the app is running on my phone...

import socket s.connect(("192.168.1.4",8000)) data = s.recv(1024) #or however many bytes to read.

In doing this I'm able to at least see something from my phone. Do you have any suggestions on how to parse it?

The main challenge I see is being able to continuously read records. It seems to start in the middle of a string, depending on when I start receiving the data.

Example output: In [23]: s.recv(1024) Out[23]: b'"value":[30.27649,-4.307556,-42.085266]}}\n{"accelerometer":{"timestamp":21643897487557,"value":[-4.0963287,0.089767456,8.895203]},"magneticField":{"timestamp":21643902522957,"value":[31.640625,-3.9642334,-42.747498]}}\n{"accelerometer":{"timestamp":21644097225106,"value":[-4.1246643,0.058303833,8.899918]},"magneticField":{"timestamp":21644089015877,"value":[31.300354,-5.3375244,-43.077087]}}\n{"accelerometer":{"timestamp":21644296962655,"value":[-4.1247406,0.09176636,8.947266]},"magneticField":{"timestamp":21644275508797,"value":[33.00476,-4.650879,-42.747498]}}\n{"accelerometer":{"timestamp":21644496700204,"value":[-4.1573486,0.07891846,8.914047]},"magneticField":{"timestamp":21644462001717,"value":[31.982422,-3.9642334,-43.737793]}}\n{"accelerometer":{"timestamp":21644696437752,"value":[-4.1020355,0.042022705,8.856262]},"magneticField":{"timestamp":21644648494637,"value":[29.936218,-3.9642334,-42.085266]}}\n{"accelerometer":{"timestamp":21644896175301,"value":[-4.1615295,0.062347412,8.919891]},"magneticField":{"'

SebastianGrans commented 4 years ago

The byte packages seem to come in a consistent chunks. I.e. not in the middle of a string.

With this script:

import socket
import numpy as np
import struct # Unpacking bytes

HOST = '192.168.0.100' # The IP of the computer you are running this script on.
PORT = 8000 # A port of your choosing. 

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print("{} connected.".format(addr))
        while True:
            data = conn.recv(1024)

            if not struct.unpack('i', data[:4])[0] == 0 or \
                not data[4] == 128 or \
                not data[-3] == 0: 
                print(data)
                continue

            # big endian long long
            t = struct.unpack('>q', data[5:13])
            # floats
            rx = struct.unpack('>f', data[13:17])
            ry = struct.unpack('>f', data[17:21])
            rz = struct.unpack('>f', data[21:25])
            euler = np.array([rx[0], ry[0], rz[0]])
            print(euler)

I was able to continuously stream the rotation angles.

engrinak commented 4 years ago

Hi Sebastian, It's actually working for me now - I don't know what was the problem - probably restarting the iPython terminal helped. I've been using JSON format and reading that with the socket module in python. Sometimes it sends multiple JSON records, and I just had to split them on the newline (\n) character. Thanks for the reply - are you using binary mode?