Hantera multipla events från samma knapptryckning (Ansi C)

Moderator: Telldus

Post Reply
josefk
Posts: 10
Joined: Fri Mar 17, 2023 9:45 am

Hantera multipla events från samma knapptryckning (Ansi C)

Post by josefk »

Jag har lekt lite med demokoden och äntligen fått saker att fungera. Vad jag irriterade mig på var att API skickar flera events för samma knapptryckning.
Jag har nu fått ihop en fungerande demo som rensar dessa med hjälp av posix timers. Vid varje inkommande event sätts globala variabler (usch!!) och en timer startas, om det nya event'et skiljer sig från det förra rapporteras föregående omedelbart.

Jag har satt timeout'en till 1,5s vilket var värdet som krävdes för Nexa's dörrmagnet, som fullkomligt spyr ur sig signaler. Koden implementerar bara timers för DeviceEvent inte SensorEvent.

Hoppas detta kan vara till nytta för nån och/eller folk ser något sätt att lösa det snyggare.

Kompilerad med GCC, lägg till flaggan -lrt

Code: Select all

#include <telldus-core.h>
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>


void my_handler(int signum);
int last_id = -1;
int last_method = -1;


void report_event() {
	if (last_id > 0) {
		if (last_method == TELLSTICK_TURNON) {
			printf("ON event from device %i\n", last_id);
		} else if (last_method == TELLSTICK_TURNOFF) {
			printf("OFF event from device %i\n", last_id);
		} else {
			printf("Unknown event from device %i\n", last_id);
		}
		last_id = -1;
	}
}

void my_handler( int signum) {
	report_event();
}



void start_timer(int id, int method) {
	struct itimerval value;
	struct sigaction sa;

	// Timeout
	value.it_value.tv_sec = 1;
	value.it_value.tv_usec = 500000;
	value.it_interval.tv_sec = 0;
	value.it_interval.tv_usec = 0;

	// Install timer handler
	memset (&sa, 0, sizeof (sa));
	sa.sa_handler = &my_handler;
	sigaction (SIGALRM, &sa, NULL);
	setitimer (ITIMER_REAL, &value, NULL);

	// Report old if new event
	if ( (id != last_id) || (method != last_method) ) {
		report_event();
	}
	last_id = id;
	last_method = method;
}




void WINAPI deviceEvent(int deviceId, int method, const char *data, int callbackId, void *context) {
	start_timer(deviceId, method);
}

void WINAPI deviceChange(int deviceId, int method, const char *data, int callbackId, void *context) {
	start_timer(deviceId, method);
}



void WINAPI sensorEvent(const char *protocol, const char *model, int sensorId, int dataType, const char *value, int ts, int callbackId, void *context) {
	char timeBuf[80];
	time_t timestamp = ts;
	
	//Print the sensor
	printf("%s,\t%s,\t%i\n", protocol, model, sensorId);

	//Retrieve the values the sensor supports
	if (dataType == TELLSTICK_TEMPERATURE) {
		strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
		printf("Temperature:\t%sº\t(%s)\n", value, timeBuf);
		
	} else if (dataType == TELLSTICK_HUMIDITY) {
		strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
		printf("Humidity:\t%s%%\t(%s)\n", value, timeBuf);
	}
	printf("\n");
}



int main(void) {
	int callbacksensorId = 0;
	int callbackdeviceId = 1;
	int callbackchangeId = 2;
	tdInit();

	// Register for callback
	callbacksensorId = tdRegisterSensorEvent( (TDSensorEvent)&sensorEvent, 0 );
	callbackdeviceId = tdRegisterDeviceEvent( (TDDeviceEvent)&deviceEvent, 0 );
	callbackchangeId = tdRegisterDeviceChangeEvent( (TDDeviceChangeEvent)&deviceChange, 0 );

	while(1) {
		sleep(100);
	}

	// Cleanup
	tdUnregisterCallback( callbacksensorId );
	tdUnregisterCallback( callbackdeviceId );
	tdUnregisterCallback( callbackchangeId );
	tdClose();
	return 0;
}
Post Reply