初始化提交
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/**************************************************************
|
||||
* This is just a test of Blynk library build in Arduino IDE
|
||||
*
|
||||
* You should NOT flash this program
|
||||
* to your hardware or try to run it.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
#if defined(ARDUINO_AVR_GEMMA) \
|
||||
|| defined(ARDUINO_attiny) \
|
||||
|| defined(ARDUINO_AVR_TRINKET3) \
|
||||
|| defined(ARDUINO_AVR_TRINKET5) \
|
||||
|| defined(ARDUINO_AVR_DIGISPARK)
|
||||
|
||||
#define BLYNK_NO_INFO
|
||||
#define BLYNK_NO_BUILTIN
|
||||
|
||||
#define SKIP_WRITES_TEST
|
||||
|
||||
#endif
|
||||
|
||||
#include <BlynkSimpleUserDefined.h>
|
||||
|
||||
char auth[] = "12345678901234567890123456789012";
|
||||
|
||||
volatile uint8_t test;
|
||||
|
||||
// This function is used by Blynk to receive data
|
||||
size_t BlynkStreamRead(void* buf, size_t len)
|
||||
{
|
||||
uint8_t* byte_buff = (uint8_t*)buf;
|
||||
size_t res = len;
|
||||
while (len--) {
|
||||
*byte_buff++ = test;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// This function is used by Blynk to send data
|
||||
size_t BlynkStreamWrite(const void* buf, size_t len)
|
||||
{
|
||||
uint8_t* byte_buff = (uint8_t*)buf;
|
||||
size_t res = len;
|
||||
while (len--) {
|
||||
test = *byte_buff++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Blynk.begin(auth);
|
||||
Blynk.connect();
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V3)
|
||||
{
|
||||
test = param.asInt();
|
||||
}
|
||||
|
||||
BLYNK_READ(V4)
|
||||
{
|
||||
Blynk.virtualWrite(V10, millis(), BlynkFreeRam());
|
||||
|
||||
Blynk.virtualWrite(V10, 1, 1U);
|
||||
Blynk.virtualWrite(V10, 1L, 1UL);
|
||||
Blynk.virtualWrite(V10, 1LL, 1ULL);
|
||||
|
||||
#ifndef SKIP_WRITES_TEST
|
||||
|
||||
Blynk.virtualWrite(V10, (int8_t)1, (uint8_t)1);
|
||||
Blynk.virtualWrite(V10, (int16_t)1, (uint16_t)1);
|
||||
Blynk.virtualWrite(V10, (int32_t)1, (uint32_t)1);
|
||||
//Blynk.virtualWrite(V10, (int64_t)1, (uint64_t)1);
|
||||
|
||||
Blynk.virtualWrite(V10, (size_t)1);
|
||||
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
Blynk.virtualWrite(V10, (float)1.0F);
|
||||
Blynk.virtualWrite(V10, (double)1.0);
|
||||
#endif
|
||||
|
||||
Blynk.virtualWrite(V10, String("Some string as String)"));
|
||||
Blynk.virtualWrite(V10, "Some string from RAM");
|
||||
|
||||
Blynk.virtualWrite(V10, BLYNK_F("Some string from Flash"));
|
||||
|
||||
BlynkParamAllocated param(128);
|
||||
Blynk.virtualWrite(V10, param);
|
||||
|
||||
Blynk.virtualWriteBinary(V10, "buffer", 6);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
bool hasIncomingData = (test > 0);
|
||||
|
||||
if (!Blynk.run(hasIncomingData)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/**************************************************************
|
||||
* This is just a test of Blynk library memory footprint.
|
||||
* It doesn't use serial, wifi, ethernet or any other library.
|
||||
* It uses a volatile variable to simulate server stream.
|
||||
*
|
||||
* You should NOT flash this program
|
||||
* to your hardware or try to run it.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
//#define ENABLE_MINIMIZATION
|
||||
#define ENABLE_HANDLERS
|
||||
|
||||
#ifdef ENABLE_MINIMIZATION
|
||||
#define BLYNK_NO_BUILTIN
|
||||
#define BLYNK_NO_INFO
|
||||
#define BLYNK_NO_FLOAT
|
||||
#endif
|
||||
|
||||
#include <BlynkSimpleUserDefined.h>
|
||||
|
||||
char auth[] = "12345678901234567890123456789012";
|
||||
|
||||
volatile uint8_t test;
|
||||
|
||||
// This function is used by Blynk to receive data
|
||||
size_t BlynkStreamRead(void* buf, size_t len)
|
||||
{
|
||||
uint8_t* byte_buff = (uint8_t*)buf;
|
||||
size_t res = len;
|
||||
while (len--) {
|
||||
*byte_buff++ = test;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// This function is used by Blynk to send data
|
||||
size_t BlynkStreamWrite(const void* buf, size_t len)
|
||||
{
|
||||
uint8_t* byte_buff = (uint8_t*)buf;
|
||||
size_t res = len;
|
||||
while (len--) {
|
||||
test = *byte_buff++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Blynk.begin(auth);
|
||||
Blynk.connect();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HANDLERS
|
||||
|
||||
BLYNK_CONNECTED()
|
||||
{
|
||||
test = 1;
|
||||
}
|
||||
|
||||
BLYNK_DISCONNECTED()
|
||||
{
|
||||
test = 2;
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V3)
|
||||
{
|
||||
test = param.asInt();
|
||||
}
|
||||
|
||||
BLYNK_READ(V4)
|
||||
{
|
||||
Blynk.virtualWrite(V4, millis(), BlynkFreeRam());
|
||||
}
|
||||
|
||||
#endif /* ENABLE_HANDLERS */
|
||||
|
||||
void loop()
|
||||
{
|
||||
bool hasIncomingData = (test > 0);
|
||||
|
||||
if (!Blynk.run(hasIncomingData)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
183
arduino-cli/libraries/Blynk/tests/GenerateJSON/GenerateJSON.ino
Normal file
183
arduino-cli/libraries/Blynk/tests/GenerateJSON/GenerateJSON.ino
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <Blynk.h>
|
||||
#include <Blynk/BlynkDetectDevice.h>
|
||||
|
||||
/*
|
||||
* Pins Quantity
|
||||
*/
|
||||
|
||||
#if defined(NUM_DIGITAL_PINS)
|
||||
#define BOARD_DIGITAL_MAX int(NUM_DIGITAL_PINS)
|
||||
#elif defined(PINS_COUNT)
|
||||
#define BOARD_DIGITAL_MAX int(PINS_COUNT)
|
||||
#else
|
||||
#warning "BOARD_DIGITAL_MAX not detected"
|
||||
#define BOARD_DIGITAL_MAX 32
|
||||
#endif
|
||||
|
||||
#if defined(NUM_ANALOG_INPUTS)
|
||||
#define BOARD_ANALOG_IN_MAX int(NUM_ANALOG_INPUTS)
|
||||
#else
|
||||
#warning "BOARD_ANALOG_IN_MAX not detected"
|
||||
#define BOARD_ANALOG_IN_MAX 0
|
||||
#endif
|
||||
|
||||
#if defined(BLYNK_USE_128_VPINS)
|
||||
#define BOARD_VIRTUAL_MAX 127
|
||||
#else
|
||||
#define BOARD_VIRTUAL_MAX 31
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pins Functions
|
||||
*/
|
||||
|
||||
#ifndef digitalPinHasPWM
|
||||
#warning "No digitalPinHasPWM"
|
||||
#define digitalPinHasPWM(x) false
|
||||
#endif
|
||||
|
||||
#if !defined(analogInputToDigitalPin)
|
||||
#warning "No analogInputToDigitalPin"
|
||||
#define analogInputToDigitalPin(x) -1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pins Ranges
|
||||
*/
|
||||
|
||||
#if !defined(BOARD_PWM_MAX)
|
||||
#if defined(PWMRANGE)
|
||||
#define BOARD_PWM_MAX PWMRANGE
|
||||
#elif defined(PWM_RESOLUTION)
|
||||
#define BOARD_PWM_MAX ((2^(PWM_RESOLUTION))-1)
|
||||
#else
|
||||
#warning "Cannot detect BOARD_PWM_MAX"
|
||||
#define BOARD_PWM_MAX 255
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOARD_ANALOG_MAX)
|
||||
#if defined(ADC_RESOLUTION)
|
||||
#define BOARD_ANALOG_MAX ((2^(ADC_RESOLUTION))-1)
|
||||
#else
|
||||
#warning "Cannot detect BOARD_ANALOG_MAX"
|
||||
#define BOARD_ANALOG_MAX 1023
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(clockCyclesPerMicrosecond)
|
||||
#define BOARD_INFO_MHZ clockCyclesPerMicrosecond()
|
||||
#elif defined(F_CPU)
|
||||
#define BOARD_INFO_MHZ ((F_CPU)/1000000UL)
|
||||
#endif
|
||||
|
||||
|
||||
struct Ser {
|
||||
template<typename T, typename... Args>
|
||||
void print(T last) {
|
||||
Serial.print(last);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void print(T head, Args... tail) {
|
||||
Serial.print(head);
|
||||
print(tail...);
|
||||
}
|
||||
} ser;
|
||||
|
||||
const char* JS[] = {
|
||||
"\n"
|
||||
"{\n"
|
||||
" ",
|
||||
"\"map\": {\n"
|
||||
" \"digital\": {\n"
|
||||
" \"pins\": {\n"
|
||||
" ", "\n"
|
||||
" },\n"
|
||||
" \"ops\": [ \"dr\", \"dw\" ]\n"
|
||||
" },\n"
|
||||
" \"analog\": {\n"
|
||||
" \"pins\": {\n"
|
||||
" ", "\n"
|
||||
" },\n"
|
||||
" \"ops\": [ \"dr\", \"dw\", \"ar\" ],\n"
|
||||
" \"arRange\": [ 0, ", " ]\n"
|
||||
" },\n"
|
||||
" \"pwm\": {\n"
|
||||
" \"pins\": [\n"
|
||||
" ", "\n"
|
||||
" ],\n"
|
||||
" \"ops\": [ \"aw\" ],\n"
|
||||
" \"awRange\": [ 0, ", " ]\n"
|
||||
" },\n"
|
||||
" \"virtual\": {\n"
|
||||
" \"pinsRange\": [ 0, ", " ],\n"
|
||||
" \"ops\": [ \"vr\", \"vw\" ]\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ser.print(JS[0]);
|
||||
ser.print("\"name\": \"", BLYNK_INFO_DEVICE, "\",\n ");
|
||||
#ifdef BLYNK_INFO_CPU
|
||||
ser.print("\"cpu\": \"", BLYNK_INFO_CPU, "\",\n ");
|
||||
#endif
|
||||
#ifdef BOARD_INFO_MHZ
|
||||
ser.print("\"mhz\": ", BOARD_INFO_MHZ, ",\n ");
|
||||
#endif
|
||||
ser.print(JS[1]);
|
||||
|
||||
for (int i = 0; i < BOARD_DIGITAL_MAX; i++) {
|
||||
ser.print("\"D", i, "\": ", i);
|
||||
if (i % 5 != 4) {
|
||||
ser.print(", ");
|
||||
} else {
|
||||
ser.print(",\n ");
|
||||
}
|
||||
}
|
||||
|
||||
ser.print(JS[2]);
|
||||
|
||||
for (int i = 0; i < BOARD_ANALOG_IN_MAX; i++) {
|
||||
int pin = analogInputToDigitalPin(i);
|
||||
if (pin != -1) {
|
||||
ser.print("\"A", i, "\": ", pin);
|
||||
if (i % 5 != 4) {
|
||||
ser.print(", ");
|
||||
} else {
|
||||
ser.print(",\n ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ser.print(JS[3]);
|
||||
ser.print(BOARD_ANALOG_MAX);
|
||||
ser.print(JS[4]);
|
||||
|
||||
for (int i = 0; i < BOARD_DIGITAL_MAX; i++) {
|
||||
bool hasPWM = digitalPinHasPWM(i);
|
||||
//bool hasInt = digitalPinToInterrupt(i) != NOT_AN_INTERRUPT;
|
||||
|
||||
if (hasPWM) {
|
||||
ser.print("\"D", i, "\", ");
|
||||
}
|
||||
}
|
||||
|
||||
ser.print(JS[5]);
|
||||
ser.print(BOARD_PWM_MAX);
|
||||
ser.print(JS[6]);
|
||||
ser.print(BOARD_VIRTUAL_MAX);
|
||||
ser.print(JS[7]);
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This utility allows you to cross-connect two serial channels
|
||||
* using any Arduino-compatible hardware.
|
||||
*
|
||||
* This is usefull for:
|
||||
* Checking wiring
|
||||
* Converting baud rate
|
||||
* Sending AT commands
|
||||
* etc.
|
||||
*
|
||||
* Popular AT command sets:
|
||||
* ESP8266: http://www.espressif.com/sites/default/files/4a-esp8266_at_instruction_set_en_v1.5.4_0.pdf
|
||||
* SIM800L: https://www.itead.cc/wiki/images/6/6f/SIM800_Series_AT_Command_Manual_V1.05.pdf
|
||||
* XBee: https://cdn.sparkfun.com/learn/materials/29/22AT%20Commands.pdf
|
||||
*/
|
||||
|
||||
#define ser1 Serial
|
||||
|
||||
#if defined(HAVE_HWSERIAL1)
|
||||
#define ser2 Serial1
|
||||
#else
|
||||
#warning Using Software Serial!
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial SerialSw(2, 3);
|
||||
#define ser2 SerialSw
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
ser1.begin(9600);
|
||||
while (!ser1);
|
||||
delay(10);
|
||||
ser2.begin(9600);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (ser1.available()) {
|
||||
int c = ser1.read();
|
||||
if (!parseCommands(c)) {
|
||||
ser2.write(c);
|
||||
}
|
||||
}
|
||||
if (ser2.available()) {
|
||||
ser1.write(ser2.read());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special commands:
|
||||
* !speed=1000000 (after ESP8266 command: AT+UART_CUR=1000000,8,1,0,0)
|
||||
*/
|
||||
|
||||
char cmd_prefix[] = "!speed=";
|
||||
uint8_t cmd_prefix_idx = 0;
|
||||
|
||||
bool parseCommands(int c) {
|
||||
if (c == cmd_prefix[cmd_prefix_idx]) {
|
||||
cmd_prefix_idx++;
|
||||
if (cmd_prefix_idx >= sizeof(cmd_prefix) - 1) {
|
||||
String cmd = ser1.readStringUntil('\n');
|
||||
long baud = cmd.toInt();
|
||||
ser1.print("Speed:"); ser1.println(baud);
|
||||
ser2.begin(baud);
|
||||
cmd_prefix_idx = 0;
|
||||
}
|
||||
return true;
|
||||
} else if (cmd_prefix_idx > 0) {
|
||||
ser2.write(cmd_prefix, cmd_prefix_idx);
|
||||
cmd_prefix_idx = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
176
arduino-cli/libraries/Blynk/tests/loopback.py
Normal file
176
arduino-cli/libraries/Blynk/tests/loopback.py
Normal file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""USAGE: loopback.py [options]
|
||||
|
||||
Options:
|
||||
--bind=S address of server to connect (default: any)
|
||||
--port=N serial port, a number or a device name (defualt: 8888)
|
||||
--sndbuf=N SO_SNDBUF override (default: no override)
|
||||
--rcvbuf=N SO_RCVBUF override (default: no override)
|
||||
--nodelay enable TCP_NODELAY
|
||||
--msg=S message content (default: 'message')
|
||||
--qty=N amount of messsages (default: 10)
|
||||
--sleep=F delay between sending messages (default: 1.0)
|
||||
--freq=N messages per second (inverse of sleep) (default: 1)
|
||||
|
||||
This is a pseudo-server that sends predefined pattern to any connected client.
|
||||
It is used to test transport behaviour and throughput.
|
||||
|
||||
Author: Volodymyr Shymanskyy
|
||||
License: The MIT license
|
||||
"""
|
||||
|
||||
import select, socket, struct
|
||||
import os, sys, time, getopt
|
||||
from threading import Thread
|
||||
|
||||
# Configuration options
|
||||
|
||||
# Parse command line options
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hb:p:",
|
||||
["help", "bind=", "port=", "sndbuf=", "rcvbuf=", "nodelay", "sleep=", "qty=", "freq=", "msg=", "dump"])
|
||||
except getopt.GetoptError:
|
||||
print >>sys.stderr, __doc__
|
||||
sys.exit(2)
|
||||
|
||||
# Default options
|
||||
HOST = '' # Bind to all interfaces
|
||||
PORT = 8888 # Bind to port 8888
|
||||
NODELAY = 0 # No TCP_NODELAY
|
||||
SNDBUF = 0 # No SNDBUF override
|
||||
RCVBUF = 0 # No RCVBUF override
|
||||
MSG_QTY = 10 # Amount of messages
|
||||
SLEEP = 1.0 # Wait some time between IO
|
||||
MSG = "message" # Message
|
||||
DUMP = 0
|
||||
|
||||
for o, v in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print __doc__
|
||||
sys.exit()
|
||||
elif o in ("-b", "--bind"):
|
||||
HOST = v
|
||||
elif o in ("-p", "--port"):
|
||||
PORT = int(v)
|
||||
elif o in ("--sndbuf",):
|
||||
SNDBUF = int(v)
|
||||
elif o in ("--rcvbuf",):
|
||||
RCVBUF = int(v)
|
||||
elif o in ("--nodelay",):
|
||||
NODELAY = 1
|
||||
elif o in ("--sleep",):
|
||||
SLEEP = float(v)
|
||||
elif o in ("--freq",):
|
||||
SLEEP = 1.0/float(v)
|
||||
elif o in ("--qty",):
|
||||
MSG_QTY = int(v)
|
||||
elif o in ("--msg",):
|
||||
MSG = v
|
||||
elif o in ("--dump",):
|
||||
DUMP = 1
|
||||
|
||||
# Print utilities
|
||||
|
||||
start_time = time.time()
|
||||
def log(msg):
|
||||
print "[{:7.3f}] {:}".format(float(time.time() - start_time), msg)
|
||||
|
||||
draw_col = 0
|
||||
def draw(c):
|
||||
global draw_col
|
||||
if not DUMP:
|
||||
sys.stdout.write(c)
|
||||
draw_col = (draw_col + 1) % 120
|
||||
if draw_col:
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
sys.stdout.write("\n")
|
||||
|
||||
def dump(msg):
|
||||
if DUMP:
|
||||
log(msg)
|
||||
|
||||
def receive(sock, length):
|
||||
d = []
|
||||
l = 0
|
||||
while l < length:
|
||||
r = sock.recv(length-l)
|
||||
if not r:
|
||||
return ''
|
||||
d.append(r)
|
||||
l += len(r)
|
||||
return ''.join(d)
|
||||
|
||||
# Threads
|
||||
|
||||
def readthread(conn, addr):
|
||||
global msgs_in
|
||||
while(msgs_in < MSG_QTY):
|
||||
data = receive(conn, len(MSG))
|
||||
if data != MSG:
|
||||
log("Data is wrong:" + data)
|
||||
#break
|
||||
draw('v')
|
||||
dump("> " + data)
|
||||
msgs_in += 1
|
||||
|
||||
|
||||
def writethread(conn, addr):
|
||||
global msgs_out
|
||||
while (msgs_out < MSG_QTY):
|
||||
conn.sendall(MSG)
|
||||
draw('.')
|
||||
dump("< " + MSG)
|
||||
msgs_out += 1
|
||||
time.sleep(SLEEP)
|
||||
|
||||
|
||||
# Main code
|
||||
|
||||
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
# Set SO_REUSEADDR, this is needed to ignore WAIT state on next run
|
||||
serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
serv.bind((HOST, PORT))
|
||||
except socket.error as msg:
|
||||
log('Bind failed. Error Code: {0}, Msg: {1}'.format(str(msg[0]), msg[1]))
|
||||
sys.exit()
|
||||
|
||||
serv.listen(1)
|
||||
log('Listening on port %d' % PORT)
|
||||
|
||||
# Wait for clients
|
||||
#while True:
|
||||
conn, addr = serv.accept()
|
||||
log('Connection from {0}:{1}'.format(addr[0], str(addr[1])))
|
||||
if NODELAY != 0:
|
||||
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
if SNDBUF != 0:
|
||||
sndbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||
log('Default SNDBUF %s changed to %s' % (sndbuf, SNDBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SNDBUF)
|
||||
if RCVBUF != 0:
|
||||
rcvbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
||||
log('Default RCVBUF %s changed to %s' % (rcvbuf, RCVBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCVBUF)
|
||||
|
||||
proc_start = time.time()
|
||||
msgs_in = 0
|
||||
msgs_out = 0
|
||||
|
||||
wt = Thread(target=readthread, args=(conn, addr))
|
||||
rt = Thread(target=writethread, args=(conn, addr))
|
||||
|
||||
wt.start()
|
||||
rt.start()
|
||||
|
||||
wt.join()
|
||||
rt.join()
|
||||
|
||||
draw("\n")
|
||||
log("Time %3.4f" % (time.time() - proc_start))
|
||||
log("Sent {0} messages".format(msgs_out))
|
||||
log("Recv {0} messages".format(msgs_in))
|
||||
conn.close()
|
||||
237
arduino-cli/libraries/Blynk/tests/pseudo-library.py
Normal file
237
arduino-cli/libraries/Blynk/tests/pseudo-library.py
Normal file
@@ -0,0 +1,237 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
This is a pseudo-library implementation
|
||||
|
||||
Example:
|
||||
./pseudo-library.py -t b168ccc8c8734fad98323247afbc1113 --dump
|
||||
|
||||
Author: Volodymyr Shymanskyy
|
||||
License: The MIT license
|
||||
'''
|
||||
import select, socket, struct
|
||||
import os, sys, time, getopt
|
||||
from threading import Thread
|
||||
|
||||
# Configuration options
|
||||
|
||||
# Parse command line options
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hs:p:t:",
|
||||
["help", "server=", "port=", "token=", "sndbuf=", "rcvbuf=", "nodelay=", "dump"])
|
||||
except getopt.GetoptError:
|
||||
print >>sys.stderr, __doc__
|
||||
sys.exit(2)
|
||||
|
||||
# Default options
|
||||
SERVER = "blynk-cloud.com"
|
||||
PORT = 80
|
||||
NODELAY = 1 # TCP_NODELAY
|
||||
SNDBUF = 0 # No SNDBUF override
|
||||
RCVBUF = 0 # No RCVBUF override
|
||||
TOKEN = "YourAuthToken"
|
||||
DUMP = 0
|
||||
|
||||
for o, v in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print __doc__
|
||||
sys.exit()
|
||||
elif o in ("-s", "--server"):
|
||||
SERVER = v
|
||||
elif o in ("-p", "--port"):
|
||||
PORT = int(v)
|
||||
elif o in ("-t", "--token"):
|
||||
TOKEN = v
|
||||
elif o in ("--sndbuf",):
|
||||
SNDBUF = int(v)
|
||||
elif o in ("--rcvbuf",):
|
||||
RCVBUF = int(v)
|
||||
elif o in ("--nodelay",):
|
||||
NODELAY = int(v)
|
||||
elif o in ("--dump",):
|
||||
DUMP = 1
|
||||
|
||||
|
||||
# Blynk protocol helpers
|
||||
|
||||
hdr = struct.Struct("!BHH")
|
||||
|
||||
class MsgType:
|
||||
RSP = 0
|
||||
LOGIN = 2
|
||||
PING = 6
|
||||
BRIDGE = 15
|
||||
HW = 20
|
||||
|
||||
class MsgStatus:
|
||||
OK = 200
|
||||
|
||||
def hw(*args):
|
||||
# Convert params to string and join using \0
|
||||
data = "\0".join(map(str, args))
|
||||
dump("< " + " ".join(map(str, args)))
|
||||
# Prepend HW command header
|
||||
return hdr.pack(MsgType.HW, genMsgId(), len(data)) + data
|
||||
|
||||
def handle_hw(data):
|
||||
params = data.split("\0")
|
||||
cmd = params.pop(0)
|
||||
if cmd == 'info':
|
||||
pass
|
||||
|
||||
### DIRECT pin operations
|
||||
elif cmd == 'pm':
|
||||
pairs = zip(params[0::2], params[1::2])
|
||||
for (pin, mode) in pairs:
|
||||
pin = int(pin)
|
||||
if mode == 'in':
|
||||
log("Pin %d mode INPUT" % pin)
|
||||
elif mode == 'out':
|
||||
log("Pin %d mode OUTPUT" % pin)
|
||||
elif mode == 'pu':
|
||||
log("Pin %d mode INPUT_PULLUP" % pin)
|
||||
elif mode == 'pd':
|
||||
log("Pin %d mode INPUT_PULLDOWN" % pin)
|
||||
else:
|
||||
log("Unknown pin %d mode: %s" % (pin, mode))
|
||||
|
||||
elif cmd == 'dw':
|
||||
pin = int(params.pop(0))
|
||||
val = params.pop(0)
|
||||
log("Digital write pin %d, value %s" % (pin, val))
|
||||
|
||||
elif cmd == 'aw':
|
||||
pin = int(params.pop(0))
|
||||
val = params.pop(0)
|
||||
log("Analog write pin %d, value %s" % (pin, val))
|
||||
|
||||
elif cmd == 'dr': # This should read digital pin
|
||||
pin = int(params.pop(0))
|
||||
log("Digital read pin %d" % pin)
|
||||
conn.sendall(hw("dw", pin, 1)) # Send value
|
||||
|
||||
elif cmd == 'ar': # This should do ADC read
|
||||
pin = int(params.pop(0))
|
||||
log("Analog read pin %d" % pin)
|
||||
conn.sendall(hw("aw", pin, 123)) # Send value
|
||||
|
||||
### VIRTUAL pin operations
|
||||
elif cmd == 'vw': # This should call user handler
|
||||
pin = int(params.pop(0))
|
||||
val = params.pop(0)
|
||||
log("Virtual write pin %d, value %s" % (pin, val))
|
||||
|
||||
elif cmd == 'vr': # This should call user handler
|
||||
pin = int(params.pop(0))
|
||||
log("Virtual read pin %d" % pin)
|
||||
conn.sendall(hw("vw", pin, "hello")) # Send value
|
||||
|
||||
else:
|
||||
log("Unknown HW cmd: %s" % cmd)
|
||||
|
||||
static_msg_id = 1
|
||||
def genMsgId():
|
||||
global static_msg_id
|
||||
static_msg_id += 1
|
||||
return static_msg_id
|
||||
|
||||
# Other utilities
|
||||
|
||||
start_time = time.time()
|
||||
def log(msg):
|
||||
print "[{:7.3f}] {:}".format(float(time.time() - start_time), msg)
|
||||
|
||||
def dump(msg):
|
||||
if DUMP:
|
||||
log(msg)
|
||||
|
||||
def receive(sock, length):
|
||||
d = []
|
||||
l = 0
|
||||
while l < length:
|
||||
r = ''
|
||||
try:
|
||||
r = sock.recv(length-l)
|
||||
except socket.timeout:
|
||||
continue
|
||||
if not r:
|
||||
return ''
|
||||
d.append(r)
|
||||
l += len(r)
|
||||
return ''.join(d)
|
||||
|
||||
# Threads
|
||||
|
||||
def readthread(conn):
|
||||
while (True):
|
||||
data = receive(conn, hdr.size)
|
||||
if not data:
|
||||
break
|
||||
msg_type, msg_id, msg_len = hdr.unpack(data)
|
||||
dump("Got {0}, {1}, {2}".format(msg_type, msg_id, msg_len))
|
||||
if msg_type == MsgType.RSP:
|
||||
pass
|
||||
elif msg_type == MsgType.PING:
|
||||
log("Got ping")
|
||||
# Send Pong
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
elif msg_type == MsgType.HW or msg_type == MsgType.BRIDGE:
|
||||
data = receive(conn, msg_len)
|
||||
# Print HW message
|
||||
dump("> " + " ".join(data.split("\0")))
|
||||
handle_hw(data)
|
||||
else:
|
||||
log("Unknown msg type")
|
||||
break
|
||||
|
||||
|
||||
def writethread(conn):
|
||||
while (True):
|
||||
time.sleep(10)
|
||||
log("Sending heartbeat...")
|
||||
conn.sendall(hdr.pack(MsgType.PING, genMsgId(), 0))
|
||||
|
||||
# Main code
|
||||
log('Connecting to %s:%d' % (SERVER, PORT))
|
||||
try:
|
||||
conn = socket.create_connection((SERVER, PORT), 3)
|
||||
except:
|
||||
log("Can't connect")
|
||||
sys.exit(1)
|
||||
|
||||
if NODELAY != 0:
|
||||
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
if SNDBUF != 0:
|
||||
sndbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||
log('Default SNDBUF %s changed to %s' % (sndbuf, SNDBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SNDBUF)
|
||||
if RCVBUF != 0:
|
||||
rcvbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
||||
log('Default RCVBUF %s changed to %s' % (rcvbuf, RCVBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCVBUF)
|
||||
|
||||
# Authenticate
|
||||
conn.sendall(hdr.pack(MsgType.LOGIN, genMsgId(), len(TOKEN)))
|
||||
conn.sendall(TOKEN)
|
||||
data = receive(conn, hdr.size)
|
||||
if not data:
|
||||
log("Auth timeout")
|
||||
sys.exit(1)
|
||||
|
||||
msg_type, msg_id, status = hdr.unpack(data)
|
||||
dump("Got {0}, {1}, {2}".format(msg_type, msg_id, status))
|
||||
|
||||
if status != MsgStatus.OK:
|
||||
log("Auth failed: %d" % status)
|
||||
sys.exit(1)
|
||||
|
||||
wt = Thread(target=readthread, args=(conn,))
|
||||
rt = Thread(target=writethread, args=(conn,))
|
||||
|
||||
wt.start()
|
||||
rt.start()
|
||||
|
||||
wt.join()
|
||||
rt.join()
|
||||
|
||||
conn.close()
|
||||
210
arduino-cli/libraries/Blynk/tests/pseudo-server-ar-mt.py
Normal file
210
arduino-cli/libraries/Blynk/tests/pseudo-server-ar-mt.py
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
This is a pseudo-server that sends predefined pattern to any connected client.
|
||||
It is used to test transport behaviour and throughput.
|
||||
|
||||
If you want to use it with a sketch, connect your PC and Blynk-enabled device
|
||||
into the same network and configure Blynk to connect to this pseudo-server:
|
||||
|
||||
IPAddress serv(192,168,0,105); // IP address of your PC
|
||||
Blynk.begin(auth, serv, 8888);
|
||||
|
||||
Author: Volodymyr Shymanskyy
|
||||
License: The MIT license
|
||||
'''
|
||||
import select, socket, struct
|
||||
import os, sys, time, getopt
|
||||
from threading import Thread
|
||||
|
||||
# Configuration options
|
||||
|
||||
# Parse command line options
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hb:p:",
|
||||
["help", "bind=", "port=", "sndbuf=", "rcvbuf=", "nodelay", "sleep=", "qty=", "freq=", "pin=", "dump"])
|
||||
except getopt.GetoptError:
|
||||
print >>sys.stderr, __doc__
|
||||
sys.exit(2)
|
||||
|
||||
# Default options
|
||||
HOST = '' # Bind to all interfaces
|
||||
PORT = 8888 # Bind to port 8888
|
||||
NODELAY = 0 # No TCP_NODELAY
|
||||
SNDBUF = 0 # No SNDBUF override
|
||||
RCVBUF = 0 # No RCVBUF override
|
||||
MSG_QTY = 10 # Amount of messages
|
||||
SLEEP = 1.0 # Wait some time between IO
|
||||
HW_PIN = "A0" # Pin #
|
||||
DUMP = 0
|
||||
|
||||
for o, v in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print __doc__
|
||||
sys.exit()
|
||||
elif o in ("-b", "--bind"):
|
||||
HOST = v
|
||||
elif o in ("-p", "--port"):
|
||||
PORT = int(v)
|
||||
elif o in ("--sndbuf",):
|
||||
SNDBUF = int(v)
|
||||
elif o in ("--rcvbuf",):
|
||||
RCVBUF = int(v)
|
||||
elif o in ("--nodelay",):
|
||||
NODELAY = 1
|
||||
elif o in ("--sleep",):
|
||||
SLEEP = float(v)
|
||||
elif o in ("--freq",):
|
||||
SLEEP = 1.0/float(v)
|
||||
elif o in ("--qty",):
|
||||
MSG_QTY = int(v)
|
||||
elif o in ("--pin",):
|
||||
HW_PIN = int(v)
|
||||
elif o in ("--dump",):
|
||||
DUMP = 1
|
||||
|
||||
|
||||
# Blynk protocol helpers
|
||||
|
||||
hdr = struct.Struct("!BHH")
|
||||
|
||||
class MsgType:
|
||||
RSP = 0
|
||||
LOGIN = 2
|
||||
PING = 6
|
||||
HW = 20
|
||||
|
||||
class MsgStatus:
|
||||
OK = 200
|
||||
|
||||
def hw(*args):
|
||||
# Convert params to string and join using \0
|
||||
data = "\0".join(map(str, args))
|
||||
dump("< " + " ".join(map(str, args)))
|
||||
# Prepend HW command header
|
||||
return hdr.pack(MsgType.HW, 1, len(data)) + data
|
||||
|
||||
# Print utilities
|
||||
|
||||
start_time = time.time()
|
||||
def log(msg):
|
||||
print "[{:7.3f}] {:}".format(float(time.time() - start_time), msg)
|
||||
|
||||
draw_col = 0
|
||||
def draw(c):
|
||||
global draw_col
|
||||
if not DUMP:
|
||||
sys.stdout.write(c)
|
||||
draw_col = (draw_col + 1) % 120
|
||||
if draw_col:
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
sys.stdout.write("\n")
|
||||
|
||||
def dump(msg):
|
||||
if DUMP:
|
||||
log(msg)
|
||||
|
||||
def receive(sock, length):
|
||||
d = []
|
||||
l = 0
|
||||
while l < length:
|
||||
r = sock.recv(length-l)
|
||||
if not r:
|
||||
return ''
|
||||
d.append(r)
|
||||
l += len(r)
|
||||
return ''.join(d)
|
||||
|
||||
# Threads
|
||||
|
||||
def readthread(conn, addr):
|
||||
global msgs_in, authenticated
|
||||
while(msgs_in < MSG_QTY):
|
||||
data = receive(conn, hdr.size)
|
||||
if not data:
|
||||
break
|
||||
msg_type, msg_id, msg_len = hdr.unpack(data)
|
||||
#dump("Got {0}, {1}, {2}".format(msg_type, msg_id, msg_len))
|
||||
if msg_type == MsgType.RSP:
|
||||
pass
|
||||
elif msg_type == MsgType.LOGIN:
|
||||
auth = receive(conn, msg_len)
|
||||
log("Auth {0}".format(auth))
|
||||
# Send auth OK and pin modes
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
conn.sendall(hw("pm", HW_PIN, "in"))
|
||||
authenticated = True
|
||||
elif msg_type == MsgType.PING:
|
||||
log("Ping")
|
||||
# Send Pong
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
elif msg_type == MsgType.HW:
|
||||
data = receive(conn, msg_len)
|
||||
# Print HW messages (just for fun :)
|
||||
draw('v')
|
||||
dump("> " + " ".join(data.split("\0")))
|
||||
msgs_in += 1
|
||||
else:
|
||||
log("Unknown msg type")
|
||||
break
|
||||
|
||||
|
||||
def writethread(conn, addr):
|
||||
global msgs_out, authenticated
|
||||
while (msgs_out < MSG_QTY):
|
||||
if authenticated:
|
||||
conn.sendall(hw("ar", HW_PIN))
|
||||
draw('.')
|
||||
msgs_out += 1
|
||||
time.sleep(SLEEP)
|
||||
|
||||
|
||||
# Main code
|
||||
|
||||
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
# Set SO_REUSEADDR, this is needed to ignore WAIT state on next run
|
||||
serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
serv.bind((HOST, PORT))
|
||||
except socket.error as msg:
|
||||
log('Bind failed. Error Code: {0}, Msg: {1}'.format(str(msg[0]), msg[1]))
|
||||
sys.exit()
|
||||
|
||||
serv.listen(1)
|
||||
log('Listening on port %d' % PORT)
|
||||
|
||||
# Wait for clients
|
||||
#while True:
|
||||
conn, addr = serv.accept()
|
||||
log('Connection from {0}:{1}'.format(addr[0], str(addr[1])))
|
||||
if NODELAY != 0:
|
||||
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
if SNDBUF != 0:
|
||||
sndbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||
log('Default SNDBUF %s changed to %s' % (sndbuf, SNDBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SNDBUF)
|
||||
if RCVBUF != 0:
|
||||
rcvbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
||||
log('Default RCVBUF %s changed to %s' % (rcvbuf, RCVBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCVBUF)
|
||||
|
||||
proc_start = time.time()
|
||||
msgs_in = 0
|
||||
msgs_out = 0
|
||||
authenticated = False
|
||||
|
||||
wt = Thread(target=readthread, args=(conn, addr))
|
||||
rt = Thread(target=writethread, args=(conn, addr))
|
||||
|
||||
wt.start()
|
||||
rt.start()
|
||||
|
||||
wt.join()
|
||||
rt.join()
|
||||
|
||||
draw("\n")
|
||||
log("Time %3.4f" % (time.time() - proc_start))
|
||||
log("Sent {0} messages".format(msgs_out))
|
||||
log("Recv {0} messages".format(msgs_in))
|
||||
conn.close()
|
||||
207
arduino-cli/libraries/Blynk/tests/pseudo-server-ar-select.py
Normal file
207
arduino-cli/libraries/Blynk/tests/pseudo-server-ar-select.py
Normal file
@@ -0,0 +1,207 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
This is a pseudo-server that sends predefined pattern to any connected client.
|
||||
It is used to test transport behaviour and throughput.
|
||||
|
||||
If you want to use it with a sketch, connect your PC and Blynk-enabled device
|
||||
into the same network and configure Blynk to connect to this pseudo-server:
|
||||
|
||||
IPAddress serv(192,168,0,105); // IP address of your PC
|
||||
Blynk.begin(auth, serv, 8888);
|
||||
|
||||
Author: Volodymyr Shymanskyy
|
||||
License: The MIT license
|
||||
'''
|
||||
import select, socket, struct
|
||||
import os, sys, time, getopt
|
||||
from threading import Thread
|
||||
|
||||
# Configuration options
|
||||
|
||||
# Parse command line options
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hb:p:",
|
||||
["help", "bind=", "port=", "sndbuf=", "rcvbuf=", "nodelay", "wait=", "sleep=", "qty=", "dump"])
|
||||
|
||||
# Default options
|
||||
HOST = '' # Bind to all interfaces
|
||||
PORT = 8888 # Bind to port 8888
|
||||
NODELAY = 0 # No TCP_NODELAY
|
||||
SNDBUF = 0 # No SNDBUF override
|
||||
RCVBUF = 0 # No RCVBUF override
|
||||
WAIT = -1 # No select timeout
|
||||
MSG_QTY = 1000 # Amount of messages
|
||||
SLEEP = 0 # Wait some time between IO
|
||||
HW_PIN = 14 # Pin #
|
||||
DUMP = 0
|
||||
|
||||
for o, v in opts:
|
||||
if o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit()
|
||||
elif o in ("-b", "--bind"):
|
||||
HOST = v
|
||||
elif o in ("-p", "--port"):
|
||||
PORT = int(v)
|
||||
elif o in ("--sndbuf",):
|
||||
SNDBUF = int(v)
|
||||
elif o in ("--rcvbuf",):
|
||||
RCVBUF = int(v)
|
||||
elif o in ("--nodelay",):
|
||||
NODELAY = 1
|
||||
elif o in ("--wait",):
|
||||
WAIT = float(v)
|
||||
elif o in ("--sleep",):
|
||||
SLEEP = float(v)
|
||||
elif o in ("--qty",):
|
||||
MSG_QTY = int(v)
|
||||
elif o in ("--pin",):
|
||||
HW_PIN = int(v)
|
||||
elif o in ("--dump",):
|
||||
DUMP = 1
|
||||
|
||||
|
||||
# Blynk protocol helpers
|
||||
|
||||
hdr = struct.Struct("!BHH")
|
||||
|
||||
class MsgType:
|
||||
RSP = 0
|
||||
LOGIN = 2
|
||||
PING = 6
|
||||
HW = 20
|
||||
|
||||
class MsgStatus:
|
||||
OK = 200
|
||||
|
||||
def hw(*args):
|
||||
# Convert params to string and join using \0
|
||||
data = "\0".join(map(str, args))
|
||||
dump("< " + " ".join(map(str, args)))
|
||||
# Prepend HW command header
|
||||
return hdr.pack(MsgType.HW, 1, len(data)) + data
|
||||
|
||||
start_time = time.time()
|
||||
def log(msg):
|
||||
print "[{:7.3f}] {:}".format(float(time.time() - start_time), msg)
|
||||
|
||||
def draw(c):
|
||||
if not DUMP:
|
||||
sys.stdout.write(c)
|
||||
sys.stdout.flush()
|
||||
|
||||
def dump(msg):
|
||||
if DUMP:
|
||||
log(msg)
|
||||
|
||||
def receive(sock, length):
|
||||
d = []
|
||||
l = 0
|
||||
while l < length:
|
||||
r = sock.recv(length-l)
|
||||
if not r:
|
||||
return ''
|
||||
d.append(r)
|
||||
l += len(r)
|
||||
return ''.join(d)
|
||||
|
||||
|
||||
def clientthread(conn, addr):
|
||||
log('Connection from {0}:{1}'.format(addr[0], str(addr[1])))
|
||||
if NODELAY != 0:
|
||||
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
if SNDBUF != 0:
|
||||
sndbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||
log('Default SNDBUF %s changed to %s' % (sndbuf, SNDBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SNDBUF)
|
||||
if RCVBUF != 0:
|
||||
rcvbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
||||
log('Default RCVBUF %s changed to %s' % (rcvbuf, RCVBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCVBUF)
|
||||
|
||||
b = 0
|
||||
msgs_out = 0
|
||||
msgs_in = 0
|
||||
msgs_delta = 0
|
||||
msgs_skip = 0
|
||||
authenticated = False
|
||||
|
||||
proc_start = time.time()
|
||||
|
||||
while(True):
|
||||
if WAIT != -1:
|
||||
rs, ws, es = select.select([conn] , [conn], [conn], WAIT)
|
||||
else:
|
||||
rs, ws, es = select.select([conn] , [conn], [conn])
|
||||
if es:
|
||||
log("Socket error")
|
||||
break;
|
||||
if rs:
|
||||
data = receive(conn, hdr.size)
|
||||
if not data:
|
||||
break
|
||||
msg_type, msg_id, msg_len = hdr.unpack(data)
|
||||
#dump("Got {0}, {1}, {2}".format(msg_type, msg_id, msg_len))
|
||||
if msg_type == MsgType.RSP:
|
||||
pass
|
||||
elif msg_type == MsgType.LOGIN:
|
||||
auth = receive(conn, msg_len)
|
||||
log("Auth {0}".format(auth))
|
||||
# Send auth OK and pin modes
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
conn.sendall(hw("pm", HW_PIN, "in"))
|
||||
authenticated = True
|
||||
elif msg_type == MsgType.PING:
|
||||
log("Ping")
|
||||
# Send Pong
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
elif msg_type == MsgType.HW:
|
||||
data = receive(conn, msg_len)
|
||||
# Print HW messages (just for fun :)
|
||||
draw('v')
|
||||
dump("> " + " ".join(data.split("\0")))
|
||||
msgs_in += 1
|
||||
if msgs_out >= MSG_QTY:
|
||||
msgs_delta += 1
|
||||
else:
|
||||
log("Unknown msg type")
|
||||
break
|
||||
if ws:
|
||||
if authenticated and msgs_out < MSG_QTY:
|
||||
conn.sendall(hw("ar", HW_PIN))
|
||||
draw('.')
|
||||
b = (b + 1) % 256
|
||||
msgs_out += 1
|
||||
elif msgs_in >= MSG_QTY:
|
||||
break
|
||||
else:
|
||||
msgs_skip += 1
|
||||
|
||||
time.sleep(SLEEP)
|
||||
|
||||
draw("\n")
|
||||
log("Time %3.4f" % (time.time() - proc_start))
|
||||
log("Sent {0} messages".format(msgs_out))
|
||||
log("Recv {0} messages (delta: {1}, skip: {2})".format(msgs_in, msgs_delta, msgs_skip))
|
||||
conn.close()
|
||||
|
||||
# Main code
|
||||
|
||||
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
# Set SO_REUSEADDR, this is needed to ignore WAIT state on next run
|
||||
serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
serv.bind((HOST, PORT))
|
||||
except socket.error as msg:
|
||||
log('Bind failed. Error Code: {0}, Msg: {1}'.format(str(msg[0]), msg[1]))
|
||||
sys.exit()
|
||||
|
||||
serv.listen(10)
|
||||
log('Listening on port %d' % PORT)
|
||||
|
||||
# Wait for clients
|
||||
#while True:
|
||||
thread = Thread(target=clientthread, args=serv.accept())
|
||||
thread.start()
|
||||
serv.close()
|
||||
thread.join()
|
||||
212
arduino-cli/libraries/Blynk/tests/pseudo-server-dw-mt.py
Normal file
212
arduino-cli/libraries/Blynk/tests/pseudo-server-dw-mt.py
Normal file
@@ -0,0 +1,212 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
This is a pseudo-server that sends predefined pattern to any connected client.
|
||||
It is used to test transport behaviour and throughput.
|
||||
|
||||
If you want to use it with a sketch, connect your PC and Blynk-enabled device
|
||||
into the same network and configure Blynk to connect to this pseudo-server:
|
||||
|
||||
IPAddress serv(192,168,0,105); // IP address of your PC
|
||||
Blynk.begin(auth, serv, 8888);
|
||||
|
||||
Author: Volodymyr Shymanskyy
|
||||
License: The MIT license
|
||||
'''
|
||||
import select, socket, struct
|
||||
import os, sys, time, getopt
|
||||
from threading import Thread
|
||||
|
||||
# Configuration options
|
||||
|
||||
# Parse command line options
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hb:p:",
|
||||
["help", "bind=", "port=", "sndbuf=", "rcvbuf=", "nodelay", "sleep=", "qty=", "freq=", "pin=", "dump"])
|
||||
except getopt.GetoptError:
|
||||
print >>sys.stderr, __doc__
|
||||
sys.exit(2)
|
||||
|
||||
# Default options
|
||||
HOST = '' # Bind to all interfaces
|
||||
PORT = 8888 # Bind to port 8888
|
||||
NODELAY = 0 # No TCP_NODELAY
|
||||
SNDBUF = 0 # No SNDBUF override
|
||||
RCVBUF = 0 # No RCVBUF override
|
||||
MSG_QTY = 10 # Amount of messages
|
||||
SLEEP = 1.0 # Wait some time between IO
|
||||
HW_PIN = 14 # Pin #
|
||||
DUMP = 0
|
||||
|
||||
for o, v in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print __doc__
|
||||
sys.exit()
|
||||
elif o in ("-b", "--bind"):
|
||||
HOST = v
|
||||
elif o in ("-p", "--port"):
|
||||
PORT = int(v)
|
||||
elif o in ("--sndbuf",):
|
||||
SNDBUF = int(v)
|
||||
elif o in ("--rcvbuf",):
|
||||
RCVBUF = int(v)
|
||||
elif o in ("--nodelay",):
|
||||
NODELAY = 1
|
||||
elif o in ("--sleep",):
|
||||
SLEEP = float(v)
|
||||
elif o in ("--freq",):
|
||||
SLEEP = 1.0/float(v)
|
||||
elif o in ("--qty",):
|
||||
MSG_QTY = int(v)
|
||||
elif o in ("--pin",):
|
||||
HW_PIN = int(v)
|
||||
elif o in ("--dump",):
|
||||
DUMP = 1
|
||||
|
||||
|
||||
# Blynk protocol helpers
|
||||
|
||||
hdr = struct.Struct("!BHH")
|
||||
|
||||
class MsgType:
|
||||
RSP = 0
|
||||
LOGIN = 2
|
||||
PING = 6
|
||||
HW = 20
|
||||
|
||||
class MsgStatus:
|
||||
OK = 200
|
||||
|
||||
def hw(*args):
|
||||
# Convert params to string and join using \0
|
||||
data = "\0".join(map(str, args))
|
||||
dump("< " + " ".join(map(str, args)))
|
||||
# Prepend HW command header
|
||||
return hdr.pack(MsgType.HW, 1, len(data)) + data
|
||||
|
||||
# Print utilities
|
||||
|
||||
start_time = time.time()
|
||||
def log(msg):
|
||||
print "[{:7.3f}] {:}".format(float(time.time() - start_time), msg)
|
||||
|
||||
draw_col = 0
|
||||
def draw(c):
|
||||
global draw_col
|
||||
if not DUMP:
|
||||
sys.stdout.write(c)
|
||||
draw_col = (draw_col + 1) % 120
|
||||
if draw_col:
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
sys.stdout.write("\n")
|
||||
|
||||
def dump(msg):
|
||||
if DUMP:
|
||||
log(msg)
|
||||
|
||||
def receive(sock, length):
|
||||
d = []
|
||||
l = 0
|
||||
while l < length:
|
||||
r = sock.recv(length-l)
|
||||
if not r:
|
||||
return ''
|
||||
d.append(r)
|
||||
l += len(r)
|
||||
return ''.join(d)
|
||||
|
||||
# Threads
|
||||
|
||||
def readthread(conn, addr):
|
||||
global msgs_in, authenticated
|
||||
while(msgs_in < MSG_QTY):
|
||||
data = receive(conn, hdr.size)
|
||||
if not data:
|
||||
break
|
||||
msg_type, msg_id, msg_len = hdr.unpack(data)
|
||||
#dump("Got {0}, {1}, {2}".format(msg_type, msg_id, msg_len))
|
||||
if msg_type == MsgType.RSP:
|
||||
pass
|
||||
elif msg_type == MsgType.LOGIN:
|
||||
auth = receive(conn, msg_len)
|
||||
log("Auth {0}".format(auth))
|
||||
# Send auth OK and pin modes
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
conn.sendall(hw("pm", HW_PIN, "out"))
|
||||
authenticated = True
|
||||
elif msg_type == MsgType.PING:
|
||||
log("Ping")
|
||||
# Send Pong
|
||||
conn.sendall(hdr.pack(MsgType.RSP, msg_id, MsgStatus.OK))
|
||||
elif msg_type == MsgType.HW:
|
||||
data = receive(conn, msg_len)
|
||||
# Print HW messages (just for fun :)
|
||||
draw('v')
|
||||
dump("> " + " ".join(data.split("\0")))
|
||||
msgs_in += 1
|
||||
else:
|
||||
log("Unknown msg type")
|
||||
break
|
||||
|
||||
|
||||
def writethread(conn, addr):
|
||||
global msgs_out, authenticated
|
||||
val = 0
|
||||
while (msgs_out < MSG_QTY):
|
||||
if authenticated:
|
||||
conn.sendall(hw("dw", HW_PIN, val))
|
||||
val = 0 if val else 1
|
||||
draw('.')
|
||||
msgs_out += 1
|
||||
time.sleep(SLEEP)
|
||||
|
||||
|
||||
# Main code
|
||||
|
||||
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
# Set SO_REUSEADDR, this is needed to ignore WAIT state on next run
|
||||
serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
serv.bind((HOST, PORT))
|
||||
except socket.error as msg:
|
||||
log('Bind failed. Error Code: {0}, Msg: {1}'.format(str(msg[0]), msg[1]))
|
||||
sys.exit()
|
||||
|
||||
serv.listen(1)
|
||||
log('Listening on port %d' % PORT)
|
||||
|
||||
# Wait for clients
|
||||
#while True:
|
||||
conn, addr = serv.accept()
|
||||
log('Connection from {0}:{1}'.format(addr[0], str(addr[1])))
|
||||
if NODELAY != 0:
|
||||
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
if SNDBUF != 0:
|
||||
sndbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||
log('Default SNDBUF %s changed to %s' % (sndbuf, SNDBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SNDBUF)
|
||||
if RCVBUF != 0:
|
||||
rcvbuf = conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
||||
log('Default RCVBUF %s changed to %s' % (rcvbuf, RCVBUF))
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCVBUF)
|
||||
|
||||
proc_start = time.time()
|
||||
msgs_in = 0
|
||||
msgs_out = 0
|
||||
authenticated = False
|
||||
|
||||
wt = Thread(target=readthread, args=(conn, addr))
|
||||
rt = Thread(target=writethread, args=(conn, addr))
|
||||
|
||||
wt.start()
|
||||
rt.start()
|
||||
|
||||
wt.join()
|
||||
#rt.join()
|
||||
|
||||
conn.close()
|
||||
draw("\n")
|
||||
log("Time %3.4f" % (time.time() - proc_start))
|
||||
log("Sent {0} messages".format(msgs_out))
|
||||
log("Recv {0} messages".format(msgs_in))
|
||||
Reference in New Issue
Block a user