Pymelsec
Python3 Implementation of MELSEC Communication
Install / Use
/learn @NothinRandom/PymelsecREADME
pymelsec
A Python3 implementation of MELSEC Communication Protocol that allows you to interact with a Mitsubishi PLC. This library was inspired by pymcprotocol, but has been rewritten to have additional features and be more flexible.
Installation
pip3 install pymelsec
Protocol type
pymelsec natively supports MELSEC Communication 3E type. Type 4E is implemented but has not been fully tested.
Type 1C~4C is not supported.
Supported PLC series
- Q Series
- L Series
- QnA Series
- iQ-L Series
- iQ-R Series
A and FX series are not supportted because they does not support 3E or 4E type.
How to use pymelsec
1. Set up PLC
You need to open PLC's port for MELSEC Communication by GxWorks2 or GxWorks3 software.
- Mitsubishi PLC manuals
- Set IP address for PLC.
- Set network port for PLC, but default port should be 5007.
| Port Number | Application | | --- | --- | | 0x1388 (5000) | For future extension (For Q series Ethernet modules, this port number is used for "Auto Open UDP Port".) | | 0x1389 (5001) | For future extension (For Q series Ethernet modules, this port number is used for "over UDP/IP and Ethernet module".) | | 0x138A (5002) | For future extension (For Q series Ethernet modules, this port number is used for "over TCP/IP and Ethernet module".) | | 0x138B (5003) to 0x138D (5005) | For future extension | | 0x138E (5006) | MELSOFT communication port (over UDP/IP and CPU module) | | 0x138F (5007) | MELSOFT communication port (over TCP/IP and CPU module) | | 0x1390 (5008) | MELSOFT direct connection port (over CPU module | | 0x1391 (5009) | For future extension |
2. Connect and Send Commands
from datetime import datetime
from pymelsec import Type3E, Type4E
from pymelsec.constants import DT
from pymelsec.tag import Tag
__READ_TAGS = [
Tag(device="X0", type=DT.BIT), # BIT
Tag(device="X1", type=DT.BIT), # BIT
Tag(device="X2", type=DT.BIT), # BIT
Tag(device="X3", type=DT.BIT), # BIT
Tag(device="D200", type=DT.SWORD), # WORD signed
Tag(device="D201", type=DT.UWORD), # WORD unsigned
Tag(device="D202", type=DT.SDWORD), # DWORD signed
Tag(device="D204", type=DT.UDWORD), # DWORD unsigned
Tag(device="D206", type=DT.FLOAT), # FLOAT
Tag(device="D208", type=DT.DOUBLE), # DOUBLE
Tag(device="D300", type=DT.SLWORD), # LWORD signed (unofficial)
Tag(device="D304", type=DT.ULWORD), # LWORD unsigned (unofficial)
]
__WRITE_TAGS = [
Tag(device="X0", value=0, type=DT.BIT), # BIT
Tag(device="X1", value=1, type=DT.BIT), # BIT
Tag(device="X2", value=0, type=DT.BIT), # BIT
Tag(device="X3", value=1, type=DT.BIT), # BIT
Tag(device="D200", value=-20000, type=DT.SWORD), # WORD signed
Tag(device="D201", value=20100, type=DT.UWORD), # WORD unsigned
Tag(device="D202", value=-20200000, type=DT.SDWORD), # DWORD signed
Tag(device="D204", value=20400000, type=DT.UDWORD), # DWORD unsigned
Tag(device="D206", value=-206.206206, type=DT.FLOAT), # FLOAT
Tag(device="D208", value=208.208208208208, type=DT.DOUBLE), # DOUBLE
Tag(device="D300", value=-10000000, type=DT.SLWORD), # LWORD signed (unofficial)
Tag(device="D304", value=10000000, type=DT.ULWORD), # LWORD unsigned (unofficial)
]
__HOST = '192.168.1.15' # REQUIRED
__PORT = 5007 # OPTIONAL: default is 5007
__PLC_TYPE = 'iQ-R' # OPTIONAL: default is 'Q'
# options: 'L', 'QnA', 'iQ-L', 'iQ-R'
with Type4E(host=__HOST, port=__PORT, plc_type=__PLC_TYPE) as plc:
"""
Set communication access mode option
example: read 5 contiguous words starting from "D0" to "D4"
Args:
comm_type(str)[Optional]: the communication access mode option
example: comm_type="binary" (default)
comm_type="ascii"
"""
plc.set_access_opt(comm_type="binary")
"""
Write mixed devices
example: write randomly mixed data types
Args:
devices(list[Tag])[Required]: list of data class Tag
example: devices=__WRITE_TAGS
Returns:
result(list[Tag]): list of incorrectly defined Tag
example:
[
Tag(
device='X0',
value=1,
type='X',
error=DataTypeError('Data type "X" is not supported.')
)
]
Notes:
look at __WRITE_TAGS to understand named tuple setup
"""
plc.write(devices=__WRITE_TAGS)
"""
Read mixed devices
example: read randomly mixed data types
Args:
devices(list[Tag])[Required]: list of data class Tag
example: devices=__WRITE_TAGS
Returns:
result(list[Tag]): list of Tag
example:
[
Tag(device='X0',value=False,type='BIT',error=''),
...
Tag(device='D208',value=208.208208208208,type='DOUBLE',error='')
]
Notes:
look at __READ_TAGS to understand named tuple setup
error status shows error reason
example:
[
Tag(
device='X0',
value=None,
type='X',
error=DataTypeError('Data type "X" is not supported.')
)
]
to access the fields of each entry in result
for tag in read_result:
print((f'device:{tag.device}, '
f'value:{tag.value}, '
f'data_type:{tag.type}, '
f'status:{tag.error}'))
"""
read_result = plc.read(devices=__READ_TAGS)
"""
Write a sequence of data types
example: write 5 consecutive signed words starting at "D100"
Args:
ref_device(str)[Required]: the reference device
example: ref_device="D100"
read_size(int)[Required]: number of points to read
example: read_size=5
data_type(str)[Required]: data type
example: data_type=DT.SWORD
Notes:
look at __READ_TAGS to understand named tuple setup
error status shows error reason
example:
[
Tag(
device='X0',
value=None,
type='X',
error=DataTypeError('Data type "X" is not supported.')
)
]
to access the fields of each entry in result
for tag in read_result:
print((f'device:{tag.device}, '
f'value:{tag.value}, '
f'data_type:{tag.type}, '
f'status:{tag.error}'))
"""
plc.batch_write(
ref_device="D100",
values=[-100,100,-1000,1000,10000],
data_type=DT.SWORD
)
# additional examples:
plc.batch_write(
ref_device="D100",
values=[-100.0,100.1,-1000.2,1000.3,10000.4],
data_type=DT.FLOAT
)
# any of these bit representation is valid
plc.batch_write(
ref_device="X0",
values=[False,True,False,True,False],
data_type=DT.BIT
)
plc.batch_write(
ref_device="X0",
values=[0,1,0,1,0],
data_type=DT.BIT
)
plc.batch_write(
ref_device="X0",
values=[False,1,0,True,0],
data_type=DT.BIT
)
"""
Read a sequence of data types
example: read 5 consecutive signed words starting at "D100"
Args:
ref_device(str)[Required]: the reference device
example: ref_device="D100"
read_size(int)[Required]: number of points to read
example: read_size=5
data_type(str)[Required]: data type
example: data_type=DT.SWORD
bool_encode(bool): encode boolean value when reading bits
example: bool_encode=False (default)
bool_encode=True
decode(bool): decode data or keep as raw bytes
example: decode=True (default)
decode=False
Returns:
result(list[Tag]): list of Tag
example:
[
Tag(device='D100',value=-100,type='SWORD',error=''),
...
Tag(device='D104',value=10000,type='SWORD',error='')
]
Notes:
look at __READ_TAGS to understand named tuple setup
error status shows error reason
example:
[
Tag(
device='X0',
value=None,
type='X',
error=DataTypeError('Data type "X" is not supported.')
)
]
to access the fields of each entry in result
for tag in read_result:
print((f'device:{tag.device}, '
f'value:{tag.value}, '
f'data_type:{tag.type}, '
f'status:{tag.error}'))
"""
read_result = plc.batch_read(
ref_device="D100",
read_size=5,
data_type=DT.SWORD
)
# additional examples:
# read raw bytes
read_result = plc.batch_read(
ref_device="D100",
read_size=5,
data_type=DT.SWORD,
decode=False
)
# read bits and return type boolean
read_result = plc.batch_read(
ref_device="X0",
read_size=5,
data_type=DT.BIT,
bool_encode=True
)
4. Utility Functions
These
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
