Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
Farmbot Yolo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Robotlab
Farmbot Yolo
Commits
7f36d777
"lib/c/2014/labcomm.h" did not exist on "321cc67d890042025625df6a591fcfe9e62ec95d"
Unverified
Commit
7f36d777
authored
Jun 13, 2022
by
Anton Tetov Johansson
Browse files
Options
Downloads
Plain Diff
Merge branch 'master' into make_pkg
parents
df3e7d36
67cbe20e
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Makefile
+2
-4
2 additions, 4 deletions
Makefile
farmbot_yolo/client.py
+217
-456
217 additions, 456 deletions
farmbot_yolo/client.py
with
219 additions
and
460 deletions
Makefile
+
2
−
4
View file @
7f36d777
.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
This diff is collapsed.
Click to expand it.
farmbot_yolo/client.py
+
217
−
456
View file @
7f36d777
<<<<<<<<
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
'
]
||||||||
90
c14bb
:
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
"
]
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment