Monthly Archives: June 2018

Spring CORS No ‘Access-Control-Allow-Origin’ header is present

Enabling CORS for the whole application is as simple as:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

To enable CORS for the whole controller:

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

To enable CORS for the method:

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

References
https://stackoverflow.com/questions/35091524/spring-cors-no-access-control-allow-origin-header-is-present

Java BACnet

Build.gradle

repositories {
    maven {
        url "https://maven.mangoautomation.net/repository/ias-release/"
    }
}
compile group: 'com.serotonin', name: 'bacnet4j', version: '4.0.1'

Read and Write Values

public class Main {

    private static LocalDevice localDevice;
    private static RemoteDevice remoteDevice;

    public static void main(String[] args) {
        try {

            IpNetwork network = new IpNetworkBuilder().
                    withBroadcast("192.168.1.255", 24).
                    build();

            Transport transport = new DefaultTransport(network);
            localDevice = new LocalDevice(6, transport);


            localDevice.initialize();

            remoteDevice = localDevice.getRemoteDeviceBlocking(6);

            DiscoveryUtils.getExtendedDeviceInformation(localDevice, remoteDevice);

            /*List oids = ((SequenceOf) RequestUtils.sendReadPropertyAllowNull(localDevice, remoteDevice,
                    remoteDevice.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();*/

            List<ObjectIdentifier> objectIdentifierList = new ArrayList<ObjectIdentifier>();

            /*for (Object obj : oids) {
                if (obj.getClass().equals(ObjectIdentifier.class)) {
                    ObjectIdentifier oid = (ObjectIdentifier) obj;

                    if (oid.getInstanceNumber() == 85) {
                        if (oid.getObjectType() == ObjectType.binaryOutput) {
                            objectIdentifierList.add(oid);
                        }
                    }
                }
            }*/

            ObjectIdentifier objectIdentifier = new ObjectIdentifier(ObjectType.binaryOutput, 85);
            objectIdentifierList.add(objectIdentifier);
            readPresentValues(objectIdentifierList);
            //readPresentValue(objectIdentifier);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static void readPresentValues(List<ObjectIdentifier> oids) throws BACnetException {
        PropertyReferences references = new PropertyReferences();

        for (ObjectIdentifier oid : oids) {
            references.add(oid, PropertyIdentifier.presentValue);
        }

        PropertyValues values = RequestUtils.readProperties(localDevice, remoteDevice, references, null);

        for (ObjectIdentifier oid : oids) {
            System.out.println(values.getString(oid, PropertyIdentifier.presentValue));
        }
    }

    private static void readPresentValue(ObjectIdentifier oid) throws Exception {
        ReadPropertyRequest rpr = new ReadPropertyRequest(oid,
                PropertyIdentifier.presentValue);
        ReadPropertyAck ack = (ReadPropertyAck) localDevice.send(remoteDevice, rpr);
        System.out.println("Present value: " + ack.getValue());
    }

    private static void setPresentValue(ObjectIdentifier oid, Encodable value, int priority) throws Exception {
        WritePropertyRequest wpr = new WritePropertyRequest(oid,
                PropertyIdentifier.presentValue, null, value, new UnsignedInteger(priority));
        localDevice.send(remoteDevice, wpr);
    }

    private static void getPriorityArray(ObjectIdentifier oid) throws Exception {
        ReadPropertyRequest rpr = new ReadPropertyRequest(oid,
                PropertyIdentifier.priorityArray);
        ReadPropertyAck ack = (ReadPropertyAck) localDevice.send(remoteDevice, rpr);
        System.out.println("Priority array: " + ack.getValue());
    }
}

References
https://github.com/infiniteautomation/BACnet4J
https://www.csimn.com/CSI_pages/BACnet101.html
https://github.com/openmucextensions/bacnet/wiki

Java Modbus Client

Modbus TCP Client Example

public class run {
	public static void main(String[] args)
	{
		ModbusClient modbusClient = new ModbusClient("127.0.0.1",502);
		try
		{
			modbusClient.Connect();
			modbusClient.WriteSingleCoil(0, true);
			modbusClient.WriteSingleRegister(0, 1234);
			modbusClient.WriteMultipleRegisters(11, ModbusClient.ConvertFloatToTwoRegisters((float) 123.56));
			System.out.println(modbusClient.ReadCoils(0, 1)[0]);
			System.out.println(modbusClient.ReadHoldingRegisters(0, 1)[0]);
			System.out.println(ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(11, 2)));
		}
		catch (Exception e)
		{		
		}	
	}
}

Read an Write 32 Bit Values

    public static void main(String[] args) 
    {
        ModbusClient modbusClient = new ModbusClient("127.0.0.1", 1536);
        try
        {
            modbusClient.Connect();
            //Write Float value to Register 10 and 11
            modbusClient.WriteMultipleRegisters(9, ModbusClient.ConvertFloatToTwoRegisters((float)(1323.55)));
            //Write 32 bit value to Register 12 and 13
            modbusClient.WriteMultipleRegisters(11, ModbusClient.ConvertDoubleToTwoRegisters((1323554)));
            //Read Float Value from Register 10 and 11
            System.out.println(ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(9, 2)));
            //Read 32 Bit Value from Register 12 and 13
            System.out.println(ModbusClient.ConvertRegistersToDouble(modbusClient.ReadHoldingRegisters(11, 2)));
        }
        catch (Exception e)
        {
        System.out.println(e.toString());
        }   
    }

References
https://www.youtube.com/user/emileackbarali/videos
https://www.udemy.com/the-1-hour-modbus-rs485-primer/
https://www.rtaautomation.com/technologies/modbus-rtu/
http://easymodbustcp.net/java-modbus-tcp-client-example
http://easymodbustcp.net/java-read-an-write-32-bit-values
https://en.wikipedia.org/wiki/Modbus

Badge for TabLayout using setCustomView

layout/tab_header_badge.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayoutTabHeader"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageViewTabHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_bell" />

    <TextView
        android:id="@+id/textViewActiveAlarmBadge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/imageViewTabHeader"
        android:text="1"
        android:textColor="@color/accent" />

</RelativeLayout>
            viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

            viewPagerAdapter.addFragment(moreFragment); // 3
            viewPagerAdapter.addFragment(alarmHistoryFragment); // 2
            viewPagerAdapter.addFragment(activeAlarmsFragment); // 1
            viewPagerAdapter.addFragment(mainFragment); // 0


            viewPagerMain.setAdapter(viewPagerAdapter);
            viewPagerMain.setCurrentItem(3); // set default view on open
            tabLayoutMain.setupWithViewPager(viewPagerMain);

            tabLayoutMain.getTabAt(3).setIcon(R.drawable.ic_home);
            //tabLayoutMain.getTabAt(2).setIcon(R.drawable.ic_bell);
            tabLayoutMain.getTabAt(1).setIcon(R.drawable.ic_envelope_open);
            tabLayoutMain.getTabAt(0).setIcon(R.drawable.ic_bars);


            View tabHeader = LayoutInflater.from(this).inflate(R.layout.tab_header_badge, null);
            TextView textViewBadge = tabHeader.findViewById(R.id.textViewActiveAlarmBadge);
            textViewBadge.setText("10");
            tabLayoutMain.getTabAt(2).setCustomView(tabHeader);

            // endregion

References
https://mobikul.com/make-custom-tabs-icons-android/
https://stackoverflow.com/questions/41530141/how-to-show-notification-counter-in-a-tablayout
https://stackoverflow.com/questions/43266079/how-to-add-badge-to-android-tablayout

Tablayout with Icons on Android

mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
  mTabLayout.getTabAt(i).setIcon(R.drawable.your_icon);
}

or

<android.support.design.widget.TabLayout
         app:tabTextColor="@color/gray"
         app:tabMode="fixed"
         app:tabBackground="@color/red"
         app:tabIndicatorHeight="4dp"
         app:tabIndicatorColor="@color/purple"
         app:tabPadding="2dp"
         app:tabSelectedTextColor="@color/white"
         app:tabMinWidth="64dp"
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <!--add height and width to TabItem -->
     <android.support.design.widget.TabItem 
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

 </android.support.design.widget.TabLayout>

References
https://stackoverflow.com/questions/30892545/tablayout-with-icons-only

How the activity should be launched with android:launchMode

Use Cases Launch Mode Multiple Instances? Comments
Normal launches for most activities standard Yes Default. The system always creates a new instance of the activity in the target task and routes the intent to it.
singleTop Conditionally If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity.
Specialized launches
(not recommended for general use)
singleTask No The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent()method, rather than creating a new one.
singleInstance No Same as “singleTask", except that the system doesn’t launch any other activities into the task holding the instance. The activity is always the single and only member of its task.

References
https://developer.android.com/guide/topics/manifest/activity-element#lmode