Skip to content
Snippets Groups Projects
Unverified Commit 7f36d777 authored by Anton Tetov Johansson's avatar Anton Tetov Johansson
Browse files

Merge branch 'master' into make_pkg

parents df3e7d36 67cbe20e
No related branches found
No related tags found
No related merge requests found
.DEFAULT_GOAL := default .DEFAULT_GOAL := default
LIBSO=1 LIBSO=1
export LIBSO
darknet: darknet:
git submodule init git submodule init
git submodule update git submodule update
default: darknet default: darknet
$(MAKE) -C darknet $(MAKE) LIBSO=$(LIBSO) -C darknet
.PHONY: default
.PHONY: default darknet
<<<<<<<< HEAD:farmbot_yolo/client.py """Communicate with the server at the manufacturer.
'''
Communicate with the server at the manufacturer
Not useful for the local drive script
'''
import paho.mqtt.client as mqtt
import json
import time
from uuid import uuid4 # 通用唯一标识符 ( Universally Unique Identifier )
import logging #日志模块
# values over max (and under min) will be clipped
MAX_X = 2400
MAX_Y = 1200
MAX_Z = 469 # TODO test this one!
def coord(x, y, z):
return {"kind": "coordinate", "args": {"x": x, "y": y, "z": z}} # 返回json 嵌套对象
def move_request(x, y, z):
return {"kind": "rpc_request", # 返回 json对象,对象内含数组
"args": {"label": ""},
"body": [{"kind": "move_absolute",
"args": {"location": coord(x, y, z),
"offset": coord(0, 0, 0),
"speed": 100}}]}
def take_photo_request():
return {"kind": "rpc_request",
"args": {"label": ""}, #label空着是为了在blocking_request中填上uuid,唯一识别码
"body": [{"kind": "take_photo", "args": {}}]}
def clip(v, min_v, max_v):
if v < min_v: return min_v
if v > max_v: return max_v
return v
class FarmbotClient(object):
def __init__(self, device_id, token):
self.device_id = device_id
self.client = mqtt.Client() # 类元素继承了另一个对象
self.client.username_pw_set(self.device_id, token) #传入 用户名和密码
self.client.on_connect = self._on_connect #???
self.client.on_message = self._on_message
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s",
filename='farmbot_client.log',
filemode='a')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter("%(asctime)s\t%(message)s"))
logging.getLogger('').addHandler(console)
self.connected = False
self.client.connect("clever-octopus.rmq.cloudamqp.com", 1883, 60) #前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port
self.client.loop_start()
# 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了
def shutdown(self):
self.client.disconnect()
self.client.loop_stop()
def move(self, x, y, z):
x = clip(x, 0, MAX_X)
y = clip(y, 0, MAX_Y)
z = clip(z, 0, MAX_Z)
status_ok = self._blocking_request(move_request(x, y, z)) # 发请求
logging.info("MOVE (%s,%s,%s) [%s]", x, y, z, status_ok) #存日志,包括执行了什么“move x y z +返回值 ”
def take_photo(self):
# TODO: is this enough? it's issue a request for the photo, but is the actual capture async?
status_ok = self._blocking_request(take_photo_request())
logging.info("TAKE_PHOTO [%s]", status_ok)
def _blocking_request(self, request, retries_remaining=3):
if retries_remaining==0:
logging.error("< blocking request [%s] OUT OF RETRIES", request) #尝试3次,然后在日志中记录错误
return False
self._wait_for_connection() #在哪定义的?
# assign a new uuid for this attempt
self.pending_uuid = str(uuid4())
request['args']['label'] = self.pending_uuid #接收move_request函数的json对象
logging.debug("> blocking request [%s] retries=%d", request, retries_remaining)
# send request off 发送请求
self.rpc_status = None
self.client.publish("bot/" + self.device_id + "/from_clients", json.dumps(request))
# wait for response
timeout_counter = 600 # ~1min 等待1s
while self.rpc_status is None: #这个self.rpc_status 是应答的flag
time.sleep(0.1)
timeout_counter -= 1
if timeout_counter == 0:
logging.warn("< blocking request TIMEOUT [%s]", request) #时间到了,无应答
return self._blocking_request(request, retries_remaining-1)
self.pending_uuid = None
# if it's ok, we're done!
if self.rpc_status == 'rpc_ok':
logging.debug("< blocking request OK [%s]", request)
return True
# if it's not ok, wait a bit and retry
if self.rpc_status == 'rpc_error':
logging.warn("< blocking request ERROR [%s]", request)
time.sleep(1)
return self._blocking_request(request, retries_remaining-1)
# unexpected state (???)
msg = "unexpected rpc_status [%s]" % self.rpc_status
logging.error(msg)
raise Exception(msg)
def _wait_for_connection(self):
# TODO: better way to do all this async event driven rather than with polling :/
timeout_counter = 600 # ~1min
while not self.connected: #用一个self.connected判断连上了没有,若没连上,等待
time.sleep(0.1)
timeout_counter -= 1
if timeout_counter == 0:
raise Exception("unable to connect")
def _on_connect(self, client, userdata, flags, rc):
logging.debug("> _on_connect")
self.client.subscribe("bot/" + self.device_id + "/from_device")
self.connected = True
logging.debug("< _on_connect")
def _on_message(self, client, userdata, msg):
resp = json.loads(msg.payload.decode())
if resp['args']['label'] != 'ping':
logging.debug("> _on_message [%s] [%s]", msg.topic, resp)
if msg.topic.endswith("/from_device") and resp['args']['label'] == self.pending_uuid:
self.rpc_status = resp['kind']
|||||||| 90c14bb:src/client.py
'''
Communicate with the server at the manufacturer
Not useful for the local drive script
'''
import paho.mqtt.client as mqtt
import json
import time
from uuid import uuid4 # 通用唯一标识符 ( Universally Unique Identifier )
import logging #日志模块
# values over max (and under min) will be clipped
MAX_X = 2400
MAX_Y = 1200
MAX_Z = 469 # TODO test this one!
def coord(x, y, z):
return {"kind": "coordinate", "args": {"x": x, "y": y, "z": z}} # 返回json 嵌套对象
def move_request(x, y, z):
return {"kind": "rpc_request", # 返回 json对象,对象内含数组
"args": {"label": ""},
"body": [{"kind": "move_absolute",
"args": {"location": coord(x, y, z),
"offset": coord(0, 0, 0),
"speed": 100}}]}
def take_photo_request():
return {"kind": "rpc_request",
"args": {"label": ""}, #label空着是为了在blocking_request中填上uuid,唯一识别码
"body": [{"kind": "take_photo", "args": {}}]}
def clip(v, min_v, max_v):
if v < min_v: return min_v
if v > max_v: return max_v
return v
class FarmbotClient(object):
def __init__(self, device_id, token):
self.device_id = device_id
self.client = mqtt.Client() # 类元素继承了另一个对象
self.client.username_pw_set(self.device_id, token) #传入 用户名和密码
self.client.on_connect = self._on_connect #???
self.client.on_message = self._on_message
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s",
filename='farmbot_client.log',
filemode='a')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter("%(asctime)s\t%(message)s"))
logging.getLogger('').addHandler(console)
self.connected = False
self.client.connect("clever-octopus.rmq.cloudamqp.com", 1883, 60) #前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port
self.client.loop_start()
# 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了
def shutdown(self):
self.client.disconnect()
self.client.loop_stop()
def move(self, x, y, z):
x = clip(x, 0, MAX_X)
y = clip(y, 0, MAX_Y)
z = clip(z, 0, MAX_Z)
status_ok = self._blocking_request(move_request(x, y, z)) # 发请求
logging.info("MOVE (%s,%s,%s) [%s]", x, y, z, status_ok) #存日志,包括执行了什么“move x y z +返回值 ”
def take_photo(self):
# TODO: is this enough? it's issue a request for the photo, but is the actual capture async?
status_ok = self._blocking_request(take_photo_request())
logging.info("TAKE_PHOTO [%s]", status_ok)
def _blocking_request(self, request, retries_remaining=3):
if retries_remaining==0:
logging.error("< blocking request [%s] OUT OF RETRIES", request) #尝试3次,然后在日志中记录错误
return False
self._wait_for_connection() #在哪定义的?
# assign a new uuid for this attempt
self.pending_uuid = str(uuid4())
request['args']['label'] = self.pending_uuid #接收move_request函数的json对象
logging.debug("> blocking request [%s] retries=%d", request, retries_remaining)
# send request off 发送请求
self.rpc_status = None
self.client.publish("bot/" + self.device_id + "/from_clients", json.dumps(request))
# wait for response
timeout_counter = 600 # ~1min 等待1s
while self.rpc_status is None: #这个self.rpc_status 是应答的flag
time.sleep(0.1)
timeout_counter -= 1
if timeout_counter == 0:
logging.warn("< blocking request TIMEOUT [%s]", request) #时间到了,无应答
return self._blocking_request(request, retries_remaining-1)
self.pending_uuid = None
# if it's ok, we're done!
if self.rpc_status == 'rpc_ok':
logging.debug("< blocking request OK [%s]", request)
return True
# if it's not ok, wait a bit and retry
if self.rpc_status == 'rpc_error':
logging.warn("< blocking request ERROR [%s]", request)
time.sleep(1)
return self._blocking_request(request, retries_remaining-1)
# unexpected state (???)
msg = "unexpected rpc_status [%s]" % self.rpc_status
logging.error(msg)
raise Exception(msg)
def _wait_for_connection(self):
# TODO: better way to do all this async event driven rather than with polling :/
timeout_counter = 600 # ~1min
while not self.connected: #用一个self.connected判断连上了没有,若没连上,等待
time.sleep(0.1)
timeout_counter -= 1
if timeout_counter == 0:
raise Exception("unable to connect")
def _on_connect(self, client, userdata, flags, rc):
logging.debug("> _on_connect")
self.client.subscribe("bot/" + self.device_id + "/from_device")
self.connected = True
logging.debug("< _on_connect")
def _on_message(self, client, userdata, msg):
resp = json.loads(msg.payload.decode())
if resp['args']['label'] != 'ping':
logging.debug("> _on_message [%s] [%s]", msg.topic, resp)
if msg.topic.endswith("/from_device") and resp['args']['label'] == self.pending_uuid:
self.rpc_status = resp['kind']
========
'''
Communicate with the server at the manufacturer
Not useful for the local drive script Not useful for the local drive script
''' """
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import json import json
import time import time
...@@ -302,13 +17,23 @@ MAX_Z = 469 # TODO test this one! ...@@ -302,13 +17,23 @@ MAX_Z = 469 # TODO test this one!
def coord(x, y, z): def coord(x, y, z):
return {"kind": "coordinate", "args": {"x": x, "y": y, "z": z}} # 返回json 嵌套对象 return {"kind": "coordinate", "args": {"x": x, "y": y, "z": z}} # 返回json 嵌套对象
def move_request(x, y, z): def move_request(x, y, z):
return {"kind": "rpc_request", # 返回 json对象,对象内含数组 return {
"kind": "rpc_request", # 返回 json对象,对象内含数组
"args": {"label": ""}, "args": {"label": ""},
"body": [{"kind": "move_absolute", "body": [
"args": {"location": coord(x, y, z), {
"kind": "move_absolute",
"args": {
"location": coord(x, y, z),
"offset": coord(0, 0, 0), "offset": coord(0, 0, 0),
"speed": 100}}]} "speed": 100,
},
}
],
}
def read_pin_request(pin_number, pin_mode="digital"): def read_pin_request(pin_number, pin_mode="digital"):
modes = {"digital": 0, "analog": 1} modes = {"digital": 0, "analog": 1}
...@@ -316,14 +41,21 @@ def read_pin_request(pin_number, pin_mode="digital"): ...@@ -316,14 +41,21 @@ def read_pin_request(pin_number, pin_mode="digital"):
if pin_mode != "digital": if pin_mode != "digital":
raise NotImplementedError() raise NotImplementedError()
return {"kind": "rpc_request", return {
"kind": "rpc_request",
"args": {"label": ""}, "args": {"label": ""},
"body": [{"kind": "read_pin", "body": [
{
"kind": "read_pin",
"args": { "args": {
"label": "pin" + str(pin_number), "label": "pin" + str(pin_number),
"pin_mode": modes[pin_mode] or (modes["digital"]), "pin_mode": modes[pin_mode] or (modes["digital"]),
"pin_number": pin_number "pin_number": pin_number,
}}]} },
}
],
}
def write_pin_request(pin_number, pin_value, pin_mode="digital"): def write_pin_request(pin_number, pin_value, pin_mode="digital"):
modes = {"digital": 0, "analog": 1} modes = {"digital": 0, "analog": 1}
...@@ -331,41 +63,54 @@ def write_pin_request(pin_number, pin_value, pin_mode="digital"): ...@@ -331,41 +63,54 @@ def write_pin_request(pin_number, pin_value, pin_mode="digital"):
if pin_mode != "digital": if pin_mode != "digital":
raise NotImplementedError() raise NotImplementedError()
return {"kind": "rpc_request", return {
"kind": "rpc_request",
"args": {"label": ""}, "args": {"label": ""},
"body": [{"kind": "write_pin", "body": [
{
"kind": "write_pin",
"args": { "args": {
"pin_mode": modes[pin_mode] or (modes["digital"]), "pin_mode": modes[pin_mode] or (modes["digital"]),
"pin_number": pin_number, "pin_number": pin_number,
"pin_value": pin_value "pin_value": pin_value,
} },
} }
] ],
} }
def toggle_pin_request(pin_number): def toggle_pin_request(pin_number):
return {"kind": "rpc_request", return {
"kind": "rpc_request",
"args": {"label": ""}, "args": {"label": ""},
"body": [{"kind": "toggle_pin", "body": [
{
"kind": "toggle_pin",
"args": { "args": {
"pin_number": pin_number, "pin_number": pin_number,
},
} }
} ],
]
} }
def take_photo_request(): def take_photo_request():
return {"kind": "rpc_request", return {
"kind": "rpc_request",
"args": {"label": ""}, # label空着是为了在blocking_request中填上uuid,唯一识别码 "args": {"label": ""}, # label空着是为了在blocking_request中填上uuid,唯一识别码
"body": [{"kind": "take_photo", "args": {}}]} "body": [{"kind": "take_photo", "args": {}}],
}
def clip(v, min_v, max_v): def clip(v, min_v, max_v):
if v < min_v: return min_v if v < min_v:
if v > max_v: return max_v return min_v
if v > max_v:
return max_v
return v return v
class FarmbotClient(object):
class FarmbotClient(object):
def __init__(self, device_id, token): def __init__(self, device_id, token):
self.device_id = device_id self.device_id = device_id
...@@ -374,21 +119,24 @@ class FarmbotClient(object): ...@@ -374,21 +119,24 @@ class FarmbotClient(object):
self.client.on_connect = self._on_connect # ??? self.client.on_connect = self._on_connect # ???
self.client.on_message = self._on_message self.client.on_message = self._on_message
logging.basicConfig(level=logging.DEBUG, logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s", format="%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s",
filename='farmbot_client.log', filename="farmbot_client.log",
filemode='a') filemode="a",
)
console = logging.StreamHandler() console = logging.StreamHandler()
console.setLevel(logging.INFO) console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter("%(asctime)s\t%(message)s")) console.setFormatter(logging.Formatter("%(asctime)s\t%(message)s"))
logging.getLogger('').addHandler(console) logging.getLogger("").addHandler(console)
self.connected = False self.connected = False
self.client.connect("clever-octopus.rmq.cloudamqp.com", 1883, 60) #前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port self.client.connect(
"clever-octopus.rmq.cloudamqp.com", 1883, 60
) # 前面的url要运行按README.md中request_token.py 后面俩是TCP Port, Websocket Port
self.client.loop_start() self.client.loop_start()
# 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了 # 初始化函数里就会连接到服务器上,所以每次实例化一个新的client时,就已经连上了
def shutdown(self): def shutdown(self):
self.client.disconnect() self.client.disconnect()
self.client.loop_stop() self.client.loop_stop()
...@@ -398,7 +146,9 @@ class FarmbotClient(object): ...@@ -398,7 +146,9 @@ class FarmbotClient(object):
y = clip(y, 0, MAX_Y) y = clip(y, 0, MAX_Y)
z = clip(z, 0, MAX_Z) z = clip(z, 0, MAX_Z)
status_ok = self._blocking_request(move_request(x, y, z)) # 发请求 status_ok = self._blocking_request(move_request(x, y, z)) # 发请求
logging.info("MOVE (%s,%s,%s) [%s]", x, y, z, status_ok) #存日志,包括执行了什么“move x y z +返回值 ” logging.info(
"MOVE (%s,%s,%s) [%s]", x, y, z, status_ok
) # 存日志,包括执行了什么“move x y z +返回值 ”
def take_photo(self): def take_photo(self):
# TODO: is this enough? it's issue a request for the photo, but is the actual capture async? # TODO: is this enough? it's issue a request for the photo, but is the actual capture async?
...@@ -406,12 +156,18 @@ class FarmbotClient(object): ...@@ -406,12 +156,18 @@ class FarmbotClient(object):
logging.info("TAKE_PHOTO [%s]", status_ok) logging.info("TAKE_PHOTO [%s]", status_ok)
def read_pin(self, pin_number, pin_mode="digital"): def read_pin(self, pin_number, pin_mode="digital"):
status_ok = self._blocking_request(read_pin_request(pin_number, pin_mode=pin_mode)) status_ok = self._blocking_request(
read_pin_request(pin_number, pin_mode=pin_mode)
)
logging.info(f"READ PIN (pin_number: {pin_number}) [{status_ok}]") logging.info(f"READ PIN (pin_number: {pin_number}) [{status_ok}]")
def write_pin(self, pin_number, pin_value, pin_mode="digital"): def write_pin(self, pin_number, pin_value, pin_mode="digital"):
status_ok = self._blocking_request(write_pin_request(pin_number, pin_value, pin_mode=pin_mode)) status_ok = self._blocking_request(
logging.info(f"WRITE PIN (pin_number: {pin_number}, pin_value: {pin_value}) [{status_ok}]") write_pin_request(pin_number, pin_value, pin_mode=pin_mode)
)
logging.info(
f"WRITE PIN (pin_number: {pin_number}, pin_value: {pin_value}) [{status_ok}]"
)
def toggle_pin(self, pin_number): def toggle_pin(self, pin_number):
status_ok = self._blocking_request(toggle_pin_request(pin_number)) status_ok = self._blocking_request(toggle_pin_request(pin_number))
...@@ -419,19 +175,23 @@ class FarmbotClient(object): ...@@ -419,19 +175,23 @@ class FarmbotClient(object):
def _blocking_request(self, request, retries_remaining=3): def _blocking_request(self, request, retries_remaining=3):
if retries_remaining == 0: if retries_remaining == 0:
logging.error("< blocking request [%s] OUT OF RETRIES", request) #尝试3次,然后在日志中记录错误 logging.error(
"< blocking request [%s] OUT OF RETRIES", request
) # 尝试3次,然后在日志中记录错误
return False return False
self._wait_for_connection() # 在哪定义的? self._wait_for_connection() # 在哪定义的?
# assign a new uuid for this attempt # assign a new uuid for this attempt
self.pending_uuid = str(uuid4()) self.pending_uuid = str(uuid4())
request['args']['label'] = self.pending_uuid #接收move_request函数的json对象 request["args"]["label"] = self.pending_uuid # 接收move_request函数的json对象
logging.debug("> blocking request [%s] retries=%d", request, retries_remaining) logging.debug("> blocking request [%s] retries=%d", request, retries_remaining)
# send request off 发送请求 # send request off 发送请求
self.rpc_status = None self.rpc_status = None
self.client.publish("bot/" + self.device_id + "/from_clients", json.dumps(request)) self.client.publish(
"bot/" + self.device_id + "/from_clients", json.dumps(request)
)
# wait for response # wait for response
timeout_counter = 600 # ~1min 等待1s timeout_counter = 600 # ~1min 等待1s
...@@ -444,12 +204,12 @@ class FarmbotClient(object): ...@@ -444,12 +204,12 @@ class FarmbotClient(object):
self.pending_uuid = None self.pending_uuid = None
# if it's ok, we're done! # if it's ok, we're done!
if self.rpc_status == 'rpc_ok': if self.rpc_status == "rpc_ok":
logging.debug("< blocking request OK [%s]", request) logging.debug("< blocking request OK [%s]", request)
return True return True
# if it's not ok, wait a bit and retry # if it's not ok, wait a bit and retry
if self.rpc_status == 'rpc_error': if self.rpc_status == "rpc_error":
logging.warn("< blocking request ERROR [%s]", request) logging.warn("< blocking request ERROR [%s]", request)
time.sleep(1) time.sleep(1)
return self._blocking_request(request, retries_remaining - 1) return self._blocking_request(request, retries_remaining - 1)
...@@ -459,7 +219,6 @@ class FarmbotClient(object): ...@@ -459,7 +219,6 @@ class FarmbotClient(object):
logging.error(msg) logging.error(msg)
raise Exception(msg) raise Exception(msg)
def _wait_for_connection(self): def _wait_for_connection(self):
# TODO: better way to do all this async event driven rather than with polling :/ # TODO: better way to do all this async event driven rather than with polling :/
timeout_counter = 600 # ~1min timeout_counter = 600 # ~1min
...@@ -477,8 +236,10 @@ class FarmbotClient(object): ...@@ -477,8 +236,10 @@ class FarmbotClient(object):
def _on_message(self, client, userdata, msg): def _on_message(self, client, userdata, msg):
resp = json.loads(msg.payload.decode()) resp = json.loads(msg.payload.decode())
if resp['args']['label'] != 'ping': if resp["args"]["label"] != "ping":
logging.debug("> _on_message [%s] [%s]", msg.topic, resp) logging.debug("> _on_message [%s] [%s]", msg.topic, resp)
if msg.topic.endswith("/from_device") and resp['args']['label'] == self.pending_uuid: if (
self.rpc_status = resp['kind'] msg.topic.endswith("/from_device")
>>>>>>>> master:src/utils/client.py and resp["args"]["label"] == self.pending_uuid
):
self.rpc_status = resp["kind"]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment