mirror of
https://github.com/suaveolent/hoymiles-wifi.git
synced 2024-09-20 03:10:11 +00:00
Compare commits
5 Commits
edfbf7fa74
...
6444872feb
Author | SHA1 | Date | |
---|---|---|---|
|
6444872feb | ||
|
255a9109d8 | ||
|
c600d5af4c | ||
|
26148448cb | ||
|
e211658185 |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This Python library facilitates communication with Hoymiles DTUs and the HMS-XXXXW-2T HMS microinverters, utilizing protobuf messages.
|
This Python library facilitates communication with Hoymiles DTUs and the HMS-XXXXW-2T HMS microinverters, utilizing protobuf messages.
|
||||||
|
|
||||||
For the Home Assistant integration have a look here:
|
For the Home Assistant integration have a look here:
|
||||||
https://github.com/suaveolent/ha-hoymiles-wifi
|
https://github.com/suaveolent/ha-hoymiles-wifi
|
||||||
|
|
||||||
**Disclaimer: This library is not affiliated with Hoymiles. It is an independent project developed to provide tools for interacting with Hoymiles HMS-XXXXW-2T series micro-inverters featuring integrated WiFi DTU. Any trademarks or product names mentioned are the property of their respective owners.**
|
**Disclaimer: This library is not affiliated with Hoymiles. It is an independent project developed to provide tools for interacting with Hoymiles HMS-XXXXW-2T series micro-inverters featuring integrated WiFi DTU. Any trademarks or product names mentioned are the property of their respective owners.**
|
||||||
@ -27,7 +27,7 @@ You can integrate the library into your own project, or simply use it in the com
|
|||||||
### Command line:
|
### Command line:
|
||||||
|
|
||||||
```
|
```
|
||||||
hoymiles-wifi [-h] --host HOST [--as-json] <command>
|
hoymiles-wifi [-h] --host HOST [--local_addr IP_OF_INTERFACE_TO_USE] [--as-json] <command>
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
get-real-data-new,
|
get-real-data-new,
|
||||||
|
@ -108,35 +108,43 @@ async def async_app_get_hist_power(
|
|||||||
|
|
||||||
|
|
||||||
async def async_set_power_limit(
|
async def async_set_power_limit(
|
||||||
dtu: DTU,
|
dtu: DTU, power_limit=-1
|
||||||
) -> CommandPB_pb2.CommandResDTO | None:
|
) -> CommandPB_pb2.CommandResDTO | None:
|
||||||
"""Set the power limit of the inverter asynchronously."""
|
"""Set the power limit of the inverter asynchronously."""
|
||||||
|
|
||||||
print( # noqa: T201
|
if power_limit == -1:
|
||||||
RED
|
print( # noqa: T201
|
||||||
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
RED
|
||||||
+ "!!! Danger zone! This will change the power limit of the dtu. !!!\n"
|
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||||
+ "!!! Please be careful and make sure you know what you are doing. !!!\n"
|
+ "!!! Danger zone! This will change the power limit of the dtu. !!!\n"
|
||||||
+ "!!! Only proceed if you know what you are doing. !!!\n"
|
+ "!!! Please be careful and make sure you know what you are doing. !!!\n"
|
||||||
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
+ "!!! Only proceed if you know what you are doing. !!!\n"
|
||||||
+ END,
|
+ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||||
)
|
+ END,
|
||||||
|
)
|
||||||
|
|
||||||
cont = input("Do you want to continue? (y/n): ")
|
cont = input("Do you want to continue? (y/n): ")
|
||||||
if cont != "y":
|
if cont != "y":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
power_limit = int(input("Enter the new power limit (0-100): "))
|
power_limit = int(input("Enter the new power limit (0-100): "))
|
||||||
|
forced_argument = False # we've retrieved the power limit in interactive mode
|
||||||
|
|
||||||
|
else:
|
||||||
|
forced_argument = True # we've retrieved the power limit via argument
|
||||||
|
|
||||||
if power_limit < 0 or power_limit > MAX_POWER_LIMIT:
|
if power_limit < 0 or power_limit > MAX_POWER_LIMIT:
|
||||||
print("Error. Invalid power limit!") # noqa: T201
|
print("Error. Invalid power limit!") # noqa: T201
|
||||||
return None
|
return None
|
||||||
|
|
||||||
print(f"Setting power limit to {power_limit}%") # noqa: T201
|
print(f"Setting power limit to {power_limit}%") # noqa: T201
|
||||||
cont = input("Are you sure? (y/n): ")
|
|
||||||
|
if not forced_argument:
|
||||||
|
# the limit has been set in interactive mode, so we ask for confirmation
|
||||||
|
cont = input("Are you sure? (y/n): ")
|
||||||
|
|
||||||
if cont != "y":
|
if cont != "y":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return await dtu.async_set_power_limit(power_limit)
|
return await dtu.async_set_power_limit(power_limit)
|
||||||
|
|
||||||
@ -314,6 +322,12 @@ async def main() -> None:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--host", type=str, required=True, help="IP address or hostname of the DTU"
|
"--host", type=str, required=True, help="IP address or hostname of the DTU"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--local_addr",
|
||||||
|
type=str,
|
||||||
|
required=False,
|
||||||
|
help="IP address of the interface to bind to",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--as-json",
|
"--as-json",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@ -345,9 +359,18 @@ async def main() -> None:
|
|||||||
],
|
],
|
||||||
help="Command to execute",
|
help="Command to execute",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--force",
|
||||||
|
type=int,
|
||||||
|
nargs='?',
|
||||||
|
const=-1,
|
||||||
|
default=-1,
|
||||||
|
help="Do not confirm certain operations and take arguments directly from commandline",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
dtu = DTU(args.host)
|
dtu = DTU(args.host, args.local_addr)
|
||||||
|
|
||||||
# Execute the specified command using a switch case
|
# Execute the specified command using a switch case
|
||||||
switch = {
|
switch = {
|
||||||
@ -372,7 +395,10 @@ async def main() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
command_func = switch.get(args.command, print_invalid_command)
|
command_func = switch.get(args.command, print_invalid_command)
|
||||||
response = await command_func(dtu)
|
if args.command == 'set-power-limit':
|
||||||
|
response = await command_func(dtu, args.force)
|
||||||
|
else:
|
||||||
|
response = await command_func(dtu)
|
||||||
|
|
||||||
if response:
|
if response:
|
||||||
if args.as_json:
|
if args.as_json:
|
||||||
|
@ -70,10 +70,11 @@ class NetworkState(Enum):
|
|||||||
class DTU:
|
class DTU:
|
||||||
"""DTU class."""
|
"""DTU class."""
|
||||||
|
|
||||||
def __init__(self, host: str):
|
def __init__(self, host: str, local_addr: str = None):
|
||||||
"""Initialize DTU class."""
|
"""Initialize DTU class."""
|
||||||
|
|
||||||
self.host = host
|
self.host = host
|
||||||
|
self.local_addr = local_addr
|
||||||
self.state = NetworkState.Unknown
|
self.state = NetworkState.Unknown
|
||||||
self.sequence = 0
|
self.sequence = 0
|
||||||
self.mutex = asyncio.Lock()
|
self.mutex = asyncio.Lock()
|
||||||
@ -365,11 +366,13 @@ class DTU:
|
|||||||
+ request_as_bytes
|
+ request_as_bytes
|
||||||
)
|
)
|
||||||
|
|
||||||
address = (self.host, dtu_port)
|
ip_to_bind = (self.local_addr, 0) if self.local_addr is not None else None
|
||||||
|
|
||||||
async with self.mutex:
|
async with self.mutex:
|
||||||
try:
|
try:
|
||||||
reader, writer = await asyncio.open_connection(*address)
|
reader, writer = await asyncio.open_connection(
|
||||||
|
host=self.host, port=dtu_port, local_addr=ip_to_bind
|
||||||
|
)
|
||||||
|
|
||||||
writer.write(message)
|
writer.write(message)
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
|
2
setup.py
2
setup.py
@ -6,7 +6,7 @@ setup(
|
|||||||
name="hoymiles-wifi",
|
name="hoymiles-wifi",
|
||||||
packages=["hoymiles_wifi", "hoymiles_wifi.protobuf"],
|
packages=["hoymiles_wifi", "hoymiles_wifi.protobuf"],
|
||||||
install_requires=["protobuf", "crcmod"],
|
install_requires=["protobuf", "crcmod"],
|
||||||
version="0.2.3",
|
version="0.2.4",
|
||||||
description="A python library for interfacing with the Hoymiles DTUs and the HMS-XXXXW-2T series of micro-inverters using protobuf messages.",
|
description="A python library for interfacing with the Hoymiles DTUs and the HMS-XXXXW-2T series of micro-inverters using protobuf messages.",
|
||||||
author="suaveolent",
|
author="suaveolent",
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
Loading…
Reference in New Issue
Block a user