Skip to content

Commit

Permalink
Update jeedom.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Loïc authored Aug 20, 2022
1 parent b96cf10 commit b7ebaaa
Showing 1 changed file with 71 additions and 54 deletions.
125 changes: 71 additions & 54 deletions resources/blead/jeedom/jeedom.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import time
import logging
import threading
import _thread as thread
import requests
import datetime
import collections
try:
from collections.abc import Mapping
except ImportError:
from collections import Mapping
import serial
import os
from os.path import join
Expand All @@ -31,7 +33,6 @@
import signal
import unicodedata
import pyudev
import globals

# ------------------------------------------------------------------------------

Expand All @@ -44,7 +45,7 @@ def __init__(self,apikey = '',url = '',cycle = 0.5,retry = 3):
self.changes = {}
if cycle > 0 :
self.send_changes_async()
logging.debug('Init request module v%s' % (str(requests.__version__),))
logging.info('Init request module v%s' % (str(requests.__version__),))

def send_changes_async(self):
try:
Expand All @@ -55,24 +56,22 @@ def send_changes_async(self):
start_time = datetime.datetime.now()
changes = self.changes
self.changes = {}
logging.debug('Send to jeedom : '+str(changes))
i = 1
bad_status_code = True
while i <= self.retry:
logging.info('Send to jeedom : '+str(changes))
i=0
while i < self.retry:
try:
r = requests.post(self.url + '?apikey=' + self.apikey, json=changes, timeout=(0.5*i, 120), verify=False)
r = requests.post(self.url + '?apikey=' + self.apikey, json=changes, timeout=(0.5, 120), verify=False)
if r.status_code == requests.codes.ok:
bad_status_code = False
break
except Exception as error:
logging.error('Error on send request to jeedom ' + str(error)+' retry : '+str(i)+'/'+str(self.retry))
i = i + 1
if bad_status_code:
if r.status_code != requests.codes.ok:
logging.error('Error on send request to jeedom, return code %s' % (str(r.status_code),))
dt = datetime.datetime.now() - start_time
ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0
timer_duration = self.cycle - ms
if timer_duration < 0.1:
if timer_duration < 0.1 :
timer_duration = 0.1
if timer_duration > self.cycle:
timer_duration = self.cycle
Expand Down Expand Up @@ -104,14 +103,14 @@ def add_changes(self,key,value):
self.changes[key] = value

def send_change_immediate(self,change):
thread.start_new_thread( self.thread_change, (change,))
threading.Thread( target=self.thread_change,args=(change,)).start()

def thread_change(self,change):
logging.debug('Send to jeedom : %s' % (str(change),))
i = 1
while i <= self.retry:
logging.info('Send to jeedom : %s' % (str(change),))
i=0
while i < self.retry:
try:
r = requests.post(self.url + '?apikey=' + self.apikey, json=change, timeout=(0.5*i, 120), verify=False)
r = requests.post(self.url + '?apikey=' + self.apikey, json=change, timeout=(0.5, 120), verify=False)
if r.status_code == requests.codes.ok:
break
except Exception as error:
Expand All @@ -127,8 +126,7 @@ def get_change(self):
def merge_dict(self,d1, d2):
for k,v2 in d2.items():
v1 = d1.get(k) # returns None if v1 has no value for this key
if ( isinstance(v1, collections.Mapping) and
isinstance(v2, collections.Mapping) ):
if isinstance(v1, Mapping) and isinstance(v2, Mapping):
self.merge_dict(v1, v2)
else:
d1[k] = v2
Expand All @@ -137,10 +135,10 @@ def test(self):
try:
response = requests.get(self.url + '?apikey=' + self.apikey, verify=False)
if response.status_code != requests.codes.ok:
logging.error('Callback error: %s %s. Please check your network configuration page'% ( response.status_code, response.text,))
logging.error('Callback error: %s %s. Please check your network configuration page'% (response.status.code, response.status.message,))
return False
except Exception as e:
logging.error('Callback result as a unknown error: %s. Please check your network configuration page ' % (str(e),))
logging.error('Callback result as a unknown error: %s. Please check your network configuration page'% (e.message,))
return False
return True

Expand All @@ -156,13 +154,13 @@ def convert_log_level(level = 'error'):
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL,
'none': logging.NOTSET}
return LEVELS.get(level, logging.NOTSET)
'none': logging.CRITICAL}
return LEVELS.get(level, logging.CRITICAL)

@staticmethod
def set_log_level(level = 'error'):
FORMAT = '[%(asctime)s.%(msecs)03d][%(levelname)s] : %(message)s'
logging.basicConfig(level=jeedom_utils.convert_log_level(level),format=FORMAT,datefmt='%Y-%m-%d %H:%M:%S')
FORMAT = '[%(asctime)-15s][%(levelname)s] : %(message)s'
logging.basicConfig(level=jeedom_utils.convert_log_level(level),format=FORMAT, datefmt="%Y-%m-%d %H:%M:%S")

@staticmethod
def find_tty_usb(idVendor, idProduct, product = None):
Expand All @@ -186,7 +184,7 @@ def stripped(str):

@staticmethod
def ByteToHex( byteStr ):
return ''.join( [ "%02X " % ord( x ) for x in str(byteStr) ] ).strip()
return byteStr.hex()

@staticmethod
def dec2bin(x, width=8):
Expand All @@ -195,8 +193,8 @@ def dec2bin(x, width=8):
@staticmethod
def dec2hex(dec):
if dec is None:
return 0
return hex(dec)[2:]
return '0x00'
return "0x{:02X}".format(dec)

@staticmethod
def testBit(int_type, offset):
Expand All @@ -215,76 +213,95 @@ def split_len(seq, length):
@staticmethod
def write_pid(path):
pid = str(os.getpid())
logging.debug("Writing PID " + pid + " to " + str(path))
logging.info("Writing PID " + pid + " to " + str(path))
open(path, 'w').write("%s\n" % pid)

@staticmethod
def remove_accents(input_str):
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str))
return u"".join([c for c in nkfd_form if not unicodedata.combining(c)])

@staticmethod
def printHex(hex):
return ' '.join([hex[i:i + 2] for i in range(0, len(hex), 2)])

# ------------------------------------------------------------------------------

class jeedom_serial():

def __init__(self,device = '',rate = '',timeout = 1):
def __init__(self,device = '',rate = '',timeout = 9,rtscts = True,xonxoff=False):
self.device = device
self.rate = rate
self.timeout = timeout
self.port = None
logging.debug('Init serial module v%s' % (str(serial.VERSION),))
self.rtscts = rtscts
self.xonxoff = xonxoff
logging.info('Init serial module v%s' % (str(serial.VERSION),))

def open(self):
if self.device:
logging.debug("Open serial port on device: " + str(self.device)+', rate '+str(self.rate)+', timeout : '+str(self.timeout))
logging.info("Open serial port on device: " + str(self.device)+', rate '+str(self.rate)+', timeout : '+str(self.timeout))
else:
logging.error("Device name missing.")
return False
logging.debug("Open Serialport")
logging.info("Open Serialport")
try:
self.port = serial.Serial(self.device,self.rate,timeout=self.timeout)
self.port = serial.Serial(
self.device,
self.rate,
timeout=self.timeout,
rtscts=self.rtscts,
xonxoff=self.xonxoff,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE
)
except serial.SerialException as e:
logging.error("Error: Failed to connect on device " + self.device + " Details : " + str(e))
return False
if not self.port.isOpen():
self.port.open()
time.sleep(0.2)
self.flushOutput()
self.flushInput()
return True

def close(self):
logging.debug("Close serial port")
logging.info("Close serial port")
try:
self.port.close()
logging.debug("Serial port closed")
logging.info("Serial port closed")
return True
except:
logging.error("Failed to close the serial port (" + self.device + ")")
return False

def write(self,data,fromqueue = False):
def write(self,data):
logging.info("Write data to serial port : "+str(jeedom_utils.ByteToHex(data)))
self.port.write(data)
if fromqueue:
globals.SENDQUEUE.task_done()

def flushOutput(self,):
logging.debug("flushOutput serial port ")
logging.info("flushOutput serial port ")
self.port.flushOutput()

def flushInput(self):
logging.debug("flushInput serial port ")
logging.info("flushInput serial port ")
self.port.flushInput()

def read(self):
if self.port.inWaiting() > 0:
if self.port.inWaiting() != 0:
return self.port.read()
return None

def readbytes(self,number):
if self.port.inWaiting() > 0:
return self.port.read(number)
return None
buf = b''
for i in range(number):
try:
byte = self.port.read()
except IOError as e:
logging.error("Error: " + str(e))
except OSError as e:
logging.error("Error: " + str(e))
buf += byte
return buf

# ------------------------------------------------------------------------------

Expand All @@ -293,12 +310,12 @@ def readbytes(self,number):
class jeedom_socket_handler(StreamRequestHandler):
def handle(self):
global JEEDOM_SOCKET_MESSAGE
logging.debug("Client connected to [%s:%d]" % self.client_address)
logging.info("Client connected to [%s:%d]" % self.client_address)
lg = self.rfile.readline()
JEEDOM_SOCKET_MESSAGE.put(lg)
logging.debug("Message read from socket: " + str(lg.strip()))
logging.info("Message read from socket: " + str(lg.strip()))
self.netAdapterClientConnected = False
logging.debug("Client disconnected from [%s:%d]" % self.client_address)
logging.info("Client disconnected from [%s:%d]" % self.client_address)

class jeedom_socket():

Expand All @@ -310,16 +327,16 @@ def __init__(self,address='localhost', port=55000):
def open(self):
self.netAdapter = TCPServer((self.address, self.port), jeedom_socket_handler)
if self.netAdapter:
logging.debug("Socket interface started")
logging.info("Socket interface started")
threading.Thread(target=self.loopNetServer, args=()).start()
else:
logging.debug("Cannot start socket interface")
logging.info("Cannot start socket interface")

def loopNetServer(self):
logging.debug("LoopNetServer Thread started")
logging.debug("Listening on: [%s:%d]" % (self.address, self.port))
logging.info("LoopNetServer Thread started")
logging.info("Listening on: [%s:%d]" % (self.address, self.port))
self.netAdapter.serve_forever()
logging.debug("LoopNetServer Thread stopped")
logging.info("LoopNetServer Thread stopped")

def close(self):
self.netAdapter.shutdown()
Expand Down

0 comments on commit b7ebaaa

Please sign in to comment.