Add MetricsLogging

This commit is contained in:
Konstantin Lampalzer 2021-09-06 18:51:52 +02:00
parent 60f252c37a
commit 3fe3139961
6 changed files with 168 additions and 61 deletions

View file

@ -2,6 +2,7 @@ import atexit
from enum import Enum
from compLib.LogstashLogging import Logging
from compLib.MetricsLogging import MetricsLogging
from compLib.Spi import Spi, Register
MOTOR_COUNT = 4
@ -47,7 +48,8 @@ class Encoder(object):
diff = Encoder.read_raw(port) - encoder_start_values[port]
if diff > 2 ** 31:
diff -= 2 ** 32
MetricsLogging.put("Encoder", diff, port)
return diff
@staticmethod

View file

@ -1,6 +1,6 @@
from compLib.LogstashLogging import Logging
from compLib.MetricsLogging import MetricsLogging
from compLib.Spi import Spi, Register
import spidev
SENSOR_COUNT = 5
@ -14,18 +14,20 @@ class IRSensor(object):
if sensor <= 0 or sensor > SENSOR_COUNT:
raise IndexError("Invalid sensor specified!")
result = 0
if sensor == 1:
return Spi.read(Register.IR_1_H, 2)
result = Spi.read(Register.IR_1_H, 2)
elif sensor == 2:
return Spi.read(Register.IR_2_H, 2)
esult = Spi.read(Register.IR_2_H, 2)
elif sensor == 3:
return Spi.read(Register.IR_3_H, 2)
esult = Spi.read(Register.IR_3_H, 2)
elif sensor == 4:
return Spi.read(Register.IR_4_H, 2)
esult = Spi.read(Register.IR_4_H, 2)
elif sensor == 5:
return Spi.read(Register.IR_5_H, 2)
else:
return 0
esult = Spi.read(Register.IR_5_H, 2)
MetricsLogging.put("Infrared", result, sensor)
return result
@staticmethod
def set(sensor: int, on: bool):

84
compLib/MetricsLogging.py Normal file
View file

@ -0,0 +1,84 @@
from influxdb_client import InfluxDBClient, Point, WritePrecision
import socket
import uuid
import os
import queue
import datetime
import threading
import requests
CONCURRENCY = 2
HOSTNAME = socket.gethostname()
RUN_TRACE = str(uuid.uuid4())
TOKEN = "aCdxnntw-Zp3agci8Z32lQAR_ep6MhdmWOJG7ObnoikYqe7nKAhFYx1jVGBpipQuId79SC4Jl0J6IBYVqauJyw=="
ORG = "robo4you"
BUCKET = "compAIR"
INFLUX_HOST = "https://influxdb.comp-air.at"
EXTENSIVE_LOGGING = os.getenv("EXTENSIVE_LOGGING", "True")
if EXTENSIVE_LOGGING == "True":
EXTENSIVE_LOGGING = True
else:
EXTENSIVE_LOGGING = False
influx_client = InfluxDBClient(url=INFLUX_HOST, token=TOKEN)
write_api = influx_client.write_api()
point_queue = queue.Queue()
workers = []
class MetricsLogging():
@staticmethod
def is_influx_reachable():
try:
r = requests.get(INFLUX_HOST)
if r.status_code == 200:
return True
else:
print(f"Could not connect to {INFLUX_HOST} -> ERROR CODE: {r.status_code}!")
return False
except requests.exceptions.RequestException as identifier:
print(f"Could not connect to {INFLUX_HOST}!")
@staticmethod
def put(sensorType, value, port):
if EXTENSIVE_LOGGING:
point = Point(sensorType) \
.tag("host", HOSTNAME) \
.tag("runID", RUN_TRACE) \
.tag("port", port) \
.field("value", value) \
.time(datetime.datetime.utcnow(), WritePrecision.MS)
point_queue.put_nowait(point)
@staticmethod
def worker():
while True:
point = point_queue.get()
if point is None: # Kill signal
return
try:
write_api.write(BUCKET, ORG, point)
finally:
point_queue.task_done()
@staticmethod
def start_workers():
global EXTENSIVE_LOGGING
if EXTENSIVE_LOGGING:
if MetricsLogging.is_influx_reachable():
EXTENSIVE_LOGGING = False
for i in range(CONCURRENCY):
worker = threading.Thread(target=MetricsLogging.worker, daemon=True)
worker.start()
workers.append(worker)
MetricsLogging.start_workers()

View file

@ -2,6 +2,7 @@ import atexit
from enum import IntEnum
from compLib.LogstashLogging import Logging
from compLib.MetricsLogging import MetricsLogging
from compLib.Spi import Spi, Register
MOTOR_COUNT = 4
@ -45,14 +46,13 @@ class Motor(object):
Spi.write(Register.PWM_4_CTRL, 1, int(mode))
@staticmethod
def power_raw(port: int, percent: float):
def power_raw(port: int, percent: float, log_metric = True):
"""Set specified motor to percentage power
:param port: Port, which the motor is connected to. 1-4
:param percent: Percentage of max speed. between -100 and 100
:raises: IndexError
"""
Logging.get_logger().debug(f"Motor.power {port} {percent}")
if port <= 0 or port > MOTOR_COUNT:
raise IndexError("Invalid Motor port specified!")
@ -60,6 +60,9 @@ class Motor(object):
if percent < -100 or percent > 100:
raise IndexError("Invalid Motor speed specified! Speed is between -100 and 100 percent!")
if log_metric:
MetricsLogging.put("MotorRaw", percent, port)
mode = MotorMode.COAST
if percent < 0:
percent = abs(percent)
@ -80,12 +83,14 @@ class Motor(object):
:param percent: Percentage of max speed. between -100 and 100
:raises: IndexError
"""
raw_power = 0
if percent > 0:
Motor.power_raw(port, Motor.__linearizePower(MOTOR_CURVE, percent))
raw_power = Motor.__linearizePower(MOTOR_CURVE, percent)
elif percent < 0:
Motor.power_raw(port, -Motor.__linearizePower(MOTOR_CURVE, -percent))
else:
Motor.power_raw(port, 0)
raw_power = -Motor.__linearizePower(MOTOR_CURVE, -percent)
MetricsLogging.put("Motor", percent, port, False)
Motor.power_raw(port, raw_power)
@staticmethod
def all_off():

View file

@ -1,36 +1,36 @@
from compLib.PCA9685 import PCA9685
# from compLib.PCA9685 import PCA9685
SERVO_COUNT = 10
# SERVO_COUNT = 10
pwm = PCA9685(0x40, debug=True)
pwm.setPWMFreq(50)
# pwm = PCA9685(0x40, debug=True)
# pwm.setPWMFreq(50)
MIN_ANGLE = -90.0
MAX_ANGLE = 90.0
# MIN_ANGLE = -90.0
# MAX_ANGLE = 90.0
class Servo:
"""Control the servo ports on the robot
"""
# class Servo:
# """Control the servo ports on the robot
# """
@staticmethod
def set_position(channel: int, angle: int, offset: float =90):
"""Set position of servo connected to port
# @staticmethod
# def set_position(channel: int, angle: int, offset: float =90):
# """Set position of servo connected to port
:param channel: channel between 0 and 7
:param angle: Angle of servo
"""
if channel < 0 or channel >= SERVO_COUNT:
raise IndexError("Invalid Servo channel specified!")
# :param channel: channel between 0 and 7
# :param angle: Angle of servo
# """
# if channel < 0 or channel >= SERVO_COUNT:
# raise IndexError("Invalid Servo channel specified!")
angle = max(min(angle, MAX_ANGLE), MIN_ANGLE)
# angle = max(min(angle, MAX_ANGLE), MIN_ANGLE)
pwm.setServoPulse(channel + 8, 500+int((angle+offset)/0.09))
# pwm.setServoPulse(channel + 8, 500+int((angle+offset)/0.09))
@staticmethod
def setup_position():
"""Set position of servos to the position used during the setup process
"""
# @staticmethod
# def setup_position():
# """Set position of servos to the position used during the setup process
# """
Servo.set_position(0, 0)
Servo.set_position(1, 0)
# Servo.set_position(0, 0)
# Servo.set_position(1, 0)

View file

@ -1,26 +1,40 @@
__version__ = "0.1.5-1"
import importlib
import compLib.LogstashLogging
import compLib.Spi
import compLib.Reset
import compLib.Encoder
import logging
import apt
try:
__versions = apt.Cache()["python3-complib"].versions
if len(__versions) != 1:
print(f"Starting compLib! \033[91mVersion: {__version__} is outdated\033[0m\n"
f"\033[92m[!] run the command 'sudo apt update && sudo apt install python3-complib' to install the newest version\033[0m")
else:
print(f"Starting compLib! \033[92mVersion: {__version__} is up to date\033[0m")
except Exception as e:
compLib.LogstashLogging.Logging.get_logger().error(f"error during checking apt package version -> {str(e)}")
print(f"\033[91merror during checking apt package version -> {str(e)}\033[0m\n")
print(f"\033[34mInitializing chipmunk board...\033[0m")
compLib.Reset.Reset.reset_bot()
compLib.Spi.Spi.health_check()
compLib.Spi.Spi.start_health_check_loop()
compLib.Encoder.Encoder.clear_all()
print(f"\033[34mReady\033[0m\n")
apt_found = importlib.util.find_spec("apt") is not None
spi_found = importlib.util.find_spec("spidev") is not None
if apt_found:
import apt
try:
__versions = apt.Cache()["python3-complib"].versions
if len(__versions) != 1:
print(f"Starting compLib! \033[91mVersion: {__version__} is outdated\033[0m\n"
f"\033[92m[!] run the command 'sudo apt update && sudo apt install python3-complib' to install the newest version\033[0m")
else:
print(f"Starting compLib! \033[92mVersion: {__version__} is up to date\033[0m")
except Exception as e:
compLib.LogstashLogging.Logging.get_logger().error(f"error during checking apt package version -> {str(e)}")
print(f"\033[91merror during checking apt package version -> {str(e)}\033[0m\n")
else:
print("apt is not installed! This is for local development only!")
if spi_found:
import compLib.Spi
import compLib.Reset
import compLib.Encoder
import logging
print(f"\033[34mInitializing chipmunk board...\033[0m")
compLib.Reset.Reset.reset_bot()
compLib.Spi.Spi.health_check()
compLib.Spi.Spi.start_health_check_loop()
compLib.Encoder.Encoder.clear_all()
print(f"\033[34mReady\033[0m\n")
else:
print("spidev is not installed! This is for local development only!")