Skip to content

thermostat raise_event - raise multiple events, only the first one is sent #72

@joseportillodev

Description

@joseportillodev

Hi SinricPro developers,

I'm contacting you to notify a small issue I find with calling raise_event several times in a row to update several device properties at once. The plan is to do this only once after initial connection, and then periodically raise events if necessary to update any value that may have changed locally by manual intervention.

I'm used to the SinricPro ESP8266 SDK, and with that one it is possible to issue multiple device.send*Event() commands in a row, e.g. to update several values on connection:

void SinricProIntegration::begin() {
	...
	SinricPro.onConnected([]() {
		Serial.println(F("INFO: [SinricPro] Connected"));
		// Update SinricPro initial state
		updatePowerStateTask();
		updateModeTask();
		updatePozoLevelsTask();
	}); 
	SinricPro.onDisconnected([]() {
		Serial.println(F("WARN: [SinricPro] Disconnected"));
	});
	SinricPro.onPong([](uint32_t rtt) {
		Serial.printf("DEBUG: [SinricPro] PING RTT: %u\r\n", rtt);
	});

	SinricPro.begin(SINRIC_APP_KEY, SINRIC_APP_SECRET);
}

void SinricProIntegration::updatePowerStateTask() {
	if (SinricPro.isConnected()) {
		for (unsigned int i = 0; i < NUM_VALVES; i++) {
			SinricProSwitch &device = SinricPro[SINRIC_VALVE_DEVICE_ID[i]];
			unsigned char value = ValveDriver::config.open[i];
			bool success = device.sendPowerStateEvent(value, "PERIODIC_POLL");
			if (!success) {
				Serial.println(F("ERROR: [SinricPro] sendPowerStateEvent failed"));
			}
		}
	}
}

With the Python SDK, in the other hand, it seems that only the first event is actually raised, the rest are silently ignored. For example, this code would send 3 events in a row every 60 seconds, for demonstration purposes:

async def events():
    while True:
        client.event_handler.raise_event(THERMOSTAT_ID, SinricProConstants.SET_POWER_STATE, data={SinricProConstants.STATE: SinricProConstants.POWER_STATE_ON})
        client.event_handler.raise_event(THERMOSTAT_ID, SinricProConstants.TARGET_TEMPERATURE, data={SinricProConstants.TEMPERATURE: 23.0})
        client.event_handler.raise_event(THERMOSTAT_ID, SinricProConstants.CURRENT_TEMPERATURE, data={SinricProConstants.TEMPERATURE: 18.5, SinricProConstants.HUMIDITY: 30.0})

        # Server will trottle / block IPs sending events too often.
        await sleep(60)

...but this yields the following log output (only event no. 1 was sent):

2025-11-16 23:31:49.903 | SUCCESS  | sinric._sinricpro_websocket:connect:54 - Connected :)
2025-11-16 23:31:49,904 - websockets.client - DEBUG - < TEXT '{"timestamp":1763332310}' [24 bytes]
2025-11-16 23:31:50.405 | INFO     | sinric._callback_handler:handle_callbacks:205 - Sending power state event
2025-11-16 23:31:50.405 | INFO     | sinric._callback_handler:handle_callbacks:206 - Request : {"header": {"payloadVersion": 2, "signatureVersion": 1}, "payload": {"action": "setPowerState", "cause": {"type": "PHYSICAL_INTERACTION"}, "createdAt": 1763332309, "deviceId": "6914********e38d", "replyToken": "b0b363bd-6e2b-443f-a8f8-5cb1e31c3fa7", "type": "event", "value": {"state": "On"}}, "signature": {"HMAC": "lGcQWxdy0ENtMxUsXfqmF4m9irpjWXXA9LjPtmLq2Sk="}}
2025-11-16 23:31:50,405 - websockets.client - DEBUG - > TEXT '{"header": {"payloadVersion": 2, "signatureVers...irpjWXXA9LjPtmLq2Sk="}}' [372 bytes]
2025-11-16 23:32:34,494 - websockets.client - DEBUG - < PING '' [0 bytes]
2025-11-16 23:32:34,494 - websockets.client - DEBUG - > PONG '' [0 bytes]

I would expect the server to reject/ignore events no. 2 and no. 3 according to the throttling policy the examples talk about, but it seems that it is the SDK itself (client code) who is skipping sending them to the server.

Inserting a 1-sec delay (await sleep(1)) between raise_event calls, it seems to send events #1 and #3:

2025-11-16 23:36:27.382 | SUCCESS  | sinric._sinricpro_websocket:connect:54 - Connected :)
2025-11-16 23:36:27,399 - websockets.client - DEBUG - < TEXT '{"timestamp":1763332587}' [24 bytes]
2025-11-16 23:36:27.900 | INFO     | sinric._callback_handler:handle_callbacks:205 - Sending power state event
2025-11-16 23:36:27.901 | INFO     | sinric._callback_handler:handle_callbacks:206 - Request : {"header": {"payloadVersion": 2, "signatureVersion": 1}, "payload": {"action": "setPowerState", "cause": {"type": "PHYSICAL_INTERACTION"}, "createdAt": 1763332587, "deviceId": "6914********e38d", "replyToken": "09e6f900-463f-45a8-998e-b91637c72a2a", "type": "event", "value": {"state": "On"}}, "signature": {"HMAC": "NXqRvWUhESVrEaK8Gca/6KmBAgYvcdme8bBJIgr8NHM="}}
2025-11-16 23:36:27,901 - websockets.client - DEBUG - > TEXT '{"header": {"payloadVersion": 2, "signatureVers...AgYvcdme8bBJIgr8NHM="}}' [372 bytes]
2025-11-16 23:36:29.404 | INFO     | sinric._callback_handler:handle_callbacks:199 - Sending temperature humidity event
2025-11-16 23:36:29.404 | INFO     | sinric._callback_handler:handle_callbacks:200 - Request : {"header": {"payloadVersion": 2, "signatureVersion": 1}, "payload": {"action": "currentTemperature", "cause": {"type": "PERIODIC_POLL"}, "createdAt": 1763332589, "deviceId": "6914********e38d", "replyToken": "85965f08-64ed-4800-bd23-196946c30932", "type": "event", "value": {"temperature": 20.0, "humidity": 30.0}}, "signature": {"HMAC": "ukx4zxxPPcs0sby+kMOKKZx7I0AutgmhnVpNR7i2Zxc="}}
2025-11-16 23:36:29,404 - websockets.client - DEBUG - > TEXT '{"header": {"payloadVersion": 2, "signatureVers...I0AutgmhnVpNR7i2Zxc="}}' [394 bytes]
2025-11-16 23:36:34,465 - websockets.client - DEBUG - < PING '' [0 bytes]
2025-11-16 23:36:34,465 - websockets.client - DEBUG - > PONG '' [0 bytes]

Inserting a 2-sec delay between raise_event calls, the three of them are sent, according to what I see in the log.

I wouldn't like to rely on inserting delays in order to get my updates sent, mostly because using delays in network-related code is a bad practice (even on async programming), since different network conditions may produce different unpredictable results.

So, maybe I'm missing something. Is there any specific, more recommended, mechanism to batch-update several values at a time? I don't mean to hammer the server, just update initial on/off state and target/current temperatures on connect.

Thank you!

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions