fix: missing files in first version

This commit is contained in:
alban 2021-12-03 22:35:55 +01:00
parent 966d4819b4
commit ce32292935
11 changed files with 579 additions and 2 deletions

2
.gitignore vendored
View File

@ -14,8 +14,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/

37
lib/audio_plugin.py Normal file
View File

@ -0,0 +1,37 @@
from debuggable import Debuggable
from random import randint, choice
from math import sqrt
from datetime import datetime, timedelta
from planning import Planning
from schedule import Schedule
class audioPlugin(Debuggable):
"""Planner for general slots allocations"""
name = "audioPlugin"
def __init__(self):
super(MyPlugin, self).__init__()
def sensor_base(self, blackboard):
# redis.get("redilysis.key")
# blackboard["audio_analysis"] = redilysis
pass
def planner_base(self, blackboard, planning: Planning):
interesting_list = []
for schedule in planning.schedules:
start_at = schedule.start_at
now = datetime.now()
if (now - start_at).total_seconds() < 3 :
continue
interesting_list.append(schedule)
mood = get_mood_from_audio()
for schedule in interesting_list:
schedule.content["mood"] = mood

5
lib/blackboard.py Normal file
View File

@ -0,0 +1,5 @@
class Blackboard(object):
def __init__( self ):
pass

14
lib/debuggable.py Normal file
View File

@ -0,0 +1,14 @@
import debugger
# from var_dump import var_dump
class Debuggable(object):
def __init__(self):
self._debugger = debugger.instance
def debug(self, tags, msg):
if not self._debugger:
print(self, " missing debugger")
self._debugger.debug(tags, msg)
# def var_dump(self,var):
# return var_dump(var)

176
lib/debugger.py Normal file
View File

@ -0,0 +1,176 @@
import asyncio
import inspect
import os
import re
import time
instance = object()
def init():
global instance
instance = Debugger()
class Debugger(object):
"""A socket based debugger """
""" a list of tags to debug """
tags = {}
knownTags = []
selectedTags = []
# subscribed = {}
def __init__(self):
self.socket_file = '/tmp/._my_debug_socket'
print('\nStarting the debugger on socket file \'{}\'.\nRequest help with \n echo help | nc -U {}\'\n '.format(
self.socket_file,
self.socket_file
))
def cleanup(self):
if os.path.exists(self.socket_file):
os.remove(self.socket_file)
def add_known_tags(self, tags):
if isinstance(tags, str):
tags = [tags]
self.tags = set(list(self.tags) + tags)
def add_selected_tags(self, tags):
if isinstance(tags, str):
tags = [tags]
self.selectedTags = set(list(self.selectedTags)).union(set(tags))
def debug(self, tags, message):
if isinstance(tags, str):
tags = [tags]
self.add_known_tags(tags)
if len(set(tags) & set(self.selectedTags)):
print(message)
# else :
# print( "skipping message %s vs. %s" % (self.selectedTags, tags ))
async def server(self):
async def handler(reader, writer):
data = await reader.read(100)
if data:
msg = ""
req = data.split()
if not len(req):
msg = "Error: empty request"
else:
cmd = "cmd_" + str(req.pop(0), "utf-8")
print("Debugger server command: %s" % (cmd))
if not hasattr(self, cmd):
msg = "Error: Invalid command '%s'" % (cmd)
else:
method = getattr(self, cmd)
if not callable(method):
msg = "Error: Called a property"
else:
try:
req = [str(i, 'utf-8') for i in req]
msg = method(req)
except Exception as e:
msg = "Error : %s " % (e)
print("Response:\n%s" % (msg))
writer.write(bytes(msg, "utf-8"))
await writer.drain()
writer.close()
self.cleanup()
return await asyncio.start_unix_server(handler, path=self.socket_file)
def cmd_help(self, params):
"""
request general help
"""
members = inspect.getmembers(self)
out = []
for name, obj in members:
if not re.match("^cmd_", name):
continue
out.append(
"- " + re.sub("^cmd_(.*)", lambda m: m.group(1), name) + (str(obj.__doc__) if obj.__doc__ else ""))
return "\n".join(out) + "\n"
def cmd_list_tags(self, params):
"""
List available debug tags
"""
msg = ""
if not len(self.tags):
msg += "No tags yet\n"
else:
msg += "Tags:"
for flag in sorted(self.tags):
msg += "\n - %s" % (flag)
msg += "\n"
return msg
def cmd_add_tags(self, params):
"""
Add a debug tag
"""
msg = ""
if not len(params):
msg = "No flag provided"
else:
for flag in params:
if flag in self.selectedTags:
msg += "Noop: flag '%s' already added" % (flag)
else:
self.add_selected_tags([flag])
msg += "Added flag '%s'" % (flag)
return msg
def cmd_del_tags(self, params):
"""
Removes a tag
"""
msg = ""
if not len(params):
msg = "No flag provided"
else:
for flag in params:
if flag not in self.selectedTags:
msg += "Noop: flag '%s' not added" % (flag)
else:
self.selectedTags.remove(flag)
msg += "Removed flag '%s'" % (flag)
return msg
# def cmd_list_objs(self, params):
# """
# List available objects
# """
# if not len(self.subscribed ):
# msg += "No subscribed object yet\n"
# else:
# msg += "Subscribed objects:"
# for i, (oid, obj) in enumerate(self.subscribed.items()) :
# msg+="\n - %s\t%s" % (oid,obj)
#
# return "\n".msg
#
#
# def cmd_add_objs(self, params):
# """
# Debug a precise object
# """
# oid = params[0]
# msg = "Unknown error"
# if not self.subscribed[oid]:
#
# msg = "No such object"
# else :
# obj = self.subscribed[oid]
# msg = obj.debugSelf()
# return msg
# def subscribe( self, oid, obj ):
# self.subscribed[ oid ] = obj

73
lib/director.py Normal file
View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
import asyncio
import inspect
import re
from debuggable import Debuggable
from plan import Plan
from blackboard import Blackboard
from schedule import Schedule
from planning import Planning
class Director(Debuggable):
def __init__(self, debug_tags=[]):
super(Director, self).__init__()
if len(debug_tags):
self._debugger.add_selected_tags(debug_tags)
self.plugins = {}
self.sensors = []
self.planners = []
self.communicators = []
self.blackboard = {} # Blackboard()
self.planning = Planning()
async def tick(self):
self.on_perceive()
self.on_plan()
self.on_communicate()
await asyncio.sleep(0.1)
def on_perceive(self):
"""Sensors are required to update the blackboard
"""
# Pass the World State to all sensors
for obj, meth in self.sensors:
getattr(self.plugins[obj], meth)(blackboard=self.blackboard)
def on_plan(self):
"""Planifiers are called
"""
for obj, meth in self.planners:
getattr(self.plugins[obj], meth)(blackboard=self.blackboard, planning=self.planning)
def on_communicate(self):
"""Communicators are called
"""
for obj, meth in self.communicators:
getattr(self.plugins[obj], meth)(planning=self.planning)
async def run(self):
while 1:
await self.tick()
def add_plugin(self, plugin):
if not hasattr(plugin, "name"):
raise Exception("No property 'name' in plugin '{}'".format(plugin))
plugin_name = plugin.name
self.plugins[plugin_name] = plugin
for method_name, prop in inspect.getmembers(plugin):
if re.match("^(sensor.*)", method_name):
self.sensors.append((plugin_name, method_name))
self.debug("config", "Added sensor {}::{}".format(plugin_name, method_name))
elif re.match("^(planner.*)", method_name):
self.planners.append((plugin_name, method_name))
self.debug("config", "Added planner {}::{}".format(plugin_name, method_name))
elif re.match("^(communicator.*)", method_name):
self.communicators.append((plugin_name, method_name))
self.debug("config", "Added communicator {}::{}".format(plugin_name, method_name))

121
lib/my_plugin.py Normal file
View File

@ -0,0 +1,121 @@
from debuggable import Debuggable
from random import randint, choice
from math import sqrt
from datetime import datetime, timedelta
from planning import Planning
from schedule import Schedule
def gen(N, n):
""" returns a list of integer numbers between 1 and n with exhaustion level N """
res = []
i = 0
while N > 1:
r = randint(1, n)
N /= r
res.append(r)
i += 1
return res
def abba(lst, item):
return [item, *lst, item]
def abab(lst, item):
return [item, *lst, item, *lst]
def baa(lst, item):
return [*lst, item, item]
def ab(lst, item):
return [item, *lst]
def ba(lst, item):
return [*lst, item]
def struct(lst):
fnList = ['abba', 'abab', 'baa', 'ab', 'ba']
ret = []
for i, w in enumerate(lst):
fn_name = choice(fnList)
fn = globals().copy().get(fn_name)
ret = fn(ret, {'id': i, 'weight': w})
return ret
class MyPlugin(Debuggable):
"""Planner for general slots allocations"""
name = "myPlugin"
def __init__(self):
super(MyPlugin, self).__init__()
self.updated = False
def sensor_base(self, blackboard):
pass
def communicator_base(self, planning):
if self.updated:
self.updated = False
self.debug("my_plugin_schedules", "Rescheduling at {}.".format(datetime.now().isoformat()))
for schedule in planning.schedules:
self.debug("my_plugin_schedules", schedule.to_string())
def planner_base(self, blackboard, planning: Planning):
"""
duration = 5
L = [4, 2, 2]
C = [{2: 3}, {1: 2}, {0: 4}, {0: 4}, {2: 3}]
where each item of C is an {pattern_id: weight}
duration of a stitch = 1 / sqrt(weight)
R = [ 0.57, 0.7, 0.5, 0.5, 0.57]
Sum of duration weights = 2.84
each stitch lasts for a fraction of the total length
comp = [{2: [3, 1.0]}, {1: [2, 1.23]}, {0: [4, 0.88]}, {0: [4, 0.88]}, {2: [3, 1.0]}]
"""
last_schedule: Schedule = planning.get_last_schedule()
if last_schedule:
self.debug("my_plugin_last_schedule","last_schedule end at {}".format(last_schedule.end_at.isoformat()))
start_at_base = last_schedule.end_at
if start_at_base > datetime.now():
self.debug("my_plugin_skip","skip")
return
else:
start_at_base = datetime.now()
duration = 10
L = gen(randint(12, 20), randint(3, 5))
C = struct(L)
R = []
Rsum = 0
Ret = []
for i in C:
R.append(1 / sqrt(i['weight']))
Rsum = sum(R)
for i, j in enumerate(C):
C[i]['duration'] = R[i] * duration / Rsum
# [{'id': 1, 'weight': 4, 'duration': 0.11670090144936807}, {'id': 0, 'weight': 1, 'duration': 0.23340180289873613}, {'id': 0, 'weight': 1, 'duration': 0.23340180289873613}, {'id': 1, 'weight': 4, 'duration': 0.11670090144936807}, {'id': 2, 'weight': 2, 'duration': 0.1650399975708623}, {'id': 3, 'weight': 3, 'duration': 0.1347545937329293}]
schedules = []
elapsed: float = 0
for item in C:
duration = item["duration"]
start_at = start_at_base + timedelta( seconds=elapsed)
schedules.append(Schedule(
start_at=start_at,
end_at=start_at + timedelta( seconds=duration),
name=item['id'],
content=item
))
elapsed += duration
planning.add(schedules)
self.updated = True

5
lib/plan.py Normal file
View File

@ -0,0 +1,5 @@
class Plan( object ):
def __init__( self ):
pass

65
lib/planner_content.py Normal file
View File

@ -0,0 +1,65 @@
from debuggable import Debuggable
class Pattern(Debuggable):
def __init__(self, arg):
super(Pattern, self).__init__()
for i in arg:
setattr(self, i, arg[i])
class ContentPlanner(Debuggable):
"""Planner for slots content allocation """
# def __init__(self):
# the patterns memory
# patternsList = []
# define the possible schedule contents
# min_weight
# max_weight
# score_first
# score_same
# score_different
# score_final
def plan(self,state, memory, plan):
# Read previous actions from memory
actionsMemory = memory.getActionsMemory()
finished = False
energy = state.energy()
finished = False
while not finished and energy > 0:
actionsWeightSum = sum(actionsMemory.values()) if actionsMemory else 1
print(__file__,actionsMemory, actionsWeightSum, self.weightTable)
for action in self.actions:
if energy + action.energy < 0 :
continue
action_weight = ( (actionsWeightSum - actionsMemory[action.name] ) / actionsWeightSum ) if action.name in actionsMemory else 1
print(__file__, action.name, actionsMemory,action.name in actionsMemory,action_weight)
self.weightTable[action.name] = action_weight
print( self.weightTable)
high_score = max(self.weightTable, key=self.weightTable.get)
chosen_action = self.actions[self.actionsIndex[high_score]]
energy += chosen_action.energy
plan.addAction( chosen_action )
print ( energy, chosen_action.name )
if action.name in actionsMemory:
actionsMemory[chosen_action.name] += 1
else :
actionsMemory[chosen_action.name] = 1
if energy < 0:
finished = True
return plan

33
lib/schedule.py Normal file
View File

@ -0,0 +1,33 @@
from debuggable import Debuggable
from datetime import datetime, timedelta
import json
class Schedule(Debuggable):
start_at = datetime.now()
end_at = datetime.now()
content = {}
name = "default"
def __init__(self, start_at=None, end_at=None, content={}, name=None):
super(Schedule, self).__init__()
self.start_at = start_at
self.end_at = end_at
self.content = content
self.name = name
self.debug("new_schedules","New schedule: {}".format(self.to_string()))
def elapsed(self):
delta = datetime.now() - self.end_at
if delta.total_seconds() > 0 :
self.debug("schedule_elapsed_true","delta is {} for {}".format(delta, self.end_at.isoformat()))
return True
return False
def to_string(self):
return json.dumps({
"start_at": self.start_at.isoformat(),
"end_at": self.end_at.isoformat(),
"name": self.name,
"content": self.content
})

50
lib/test.py Normal file
View File

@ -0,0 +1,50 @@
def gen( N, n ):
res = []
i = 0
while N > 1:
r = randint(1,n)
N /= r
res.append(r)
i += 1
return res
def abba( lst, item ):
return [ item, *lst, item]
def abab( lst, item ):
return [ item, *lst, item, *lst]
def baa( lst, item ):
return [ *lst, item, item ]
def ab( lst, item ):
return [ item, *lst ]
def ba( lst, item ):
return [ *lst, item ]
def struct( lst ):
fnList = ['abba','abab','baa','ab','ba']
ret = []
for i,v in enumerate(lst):
fn_name = choice(fnList)
fn = globals().copy().get(fn_name)
ret = fn(ret,{i:v})
return ret
L = gen(randint(12,20),randint(3,5))
C = struct(L)
R = []
Rsum = 0
Ret = []
for i in C :
R.append( 1/ sqrt(sum(i.values()) ))
Rsum = sum(R)
for i,j in enumerate(C) :
length = R[i] * duration / Rsum
print(i,j,length)
for id in j.keys():
print(id)
Ret.append( { id : [j[id],length]} )