{"id":14978104,"url":"https://github.com/jorticus/pymate","last_synced_at":"2025-10-28T08:31:49.873Z","repository":{"id":42305841,"uuid":"46999514","full_name":"jorticus/pymate","owner":"jorticus","description":"Outback MATE python interface","archived":false,"fork":false,"pushed_at":"2022-04-09T04:37:18.000Z","size":10041,"stargazers_count":29,"open_issues_count":8,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-01T13:02:11.649Z","etag":null,"topics":["python","python-library","raspberrypi"],"latest_commit_sha":null,"homepage":"https://jared.geek.nz/pymate","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jorticus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-27T21:12:45.000Z","updated_at":"2024-11-28T17:26:00.000Z","dependencies_parsed_at":"2022-09-04T23:22:19.225Z","dependency_job_id":null,"html_url":"https://github.com/jorticus/pymate","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorticus%2Fpymate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorticus%2Fpymate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorticus%2Fpymate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jorticus%2Fpymate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jorticus","download_url":"https://codeload.github.com/jorticus/pymate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237604122,"owners_count":19337254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","python-library","raspberrypi"],"created_at":"2024-09-24T13:56:52.185Z","updated_at":"2025-10-28T08:31:49.009Z","avatar_url":"https://github.com/jorticus.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyMATE\n\n![pyMATE](doc/pymate.png \"pyMATE\")\n\npyMATE is a python library that can be used to emulate an Outback MATE unit, and talk to any supported\nOutback Power Inc. device such as an MX charge controller, an FX inverter, a FlexNET DC monitor, or a hub with\nmultiple devices attached to it.\n\nYou will need a simple adapter circuit and a TTL serial port. For more details, see [jared.geek.nz/pymate](http://jared.geek.nz/pymate)\n\nTo see the library in action, check out my post on connecting it with Grafana! [jared.geek.nz/grafana-outback-solar](http://jared.geek.nz/grafana-outback-solar)\n\n### Related Projects\n\n- [outback_mate_rs232](https://github.com/Ryanf55/outback_mate_rs232) - For use with the Mate's RS232 port\n- [uMATE](https://github.com/jorticus/uMATE) - Companion Arduino library, featuring more reliable communication and better perf\n\n## MX/CC Charge Controller Interface\n\nTo set up communication with an MX charge controller:\n    \n```python\nmate_bus = MateNET('COM1')         # Windows\nmate_bus = MateNET('/dev/ttyUSB0') # Linux\n\nmate_mx = MateMXDevice(mate_bus, port=0) # 0: No hub. 1-9: Hub port\nmate_mx.scan()  # This will raise an exception if the device isn't found\n```\n\nOr to automatically a hub for an attached MX:\n```python\nbus = MateNET('COM1', supports_spacemark=False)\nmate = MateMXDevice(bus, port=bus.find_device(MateNET.DEVICE_MX))\n\n# Check that an MX unit is attached and is responding\nmate.scan()\n```\n\nYou can now communicate with the MX as though you are a MATE device.\n\n### Status\n\nYou can query a status with `mate_mx.get_status()`. This will return an [MXStatusPacket](matenet/mx.py#L14) with the following information:\n\n```python\nstatus = mate_mx.get_status()\nstatus.amp_hours       # 0 - 255 Ah\nstatus.kilowatt_hours  # 0.0 - 6553.5 kWh\nstatus.pv_current      # 0 - 255 A\nstatus.bat_current     # 0 - 255 A\nstatus.pv_voltage      # 0.0 - 6553.5 V\nstatus.bat_voltage     # 0.0 - 6553.5 V\nstatus.status          # A status code. See MXStatusPacket.STATUS_* constants.\nstatus.errors          # A 8 bit bit-field (documented in Outback's PDF)\n```\n\nAll values are floating-point numbers with units attached. You can convert them to real floats with eg. `float(status.pv_voltage) # 123.4`, or display them as a human-friendly string with `str(status.pv_voltage) # '123.4 V'`\n    \n### Log Pages\n    \nYou can also query a log page (just like you can on the MATE), up to 127 days in the past: (Logpages are stored at midnight, 0 is the current day so far)\n\n```python\nlogpage = mate_mx.get_logpage(-1)  # Yesterday's logpage\nlogpage.bat_max         # 0.0 - 102.3 V\nlogpage.bat_min         # 0.0 - 102.3 V\nlogpage.kilowatt_hours  # 0.0 - 409.5 kWh\nlogpage.amp_hours       # 0 - 16383 Ah\nlogpage.volts_peak      # 0 - 255 Vpk\nlogpage.amps_peak       # 0.0 - 102.3 Apk\nlogpage.absorb_time     # 4095 min  (minutes)\nlogpage.float_time      # 4095 min\nlogpage.kilowatts_peak  # 0.000 - 2.047 kWpk\nlogpage.day             # 0 .. -127\n```\n    \n### Properties\n    \nAdditionally, you can query individual registers (just like you can on the MATE - though it's buried quite deep in the menus somewhere)\n\n```python\nmate_mx.charger_watts\nmate_mx.charger_kwh\nmate_mx.charger_amps_dc\nmate_mx.bat_voltage\nmate_mx.panel_voltage\nmate_mx.status\nmate_mx.aux_relay_mode\nmate_mx.max_battery\nmate_mx.voc\nmate_mx.max_voc\nmate_mx.total_kwh_dc\nmate_mx.total_kah\nmate_mx.max_wattage\nmate_mx.setpt_absorb\nmate_mx.setpt_float\n```\n    \nNote that to read each of these properties a separate message must be sent, so it will be slower than getting values from a status packet.\n\n## FX Inverter Interface\n\nTo set up communication with an FX inverter:\n\n```python\nmate_bus = MateNET('COM1')         # Windows\nmate_bus = MateNET('/dev/ttyUSB0') # Linux\n\nmate_fx = MateDCDevice(bus, port=bus.find_device(MateNET.DEVICE_FX))\nmate_fx.scan()\n\nstatus = mate_fx.get_status()\nerrors = mate_fx.errors\nwarnings = mate_fx.warnings\n```\n\n### Controls\n\nYou can control an FX unit like you can through the MATE unit:\n\n```python\nmate_fx.inverter_control = 0  # 0: Off, 1: Search, 2: On\nmate_fx.acin_control = 0      # 0: Drop, 1: Use\nmate_fx.charge_control = 0    # 0: Off, 1: Auto, 2: On\nmate_fx.aux_control = 0       # 0: Off, 1: Auto, 2: On\nmate_fx.eq_control = 0        # 0: Off, 1: Auto, 2: On\n```\n    \nThese are implemented as python properties, so you can read and write them. Writing to them affects the FX unit.\n\n**WARNING**: Setting inverter_control to 0 **WILL** cut power to your house!\n    \n### Properties\n\nThere are a bunch of interesting properties, many of which are not available from the status packet:\n\n```python\nmate_fx.disconn_status\nmate_fx.sell_status\nmate_fx.temp_battery\nmate_fx.temp_air\nmate_fx.temp_fets\nmate_fx.temp_capacitor\nmate_fx.output_voltage\nmate_fx.input_voltage\nmate_fx.inverter_current\nmate_fx.charger_current\nmate_fx.input_current\nmate_fx.sell_current\nmate_fx.battery_actual\nmate_fx.battery_temp_compensated\nmate_fx.absorb_setpoint\nmate_fx.absorb_time_remaining\nmate_fx.float_setpoint\nmate_fx.float_time_remaining\nmate_fx.refloat_setpoint\nmate_fx.equalize_setpoint\nmate_fx.equalize_time_remaining\n```\n\n## FLEXnet DC Power Monitor Interface\n\nTo set up communication with a FLEXnet DC power monitor:\n\n```python\nmate_bus = MateNET('COM1')         # Windows\nmate_bus = MateNET('/dev/ttyUSB0') # Linux\n\nmate_dc = MateDCDevice(bus, port=bus.find_device(MateNET.DEVICE_FLEXNETDC))\n\nmate_dc.scan()\n\nstatus = mate_dc.get_status()\n```\n\nThe following information is available through `get_status()`:\n- State of Charge (%)\n- Battery Voltage (0-80V, 0.1V resolution)\n- Current kW/Amps for Shunts A/B/C\n- Current kW/Amps for In/Out/Battery (Max +/-1000A, 10W/0.1A resolution)\n- Daily kWH/Ah for Shunts A/B/C \u0026 In/Out/Battery/Net\n- Daily minimum State of Charge\n- Days since last full charge (0.1 day resolution)\n\nYou can manually reset daily accumulated values by writing to certain registers, \nbut this is not yet implemented.\n\n## Example Server\n\nFor convenience, a simple server is included that captures data periodically\nand uploads it to a remote server via a REST API.\nThe remote server then stores the received data into a database of your choice.\n\n\n## PJON Bridge\n\nThe default serial interface doesn't always work well, and it's not the most efficient,\nso there is an alternative protocol you can use which pipes the data to an Arduino via PJON protocol.\n\nTo use this alternative protocol:\n\n```python\nport = MateNETPJON('COM1')\nbus = MateNET(port)\n```\n\nSee [this page](https://github.com/jorticus/uMATE/blob/master/examples/Bridge/Bridge.ino) in my uMATE project for an example bridge implementation.\n\n## MATE Protocol RE ###\n\nFor details on the low-level communication protocol and available registers, see [doc/protocol/Protocol.md](doc/protocol/Protocol.md)\n\n---\n\nI am open to contributions, especially if you can test it with any devices I don't have.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorticus%2Fpymate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjorticus%2Fpymate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjorticus%2Fpymate/lists"}