thermferm/one-wire.c

Tue, 02 Apr 2024 15:29:16 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 02 Apr 2024 15:29:16 +0200
changeset 655
780cc08df263
parent 654
e981d0185485
child 656
ca47c742a25d
permissions
-rw-r--r--

State machine logging only when debug is active.

/**
 * @brief One-wire devices
 *
 * Copyright (C) 2024
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * mbsePi-apps is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MBSE BBS; see the file COPYING.  If not, write to the Free
 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

extern int		debug;

#include "thermferm.h"
#include "statetbl.h"
#include "one-wire.h"
#include "xutil.h"


extern sys_config	Config;
extern int		my_shutdown;
extern pthread_mutex_t	mutexes[5];

int			my_one_wire_state = 0;
w1_list			*w1_devices = NULL;


static int one_wire(void);

void *my_one_wire_loop(void *threadid)
{
    my_one_wire_state = 1;
    syslog(LOG_NOTICE, "Thread my_one_wire_loop started");

    /*
     * Run the state machine
     */
    one_wire();

    /*
     * Remove the dynamic tables.
     */

    syslog(LOG_NOTICE, "Thread my_one_wire_loop stopped");
    my_one_wire_state = 0;
    return 0;
}




SM_DECL(one_wire,(char *)"one-wire")
SM_STATES
    Scan,
    Reading,
    Missing
SM_NAMES
    (char *)"Scan",
    (char *)"Reading",
    (char *)"Missing"
SM_EDECL

    int			found, i;
    FILE		*fp;
//    devices_list	*device, *ndev;
    w1_list		*dev_w1, *n_w1, *cur_w1 = NULL;
    char		buffer[25], w1type[10];
    uuid_t		uu;

SM_START(Scan)

SM_STATE(Scan)

    if (my_shutdown) {
	SM_SUCCESS;
    }

    /*
     * Scan for current one-wire devices.
     */
    fp = fopen("/sys/devices/w1_bus_master1/w1_master_slaves", "r");
    if (fp == NULL) {
	syslog(LOG_NOTICE, "No w1_bus_master: %s", strerror(errno));
	SM_ERROR;
    }
    while ((fgets(buffer, 25, fp))) {
	buffer[strlen(buffer)-1] = '\0';
//	syslog(LOG_NOTICE, "device %d %s", strlen(buffer), buffer);

	strncpy(w1type, buffer, 2);
	w1type[2] = '\0';

	/*
	 * Check if device is known and already detected.
	 */
	if ((strcmp(w1type, (char *)"3a") == 0) || (strcmp(w1type, (char *)"10") == 0) ||
	    (strcmp(w1type, (char *)"22") == 0) || (strcmp(w1type, (char *)"28") == 0) ||
	    (strcmp(w1type, (char *)"3b") == 0) || (strcmp(w1type, (char *)"42") == 0)) {
	    found = FALSE;
	    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
		if (strcmp(dev_w1->address, buffer) == 0) {
		    found = TRUE;
		    dev_w1->timestamp = time(NULL);
		    if (dev_w1->present != DEVPRESENT_YES) {
			syslog(LOG_NOTICE, "One-wire device %s is back", buffer);
			pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
			dev_w1->present = DEVPRESENT_YES;
			pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
		    }
		    break;
		}
	    }
	    if (found == FALSE) {
		syslog(LOG_NOTICE, "One-wire device %s add new", buffer);
		n_w1 = (w1_list *)malloc(sizeof(w1_list));
		n_w1->next = NULL;
		n_w1->address = xstrcpy(buffer);
		strncpy(n_w1->family, buffer, 2);
		n_w1->family[2] = '\0';
		n_w1->present = DEVPRESENT_YES;
		n_w1->subdevices = (strcmp(w1type, (char *)"3a") == 0) ? 2:1;
		n_w1->timestamp = time(NULL);

		pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
		if (w1_devices == NULL) {
		    w1_devices = n_w1;
		    cur_w1 = w1_devices;	/* Point to first device	*/
		} else {
		    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
			if (dev_w1->next == NULL) {
			    dev_w1->next = n_w1;
			    break;
			}
		    }
		}
		pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
	    }
	} else {
	    syslog(LOG_NOTICE, "One-wire device %d %s unknown", strlen(buffer), buffer);
	}
    }
    fclose(fp);
    SM_PROCEED(Reading);

SM_STATE(Reading)

    if (my_shutdown) {
	SM_SUCCESS;
    }

    /*
     * cur_w1 points to the next not handled device.
     */
    if (cur_w1 != NULL) {

	syslog(LOG_NOTICE, "Reading %s", cur_w1->address);

	sleep(1);

	if (cur_w1->next != NULL) {
	    cur_w1 = cur_w1->next;
	} else {
	    cur_w1 = w1_devices;
	}

    } else {
    	sleep(1);
    }

    SM_PROCEED(Missing);

SM_STATE(Missing)

    if (my_shutdown) {
	SM_SUCCESS;
    }

    sleep(1);
    SM_PROCEED(Scan);

SM_END
SM_RETURN

mercurial