# HG changeset patch # User Michiel Broek # Date 1712062992 -7200 # Node ID e981d01854855d0795f11e1eaa8c169f1b85a48e # Parent 6c4c884be155bb729dc60c1cb9b0b72cd99ee6e9 Added one-wire thread and some old state table macro's. The state machine first state scans new one-wire devices and stores them in a linked list. diff -r 6c4c884be155 -r e981d0185485 MIGRATION --- a/MIGRATION Wed Mar 27 18:59:39 2024 +0100 +++ b/MIGRATION Tue Apr 02 15:03:12 2024 +0200 @@ -41,3 +41,20 @@ Add pigpio library and make it testable by the configure script. + + Flow one-wire. + -------------- + +States: + 1. Init state. + 2. Check for exit. + Scan for devices. Add to one-wire list. + 3. Check for exit. + Read all DS2413 devices programmed as input. + 4. Check for exit. + Read one temperture sensor from list and update device. + 5. Check for exit. + Check for missing devices not in one wire table. + Goto 2. + 6. Exit state. + diff -r 6c4c884be155 -r e981d0185485 thermferm/Makefile --- a/thermferm/Makefile Wed Mar 27 18:59:39 2024 +0100 +++ b/thermferm/Makefile Tue Apr 02 15:03:12 2024 +0200 @@ -56,7 +56,8 @@ # DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT # Dependencies generated by make depend mqtt.o: thermferm.h rdconfig.h devices.h xutil.h delay.h mqtt.h -thermferm.o: lock.h rdconfig.h devices.h server.h thermferm.h delay.h simulator.h lcd-pcf8574.h lcd-buffer.h slcd.h panel.h futil.h xutil.h pid.h mqtt.h +thermferm.o: lock.h rdconfig.h server.h thermferm.h devices.h delay.h simulator.h lcd-pcf8574.h lcd-buffer.h slcd.h panel.h one-wire.h futil.h xutil.h pid.h mqtt.h +one-wire.o: thermferm.h statetbl.h one-wire.h xutil.h panel.o: thermferm.h delay.h lcd-pcf8574.h slcd.h panel.h devices.o: thermferm.h delay.h devices.h rc-switch.h panel.h xutil.h lcd-buffer.o: thermferm.h lcd-buffer.h lcd-pcf8574.h slcd.h panel.h diff -r 6c4c884be155 -r e981d0185485 thermferm/devices.c --- a/thermferm/devices.c Wed Mar 27 18:59:39 2024 +0100 +++ b/thermferm/devices.c Tue Apr 02 15:03:12 2024 +0200 @@ -504,7 +504,6 @@ } closedir(fd); } - syslog(LOG_NOTICE, "%s", dhtaddr); if (dhtaddr) { diff -r 6c4c884be155 -r e981d0185485 thermferm/devices.h --- a/thermferm/devices.h Wed Mar 27 18:59:39 2024 +0100 +++ b/thermferm/devices.h Tue Apr 02 15:03:12 2024 +0200 @@ -1,9 +1,11 @@ #ifndef MY_DEVICES_H #define MY_DEVICES_H +int read_w1(char *address, char *file); +int write_w1(char *address, char *file, uint8_t val); -int device_out(char *, int); -int device_in(char *, int *); +int device_out(char *uuid, int value); +int device_in(char *uuid, int *value); int devices_detect(void); void *my_devices_loop(void *); diff -r 6c4c884be155 -r e981d0185485 thermferm/one-wire.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thermferm/one-wire.c Tue Apr 02 15:03:12 2024 +0200 @@ -0,0 +1,191 @@ +/** + * @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. + */ + +#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 + + diff -r 6c4c884be155 -r e981d0185485 thermferm/one-wire.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thermferm/one-wire.h Tue Apr 02 15:03:12 2024 +0200 @@ -0,0 +1,11 @@ +/** + * @file one-wire.h + * @brief One-wire bus functions. + */ + +#ifndef ONE_WIRE_H +#define ONE_WIRE_H + +void *my_one_wire_loop(void *); + +#endif diff -r 6c4c884be155 -r e981d0185485 thermferm/statetbl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thermferm/statetbl.h Tue Apr 02 15:03:12 2024 +0200 @@ -0,0 +1,57 @@ +/** + * @brief State table macro's + */ + +#ifndef STATETBL_H +#define STATETBL_H + +#define SM_DECL(proc,name) \ +int proc(void)\ +{\ + int sm_success=0;\ + char *sm_name=name; + +#define SM_STATES \ + enum { + +#define SM_NAMES \ + } sm_state; \ + char * sm_sname[] = { + +#define SM_EDECL \ + }; + +#define SM_START(x) \ + sm_state=x;\ + syslog(LOG_NOTICE, "SM (%s): Start => %s", sm_name, sm_sname[sm_state]); \ + while (!sm_success) switch (sm_state)\ + {\ + default: syslog(LOG_WARNING, "Statemachine %s error: state=%d",sm_name,sm_state);\ + sm_success=-1; + +#define SM_STATE(x) \ + break;\ + case x: + +#define SM_END \ + }\ + +#define SM_RETURN \ + return (sm_success != 1);\ +} + +#define SM_PROCEED(x) \ + if (x != sm_state) {\ + syslog(LOG_NOTICE, "SM (%s): %s => %s", sm_name, sm_sname[sm_state], sm_sname[x]);\ + }\ + sm_state=x; break; + +#define SM_SUCCESS \ + syslog(LOG_NOTICE, "SM (%s): %s => Success", sm_name, sm_sname[sm_state]);\ + sm_success=1; break; + +#define SM_ERROR \ + syslog(LOG_WARNING, "SM (%s): %s => Error", sm_name, sm_sname[sm_state]);\ + sm_success=-1; break; + +#endif diff -r 6c4c884be155 -r e981d0185485 thermferm/thermferm.c --- a/thermferm/thermferm.c Wed Mar 27 18:59:39 2024 +0100 +++ b/thermferm/thermferm.c Tue Apr 02 15:03:12 2024 +0200 @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (C) 2014-2022 + * Copyright (C) 2014-2024 * * Michiel Broek * @@ -22,15 +22,16 @@ #include "lock.h" #include "rdconfig.h" -#include "devices.h" #include "server.h" #include "thermferm.h" +#include "devices.h" #include "delay.h" #include "simulator.h" #include "lcd-pcf8574.h" #include "lcd-buffer.h" #include "slcd.h" #include "panel.h" +#include "one-wire.h" #include "futil.h" #include "xutil.h" #include "pid.h" @@ -51,6 +52,7 @@ extern int my_panel_state; extern int my_server_state; extern int my_simulator_state; +extern int my_one_wire_state; int setupmenu = MENU_NONE; units_list *current_unit = NULL; /* In panel editor this points to the current unit. */ float temp_temp = 20.0; @@ -1064,6 +1066,14 @@ t++; } + rc = pthread_create(&threads[t], NULL, my_one_wire_loop, (void *)t ); + if (rc) { + fprintf(stderr, "my_one_wire_loop thread didn't start rc=%d\n", rc); + syslog(LOG_NOTICE, "my_one_wire_loop thread didn't start rc=%d", rc); + } else { + t++; + } + #ifdef USE_SIMULATOR rc = pthread_create(&threads[t], NULL, my_simulator_loop, (void *)t ); if (rc) { @@ -1915,9 +1925,9 @@ /* * Note that we don't care if the command server is stopped, this one - * does almost certain keep running but tat doesn't harm. + * does almost certain keep running but that doesn't harm. */ - while ((my_devices_state + my_panel_state + my_simulator_state) > 0) { sleep(1); }; + while ((my_devices_state + my_panel_state + my_simulator_state + my_one_wire_state) > 0) { sleep(1); }; mqtt_disconnect(); stopLCD(); diff -r 6c4c884be155 -r e981d0185485 thermferm/thermferm.h --- a/thermferm/thermferm.h Wed Mar 27 18:59:39 2024 +0100 +++ b/thermferm/thermferm.h Tue Apr 02 15:03:12 2024 +0200 @@ -58,7 +58,7 @@ #define LOCK_DEVICES 0 #define LOCK_LCD 1 #define LOCK_MENU 2 -#define LOCK_SPARE2 3 +#define LOCK_ONE_WIRE 3 #define LOCK_SPARE3 4 @@ -304,6 +304,21 @@ #define DEVDIR_OUT_PWM 5 /* PWM outout */ #define DEVDIR_INTERN 6 /* Internal function */ + +/* + * Dynamic one-wire devices list + */ +typedef struct _w1_list { + struct _w1_list *next; + char *address; ///< Device address + char family[3]; ///< Device family + int present; ///< Present on bus + int subdevices; ///< Number of subdevices + time_t timestamp; ///< Last seen +} w1_list; + + + #ifdef USE_SIMULATOR /*