【Spring-boot】使用【React】操作本地环境的Nature Remo

自然遥控

一种可以通过智能手机、智能音箱等设备控制电视、空调等红外线操作的家电设备,名为Nature Remo(自然遥控)。

总结

偶尔AWS故障会波及到NatureRemo导致无法使用。
一旦这种情况发生,平时通过Alexa来操作家电的切换就无法使用遥控器了。

昨晚深夜开始的Nature Remo系统故障是由于AWS(亚马逊网络服务)的故障引起的。目前已经部分改善,但完全恢复还需要一些时间。非常抱歉给您带来不便。希望您能稍等恢复,谢谢。

此外,NatureRemo还提供了一个可以从本地环境访问的API,该API只能获取和执行红外信号。
利用这个API,我们将开发一个可以在本地环境中操作NatureRemo的应用程序。
尚未实现保存红外信号的机制,我们也将一并进行实现。
Nature Inc.

环境整理 – 整理环境

    • サーバ: Spring-boot

 

    • フロントエンド: React.js

 

    DB: Cassandra

服务器端

akapo001/local-remo 在服务器端使用SpringBoot实现了REST API。
虽然也可以使用Firebase进行实现,但是下一个分配的项目计划中会使用Spring,为了回忆起来,我决定自己实现。
由于从NatureRemo获取的红外线信息在格式上看起来很棘手,我决定使用NoSQL的Cassandra进行数据存储。
Cassandra是使用Docker镜像进行构建的。

API清单

    • 信号取得

NatureRemoから赤外線信号を取得する
NatureRemoに赤外線信号を当てたあとこのAPIを実行すると赤外線情報を取得できる

信号保存

信号取得で取得した赤外線情報をそのままこのAPIのBodyにわたすとサーバ側のCassandraに保存するAPI
パスパラメータに信号に紐付ける名前を指定する。

信号一覧取得

Cassandraに保存されている信号の一覧を取得する。

信号実行

信号一覧で取得したデータから実行したい信号のIDを設定してリクエストするとNatureRemoを通して家電の操作ができる。

信号削除

信号一覧で取得したデータから削除したい信号のIDを設定してリクエストするとCassandraからデータを削除する。

将Spring配置连接到Cassandra。

由于缺乏Spring调用Cassandra的示例,我遇到了一些困难,但通过定义以下类作为配置类,我成功进行了连接。
将Keyspace、主机和端口等信息从配置文件中读取。

@Configuration
@EnableCassandraRepositories(cassandraTemplateRef = "cassandraTemplate")
public class CassandraConfig extends AbstractCassandraConfiguration {
    @Value("${spring.data.cassandra.username}")
    private String username;

    @Value("${spring.data.cassandra.password}")
    private String password;

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspaceName;

    @Value("${spring.data.cassandra.contact-points}")
    private String contactPoints;

    @Value("${spring.data.cassandra.port}")
    private int port;


    @Override
    @Primary
    @Bean
    public CassandraAdminTemplate cassandraTemplate() {
        CqlSession session = CqlSession.builder().withKeyspace(keyspaceName).build();
        return new CassandraAdminTemplate(session);
    }

    // ポート番号の設定
    @Override
    @Bean(name = "Port")
    public int getPort() {
        return port;  // デフォルトは9042
    }

    // キースペースの設定
    @Override
    @Bean(name = "KeySpace")
    protected String getKeyspaceName() {
        return keyspaceName;
    }

}

Cassandra操作

由于这也是最新版本,API的接口似乎不同,所以很难访问。在下面附上样例。

@Service
public class CassandraService {

    @Autowired
    CassandraAdminTemplate cassandraTemplate;

    public SignalTable insert(Signal signal, String name) {
        return cassandraTemplate.insert(new SignalTable(Uuids.timeBased(), name, signal));
    }

    public List<SignalTable> selectAll() {
        SimpleStatement select = QueryBuilder.selectFrom("signal").all().build();
        return cassandraTemplate.select(select, SignalTable.class);
    }

    public SignalTable select(String id) {
        UUID uuid = UUID.fromString(id);
        return cassandraTemplate.selectOneById(uuid, SignalTable.class);
    }

    public String delete(String id) throws NotFoundSignal {
        UUID uuid = UUID.fromString(id);
        Boolean res = cassandraTemplate.deleteById(uuid, SignalTable.class);
        if(!res) throw new NotFoundSignal("信号が見つかりませんでした");

        return id;
    }

}

跨域资源共享(CORS)对策

从本地前端调用本地独立设置的服务器时出现了以下错误。

The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

通过给controller类添加CrossOrigin注解,我们成功避免了这个问题。默认情况下,允许所有访问。

@RestController
@CrossOrigin
public class SignalController {
    @Autowired
    SignalService signalService;
    @Autowired
    CassandraService cassandraService;

    @GetMapping("/signal")
    Signal getSignal() {
        return signalService.fetchSignal();
    }

    @PostMapping("/signal")
    Signal sendSignal(@RequestBody SendSignal sendSignal) {
        Signal signal = cassandraService.select(sendSignal.getId()).getSignal();
        return signalService.sendSignal(signal);
    }

    @PostMapping("/signal/{name}")
    SignalTable  postSignal(@RequestBody Signal signal, @PathVariable String name) {return cassandraService.insert(signal, name);}

    @GetMapping("/all-signal")
    List<SignalTable> getAllSignal() { return cassandraService.selectAll();}

    @DeleteMapping("/signal/{id}")
    SimpleResponse deleteSignal(@PathVariable String id) throws NotFoundSignal {
        System.out.println(id);
        cassandraService.delete(id);
        return new SimpleResponse("削除成功");
    }
}

前端

实现一个功能,用React.js调用上述的API。前端设计很简单,省略了源代码等详细信息。

画面列表

家 (jiā)

在画面显示时,调用信号列表获取的API来以列表形式显示。

スクリーンショット 2021-03-08 11.55.03.png

创建

スクリーンショット 2021-03-08 11.51.17.png

从iPhone上的访问

IMG_6099.PNG
广告
将在 10 秒后关闭
bannerAds