Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print File name works! #14

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions custom_components/flashforge_adventurer_3/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
STATUS_COMMAND = '~M601 S1'
PRINT_JOB_INFO_COMMAND = '~M27'
TEMPERATURE_COMMAND = '~M105'
FILE_COMMAND = '~M119'

STATUS_REPLY_REGEX = re.compile('CMD M27 Received.\r\n\w+ printing byte (\d+)/(\d+)\r\n(.*?)ok\r\n')
TEMPERATURE_REPLY_REGEX = re.compile('CMD M105 Received.\r\nT0:(\d+)\W*/(\d+) B:(\d+)\W*/(\d+)\r\n(.*?)ok\r\n')
Expand All @@ -24,6 +25,7 @@ class PrinterStatus(TypedDict):
desired_bed_temperature: Optional[int]
nozzle_temperature: Optional[int]
desired_nozzle_temperature: Optional[int]
filename: Optional[str]


async def send_msg(reader: StreamReader, writer: StreamWriter, payload: str):
Expand All @@ -46,8 +48,17 @@ async def collect_data(ip: str, port: int) -> Tuple[PrinterStatus, Optional[str]
await send_msg(reader, writer, STATUS_COMMAND)
print_job_info = await send_msg(reader, writer, PRINT_JOB_INFO_COMMAND)
temperature_info = await send_msg(reader, writer, TEMPERATURE_COMMAND)
filename_info = await send_msg(reader, writer, FILE_COMMAND)
writer.close()
await writer.wait_closed()

if filename_info:
filename_match = re.search(r'CurrentFile: ([^\.]+)\.gx', filename_info)
if filename_match:
response['filename'] = filename_match.group(1)
else:
response['filename'] = " "

return response, print_job_info, temperature_info


Expand All @@ -67,16 +78,31 @@ def parse_data(response: PrinterStatus, print_job_info: str, temperature_info: s
response['desired_nozzle_temperature'] = desired_nozzle_temperature
response['bed_temperature'] = int(temperature_match.group(3))
response['desired_bed_temperature'] = desired_bed_temperature
filename_info = response['filename']

if filename_info:
filename_match = re.search(r'CurrentFile: ([^\.]+)\.gx', filename_info)
if filename_match:
response['filename'] = filename_match.group(1)
return response


async def get_print_job_status(ip: str, port: int) -> PrinterStatus:
response, print_job_info, temperature_info = await collect_data(ip, port)
if not response['online']:
return response

filename_info = response['filename']
if filename_info:
filename_match = re.search(r'CurrentFile: ([^\.]+)\.gx', filename_info)
if filename_match:
response['filename'] = filename_match.group(1)

return parse_data(response, print_job_info, temperature_info)


if __name__ == '__main__':

status = asyncio.run(get_print_job_status(os.environ['PRINTER_IP'], 8899))
print(status)

22 changes: 22 additions & 0 deletions custom_components/flashforge_adventurer_3/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async def async_setup_entry(
sensors = [
FlashforgeAdventurer3StateSensor(coordinator, config),
FlashforgeAdventurer3ProgressSensor(coordinator, config),
FlashforgeAdventurer3FilenameSensor(coordinator, config),
]
async_add_entities(sensors, update_before_add=True)

Expand Down Expand Up @@ -152,3 +153,24 @@ def icon(self) -> str:
@property
def unit_of_measurement(self) -> str:
return '%'

class FlashforgeAdventurer3FilenameSensor(BaseFlashforgeAdventurer3Sensor):
@property
def name(self) -> str:
return f'{super().name} filename'

@property
def unique_id(self) -> str:
return f'{super().unique_id}_filename'

@property
def available(self) -> bool:
return bool(self.attrs.get('online') and self.attrs.get('filename'))

@property
def state(self) -> Optional[str]:
return self.attrs.get('filename')

@property
def icon(self) -> str:
return 'mdi:file'