Example #1
0
inline void timeservice_timer_handler(device_data_timeservice *p, uint8_t zyklus)
{
	if (zyklus != 1) return; // 1s-Zyklus verwendet

	// Increment our counter
	if (p->last_time_frame_received < 255)
		p->last_time_frame_received++;

	// Check, if the time we wait for an time frame has elapsed
	if (p->last_time_frame_received >= p->config.takeover_time)
	{
		// time has elapsed: We did not receive any time frame
		// which had a lower level than us in the given takeover_time
		//
		// So, we will become the time master.
		 
		if (p->last_time_frame_sent++ == p->config.interval)
		{
			canix_frame message;

			// The end of the interval has been reached, so send a new
			// time frame because we are the master !
			p->last_time_frame_sent = 0;

			message.src = canix_selfaddr();
			message.dst = HCAN_MULTICAST_INFO;
			message.proto = HCAN_PROTO_SFP;
			message.data[0] = HCAN_SRV_RTS;
			message.data[1] = HCAN_RTS_TIME_INFO;
			message.data[2] = p->config.level;
			message.data[3] = canix_rtc_clock.day_of_week;
			message.data[4] = canix_rtc_clock.hour;
			message.data[5] = canix_rtc_clock.minute;
			message.data[6] = canix_rtc_clock.second;
			message.size = 7;
			canix_frame_send(&message);

			// ... and send the date
			message.src = canix_selfaddr();
			message.dst = HCAN_MULTICAST_INFO;
			message.proto = HCAN_PROTO_SFP;
			message.data[0] = HCAN_SRV_RTS;
			message.data[1] = HCAN_RTS_DATE_INFO;
			message.data[2] = p->config.level;
			message.data[3] = canix_rtc_clock.day_of_month;
			message.data[4] = canix_rtc_clock.month_of_year;
			message.data[5] = canix_rtc_clock.year;
			message.size = 6;
			canix_frame_send(&message);
		}
	}
}
Example #2
0
void powerport_page_print_page(eds_powerport_page_block_t *p)
{
	char s[40];
	canix_frame message;

	// LCD Bildschirm loeschen
	lcd_clrscr();

	// 1. Zeile
	snprintf_P(s,sizeof(s), PSTR("%s"), p->line0); 
	lcd_gotoxy(0,0);
	lcd_puts(s);

	snprintf_P(s,sizeof(s), PSTR("%s"), p->line1); 
	lcd_gotoxy(0,1);
	lcd_puts(s);

	// In powerport_page_state wird spaeter der State gespeichert; sollte
	// keine Meldung eintreffen, so nuetzt es nichts, wenn der User OK
	// drueckt - man weiss ja den State nicht und kann ihn nicht aendern!
	// Das erkennt man am Wert -1
	powerport_page_state = -1;
	powerport_page_timer = -1;

	// nun den Status des Powerports erfragen und (asynchron)
	// in powerport_page_can_callback weitermachen

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_POWER_GROUP_STATE_QUERY;
	message.data[2] = p->gruppe;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

	canix_sleep_100th(1);

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_POWER_GROUP_TIMER_QUERY;
	message.data[2] = p->gruppe;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

}
Example #3
0
void rolladen_page_handle_key_down_event(eds_rolladen_page_block_t *p, 
		uint8_t key)
{
	if (key == KEY_OK)
	{
		canix_frame message;

		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_CONTROL;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
		message.data[1] = HCAN_HES_ROLLADEN_POSITION_SET;
		message.data[2] = p->gruppe;
		message.data[3] = p->pos;
		message.size = 4;
		canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

		lcdctrl_blink();

		return;
	}

	if (key == KEY_ESC)
	{
		goto_page_up();
		return;
	}

	if (key == KEY_UP)
		goto_prev_page();

	if (key == KEY_DOWN)
		goto_next_page();
}
Example #4
0
static inline void sendMessage(device_data_schalter *p, uint8_t active)
{
	canix_frame message;

	if(active)
		p->lastEdge = RISING;
	else
		p->lastEdge = FALLING;


	if(p->config.feature & (1<<FEATURE_SCHALTER_INVERTIEREN))
		active = !active; // invertieren

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	if(active)
	{
		if(p->config.feature & (1<<FEATURE_SCHALTER_MUTE))
			message.data[1] = HCAN_HES_MUTE_ON;
		else message.data[1] = HCAN_HES_SCHALTER_ON;
	}
	else
	{
		if(p->config.feature & (1<<FEATURE_SCHALTER_MUTE))
			message.data[1] = HCAN_HES_MUTE_OFF;
		else message.data[1] = HCAN_HES_SCHALTER_OFF;
	}
	message.data[2] = p->config.gruppe;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
}
Example #5
0
uint8_t get_weck_details(uint8_t weck_id, uint16_t *dauer)
{
	canix_frame message;

	weck_details_weck_id = weck_id;

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_WECKER_DETAILS_REQUEST;
	message.data[2] = weck_id;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
	weck_details_expected = 1; // Bit 0 = HCAN_HES_WECKER_DETAILS_REQUEST

	// Auf die Anwort warten
	canix_sleep_100th(5);

	if (weck_details_expected == 0)
	{
		// aha, es ist eine Antwort eingetroffen... (und zwar HCAN_HES_WECKER_DETAILS)

		*dauer = weck_details_dauer;
		weck_details_weck_id = 0;

		return 0;
	}

	// Timeout... keine Antwort erhalten :-(
	return 1;
}
Example #6
0
void set_weck_edited_details(eds_weck_page_block_t *p)
{
	canix_frame message;

	// 1. herausfinden, welcher Parameter geaendert wurde
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_WECKER_SET;
	message.data[2] = p->weck_id; //=Powerport-Gruppe

	message.data[3] = POWERPORT_FEATURE_WECK_VERZOEGERT_EIN; //Vorbelegung
	if ( p->feature & (1<<POWERPORT_FEATURE_WECK_VERZOEGERT_EIN) )
	{
		message.data[3] = POWERPORT_FEATURE_WECK_VERZOEGERT_EIN;
	}
	else if ( p->feature & (1<<POWERPORT_FEATURE_WECK_AUTO_AUS) )
	{
		message.data[3] = POWERPORT_FEATURE_WECK_AUTO_AUS;
	}

	message.data[4] = weck_details_dauer_edit >> 8; //Dauer bis Wecker einschaltet
	message.data[5] = weck_details_dauer_edit; //LSB
	message.size = 6;

	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

}
Example #7
0
void switch_to_battery(void)
{
	canix_frame message;

	// Status merken:
	on_battery = 1;


	// Relais schalten
	darlingtonoutput_setpin(7,1);

	// Timer auf 2 Sekunden setzen, d.h. fruehstens in
	// 2 Sekunden kann die USV wieder reagieren. Das ist noetig
	// damit kein "Prellen" oder "Flackern" passiert
	usv_timer = 200;

	// LEDs anpassen:
	led_set(3,0);
	led_set(6,10);

	// Busteilnehmer informieren:
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_INFO;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_USVS;
	message.data[1] = HCAN_USVS_STATE_INFO;
	message.data[2] = on_battery;
	message.size = 3;
	canix_frame_send(&message);
}
Example #8
0
void switch_to_netzbetrieb(void)
{
	canix_frame message;

	// Status merken:
	on_battery = 0;

	// Relais schalten
	darlingtonoutput_setpin(7,0);

	// Auch hier wieder: ein Prellen verhindern
	usv_timer = 10;

	// LEDs anpassen:
	led_set(3,10);
	led_set(6,0);

	// Busteilnehmer informieren:
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_INFO;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_USVS;
	message.data[1] = HCAN_USVS_STATE_INFO;
	message.data[2] = on_battery;
	message.size = 3;
	canix_frame_send(&message);
}
Example #9
0
void usv_can_callback(const canix_frame *frame)
{
	canix_frame answer;

	answer.src = canix_selfaddr();
	answer.dst = frame->src;
	answer.proto = HCAN_PROTO_SFP;
	answer.data[0] = HCAN_SRV_USVS;

	switch (frame->data[1])
	{
		case HCAN_USVS_STATE_REQUEST :
			{
				answer.data[1] = HCAN_USVS_STATE_INFO;
				answer.data[2] = on_battery;
				answer.size = 3;

				canix_frame_send(&answer);
			}
			return;
		case HCAN_USVS_VOLTAGE_REQUEST :
			{
				// "- 1" : U1-U5 wird abgebildet auf 0..4
				const uint8_t n = frame->data[2] - 1;

				if (n < 5)
				{
					uint16_t U = adc_reach_channel(n);
					answer.data[1] = HCAN_USVS_VOLTAGE_REPLAY;
					answer.data[2] = U >> 8;
					answer.data[3] = U;
					answer.size = 4;

					canix_frame_send(&answer);
				}
			}
			return;
		case HCAN_USVS_VOLTAGE_STATS_REQUEST :
			{
				// "- 1" : U1-U5 wird abgebildet auf 0..4
				const uint8_t n = frame->data[2] - 1;

				if (n < 5)
				{
					answer.data[1] = HCAN_USVS_VOLTAGE_STATS_REPLAY;
					answer.data[2] = frame->data[2];
					answer.data[3] = U_min[n] >> 8;
					answer.data[4] = U_min[n];
					answer.data[5] = U_max[n] >> 8;
					answer.data[6] = U_max[n];
					answer.size = 7;

					canix_frame_send(&answer);
				}
			}
Example #10
0
uint8_t get_heiz_details(uint8_t heiz_id, 
		uint8_t *mode,
		uint8_t *rate,
		int16_t *Tsoll,
		uint16_t *dauer,
		uint16_t *Tist)
{
	canix_frame message;

	heiz_details_heiz_id = heiz_id;
	heiz_details_Tsoll = 0;

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_HEIZUNG_DETAILS_REQUEST;
	message.data[2] = heiz_id;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
	heiz_details_expected = 1; // Bit 0 = HCAN_HES_HEIZUNG_DETAILS_REQUEST

	// Auf die Anwort warten
	canix_sleep_100th(5);

	// ... und noch nach T(ist) fragen...
	message.data[1] = HCAN_HES_HEIZUNG_TIST_REQUEST;
	message.data[2] = heiz_id;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
	heiz_details_expected = 2; // Bit 1 = HCAN_HES_HEIZUNG_TIST_REQUEST

	// Auf die Anwort warten
	canix_sleep_100th(5);

	if (heiz_details_expected == 0)
	{
		// aha, es ist eine Antwort eingetroffen...

		*mode = heiz_details_mode;
		*rate = heiz_details_rate;
		*Tsoll = heiz_details_Tsoll;
		*Tist = heiz_details_Tist;
		*dauer = heiz_details_dauer;
		heiz_details_heiz_id = 0;

		return 0;
	}

	// Timeout... keine Antwort erhalten :-(
	return 1;
}
Example #11
0
static inline void sendMessage(device_data_zeitschaltuhr *p, uint8_t zustandToSend)
{
	canix_frame message;
	
		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_CONTROL;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
	message.data[1] = zustandToSend;
		message.data[2] = p->config.power_gruppe;
		message.size    = 3;
		canix_frame_send(&message);
}
Example #12
0
static inline void sendMessage(device_data_zentralheizungspumpe *p, uint8_t zustandToSend)
{
	canix_frame message;

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = zustandToSend; // Zentralheizungspumpe schalten
	message.data[2] = p->config.gruppe;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
}
Example #13
0
void send_log(uint8_t data, uint8_t data2)
{
	canix_frame answer;

	answer.src = canix_selfaddr();
	answer.dst = 40;
	answer.proto = HCAN_PROTO_SFP;
	answer.data[0] = 21;
	answer.data[1] = data;
	answer.data[2] = data2;
	answer.size = 3;
	canix_frame_send(&answer);
	delay(1);
}
Example #14
0
void send_rolladen_position_set(device_data_rolladenSchlitzpos *p, uint8_t soll_position)
{
	canix_frame message;

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_ROLLADEN_POSITION_SET;
	message.data[2] = p->config.rolladen;
	message.data[3] = soll_position; //gewuenschte Rollladenposition: z.B. Pos: 0=zu, SCHLITZ_POS
	message.size = 4;

	canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);
}
Example #15
0
/** Der poti_timer_handler liest den ADC-Wert des
 *  konfigurierten Potis und sendet diesen auf den CAN-Bus. */
inline void poti_timer_handler(device_data_poti *p, uint8_t zyklus)
{		
	if (zyklus != 10) return; // 10tel-Sekunden-Zyklus verwendet

	int16_t currentADCvalue;
	
	setADMUX(p->config.port);
	currentADCvalue = getADCvalue();	
		
	if (p->potiTelegramCountdown)
	{
		/* Abfrage, ob sich der ADC-Wert signifikant aenderte,
		 * gegenueber dem Wert im letzten Potitelegramm (Filterung): */
		if ( ( currentADCvalue > (p->lastPotiValue + POTI_VALUE_TOLERANCE) ) ||
			 ( currentADCvalue < (p->lastPotiValue - POTI_VALUE_TOLERANCE) ) )
		{
			//sign. Potiwertaenderung gegenueber dem currentADCvalue
			p->potiTelegramCountdown--;
		}
		else
		{
			//Potiwert wieder der gleiche Wert (oder zumindest in etwa)
			p->potiTelegramCountdown = POTI_TELEGRAM_COUNTDOWN_INIT;
		}
	}
	else //p->potiTelegramCountdown == 0
	{
		//Das Potitelegramm senden:
		p->lastPotiValue = currentADCvalue; //Angleich
		p->potiTelegramCountdown = POTI_TELEGRAM_COUNTDOWN_INIT;
		
		//sende das Potitelegramm: 
		canix_frame message;
	
		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_CONTROL;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
		
		message.data[1] = HCAN_HES_POTI_POS_CHANGED;
		message.data[2] = p->config.gruppe;
		message.data[3] = (uint8_t)((currentADCvalue & 0xFF00) >> 8); //high value
		message.data[4] = (uint8_t)currentADCvalue; //low value
		message.size = 5;
		canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);
	}
}
Example #16
0
static void rolladen_send_changed_info(device_data_rolladen *p, uint8_t pos)
{
	canix_frame message;

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_INFO;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = HCAN_HES_ROLLADEN_POSITION_CHANGED_INFO;
	message.data[2] = p->config.taster;
	message.data[3] = pos; // aktuelle Position in %
	message.data[4] = 0; // Quelle des cmd: nicht verwendet
	message.data[5] = 0; // Quelle des cmd: nicht verwendet
	message.size = 6;

	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
}
Example #17
0
void canix_syslog_P(uint8_t prio, const char *fmt, ...)
{
	if (canix_debug_level >= prio)
	{
		canix_frame message;
		uint8_t s_counter, payload_counter;
		char s[128];
		va_list ap;

		va_start(ap, fmt);
		vsnprintf_P(s, sizeof(s)-2, fmt, ap);
		va_end(ap);

		// An das Ende ein Retrun Zeichen anhaengen; somit kann die
		// empfangende Seite erkennen, wann die Meldung beendet ist.
		//
		// Hier benoetigen wir keinen Laengen-Check, da wir oben
		// sizeof(s)-2 verwendet haben.
		strcat(s,"\n");

		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_SYSLOG;
		message.proto = HCAN_PROTO_SYSLOG;

		s_counter = 0;

		message.data[0] = prio;
		payload_counter = 1;

		while (s_counter < strlen(s))
		{
			wdt_reset();

			while ((payload_counter < 8) && (s_counter < strlen(s)))
			{
				message.data[payload_counter++] = s[s_counter++];
			}

			message.size = payload_counter;
			payload_counter = 0;
			canix_frame_send(&message);
		}

		canix_sleep_100th(1);
	}
}
Example #18
0
inline void rolladenSchlitzpos_timer_handler(device_data_rolladenSchlitzpos *p, uint8_t zyklus)
{
	if (zyklus != 10) return; // 10tel-Sekunden-Zyklus verwendet

	canix_frame message;

	if(p->rolladenSchlitzJob < SCHLITZ_JOB_ABGEMELDET) //ist der Job angemeldet
	{
		p->rolladenSchlitzJob--; //es sind wieder 100 ms vergangen
		//canix_syslog_P(SYSLOG_PRIO_DEBUG, PSTR("p->rolladenSchlitzJob=%d"), p->rolladenSchlitzJob);
		if(p->rolladenSchlitzJob == 0)
		{
			p->rolladenSchlitzJob = SCHLITZ_JOB_ABGEMELDET;

			/* Warte zwei Sekunden. Falls das Fenster wieder geoeffnet wird,
			 * wird der rolladenSchlitzJob wieder abgemeldet,
			 * die HCAN_HES_REEDKONTAKT_STATE_QUERY nicht gesendet
			 * und somit der Rollladen nicht geschlossen.
			 * ...und dann in HCAN_HES_REEDKONTAKT_STATE_REPLAY die Abfrage,
			 * ob der Reedkontakt immer noch zu ist: */
			message.src = canix_selfaddr();
			message.dst = HCAN_MULTICAST_CONTROL;
			message.proto = HCAN_PROTO_SFP;
			message.data[0] = HCAN_SRV_HES;

			message.data[1] = HCAN_HES_ROLLADEN_POSITION_REQUEST;
			message.data[2] = p->config.rolladen;
			message.size = 3;
			canix_frame_send_with_prio(&message, HCAN_PRIO_HI); //rolladenIstposition-Abfrage

			//und Reedkontakt(e) abfragen:
			message.data[1] = HCAN_HES_REEDKONTAKT_STATE_QUERY;
			message.data[2] = p->config.reed0;
			message.size = 3;
			canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);

			if(p->config.reed1 != 255) //zweiter Reedkontakt vorhanden?
			{
				message.data[2] = p->config.reed1;
				canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);
			}
		}
	}
}
/**
 * Fragt alle konfigurierten Reedkontakte nach ihrem Status und sammelt
 * die Ergebnisse in fenster_monitor_reed_state; liefert die Anzahl der
 * offenen Reedkontakte zurueck
 */
uint8_t fenster_monitor_collect_reed_states(eds_fenster_monitor_page_block_t 
		*p)
{
	uint8_t i,n_reed_open;
	uint8_t *reeds = (uint8_t *)(&p->reed0);

	// Ergebnis-Array initialisieren:
	for (i = 0; i < 24; i++)
		fenster_monitor_reed_state[i] = 255;

	// ueber alle Reedkontakte iterieren:
	for (i = 0; i < 24; i++)
	{
		if (reeds[i] != 255) // ist es ein konfigurierter Reedkontakt?
		{
			// Nach Kontakt-Status fragen; die Ergebnisse kommen asynchron
			// ueber den CAN Handler rein
			canix_frame message;
			message.src = canix_selfaddr();
			message.dst = HCAN_MULTICAST_CONTROL;
			message.proto = HCAN_PROTO_SFP;
			message.data[0] = HCAN_SRV_HES;
			message.data[1] = HCAN_HES_REEDKONTAKT_STATE_QUERY;
			message.data[2] = reeds[i]; // die Reedkontakt-Gruppen-ID
			message.size = 3;
			canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);

			canix_sleep_100th(10); // 100msec Pause
		}
		wdt_reset();
	}

	// Reedkontakte zaehlen:
	n_reed_open = 0;
	for (i = 0; i < 24; i++)
	{
		if ((fenster_monitor_reed_state[i]) && 
				(fenster_monitor_reed_state[i] != 255))
			n_reed_open++;
	}

	return n_reed_open;
}
Example #20
0
/**
 * Fragt alle konfigurierten Reedkontakte nach ihrem Status und sammelt
 * die Ergebnisse in monitor_reedkontakt_state
 */
static void init_monitor_reedkontakt_request_states(void)
{
	eds_block_p it = eds_find_next_block((eds_block_p)0, EDS_userpanel_reedkontakte_BLOCK_ID);
	if (!it)
	{
		load_error_page(ERROR_CONF_REEDKONTAKTE_MISSING);
		reedkontakt_configured = 0;
		return;
	}

	userpanel_reedkontakte_t c;
	eeprom_read_block(&c, (it+2), sizeof(c));
	uint8_t i;

	// Ergebnis-Array initialisieren:
	for (i = 0; i < 24; i++)
		monitor_reedkontakt_state[i] = 255;

	// ueber alle Reedkontakte iterieren:
	for (i = 0; i < 24; i++)
	{
		if (c.reed[i] != 255) // ist es ein konfigurierter Reedkontakt?
		{
			// Nach Kontakt-Status fragen; die Ergebnisse kommen asynchron
			// ueber den CAN Handler rein
			canix_frame message;
			message.src = canix_selfaddr();
			message.dst = HCAN_MULTICAST_CONTROL;
			message.proto = HCAN_PROTO_SFP;
			message.data[0] = HCAN_SRV_HES;
			message.data[1] = HCAN_HES_REEDKONTAKT_STATE_QUERY;
			message.data[2] = c.reed[i]; // die Reedkontakt-Gruppen-ID
			message.size = 3;
			canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);

			canix_sleep_100th(10); // 100msec Pause
		}
		wdt_reset();
	}
}
Example #21
0
static inline void sendMessage(device_data_powerportAutomat *p, uint8_t active)
{
	canix_frame message;

	// Helligkeitssensor:
	if(	p->automatikEin // Automatikbetrieb
		&& (HCAN_HES_POWER_GROUP_ON == active) // HCAN_HES_POWER_GROUP_OFF soll immer moeglich sein
		&& (p->brightness != 65535) // Helligkeitssensor verwenden?
		&& (p->brightness > p->config.helligkeitsschwelle) ) // zu hell?
	{
		return; // zu hell -> kein HCAN_HES_POWER_GROUP_ON senden
	}

	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	message.data[1] = active; // HCAN_HES_POWER_GROUP_ON oder HCAN_HES_POWER_GROUP_OFF
	message.data[2] = p->config.powerport_gruppe;
	message.size = 3;
	canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
}
Example #22
0
void hauselektrik_callback(const canix_frame *frame)
{
	// Dieser Handler wird fuer alle Destination Adressen ausgefuehrt
	// daher muss gefiltert werden, was uns betrifft und was nicht

	if ( (frame->data[0] != HCAN_SRV_HES) || 
			((frame->dst != canix_selfaddr()) && 
			 (frame->dst != HCAN_MULTICAST_CONTROL) &&
			 (frame->dst != HCAN_MULTICAST_INFO))) 
	{
		// Diese Message ist nicht interessant, daher ignorieren
		return;
	}

	lcdstatemachine_can_callback(frame);

	switch (frame->data[1])
	{
		case HCAN_HES_CONFIG_RELOAD :
			return;
	}
}
Example #23
0
void taster_page_handle_key_down_event(eds_taster_page_block_t *p, 
		uint8_t key)
{
	if (key == KEY_OK)
	{
		canix_frame message;

		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_CONTROL;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
		message.data[1] = HCAN_HES_TASTER_DOWN;
		message.data[2] = p->gruppe;
		message.size = 3;
		canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

		canix_sleep_100th(1);
		
		message.data[1] = HCAN_HES_TASTER_UP;
		message.size = 3;
		canix_frame_send_with_prio(&message, HCAN_PRIO_HI);

		lcdctrl_blink();

		return;
	}

	if (key == KEY_ESC)
	{
		goto_page_up();
		return;
	}

	if (key == KEY_UP)
		goto_prev_page();

	if (key == KEY_DOWN)
		goto_next_page();
}
Example #24
0
/** Der helligkeitssensor_timer_handler wird alle 1 s aufgerufen: Er liest den ADC-Wert des
 *  konfigurierten helligkeitssensors und sendet diesen auf den CAN-Bus. */
inline void helligkeitssensor_timer_handler(device_data_helligkeitssensor *p, uint8_t zyklus)
{		
	if (zyklus != 1) return; // 1s-Zyklus verwendet

	uint16_t currentADCaverage;
	
	if (p->secsUntilNextSend)
	{
		p->secsUntilNextSend--;

		// nur die letzten n Werte vorm Senden sind wichtig:
		if(p->secsUntilNextSend <= SIZE_OF_AVG)
		{
			setADMUX(p->config.port);
			addToFloatAvg(&(p->filterBrightness), getADCvalue_inverted());
		}
	}
	else
	{
		currentADCaverage = getOutputValue(&(p->filterBrightness));

		// sende das Helligkeitssensortelegramm:
		canix_frame message;
		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_CONTROL;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;

		message.data[1] = HCAN_HES_HELLIGKEITS_INFO; //z.B. fuer rolladenAutomat-Device
		message.data[2] = p->config.gruppe;
		message.data[3] = (uint8_t)((currentADCaverage & 0xFF00) >> 8); //high value
		message.data[4] = (uint8_t)currentADCaverage; //low value
		message.size = 5;
		canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);

		p->secsUntilNextSend = (uint16_t) 60 * p->config.sendCycleMins;
	}
}
Example #25
0
/**
 * Sendet Updates an alle Action-Gruppen
 */
void inform_action_groups(const device_data_lichtzone *p)
{
	canix_frame answer;
	uint8_t *action_group;
	uint8_t i;

	action_group = (uint8_t *)&(p->config.action_gruppe0);

	for (i = 0; i < 2; i++)
	{
		if (action_group[i] != 255)
		{
			answer.src = canix_selfaddr();
			answer.dst = HCAN_MULTICAST_CONTROL;
			answer.proto = HCAN_PROTO_SFP;
			answer.data[0] = HCAN_SRV_HES;
			answer.data[1] = p->state != 0 ? HCAN_HES_POWER_GROUP_ON : HCAN_HES_POWER_GROUP_OFF;
			answer.data[2] = action_group[i];
			answer.size = 3;
			canix_frame_send_with_prio(&answer, HCAN_PRIO_HI);
		}
	}
}
Example #26
0
void heizung_can_callback(device_data_heizung *p, const canix_frame *frame)
{
	canix_frame answer;

	answer.src = canix_selfaddr();
	answer.dst = frame->src;
	answer.proto = HCAN_PROTO_SFP;
	answer.data[0] = HCAN_SRV_HES;

	switch (frame->data[1])
	{
		case HCAN_HES_1WIRE_TEMPERATURE :
			if (frame->data[2] == p->config.sensor_id)
			{
				// we have a heizung and a temp sensor frame
				// now look if if fits to the heizung

				// temperature is a fixed point number mit 4 LSB Bits
				int16_t sensor_temp = frame->data[3] << 8 | 
					frame->data[4];

				// store the measure value
				p->measure_value = sensor_temp;
				p->received_interval_counter = 0;
			}
			break;

		case HCAN_HES_HEIZUNG_SET_MODE_OFF :
			if (p->config.id == frame->data[2])
				p->mode = HEIZUNG_MODE_OFF;
			break;

		case HCAN_HES_HEIZUNG_SET_MODE_MANUAL :
			if (p->config.id == frame->data[2])
			{
				p->mode = HEIZUNG_MODE_MANUAL;
				p->manual_rate = frame->data[3];
				p->duration_counter = (frame->data[4] << 8) | frame->data[5];
			}
			break;

		case HCAN_HES_HEIZUNG_SET_MODE_THERMOSTAT_DETAILS :
			if (p->config.id == frame->data[2])
			{
				p->mode = HEIZUNG_MODE_THERMOSTAT;
				p->thermostat_temp = (frame->data[3] << 8) | frame->data[4];
				p->duration_counter = (frame->data[5] << 8) | frame->data[6];
			}
			break;

		case HCAN_HES_HEIZUNG_SET_MODE_AUTOMATIK:
			if (p->config.id == frame->data[2])
				p->mode = HEIZUNG_MODE_AUTOMATIK;
			break;

		case HCAN_HES_HEIZUNG_DETAILS_REQUEST :
			{
				if (p->config.id == frame->data[2])
				{
					switch (p->mode)
					{
						case HEIZUNG_MODE_OFF :
							answer.data[1] = 
								HCAN_HES_HEIZUNG_MODE_OFF_DETAILS;
							answer.data[2] = p->config.id;
							answer.size = 3;
							canix_frame_send_with_prio(&answer, HCAN_PRIO_HI);
							break;

						case HEIZUNG_MODE_MANUAL :
							answer.data[1] = 
								HCAN_HES_HEIZUNG_MODE_MANUAL_DETAILS;
							answer.data[2] = p->config.id;
							answer.data[3] = p->manual_rate;
							answer.data[4] = p->duration_counter >> 8;
							answer.data[5] = p->duration_counter;
							answer.size = 6;
							canix_frame_send_with_prio(&answer, HCAN_PRIO_HI);
							break;

						case HEIZUNG_MODE_THERMOSTAT :
							answer.data[1] = 
								HCAN_HES_HEIZUNG_MODE_THERMOSTAT_DETAILS;
							answer.data[2] = p->config.id;
							answer.data[3] = p->thermostat_temp >> 8;
							answer.data[4] = p->thermostat_temp;
							answer.data[5] = p->duration_counter >> 8;
							answer.data[6] = p->duration_counter;
							answer.size = 7;
							canix_frame_send_with_prio(&answer, HCAN_PRIO_HI);
							break;

						case HEIZUNG_MODE_AUTOMATIK :
							{
								int8_t index;
								index = heizung_get_matching_zeitzone_index(p);
								if (index != -1)
								{
									// we got an zeitzone which matches
									int16_t master_value = 0;
									solltemp_line_t *zeitzone = 
										(solltemp_line_t *) 
										&(p->config.zeitzone0_id);

									master_value = zeitzone[index].temp;
									answer.data[1] = 
										HCAN_HES_HEIZUNG_MODE_AUTOMATIK_DETAILS;
									answer.data[2] = frame->data[2];
									answer.data[3] = master_value >> 8;
									answer.data[4] = master_value;
									answer.data[5] = 
										heizung_get_matching_zeitzone_id(p);
									answer.size = 6;
								}
								else
								{
									canix_syslog_P(SYSLOG_PRIO_ERROR,
											PSTR("zeitzone: no match!"));

									answer.data[1] = 
										HCAN_HES_HEIZUNG_MODE_AUTOMATIK_DETAILS;
									answer.data[2] = frame->data[2];
									answer.data[3] = 0;
									answer.data[4] = 0;
									answer.data[5] = 0;
									answer.size = 6;
								}
								canix_frame_send_with_prio(&answer, 
										HCAN_PRIO_HI);
							}
							break;
					}
				}
			}
Example #27
0
/**
 * this timer handler is called every second
 */
void heizung_timer_handler(device_data_heizung *p)
{
	if (p->ventilpflege_counter > 0)
		p->ventilpflege_counter--;

	// Ventilpflege aktivieren, falls der richtige Zeitpunkt dazu ist:
	heizung_check_ventilpflege(p);

	if (p->received_interval_counter != 0xff)
		p->received_interval_counter++;

	heizung_handle_pwm(p);

	if (p->duration_counter > 0)
	{
		p->duration_counter -= 1;
		if (p->duration_counter == 0)
		{
			// Zeit ist abgelaufen; nun wieder auf Automatik-Modus
			// stellen:
			//
			p->mode = HEIZUNG_MODE_AUTOMATIK;
		}
	}

	if (p->reed_heiz_stop_counter > 0)
	{	
		p->reed_heiz_stop_counter -= 1;

		if (p->reed_heiz_stop_counter == 0)
		{
			canix_syslog_P(SYSLOG_PRIO_DEBUG,
					PSTR("heiz-stop ende (heizung %d)"), p->config.id);
		}
	}

	/*
	 * Schaltet die HK-Ventile aus, wenn ein Heizstop vorliegt. Dies passiert
	 * in regelmaessigen Abstaenden, da eventuell aufgrund der Heizsteuerlogik
	 * die PWM nicht regelmaessig upgedatet wird und so das HK-Ventil nicht auf
	 * den Reedkontakt reagiert.
	 */
	heizung_update_heizstop(p);

	if (p->timer_counter++ >= 5)
	{
		p->timer_counter = 0;

		switch (p->mode)
		{
			case HEIZUNG_MODE_OFF : 
				{
					if (p->ventilpflege_counter)
					{
						// Sonderfall: Ventilpflege ist aktiv; dazu
						// Ventil einschalten, sonst aber nichts
						// unternehmen:
						
						p->manual_rate = 0;

						// Ventil einschalten:
						heizung_set_pwm(p,100);
						darlingtonoutput_setpin(p->config.port, 1);

						canix_syslog_P(SYSLOG_PRIO_DEBUG, 
								PSTR("ventilpflege: 1"));
					}
					else
					{
						// das ist Normalfall: keine Ventilpflege aktiv.
						p->manual_rate = 0;
						heizung_set_pwm(p,0);

						// Ventil ausschalten, falls es an ist:
						if (darlingtonoutput_getpin(p->config.port))
							darlingtonoutput_setpin(p->config.port, 0);
					}
					return;
				}
			case HEIZUNG_MODE_MANUAL :
				{
					heizung_set_pwm(p, p->manual_rate);
				}
				break;
			case HEIZUNG_MODE_AUTOMATIK :
				{
					// Wenn ein gueltiger Messwert vorliegt
					// (d.h. wenn innerhalb eines definierten Zeitraumes
					// ein Sensor-Messwert eingetroffen ist:
					if (p->received_interval_counter < 255)
					{
						int8_t index;
						index = heizung_get_matching_zeitzone_index(p);
						if (index != -1)
						{
							// we got an zeitzone which matches
							solltemp_line_t *solltemp_line = (solltemp_line_t*) 
								&(p->config.zeitzone0_id);
							heizung_set_pwm_by_temp(p, 
									solltemp_line[index].temp,
									p->measure_value);
						}
						else
						{
							// keine passende Zeitzone gefunden
							heizung_set_pwm(p,0);
						}
					}
					else
					{
						canix_syslog_P(SYSLOG_PRIO_ERROR, 
								PSTR("keine Sensor-Messwerte vorhanden!"));
					}
				}
				break;
			case HEIZUNG_MODE_THERMOSTAT :
				{
					// Wenn ein gueltiger Messwert vorliegt
					// (d.h. wenn innerhalb eines definierten Zeitraumes
					// ein Sensor-Messwert eingetroffen ist:
					if (p->received_interval_counter < 255)
					{
						heizung_set_pwm_by_temp(p, p->thermostat_temp,
								p->measure_value);
					}
					else
					{
						canix_syslog_P(SYSLOG_PRIO_ERROR, 
								PSTR("keine Sensor-Messwerte vorhanden!"));
					}
				}
				break;
		}
	}

	// Waermebedarfsmeldung versenden:
	if (p->waermebedarf_counter-- == 0)
	{
		canix_frame message;

		// Waermebedarfsmeldungen alle 60 Sekunden
		p->waermebedarf_counter = 60;

		// den aktuellen Ventilstand / Heizrate ermitteln:
		uint8_t rate = heizung_get_pwm(p);

		// Feature-Bit testen, und ggfls Waermebedarf verdoppeln:
		if (p->config.feature & (1<<HEIZUNG_FEATURE_DOPPEL_WAERMEBEDARF))
			rate = rate << 1;

		// Der Waermebedarf ist proportional zur Ventilstellung, d.h.
		// der Bedarf ist hoch, wenn das Ventil voll offen ist, und ist
		// nicht vorhanden, wenn das Ventil zu ist.

		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_INFO;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
		message.data[1] = HCAN_HES_HEIZUNG_WAERMEBEDARF_INFO;
		message.data[2] = p->config.id;
		message.data[3] = rate;
		message.size = 4;

		canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);
	}
}
Example #28
0
void set_heiz_edited_details(eds_heiz_page_block_t *p)
{
	canix_frame message;

	// 1. wir muessen anhand er subpage herausfinden, welcher Parameter
	// geaendert wurde
	
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;

	switch (heiz_page_subpage)
	{
		case 0 :
			// hier wurde der Modus geaendert. Das bedeutet, dass wir
			// die Parameter, die dieser Modus beinhaltet, nicht kennen und
			// erstmal Defaults senden muessen. Der Benutzer kann dann
			// diese Parameter finetunen, wenn der Modus gewechselt ist.

			switch (heiz_details_mode_edit)
			{
				case HEIZUNG_MODE_OFF :
					message.data[1] = HCAN_HES_HEIZUNG_SET_MODE_OFF;
					message.data[2] = p->heiz_id;
					message.size = 3;
					break;
				case HEIZUNG_MODE_MANUAL :
					message.data[1] = HCAN_HES_HEIZUNG_SET_MODE_MANUAL;
					message.data[2] = p->heiz_id;
					message.data[3] = 0;
					message.data[4] = 84;
					message.data[5] = 96; // Dauer: 6h
					message.size = 6;
					break;
				case HEIZUNG_MODE_THERMOSTAT : 
					message.data[1] = 
						HCAN_HES_HEIZUNG_SET_MODE_THERMOSTAT_DETAILS;
					message.data[2] = p->heiz_id;
					message.data[3] = 1;
					message.data[4] = 64; // 20 Grad ist Standard
					message.data[5] = 84;
					message.data[6] = 96; // Dauer: 6h
					message.size = 7;
					break;
				case HEIZUNG_MODE_AUTOMATIK : 
					message.data[1] = HCAN_HES_HEIZUNG_SET_MODE_AUTOMATIK;
					message.data[2] = p->heiz_id;
					message.size = 3;
					break;
			}
			break;
		
		case 1 :
		case 2 :
			if (heiz_details_mode_edit == HEIZUNG_MODE_MANUAL)
			{
				message.data[1] = HCAN_HES_HEIZUNG_SET_MODE_MANUAL;
				message.data[2] = p->heiz_id;
				message.data[3] = heiz_details_rate_edit;
				message.data[4] = heiz_details_dauer_edit >> 8;
				message.data[5] = heiz_details_dauer_edit;
				message.size = 6;
				break;
			}
			if (heiz_details_mode_edit == HEIZUNG_MODE_THERMOSTAT)
			{
				message.data[1] = HCAN_HES_HEIZUNG_SET_MODE_THERMOSTAT_DETAILS;
				message.data[2] = p->heiz_id;
				message.data[3] = heiz_details_Tsoll_edit >> 8;
				message.data[4] = heiz_details_Tsoll_edit;
				message.data[5] = heiz_details_dauer_edit >> 8;
				message.data[6] = heiz_details_dauer_edit;
				message.size = 7;
				break;
			}
Example #29
0
void canix_SFP_HMS_handler(const canix_frame *frame)
{
	canix_frame answer;

	answer.src = canix_selfaddr();
	answer.dst = frame->src;
	answer.proto = HCAN_PROTO_SFP;
	answer.data[0] = HCAN_SRV_HMS;


	switch (frame->data[1])
	{
		case HCAN_HMS_PING_REQUEST :
			answer.data[1] = HCAN_HMS_PING_REPLAY;
			answer.size = 2;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_DEVICE_STATE_REQUEST :
			answer.data[1] = HCAN_HMS_DEVICE_STATE_REPLAY;
			answer.data[2] = HCAN_HMS_DEV_STATE_APPLICATION;
			answer.size = 3;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_DEVICE_RESET :
			canix_reset();
			break;
		case HCAN_HMS_DEVICE_TYPE_REQUEST :
			answer.data[1] = HCAN_HMS_DEVICE_TYPE_REPLAY;
#if defined (__AVR_ATmega8__)
			answer.data[2] = 0;
#elif defined (__AVR_ATmega32__)
			answer.data[2] = 1;
#elif defined (__AVR_ATmega644__)
			answer.data[2] = 2;
#endif
			answer.data[3] = eeprom_read_byte((uint8_t *)EEPR_BOARD_TYPE);
			answer.size = 4;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_INTERNAL_EEPROM_WRITE :
			{
				// only write to eeprom, if the value changed !
				uint8_t read = 
					eeprom_read_byte((uint8_t *)(frame->data[2] |
								(frame->data[3] << 8)));

				if (read != frame->data[4])
					eeprom_write_byte((uint8_t *)(frame->data[2] |
								(frame->data[3] << 8)), frame->data[4]);

				answer.data[1] = HCAN_HMS_INTERNAL_EEPROM_WRITE_ACK;
				answer.size = 2;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_INTERNAL_EEPROM_READ_REQUEST :
			answer.data[1] = HCAN_HMS_INTERNAL_EEPROM_READ_REPLAY;
			answer.data[2] = eeprom_read_byte((uint8_t *)(frame->data[2] |
						(frame->data[3] << 8)));
			answer.size = 3;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_INTERNAL_EEPROM_READ_BULK_REQUEST :
			{
				uint16_t address;
				address = frame->data[2] | (frame->data[3] << 8);
				answer.data[1] = HCAN_HMS_INTERNAL_EEPROM_READ_BULK_REPLAY;
				answer.data[2] = eeprom_read_byte((uint8_t*) (address + 0));
				answer.data[3] = eeprom_read_byte((uint8_t*) (address + 1));
				answer.data[4] = eeprom_read_byte((uint8_t*) (address + 2));
				answer.data[5] = eeprom_read_byte((uint8_t*) (address + 3));
				answer.data[6] = eeprom_read_byte((uint8_t*) (address + 4));
				answer.data[7] = eeprom_read_byte((uint8_t*) (address + 5));
				answer.size = 8;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_UPTIME_QUERY :
			answer.size = 6;
			answer.data[1] = HCAN_HMS_UPTIME_REPLAY;
			answer.data[2] = canix_rtc_clock.uptime_sec >> 24;
			answer.data[3] = canix_rtc_clock.uptime_sec >> 16;
			answer.data[4] = canix_rtc_clock.uptime_sec >> 8;
			answer.data[5] = canix_rtc_clock.uptime_sec;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_SYSLOG_LEVEL_SET :
#ifdef CANIX_SYSLOG
			canix_set_syslog_level(frame->data[2]);
			eeprom_write_byte((uint8_t *)EEPR_DEBUG_LEVEL, frame->data[2]);
#endif
			break;
		case HCAN_HMS_BUILD_VERSION_QUERY :
			answer.data[1] = HCAN_HMS_BUILD_VERSION_REPLAY;
			answer.data[2] = 
#include <buildver> 
				>> 8;
			answer.data[3] = 
#include <buildver>
				;
			answer.size = 4;
			canix_frame_send(&answer);
			break;
		case HCAN_HMS_CAN_EC_QUERY :
			{
				uint16_t ec = can_error_counters();
				answer.data[1] = HCAN_HMS_CAN_EC_REPLAY;
				answer.data[2] = ec >> 8;
				answer.data[3] = ec;
				answer.size = 4;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_RX_RECEIVED_QUERY :
			{
				answer.data[1] = HCAN_HMS_RX_RECEIVED_REPLAY;
				answer.data[2] = canix_rx_received >> 24;
				answer.data[3] = canix_rx_received >> 16;
				answer.data[4] = canix_rx_received >> 8;
				answer.data[5] = canix_rx_received;
				answer.size = 6;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_RX_LOST_QUERY :
			{
				answer.data[1] = HCAN_HMS_RX_LOST_REPLAY;
				answer.data[2] = canix_rx_lost >> 24;
				answer.data[3] = canix_rx_lost >> 16;
				answer.data[4] = canix_rx_lost >> 8;
				answer.data[5] = canix_rx_lost;
				answer.size = 6;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_TX_SENT_QUERY :
			{
				answer.data[1] = HCAN_HMS_TX_SENT_REPLAY;
				answer.data[2] = canix_tx_sent >> 24;
				answer.data[3] = canix_tx_sent >> 16;
				answer.data[4] = canix_tx_sent >> 8;
				answer.data[5] = canix_tx_sent;
				answer.size = 6;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_TX_DROPPED_QUERY :
			{
				answer.data[1] = HCAN_HMS_TX_DROPPED_REPLAY;
				answer.data[2] = canix_tx_dropped >> 24;
				answer.data[3] = canix_tx_dropped >> 16;
				answer.data[4] = canix_tx_dropped >> 8;
				answer.data[5] = canix_tx_dropped;
				answer.size = 6;
				canix_frame_send(&answer);
			}
			break;
		case HCAN_HMS_RX_TX_STATS_RESET : 
			{
				canix_rx_received = 0;
				canix_rx_lost = 0;
				canix_tx_sent = 0;
				canix_tx_dropped = 0;
			}
			break;
	}
}
Example #30
0
/** multitaster_timer_handler sendet eine Taster UP-/DOWN-Nachricht
 *  auf den CAN-Bus. Der multitaster_timer_handler wird alle 10msec aufgerufen. */ 
void multitaster_timer_handler(device_data_multitaster *p)
{
	canix_frame message;
	uint8_t time;

	// Wenn Taste gedrueckt ist, dann ist der Pin 0, ansonsten 1
	uint8_t status = ! tasterport_read(p->config.taster_port);

	// Message schon mal vorbereiten:
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_CONTROL;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_HES;
	// message.data[1] wird unten ausgefuellt
	message.data[2] = getGroup(p);
	// message.data[3] wird unten ausgefuellt
	message.size = 4;

	if (status) // gedrueckt
	{
		// Entprellschutz:
		if (p->pressed < 255)
			p->pressed++;
	}
	else
	{
		// Wenn Schalter-Down schon gesendet wurde,
		// dann ein Schalter-Up Event senden:
		if (p->pressed > 3)
		{
			//...und kein Rollladentaster im 2-Tasterbetrieb konfiguriert ist:
			if ( !(p->config.feature & ((1<<FEATURE_MULTITASTER_ROLLADEN_ZU) | (1<<FEATURE_MULTITASTER_ROLLADEN_AUF))) )
			{
				message.data[1] = HCAN_HES_TASTER_UP;
				message.data[3] = p->config.taster_port;
				canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
			}
		}

		// Taste wurde losgelassen, also Zaehler zuruecksetzen
		p->pressed = 0;
	}

	if (p->config.feature & (1<<FEATURE_MULTITASTER_ENTPRELL_1S))
		time = 100;
	else
		time = 3;

	
	if (p->pressed == time) // mind. 30msec gedrueckt
	{
		if (p->config.feature & (1<<FEATURE_MULTITASTER_ROLLADEN_ZU))
		{
			message.data[1] = HCAN_HES_ROLLADEN_POSITION_SET;
			message.data[3] = 200; //gewuenschte Rollladenposition: Pos=200=0%=zu
		}
		else if (p->config.feature & (1<<FEATURE_MULTITASTER_ROLLADEN_AUF))
		{
			message.data[1] = HCAN_HES_ROLLADEN_POSITION_SET;
			message.data[3] = 201; //gewuenschte Rollladenposition: Pos=201=100%=auf
		}
		else //kein Rollladentaster im 2-Tasterbetrieb
		{
			message.data[1] = HCAN_HES_TASTER_DOWN;
			message.data[3] = p->config.taster_port;
		}
		
		canix_frame_send_with_prio(&message, HCAN_PRIO_HI);
	}
}