2021-02-02 21:22:59 +01:00
# -*- coding: utf-8 -*-
import asyncio
2023-03-25 11:30:38 +01:00
import logging
2021-02-02 21:22:59 +01:00
from aiohttp import web
from cbpi . api import *
2023-03-25 11:30:38 +01:00
import os , threading , time
2021-02-06 00:40:55 +01:00
from subprocess import call
2023-03-25 11:30:38 +01:00
from cbpi . api . dataclasses import NotificationAction , NotificationType
2021-02-02 21:22:59 +01:00
2021-02-06 00:40:55 +01:00
def getSensors ( ) :
try :
arr = [ ]
for dirname in os . listdir ( ' /sys/bus/w1/devices ' ) :
if ( dirname . startswith ( " 28 " ) or dirname . startswith ( " 10 " ) ) :
arr . append ( dirname )
return arr
except :
2021-02-06 14:11:30 +01:00
return [ ]
2021-02-06 00:40:55 +01:00
2021-02-02 21:22:59 +01:00
2021-02-06 00:40:55 +01:00
class ReadThread ( threading . Thread ) :
2021-02-02 21:22:59 +01:00
2021-02-06 00:40:55 +01:00
value = 0
2021-02-02 21:22:59 +01:00
def __init__ ( self , sensor_name ) :
threading . Thread . __init__ ( self )
self . value = 0
self . sensor_name = sensor_name
self . runnig = True
def shutdown ( self ) :
pass
def stop ( self ) :
self . runnig = False
def run ( self ) :
while self . runnig :
2021-02-06 00:40:55 +01:00
try :
if self . sensor_name is None :
return
2022-01-25 07:47:40 +01:00
with open ( ' /sys/bus/w1/devices/ %s /w1_slave ' % self . sensor_name , ' r ' ) as content_file :
2021-02-06 00:40:55 +01:00
content = content_file . read ( )
if ( content . split ( ' \n ' ) [ 0 ] . split ( ' ' ) [ 11 ] == " YES " ) :
temp = float ( content . split ( " = " ) [ - 1 ] ) / 1000 # temp in Celcius
self . value = temp
2021-02-02 21:22:59 +01:00
except :
pass
2021-02-16 20:37:51 +01:00
2021-02-02 21:22:59 +01:00
time . sleep ( 1 )
2021-04-09 10:36:06 +02:00
@parameters ( [ Property . Select ( label = " Sensor " , options = getSensors ( ) ) ,
2021-05-02 10:03:25 +02:00
Property . Number ( label = " offset " , configurable = True , default_value = 0 , description = " Sensor Offset (Default is 0) " ) ,
2023-03-25 11:30:38 +01:00
Property . Select ( label = " Interval " , options = [ 1 , 5 , 10 , 30 , 60 ] , description = " Interval in Seconds " ) ,
2024-05-28 21:51:17 +02:00
Property . Kettle ( label = " Kettle " , description = " Reduced logging if Kettle is inactive / range warning in dashboard(only Kettle or Fermenter to be selected) " ) ,
Property . Fermenter ( label = " Fermenter " , description = " Reduced logging in seconds if Fermenter is inactive / range warning in dashboard (only Kettle or Fermenter to be selected) " ) ,
Property . Number ( label = " ReducedLogging " , configurable = True , description = " Reduced logging frequency in seconds if selected Kettle or Fermenter is inactive (default: 60 sec | disabled: 0) " ) ,
Property . Number ( label = " TempRange " , configurable = True , unit = " degree " ,
description = " Temp range in degree between reading and target temp of fermenter/kettle. Larger difference shows different color in dashboard (default:0 | deactivated: 0) " )
] )
2021-02-02 21:22:59 +01:00
class OneWire ( CBPiSensor ) :
def __init__ ( self , cbpi , id , props ) :
super ( OneWire , self ) . __init__ ( cbpi , id , props )
2021-02-27 20:09:19 +01:00
self . value = 200
2023-03-25 13:54:24 +01:00
async def start ( self ) :
await super ( ) . start ( )
self . name = self . props . get ( " Sensor " )
self . interval = int ( self . props . get ( " Interval " , 60 ) )
self . offset = float ( self . props . get ( " offset " , 0 ) )
2023-03-25 14:15:30 +01:00
self . reducedfrequency = float ( self . props . get ( " ReducedLogging " , 60 ) )
2023-03-27 20:19:37 +02:00
if self . reducedfrequency < 0 :
self . reducedfrequency = 0
2023-03-25 13:51:13 +01:00
self . lastlog = 0
2024-05-28 21:51:17 +02:00
self . temprange = float ( self . props . get ( " TempRange " , 0 ) )
2023-03-25 13:51:13 +01:00
self . sensor = self . get_sensor ( self . id )
2023-03-25 11:30:38 +01:00
self . kettleid = self . props . get ( " Kettle " , None )
self . fermenterid = self . props . get ( " Fermenter " , None )
2023-03-25 12:56:37 +01:00
self . reducedlogging = True if self . kettleid or self . fermenterid else False
2023-03-25 11:30:38 +01:00
if self . kettleid is not None and self . fermenterid is not None :
self . reducedlogging = False
2024-05-28 21:51:17 +02:00
self . cbpi . notify ( " OneWire Sensor " , " Sensor ' " + str ( self . sensor . name ) + " ' cant ' t have Fermenter and Kettle defined for reduced logging / range warning. " , NotificationType . WARNING , action = [ NotificationAction ( " OK " , self . Confirm ) ] )
2023-03-27 22:12:11 +02:00
if ( self . reducedfrequency != 0 ) and ( self . interval > = self . reducedfrequency ) :
2023-03-25 11:30:38 +01:00
self . reducedlogging = False
self . cbpi . notify ( " OneWire Sensor " , " Sensor ' " + str ( self . sensor . name ) + " ' has shorter or equal ' reduced logging ' compared to regular interval. " , NotificationType . WARNING , action = [ NotificationAction ( " OK " , self . Confirm ) ] )
2021-02-06 00:40:55 +01:00
self . t = ReadThread ( self . name )
self . t . daemon = True
2023-03-25 11:30:38 +01:00
def shutdown ( ) :
shutdown . cb . shutdown ( )
shutdown . cb = self . t
2021-02-02 21:22:59 +01:00
self . t . start ( )
2023-03-25 11:30:38 +01:00
async def Confirm ( self , * * kwargs ) :
pass
2021-02-02 21:22:59 +01:00
async def stop ( self ) :
try :
self . t . stop ( )
2021-02-06 00:40:55 +01:00
self . running = False
2021-02-02 21:22:59 +01:00
except :
pass
async def run ( self ) :
2023-03-25 14:23:21 +01:00
self . kettle = self . get_kettle ( self . kettleid ) if self . kettleid is not None else None
self . fermenter = self . get_fermenter ( self . fermenterid ) if self . fermenterid is not None else None
2021-03-08 01:34:13 +01:00
while self . running == True :
2021-04-09 10:36:06 +02:00
self . TEMP_UNIT = self . get_config_value ( " TEMP_UNIT " , " C " )
if self . TEMP_UNIT == " C " : # Report temp in C if nothing else is selected in settings
self . value = round ( ( self . t . value + self . offset ) , 2 )
else : # Report temp in F if unit selected in settings
2023-03-25 11:30:38 +01:00
self . value = round ( ( 9.0 / 5.0 * self . t . value + 32 + self . offset ) , 2 )
2021-02-02 21:22:59 +01:00
self . push_update ( self . value )
2023-03-25 11:30:38 +01:00
if self . reducedlogging :
await self . logvalue ( )
else :
2023-03-25 12:56:37 +01:00
logging . info ( " OneWire {} regular logging " . format ( self . sensor . name ) )
2023-03-25 11:30:38 +01:00
self . log_data ( self . value )
self . lastlog = time . time ( )
2021-02-06 00:40:55 +01:00
await asyncio . sleep ( self . interval )
2023-03-25 11:30:38 +01:00
async def logvalue ( self ) :
2023-03-28 07:00:21 +02:00
now = time . time ( )
logging . info ( " OneWire {} logging subroutine " . format ( self . sensor . name ) )
if self . kettle is not None :
try :
kettlestatus = self . kettle . instance . state
except :
kettlestatus = False
if kettlestatus :
self . log_data ( self . value )
logging . info ( " OneWire {} Kettle Active " . format ( self . sensor . name ) )
self . lastlog = time . time ( )
else :
logging . info ( " OneWire {} Kettle Inactive " . format ( self . sensor . name ) )
if self . reducedfrequency != 0 :
2023-03-27 20:19:37 +02:00
if now > = self . lastlog + self . reducedfrequency :
self . log_data ( self . value )
self . lastlog = time . time ( )
logging . info ( " Logged with reduced freqency " )
pass
2023-03-28 07:00:21 +02:00
if self . fermenter is not None :
try :
fermenterstatus = self . fermenter . instance . state
except :
fermenterstatus = False
if fermenterstatus :
self . log_data ( self . value )
logging . info ( " OneWire {} Fermenter Active " . format ( self . sensor . name ) )
self . lastlog = time . time ( )
else :
logging . info ( " OneWire {} Fermenter Inactive " . format ( self . sensor . name ) )
if self . reducedfrequency != 0 :
2023-03-27 20:19:37 +02:00
if now > = self . lastlog + self . reducedfrequency :
self . log_data ( self . value )
self . lastlog = time . time ( )
logging . info ( " Logged with reduced freqency " )
pass
2023-03-25 11:30:38 +01:00
2021-02-02 21:22:59 +01:00
def get_state ( self ) :
return dict ( value = self . value )
def setup ( cbpi ) :
cbpi . plugin . register ( " OneWire " , OneWire )
2021-02-06 00:40:55 +01:00
try :
# Global Init
2023-10-14 16:17:03 +02:00
call ( [ " sudo " , " modprobe " , " w1-gpio " ] )
call ( [ " sudo " , " modprobe " , " w1-therm " ] )
2021-02-06 00:40:55 +01:00
except Exception as e :
pass