Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
osie
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
osie
Commits
8cd43f94
Commit
8cd43f94
authored
Feb 06, 2023
by
Ivan Tyagov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove not longer maintained modbus implementation.
parent
921c4183
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
368 deletions
+0
-368
eggs/osie_coupler/osie_modbus.py
eggs/osie_coupler/osie_modbus.py
+0
-214
eggs/osie_coupler/osie_ocr.py
eggs/osie_coupler/osie_ocr.py
+0
-143
eggs/osie_coupler/setup.py
eggs/osie_coupler/setup.py
+0
-11
No files found.
eggs/osie_coupler/osie_modbus.py
deleted
100755 → 0
View file @
921c4183
#!/usr/bin/env python3
"""
Modbus server implementation for Lime2 -> MOD-IO which controls relays.
root@a20:~/osie/examples/modbus# pymodbus.console tcp --host localhost --port 502
To switch on relay 1:
> client.write_registers address=0 values=1 unit=1
To switch OFF:
> client.write_registers address=0 values=0 unit=1
"""
import
os
import
sys
from
pymodbus.server.asynchronous
import
StartTcpServer
from
pymodbus.server.asynchronous
import
StartUdpServer
from
pymodbus.server.asynchronous
import
StartSerialServer
from
pymodbus.device
import
ModbusDeviceIdentification
from
pymodbus.datastore
import
ModbusSequentialDataBlock
from
pymodbus.datastore
import
ModbusSlaveContext
,
ModbusServerContext
from
pymodbus.transaction
import
(
ModbusRtuFramer
,
ModbusAsciiFramer
,
ModbusBinaryFramer
)
from
pymodbus.pdu
import
ModbusRequest
from
pyA20Lime2
import
i2c
import
bitarray
from
bitarray.util
import
ba2int
from
argparse
import
ArgumentParser
# XXX: is it needed actually, examine
ModbusRequest
.
function_code
=
55
# name fo device within Lime2
DEFAULT_MOD_IO_DEVICE_NAME
=
"/dev/i2c-1"
class
Lime2MODIOI2c
:
"""
Class to communication from Lime2 -> MOD-IO (over I2c)
Keep relay state internally as take into account to preserver relay state!
"""
# state of 4 relays of mod-io, by default OFF
# added 8 as their format is 8 bit and maybe they extend mod-io
# only last 4 bits are used
relay_state_list
=
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]
def
__init__
(
self
,
mod_io_device_name
=
DEFAULT_MOD_IO_DEVICE_NAME
):
self
.
mod_io_device_name
=
mod_io_device_name
def
open
(
self
):
"""
Open connection to MOD-IO.
"""
i2c
.
init
(
self
.
mod_io_device_name
)
i2c
.
open
(
0x58
)
def
close
(
self
):
"""
Close connection to MOD-IO.
"""
i2c
.
close
()
def
write
(
self
,
code
):
"""
Write / send to device.
"""
self
.
open
()
while
1
:
try
:
i2c
.
write
([
0x10
,
code
])
break
except
:
print
(
"Failed to sent command: %s"
%
code
)
# be a good citizen and close
self
.
close
()
def
setRelayState
(
self
,
relay_number
,
relay_state
):
"""
Set relay state.
relay_number: 0 - 3
relay_state: 0 (off), 1 (on)
"""
if
relay_state
not
in
(
0
,
1
):
raise
ValueError
(
"Incorect relay state!"
)
if
relay_number
not
in
(
0
,
1
,
2
,
3
):
raise
ValueError
(
"Incorrect relay number!"
)
# relay1 is the most right element in list / byte command representation
self
.
relay_state_list
[
-
(
1
+
relay_number
)]
=
relay_state
# generate proper relay state command of all 4 relays
# which doesn't override any other relays' state
# which itself is kept in this app's RAM
ba
=
bitarray
.
bitarray
(
self
.
relay_state_list
)
self
.
write
(
ba2int
(
ba
))
def
setRelayStateAllOff
(
self
):
"""
Switch off all relays.
"""
self
.
relay_state_list
=
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]
ba
=
bitarray
.
bitarray
(
self
.
relay_state_list
)
self
.
write
(
ba2int
(
ba
))
def
setRelayStateAllOn
(
self
):
"""
Switch on all relays.
"""
self
.
relay_state_list
=
[
0
,
0
,
0
,
0
,
1
,
1
,
1
,
1
]
ba
=
bitarray
.
bitarray
(
self
.
relay_state_list
)
self
.
write
(
ba2int
(
ba
))
# --------------------------------------------------------------------------- #
# configure the service logging
# --------------------------------------------------------------------------- #
import
logging
FORMAT
=
(
'%(asctime)-15s %(threadName)-15s'
' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s'
)
logging
.
basicConfig
(
format
=
FORMAT
)
log
=
logging
.
getLogger
()
log
.
setLevel
(
logging
.
DEBUG
)
# argument parsing
parser
=
ArgumentParser
()
parser
.
add_argument
(
"-p"
,
"--port"
,
dest
=
"port"
,
default
=
502
,
type
=
int
,
help
=
"The port modbus server will listen to."
,
metavar
=
"PORT"
)
parser
.
add_argument
(
"-i"
,
"--interface"
,
dest
=
"interface"
,
default
=
"0.0.0.0"
,
type
=
str
,
help
=
"The interface modbus server will bind to."
,
metavar
=
"INTERFACE"
)
args
=
parser
.
parse_args
()
PORT
=
args
.
port
INTERFACE
=
args
.
interface
# main class to communicate with MOD-IO
mod_io
=
Lime2MODIOI2c
()
class
LimeModbusSlaveContext
(
ModbusSlaveContext
):
"""
Control Lime2 -> Mod-io ->relay {1..4}
"""
def
setValues
(
self
,
fx
,
address
,
values
):
if
not
self
.
zero_mode
:
address
=
address
+
1
log
.
debug
(
"setValues[%d] %d:%s"
%
(
fx
,
address
,
values
))
self
.
store
[
self
.
decode
(
fx
)].
setValues
(
address
,
values
)
# control relays
value
=
int
(
values
[
0
])
log
.
debug
(
address
)
log
.
debug
(
value
)
# switch relays at MOD-IO
mod_io
.
setRelayState
(
address
,
value
)
def
run_async_server
(
port
=
502
,
interface
=
"0.0.0.0"
):
store
=
LimeModbusSlaveContext
(
di
=
ModbusSequentialDataBlock
(
0
,
[
0
]
*
10
),
co
=
ModbusSequentialDataBlock
(
0
,
[
0
]
*
10
),
hr
=
ModbusSequentialDataBlock
(
0
,
[
0
]
*
10
),
ir
=
ModbusSequentialDataBlock
(
0
,
[
0
]
*
10
),
zero_mode
=
True
)
store
.
register
(
ModbusRequest
.
function_code
,
'cm'
,
ModbusSequentialDataBlock
(
0
,
[
17
]
*
100
))
context
=
ModbusServerContext
(
slaves
=
store
,
single
=
True
)
# ----------------------------------------------------------------------- #
# initialize the server information
# ----------------------------------------------------------------------- #
# If you don't set this or any fields, they are defaulted to empty strings.
# ----------------------------------------------------------------------- #
identity
=
ModbusDeviceIdentification
()
identity
.
VendorName
=
'Nexedi'
identity
.
ProductCode
=
'OSIE-coupler'
identity
.
VendorUrl
=
'https://lab.nexedi.com/nexedi/osie/'
identity
.
ProductName
=
'Pymodbus Server'
identity
.
ModelName
=
'Pymodbus Server'
identity
.
MajorMinorRevision
=
'0.0.1'
# TCP Server
StartTcpServer
(
context
,
identity
=
identity
,
address
=
(
interface
,
port
),
custom_functions
=
[
ModbusRequest
])
def
main
():
# check if we actually are running on proper platform
if
os
.
uname
().
machine
!=
"armv7l"
:
log
.
error
(
"Not supported platform and / or CPU type."
)
sys
.
exit
(
1
)
# switch OFF all relays
mod_io
.
setRelayStateAllOff
()
# run modbus "server"
run_async_server
(
interface
=
INTERFACE
,
port
=
PORT
)
# switch off all
mod_io
.
setRelayStateAllOff
()
if
__name__
==
"__main__"
:
main
()
eggs/osie_coupler/osie_ocr.py
deleted
100755 → 0
View file @
921c4183
"""
Implement a basic OCR app that can find countours in image and
based on number of countours control a modbus server remotely.
This is a POC.
"""
import
cv2
import
numpy
as
np
import
pymodbus
from
pymodbus.client.sync
import
ModbusTcpClient
as
ModbusClient
from
time
import
sleep
from
datetime
import
datetime
import
os
import
time
UNIT
=
0x1
OSIE_PLC_ADDRESS
=
"localhost"
# "192.168.0.48" for real machine
OSIE_PLC_PORT
=
502
ROOT_FOLDER_PATH
=
"/mnt/flash"
def
nothing
(
x
):
# any operation
pass
def
setConveyorState
(
state
):
"""
Send to modbus server command to start (state 1)
or stop (state 0) conveyor.
"""
client
=
ModbusClient
(
OSIE_PLC_ADDRESS
,
port
=
OSIE_PLC_PORT
)
client
.
connect
()
client
.
write_coils
(
0
,
[
state
],
unit
=
UNIT
)
client
.
close
()
def
openAndCloseAirValve
(
seconds
=
0.05
):
"""
Send to modbus server command to open and close the air valve for
a specified amount of time in seconds.
"""
client
=
ModbusClient
(
OSIE_PLC_ADDRESS
,
port
=
OSIE_PLC_PORT
)
client
.
connect
()
#rr = client.read_coils(1, 1, unit=UNIT)
client
.
write_coils
(
1
,
[
True
],
unit
=
UNIT
)
sleep
(
seconds
)
client
.
write_coils
(
1
,
[
False
],
unit
=
UNIT
)
client
.
close
()
def
storeFrame
(
frame
):
"""
Store a video frame in locally.
"""
folder_path
=
"%s/%s"
%
(
ROOT_FOLDER_PATH
,
datetime
.
today
().
strftime
(
'%Y-%m-%d'
))
if
not
os
.
path
.
isdir
(
folder_path
):
os
.
mkdir
(
folder_path
)
millis
=
int
(
round
(
time
.
time
()
*
1000
))
file_path
=
"%s/%s.jpg"
%
(
folder_path
,
millis
)
cv2
.
imwrite
(
file_path
,
frame
)
#f = open(file_path, "w")
#f.write(file_content)
#f.close()
# start conveyor
setConveyorState
(
1
)
cap
=
cv2
.
VideoCapture
(
1
)
cv2
.
namedWindow
(
"Trackbars"
)
cv2
.
createTrackbar
(
"L-H"
,
"Trackbars"
,
0
,
180
,
nothing
)
cv2
.
createTrackbar
(
"L-S"
,
"Trackbars"
,
66
,
255
,
nothing
)
cv2
.
createTrackbar
(
"L-V"
,
"Trackbars"
,
134
,
255
,
nothing
)
cv2
.
createTrackbar
(
"U-H"
,
"Trackbars"
,
180
,
180
,
nothing
)
cv2
.
createTrackbar
(
"U-S"
,
"Trackbars"
,
255
,
255
,
nothing
)
cv2
.
createTrackbar
(
"U-V"
,
"Trackbars"
,
243
,
255
,
nothing
)
font
=
cv2
.
FONT_HERSHEY_COMPLEX
while
True
:
_
,
frame
=
cap
.
read
()
hsv
=
cv2
.
cvtColor
(
frame
,
cv2
.
COLOR_BGR2HSV
)
l_h
=
cv2
.
getTrackbarPos
(
"L-H"
,
"Trackbars"
)
l_s
=
cv2
.
getTrackbarPos
(
"L-S"
,
"Trackbars"
)
l_v
=
cv2
.
getTrackbarPos
(
"L-V"
,
"Trackbars"
)
u_h
=
cv2
.
getTrackbarPos
(
"U-H"
,
"Trackbars"
)
u_s
=
cv2
.
getTrackbarPos
(
"U-S"
,
"Trackbars"
)
u_v
=
cv2
.
getTrackbarPos
(
"U-V"
,
"Trackbars"
)
lower_red
=
np
.
array
([
l_h
,
l_s
,
l_v
])
upper_red
=
np
.
array
([
u_h
,
u_s
,
u_v
])
mask
=
cv2
.
inRange
(
hsv
,
lower_red
,
upper_red
)
kernel
=
np
.
ones
((
5
,
5
),
np
.
uint8
)
mask
=
cv2
.
erode
(
mask
,
kernel
)
# Contours detection
if
int
(
cv2
.
__version__
[
0
])
>
3
:
# Opencv 4.x.x
contours
,
_
=
cv2
.
findContours
(
mask
,
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
else
:
# Opencv 3.x.x
_
,
contours
,
_
=
cv2
.
findContours
(
mask
,
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
for
cnt
in
contours
:
area
=
cv2
.
contourArea
(
cnt
)
approx
=
cv2
.
approxPolyDP
(
cnt
,
0.02
*
cv2
.
arcLength
(
cnt
,
True
),
True
)
x
=
approx
.
ravel
()[
0
]
y
=
approx
.
ravel
()[
1
]
if
area
>
400
:
cv2
.
drawContours
(
frame
,
[
approx
],
0
,
(
0
,
0
,
0
),
5
)
if
len
(
approx
)
==
3
:
cv2
.
putText
(
frame
,
"Triangle"
,
(
x
,
y
),
font
,
1
,
(
0
,
0
,
0
))
storeFrame
(
frame
)
openAndCloseAirValve
()
elif
len
(
approx
)
==
4
:
cv2
.
putText
(
frame
,
"Rectangle"
,
(
x
,
y
),
font
,
1
,
(
0
,
0
,
0
))
storeFrame
(
frame
)
openAndCloseAirValve
()
elif
10
<
len
(
approx
)
<
20
:
cv2
.
putText
(
frame
,
"Circle-fire!"
,
(
x
,
y
),
font
,
1
,
(
0
,
0
,
0
))
storeFrame
(
frame
)
openAndCloseAirValve
()
cv2
.
imshow
(
"Frame"
,
frame
)
cv2
.
imshow
(
"Mask"
,
mask
)
key
=
cv2
.
waitKey
(
1
)
if
key
==
27
:
break
cap
.
release
()
cv2
.
destroyAllWindows
()
# stop conveyor
setConveyorState
(
0
)
eggs/osie_coupler/setup.py
deleted
100644 → 0
View file @
921c4183
"""
Install OSIE's coupler.
"""
from
setuptools
import
setup
setup
(
name
=
'osie_coupler'
,
version
=
'0.1'
,
entry_points
=
{
'console_scripts'
:
[
'osie_coupler_modbus = osie_coupler.osie_modbus:main'
]},
install_requires
=
[
'pyA20Lime2'
,
'pymodbus[twisted]'
,
'click'
,
'prompt_toolkit'
,
'pygments'
,
'bitarray'
]
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment