{"id":13060,"date":"2026-09-18T07:35:00","date_gmt":"2026-09-18T05:35:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=13060"},"modified":"2026-08-31T15:15:29","modified_gmt":"2026-08-31T13:15:29","slug":"tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/","title":{"rendered":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP"},"content":{"rendered":"<p>A register number found in a forum post works. It works until a firmware update, until the next model of the same inverter, until a second device joins that stores the same value somewhere else. Then the number is wrong, and nothing says so: Modbus returns whatever is at that address, and a plausible number is indistinguishable from a correct one.<\/p>\n<p>SunSpec exists for this reason. It is a directory laid over the register space, and reading it takes four steps that work identically on every inverter that implements it.<\/p>\n<figure class=\"lw-diagram\">\n<img src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/sunspec-register-en.png\" width=\"1120\" height=\"580\" decoding=\"async\" loading=\"lazy\"\n     alt=\"A register map from address 40000 with the SunS marker, two model headers with their blocks and the end marker, beside a decode of one value together with its scale factor register\"><figcaption>The chain is self-describing: every model states its own length, so the address of the next one follows from the current one. Only the starting point has to be found.<\/figcaption><\/figure>\n<h2>Why a Register Number Alone Is Not Enough<\/h2>\n<p>Modbus has no notion of names, units or types. A read returns sixteen bits, and every interpretation of those bits happens in the reader. A register holding 1234 might be 1234 watts, 123.4 volts or 12.34 amperes, and the protocol has nothing to say about which.<\/p>\n<p>SunSpec adds three things on top of that, and all three are stored in the register space itself: a marker that says the map is present, a chain of blocks that says which measurements exist and where, and per group of values a scale factor that says where the decimal point goes.<\/p>\n<p>The practical consequence is that a reader written once works on the next device too. That is worth more than it sounds, because the alternative &#8211; a table of addresses per manufacturer and firmware version &#8211; is exactly the thing that quietly goes out of date.<\/p>\n<h2>Finding the Base Address and the Marker<\/h2>\n<p>The map begins at one of three addresses, and the first two registers say whether it does. They hold the four characters <code>SunS<\/code>, which as a 32-bit value is 0x53756E53.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>from pymodbus.client import ModbusTcpClient\n\nc = ModbusTcpClient(\"192.168.1.50\", port=502)\nc.connect()\n\nfor basis in (40000, 0, 50000):\n    r = c.read_holding_registers(basis, count=2, slave=1)\n    if not r.isError() and r.registers == [0x5375, 0x6E53]:\n        print(\"SunSpec at\", basis)\n        break<\/code><\/pre>\n<p>Two stumbling blocks live in that short piece of code. The first is the off-by-one that catches everybody once: documentation numbers registers from one, the protocol addresses them from zero. An address printed as 40001 in a manual is offset 40000 on the wire, and reading at 40001 returns the second half of the marker and no match.<\/p>\n<p>The second is the unit id. An inverter with a built-in smart meter answers as two devices on the same connection, each with its own id and its own SunSpec map. Reading the meter&#8217;s power from the inverter&#8217;s id gives a value that is not an error and not the truth. Which ids are in use is shown in the Modbus page of the device&#8217;s own web interface &#8211; and that page is also where Modbus TCP has to be switched on in the first place, because it is off by default on most inverters.<\/p>\n<h2>Walking the Model Chain<\/h2>\n<p>After the marker comes a sequence of blocks, and each block begins with two registers: its model number and its length. Adding the length to the current position gives the start of the next block, and a model number of 65535 ends the chain.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>pos = basis + 2\nwhile True:\n    kopf = c.read_holding_registers(pos, count=2, slave=1).registers\n    modell, laenge = kopf[0], kopf[1]\n    if modell == 0xFFFF:\n        break\n    print(f\"model {modell:5d}  length {laenge:3d}  data at {pos + 2}\")\n    pos += 2 + laenge<\/code><\/pre>\n<p>A typical inverter answers with three or four models, and the numbers say what each of them is.<\/p>\n<table style=\"width:100%;border-collapse:collapse;table-layout:auto;\">\n<thead>\n<tr>\n<th style=\"white-space:nowrap;vertical-align:top;\">Model<\/th>\n<th style=\"vertical-align:top;\">Content<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top;\">1<\/td>\n<td>Common: manufacturer, model designation, serial number, firmware version<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top;\">101, 102, 103<\/td>\n<td>Inverter, single phase, split phase, three phase &#8211; integers with scale factors<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top;\">111, 112, 113<\/td>\n<td>The same measurements as floating point numbers, without scale factors<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top;\">160<\/td>\n<td>The individual strings, one repeating block per MPP tracker<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top;\">201 to 204<\/td>\n<td>Meter, one model per wiring type<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Whether a device offers 103 or 113 is usually a setting rather than a property. Many inverters have a switch between integer with scale factors and floating point, and it decides which of the two model families appears in the chain. A reader that expects one and finds the other reports no measurements at all, which is a confusing symptom for a setting nobody remembers changing.<\/p>\n<h2>Scale Factors, Data Types and the Sentinels<\/h2>\n<p>Inside a model block, the position of a value is fixed by the specification and counted from the start of the data. The phase A current sits at offset 2, and the scale factor that belongs to it at offset 5.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>Model 103, data starting at 40071\n\n  offset 1   A      uint16   total current\n  offset 2   AphA   uint16   phase A\n  offset 3   AphB   uint16   phase B\n  offset 4   AphC   uint16   phase C\n  offset 5   A_SF   int16    scale factor for all four\n\n  40072 = 1234        raw value\n  40075 = 0xFFFE      two's complement, so \u22122\n\n  1234 \u00d7 10\u207b\u00b2 = 12.34 A<\/code><\/pre>\n<p>The scale factor is a signed exponent to base ten and applies to a whole group of values, not to one. That is why it appears once for four currents, and why reading a current without it produces a number a hundred times too large &#8211; which on a domestic system still looks like a plausible reading.<\/p>\n<p>Three more properties of the encoding matter in practice. Values spanning two registers are big-endian with the high word first, which is the Modbus convention and which almost every library gets right by default. Text fields are fixed-length and padded with null bytes rather than terminated by them. And a value that the device does not implement is not zero but a sentinel: 0x8000 for int16, 0xFFFF for uint16, 0x80000000 for int32. A reader that treats those as numbers reports 65535 volts, and a rule that discards them is three lines long.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>LEER = {\"int16\": 0x8000, \"uint16\": 0xFFFF,\n        \"int32\": 0x80000000, \"uint32\": 0xFFFFFFFF}\n\ndef wert(roh, typ, sf):\n    if roh == LEER.get(typ):\n        return None\n    return roh * (10 ** sf)<\/code><\/pre>\n<h2>Reading One Value End to End<\/h2>\n<p>The pieces together give a reader that finds the model rather than assuming its address.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>def modell_finden(c, basis, gesucht, slave=1):\n    pos = basis + 2\n    while True:\n        m, laenge = c.read_holding_registers(pos, count=2, slave=slave).registers\n        if m == 0xFFFF:\n            return None\n        if m == gesucht:\n            return pos + 2, laenge\n        pos += 2 + laenge\n\ndef vorzeichen(r):\n    return r - 0x10000 if r &gt; 0x7FFF else r\n\nstart, _ = modell_finden(c, 40000, 103)\nblock    = c.read_holding_registers(start, count=6, slave=1).registers\n\nstrom = block[1]                 # AphA, offset 2 counted from one\nsf    = vorzeichen(block[4])     # A_SF, offset 5\nprint(f\"{strom * 10 ** sf:.2f} A\")<\/code><\/pre>\n<p>Worth reading the whole block in one request rather than each value on its own. A Modbus read takes a few milliseconds of round trip regardless of length, so six registers in one call cost what one register in one call costs &#8211; and, more importantly, all six values then come from the same moment. Six separate reads of a current, a voltage and a power give three quantities that do not multiply together, and a plausibility check built on them fails for no reason.<\/p>\n<p>A note on polling frequency: an inverter is not a database. A request every five seconds is unproblematic, once a second is at the limit on some devices, and faster than that produces timeouts that look like network faults. The measured values themselves rarely update faster than every second anyway.<\/p>\n<h2>Putting It into Home Assistant<\/h2>\n<p>With the addresses known, the same reading works declaratively. Home Assistant&#8217;s Modbus integration handles the data type and the sign; only the scale factor has to be entered as a number, because the integration does not read it from the device.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>modbus:\n  - name: wechselrichter\n    type: tcp\n    host: 192.168.1.50\n    port: 502\n    sensors:\n      - name: \"Strom Phase A\"\n        slave: 1\n        address: 40072\n        data_type: uint16\n        scale: 0.01\n        precision: 2\n        unit_of_measurement: \"A\"\n        device_class: current\n        state_class: measurement\n        scan_interval: 10\n      - name: \"Wirkleistung\"\n        slave: 1\n        address: 40084\n        data_type: int16\n        scale: 1\n        precision: 0\n        unit_of_measurement: \"W\"\n        device_class: power\n        state_class: measurement\n        scan_interval: 10<\/code><\/pre>\n<p>The hard-coded <code>scale<\/code> is the compromise in this approach, and it is worth noting where it comes from. The scale factor was read once with the script above; it is stored in the device and practically never changes, but it is not guaranteed. After a firmware update, one comparison between the displayed value and the inverter&#8217;s own screen takes ten seconds and catches a factor of a hundred immediately.<\/p>\n<p>One last field decides whether the value ends up in the energy statistics rather than only on a card. A power reading in watts is <code>device_class: power<\/code> with <code>state_class: measurement<\/code>; a meter reading in kilowatt-hours is <code>device_class: energy<\/code> with <code>state_class: total_increasing<\/code>. The two are not interchangeable, and only the second can be selected as an energy source.<\/p>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/sunspec.org\/wp-content\/uploads\/2021\/02\/SunSpec-Device-Information-Model-Specificiation-V1-0-02-01-2021.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">SunSpec Device Information Model Specification (base addresses, SunS marker, scale factors)<\/a><\/li>\n<li><a href=\"https:\/\/sunspec.org\/wp-content\/uploads\/2019\/08\/SunSpec-Information-Models-12041.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">SunSpec Information Model Specification (model catalogue)<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A register number from a forum post works until the firmware moves it. Walking the SunSpec model chain finds the same value on any inverter &#8211; and the scale factor two registers further on is what turns 1234 into 12.34 amperes.<\/p>\n","protected":false},"author":1,"featured_media":13237,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[92624],"tags":[91371,91365,91657,91362,91219],"class_list":["post-13060","post","type-post","status-publish","format-standard","hentry","category-tutorials-en-smart-home","tag-energy-management","tag-home-assistant","tag-modbus","tag-photovoltaics","tag-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog<\/title>\n<meta name=\"description\" content=\"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-18T05:35:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP\",\"datePublished\":\"2026-09-18T05:35:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/\"},\"wordCount\":1179,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/hero-13060-tutorial-reading-sunspec-registers-from-.png\",\"keywords\":[\"Energy Management\",\"Home Assistant\",\"Modbus\",\"Photovoltaics\",\"Tutorial\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/\",\"name\":\"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/hero-13060-tutorial-reading-sunspec-registers-from-.png\",\"datePublished\":\"2026-09-18T05:35:00+00:00\",\"description\":\"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/hero-13060-tutorial-reading-sunspec-registers-from-.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/hero-13060-tutorial-reading-sunspec-registers-from-.png\",\"width\":1200,\"height\":630,\"caption\":\"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/smart-home\\\/tutorials-en-smart-home\\\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog","description":"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/","og_locale":"en_US","og_type":"article","og_title":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog","og_description":"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-09-18T05:35:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP","datePublished":"2026-09-18T05:35:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/"},"wordCount":1179,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png","keywords":["Energy Management","Home Assistant","Modbus","Photovoltaics","Tutorial"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/","name":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png","datePublished":"2026-09-18T05:35:00+00:00","description":"Finding the SunS marker, walking the model chain, decoding scale factors and data types, and turning the result into a Home Assistant sensor.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/hero-13060-tutorial-reading-sunspec-registers-from-.png","width":1200,"height":630,"caption":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/smart-home\/tutorials-en-smart-home\/tutorial-reading-sunspec-registers-from-a-pv-inverter-over-modbus-tcp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Tutorial: Reading SunSpec Registers From a PV Inverter Over Modbus TCP"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13060","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=13060"}],"version-history":[{"count":1,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13060\/revisions"}],"predecessor-version":[{"id":13411,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13060\/revisions\/13411"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/13237"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=13060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=13060"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=13060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}