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()