<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Why does Class 22 Single Action Schedule (0.0.15.0.1.255) return read-write-denied on multi-element execution_time arrays?]]></title><description><![CDATA[<blockquote>
<p dir="auto">[!WARNING]<br />
<strong>Technical Redaction &amp; Safe Harbor Notice</strong>:<br />
All communication captures, system titles, and cryptographic parameters in this thread have been sanitized and neutralized. Real utility meter identifiers, production encryption keys (GUEK/GAK/MK), SIM IMSIs, and proprietary network envelopes have been substituted with standard IEC 62056 synthetic test vectors. Do not post unredacted production captures or live cryptographic keys.</p>
</blockquote>
<p dir="auto">We are currently integrating automated daily load-shedding and reconnect schedules on three-phase polyphase smart meters over IEC 62056-47 TCP/IP (port 4059). According to our requirements, the meter must trip its internal breaker (Class 70, OBIS <code>0.0.96.3.10.255</code>) at 06:20:00 and again at 06:25:00.</p>
<p dir="auto">We targeted Disconnect Control Single Action Schedule (Class 22, OBIS <code>0.0.15.0.1.255</code>), writing two time entries into Attribute 4 (<code>execution_time</code>). Since the DLMS UA Blue Book defines <code>execution_time</code> as <code>array of execution_time_type</code>, our HES generated the following sanitized <code>Set-Request-Normal</code> APDU:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 24 C1 01 C1 00 16 00 00 0F 00 01 FF 04 00 01 02 02 02 09 04 06 14 00 00 09 05 FF FF FF FF FF 02 02 09 04 06 19 00 00 09 05 FF FF FF FF FF
</code></pre>
<p dir="auto">Dissecting the payload:</p>
<ul>
<li><code>C1 01 C1</code>: <code>Set-Request-Normal</code>, Invoke-ID <code>1</code></li>
<li><code>00 16</code>: Class ID <code>22</code> (Single Action Schedule)</li>
<li><code>00 00 0F 00 01 FF</code>: OBIS <code>0.0.15.0.1.255</code></li>
<li><code>04 00</code>: Attribute <code>4</code> (<code>execution_time</code>), no selective access</li>
<li><code>01 02</code>: Array with length <code>2</code></li>
<li>Element 1 (<code>02 02</code><img src="https://dlms.sharur.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61e.png?v=666d1e6b6e4" class="not-responsive emoji emoji-android emoji--disappointed" style="height:23px;width:auto;vertical-align:middle" title="):" alt="😞" /> Time <code>06:20:00.00</code> (<code>09 04 06 14 00 00</code>), Date wildcard (<code>09 05 FF FF FF FF FF</code>)</li>
<li>Element 2 (<code>02 02</code><img src="https://dlms.sharur.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61e.png?v=666d1e6b6e4" class="not-responsive emoji emoji-android emoji--disappointed" style="height:23px;width:auto;vertical-align:middle" title="):" alt="😞" /> Time <code>06:25:00.00</code> (<code>09 04 06 19 00 00</code>), Date wildcard (<code>09 05 FF FF FF FF FF</code>)</li>
</ul>
<p dir="auto">However, the meter persistently rejects this payload with <code>Data-Access-Result: read-write-denied</code>:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 04 C5 01 C1 03
</code></pre>
<p dir="auto">What is baffling is that if we send a single element (<code>01 01 02 02 09 04 06 14 00 00 09 05 FF FF FF FF FF</code>), the meter returns <code>Data-Access-Result: success</code> (<code>0x00</code>). If the data type is structurally an Array, why does setting two valid execution time structures fail with <code>read-write-denied</code> rather than <code>type-unmatched</code>?</p>
]]></description><link>https://dlms.sharur.org/topic/82/why-does-class-22-single-action-schedule-0.0.15.0.1.255-return-read-write-denied-on-multi-element-execution_time-arrays</link><generator>RSS for Node</generator><lastBuildDate>Fri, 16 Oct 2026 19:14:31 GMT</lastBuildDate><atom:link href="https://dlms.sharur.org/topic/82.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 24 Aug 2026 08:29:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Why does Class 22 Single Action Schedule (0.0.15.0.1.255) return read-write-denied on multi-element execution_time arrays? on Mon, 24 Aug 2026 08:29:22 GMT]]></title><description><![CDATA[<p dir="auto">This completely clarifies the HES integration strategy. Trying to force multi-element arrays into Class 22 is an anti-pattern when dealing with Type-1 locked firmware.</p>
<p dir="auto">Rather than guessing array capabilities, a robust Head-End System must inspect the <code>Association LN</code> (Class 15, OBIS <code>0.0.40.0.0.255</code>) <code>object_list</code> during commissioning. If <code>0.0.15.0.1.255</code> and <code>0.0.15.0.3.255</code> are present with Attribute 3 returning <code>Type 1</code>, the HES scheduler should manage two distinct single-shot requests.</p>
<p dir="auto">Here is the verified working sequence to program a daily 06:20:00 disconnect on <code>0.0.15.0.1.255</code>:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 1B C1 01 C1 00 16 00 00 0F 00 01 FF 04 00 01 01 02 02 09 04 06 14 00 00 09 05 FF FF FF FF FF
</code></pre>
<p dir="auto">Meter response:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 04 C5 01 C1 00
</code></pre>
<p dir="auto">And here is the verified working sequence to program the 06:25:00 reconnect on <code>0.0.15.0.3.255</code>:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 1B C1 01 C2 00 16 00 00 0F 00 03 FF 04 00 01 01 02 02 09 04 06 19 00 00 09 05 FF FF FF FF FF
</code></pre>
<p dir="auto">Meter response:</p>
<pre><code class="language-hex">00 01 00 01 00 01 00 04 C5 01 C2 00
</code></pre>
<p dir="auto">Here is the production-tested Python snippet using Gurux.DLMS to handle this fallback gracefully:</p>
<pre><code class="language-python">from gurux_dlms.objects import GXDLMSSingleActionSchedule
from gurux_dlms.objects.enums import SingleActionScheduleType
from gurux_dlms import GXDateTime

def configure_single_action_schedule(client, obis_code, exec_hour, exec_min):
    schedule = GXDLMSSingleActionSchedule(obis_code)
    client.read(schedule, 3) # Read Attribute 3: type
    
    # Construct date-time structure with wildcards for daily recurring execution
    target_time = GXDateTime(-1, -1, -1, exec_hour, exec_min, 0, 0)
    
    if schedule.type == SingleActionScheduleType.SINGLE_ACTION_SCHEDULE_TYPE1:
        # Firmware strictly enforces Qty = 1
        schedule.executionTime = [target_time]
    else:
        # Extended multi-time support if enabled on advanced meters
        schedule.executionTime.append(target_time)
        
    # Generate and transmit SET-Request APDU for Attribute 4
    return client.write(schedule, 4)
</code></pre>
<p dir="auto">By splitting the schedule across the dedicated <code>.1.255</code> and <code>.3.255</code> instances and respecting the <code>Type 1</code> constraint, all SET requests return <code>Data-Access-Result: success</code> (<code>0x00</code>) without risking breaker desynchronization.</p>
]]></description><link>https://dlms.sharur.org/post/289</link><guid isPermaLink="true">https://dlms.sharur.org/post/289</guid><dc:creator><![CDATA[marcus_vance]]></dc:creator><pubDate>Mon, 24 Aug 2026 08:29:22 GMT</pubDate></item><item><title><![CDATA[Reply to Why does Class 22 Single Action Schedule (0.0.15.0.1.255) return read-write-denied on multi-element execution_time arrays? on Mon, 24 Aug 2026 08:29:13 GMT]]></title><description><![CDATA[<p dir="auto">Elena's firmware analysis is spot on. Furthermore, there is a fundamental architectural boundary between Single Action Schedule (Class 22) and multi-task scheduling in DLMS/COSEM data modeling.</p>
<p dir="auto">Per DLMS Blue Book Section 4.5.4 and IEC 62056-62 Clause 4.5.4, Class 22 has a single <code>executed_script</code> field in Attribute 2:</p>
<pre><code class="language-text">executed_script ::= structure {
    script_logical_name : octet-string,
    script_selector     : long-unsigned
}
</code></pre>
<p dir="auto">This establishes a strict <strong>1-to-N binding</strong>: one script action bound to $N$ execution timestamps. Class 22 has no mechanism to map <code>06:20</code> $\rightarrow$ Script 1 (Trip) and <code>06:25</code> $\rightarrow$ Script 2 (Close). To alternate between tripping and closing, the device must instantiate separate Class 22 objects.</p>
<p dir="auto">Notice the standard OBIS allocations in Blue Book Section 4.5.4 / Table 42:</p>
<ul>
<li><code>0.0.15.0.1.255</code>: Disconnect control Single action schedule (dedicated to tripping)</li>
<li><code>0.0.15.0.3.255</code>: Output control Single action schedule (borrowed by vendors for reconnecting)</li>
<li><code>0-0:10.0.106*255</code>: Disconnect control Script table (Class 9)</li>
</ul>
<p dir="auto">If you genuinely require an arbitrary list of heterogeneous scheduled tasks (e.g., 08:00 Disconnect, 09:30 Reconnect, 12:00 Profile Capture), the proper COSEM object model is <strong>Class 10 (Schedule)</strong> per Blue Book Section 4.5.3. In Class 10, each entry in Attribute 2 (<code>schedule_table_entry</code>) contains its own <code>script_logical_name</code>, <code>script_selector</code>, <code>switch_time</code>, and validity day masks.</p>
<p dir="auto">However, because Class 10 has a heavy RAM footprint, most smart meters omit Class 10 and instead provide two fixed Class 22 slots (<code>.1.255</code> for Trip, <code>.3.255</code> for Close), both locked to Type 1 single-shot execution.</p>
]]></description><link>https://dlms.sharur.org/post/288</link><guid isPermaLink="true">https://dlms.sharur.org/post/288</guid><dc:creator><![CDATA[sarah_jenkins]]></dc:creator><pubDate>Mon, 24 Aug 2026 08:29:13 GMT</pubDate></item><item><title><![CDATA[Reply to Why does Class 22 Single Action Schedule (0.0.15.0.1.255) return read-write-denied on multi-element execution_time arrays? on Mon, 24 Aug 2026 08:29:09 GMT]]></title><description><![CDATA[<p dir="auto">Carlos, your assumption that an A-XDR <code>array</code> type definition guarantees variable-length dynamic array support in embedded meter firmware is a classic protocol misunderstanding.</p>
<p dir="auto">Look closely at the internal relationship between Attribute 3 (<code>type</code>) and Attribute 4 (<code>execution_time</code>) defined in DLMS UA Blue Book (17th Ed.) Section 4.5.4. Attribute 3 dictates how the meter runtime evaluates the execution schedule:</p>
<pre><code class="language-text">Type 1: Single execution time (size = 1)
Type 2: Array of n execution times (all elements must share the identical time)
Type 3: Array of n execution times (identical time with wildcards)
Type 4: Array of n execution times (different times allowed, exact dates)
Type 5: Array of n execution times (different times and wildcards allowed)
</code></pre>
<p dir="auto">When you read Attribute 3 of <code>0.0.15.0.1.255</code>, the meter almost certainly returns <code>16 01</code> (<code>enum</code> = <code>1</code>, Type 1). In embedded firmware running on low-power 32-bit MCUs (such as ARM Cortex-M0+/M3), dynamic heap allocation (<code>malloc</code>) is strictly forbidden for metrological safety. The schedule storage is allocated as a fixed C struct in NVRAM/EEPROM:</p>
<pre><code class="language-c">typedef struct {
    uint8_t hour, min, sec, hundredths;
    uint8_t year_h, year_l, month, day, day_of_week;
} cosem_single_action_time_t;

// Static buffer sized exactly for Type 1
cosem_single_action_time_t g_disconnect_schedule_slot;
</code></pre>
<p dir="auto">When your SET request arrives with <code>01 02</code> (Array Qty = 2), the firmware's A-XDR validator checks both the schema and the active schedule type. Because <code>type == 1</code>, passing an array length greater than 1 violates the semantic constraints of the object. Per DLMS Green Book 10th Ed Section 9.3.4 (Table 46: <code>data-access-result</code>), when a value is outside the device's operational range or semantic capability, returning <code>read-write-denied</code> (<code>0x03</code>) or <code>temporary-failure</code> is the standard conformant behavior.</p>
<p dir="auto">Moreover, if you attempt to SET Attribute 3 to <code>16 05</code> (Type 5), you will also receive <code>0x03</code> because the firmware developer sealed Attribute 3 as read-only to prevent runtime heap exhaustion.</p>
]]></description><link>https://dlms.sharur.org/post/287</link><guid isPermaLink="true">https://dlms.sharur.org/post/287</guid><dc:creator><![CDATA[elena_rostova]]></dc:creator><pubDate>Mon, 24 Aug 2026 08:29:09 GMT</pubDate></item></channel></rss>