From 871a29a9dd2e8a6b0f1be2194530dd2c6621924f Mon Sep 17 00:00:00 2001 From: root Date: Tue, 11 Jul 2017 16:07:04 +0530 Subject: [PATCH 01/12] Adding can bus protocol implementation --- examples/can/simulated_can.py | 12 +++ liota/device_comms/can_device_comms.py | 118 +++++++++++++++++++++++++ liota/lib/transports/Can.py | 117 ++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 examples/can/simulated_can.py create mode 100644 liota/device_comms/can_device_comms.py create mode 100644 liota/lib/transports/Can.py diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py new file mode 100644 index 00000000..18b98ab2 --- /dev/null +++ b/examples/can/simulated_can.py @@ -0,0 +1,12 @@ +import Queue + +from liota.device_comms.can_device_comms import CanDeviceComms +from liota.entities.metrics.metric import Metric + +def can_connect(): + bus1 = CanDeviceComms(bustype='virtual') + bus2 = CanDeviceComms(bustype='virtual') + bus1.send(data=[1,2,3]) + bus2.receive() + +can_connect() diff --git a/liota/device_comms/can_device_comms.py b/liota/device_comms/can_device_comms.py new file mode 100644 index 00000000..2d540f19 --- /dev/null +++ b/liota/device_comms/can_device_comms.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + +import logging + +from liota.device_comms.device_comms import DeviceComms +from liota.lib.transports.Can import Can, CanMessagingAttributes +import random + +log = logging.getLogger(__name__) + + +class CanDeviceComms(DeviceComms): + """ + DeviceComms for Can bus protocol + """ + + def __init__(self, channel=None, can_filters=None, bustype=None, listeners=None, can_msg_attr=None): + """ + :param channel: The can interface identifier. Expected type is backend dependent. + :param can_filters:A list of dictionaries each containing a "can_id" and a "can_mask". + >>> [{"can_id": 0x11, "can_mask": 0x21}] + A filter matches, when `` & can_mask == can_id & can_mask`` + :param bustype: The ref:`bus` to listen too. + :param listeners: An iterable of class:`can.Listeners` + :param userdata: userdata is used to store messages coming from the receive channel. + """ + self.channel = channel + if bustype is None: + log.error("Bus Type can't be None") + raise TypeError("Bus Type can't be none") + else: + self.bustype=bustype + self.bustype = bustype + self.can_filters=can_filters + self.listeners = listeners + #self.userdata = Queue.Queue() + if can_msg_attr is None: + log.info("arbitration_id will be auto-generated and extended_id will be true by default") + self.msg_attr = CanMessagingAttributes(arbitration_id=random.randint(0,2**29-1),extended_id=True) + elif isinstance(can_msg_attr, CanMessagingAttributes): + log.info("User configured arbitration_id and extended_id") + self.msg_attr = can_msg_attr + else: + log.error("can_msg_attr should either be None or of type CanMessagingAttributes") + raise TypeError("can_msg_attr should either be None or of type CanMessagingAttributes") + self._connect() + + def _connect(self): + self.client = Can(self.channel, self.can_filters, self.bustype, self.listeners) + self.client.connect() + + def _disconnect(self): + raise NotImplementedError + + def send(self, data, msg_attr=None): + ''' + :param data(bytearray): data sent to can bus + :param msg_attr : CanMessaging attribute instance + Messages can use extended identifiers, be remote or error frames, and contain data. + ''' + if msg_attr: + self.client.send(msg_attr.arbitration_id, data, msg_attr.extended_id) + else: + self.client.send(self.msg_attr.arbitration_id, data, self.msg_attr.extended_id) + + def receive(self, timeout=0): + ''' + :param timeout(float): Seconds to wait for a message + ''' + msg = self.client.recv(timeout) + if msg is not None: + print(msg) + else: + print("No message received") + log.error("No message received") + + def set_filters(self): + self.client.set_filters(self.can_filters) + + def flush_tx_buffer(self): + self.client.flush_tx_buffer() + + def send_periodic(self, data, msg_attr=None, period=0.0, duration=None): + task = self.client.send_periodic(data, msg_attr.arbitration_id, msg_attr.extended_id, period, duration) + #To-Do how the task will be used + + def shutdown(): + self.client.shutdown() \ No newline at end of file diff --git a/liota/lib/transports/Can.py b/liota/lib/transports/Can.py new file mode 100644 index 00000000..23466333 --- /dev/null +++ b/liota/lib/transports/Can.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + +import logging +import os +import sys +import time +import can +from random import randint + +log = logging.getLogger(__name__) + +class Can: + ''' + CAN implementation for LIOTA. It uses python-can internally. + ''' + def __init__(self, channel=None, can_filters=None, bustype=None, listeners=None, bus=None): + + self.channel = channel + self.bustype = bustype + self.can_filters = can_filters + self.listeners = listeners + + def connect(self): + self.bus = can.interface.Bus(bustype=self.bustype, channel=self.channel) + log.info("Connected to Can Bus") + + def send(self, arbitration_id, data, extended_id): + message = can.Message(arbitration_id=arbitration_id, data=data, extended_id=extended_id) + try: + self.bus.send(message) + print("Message sent on {}".format(self.bus.channel_info)) + except can.CanError: + print("Message not sent") + log.error("Message not sent over channel") + + + def recv(self, timeout): + return self.bus.recv(timeout=timeout) + + def set_filters(self): + self.bus.set_filters(self.can_filters) + + def flush_tx_buffer(self): + self.bus.flush_tx_buffer() + + def send_periodic(self, data, arbitration_id, extended_id, period, duration=None): + ''' + :param float period: + Period in seconds between each message + :param float duration: + The duration to keep sending this message at given rate. If + no duration is provided, the task will continue indefinitely. + + :return: A started task instance + :rtype: can.CyclicSendTaskABC + ''' + message = can.Message(arbitration_id=arbitration_id, data=data, extended_id=extended_id) + task = can.send_periodic(message, period, duration) + assert isinstance(task, can.CyclicSendTaskABC) + return task + + def shutdown(self): + self.bus.shutdown() + + def stop(self): + pass + +class CanMessagingAttributes: + + def __init__(self, pub_timestamp=0.0, arbitration_id=0, extended_id=True, is_remote_frame=False, + is_error_frame=False, dlc=None): + + self.arbitration_id = arbitration_id + self.extended_id = extended_id + + self.pub_timestamp = pub_timestamp + self.arbitration_id = arbitration_id + self.id_type = extended_id + self.is_remote_frame = is_remote_frame + self.is_error_frame = is_error_frame + + + + + + + \ No newline at end of file From 70e7c6307f6af24f8691bf10843860f6cbeb69a6 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 11 Jul 2017 19:54:18 +0530 Subject: [PATCH 02/12] Check for arb_id --- examples/can/simulated_can.py | 17 +++++++++++------ liota/device_comms/can_device_comms.py | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py index 18b98ab2..20e046d8 100644 --- a/examples/can/simulated_can.py +++ b/examples/can/simulated_can.py @@ -1,12 +1,17 @@ -import Queue - from liota.device_comms.can_device_comms import CanDeviceComms from liota.entities.metrics.metric import Metric +from liota.lib.transports.Can import CanMessagingAttributes + +def actuator_value(value): + print value def can_connect(): - bus1 = CanDeviceComms(bustype='virtual') + msg_attr = CanMessagingAttributes(arbitration_id=11,extended_id=False) + bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) bus2 = CanDeviceComms(bustype='virtual') - bus1.send(data=[1,2,3]) - bus2.receive() + bus1.send(data=[1,2,3],msg_attr=msg_attr) + msg = bus2.receive() + actuator_value(msg) -can_connect() +if __name__ == "__main__": + can_connect() diff --git a/liota/device_comms/can_device_comms.py b/liota/device_comms/can_device_comms.py index 2d540f19..c3672ce9 100644 --- a/liota/device_comms/can_device_comms.py +++ b/liota/device_comms/can_device_comms.py @@ -99,7 +99,7 @@ def receive(self, timeout=0): ''' msg = self.client.recv(timeout) if msg is not None: - print(msg) + return msg else: print("No message received") log.error("No message received") From 856e23b0402eaa59b37f9f34cabe6007362547e5 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 12 Jul 2017 16:48:19 +0530 Subject: [PATCH 03/12] Added can_simulated and graphite_can_simulated --- examples/can/simulated_can.py | 3 +- .../model_simulated/graphite_can_simulated.py | 36 +++++++++++++++++++ .../graphite_thermistor_simulated.py | 1 + examples/sampleProp.conf | 4 +-- liota/entities/devices/can_simulated.py | 28 +++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 examples/model_simulated/graphite_can_simulated.py create mode 100644 liota/entities/devices/can_simulated.py diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py index 20e046d8..2d37366d 100644 --- a/examples/can/simulated_can.py +++ b/examples/can/simulated_can.py @@ -2,6 +2,7 @@ from liota.entities.metrics.metric import Metric from liota.lib.transports.Can import CanMessagingAttributes + def actuator_value(value): print value @@ -14,4 +15,4 @@ def can_connect(): actuator_value(msg) if __name__ == "__main__": - can_connect() + can_connect() \ No newline at end of file diff --git a/examples/model_simulated/graphite_can_simulated.py b/examples/model_simulated/graphite_can_simulated.py new file mode 100644 index 00000000..31169f93 --- /dev/null +++ b/examples/model_simulated/graphite_can_simulated.py @@ -0,0 +1,36 @@ +from liota.dcc_comms.socket_comms import SocketDccComms +from liota.dccs.graphite import Graphite +from liota.entities.metrics.metric import Metric +from liota.entities.edge_systems.dell5k_edge_system import Dell5KEdgeSystem +from liota.lib.transports.Can import CanMessagingAttributes +from liota.entities.devices.can_simulated import CanSimulated +from liota.lib.utilities.utility import read_user_config + +config = read_user_config('../sampleProp.conf') + +def get_data(): + data = can_model.get_data() + return data + +if __name__ == "__main__": + edge_system = Dell5KEdgeSystem(config['EdgeSystemName']) + + can_model = CanSimulated(name=config['DeviceName'], extended_id=True) + + graphite = Graphite(SocketDccComms(ip=config['GraphiteIP'], + port=config['GraphitePort'])) + + graphite_reg_dev = graphite.register(can_model) + + can_msg_metric = "model.can.msg" + + can_msg_data = Metric( + name=can_msg_metric, + unit=None, + interval=1, + sampling_function=get_data + ) + + reg_can_msg = graphite.register(can_msg_data) + graphite.create_relationship(graphite_reg_dev, reg_can_msg) + reg_can_msg.start_collecting() \ No newline at end of file diff --git a/examples/model_simulated/graphite_thermistor_simulated.py b/examples/model_simulated/graphite_thermistor_simulated.py index acf82674..8cbb1e17 100644 --- a/examples/model_simulated/graphite_thermistor_simulated.py +++ b/examples/model_simulated/graphite_thermistor_simulated.py @@ -132,6 +132,7 @@ def get_thermistor_temperature(): graphite_reg_dev = graphite.register(thermistor_model) metric_name = "model.thermistor.temperature" + thermistor_temper = Metric( name=metric_name, unit=ureg.degC, diff --git a/examples/sampleProp.conf b/examples/sampleProp.conf index 1906d364..fd6e2d31 100644 --- a/examples/sampleProp.conf +++ b/examples/sampleProp.conf @@ -21,5 +21,5 @@ ClientCertFile = None #### [GRAPHITE] #### -GraphiteIP = "Graphite-IP" -GraphitePort = None +GraphiteIP = "92.246.246.188" +GraphitePort = 2003 diff --git a/liota/entities/devices/can_simulated.py b/liota/entities/devices/can_simulated.py new file mode 100644 index 00000000..6209af93 --- /dev/null +++ b/liota/entities/devices/can_simulated.py @@ -0,0 +1,28 @@ +import random +from liota.entities.devices.device import Device +from liota.lib.utilities.utility import systemUUID + +class CanSimulated(Device): + def __init__(self, name, extended_id=True): + super(CanSimulated, self).__init__( + name=name, + entity_id=systemUUID().get_uuid(name), + entity_type="CanSimulator" + ) + + self.extended_id=extended_id + self.c1 = 1 #constant to generate different data always + self.data = [1,2,3] + self.arbitration_id=100 + + def get_data(self): + self.c1+=1 + return self.data + + def get_id(self): + if self.extended_id is True: + self.arbitration_id=random.randint(0,2**29-1) + else: + self.arbitration_id=random.randint(0,2**11-1) + return self.arbitration_id + From 9b2b241978f293ff724dcd8631f2247ba2e7fb19 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 12 Jul 2017 19:03:12 +0530 Subject: [PATCH 04/12] Added test for can_device_comms --- examples/can/simulated_can.py | 12 ++++---- liota/device_comms/can_device_comms.py | 5 +++- liota/device_comms/device_comms.py | 1 - tests/test_can.py | 38 ++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 tests/test_can.py diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py index 2d37366d..c8e50169 100644 --- a/examples/can/simulated_can.py +++ b/examples/can/simulated_can.py @@ -8,11 +8,13 @@ def actuator_value(value): def can_connect(): msg_attr = CanMessagingAttributes(arbitration_id=11,extended_id=False) - bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) - bus2 = CanDeviceComms(bustype='virtual') - bus1.send(data=[1,2,3],msg_attr=msg_attr) - msg = bus2.receive() - actuator_value(msg) + #bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) + #bus3 = CanDeviceComms() + bustype = "virtual" + bus2 = CanDeviceComms(bustype=bustype,can_msg_attr="asd") + #bus1.send(data=[1,2,3],msg_attr=msg_attr) + #msg = bus2.receive() + #actuator_value(msg) if __name__ == "__main__": can_connect() \ No newline at end of file diff --git a/liota/device_comms/can_device_comms.py b/liota/device_comms/can_device_comms.py index c3672ce9..eda147ed 100644 --- a/liota/device_comms/can_device_comms.py +++ b/liota/device_comms/can_device_comms.py @@ -44,7 +44,7 @@ class CanDeviceComms(DeviceComms): DeviceComms for Can bus protocol """ - def __init__(self, channel=None, can_filters=None, bustype=None, listeners=None, can_msg_attr=None): + def __init__(self, channel=None, can_filters=None, bustype=None, listeners=None, can_msg_attr): """ :param channel: The can interface identifier. Expected type is backend dependent. :param can_filters:A list of dictionaries each containing a "can_id" and a "can_mask". @@ -88,6 +88,9 @@ def send(self, data, msg_attr=None): :param msg_attr : CanMessaging attribute instance Messages can use extended identifiers, be remote or error frames, and contain data. ''' + if data is None: + raise TypeError + if msg_attr: self.client.send(msg_attr.arbitration_id, data, msg_attr.extended_id) else: diff --git a/liota/device_comms/device_comms.py b/liota/device_comms/device_comms.py index dc179d83..e48a54ca 100644 --- a/liota/device_comms/device_comms.py +++ b/liota/device_comms/device_comms.py @@ -39,7 +39,6 @@ class DeviceComms: Abstract base class for all device communications. """ __metaclass__ = ABCMeta - #----------------------------------------------------------------------- # If a specific DeviceComms has parameters to establish connection, pass # them to its constructor, not self._connect. Keep self._connect free of diff --git a/tests/test_can.py b/tests/test_can.py new file mode 100644 index 00000000..730ebb82 --- /dev/null +++ b/tests/test_can.py @@ -0,0 +1,38 @@ +import unittest +import mock +from liota.device_comms.can_device_comms import CanDeviceComms +from liota.device_comms.device_comms import DeviceComms +from liota.lib.transports.Can import CanMessagingAttributes + +bus_type = "virtual" + +class TestCanDeviceComms(unittest.TestCase): + + + def test_canDeviceComms_fail_without_bustype(self): + with self.assertRaises(Exception): + c = CanDeviceComms("asd") + assertNotIsInstance(c, CanDeviceComms) + + with self.assertRaises(Exception): + c = CanDeviceComms() + assert c is None + + def test_canDeviceComms_takes_bustype(self): + + c = CanDeviceComms(bustype = bus_type) + assert isinstance(c, CanDeviceComms) + + def test_canDeviceComms_fail_with_invalidArg_msg_attr(self): + with self.assertRaises(Exception): + c = CanDeviceComms(bustype = bus_type, can_msg_attr="asd") + assertNotIsInstance(c, CanDeviceComms) + + def test_canDeviceComms_pass_with_validArg_msg_attr(self): + mock_can_msg_attr = mock.create_autospec(CanMessagingAttributes) + c = CanDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) + assert isinstance(c, CanDeviceComms) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From efb3412ec32c5212f85b25e3366870f59aa7eb8f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 12 Jul 2017 19:08:04 +0530 Subject: [PATCH 05/12] Added test for can_device_comms --- tests/{test_can.py => test_can_device_comms.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{test_can.py => test_can_device_comms.py} (96%) diff --git a/tests/test_can.py b/tests/test_can_device_comms.py similarity index 96% rename from tests/test_can.py rename to tests/test_can_device_comms.py index 730ebb82..e47d549d 100644 --- a/tests/test_can.py +++ b/tests/test_can_device_comms.py @@ -16,7 +16,7 @@ def test_canDeviceComms_fail_without_bustype(self): with self.assertRaises(Exception): c = CanDeviceComms() - assert c is None + assertNotIsInstance(c, CanDeviceComms) def test_canDeviceComms_takes_bustype(self): From 518d05f1a990b96887b0cec3660a0dac3b529581 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 12 Jul 2017 19:21:03 +0530 Subject: [PATCH 06/12] Small modifications to simulated_can --- examples/can/simulated_can.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py index c8e50169..2d37366d 100644 --- a/examples/can/simulated_can.py +++ b/examples/can/simulated_can.py @@ -8,13 +8,11 @@ def actuator_value(value): def can_connect(): msg_attr = CanMessagingAttributes(arbitration_id=11,extended_id=False) - #bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) - #bus3 = CanDeviceComms() - bustype = "virtual" - bus2 = CanDeviceComms(bustype=bustype,can_msg_attr="asd") - #bus1.send(data=[1,2,3],msg_attr=msg_attr) - #msg = bus2.receive() - #actuator_value(msg) + bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) + bus2 = CanDeviceComms(bustype='virtual') + bus1.send(data=[1,2,3],msg_attr=msg_attr) + msg = bus2.receive() + actuator_value(msg) if __name__ == "__main__": can_connect() \ No newline at end of file From d2b2b89b51ae31e17526906b1bcb1e27d89255eb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 Jul 2017 18:14:48 +0530 Subject: [PATCH 07/12] Added can_bus --- examples/can/simulated_can.py | 2 +- liota/dccs/graphite.py | 1 + liota/device_comms/can_device_comms.py | 4 +-- tests/test_can.py | 38 ++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tests/test_can.py diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py index 2d37366d..6c237851 100644 --- a/examples/can/simulated_can.py +++ b/examples/can/simulated_can.py @@ -9,7 +9,7 @@ def actuator_value(value): def can_connect(): msg_attr = CanMessagingAttributes(arbitration_id=11,extended_id=False) bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) - bus2 = CanDeviceComms(bustype='virtual') + bus2 = CanDeviceComms(bustype='virtual',can_msg_attr=None) bus1.send(data=[1,2,3],msg_attr=msg_attr) msg = bus2.receive() actuator_value(msg) diff --git a/liota/dccs/graphite.py b/liota/dccs/graphite.py index 24b2ff55..da95d06b 100644 --- a/liota/dccs/graphite.py +++ b/liota/dccs/graphite.py @@ -62,6 +62,7 @@ def _format_data(self, reg_metric): return for _ in range(met_cnt): v = reg_metric.values.get(block=True) + print("V: ",v) if v is not None: # Graphite expects time in seconds, not milliseconds. Hence, # dividing by 1000 diff --git a/liota/device_comms/can_device_comms.py b/liota/device_comms/can_device_comms.py index eda147ed..821399db 100644 --- a/liota/device_comms/can_device_comms.py +++ b/liota/device_comms/can_device_comms.py @@ -44,7 +44,7 @@ class CanDeviceComms(DeviceComms): DeviceComms for Can bus protocol """ - def __init__(self, channel=None, can_filters=None, bustype=None, listeners=None, can_msg_attr): + def __init__(self, can_msg_attr, channel=None, can_filters=None, bustype=None, listeners=None): """ :param channel: The can interface identifier. Expected type is backend dependent. :param can_filters:A list of dictionaries each containing a "can_id" and a "can_mask". @@ -89,7 +89,7 @@ def send(self, data, msg_attr=None): Messages can use extended identifiers, be remote or error frames, and contain data. ''' if data is None: - raise TypeError + raise TypeError("Data can't be none") if msg_attr: self.client.send(msg_attr.arbitration_id, data, msg_attr.extended_id) diff --git a/tests/test_can.py b/tests/test_can.py new file mode 100644 index 00000000..e47d549d --- /dev/null +++ b/tests/test_can.py @@ -0,0 +1,38 @@ +import unittest +import mock +from liota.device_comms.can_device_comms import CanDeviceComms +from liota.device_comms.device_comms import DeviceComms +from liota.lib.transports.Can import CanMessagingAttributes + +bus_type = "virtual" + +class TestCanDeviceComms(unittest.TestCase): + + + def test_canDeviceComms_fail_without_bustype(self): + with self.assertRaises(Exception): + c = CanDeviceComms("asd") + assertNotIsInstance(c, CanDeviceComms) + + with self.assertRaises(Exception): + c = CanDeviceComms() + assertNotIsInstance(c, CanDeviceComms) + + def test_canDeviceComms_takes_bustype(self): + + c = CanDeviceComms(bustype = bus_type) + assert isinstance(c, CanDeviceComms) + + def test_canDeviceComms_fail_with_invalidArg_msg_attr(self): + with self.assertRaises(Exception): + c = CanDeviceComms(bustype = bus_type, can_msg_attr="asd") + assertNotIsInstance(c, CanDeviceComms) + + def test_canDeviceComms_pass_with_validArg_msg_attr(self): + mock_can_msg_attr = mock.create_autospec(CanMessagingAttributes) + c = CanDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) + assert isinstance(c, CanDeviceComms) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 58fae7711f60f2df0798153a1c7ef655ea70b6ce Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 Jul 2017 19:42:40 +0530 Subject: [PATCH 08/12] Added canbus tests and simulations --- examples/can/simulated_can.py | 18 --------- examples/canbus/simulated_canbus.py | 19 ++++++++++ ...ulated.py => graphite_canbus_simulated.py} | 9 +++-- ...device_comms.py => canbus_device_comms.py} | 17 +++++---- .../{can_simulated.py => canbus_simulated.py} | 6 +-- liota/lib/transports/{Can.py => CanBus.py} | 4 +- tests/test_can.py | 38 ------------------- tests/test_can_device_comms.py | 38 ------------------- tests/test_canbus.py | 38 +++++++++++++++++++ 9 files changed, 76 insertions(+), 111 deletions(-) delete mode 100644 examples/can/simulated_can.py create mode 100644 examples/canbus/simulated_canbus.py rename examples/model_simulated/{graphite_can_simulated.py => graphite_canbus_simulated.py} (78%) rename liota/device_comms/{can_device_comms.py => canbus_device_comms.py} (90%) rename liota/entities/devices/{can_simulated.py => canbus_simulated.py} (85%) rename liota/lib/transports/{Can.py => CanBus.py} (98%) delete mode 100644 tests/test_can.py delete mode 100644 tests/test_can_device_comms.py create mode 100644 tests/test_canbus.py diff --git a/examples/can/simulated_can.py b/examples/can/simulated_can.py deleted file mode 100644 index 6c237851..00000000 --- a/examples/can/simulated_can.py +++ /dev/null @@ -1,18 +0,0 @@ -from liota.device_comms.can_device_comms import CanDeviceComms -from liota.entities.metrics.metric import Metric -from liota.lib.transports.Can import CanMessagingAttributes - - -def actuator_value(value): - print value - -def can_connect(): - msg_attr = CanMessagingAttributes(arbitration_id=11,extended_id=False) - bus1 = CanDeviceComms(bustype='virtual',can_msg_attr=msg_attr) - bus2 = CanDeviceComms(bustype='virtual',can_msg_attr=None) - bus1.send(data=[1,2,3],msg_attr=msg_attr) - msg = bus2.receive() - actuator_value(msg) - -if __name__ == "__main__": - can_connect() \ No newline at end of file diff --git a/examples/canbus/simulated_canbus.py b/examples/canbus/simulated_canbus.py new file mode 100644 index 00000000..219343b0 --- /dev/null +++ b/examples/canbus/simulated_canbus.py @@ -0,0 +1,19 @@ +from liota.device_comms.canbus_device_comms import CanBusDeviceComms +from liota.entities.metrics.metric import Metric +from liota.lib.transports.CanBus import CanBusMessagingAttributes + + +def actuator_value(value): + print value + +def can_connect(): + msg_attr = CanBusMessagingAttributes(arbitration_id=11,extended_id=False) + bus1 = CanBusDeviceComms (bustype='virtual',can_msg_attr=msg_attr) + bus2 = CanBusDeviceComms (bustype='virtual',can_msg_attr=None) + bus1.send(data=[1,2,3],msg_attr=msg_attr) + msg = bus2.receive() + actuator_value(msg) + +if __name__ == "__main__": + can_connect() + \ No newline at end of file diff --git a/examples/model_simulated/graphite_can_simulated.py b/examples/model_simulated/graphite_canbus_simulated.py similarity index 78% rename from examples/model_simulated/graphite_can_simulated.py rename to examples/model_simulated/graphite_canbus_simulated.py index 31169f93..31c8d993 100644 --- a/examples/model_simulated/graphite_can_simulated.py +++ b/examples/model_simulated/graphite_canbus_simulated.py @@ -2,8 +2,8 @@ from liota.dccs.graphite import Graphite from liota.entities.metrics.metric import Metric from liota.entities.edge_systems.dell5k_edge_system import Dell5KEdgeSystem -from liota.lib.transports.Can import CanMessagingAttributes -from liota.entities.devices.can_simulated import CanSimulated +from liota.lib.transports.CanBus import CanBusMessagingAttributes +from liota.entities.devices.can_simulated import CanBusSimulated from liota.lib.utilities.utility import read_user_config config = read_user_config('../sampleProp.conf') @@ -15,7 +15,7 @@ def get_data(): if __name__ == "__main__": edge_system = Dell5KEdgeSystem(config['EdgeSystemName']) - can_model = CanSimulated(name=config['DeviceName'], extended_id=True) + can_model = CanBusSimulated(name=config['DeviceName'], extended_id=True) graphite = Graphite(SocketDccComms(ip=config['GraphiteIP'], port=config['GraphitePort'])) @@ -33,4 +33,5 @@ def get_data(): reg_can_msg = graphite.register(can_msg_data) graphite.create_relationship(graphite_reg_dev, reg_can_msg) - reg_can_msg.start_collecting() \ No newline at end of file + reg_can_msg.start_collecting() + \ No newline at end of file diff --git a/liota/device_comms/can_device_comms.py b/liota/device_comms/canbus_device_comms.py similarity index 90% rename from liota/device_comms/can_device_comms.py rename to liota/device_comms/canbus_device_comms.py index 821399db..8f866541 100644 --- a/liota/device_comms/can_device_comms.py +++ b/liota/device_comms/canbus_device_comms.py @@ -33,13 +33,13 @@ import logging from liota.device_comms.device_comms import DeviceComms -from liota.lib.transports.Can import Can, CanMessagingAttributes +from liota.lib.transports.CanBus import CanBus, CanBusMessagingAttributes import random log = logging.getLogger(__name__) -class CanDeviceComms(DeviceComms): +class CanBusDeviceComms(DeviceComms): """ DeviceComms for Can bus protocol """ @@ -66,17 +66,17 @@ def __init__(self, can_msg_attr, channel=None, can_filters=None, bustype=None, l #self.userdata = Queue.Queue() if can_msg_attr is None: log.info("arbitration_id will be auto-generated and extended_id will be true by default") - self.msg_attr = CanMessagingAttributes(arbitration_id=random.randint(0,2**29-1),extended_id=True) - elif isinstance(can_msg_attr, CanMessagingAttributes): + self.msg_attr = CanBusMessagingAttributes(arbitration_id=random.randint(0,2**29-1),extended_id=True) + elif isinstance(can_msg_attr, CanBusMessagingAttributes): log.info("User configured arbitration_id and extended_id") self.msg_attr = can_msg_attr else: - log.error("can_msg_attr should either be None or of type CanMessagingAttributes") - raise TypeError("can_msg_attr should either be None or of type CanMessagingAttributes") + log.error("can_msg_attr should either be None or of type CanBusMessagingAttributes") + raise TypeError("can_msg_attr should either be None or of type CanBusMessagingAttributes") self._connect() def _connect(self): - self.client = Can(self.channel, self.can_filters, self.bustype, self.listeners) + self.client = CanBus(self.channel, self.can_filters, self.bustype, self.listeners) self.client.connect() def _disconnect(self): @@ -118,4 +118,5 @@ def send_periodic(self, data, msg_attr=None, period=0.0, duration=None): #To-Do how the task will be used def shutdown(): - self.client.shutdown() \ No newline at end of file + self.client.shutdown() + \ No newline at end of file diff --git a/liota/entities/devices/can_simulated.py b/liota/entities/devices/canbus_simulated.py similarity index 85% rename from liota/entities/devices/can_simulated.py rename to liota/entities/devices/canbus_simulated.py index 6209af93..47536419 100644 --- a/liota/entities/devices/can_simulated.py +++ b/liota/entities/devices/canbus_simulated.py @@ -2,12 +2,12 @@ from liota.entities.devices.device import Device from liota.lib.utilities.utility import systemUUID -class CanSimulated(Device): +class CanBusSimulated(Device): def __init__(self, name, extended_id=True): - super(CanSimulated, self).__init__( + super(CanBusSimulated, self).__init__( name=name, entity_id=systemUUID().get_uuid(name), - entity_type="CanSimulator" + entity_type="CanBusSimulator" ) self.extended_id=extended_id diff --git a/liota/lib/transports/Can.py b/liota/lib/transports/CanBus.py similarity index 98% rename from liota/lib/transports/Can.py rename to liota/lib/transports/CanBus.py index 23466333..46d309ec 100644 --- a/liota/lib/transports/Can.py +++ b/liota/lib/transports/CanBus.py @@ -39,7 +39,7 @@ log = logging.getLogger(__name__) -class Can: +class CanBus: ''' CAN implementation for LIOTA. It uses python-can internally. ''' @@ -95,7 +95,7 @@ def shutdown(self): def stop(self): pass -class CanMessagingAttributes: +class CanBusMessagingAttributes: def __init__(self, pub_timestamp=0.0, arbitration_id=0, extended_id=True, is_remote_frame=False, is_error_frame=False, dlc=None): diff --git a/tests/test_can.py b/tests/test_can.py deleted file mode 100644 index e47d549d..00000000 --- a/tests/test_can.py +++ /dev/null @@ -1,38 +0,0 @@ -import unittest -import mock -from liota.device_comms.can_device_comms import CanDeviceComms -from liota.device_comms.device_comms import DeviceComms -from liota.lib.transports.Can import CanMessagingAttributes - -bus_type = "virtual" - -class TestCanDeviceComms(unittest.TestCase): - - - def test_canDeviceComms_fail_without_bustype(self): - with self.assertRaises(Exception): - c = CanDeviceComms("asd") - assertNotIsInstance(c, CanDeviceComms) - - with self.assertRaises(Exception): - c = CanDeviceComms() - assertNotIsInstance(c, CanDeviceComms) - - def test_canDeviceComms_takes_bustype(self): - - c = CanDeviceComms(bustype = bus_type) - assert isinstance(c, CanDeviceComms) - - def test_canDeviceComms_fail_with_invalidArg_msg_attr(self): - with self.assertRaises(Exception): - c = CanDeviceComms(bustype = bus_type, can_msg_attr="asd") - assertNotIsInstance(c, CanDeviceComms) - - def test_canDeviceComms_pass_with_validArg_msg_attr(self): - mock_can_msg_attr = mock.create_autospec(CanMessagingAttributes) - c = CanDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) - assert isinstance(c, CanDeviceComms) - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/test_can_device_comms.py b/tests/test_can_device_comms.py deleted file mode 100644 index e47d549d..00000000 --- a/tests/test_can_device_comms.py +++ /dev/null @@ -1,38 +0,0 @@ -import unittest -import mock -from liota.device_comms.can_device_comms import CanDeviceComms -from liota.device_comms.device_comms import DeviceComms -from liota.lib.transports.Can import CanMessagingAttributes - -bus_type = "virtual" - -class TestCanDeviceComms(unittest.TestCase): - - - def test_canDeviceComms_fail_without_bustype(self): - with self.assertRaises(Exception): - c = CanDeviceComms("asd") - assertNotIsInstance(c, CanDeviceComms) - - with self.assertRaises(Exception): - c = CanDeviceComms() - assertNotIsInstance(c, CanDeviceComms) - - def test_canDeviceComms_takes_bustype(self): - - c = CanDeviceComms(bustype = bus_type) - assert isinstance(c, CanDeviceComms) - - def test_canDeviceComms_fail_with_invalidArg_msg_attr(self): - with self.assertRaises(Exception): - c = CanDeviceComms(bustype = bus_type, can_msg_attr="asd") - assertNotIsInstance(c, CanDeviceComms) - - def test_canDeviceComms_pass_with_validArg_msg_attr(self): - mock_can_msg_attr = mock.create_autospec(CanMessagingAttributes) - c = CanDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) - assert isinstance(c, CanDeviceComms) - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/test_canbus.py b/tests/test_canbus.py new file mode 100644 index 00000000..afa761ce --- /dev/null +++ b/tests/test_canbus.py @@ -0,0 +1,38 @@ +import unittest +import mock +from liota.device_comms.canbus_device_comms import CanBusDeviceComms +from liota.device_comms.device_comms import DeviceComms +from liota.lib.transports.CanBus import CanBusMessagingAttributes + +bus_type = "virtual" + +class TestCanBusDeviceComms(unittest.TestCase): + + + def test_CanBusDeviceComms_fail_without_bustype(self): + with self.assertRaises(Exception): + c = CanBusDeviceComms("asd") + assertNotIsInstance(c, CanBusDeviceComms) + + with self.assertRaises(Exception): + c = CanBusDeviceComms() + assertNotIsInstance(c, CanBusDeviceComms) + + def test_CanBusDeviceComms_takes_bustype(self): + + c = CanBusDeviceComms(bustype = bus_type, can_msg_attr=None) + assert isinstance(c, CanBusDeviceComms) + + def test_CanBusDeviceComms_fail_with_invalidArg_msg_attr(self): + with self.assertRaises(Exception): + c = CanBusDeviceComms(bustype = bus_type, can_msg_attr="asd") + assertNotIsInstance(c, CanBusDeviceComms) + + def test_CanBusDeviceComms_pass_with_validArg_msg_attr(self): + mock_can_msg_attr = mock.create_autospec(CanBusMessagingAttributes) + c = CanBusDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) + assert isinstance(c, CanBusDeviceComms) + + +if __name__ == '__main__': + unittest.main() From 51764a9930fca23b1fbddfd972deebb47752b755 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 Jul 2017 20:31:33 +0530 Subject: [PATCH 09/12] Changes to the test file variables --- tests/test_canbus.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_canbus.py b/tests/test_canbus.py index afa761ce..1c47f8f1 100644 --- a/tests/test_canbus.py +++ b/tests/test_canbus.py @@ -11,27 +11,27 @@ class TestCanBusDeviceComms(unittest.TestCase): def test_CanBusDeviceComms_fail_without_bustype(self): with self.assertRaises(Exception): - c = CanBusDeviceComms("asd") - assertNotIsInstance(c, CanBusDeviceComms) + deviceComms = CanBusDeviceComms("asd") + assertNotIsInstance(deviceComms, CanBusDeviceComms) with self.assertRaises(Exception): - c = CanBusDeviceComms() - assertNotIsInstance(c, CanBusDeviceComms) + deviceComms = CanBusDeviceComms() + assertNotIsInstance(deviceComms, CanBusDeviceComms) def test_CanBusDeviceComms_takes_bustype(self): - c = CanBusDeviceComms(bustype = bus_type, can_msg_attr=None) - assert isinstance(c, CanBusDeviceComms) + deviceComms = CanBusDeviceComms(bustype = bus_type, can_msg_attr=None) + assert isinstance(deviceComms, CanBusDeviceComms) def test_CanBusDeviceComms_fail_with_invalidArg_msg_attr(self): with self.assertRaises(Exception): - c = CanBusDeviceComms(bustype = bus_type, can_msg_attr="asd") - assertNotIsInstance(c, CanBusDeviceComms) + deviceComms = CanBusDeviceComms(bustype = bus_type, can_msg_attr="asd") + assertNotIsInstance(deviceComms, CanBusDeviceComms) def test_CanBusDeviceComms_pass_with_validArg_msg_attr(self): mock_can_msg_attr = mock.create_autospec(CanBusMessagingAttributes) - c = CanBusDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) - assert isinstance(c, CanBusDeviceComms) + deviceComms = CanBusDeviceComms(bustype = bus_type, can_msg_attr=mock_can_msg_attr) + assert isinstance(deviceComms, CanBusDeviceComms) if __name__ == '__main__': From e8b88ced0dfc35bb152ec715e56790e299382876 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Jul 2017 15:35:41 +0530 Subject: [PATCH 10/12] Changes to the can bus simulations --- .../graphite_canbus_simulated.py | 23 ++++++++++--------- liota/dccs/graphite.py | 2 +- liota/entities/devices/canbus_simulated.py | 2 ++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/examples/model_simulated/graphite_canbus_simulated.py b/examples/model_simulated/graphite_canbus_simulated.py index 31c8d993..73e39b61 100644 --- a/examples/model_simulated/graphite_canbus_simulated.py +++ b/examples/model_simulated/graphite_canbus_simulated.py @@ -3,35 +3,36 @@ from liota.entities.metrics.metric import Metric from liota.entities.edge_systems.dell5k_edge_system import Dell5KEdgeSystem from liota.lib.transports.CanBus import CanBusMessagingAttributes -from liota.entities.devices.can_simulated import CanBusSimulated +from liota.entities.devices.canbus_simulated import CanBusSimulated from liota.lib.utilities.utility import read_user_config config = read_user_config('../sampleProp.conf') -def get_data(): - data = can_model.get_data() - return data +def get_id(): + id = can_model.get_id() + print("Id: ", id) + return id if __name__ == "__main__": edge_system = Dell5KEdgeSystem(config['EdgeSystemName']) - can_model = CanBusSimulated(name=config['DeviceName'], extended_id=True) + can_model = CanBusSimulated(name=config['DeviceName'], extended_id=False) graphite = Graphite(SocketDccComms(ip=config['GraphiteIP'], port=config['GraphitePort'])) graphite_reg_dev = graphite.register(can_model) - can_msg_metric = "model.can.msg" + can_msg_metric = "model.can.id" - can_msg_data = Metric( + can_msg_id = Metric( name=can_msg_metric, unit=None, interval=1, - sampling_function=get_data + sampling_function=get_id ) - reg_can_msg = graphite.register(can_msg_data) - graphite.create_relationship(graphite_reg_dev, reg_can_msg) - reg_can_msg.start_collecting() + reg_can_id = graphite.register(can_msg_id) + graphite.create_relationship(graphite_reg_dev, reg_can_id) + reg_can_id.start_collecting() \ No newline at end of file diff --git a/liota/dccs/graphite.py b/liota/dccs/graphite.py index da95d06b..cdb47086 100644 --- a/liota/dccs/graphite.py +++ b/liota/dccs/graphite.py @@ -62,7 +62,6 @@ def _format_data(self, reg_metric): return for _ in range(met_cnt): v = reg_metric.values.get(block=True) - print("V: ",v) if v is not None: # Graphite expects time in seconds, not milliseconds. Hence, # dividing by 1000 @@ -72,6 +71,7 @@ def _format_data(self, reg_metric): return log.info ("Publishing values to Graphite DCC") log.debug("Formatted message: {0}".format(message)) + print("Message: ", message) return message def set_properties(self, reg_entity, properties): diff --git a/liota/entities/devices/canbus_simulated.py b/liota/entities/devices/canbus_simulated.py index 47536419..4809ff38 100644 --- a/liota/entities/devices/canbus_simulated.py +++ b/liota/entities/devices/canbus_simulated.py @@ -1,3 +1,4 @@ +import threading import random from liota.entities.devices.device import Device from liota.lib.utilities.utility import systemUUID @@ -17,6 +18,7 @@ def __init__(self, name, extended_id=True): def get_data(self): self.c1+=1 + self.data = list(map(lambda x:x+self.c1, self.data)) return self.data def get_id(self): From dafc6f4395dc8f0b4f24702f194e1a8ea4fd0eed Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Jul 2017 15:51:12 +0530 Subject: [PATCH 11/12] Small change to graphite_can_simulated.py --- examples/model_simulated/graphite_canbus_simulated.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/model_simulated/graphite_canbus_simulated.py b/examples/model_simulated/graphite_canbus_simulated.py index 73e39b61..e2220d37 100644 --- a/examples/model_simulated/graphite_canbus_simulated.py +++ b/examples/model_simulated/graphite_canbus_simulated.py @@ -35,4 +35,5 @@ def get_id(): reg_can_id = graphite.register(can_msg_id) graphite.create_relationship(graphite_reg_dev, reg_can_id) reg_can_id.start_collecting() + \ No newline at end of file From 968b6ba36ab54a67731559d4e8519207fd0c5977 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 18 Jul 2017 15:54:36 +0530 Subject: [PATCH 12/12] Added readme for can bus --- examples/canbus/README.md | 23 +++++++++ examples/canbus/simulated_canbus.py | 50 ++++++++++++++++--- .../graphite_canbus_simulated.py | 33 +++++++++++- liota/entities/devices/canbus_simulated.py | 32 ++++++++++++ tests/test_canbus.py | 32 ++++++++++++ 5 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 examples/canbus/README.md diff --git a/examples/canbus/README.md b/examples/canbus/README.md new file mode 100644 index 00000000..2de58545 --- /dev/null +++ b/examples/canbus/README.md @@ -0,0 +1,23 @@ +# Using Can Bus as Transport in LIOTA + +LIOTA offers Can bus protocol as transport at Device end via [CanBusDeviceComms](https://github.com/lucifercr07/liota/blob/can_bus/liota/device_comms/canbus_device_comms.py) + +## Using CanBusDeviceComms + +Can bus related parameters required in `send()` and `receive()` like bustype, channel etc., are fetched directly from the user. Please refer this [example](https://github.com/lucifercr07/liota/blob/can_bus/examples/canbus/simulated_canbus.py) for detailed explanation. + +### CanBusMessagingAttributes + +Can bus Messaging attributes allows you to define parameters such as arbitration_id, extended_id etc. which are used in the communication with can bus. + +Currently, using CanBusDeviceComms one can send and receive messages from a can bus. The data can be published over a dcc example graphite. +[example](https://github.com/lucifercr07/liota/blob/can_bus/examples/model_simulated/graphite_canbus_simulated.py) + +#### Default Values: + +* channel, bustype, can_filters and listeners will be **None** +* extende_id will be **True** +* arbitration_id will be **0** and +* dlc will be **None** + +**NOTE:** CanBusMessagingAttributes for a RegisteredMetric object MUST always be passed via **msg_attr** attribute of that RegisteredMetric Object. diff --git a/examples/canbus/simulated_canbus.py b/examples/canbus/simulated_canbus.py index 219343b0..bdf2544b 100644 --- a/examples/canbus/simulated_canbus.py +++ b/examples/canbus/simulated_canbus.py @@ -1,19 +1,55 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + +import time + from liota.device_comms.canbus_device_comms import CanBusDeviceComms from liota.entities.metrics.metric import Metric from liota.lib.transports.CanBus import CanBusMessagingAttributes - def actuator_value(value): print value -def can_connect(): - msg_attr = CanBusMessagingAttributes(arbitration_id=11,extended_id=False) +def can_connect(id): + msg_attr = CanBusMessagingAttributes(arbitration_id=0x0cf02200+id,extended_id=False) bus1 = CanBusDeviceComms (bustype='virtual',can_msg_attr=msg_attr) bus2 = CanBusDeviceComms (bustype='virtual',can_msg_attr=None) - bus1.send(data=[1,2,3],msg_attr=msg_attr) - msg = bus2.receive() - actuator_value(msg) + for i in range(5): + bus1.send(data=[id, i, 0, 1, 3, 1, 4, 1],msg_attr=msg_attr) + msg = bus2.receive() + actuator_value(msg) + time.sleep(1) if __name__ == "__main__": - can_connect() + for id in range(5): + can_connect(id) \ No newline at end of file diff --git a/examples/model_simulated/graphite_canbus_simulated.py b/examples/model_simulated/graphite_canbus_simulated.py index e2220d37..789e5f28 100644 --- a/examples/model_simulated/graphite_canbus_simulated.py +++ b/examples/model_simulated/graphite_canbus_simulated.py @@ -1,3 +1,35 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + from liota.dcc_comms.socket_comms import SocketDccComms from liota.dccs.graphite import Graphite from liota.entities.metrics.metric import Metric @@ -36,4 +68,3 @@ def get_id(): graphite.create_relationship(graphite_reg_dev, reg_can_id) reg_can_id.start_collecting() - \ No newline at end of file diff --git a/liota/entities/devices/canbus_simulated.py b/liota/entities/devices/canbus_simulated.py index 4809ff38..9b064816 100644 --- a/liota/entities/devices/canbus_simulated.py +++ b/liota/entities/devices/canbus_simulated.py @@ -1,3 +1,35 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + import threading import random from liota.entities.devices.device import Device diff --git a/tests/test_canbus.py b/tests/test_canbus.py index 1c47f8f1..eaba0f42 100644 --- a/tests/test_canbus.py +++ b/tests/test_canbus.py @@ -1,3 +1,35 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------# +# Copyright © 2015-2016 VMware, Inc. All Rights Reserved. # +# # +# Licensed under the BSD 2-Clause License (the “License”); you may not use # +# this file except in compliance with the License. # +# # +# The BSD 2-Clause License # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met:# +# # +# - Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# - Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"# +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # +# THE POSSIBILITY OF SUCH DAMAGE. # +# ----------------------------------------------------------------------------# + import unittest import mock from liota.device_comms.canbus_device_comms import CanBusDeviceComms