Last active
April 9, 2018 07:30
-
-
Save msqr/c1cda8595e56b00e3bf7e0c2d956df1a to your computer and use it in GitHub Desktop.
Spring Boot app configuration of WebsocketLoxoneService
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MIT License | |
// | |
// Copyright (c) 2018 Matt Magoffin | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
import static net.solarnetwork.node.loxone.dao.jdbc.BaseUUIDEntityDao.TABLE_NAME_FORMAT; | |
import java.util.Arrays; | |
import javax.sql.DataSource; | |
import org.osgi.service.event.EventAdmin; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.messaging.simp.SimpMessageSendingOperations; | |
import org.springframework.scheduling.TaskScheduler; | |
import org.springframework.transaction.PlatformTransactionManager; | |
import org.springframework.transaction.support.TransactionTemplate; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import net.solarnetwork.node.dao.SettingDao; | |
import net.solarnetwork.node.dao.jdbc.JdbcSettingDao; | |
import net.solarnetwork.node.loxone.LoxoneService; | |
import net.solarnetwork.node.loxone.dao.CategoryDao; | |
import net.solarnetwork.node.loxone.dao.ConfigDao; | |
import net.solarnetwork.node.loxone.dao.ControlDao; | |
import net.solarnetwork.node.loxone.dao.RoomDao; | |
import net.solarnetwork.node.loxone.dao.ValueEventDao; | |
import net.solarnetwork.node.loxone.dao.jdbc.JdbcCategoryDao; | |
import net.solarnetwork.node.loxone.dao.jdbc.JdbcControlDao; | |
import net.solarnetwork.node.loxone.dao.jdbc.JdbcRoomDao; | |
import net.solarnetwork.node.loxone.dao.jdbc.JdbcValueEventDao; | |
import net.solarnetwork.node.loxone.dao.jdbc.SettingsConfigDao; | |
import net.solarnetwork.node.loxone.impl.WebsocketLoxoneService; | |
import net.solarnetwork.node.loxone.protocol.ws.BinaryFileHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.CommandHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.LoxoneEvents; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.GetStructureFileCommandHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.IoControlCommandHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.StructureFileLastModifiedDateCommandHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.TextEventBinaryFileHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.ValueEventBinaryFileHandler; | |
import net.solarnetwork.node.loxone.protocol.ws.handler.WeatherEventBinaryFileHandler; | |
import net.solarnetwork.support.EventHandlerRegistrar; | |
import net.solarnetwork.util.OptionalService; | |
import net.solarnetwork.util.StaticOptionalService; | |
/** | |
* Example of Spring Boot based configuration of the SolarNode | |
* {@code net.solarnetwork.node.loxone.impl.WebsocketLoxoneService} class. | |
*/ | |
@Configuration | |
public class LoxoneSetupExample { | |
// First, some external configuration from application.(properties|yml)... | |
@Value("${loxone.dao.sqlResourcePrefix:derby-%s}") | |
private String sqlResourcePrefix = "derby-%s"; | |
@Value("${loxone.username:user}") | |
private String loxoneUsername = "user"; | |
@Value("${loxone.password:password}") | |
private String loxonePassword = "password"; | |
// Second, some external dependencies configured elsewhere in the app... | |
@Autowired | |
private DataSource dataSource; | |
@Autowired | |
private PlatformTransactionManager txManager; | |
@Autowired | |
private ObjectMapper objectMapper; | |
@Autowired | |
private TaskScheduler taskScheduler; | |
@Autowired | |
private OptionalService<EventAdmin> optionalEventAdmin; | |
@Autowired | |
private EventHandlerRegistrar eventHandlerRegistrar; | |
@Autowired | |
private SimpMessageSendingOperations messageSendingOperations; | |
// Third, the main configuration of the LoxoneService | |
@Bean | |
public LoxoneService createLoxoneService(String uid, String host, String username, | |
String password) { | |
WebsocketLoxoneService client = new WebsocketLoxoneService(); | |
client.setUid(uid); | |
client.setConfigKey(client.getUid()); | |
client.setConfigDao(loxoneConfigDao()); | |
client.setControlDao(loxoneControlDao()); | |
client.setObjectMapper(objectMapper); | |
client.setTaskScheduler(taskScheduler); | |
client.setEventAdmin(optionalEventAdmin); | |
client.setEventDaos(Arrays.asList(loxoneValueEventDao())); | |
client.setBinaryFileHandlers(new BinaryFileHandler[] { | |
valueEventBinaryFileHandler(), | |
textEventBinaryFileHandler(), | |
weatherEventBinaryFileHandler(), | |
structureFileCommandHandler(), | |
}); | |
client.setCommandHandlers(new CommandHandler[] { | |
ioControlCommandHandler(), | |
structureFileCommandHandler(), | |
structureFileLastModifiedDateCommandHandler(), | |
}); | |
client.setHost(host); | |
client.setUsername(username != null ? username : loxoneUsername); | |
client.setPassword(password != null ? password : loxonePassword); | |
eventHandlerRegistrar.registerEventHandler(client, LoxoneEvents.STRUCTURE_FILE_SAVED_EVENT, | |
LoxoneEvents.STRUCTURE_FILE_MODIFICATION_DATE_EVENT); | |
return client; | |
} | |
// Forth, configuraiton of the handlers that respond to Loxone messages... | |
@Bean | |
public IoControlCommandHandler ioControlCommandHandler() { | |
IoControlCommandHandler handler = new IoControlCommandHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
return handler; | |
} | |
@Bean | |
public OptionalService<SimpMessageSendingOperations> optionalMessageSendingOperations() { | |
return new StaticOptionalService<SimpMessageSendingOperations>(messageSendingOperations); | |
} | |
@Bean | |
public ValueEventBinaryFileHandler valueEventBinaryFileHandler() { | |
ValueEventBinaryFileHandler handler = new ValueEventBinaryFileHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
handler.setMessageSendingOps(optionalMessageSendingOperations()); | |
handler.setEventDao(loxoneValueEventDao()); | |
handler.setSendValueEventsUpdatedEvents(true); | |
handler.setIgnoreUnchangedValues(false); | |
return handler; | |
} | |
@Bean | |
public TextEventBinaryFileHandler textEventBinaryFileHandler() { | |
TextEventBinaryFileHandler handler = new TextEventBinaryFileHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
handler.setMessageSendingOps(optionalMessageSendingOperations()); | |
return handler; | |
} | |
@Bean | |
public WeatherEventBinaryFileHandler weatherEventBinaryFileHandler() { | |
WeatherEventBinaryFileHandler handler = new WeatherEventBinaryFileHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
handler.setMessageSendingOps(optionalMessageSendingOperations()); | |
handler.setSendWeatherEvents(true); | |
return handler; | |
} | |
@Bean | |
public GetStructureFileCommandHandler structureFileCommandHandler() { | |
GetStructureFileCommandHandler handler = new GetStructureFileCommandHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
handler.setCategoryDao(loxoneCategoryDao()); | |
handler.setConfigDao(loxoneConfigDao()); | |
handler.setControlDao(loxoneControlDao()); | |
handler.setObjectMapper(objectMapper); | |
handler.setRoomDao(loxoneRoomDao()); | |
return handler; | |
} | |
@Bean | |
public StructureFileLastModifiedDateCommandHandler structureFileLastModifiedDateCommandHandler() { | |
StructureFileLastModifiedDateCommandHandler handler = new StructureFileLastModifiedDateCommandHandler(); | |
handler.setEventAdmin(optionalEventAdmin); | |
return handler; | |
} | |
// Fifth, configuration of the database (DAO) layer | |
@Bean | |
public SettingDao solarNodeSettingDao() { | |
JdbcSettingDao dao = new JdbcSettingDao(); | |
dao.setDataSource(dataSource); | |
dao.setTransactionTemplate(new TransactionTemplate(txManager)); | |
return dao; | |
} | |
@Bean | |
public CategoryDao loxoneCategoryDao() { | |
JdbcCategoryDao dao = new JdbcCategoryDao(sqlResourcePrefix, TABLE_NAME_FORMAT); | |
dao.setDataSource(dataSource); | |
return dao; | |
} | |
@Bean | |
public ConfigDao loxoneConfigDao() { | |
SettingsConfigDao dao = new SettingsConfigDao(); | |
dao.setSettingDao(solarNodeSettingDao()); | |
return dao; | |
} | |
@Bean | |
public ControlDao loxoneControlDao() { | |
JdbcControlDao dao = new JdbcControlDao(sqlResourcePrefix, TABLE_NAME_FORMAT); | |
dao.setDataSource(dataSource); | |
return dao; | |
} | |
@Bean | |
public ValueEventDao loxoneValueEventDao() { | |
JdbcValueEventDao dao = new JdbcValueEventDao(sqlResourcePrefix, TABLE_NAME_FORMAT); | |
dao.setDataSource(dataSource); | |
return dao; | |
} | |
@Bean | |
public RoomDao loxoneRoomDao() { | |
JdbcRoomDao dao = new JdbcRoomDao(sqlResourcePrefix, TABLE_NAME_FORMAT); | |
dao.setDataSource(dataSource); | |
return dao; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- MIT License | |
-- | |
-- Copyright (c) 2018 Matt Magoffin | |
-- | |
-- Permission is hereby granted, free of charge, to any person obtaining a copy | |
-- of this software and associated documentation files (the "Software"), to deal | |
-- in the Software without restriction, including without limitation the rights | |
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
-- copies of the Software, and to permit persons to whom the Software is | |
-- furnished to do so, subject to the following conditions: | |
-- | |
-- The above copyright notice and this permission notice shall be included in all | |
-- copies or substantial portions of the Software. | |
-- | |
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
-- SOFTWARE. | |
-- Example of a PostgreSQL DDL script to initialize tables required by the | |
-- net.solarnetwork.node.loxone.impl.WebsocketLoxoneService class at runtime. | |
CREATE SCHEMA IF NOT EXISTS solarnode; | |
CREATE TABLE solarnode.sn_settings ( | |
skey VARCHAR(256) NOT NULL, | |
tkey VARCHAR(256) NOT NULL DEFAULT '', | |
svalue VARCHAR(256) NOT NULL, | |
flags INTEGER NOT NULL DEFAULT 0, | |
modified TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
CONSTRAINT sn_settings_pk PRIMARY KEY (skey, tkey) | |
); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.sn_settings.version', '5'); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.db.create.time', CAST(CURRENT_TIMESTAMP AS VARCHAR(256))); | |
CREATE TABLE solarnode.loxone_category ( | |
uuid_hi BIGINT NOT NULL, | |
uuid_lo BIGINT NOT NULL, | |
config_id BIGINT NOT NULL, | |
name VARCHAR(256) NOT NULL, | |
sort INTEGER NOT NULL DEFAULT 0, | |
image VARCHAR(48), | |
ctype SMALLINT NOT NULL DEFAULT -1, | |
CONSTRAINT loxone_category_pk PRIMARY KEY (config_id, uuid_hi, uuid_lo) | |
); | |
CREATE INDEX loxone_category_name_idx ON solarnode.loxone_category (name); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.loxone_category.version', '2'); | |
CREATE TABLE solarnode.loxone_control ( | |
uuid_hi BIGINT NOT NULL, | |
uuid_lo BIGINT NOT NULL, | |
config_id BIGINT NOT NULL, | |
name VARCHAR(256) NOT NULL, | |
sort INTEGER NOT NULL DEFAULT 0, | |
ctype SMALLINT NOT NULL DEFAULT -1, | |
room_hi BIGINT, | |
room_lo BIGINT, | |
cat_hi BIGINT, | |
cat_lo BIGINT, | |
CONSTRAINT loxone_control_pk PRIMARY KEY (config_id, uuid_hi, uuid_lo) | |
); | |
CREATE INDEX loxone_control_name_idx ON solarnode.loxone_control (name); | |
CREATE TABLE solarnode.loxone_control_state ( | |
uuid_hi BIGINT NOT NULL, | |
uuid_lo BIGINT NOT NULL, | |
config_id BIGINT NOT NULL, | |
name VARCHAR(256) NOT NULL, | |
event_hi BIGINT NOT NULL, | |
event_lo BIGINT NOT NULL, | |
CONSTRAINT loxone_control_state_control_fk FOREIGN KEY (config_id, uuid_hi, uuid_lo) | |
REFERENCES solarnode.loxone_control (config_id, uuid_hi, uuid_lo) | |
ON DELETE CASCADE | |
); | |
CREATE UNIQUE INDEX loxone_control_state_idx | |
ON solarnode.loxone_control_state (config_id, uuid_hi, uuid_lo, name); | |
CREATE INDEX loxone_control_state_name_idx ON solarnode.loxone_control_state (name); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.loxone_control.version', '2'); | |
CREATE TABLE solarnode.loxone_room ( | |
uuid_hi BIGINT NOT NULL, | |
uuid_lo BIGINT NOT NULL, | |
config_id BIGINT NOT NULL, | |
name VARCHAR(256) NOT NULL, | |
sort INTEGER NOT NULL DEFAULT 0, | |
image VARCHAR(48), | |
CONSTRAINT loxone_room_pk PRIMARY KEY (config_id, uuid_hi, uuid_lo) | |
); | |
CREATE INDEX loxone_room_name_idx ON solarnode.loxone_room (name); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.loxone_room.version', '2'); | |
CREATE TABLE solarnode.loxone_vevent ( | |
uuid_hi BIGINT NOT NULL, | |
uuid_lo BIGINT NOT NULL, | |
config_id BIGINT NOT NULL, | |
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
fvalue DOUBLE PRECISION NOT NULL, | |
CONSTRAINT loxone_vevent_pk PRIMARY KEY (config_id, uuid_hi, uuid_lo) | |
); | |
INSERT INTO solarnode.sn_settings (skey, svalue) | |
VALUES ('solarnode.loxone_vevent.version', '1'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment