diff --git a/osc_server.py b/osc_server.py new file mode 100644 index 0000000..a3a4558 --- /dev/null +++ b/osc_server.py @@ -0,0 +1,155 @@ +import psutil +import datetime +import logging +import time +import requests +from pythonosc.osc_server import ThreadingOSCUDPServer +from pythonosc.dispatcher import Dispatcher +from pythonosc.osc_bundle_builder import OscBundleBuilder +from pythonosc.osc_bundle_builder import IMMEDIATELY +from pythonosc.osc_message_builder import OscMessageBuilder +from pythonosc.udp_client import SimpleUDPClient + +logger = logging.getLogger("root") + +class cpuData(object): + logger = logger.getChild("cpuData") + @classmethod + def get_data(cls): + cls.logger.info("getting data") + data = {} + data["cpu"] = psutil.cpu_freq().current + data["ram"] = psutil.virtual_memory().percent + data = cls._construct_osc_bundle(data) + return data + + @classmethod + def _construct_osc_bundle(cls, data): + bundle = OscBundleBuilder(IMMEDIATELY) + for key, value in data.items(): + msg = OscMessageBuilder("/cpu/{}".format(key)) + msg.add_arg(value) + bundle.add_content(msg.build()) + bundle = bundle.build() + return bundle + + +class openWeatherData(object): + logger = logger.getChild("openWeatherData") + API_KEY = "4398785f60059433ff91c603e887f7ac" + URL = "http://api.openweathermap.org/data/2.5/weather?" + _data = {} + + @classmethod + def _request_city_data(cls, city): + url = "{}appid={}&q={}".format( + cls.URL, + cls.API_KEY, + city, + ) + data = requests.get(url).json() + cls.logger.info(data) + cls._data[city] = data + return data + + @classmethod + def get_data(cls, city): + cls.logger.info("getting data") + city = str(city).lower() + if city not in cls._data.keys(): + cls.logger.info("requesting city: {}".format(city)) + cls._request_city_data(city) + data = cls._construct_osc_bundle(city) + return data + else: + cls.logger.info("retrieving city from internal database: {}".format(city)) + data = cls._construct_osc_bundle(city) + return data + + @classmethod + def _construct_osc_bundle(cls, city): + bundle = OscBundleBuilder(IMMEDIATELY) + for key, value in cls._data[city].items(): + if isinstance(value, int): + msg = OscMessageBuilder("/weather/{}".format(key)) + msg.add_arg(value) + bundle.add_content(msg.build()) + if isinstance(value, dict): + for subkey, subvalue in value.items(): + msg = OscMessageBuilder("/weather/{}/{}".format(key, subkey)) + msg.add_arg(subvalue) + bundle.add_content(msg.build()) + bundle = bundle.build() + return bundle + +class bitcoinData(object): + logger = logger.getChild("bitcoinData") + URL = "https://api.coinmarketcap.com/v1/ticker/bitcoin/" + + @classmethod + def get_data(cls): + cls.logger.info("getting data") + data = requests.get(cls.URL).json() + data = cls._construct_osc_bundle(data) + return data + + @classmethod + def _construct_osc_bundle(cls, data): + bundle = OscBundleBuilder(IMMEDIATELY) + for element in data: + for key, value in element.items(): + msg = OscMessageBuilder("/bitcoin/{}".format(key)) + msg.add_arg(value) + bundle.add_content(msg.build()) + bundle = bundle.build() + return bundle + +class oscDataServer(object): + def __init__(self, port=8080): + self.logger = logger.getChild(self.__class__.__name__) + self._dispatcher = Dispatcher() + self._dispatcher.map("/get/cpu", self.get_cpu, needs_reply_address=True) + self._dispatcher.map("/get/weather", self.get_city, needs_reply_address=True) + self._dispatcher.map("/get/bitcoin", self.get_bitcoin, needs_reply_address=True) + self._weather_data = openWeatherData() + self._bitcoin_data = bitcoinData() + self._cpu_data = cpuData() + self._server = ThreadingOSCUDPServer(("0.0.0.0", port), self._dispatcher) + + def main(self): + self.logger.info("starting server") + self._server.serve_forever() + + def get_cpu(self, *args, **kwargs): + data = self._cpu_data.get_data() + client = SimpleUDPClient(args[0][0], port=8081) + client.send(data) + self.logger.info("data sent to {}".format(args[0][0])) + + def get_bitcoin(self, *args, **kwargs): + data = self._bitcoin_data.get_data() + client = SimpleUDPClient(args[0][0], port=8081) + client.send(data) + self.logger.info("data sent to {}".format(args[0][0])) + + def get_city(self, *args, **kwargs): + data = self._weather_data.get_data(args[2]) + client = SimpleUDPClient(args[0][0], port=8081) + client.send(data) + self.logger.info("data sent to {}".format(args[0][0])) + +def main(): + server = oscDataServer() + server.main() + +if __name__ == "__main__": + logger.setLevel(logging.INFO) + streamhandler = logging.StreamHandler() + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + streamhandler.setFormatter(formatter) + logger.addHandler(streamhandler) + + logger.info("hello world") + + main() +